diff options
Diffstat (limited to 'src/glibext')
29 files changed, 3124 insertions, 1367 deletions
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am index ba4e3fa..e2c9d69 100644 --- a/src/glibext/Makefile.am +++ b/src/glibext/Makefile.am @@ -4,10 +4,6 @@ BUILT_SOURCES = chrysamarshal.h chrysamarshal.c resources.h resources.c noinst_LTLIBRARIES = libglibext4.la libglibextui.la # libglibext.la libglibext_la_SOURCES = \ - buffercache-int.h \ - buffercache.h buffercache.c \ - bufferline.h bufferline.c \ - chrysamarshal.h chrysamarshal.c \ comparison-int.h \ comparison.h comparison.c \ configuration-int.h \ @@ -17,11 +13,9 @@ libglibext_la_SOURCES = \ gbinarycursor.h gbinarycursor.c \ gbinportion-int.h \ gbinportion.h gbinportion.c \ - displayoptions.h displayoptions.c \ glinecursor-int.h \ glinecursor.h glinecursor.c \ gnhash.h gnhash.c \ - linecolumn.h linecolumn.c \ notifier.h \ objhole.h \ proto.h \ @@ -35,12 +29,10 @@ libglibext_la_SOURCES = \ if BUILD_GTK_SUPPORT libglibext_la_SOURCES += \ - bufferview.h bufferview.c \ gloadedpanel-int.h \ gloadedpanel.h gloadedpanel.c \ named-int.h \ - named.h named.c \ - widthtracker.h widthtracker.c + named.h named.c endif @@ -51,6 +43,7 @@ libglibext_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) libglibext4_la_SOURCES = \ + chrysamarshal.h chrysamarshal.c \ helpers.h libglibext4_la_CFLAGS = $(TOOLKIT_CFLAGS) @@ -60,19 +53,37 @@ RES_FILES = \ tokenstyle.css libglibextui_la_SOURCES = \ + buffercache-int.h \ + buffercache.h buffercache.c \ + bufferline-int.h \ + bufferline.h bufferline.c \ + bufferview-int.h \ + bufferview.h bufferview.c \ + generator-int.h \ + generator.h generator.c \ + linecolumn.h linecolumn.c \ + linetoken.h linetoken.c \ + options-int.h \ + options.h options.c \ tokenstyle-int.h \ tokenstyle.h tokenstyle.c \ - resources.h resources.c + resources.h resources.c \ + widthtracker-int.h \ + widthtracker.h widthtracker.c libglibextui_la_CFLAGS = $(LIBGTK4_CFLAGS) +libglibextui_la_LIBADD = \ + generators/libglibextgenerators.la \ + options/libglibextoptions.la + devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) dev_HEADERS = $(libglibext_la_SOURCES:%c=) -#SUBDIRS = generators +SUBDIRS = generators options chrysamarshal.h: chrysamarshal.list diff --git a/src/glibext/buffercache-int.h b/src/glibext/buffercache-int.h index 0e831a2..59d273b 100644 --- a/src/glibext/buffercache-int.h +++ b/src/glibext/buffercache-int.h @@ -33,20 +33,20 @@ /* Informations rattachées à la génération d'une ligne */ -typedef struct _generator_link +typedef struct _generator_link_t { - GLineGenerator *instance; /* Fournisseur de contenu */ + GTokenGenerator *instance; /* Fournisseur de contenu */ size_t repeat; /* Compteur de successions */ -} generator_link; +} generator_link_t; /* Suivi interne de l'état d'une ligne */ -typedef struct _cache_info +typedef struct _cache_info_t { union { - generator_link generator; /* Générateur unique */ - generator_link *generators; /* Liste de générateurs */ + generator_link_t generator; /* Générateur unique */ + generator_link_t *generators; /* Liste de générateurs */ }; size_t count; /* Taille de cette liste */ @@ -54,7 +54,7 @@ typedef struct _cache_info BufferLineFlags extra_flags; /* Propriétés supplémentaires */ -} cache_info; +} cache_info_t; @@ -66,13 +66,25 @@ struct _GBufferCache { GObject parent; /* A laisser en premier */ + size_t opt_count; /* Qté de colonnes en option */ + size_t reg_count; /* Nombre de colonnes normales */ +#ifndef NDEBUG + size_t col_count; /* Nombre maximum de colonnes */ +#endif + + + +#if 0 GBinContent *content; /* Contenu binaire global */ #ifdef INCLUDE_GTK_SUPPORT GWidthTracker *tracker; /* Suivi des largeurs */ #endif +#endif + - cache_info *lines; /* Liste des lignes intégrées */ + + cache_info_t *lines; /* Liste des lignes intégrées */ size_t count; /* Quantité en cache */ size_t used; /* Quantité utilisée */ GRWLock access; /* Verrou de protection */ @@ -84,18 +96,20 @@ struct _GBufferCacheClass { GObjectClass parent; /* A laisser en premier */ - gint line_height; /* Hauteur maximale des lignes */ - gint left_margin; /* Marge gauche + espace */ - gint text_pos; /* Début d'impression du code */ - /* Signaux */ void (* size_changed) (GBufferCache *, bool, size_t, size_t); +#if 0 void (* line_updated) (GBufferCache *, size_t); +#endif }; +/* Met en place un nouveau tampon pour lignes quelconques. */ +bool g_buffer_cache_create(GBufferCache *, size_t, size_t); + + #endif /* _GLIBEXT_BUFFERCACHE_INT_H */ diff --git a/src/glibext/buffercache.c b/src/glibext/buffercache.c index 78c7479..7856ff2 100644 --- a/src/glibext/buffercache.c +++ b/src/glibext/buffercache.c @@ -37,40 +37,45 @@ /* --------------------- FONCTIONS AUXILIAIRES DE MANIPULATIONS --------------------- */ -/* Gros verrou global pour alléger les structures... */ -G_LOCK_DEFINE_STATIC(_line_update); - - /* Met en place un nouvel ensemble d'information sur une ligne. */ -static void init_cache_info(cache_info *, GLineGenerator *, size_t, BufferLineFlags); +static void init_cache_info(cache_info_t *, GTokenGenerator *, size_t, BufferLineFlags); /* Libère la mémoire occupée par des informations sur une ligne. */ -static void release_cache_info(cache_info *); +static void release_cache_info(cache_info_t *); + +/* Force la réinitialisation d'une éventuelle ligne cachée. */ +static void reset_cache_info_line(cache_info_t *); + +/* Suivit les variations du compteur de références d'une ligne. */ +static void on_line_ref_toggle(cache_info_t *, GBufferLine *, gboolean); + +/* Fournit la ligne de tampon correspondant aux générateurs. */ +static GBufferLine *get_cache_info_line(cache_info_t *, size_t, size_t, void *); + +/* Calcule l'indice d'apparition d'un générateur. */ +static size_t compute_cache_info_repetition(const cache_info_t *, GTokenGenerator *); + + + +#if 0 +/* Gros verrou global pour alléger les structures... */ +G_LOCK_DEFINE_STATIC(_line_update); + /* Ajoute un générateur aux informations sur une ligne. */ -static void extend_cache_info(cache_info *, GLineGenerator *, BufferLineFlags); +static void extend_cache_info(cache_info_t *, GLineGenerator *, BufferLineFlags); /* Retire un générateur aux informations d'une ligne. */ -static void remove_from_cache_info(cache_info *, GLineGenerator *); +static void remove_from_cache_info(cache_info_t *, GLineGenerator *); /* Retrouve l'emplacement correspondant à une position de ligne. */ -static void get_cache_info_cursor(const cache_info *, size_t, gint, GLineCursor **); - -/* Suivit les variations du compteur de références d'une ligne. */ -static void on_line_ref_toggle(cache_info *, GBufferLine *, gboolean); +static void get_cache_info_cursor(const cache_info_t *, size_t, gint, GLineCursor **); #ifdef INCLUDE_GTK_SUPPORT -/* Fournit la ligne de tampon correspondant aux générateurs. */ -static GBufferLine *get_cache_info_line(cache_info *, const GWidthTracker *, size_t, const GBinContent *); - #endif -/* Force la réinitialisation d'une éventuelle ligne cachée. */ -static void _reset_cache_info_line_unlocked(cache_info *); - -/* Force la réinitialisation d'une éventuelle ligne cachée. */ -static void reset_cache_info_line(cache_info *); +#endif @@ -78,7 +83,7 @@ static void reset_cache_info_line(cache_info *); /* Taille des allocations de masse */ -#define LINE_ALLOC_BULK 1000 +//#define LINE_ALLOC_BULK 1000 /* Procède à l'initialisation d'une classe de tampon de lignes. */ @@ -93,9 +98,6 @@ static void g_buffer_cache_dispose(GBufferCache *); /* Procède à la libération totale de la mémoire. */ static void g_buffer_cache_finalize(GBufferCache *); -/* Calcule l'indice d'apparition d'un générateur dans le tampon. */ -static size_t g_buffer_cache_compute_repetition(GBufferCache *, size_t, GLineGenerator *); - /* ---------------------------------------------------------------------------------- */ @@ -118,12 +120,12 @@ static size_t g_buffer_cache_compute_repetition(GBufferCache *, size_t, GLineGen * * ******************************************************************************/ -static void init_cache_info(cache_info *info, GLineGenerator *generator, size_t repeat, BufferLineFlags flags) +static void init_cache_info(cache_info_t *info, GTokenGenerator *generator, size_t repeat, BufferLineFlags flags) { info->generator.instance = generator; info->generator.repeat = repeat; - g_object_ref(G_OBJECT(generator)); + ref_object(generator); info->count = 1; @@ -146,16 +148,16 @@ static void init_cache_info(cache_info *info, GLineGenerator *generator, size_t * * ******************************************************************************/ -static void release_cache_info(cache_info *info) +static void release_cache_info(cache_info_t *info) { size_t i; /* Boucle de parcours */ if (info->count == 1) - g_object_unref(G_OBJECT(info->generator.instance)); + unref_object(info->generator.instance); else for (i = 0; i < info->count; i++) - g_object_unref(G_OBJECT(info->generators[i].instance)); + unref_object(info->generators[i].instance); reset_cache_info_line(info); @@ -164,6 +166,155 @@ static void release_cache_info(cache_info *info) /****************************************************************************** * * +* Paramètres : info = informations sur une ligne à venir manipuler. * +* * +* Description : Force la réinitialisation d'une éventuelle ligne cachée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void reset_cache_info_line(cache_info_t *info) +{ + if (info->line != NULL) + { + g_object_remove_toggle_ref(G_OBJECT(info->line), (GToggleNotify)on_line_ref_toggle, info); + + info->line = NULL; + + } + +} + + +/****************************************************************************** +* * +* Paramètres : info = informations sur une ligne à venir manipuler. * +* line = tampon de lignes à venir supprimer au besoin. * +* last = indication sur la valeur du compteur de références. * +* * +* Description : Suivit les variations du compteur de références d'une ligne. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_line_ref_toggle(cache_info_t *info, GBufferLine *line, gboolean last) +{ + if (last) + { + assert(info->line != NULL); + + reset_cache_info_line(info); + + } + +} + + +/****************************************************************************** +* * +* Paramètres : info = informations sur une ligne à venir manipuler. * +* index = indice de la ligne à constituer. * +* col_count = quantité de colonnes à considérer. * +* data = éventuelle donnée complémentaire fournie. * +* * +* Description : Fournit la ligne de tampon correspondant aux générateurs. * +* * +* Retour : Ligne déjà en place ou créée pour le besoin. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static GBufferLine *get_cache_info_line(cache_info_t *info, size_t index, size_t col_count, void *data) +{ + GBufferLine *result; /* Construction à retourner */ + size_t i; /* Boucle de parcours */ + + result = info->line; + + if (result != NULL) + ref_object(result); + + else + { + result = g_buffer_line_new(col_count); + + //g_buffer_line_add_flag(result, info->extra_flags); + + g_object_add_toggle_ref(G_OBJECT(result), (GToggleNotify)on_line_ref_toggle, info); + + if (info->count == 1) + g_token_generator_populate_line(info->generator.instance, + index, info->generator.repeat, + result, data); + + else + for (i = 0; i < info->count; i++) + g_token_generator_populate_line(info->generators[i].instance, + index, info->generators[i].repeat, + result, data); + + info->line = result; + + } + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : info = informations sur une ligne à consulter. * +* generator = générateur associé à au moins une ligne. * +* * +* Description : Calcule l'indice d'apparition d'un générateur. * +* * +* Retour : Indice de répétition, 0 si aucune. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t compute_cache_info_repetition(const cache_info_t *info, GTokenGenerator *generator) +{ + size_t result; /* Compteur à retourner */ + size_t i; /* Boucle de parcours */ + + result = 0; + + if (info->count == 1) + { + if (info->generator.instance == generator) + result = info->generator.repeat + 1; + + } + + else + for (i = 0; i < info->count; i++) + if (info->generators[i].instance == generator) + { + result = info->generators[i].repeat + 1; + break; + } + + return result; + +} + + + + + +#if 0 +/****************************************************************************** +* * * Paramètres : info = informations concernant une ligne à actualiser. * * generator = générateur à associer à toutes les lignes. * * flags = propriétés supplémentaires à associer à la ligne.* @@ -176,7 +327,7 @@ static void release_cache_info(cache_info *info) * * ******************************************************************************/ -static void extend_cache_info(cache_info *info, GLineGenerator *generator, BufferLineFlags flags) +static void extend_cache_info(cache_info_t *info, GLineGenerator *generator, BufferLineFlags flags) { generator_link first; /* Générateur déjà en place */ generator_link *new; /* Nouveau générateur placé */ @@ -235,7 +386,7 @@ static void extend_cache_info(cache_info *info, GLineGenerator *generator, Buffe * * ******************************************************************************/ -static void remove_from_cache_info(cache_info *info, GLineGenerator *generator) +static void remove_from_cache_info(cache_info_t *info, GLineGenerator *generator) { generator_link *link; /* Accès simplifié */ size_t i; /* Boucle de parcours */ @@ -326,7 +477,7 @@ static void remove_from_cache_info(cache_info *info, GLineGenerator *generator) * * ******************************************************************************/ -static void get_cache_info_cursor(const cache_info *info, size_t index, gint x, GLineCursor **cursor) +static void get_cache_info_cursor(const cache_info_t *info, size_t index, gint x, GLineCursor **cursor) { const generator_link *generator; /* Générateur retenu */ @@ -340,145 +491,18 @@ static void get_cache_info_cursor(const cache_info *info, size_t index, gint x, } -/****************************************************************************** -* * -* Paramètres : info = informations sur une ligne à venir manipuler. * -* line = tampon de lignes à venir supprimer au besoin. * -* last = indication sur la valeur du compteur de références. * -* * -* Description : Suivit les variations du compteur de références d'une ligne. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void on_line_ref_toggle(cache_info *info, GBufferLine *line, gboolean last) -{ - if (last) - { - G_LOCK(_line_update); - - assert(info->line != NULL); - - _reset_cache_info_line_unlocked(info); - - G_UNLOCK(_line_update); - - } - -} - #ifdef INCLUDE_GTK_SUPPORT -/****************************************************************************** -* * -* Paramètres : info = informations sur une ligne à venir manipuler. * -* tracker = gestionnaire de largeurs à consulter si besoin est.* -* index = indice de la ligne à constituer. * -* content = éventuel contenu binaire brut à imprimer. * -* * -* Description : Fournit la ligne de tampon correspondant aux générateurs. * -* * -* Retour : Ligne déjà en place ou créée pour le besoin. * -* * -* Remarques : - * -* * -******************************************************************************/ - -static GBufferLine *get_cache_info_line(cache_info *info, const GWidthTracker *tracker, size_t index, const GBinContent *content) -{ - GBufferLine *result; /* Construction à retourner */ - size_t i; /* Boucle de parcours */ - - G_LOCK(_line_update); - - result = info->line; - - if (result == NULL) - { - result = g_buffer_line_new(g_width_tracker_count_columns(tracker)); - - g_buffer_line_add_flag(result, info->extra_flags); - - g_object_add_toggle_ref(G_OBJECT(result), (GToggleNotify)on_line_ref_toggle, info); - - if (info->count == 1) - g_line_generator_print(info->generator.instance, result, index, - info->generator.repeat, content); - - else - for (i = 0; i < info->count; i++) - g_line_generator_print(info->generators[i].instance, result, index, - info->generators[i].repeat, content); - - info->line = result; - - } - - else - g_object_ref(G_OBJECT(result)); - - G_UNLOCK(_line_update); - - return result; - -} #endif -/****************************************************************************** -* * -* Paramètres : info = informations sur une ligne à venir manipuler. * -* * -* Description : Force la réinitialisation d'une éventuelle ligne cachée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void _reset_cache_info_line_unlocked(cache_info *info) -{ - if (info->line != NULL) - { - g_object_remove_toggle_ref(G_OBJECT(info->line), (GToggleNotify)on_line_ref_toggle, info); - - info->line = NULL; - } - -} - - -/****************************************************************************** -* * -* Paramètres : info = informations sur une ligne à venir manipuler. * -* * -* Description : Force la réinitialisation d'une éventuelle ligne cachée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void reset_cache_info_line(cache_info *info) -{ - G_LOCK(_line_update); - - _reset_cache_info_line_unlocked(info); - - G_UNLOCK(_line_update); - -} +#endif /* ---------------------------------------------------------------------------------- */ @@ -511,10 +535,6 @@ static void g_buffer_cache_class_init(GBufferCacheClass *class) object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_cache_dispose; object->finalize = (GObjectFinalizeFunc)g_buffer_cache_finalize; - class->line_height = 17; - class->left_margin = 2 * class->line_height; - class->text_pos = 2.5 * class->line_height; - /* Signaux */ g_signal_new("size-changed", @@ -525,6 +545,8 @@ static void g_buffer_cache_class_init(GBufferCacheClass *class) g_cclosure_user_marshal_VOID__BOOLEAN_ULONG_ULONG, G_TYPE_NONE, 3, G_TYPE_BOOLEAN, G_TYPE_ULONG, G_TYPE_ULONG); +#if 0 + g_signal_new("line-updated", G_TYPE_BUFFER_CACHE, G_SIGNAL_RUN_LAST, @@ -533,6 +555,8 @@ static void g_buffer_cache_class_init(GBufferCacheClass *class) g_cclosure_marshal_VOID__ULONG, G_TYPE_NONE, 1, G_TYPE_ULONG); +#endif + } @@ -550,6 +574,8 @@ static void g_buffer_cache_class_init(GBufferCacheClass *class) static void g_buffer_cache_init(GBufferCache *cache) { +#if 0 + cache->content = NULL; cache->lines = NULL; @@ -561,6 +587,8 @@ static void g_buffer_cache_init(GBufferCache *cache) cache->tracker = NULL; #endif +#endif + } @@ -578,8 +606,9 @@ static void g_buffer_cache_init(GBufferCache *cache) static void g_buffer_cache_dispose(GBufferCache *cache) { +#if 0 size_t i; /* Boucle de parcours #1 */ - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ size_t j; /* Boucle de parcours #2 */ g_clear_object(&cache->content); @@ -603,6 +632,8 @@ static void g_buffer_cache_dispose(GBufferCache *cache) g_clear_object(&cache->tracker); #endif +#endif + G_OBJECT_CLASS(g_buffer_cache_parent_class)->dispose(G_OBJECT(cache)); } @@ -622,8 +653,10 @@ static void g_buffer_cache_dispose(GBufferCache *cache) static void g_buffer_cache_finalize(GBufferCache *cache) { + +#if 0 size_t i; /* Boucle de parcours */ - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ for (i = 0; i < cache->used; i++) { @@ -639,6 +672,8 @@ static void g_buffer_cache_finalize(GBufferCache *cache) g_rw_lock_clear(&cache->access); +#endif + G_OBJECT_CLASS(g_buffer_cache_parent_class)->finalize(G_OBJECT(cache)); } @@ -646,11 +681,10 @@ static void g_buffer_cache_finalize(GBufferCache *cache) /****************************************************************************** * * -* Paramètres : content = éventuel contenu binaire brut à référencer. * -* col_count = quantité maximale de colonnes à considérer. * -* opt_count = quantité de colonnes optionnelles. * +* Paramètres : opt_count = quantité de colonnes optionnelles. * +* reg_count = quantité de colonnes normales à considérer. * * * -* Description : Crée un nouveau composant de tampon pour code désassemblé. * +* Description : Crée un nouveau tampon pour lignes quelconques. * * * * Retour : Composant GLib créé. * * * @@ -658,21 +692,14 @@ static void g_buffer_cache_finalize(GBufferCache *cache) * * ******************************************************************************/ -GBufferCache *g_buffer_cache_new(GBinContent *content, size_t col_count, size_t opt_count) +GBufferCache *g_buffer_cache_new(size_t opt_count, size_t reg_count) { GBufferCache *result; /* Composant à retourner */ result = g_object_new(G_TYPE_BUFFER_CACHE, NULL); - if (content != NULL) - { - result->content = content; - g_object_ref(G_OBJECT(content)); - } - -#ifdef INCLUDE_GTK_SUPPORT - result->tracker = g_width_tracker_new(result, col_count, opt_count); -#endif + if (!g_buffer_cache_create(result, opt_count, reg_count)) + g_clear_object(&result); return result; @@ -681,24 +708,30 @@ GBufferCache *g_buffer_cache_new(GBinContent *content, size_t col_count, size_t /****************************************************************************** * * -* Paramètres : cache = tampon de lignes à consulter. * +* Paramètres : cache = cache de lignes à initialiser. * +* opt_count = quantité de colonnes optionnelles. * +* reg_count = quantité de colonnes normales à considérer. * * * -* Description : Indique l'éventuel contenu binaire associé au cache. * +* Description : Met en place un nouveau tampon pour lignes quelconques. * * * -* Retour : Eventuel contenu renseigné ou NULL. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -GBinContent *g_buffer_cache_get_content(const GBufferCache *cache) +bool g_buffer_cache_create(GBufferCache *cache, size_t opt_count, size_t reg_count) { - GBinContent *result; /* Contenu à retourner */ + bool result; /* Bilen à retourner */ - result = cache->content; + result = true; - if (result != NULL) - g_object_ref(G_OBJECT(result)); + cache->opt_count = opt_count; + cache->reg_count = reg_count; + +#ifndef NDEBUG + cache->col_count = opt_count + reg_count; +#endif return result; @@ -707,111 +740,191 @@ GBinContent *g_buffer_cache_get_content(const GBufferCache *cache) /****************************************************************************** * * -* Paramètres : cache = tampon de lignes à consulter. * +* Paramètres : cache = tampon de lignes à consulter. * +* opt_count = quantité de colonnes optionnelles. [OUT] * +* reg_count = quantité de colonnes normales à considérer. [OUT]* * * -* Description : Fournit la hauteur d'impression d'une ligne visualisée. * +* Description : Fournit le nombre de colonnes supportées par un tampon. * * * -* Retour : Hauteur de ligne en pixels. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -gint g_buffer_cache_get_line_height(const GBufferCache *cache) +void g_buffer_cache_count_columns(const GBufferCache *cache, size_t *opt_count, size_t *reg_count) { - GBufferCacheClass *class; /* Classe des tampons */ + *opt_count = cache->opt_count; + *reg_count = cache->reg_count; - class = G_BUFFER_CACHE_GET_CLASS(cache); +} - return class->line_height; + +/****************************************************************************** +* * +* Paramètres : cache = cache de lignes à mettre à jour. * +* write = précise le type d'accès prévu (lecture/écriture). * +* lock = indique le sens du verrouillage à mener. * +* * +* Description : Met à disposition un encadrement des accès aux lignes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_cache_lock_unlock(GBufferCache *cache, bool write, bool lock) +{ + if (write) + { + if (lock) g_rw_lock_writer_lock(&cache->access); + else g_rw_lock_writer_unlock(&cache->access); + } + else + { + if (lock) g_rw_lock_reader_lock(&cache->access); + else g_rw_lock_reader_unlock(&cache->access); + } } /****************************************************************************** * * -* Paramètres : cache = tampon de lignes à consulter. * +* Paramètres : cache = instance GLib à consulter. * * * -* Description : Fournit la taille réservée pour la marge gauche. * +* Description : Compte le nombre de lignes rassemblées dans un tampon. * * * -* Retour : Largeur en pixels. * +* Retour : Nombre de lignes constituant le tampon. * * * * Remarques : - * * * ******************************************************************************/ -gint g_buffer_cache_get_left_margin(const GBufferCache *cache) +size_t g_buffer_cache_count_lines(GBufferCache *cache) { - GBufferCacheClass *class; /* Classe des tampons */ + size_t result; /* Quantité à retourner */ - class = G_BUFFER_CACHE_GET_CLASS(cache); + assert(!g_rw_lock_writer_trylock(&cache->access)); - return class->left_margin; + result = cache->used; + + return result; } /****************************************************************************** * * -* Paramètres : cache = tampon de lignes à consulter. * +* Paramètres : cache = instance GLib à modifier. * +* count = quantité totale de lignes à avoir à disposition. * +* generator = générateur à associer à toutes les lignes. * * * -* Description : Fournit la position de départ pour l'impression de texte. * +* Description : Etend un tampon avec un générateur de lignes unique. * * * -* Retour : Position en pixels. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -gint g_buffer_cache_get_text_position(const GBufferCache *cache) +void g_buffer_cache_extend_with(GBufferCache *cache, size_t count, GTokenGenerator *generator) { - GBufferCacheClass *class; /* Classe des tampons */ + size_t index; /* Point d'insertion */ + size_t repeat; /* Compteur de répétition */ + size_t i; /* Boucle de parcours */ + size_t added; /* Nombre d'ajouts effectués */ - class = G_BUFFER_CACHE_GET_CLASS(cache); + assert(!g_rw_lock_writer_trylock(&cache->access)); - return class->text_pos; + assert(count >= cache->used); -} + if (count > cache->count) + { + cache->lines = realloc(cache->lines, count * sizeof(cache_info_t)); + cache->count = count; + } + index = cache->used; -#ifdef INCLUDE_GTK_SUPPORT + if (index == 0) + repeat = 0; + else + repeat = compute_cache_info_repetition(&cache->lines[index - 1], generator); + + for (i = index; i < count; i++) + init_cache_info(&cache->lines[i], generator, repeat++, BLF_NONE); + + added = count - cache->used; + + cache->used = count; + + if (added > 0) + { + //g_width_tracker_update_added(cache->tracker, index, added); + + g_signal_emit_by_name(cache, "size-changed", true, index, added); + + } + +} /****************************************************************************** * * -* Paramètres : cache = composant GLib à consulter. * +* Paramètres : cache = instance GLib à modifier. * +* max = nombre maximal de lignes à conserver. * * * -* Description : Fournit un lien vers la structure de suivi de largeurs. * +* Description : Réduit le tampon à une quantité de lignes précise. * * * -* Retour : Gestionnaire de largeurs de lignes. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache) +void g_buffer_cache_truncate(GBufferCache *cache, size_t max) { - GWidthTracker *result; /* Instance à retourner * */ + size_t i; /* Boucle de parcours */ + size_t removed; /* Nombre de retraits effectués*/ - result = cache->tracker; + assert(!g_rw_lock_writer_trylock(&cache->access)); - g_object_ref(G_OBJECT(result)); + for (i = max; i < cache->used; i++) + release_cache_info(&cache->lines[i]); - return result; + if (max < cache->used) + { + removed = cache->used - max; + + cache->used = max; + + //g_width_tracker_update_deleted(cache->tracker, max, max + removed - 1); + + g_signal_emit_by_name(cache, "size-changed", false, max, removed); + + } } -#endif + + + /****************************************************************************** * * -* Paramètres : cache = cache de lignes à mettre à jour. * -* write = précise le type d'accès prévu (lecture/écriture). * -* lock = indique le sens du verrouillage à mener. * +* Paramètres : cache = visualisation à représenter. * +* cr = contexte graphique dédié à la procédure. * +* column = (première) colonne à traiter. * +* top = ordonnée attribuée à la première ligne. * +* first = première ligne à dessiner. * +* last = dernière ligne à dessiner. * +* style = style de rendu pour les bribes de texte. * * * -* Description : Met à disposition un encadrement des accès aux lignes. * +* Description : Imprime une partie choisie du tampon contenant des lignes. * * * * Retour : - * * * @@ -819,41 +932,67 @@ GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache) * * ******************************************************************************/ -void g_buffer_cache_lock_unlock(GBufferCache *cache, bool write, bool lock) +void g_buffer_cache_draw(GBufferCache *cache, cairo_t *cr, size_t column, int top, size_t first, size_t last, const GTokenStyle *style) { - if (write) - { - if (lock) g_rw_lock_writer_lock(&cache->access); - else g_rw_lock_writer_unlock(&cache->access); - } - else + int y; /* Point de départ en ordonnée */ + int lheight; /* Hauteur d'une ligne */ + size_t i; /* Boucle de parcours */ + GBufferLine *line; /* Ligne à venir dessiner */ + + if (cache->used > 0) { - if (lock) g_rw_lock_reader_lock(&cache->access); - else g_rw_lock_reader_unlock(&cache->access); + y = top; + + lheight = g_token_style_get_line_height(style); + + g_buffer_cache_rlock(cache); + + for (i = first; i <= last; i++) + { + line = get_cache_info_line(&cache->lines[i], i, cache->opt_count + cache->reg_count, NULL); + + g_buffer_line_draw(line, cr, column, y, style); + + unref_object(line); + + y += lheight; + + } + + g_buffer_cache_runlock(cache); + } } + + + + + + +#if 0 /****************************************************************************** * * -* Paramètres : cache = instance GLib à consulter. * +* Paramètres : cache = tampon de lignes à consulter. * * * -* Description : Compte le nombre de lignes rassemblées dans un tampon. * +* Description : Indique l'éventuel contenu binaire associé au cache. * * * -* Retour : Nombre de lignes constituant le tampon. * +* Retour : Eventuel contenu renseigné ou NULL. * * * * Remarques : - * * * ******************************************************************************/ -size_t g_buffer_cache_count_lines(GBufferCache *cache) +GBinContent *g_buffer_cache_get_content(const GBufferCache *cache) { - size_t result; /* Quantité à retourner */ + GBinContent *result; /* Contenu à retourner */ - assert(!g_rw_lock_writer_trylock(&cache->access)); + result = cache->content; - result = cache->used; + if (result != NULL) + g_object_ref(G_OBJECT(result)); return result; @@ -862,52 +1001,110 @@ size_t g_buffer_cache_count_lines(GBufferCache *cache) /****************************************************************************** * * -* Paramètres : cache = instance GLib à consulter. * -* index = indice de la ligne où se trouve le générateur. * -* generator = générateur associé à au moins une ligne. * +* Paramètres : cache = tampon de lignes à consulter. * * * -* Description : Calcule l'indice d'apparition d'un générateur dans le tampon.* +* Description : Fournit la hauteur d'impression d'une ligne visualisée. * * * -* Retour : - * +* Retour : Hauteur de ligne en pixels. * * * * Remarques : - * * * ******************************************************************************/ -static size_t g_buffer_cache_compute_repetition(GBufferCache *cache, size_t index, GLineGenerator *generator) +gint g_buffer_cache_get_line_height(const GBufferCache *cache) { - size_t result; /* Compteur à retourner */ - cache_info *info; /* Accès direct à une ligne */ - size_t i; /* Boucle de parcours */ + GBufferCacheClass *class; /* Classe des tampons */ - result = 0; + class = G_BUFFER_CACHE_GET_CLASS(cache); - if (index > 0) - { - info = &cache->lines[index - 1]; + return class->line_height; - if (info->count == 1) - { - if (info->generator.instance == generator) - result = info->generator.repeat + 1; +} - } - else - for (i = 0; i < info->count; i++) - if (info->generators[i].instance == generator) - { - result = info->generators[i].repeat + 1; - break; - } +/****************************************************************************** +* * +* Paramètres : cache = tampon de lignes à consulter. * +* * +* Description : Fournit la taille réservée pour la marge gauche. * +* * +* Retour : Largeur en pixels. * +* * +* Remarques : - * +* * +******************************************************************************/ - } +gint g_buffer_cache_get_left_margin(const GBufferCache *cache) +{ + GBufferCacheClass *class; /* Classe des tampons */ + + class = G_BUFFER_CACHE_GET_CLASS(cache); + + return class->left_margin; + +} + + +/****************************************************************************** +* * +* Paramètres : cache = tampon de lignes à consulter. * +* * +* Description : Fournit la position de départ pour l'impression de texte. * +* * +* Retour : Position en pixels. * +* * +* Remarques : - * +* * +******************************************************************************/ + +gint g_buffer_cache_get_text_position(const GBufferCache *cache) +{ + GBufferCacheClass *class; /* Classe des tampons */ + + class = G_BUFFER_CACHE_GET_CLASS(cache); + + return class->text_pos; + +} + + +#ifdef INCLUDE_GTK_SUPPORT + + +/****************************************************************************** +* * +* Paramètres : cache = composant GLib à consulter. * +* * +* Description : Fournit un lien vers la structure de suivi de largeurs. * +* * +* Retour : Gestionnaire de largeurs de lignes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *cache) +{ + GWidthTracker *result; /* Instance à retourner * */ + + result = cache->tracker; + + g_object_ref(G_OBJECT(result)); return result; } +#endif + + + + + + + + /****************************************************************************** * * * Paramètres : cache = instance GLib à modifier. * @@ -1063,7 +1260,7 @@ void g_buffer_cache_insert_at(GBufferCache *cache, size_t index, GLineGenerator void g_buffer_cache_delete_at(GBufferCache *cache, size_t index) { - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1107,7 +1304,7 @@ void g_buffer_cache_delete_at(GBufferCache *cache, size_t index) GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *cache, size_t index, GType type, bool before, bool after) { GLineGenerator *result; /* Prédécesseur à retourner */ - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ generator_link *link; /* Accès simplifié */ size_t i; /* Boucle de parcours */ size_t count; /* Emplacements occupés */ @@ -1236,7 +1433,7 @@ void g_buffer_cache_append(GBufferCache *cache, GLineGenerator *generator, Buffe size_t count; /* Nombre de lignes générées */ size_t index; /* Point d'insertion */ size_t i; /* Boucle de parcours */ - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ size_t repeat; /* Compteur de répétition */ assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1255,146 +1452,37 @@ void g_buffer_cache_append(GBufferCache *cache, GLineGenerator *generator, Buffe index = cache->used; - for (i = 0; i < count; i++) - { - info = &cache->lines[index + i]; - - repeat = g_buffer_cache_compute_repetition(cache, index + i, generator); - - init_cache_info(info, generator, repeat, flags); - - } - - cache->used += count; - -#ifdef INCLUDE_GTK_SUPPORT - g_width_tracker_update_added(cache->tracker, index, count); -#endif - - g_signal_emit_by_name(cache, "size-changed", true, index, count); - -} - - -/****************************************************************************** -* * -* Paramètres : cache = instance GLib à modifier. * -* count = quantité totale de lignes à avoir à disposition. * -* generator = générateur à associer à toutes les lignes. * -* * -* Description : Etend un tampon avec un générateur de lignes unique. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_buffer_cache_extend_with(GBufferCache *cache, size_t count, GLineGenerator *generator) -{ - size_t index; /* Point d'insertion */ - size_t i; /* Boucle de parcours */ - cache_info *info; /* Accès direct à une ligne */ - size_t repeat; /* Compteur de répétition */ - size_t added; /* Nombre d'ajouts effectués */ - - assert(!g_rw_lock_writer_trylock(&cache->access)); - assert(count >= cache->used); + if (index == 0) + repeat = 0; - if (count > cache->count) + else { - cache->lines = realloc(cache->lines, count * sizeof(cache_info)); - cache->count = count; + info = &cache->lines[index - 1]; + repeat = compute_cache_info_repetition(info, generator); } - index = cache->used; - - for (i = index; i < count; i++) + for (i = 0; i < count; i++) { - info = &cache->lines[i]; - - repeat = g_buffer_cache_compute_repetition(cache, i, generator); - - init_cache_info(info, generator, repeat, BLF_NONE); - + info = &cache->lines[index + i]; + init_cache_info(info, generator, repeat++, flags); } - added = count - cache->used; + cache->used += count; - cache->used = count; + /* - if (added > 0) - { #ifdef INCLUDE_GTK_SUPPORT - g_width_tracker_update_added(cache->tracker, index, added); + g_width_tracker_update_added(cache->tracker, index, count); #endif - g_signal_emit_by_name(cache, "size-changed", true, index, added); + g_signal_emit_by_name(cache, "size-changed", true, index, count); - } + */ } -/****************************************************************************** -* * -* Paramètres : cache = instance GLib à modifier. * -* max = nombre maximal de lignes à conserver. * -* * -* Description : Réduit le tampon à une quantité de lignes précise. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_buffer_cache_truncate(GBufferCache *cache, size_t max) -{ - size_t i; /* Boucle de parcours #1 */ - cache_info *info; /* Accès direct à une ligne */ - size_t j; /* Boucle de parcours #2 */ - size_t removed; /* Nombre de retraits effectués*/ - - assert(!g_rw_lock_writer_trylock(&cache->access)); - - for (i = max; i < cache->used; i++) - { - info = &cache->lines[i]; - - if (info->count == 1) - g_object_unref(G_OBJECT(info->generator.instance)); - - else - { - for (j = 0; j < info->count; j++) - g_object_unref(G_OBJECT(info->generators[j].instance)); - - free(info->generators); - - } - - reset_cache_info_line(info); - - } - - if (max < cache->used) - { - removed = cache->used - max; - - cache->used = max; - -#ifdef INCLUDE_GTK_SUPPORT - g_width_tracker_update_deleted(cache->tracker, max, max + removed - 1); -#endif - - g_signal_emit_by_name(cache, "size-changed", false, max, removed); - - } - -} - #ifdef INCLUDE_GTK_SUPPORT @@ -1444,7 +1532,7 @@ void g_buffer_cache_get_line_cursor(GBufferCache *cache, size_t index, gint x, G void g_buffer_cache_add_line_flag(GBufferCache *cache, size_t index, BufferLineFlags flag) { - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1482,7 +1570,7 @@ void g_buffer_cache_add_line_flag(GBufferCache *cache, size_t index, BufferLineF BufferLineFlags g_buffer_cache_get_line_flags(GBufferCache *cache, size_t index) { BufferLineFlags result; /* Somme à renvoyer */ - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ const generator_link *generator; /* Générateur retenu */ size_t i; /* Boucle de parcours */ @@ -1528,7 +1616,7 @@ BufferLineFlags g_buffer_cache_get_line_flags(GBufferCache *cache, size_t index) void g_buffer_cache_remove_line_flag(GBufferCache *cache, size_t index, BufferLineFlags flag) { - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1621,7 +1709,7 @@ size_t g_buffer_cache_look_for_flag(GBufferCache *cache, size_t start, BufferLin void g_buffer_cache_refresh_line(GBufferCache *cache, size_t index) { - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1689,6 +1777,8 @@ void g_buffer_cache_collect_widths(GBufferCache *cache, size_t index, size_t col { GBufferLine *line; /* Ligne éphémère à mesurer */ + // Need lock + line = get_cache_info_line(&cache->lines[index], cache->tracker, index, cache->content); g_buffer_line_collect_widths(line, col_count, opt_count, widths, merged); @@ -1723,7 +1813,7 @@ void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, s gint y; /* Point de départ en ordonnée */ bool wait_selection; /* Sélection déjà passée ? */ size_t i; /* Boucle de parcours */ - cache_info *info; /* Accès direct à une ligne */ + cache_info_t *info; /* Accès direct à une ligne */ GBufferLine *line; /* Ligne à venir dessiner */ class = G_BUFFER_CACHE_GET_CLASS(cache); @@ -1749,6 +1839,8 @@ void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, s info = &cache->lines[i]; + // Need lock + line = get_cache_info_line(info, cache->tracker, i, cache->content); g_buffer_line_draw(line, i, cr, class->text_pos, y, cache->tracker, options, list); @@ -1784,11 +1876,11 @@ void g_buffer_cache_draw(const GBufferCache *cache, cairo_t *cr, size_t first, s size_t _g_buffer_cache_find_index_by_cursor(GBufferCache *cache, const GLineCursor *cursor, bool first, size_t start, size_t end) { size_t result; /* Indice à retourner */ - cache_info *found; /* Eventuel élément trouvé */ + cache_info_t *found; /* Eventuel élément trouvé */ assert(!g_rw_lock_writer_trylock(&cache->access)); - int find_containing_generator(const GLineCursor *c, const cache_info *i) + int find_containing_generator(const GLineCursor *c, const cache_info_t *i) { const generator_link *generator; /* Générateur retenu */ @@ -1802,7 +1894,7 @@ size_t _g_buffer_cache_find_index_by_cursor(GBufferCache *cache, const GLineCurs } - found = (cache_info *)bsearch(cursor, &cache->lines[start], end - start + 1, + found = (cache_info_t *)bsearch(cursor, &cache->lines[start], end - start + 1, sizeof(cache_info), (__compar_fn_t)find_containing_generator); if (found == NULL) @@ -1898,7 +1990,7 @@ bool g_buffer_cache_get_cursor_coordinates(GBufferCache *cache, const GLineCurso bool result; /* Bilan à retourner */ size_t index; /* Indice de correspondance */ gint lheight; /* Hauteur d'une ligne */ - const cache_info *info; /* Infos sur une ligne donnée */ + const cache_info_t *info; /* Infos sur une ligne donnée */ const generator_link *generator; /* Générateur retenu */ assert(!g_rw_lock_writer_trylock(&cache->access)); @@ -1944,3 +2036,4 @@ bool g_buffer_cache_get_cursor_coordinates(GBufferCache *cache, const GLineCurso #endif +#endif diff --git a/src/glibext/buffercache.h b/src/glibext/buffercache.h index 68941c5..87aae4e 100644 --- a/src/glibext/buffercache.h +++ b/src/glibext/buffercache.h @@ -25,6 +25,57 @@ #define _GLIBEXT_BUFFERCACHE_H +#include <gtk/gtk.h> + + +#include "helpers.h" +#include "generator.h" + + + +#define G_TYPE_BUFFER_CACHE (g_buffer_cache_get_type()) + +DECLARE_GTYPE(GBufferCache, g_buffer_cache, G, BUFFER_CACHE); + + +/* Crée un nouveau tampon pour lignes quelconques. */ +GBufferCache *g_buffer_cache_new(size_t, size_t); + +/* Fournit le nombre de colonnes supportées par un tampon. */ +void g_buffer_cache_count_columns(const GBufferCache *, size_t *, size_t *); + +/* Met à disposition un encadrement des accès aux lignes. */ +void g_buffer_cache_lock_unlock(GBufferCache *, bool, bool); + +#define g_buffer_cache_wlock(cache) g_buffer_cache_lock_unlock(cache, true, true); +#define g_buffer_cache_wunlock(cache) g_buffer_cache_lock_unlock(cache, true, false); + +#define g_buffer_cache_rlock(cache) g_buffer_cache_lock_unlock(cache, false, true); +#define g_buffer_cache_runlock(cache) g_buffer_cache_lock_unlock(cache, false, false); + +/* Compte le nombre de lignes rassemblées dans un tampon. */ +size_t g_buffer_cache_count_lines(GBufferCache *); + +/* Etend un tampon avec un générateur de lignes unique. */ +void g_buffer_cache_extend_with(GBufferCache *, size_t, GTokenGenerator *); + +/* Réduit le tampon à une quantité de lignes précise. */ +void g_buffer_cache_truncate(GBufferCache *, size_t); + + + + +/* Imprime une partie choisie du tampon contenant des lignes. */ +void g_buffer_cache_draw(GBufferCache *, cairo_t *, size_t, int, size_t, size_t, const GTokenStyle *); + + + + + + + +#if 0 + #include <glib-object.h> #include <stdbool.h> #ifdef INCLUDE_GTK_SUPPORT @@ -84,18 +135,18 @@ GWidthTracker *g_buffer_cache_get_width_tracker(const GBufferCache *); #endif /* Met à disposition un encadrement des accès aux lignes. */ -void g_buffer_cache_lock_unlock(GBufferCache *, bool, bool); +//void g_buffer_cache_lock_unlock(GBufferCache *, bool, bool); -#define g_buffer_cache_wlock(cache) g_buffer_cache_lock_unlock(cache, true, true); -#define g_buffer_cache_wunlock(cache) g_buffer_cache_lock_unlock(cache, true, false); +//#define g_buffer_cache_wlock(cache) g_buffer_cache_lock_unlock(cache, true, true); +//#define g_buffer_cache_wunlock(cache) g_buffer_cache_lock_unlock(cache, true, false); -#define g_buffer_cache_rlock(cache) g_buffer_cache_lock_unlock(cache, false, true); -#define g_buffer_cache_runlock(cache) g_buffer_cache_lock_unlock(cache, false, false); +//#define g_buffer_cache_rlock(cache) g_buffer_cache_lock_unlock(cache, false, true); +//#define g_buffer_cache_runlock(cache) g_buffer_cache_lock_unlock(cache, false, false); /* Compte le nombre de lignes rassemblées dans un tampon. */ -size_t g_buffer_cache_count_lines(GBufferCache *); +//size_t g_buffer_cache_count_lines(GBufferCache *); /* Insère un générateur dans des lignes à une position donnée. */ void g_buffer_cache_insert_at(GBufferCache *, size_t, GLineGenerator *, BufferLineFlags, bool, bool); @@ -110,10 +161,10 @@ GLineGenerator *g_buffer_cache_delete_type_at(GBufferCache *, size_t, GType, boo void g_buffer_cache_append(GBufferCache *, GLineGenerator *, BufferLineFlags); /* Etend un tampon avec un générateur de lignes unique. */ -void g_buffer_cache_extend_with(GBufferCache *, size_t, GLineGenerator *); +//void g_buffer_cache_extend_with(GBufferCache *, size_t, GLineGenerator *); /* Réduit le tampon à une quantité de lignes précise. */ -void g_buffer_cache_truncate(GBufferCache *, size_t); +//void g_buffer_cache_truncate(GBufferCache *, size_t); #ifdef INCLUDE_GTK_SUPPORT @@ -146,7 +197,7 @@ GBufferLine *g_buffer_cache_find_line_by_index(GBufferCache *, size_t); void g_buffer_cache_collect_widths(GBufferCache *, size_t, size_t, size_t, gint *, gint *); /* Imprime une partie choisie du tampon contenant des lignes. */ -void g_buffer_cache_draw(const GBufferCache *, cairo_t *, size_t, size_t, const cairo_rectangle_int_t *, const GDisplayOptions *, const gint *, const segcnt_list *); +//void g_buffer_cache_draw(const GBufferCache *, cairo_t *, size_t, size_t, const cairo_rectangle_int_t *, const GDisplayOptions *, const gint *, const segcnt_list *); #endif @@ -164,5 +215,8 @@ bool g_buffer_cache_get_cursor_coordinates(GBufferCache *, const GLineCursor *, #endif +#endif + + #endif /* _GLIBEXT_BUFFERCACHE_H */ diff --git a/src/glibext/bufferline-int.h b/src/glibext/bufferline-int.h new file mode 100644 index 0000000..8bee3c2 --- /dev/null +++ b/src/glibext/bufferline-int.h @@ -0,0 +1,94 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bufferline-int.h - prototypes pour la définition interne d'une représentation de fragments de texte en ligne + * + * Copyright (C) 2024 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GLIBEXT_BUFFERLINE_INT_H +#define _GLIBEXT_BUFFERLINE_INT_H + + +#include "bufferline.h" +#include "linecolumn.h" + + + +#if 0 +/* Mémorisation des origines de texte */ +typedef struct _content_origin +{ + col_coord_t coord; /* Localisation d'attachement */ + + GObject *creator; /* Origine de la création */ + +} content_origin; +#endif + + +/* Représentation de fragments de texte en ligne (instance) */ +struct _GBufferLine +{ + GObject parent; /* A laisser en premier */ + + line_column_t *columns; /* Répartition du texte */ + size_t col_count; /* Nombre de colonnes présentes*/ + size_t merge_start; /* Début de la zone globale */ + + BufferLineFlags flags; /* Drapeaux particuliers */ + +#if 0 + + content_origin *origins; /* Mémorisation des origines */ + size_t ocount; /* Nombre de ces mémorisations */ + +#endif + +}; + +/* Représentation de fragments de texte en ligne (classe) */ +struct _GBufferLineClass +{ + GObjectClass parent; /* A laisser en premier */ + +#if 0 + +#ifdef INCLUDE_GTK_SUPPORT + cairo_surface_t *entrypoint_img; /* Image pour les entrées */ + cairo_surface_t *bookmark_img; /* Image pour les signets */ +#endif + + /* Signaux */ + + void (* content_changed) (GBufferLine *, line_segment *); + + void (* flip_flag) (GBufferLine *, BufferLineFlags, BufferLineFlags); + +#endif + +}; + + + +/* Met en place une nouvelle représentation de bribes de texte. */ +bool g_buffer_line_create(GBufferLine *, size_t); + + + +#endif /* _GLIBEXT_BUFFERLINE_INT_H */ diff --git a/src/glibext/bufferline.c b/src/glibext/bufferline.c index 2bdfebc..4862e9f 100644 --- a/src/glibext/bufferline.c +++ b/src/glibext/bufferline.c @@ -24,63 +24,27 @@ #include "bufferline.h" +#include "bufferline-int.h" + + + +#if 0 + #include <assert.h> #include <malloc.h> #include <string.h> #include "chrysamarshal.h" -#include "linecolumn.h" +//#include "linecolumn.h" #include "../common/extstr.h" #include "../core/paths.h" - - -/* ---------------------------- GESTION DE LINE COMPLETE ---------------------------- */ - - -/* Mémorisation des origines de texte */ -typedef struct _content_origin -{ - col_coord_t coord; /* Localisation d'attachement */ - - GObject *creator; /* Origine de la création */ - -} content_origin; - -/* Représentation de fragments de texte en ligne (instance) */ -struct _GBufferLine -{ - GObject parent; /* A laisser en premier */ - - line_column *columns; /* Répartition du texte */ - size_t col_count; /* Nombre de colonnes présentes*/ - size_t merge_start; /* Début de la zone globale */ - - BufferLineFlags flags; /* Drapeaux particuliers */ - - content_origin *origins; /* Mémorisation des origines */ - size_t ocount; /* Nombre de ces mémorisations */ - -}; - -/* Représentation de fragments de texte en ligne (classe) */ -struct _GBufferLineClass -{ - GObjectClass parent; /* A laisser en premier */ - -#ifdef INCLUDE_GTK_SUPPORT - cairo_surface_t *entrypoint_img; /* Image pour les entrées */ - cairo_surface_t *bookmark_img; /* Image pour les signets */ #endif - /* Signaux */ - void (* content_changed) (GBufferLine *, line_segment *); - void (* flip_flag) (GBufferLine *, BufferLineFlags, BufferLineFlags); - -}; +/* ---------------------------- GESTION DE LINE COMPLETE ---------------------------- */ /* Procède à l'initialisation d'une classe de représentation. */ @@ -106,7 +70,6 @@ static void g_buffer_line_finalize(GBufferLine *); G_DEFINE_TYPE(GBufferLine, g_buffer_line, G_TYPE_OBJECT); - /****************************************************************************** * * * Paramètres : class = classe de composant GTK à initialiser. * @@ -131,6 +94,9 @@ static void g_buffer_line_class_init(GBufferLineClass *class) object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_line_dispose; object->finalize = (GObjectFinalizeFunc)g_buffer_line_finalize; + +#if 0 + #ifdef INCLUDE_GTK_SUPPORT filename = find_pixmap_file("entrypoint.png"); @@ -165,12 +131,14 @@ static void g_buffer_line_class_init(GBufferLineClass *class) g_cclosure_user_marshal_VOID__ENUM_ENUM, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); +#endif + } /****************************************************************************** * * -* Paramètres : line = composant GTK à initialiser. * +* Paramètres : line = composant GLib à initialiser. * * * * Description : Procède à l'initialisation d'une représentation de fragments.* * * @@ -203,10 +171,12 @@ static void g_buffer_line_init(GBufferLine *line) static void g_buffer_line_dispose(GBufferLine *line) { +#if 0 size_t i; /* Boucle de parcours */ for (i = 0; i < line->ocount; i++) g_object_unref(G_OBJECT(line->origins[i].creator)); +#endif G_OBJECT_CLASS(g_buffer_line_parent_class)->dispose(G_OBJECT(line)); @@ -235,8 +205,10 @@ static void g_buffer_line_finalize(GBufferLine *line) if (line->columns != NULL) free(line->columns); +#if 0 if (line->origins != NULL) free(line->origins); +#endif G_OBJECT_CLASS(g_buffer_line_parent_class)->finalize(G_OBJECT(line)); @@ -258,22 +230,195 @@ static void g_buffer_line_finalize(GBufferLine *line) GBufferLine *g_buffer_line_new(size_t col_count) { GBufferLine *result; /* Composant à retourner */ - size_t i; /* Boucle de parcours */ result = g_object_new(G_TYPE_BUFFER_LINE, NULL); - result->columns = malloc(col_count * sizeof(line_column)); + if (!g_buffer_line_create(result, col_count)) + g_clear_object(&result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : line = ligne de représentation à initialiser. * +* col_count = quantité de colonnes à considérer. * +* * +* Description : Met en place une nouvelle représentation de bribes de texte. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_buffer_line_create(GBufferLine *line, size_t col_count) +{ + bool result; /* Bilen à retourner */ + size_t i; /* Boucle de parcours */ + + result = true; + + line->columns = malloc(col_count * sizeof(line_column_t)); for (i = 0; i < col_count; i++) - init_line_column(&result->columns[i]); + init_line_column(&line->columns[i]); - result->col_count = col_count; + line->col_count = col_count; return result; } + + + + + + + +/****************************************************************************** +* * +* Paramètres : line = ligne à venir compléter. * +* column = colonne de la ligne visée par l'insertion. * +* tag = type de décorateur à utiliser. * +* text = texte à insérer dans l'existant. * +* length = taille du texte à traiter. * +* style = gestionnaire de paramètres de rendu à consulter. * +* creator = instance GLib quelconque à associer. * +* * +* Description : Ajoute du texte à formater dans une ligne donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_line_append_text(GBufferLine *line, size_t column, TokenRenderingTag tag, const char *text, size_t length, const GTokenStyle *style, GObject *creator) +{ + size_t index; /* Indice d'insertion */ + //content_origin *origin; /* Définition d'une origine */ + + assert(column < line->col_count); + assert(length > 0); + + index = append_text_to_line_column(&line->columns[column], tag, text, length, style); + + /* + if (creator != NULL) + { + line->origins = realloc(line->origins, ++line->ocount * sizeof(content_origin)); + + origin = &line->origins[line->ocount - 1]; + + origin->coord.column = column; + origin->coord.index = index; + + origin->creator = creator; + g_object_ref(G_OBJECT(creator)); + + } + */ + +} + + + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : line = ligne de texte à manipuler. * +* cr = contexte graphique dédié à la procédure. * +* column = (première) colonne à traiter. * +* y = ordonnée du point d'impression. * +* style = style de rendu pour les bribes de texte. * +* * +* Description : Imprime la ligne de texte représentée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_line_draw(const GBufferLine *line, cairo_t *cr, size_t column, int y, const GTokenStyle *style) +{ +#if 0 + GBufferLineClass *class; /* Stockage de briques de base */ + bool has_src_surface; /* Note une présence définie */ +#endif + size_t max_column; /* Borne de fin des colonnes */ + int x; /* Point de départ d'impression*/ + size_t i; /* Boucle de parcours */ + + /* + if (line->flags != BLF_NONE) + { + class = G_BUFFER_LINE_GET_CLASS(line); + + if (line->flags & BLF_ENTRYPOINT) + { + cairo_set_source_surface(cairo, class->entrypoint_img, 5, y); + has_src_surface = true; + } + else if (line->flags & BLF_BOOKMARK) + { + cairo_set_source_surface(cairo, class->bookmark_img, 5, y); + has_src_surface = true; + } + else + has_src_surface = false; + + if (has_src_surface) + cairo_paint(cairo); + + } + */ + + + /* Détermination de l'éventail des colonnes à traiter */ + + if (column == line->merge_start) + max_column = line->col_count; + + else if (column > line->merge_start) + max_column = 0; + + else + max_column = column + 1; + + /* Dessin du contenu de ces colonnes */ + + x = 0; + + for (i = column; i < max_column; i++) + draw_line_column(&line->columns[i], cr, &x, y, style); + +} + + + + + + + + + + +#if 0 + + /****************************************************************************** * * * Paramètres : line = ligne à venir compléter. * @@ -1492,3 +1637,6 @@ void g_buffer_line_draw(GBufferLine *line, size_t index, cairo_t *cairo, gint x_ #endif + + +#endif diff --git a/src/glibext/bufferline.h b/src/glibext/bufferline.h index f5f25d0..d6a2e2d 100644 --- a/src/glibext/bufferline.h +++ b/src/glibext/bufferline.h @@ -25,10 +25,21 @@ #define _GLIBEXT_BUFFERLINE_H -#include <glib-object.h> #include <stdbool.h> +#include "helpers.h" +#include "tokenstyle.h" + + + + + +#if 0 + +#include <glib-object.h> + + #include "gdisplayoptions.h" #include "linesegment.h" #ifdef INCLUDE_GTK_SUPPORT @@ -60,6 +71,14 @@ typedef struct _GBufferLineClass GBufferLineClass; /* Espace entre les colonnes */ #define COL_MARGIN 23 +#endif + + + +#define G_TYPE_BUFFER_LINE (g_buffer_line_get_type()) + +DECLARE_GTYPE(GBufferLine, g_buffer_line, G, BUFFER_LINE); + /* Propriétés particulières supplémentaires */ typedef enum _BufferLineFlags @@ -76,12 +95,28 @@ typedef enum _BufferLineFlags } BufferLineFlags; -/* Détermine le type de la représentation de fragments de texte en ligne. */ -GType g_buffer_line_get_type(void); - /* Crée une nouvelle représentation de fragments de texte. */ GBufferLine *g_buffer_line_new(size_t); + + +/* Ajoute du texte à formater dans une ligne donnée. */ +void g_buffer_line_append_text(GBufferLine *, size_t, TokenRenderingTag, const char *, size_t, const GTokenStyle *, GObject *); + + + +/* Imprime la ligne de texte représentée. */ +void g_buffer_line_draw(const GBufferLine *, cairo_t *, size_t, int, const GTokenStyle *); + + + + + +#if 0 + +/* Détermine le type de la représentation de fragments de texte en ligne. */ +GType g_buffer_line_get_type(void); + /* Construit le tronc commun d'une ligne autour de sa position. */ void g_buffer_line_fill_phys(GBufferLine *, size_t, MemoryDataSize, const vmpa2t *); @@ -95,7 +130,7 @@ void g_buffer_line_fill_content(GBufferLine *, size_t, const GBinContent *, cons GObject *g_buffer_line_find_first_segment_creator(const GBufferLine *, size_t); /* Ajoute du texte à formater dans une ligne donnée. */ -void g_buffer_line_append_text(GBufferLine *, size_t, const char *, size_t, RenderingTagType, GObject *); +//void g_buffer_line_append_text(GBufferLine *, size_t, const char *, size_t, RenderingTagType, GObject *); /* Remplace du texte dans une ligne donnée. */ bool g_buffer_line_replace_text(GBufferLine *, const GObject *, const char *, size_t); @@ -162,7 +197,10 @@ GObject *g_buffer_line_get_creator_at(const GBufferLine *, size_t, GWidthTracker bool g_buffer_line_find_near_coord(const GBufferLine *, size_t, col_coord_t *, GWidthTracker *, const GDisplayOptions *, GdkScrollDirection, gint *); /* Imprime la ligne de texte représentée. */ -void g_buffer_line_draw(GBufferLine *, size_t, cairo_t *, gint, gint, GWidthTracker *, const GDisplayOptions *, const segcnt_list *); +//void g_buffer_line_draw(GBufferLine *, size_t, cairo_t *, gint, gint, GWidthTracker *, const GDisplayOptions *, const segcnt_list *); + +#endif + #endif diff --git a/src/glibext/bufferview-int.h b/src/glibext/bufferview-int.h new file mode 100644 index 0000000..7751c1e --- /dev/null +++ b/src/glibext/bufferview-int.h @@ -0,0 +1,83 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * bufferview.h - prototypes pour l'affichage d'une vue particulière d'un tampon de lignes + * + * Copyright (C) 2016-2024 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GLIBEXT_BUFFERVIEW_INT_H +#define _GLIBEXT_BUFFERVIEW_INT_H + + +#include "bufferview.h" + + +/* Vue d'un tampon pour code désassemblé (instance) */ +struct _GBufferView +{ + GObject parent; /* A laisser en premier */ + + GBufferCache *cache; /* Tampon du contenu visualisé */ + GWidthTracker *tracker; /* Collecteur de largeurs */ + GTokenStyle *style; /* Style dédié aux rendus */ + + + + bool unrestricted; /* Validité des informations */ + + + size_t first; /* Indice de la première ligne */ + size_t last; /* Indice de la dernière ligne */ + + +#if 0 + + segcnt_list *highlighted; /* Segments mis en évidence */ + + //bool unrestricted; /* Validité des informations */ + GLineCursor *start; /* Première ligne intégrée */ + GLineCursor *end; /* Dernière ligne intégrée */ + + //size_t first; /* Indice de la première ligne */ + //size_t last; /* Indice de la dernière ligne */ + + GWidthTracker *tracker; /* Suivi des largeurs */ + +#endif + +}; + +/* Vue d'un tampon pour code désassemblé (classe) */ +struct _GBufferViewClass +{ + GObjectClass parent; /* A laisser en premier */ + + /* Signaux */ + + void (* need_redraw) (GBufferView *); + +}; + + +/* Met en place une nouvelle vue pour un tampon de texte. */ +bool g_buffer_view_create(GBufferView *, GBufferCache *, GTokenStyle *); + + + +#endif /* _GLIBEXT_BUFFERVIEW_INT_H */ diff --git a/src/glibext/bufferview.c b/src/glibext/bufferview.c index 72740b1..3747e2c 100644 --- a/src/glibext/bufferview.c +++ b/src/glibext/bufferview.c @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * bufferview.c - affichage d'une vue particulière d'un tampon de lignes * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -24,46 +24,17 @@ #include "bufferview.h" -#include <assert.h> - +#include "bufferview-int.h" -/* Vue d'un tampon pour code désassemblé (instance) */ -struct _GBufferView -{ - GObject parent; /* A laisser en premier */ - GBufferCache *cache; /* Tampon du contenu visualisé */ - - segcnt_list *highlighted; /* Segments mis en évidence */ - - bool unrestricted; /* Validité des informations */ - GLineCursor *start; /* Première ligne intégrée */ - GLineCursor *end; /* Dernière ligne intégrée */ - - size_t first; /* Indice de la première ligne */ - size_t last; /* Indice de la dernière ligne */ - - GWidthTracker *tracker; /* Suivi des largeurs */ - -}; - -/* Vue d'un tampon pour code désassemblé (classe) */ -struct _GBufferViewClass -{ - GObjectClass parent; /* A laisser en premier */ - - /* Signaux */ - - void (* need_redraw) (GBufferView *); - -}; +/* -------------------------- DEFINITION D'UN NOUVEL OBJET -------------------------- */ /* Procède à l'initialisation d'une classe de vue de tampon. */ static void g_buffer_view_class_init(GBufferViewClass *); -/* Procède à l'initialisation d'une vue d'un tampon pour code. */ +/* Procède à l'initialisation d'une vue d'un tampon. */ static void g_buffer_view_init(GBufferView *); /* Supprime toutes les références externes. */ @@ -75,23 +46,15 @@ static void g_buffer_view_finalize(GBufferView *); /* Accompagne une variation de la quantité de lignes du tampon. */ static void on_buffer_cache_size_changed(const GBufferCache *, bool, size_t, size_t, GBufferView *); -/* Réagit à la modification d'une ligne du tampon. */ -static void on_buffer_cache_line_updated(const GBufferCache *, size_t, GBufferView *); - -/* Calcule la position idéale de curseur pour un point donné. */ -static bool _g_buffer_view_compute_caret_full(GBufferView *, gint, GBufferLine *, size_t, const GDisplayOptions *, cairo_rectangle_int_t *, GLineCursor **); - -/* Fournit la ligne présente à une ordonnée donnée. */ -static GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *); - -/* Déplace le curseur au sein d'une vue de tampon. */ -static bool _g_buffer_view_move_caret(GBufferView *, const GBufferLine *, size_t, cairo_rectangle_int_t *, bool, GdkScrollDirection, const GDisplayOptions *); +/* ---------------------------------------------------------------------------------- */ +/* DEFINITION D'UN NOUVEL OBJET */ +/* ---------------------------------------------------------------------------------- */ /* Détermine le type de la vue d'un tampon pour code désassemblé. */ @@ -100,7 +63,7 @@ G_DEFINE_TYPE(GBufferView, g_buffer_view, G_TYPE_OBJECT); /****************************************************************************** * * -* Paramètres : class = classe de composant GTK à initialiser. * +* Paramètres : class = classe de composant GLib à initialiser. * * * * Description : Procède à l'initialisation d'une classe de vue de tampon. * * * @@ -136,7 +99,7 @@ static void g_buffer_view_class_init(GBufferViewClass *class) * * * Paramètres : view = composant GLib à initialiser. * * * -* Description : Procède à l'initialisation d'une vue d'un tampon pour code. * +* Description : Procède à l'initialisation d'une vue d'un tampon. * * * * Retour : - * * * @@ -147,22 +110,26 @@ static void g_buffer_view_class_init(GBufferViewClass *class) static void g_buffer_view_init(GBufferView *view) { view->cache = NULL; - - view->highlighted = NULL; + view->tracker = NULL; + view->style = NULL; /** * Inversion du statut pour forcer l'actualisation lors de la création. */ view->unrestricted = false; +#if 0 + view->start = NULL; view->end = NULL; +#endif + + + view->first = 0; view->last = 0; - view->tracker = NULL; - } @@ -181,11 +148,13 @@ static void g_buffer_view_init(GBufferView *view) static void g_buffer_view_dispose(GBufferView *view) { g_clear_object(&view->cache); + g_clear_object(&view->tracker); + g_clear_object(&view->style); +#if 0 g_clear_object(&view->start); g_clear_object(&view->end); - - g_clear_object(&view->tracker); +#endif G_OBJECT_CLASS(g_buffer_view_parent_class)->dispose(G_OBJECT(view)); @@ -206,9 +175,6 @@ static void g_buffer_view_dispose(GBufferView *view) static void g_buffer_view_finalize(GBufferView *view) { - if (view->highlighted != NULL) - unref_segment_content_list(view->highlighted); - G_OBJECT_CLASS(g_buffer_view_parent_class)->finalize(G_OBJECT(view)); } @@ -216,38 +182,25 @@ static void g_buffer_view_finalize(GBufferView *view) /****************************************************************************** * * -* Paramètres : buffer = tampon à représenter à l'écran. * -* highlighted = gestionnaire de surbrillance pour segments. * +* Paramètres : cache = cache de lignes à présenter à la vue. * +* style = modèles de rendus pour tous les types de bribes. * * * -* Description : Crée une nouvelle vue d'un tampon pour code désassemblé. * +* Description : Crée une nouvelle vue d'un tampon de texte. * * * -* Retour : Composant GTK créé. * +* Retour : Vue de tampon mise en place ou NULL en cas d'erreur. * * * * Remarques : - * * * ******************************************************************************/ -GBufferView *g_buffer_view_new(GBufferCache *cache, segcnt_list *highlighted) +GBufferView *g_buffer_view_new(GBufferCache *cache, GTokenStyle *style) { GBufferView *result; /* Composant à retourner */ result = g_object_new(G_TYPE_BUFFER_VIEW, NULL); - result->cache = cache; - g_object_ref_sink(G_OBJECT(cache)); - - g_buffer_view_restrict(result, NULL, NULL); - - g_signal_connect(cache, "size-changed", G_CALLBACK(on_buffer_cache_size_changed), result); - g_signal_connect(cache, "line-updated", G_CALLBACK(on_buffer_cache_line_updated), result); - - if (highlighted != NULL) - { - ref_segment_content_list(highlighted); - result->highlighted = highlighted; - } - else - result->highlighted = init_segment_content_list(); + if (!g_buffer_view_create(result, cache, style)) + g_clear_object(&result); return result; @@ -256,21 +209,50 @@ GBufferView *g_buffer_view_new(GBufferCache *cache, segcnt_list *highlighted) /****************************************************************************** * * -* Paramètres : cache = tampon de lignes cohérentes à manipuler. * -* index = indice de la première ligne actualisée. * +* Paramètres : view = vue de tampon à initialiser. * +* cache = cache de lignes à présenter à la vue. * +* style = modèles de rendus pour tous les types de bribes. * * * -* Description : Réagit à la modification d'une ligne du tampon. * +* Description : Met en place une nouvelle vue pour un tampon de texte. * * * -* Retour : - * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static void on_buffer_cache_line_updated(const GBufferCache *cache, size_t index, GBufferView *view) +bool g_buffer_view_create(GBufferView *view, GBufferCache *cache, GTokenStyle *style) { - if (view->first <= index && index <= view->last) - g_signal_emit_by_name(view, "need-redraw"); + bool result; /* Bilan à retourner */ + + result = true; + + view->cache = cache; + ref_object(cache); + + view->tracker = g_width_tracker_new(cache); + + view->style = style; + ref_object(style); + + g_buffer_view_restrict(view, NULL, NULL); + + g_signal_connect(cache, "size-changed", G_CALLBACK(on_buffer_cache_size_changed), view); + + +#if 0 + g_signal_connect(cache, "line-updated", G_CALLBACK(on_buffer_cache_line_updated), result); + + if (highlighted != NULL) + { + ref_segment_content_list(highlighted); + result->highlighted = highlighted; + } + else + result->highlighted = init_segment_content_list(); +#endif + + return result; } @@ -411,7 +393,32 @@ GBufferCache *g_buffer_view_get_cache(const GBufferView *view) result = view->cache; - g_object_ref(G_OBJECT(result)); + ref_object(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : view = visualisateur à consulter. * +* * +* Description : Fournit le collecteur de largeurs associé au tampon lié. * +* * +* Retour : Collecteur de largeurs des lignes du tampon représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GWidthTracker *g_buffer_view_get_tracker(const GBufferView *view) +{ + GWidthTracker *result; /* Instance à retourner */ + + result = view->tracker; + + ref_object(result); return result; @@ -432,10 +439,10 @@ GBufferCache *g_buffer_view_get_cache(const GBufferView *view) * * ******************************************************************************/ -void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor *end) +void g_buffer_view_restrict(GBufferView *view, /*GLineCursor*/void *start, /*GLineCursor*/void *end) { bool state; /* Nouvel état à proclamer */ - GWidthTracker *template; /* Suivi déjà en place */ + //GWidthTracker *template; /* Suivi déjà en place */ state = (start == NULL || end == NULL); @@ -443,11 +450,11 @@ void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor * { view->unrestricted = state; - template = g_buffer_cache_get_width_tracker(view->cache); + //template = g_buffer_cache_get_width_tracker(view->cache); /* Vérification pour le cas particulier du démarrage */ - if (view->tracker != NULL) - g_object_unref(G_OBJECT(view->tracker)); + //if (view->tracker != NULL) + // g_object_unref(G_OBJECT(view->tracker)); g_buffer_cache_rlock(view->cache); @@ -456,12 +463,14 @@ void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor * view->first = 0; view->last = g_buffer_cache_count_lines(view->cache) - 1; - view->tracker = template; + //view->tracker = template; } else { + /* + g_object_ref_sink(G_OBJECT(start)); g_object_ref_sink(G_OBJECT(end)); @@ -475,6 +484,8 @@ void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor * g_object_unref(G_OBJECT(template)); + */ + } g_buffer_cache_runlock(view->cache); @@ -484,6 +495,156 @@ void g_buffer_view_restrict(GBufferView *view, GLineCursor *start, GLineCursor * } + + + + + + +/****************************************************************************** +* * +* Paramètres : view = visualisation à consulter. * +* style = style de rendu pour les bribes de texte. * +* width = largeur requise pour un affichage complet. [OUT] * +* height = hauteur requise pour un affichage complet. [OUT] * +* * +* Description : Détermine la taille nécessaire à une représentation complète.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_view_compute_size(const GBufferView *view, int *width, int *height) +{ + size_t last; /* Dernière ligne à dessiner */ + + /* Largeur de l'ensemble des colonnes */ + + g_width_tracker_compute_width(view->tracker, width); + + /* Hauteur de l'ensemble des lignes */ + + *height = g_token_style_get_line_height(view->style) * (view->last + 1); + +} + + + + + +/****************************************************************************** +* * +* Paramètres : view = visualisation à représenter. * +* cr = contexte graphique dédié à la procédure. * +* column = (première) colonne à traiter. * +* virt_top = ordonnée présentée au point 0 à l'écran. * +* height = hauteur disponible pour les représentations. * +* * +* Description : Imprime la visualisation du tampon de lignes quelconques. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_buffer_view_draw(const GBufferView *view, cairo_t *cr, size_t column, int virt_top, int height) +{ + int line_height; /* Hauteur d'une ligne */ + gint cr_y; /* Ordonnée pour le dessin */ + size_t first; /* Première ligne visée */ + size_t last; /* Dernière ligne visée */ + + line_height = g_token_style_get_line_height(view->style); + + /* Indice et point de départ */ + + first = view->first; + first += (virt_top / line_height); + + cr_y = -(virt_top % line_height); + + /* Indice de d'arrivée */ + + last = first + (height / line_height); + if (height % line_height > 0) last++; + + last = MIN(last, view->last); + + /* Phase de dessin ! */ + + g_buffer_cache_draw(view->cache, cr, column, cr_y, first, last, view->style); + +} + + + + + + + + + + + + + +#if 0 + +#include <assert.h> + + + + +/* Accompagne une variation de la quantité de lignes du tampon. */ +//static void on_buffer_cache_size_changed(const GBufferCache *, bool, size_t, size_t, GBufferView *); + +/* Réagit à la modification d'une ligne du tampon. */ +static void on_buffer_cache_line_updated(const GBufferCache *, size_t, GBufferView *); + +/* Calcule la position idéale de curseur pour un point donné. */ +static bool _g_buffer_view_compute_caret_full(GBufferView *, gint, GBufferLine *, size_t, const GDisplayOptions *, cairo_rectangle_int_t *, GLineCursor **); + +/* Fournit la ligne présente à une ordonnée donnée. */ +static GBufferLine *g_buffer_view_find_line_at(GBufferView *, gint, size_t *); + +/* Déplace le curseur au sein d'une vue de tampon. */ +static bool _g_buffer_view_move_caret(GBufferView *, const GBufferLine *, size_t, cairo_rectangle_int_t *, bool, GdkScrollDirection, const GDisplayOptions *); + + + + + + + + + +/****************************************************************************** +* * +* Paramètres : cache = tampon de lignes cohérentes à manipuler. * +* index = indice de la première ligne actualisée. * +* * +* Description : Réagit à la modification d'une ligne du tampon. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void on_buffer_cache_line_updated(const GBufferCache *cache, size_t index, GBufferView *view) +{ + if (view->first <= index && index <= view->last) + g_signal_emit_by_name(view, "need-redraw"); + +} + + + + + /****************************************************************************** * * * Paramètres : view = visualisateur à consulter. * @@ -1313,3 +1474,44 @@ bool g_buffer_view_get_cursor_coordinates(GBufferView *view, const GLineCursor * return result; } + + + +#endif + + + + + +#if 0 + + +/****************************************************************************** +* * +* Paramètres : view = visualisation à consulter. * +* cursor = emplacement à présenter à l'écran. * +* code = s'arrête si possible à une ligne avec code. * +* x = position horizontale au sein du composant. [OUT] * +* y = position verticale au sein du composant. [OUT] * +* * +* Description : Indique la position d'affichage d'une adresse donnée. * +* * +* Retour : true si l'adresse fait partie du composant, false sinon. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_buffer_view_allocate_widths(GBufferView *view, int width, int height, int fill, int *out) +{ + + + + + + +} + + + +#endif diff --git a/src/glibext/bufferview.h b/src/glibext/bufferview.h index 43e6293..d5af6d1 100644 --- a/src/glibext/bufferview.h +++ b/src/glibext/bufferview.h @@ -2,7 +2,7 @@ /* Chrysalide - Outil d'analyse de fichiers binaires * bufferview.h - prototypes pour l'affichage d'une vue particulière d'un tampon de lignes * - * Copyright (C) 2016-2019 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -25,6 +25,48 @@ #define _GLIBEXT_BUFFERVIEW_H +#include "buffercache.h" +#include "helpers.h" +#include "tokenstyle.h" +#include "widthtracker.h" + + + +#define G_TYPE_BUFFER_VIEW (g_buffer_view_get_type()) + +DECLARE_GTYPE(GBufferView, g_buffer_view, G, BUFFER_VIEW); + + +/* Crée une nouvelle vue d'un tampon de texte. */ +GBufferView *g_buffer_view_new(GBufferCache *, GTokenStyle *); + +/* Fournit le tampon de code lié à un visualisateur donné. */ +GBufferCache *g_buffer_view_get_cache(const GBufferView *); + +/* Fournit le collecteur de largeurs associé au tampon lié. */ +GWidthTracker *g_buffer_view_get_tracker(const GBufferView *); + +/* Restreint le champ d'application de l'affichage. */ +void g_buffer_view_restrict(GBufferView *, /*GLineCursor*/void *, /*GLineCursor*/void *); + + + +/* Détermine la taille nécessaire à une représentation complète. */ +void g_buffer_view_compute_size(const GBufferView *, int *, int *); + + + +/* Imprime la visualisation du tampon de lignes quelconques. */ +void g_buffer_view_draw(const GBufferView *, cairo_t *, size_t, int, int); + + + + + + + +#if 0 + #include <glib-object.h> @@ -52,13 +94,13 @@ typedef struct _GBufferViewClass GBufferViewClass; GType g_buffer_view_get_type(void); /* Crée une nouvelle vue d'un tampon pour lignes générées. */ -GBufferView *g_buffer_view_new(GBufferCache *, segcnt_list *); +//GBufferView *g_buffer_view_new(GBufferCache *, segcnt_list *); /* Fournit le tampon de code lié à un visualisateur donné. */ -GBufferCache *g_buffer_view_get_cache(const GBufferView *); +//GBufferCache *g_buffer_view_get_cache(const GBufferView *); /* Restreint le champ d'application de l'affichage. */ -void g_buffer_view_restrict(GBufferView *, GLineCursor *, GLineCursor *); +//void g_buffer_view_restrict(GBufferView *, GLineCursor *, GLineCursor *); /* Indique le champ d'application de l'affichage. */ bool g_buffer_view_get_restrictions(const GBufferView *, GLineCursor **, GLineCursor **); @@ -110,6 +152,9 @@ bool g_buffer_view_get_cursor_coordinates(GBufferView *, const GLineCursor *, bo +#endif + + #endif /* _GLIBEXT_BUFFERVIEW_H */ diff --git a/src/glibext/generator-int.h b/src/glibext/generator-int.h index 6952f69..8b7e28d 100644 --- a/src/glibext/generator-int.h +++ b/src/glibext/generator-int.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * linegen-int.h - définitions internes propres aux intermédiaires de génération de lignes + * generator-int.h - définitions internes propres aux intermédiaires de génération de lignes à partir de bribres de texte * - * Copyright (C) 2016-2018 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,47 +21,52 @@ */ -#ifndef _GLIBEXT_LINEGEN_INT_H -#define _GLIBEXT_LINEGEN_INT_H +#ifndef _GLIBEXT_GENERATOR_INT_H +#define _GLIBEXT_GENERATOR_INT_H -#include "linegen.h" +#include "generator.h" /* Indique le nombre de ligne prêtes à être générées. */ -typedef size_t (* linegen_count_lines_fc) (const GLineGenerator *); +typedef size_t (* count_tokgen_lines_fc) (const GTokenGenerator *); + +/* Renseigne sur les propriétés liées à un générateur. */ +typedef BufferLineFlags (* get_tokgen_flags_fc) (const GTokenGenerator *, size_t, size_t); + +/* Imprime dans une ligne de rendu le contenu représenté. */ +typedef void (* populate_tokgen_line_fc) (const GTokenGenerator *, size_t, size_t, GBufferLine *, void *); + +#if 0 /* Retrouve l'emplacement correspondant à une position donnée. */ -typedef void (* linegen_compute_fc) (const GLineGenerator *, gint, size_t, size_t, GLineCursor **); +typedef void (* compute_tokgen_fc) (const GTokenGenerator *, gint, size_t, size_t, GLineCursor **); /* Détermine si le conteneur s'inscrit dans une plage donnée. */ -typedef int (* linegen_contain_fc) (const GLineGenerator *, size_t, size_t, const GLineCursor *); +typedef int (* contain_tokgen_fc) (const GTokenGenerator *, size_t, size_t, const GLineCursor *); -/* Renseigne sur les propriétés liées à un générateur. */ -typedef BufferLineFlags (* linegen_get_flags_fc) (const GLineGenerator *, size_t, size_t); - -/* Imprime dans une ligne de rendu le contenu représenté. */ -typedef void (* linegen_print_fc) (GLineGenerator *, GBufferLine *, size_t, size_t, const GBinContent *); +#endif /* Intermédiaire pour la génération de lignes (interface) */ -struct _GLineGeneratorIface +struct _GTokenGeneratorInterface { GTypeInterface base_iface; /* A laisser en premier */ - linegen_count_lines_fc count; /* Décompte des lignes */ - linegen_compute_fc compute; /* Calcul d'emplacement */ - linegen_contain_fc contain; /* Inclusion de positions */ - linegen_get_flags_fc get_flags; /* Récupération des drapeaux */ - linegen_print_fc print; /* Impression d'une ligne */ + count_tokgen_lines_fc count; /* Décompte des lignes */ + get_tokgen_flags_fc get_flags; /* Récupération des drapeaux */ + populate_tokgen_line_fc populate; /* Impression d'une ligne */ -}; +#if 0 + compute_tokgen_fc compute; /* Calcul d'emplacement */ + contain_tokgen_fc contain; /* Inclusion de positions */ -/* Redéfinition */ -typedef GLineGeneratorIface GLineGeneratorInterface; +#endif + +}; -#endif /* _GLIBEXT_LINEGEN_INT_H */ +#endif /* _GLIBEXT_GENERATOR_INT_H */ diff --git a/src/glibext/generator.c b/src/glibext/generator.c index c5291ab..2d3d349 100644 --- a/src/glibext/generator.c +++ b/src/glibext/generator.c @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * linegen.c - intermédiaires de génération de lignes + * generator.c - intermédiaires de génération de lignes à partir de bribres de texte * - * Copyright (C) 2016-2018 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,23 +21,26 @@ */ -#include "linegen.h" +#include "generator.h" #include <assert.h> -#include "linegen-int.h" +#include "generator-int.h" /* Procède à l'initialisation de l'interface de génération. */ -static void g_line_generator_default_init(GLineGeneratorInterface *); +static void g_token_generator_default_init(GTokenGeneratorInterface *); + +/* Indique le nombre de ligne prêtes à être générées. */ +static size_t _g_token_generator_count_one_line(const GTokenGenerator *); /* Détermine le type d'une interface pour la mise en place de lignes. */ -G_DEFINE_INTERFACE(GLineGenerator, g_line_generator, G_TYPE_OBJECT) +G_DEFINE_INTERFACE(GTokenGenerator, g_token_generator, G_TYPE_OBJECT) /****************************************************************************** @@ -52,8 +55,32 @@ G_DEFINE_INTERFACE(GLineGenerator, g_line_generator, G_TYPE_OBJECT) * * ******************************************************************************/ -static void g_line_generator_default_init(GLineGeneratorInterface *iface) +static void g_token_generator_default_init(GTokenGeneratorInterface *iface) +{ + iface->count = _g_token_generator_count_one_line; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * +* * +* Description : Indique le nombre de ligne prêtes à être générées. * +* * +* Retour : Nombre de lignes devant apparaître au final. * +* * +* Remarques : - * +* * +******************************************************************************/ + +static size_t _g_token_generator_count_one_line(const GTokenGenerator *generator) { + size_t result; /* Décompte à retourner */ + + result = 1; + + return result; } @@ -70,12 +97,12 @@ static void g_line_generator_default_init(GLineGeneratorInterface *iface) * * ******************************************************************************/ -size_t g_line_generator_count_lines(const GLineGenerator *generator) +size_t g_token_generator_count_lines(const GTokenGenerator *generator) { size_t result; /* Décompte à retourner */ - GLineGeneratorIface *iface; /* Interface utilisée */ + GTokenGeneratorInterface *iface; /* Interface utilisée */ - iface = G_LINE_GENERATOR_GET_IFACE(generator); + iface = G_TOKEN_GENERATOR_GET_IFACE(generator); result = iface->count(generator); @@ -87,31 +114,29 @@ size_t g_line_generator_count_lines(const GLineGenerator *generator) /****************************************************************************** * * * Paramètres : generator = générateur à consulter. * -* x = position géographique sur la ligne concernée. * * index = indice de cette même ligne dans le tampon global.* * repeat = indice d'utilisations successives du générateur. * * * -* Description : Retrouve l'emplacement correspondant à une position donnée. * +* Description : Renseigne sur les propriétés liées à un générateur. * * * -* Retour : Emplacement constitué. * +* Retour : Propriétés particulières associées. * * * * Remarques : - * * * ******************************************************************************/ -GLineCursor *g_line_generator_compute_cursor(const GLineGenerator *generator, gint x, size_t index, size_t repeat) +BufferLineFlags g_token_generator_get_flags(const GTokenGenerator *generator, size_t index, size_t repeat) { - GLineCursor *result; /* Emplacement à renvoyer */ - GLineGeneratorIface *iface; /* Interface utilisée */ + BufferLineFlags result; /* Fanions à retourner */ + GTokenGeneratorInterface *iface; /* Interface utilisée */ - iface = G_LINE_GENERATOR_GET_IFACE(generator); + iface = G_TOKEN_GENERATOR_GET_IFACE(generator); #ifndef NDEBUG - if (iface->count != NULL) - assert(repeat < g_line_generator_count_lines(generator)); + assert(repeat < g_token_generator_count_lines(generator)); #endif - iface->compute(generator, x, index, repeat, &result); + result = iface->get_flags(generator, index, repeat); return result; @@ -120,65 +145,65 @@ GLineCursor *g_line_generator_compute_cursor(const GLineGenerator *generator, gi /****************************************************************************** * * -* Paramètres : generator = générateur à consulter. * +* Paramètres : generator = générateur à utiliser pour l'impression. * * index = indice de cette même ligne dans le tampon global.* * repeat = indice d'utilisations successives du générateur. * -* cursor = emplacement à analyser. * +* line = ligne de rendu à compléter. * +* data = éventuelle donnée complémentaire fournie. * * * -* Description : Détermine si le conteneur s'inscrit dans une plage donnée. * +* Description : Etablit dans une ligne de rendu le contenu représenté. * * * -* Retour : Bilan de la détermination, utilisable en comparaisons. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -int g_line_generator_contain_cursor(const GLineGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor) +void g_token_generator_populate_line(const GTokenGenerator *generator, size_t index, size_t repeat, GBufferLine *line, void *data) { - int result; /* Bilan d'analyse à retourner */ - GLineGeneratorIface *iface; /* Interface utilisée */ + GTokenGeneratorInterface *iface; /* Interface utilisée */ - iface = G_LINE_GENERATOR_GET_IFACE(generator); + iface = G_TOKEN_GENERATOR_GET_IFACE(generator); #ifndef NDEBUG - if (iface->count != NULL) - assert(repeat < g_line_generator_count_lines(generator)); + assert(repeat < g_token_generator_count_lines(generator)); #endif - result = iface->contain(generator, index, repeat, cursor); - - return result; + iface->populate(generator, index, repeat, line, data); } +#if 0 + + /****************************************************************************** * * * Paramètres : generator = générateur à consulter. * +* x = position géographique sur la ligne concernée. * * index = indice de cette même ligne dans le tampon global.* * repeat = indice d'utilisations successives du générateur. * * * -* Description : Renseigne sur les propriétés liées à un générateur. * +* Description : Retrouve l'emplacement correspondant à une position donnée. * * * -* Retour : Propriétés particulières associées. * +* Retour : Emplacement constitué. * * * * Remarques : - * * * ******************************************************************************/ -BufferLineFlags g_line_generator_get_flags(const GLineGenerator *generator, size_t index, size_t repeat) +GLineCursor *g_token_generator_compute_cursor(const GTokenGenerator *generator, gint x, size_t index, size_t repeat) { - BufferLineFlags result; /* Fanions à retourner */ - GLineGeneratorIface *iface; /* Interface utilisée */ + GLineCursor *result; /* Emplacement à renvoyer */ + GTokenGeneratorInterface *iface; /* Interface utilisée */ - iface = G_LINE_GENERATOR_GET_IFACE(generator); + iface = G_TOKEN_GENERATOR_GET_IFACE(generator); #ifndef NDEBUG - if (iface->count != NULL) - assert(repeat < g_line_generator_count_lines(generator)); + assert(repeat < g_token_generator_count_lines(generator)); #endif - result = iface->get_flags(generator, index, repeat); + iface->compute(generator, x, index, repeat, &result); return result; @@ -187,31 +212,35 @@ BufferLineFlags g_line_generator_get_flags(const GLineGenerator *generator, size /****************************************************************************** * * -* Paramètres : generator = générateur à utiliser pour l'impression. * -* line = ligne de rendu à compléter. * +* Paramètres : generator = générateur à consulter. * * index = indice de cette même ligne dans le tampon global.* * repeat = indice d'utilisations successives du générateur. * -* content = éventuel contenu binaire brut à imprimer. * +* cursor = emplacement à analyser. * * * -* Description : Imprime dans une ligne de rendu le contenu représenté. * +* Description : Détermine si le conteneur s'inscrit dans une plage donnée. * * * -* Retour : - * +* Retour : Bilan de la détermination, utilisable en comparaisons. * * * * Remarques : - * * * ******************************************************************************/ -void g_line_generator_print(GLineGenerator *generator, GBufferLine *line, size_t index, size_t repeat, const GBinContent *content) +int g_token_generator_contain_cursor(const GTokenGenerator *generator, size_t index, size_t repeat, const GLineCursor *cursor) { - GLineGeneratorIface *iface; /* Interface utilisée */ + int result; /* Bilan d'analyse à retourner */ + GTokenGeneratorInterface *iface; /* Interface utilisée */ - iface = G_LINE_GENERATOR_GET_IFACE(generator); + iface = G_TOKEN_GENERATOR_GET_IFACE(generator); #ifndef NDEBUG - if (iface->count != NULL) - assert(repeat < g_line_generator_count_lines(generator)); + assert(repeat < g_token_generator_count_lines(generator)); #endif - iface->print(generator, line, index, repeat, content); + result = iface->contain(generator, index, repeat, cursor); + + return result; } + + +#endif diff --git a/src/glibext/generator.h b/src/glibext/generator.h index d40a598..c93e0a0 100644 --- a/src/glibext/generator.h +++ b/src/glibext/generator.h @@ -1,8 +1,8 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * linegen.h - prototypes pour les intermédiaires de génération de lignes + * generator.h - prototypes pour les intermédiaires de génération de lignes à partir de bribres de texte * - * Copyright (C) 2016-2018 Cyrille Bagard + * Copyright (C) 2016-2024 Cyrille Bagard * * This file is part of Chrysalide. * @@ -21,52 +21,43 @@ */ -#ifndef _GLIBEXT_LINEGEN_H -#define _GLIBEXT_LINEGEN_H - - -#include <glib-object.h> +#ifndef _GLIBEXT_GENERATOR_H +#define _GLIBEXT_GENERATOR_H #include "bufferline.h" +#include "helpers.h" +/* #include "glinecursor.h" -#include "../analysis/content.h" +*/ -#define G_TYPE_LINE_GENERATOR g_line_generator_get_type() -#define G_LINE_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_LINE_GENERATOR, GLineGenerator)) -#define G_LINE_GENERATOR_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST((vtable), G_TYPE_LINE_GENERATOR, GLineGeneratorIface)) -#define GTK_IS_LINE_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_LINE_GENERATOR)) -#define GTK_IS_LINE_GENERATOR_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE((vtable), G_TYPE_LINE_GENERATOR)) -#define G_LINE_GENERATOR_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), G_TYPE_LINE_GENERATOR, GLineGeneratorIface)) +#define G_TYPE_TOKEN_GENERATOR (g_token_generator_get_type()) +DECLARE_INTERFACE(GTokenGenerator, g_token_generator, G, TOKEN_GENERATOR); -/* Intermédiaire pour la génération de lignes (coquille vide) */ -typedef struct _GLineGenerator GLineGenerator; -/* Intermédiaire pour la génération de lignes (interface) */ -typedef struct _GLineGeneratorIface GLineGeneratorIface; +/* Indique le nombre de ligne prêtes à être générées. */ +size_t g_token_generator_count_lines(const GTokenGenerator *); -/* Détermine le type d'une interface pour la mise en place de lignes. */ -GType g_line_generator_get_type(void) G_GNUC_CONST; +/* Renseigne sur les propriétés liées à un générateur. */ +BufferLineFlags g_token_generator_get_flags(const GTokenGenerator *, size_t, size_t); -/* Indique le nombre de ligne prêtes à être générées. */ -size_t g_line_generator_count_lines(const GLineGenerator *); +/* Etablit dans une ligne de rendu le contenu représenté. */ +void g_token_generator_populate_line(const GTokenGenerator *, size_t, size_t, GBufferLine *, void *); -/* Retrouve l'emplacement correspondant à une position donnée. */ -GLineCursor *g_line_generator_compute_cursor(const GLineGenerator *, gint, size_t, size_t); -/* Détermine si le conteneur s'inscrit dans une plage donnée. */ -int g_line_generator_contain_cursor(const GLineGenerator *, size_t, size_t, const GLineCursor *); +#if 0 -/* Renseigne sur les propriétés liées à un générateur. */ -BufferLineFlags g_line_generator_get_flags(const GLineGenerator *, size_t, size_t); +/* Retrouve l'emplacement correspondant à une position donnée. */ +GLineCursor *g_token_generator_compute_cursor(const GTokenGenerator *, gint, size_t, size_t); -/* Imprime dans une ligne de rendu le contenu représenté. */ -void g_line_generator_print(GLineGenerator *, GBufferLine *, size_t, size_t, const GBinContent *); +/* Détermine si le conteneur s'inscrit dans une plage donnée. */ +int g_token_generator_contain_cursor(const GTokenGenerator *, size_t, size_t, const GLineCursor *); +#endif -#endif /* _GLIBEXT_LINEGEN_H */ +#endif /* _GLIBEXT_GENERATOR_H */ diff --git a/src/glibext/generators/Makefile.am b/src/glibext/generators/Makefile.am index a332498..e95618f 100644 --- a/src/glibext/generators/Makefile.am +++ b/src/glibext/generators/Makefile.am @@ -3,17 +3,14 @@ noinst_LTLIBRARIES = libglibextgenerators.la libglibextgenerators_la_SOURCES = \ - prologue.h prologue.c \ - rborder.h rborder.c + hex.h hex.c -if BUILD_GTK_SUPPORT -libglibextgenerators_la_SOURCES += \ - hex.h hex.c -endif +# prologue.h prologue.c \ +# rborder.h rborder.c -libglibextgenerators_la_CFLAGS = $(TOOLKIT_CFLAGS) $(LIBXML_CFLAGS) +libglibextgenerators_la_CFLAGS = $(TOOLKIT_CFLAGS) devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%) diff --git a/src/glibext/generators/hex.c b/src/glibext/generators/hex.c index 668ebae..6058825 100644 --- a/src/glibext/generators/hex.c +++ b/src/glibext/generators/hex.c @@ -28,14 +28,26 @@ #include <ctype.h> +#include "../generator-int.h" +#include "../options/hex.h" + + + + +#if 0 + +//#include <ctype.h> + + #include "../bufferline.h" #include "../gbinarycursor.h" -#include "../linegen-int.h" #include "../linesegment.h" #include "../../core/columns.h" #include "../../core/params.h" #include "../../gtkext/hexdisplay.h" +#endif + /* --------------------------- RENDU AMIQUE D'HEXADECIMAL --------------------------- */ @@ -48,9 +60,13 @@ struct _GHexGenerator GBinContent *content; /* Contenu à représenter */ +#if 0 + gint left_start; /* Abscisse des impressions */ gint padding; /* Bourrage supplémentaire */ +#endif + phys_t bytes_per_line; /* Nombre d'octets par ligne */ }; @@ -60,11 +76,15 @@ struct _GHexGeneratorClass { GObjectClass parent; /* A laisser en premier */ +#if 0 + gint addr_width; /* Largeur des positions */ gint byte_width; /* Largeur d'un octet brut */ gint sep_width; /* Largeur de séparation */ gint char_width; /* Largeur d'un caractère */ +#endif + }; @@ -75,7 +95,7 @@ static void g_hex_generator_class_init(GHexGeneratorClass *); static void g_hex_generator_init(GHexGenerator *); /* Procède à l'initialisation de l'interface de génération. */ -static void g_hex_generator_interface_init(GLineGeneratorInterface *); +static void g_hex_generator_token_generator_iface_init(GTokenGeneratorInterface *); /* Supprime toutes les références externes. */ static void g_hex_generator_dispose(GHexGenerator *); @@ -91,6 +111,13 @@ static void g_hex_generator_finalize(GHexGenerator *); /* Indique le nombre de ligne prêtes à être générées. */ static size_t g_hex_generator_count_lines(const GHexGenerator *); +/* Etablit dans une ligne de rendu le contenu représenté. */ +static void g_hex_generator_populate_line(const GHexGenerator *, size_t, size_t, GBufferLine *, void *); + + + + +#if 0 #ifdef INCLUDE_GTK_SUPPORT /* Retrouve l'emplacement correspondant à une position donnée. */ @@ -106,6 +133,7 @@ static BufferLineFlags g_hex_generator_get_flags(const GHexGenerator *, size_t, /* Imprime dans une ligne de rendu le contenu représenté. */ static void g_hex_generator_print(GHexGenerator *, GBufferLine *, size_t, size_t); +#endif @@ -116,7 +144,7 @@ static void g_hex_generator_print(GHexGenerator *, GBufferLine *, size_t, size_t /* Détermine le type du générateur de lignes hexadécimales à la volée. */ G_DEFINE_TYPE_WITH_CODE(GHexGenerator, g_hex_generator, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(G_TYPE_LINE_GENERATOR, g_hex_generator_interface_init)); + G_IMPLEMENT_INTERFACE(G_TYPE_TOKEN_GENERATOR, g_hex_generator_token_generator_iface_init)); /****************************************************************************** @@ -134,13 +162,15 @@ G_DEFINE_TYPE_WITH_CODE(GHexGenerator, g_hex_generator, G_TYPE_OBJECT, static void g_hex_generator_class_init(GHexGeneratorClass *class) { GObjectClass *object; /* Autre version de la classe */ - line_segment *segment; /* Segment de test pour mesure */ + //line_segment *segment; /* Segment de test pour mesure */ object = G_OBJECT_CLASS(class); object->dispose = (GObjectFinalizeFunc/* ! */)g_hex_generator_dispose; object->finalize = (GObjectFinalizeFunc)g_hex_generator_finalize; +#if 0 + /* Mesure de quelques dimensions */ segment = get_new_line_segment(RTT_PHYS_ADDR, "0x00000000", 10); @@ -167,6 +197,8 @@ static void g_hex_generator_class_init(GHexGeneratorClass *class) release_line_segment(segment); +#endif + } @@ -184,7 +216,7 @@ static void g_hex_generator_class_init(GHexGeneratorClass *class) static void g_hex_generator_init(GHexGenerator *generator) { - generator->bytes_per_line = 4; + generator->bytes_per_line = 0; } @@ -201,15 +233,20 @@ static void g_hex_generator_init(GHexGenerator *generator) * * ******************************************************************************/ -static void g_hex_generator_interface_init(GLineGeneratorInterface *iface) +static void g_hex_generator_token_generator_iface_init(GTokenGeneratorInterface *iface) { - iface->count = (linegen_count_lines_fc)g_hex_generator_count_lines; + iface->count = (count_tokgen_lines_fc)g_hex_generator_count_lines; + + iface->populate = (populate_tokgen_line_fc)g_hex_generator_populate_line; + +#if 0 #ifdef INCLUDE_GTK_SUPPORT iface->compute = (linegen_compute_fc)g_hex_generator_compute_cursor; iface->contain = (linegen_contain_fc)g_hex_generator_contain_cursor; #endif iface->get_flags = (linegen_get_flags_fc)g_hex_generator_get_flags; iface->print = (linegen_print_fc)g_hex_generator_print; +#endif } @@ -228,8 +265,7 @@ static void g_hex_generator_interface_init(GLineGeneratorInterface *iface) static void g_hex_generator_dispose(GHexGenerator *generator) { - if (generator->content != NULL) - g_object_unref(G_OBJECT(generator->content)); + g_clear_object(&generator->content); G_OBJECT_CLASS(g_hex_generator_parent_class)->dispose(G_OBJECT(generator)); @@ -274,8 +310,239 @@ GHexGenerator *g_hex_generator_new(GBinContent *content) result = g_object_new(G_TYPE_HEX_GENERATOR, NULL); result->content = content; + ref_object(content); + + return result; + +} + + +// TODO create... + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * +* * +* Description : Fournit le contenu associé au générateur de lignes hexa. * +* * +* Retour : Contenu dans lequel puise le générateur pour les lignes. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GBinContent *g_hex_generator_get_content(const GHexGenerator *generator) +{ + GBinContent *result; /* Référence à retourner */ + + result = generator->content; + + ref_object(result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à ajuster. * +* options = options d'affichage des colonnes. * +* style = style de rendus des bribes de texte. * +* width = largeur disponible pour les différentes colonnes.* +* * +* Description : Détermine la hauteur idéale d'un contenu lié à une largeur. * +* * +* Retour : Hauteur nécessaire pour les lignes induites. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_hex_generator_mesure_height_for_width(GHexGenerator *generator, const GDisplayOptions *options, const GTokenStyle *style, int width) +{ + int result; /* Taille à retourner */ + vmpa2t end; /* Position terminale */ + bool status; /* Bilan d'une opération */ + int off_size; /* Taille des emplacements */ + int byte_width; /* Largeur d'un octet brut */ + int sep_width; /* Largeur de séparation */ + int char_width; /* Largeur d'un caractère */ + phys_t i; /* Boucle de parcours */ + phys_t block_count; /* Nombre de blocs d'octets */ + int requested; /* Espace requis pour X octets */ + phys_t size; /* Taille du contenu binaire */ + phys_t line_count; /* Nombre de lignes requises */ + + result = -1; + + /* Largeur des positions */ + + if (g_display_options_get(options, HCO_OFFSET)) + { + status = g_binary_content_compute_end_pos(generator->content, &end); + assert(status); + if (!status) goto done; + + off_size = g_token_style_compute_location_width(style, end.physical, false); + + width -= off_size; + + } + + /* Détermination des tailles basiques */ + + byte_width = g_token_style_measure_width(style, TRT_RAW_CODE, 2 /* 00 */); + + sep_width = g_token_style_measure_width(style, TRT_RAW_CODE, TAB_SIZE /* \t */); + + char_width = g_token_style_measure_width(style, TRT_RAW_CODE, 1 /* 0 */); + + for (i = 4; ; i += 4) + { + block_count = (i / 4); + + requested = i * byte_width + 3 * block_count * char_width; + requested += (block_count > 1 ? block_count - 1 : 0) * sep_width; + + requested += i * char_width; + + /* Limite atteinte ? */ + if (requested > width) + { + i -= 4; + break; + } + + } + + if (i == 0) + i = 4; + + /* Détermination de la taille pour un nombre de lignes donné */ + + size = g_binary_content_compute_size(generator->content); + + line_count = size / i; + + if (size % i > 0) + line_count++; + + result = line_count * g_token_style_get_line_height(style); + + done: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à ajuster. * +* options = options d'affichage des colonnes. * +* style = style de rendus des bribes de texte. * +* width = largeur disponible pour les différentes colonnes.* +* columns = largeurs adaptées pour les colonnes. [OUT] * +* * +* Description : Détermine les différentes largeurs de colonnes requises. * +* * +* Retour : true si un changement de contenu a été déterminé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_hex_generator_allocate(GHexGenerator *generator, const GDisplayOptions *options, const GTokenStyle *style, int width, int *columns) +{ + bool result; /* Variation d'état à remonter */ + vmpa2t end; /* Position terminale */ + bool status; /* Bilan d'une opération */ + int byte_width; /* Largeur d'un octet brut */ + int sep_width; /* Largeur de séparation */ + int char_width; /* Largeur d'un caractère */ + phys_t i; /* Boucle de parcours */ + phys_t block_count; /* Nombre de blocs d'octets */ + int requested; /* Espace requis pour X octets */ + + result = false; + + /* Largeur des positions */ + + status = g_binary_content_compute_end_pos(generator->content, &end); + assert(status); + if (!status) goto done; + + columns[HCO_OFFSET] = g_token_style_compute_location_width(style, end.physical, false); + + if (g_display_options_get(options, HCO_OFFSET)) + width -= columns[HCO_OFFSET]; + + /* Détermination des tailles basiques */ + + byte_width = g_token_style_measure_width(style, TRT_RAW_CODE, 2 /* 00 */); + + sep_width = g_token_style_measure_width(style, TRT_RAW_CODE, TAB_SIZE /* \t */); + + char_width = g_token_style_measure_width(style, TRT_RAW_CODE, 1 /* 0 */); + + for (i = 4; ; i += 4) + { + block_count = (i / 4); + + requested = i * byte_width + 3 * block_count * char_width; + requested += (block_count > 1 ? block_count - 1 : 0) * sep_width; + + requested += i * char_width; + + /* Limite atteinte ? */ + if (requested > width) + { + i -= 4; + break; + } + + } + + if (i == 0) + i = 4; + + /* Détermination des largeurs de colonnes principales */ + + columns[HCO_COUNT + 0] = i * byte_width + 3 * block_count * char_width; + columns[HCO_COUNT + 0] += (block_count > 1 ? block_count - 1 : 0) * sep_width; + + columns[HCO_COUNT + 1] = i * char_width; + + result = (generator->bytes_per_line != i); + + generator->bytes_per_line = i; + + done: + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : generator = générateur à consulter. * +* * +* Description : Indique le nombre d'octets programmés constituer une ligne. * +* * +* Retour : Nombre d'octets représentés sur chaque ligne. * +* * +* Remarques : - * +* * +******************************************************************************/ - g_object_ref(G_OBJECT(result->content)); +phys_t g_hex_generator_get_bytes_per_line(const GHexGenerator *generator) +{ + phys_t result; /* Quantité d'octets à renvoyer*/ + + result = generator->bytes_per_line; return result; @@ -317,6 +584,136 @@ static size_t g_hex_generator_count_lines(const GHexGenerator *generator) } +/****************************************************************************** +* * +* Paramètres : generator = générateur à utiliser pour l'impression. * +* index = indice de cette même ligne dans le tampon global.* +* repeat = indice d'utilisations successives du générateur. * +* line = ligne de rendu à compléter. * +* data = éventuelle donnée complémentaire fournie. * +* * +* Description : Etablit dans une ligne de rendu le contenu représenté. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_hex_generator_populate_line(const GHexGenerator *generator, size_t index, size_t repeat, GBufferLine *line, void *data) +{ + + + //GGenConfig *config; /* Configuration à consulter */ + bool upper_case; /* Casse des données en hexa */ +#ifndef NDEBUG + bool status; /* Bilan de la consultation */ +#endif + const char *hexa; /* Chaîne à considérer #0 */ + const char *ff; /* Chaîne à considérer #1 */ + vmpa2t pos; /* Position définie à la volée */ + phys_t got; /* Quantité affichable */ + const bin_t *raw; /* Accès direct et brut */ + phys_t i; /* Boucle de parcours */ + bin_t byte; /* Copie pour confort */ + char tmp[2]; /* Représentation d'un octet */ + + static const char hexa_lower[] = "0123456789abcdef"; + static const char hexa_upper[] = "0123456789ABCDEF"; + static const char ff_lower[] = "ff"; + static const char ff_upper[] = "FF"; + + /* + config = get_main_configuration(); + +#ifndef NDEBUG + status = g_generic_config_get_value(config, MPK_HEX_UPPER_CASE, &upper_case); + assert(status); +#else + g_generic_config_get_value(config, MPK_HEX_UPPER_CASE, &upper_case); +#endif + */ + + upper_case = true; + + if (upper_case) + { + hexa = hexa_upper; + ff = ff_upper; + } + else + { + hexa = hexa_lower; + ff = ff_lower; + } + + /* Position physique */ + + init_vmpa(&pos, generator->bytes_per_line * index, VMPA_NO_VIRTUAL); + + //g_buffer_line_fill_phys(line, HLC_PHYSICAL, MDS_32_BITS_UNSIGNED, &pos); + + /* Contenu brut */ + + got = g_binary_content_compute_size(generator->content) - get_phy_addr(&pos); + + if (got > generator->bytes_per_line) + got = generator->bytes_per_line; + + raw = g_binary_content_get_raw_access(generator->content, &pos, got); + + for (i = 0; i < got; i++) + { + /* Séparation ? */ + + if (i > 0) + { + if (i % 4 == 0) + g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_NONE, "\t", 1, NULL, NULL); + else + g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_NONE, " ", 1, NULL, NULL); + } + + /* Binaire brut */ + + byte = raw[i]; + + if (byte == 0x00) + g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_RAW_NULL, "00", 2, NULL, NULL); + + else if (byte == 0xff) + g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_RAW_FULL, ff, 2, NULL, NULL); + + else + { + tmp[1] = hexa[byte & 0xf]; + tmp[0] = hexa[(byte >> 4) & 0xf]; + + if (isgraph(byte) || byte == ' ') + g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_RAW_PRINTABLE, tmp, 2, NULL, NULL); + else + g_buffer_line_append_text(line, HCO_COUNT + 0, TRT_RAW_NOT_PRINTABLE, tmp, 2, NULL, NULL); + + } + + /* Représentation humaine ? */ + + if (isgraph(byte) || byte == ' ') + g_buffer_line_append_text(line, HCO_COUNT + 1, TRT_CHR_PRINTABLE, (char *)raw + i, 1, NULL, NULL); + else + g_buffer_line_append_text(line, HCO_COUNT + 1, TRT_CHR_NOT_PRINTABLE, ".", 1, NULL, NULL); + + } + +} + + + + + + + +#if 0 #ifdef INCLUDE_GTK_SUPPORT @@ -538,9 +935,9 @@ static void g_hex_generator_print(GHexGenerator *generator, GBufferLine *line, s if (i > 0) { if (i % 4 == 0) - g_buffer_line_append_text(line, HLC_BINARY, "\t", 1, RTT_RAW, NULL); + g_buffer_line_append_text(line, HCO_COUNT + 0, "\t", 1, RTT_RAW, NULL); else - g_buffer_line_append_text(line, HLC_BINARY, " ", 1, RTT_RAW, NULL); + g_buffer_line_append_text(line, HCO_COUNT + 0, " ", 1, RTT_RAW, NULL); } /* Binaire brut */ @@ -548,17 +945,17 @@ static void g_hex_generator_print(GHexGenerator *generator, GBufferLine *line, s byte = raw[i]; if (byte == 0x00) - g_buffer_line_append_text(line, HLC_BINARY, "00", 2, RTT_RAW_NULL, NULL); + g_buffer_line_append_text(line, HCO_COUNT + 0, "00", 2, RTT_RAW_NULL, NULL); else if (byte == 0xff) - g_buffer_line_append_text(line, HLC_BINARY, ff, 2, RTT_RAW_FULL, NULL); + g_buffer_line_append_text(line, HCO_COUNT + 0, ff, 2, RTT_RAW_FULL, NULL); else { tmp[1] = hexa[byte & 0xf]; tmp[0] = hexa[(byte >> 4) & 0xf]; - g_buffer_line_append_text(line, HLC_BINARY, tmp, 2, RTT_RAW, NULL); + g_buffer_line_append_text(line, HCO_COUNT + 0, tmp, 2, RTT_RAW, NULL); } @@ -574,30 +971,6 @@ static void g_hex_generator_print(GHexGenerator *generator, GBufferLine *line, s } -/****************************************************************************** -* * -* Paramètres : generator = générateur à consulter. * -* * -* Description : Fournit le contenu associé au générateur de lignes hexa. * -* * -* Retour : Contenu dans lequel puise le générateur pour les lignes. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GBinContent *g_hex_generator_get_content(const GHexGenerator *generator) -{ - GBinContent *result; /* Référence à retourner */ - - result = generator->content; - - g_object_ref(G_OBJECT(result)); - - return result; - -} - /****************************************************************************** * * @@ -665,20 +1038,4 @@ bool g_hex_generator_auto_fit(GHexGenerator *generator, gint left, bool show_pos } -/****************************************************************************** -* * -* Paramètres : generator = générateur à consulter. * -* * -* Description : Indique le nombre d'octets programmés constituer une ligne. * -* * -* Retour : Nombre d'octets représentés sur chaque ligne. * -* * -* Remarques : - * -* * -******************************************************************************/ - -phys_t g_hex_generator_get_bytes_per_line(const GHexGenerator *generator) -{ - return generator->bytes_per_line; - -} +#endif diff --git a/src/glibext/generators/hex.h b/src/glibext/generators/hex.h index f4aeb03..e404adf 100644 --- a/src/glibext/generators/hex.h +++ b/src/glibext/generators/hex.h @@ -25,30 +25,17 @@ #define _GLIBEXT_GENERATORS_HEX_H -#include <glib-object.h> - - +#include "../helpers.h" +#include "../options.h" +#include "../tokenstyle.h" #include "../../analysis/content.h" -#define G_TYPE_HEX_GENERATOR (g_hex_generator_get_type()) -#define G_HEX_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_HEX_GENERATOR, GHexGenerator)) -#define G_IS_HEX_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), G_TYPE_HEX_GENERATOR)) -#define G_HEX_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_HEX_GENERATOR, GHexGeneratorClass)) -#define G_IS_HEX_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_HEX_GENERATOR)) -#define G_HEX_GENERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_HEX_GENERATOR, GHexGeneratorClass)) - +#define G_TYPE_HEX_GENERATOR (g_hex_generator_get_type()) -/* Tampon pour générateur de lignes hexadécimales (instance) */ -typedef struct _GHexGenerator GHexGenerator; +DECLARE_GTYPE(GHexGenerator, g_hex_generator, G, HEX_GENERATOR); -/* Tampon pour générateur de lignes hexadécimales (classe) */ -typedef struct _GHexGeneratorClass GHexGeneratorClass; - - -/* Détermine le type du générateur de lignes hexadécimales à la volée. */ -GType g_hex_generator_get_type(void); /* Crée un nouveau générateur de lignes hexadécimales. */ GHexGenerator *g_hex_generator_new(GBinContent *); @@ -56,8 +43,11 @@ GHexGenerator *g_hex_generator_new(GBinContent *); /* Fournit le contenu associé au générateur de lignes hexa. */ GBinContent *g_hex_generator_get_content(const GHexGenerator *); -/* Ajuste la génération à une nouvelle largeur de rendu. */ -bool g_hex_generator_auto_fit(GHexGenerator *, gint, bool, gint, gint); +/* Détermine la hauteur idéale d'un contenu lié à une largeur. */ +int g_hex_generator_mesure_height_for_width(GHexGenerator *, const GDisplayOptions *, const GTokenStyle *, int); + +/* Détermine les différentes largeurs de colonnes requises. */ +bool g_hex_generator_allocate(GHexGenerator *, const GDisplayOptions *, const GTokenStyle *, int, int *); /* Indique le nombre d'octets programmés constituer une ligne. */ phys_t g_hex_generator_get_bytes_per_line(const GHexGenerator *); diff --git a/src/glibext/helpers.h b/src/glibext/helpers.h index 71a7269..04e51ad 100644 --- a/src/glibext/helpers.h +++ b/src/glibext/helpers.h @@ -90,6 +90,36 @@ /** + * Bis repetita pour les interfaces... + */ + +#define DECLARE_INTERFACE(TN, t_n, MOD, NAME) \ + \ + GType t_n##_get_type(void) G_GNUC_CONST; \ + \ + /* Coquille vide */ \ + typedef struct _##TN TN; \ + /* Interface */ \ + typedef struct _##TN##Interface TN##Interface; \ + \ + G_GNUC_UNUSED static inline TN *MOD##_##NAME(gconstpointer obj) \ + { \ + return G_TYPE_CHECK_INSTANCE_CAST(obj, MOD##_TYPE_##NAME, TN); \ + } \ + \ + G_GNUC_UNUSED static inline gboolean MOD##_IS_##NAME(gconstpointer obj) \ + { \ + return G_TYPE_CHECK_INSTANCE_TYPE(obj, MOD##_TYPE_##NAME); \ + } \ + \ + G_GNUC_UNUSED static inline TN##Interface *MOD##_##NAME##_GET_IFACE(gconstpointer obj) \ + { \ + return G_TYPE_INSTANCE_GET_INTERFACE(obj, MOD##_TYPE_##NAME, TN##Interface); \ + } + + + +/** * Les principales fonctions incrémentant ou réduisant le nombre de références * attachées à un objet acceptent de simples pointeurs génériques (cf. définitions * du fichier <glib-2.80>/gobject/gobject.h : @@ -143,7 +173,7 @@ assert(__inst != NULL); \ g_object_ref(ip); \ } \ - while (0); + while (0) # define unref_object(ip) \ do \ @@ -153,7 +183,7 @@ assert(__inst != NULL); \ g_object_unref(ip); \ } \ - while (0); + while (0) #else diff --git a/src/glibext/linecolumn.c b/src/glibext/linecolumn.c index 35f7698..22ff2a4 100644 --- a/src/glibext/linecolumn.c +++ b/src/glibext/linecolumn.c @@ -24,13 +24,9 @@ #include "linecolumn.h" -#include <assert.h> #include <malloc.h> -#include "../common/extstr.h" - - /****************************************************************************** * * @@ -44,14 +40,12 @@ * * ******************************************************************************/ -void init_line_column(line_column *column) +void init_line_column(line_column_t *column) { - column->segments = NULL; + column->tokens = NULL; column->count = 0; -#ifdef INCLUDE_GTK_SUPPORT column->max_width = 0; -#endif } @@ -68,114 +62,162 @@ void init_line_column(line_column *column) * * ******************************************************************************/ -void reset_line_column(line_column *column) +void reset_line_column(line_column_t *column) { size_t i; /* Boucle de parcours */ for (i = 0; i < column->count; i++) - release_line_segment(column->segments[i]); + release_line_token(column->tokens[i]); - if (column->segments != NULL) + if (column->tokens != NULL) { - free(column->segments); - column->segments = NULL; + free(column->tokens); + column->tokens = NULL; } column->count = 0; -#ifdef INCLUDE_GTK_SUPPORT column->max_width = 0; -#endif } -#ifdef INCLUDE_GTK_SUPPORT + /****************************************************************************** * * -* Paramètres : column = colonne de ligne à mettre à jour. * +* Paramètres : column = colonne de ligne à venir compléter. * +* tag = propriétés de la zone de texte. * +* text = chaîne de caractères à traiter. * +* length = quantité de ces caractères. * +* style = gestionnaire de paramètres de rendu à consulter. * * * -* Description : Recalcule la largeur d'une colonne de segments. * +* Description : Ajoute un fragment de texte à une colonne de ligne. * * * -* Retour : - * +* Retour : Indice du point d'insertion. * * * * Remarques : - * * * ******************************************************************************/ -void refresh_line_column_width(line_column *column) +size_t append_text_to_line_column(line_column_t *column, TokenRenderingTag tag, const char *text, size_t length, const GTokenStyle *style) { - size_t i; /* Boucle de parcours */ + size_t result; /* Indice à retourner */ + line_token_t *token; /* Contenu à représenter */ - column->max_width = 0; + result = column->count; - for (i = 0; i < column->count; i++) - column->max_width += get_line_segment_width(column->segments[i]); + token = get_new_line_token(tag, text, length); + + column->tokens = realloc(column->tokens, ++column->count * sizeof(line_token_t *)); + + column->tokens[result] = token; + + //column->max_width += g_token_style_measure_width(style, tag, length); + + return result; } + + + + /****************************************************************************** * * -* Paramètres : column = colonne de ligne à consulter. * +* Paramètres : column = colonne de ligne de texte à manipuler. * +* cr = contexte graphique à utiliser pour les pinceaux. * +* x = abscisse du point d'impression (à maj). [OUT] * +* y = ordonnée du point d'impression. * +* style = style de rendu pour les bribes de texte. * * * -* Description : Fournit la quantité de pixels requise pour l'impression. * +* Description : Imprime le contenu d'une colonne de ligne de texte. * * * -* Retour : Largeur requise par la colonne, en pixel. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -gint get_column_width(const line_column *column) +void draw_line_column(const line_column_t *column, cairo_t *cr, int *x, int y, const GTokenStyle *style) { - return column->max_width; + size_t i; /* Boucle de parcours */ + + for (i = 0; i < column->count; i++) + draw_line_token(column->tokens[i], cr, x, y, style); } -#endif + + + + +#if 0 + +#include <assert.h> +#include <malloc.h> + + +#include "../common/extstr.h" + + + + + +#ifdef INCLUDE_GTK_SUPPORT /****************************************************************************** * * -* Paramètres : column = colonne de ligne à venir compléter. * -* text = texte à insérer dans l'existant. * -* length = taille du texte à traiter. * -* type = type de décorateur à utiliser. * +* Paramètres : column = colonne de ligne à mettre à jour. * * * -* Description : Ajoute un fragment de texte à une colonne de ligne. * +* Description : Recalcule la largeur d'une colonne de segments. * * * -* Retour : Indice du point d'insertion. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -size_t append_text_to_line_column(line_column *column, const char *text, size_t length, RenderingTagType type) +void refresh_line_column_width(line_column *column) { - size_t result; /* Indice à retourner */ - line_segment *segment; /* Contenu à représenter */ + size_t i; /* Boucle de parcours */ - result = column->count; + column->max_width = 0; - segment = get_new_line_segment(type, text, length); + for (i = 0; i < column->count; i++) + column->max_width += get_line_segment_width(column->segments[i]); - column->segments = realloc(column->segments, ++column->count * sizeof(line_segment *)); +} - column->segments[result] = segment; -#ifdef INCLUDE_GTK_SUPPORT - column->max_width += get_line_segment_width(segment); -#endif +/****************************************************************************** +* * +* Paramètres : column = colonne de ligne à consulter. * +* * +* Description : Fournit la quantité de pixels requise pour l'impression. * +* * +* Retour : Largeur requise par la colonne, en pixel. * +* * +* Remarques : - * +* * +******************************************************************************/ - return result; +gint get_column_width(const line_column *column) +{ + return column->max_width; } +#endif + + + + /****************************************************************************** * * * Paramètres : column = colonne de ligne à venir compléter. * @@ -202,7 +244,7 @@ void replace_text_in_line_column(line_column *column, size_t index, const char * segment = column->segments[index]; - type = get_line_segment_type(segment); + type = get_line_token_type(segment); release_line_segment(segment); @@ -544,3 +586,5 @@ void export_line_column_segments(const line_column *column, buffer_export_contex } } + +#endif diff --git a/src/glibext/linecolumn.h b/src/glibext/linecolumn.h index 6dd50f6..a1757f9 100644 --- a/src/glibext/linecolumn.h +++ b/src/glibext/linecolumn.h @@ -25,39 +25,58 @@ #define _GLIBEXT_LINECOLUMN_H -#include <stdbool.h> -#include <glib-object.h> -#ifdef INCLUDE_GTK_SUPPORT -# include <gdk/gdk.h> -#endif +#include <sys/types.h> -#include "linesegment.h" +#include "linetoken.h" /* Informations sur le contenu d'une colonne */ -typedef struct _line_column line_column; - - -/* Informations sur le contenu d'une colonne */ -struct _line_column +typedef struct _line_column_t { - line_segment **segments; /* Liste des segments contenus */ + line_token_t **tokens; /* Liste des segments contenus */ size_t count; /* Taille de cette liste */ -#ifdef INCLUDE_GTK_SUPPORT int max_width; /* Largeur max. de l'espace */ -#endif -}; +} line_column_t; + /* Initialise une colonne de ligne. */ -void init_line_column(line_column *); +void init_line_column(line_column_t *); /* Réinitialise une colonne de ligne. */ -void reset_line_column(line_column *); +void reset_line_column(line_column_t *); + +/* Ajoute un fragment de texte à une colonne de ligne. */ +size_t append_text_to_line_column(line_column_t *, TokenRenderingTag, const char *, size_t, const GTokenStyle *); + + + + +/* Imprime le contenu d'une colonne de ligne de texte. */ +void draw_line_column(const line_column_t *, cairo_t *, int *, int, const GTokenStyle *); + + + + +#if 0 + +#include <stdbool.h> +#include <glib-object.h> +#ifdef INCLUDE_GTK_SUPPORT +# include <gdk/gdk.h> +#endif + + +#include "linesegment.h" + + + +/* Réinitialise une colonne de ligne. */ +//void reset_line_column(line_column *); #ifdef INCLUDE_GTK_SUPPORT @@ -70,7 +89,7 @@ gint get_column_width(const line_column *); #endif /* Ajoute un fragment de texte à une colonne de ligne. */ -size_t append_text_to_line_column(line_column *, const char *, size_t, RenderingTagType); +//size_t append_text_to_line_column(line_column *, const char *, size_t, RenderingTagType); /* Remplace un fragment de texte dans une colonne de ligne. */ void replace_text_in_line_column(line_column *, size_t, const char *, size_t); @@ -104,5 +123,8 @@ char *get_line_column_text(const line_column *, bool); void export_line_column_segments(const line_column *, buffer_export_context *, BufferExportType, int); +#endif + + #endif /* _GLIBEXT_LINECOLUMN_H */ diff --git a/src/glibext/linetoken.c b/src/glibext/linetoken.c index 192e030..6caa7df 100644 --- a/src/glibext/linetoken.c +++ b/src/glibext/linetoken.c @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * linesegment.c - concentration d'un fragment de caractères aux propriétés communes + * linetoken.c - concentration d'un fragment de caractères aux propriétés communes * * Copyright (C) 2016-2019 Cyrille Bagard * @@ -21,173 +21,137 @@ */ -#include "linesegment.h" +#include "linetoken.h" -#include <assert.h> -#include <limits.h> +#include <glib.h> #include <malloc.h> -#include <stdbool.h> -#include <stdlib.h> #include <string.h> -#include "../common/extstr.h" #include "../common/fnv1a.h" -#include "../core/paths.h" -#ifdef INCLUDE_GTK_SUPPORT -# include "../gtkext/rendering.h" -#endif -/* ------------------------ NATURE POUR UN FRAGMENT DE TEXTE ------------------------ */ +/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */ -/* Nom des éléments CSS */ +/* Fragment de caractères aux propriétés potentiellement partagées */ +struct _line_token_t +{ + gint ref_count; /* Compteur de références */ -#define SEGMENT_NAME(s) "token-" s + TokenRenderingTag tag; /* Type de rendu attendu */ -static const char *_segment_names[RTT_COUNT] = { + fnv64_t hash; /* Empreinte pour comparaisons */ - [RTT_NONE] = SEGMENT_NAME("none"), - [RTT_RAW] = SEGMENT_NAME("raw"), - [RTT_RAW_FULL] = SEGMENT_NAME("raw-full"), - [RTT_RAW_NULL] = SEGMENT_NAME("raw-null"), - [RTT_PRINTABLE] = SEGMENT_NAME("printable"), - [RTT_NOT_PRINTABLE] = SEGMENT_NAME("not-printable"), - [RTT_COMMENT] = SEGMENT_NAME("comment"), - [RTT_INDICATION] = SEGMENT_NAME("indication"), - [RTT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"), - [RTT_PHYS_ADDR] = SEGMENT_NAME("phys-addr"), - [RTT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"), - [RTT_VIRT_ADDR] = SEGMENT_NAME("virt-addr"), - [RTT_RAW_CODE] = SEGMENT_NAME("raw-code"), - [RTT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"), - [RTT_LABEL] = SEGMENT_NAME("label"), - [RTT_INSTRUCTION] = SEGMENT_NAME("instruction"), - [RTT_IMMEDIATE] = SEGMENT_NAME("immediate"), - [RTT_REGISTER] = SEGMENT_NAME("register"), - [RTT_PUNCT] = SEGMENT_NAME("punct"), - [RTT_HOOK] = SEGMENT_NAME("hooks"), - [RTT_SIGNS] = SEGMENT_NAME("signs"), - [RTT_LTGT] = SEGMENT_NAME("ltgt"), - [RTT_SECTION] = SEGMENT_NAME("section"), - [RTT_SEGMENT] = SEGMENT_NAME("segment"), - [RTT_STRING] = SEGMENT_NAME("string"), - [RTT_VAR_NAME] = SEGMENT_NAME("var-name"), - [RTT_KEY_WORD] = SEGMENT_NAME("keyword"), - [RTT_ERROR] = SEGMENT_NAME("error"), + size_t length; /* Taille du texte brut */ + char text[0]; /* Texte brut conservé */ }; +/* Fournit l'empreinte d'une bribe de texte pour rendu. */ +static guint hash_line_token(const line_token_t *); -#ifdef INCLUDE_GTK_SUPPORT - -/* Compléments à Cairo */ - -#define CAIRO_FONT_SLANT_COUNT 3 -#define CAIRO_FONT_WEIGHT_COUNT 2 +/* Détermine si deux fragments de texte sont identiques. */ +static bool is_line_token_equal(const line_token_t *, const line_token_t *); -#define CAIRO_FONTS_COUNT (CAIRO_FONT_SLANT_COUNT * CAIRO_FONT_WEIGHT_COUNT) -#define CAIRO_FONT_INDEX(s, w) ((s) + (w) * CAIRO_FONT_WEIGHT_COUNT) - - -/* Propriétés de rendu */ -typedef struct _segment_rendering -{ - rendering_color_t selection_bg; /* Fond d'impression */ - cairo_t *font_ctxts[CAIRO_FONTS_COUNT]; /* Contextes de police */ - double x_advances[CAIRO_FONTS_COUNT]; /* Largeurs par caractère */ - rendering_pattern_t patterns[RTT_COUNT];/* Modèles d'impression */ +/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ -} segment_rendering; +/* Conservation de toutes les créations partagées */ +static GHashTable *_token_htable; +G_LOCK_DEFINE_STATIC(_token_mutex); -/* Configuration globale des rendus */ -static segment_rendering _seg_params; +/* Fournit l'adresse d'un fragment de texte unique. */ +static line_token_t *get_shared_line_token(const line_token_t *); -#endif +/* Abandonne un contenu pour segments. */ +static void release_shared_line_token(line_token_t *); -/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ +/* ---------------------------------------------------------------------------------- */ +/* NATURE DE BASE POUR UN FRAGMENT DE TEXTE */ +/* ---------------------------------------------------------------------------------- */ +/****************************************************************************** +* * +* Paramètres : tag = propriétés de la zone de texte. * +* text = chaîne de caractères à traiter. * +* length = quantité de ces caractères. * +* * +* Description : Crée un nouveau fragment de texte avec des propriétés. * +* * +* Retour : Elément créé ou recyclé. * +* * +* Remarques : - * +* * +******************************************************************************/ -/* Fragment de caractères aux propriétés potentiellement partagées */ -struct _line_segment +line_token_t *get_new_line_token(TokenRenderingTag tag, const char *text, size_t length) { - gint ref_count; /* Compteur de références */ - -#ifdef INCLUDE_GTK_SUPPORT - rendering_pattern_t *pattern; /* Propriétés du rendu */ -#else - RenderingTagType type; /* Type de rendu attendu */ -#endif - - fnv64_t hash; /* Empreinte pour comparaisons */ - char text[0]; /* Texte brut conservé */ + line_token_t *result; /* Elément à retourner */ + char atmp[sizeof(line_token_t) + 128]; /* Allocation static facile */ + line_token_t *template; /* Contenu à mettre en place ? */ -}; + assert(length > 0); + /** + * L'octet nul final est attendu par la fonction cairo_show_text() + * pour le rendu. + */ -/* Conservation de toutes les créations partagées */ -static GHashTable *_segcnt_htable; -G_LOCK_DEFINE_STATIC(_segcnt_mutex); + if ((length + 1) < (sizeof(atmp) - sizeof(line_token_t))) + template = (line_token_t *)atmp; + else + template = malloc(sizeof(line_token_t) + length + 1); + template->tag = tag; -/* Fournit l'empreinte d'un contenu pour segments. */ -static guint get_line_segment_hash(const line_segment *); + template->hash = fnv_64a_hash(text); -/* Détermine si deux contenus pour segments sont identiques. */ -static bool is_line_segment_equal(const line_segment *, const line_segment *); + template->length = length; -/* Détermine si deux contenus pour segments sont identiques. */ -static line_segment *get_shared_segment_content(const line_segment *); + memcpy(template->text, text, length); + template->text[length] = '\0'; -/* Abandonne un contenu pour segments. */ -static void release_shared_segment_content(line_segment *); + result = get_shared_line_token(template); + if (template != (line_token_t *)atmp) + free(template); + return result; -/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ +} -#ifdef INCLUDE_GTK_SUPPORT +/****************************************************************************** +* * +* Paramètres : token = fragment de texte à traiter. * +* * +* Description : Augmente le compteur de références d'un fragment de texte. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ -/* Liste identifiant un ensemble de segments */ -struct _segcnt_list +void ref_line_token(line_token_t *token) { - fnv64_t *hashes; /* Empreinte pour comparaisons */ - size_t count; /* Nommbre de ces empreintes */ - - unsigned int ref_count; /* Compteur de références */ - -}; - - -/* Indique si le contenu d'un segment est notable ou non. */ -bool selection_list_has_segment_content(const segcnt_list *, const line_segment *); - -#endif + g_atomic_int_inc(&token->ref_count); - - -/* ---------------------------------------------------------------------------------- */ -/* NATURE POUR UN FRAGMENT DE TEXTE */ -/* ---------------------------------------------------------------------------------- */ - - -#ifdef INCLUDE_GTK_SUPPORT +} /****************************************************************************** * * -* Paramètres : - * +* Paramètres : token = fragment de texte à libérer de la mémoire. * * * -* Description : Procède à l'initialisation des paramètres de rendu de texte. * +* Description : Retire une utilisation à un fragment de texte. * * * * Retour : - * * * @@ -195,164 +159,152 @@ bool selection_list_has_segment_content(const segcnt_list *, const line_segment * * ******************************************************************************/ -bool load_segment_rendering_parameters(void) +void release_line_token(line_token_t *token) { - cairo_font_slant_t s; /* Boucle de parcours #1 */ - cairo_font_weight_t w; /* Boucle de parcours #2 */ - cairo_t **cr; /* Contexte à créer */ - cairo_surface_t *surface; /* Surface pour dessin Cairo */ - cairo_text_extents_t extents; /* Couverture des caractères */ - RenderingTagType i; /* Boucle de parcours */ + release_shared_line_token(token); - /* Contextes pour les mesures initiales */ +} - for (s = CAIRO_FONT_SLANT_NORMAL; s < CAIRO_FONT_SLANT_COUNT; s++) - for (w = CAIRO_FONT_WEIGHT_NORMAL; w < CAIRO_FONT_WEIGHT_COUNT; w++) - { - cr = &_seg_params.font_ctxts[CAIRO_FONT_INDEX(s, w)]; +/****************************************************************************** +* * +* Paramètres : token = fragment de texte à consulter. * +* * +* Description : Fournit l'empreinte d'une bribe de texte pour rendu. * +* * +* Retour : Empreinte de lu contenu représenté. * +* * +* Remarques : - * +* * +******************************************************************************/ - surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); - *cr = cairo_create(surface); - cairo_surface_destroy(surface); +static guint hash_line_token(const line_token_t *token) +{ + return token->hash; - cairo_select_font_face(*cr, "mono", s, w); - cairo_set_font_size(*cr, 13); +} - cairo_text_extents(*cr, "A", &extents); - _seg_params.x_advances[CAIRO_FONT_INDEX(s, w)] = extents.x_advance; - } +/****************************************************************************** +* * +* Paramètres : token = premier fragment de texte à analyser. * +* other = second fragment de texte à analyser. * +* * +* Description : Détermine si deux fragments de texte sont identiques. * +* * +* Retour : Bilan de la comparaison. * +* * +* Remarques : - * +* * +******************************************************************************/ - /* Fond d'impression */ +static bool is_line_token_equal(const line_token_t *token, const line_token_t *other) +{ + bool result; /* Résultat à retourner */ - _seg_params.selection_bg.has_color = true; - _seg_params.selection_bg.color.red = 0.5; - _seg_params.selection_bg.color.green = 0.5; - _seg_params.selection_bg.color.blue = 0.5; - _seg_params.selection_bg.color.alpha = 1.0; + result = (cmp_fnv_64a(token->hash, other->hash) == 0); - /* Chargement des définitions utiles */ + if (result) + result = (token->length == other->length); - for (i = 0; i < RTT_COUNT; i++) - load_rendering_pattern(_segment_names[i], &_seg_params.patterns[i]); + if (result) + result = (token->tag == other->tag); - return true; + if (result) + result = (strncmp(token->text, other->text, token->length) == 0); + + return result; } -#endif -/* ---------------------------------------------------------------------------------- */ -/* ISOLATION DE CONTENUS PARTAGEABLES */ -/* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : - * +* Paramètres : token = fragment de texte à manipuler. * +* cr = contexte graphique à utiliser pour les pinceaux. * +* x = abscisse du point d'impression (à maj). [OUT] * +* y = ordonnée du point d'impression. * +* style = style de rendu pour les bribes de texte. * * * -* Description : Initialise la table mémorisant les contenus pour segments. * +* Description : Imprime le fragment de texte représenté. * * * -* Retour : Bilan de l'opération. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -bool init_segment_content_hash_table(void) +void draw_line_token(const line_token_t *token, cairo_t *cr, int *x, int y, const GTokenStyle *style) { - _segcnt_htable = g_hash_table_new_full((GHashFunc)get_line_segment_hash, - (GEqualFunc)is_line_segment_equal, - free, NULL); - - return (_segcnt_htable != NULL); + g_token_style_draw_text(style, token->tag, cr, x, y, token->text, token->length); } -/****************************************************************************** -* * -* Paramètres : - * -* * -* Description : Organise la sortie de la table des contenus pour segments. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ -void exit_segment_content_hash_table(void) -{ - assert(g_hash_table_size(_segcnt_htable) == 0); - g_hash_table_unref(_segcnt_htable); -} + + + +/* ---------------------------------------------------------------------------------- */ +/* ISOLATION DE CONTENUS PARTAGEABLES */ +/* ---------------------------------------------------------------------------------- */ /****************************************************************************** * * -* Paramètres : content = contenu pour segment à consulter. * +* Paramètres : - * * * -* Description : Fournit l'empreinte d'un contenu pour segments. * +* Description : Initialise la table mémorisant les contenus pour segments. * * * -* Retour : Empreinte de lu contenu représenté. * +* Retour : Bilan de l'opération. * * * * Remarques : - * * * ******************************************************************************/ -static guint get_line_segment_hash(const line_segment *content) +bool init_segment_content_hash_table(void) { - return content->hash; + _token_htable = g_hash_table_new_full((GHashFunc)hash_line_token, + (GEqualFunc)is_line_token_equal, + free, NULL); + + return (_token_htable != NULL); } /****************************************************************************** * * -* Paramètres : content = premier contenu pour segment à analyser. * -* other = second contenu pour segment à analyser. * +* Paramètres : - * * * -* Description : Détermine si deux contenus pour segments sont identiques. * +* Description : Organise la sortie de la table des contenus pour segments. * * * -* Retour : Bilan de la comparaison. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -static bool is_line_segment_equal(const line_segment *content, const line_segment *other) +void exit_segment_content_hash_table(void) { - bool result; /* Résultat à retourner */ - -#ifdef INCLUDE_GTK_SUPPORT - result = (content->pattern == other->pattern); -#else - result = (content->type == other->type); -#endif + assert(g_hash_table_size(_token_htable) == 0); - if (result) - result = (cmp_fnv_64a(content->hash, other->hash) == 0); - - if (result) - result = (strcmp(content->text, other->text) == 0); - - return result; + g_hash_table_unref(_token_htable); } /****************************************************************************** * * -* Paramètres : content = premier contenu pour segment à analyser. * -* other = second contenu pour segment à analyser. * +* Paramètres : template = premier contenu pour segment à rechercher. * * * -* Description : Détermine si deux contenus pour segments sont identiques. * +* Description : Fournit l'adresse d'un fragment de texte unique. * * * * Retour : Bilan de la comparaison. * * * @@ -360,34 +312,34 @@ static bool is_line_segment_equal(const line_segment *content, const line_segmen * * ******************************************************************************/ -static line_segment *get_shared_segment_content(const line_segment *content) +static line_token_t *get_shared_line_token(const line_token_t *template) { - line_segment *result; /* Contenu partagé à renvoyer */ + line_token_t *result; /* Contenu partagé à renvoyer */ gboolean found; /* Le contenu existe déjà ? */ size_t allocated; /* Besoin complet en mémoire */ #ifndef NDEBUG gboolean created; /* Validation de mise en place */ #endif - G_LOCK(_segcnt_mutex); + G_LOCK(_token_mutex); - found = g_hash_table_lookup_extended(_segcnt_htable, content, (gpointer *)&result, NULL); + found = g_hash_table_lookup_extended(_token_htable, template, (gpointer *)&result, NULL); if (!found) { - allocated = sizeof(line_segment) + strlen(content->text) + 1; + allocated = sizeof(line_token_t) + template->length + 1; - result = (line_segment *)malloc(allocated); + result = malloc(allocated); - memcpy(result, content, allocated); + memcpy(result, template, allocated); g_atomic_int_set(&result->ref_count, 1); #ifndef NDEBUG - created = g_hash_table_insert(_segcnt_htable, result, result); + created = g_hash_table_insert(_token_htable, result, result); assert(created); #else - g_hash_table_insert(_segcnt_htable, result, result); + g_hash_table_insert(_token_htable, result, result); #endif } @@ -400,7 +352,7 @@ static line_segment *get_shared_segment_content(const line_segment *content) } - G_UNLOCK(_segcnt_mutex); + G_UNLOCK(_token_mutex); return result; @@ -409,7 +361,7 @@ static line_segment *get_shared_segment_content(const line_segment *content) /****************************************************************************** * * -* Paramètres : content = contenu pour segments à délaisser. * +* Paramètres : token = fragment de texte à délaisser. * * * * Description : Abandonne un contenu pour segments. * * * @@ -419,24 +371,24 @@ static line_segment *get_shared_segment_content(const line_segment *content) * * ******************************************************************************/ -static void release_shared_segment_content(line_segment *content) +static void release_shared_line_token(line_token_t *token) { #ifndef NDEBUG gboolean deleted; /* Validation de suppression */ #endif - if (g_atomic_int_dec_and_test(&content->ref_count)) + if (g_atomic_int_dec_and_test(&token->ref_count)) { - G_LOCK(_segcnt_mutex); + G_LOCK(_token_mutex); #ifndef NDEBUG - deleted = g_hash_table_remove(_segcnt_htable, content); + deleted = g_hash_table_remove(_token_htable, token); assert(deleted); #else - g_hash_table_remove(_segcnt_htable, content); + g_hash_table_remove(_token_htable, token); #endif - G_UNLOCK(_segcnt_mutex); + G_UNLOCK(_token_mutex); } @@ -445,59 +397,240 @@ static void release_shared_segment_content(line_segment *content) + + + + + + + + + + +#if 0 + +#include <assert.h> +#include <limits.h> +#include <malloc.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> + + +#include "../common/extstr.h" +//#include "../common/fnv1a.h" +#include "../core/paths.h" +#ifdef INCLUDE_GTK_SUPPORT +# include "../gtkext/rendering.h" +#endif + + + +/* ------------------------ NATURE POUR UN FRAGMENT DE TEXTE ------------------------ */ + + +/* Nom des éléments CSS */ + +#define SEGMENT_NAME(s) "token-" s + +static const char *_segment_names[RTT_COUNT] = { + + [RTT_NONE] = SEGMENT_NAME("none"), + [RTT_RAW] = SEGMENT_NAME("raw"), + [RTT_RAW_FULL] = SEGMENT_NAME("raw-full"), + [RTT_RAW_NULL] = SEGMENT_NAME("raw-null"), + [RTT_PRINTABLE] = SEGMENT_NAME("printable"), + [RTT_NOT_PRINTABLE] = SEGMENT_NAME("not-printable"), + [RTT_COMMENT] = SEGMENT_NAME("comment"), + [RTT_INDICATION] = SEGMENT_NAME("indication"), + [RTT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"), + [RTT_PHYS_ADDR] = SEGMENT_NAME("phys-addr"), + [RTT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"), + [RTT_VIRT_ADDR] = SEGMENT_NAME("virt-addr"), + [RTT_RAW_CODE] = SEGMENT_NAME("raw-code"), + [RTT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"), + [RTT_LABEL] = SEGMENT_NAME("label"), + [RTT_INSTRUCTION] = SEGMENT_NAME("instruction"), + [RTT_IMMEDIATE] = SEGMENT_NAME("immediate"), + [RTT_REGISTER] = SEGMENT_NAME("register"), + [RTT_PUNCT] = SEGMENT_NAME("punct"), + [RTT_HOOK] = SEGMENT_NAME("hooks"), + [RTT_SIGNS] = SEGMENT_NAME("signs"), + [RTT_LTGT] = SEGMENT_NAME("ltgt"), + [RTT_SECTION] = SEGMENT_NAME("section"), + [RTT_SEGMENT] = SEGMENT_NAME("segment"), + [RTT_STRING] = SEGMENT_NAME("string"), + [RTT_VAR_NAME] = SEGMENT_NAME("var-name"), + [RTT_KEY_WORD] = SEGMENT_NAME("keyword"), + [RTT_ERROR] = SEGMENT_NAME("error"), + +}; + + +#ifdef INCLUDE_GTK_SUPPORT + +/* Compléments à Cairo */ + +#define CAIRO_FONT_SLANT_COUNT 3 +#define CAIRO_FONT_WEIGHT_COUNT 2 + +#define CAIRO_FONTS_COUNT (CAIRO_FONT_SLANT_COUNT * CAIRO_FONT_WEIGHT_COUNT) +#define CAIRO_FONT_INDEX(s, w) ((s) + (w) * CAIRO_FONT_WEIGHT_COUNT) + + +/* Propriétés de rendu */ +typedef struct _segment_rendering +{ + rendering_color_t selection_bg; /* Fond d'impression */ + + cairo_t *font_ctxts[CAIRO_FONTS_COUNT]; /* Contextes de police */ + double x_advances[CAIRO_FONTS_COUNT]; /* Largeurs par caractère */ + + rendering_pattern_t patterns[RTT_COUNT];/* Modèles d'impression */ + +} segment_rendering; + + +/* Configuration globale des rendus */ +static segment_rendering _seg_params; + +#endif + + + +/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ + + +/* Fragment de caractères aux propriétés potentiellement partagées */ +struct _line_segment +{ + gint ref_count; /* Compteur de références */ + +#ifdef INCLUDE_GTK_SUPPORT + rendering_pattern_t *pattern; /* Propriétés du rendu */ +#else + RenderingTagType type; /* Type de rendu attendu */ +#endif + + fnv64_t hash; /* Empreinte pour comparaisons */ + char text[0]; /* Texte brut conservé */ + +}; + + + +/* Détermine si deux contenus pour segments sont identiques. */ +static line_segment *get_shared_segment_content(const line_segment *); + +/* Abandonne un contenu pour segments. */ +static void release_shared_segment_content(line_segment *); + + + +/* -------------------- GESTION OPTIMALE D'UNE LISTE DE CONTENUS -------------------- */ + + +#ifdef INCLUDE_GTK_SUPPORT + +/* Liste identifiant un ensemble de segments */ +struct _segcnt_list +{ + fnv64_t *hashes; /* Empreinte pour comparaisons */ + size_t count; /* Nommbre de ces empreintes */ + + unsigned int ref_count; /* Compteur de références */ + +}; + + +/* Indique si le contenu d'un segment est notable ou non. */ +bool selection_list_has_segment_content(const segcnt_list *, const line_segment *); + +#endif + + + /* ---------------------------------------------------------------------------------- */ -/* NATURE DE BASE POUR UN FRAGMENT DE TEXTE */ +/* NATURE POUR UN FRAGMENT DE TEXTE */ /* ---------------------------------------------------------------------------------- */ +#ifdef INCLUDE_GTK_SUPPORT + + /****************************************************************************** * * -* Paramètres : type = propriétés de la zone de texte. * -* text = chaîne de caractères à traiter. * -* length = quantité de ces caractères. * +* Paramètres : - * * * -* Description : Crée un nouveau fragment de texte avec des propriétés. * +* Description : Procède à l'initialisation des paramètres de rendu de texte. * * * -* Retour : Elément créé ou recyclé. * +* Retour : - * * * * Remarques : - * * * ******************************************************************************/ -line_segment *get_new_line_segment(RenderingTagType type, const char *text, size_t length) +bool load_segment_rendering_parameters(void) { - line_segment *result; /* Elément à retourner */ - char atmp[sizeof(line_segment) + 128]; /* Allocation static facile */ - line_segment *content; /* Contenu à mettre en place ? */ + cairo_font_slant_t s; /* Boucle de parcours #1 */ + cairo_font_weight_t w; /* Boucle de parcours #2 */ + cairo_t **cr; /* Contexte à créer */ + cairo_surface_t *surface; /* Surface pour dessin Cairo */ + cairo_text_extents_t extents; /* Couverture des caractères */ + RenderingTagType i; /* Boucle de parcours */ - assert(length > 0); + /* Contextes pour les mesures initiales */ - if (length < (sizeof(atmp) - sizeof(line_segment))) - content = (line_segment *)atmp; - else - content = (line_segment *)malloc(sizeof(line_segment) + length + 1); + for (s = CAIRO_FONT_SLANT_NORMAL; s < CAIRO_FONT_SLANT_COUNT; s++) + for (w = CAIRO_FONT_WEIGHT_NORMAL; w < CAIRO_FONT_WEIGHT_COUNT; w++) + { + cr = &_seg_params.font_ctxts[CAIRO_FONT_INDEX(s, w)]; -#ifdef INCLUDE_GTK_SUPPORT - content->pattern = &_seg_params.patterns[type]; -#else - content->type = type; -#endif + surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1); + *cr = cairo_create(surface); + cairo_surface_destroy(surface); - content->hash = fnv_64a_hash(text); + cairo_select_font_face(*cr, "mono", s, w); + cairo_set_font_size(*cr, 13); - memcpy(content->text, text, length); - content->text[length] = '\0'; + cairo_text_extents(*cr, "A", &extents); + _seg_params.x_advances[CAIRO_FONT_INDEX(s, w)] = extents.x_advance; - result = get_shared_segment_content(content); + } - if (content != (line_segment *)atmp) - free(content); + /* Fond d'impression */ - return result; + _seg_params.selection_bg.has_color = true; + _seg_params.selection_bg.color.red = 0.5; + _seg_params.selection_bg.color.green = 0.5; + _seg_params.selection_bg.color.blue = 0.5; + _seg_params.selection_bg.color.alpha = 1.0; + + /* Chargement des définitions utiles */ + + for (i = 0; i < RTT_COUNT; i++) + load_rendering_pattern(_segment_names[i], &_seg_params.patterns[i]); + + return true; } +#endif + + + + + + + +/* ---------------------------------------------------------------------------------- */ +/* NATURE DE BASE POUR UN FRAGMENT DE TEXTE */ +/* ---------------------------------------------------------------------------------- */ + + + + /****************************************************************************** * * * Paramètres : segment = fragment de texte à traiter. * @@ -555,7 +688,7 @@ RenderingTagType get_line_segment_type(const line_segment *segment) #ifdef INCLUDE_GTK_SUPPORT result = (RenderingTagType)(segment->pattern - _seg_params.patterns); #else - result = segment->type; + result = segment->tag; #endif return result; @@ -1204,3 +1337,5 @@ bool selection_list_has_segment_content(const segcnt_list *list, const line_segm #endif + +#endif diff --git a/src/glibext/linetoken.h b/src/glibext/linetoken.h index 4e06f8c..25c93ed 100644 --- a/src/glibext/linetoken.h +++ b/src/glibext/linetoken.h @@ -1,6 +1,6 @@ /* Chrysalide - Outil d'analyse de fichiers binaires - * linesegment.h - prototypes pour la concentration d'un fragment de caractères aux propriétés communes + * linetoken.h - prototypes pour la concentration d'un fragment de caractères aux propriétés communes * * Copyright (C) 2016-2019 Cyrille Bagard * @@ -21,12 +21,61 @@ */ -#ifndef _GLIBEXT_LINESEGMENT_H -#define _GLIBEXT_LINESEGMENT_H +#ifndef _GLIBEXT_LINETOKEN_H +#define _GLIBEXT_LINETOKEN_H -#include <glib-object.h> #include <stdbool.h> + + +#include "tokenstyle.h" + + + +/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */ + + +/* Fragment de caractères aux propriétés potentiellement partagées */ +typedef struct _line_token_t line_token_t; + + +/* Crée un nouveau fragment de texte avec des propriétés. */ +line_token_t *get_new_line_token(TokenRenderingTag, const char *, size_t); + +/* Augmente le compteur de références d'un fragment de texte. */ +void ref_line_token(line_token_t *); + +/* Retire une utilisation à un fragment de texte. */ +void release_line_token(line_token_t *); + + + + + + + +/* ----------------------- ISOLATION DE CONTENUS PARTAGEABLES ----------------------- */ + + +/* Initialise la table mémorisant les contenus pour segments. */ +bool init_segment_content_hash_table(void); + +/* Organise la sortie de la table des contenus pour segments. */ +void exit_segment_content_hash_table(void); + + + +/* Imprime le fragment de texte représenté. */ +void draw_line_token(const line_token_t *, cairo_t *, int *, int, const GTokenStyle *); + + + + + + +#if 0 + +#include <glib-object.h> #ifdef INCLUDE_GTK_SUPPORT # include <gdk/gdk.h> # include <pango/pango.h> @@ -58,14 +107,14 @@ bool load_segment_rendering_parameters(void); /* Fragment de caractères aux propriétés potentiellement partagées */ -typedef struct _line_segment line_segment; +//typedef struct _line_segment line_segment; /* Initialise la table mémorisant les contenus pour segments. */ -bool init_segment_content_hash_table(void); +//bool init_segment_content_hash_table(void); /* Organise la sortie de la table des contenus pour segments. */ -void exit_segment_content_hash_table(void); +//void exit_segment_content_hash_table(void); @@ -74,13 +123,13 @@ void exit_segment_content_hash_table(void); /* Crée un nouveau fragment de texte avec des propriétés. */ -line_segment *get_new_line_segment(RenderingTagType, const char *, size_t); +//line_segment *get_new_line_segment(RenderingTagType, const char *, size_t); /* Augmente le compteur de références d'un fragment de texte. */ -void ref_line_segment(line_segment *); +//void ref_line_segment(line_segment *); /* Retire une utilisation à un fragment de texte. */ -void release_line_segment(line_segment *); +//void release_line_segment(line_segment *); /* Indique le type de rendu associé à un segment de ligne. */ RenderingTagType get_line_segment_type(const line_segment *); @@ -100,7 +149,7 @@ gint get_caret_position_from_line_segment(const line_segment *, gint); bool move_caret_on_line_segment(const line_segment *, gint *, bool, GdkScrollDirection); /* Imprime le fragment de texte représenté. */ -void draw_line_segment(const line_segment *, cairo_t *, gint *, gint, const segcnt_list *); +//void draw_line_segment(const line_segment *, cairo_t *, gint *, gint, const segcnt_list *); #endif @@ -174,6 +223,7 @@ bool add_segment_content_to_selection_list(segcnt_list *, const line_segment *); #endif +#endif -#endif /* _GLIBEXT_LINESEGMENT_H */ +#endif /* _GLIBEXT_LINETOKEN_H */ diff --git a/src/glibext/options/hex.c b/src/glibext/options/hex.c index 5804a57..ab461a7 100644 --- a/src/glibext/options/hex.c +++ b/src/glibext/options/hex.c @@ -101,7 +101,7 @@ static void g_hex_options_init(GHexOptions *options) #endif (const char *[]) { _("Offset") }, (const bool []) { true }, - 1); + HCO_COUNT); assert(status); diff --git a/src/glibext/options/hex.h b/src/glibext/options/hex.h index 48ce942..0d187dc 100644 --- a/src/glibext/options/hex.h +++ b/src/glibext/options/hex.h @@ -29,6 +29,16 @@ +/* Liste des colonnes en options */ +typedef enum _HexColumnOptions +{ + HCO_OFFSET, /* Position */ + + HCO_COUNT + +} HexColumnOptions; + + #define G_TYPE_HEX_OPTIONS (g_hex_options_get_type()) DECLARE_GTYPE(GHexOptions, g_hex_options, G, HEX_OPTIONS); diff --git a/src/glibext/tokenstyle.c b/src/glibext/tokenstyle.c index e797856..df1d42a 100644 --- a/src/glibext/tokenstyle.c +++ b/src/glibext/tokenstyle.c @@ -25,6 +25,7 @@ #include "tokenstyle.h" +#include <math.h> #include <string.h> @@ -60,34 +61,35 @@ static void g_token_style_finalize(GTokenStyle *); static const char *_token_names[TRT_COUNT] = { - [TRT_NONE] = SEGMENT_NAME("none"), - [TRT_RAW] = SEGMENT_NAME("raw"), - [TRT_RAW_FULL] = SEGMENT_NAME("raw-full"), - [TRT_RAW_NULL] = SEGMENT_NAME("raw-null"), - [TRT_PRINTABLE] = SEGMENT_NAME("printable"), - [TRT_NOT_PRINTABLE] = SEGMENT_NAME("not-printable"), - [TRT_COMMENT] = SEGMENT_NAME("comment"), - [TRT_INDICATION] = SEGMENT_NAME("indication"), - [TRT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"), - [TRT_PHYS_ADDR] = SEGMENT_NAME("phys-addr"), - [TRT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"), - [TRT_VIRT_ADDR] = SEGMENT_NAME("virt-addr"), - [TRT_RAW_CODE] = SEGMENT_NAME("raw-code"), - [TRT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"), - [TRT_LABEL] = SEGMENT_NAME("label"), - [TRT_INSTRUCTION] = SEGMENT_NAME("instruction"), - [TRT_IMMEDIATE] = SEGMENT_NAME("immediate"), - [TRT_REGISTER] = SEGMENT_NAME("register"), - [TRT_PUNCT] = SEGMENT_NAME("punct"), - [TRT_HOOK] = SEGMENT_NAME("hooks"), - [TRT_SIGNS] = SEGMENT_NAME("signs"), - [TRT_LTGT] = SEGMENT_NAME("ltgt"), - [TRT_SECTION] = SEGMENT_NAME("section"), - [TRT_SEGMENT] = SEGMENT_NAME("segment"), - [TRT_STRING] = SEGMENT_NAME("string"), - [TRT_VAR_NAME] = SEGMENT_NAME("var-name"), - [TRT_KEY_WORD] = SEGMENT_NAME("keyword"), - [TRT_ERROR] = SEGMENT_NAME("error"), + [TRT_NONE] = SEGMENT_NAME("none"), + [TRT_RAW_PRINTABLE] = SEGMENT_NAME("raw-printable"), + [TRT_RAW_NOT_PRINTABLE] = SEGMENT_NAME("raw-not-printable"), + [TRT_RAW_FULL] = SEGMENT_NAME("raw-full"), + [TRT_RAW_NULL] = SEGMENT_NAME("raw-null"), + [TRT_CHR_PRINTABLE] = SEGMENT_NAME("chr-printable"), + [TRT_CHR_NOT_PRINTABLE] = SEGMENT_NAME("chr-not-printable"), + [TRT_COMMENT] = SEGMENT_NAME("comment"), + [TRT_INDICATION] = SEGMENT_NAME("indication"), + [TRT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"), + [TRT_PHYS_ADDR] = SEGMENT_NAME("phys-addr"), + [TRT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"), + [TRT_VIRT_ADDR] = SEGMENT_NAME("virt-addr"), + [TRT_RAW_CODE] = SEGMENT_NAME("raw-code"), + [TRT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"), + [TRT_LABEL] = SEGMENT_NAME("label"), + [TRT_INSTRUCTION] = SEGMENT_NAME("instruction"), + [TRT_IMMEDIATE] = SEGMENT_NAME("immediate"), + [TRT_REGISTER] = SEGMENT_NAME("register"), + [TRT_PUNCT] = SEGMENT_NAME("punct"), + [TRT_HOOK] = SEGMENT_NAME("hooks"), + [TRT_SIGNS] = SEGMENT_NAME("signs"), + [TRT_LTGT] = SEGMENT_NAME("ltgt"), + [TRT_SECTION] = SEGMENT_NAME("section"), + [TRT_SEGMENT] = SEGMENT_NAME("segment"), + [TRT_STRING] = SEGMENT_NAME("string"), + [TRT_VAR_NAME] = SEGMENT_NAME("var-name"), + [TRT_KEY_WORD] = SEGMENT_NAME("keyword"), + [TRT_ERROR] = SEGMENT_NAME("error"), }; @@ -272,12 +274,35 @@ bool g_token_style_create(GTokenStyle *style, GtkWidget *target) /****************************************************************************** * * * Paramètres : style = gestionnaire de paramètres de rendu à consulter. * +* * +* Description : Fournit la quantité de pixels requise pour une ligne. * +* * +* Retour : Hauteur de chaque ligne de rendu, en pixels. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_token_style_get_line_height(const GTokenStyle *style) +{ + int result; /* Hauteur à retourner */ + + result = style->font_extents.height; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : style = gestionnaire de paramètres de rendu à consulter. * * tag = type de rendu sollicité. * * length = nombre de caractères à mesurer. * * * * Description : Fournit la quantité de pixels requise pour l'impression. * * * -* Retour : Largeur requise par la colonne, en pixel. * +* Retour : Largeur requise par la colonne, en pixels. * * * * Remarques : - * * * @@ -325,6 +350,13 @@ void g_token_style_draw_text(const GTokenStyle *style, TokenRenderingTag tag, ca cairo_operator_t old; /* Sauvegarde avant changement */ const rendering_property_t *prop; /* Motif de rendu visé */ + /* Cas particulier d'une tabulation */ + if (length == 1 && (text[0] == '\t' || text[0] == ' ')) + { + width = g_token_style_measure_width(style, tag, text[0] == '\t' ? TAB_SIZE : 1); + goto small_sep; + } + selected = false;//selection_list_has_segment_content(list, segment); width = g_token_style_measure_width(style, tag, length); @@ -378,6 +410,8 @@ void g_token_style_draw_text(const GTokenStyle *style, TokenRenderingTag tag, ca cairo_show_text(cr, text); + small_sep: + *x += width; } @@ -467,6 +501,56 @@ char *g_token_style_append_markup(const GTokenStyle *style, char *base, TokenRen } +/****************************************************************************** +* * +* Paramètres : style = gestionnaire de paramètres de rendu à consulter. * +* max = valeur maximale atteignable. * +* virt = indique une position virtuelle et non physique. * +* * +* Description : Détermine une taille de localisation, physique ou virtuelle. * +* * +* Retour : Largeur minimale à observer en pixels. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_token_style_compute_location_width(const GTokenStyle *style, uint64_t max, bool virt) +{ + int result; /* Taille à retourner */ + double n; /* Nombre de chiffres hexa */ + double c; /* Valeur ajustée */ + TokenRenderingTag tag; /* Type de représentation */ + + /** + * Les situations suivantes ont été évaluées : + * + * max | n | c + * ----------------------------------- + * 0 | 0 | 0 + * 1 | 0,25 | 1 + * f | 1 | 1 + * 10 | 1,02187 | 2 + * 11 | 1,04248 | 2 + * ff | 2 | 2 + * 100 | 2,00141 | 3 + * ffffffff | 8 | 8 + * ffffffffffffffff | 16 | 16 + */ + + n = log1p(max) / log(16); + + c = ceil(n); + + tag = virt ? TRT_VIRT_ADDR : TRT_PHYS_ADDR; + + result = g_token_style_measure_width(style, tag, c); + + return result; + +} + + /* ---------------------------------------------------------------------------------- */ /* RECEPTACLES DE SIGNAUX CONNECTES */ diff --git a/src/glibext/tokenstyle.css b/src/glibext/tokenstyle.css index 0cf9f37..6fb78aa 100644 --- a/src/glibext/tokenstyle.css +++ b/src/glibext/tokenstyle.css @@ -6,21 +6,30 @@ } +.token-raw-printable, +.token-chr-printable { + color: white; + +} + +.token-raw-not-printable, +.token-chr-not-printable { + + color: #bbbbbb; + +} .token-raw-full { color: white; - font-style: italic; font-weight: bold; } .token-raw-null { - color: black; - - background-color: pink; + color: #666666; } diff --git a/src/glibext/tokenstyle.h b/src/glibext/tokenstyle.h index 923b725..2e19b51 100644 --- a/src/glibext/tokenstyle.h +++ b/src/glibext/tokenstyle.h @@ -26,6 +26,8 @@ #define _GLIBEXT_TOKENSTYLE_H +#include <stdbool.h> +#include <stdint.h> #include <gtk/gtk.h> @@ -38,11 +40,12 @@ typedef enum _TokenRenderingTag { TRT_NONE, /* Espace ou tabulation */ - TRT_RAW, /* Contenu brut */ + TRT_RAW_PRINTABLE, /* Contenu brut */ + TRT_RAW_NOT_PRINTABLE, /* Contenu brut */ TRT_RAW_FULL, /* Contenu brut et complet */ TRT_RAW_NULL, /* Contenu brut et nul */ - TRT_PRINTABLE, /* Caractère imprimable */ - TRT_NOT_PRINTABLE, /* Caractère non imprimable */ + TRT_CHR_PRINTABLE, /* Caractère imprimable */ + TRT_CHR_NOT_PRINTABLE, /* Caractère non imprimable */ TRT_COMMENT, /* Commentaire */ TRT_INDICATION, /* Aide à la lecture */ @@ -82,6 +85,10 @@ typedef enum _TokenRenderingTag } TokenRenderingTag; +/* Caractères par tabulation */ +#define TAB_SIZE 2 + + #define G_TYPE_TOKEN_STYLE (g_token_style_get_type()) DECLARE_GTYPE(GTokenStyle, g_token_style, G, TOKEN_STYLE); @@ -90,6 +97,9 @@ DECLARE_GTYPE(GTokenStyle, g_token_style, G, TOKEN_STYLE); /* Crée un gestionnaire de style pour le rendu des lignes. */ GTokenStyle *g_token_style_new(GtkWidget *); +/* Fournit la quantité de pixels requise pour une ligne. */ +int g_token_style_get_line_height(const GTokenStyle *); + /* Fournit la quantité de pixels requise pour l'impression. */ int g_token_style_measure_width(const GTokenStyle *, TokenRenderingTag, size_t); @@ -102,6 +112,9 @@ char *g_token_style_build_markup(const GTokenStyle *, TokenRenderingTag, const c /* Ajoute du texte enjolivé selon un élément de thème. */ char *g_token_style_append_markup(const GTokenStyle *, char *, TokenRenderingTag, const char *); +/* Détermine une taille de localisation, physique ou virtuelle. */ +int g_token_style_compute_location_width(const GTokenStyle *, uint64_t, bool); + #endif /* _GLIBEXT_TOKENSTYLE_H */ diff --git a/src/glibext/widthtracker-int.h b/src/glibext/widthtracker-int.h new file mode 100644 index 0000000..50f5757 --- /dev/null +++ b/src/glibext/widthtracker-int.h @@ -0,0 +1,80 @@ + +/* Chrysalide - Outil d'analyse de fichiers binaires + * widthtracker-int.h - prototypes internes pour le suivi des largeurs associées à un ensemble de lignes + * + * Copyright (C) 2016-2024 Cyrille Bagard + * + * This file is part of Chrysalide. + * + * Chrysalide is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Chrysalide is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef _GLIBEXT_WIDTHTRACKER_INT_H +#define _GLIBEXT_WIDTHTRACKER_INT_H + + +#include "widthtracker.h" + + + +/* Portions de largeurs communes */ +typedef struct _common_metrics_t +{ + size_t first; /* Premier indice de portion */ + size_t last; /* Dernier indice de portion */ + + size_t merging_index; /* Indice de colonne de fusion */ + + int *summary; /* Compilation de largeurs */ + bool cached; /* Mise en cache des calculs */ + +} common_metrics_t; + + +/* Gestionnaire de largeurs associées aux lignes (instance) */ +struct _GWidthTracker +{ + GObject parent; /* A laisser en premier */ + + GBufferCache *cache; /* Ensemble complet de lignes */ + size_t opt_count; /* Qté de colonnes en option */ + size_t reg_count; /* Nombre de colonnes normales */ +#ifndef NDEBUG + size_t col_count; /* Nombre maximum de colonnes */ +#endif + + common_metrics_t *locals; /* Portions représentées */ + size_t count; /* Quantité de ces portions */ + + int *min_widths; /* Largeurs requises suivies */ + bool *fixed; /* Indication d'impositions */ + bool cached; /* Mise en cache des calculs */ + +}; + +/* Gestionnaire de largeurs associées aux lignes (classe) */ +struct _GWidthTrackerClass +{ + GObjectClass parent; /* A laisser en premier */ + +}; + + +/* Met en place un nouveau suivi de largeurs au sein de lignes. */ +bool g_width_tracker_create(GWidthTracker *, GBufferCache *); + + + +#endif /* _GLIBEXT_WIDTHTRACKER_INT_H */ diff --git a/src/glibext/widthtracker.c b/src/glibext/widthtracker.c index bfeb32c..7e06578 100644 --- a/src/glibext/widthtracker.c +++ b/src/glibext/widthtracker.c @@ -26,6 +26,331 @@ #include <assert.h> #include <malloc.h> + + +#include "widthtracker-int.h" + + + +/* ---------------------------- PRISE DE MESURES LOCALES ---------------------------- */ + + +/* Supprime de la mémoire une collecte de mesures locales. */ +static void delete_common_metrics(common_metrics_t *); + + + +/* ---------------------------- RASSEMBLEMENT DE MESURES ---------------------------- */ + + +/* Procède à l'initialisation d'une classe de suivi de largeurs. */ +static void g_width_tracker_class_init(GWidthTrackerClass *); + +/* Procède à l'initialisation d'un suivi de largeurs de lignes. */ +static void g_width_tracker_init(GWidthTracker *); + +/* Supprime toutes les références externes. */ +static void g_width_tracker_dispose(GWidthTracker *); + +/* Procède à la libération totale de la mémoire. */ +static void g_width_tracker_finalize(GWidthTracker *); + + + +/* ---------------------------------------------------------------------------------- */ +/* PRISE DE MESURES LOCALES */ +/* ---------------------------------------------------------------------------------- */ + + +/****************************************************************************** +* * +* Paramètres : metrics = mesures locales conservées. * +* * +* Description : Supprime de la mémoire une collecte de mesures locales. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void delete_common_metrics(common_metrics_t *metrics) +{ + free(metrics->summary); + +} + + + +/* ---------------------------------------------------------------------------------- */ +/* RASSEMBLEMENT DE MESURES */ +/* ---------------------------------------------------------------------------------- */ + + +/* Détermine le type du gestionnaire de largeurs associées aux lignes. */ +G_DEFINE_TYPE(GWidthTracker, g_width_tracker, G_TYPE_OBJECT); + + +/****************************************************************************** +* * +* Paramètres : class = classe de composant GLib à initialiser. * +* * +* Description : Procède à l'initialisation d'une classe de suivi de largeurs.* +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_width_tracker_class_init(GWidthTrackerClass *class) +{ + GObjectClass *object; /* Autre version de la classe */ + + object = G_OBJECT_CLASS(class); + + object->dispose = (GObjectFinalizeFunc/* ! */)g_width_tracker_dispose; + object->finalize = (GObjectFinalizeFunc)g_width_tracker_finalize; + +} + + +/****************************************************************************** +* * +* Paramètres : tracker = composant GLib à initialiser. * +* * +* Description : Procède à l'initialisation d'un suivi de largeurs de lignes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_width_tracker_init(GWidthTracker *tracker) +{ + tracker->cache = NULL; + tracker->opt_count = 0; + tracker->reg_count = 0; + + tracker->locals = NULL; + tracker->count = 0; + + tracker->min_widths = NULL; + tracker->fixed = NULL; + tracker->cached = false; + +} + + +/****************************************************************************** +* * +* Paramètres : tracker = instance d'objet GLib à traiter. * +* * +* Description : Supprime toutes les références externes. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_width_tracker_dispose(GWidthTracker *tracker) +{ + g_clear_object(&tracker->cache); + + G_OBJECT_CLASS(g_width_tracker_parent_class)->dispose(G_OBJECT(tracker)); + +} + + +/****************************************************************************** +* * +* Paramètres : tracker = instance d'objet GLib à traiter. * +* * +* Description : Procède à la libération totale de la mémoire. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void g_width_tracker_finalize(GWidthTracker *tracker) +{ + size_t i; /* Boucle de parcours */ + + for (i = 0; i < tracker->count; i++) + delete_common_metrics(&tracker->locals[i]); + + if (tracker->locals != NULL) + free(tracker->locals); + + if (tracker->min_widths != NULL) + free(tracker->min_widths); + + if (tracker->fixed != NULL) + free(tracker->fixed); + + G_OBJECT_CLASS(g_width_tracker_parent_class)->finalize(G_OBJECT(tracker)); + +} + + +/****************************************************************************** +* * +* Paramètres : cache = tampon de lignes à lier au futur collecteur. * +* * +* Description : Crée un nouveau suivi de largeurs au sein de lignes. * +* * +* Retour : Composant GLib créé. * +* * +* Remarques : - * +* * +******************************************************************************/ + +GWidthTracker *g_width_tracker_new(GBufferCache *cache) +{ + GWidthTracker *result; /* Composant à retourner */ + + result = g_object_new(G_TYPE_WIDTH_TRACKER, NULL); + + if (!g_width_tracker_create(result, cache)) + g_clear_object(&result); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tracker = collecteur de largeur à initialiser pleinement. * +* cache = tampon de lignes à lier au futur élément. * +* * +* Description : Met en place un nouveau suivi de largeurs au sein de lignes. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool g_width_tracker_create(GWidthTracker *tracker, GBufferCache *cache) +{ + bool result; /* Bilen à retourner */ + size_t col_count; /* Nombre maximum de colonnes */ + + result = true; + + tracker->cache = cache; + ref_object(cache); + + g_buffer_cache_count_columns(cache, &tracker->opt_count, &tracker->reg_count); + + col_count = tracker->opt_count + tracker->reg_count; + +#ifndef NDEBUG + tracker->col_count = col_count; +#endif + + tracker->min_widths = malloc(col_count * sizeof(int)); + tracker->fixed = calloc(col_count, sizeof(bool)); + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tracker = gestionnaire de largeurs de lignes à mettre jour. * +* col = indice de colonne visée. * +* * +* Description : Indique la largeur minimale pour une colonne donnée. * +* * +* Retour : Largeur minimale à imposée, nulle ou positive. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int g_width_tracker_get_column_min_width(const GWidthTracker *tracker, size_t col) +{ + int result; /* Largeur à renvoyer */ + + assert(col < tracker->col_count); + + result = tracker->min_widths[col]; + + return result; + +} + + +/****************************************************************************** +* * +* Paramètres : tracker = gestionnaire de largeurs de lignes à mettre jour. * +* col = indice de colonne visée. * +* width = largeur minimale à imposer. * +* * +* Description : Impose une largeur minimale pour une colonne donnée. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_width_tracker_set_column_min_width(GWidthTracker *tracker, size_t col, int width) +{ + assert(col < tracker->col_count); + + if (width < 0) + width = 0; + + tracker->min_widths[col] = width; + tracker->fixed[col] = true; + +} + + +/****************************************************************************** +* * +* Paramètres : tracker = gestionnaire de largeurs de lignes à consulter. * +* width = largeur requise pour un affichage complet. [OUT] * +* * +* Description : Détermine la largeur nécessaire à une pleine représentation. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void g_width_tracker_compute_width(const GWidthTracker *tracker, int *width) +{ + size_t i; /* Boucle de parcours */ + + *width = 0; + + // FIX access to col_count + + for (i = 0; i < tracker->col_count; i++) + *width += tracker->min_widths[i]; + +} + + + + + + +#if 0 + + +//#include <assert.h> +//#include <malloc.h> #include <stdlib.h> #include <string.h> @@ -33,7 +358,7 @@ #include <i18n.h> -#include "buffercache.h" +//#include "buffercache.h" #include "delayed-int.h" #include "../core/global.h" #include "../core/nproc.h" @@ -104,56 +429,7 @@ static void g_width_update_collect(GWidthUpdate *, line_width_summary *); /* ---------------------------- RASSEMBLEMENT DE MESURES ---------------------------- */ -/* Portions de largeurs communes */ -typedef struct _common_metrics -{ - size_t first; /* Premier indice de portion */ - size_t last; /* Dernier indice de portion */ - - line_width_summary summary; /* Compilation de largeurs */ - bool cached; /* Mise en cache des calculs */ - -} common_metrics; - - -/* Gestionnaire de largeurs associées aux lignes (instance) */ -struct _GWidthTracker -{ - GObject parent; /* A laisser en premier */ - - GBufferCache *cache; /* Ensemble complet de lignes */ - size_t col_count; /* Nombre maximum de colonnes */ - size_t opt_count; /* Qté de colonnes en option */ - - common_metrics *portions; /* Portions représentées */ - size_t count; /* Quantité de ces portions */ - - gint *min_widths; /* Largeurs min. à respecter */ - - line_width_summary summary; /* Largeurs requises suivies */ - bool cached; /* Mise en cache des calculs */ - -}; - -/* Gestionnaire de largeurs associées aux lignes (classe) */ -struct _GWidthTrackerClass -{ - GObjectClass parent; /* A laisser en premier */ - -}; - - -/* Procède à l'initialisation d'une classe de suivi de largeurs. */ -static void g_width_tracker_class_init(GWidthTrackerClass *); - -/* Procède à l'initialisation d'un suivi de largeurs de lignes. */ -static void g_width_tracker_init(GWidthTracker *); -/* Supprime toutes les références externes. */ -static void g_width_tracker_dispose(GWidthTracker *); - -/* Procède à la libération totale de la mémoire. */ -static void g_width_tracker_finalize(GWidthTracker *); /* Recherche la portion contenant un indice de ligne donné. */ static size_t g_width_tracker_find_metrics(const GWidthTracker *, size_t); @@ -375,131 +651,6 @@ static void g_width_update_collect(GWidthUpdate *update, line_width_summary *glo /* ---------------------------------------------------------------------------------- */ -/* Détermine le type du gestionnaire de largeurs associées aux lignes. */ -G_DEFINE_TYPE(GWidthTracker, g_width_tracker, G_TYPE_OBJECT); - - -/****************************************************************************** -* * -* Paramètres : class = classe de composant GTK à initialiser. * -* * -* Description : Procède à l'initialisation d'une classe de suivi de largeurs.* -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_width_tracker_class_init(GWidthTrackerClass *class) -{ - GObjectClass *object; /* Autre version de la classe */ - - object = G_OBJECT_CLASS(class); - - object->dispose = (GObjectFinalizeFunc/* ! */)g_width_tracker_dispose; - object->finalize = (GObjectFinalizeFunc)g_width_tracker_finalize; - -} - - -/****************************************************************************** -* * -* Paramètres : tracker = composant GLib à initialiser. * -* * -* Description : Procède à l'initialisation d'un suivi de largeurs de lignes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_width_tracker_init(GWidthTracker *tracker) -{ - tracker->portions = NULL; - tracker->count = 0; - - memset(&tracker->summary, 0, sizeof(line_width_summary)); - tracker->cached = false; - -} - - -/****************************************************************************** -* * -* Paramètres : tracker = instance d'objet GLib à traiter. * -* * -* Description : Supprime toutes les références externes. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_width_tracker_dispose(GWidthTracker *tracker) -{ - g_object_unref(G_OBJECT(tracker->cache)); - - G_OBJECT_CLASS(g_width_tracker_parent_class)->dispose(G_OBJECT(tracker)); - -} - - -/****************************************************************************** -* * -* Paramètres : tracker = instance d'objet GLib à traiter. * -* * -* Description : Procède à la libération totale de la mémoire. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -static void g_width_tracker_finalize(GWidthTracker *tracker) -{ - if (tracker->min_widths != NULL) - free(tracker->min_widths); - - G_OBJECT_CLASS(g_width_tracker_parent_class)->finalize(G_OBJECT(tracker)); - -} - - -/****************************************************************************** -* * -* Paramètres : cache = tampon de lignes à lier au futur élément. * -* col_count = quantité maximale de colonnes à considérer. * -* opt_count = quantité de colonnes optionnelles. * -* * -* Description : Crée un nouveau suivi de largeurs au sein de lignes. * -* * -* Retour : Composant GLib créé. * -* * -* Remarques : - * -* * -******************************************************************************/ - -GWidthTracker *g_width_tracker_new(GBufferCache *cache, size_t col_count, size_t opt_count) -{ - GWidthTracker *result; /* Composant à retourner */ - - result = g_object_new(G_TYPE_WIDTH_TRACKER, NULL); - - g_object_ref(G_OBJECT(cache)); - result->cache = cache; - - result->col_count = col_count; - result->opt_count = opt_count; - - result->min_widths = calloc(col_count, sizeof(gint)); - - return result; - -} /****************************************************************************** @@ -588,57 +739,6 @@ size_t g_width_tracker_count_columns(const GWidthTracker *tracker) } -/****************************************************************************** -* * -* Paramètres : tracker = gestionnaire de largeurs de lignes à mettre jour. * -* col = indice de colonne visée. * -* * -* Description : Indique la largeur minimale pour une colonne donnée. * -* * -* Retour : Largeur minimale à imposée, nulle ou positive. * -* * -* Remarques : - * -* * -******************************************************************************/ - -gint g_width_tracker_get_column_min_width(GWidthTracker *tracker, size_t col) -{ - gint result; /* Largeur à renvoyer */ - - assert(col < tracker->col_count); - - result = tracker->min_widths[col]; - - return result; - -} - - -/****************************************************************************** -* * -* Paramètres : tracker = gestionnaire de largeurs de lignes à mettre jour. * -* col = indice de colonne visée. * -* width = largeur minimale à imposer. * -* * -* Description : Impose une largeur minimale pour une colonne donnée. * -* * -* Retour : - * -* * -* Remarques : - * -* * -******************************************************************************/ - -void g_width_tracker_set_column_min_width(GWidthTracker *tracker, size_t col, gint width) -{ - assert(col < tracker->col_count); - - if (width < 0) - width = 0; - - tracker->min_widths[col] = width; - -} - /****************************************************************************** * * @@ -1367,3 +1467,7 @@ gint g_width_tracker_get_local_column_width(GWidthTracker *tracker, size_t index return result; } + + +#endif + diff --git a/src/glibext/widthtracker.h b/src/glibext/widthtracker.h index ce0aa93..c67e335 100644 --- a/src/glibext/widthtracker.h +++ b/src/glibext/widthtracker.h @@ -25,6 +25,34 @@ #define _GLIBEXT_WIDTHTRACKER_H +#include "buffercache.h" +#include "helpers.h" + + + +#define G_TYPE_WIDTH_TRACKER (g_width_tracker_get_type()) + +DECLARE_GTYPE(GWidthTracker, g_width_tracker, G, WIDTH_TRACKER); + + +/* Crée un nouveau suivi de largeurs au sein de lignes. */ +GWidthTracker *g_width_tracker_new(GBufferCache *); + +/* Indique la largeur minimale pour une colonne donnée. */ +int g_width_tracker_get_column_min_width(const GWidthTracker *, size_t); + +/* Impose une largeur minimale pour une colonne donnée. */ +void g_width_tracker_set_column_min_width(GWidthTracker *, size_t, int); + +/* Détermine la largeur nécessaire à une pleine représentation. */ +void g_width_tracker_compute_width(const GWidthTracker *, int *); + + + + +#if 0 + + #include <glib-object.h> #include <stdbool.h> @@ -74,7 +102,7 @@ typedef struct _GWidthTrackerClass GWidthTrackerClass; GType g_width_tracker_get_type(void); /* Crée un nouveau suivi de largeurs au sein de lignes. */ -GWidthTracker *g_width_tracker_new(GBufferCache *, size_t, size_t); +//GWidthTracker *g_width_tracker_new(GBufferCache *, size_t, size_t); /* Crée un nouveau suivi de largeurs au sein de lignes. */ GWidthTracker *g_width_tracker_new_restricted(const GWidthTracker *, size_t, size_t); @@ -82,12 +110,6 @@ GWidthTracker *g_width_tracker_new_restricted(const GWidthTracker *, size_t, siz /* Indique le nombre de colonnes prises en compte. */ size_t g_width_tracker_count_columns(const GWidthTracker *); -/* Indique la largeur minimale pour une colonne donnée. */ -gint g_width_tracker_get_column_min_width(GWidthTracker *, size_t); - -/* Impose une largeur minimale pour une colonne donnée. */ -void g_width_tracker_set_column_min_width(GWidthTracker *, size_t, gint); - /* Prend acte d'un changement sur une ligne pour les largeurs. */ void g_width_tracker_update(GWidthTracker *, size_t); @@ -110,5 +132,8 @@ gint g_width_tracker_get_margin(GWidthTracker *, const GDisplayOptions *); gint g_width_tracker_get_local_column_width(GWidthTracker *, size_t, size_t, size_t); +#endif + + #endif /* _GLIBEXT_WIDTHTRACKER_H */ |