summaryrefslogtreecommitdiff
path: root/src/glibext/tokenstyle.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glibext/tokenstyle.c')
-rw-r--r--src/glibext/tokenstyle.c769
1 files changed, 684 insertions, 85 deletions
diff --git a/src/glibext/tokenstyle.c b/src/glibext/tokenstyle.c
index 8badf21..e797856 100644
--- a/src/glibext/tokenstyle.c
+++ b/src/glibext/tokenstyle.c
@@ -1,8 +1,8 @@
/* Chrysalide - Outil d'analyse de fichiers binaires
- * rendering.h - prototypes pour la transformation de paramètres du thème GTK courant
+ * tokenstyle.c - centralisation des paramètres de rendu de bribes textuelles
*
- * Copyright (C) 2018 Cyrille Bagard
+ * Copyright (C) 2018-2024 Cyrille Bagard
*
* This file is part of Chrysalide.
*
@@ -22,25 +22,104 @@
*/
-#include "rendering.h"
+#include "tokenstyle.h"
-#include <malloc.h>
-#include <stdio.h>
#include <string.h>
-#include <gtk/gtk.h>
+#include "tokenstyle-int.h"
+#include "../core/logs.h"
#include "../common/extstr.h"
+/* -------------------------- DEFINITION D'UN NOUVEL OBJET -------------------------- */
+
+
+/* Procède à l'initialisation des gestionnaires de paramètres. */
+static void g_token_style_class_init(GTokenStyleClass *);
+
+/* Procède à l'initialisation d'un gestionnaire de paramètres. */
+static void g_token_style_init(GTokenStyle *);
+
+/* Supprime toutes les références externes. */
+static void g_token_style_dispose(GTokenStyle *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_token_style_finalize(GTokenStyle *);
+
+
+
+/* ------------------------ RECEPTACLES DE SIGNAUX CONNECTES ------------------------ */
+
+
+/* Nom des éléments CSS */
+
+#define SEGMENT_NAME(s) "token-" s
+
+static const char *_token_names[TRT_COUNT] = {
+
+ [TRT_NONE] = SEGMENT_NAME("none"),
+ [TRT_RAW] = SEGMENT_NAME("raw"),
+ [TRT_RAW_FULL] = SEGMENT_NAME("raw-full"),
+ [TRT_RAW_NULL] = SEGMENT_NAME("raw-null"),
+ [TRT_PRINTABLE] = SEGMENT_NAME("printable"),
+ [TRT_NOT_PRINTABLE] = SEGMENT_NAME("not-printable"),
+ [TRT_COMMENT] = SEGMENT_NAME("comment"),
+ [TRT_INDICATION] = SEGMENT_NAME("indication"),
+ [TRT_PHYS_ADDR_PAD] = SEGMENT_NAME("phys-addr-padding"),
+ [TRT_PHYS_ADDR] = SEGMENT_NAME("phys-addr"),
+ [TRT_VIRT_ADDR_PAD] = SEGMENT_NAME("virt-addr-padding"),
+ [TRT_VIRT_ADDR] = SEGMENT_NAME("virt-addr"),
+ [TRT_RAW_CODE] = SEGMENT_NAME("raw-code"),
+ [TRT_RAW_CODE_NULL] = SEGMENT_NAME("raw-code-null"),
+ [TRT_LABEL] = SEGMENT_NAME("label"),
+ [TRT_INSTRUCTION] = SEGMENT_NAME("instruction"),
+ [TRT_IMMEDIATE] = SEGMENT_NAME("immediate"),
+ [TRT_REGISTER] = SEGMENT_NAME("register"),
+ [TRT_PUNCT] = SEGMENT_NAME("punct"),
+ [TRT_HOOK] = SEGMENT_NAME("hooks"),
+ [TRT_SIGNS] = SEGMENT_NAME("signs"),
+ [TRT_LTGT] = SEGMENT_NAME("ltgt"),
+ [TRT_SECTION] = SEGMENT_NAME("section"),
+ [TRT_SEGMENT] = SEGMENT_NAME("segment"),
+ [TRT_STRING] = SEGMENT_NAME("string"),
+ [TRT_VAR_NAME] = SEGMENT_NAME("var-name"),
+ [TRT_KEY_WORD] = SEGMENT_NAME("keyword"),
+ [TRT_ERROR] = SEGMENT_NAME("error"),
+
+};
+
+
+/* Réagit à un changement de racine pour le composant suivi. */
+static void on_root_change(GtkWidget *, GParamSpec *, GTokenStyle *);
+
+/* Charge toutes les indications liées aux polices. */
+static bool g_token_style_retrieve_font(GTokenStyle *);
+
+/* Détermine les tailles d'impression possibles pour les rendus. */
+static bool g_token_style_retrieve_advances(GTokenStyle *);
+
+/* Charge les définitions complémentaires spécifiques. */
+static bool g_token_style_retrieve_rendering_properties(GTokenStyle *, TokenRenderingTag );
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* DEFINITION D'UN NOUVEL OBJET */
+/* ---------------------------------------------------------------------------------- */
+
+
+/* Détermine le type du composant d'affichage générique. */
+G_DEFINE_TYPE(GTokenStyle, g_token_style, G_TYPE_OBJECT);
+
+
/******************************************************************************
* *
-* Paramètres : name = désignation d'un élément dans une feuille de style.*
-* pattern = paramètres restitués en interne. |OUT] *
+* Paramètres : class = classe des objets à initialiser. *
* *
-* Description : Récupère les informations de rendus d'un élément de thème. *
+* Description : Procède à l'initialisation des gestionnaires de paramètres. *
* *
* Retour : - *
* *
@@ -48,84 +127,267 @@
* *
******************************************************************************/
-void load_rendering_pattern(const char *name, rendering_pattern_t *pattern)
+static void g_token_style_class_init(GTokenStyleClass *class)
{
- GtkStyleContext *context; /* Contexte pour les styles */
- GtkWidgetPath *path; /* Chemin d'accès aux thèmes */
- GdkRGBA *tmp_color; /* Description d'une couleur */
- PangoFontDescription *font_desc; /* Description d'une police */
+ GObjectClass *object; /* Plus haut niveau équivalent */
- /* Création d'un contexte d'accès */
+ object = G_OBJECT_CLASS(class);
- path = gtk_widget_path_new();
- gtk_widget_path_append_type(path, G_TYPE_OBJECT);
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_token_style_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_token_style_finalize;
- context = gtk_style_context_new();
- gtk_style_context_set_path(context, path);
- gtk_style_context_set_screen(context, gdk_screen_get_default());
+}
- gtk_style_context_add_class(context, name);
- gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_COLOR, &tmp_color, NULL);
+/******************************************************************************
+* *
+* Paramètres : style = centralisation de paramètres de rendu à initialiser. *
+* *
+* Description : Procède à l'initialisation d'un gestionnaire de paramètres. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
- pattern->foreground.has_color = true;
- pattern->foreground.color = *tmp_color;
+static void g_token_style_init(GTokenStyle *style)
+{
+ style->target = NULL;
- pattern->inverted.has_color = true;
- pattern->inverted.color.red = 1.0 - tmp_color->red;
- pattern->inverted.color.green = 1.0 - tmp_color->green;
- pattern->inverted.color.blue = 1.0 - tmp_color->blue;
- pattern->inverted.color.alpha = tmp_color->alpha;
+ style->loaded = false;
- gdk_rgba_free(tmp_color);
+ style->font_family = NULL;
+ style->font_size = 0;
- gtk_style_context_get(context, GTK_STATE_FLAG_NORMAL, GTK_STYLE_PROPERTY_FONT, &font_desc, NULL);
+}
- switch (pango_font_description_get_style(font_desc))
- {
- case PANGO_STYLE_NORMAL:
- pattern->slant = CAIRO_FONT_SLANT_NORMAL;
- break;
- case PANGO_STYLE_ITALIC:
- pattern->slant = CAIRO_FONT_SLANT_ITALIC;
- break;
- case PANGO_STYLE_OBLIQUE:
- pattern->slant = CAIRO_FONT_SLANT_OBLIQUE;
- break;
- }
- switch (pango_font_description_get_weight(font_desc))
+/******************************************************************************
+* *
+* Paramètres : style = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_token_style_dispose(GTokenStyle *style)
+{
+ g_clear_object(&style->target);
+
+ G_OBJECT_CLASS(g_token_style_parent_class)->dispose(G_OBJECT(style));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : style = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_token_style_finalize(GTokenStyle *style)
+{
+ if (style->font_family != NULL)
+ free(style->font_family);
+
+ G_OBJECT_CLASS(g_token_style_parent_class)->finalize(G_OBJECT(style));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : target = composant GTK à dédier au futur gestionnaire. *
+* *
+* Description : Crée un gestionnaire de style pour le rendu des lignes. *
+* *
+* Retour : Centralisateur mis en place pour un composant GTK donné. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GTokenStyle *g_token_style_new(GtkWidget *target)
+{
+ GTokenStyle *result; /* Nouvelle instance à renvoyer*/
+
+ result = g_object_new(G_TYPE_TOKEN_STYLE, NULL);
+
+ if (!g_token_style_create(result, target))
+ g_clear_object(&result);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : style = gestionnaire à initialiser. *
+* target = composant GTK à dédier au gestionnaire préparé. *
+* *
+* Description : Met en place un nouveau gestionnaire de rendu des lignes. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+bool g_token_style_create(GTokenStyle *style, GtkWidget *target)
+{
+ bool result; /* Bilan à retourner */
+
+ result = true;
+
+ style->target = target;
+ ref_object(target);
+
+ /**
+ * Si le composant est déjà affiché, l'actualisation des paramètres est
+ * forcée ! Dans le cas contraire, la surveillance des changements
+ * déclenchera l'opération.
+ */
+ if (gtk_widget_get_root(target) != NULL)
+ on_root_change(target, NULL, style);
+
+ g_signal_connect(target, "notify::root", G_CALLBACK(on_root_change), style);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : style = gestionnaire de paramètres de rendu à consulter. *
+* tag = type de rendu sollicité. *
+* length = nombre de caractères à mesurer. *
+* *
+* Description : Fournit la quantité de pixels requise pour l'impression. *
+* *
+* Retour : Largeur requise par la colonne, en pixel. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+int g_token_style_measure_width(const GTokenStyle *style, TokenRenderingTag tag, size_t length)
+{
+ int result; /* Largeur à retourner */
+ const rendering_property_t *prop; /* Motif de rendu visé */
+ size_t index; /* Indice de config. adaptée */
+
+ prop = &style->properties[tag];
+
+ index = CAIRO_FONT_INDEX(prop->slant, prop->weight);
+
+ result = style->x_advances[index] * length;
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : style = gestionnaire de paramètres de rendu à consulter. *
+* tag = type de rendu sollicité. *
+* cr = contexte graphique à utiliser pour les pinceaux. *
+* x = abscisse du point d'impression (à maj). [OUT] *
+* y = ordonnée du point d'impression. *
+* text = texte UTF-8 à faire appraître. *
+* length = taille de ce texte à imprimer. *
+* *
+* Description : Imprime le fragment de texte transmis. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_token_style_draw_text(const GTokenStyle *style, TokenRenderingTag tag, cairo_t *cr, int *x, int y, const char *text, size_t length)
+{
+ bool selected; /* Marquer une sélection ? */
+ gint width; /* Largeur du segment */
+ cairo_operator_t old; /* Sauvegarde avant changement */
+ const rendering_property_t *prop; /* Motif de rendu visé */
+
+ selected = false;//selection_list_has_segment_content(list, segment);
+
+ width = g_token_style_measure_width(style, tag, length);
+
+ /* Fond du texte */
+ if (selected)
{
- case PANGO_WEIGHT_THIN:
- case PANGO_WEIGHT_ULTRALIGHT:
- case PANGO_WEIGHT_LIGHT:
- case PANGO_WEIGHT_SEMILIGHT:
- case PANGO_WEIGHT_BOOK:
- case PANGO_WEIGHT_NORMAL:
- case PANGO_WEIGHT_MEDIUM:
- pattern->weight = CAIRO_FONT_WEIGHT_NORMAL;
- break;
- case PANGO_WEIGHT_SEMIBOLD:
- case PANGO_WEIGHT_BOLD:
- case PANGO_WEIGHT_ULTRABOLD:
- case PANGO_WEIGHT_HEAVY:
- case PANGO_WEIGHT_ULTRAHEAVY:
- pattern->weight = CAIRO_FONT_WEIGHT_BOLD;
- break;
+#if 0
+
+ cairo_set_source_rgba(cr,
+ _seg_params.selection_bg.color.red,
+ _seg_params.selection_bg.color.green,
+ _seg_params.selection_bg.color.blue,
+ _seg_params.selection_bg.color.alpha);
+
+ cairo_rectangle(cr, *x, y, width, 17);
+
+ old = cairo_get_operator(cr);
+ cairo_set_operator(cr, CAIRO_OPERATOR_DIFFERENCE);
+ cairo_fill(cr);
+ cairo_set_operator(cr, old);
+
+#endif
+
}
- pango_font_description_free(font_desc);
+ /* Couleur d'impression */
+
+ prop = &style->properties[tag];
+
+ if (selected)
+ cairo_set_source_rgba(cr,
+ prop->inverted.red,
+ prop->inverted.green,
+ prop->inverted.blue,
+ prop->inverted.alpha);
+
+ else
+ cairo_set_source_rgba(cr,
+ prop->foreground.red,
+ prop->foreground.green,
+ prop->foreground.blue,
+ prop->foreground.alpha);
+
+ /* Impression du texte */
+
+ cairo_select_font_face(cr, style->font_family, prop->slant, prop->weight);
+ cairo_set_font_size(cr, style->font_size);
- gtk_widget_path_free(path);
- g_object_unref(context);
+ cairo_move_to(cr, *x, y + style->font_extents.ascent);
+
+ cairo_show_text(cr, text);
+
+ *x += width;
}
/******************************************************************************
* *
-* Paramètres : text = texte à encadrer par des balises Pango. *
-* pattern = paramètres restitués en interne. *
+* Paramètres : style = gestionnaire de paramètres de rendu à consulter. *
+* tag = type de rendu sollicité. *
+* text = texte à encadrer par des balises Pango. *
* *
* Description : Enjolive du texte selon les paramètres d'un élément de thème.*
* *
@@ -135,36 +397,35 @@ void load_rendering_pattern(const char *name, rendering_pattern_t *pattern)
* *
******************************************************************************/
-char *build_pango_markup_for(const char *text, const rendering_pattern_t *pattern)
+char *g_token_style_build_markup(const GTokenStyle *style, TokenRenderingTag tag, const char *text)
{
char *result; /* Construction à retourner */
+ const rendering_property_t *prop; /* Motif de rendu visé */
char color[10]; /* Définition hexa de couleur */
result = strdup(text);
- if (pattern->foreground.has_color)
- {
- snprintf(color, sizeof(color), "#%02hhx%02hhx%02hhx%02hhx",
- (unsigned char)(255 * pattern->foreground.color.red),
- (unsigned char)(255 * pattern->foreground.color.green),
- (unsigned char)(255 * pattern->foreground.color.blue),
- (unsigned char)(255 * pattern->foreground.color.alpha));
+ prop = &style->properties[tag];
- result = strprep(result, "\">");
- result = strprep(result, color);
- result = strprep(result, "<span color=\"");
+ snprintf(color, sizeof(color), "#%02hhx%02hhx%02hhx%02hhx",
+ (unsigned char)(255 * prop->foreground.red),
+ (unsigned char)(255 * prop->foreground.green),
+ (unsigned char)(255 * prop->foreground.blue),
+ (unsigned char)(255 * prop->foreground.alpha));
- result = stradd(result, "</span>");
+ result = strprep(result, "\">");
+ result = strprep(result, color);
+ result = strprep(result, "<span color=\"");
- }
+ result = stradd(result, "</span>");
- if (pattern->slant == CAIRO_FONT_SLANT_ITALIC || pattern->slant == CAIRO_FONT_SLANT_OBLIQUE)
+ if (prop->slant == CAIRO_FONT_SLANT_ITALIC || prop->slant == CAIRO_FONT_SLANT_OBLIQUE)
{
result = strprep(result, "<i>");
result = stradd(result, "</i>");
}
- if (pattern->weight == CAIRO_FONT_WEIGHT_BOLD)
+ if (prop->weight == CAIRO_FONT_WEIGHT_BOLD)
{
result = strprep(result, "<b>");
result = stradd(result, "</b>");
@@ -177,9 +438,10 @@ char *build_pango_markup_for(const char *text, const rendering_pattern_t *patter
/******************************************************************************
* *
-* Paramètres : base = base de texte à compléter. *
-* text = texte à encadrer par des balises Pango. *
-* pattern = paramètres restitués en interne. *
+* Paramètres : style = gestionnaire de paramètres de rendu à consulter. *
+* base = base de texte à compléter. *
+* tag = type de rendu sollicité. *
+* text = texte à encadrer par des balises Pango. *
* *
* Description : Ajoute du texte enjolivé selon un élément de thème. *
* *
@@ -189,12 +451,12 @@ char *build_pango_markup_for(const char *text, const rendering_pattern_t *patter
* *
******************************************************************************/
-char *append_pango_markup_with(char *base, const char *text, const rendering_pattern_t *pattern)
+char *g_token_style_append_markup(const GTokenStyle *style, char *base, TokenRenderingTag tag, const char *text)
{
char *result; /* Construction à retourner */
char *tmp; /* Stockage temporaire */
- tmp = build_pango_markup_for(text, pattern);
+ tmp = g_token_style_build_markup(style, tag, text);
result = stradd(base, tmp);
@@ -203,3 +465,340 @@ char *append_pango_markup_with(char *base, const char *text, const rendering_pat
return result;
}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* RECEPTACLES DE SIGNAUX CONNECTES */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : widget = composant graphique de GTK changeant d'affichage. *
+* pspec = détails de la propriété ayant évolué. *
+* style = concentration de paramètres de rendu à actualiser. *
+* *
+* Description : Réagit à un changement de racine pour le composant suivi. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void on_root_change(GtkWidget *widget, GParamSpec *pspec, GTokenStyle *style)
+{
+ GtkCssProvider *css; /* Feuille de style maison */
+ GdkDisplay *display; /* Zone d'affichage courante */
+ TokenRenderingTag i; /* Boucle de parcours */
+
+ /**
+ * Si on fermeture n'est pas en court...
+ */
+ if (gtk_widget_get_root(widget) != NULL)
+ {
+ /* Chargement des définitions dédiées */
+
+ css = gtk_css_provider_new();
+
+ gtk_css_provider_load_from_resource(css, "/re/chrysalide/framework/glibext/tokenstyle.css");
+
+ display = gtk_widget_get_display(widget);
+
+ gtk_style_context_add_provider_for_display(display, GTK_STYLE_PROVIDER(css),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+ /* Relecture des paramètres */
+
+ gtk_widget_add_css_class(widget, "token-generic");
+
+ style->loaded = g_token_style_retrieve_font(style);
+
+ if (style->loaded)
+ style->loaded = g_token_style_retrieve_advances(style);
+
+ for (i = 0; i < TRT_COUNT && style->loaded; i++)
+ {
+ gtk_widget_add_css_class(widget, _token_names[i]);
+
+ style->loaded = g_token_style_retrieve_rendering_properties(style, i);
+
+ gtk_widget_remove_css_class(widget, _token_names[i]);
+
+ }
+
+ gtk_widget_remove_css_class(widget, "token-generic");
+
+ /* Déchargement des définitions prises en compte */
+
+ gtk_style_context_remove_provider_for_display(display, GTK_STYLE_PROVIDER(css));
+
+ unref_object(css);
+
+ }
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : style = gestionnaire de paramètres de rendu à actualiser. *
+* *
+* Description : Charge toutes les indications liées aux polices. *
+* *
+* Retour : Bilan de l'opération : true pour un chargement sans encombre.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_token_style_retrieve_font(GTokenStyle *style)
+{
+ bool result; /* Bilan à faire remonter */
+ PangoContext *context; /* Contexte Pango du composant */
+ PangoFontDescription *desc; /* Détails de la police liée */
+ const char *family; /* Eventuelle désignation */
+ bool is_mono; /* Propriété attendue de chasse*/
+ PangoFontFamily **pango_families; /* Liste des familles connues */
+ int pango_families_count; /* Taille de cette liste */
+ int k; /* Boucle de parcours */
+ const char *other; /* Autre nom à comparer */
+
+ result = true;
+
+ /* Réinitialisation */
+
+ if (style->font_family != NULL)
+ {
+ free(style->font_family);
+ style->font_family = NULL;
+ }
+
+ style->font_size = 0;
+
+ /* Chargement */
+
+ context = gtk_widget_create_pango_context(style->target);
+
+ desc = pango_context_get_font_description(context);
+
+ if (desc != NULL)
+ {
+ family = pango_font_description_get_family(desc);
+
+ if (family != NULL)
+ {
+ is_mono = false;
+
+ pango_context_list_families(context, &pango_families, &pango_families_count);
+
+ for (k = 0; k < pango_families_count && !is_mono; k++)
+ {
+ if (!pango_font_family_is_monospace(pango_families[k]))
+ continue;
+
+ other = pango_font_family_get_name(pango_families[k]);
+
+ is_mono = (strcmp(family, other) == 0);
+
+ }
+
+ g_free(pango_families);
+
+ if (is_mono)
+ style->font_family = strdup(family);
+ else
+ log_variadic_message(LMT_WARNING,
+ _("Selected font '%s' does not seem to be a monospace font; skipping it..."),
+ family);
+
+ }
+
+ style->font_size = pango_font_description_get_size(desc);
+
+ if (pango_font_description_get_size_is_absolute(desc))
+ style->font_size /= PANGO_SCALE;
+
+ }
+
+ /* Application de valeurs par défaut au besoin */
+
+ if (style->font_family == NULL)
+ {
+ style->font_family = strdup(DEFAULT_FONT_FAMILY);
+
+ log_variadic_message(LMT_WARNING,
+ _("No font family defined; switching to '%s' as default"),
+ DEFAULT_FONT_FAMILY);
+
+ }
+
+ if (style->font_size == 0)
+ {
+ style->font_size = DEFAULT_FONT_SIZE;
+
+ log_variadic_message(LMT_WARNING,
+ _("No font size defined; switching to '%s' as default"),
+ DEFAULT_FONT_SIZE);
+
+ }
+
+ log_variadic_message(LMT_INFO,
+ _("Using '%s' as font family for buffer rendering (size: %d)"),
+ style->font_family, style->font_size);
+
+ unref_object(context);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : style = gestionnaire de paramètres de rendu à actualiser. *
+* *
+* Description : Détermine les tailles d'impression possibles pour les rendus.*
+* *
+* Retour : Bilan de l'opération : true pour un chargement sans encombre.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_token_style_retrieve_advances(GTokenStyle *style)
+{
+ bool result; /* Bilan à faire remonter */
+ cairo_font_slant_t s; /* Boucle de parcours #1 */
+ cairo_font_weight_t w; /* Boucle de parcours #2 */
+ cairo_t *cr; /* Contexte à usage unique */
+ cairo_surface_t *surface; /* Surface pour dessin Cairo */
+ cairo_text_extents_t extents; /* Couverture des caractères */
+
+ result = true;
+
+ for (s = CAIRO_FONT_SLANT_NORMAL; s < CAIRO_FONT_SLANT_COUNT; s++)
+ for (w = CAIRO_FONT_WEIGHT_NORMAL; w < CAIRO_FONT_WEIGHT_COUNT; w++)
+ {
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 100, 100);
+ cr = cairo_create(surface);
+
+ cairo_select_font_face(cr, style->font_family, s, w);
+ cairo_set_font_size(cr, style->font_size);
+
+ if (s == CAIRO_FONT_SLANT_NORMAL && w == CAIRO_FONT_WEIGHT_NORMAL)
+ {
+ cairo_font_extents(cr, &style->font_extents);
+ }
+
+ cairo_text_extents(cr, "A", &extents);
+ style->x_advances[CAIRO_FONT_INDEX(s, w)] = extents.x_advance;
+
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : style = gestionnaire de paramètres de rendu à actualiser. *
+* tag = désignation du style de rendu à traiter. *
+* *
+* Description : Charge les définitions complémentaires spécifiques. *
+* *
+* Retour : Bilan de l'opération : true pour un chargement sans encombre.*
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool g_token_style_retrieve_rendering_properties(GTokenStyle *style, TokenRenderingTag tag)
+{
+ bool result; /* Bilan à faire remonter */
+ rendering_property_t *prop; /* Motif de rendu visé */
+ GtkStyleContext *s_context; /* Contexte voué à disparaître */
+ PangoContext *context; /* Contexte Pango du composant */
+ PangoFontDescription *desc; /* Détails de la police liée */
+
+ result = true;
+
+ prop = &style->properties[tag];
+
+ /* Couleur d'impression */
+
+ /**
+ * En attendant la disponibilité de GTK 4.10 et l'appel
+ * gtk_widget_get_color(widget, &color);
+ */
+
+ s_context = gtk_widget_get_style_context(style->target);
+
+ gtk_style_context_get_color(s_context, &prop->foreground);
+
+ /* Couleur inversée */
+
+ prop->inverted.red = 1.0 - prop->foreground.red;
+ prop->inverted.green = 1.0 - prop->foreground.green;
+ prop->inverted.blue = 1.0 - prop->foreground.blue;
+ prop->inverted.alpha = prop->foreground.alpha;
+
+ /* Style d'impression */
+
+ context = gtk_widget_create_pango_context(style->target);
+
+ desc = pango_context_get_font_description(context);
+
+ if (desc == NULL)
+ {
+ prop->slant = CAIRO_FONT_SLANT_NORMAL;
+ prop->weight = CAIRO_FONT_WEIGHT_NORMAL;
+ }
+
+ else
+ {
+ switch (pango_font_description_get_style(desc))
+ {
+ case PANGO_STYLE_NORMAL:
+ prop->slant = CAIRO_FONT_SLANT_NORMAL;
+ break;
+ case PANGO_STYLE_ITALIC:
+ prop->slant = CAIRO_FONT_SLANT_ITALIC;
+ break;
+ case PANGO_STYLE_OBLIQUE:
+ prop->slant = CAIRO_FONT_SLANT_OBLIQUE;
+ break;
+ }
+
+ switch (pango_font_description_get_weight(desc))
+ {
+ case PANGO_WEIGHT_THIN:
+ case PANGO_WEIGHT_ULTRALIGHT:
+ case PANGO_WEIGHT_LIGHT:
+ case PANGO_WEIGHT_SEMILIGHT:
+ case PANGO_WEIGHT_BOOK:
+ case PANGO_WEIGHT_NORMAL:
+ case PANGO_WEIGHT_MEDIUM:
+ prop->weight = CAIRO_FONT_WEIGHT_NORMAL;
+ break;
+ case PANGO_WEIGHT_SEMIBOLD:
+ case PANGO_WEIGHT_BOLD:
+ case PANGO_WEIGHT_ULTRABOLD:
+ case PANGO_WEIGHT_HEAVY:
+ case PANGO_WEIGHT_ULTRAHEAVY:
+ prop->weight = CAIRO_FONT_WEIGHT_BOLD;
+ break;
+ }
+
+ }
+
+ unref_object(context);
+
+ return result;
+
+}