diff options
Diffstat (limited to 'src/glibext/linetoken.c')
-rw-r--r-- | src/glibext/linetoken.c | 627 |
1 files changed, 381 insertions, 246 deletions
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 |