summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2012-12-09 23:22:46 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2012-12-09 23:22:46 (GMT)
commit42420cfa1f406a5f0a9f062b258ece72098635b5 (patch)
tree0e497bc16a971a91b842340e9942d3f28eedddd5
parent4dd8356e19b9e58990b2f3e0c4110aa2fe9642d1 (diff)
Used Cairo for rendering text and tried to deal properly with Pango context / fonts.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@298 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
-rw-r--r--ChangeLog22
-rw-r--r--src/glibext/Makefile.am1
-rw-r--r--src/glibext/gbufferline.c51
-rw-r--r--src/glibext/gbufferline.h2
-rw-r--r--src/glibext/gbuffersegment.c85
-rw-r--r--src/glibext/gbuffersegment.h7
-rw-r--r--src/glibext/gcodebuffer.c17
-rw-r--r--src/glibext/gfontcache.c294
-rw-r--r--src/glibext/gfontcache.h79
-rw-r--r--src/main.c4
10 files changed, 491 insertions, 71 deletions
diff --git a/ChangeLog b/ChangeLog
index 95b54c0..6733926 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+12-12-10 Cyrille Bagard <nocbos@gmail.com>
+
+ * src/glibext/gbufferline.c:
+ * src/glibext/gbufferline.h:
+ * src/glibext/gbuffersegment.c:
+ * src/glibext/gbuffersegment.h:
+ * src/glibext/gcodebuffer.c:
+ Use Cairo for rendering text. Try to avoid a bug when dealing with
+ fonts / Pango context ; still need to be properly fixed. Avoid a memory
+ leak for the PangoContext singleton used in the program.
+
+ * src/glibext/gfontcache.c:
+ * src/glibext/gfontcache.h:
+ New entries: try to centralize all the things needing for text
+ rendering here ; still need to be digged / improved...
+
+ * src/glibext/Makefile.am:
+ Add the 'gfontcache.[ch]' files to libglibext_la_SOURCES.
+
+ * src/main.c:
+ Create and delete the PangoContext singleton used in the program.
+
12-12-08 Cyrille Bagard <nocbos@gmail.com>
* configure.ac:
diff --git a/src/glibext/Makefile.am b/src/glibext/Makefile.am
index 2365190..d5235c8 100644
--- a/src/glibext/Makefile.am
+++ b/src/glibext/Makefile.am
@@ -7,6 +7,7 @@ libglibext_la_SOURCES = \
gbufferline.h gbufferline.c \
gbuffersegment.h gbuffersegment.c \
gcodebuffer.h gcodebuffer.c \
+ gfontcache.h gfontcache.c \
gnhash.h gnhash.c \
proto.h
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index cef34ef..562aded 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -67,7 +67,7 @@ static GBufferSegment *get_segment_at(const buffer_line_column *, gint);
GSList *highlight_all_same_segments(const buffer_line_column *, GSList *, const GBufferSegment *);
/* Imprime le contenu d'une colonne de ligne de texte. */
-static void draw_segments_of_column(buffer_line_column *, GdkDrawable *, GdkGC *, gint, gint);
+static void draw_segments_of_column(buffer_line_column *, cairo_t *, GFontCache *, gint, gint);
@@ -94,7 +94,6 @@ struct _GBufferLineClass
{
GObjectClass parent; /* A laisser en premier */
- PangoContext *context; /* Contexte graphique Pango */
PangoAttrList *attribs[RTT_COUNT]; /* Décorateurs pour tampons */
};
@@ -264,11 +263,11 @@ GSList *highlight_all_same_segments(const buffer_line_column *column, GSList *li
/******************************************************************************
* *
-* Paramètres : column = colonne de ligne de texte à manipuler. *
-* drawable = surface de rendu où travailler. *
-* gc = contexte graphique à utiliser pour les pinceaux. *
-* x_init = abscisse du point d'impression de départ. *
-* y = ordonnée du point d'impression. *
+* Paramètres : column = colonne de ligne de texte à manipuler. *
+* cairo = contexte graphique à utiliser pour les pinceaux. *
+* fcache = gestionnaire des polices pour l'impression. *
+* x_init = abscisse du point d'impression de départ. *
+* y = ordonnée du point d'impression. *
* *
* Description : Imprime le contenu d'une colonne de ligne de texte. *
* *
@@ -278,7 +277,7 @@ GSList *highlight_all_same_segments(const buffer_line_column *column, GSList *li
* *
******************************************************************************/
-static void draw_segments_of_column(buffer_line_column *column, GdkDrawable *drawable, GdkGC *gc, gint x_init, gint y)
+static void draw_segments_of_column(buffer_line_column *column, cairo_t *cairo, GFontCache *fcache, gint x_init, gint y)
{
gint x;
size_t i;
@@ -286,7 +285,7 @@ static void draw_segments_of_column(buffer_line_column *column, GdkDrawable *dra
x = x_init;
for (i = 0; i < column->count; i++)
- g_buffer_segment_draw(column->segments[i], drawable, gc, &x, y);
+ g_buffer_segment_draw(column->segments[i], cairo, fcache, &x, y);
}
@@ -316,21 +315,8 @@ G_DEFINE_TYPE(GBufferLine, g_buffer_line, G_TYPE_OBJECT);
static void g_buffer_line_class_init(GBufferLineClass *class)
{
- GdkScreen *screen; /* Ecran pour GDK */
- PangoFontDescription *font_desc; /* Police de caractère */
PangoAttribute *attrib; /* Propriété de rendu */
- /* Base des exportations */
-
- screen = gdk_screen_get_default();
- class->context = gdk_pango_context_get_for_screen(screen);
-
- font_desc = pango_font_description_from_string("mono 10");
- pango_context_set_font_description(class->context, font_desc);
-
- pango_context_set_base_dir(class->context, PANGO_DIRECTION_LTR);
- pango_context_set_language(class->context, gtk_get_default_language());
-
/* RTT_RAW */
class->attribs[RTT_RAW] = pango_attr_list_new();
@@ -641,14 +627,17 @@ void g_buffer_line_insert_text(GBufferLine *line, BufferLineColumn column, const
GBufferLineClass *class; /* Stockage de briques de base */
GBufferSegment *segment; /* Portion de texte à ajouter */
- class = G_BUFFER_LINE_GET_CLASS(line);
-
if (column == BLC_LAST_USED)
column = line->last_used;
else
line->last_used = column;
- segment = g_buffer_segment_new(class->context, class->attribs[type], text, length);
+ if (length == 0)
+ return;
+
+ class = G_BUFFER_LINE_GET_CLASS(line);
+
+ segment = g_buffer_segment_new(class->attribs[type], text, length);
g_buffer_line_add_segment(line, column, segment);
}
@@ -756,13 +745,13 @@ void g_buffer_line_start_merge_at(GBufferLine *line, BufferLineColumn start)
/******************************************************************************
* *
* Paramètres : line = ligne de texte à manipuler. *
-* drawable = surface de rendu où travailler. *
-* gc = contexte graphique à utiliser pour les pinceaux.*
+* cairo = contexte graphique à utiliser pour les pinceaux.*
+* fcache = gestionnaire des polices pour l'impression. *
* max_widths = largeurs de colonne à respecter. *
* x_init = abscisse du point d'impression de départ. *
* y = ordonnée du point d'impression. *
-* addr = indique si les positions doivent être affichées. *
-* code = indique si le code binaire doit être affiché. *
+* addr = indique si les positions doivent être affichées.*
+* code = indique si le code binaire doit être affiché. *
* *
* Description : Imprime la ligne de texte représentée. *
* *
@@ -772,7 +761,7 @@ void g_buffer_line_start_merge_at(GBufferLine *line, BufferLineColumn start)
* *
******************************************************************************/
-void g_buffer_line_draw(GBufferLine *line, GdkDrawable *drawable, GdkGC *gc, const gint max_widths[BLC_COUNT], gint x_init, gint y, bool addr, bool code)
+void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, GFontCache *fcache, const gint max_widths[BLC_COUNT], gint x_init, gint y, bool addr, bool code)
{
gint x; /* Point de départ d'impression*/
BufferLineColumn i; /* Boucle de parcours */
@@ -784,7 +773,7 @@ void g_buffer_line_draw(GBufferLine *line, GdkDrawable *drawable, GdkGC *gc, con
if (i == BLC_ADDRESS && !addr) continue;
if (i == BLC_BINARY && !code) continue;
- draw_segments_of_column(&line->columns[i], drawable, gc, x, y);
+ draw_segments_of_column(&line->columns[i], cairo, fcache, x, y);
if (i < line->merge_start)
x += max_widths[i] + COL_MARGIN;
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index f1be296..028ae8e 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -149,7 +149,7 @@ gint g_buffer_line_get_width(GBufferLine *, BufferLineColumn);
void g_buffer_line_start_merge_at(GBufferLine *, BufferLineColumn);
/* Imprime la ligne de texte représentée. */
-void g_buffer_line_draw(GBufferLine *, GdkDrawable *, GdkGC *, const gint [BLC_COUNT], gint, gint, bool, bool);
+void g_buffer_line_draw(GBufferLine *, cairo_t *, GFontCache *, const gint [BLC_COUNT], gint, gint, bool, bool);
/* Exporte la ligne de texte représentée. */
void g_buffer_line_export(GBufferLine *, int, BufferExportType, bool, bool, bool);
diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c
index 9510fa2..861c7cb 100644
--- a/src/glibext/gbuffersegment.c
+++ b/src/glibext/gbuffersegment.c
@@ -55,7 +55,7 @@ struct _GBufferSegment
GdkColor *cache_used_fg; /* Couleur d'impression utile */
PangoGlyphString *glyphs; /* Caractères traités */
- PangoFont *font; /* Police utilisée à l'analyse */
+ PangoFontDescription *desc; /* Description de police */
PangoRectangle logical; /* Dimension du texte */
@@ -127,7 +127,7 @@ static bool ascii_glyph_table_init(GBufferSegmentClass *class, PangoContext *con
if (class->ascii_ready)
{
PangoItem *item;
- int width;
+ //int width;
item = (PangoItem *)list->data;
//width = gui.char_width * PANGO_SCALE;
@@ -159,10 +159,10 @@ static bool ascii_glyph_table_init(GBufferSegmentClass *class, PangoContext *con
}
- g_list_foreach(list, (GFunc)&pango_item_free, NULL);
- g_list_free(list);
+ //g_list_foreach(list, (GFunc)&pango_item_free, NULL);
+ //g_list_free(list);
- pango_attr_list_unref(attribs);
+ //pango_attr_list_unref(attribs);
}
@@ -201,11 +201,11 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *cont
GList *item_list;
PangoItem *item;
- PangoRectangle logical;
+ //PangoRectangle logical;
- char *max;
- char *iter;
+ const char *max;
+ const char *iter;
GBufferSegmentClass *class;
@@ -215,6 +215,12 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *cont
gint *log_clusters;
PangoGlyphInfo *ref;
+ PangoFont *font; /* Modèle de police */
+ PangoFontDescription *desc; /* Description de cette police */
+
+
+
+
glyphs = pango_glyph_string_new();
@@ -255,6 +261,8 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *cont
max = text + length;
+ goto not_ascii;
+
for (iter = text; iter < max; iter++)
if (*iter & 0x80)
goto not_ascii;
@@ -272,13 +280,11 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *cont
for (i = 0; i < length; i++)
{
- info[i] = ref[text[i]];
+ info[i] = ref[(unsigned int)text[i]];
log_clusters[i] = i;
}
- segment->font = class->ascii_font;
-
- pango_glyph_string_extents(glyphs, class->ascii_font, NULL, &segment->logical);
+ font = class->ascii_font;
goto next;
@@ -294,13 +300,14 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *cont
item = (PangoItem *)item_list->data;
pango_shape(text, length, &item->analysis, glyphs);
- segment->font = item->analysis.font;/* TODO : ref ! */
-
- pango_glyph_string_extents(glyphs, item->analysis.font, NULL, &segment->logical);
-
+ font = item->analysis.font;
next:
+ desc = pango_font_describe(font);
+ segment->desc = pango_font_description_copy(desc);
+
+ pango_glyph_string_extents(glyphs, font, NULL, &segment->logical);
//pango_shape(text, length, &item->analysis, glyphs);
@@ -371,8 +378,7 @@ static void g_buffer_segment_init(GBufferSegment *segment)
/******************************************************************************
* *
-* Paramètres : context = contexte Pango pour l'analyse des caractères. *
-* attribs = propriétés de la zone de texte. *
+* Paramètres : attribs = propriétés de la zone de texte. *
* text = chaîne de caractères à traiter. *
* length = quantité de ces caractères. *
* *
@@ -384,19 +390,18 @@ static void g_buffer_segment_init(GBufferSegment *segment)
* *
******************************************************************************/
-GBufferSegment *g_buffer_segment_new(PangoContext *context, PangoAttrList *attribs, const char *text, size_t length)
+GBufferSegment *g_buffer_segment_new(PangoAttrList *attribs, const char *text, size_t length)
{
GBufferSegment *result; /* Composant à retourner */
result = g_object_new(G_TYPE_BUFFER_SEGMENT, NULL);
- //result = g_new(GBufferSegment, 1);
result->text = strdup(text);
result->hash = fnv_64a_hash(text);
result->attribs = pango_attr_list_ref(attribs);
- g_buffer_segment_prepare(result, context, attribs, text, length);
+ g_buffer_segment_prepare(result, get_global_pango_context(), attribs, text, length);
g_buffer_segment_cache_colors(result);
@@ -556,11 +561,11 @@ void g_buffer_segment_set_style(GBufferSegment *segment, SegRenderingStyle style
/******************************************************************************
* *
-* Paramètres : segment = fragment de texte à manipuler. *
-* drawable = surface de rendu où travailler. *
-* gc = contexte graphique à utiliser pour les pinceaux. *
-* x = abscisse du point d'impression (à maj). [OUT] *
-* y = ordonnée du point d'impression. *
+* Paramètres : segment = fragment de texte à manipuler. *
+* cairo = contexte graphique à utiliser pour les pinceaux. *
+* fcache = gestionnaire des polices pour l'impression. *
+* x = abscisse du point d'impression (à maj). [OUT] *
+* y = ordonnée du point d'impression. *
* *
* Description : Imprime le fragment de texte représenté. *
* *
@@ -570,27 +575,41 @@ void g_buffer_segment_set_style(GBufferSegment *segment, SegRenderingStyle style
* *
******************************************************************************/
-void g_buffer_segment_draw(GBufferSegment *segment, GdkDrawable *drawable, GdkGC *gc, gint *x, gint y)
+void g_buffer_segment_draw(GBufferSegment *segment, cairo_t *cairo, GFontCache *fcache, gint *x, gint y)
{
+ PangoFont *font; /* Police d'impression */
+
+ /* FIXME */
+ g_buffer_segment_prepare(segment, get_global_pango_context(),
+ segment->attribs, segment->text, strlen(segment->text));
+
/* Fond du texte */
if (segment->style != SRS_CLASSIC)
{
- gdk_gc_set_rgb_fg_color(gc, &segment->cache_bg);
+ cairo_set_source_rgb(cairo,
+ segment->cache_bg.red / 65535.0,
+ segment->cache_bg.green / 65535.0,
+ segment->cache_bg.blue / 65535.0);
- gdk_draw_rectangle(drawable, gc, TRUE,
- *x, y, segment->logical.width, segment->logical.height);
+ cairo_rectangle(cairo, *x, y, segment->logical.width, segment->logical.height);
+ cairo_fill(cairo);
}
/* Couleur d'impression */
if (segment->cache_fg.pixel == COLOR_SET)
- gdk_gc_set_rgb_fg_color(gc, segment->cache_used_fg);
+ cairo_set_source_rgb(cairo,
+ segment->cache_used_fg->red / 65535.0,
+ segment->cache_used_fg->green / 65535.0,
+ segment->cache_used_fg->blue / 65535.0);
/* Impression du texte */
- gdk_draw_glyphs(drawable, gc, segment->font,
- *x, y - segment->logical.y, segment->glyphs);
+ cairo_move_to(cairo, *x, y - segment->logical.y);
+
+ font = g_font_cache_lookup(fcache, segment->desc);
+ pango_cairo_show_glyph_string(cairo, font, segment->glyphs);
*x += segment->logical.width;
diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h
index edbf44c..96011bb 100644
--- a/src/glibext/gbuffersegment.h
+++ b/src/glibext/gbuffersegment.h
@@ -31,6 +31,9 @@
#include <pango/pango.h>
+#include "gfontcache.h"
+
+
#define G_TYPE_BUFFER_SEGMENT (g_buffer_segment_get_type())
#define G_BUFFER_SEGMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), G_TYPE_BUFFER_SEGMENT, GBufferSegment))
@@ -72,7 +75,7 @@ typedef struct _GBufferSegmentClass GBufferSegmentClass;
GType g_buffer_segment_get_type(void);
/* Crée un nouveau fragment de texte avec des propriétés. */
-GBufferSegment *g_buffer_segment_new(PangoContext *, PangoAttrList *, const char *, size_t);
+GBufferSegment *g_buffer_segment_new(PangoAttrList *, const char *, size_t);
/* Indique si les textes de deux segments sont identiques. */
bool g_buffer_segment_compare(const GBufferSegment *, const GBufferSegment *);
@@ -90,7 +93,7 @@ void g_buffer_segment_cache_colors(GBufferSegment *);
void g_buffer_segment_set_style(GBufferSegment *, SegRenderingStyle);
/* Imprime le fragment de texte représenté. */
-void g_buffer_segment_draw(GBufferSegment *, GdkDrawable *, GdkGC *, gint *, gint);
+void g_buffer_segment_draw(GBufferSegment *, cairo_t *, GFontCache *, gint *, gint);
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index 4ffc15a..4302f14 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -140,6 +140,8 @@ struct _GBufferView
vmpa_t start; /* Première ligne intégrée */
vmpa_t end; /* Dernière ligne intégrée */
+ GFontCache *fcache; /* Cache pour les polices */
+
gint line_height; /* Hauteur maximale des lignes */
gint max_widths[BLC_COUNT]; /* Taille cachée des colonnes */
gint left_margin; /* Marge gauche + espace */
@@ -709,6 +711,7 @@ static void g_buffer_view_class_init(GBufferViewClass *class)
static void g_buffer_view_init(GBufferView *buffer)
{
+ buffer->fcache = g_font_cache_new();
}
@@ -716,6 +719,7 @@ static void g_buffer_view_init(GBufferView *buffer)
/******************************************************************************
* *
* Paramètres : buffer = tampon à représenter à l'écran. *
+* widget = composant GTK de destination pour le rendu. *
* *
* Description : Crée une nouvelle vue d'un tampon pour code désassemblé. *
* *
@@ -1088,7 +1092,7 @@ void g_buffer_view_define_extra_drawing(GBufferView *view, buffer_line_draw_fc m
void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, GdkGC *gc, gint fake_x, gint fake_y, bool addr, bool code)
{
- GdkDrawable *drawable; /* Surface de dessin */
+ cairo_t *cairo; /* Gestionnaire de rendu */
gint real_x; /* Abscisse réelle pour tampon */
gint real_y; /* Ordonnée réelle pour tampon */
@@ -1102,8 +1106,9 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd
size_t i; /* Boucle de parcours */
- drawable = GDK_DRAWABLE(event->window);
+ cairo = gdk_cairo_create(event->window);
+ gdk_cairo_region(cairo, event->region);
real_x = fake_x + view->left_text;
real_y = fake_y + event->area.y;
@@ -1127,16 +1132,20 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd
for (i = first; i <= last; i++)
{
/* TODO : skip if... */
-
+ /*
if (view->drawing_extra != NULL)
view->drawing_extra(lines[i], drawable, gc, fake_x, y, view->drawing_data);
+ */
- g_buffer_line_draw(lines[i], drawable, gc, view->max_widths, real_x, y, addr, code);
+ g_buffer_line_draw(lines[i], cairo, view->fcache,
+ view->max_widths, real_x, y, addr, code);
y += view->line_height;
}
+ cairo_destroy(cairo);
+
}
diff --git a/src/glibext/gfontcache.c b/src/glibext/gfontcache.c
new file mode 100644
index 0000000..2441d27
--- /dev/null
+++ b/src/glibext/gfontcache.c
@@ -0,0 +1,294 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gfontcache.c - mise en cache avec actualisation des polices
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "gfontcache.h"
+
+
+
+/* ----------------------- MISE EN PLACE D'UN CONTEXTE GLOBAL ----------------------- */
+
+
+/* Utilisable par toutes les impressions. */
+static PangoContext *_context = NULL;
+
+
+
+/* ---------------------------- CACHE DE POLICES PAR VUE ---------------------------- */
+
+
+/* Description d'un cache pour polices (instance) */
+struct _GFontCache
+{
+ GObject parent; /* A laisser en premier */
+
+ GHashTable *table; /* Associations desc./police */
+
+ GtkWidget *widget;
+
+};
+
+/* Description d'un cache pour polices (classe) */
+struct _GFontCacheClass
+{
+ GObjectClass parent; /* A laisser en premier */
+
+};
+
+
+/* Initialise la classe des caches pour polices. */
+static void g_font_cache_class_init(GFontCacheClass *);
+
+/* Initialise un cache pour polices. */
+static void g_font_cache_init(GFontCache *);
+
+/* Supprime toutes les références externes. */
+static void g_font_cache_dispose(GFontCache *);
+
+/* Procède à la libération totale de la mémoire. */
+static void g_font_cache_finalize(GFontCache *);
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* MISE EN PLACE D'UN CONTEXTE GLOBAL */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Initialise le contexte Pango pour la gestion des textes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void init_global_pango_context(void)
+{
+ PangoFontDescription *desc; /* Police de caractères */
+
+ _context = gdk_pango_context_get();
+
+ desc = pango_font_description_from_string("mono 10");
+ pango_context_set_font_description(_context, desc);
+ pango_font_description_free(desc);
+
+ pango_context_set_base_dir(_context, PANGO_DIRECTION_LTR);
+ pango_context_set_language(_context, gtk_get_default_language());
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Fournit le contexte Pango global pour l'impression. *
+* *
+* Retour : Contexte prêt à emploi. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PangoContext *get_global_pango_context(void)
+{
+ return _context;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Supprime le contexte Pango pour la gestion des textes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void exit_global_pango_context(void)
+{
+ g_object_unref(G_OBJECT(_context));
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/* CACHE DE POLICES PAR VUE */
+/* ---------------------------------------------------------------------------------- */
+
+
+
+/* Indique le type défini pour un cache pour polices. */
+G_DEFINE_TYPE(GFontCache, g_font_cache, G_TYPE_OBJECT);
+
+
+/******************************************************************************
+* *
+* Paramètres : class = classe à initialiser. *
+* *
+* Description : Initialise la classe des caches pour polices. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_font_cache_class_init(GFontCacheClass *class)
+{
+ GObjectClass *object; /* Autre version de la classe */
+
+ object = G_OBJECT_CLASS(class);
+
+ object->dispose = (GObjectFinalizeFunc/* ! */)g_font_cache_dispose;
+ object->finalize = (GObjectFinalizeFunc)g_font_cache_finalize;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : fcache = instance à initialiser. *
+* *
+* Description : Initialise un cache pour polices. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_font_cache_init(GFontCache *fcache)
+{
+ fcache->table = g_hash_table_new_full((GHashFunc)pango_font_description_hash,
+ (GEqualFunc)pango_font_description_equal,
+ (GDestroyNotify)pango_font_description_free,
+ (GDestroyNotify)g_object_unref);
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : fcache = instance d'objet GLib à traiter. *
+* *
+* Description : Supprime toutes les références externes. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_font_cache_dispose(GFontCache *fcache)
+{
+ g_hash_table_destroy(fcache->table);
+
+ G_OBJECT_CLASS(g_font_cache_parent_class)->dispose(G_OBJECT(fcache));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : fcache = instance d'objet GLib à traiter. *
+* *
+* Description : Procède à la libération totale de la mémoire. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_font_cache_finalize(GFontCache *fcache)
+{
+ G_OBJECT_CLASS(g_font_cache_parent_class)->finalize(G_OBJECT(fcache));
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : - *
+* *
+* Description : Crée un bloc virtuel d'instructions. *
+* *
+* Retour : Adresse de la structure mise en place. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+GFontCache *g_font_cache_new(void)
+{
+ GFontCache *result; /* Structure à retourner */
+
+ result = g_object_new(G_TYPE_FONT_CACHE, NULL);
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
+* Paramètres : fcache = instance à consulter, voire compléter. *
+* desc = description de la police recherchée. *
+* *
+* Description : Fournit une police utilisable répondant au besoin. *
+* *
+* Retour : Police prête à usage. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+PangoFont *g_font_cache_lookup(GFontCache *fcache, const PangoFontDescription *desc)
+{
+ PangoFont *result; /* Instance à retourner */
+ PangoFontDescription *key; /* Copie de la description */
+
+ result = (PangoFont *)g_hash_table_lookup(fcache->table, desc);
+
+ if (result == NULL)
+ {
+ result = pango_context_load_font(get_global_pango_context(), desc);
+
+ key = pango_font_description_copy(desc);
+ g_hash_table_insert(fcache->table, key, result);
+
+ }
+
+ return result;
+
+}
diff --git a/src/glibext/gfontcache.h b/src/glibext/gfontcache.h
new file mode 100644
index 0000000..e6ef2d6
--- /dev/null
+++ b/src/glibext/gfontcache.h
@@ -0,0 +1,79 @@
+
+/* OpenIDA - Outil d'analyse de fichiers binaires
+ * gfontcache.h - prototypes pour la mise en cache avec actualisation des polices
+ *
+ * Copyright (C) 2012 Cyrille Bagard
+ *
+ * This file is part of OpenIDA.
+ *
+ * OpenIDA 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.
+ *
+ * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifndef _GLIBEXT_GFONTCACHE_H
+#define _GLIBEXT_GFONTCACHE_H
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtkwidget.h>
+#include <pango/pango-context.h>
+#include <pango/pango-font.h>
+
+
+
+/* ----------------------- MISE EN PLACE D'UN CONTEXTE GLOBAL ----------------------- */
+
+
+/* Initialise le contexte Pango pour la gestion des textes. */
+void init_global_pango_context(void);
+
+/* Fournit le contexte Pango global pour l'impression. */
+PangoContext *get_global_pango_context(void);
+
+/* Supprime le contexte Pango pour la gestion des textes. */
+void exit_global_pango_context(void);
+
+
+
+/* ---------------------------- CACHE DE POLICES PAR VUE ---------------------------- */
+
+
+#define G_TYPE_FONT_CACHE g_font_cache_get_type()
+#define G_FONT_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), g_font_cache_get_type(), GFontCache))
+#define G_IS_FONT_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), g_font_cache_get_type()))
+#define G_FONT_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), G_TYPE_FONT_CACHE, GFontCacheClass))
+#define G_IS_FONT_CACHE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), G_TYPE_FONT_CACHE))
+#define G_FONT_CACHE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), G_TYPE_FONT_CACHE, GFontCacheClass))
+
+
+/* Description d'un cache pour polices (instance) */
+typedef struct _GFontCache GFontCache;
+
+/* Description d'un cache pour polices (classe) */
+typedef struct _GFontCacheClass GFontCacheClass;
+
+
+/* Indique le type défini pour un cache pour polices. */
+GType g_font_cache_get_type(void);
+
+/* Crée un bloc virtuel d'instructions. */
+GFontCache *g_font_cache_new(void);
+
+/* Fournit une police utilisable répondant au besoin. */
+PangoFont *g_font_cache_lookup(GFontCache *, const PangoFontDescription *);
+
+
+
+#endif /* _GLIBEXT_GFONTCACHE_H */
diff --git a/src/main.c b/src/main.c
index 6e06e98..09d9998 100644
--- a/src/main.c
+++ b/src/main.c
@@ -35,6 +35,7 @@
#include "arch/processor.h"
#include "format/format.h"
#include "glibext/delayed.h"
+#include "glibext/gfontcache.h"
#include "gtkext/support.h"
#include "plugins/pglist.h"
#include "../revision.h"
@@ -134,6 +135,7 @@ int main(int argc, char **argv)
/* Initialisation du programme */
init_all_processors();
init_all_formats();
+ init_global_pango_context();
/* Création de l'interface */
@@ -162,6 +164,8 @@ int main(int argc, char **argv)
gtk_main();
//gdk_threads_leave();
+ exit_global_pango_context();
+
unload_configuration(config);
return EXIT_SUCCESS;