diff options
| -rw-r--r-- | ChangeLog | 36 | ||||
| -rw-r--r-- | src/analysis/binary.c | 8 | ||||
| -rw-r--r-- | src/analysis/exporter.c | 50 | ||||
| -rw-r--r-- | src/analysis/line-int.h | 1 | ||||
| -rw-r--r-- | src/analysis/line.c | 20 | ||||
| -rw-r--r-- | src/analysis/line.h | 3 | ||||
| -rw-r--r-- | src/analysis/line_comment.c | 47 | ||||
| -rw-r--r-- | src/analysis/line_prologue.c | 35 | ||||
| -rw-r--r-- | src/common/dllist.h | 19 | ||||
| -rw-r--r-- | src/glibext/gbufferline.c | 35 | ||||
| -rw-r--r-- | src/glibext/gbufferline.h | 3 | ||||
| -rw-r--r-- | src/glibext/gbuffersegment.c | 96 | ||||
| -rw-r--r-- | src/glibext/gbuffersegment.h | 3 | ||||
| -rw-r--r-- | src/glibext/gcodebuffer.c | 2 | 
14 files changed, 344 insertions, 14 deletions
| @@ -1,3 +1,39 @@ +10-04-19  Cyrille Bagard <nocbos@gmail.com> + +	* src/analysis/binary.c: +	Display the old built prologues. + +	* src/analysis/exporter.c: +	Define attributes for printing binary content using GLib. + +	* src/analysis/line.c: +	Provide a function to merge lines lists. + +	* src/analysis/line_comment.c: +	Export content to GLib buffer. + +	* src/analysis/line.h: +	* src/analysis/line-int.h: +	Provide a function to merge lines lists. + +	* src/analysis/line_prologue.c: +	Export content to GLib buffer. + +	* src/common/dllist.h: +	Merge lists using dl_list_merge ; dl_list_pop needs to be fixed. + +	* src/glibext/gbufferline.c: +	* src/glibext/gbufferline.h: +	Add the ability to merge line columns. + +	* src/glibext/gbuffersegment.c: +	* src/glibext/gbuffersegment.h: +	Take care of attributes when drawing glyphs. + +	* src/glibext/gcodebuffer.c: +	Fix a bug: the range of lines to draw has to be smaller than the number +	of internal lines. +  10-04-18  Cyrille Bagard <nocbos@gmail.com>  	* src/analysis/Makefile.am: 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); | 
