summaryrefslogtreecommitdiff
path: root/src/glibext
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2024-05-30 20:10:50 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2024-05-30 20:10:50 (GMT)
commitc21a38d5af9a57e470d5445fcec354b07de784f2 (patch)
tree6c461364d39498193a8ee1a9501aed08a8eedc67 /src/glibext
parent8043a52accf1b413362c54adb117c7786e237917 (diff)
Centralize the CSS rendering features.
Diffstat (limited to 'src/glibext')
-rw-r--r--src/glibext/Makefile.am26
-rw-r--r--src/glibext/gresource.xml6
-rw-r--r--src/glibext/linetoken.h48
-rw-r--r--src/glibext/tokenstyle-int.h94
-rw-r--r--src/glibext/tokenstyle.c769
-rw-r--r--src/glibext/tokenstyle.css26
-rw-r--r--src/glibext/tokenstyle.h90
7 files changed, 900 insertions, 159 deletions
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index ac8668c..336c121 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -1,7 +1,7 @@
-BUILT_SOURCES = chrysamarshal.h chrysamarshal.c
+BUILT_SOURCES = chrysamarshal.h chrysamarshal.c resources.h resources.c
-noinst_LTLIBRARIES = libglibext4.la # libglibext.la
+noinst_LTLIBRARIES = libglibext4.la libglibextui.la # libglibext.la
libglibext_la_SOURCES = \
buffercache-int.h \
@@ -58,6 +58,17 @@ libglibext4_la_SOURCES = \
libglibext4_la_CFLAGS = $(TOOLKIT_CFLAGS)
+RES_FILES = \
+ tokenstyle.css
+
+libglibextui_la_SOURCES = \
+ tokenstyle-int.h \
+ tokenstyle.h tokenstyle.c \
+ resources.h resources.c
+
+libglibextui_la_CFLAGS = $(LIBGTK4_CFLAGS)
+
+
devdir = $(includedir)/chrysalide/$(subdir:src/%=core/%)
dev_HEADERS = $(libglibext_la_SOURCES:%c=)
@@ -72,3 +83,14 @@ chrysamarshal.h: chrysamarshal.list
chrysamarshal.c: chrysamarshal.list
echo "#include <$(subst .c,.h,$@)>" > $@
glib-genmarshal --body $< >> $@
+
+resources.c: gresource.xml $(RES_FILES)
+ glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-source --c-name glibext gresource.xml
+
+resources.h: gresource.xml
+ glib-compile-resources --target=$@ --sourcedir=$(srcdir) --generate-header --c-name glibext gresource.xml
+
+
+CLEANFILES = resources.h resources.c
+
+EXTRA_DIST = gresource.xml $(RES_FILES)
diff --git a/src/glibext/gresource.xml b/src/glibext/gresource.xml
new file mode 100644
index 0000000..0a88e4c
--- /dev/null
+++ b/src/glibext/gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/re/chrysalide/framework/glibext">
+ <file compressed="true">tokenstyle.css</file>
+ </gresource>
+</gresources>
diff --git a/src/glibext/linetoken.h b/src/glibext/linetoken.h
index 4859fbb..4e06f8c 100644
--- a/src/glibext/linetoken.h
+++ b/src/glibext/linetoken.h
@@ -72,54 +72,6 @@ void exit_segment_content_hash_table(void);
/* -------------------- NATURE DE BASE POUR UN FRAGMENT DE TEXTE -------------------- */
-/* Types de partie de rendu */
-typedef enum _RenderingTagType
-{
- RTT_NONE, /* Espace ou tabulation */
-
- RTT_RAW, /* Contenu brut */
- RTT_RAW_FULL, /* Contenu brut et complet */
- RTT_RAW_NULL, /* Contenu brut et nul */
- RTT_PRINTABLE, /* Caractère imprimable */
- RTT_NOT_PRINTABLE, /* Caractère non imprimable */
-
- RTT_COMMENT, /* Commentaire */
- RTT_INDICATION, /* Aide à la lecture */
-
- RTT_PHYS_ADDR_PAD, /* Position physique (début) */
- RTT_PHYS_ADDR, /* Position physique */
- RTT_VIRT_ADDR_PAD, /* Adresse virtuelle (début) */
- RTT_VIRT_ADDR, /* Adresse virtuelle */
- RTT_RAW_CODE, /* Code binaire brut */
- RTT_RAW_CODE_NULL, /* Code binaire brut et nul */
-
- RTT_LABEL, /* Etiquette sur une adresse */
-
- RTT_INSTRUCTION, /* Code binaire brut */
-
- RTT_IMMEDIATE, /* Valeur immédiate */
-
- RTT_REGISTER, /* Registre */
-
- RTT_PUNCT, /* Signes de ponctuation */
- RTT_HOOK, /* Crochets '[' et ']' */
- RTT_SIGNS, /* Signes '+', '-' et '*' */
- RTT_LTGT, /* Caractères '<' et '>' */
-
- RTT_SECTION, /* Identifiant de section */
- RTT_SEGMENT, /* Indication de segment */
- RTT_STRING, /* Chaîne de caractères avec " */
-
- RTT_VAR_NAME, /* Nom de variable */
-
- RTT_KEY_WORD, /* Mot clef de langage */
-
- RTT_ERROR, /* Erreur "interne" */
-
- RTT_COUNT
-
-} RenderingTagType;
-
/* Crée un nouveau fragment de texte avec des propriétés. */
line_segment *get_new_line_segment(RenderingTagType, const char *, size_t);
diff --git a/src/glibext/tokenstyle-int.h b/src/glibext/tokenstyle-int.h
new file mode 100644
index 0000000..9cf4df2
--- /dev/null
+++ b/src/glibext/tokenstyle-int.h
@@ -0,0 +1,94 @@
+
+/* Chrysalide - Outil d'analyse de fichiers binaires
+ * tokenstyle-int.h - définitions internes propres à la centralisation des paramètres de rendu de bribes textuelles
+ *
+ * Copyright (C) 2024 Cyrille Bagard
+ *
+ * This file is part of Chrysalide.
+ *
+ * Chrysalide is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Chrysalide is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Chrysalide. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_TOKENSTYLE_INT_H
+#define _GLIBEXT_TOKENSTYLE_INT_H
+
+
+#include "tokenstyle.h"
+
+
+#include <stdbool.h>
+
+
+
+/* Valeurs principales par défaut */
+
+#define DEFAULT_FONT_FAMILY "cairo:monospace"
+#define DEFAULT_FONT_SIZE 14
+
+
+/* Condensé de propriétés de 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)
+
+
+/* Restitution d'un élément de thème pour bribe de texte */
+typedef struct _rendering_property_t
+{
+ GdkRGBA foreground; /* Couleur d'impression */
+ GdkRGBA inverted; /* Couleur inversée pour sél. */
+
+ cairo_font_slant_t slant; /* Style d'impression */
+ cairo_font_weight_t weight; /* Poids de la police */
+
+} rendering_property_t;
+
+
+/* Centralisation de paramètres de rendu (instance) */
+struct _GTokenStyle
+{
+ GObject parent; /* A laisser en premier */
+
+ GtkWidget *target; /* Composant ciblé */
+
+ bool loaded; /* Validité des paramètres */
+
+ char *font_family; /* Désignation de la police */
+ int font_size; /* Taille de police choisie */
+ cairo_font_extents_t font_extents; /* Dimensions de la police */
+
+ double x_advances[CAIRO_FONTS_COUNT]; /* Largeurs par caractère */
+
+ rendering_property_t properties[TRT_COUNT]; /* Modèles d'impression */
+
+};
+
+/* Centralisation de paramètres de rendu (classe) */
+struct _GTokenStyleClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Met en place un nouveau gestionnaire de rendu des lignes. */
+bool g_token_style_create(GTokenStyle *, GtkWidget *);
+
+
+
+#endif /* _GLIBEXT_TOKENSTYLE_INT_H */
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;
+
+}
diff --git a/src/glibext/tokenstyle.css b/src/glibext/tokenstyle.css
new file mode 100644
index 0000000..0cf9f37
--- /dev/null
+++ b/src/glibext/tokenstyle.css
@@ -0,0 +1,26 @@
+
+.token-generic {
+
+ font-family: Cousine;
+
+}
+
+
+
+
+.token-raw-full {
+
+ color: white;
+
+ font-style: italic;
+ font-weight: bold;
+
+}
+
+.token-raw-null {
+
+ color: black;
+
+ background-color: pink;
+
+}
diff --git a/src/glibext/tokenstyle.h b/src/glibext/tokenstyle.h
index 9adfe1a..923b725 100644
--- a/src/glibext/tokenstyle.h
+++ b/src/glibext/tokenstyle.h
@@ -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.h - prototypes pour la 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,44 +22,86 @@
*/
-#ifndef _GTKEXT_RENDERING_H
-#define _GTKEXT_RENDERING_H
+#ifndef _GLIBEXT_TOKENSTYLE_H
+#define _GLIBEXT_TOKENSTYLE_H
-#include <stdbool.h>
-#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include "helpers.h"
-/* Restitution d'une couleur */
-typedef struct _rendering_color_t
-{
- GdkRGBA color; /* Couleur de rendu */
- bool has_color; /* Définition en place ? */
-} rendering_color_t;
-/* Restitution d'un élément de thème */
-typedef struct _rendering_pattern_t
+/* Types de partie de rendu */
+typedef enum _TokenRenderingTag
{
- rendering_color_t foreground; /* Couleur d'impression */
- rendering_color_t inverted; /* Couleur inversée pour sél. */
+ TRT_NONE, /* Espace ou tabulation */
+
+ TRT_RAW, /* Contenu brut */
+ TRT_RAW_FULL, /* Contenu brut et complet */
+ TRT_RAW_NULL, /* Contenu brut et nul */
+ TRT_PRINTABLE, /* Caractère imprimable */
+ TRT_NOT_PRINTABLE, /* Caractère non imprimable */
+
+ TRT_COMMENT, /* Commentaire */
+ TRT_INDICATION, /* Aide à la lecture */
+
+ TRT_PHYS_ADDR_PAD, /* Position physique (début) */
+ TRT_PHYS_ADDR, /* Position physique */
+ TRT_VIRT_ADDR_PAD, /* Adresse virtuelle (début) */
+ TRT_VIRT_ADDR, /* Adresse virtuelle */
+ TRT_RAW_CODE, /* Code binaire brut */
+ TRT_RAW_CODE_NULL, /* Code binaire brut et nul */
+
+ TRT_LABEL, /* Etiquette sur une adresse */
+
+ TRT_INSTRUCTION, /* Code binaire brut */
+
+ TRT_IMMEDIATE, /* Valeur immédiate */
+
+ TRT_REGISTER, /* Registre */
+
+ TRT_PUNCT, /* Signes de ponctuation */
+ TRT_HOOK, /* Crochets '[' et ']' */
+ TRT_SIGNS, /* Signes '+', '-' et '*' */
+ TRT_LTGT, /* Caractères '<' et '>' */
+
+ TRT_SECTION, /* Identifiant de section */
+ TRT_SEGMENT, /* Indication de segment */
+ TRT_STRING, /* Chaîne de caractères avec " */
+
+ TRT_VAR_NAME, /* Nom de variable */
+
+ TRT_KEY_WORD, /* Mot clef de langage */
+
+ TRT_ERROR, /* Erreur "interne" */
+
+ TRT_COUNT
+
+} TokenRenderingTag;
+
+
+#define G_TYPE_TOKEN_STYLE (g_token_style_get_type())
+
+DECLARE_GTYPE(GTokenStyle, g_token_style, G, TOKEN_STYLE);
- cairo_font_slant_t slant; /* Style d'impression */
- cairo_font_weight_t weight; /* Poids de la police */
-} rendering_pattern_t;
+/* Crée un gestionnaire de style pour le rendu des lignes. */
+GTokenStyle *g_token_style_new(GtkWidget *);
+/* Fournit la quantité de pixels requise pour l'impression. */
+int g_token_style_measure_width(const GTokenStyle *, TokenRenderingTag, size_t);
-/* Récupère les informations de rendus d'un élément de thème. */
-void load_rendering_pattern(const char *, rendering_pattern_t *);
+/* Imprime le fragment de texte transmis. */
+void g_token_style_draw_text(const GTokenStyle *, TokenRenderingTag, cairo_t *, int *, int, const char *, size_t);
/* Enjolive du texte selon les paramètres d'un élément de thème. */
-char *build_pango_markup_for(const char *, const rendering_pattern_t *);
+char *g_token_style_build_markup(const GTokenStyle *, TokenRenderingTag, const char *);
/* Ajoute du texte enjolivé selon un élément de thème. */
-char *append_pango_markup_with(char *, const char *, const rendering_pattern_t *);
+char *g_token_style_append_markup(const GTokenStyle *, char *, TokenRenderingTag, const char *);
-#endif /* _GTKEXT_RENDERING_H */
+#endif /* _GLIBEXT_TOKENSTYLE_H */