summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2010-04-18 22:30:19 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2010-04-18 22:30:19 (GMT)
commitfb12cfc1727ba949b70a48ee042a2aec9ebbb407 (patch)
treee2c7300262312d77c9f57657e5238d269b7189c0 /src
parentef29fbc801e23f547b9ee7666b713bcf32d7e787 (diff)
Defined attributes for printing binary content using GLib.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@153 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src')
-rw-r--r--src/analysis/binary.c8
-rw-r--r--src/analysis/exporter.c50
-rw-r--r--src/analysis/line-int.h1
-rw-r--r--src/analysis/line.c20
-rw-r--r--src/analysis/line.h3
-rw-r--r--src/analysis/line_comment.c47
-rw-r--r--src/analysis/line_prologue.c35
-rw-r--r--src/common/dllist.h19
-rw-r--r--src/glibext/gbufferline.c35
-rw-r--r--src/glibext/gbufferline.h3
-rw-r--r--src/glibext/gbuffersegment.c96
-rw-r--r--src/glibext/gbuffersegment.h3
-rw-r--r--src/glibext/gcodebuffer.c2
13 files changed, 308 insertions, 14 deletions
diff --git a/src/analysis/binary.c b/src/analysis/binary.c
index c35118e..d518328 100644
--- a/src/analysis/binary.c
+++ b/src/analysis/binary.c
@@ -736,6 +736,8 @@ GOpenidaBinary *g_openida_binary_new_from_file(const char *filename)
break;
}
+ result->lines = build_binary_prologue(filename, result->bin_data, result->bin_length);
+
result->proc = get_arch_processor_from_format(result->format);
result->options = g_rendering_options_new(result->format);
@@ -1344,7 +1346,7 @@ GRenderingLine *build_binary_prologue(const char *filename, const uint8_t *data,
line = g_prologue_line_new("Disassembly generated by OpenIDA");
g_rendering_line_add_to_lines(&result, line);
- line = g_prologue_line_new("OpenIDA is free software - © 2008-2009 Cyrille Bagard");
+ line = g_prologue_line_new("OpenIDA is free software - © 2008-2010 Cyrille Bagard");
g_rendering_line_add_to_lines(&result, line);
line = g_prologue_line_new("");
@@ -1413,9 +1415,7 @@ void ack_completed_disassembly(GDelayedDisassembly *disass, GOpenidaBinary *bina
size_t i; /* Boucle de parcours */
- binary->lines = disass->lines;
-
-
+ g_rendering_line_merge(&binary->lines, &disass->lines);
diff --git a/src/analysis/exporter.c b/src/analysis/exporter.c
index b6d773a..9de5fbc 100644
--- a/src/analysis/exporter.c
+++ b/src/analysis/exporter.c
@@ -48,6 +48,7 @@ static void g_content_exporter_class_init(GContentExporterClass *klass)
{
GdkScreen *screen; /* Ecran pour GDK */
PangoFontDescription *font_desc; /* Police de caractère */
+ PangoAttribute *attrib; /* Propriété de rendu */
/* Exportation vers un tampon de code */
@@ -61,22 +62,71 @@ static void g_content_exporter_class_init(GContentExporterClass *klass)
pango_context_set_base_dir(klass->context, PANGO_DIRECTION_LTR);
pango_context_set_language(klass->context, gtk_get_default_language());
+ /* RTT_RAW */
+
klass->attribs[RTT_RAW] = pango_attr_list_new();
+ attrib = pango_attr_foreground_new(0, 0, 0);
+ pango_attr_list_insert(klass->attribs[RTT_RAW], attrib);
+
+ /* RTT_COMMENT */
+
klass->attribs[RTT_COMMENT] = pango_attr_list_new();
+ attrib = pango_attr_foreground_new(14335, 45311, 23551);
+ pango_attr_list_insert(klass->attribs[RTT_COMMENT], attrib);
+
+ /* RTT_RAW_CODE */
+
klass->attribs[RTT_RAW_CODE] = pango_attr_list_new();
+ attrib = pango_attr_foreground_new(48895, 48895, 48895);
+ pango_attr_list_insert(klass->attribs[RTT_RAW_CODE], attrib);
+
+ /* RTT_INSTRUCTION */
+
klass->attribs[RTT_INSTRUCTION] = pango_attr_list_new();
+ attrib = pango_attr_foreground_new(0, 0, 0);
+ pango_attr_list_insert(klass->attribs[RTT_INSTRUCTION], attrib);
+
+ /* RTT_IMMEDIATE */
+
klass->attribs[RTT_IMMEDIATE] = pango_attr_list_new();
+ attrib = pango_attr_foreground_new(41215, 8447, 61695);
+ pango_attr_list_insert(klass->attribs[RTT_IMMEDIATE], attrib);
+
+ /* RTT_REGISTER */
+
klass->attribs[RTT_REGISTER] = pango_attr_list_new();
+ //attrib = pango_attr_foreground_new(23551, 23551, 51455);
+ attrib = pango_attr_foreground_new(16895, 16895, 53759);
+ pango_attr_list_insert(klass->attribs[RTT_REGISTER], attrib);
+
+ /* RTT_HOOK */
+
klass->attribs[RTT_HOOK] = pango_attr_list_new();
+ attrib = pango_attr_foreground_new(0, 0, 0);
+ pango_attr_list_insert(klass->attribs[RTT_HOOK], attrib);
+
+ attrib = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
+ pango_attr_list_insert(klass->attribs[RTT_HOOK], attrib);
+
+ /* RTT_SIGNS */
+
klass->attribs[RTT_SIGNS] = pango_attr_list_new();
+ attrib = pango_attr_foreground_new(0, 0, 0);
+ pango_attr_list_insert(klass->attribs[RTT_SIGNS], attrib);
+
+ attrib = pango_attr_weight_new(PANGO_WEIGHT_SEMIBOLD);
+ pango_attr_list_insert(klass->attribs[RTT_SIGNS], attrib);
+
+ /* RTT_LTGT */
+
klass->attribs[RTT_LTGT] = pango_attr_list_new();
klass->attribs[RTT_SEGMENT] = pango_attr_list_new();
diff --git a/src/analysis/line-int.h b/src/analysis/line-int.h
index 38efeda..795adcc 100644
--- a/src/analysis/line-int.h
+++ b/src/analysis/line-int.h
@@ -63,6 +63,7 @@ struct _GRenderingLine
#define lines_list_add_before(new, head, pos) dl_list_add_before(new, head, pos, link)
#define lines_list_add_tail(new, head) dl_list_add_tail(new, head, GRenderingLine, link)
#define lines_list_del(item, head) dl_list_del(item, head, GRenderingLine, link)
+#define lines_list_merge(head1, head2) dl_list_merge(head1, head2, GRenderingLine, link)
#define lines_list_for_each(pos, head) dl_list_for_each(pos, head, GRenderingLine, link)
#define lines_list_for_each_safe(pos, head, next) dl_list_for_each_safe(pos, head, next, GRenderingLine, link)
diff --git a/src/analysis/line.c b/src/analysis/line.c
index bb4188a..a964b2a 100644
--- a/src/analysis/line.c
+++ b/src/analysis/line.c
@@ -540,6 +540,26 @@ void g_rendering_line_remove_range(GRenderingLine **lines, vmpa_t start, vmpa_t
/******************************************************************************
* *
+* Paramètres : lines1 = première liste à fusionner. *
+* lines2 = seconde liste à intégrer à la première. *
+* *
+* Description : Fusionne deux listes de lignes de rendu. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_rendering_line_merge(GRenderingLine **lines1, GRenderingLine **lines2)
+{
+ lines_list_merge(lines1, lines2);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : lines = liste de lignes de représentation à actualiser. *
* : iter = position actuelle dans la liste. *
* last = dernière élément imposé du parcours ou NULL. *
diff --git a/src/analysis/line.h b/src/analysis/line.h
index fbc560f..b7565f6 100644
--- a/src/analysis/line.h
+++ b/src/analysis/line.h
@@ -128,6 +128,9 @@ void g_rendering_line_insert_lines(GRenderingLine **, GRenderingLine **);
/* Supprime une série de lignes comprises dans un intervalle. */
void g_rendering_line_remove_range(GRenderingLine **, vmpa_t, vmpa_t);
+/* Fusionne deux listes de lignes de rendu. */
+void g_rendering_line_merge(GRenderingLine **, GRenderingLine **);
+
/* Fournit l'élement suivant un autre pour un parcours. */
GRenderingLine *g_rendering_line_get_next_iter(GRenderingLine *, const GRenderingLine *, const GRenderingLine *);
diff --git a/src/analysis/line_comment.c b/src/analysis/line_comment.c
index 5bdf29a..7d2758d 100644
--- a/src/analysis/line_comment.c
+++ b/src/analysis/line_comment.c
@@ -60,6 +60,8 @@ static void g_comment_line_init(GCommentLine *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_comment_line_add_text(GCommentLine *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_comment_line_to_buffer(GCommentLine *, GBufferLine *, GRenderingOptions *);
/* Indique le type définit par la GLib pour la ligne. */
@@ -105,6 +107,7 @@ static void g_comment_line_init(GCommentLine *line)
exporter_parent = G_CONTENT_EXPORTER(line);
exporter_parent->add_text = (add_text_fc)g_comment_line_add_text;
+ exporter_parent->export_buffer = (export_buffer_fc)g_comment_line_to_buffer;
line_parent = G_RENDERING_LINE(line);
@@ -173,6 +176,50 @@ static void g_comment_line_add_text(GCommentLine *line, GRenderingOptions *optio
/******************************************************************************
* *
+* Paramètres : line = ligne de représentation à représenter. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_comment_line_to_buffer(GCommentLine *line, GBufferLine *buffer, GRenderingOptions *options)
+{
+ GContentExporter *exporter; /* Autre vision de la ligne */
+ MemoryDataSize msize; /* Taille du bus d'adresses */
+ char address[VMPA_MAX_SIZE]; /* Adresse au format texte */
+ size_t len; /* Taille de l'élément inséré */
+
+ exporter = G_CONTENT_EXPORTER(line);
+
+ g_buffer_line_start_merge_at(buffer, BLC_ASSEMBLY_HEAD);
+
+ /* Eventuelle adresse virtuelle ou physique */
+
+ msize = g_arch_processor_get_memory_size(g_rendering_options_get_processor(line->options));
+
+ len = vmpa_to_string(G_RENDERING_LINE(line)->offset, msize, address);
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_ADDRESS, address, len, RTT_RAW);
+
+ /* Commentaire ? */
+
+ len = strlen(line->comment);
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_COMMENTS, "; ", 2, RTT_COMMENT);
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_COMMENTS,
+ line->comment, len, RTT_COMMENT);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : offset = emplacement physique ou en mémoire. *
* comment = texte à afficher au final. *
* options = paramétrage du rendu. *
diff --git a/src/analysis/line_prologue.c b/src/analysis/line_prologue.c
index d530a44..70c8e79 100644
--- a/src/analysis/line_prologue.c
+++ b/src/analysis/line_prologue.c
@@ -59,6 +59,8 @@ static void g_prologue_line_init(GPrologueLine *);
/* Ajoute du texte simple à un fichier ouvert en écriture. */
static void g_prologue_line_add_text(GPrologueLine *, GRenderingOptions *, MainRendering, FILE *);
+/* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
+static void g_prologue_line_to_buffer(GPrologueLine *, GBufferLine *, GRenderingOptions *);
/* Indique le type définit par la GLib pour la ligne. */
@@ -104,6 +106,7 @@ static void g_prologue_line_init(GPrologueLine *line)
exporter_parent = G_CONTENT_EXPORTER(line);
exporter_parent->add_text = (add_text_fc)g_prologue_line_add_text;
+ exporter_parent->export_buffer = (export_buffer_fc)g_prologue_line_to_buffer;
line_parent = G_RENDERING_LINE(line);
@@ -144,6 +147,38 @@ static void g_prologue_line_add_text(GPrologueLine *line, GRenderingOptions *opt
/******************************************************************************
* *
+* Paramètres : line = ligne de représentation à représenter. *
+* buffer = espace où placer ledit contenu. *
+* options = options de rendu. *
+* *
+* Description : Ajoute à un tampon GLib le contenu de l'instance spécifiée. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static void g_prologue_line_to_buffer(GPrologueLine *line, GBufferLine *buffer, GRenderingOptions *options)
+{
+ GContentExporter *exporter; /* Autre vision de la ligne */
+ size_t len; /* Taille de l'élément inséré */
+
+ exporter = G_CONTENT_EXPORTER(line);
+
+ g_buffer_line_start_merge_at(buffer, BLC_ADDRESS);
+
+ len = strlen(line->comment);
+
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_COMMENTS, "; ", 2, RTT_COMMENT);
+ g_content_exporter_insert_into_buffer(exporter, buffer, BLC_COMMENTS,
+ line->comment, len, RTT_COMMENT);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : comment = texte à afficher au final. *
* *
* Description : Crée une des lignes de descriptions initiales. *
diff --git a/src/common/dllist.h b/src/common/dllist.h
index 504291e..f309dc9 100644
--- a/src/common/dllist.h
+++ b/src/common/dllist.h
@@ -108,11 +108,28 @@ void __dl_list_del(dl_list_item *, dl_list_head *);
} \
while(0)
+#define dl_list_merge(head1, head2, type, member) \
+ do \
+ { \
+ if (dl_list_empty(*head1)) *head1 = *head2; \
+ else if (!dl_list_empty(*head2)) \
+ { \
+ dl_list_item *hmbr1 = &(*head1)->member; \
+ dl_list_item *hmbr2 = &(*head2)->member; \
+ dl_list_item *mid = hmbr1->prev; \
+ mid->next = hmbr2; \
+ hmbr1->prev = hmbr2->prev; \
+ hmbr2->prev->next = hmbr1; \
+ hmbr2->prev = mid; \
+ } \
+ } \
+ while(0)
+
#define dl_list_push dl_list_add_tail
#define dl_list_pop(head, type, member) \
({ \
- type *_result = *head; \
+ type *_result = *head;/* FIXME : ARgh ! */ \
dl_list_del(_result, head, type, member); \
_result; \
})
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index bfb77bb..da08184 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -63,6 +63,7 @@ struct _GBufferLine
GObject parent; /* A laisser en premier */
buffer_line_column columns[BLC_COUNT]; /* Répartition du texte */
+ BufferLineColumn merge_start; /* Début de la zone globale */
};
@@ -250,11 +251,13 @@ static void g_buffer_line_class_init(GBufferLineClass *class)
static void g_buffer_line_init(GBufferLine *line)
{
- unsigned int i; /* Boucle de parcours */
+ BufferLineColumn i; /* Boucle de parcours */
- for (i = 0; i < BLC_COUNT; i++)
+ for (i = BLC_ADDRESS; i < BLC_COUNT; i++)
reset_column(&line->columns[i]);
+ line->merge_start = BLC_COUNT;
+
}
@@ -325,6 +328,26 @@ gint g_buffer_line_get_width(GBufferLine *line, BufferLineColumn index)
/******************************************************************************
* *
+* Paramètres : line = ligne à venir compléter. *
+* start = début de la première (et unique) zone globale. *
+* *
+* Description : Définit la colonne à partir de laquelle la fusion opère. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_line_start_merge_at(GBufferLine *line, BufferLineColumn start)
+{
+ line->merge_start = start;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : line = ligne de texte à manipuler. *
* drawable = surface de rendu où travailler. *
* gc = contexte graphique à utiliser pour les pinceaux.*
@@ -343,16 +366,18 @@ gint g_buffer_line_get_width(GBufferLine *line, BufferLineColumn index)
void g_buffer_line_draw(GBufferLine *line, GdkDrawable *drawable, GdkGC *gc, const gint max_widths[BLC_COUNT], gint x_init, gint y)
{
gint x; /* Point de départ d'impression*/
- unsigned int i; /* Boucle de parcours */
+ BufferLineColumn i; /* Boucle de parcours */
x = x_init;
- for (i = 0; i < BLC_COUNT; i++)
+ for (i = BLC_ADDRESS; i < BLC_COUNT; i++)
{
/* TODO : skip if... */
draw_segments_of_column(&line->columns[i], drawable, gc, x, y);
- x += max_widths[i] + 23;
+
+ if (i < line->merge_start)
+ x += max_widths[i] + 23;
}
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index 4113c28..d9e1edb 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -78,6 +78,9 @@ void g_buffer_line_add_segment(GBufferLine *, BufferLineColumn, GBufferSegment *
/* Fournit la largeur requise pour une colonne de ligne donnée. */
gint g_buffer_line_get_width(GBufferLine *, BufferLineColumn);
+/* Définit la colonne à partir de laquelle la fusion opère. */
+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);
diff --git a/src/glibext/gbuffersegment.c b/src/glibext/gbuffersegment.c
index bcafa97..0714e9c 100644
--- a/src/glibext/gbuffersegment.c
+++ b/src/glibext/gbuffersegment.c
@@ -28,7 +28,9 @@
-
+/* Utilisation du champ pixel des couleurs cachées */
+#define COLOR_NOT_SET 0
+#define COLOR_SET 1
/* Fragment de caractères aux propriétés communes (instance) */
@@ -36,6 +38,10 @@ struct _GBufferSegment
{
GObject parent; /* A laisser en premier */
+ PangoAttrList *attribs; /* Propriétés du rendu */
+
+ GdkColor cache_fg; /* Couleur d'impression */
+
PangoGlyphString *glyphs; /* Caractères traités */
PangoFont *font; /* Police utilisée à l'analyse */
@@ -176,6 +182,9 @@ static bool ascii_glyph_table_init(GBufferSegmentClass *class, PangoContext *con
static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *context, PangoAttrList *attribs, const char *text, size_t length)
{
PangoGlyphString *glyphs; /* Caractères traités */
+ bool must_use_pango; /* Passage par Pango obligé ? */
+ PangoAttrIterator *iterator; /* Guide de parcours */
+ PangoAttribute *attrib; /* Attribut générique */
GList *item_list;
PangoItem *item;
@@ -199,6 +208,29 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *cont
+
+
+ /* Existe-t-il des attributs particuliers ? */
+
+ must_use_pango = false;
+
+ iterator = pango_attr_list_get_iterator(attribs);
+
+ attrib = pango_attr_iterator_get(iterator, PANGO_ATTR_WEIGHT);
+ must_use_pango |= (attrib != NULL);
+
+ pango_attr_iterator_destroy(iterator);
+
+ if (must_use_pango)
+ goto not_ascii;
+
+
+
+
+
+
+
+
/**
* Petite astuce empruntée à Vim...
* (cf. src/gui_gtk_x11.c, fonction gui_gtk2_draw_string()).
@@ -229,6 +261,10 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *cont
log_clusters[i] = i;
}
+ segment->font = class->ascii_font;
+
+ pango_glyph_string_extents(glyphs, class->ascii_font, NULL, &segment->logical);
+
goto next;
not_ascii:
@@ -243,7 +279,9 @@ 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 ! */
+ segment->font = item->analysis.font;/* TODO : ref ! */
+
+ pango_glyph_string_extents(glyphs, item->analysis.font, NULL, &segment->logical);
next:
@@ -252,7 +290,7 @@ static void g_buffer_segment_prepare(GBufferSegment *segment, PangoContext *cont
//pango_shape(text, length, &item->analysis, glyphs);
- pango_glyph_string_extents(glyphs, class->ascii_font, NULL, &segment->logical);
+ //pango_glyph_string_extents(glyphs, class->ascii_font, NULL, &segment->logical);
segment->logical.y /= PANGO_SCALE;
segment->logical.width /= PANGO_SCALE;
@@ -338,8 +376,11 @@ GBufferSegment *g_buffer_segment_new(PangoContext *context, PangoAttrList *attri
result = g_object_new(G_TYPE_BUFFER_SEGMENT, NULL);
//result = g_new(GBufferSegment, 1);
+ result->attribs = pango_attr_list_ref(attribs);
+
g_buffer_segment_prepare(result, context, attribs, text, length);
+ g_buffer_segment_cache_colors(result);
return result;
@@ -367,6 +408,46 @@ gint g_buffer_segment_get_width(const GBufferSegment *segment)
/******************************************************************************
* *
+* Paramètres : segment = fragment de texte à manipuler. *
+* *
+* Description : (Re)charge les couleurs à partir de la liste d'attributs. *
+* *
+* Retour : - *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+void g_buffer_segment_cache_colors(GBufferSegment *segment)
+{
+ PangoAttrIterator *iterator; /* Guide de parcours */
+ PangoAttribute *attrib; /* Attribut générique */
+ PangoAttrColor *color_attrib; /* Propriété de couleur */
+
+ iterator = pango_attr_list_get_iterator(segment->attribs);
+
+ /* Couleur d'impression */
+
+ attrib = pango_attr_iterator_get(iterator, PANGO_ATTR_FOREGROUND);
+ segment->cache_fg.pixel = (attrib != NULL ? COLOR_SET : COLOR_NOT_SET);
+
+ if (segment->cache_fg.pixel == COLOR_SET)
+ {
+ color_attrib = (PangoAttrColor *)attrib;
+
+ segment->cache_fg.red = color_attrib->color.red;
+ segment->cache_fg.green = color_attrib->color.green;
+ segment->cache_fg.blue = color_attrib->color.blue;
+
+ }
+
+ pango_attr_iterator_destroy(iterator);
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : segment = fragment de texte à manipuler. *
* drawable = surface de rendu où travailler. *
* gc = contexte graphique à utiliser pour les pinceaux. *
@@ -383,7 +464,14 @@ gint g_buffer_segment_get_width(const GBufferSegment *segment)
void g_buffer_segment_draw(GBufferSegment *segment, GdkDrawable *drawable, GdkGC *gc, gint *x, gint y)
{
- gdk_draw_glyphs(drawable, gc, G_BUFFER_SEGMENT_GET_CLASS(segment)->ascii_font,
+ /* Couleur d'impression */
+
+ if (segment->cache_fg.pixel == COLOR_SET)
+ gdk_gc_set_rgb_fg_color(gc, &segment->cache_fg);
+
+ /* Impression du texte */
+
+ gdk_draw_glyphs(drawable, gc, segment->font,
*x, y - segment->logical.y, segment->glyphs);
*x += segment->logical.width;
diff --git a/src/glibext/gbuffersegment.h b/src/glibext/gbuffersegment.h
index 28338b9..5731415 100644
--- a/src/glibext/gbuffersegment.h
+++ b/src/glibext/gbuffersegment.h
@@ -57,6 +57,9 @@ GBufferSegment *g_buffer_segment_new(PangoContext *, PangoAttrList *, const char
/* Fournit la quantité de pixels requise pour l'impression. */
gint g_buffer_segment_get_width(const GBufferSegment *);
+/* (Re)charge les couleurs à partir de la liste d'attributs. */
+void g_buffer_segment_cache_colors(GBufferSegment *);
+
/* Imprime le fragment de texte représenté. */
void g_buffer_segment_draw(GBufferSegment *, GdkDrawable *, GdkGC *, gint *, gint);
diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c
index fda2c01..75c2e94 100644
--- a/src/glibext/gcodebuffer.c
+++ b/src/glibext/gcodebuffer.c
@@ -461,6 +461,8 @@ void g_buffer_view_draw(const GBufferView *view, const GdkEventExpose *event, Gd
last = first + (event->area.height / view->line_height);
if (event->area.height % view->line_height > 0) last++;
+ last = MIN(last, view->buffer->used > 0 ? view->buffer->used - 1 : 0);
+
y = event->area.y - (real_y % view->line_height);