diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2024-06-18 06:31:42 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2024-06-18 06:31:58 (GMT) |
commit | 53edb30496d1065019406de16f9f9d96ba61cd3c (patch) | |
tree | 162cad07e27a01990d721f69f3270581417c31e7 /src/glibext/buffercache.c | |
parent | 334126eb659bc310a72a9f7f9238b7cd205a0770 (diff) |
Rebuild hex views for large contents.
Diffstat (limited to 'src/glibext/buffercache.c')
-rw-r--r-- | src/glibext/buffercache.c | 893 |
1 files changed, 493 insertions, 400 deletions
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 |