From 8c94dfe5c836741807a93ced0ef90861097e61d3 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Mon, 18 Feb 2019 18:46:19 +0100
Subject: Reorganized code.

---
 src/gtkext/graph/cluster.c | 994 ++++++++++++++++++++++-----------------------
 1 file changed, 497 insertions(+), 497 deletions(-)

diff --git a/src/gtkext/graph/cluster.c b/src/gtkext/graph/cluster.c
index 765bbac..16afe57 100644
--- a/src/gtkext/graph/cluster.c
+++ b/src/gtkext/graph/cluster.c
@@ -97,6 +97,57 @@ static int cmp_incoming_links(const incoming_link_t **, const incoming_link_t **
 
 
 
+/* ------------------------ ENCADREMENTS D'ESPACES VERTICAUX ------------------------ */
+
+
+/* Réservations d'espaces latéraux */
+typedef struct _vspace_booking_t
+{
+    leaving_link_t *from;                   /* Bloc de départ du lien      */
+    incoming_link_t *to;                    /* Bloc d'arrivée du lien      */
+
+    GdkPoint *pts;                          /* Coordonnées des points      */
+
+} vspace_booking_t;
+
+/* Réservations d'espaces latéraux */
+typedef struct _vspace_manager_t
+{
+    vspace_booking_t *pending;              /* Besoins exprimés            */
+    size_t pending_count;                   /* Nombre de ces besoins       */
+
+    vspace_booking_t **left;                /* Lignes disposées à gauche   */
+    size_t left_count;                      /* Quantité de ces lignes      */
+
+    vspace_booking_t **right;               /* Lignes disposées à droite  */
+    size_t right_count;                     /* Quantité de ces lignes      */
+
+} vspace_manager_t;
+
+
+/* Initialise les réservations liens verticaux. */
+static void init_vspace_manager(vspace_manager_t *);
+
+/* Termine les réservations liens verticaux. */
+static void exit_vspace_manager(vspace_manager_t *);
+
+/* Inscrit une nouvelle réservation d'espace latéral. */
+static void extend_vspace_manager(vspace_manager_t *, leaving_link_t *, incoming_link_t *, GdkPoint *);
+
+/* Détermine l'emplacement requis pour les espaces latéraux. */
+static void compute_vspace_manager_needed_alloc(const vspace_manager_t *, GtkAllocation *);
+
+/* Réorganise au besoin les liens de boucle entre blocs. */
+static void sort_incoming_links_for_vspace_manager(vspace_manager_t *);
+
+/* Détermine les abscisses de tous les liens en place. */
+static void compute_loop_link_x_with_vspace_manager(vspace_manager_t *, GGraphCluster *);
+
+/* Détermine les ordonnées de tous les liens en place. */
+static void compute_loop_link_y_with_vspace_manager(vspace_manager_t *, GGraphCluster *);
+
+
+
 /* ---------------------- DESCENDANTS DIRECTS CLASSES PAR RANG ---------------------- */
 
 
@@ -175,57 +226,6 @@ static void set_y_for_graph_rank(const graph_rank_t *, gint *);
 
 
 
-/* ------------------------ ENCADREMENTS D'ESPACES VERTICAUX ------------------------ */
-
-
-/* Réservations d'espaces latéraux */
-typedef struct _vspace_booking_t
-{
-    leaving_link_t *from;                   /* Bloc de départ du lien      */
-    incoming_link_t *to;                    /* Bloc d'arrivée du lien      */
-
-    GdkPoint *pts;                          /* Coordonnées des points      */
-
-} vspace_booking_t;
-
-/* Réservations d'espaces latéraux */
-typedef struct _vspace_manager_t
-{
-    vspace_booking_t *pending;              /* Besoins exprimés            */
-    size_t pending_count;                   /* Nombre de ces besoins       */
-
-    vspace_booking_t **left;                /* Lignes disposées à gauche   */
-    size_t left_count;                      /* Quantité de ces lignes      */
-
-    vspace_booking_t **right;               /* Lignes disposées à droite  */
-    size_t right_count;                     /* Quantité de ces lignes      */
-
-} vspace_manager_t;
-
-
-/* Initialise les réservations liens verticaux. */
-static void init_vspace_manager(vspace_manager_t *);
-
-/* Termine les réservations liens verticaux. */
-static void exit_vspace_manager(vspace_manager_t *);
-
-/* Inscrit une nouvelle réservation d'espace latéral. */
-static void extend_vspace_manager(vspace_manager_t *, leaving_link_t *, incoming_link_t *, GdkPoint *);
-
-/* Détermine l'emplacement requis pour les espaces latéraux. */
-static void compute_vspace_manager_needed_alloc(const vspace_manager_t *, GtkAllocation *);
-
-/* Réorganise au besoin les liens de boucle entre blocs. */
-static void sort_incoming_links_for_vspace_manager(vspace_manager_t *);
-
-/* Détermine les abscisses de tous les liens en place. */
-static void compute_loop_link_x_with_vspace_manager(vspace_manager_t *, GGraphCluster *);
-
-/* Détermine les ordonnées de tous les liens en place. */
-static void compute_loop_link_y_with_vspace_manager(vspace_manager_t *, GGraphCluster *);
-
-
-
 /* -------------------------- DEFINITION D'UN CHEF DE FILE -------------------------- */
 
 
@@ -592,109 +592,104 @@ static int cmp_incoming_links(const incoming_link_t **a, const incoming_link_t *
 
 
 /* ---------------------------------------------------------------------------------- */
-/*                        DESCENDANTS DIRECTS CLASSES PAR RANG                        */
+/*                          ENCADREMENTS D'ESPACES VERTICAUX                          */
 /* ---------------------------------------------------------------------------------- */
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : start = abscisse de départ de ligne.                         *
+*  Paramètres  : manager = structure à initialiser.                           *
 *                                                                             *
-*  Description : Prépare une réservation d'espace pour ligne horizontale.     *
+*  Description : Initialise les réservations liens verticaux.                 *
 *                                                                             *
-*  Retour      : Structure mise en place pour la conservation d'informations. *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static hspace_booking *create_hspace_booking(gint start)
+static void init_vspace_manager(vspace_manager_t *manager)
 {
-    hspace_booking *result;                 /* Structure à retourner       */
-
-    result = malloc(sizeof(hspace_booking));
+    manager->pending = NULL;
+    manager->pending_count = 0;
 
-    result->start = start;
+    manager->left = NULL;
+    manager->left_count = 0;
 
-    return result;
+    manager->right = NULL;
+    manager->right_count = 0;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : a = première réservation d'espace à comparer.                *
-*                b = seconde réservation d'espace à comparer.                 *
+*  Paramètres  : manager = structure à vider.                                 *
 *                                                                             *
-*  Description : Compare deux réservations d'espace.                          *
+*  Description : Termine les réservations liens verticaux.                    *
 *                                                                             *
-*  Retour      : Bilan de comparaison.                                        *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static int cmp_hspace_booking_r2l(const hspace_booking **a, const hspace_booking **b)
+static void exit_vspace_manager(vspace_manager_t *manager)
 {
-    int result;                             /* Bilan à retourner           */
+    size_t i;                               /* Boucle de parcours          */
 
-    if ((*a)->start > (*b)->start)
-        result = -1;
+    for (i = 0; i < manager->pending_count; i++)
+        free(manager->pending[i].pts);
 
-    else if ((*a)->start < (*b)->start)
-        result = 1;
+    if (manager->pending != NULL)
+        free(manager->pending);
 
-    else
-    {
-        assert(false);
-        result = 0;
-    }
+    if (manager->left != NULL)
+        free(manager->left);
 
-    return result;
+    if (manager->right != NULL)
+        free(manager->right);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : a = première réservation d'espace à comparer.                *
-*                b = seconde réservation d'espace à comparer.                 *
+*  Paramètres  : manager = structure à compléter.                             *
+*                from    = point de départ du lien concerné.                  *
+*                to      = point d'arrivée du lien concerné.                  *
+*                pts     = points intermédiaires du tracé complet final.      *
 *                                                                             *
-*  Description : Compare deux réservations d'espace.                          *
+*  Description : Inscrit une nouvelle réservation d'espace latéral.           *
 *                                                                             *
-*  Retour      : Bilan de comparaison.                                        *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static int cmp_hspace_booking_l2r(const hspace_booking **a, const hspace_booking **b)
+static void extend_vspace_manager(vspace_manager_t *manager, leaving_link_t *from, incoming_link_t *to, GdkPoint *pts)
 {
-    int result;                             /* Bilan à retourner           */
+    vspace_booking_t *new;                  /* Réservation à constituer    */
 
-    if ((*a)->start < (*b)->start)
-        result = -1;
+    manager->pending = realloc(manager->pending, ++manager->pending_count * sizeof(vspace_booking_t));
 
-    else if ((*a)->start > (*b)->start)
-        result = 1;
+    new = &manager->pending[manager->pending_count - 1];
 
-    else
-    {
-        assert(false);
-        result = 0;
-    }
+    new->from = from;
+    new->to = to;
 
-    return result;
+    new->pts = pts;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank   = structure à initialiser. [OUT]                     *
-*                cluster = chef de file d'un ensemble de blocs.               *
+*  Paramètres  : manager = gestion des espaces latéraux à consulter.          *
+*                alloc   = emplacement idéal pour l'affichage. [OUT]          *
 *                                                                             *
-*  Description : Initialise la gestion d'un ensemble de blocs de même rang.   *
+*  Description : Détermine l'emplacement requis pour les espaces latéraux.    *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -702,27 +697,33 @@ static int cmp_hspace_booking_l2r(const hspace_booking **a, const hspace_booking
 *                                                                             *
 ******************************************************************************/
 
-static void init_graph_rank(graph_rank_t *grank, GGraphCluster *cluster)
+static void compute_vspace_manager_needed_alloc(const vspace_manager_t *manager, GtkAllocation *alloc)
 {
-    grank->right2left = NULL;
-    grank->r2l_count = 0;
+    gint width;                             /* Largeur supplémentaire      */
 
-    grank->left2right = NULL;
-    grank->l2r_count = 0;
+    /* Extension de la largeur */
 
-    grank->clusters = malloc(sizeof(GGraphCluster *));
-    grank->count = 1;
+    width = 0;
 
-    grank->clusters[0] = cluster;
+    width += manager->left_count * LINK_MARGIN;
+
+    width += manager->right_count * LINK_MARGIN;
+
+    alloc->x -= width / 2;
+    alloc->width += width;
+
+    /* Extension de la hauteur */
+
+    alloc->height += manager->pending_count * VERTICAL_MARGIN;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank = structure à vider.                                   *
+*  Paramètres  : manager = gestion d'espaces latéraux à manipuler.            *
 *                                                                             *
-*  Description : Termine la gestion d'un ensemble de blocs de même rang.      *
+*  Description : Réorganise au besoin les liens de boucle entre blocs.        *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -730,34 +731,46 @@ static void init_graph_rank(graph_rank_t *grank, GGraphCluster *cluster)
 *                                                                             *
 ******************************************************************************/
 
-static void exit_graph_rank(graph_rank_t *grank)
+static void sort_incoming_links_for_vspace_manager(vspace_manager_t *manager)
 {
     size_t i;                               /* Boucle de parcours          */
+    vspace_booking_t *pending;              /* Elément traité              */
+    gint x1;                                /* Abscisse de départ de lien  */
+    size_t idx;                             /* Indice du lien entrant      */
+    gint x2;                                /* Abscisse d'arrivée de lien  */
 
-    for (i = 0; i < grank->r2l_count; i++)
-        free(grank->right2left[i]);
+    for (i = 0; i < manager->pending_count; i++)
+    {
+        pending = &manager->pending[i];
 
-    if (grank->right2left != NULL)
-        free(grank->right2left);
+        x1 = g_graph_cluster_compute_leaving_link_position(pending->from->owner, pending->from->index);
 
-    for (i = 0; i < grank->l2r_count; i++)
-        free(grank->left2right[i]);
+        idx = g_graph_cluster_find_incoming_link(pending->to->owner, pending->from);
 
-    if (grank->left2right != NULL)
-        free(grank->left2right);
+        x2 = g_graph_cluster_compute_incoming_link_position(pending->to->owner, idx);
 
-    assert(grank->clusters != NULL);
+        if (x1 < x2)
+        {
+            manager->left = realloc(manager->left, ++manager->left_count * sizeof(vspace_booking_t *));
+            manager->left[manager->left_count - 1] = pending;
+        }
+        else
+        {
+            manager->right = realloc(manager->right, ++manager->right_count * sizeof(vspace_booking_t *));
+            manager->right[manager->right_count - 1] = pending;
+        }
 
-    free(grank->clusters);
+    }
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank = ensemble de même rang à consulter.                   *
+*  Paramètres  : manager = structure à consulter.                             *
+*                cluster = graphique de blocs sur lequel s'appuyer.           *
 *                                                                             *
-*  Description : Assigne à un ensemble de blocs un emplacement initial.       *
+*  Description : Détermine les abscisses de tous les liens en place.          *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -765,33 +778,144 @@ static void exit_graph_rank(graph_rank_t *grank)
 *                                                                             *
 ******************************************************************************/
 
-static void reset_graph_rank_allocation(const graph_rank_t *grank)
+static void compute_loop_link_x_with_vspace_manager(vspace_manager_t *manager, GGraphCluster *cluster)
 {
+    GtkAllocation needed;                   /* Espace nécessaire et alloué */
     size_t i;                               /* Boucle de parcours          */
+    vspace_booking_t *booking;              /* Réservation à traiter       */
+    gint x;                                 /* Position à appliquer        */
+    GGraphCluster *container;               /* Parent direct à décaler     */
+
+    g_graph_cluster_compute_needed_alloc(cluster, &needed);
+
+    for (i = 0; i < manager->left_count; i++)
+    {
+        booking = manager->left[i];
+
+        x = i * LINK_MARGIN;
+
+        booking->pts[0].x = needed.x + x;
+        booking->pts[1].x = needed.x + x;
+
+    }
+
+    if (manager->left_count > 0)
+    {
+        x = manager->left_count * LINK_MARGIN;
+
+        /**
+         * Si la routine est une boucle sans fin,
+         * alors la boucle peut renvoyer vers le premier bloc.
+         */
+        if (cluster->owner != NULL)
+        {
+            container = cluster->owner;
+
+            /**
+             * On recherche le plus haut propritétaire bénéficiant d'une chaîne
+             * de liens directs et droits, histoire de transmettre le décalage
+             * et de garder ces liens bien verticaux.
+             */
+            while (container->owner != NULL)
+            {
+                if (!container->owner->has_straight)
+                    break;
+
+                if (container->owner->straight_index != *container->parent_index)
+                    break;
+
+                container = container->owner;
+
+            }
+
+            g_graph_cluster_offset_x(container, x);
+
+        }
+
+    }
+
+    for (i = 0; i < manager->right_count; i++)
+    {
+        booking = manager->right[i];
+
+        x = (i + 1) * LINK_MARGIN;
+
+        booking->pts[0].x = x;
+        booking->pts[1].x = x;
+
+    }
 
-    for (i = 0; i < grank->count; i++)
-        g_graph_cluster_reset_allocation(grank->clusters[i]);
-
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank = ensemble de même rang à consulter.                   *
+*  Paramètres  : manager = structure à consulter.                             *
+*                cluster = graphique de blocs sur lequel s'appuyer.           *
 *                                                                             *
-*  Description : Fournit le rang d'un ensemble de blocs.                      *
+*  Description : Détermine les ordonnées de tous les liens en place.          *
 *                                                                             *
-*  Retour      : Rang d'un ensemble de blocs de même rang.                    *
+*  Retour      : -                                                            *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static size_t get_graph_rank(const graph_rank_t *grank)
+static void compute_loop_link_y_with_vspace_manager(vspace_manager_t *manager, GGraphCluster *cluster)
 {
-    size_t result;                          /* Rang à retourner            */
+    GtkAllocation needed;                   /* Espace nécessaire et alloué */
+    size_t i;                               /* Boucle de parcours          */
+    vspace_booking_t *booking;              /* Réservation à traiter       */
 
-    result = g_code_block_get_rank(grank->clusters[0]->block);
+    g_graph_cluster_compute_needed_alloc(cluster, &needed);
+
+    for (i = 0; i < manager->pending_count; i++)
+    {
+        booking = &manager->pending[i];
+
+        /**
+         * On corrige le raccourci pris sans distinction de type de lien dans
+         * la fonction g_graph_cluster_compute_link_y_positions().
+         */
+
+        booking->from->start[1].y = needed.y + needed.height;
+
+        /* Définition de l'ordonnée des points du lien */
+
+        booking->pts[0].y = booking->from->start[1].y;
+
+        booking->pts[1].y = booking->to->end[0].y;
+
+    }
+
+}
+
+
+
+/* ---------------------------------------------------------------------------------- */
+/*                        DESCENDANTS DIRECTS CLASSES PAR RANG                        */
+/* ---------------------------------------------------------------------------------- */
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : start = abscisse de départ de ligne.                         *
+*                                                                             *
+*  Description : Prépare une réservation d'espace pour ligne horizontale.     *
+*                                                                             *
+*  Retour      : Structure mise en place pour la conservation d'informations. *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+static hspace_booking *create_hspace_booking(gint start)
+{
+    hspace_booking *result;                 /* Structure à retourner       */
+
+    result = malloc(sizeof(hspace_booking));
+
+    result->start = start;
 
     return result;
 
@@ -800,10 +924,10 @@ static size_t get_graph_rank(const graph_rank_t *grank)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : a = premier ensemble de même rang à comparer.                *
-*                b = second ensemble de même rang à comparer.                 *
+*  Paramètres  : a = première réservation d'espace à comparer.                *
+*                b = seconde réservation d'espace à comparer.                 *
 *                                                                             *
-*  Description : Compare deux rangées de blocs de code.                       *
+*  Description : Compare deux réservations d'espace.                          *
 *                                                                             *
 *  Retour      : Bilan de comparaison.                                        *
 *                                                                             *
@@ -811,23 +935,21 @@ static size_t get_graph_rank(const graph_rank_t *grank)
 *                                                                             *
 ******************************************************************************/
 
-static int cmp_graph_rank(const graph_rank_t *a, const graph_rank_t *b)
+static int cmp_hspace_booking_r2l(const hspace_booking **a, const hspace_booking **b)
 {
     int result;                             /* Bilan à retourner           */
-    size_t level_a;                         /* Niveau de l'ensemble A      */
-    size_t level_b;                         /* Niveau de l'ensemble B      */
 
-    level_a = get_graph_rank(a);
-    level_b = get_graph_rank(b);
-
-    if (level_a < level_b)
+    if ((*a)->start > (*b)->start)
         result = -1;
 
-    else if (level_a > level_b)
+    else if ((*a)->start < (*b)->start)
         result = 1;
 
     else
+    {
+        assert(false);
         result = 0;
+    }
 
     return result;
 
@@ -836,34 +958,44 @@ static int cmp_graph_rank(const graph_rank_t *a, const graph_rank_t *b)
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank   = structure à compléter.                             *
-*                cluster = chef de file d'un ensemble de blocs.               *
+*  Paramètres  : a = première réservation d'espace à comparer.                *
+*                b = seconde réservation d'espace à comparer.                 *
 *                                                                             *
-*  Description : Etend un ensemble de blocs de même rang.                     *
+*  Description : Compare deux réservations d'espace.                          *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Bilan de comparaison.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void extend_graph_rank(graph_rank_t *grank, GGraphCluster *cluster)
+static int cmp_hspace_booking_l2r(const hspace_booking **a, const hspace_booking **b)
 {
-    grank->count++;
-    grank->clusters = realloc(grank->clusters, sizeof(GGraphCluster *) * grank->count);
+    int result;                             /* Bilan à retourner           */
 
-    grank->clusters[grank->count - 1] = cluster;
+    if ((*a)->start < (*b)->start)
+        result = -1;
+
+    else if ((*a)->start > (*b)->start)
+        result = 1;
+
+    else
+    {
+        assert(false);
+        result = 0;
+    }
+
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank = ensemble de descendants d'un même rang.              *
-*                last  = indique s'il s'agit du dernier étage de l'ensemble.  *
-*                alloc = emplacement idéal pour l'affichage. [OUT]            *
+*  Paramètres  : grank   = structure à initialiser. [OUT]                     *
+*                cluster = chef de file d'un ensemble de blocs.               *
 *                                                                             *
-*  Description : Détermine l'emplacement requis d'un ensemble de blocs.       *
+*  Description : Initialise la gestion d'un ensemble de blocs de même rang.   *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -871,80 +1003,27 @@ static void extend_graph_rank(graph_rank_t *grank, GGraphCluster *cluster)
 *                                                                             *
 ******************************************************************************/
 
-static void compute_graph_rank_needed_alloc(const graph_rank_t *grank, bool last, GtkAllocation *alloc)
+static void init_graph_rank(graph_rank_t *grank, GGraphCluster *cluster)
 {
-    GtkAllocation needed;                   /* Taille requise              */
-
-    switch (grank->count)
-    {
-        case 1:
-
-            g_graph_cluster_compute_needed_alloc(grank->clusters[0], &needed);
-
-            if (needed.x < alloc->x)
-            {
-                alloc->width += (alloc->x - needed.x);
-                alloc->x = needed.x;
-            }
-
-            if ((needed.x + needed.width) > (alloc->x + alloc->width))
-                alloc->width += needed.x + needed.width - alloc->x - alloc->width;
-
-            /* La hauteur maximale n'est présente qu'avec le dernier morceau */
-            if (last)
-            {
-                if ((needed.y + needed.height) > (alloc->y + alloc->height))
-                    alloc->height += needed.y + needed.height - alloc->y - alloc->height;
-            }
-
-            break;
-
-        default:
-
-            assert(grank->count >= 2);
-
-            g_graph_cluster_compute_needed_alloc(grank->clusters[0], &needed);
-
-            if (needed.x < alloc->x)
-            {
-                alloc->width += (alloc->x - needed.x);
-                alloc->x = needed.x;
-            }
-
-            /* La hauteur maximale n'est présente qu'avec le dernier morceau */
-            if (last)
-            {
-                if ((needed.y + needed.height) > (alloc->y + alloc->height))
-                    alloc->height += needed.y + needed.height - alloc->y - alloc->height;
-            }
-
-            g_graph_cluster_compute_needed_alloc(grank->clusters[grank->count - 1], &needed);
-
-            if ((needed.x + needed.width) > (alloc->x + alloc->width))
-                alloc->width += needed.x + needed.width - alloc->x - alloc->width;
+    grank->right2left = NULL;
+    grank->r2l_count = 0;
 
-            /* La hauteur maximale n'est présente qu'avec le dernier morceau */
-            if (last)
-            {
-                if ((needed.y + needed.height) > (alloc->y + alloc->height))
-                    alloc->height += needed.y + needed.height - alloc->y - alloc->height;
-            }
+    grank->left2right = NULL;
+    grank->l2r_count = 0;
 
-            break;
+    grank->clusters = malloc(sizeof(GGraphCluster *));
+    grank->count = 1;
 
-    }
+    grank->clusters[0] = cluster;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : iter = début de la boucle de parcours.                       *
-*                loop = nombre d'itérations à mener.                          *
-*                base = position de base sur l'axe des abscisses.             *
-*                dir  = direction du parcours.                                *
+*  Paramètres  : grank = structure à vider.                                   *
 *                                                                             *
-*  Description : Affine l'abscisse d'un ensemble de blocs de même rang.       *
+*  Description : Termine la gestion d'un ensemble de blocs de même rang.      *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -952,36 +1031,34 @@ static void compute_graph_rank_needed_alloc(const graph_rank_t *grank, bool last
 *                                                                             *
 ******************************************************************************/
 
-static void _place_graph_rank_clusters(GGraphCluster **iter, size_t loop, gint base, int dir)
+static void exit_graph_rank(graph_rank_t *grank)
 {
     size_t i;                               /* Boucle de parcours          */
-    GtkAllocation needed;                   /* Taille requise              */
 
-    assert(dir == -1 || dir == 1);
+    for (i = 0; i < grank->r2l_count; i++)
+        free(grank->right2left[i]);
 
-    for (i = 0; i < loop; i++, iter += dir)
-    {
-        g_graph_cluster_dispatch_x(*iter);
+    if (grank->right2left != NULL)
+        free(grank->right2left);
 
-        g_graph_cluster_compute_needed_alloc(*iter, &needed);
+    for (i = 0; i < grank->l2r_count; i++)
+        free(grank->left2right[i]);
 
-        if (dir > 0)
-            g_graph_cluster_offset_x(*iter, base - needed.x);
-        else
-            g_graph_cluster_offset_x(*iter, base - needed.x - needed.width);
+    if (grank->left2right != NULL)
+        free(grank->left2right);
 
-        base += dir * (needed.width + HORIZONTAL_MARGIN);
+    assert(grank->clusters != NULL);
 
-    }
+    free(grank->clusters);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank = ensemble de blocs de même rang à manipuler.          *
+*  Paramètres  : grank = ensemble de même rang à consulter.                   *
 *                                                                             *
-*  Description : Organise la disposition d'un ensemble de blocs basiques.     *
+*  Description : Assigne à un ensemble de blocs un emplacement initial.       *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -989,77 +1066,81 @@ static void _place_graph_rank_clusters(GGraphCluster **iter, size_t loop, gint b
 *                                                                             *
 ******************************************************************************/
 
-static void dispatch_x_graph_rank(const graph_rank_t *grank)
+static void reset_graph_rank_allocation(const graph_rank_t *grank)
 {
-    size_t mid;                             /* Position centrale de départ */
-    gint start;                             /* Position initiale de départ */
-
-    if (grank->count % 2 == 1)
-    {
-        if (grank->count > 1)
-        {
-            mid = grank->count / 2;
-
-            start = grank->clusters[mid]->alloc.x - HORIZONTAL_MARGIN;
-
-            _place_graph_rank_clusters(grank->clusters + mid - 1, mid, start, -1);
-
-            start *= -1;
-
-            _place_graph_rank_clusters(grank->clusters + mid + 1, mid, start, 1);
-
-        }
-
-        else
-            g_graph_cluster_dispatch_x(grank->clusters[0]);
+    size_t i;                               /* Boucle de parcours          */
 
-    }
+    for (i = 0; i < grank->count; i++)
+        g_graph_cluster_reset_allocation(grank->clusters[i]);
 
-    else
-    {
-        mid = grank->count / 2 - 1;
+}
 
-        start = - HORIZONTAL_MARGIN / 2;
 
-        _place_graph_rank_clusters(grank->clusters + mid, mid + 1, start, -1);
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : grank = ensemble de même rang à consulter.                   *
+*                                                                             *
+*  Description : Fournit le rang d'un ensemble de blocs.                      *
+*                                                                             *
+*  Retour      : Rang d'un ensemble de blocs de même rang.                    *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
 
-        start *= -1;
+static size_t get_graph_rank(const graph_rank_t *grank)
+{
+    size_t result;                          /* Rang à retourner            */
 
-        _place_graph_rank_clusters(grank->clusters + mid + 1, mid + 1, start, 1);
+    result = g_code_block_get_rank(grank->clusters[0]->block);
 
-    }
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank  = ensemble de blocs de même rang à actualiser.        *
+*  Paramètres  : a = premier ensemble de même rang à comparer.                *
+*                b = second ensemble de même rang à comparer.                 *
 *                                                                             *
-*  Description : Réorganise au besoin les liens entrants un ensemble de blocs.*
+*  Description : Compare deux rangées de blocs de code.                       *
 *                                                                             *
-*  Retour      : -                                                            *
+*  Retour      : Bilan de comparaison.                                        *
 *                                                                             *
 *  Remarques   : -                                                            *
 *                                                                             *
 ******************************************************************************/
 
-static void sort_graph_rank_incoming_links(const graph_rank_t *grank)
+static int cmp_graph_rank(const graph_rank_t *a, const graph_rank_t *b)
 {
-    size_t i;                               /* Boucle de parcours          */
+    int result;                             /* Bilan à retourner           */
+    size_t level_a;                         /* Niveau de l'ensemble A      */
+    size_t level_b;                         /* Niveau de l'ensemble B      */
 
-    for (i = 0; i < grank->count; i++)
-        g_graph_cluster_sort_incoming_links(grank->clusters[i]);
+    level_a = get_graph_rank(a);
+    level_b = get_graph_rank(b);
+
+    if (level_a < level_b)
+        result = -1;
+
+    else if (level_a > level_b)
+        result = 1;
+
+    else
+        result = 0;
+
+    return result;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank  = ensemble de blocs de même rang à actualiser.        *
-*                offset = décalage à appliquer.                               *
+*  Paramètres  : grank   = structure à compléter.                             *
+*                cluster = chef de file d'un ensemble de blocs.               *
 *                                                                             *
-*  Description : Décale vers la droite un ensemble de blocs basiques.         *
+*  Description : Etend un ensemble de blocs de même rang.                     *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1067,22 +1148,23 @@ static void sort_graph_rank_incoming_links(const graph_rank_t *grank)
 *                                                                             *
 ******************************************************************************/
 
-static void offset_x_graph_rank(const graph_rank_t *grank, gint offset)
+static void extend_graph_rank(graph_rank_t *grank, GGraphCluster *cluster)
 {
-    size_t i;                               /* Boucle de parcours          */
+    grank->count++;
+    grank->clusters = realloc(grank->clusters, sizeof(GGraphCluster *) * grank->count);
 
-    for (i = 0; i < grank->count; i++)
-        g_graph_cluster_offset_x(grank->clusters[i], offset);
+    grank->clusters[grank->count - 1] = cluster;
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : grank = ensemble de blocs de même rang à actualiser.         *
-*                base  = position ordonnée à appliquer.                       *
+*  Paramètres  : grank = ensemble de descendants d'un même rang.              *
+*                last  = indique s'il s'agit du dernier étage de l'ensemble.  *
+*                alloc = emplacement idéal pour l'affichage. [OUT]            *
 *                                                                             *
-*  Description : Décale vers le bas un ensemble de blocs basiques.            *
+*  Description : Détermine l'emplacement requis d'un ensemble de blocs.       *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1090,92 +1172,80 @@ static void offset_x_graph_rank(const graph_rank_t *grank, gint offset)
 *                                                                             *
 ******************************************************************************/
 
-static void set_y_for_graph_rank(const graph_rank_t *grank, gint *base)
+static void compute_graph_rank_needed_alloc(const graph_rank_t *grank, bool last, GtkAllocation *alloc)
 {
-    gint max;                               /* Hauteur maximale rencontrée */
-    size_t i;                               /* Boucle de parcours          */
-    GGraphCluster *sub;                     /* Sous-ensemble traité        */
-    GtkAllocation alloc;                    /* Allocation courante         */
-
-    /* On ajoute l'espace vertical pour les lignes horizontales */
-
-    if (grank->r2l_count > grank->l2r_count)
-        max = grank->r2l_count;
-    else
-        max = grank->l2r_count;
-
-    *base += VERTICAL_MARGIN;
-
-    /**
-     * Comme les liens purement verticaux n'entrainent pas de réservation,
-     * il n'y a potentiellement pas toujours d'espace à ajouter.
-     */
+    GtkAllocation needed;                   /* Taille requise              */
 
-    if (max > 0)
+    switch (grank->count)
     {
-        *base += ((max - 1) * LINK_MARGIN);
-        *base += VERTICAL_MARGIN;
-    }
-
-    /* On ajoute l'espace requis pour l'affichage des blocs */
-
-    max = 0;
+        case 1:
 
-    for (i = 0; i < grank->count; i++)
-    {
-        sub = grank->clusters[i];
+            g_graph_cluster_compute_needed_alloc(grank->clusters[0], &needed);
 
-        g_graph_cluster_set_y(sub, *base);
+            if (needed.x < alloc->x)
+            {
+                alloc->width += (alloc->x - needed.x);
+                alloc->x = needed.x;
+            }
 
-        g_graph_cluster_compute_needed_alloc(sub, &alloc);
+            if ((needed.x + needed.width) > (alloc->x + alloc->width))
+                alloc->width += needed.x + needed.width - alloc->x - alloc->width;
 
-        if ((alloc.y + alloc.height) > max)
-            max = alloc.y + alloc.height;
+            /* La hauteur maximale n'est présente qu'avec le dernier morceau */
+            if (last)
+            {
+                if ((needed.y + needed.height) > (alloc->y + alloc->height))
+                    alloc->height += needed.y + needed.height - alloc->y - alloc->height;
+            }
 
-    }
+            break;
 
-    *base = max;
+        default:
 
-}
+            assert(grank->count >= 2);
 
+            g_graph_cluster_compute_needed_alloc(grank->clusters[0], &needed);
 
+            if (needed.x < alloc->x)
+            {
+                alloc->width += (alloc->x - needed.x);
+                alloc->x = needed.x;
+            }
 
-/* ---------------------------------------------------------------------------------- */
-/*                          ENCADREMENTS D'ESPACES VERTICAUX                          */
-/* ---------------------------------------------------------------------------------- */
+            /* La hauteur maximale n'est présente qu'avec le dernier morceau */
+            if (last)
+            {
+                if ((needed.y + needed.height) > (alloc->y + alloc->height))
+                    alloc->height += needed.y + needed.height - alloc->y - alloc->height;
+            }
 
+            g_graph_cluster_compute_needed_alloc(grank->clusters[grank->count - 1], &needed);
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : manager = structure à initialiser.                           *
-*                                                                             *
-*  Description : Initialise les réservations liens verticaux.                 *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+            if ((needed.x + needed.width) > (alloc->x + alloc->width))
+                alloc->width += needed.x + needed.width - alloc->x - alloc->width;
 
-static void init_vspace_manager(vspace_manager_t *manager)
-{
-    manager->pending = NULL;
-    manager->pending_count = 0;
+            /* La hauteur maximale n'est présente qu'avec le dernier morceau */
+            if (last)
+            {
+                if ((needed.y + needed.height) > (alloc->y + alloc->height))
+                    alloc->height += needed.y + needed.height - alloc->y - alloc->height;
+            }
 
-    manager->left = NULL;
-    manager->left_count = 0;
+            break;
 
-    manager->right = NULL;
-    manager->right_count = 0;
+    }
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : manager = structure à vider.                                 *
+*  Paramètres  : iter = début de la boucle de parcours.                       *
+*                loop = nombre d'itérations à mener.                          *
+*                base = position de base sur l'axe des abscisses.             *
+*                dir  = direction du parcours.                                *
 *                                                                             *
-*  Description : Termine les réservations liens verticaux.                    *
+*  Description : Affine l'abscisse d'un ensemble de blocs de même rang.       *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1183,33 +1253,36 @@ static void init_vspace_manager(vspace_manager_t *manager)
 *                                                                             *
 ******************************************************************************/
 
-static void exit_vspace_manager(vspace_manager_t *manager)
+static void _place_graph_rank_clusters(GGraphCluster **iter, size_t loop, gint base, int dir)
 {
     size_t i;                               /* Boucle de parcours          */
+    GtkAllocation needed;                   /* Taille requise              */
 
-    for (i = 0; i < manager->pending_count; i++)
-        free(manager->pending[i].pts);
+    assert(dir == -1 || dir == 1);
 
-    if (manager->pending != NULL)
-        free(manager->pending);
+    for (i = 0; i < loop; i++, iter += dir)
+    {
+        g_graph_cluster_dispatch_x(*iter);
 
-    if (manager->left != NULL)
-        free(manager->left);
+        g_graph_cluster_compute_needed_alloc(*iter, &needed);
 
-    if (manager->right != NULL)
-        free(manager->right);
+        if (dir > 0)
+            g_graph_cluster_offset_x(*iter, base - needed.x);
+        else
+            g_graph_cluster_offset_x(*iter, base - needed.x - needed.width);
+
+        base += dir * (needed.width + HORIZONTAL_MARGIN);
+
+    }
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : manager = structure à compléter.                             *
-*                from    = point de départ du lien concerné.                  *
-*                to      = point d'arrivée du lien concerné.                  *
-*                pts     = points intermédiaires du tracé complet final.      *
+*  Paramètres  : grank = ensemble de blocs de même rang à manipuler.          *
 *                                                                             *
-*  Description : Inscrit une nouvelle réservation d'espace latéral.           *
+*  Description : Organise la disposition d'un ensemble de blocs basiques.     *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1217,62 +1290,54 @@ static void exit_vspace_manager(vspace_manager_t *manager)
 *                                                                             *
 ******************************************************************************/
 
-static void extend_vspace_manager(vspace_manager_t *manager, leaving_link_t *from, incoming_link_t *to, GdkPoint *pts)
+static void dispatch_x_graph_rank(const graph_rank_t *grank)
 {
-    vspace_booking_t *new;                  /* Réservation à constituer    */
-
-    manager->pending = realloc(manager->pending, ++manager->pending_count * sizeof(vspace_booking_t));
+    size_t mid;                             /* Position centrale de départ */
+    gint start;                             /* Position initiale de départ */
 
-    new = &manager->pending[manager->pending_count - 1];
+    if (grank->count % 2 == 1)
+    {
+        if (grank->count > 1)
+        {
+            mid = grank->count / 2;
 
-    new->from = from;
-    new->to = to;
+            start = grank->clusters[mid]->alloc.x - HORIZONTAL_MARGIN;
 
-    new->pts = pts;
+            _place_graph_rank_clusters(grank->clusters + mid - 1, mid, start, -1);
 
-}
+            start *= -1;
 
+            _place_graph_rank_clusters(grank->clusters + mid + 1, mid, start, 1);
 
-/******************************************************************************
-*                                                                             *
-*  Paramètres  : manager = gestion des espaces latéraux à consulter.          *
-*                alloc   = emplacement idéal pour l'affichage. [OUT]          *
-*                                                                             *
-*  Description : Détermine l'emplacement requis pour les espaces latéraux.    *
-*                                                                             *
-*  Retour      : -                                                            *
-*                                                                             *
-*  Remarques   : -                                                            *
-*                                                                             *
-******************************************************************************/
+        }
 
-static void compute_vspace_manager_needed_alloc(const vspace_manager_t *manager, GtkAllocation *alloc)
-{
-    gint width;                             /* Largeur supplémentaire      */
+        else
+            g_graph_cluster_dispatch_x(grank->clusters[0]);
 
-    /* Extension de la largeur */
+    }
 
-    width = 0;
+    else
+    {
+        mid = grank->count / 2 - 1;
 
-    width += manager->left_count * LINK_MARGIN;
+        start = - HORIZONTAL_MARGIN / 2;
 
-    width += manager->right_count * LINK_MARGIN;
+        _place_graph_rank_clusters(grank->clusters + mid, mid + 1, start, -1);
 
-    alloc->x -= width / 2;
-    alloc->width += width;
+        start *= -1;
 
-    /* Extension de la hauteur */
+        _place_graph_rank_clusters(grank->clusters + mid + 1, mid + 1, start, 1);
 
-    alloc->height += manager->pending_count * VERTICAL_MARGIN;
+    }
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : manager = gestion d'espaces latéraux à manipuler.            *
+*  Paramètres  : grank  = ensemble de blocs de même rang à actualiser.        *
 *                                                                             *
-*  Description : Réorganise au besoin les liens de boucle entre blocs.        *
+*  Description : Réorganise au besoin les liens entrants un ensemble de blocs.*
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1280,46 +1345,22 @@ static void compute_vspace_manager_needed_alloc(const vspace_manager_t *manager,
 *                                                                             *
 ******************************************************************************/
 
-static void sort_incoming_links_for_vspace_manager(vspace_manager_t *manager)
+static void sort_graph_rank_incoming_links(const graph_rank_t *grank)
 {
     size_t i;                               /* Boucle de parcours          */
-    vspace_booking_t *pending;              /* Elément traité              */
-    gint x1;                                /* Abscisse de départ de lien  */
-    size_t idx;                             /* Indice du lien entrant      */
-    gint x2;                                /* Abscisse d'arrivée de lien  */
-
-    for (i = 0; i < manager->pending_count; i++)
-    {
-        pending = &manager->pending[i];
-
-        x1 = g_graph_cluster_compute_leaving_link_position(pending->from->owner, pending->from->index);
-
-        idx = g_graph_cluster_find_incoming_link(pending->to->owner, pending->from);
-
-        x2 = g_graph_cluster_compute_incoming_link_position(pending->to->owner, idx);
-
-        if (x1 < x2)
-        {
-            manager->left = realloc(manager->left, ++manager->left_count * sizeof(vspace_booking_t *));
-            manager->left[manager->left_count - 1] = pending;
-        }
-        else
-        {
-            manager->right = realloc(manager->right, ++manager->right_count * sizeof(vspace_booking_t *));
-            manager->right[manager->right_count - 1] = pending;
-        }
 
-    }
+    for (i = 0; i < grank->count; i++)
+        g_graph_cluster_sort_incoming_links(grank->clusters[i]);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : manager = structure à consulter.                             *
-*                cluster = graphique de blocs sur lequel s'appuyer.           *
+*  Paramètres  : grank  = ensemble de blocs de même rang à actualiser.        *
+*                offset = décalage à appliquer.                               *
 *                                                                             *
-*  Description : Détermine les abscisses de tous les liens en place.          *
+*  Description : Décale vers la droite un ensemble de blocs basiques.         *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1327,82 +1368,22 @@ static void sort_incoming_links_for_vspace_manager(vspace_manager_t *manager)
 *                                                                             *
 ******************************************************************************/
 
-static void compute_loop_link_x_with_vspace_manager(vspace_manager_t *manager, GGraphCluster *cluster)
+static void offset_x_graph_rank(const graph_rank_t *grank, gint offset)
 {
-    GtkAllocation needed;                   /* Espace nécessaire et alloué */
     size_t i;                               /* Boucle de parcours          */
-    vspace_booking_t *booking;              /* Réservation à traiter       */
-    gint x;                                 /* Position à appliquer        */
-    GGraphCluster *container;               /* Parent direct à décaler     */
-
-    g_graph_cluster_compute_needed_alloc(cluster, &needed);
-
-    for (i = 0; i < manager->left_count; i++)
-    {
-        booking = manager->left[i];
-
-        x = i * LINK_MARGIN;
-
-        booking->pts[0].x = needed.x + x;
-        booking->pts[1].x = needed.x + x;
-
-    }
-
-    if (manager->left_count > 0)
-    {
-        x = manager->left_count * LINK_MARGIN;
-
-        /**
-         * Si la routine est une boucle sans fin,
-         * alors la boucle peut renvoyer vers le premier bloc.
-         */
-        if (cluster->owner != NULL)
-        {
-            container = cluster->owner;
-
-            /**
-             * On recherche le plus haut propritétaire bénéficiant d'une chaîne
-             * de liens directs et droits, histoire de transmettre le décalage
-             * et de garder ces liens bien verticaux.
-             */
-            while (container->owner != NULL)
-            {
-                if (!container->owner->has_straight)
-                    break;
-
-                if (container->owner->straight_index != *container->parent_index)
-                    break;
-
-                container = container->owner;
-
-            }
-
-            g_graph_cluster_offset_x(container, x);
-
-        }
-
-    }
-
-    for (i = 0; i < manager->right_count; i++)
-    {
-        booking = manager->right[i];
-
-        x = (i + 1) * LINK_MARGIN;
-
-        booking->pts[0].x = x;
-        booking->pts[1].x = x;
 
-    }
+    for (i = 0; i < grank->count; i++)
+        g_graph_cluster_offset_x(grank->clusters[i], offset);
 
 }
 
 
 /******************************************************************************
 *                                                                             *
-*  Paramètres  : manager = structure à consulter.                             *
-*                cluster = graphique de blocs sur lequel s'appuyer.           *
+*  Paramètres  : grank = ensemble de blocs de même rang à actualiser.         *
+*                base  = position ordonnée à appliquer.                       *
 *                                                                             *
-*  Description : Détermine les ordonnées de tous les liens en place.          *
+*  Description : Décale vers le bas un ensemble de blocs basiques.            *
 *                                                                             *
 *  Retour      : -                                                            *
 *                                                                             *
@@ -1410,33 +1391,52 @@ static void compute_loop_link_x_with_vspace_manager(vspace_manager_t *manager, G
 *                                                                             *
 ******************************************************************************/
 
-static void compute_loop_link_y_with_vspace_manager(vspace_manager_t *manager, GGraphCluster *cluster)
+static void set_y_for_graph_rank(const graph_rank_t *grank, gint *base)
 {
-    GtkAllocation needed;                   /* Espace nécessaire et alloué */
+    gint max;                               /* Hauteur maximale rencontrée */
     size_t i;                               /* Boucle de parcours          */
-    vspace_booking_t *booking;              /* Réservation à traiter       */
+    GGraphCluster *sub;                     /* Sous-ensemble traité        */
+    GtkAllocation alloc;                    /* Allocation courante         */
 
-    g_graph_cluster_compute_needed_alloc(cluster, &needed);
+    /* On ajoute l'espace vertical pour les lignes horizontales */
 
-    for (i = 0; i < manager->pending_count; i++)
+    if (grank->r2l_count > grank->l2r_count)
+        max = grank->r2l_count;
+    else
+        max = grank->l2r_count;
+
+    *base += VERTICAL_MARGIN;
+
+    /**
+     * Comme les liens purement verticaux n'entrainent pas de réservation,
+     * il n'y a potentiellement pas toujours d'espace à ajouter.
+     */
+
+    if (max > 0)
     {
-        booking = &manager->pending[i];
+        *base += ((max - 1) * LINK_MARGIN);
+        *base += VERTICAL_MARGIN;
+    }
 
-        /**
-         * On corrige le raccourci pris sans distinction de type de lien dans
-         * la fonction g_graph_cluster_compute_link_y_positions().
-         */
+    /* On ajoute l'espace requis pour l'affichage des blocs */
 
-        booking->from->start[1].y = needed.y + needed.height;
+    max = 0;
 
-        /* Définition de l'ordonnée des points du lien */
+    for (i = 0; i < grank->count; i++)
+    {
+        sub = grank->clusters[i];
 
-        booking->pts[0].y = booking->from->start[1].y;
+        g_graph_cluster_set_y(sub, *base);
 
-        booking->pts[1].y = booking->to->end[0].y;
+        g_graph_cluster_compute_needed_alloc(sub, &alloc);
+
+        if ((alloc.y + alloc.height) > max)
+            max = alloc.y + alloc.height;
 
     }
 
+    *base = max;
+
 }
 
 
-- 
cgit v0.11.2-87-g4458