summaryrefslogtreecommitdiff
path: root/src/glibext/linetoken.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glibext/linetoken.c')
-rw-r--r--src/glibext/linetoken.c627
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