summaryrefslogtreecommitdiff
path: root/src/glibext/gbufferline.c
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2020-07-23 11:21:16 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2020-07-23 11:21:16 (GMT)
commit19516ffcca14abb082c5109125b7249bdc7fc199 (patch)
tree5fec885bae9e08154e133a8302bfdd00397126cc /src/glibext/gbufferline.c
parentb806230a94be8d3cefb79d7756c95660033596b2 (diff)
Renamed some files.
Diffstat (limited to 'src/glibext/gbufferline.c')
-rw-r--r--src/glibext/gbufferline.c1558
1 files changed, 0 insertions, 1558 deletions
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
deleted file mode 100644
index e3482aa..0000000
--- a/src/glibext/gbufferline.c
+++ /dev/null
@@ -1,1558 +0,0 @@
-
-/* Chrysalide - Outil d'analyse de fichiers binaires
- * gbufferline.c - représentation de fragments de texte en ligne
- *
- * Copyright (C) 2010-2019 Cyrille Bagard
- *
- * This file is part of Chrysalide.
- *
- * Chrysalide 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.
- *
- * Chrysalide 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 Chrysalide. If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-#include "gbufferline.h"
-
-
-#include <assert.h>
-#include <malloc.h>
-#include <string.h>
-
-
-#include "chrysamarshal.h"
-#include "linecolumn.h"
-#include "../common/extstr.h"
-#include "../core/paths.h"
-
-
-
-/* ---------------------------- GESTION DE LINE COMPLETE ---------------------------- */
-
-
-/* Mémorisation des origines de texte */
-typedef struct _content_origin
-{
- col_coord_t coord; /* Localisation d'attachement */
-
- GObject *creator; /* Origine de la création */
-
-} content_origin;
-
-/* Représentation de fragments de texte en ligne (instance) */
-struct _GBufferLine
-{
- GObject parent; /* A laisser en premier */
-
- mrange_t range; /* Couverture geographique */
- BufferLineColumn main_column; /* Colonne principale */
-
- line_column columns[BLC_COUNT]; /* Répartition du texte */
- BufferLineColumn merge_start; /* Début de la zone globale */
- BufferLineColumn last_used; /* Dernière colonne utilisée */
-
- BufferLineFlags flags; /* Drapeaux particuliers */
-
- content_origin *origins; /* Mémorisation des origines */
- size_t ocount; /* Nombre de ces mémorisations */
-
- union
- {
- struct
- {
- gint max_widths[BLC_COUNT]; /* Taille cachée des colonnes */
- gint merged_width; /* Largeur cumulée avant fusion*/
- };
- };
-
-};
-
-/* Représentation de fragments de texte en ligne (classe) */
-struct _GBufferLineClass
-{
- GObjectClass parent; /* A laisser en premier */
-
- cairo_surface_t *entrypoint_img; /* Image pour les entrées */
- cairo_surface_t *bookmark_img; /* Image pour les signets */
-
- /* Signaux */
-
- void (* content_changed) (GBufferLine *, line_segment *);
-
- void (* flip_flag) (GBufferLine *, BufferLineFlags, BufferLineFlags);
-
-};
-
-
-/* Procède à l'initialisation d'une classe de représentation. */
-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 *);
-
-
-
-/* ---------------------------------------------------------------------------------- */
-/* GESTION DE LINE COMPLETE */
-/* ---------------------------------------------------------------------------------- */
-
-
-/* Détermine le type de la représentation de fragments de texte en ligne. */
-G_DEFINE_TYPE(GBufferLine, g_buffer_line, G_TYPE_OBJECT);
-
-
-
-/******************************************************************************
-* *
-* Paramètres : class = classe de composant GTK à initialiser. *
-* *
-* Description : Procède à l'initialisation d'une classe de représentation. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-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);
-
- class->entrypoint_img = cairo_image_surface_create_from_png(filename);
-
- g_free(filename);
-
- filename = find_pixmap_file("bookmark.png");
- assert(filename != NULL);
-
- class->bookmark_img = cairo_image_surface_create_from_png(filename);
-
- g_free(filename);
-
- g_signal_new("content-changed",
- G_TYPE_BUFFER_LINE,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(GBufferLineClass, content_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_OBJECT);
-
- g_signal_new("flip-flag",
- G_TYPE_BUFFER_LINE,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(GBufferLineClass, flip_flag),
- NULL, NULL,
- g_cclosure_user_marshal_VOID__ENUM_ENUM,
- G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = composant GTK à initialiser. *
-* *
-* Description : Procède à l'initialisation d'une représentation de fragments.*
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-static void g_buffer_line_init(GBufferLine *line)
-{
- BufferLineColumn i; /* Boucle de parcours */
-
- for (i = 0; i < BLC_COUNT; i++)
- init_line_column(&line->columns[i]);
-
- line->merge_start = BLC_COUNT;
- line->last_used = BLC_COUNT;
-
-}
-
-
-/******************************************************************************
-* *
-* 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)
-{
- size_t i; /* Boucle de parcours */
-
- for (i = 0; i < line->ocount; i++)
- g_object_unref(G_OBJECT(line->origins[i].creator));
-
- 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)
-{
- BufferLineColumn i; /* Boucle de parcours */
-
- for (i = 0; i < BLC_COUNT; i++)
- reset_line_column(&line->columns[i]);
-
- if (line->origins != NULL)
- free(line->origins);
-
- 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. *
-* *
-* Description : Crée une nouvelle représentation de fragments de texte. *
-* *
-* Retour : Composant GTK créé. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GBufferLine *g_buffer_line_new(const mrange_t *range, BufferLineColumn main)
-{
- GBufferLine *result; /* Composant à retourner */
-
- result = g_object_new(G_TYPE_BUFFER_LINE, NULL);
-
- copy_mrange(&result->range, range);
- result->main_column = main;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* *
-* Description : Indique la zone mémoire où se situe la ligne. *
-* *
-* Retour : Emplacement mémoire virtuel ou physique. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-const mrange_t *g_buffer_line_get_range(const GBufferLine *line)
-{
- return &line->range;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir compléter. *
-* size = taille souhaitée de l'impression des positions. *
-* addr = localisation physique à venir représenter. *
-* *
-* Description : Construit le tronc commun d'une ligne autour de sa position. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_fill_phys(GBufferLine *line, MemoryDataSize size, const vmpa2t *addr)
-{
- VMPA_BUFFER(position); /* Emplacement au format texte */
- size_t len; /* Taille de l'élément inséré */
- size_t i; /* Boucle de parcours #1 */
-
- vmpa2_phys_to_string(addr, size, position, &len);
-
- for (i = 2; i < len; i++)
- if (position[i] != '0') break;
-
- if (i == len)
- i = len - 1;
-
- if (i > 0)
- g_buffer_line_append_text(line, BLC_PHYSICAL, position, i, RTT_PHYS_ADDR_PAD, NULL);
-
- g_buffer_line_append_text(line, BLC_PHYSICAL, &position[i], len - i, RTT_PHYS_ADDR, NULL);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir compléter. *
-* size = taille souhaitée de l'impression des positions. *
-* addr = localisation virtuelle à venir représenter. *
-* *
-* Description : Construit le tronc commun d'une ligne autour de sa position. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_fill_virt(GBufferLine *line, MemoryDataSize size, const vmpa2t *addr)
-{
- VMPA_BUFFER(position); /* Emplacement au format texte */
- size_t len; /* Taille de l'élément inséré */
- size_t i; /* Boucle de parcours #1 */
-
- vmpa2_virt_to_string(addr, size, position, &len);
-
- if (has_virt_addr(addr))
- {
- for (i = 2; i < len; i++)
- if (position[i] != '0') break;
-
- if (i == len)
- i = len - 1;
-
- if (i > 0)
- g_buffer_line_append_text(line, BLC_VIRTUAL, position, i, RTT_VIRT_ADDR_PAD, NULL);
-
- g_buffer_line_append_text(line, BLC_VIRTUAL, &position[i], len - i, RTT_VIRT_ADDR, NULL);
-
- }
-
- else
- g_buffer_line_append_text(line, BLC_VIRTUAL, position, len, RTT_VIRT_ADDR_PAD, NULL);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir compléter. *
-* addr = localisation à afficher. *
-* psize = taille souhaitée de l'impression des positions. *
-* vsize = taille souhaitée de l'impression des adresses. *
-* *
-* Description : Construit le tronc commun d'une ligne autour de sa position. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_fill_vmpa(GBufferLine *line, const vmpa2t *addr, MemoryDataSize psize, MemoryDataSize vsize)
-{
- g_buffer_line_fill_phys(line, psize, addr);
-
- g_buffer_line_fill_virt(line, vsize, addr);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir compléter. *
-* content = contenu binaire global à venir lire. *
-* range = localisation des données à venir lire et présenter.*
-* max = taille maximale de la portion binaire en octets. *
-* *
-* Description : Construit le tronc commun d'une ligne autour de son contenu. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_fill_content(GBufferLine *line, const GBinContent *content, const mrange_t *range, phys_t max)
-{
- phys_t length; /* Taille de la couverture */
- bool truncated; /* Indique si le code est coupé*/
- size_t required; /* Taille de traitement requise*/
- char static_buffer[64]; /* Petit tampon local rapide */
- char *bin_code; /* Tampon utilisé pour le code */
- vmpa2t pos; /* Boucle de parcours #1 */
- phys_t i; /* Boucle de parcours #2 */
- char *iter; /* Boucle de parcours #3 */
- int ret; /* Progression dans l'écriture */
- uint8_t byte; /* Octet à représenter */
-
- static const char *charset = "0123456789abcdef";
-
- /* Détermination du réceptacle */
-
- length = get_mrange_length(range);
-
- truncated = (max != VMPA_NO_PHYSICAL && length > max);
-
- if (truncated)
- {
- length = max;
- required = length * 3 + 4 /* "..." */ + 1;
- }
- else
- required = length * 3 + 1;
-
- if (required <= sizeof(static_buffer))
- bin_code = static_buffer;
- else
- bin_code = (char *)calloc(required, sizeof(char));
-
- /* Code brut */
-
- copy_vmpa(&pos, get_mrange_addr(range));
-
- for (i = 0, iter = bin_code; i < length; i++, iter += ret)
- {
- if (i == 0)
- ret = 0;
- else
- {
- iter[0] = ' ';
- ret = 1;
- }
-
- if (!g_binary_content_read_u8(content, &pos, &byte))
- {
- iter[ret + 0] = '?';
- iter[ret + 1] = '?';
- }
- else
- {
- iter[ret + 0] = charset[byte >> 4];
- iter[ret + 1] = charset[byte & 0x0f];
- }
-
- ret += 2;
-
- }
-
- if (truncated)
- {
- strcpy(iter, "...");
- iter += 3;
- }
- else
- *iter = '\0';
-
- /* Conclusion */
-
- g_buffer_line_append_text(line, BLC_BINARY, bin_code, iter - bin_code, RTT_RAW_CODE, NULL);
-
- if (bin_code != static_buffer)
- free(bin_code);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* column = indice de la colonne visée par les recherches. *
-* *
-* Description : Recherche le premier créateur enregistré dans des segments. *
-* *
-* Retour : Créateur trouvé à déréférencer par la suite ou NULL si échec.*
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GObject *g_buffer_line_find_first_segment_creator(const GBufferLine *line, BufferLineColumn column)
-{
- GObject *result; /* Trouvaille à retourner */
- size_t i; /* Boucle de parcours */
-
- assert(column < BLC_COUNT);
-
- result = NULL;
-
- for (i = 0; i < line->ocount && result == NULL; i++)
- {
- if (line->origins[i].coord.column == column)
- result = line->origins[i].creator;
- }
-
- if (result != NULL)
- g_object_ref(G_OBJECT(result));
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir compléter. *
-* column = colonne de la ligne visée par l'insertion. *
-* text = texte à insérer dans l'existant. *
-* length = taille du texte à traiter. *
-* type = type de décorateur à utiliser. *
-* creator = instance GLib quelconque à associer. *
-* *
-* Description : Ajoute du texte à formater dans une ligne donnée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_append_text(GBufferLine *line, size_t column, const char *text, size_t length, RenderingTagType type, GObject *creator)
-{
- size_t index; /* Indice d'insertion */
- content_origin *origin; /* Définition d'une origine */
-
- assert(length > 0);
-
- if (column == -1)
- column = BLC_LAST_USED;
-
- if (column == BLC_MAIN)
- column = BLC_ASSEMBLY;//line->main_column;
-
- if (column == BLC_LAST_USED)
- column = line->last_used;
- else
- line->last_used = column;
-
- index = append_text_to_line_column(&line->columns[column], text, length, type);
-
- if (creator != NULL)
- {
- line->origins = (content_origin *)realloc(line->origins, ++line->ocount * sizeof(content_origin));
-
- origin = &line->origins[line->ocount - 1];
-
- origin->coord.column = column;
- origin->coord.index = index;
-
- origin->creator = creator;
- g_object_ref(G_OBJECT(creator));
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir compléter. *
-* creator = instance GLib quelconque identifiant un segment. *
-* text = texte à insérer dans l'existant. *
-* length = taille du texte à traiter. *
-* *
-* Description : Remplace du texte dans une ligne donnée. *
-* *
-* Retour : Bilan de l'opération. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_buffer_line_replace_text(GBufferLine *line, const GObject *creator, const char *text, size_t length)
-{
- bool result; /* Bilan à retourner */
- size_t i; /* Boucle de parcours */
- const col_coord_t *coord; /* Emplacement du contenu visé */
-
- result = false;
-
- for (i = 0; i < line->ocount && !result; i++)
- {
- if (line->origins[i].creator == creator)
- {
- coord = &line->origins[i].coord;
-
- replace_text_in_line_column(&line->columns[coord->column], coord->index, text, length);
-
- g_signal_emit_by_name(line, "content-changed", NULL);
-
- result = true;
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* first = première colonne à parcourir. *
-* end = colonne de fin de parcours. *
-* *
-* Description : Indique si du texte est présent dans une ligne de tampon. *
-* *
-* Retour : true pour indiquer la présence de texte, false pour du vide. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_buffer_line_has_text(const GBufferLine *line, BufferLineColumn first, BufferLineColumn end)
-{
- bool result; /* Bilan à retourner */
- BufferLineColumn i; /* Boucle de parcours */
-
- result = false;
-
- assert(first < end);
-
- for (i = first; i < end && !result; i++)
- result = (line->columns[i].count > 0);
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* first = première colonne à parcourir. *
-* end = colonne de fin de parcours. *
-* markup = indique si le texte doit être décoré ou non. *
-* *
-* Description : Donne le texte représenté par une ligne de tampon. *
-* *
-* Retour : Texte à libérer de la mémoire après usage. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-char *g_buffer_line_get_text(const GBufferLine *line, BufferLineColumn first, BufferLineColumn end, bool markup)
-{
- char *result; /* Construction à retourner */
- BufferLineColumn i; /* Boucle de parcours */
- char *extra; /* Contenu à intégrer au texte */
-
- result = NULL;
-
- assert(first < end);
-
- for (i = first; i < end; i++)
- {
- if (i > first && result != NULL)
- result = stradd(result, " ");
-
- extra = get_line_column_text(&line->columns[i], markup);
-
- /* Si la colonne était vide, suivante ! */
- if (extra == NULL) continue;
-
- if (result == NULL)
- result = extra;
-
- else
- {
- result = stradd(result, extra);
- free(extra);
- }
-
- }
-
- return result;
-
-}
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir modifier. *
-* first = première colonne à parcourir. *
-* end = colonne de fin de parcours. *
-* *
-* Description : Supprime du texte représenté par une ligne de tampon. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_delete_text(GBufferLine *line, BufferLineColumn first, BufferLineColumn end)
-{
- BufferLineColumn i; /* Boucle de parcours #1 */
-
- assert(first < end);
-
- for (i = first; i < end; i++)
- reset_line_column(&line->columns[i]);
-
-}
-
-
-/******************************************************************************
-* *
-* 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. *
-* *
-* 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)
-{
- if (start == BLC_LAST_USED)
- line->merge_start = line->last_used;
- else
- line->merge_start = start;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir compléter. *
-* flag = propriété à intégrer. *
-* *
-* Description : Ajoute une propriété particulière à une ligne donnée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_add_flag(GBufferLine *line, BufferLineFlags flag)
-{
- if ((line->flags & flag) == 0)
- {
- g_signal_emit_by_name(line, "flip-flag", line->flags, flag);
-
- line->flags |= flag;
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* *
-* Description : Renseigne sur les propriétés particulières liées à une ligne.*
-* *
-* Retour : Propriétés intégrées. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-BufferLineFlags g_buffer_line_get_flags(const GBufferLine *line)
-{
- return line->flags;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir compléter. *
-* flag = propriété à supprimer. *
-* *
-* Description : Retire une propriété particulière à une ligne donnée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_remove_flag(GBufferLine *line, BufferLineFlags flag)
-{
- if ((line->flags & flag) != 0)
- {
- g_signal_emit_by_name(line, "flip-flag", line->flags, flag);
-
- line->flags &= ~flag;
-
- }
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne de texte à manipuler. *
-* ctx = éléments à disposition pour l'exportation. *
-* type = type d'exportation attendue. *
-* display = règles d'affichage des colonnes modulables. *
-* *
-* Description : Exporte la ligne de texte représentée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_export(GBufferLine *line, buffer_export_context *ctx, BufferExportType type, const bool *display)
-{
- BufferLineColumn i; /* Boucle de parcours */
- int col_span; /* Fusion de colonnes ? */
-
- switch (type)
- {
- case BET_HTML:
- dprintf(ctx->fd, "\t<TR>\n");
- break;
- default:
- break;
- }
-
- for (i = 0; i < BLC_COUNT; i++)
- {
- if (i < BLC_DISPLAY && !display[i]) continue;
-
- switch (type)
- {
- case BET_TEXT:
- if (i > 0) dprintf(ctx->fd, "%s", ctx->sep);
- break;
- default:
- break;
- }
-
- /**
- * Pour la signification des différentes valeurs assignées,
- * se référer au code de export_line_column_segments().
- *
- * En gros :
- * - 1 = rien de spécial.
- * - >1 = il s'agit de la première cellule fusionnée de la ligne.
- * - 0 = fusion déjà faite, on ne peut que rajouter du contenu dedans.
- * - <1 = il s'agit de la dernière cellule fusionnée de la ligne.
- *
- * On considère qu'une fusion ne peut pas se réaliser sur la dernière
- * cellule uniquement (ce qui a du sens : c'est inutile).
- */
-
- if (i < line->merge_start)
- col_span = 1;
-
- else if (i == line->merge_start)
- col_span = BLC_COUNT - i;
-
- else
- col_span = ((i + 1) == BLC_COUNT ? -1 : 0);
-
- export_line_column_segments(&line->columns[i], ctx, type, col_span);
-
- }
-
- switch (type)
- {
- case BET_TEXT:
- dprintf(ctx->fd, "\n");
- break;
- case BET_HTML:
- dprintf(ctx->fd, "</TR>\n");
- break;
- default:
- break;
- }
-
-}
-
-
-
-/*----------------------------------------------------------------------------------- */
-/* MANIPULATION DES LARGEURS REQUISES */
-/* ---------------------------------------------------------------------------------- */
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* summary = largeurs maximales à faire évoluer. *
-* *
-* Description : Fait remonter les largeurs requises par une ligne donnée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_collect_widths(GBufferLine *line, line_width_summary *summary)
-{
- gint merged_width; /* Largeur cumulée avant fusion*/
- BufferLineColumn i; /* Boucle de parcours */
- gint width; /* Largeur d'une colonne */
-
- merged_width = 0;
-
- for (i = 0; i < BLC_COUNT; i++)
- {
- width = get_column_width(&line->columns[i]);
-
- if (i < line->merge_start)
- summary->max_widths[i] = MAX(summary->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)
- summary->merged_width = MAX(summary->merged_width, merged_width);
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* index = indice de la colonne visée. *
-* summary = résumé des largeurs maximales. *
-* offsets = décalages supplémentaires à appliquer. *
-* *
-* 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 line_width_summary *summary, const line_width_summary *offsets)
-{
- gint result; /* Largeur à retourner */
-
- assert(index < BLC_COUNT);
-
- if (index >= line->merge_start)
- result = get_column_width(&line->columns[index]);
-
- else
- result = summary->max_widths[index];
-
- if (result < offsets->max_widths[index])
- result = offsets->max_widths[index];
-
- return result;
-
-}
-
-
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* coord = coordonnées interne du segment à retrouver. *
-* *
-* Description : Fournit le segment présent à une position donnée. *
-* *
-* Retour : Segment trouvé ou NULL si hors borne. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-line_segment *g_buffer_line_get_segment_from_coord(const GBufferLine *line, const col_coord_t *coord)
-{
- line_segment *result; /* Trouvaille à retourner */
-
- if (coord->column < BLC_COUNT)
- result = get_line_column_content_from_index(&line->columns[coord->column], coord->index);
- else
- result = NULL;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* summary = résumé des largeurs maximales. *
-* options = règles d'affichage des colonnes modulables. *
-* offsets = décalages supplémentaires à appliquer. *
-* base = position jusqu'au segment trouvé. [OUT] *
-* offset = position à la colonne visée. [OUT] *
-* dir = direction d'un éventuel déplacement en cours. *
-* force = accepte les segments en bordure au pire. *
-* coord = cordonnées à usage interne à renseigner. [OUT] *
-* *
-* Description : Fournit les coordonnées correspondant à une abscisse donnée. *
-* *
-* Retour : true si des coordonnées valides ont été renseignées. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_buffer_line_get_coord_at(const GBufferLine *line, const line_width_summary *summary, const GDisplayOptions *options, const line_width_summary *offsets, gint *base, gint *offset, GdkScrollDirection dir, bool force, col_coord_t *coord)
-{
- bool result; /* Bilan à retourner */
- BufferLineColumn last; /* Dernière colonne remplie */
- gint last_base; /* Dernière abscisse associée */
- size_t count; /* Qté de colonnes en option */
- size_t i; /* Boucle de parcours */
- gint width; /* Largeur d'une colonne donnée*/
- gint limit; /* Limite d'appartenance */
- gint consumed; /* Distance vers le segment */
- gint old_base; /* Somme de toutes les largeurs*/
-
- result = false;
-
- *base = 0;
-
- last = BLC_COUNT;
- last_base = 0;
-
- /* On cible déjà la colonne idéale */
-
- count = g_display_options_count(options);
-
- for (i = 0; i < BLC_COUNT; i++)
- {
- if (i < count)
- {
- if (!g_display_options_get(options, i))
- continue;
- }
-
- /* Mémorisation de la dernière colonne contenant quelque chose... */
- if (get_column_width(&line->columns[i]) > 0)
- {
- last = i;
- last_base = *base;
- }
-
- if (i < line->merge_start)
- {
- width = g_buffer_line_compute_max_width(line, i, summary, offsets);
-
- /* Si la colonne n'est absolument pas visible, on ne s'arrête pas dessus ! */
- if (width == 0) continue;
-
- if ((i + 1) < BLC_COUNT) limit = width + COL_MARGIN / 2;
- else limit = width;
-
- if (*offset <= limit) break;
- else
- {
- *offset -= width + COL_MARGIN;
- *base += width + COL_MARGIN;
- }
-
- }
- else
- {
- width = get_column_width(&line->columns[i]);
-
- if (*offset <= width) break;
- else
- {
- *offset -= width;
- *base += width;
- }
-
- }
-
-
- }
-
- /* Si l'abscisse fournie tombe encore dans une colonne... */
-
- if (i < BLC_COUNT)
- {
- /* Il y a bien du contenu dans cette colonne */
-
- if (get_column_width(&line->columns[i]) > 0)
- {
- /**
- * Si la position était au milieu d'une marge, la sélection a pu pousser
- * jusqu'à la colonne suivante, plus proche.
- * Relativment à la base de cette dernière, la position est donc devenue négative.
- */
- if (*offset < 0) *offset = 0;
-
- result = get_line_column_content_index_at(&line->columns[i], offset, dir, &consumed, &coord->index);
-
- if (result)
- {
- coord->column = i;
-
- *base += consumed;
-
- }
-
- }
-
- /* La position fournie tombe dans une colonne vide ! */
-
- else
- {
- if (force || get_column_width(&line->columns[i]) == 0)
- {
- result = false;
- *offset = 0;
-
- old_base = *base;
-
- for (i++; i < BLC_COUNT && !result; i++)
- {
- if ((i - 1) < line->merge_start)
- {
- width = g_buffer_line_compute_max_width(line, i - 1, summary, offsets);
-
- if (width > 0)
- *base += (width + COL_MARGIN);
-
- }
- else
- *base += get_column_width(&line->columns[i - 1]);
-
- result = get_line_column_first_content_index(&line->columns[i], &coord->index);
-
- if (result)
- coord->column = i;
-
- }
-
- if (!result)
- {
- *base = old_base;
- goto use_right_border;
- }
-
- }
-
- }
-
- }
-
- else /* if (i == BLC_COUNT) */
- {
- if (force)
- {
- use_right_border:
-
- if (last != BLC_COUNT)
- {
- result = get_line_column_last_content_index(&line->columns[last], &coord->index);
-
- if (result)
- {
- coord->column = last;
-
- *base = last_base;
- *offset = get_column_width(&line->columns[last]);
-
- }
-
- }
-
- /* Il n'y a rien sur la ligne ! */
- else
- {
- result = true;
-
- *base = 0;
- *offset = 0;
-
- coord->column = BLC_COUNT;
- coord->index = -1;
-
- }
-
- }
- else
- result = false;
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* summary = résumé des largeurs maximales. *
-* options = règles d'affichage des colonnes modulables. *
-* offsets = décalages supplémentaires à appliquer. *
-* base = position jusqu'au segment trouvé. [OUT] *
-* offset = position à la colonne visée. [OUT] *
-* dir = direction d'un éventuel déplacement en cours. *
-* force = accepte les segments en bordure au pire. *
-* *
-* Description : Donne le segment présent à une abscisse donnée. *
-* *
-* Retour : Segment trouvé ou NULL si hors borne. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-line_segment *g_buffer_line_get_segment_at(const GBufferLine *line, const line_width_summary *summary, const GDisplayOptions *options, const line_width_summary *offsets, gint *base, gint *offset, GdkScrollDirection dir, bool force)
-{
- line_segment *result; /* Trouvaille à retourner */
- col_coord_t coord; /* Emplacement du contenu visé */
- bool status; /* Bilan de la localisation */
-
- status = g_buffer_line_get_coord_at(line, summary, options, offsets, base, offset, dir, force, &coord);
-
- if (status)
- result = g_buffer_line_get_segment_from_coord(line, &coord);
- else
- result = NULL;
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* summary = résumé des largeurs maximales. *
-* options = règles d'affichage des colonnes modulables. *
-* offsets = décalages supplémentaires à appliquer. *
-* base = position jusqu'au segment trouvé. [OUT] *
-* offset = position à la colonne visée. [OUT] *
-* dir = direction d'un éventuel déplacement en cours. *
-* force = accepte les segments en bordure au pire. *
-* *
-* Description : Donne le créateur présent à une abscisse donnée. *
-* *
-* Retour : Créateur trouvé ou NULL si hors borne. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-GObject *g_buffer_line_get_creator_at(const GBufferLine *line, const line_width_summary *summary, const GDisplayOptions *options, const line_width_summary *offsets, gint *base, gint *offset, GdkScrollDirection dir, bool force)
-{
- GObject *result; /* Trouvaille à retourner */
- col_coord_t target; /* Emplacement du contenu visé */
- bool status; /* Bilan de la localisation */
- size_t i; /* Boucle de parcours */
- const col_coord_t *coord; /* Emplacement du contenu visé */
-
- result = NULL;
-
- status = g_buffer_line_get_coord_at(line, summary, options, offsets, base, offset, dir, force, &target);
-
- if (status)
- {
- for (i = 0; i < line->ocount && result == NULL; i++)
- {
- coord = &line->origins[i].coord;
-
- if (coord->column == target.column && coord->index == target.index)
- result = line->origins[i].creator;
-
- }
-
- if (result != NULL)
- g_object_ref(G_OBJECT(result));
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne à venir consulter. *
-* coord = cordonnées à consulter puis renseigner. [OUT] *
-* summary = résumé des largeurs maximales. *
-* options = règles d'affichage des colonnes modulables. *
-* offsets = décalages supplémentaires à appliquer. *
-* dir = orientation des recherches. *
-* offset = décalage pour amener à l'extrémité nouvelle. [OUT] *
-* *
-* Description : Fournit des coordonnées voisines selon une direction donnée. *
-* *
-* Retour : true si des coordonnées valides ont été renseignées. *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-bool g_buffer_line_find_near_coord(const GBufferLine *line, col_coord_t *coord, const line_width_summary *summary, const GDisplayOptions *options, const line_width_summary *offsets, GdkScrollDirection dir, gint *offset)
-{
- bool result; /* Bilan à retourner */
- size_t count; /* Qté de colonnes en option */
- size_t i; /* Boucle de parcours #1 */
- bool displayed; /* Confort de lecture */
- size_t k; /* Boucle de parcours #2 */
- gint width; /* Largeur d'une colonne donnée*/
-
- result = false;
-
- /* Recherche dans la colonne de départ */
-
- i = coord->column;
-
- if (i == BLC_COUNT) return false;
-
- result = find_near_segment(&line->columns[i], &coord->index, dir);
-
- /* Recherche dans la direction des colonnes voisines */
-
- count = g_display_options_count(options);
-
- if (!result)
- switch (dir)
- {
- case GDK_SCROLL_LEFT:
-
- /* Si on a atteint la première colonne sans trouver... */
- if (i == 0) break;
-
- /* On s'assure que la colonne précédente est visible et peuplée */
- for (; i > BLC_FIRST && !result; i--)
- {
- displayed = (i <= count ? g_display_options_get(options, i - 1) : true);
-
- if (displayed)
- {
- result = get_line_column_first_content_index(&line->columns[i - 1], &coord->index);
-
- if (result)
- coord->column = i - 1;
-
- }
-
- }
-
- break;
-
- case GDK_SCROLL_RIGHT:
-
- /* On s'assure que la colonne suivante est visible et peuplée */
- for (; (i + 1) < BLC_COUNT && !result; i++)
- {
- displayed = ((i + 1) < count ? g_display_options_get(options, i + 1) : true);
-
- if (displayed)
- {
- result = get_line_column_first_content_index(&line->columns[i + 1], &coord->index);
-
- if (result)
- coord->column = i + 1;
-
- }
-
- }
-
- break;
-
- default:
- break;
-
- }
-
- /* Calcul de la position finale */
-
- if (result)
- {
- *offset = 0;
-
- for (k = 0; k < i; k++)
- {
- displayed = (k < count ? g_display_options_get(options, k) : true);
-
- if (displayed)
- {
- width = g_buffer_line_compute_max_width(line, k, summary, offsets);
-
- if (width > 0)
- {
- *offset += width;
- if (k < line->merge_start) *offset += COL_MARGIN;
- }
-
- }
-
- }
-
- switch (dir)
- {
- case GDK_SCROLL_LEFT:
- *offset += get_column_width(&line->columns[i]);
- break;
-
- case GDK_SCROLL_RIGHT:
- /**offset += 0;*/
- break;
-
- default:
- break;
-
- }
-
- }
-
- return result;
-
-}
-
-
-/******************************************************************************
-* *
-* Paramètres : line = ligne de texte à manipuler. *
-* cairo = contexte graphique à utiliser pour les pinceaux. *
-* summary = résumé des largeurs maximales. *
-* x_init = abscisse du point d'impression de départ. *
-* y = ordonnée du point d'impression. *
-* options = règles d'affichage des colonnes modulables. *
-* offsets = décalages supplémentaires à appliquer. *
-* list = liste de contenus à mettre en évidence. *
-* *
-* Description : Imprime la ligne de texte représentée. *
-* *
-* Retour : - *
-* *
-* Remarques : - *
-* *
-******************************************************************************/
-
-void g_buffer_line_draw(GBufferLine *line, cairo_t *cairo, const line_width_summary *summary, gint x_init, gint y, const GDisplayOptions *options, const line_width_summary *offsets, const segcnt_list *list)
-{
- GBufferLineClass *class; /* Stockage de briques de base */
- bool has_src_surface; /* Note une présence définie */
- gint x; /* Point de départ d'impression*/
- size_t count; /* Qté de colonnes en option */
- size_t i; /* Boucle de parcours */
- gint max_width; /* Largeur maximale de colonne */
-
- if (line->flags != BLF_NONE && line->flags != BLF_HAS_CODE)
- {
- class = G_BUFFER_LINE_GET_CLASS(line);
-
- if (line->flags & BLF_ENTRYPOINT)
- {
- cairo_set_source_surface(cairo, class->entrypoint_img, 5, y);
- has_src_surface = true;
- }
- else if (line->flags & BLF_BOOKMARK)
- {
- cairo_set_source_surface(cairo, class->bookmark_img, 5, y);
- has_src_surface = true;
- }
- else
- has_src_surface = false;
-
- if (has_src_surface)
- cairo_paint(cairo);
-
- }
-
- x = x_init;
-
- count = g_display_options_count(options);
-
- for (i = 0; i < BLC_COUNT; i++)
- {
- if (i < count)
- {
- if (!g_display_options_get(options, i))
- continue;
- }
-
- draw_line_column_segments(&line->columns[i], cairo, x, y, list);
-
- if (i < line->merge_start)
- {
- max_width = g_buffer_line_compute_max_width(line, i, summary, offsets);
-
- if (max_width > 0)
- x += max_width + COL_MARGIN;
-
- }
-
- }
-
-}