diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/analysis/disass/disassembler.c | 12 | ||||
| -rw-r--r-- | src/analysis/disass/output.c | 20 | ||||
| -rw-r--r-- | src/glibext/gbinportion.c | 2 | ||||
| -rw-r--r-- | src/glibext/gbufferline.c | 239 | ||||
| -rw-r--r-- | src/glibext/gbufferline.h | 25 | ||||
| -rw-r--r-- | src/glibext/gcodebuffer.c | 113 | 
6 files changed, 338 insertions, 73 deletions
| diff --git a/src/analysis/disass/disassembler.c b/src/analysis/disass/disassembler.c index ce2e6ff..c563b2e 100644 --- a/src/analysis/disass/disassembler.c +++ b/src/analysis/disass/disassembler.c @@ -625,13 +625,20 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con  {      GLangOutput *output;                    /* Modèle de sortie adéquat    */      GBufferLine *line;                      /* Ligne de destination        */ +    bool managed;                           /* Groupe déjà défini ?        */      size_t len;                             /* Taille du texte             */      char *content;                          /* Contenu textuel d'une ligne */      output = g_asm_output_new();      line = g_lang_output_start_comments(output, buffer); -    if (line != NULL) g_buffer_line_start_merge_at(line, BLC_PHYSICAL); +    if (line != NULL) +    { +        g_buffer_line_start_merge_at(line, BLC_PHYSICAL); +        g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER); +    } + +    managed = (line != NULL);      /* Introduction */ @@ -639,6 +646,9 @@ static void build_disass_prologue(GCodeBuffer *buffer, const char *filename, con                                             SL(_("Disassembly generated by Chrysalide")));      g_buffer_line_start_merge_at(line, BLC_PHYSICAL); +    if (!managed) +        g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER); +      line = g_lang_output_continue_comments(output, buffer,                                             SL(_("Chrysalide is free software - © 2008-2015 Cyrille Bagard")));      g_buffer_line_start_merge_at(line, BLC_PHYSICAL); diff --git a/src/analysis/disass/output.c b/src/analysis/disass/output.c index d698c71..727c34f 100644 --- a/src/analysis/disass/output.c +++ b/src/analysis/disass/output.c @@ -236,12 +236,29 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form              if (cmp_vmpa(iaddr, saddr) == 0)              { -                  /* Point d'entrée ? */                  if (g_binary_symbol_get_target_type(symbols[sym_index]) == STP_ENTRY_POINT)                      g_buffer_line_add_flag(line, BLF_ENTRYPOINT); +                /* Début d'un groupe bien cohérent avec les alignements ? */ + +                switch (g_binary_symbol_get_target_type(symbols[sym_index])) +                { +                    case STP_ROUTINE: +                    case STP_OBJECT: +                    case STP_FUNCTION: +                    case STP_ENTRY_POINT: +                    case STP_STRING: +                    case STP_RO_STRING: +                        g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER); +                        break; + +                    default: +                        break; + +                } +                  /* Commentaire ? */                  comment = g_binary_symbol_get_comment(symbols[sym_index]); @@ -266,7 +283,6 @@ void print_disassembled_instructions(GCodeBuffer *buffer, const GExeFormat *form                  sym_index++; -              }          } diff --git a/src/glibext/gbinportion.c b/src/glibext/gbinportion.c index 16f4814..bd4702b 100644 --- a/src/glibext/gbinportion.c +++ b/src/glibext/gbinportion.c @@ -711,6 +711,8 @@ void g_binary_portion_print(const GBinPortion *portion, GCodeBuffer *buffer, Mem      line = g_code_buffer_append_new_line(buffer, &range);      g_buffer_line_fill_mrange(line, msize, msize); +    g_buffer_line_add_flag(line, BLF_WIDTH_MANAGER); +      /* Séparation */      line = g_code_buffer_append_new_line(buffer, &range); diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c index 7768a0e..c998fce 100644 --- a/src/glibext/gbufferline.c +++ b/src/glibext/gbufferline.c @@ -99,6 +99,16 @@ struct _GBufferLine      BufferLineFlags flags;                  /* Drapeaux particuliers       */ +    union +    { +        struct +        { +            gint max_widths[BLC_COUNT];     /* Taille cachée des colonnes  */ +            gint merged_width;              /* Largeur cumulée avant fusion*/ +        }; +        GBufferLine *manager;               /* Représentante d'un groupe   */ +    }; +  };  /* Représentation de fragments de texte en ligne (classe) */ @@ -122,6 +132,12 @@ static void g_buffer_line_class_init(GBufferLineClass *);  /* Procède à l'initialisation d'une représentation de fragments. */  static void g_buffer_line_init(GBufferLine *); +/* Supprime toutes les références externes. */ +static void g_buffer_line_dispose(GBufferLine *); + +/* Procède à la libération totale de la mémoire. */ +static void g_buffer_line_finalize(GBufferLine *); +  /* ---------------------------------------------------------------------------------- */ @@ -453,8 +469,14 @@ G_DEFINE_TYPE(GBufferLine, g_buffer_line, G_TYPE_OBJECT);  static void g_buffer_line_class_init(GBufferLineClass *class)  { +    GObjectClass *object;                   /* Autre version de la classe  */      gchar *filename;                        /* Chemin d'accès à utiliser   */ +    object = G_OBJECT_CLASS(class); + +    object->dispose = (GObjectFinalizeFunc/* ! */)g_buffer_line_dispose; +    object->finalize = (GObjectFinalizeFunc)g_buffer_line_finalize; +      filename = find_pixmap_file("entrypoint.png");      assert(filename != NULL); @@ -507,6 +529,49 @@ static void g_buffer_line_init(GBufferLine *line)  /******************************************************************************  *                                                                             * +*  Paramètres  : line = instance d'objet GLib à traiter.                      * +*                                                                             * +*  Description : Supprime toutes les références externes.                     * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_buffer_line_dispose(GBufferLine *line) +{ +    if (line->flags & BLF_WIDTH_MANAGER) +        g_object_unref(G_OBJECT(line->manager)); + +    G_OBJECT_CLASS(g_buffer_line_parent_class)->dispose(G_OBJECT(line)); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line = instance d'objet GLib à traiter.                      * +*                                                                             * +*  Description : Procède à la libération totale de la mémoire.                * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_buffer_line_finalize(GBufferLine *line) +{ +    /* TODO : segments des colonnes... */ + +    G_OBJECT_CLASS(g_buffer_line_parent_class)->finalize(G_OBJECT(line)); + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : range = emplacement où va se situer la ligne.                *  *                main  = colonne à référencer comme étant la principale.      *  *                                                                             * @@ -792,7 +857,7 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint          if (i < line->merge_start)          { -            width = max_widths[i]; +            width = g_buffer_line_compute_max_width(line, i, max_widths);              if ((i + 1) < BLC_COUNT) limit = width + COL_MARGIN / 2;              else limit = width; @@ -863,7 +928,10 @@ GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *line, const gint                      printf(" -- update to col %u  -- x = %d\n", i, *offset);                      if ((i - 1) < line->merge_start) -                        *base += (max_widths[i - 1] + COL_MARGIN); +                    { +                        width = g_buffer_line_compute_max_width(line, i - 1, max_widths); +                        *base += (width + COL_MARGIN); +                    }                      else                          *base += get_column_width(&line->columns[i - 1]); @@ -998,7 +1066,10 @@ GBufferSegment *g_buffer_line_find_near_segment(const GBufferLine *line, GBuffer              displayed = (k < BLC_DISPLAY ? display[k] : true);              if (displayed) -                *offset += max_widths[k] + COL_MARGIN; +            { +                *offset += g_buffer_line_compute_max_width(line, k, max_widths); +                if (k < line->merge_start) *offset += COL_MARGIN; +            }          } @@ -1118,55 +1189,147 @@ char *g_buffer_line_get_text(const GBufferLine *line, BufferLineColumn first, Bu  /******************************************************************************  *                                                                             * -*  Paramètres  : line  = ligne à venir compléter.                             * -*                index = index de la colonne visée par la procédure.          * +*  Paramètres  : line    = ligne à venir consulter/compléter.                 * +*                manager = ligne de départ d'un groupe de ligne.              *  *                                                                             * -*  Description : Fournit la largeur requise pour une colonne de ligne donnée. * +*  Description : Retient les largeurs d'une ligne si maximales.               *  *                                                                             * -*  Retour      : Largeur en pixel requise.                                    * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -gint g_buffer_line_get_column_width(GBufferLine *line, BufferLineColumn index) +void g_buffer_line_update_max_widths(GBufferLine *line, GBufferLine *manager)  { -    gint result;                            /* Largeur à retourner         */ +    BufferLineColumn i;                     /* Boucle de parcours          */ +    GBufferLine *old;                       /* Ancienne ligne associée     */ +    gint merged_width;                      /* Largeur cumulée avant fusion*/ +    gint width;                             /* Largeur d'une colonne       */ -    if (index >= line->merge_start) result = 0; -    else result = get_column_width(&line->columns[index]); +    /* Réinitialisation ? */ -    return result; +    if (line == manager) +    { +        assert(line->flags & BLF_WIDTH_MANAGER); + +        for (i = 0; i < BLC_COUNT; i++) +            line->max_widths[i] = 0; + +        line->merged_width = 0; + +    } +    else +    { +        assert((line->flags & BLF_WIDTH_MANAGER) == 0); + +        old = line->manager; + +        g_object_ref(G_OBJECT(manager)); +        line->manager = manager; + +        g_object_unref(G_OBJECT(old)); + +    } + +    /* Mises à jour */ + +    merged_width = 0; + +    for (i = 0; i < BLC_COUNT; i++) +    { +        width = get_column_width(&line->columns[i]); + +        if (i < line->merge_start) +            manager->max_widths[i] = MAX(manager->max_widths[i], width); + +        if (i >= BLC_DISPLAY) +        { +            merged_width += width; + +            if (i < line->merge_start && (i + 1) < BLC_COUNT) +                merged_width += COL_MARGIN; + +        } + +    } + +    if (line->merge_start != BLC_COUNT) +        manager->merged_width = MAX(manager->merged_width, merged_width);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : line    = ligne à venir compléter.                           * -*                merge   = précise la première colonne marquant la fusion. [OUT]* -*                display = règles d'affichage des colonnes modulables.        * +*  Paramètres  : line         = ligne à venir consulter.                      * +*                max_widths   = tableau résumant les largeurs maximales. [OUT]* +*                merged_width = largeur maximale en cas de fusion. |OUT]      *  *                                                                             * -*  Description : Fournit la dernière largeur d'une ligne avec fusion.         * +*  Description : Filtre des largeurs de lignes et ne garde que les maximales. *  *                                                                             * -*  Retour      : Largeur en pixel requise.                                    * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -gint g_buffer_line_get_merge_width(GBufferLine *line, BufferLineColumn *merge, const bool *display) +void g_buffer_line_apply_max_widths(GBufferLine *line, gint *max_widths, gint *merged_width) +{ +    GBufferLine *manager;                   /* Gestionnaire de groupe      */ +    BufferLineColumn i;                     /* Boucle de parcours          */ + +    if (line->flags & BLF_WIDTH_MANAGER) +        manager = line; +    else +        manager = line->manager; + +    for (i = 0; i < BLC_COUNT; i++) +        max_widths[i] = MAX(manager->max_widths[i], max_widths[i]); + +    *merged_width = MAX(manager->merged_width, *merged_width); + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : line       = ligne à venir consulter.                        * +*                index      = indice de la colonne visée.                     * +*                max_widths = tableau résumant les largeurs maximales.        * +*                                                                             * +*  Description : Fournit la largeur d'une colonne finalement appliquée.       * +*                                                                             * +*  Retour      : Largeur globale ou spécifique, selon l'indice communiqué.    * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +gint g_buffer_line_compute_max_width(const GBufferLine *line, BufferLineColumn index, const gint *max_widths)  {      gint result;                            /* Largeur à retourner         */ -    result = 0; +    assert(index < BLC_COUNT); + +    if (index >= line->merge_start) +        result = get_column_width(&line->columns[index]); + +    else +    { +        if (index < BLC_ASSEMBLY) +            result = max_widths[index]; -    /* TODO : wtf ?! quelle est l'utilité des arguments booléens ? */ +        else +        { +            if (line->flags & BLF_WIDTH_MANAGER) +                result = line->max_widths[index]; +            else +                result = line->manager->max_widths[index]; -    *merge = line->merge_start; +        } -    if (line->merge_start < BLC_COUNT) -        result = get_column_width(&line->columns[line->merge_start]); +    }      return result; @@ -1175,6 +1338,25 @@ gint g_buffer_line_get_merge_width(GBufferLine *line, BufferLineColumn *merge, c  /******************************************************************************  *                                                                             * +*  Paramètres  : line = ligne à venir consulter.                              * +*                                                                             * +*  Description : Fournit la colonne à partir de laquelle une fusion opère.    * +*                                                                             * +*  Retour      : Début de la première (et unique) zone globale.               * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line) +{ +    return line->merge_start; + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : line  = ligne à venir compléter.                             *  *                start = début de la première (et unique) zone globale.       *  *                                                                             * @@ -1290,6 +1472,7 @@ void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const gint max_widths      GBufferLineClass *class;                /* Stockage de briques de base */      gint x;                                 /* Point de départ d'impression*/      BufferLineColumn i;                     /* Boucle de parcours          */ +    gint max_width;                         /* Largeur maximale de colonne */      if (line->flags != BLF_NONE && line->flags != BLF_HAS_CODE)      { @@ -1300,6 +1483,9 @@ void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const gint max_widths          else if (line->flags & BLF_BOOKMARK)              cairo_set_source_surface(cairo, class->bookmark_img, 5, y); +        ////////////////// +        cairo_set_source_surface(cairo, class->entrypoint_img, 5, y); +          cairo_paint(cairo);      } @@ -1313,7 +1499,12 @@ void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const gint max_widths          draw_segments_of_column(&line->columns[i], cairo, x, y, list);          if (i < line->merge_start) -            x += max_widths[i] + COL_MARGIN; +        { +            max_width = g_buffer_line_compute_max_width(line, i, max_widths); + +            x += max_width + COL_MARGIN; + +        }      } diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h index 0da5ffd..7ba5467 100644 --- a/src/glibext/gbufferline.h +++ b/src/glibext/gbufferline.h @@ -87,12 +87,13 @@ typedef enum _BufferLineColumn  /* Propriétés particulières supplémentaires */  typedef enum _BufferLineFlags  { -    BLF_NONE        = 0 << 0,               /* Aucune                      */ -    BLF_HAS_CODE    = 1 << 0,               /* La ligne contient du code   */ -    BLF_ENTRYPOINT  = 1 << 1,               /* Représentation d'une entrée */ -    BLF_BOOKMARK    = 1 << 2,               /* Signet associé              */ +    BLF_NONE            = 0 << 0,           /* Aucune                      */ +    BLF_HAS_CODE        = 1 << 0,           /* La ligne contient du code   */ +    BLF_ENTRYPOINT      = 1 << 1,           /* Représentation d'une entrée */ +    BLF_BOOKMARK        = 1 << 2,           /* Signet associé              */ +    BLF_WIDTH_MANAGER   = 1 << 3,           /* Début de groupe des largeurs*/ -    BLF_ALL         = ((1 << 3) - 1) +    BLF_ALL             = ((1 << 4) - 1)  } BufferLineFlags; @@ -127,11 +128,17 @@ GBufferSegment *g_buffer_line_insert_text(GBufferLine *, BufferLineColumn, const  /* Donne le texte représenté par une ligne de tampon. */  char *g_buffer_line_get_text(const GBufferLine *, BufferLineColumn, BufferLineColumn, bool); -/* Fournit la largeur requise pour une colonne de ligne donnée. */ -gint g_buffer_line_get_column_width(GBufferLine *, BufferLineColumn); +/* Retient les largeurs d'une ligne si maximales. */ +void g_buffer_line_update_max_widths(GBufferLine *, GBufferLine *); -/* Fournit la dernière largeur d'une ligne avec fusion. */ -gint g_buffer_line_get_merge_width(GBufferLine *, BufferLineColumn *, const bool *); +/* Filtre des largeurs de lignes et ne garde que les maximales. */ +void g_buffer_line_apply_max_widths(GBufferLine *, gint *, gint *); + +/* Fournit la largeur d'une colonne finalement appliquée. */ +gint g_buffer_line_compute_max_width(const GBufferLine *, BufferLineColumn, const gint *); + +/* Fournit la colonne à partir de laquelle une fusion opère. */ +BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *);  /* Définit la colonne à partir de laquelle la fusion opère. */  void g_buffer_line_start_merge_at(GBufferLine *, BufferLineColumn); diff --git a/src/glibext/gcodebuffer.c b/src/glibext/gcodebuffer.c index c676b7c..b211c4a 100644 --- a/src/glibext/gcodebuffer.c +++ b/src/glibext/gcodebuffer.c @@ -24,6 +24,7 @@  #include "gcodebuffer.h" +#include <assert.h>  #include <malloc.h>  #include <stdlib.h>  #include <string.h> @@ -132,6 +133,9 @@ static size_t _g_code_buffer_get_index_from_address_new(const GCodeBuffer *, con  /* Convertit une adresse en indice de ligne. */  static size_t g_code_buffer_get_index_from_address(GCodeBuffer *, const vmpa2t *, bool); +/* Actualise les largeurs maximales par groupes de lignes. */ +static void g_code_buffer_update_line_max_widths(const GCodeBuffer *, size_t, size_t); +  /* ---------------------- VUE PARTICULIERE D'UN TAMPON DE CODE ---------------------- */ @@ -149,11 +153,10 @@ struct _GBufferView      size_t last_index;                      /* Indice de la dernière ligne */   /* FIXME : idem */      gint line_height;                       /* Hauteur maximale des lignes */ -    gint max_widths[BLC_COUNT];             /* Taille cachée des colonnes  */      gint left_margin;                       /* Marge gauche + espace       */      gint left_text;                         /* Début d'impression du code  */ -    gint last_width;                        /* Plus grande col. de fusion  */ -    BufferLineColumn last_merge;            /* Colonne de fusion extrême   */ +    gint max_widths[BLC_COUNT];             /* Taille cachée des colonnes  */ +    gint merged_width;                      /* Plus grande taille de fusion*/      segcnt_list *highlighted;               /* Segments mis en évidence    */      bool external;                          /* Note l'origine de la liste  */ @@ -634,6 +637,60 @@ static size_t g_code_buffer_get_index_from_address(GCodeBuffer *buffer, const vm  /******************************************************************************  *                                                                             * +*  Paramètres  : buffer = tampon contentenant un ensemble de lignes.          * +*                first  = première ligne modifiée à considérer.               * +*                last   = dernière ligne modifiée à considérer.               * +*                                                                             * +*  Description : Actualise les largeurs maximales par groupes de lignes.      * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +static void g_code_buffer_update_line_max_widths(const GCodeBuffer *buffer, size_t first, size_t last) +{ +    GBufferLine **lines;                    /* Liste des lignes à traiter  */ +    size_t start;                           /* Début de groupe de largeurs */ +    size_t end;                             /* Fin de groupe de largeurs   */ +    GBufferLine *manager;                   /* Ligne de gestion de largeurs*/ +    size_t i;                               /* Boucle de parcours          */ + +    assert(buffer->used > 0); + +    lines = buffer->lines; + +    /* Recherche des bornes du groupe de largeurs courant */ + +    for (start = first; start > 0; start--) +        if (g_buffer_line_get_flags(lines[start]) & BLF_WIDTH_MANAGER) +            break; + +    for (end = last; end < (buffer->used - 1); end++) +        if (g_buffer_line_get_flags(lines[end + 1]) & BLF_WIDTH_MANAGER) +            break; + +    /* Réinitialisation ciblée des largeurs */ + +    assert(g_buffer_line_get_flags(lines[start]) & BLF_WIDTH_MANAGER); + +    manager = NULL; + +    for (i = start; i <= end; i++) +    { +        if (g_buffer_line_get_flags(lines[i]) & BLF_WIDTH_MANAGER) +            manager = lines[i]; + +        g_buffer_line_update_max_widths(lines[i], manager); + +    } + +} + + +/****************************************************************************** +*                                                                             *  *  Paramètres  : buffer = composant GTK à mettre à jour.                      *  *                range  = emplacement où va se situer la ligne.               *  *                                                                             * @@ -1144,6 +1201,8 @@ static void g_buffer_view_reset_required_widths(GBufferView *view)      for (i = 0; i < BLC_COUNT; i++)          view->max_widths[i] = -1; +    view->merged_width = 0; +  } @@ -1184,10 +1243,7 @@ static void g_buffer_view_compute_required_widths(GBufferView *view, const bool      GBufferLine **lines;                    /* Liste des lignes à traiter  */      size_t first;                           /* Première ligne intégrée     */      size_t last;                            /* Dernière ligne intégrée     */ -    size_t i;                               /* Boucle de parcours #1       */ -    unsigned int j;                         /* Boucle de parcours #2       */ -    gint width;                             /* Largeur d'une colonne       */ -    BufferLineColumn merge;                 /* Début de fusion de colonnes */ +    size_t i;                               /* Boucle de parcours          */      if (!HEIGHT_CACHED(view))          g_buffer_view_compute_required_height(view); @@ -1200,32 +1256,14 @@ static void g_buffer_view_compute_required_widths(GBufferView *view, const bool      view->left_margin = 2 * view->line_height;      view->left_text = 2.5 * view->line_height; -    view->last_width = 0; -    view->last_merge = BLC_INVALID; -      if (view->buffer->used > 0) -        for (i = first; i <= last; i++) -        { -            for (j = 0; j < BLC_COUNT; j++) -            { -                width = g_buffer_line_get_column_width(lines[i], j); -                view->max_widths[j] = MAX(view->max_widths[j], width); -            } - -            width = g_buffer_line_get_merge_width(lines[i], &merge, display); -            view->last_width = MAX(view->last_width, width); -            if (merge != BLC_COUNT) -            { -                if (view->last_merge == BLC_INVALID) -                    view->last_merge = merge; -                else -                    view->last_merge = MAX(view->last_merge, merge); -            } +    { +        g_code_buffer_update_line_max_widths(view->buffer, first, last); -        } +        for (i = first; i <= last; i++) +            g_buffer_line_apply_max_widths(lines[i], view->max_widths, &view->merged_width); -    if (view->last_merge == BLC_INVALID) -        view->last_merge = BLC_COUNT; +    }  } @@ -1295,18 +1333,15 @@ gint g_buffer_view_get_width(GBufferView *view, const bool *display)      /* Seconde méthode */ -    for (i = 0; i < view->last_merge; i++) +    for (i = 0; i < BLC_DISPLAY; i++)      { -        if (i < BLC_DISPLAY && !display[i]) continue; - -        full_width += view->max_widths[i]; +        if (!display[i]) continue; -        if ((i + 1) < view->last_merge) -            full_width += COL_MARGIN; +        full_width += view->max_widths[i] + COL_MARGIN;      } -    full_width += view->last_width + COL_MARGIN; +    full_width += view->merged_width;      /* Mise en concurrence et poursuite... */ @@ -1712,7 +1747,11 @@ const vmpa2t *g_buffer_view_move_caret(GBufferView *view, GdkRectangle *caret, b              for (i = BLC_ASSEMBLY_HEAD; i < BLC_COUNT; i++)                  right_pos += view->max_widths[i] + COL_MARGIN; +            /* +gint g_buffer_line_compute_max_width(const GBufferLine *line, BufferLineColumn index, const gint *max_widths) +BufferLineColumn g_buffer_line_get_merge_start(const GBufferLine *line) +            */              left_pos = view->left_text; | 
