diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2012-11-02 15:50:07 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2012-11-02 15:50:07 (GMT) |
commit | f5df6496fa50927d3d274c939a888afde652b7ad (patch) | |
tree | 281dbfdfdcb8765fea7036af274c63fb5acde8ff /src/gtkext/graph/dot.c | |
parent | c3aba0893c29cc098c029306fd7a4c8c1fa2eee2 (diff) |
Improved the computing and the rendering of the graphic view.
git-svn-id: svn://svn.gna.org/svn/chrysalide/trunk@277 abbe820e-26c8-41b2-8c08-b7b2b41f8b0a
Diffstat (limited to 'src/gtkext/graph/dot.c')
-rw-r--r-- | src/gtkext/graph/dot.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/src/gtkext/graph/dot.c b/src/gtkext/graph/dot.c new file mode 100644 index 0000000..396aa93 --- /dev/null +++ b/src/gtkext/graph/dot.c @@ -0,0 +1,267 @@ + +/* OpenIDA - Outil d'analyse de fichiers binaires + * dot.c - interactions avec le système dot + * + * Copyright (C) 2009-2012 Cyrille Bagard + * + * This file is part of OpenIDA. + * + * OpenIDA 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. + * + * OpenIDA 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 Foobar. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "dot.h" + + +#include <malloc.h> +#include <graphviz/gvc.h> +#include <graphviz/types.h> + + + +/* Graphique selon Graphviz */ +struct _graph_layout +{ + GVC_t *context; /* Contexte pour Graphviz */ + graph_t *graph; /* Graphique construit */ + +}; + + + +/****************************************************************************** +* * +* Paramètres : cmds = description textuelle du graphique à représenter. * +* * +* Description : Charge un graphique à partir de sa description. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +graph_layout *create_graph_layout(char *cmds) +{ + graph_layout *result; /* Composants à retourner */ + int ret; /* Bilan d'un appel */ + + result = (graph_layout *)calloc(1, sizeof(graph_layout)); + + result->context = gvContext(); + result->graph = agmemread(cmds); + + if (result->graph == NULL) goto cdl_error; + + + + //printf("CMDS =======\n%s\n\n=================\n", cmds); + + ret = gvLayout(result->context, result->graph, "dot"); + if (ret != 0) goto cdl_error; + + + //printf("ret = %d\n", ret); + + /* + ret = gvLayoutJobs(result->context, result->graph); + printf("ret = %d\n", ret); + ret = gvRenderJobs(result->context, result->graph); + printf("ret = %d\n", ret); + */ + + ret = gvRender(result->context, result->graph, "dot", NULL); + if (ret != 0) goto cdl_error; + + + + //ret = gvRender(result->context, result->graph, "plain", NULL); + + //printf("ret = %d\n", ret); + + + + + + return result; + + cdl_error: + + delete_graph_layout(result); + + return NULL; + +} + + +/****************************************************************************** +* * +* Paramètres : layout = graphique à supprimer de la mémoire. * +* * +* Description : Décharge un graphique. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void delete_graph_layout(graph_layout *layout) +{ + if (layout->graph != NULL) + { + gvFreeLayout(layout->context, layout->graph); + agclose(layout->graph); + } + + gvFreeContext(layout->context); + + free(layout); + +} + + +/****************************************************************************** +* * +* Paramètres : layout = graphique à supprimer de la mémoire. * +* view = support de destination. * +* nodes = liste de noeuds à traiter. * +* count = taille de la liste. * +* * +* Description : Place tous les éléments du graphique à l'écran. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +void place_nodes_of_graph_layout(const graph_layout *layout, GtkGraphView *view, GGraphNode **nodes, size_t count) +{ + int height; /* Hauteur du graphique */ + node_t *iter; /* Boucle de parcours */ + GGraphNode *node; /* Intermédiaire concerné */ + + height = GD_bb(layout->graph).UR.y; + + for (iter = agfstnode(layout->graph); iter != NULL; iter = agnxtnode(layout->graph, iter)) + { + node = find_graph_node_by_name(nodes, count, iter->name); + g_graph_node_place(node, view, iter->u.coord.x, height - iter->u.coord.y); + } + +} + + +/****************************************************************************** +* * +* Paramètres : layout = graphique à supprimer de la mémoire. * +* count = nombre d'éléments mis en place. * +* nodes = liste de noeuds à consulter. * +* ncount = taille de la liste des noeuds. * +* * +* Description : Charge la définition de tous les liens graphiques. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +GtkLinkRenderer **create_links_from_graph_layout(const graph_layout *layout, size_t *count, GGraphNode **nodes, size_t ncount) +{ + GtkLinkRenderer **result; /* Liste à retourner */ + int height; /* Hauteur du graphique */ + node_t *niter; /* Boucle de parcours #1 */ + edge_t *eiter; /* Boucle de parcours #2 */ + GdkPoint *points; /* Points de ligne relus */ + size_t points_count; /* Nombre de ces points */ + splines *lines; /* Lignes déjà tracées */ + GGraphNode *node; /* Noeud rattaché */ + int i; /* Boucle de parcours #3 */ + int k; /* Boucle de parcours #4 */ + bezier *bez; /* Courbe à reproduire */ + Agsym_t *attrib; /* Couleur d'un lien */ + LinkColor color; /* Couleur d'impression */ + + result = NULL; + *count = 0; + + height = GD_bb(layout->graph).UR.y; + + for (niter = agfstnode(layout->graph); niter != NULL; niter = agnxtnode(layout->graph, niter)) + for (eiter = agfstout(layout->graph, niter); eiter != NULL; eiter = agnxtout(layout->graph, eiter)) + { + points = NULL; + points_count = 0; + + lines = ED_spl(eiter); + + /* Raccordement au point de départ */ + + node = find_graph_node_by_name(nodes, ncount, agtail(eiter)->name); + + g_graph_node_connect(node, + lines->list[0].list[0].x, + height - lines->list[0].list[0].y, + &points, &points_count); + + /* Tracé du lien... */ + + for (i = 0; i < lines->size; i++) + { + bez = &lines->list[i]; + + points = (GdkPoint *)realloc(points, (points_count + bez->size) * sizeof(GdkPoint)); + + for (k = 0; k < bez->size; k++) + { + points[points_count + k].x = bez->list[k].x; + points[points_count + k].y = height - bez->list[k].y; + } + + points_count += bez->size; + + } + + /* Raccordement au point d'arrivée */ + + node = find_graph_node_by_name(nodes, ncount, aghead(eiter)->name); + + g_graph_node_connect(node, + bez->list[k - 1].x, + height - bez->list[k - 1].y, + &points, &points_count); + + /* Détermination de la couleur */ + + attrib = agfindedgeattr(agraphof(agtail(eiter)), "color"); + + result = (GtkLinkRenderer **)realloc(result, ++(*count) * sizeof(GtkLinkRenderer *)); + + if (eiter->attr[attrib->index][0] == 'g') /* "green" */ + color = LKC_GREEN; + else if (eiter->attr[attrib->index][0] == 'r') /* "red" */ + color = LKC_RED; + else + color = LKC_DEFAULT; + + result[*count - 1] = GTK_LINK_RENDERER(gtk_link_renderer_new(color, + points, points_count)); + + } + + return result; + +} |