/* OpenIDA - Outil d'analyse de fichiers binaires * gtklinkrenderer.c - liens graphiques entre différents morceaux de code * * Copyright (C) 2009 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 . */ #include "gtklinkrenderer.h" #include /* Lien entre morceaux de code (instance) */ struct _GtkLinkRenderer { GtkObject parent; /* A laisser en premier */ LinkColor color; /* Couleur d'impression */ GdkPoint *points; /* Points de la ligne dessinée */ size_t count; /* Quantité de ces points */ }; /* Lien entre morceaux de code (classe) */ struct _GtkLinkRendererClass { GtkObjectClass parent; /* A laisser en premier */ }; #define ARROW_LENGHT 10 #define ARROW_DEGREES 10 /* Initialise la classe générique des liens graphiques. */ static void gtk_link_renderer_class_init(GtkLinkRendererClass *); /* Initialise une instance de lien graphique entre codes. */ static void gtk_link_renderer_init(GtkLinkRenderer *); /* Dessine une flèche au bout du lien représenté. */ static void draw_link_arrow(cairo_t *, gint, gint, gint, gint); /* Détermine le type du moteur de rendu pour les liens graphiques. */ G_DEFINE_TYPE(GtkLinkRenderer, gtk_link_renderer, GTK_TYPE_OBJECT) /****************************************************************************** * * * Paramètres : class = classe GTK à initialiser. * * * * Description : Initialise la classe générique des liens graphiques. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_link_renderer_class_init(GtkLinkRendererClass *class) { } /****************************************************************************** * * * Paramètres : view = instance GTK à initialiser. * * * * Description : Initialise une instance de lien graphique entre codes. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void gtk_link_renderer_init(GtkLinkRenderer *view) { } /****************************************************************************** * * * Paramètres : color = couleur d'impression. * ù points = points consituant la ligne à représenter. * * count = nombre de ces points. * * * * Description : Crée un nouveau moteur de rendu pour les liens graphiques. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ GtkObject *gtk_link_renderer_new(LinkColor color, GdkPoint *points, size_t count) { GtkLinkRenderer *result; /* Moteur de rendu à retourner */ result = g_object_new(GTK_TYPE_LINK_RENDERER, NULL); result->color = color; result->points = points; result->count = count; return GTK_OBJECT(result); } /****************************************************************************** * * * Paramètres : renderer = moteur de rendu à manipuler. * * drawable = surface de rendu à utiliser. * * gc = contexte graphique du dessin. * * * * Description : Dessine les liens graphiques enregistrés dans le moteur. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void gtk_link_renderer_draw(const GtkLinkRenderer *renderer, GdkDrawable *drawable, GdkGC *gc) { cairo_t *cairo; /* Gestionnaire de rendu */ cairo = gdk_cairo_create(drawable); _gtk_link_renderer_draw(renderer, cairo, true); cairo_destroy(cairo); } /****************************************************************************** * * * Paramètres : renderer = moteur de rendu à manipuler. * * cairo = assistant pour le rendu graphique. * * arrow = indique le besoin en flèche à l'arrivée. * * * * Description : Dessine les liens graphiques enregistrés dans le moteur. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ void _gtk_link_renderer_draw(const GtkLinkRenderer *renderer, cairo_t *cairo, bool arrow) { size_t i; /* Boucle de parcours */ switch (renderer->color) { default: case LKC_DEFAULT: cairo_set_source_rgb(cairo, 0, 0, 0); break; case LKC_GREEN: cairo_set_source_rgb(cairo, 0, 0.6, 0); break; case LKC_RED: cairo_set_source_rgb(cairo, 0.8, 0, 0); break; case LKC_DASHED_GRAY: cairo_set_source_rgb(cairo, 0.4, 0.4, 0.4); break; } switch (renderer->color) { default: case LKC_DEFAULT: case LKC_GREEN: case LKC_RED: cairo_set_dash(cairo, (double []) { 6.0 }, 0, 0.0); break; case LKC_DASHED_GRAY: cairo_set_dash(cairo, (double []) { 6.0 }, 1, 0.0); break; } /** * Si on ne veut pas de flèche, on doit se destiner à un aperçu... * Dans ce cas, pour plus de lisibilité, on double la taille d'impression. */ cairo_set_line_width(cairo, arrow ? 1 : 2); cairo_move_to(cairo, renderer->points[0].x, renderer->points[0].y); for (i = 1; i < renderer->count; i++) cairo_line_to(cairo, renderer->points[i].x, renderer->points[i].y); cairo_stroke(cairo); if (arrow) draw_link_arrow(cairo, renderer->points[renderer->count - 2].x, renderer->points[renderer->count - 2].y, renderer->points[renderer->count - 1].x, renderer->points[renderer->count - 1].y); } /****************************************************************************** * * * Paramètres : cairo = gestionnaire de rendu graphique. * * start_x = abscisse du début du segment final. * * start_y = ordonnée du début du segment final. * * end_x = abscisse de fin de segment et pointe de flèche. * * end_y = ordonnée de fin de segment et pointe de flèche. * * * * Description : Dessine une flèche au bout du lien représenté. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void draw_link_arrow(cairo_t *cairo, gint start_x, gint start_y, gint end_x, gint end_y) { double angle; /* Angle du triangle à remplir */ double factor_x; /* Direction de la flèche #1 */ double factor_y; /* Direction de la flèche #2 */ double x1; /* Abscisse du point n°1 */ double y1; /* Ordonnée du point n°1 */ double x2; /* Abscisse du point n°2 */ double y2; /* Ordonnée du point n°2 */ angle = atan2(end_y - start_y, end_x - start_x) + M_PI; factor_x = -1; factor_y = -1; x1 = end_x + factor_x * ARROW_LENGHT * cos(angle - ARROW_DEGREES); y1 = end_y + factor_y * ARROW_LENGHT * sin(angle - ARROW_DEGREES); x2 = end_x + factor_x * ARROW_LENGHT * cos(angle + ARROW_DEGREES); y2 = end_y + factor_y * ARROW_LENGHT * sin(angle + ARROW_DEGREES); cairo_move_to(cairo, end_x, end_y); cairo_line_to(cairo, x1, y1); cairo_line_to(cairo, x2, y2); cairo_move_to(cairo, end_x, end_y); cairo_fill(cairo); }