From 16d37d997b84c75c1f9b877fe446b3b3e5ce2495 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Wed, 10 Dec 2014 13:41:00 +0000
Subject: Loaded major segment properties for an external GTK3 theme and
 defined some new rendering categories.

git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@440 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
---
 ChangeLog                    |  16 ++++
 src/glibext/gbufferline.c    |  39 ++++++--
 src/glibext/gbuffersegment.c | 208 ++++++++++++++++++++++++++++---------------
 src/glibext/gbuffersegment.h |   5 ++
 src/gtkext/theme.c           |   7 +-
 themes/segments.css          | 189 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 382 insertions(+), 82 deletions(-)
 create mode 100644 themes/segments.css

diff --git a/ChangeLog b/ChangeLog
index 11b825a..0fa2ff3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 14-12-10  Cyrille Bagard <nocbos@gmail.com>
 
+	* src/glibext/gbufferline.c:
+	Improve the rendering of physical and virtual addresses.
+
+	* src/glibext/gbuffersegment.c:
+	* src/glibext/gbuffersegment.h:
+	Load major segment properties for an external GTK3 theme and define some
+	new rendering categories.
+
+	* src/gtkext/theme.c:
+	Load an extra theme file called 'segments.css'.
+
+	* themes/segments.css:
+	New entry: define a GTK3 theme for buffer segments.
+
+14-12-10  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/arch/arm/v7/opcodes/opcodes_tmp_arm.h:
 	Update missing prototypes.
 
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index a71ef9d..cd85cf4 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -484,14 +484,41 @@ void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDa
 {
     size_t len;                             /* Taille de l'élément inséré  */
     VMPA_BUFFER(address);                   /* Adresse au format texte     */
+    size_t i;                               /* Boucle de parcours          */
 
-    /* Adresse physique puis virtuelle */
+    /* Position physique */
 
     mrange_phys_to_string(&line->range, psize, true, address, &len);
-    g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_RAW);
+
+    for (i = 2; i < len; i++)
+        if (address[i] != '0') break;
+
+    if (i == len)
+        g_buffer_line_insert_text(line, BLC_PHYSICAL, address, len, RTT_PHYS_ADDR_PAD);
+
+    else
+    {
+        g_buffer_line_insert_text(line, BLC_PHYSICAL, address, 2, RTT_PHYS_ADDR);
+        g_buffer_line_insert_text(line, BLC_PHYSICAL, &address[2], i - 2, RTT_PHYS_ADDR_PAD);
+        g_buffer_line_insert_text(line, BLC_PHYSICAL, &address[i], len - i, RTT_PHYS_ADDR);
+    }
+
+    /* Adresse virtuelle */
 
     mrange_virt_to_string(&line->range, vsize, true, address, &len);
-    g_buffer_line_insert_text(line, BLC_VIRTUAL, address, len, RTT_RAW);
+
+    for (i = 2; i < len; i++)
+        if (address[i] != '0') break;
+
+    if (i == len)
+        g_buffer_line_insert_text(line, BLC_VIRTUAL, address, len, RTT_VIRT_ADDR_PAD);
+
+    else
+    {
+        g_buffer_line_insert_text(line, BLC_VIRTUAL, address, 2, RTT_VIRT_ADDR);
+        g_buffer_line_insert_text(line, BLC_VIRTUAL, &address[2], i - 2, RTT_VIRT_ADDR_PAD);
+        g_buffer_line_insert_text(line, BLC_VIRTUAL, &address[i], len - i, RTT_VIRT_ADDR);
+    }
 
 }
 
@@ -906,6 +933,9 @@ void g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn column, const
 {
     GBufferSegment *segment;                /* Portion de texte à ajouter  */
 
+    if (length == 0)
+        return;
+
     if (column == BLC_MAIN)
         column = line->main_column;
 
@@ -914,9 +944,6 @@ void g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn column, const
     else
         line->last_used = column;
 
-    if (length == 0)
-        return;
-
     segment = g_buffer_segment_new(type, text, length);
     g_buffer_line_add_segment(line, column, segment);
 
diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c
index 0c31b9c..1e1a9b9 100644
--- a/src/glibext/gbuffersegment.c
+++ b/src/glibext/gbuffersegment.c
@@ -35,20 +35,54 @@
 
 
 
-/* Utilisation du champ pixel des couleurs cachées */
-#define COLOR_NOT_SET   0
-#define COLOR_SET       1
-
 /* Propriétés de rendu */
+
+typedef struct _rendering_color_t
+{
+    GdkRGBA color;                          /* Couleur de rendu            */
+    bool has_color;                         /* Définition en place ?       */
+
+} rendering_color_t;
+
 typedef struct _rendering_pattern_t
 {
-    GdkColor foreground;                    /* Couleur d'impression        */
+    rendering_color_t foreground;           /* Couleur d'impression        */
 
     cairo_font_slant_t slant;               /* Style d'impression          */
     cairo_font_weight_t weight;             /* Poids de la police          */
 
 } rendering_pattern_t;
 
+/* Nom des éléments CSS */
+
+#define SEGMENT_NAME(s) "segment-" s
+
+static const char *_segment_names[RTT_COUNT] = {
+
+    [RTT_RAW]           = SEGMENT_NAME("raw"),
+    [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_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"),
+
+};
+
 /* Compléments à Cairo */
 
 #define CAIRO_FONT_SLANT_COUNT  3
@@ -69,9 +103,9 @@ struct _GBufferSegment
 
     SegRenderingStyle style;                /* Apparence du segment        */
 
-    GdkColor cache_bg;                      /* Fond d'impression           */
-    GdkColor alt_fg;                        /* Couleur d'impression bis    */
-    GdkColor *used_fg;                      /* Couleur d'impression utile  */
+    rendering_color_t cache_bg;             /* Fond d'impression           */
+    rendering_color_t alt_fg;               /* Couleur d'impression bis    */
+    const rendering_color_t *used_fg;       /* Couleur d'impression utile  */
 
     gint x_advance;                         /* Dimensions du texte         */
 
@@ -118,12 +152,24 @@ G_DEFINE_TYPE(GBufferSegment, g_buffer_segment, G_TYPE_OBJECT);
 
 static void g_buffer_segment_class_init(GBufferSegmentClass *class)
 {
+    GtkStyleContext *context;               /* Contexte pour les styles    */
+    GtkWidgetPath *path;                    /* Chemin d'accès aux thèmes   */
     gchar *filename;                        /* Accès à une image 1x1       */
     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          */
+
+    /* Création d'un contexte d'accès */
+
+    path = gtk_widget_path_new();
+    gtk_widget_path_append_type(path, G_TYPE_OBJECT);
+
+    context = gtk_style_context_new();
+    gtk_style_context_set_path(context, path);
+    gtk_style_context_set_screen(context, gdk_screen_get_default());
 
     /* Contextes pour les mesures initiales */
 
@@ -149,58 +195,70 @@ static void g_buffer_segment_class_init(GBufferSegmentClass *class)
 
     g_free(filename);
 
-    /* Propriétés d'impression */
-
-#define GET_RESET_PATTERN(tp)                           \
-    ({                                                  \
-        rendering_pattern_t *__p;                       \
-        __p = &class->patterns[RTT_ ## tp];             \
-        memset(__p, 0, sizeof(rendering_pattern_t));    \
-        __p;                                            \
-    })
-
-#define DEFINE_SIMPLE_PATTERN(rtt)                      \
-    do                                                  \
-    {                                                   \
-        rendering_pattern_t *__ptn;                     \
-        __ptn = GET_RESET_PATTERN(rtt);                 \
-        __ptn->slant = CAIRO_FONT_SLANT_NORMAL;         \
-        __ptn->weight = CAIRO_FONT_WEIGHT_NORMAL;       \
-        __ptn->foreground.pixel = COLOR_NOT_SET;        \
-    }                                                   \
-    while (0)
-
-#define DEFINE_PATTERN(rtt, s, w, r, g, b)              \
-    do                                                  \
-    {                                                   \
-        rendering_pattern_t *__ptn;                     \
-        __ptn = GET_RESET_PATTERN(rtt);                 \
-        __ptn->slant = CAIRO_FONT_SLANT_ ## s;          \
-        __ptn->weight = CAIRO_FONT_WEIGHT_ ## w;        \
-        __ptn->foreground.red = r;                      \
-        __ptn->foreground.green = g;                    \
-        __ptn->foreground.blue = b;                     \
-        __ptn->foreground.pixel = COLOR_SET;            \
-    }                                                   \
-    while (0)
-
-    DEFINE_PATTERN(RAW,         NORMAL, NORMAL, 0, 0, 0);
-    DEFINE_PATTERN(COMMENT,     NORMAL, NORMAL, 14335, 45311, 23551);
-    DEFINE_PATTERN(INDICATION,  ITALIC, NORMAL, 33410, 33410, 33410);
-    DEFINE_PATTERN(RAW_CODE,    NORMAL, NORMAL, 48895, 48895, 48895);
-    DEFINE_PATTERN(INSTRUCTION, NORMAL, NORMAL, 0, 0, 0);
-    DEFINE_PATTERN(IMMEDIATE,   NORMAL, NORMAL, 41215, 8447, 61695);
-    DEFINE_PATTERN(REGISTER,    NORMAL, NORMAL, 16895, 16895, 53759);
-    DEFINE_PATTERN(PUNCT,       NORMAL, BOLD,   0, 0, 0);
-    DEFINE_PATTERN(HOOK,        NORMAL, BOLD,   0, 0, 0);
-    DEFINE_PATTERN(SIGNS,       NORMAL, BOLD,   0, 0, 0);
-    DEFINE_SIMPLE_PATTERN(LTGT);
-    DEFINE_PATTERN(SECTION,     NORMAL, NORMAL, 51200, 2560, 2560);
-    DEFINE_SIMPLE_PATTERN(SEGMENT);
-    DEFINE_PATTERN(STRING,      NORMAL, NORMAL, 52224, 32256, 0);
-    DEFINE_PATTERN(VAR_NAME,    NORMAL, NORMAL, 0, 0, 0);
-    DEFINE_PATTERN(KEY_WORD,    NORMAL, NORMAL, 0, 0, 0);
-    DEFINE_PATTERN(ERROR,       NORMAL, BOLD,   65535, 0, 0);
+    /* Chargement des définitions utiles */
+
+    void define_rendering_pattern(GtkStyleContext *ctx, const char *name, rendering_pattern_t *pattern)
+    {
+        GdkRGBA *tmp_color;
+        PangoFontDescription *font_desc;    /* Description d'une police    */
+
+        gtk_style_context_save(ctx);
+
+        gtk_style_context_add_class(context, name);
+
+        gtk_style_context_get(ctx, GTK_STATE_NORMAL, GTK_STYLE_PROPERTY_COLOR, &tmp_color, NULL);
+        pattern->foreground.has_color = true;
+        pattern->foreground.color = *tmp_color;
+        gdk_rgba_free(tmp_color);
+
+        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_OBLIQUE:
+                pattern->slant = CAIRO_FONT_SLANT_ITALIC;
+                break;
+            case PANGO_STYLE_ITALIC:
+                pattern->slant = CAIRO_FONT_SLANT_OBLIQUE;
+                break;
+        }
+
+        switch (pango_font_description_get_weight(font_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:
+                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;
+        }
+
+        pango_font_description_free(font_desc);
+
+        gtk_style_context_restore(context);
+
+    }
+
+    for (i = 0; i < RTT_COUNT; i++)
+        define_rendering_pattern(context, _segment_names[i], &class->patterns[i]);
+
+    /* Nettoyages finaux... */
+
+    gtk_widget_path_free(path);
+    g_object_unref(context);
 
 }
 
@@ -289,10 +347,10 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, size_t length)
 
     /* Couleurs */
 
-    segment->alt_fg.red = 65535 - segment->pattern->foreground.red;
-    segment->alt_fg.green = 65535 - segment->pattern->foreground.green;
-    segment->alt_fg.blue = 65535 - segment->pattern->foreground.blue;
-    segment->alt_fg.pixel = segment->pattern->foreground.pixel;
+    segment->alt_fg.color.red = 1.0 - segment->pattern->foreground.color.red;
+    segment->alt_fg.color.green = 1.0 - segment->pattern->foreground.color.green;
+    segment->alt_fg.color.blue = 1.0 - segment->pattern->foreground.color.blue;
+    segment->alt_fg.has_color = segment->pattern->foreground.has_color;
 
 }
 
@@ -493,9 +551,9 @@ void g_buffer_segment_set_style(GBufferSegment *segment, SegRenderingStyle style
 
         case SRS_HIGHLIGHT_SAME:
 
-            segment->cache_bg.red = 32768;
-            segment->cache_bg.green = 32768;
-            segment->cache_bg.blue = 32768;
+            segment->cache_bg.color.red = 0.5;
+            segment->cache_bg.color.green = 0.5;
+            segment->cache_bg.color.blue = 0.5;
 
             segment->used_fg = &segment->alt_fg;
 
@@ -532,9 +590,9 @@ void g_buffer_segment_draw(GBufferSegment *segment, cairo_t *cairo, gint *x, gin
     if (segment->style != SRS_CLASSIC)
     {
         cairo_set_source_rgb(cairo,
-                             segment->cache_bg.red / 65535.0,
-                             segment->cache_bg.green / 65535.0,
-                             segment->cache_bg.blue / 65535.0);
+                             segment->cache_bg.color.red,
+                             segment->cache_bg.color.green,
+                             segment->cache_bg.color.blue);
 
         cairo_rectangle(cairo, *x, y, segment->x_advance, 17);
 
@@ -546,11 +604,13 @@ void g_buffer_segment_draw(GBufferSegment *segment, cairo_t *cairo, gint *x, gin
 
     /* Couleur d'impression */
 
-    if (segment->used_fg->pixel == COLOR_SET)
+    if (segment->used_fg->has_color)
         cairo_set_source_rgb(cairo,
-                             segment->used_fg->red / 65535.0,
-                             segment->used_fg->green / 65535.0,
-                             segment->used_fg->blue / 65535.0);
+                             segment->used_fg->color.red,
+                             segment->used_fg->color.green,
+                             segment->used_fg->color.blue);
+    else
+        cairo_set_source_rgb(cairo, 0, 0, 0);
 
     /* Impression du texte */
 
diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h
index bb82bba..2dd0b6d 100644
--- a/src/glibext/gbuffersegment.h
+++ b/src/glibext/gbuffersegment.h
@@ -47,6 +47,11 @@ typedef enum _RenderingTagType
 
     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_INSTRUCTION,                        /* Code binaire brut           */
diff --git a/src/gtkext/theme.c b/src/gtkext/theme.c
index 493692a..41e0b4a 100644
--- a/src/gtkext/theme.c
+++ b/src/gtkext/theme.c
@@ -54,19 +54,19 @@ static const char *_themes_directories[] = {
 bool load_extra_gtk_theme(void)
 {
     GdkScreen *screen;                      /* Ecran(s) concerné(s)        */
-    GtkCssProvider *provider;               /* Fournisseur par défaut      */
     const char **iter_f;                    /* Boucle de parcours #1       */
     bool done;                              /* Traitement d'un fichier     */
     const char **iter_d;                    /* Boucle de parcours #2       */
     gchar *filename;                        /* Chemin d'accès constitué    */
+    GtkCssProvider *provider;               /* Nouveau fournisseur CSS     */
 
     static const char *css_files[] = {
         "portions.css",
+        "segments.css",
         NULL
     };
 
     screen = gdk_screen_get_default();
-    provider = gtk_css_provider_get_default();
 
     done = true;
 
@@ -80,12 +80,15 @@ bool load_extra_gtk_theme(void)
 
             if (g_file_test(filename, G_FILE_TEST_EXISTS))
             {
+                provider = gtk_css_provider_new();
                 done = gtk_css_provider_load_from_path(provider, filename, NULL);
 
                 if (done)
                     gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider),
                                                               GTK_STYLE_PROVIDER_PRIORITY_USER);
 
+                g_object_unref(G_OBJECT(provider));
+
             }
 
             g_free(filename);
diff --git a/themes/segments.css b/themes/segments.css
new file mode 100644
index 0000000..daeac45
--- /dev/null
+++ b/themes/segments.css
@@ -0,0 +1,189 @@
+
+.segment-raw {
+
+    color: #000;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-comment {
+
+    color: #37b05b;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-indication {
+
+    color: #828282;
+
+    font-style: italic;
+    font-weight: normal;
+    
+}
+
+.segment-phys-addr-padding {
+
+    color: darker(#7c7c7b);
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-phys-addr {
+
+    color: #7c7c7b;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-virt-addr-padding {
+
+    color: darker(#7c7c7b);
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-virt-addr {
+
+    color: #7c7c7b;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-raw-code {
+
+    color: #000;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-instruction {
+
+    color: #bebebe;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-immediate {
+
+    color: #a020f0;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-register {
+
+    color: #4141d1;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-punct {
+
+    color: #000;
+
+    font-style: normal;
+    font-weight: bold;
+
+}
+
+.segment-hooks {
+
+    color: #000;
+
+    font-style: normal;
+    font-weight: bold;
+
+}
+
+.segment-signs {
+
+    color: #000;
+
+    font-style: normal;
+    font-weight: bold;
+
+}
+
+.segment-ltgt {
+
+    color: #000;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-section {
+
+    color: #c80a0a;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-segment {
+
+    color: #000;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-string {
+
+    color: #cc7e00;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-var-name {
+
+    color: #000;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-keyword {
+
+    color: #000;
+
+    font-style: normal;
+    font-weight: normal;
+
+}
+
+.segment-error {
+
+    color: #ff0000;
+
+    font-style: normal;
+    font-weight: bold;
+
+}
-- 
cgit v0.11.2-87-g4458