add EPA stuff from 2.X
[ardour.git] / libs / gnomecanvas / libgnomecanvas / gnome-canvas-polygon.c
1 /*
2  * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
3  * All rights reserved.
4  *
5  * This file is part of the Gnome Library.
6  *
7  * The Gnome Library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * The Gnome Library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with the Gnome Library; see the file COPYING.LIB.  If not,
19  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 /*
23   @NOTATION@
24  */
25 /* Polygon item type for GnomeCanvas widget
26  *
27  * GnomeCanvas is basically a port of the Tk toolkit's most excellent canvas widget.  Tk is
28  * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties.
29  *
30  * Author: Federico Mena <federico@nuclecu.unam.mx>
31  *         Rusty Conover <rconover@bangtail.net>
32  */
33
34 #include <config.h>
35 #include <math.h>
36 #include <string.h>
37 #include "libart_lgpl/art_vpath.h"
38 #include "libart_lgpl/art_svp.h"
39 #include "libart_lgpl/art_svp_vpath.h"
40 #include "libart_lgpl/art_svp_vpath_stroke.h"
41 #include "libgnomecanvas.h"
42
43 #include "gnome-canvas-shape.h"
44
45 #define NUM_STATIC_POINTS 256   /* Number of static points to use to avoid allocating arrays */
46
47 enum {
48         PROP_0,
49         PROP_POINTS
50 };
51
52 static void gnome_canvas_polygon_class_init (GnomeCanvasPolygonClass *class);
53 static void gnome_canvas_polygon_init       (GnomeCanvasPolygon      *poly);
54 static void gnome_canvas_polygon_destroy    (GtkObject               *object);
55 static void gnome_canvas_polygon_set_property (GObject              *object,
56                                                guint                 param_id,
57                                                const GValue         *value,
58                                                GParamSpec           *pspec);
59 static void gnome_canvas_polygon_get_property (GObject              *object,
60                                                guint                 param_id,
61                                                GValue               *value,
62                                                GParamSpec           *pspec);
63
64 static void gnome_canvas_polygon_update      (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags);
65
66 static GnomeCanvasItemClass *parent_class;
67
68 GType
69 gnome_canvas_polygon_get_type (void)
70 {
71         static GType polygon_type;
72
73         if (!polygon_type) {
74                 const GTypeInfo object_info = {
75                         sizeof (GnomeCanvasPolygonClass),
76                         (GBaseInitFunc) NULL,
77                         (GBaseFinalizeFunc) NULL,
78                         (GClassInitFunc) gnome_canvas_polygon_class_init,
79                         (GClassFinalizeFunc) NULL,
80                         NULL,                   /* class_data */
81                         sizeof (GnomeCanvasPolygon),
82                         0,                      /* n_preallocs */
83                         (GInstanceInitFunc) gnome_canvas_polygon_init,
84                         NULL                    /* value_table */
85                 };
86
87                 polygon_type = g_type_register_static (GNOME_TYPE_CANVAS_SHAPE, "GnomeCanvasPolygon",
88                                                        &object_info, 0);
89         }
90
91         return polygon_type;
92 }
93
94 static void
95 gnome_canvas_polygon_class_init (GnomeCanvasPolygonClass *class)
96 {
97         GObjectClass *gobject_class;
98         GtkObjectClass *object_class;
99         GnomeCanvasItemClass *item_class;
100
101         gobject_class = (GObjectClass *) class;
102         object_class = (GtkObjectClass *) class;
103         item_class = (GnomeCanvasItemClass *) class;
104
105         parent_class = g_type_class_peek_parent (class);
106
107         gobject_class->set_property = gnome_canvas_polygon_set_property;
108         gobject_class->get_property = gnome_canvas_polygon_get_property;
109
110         g_object_class_install_property
111                 (gobject_class,
112                  PROP_POINTS,
113                  g_param_spec_boxed ("points", NULL, NULL,
114                                      GNOME_TYPE_CANVAS_POINTS,
115                                      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
116
117         object_class->destroy = gnome_canvas_polygon_destroy;
118
119         item_class->update = gnome_canvas_polygon_update;
120 }
121
122 static void
123 gnome_canvas_polygon_init (GnomeCanvasPolygon *poly)
124 {
125         poly->path_def = NULL;
126 }
127
128 static void
129 gnome_canvas_polygon_destroy (GtkObject *object)
130 {
131         GnomeCanvasPolygon *poly;
132
133         g_return_if_fail (object != NULL);
134         g_return_if_fail (GNOME_IS_CANVAS_POLYGON (object));
135
136         poly = GNOME_CANVAS_POLYGON (object);
137
138         /* remember, destroy can be run multiple times! */
139
140         if(poly->path_def)
141                 gnome_canvas_path_def_unref(poly->path_def);
142
143         poly->path_def = NULL;
144
145
146         if (GTK_OBJECT_CLASS (parent_class)->destroy)
147                 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
148 }
149
150 static void
151 set_points (GnomeCanvasPolygon *poly, GnomeCanvasPoints *points)
152 {
153         int i;
154
155
156         if (poly->path_def)
157                 gnome_canvas_path_def_unref(poly->path_def);
158
159         if (!points) {
160                 poly->path_def = gnome_canvas_path_def_new();
161                 gnome_canvas_shape_set_path_def (GNOME_CANVAS_SHAPE (poly), poly->path_def);
162                 return;
163         }
164
165
166         /* Optomize the path def to the number of points */
167         poly->path_def = gnome_canvas_path_def_new_sized(points->num_points+1);
168
169 #if 0
170         /* No need for explicit duplicate, as closepaths does it for us (Lauris) */
171         /* See if we need to duplicate the first point */
172         duplicate = ((points->coords[0] != points->coords[2 * points->num_points - 2])
173                      || (points->coords[1] != points->coords[2 * points->num_points - 1]));
174 #endif
175
176         
177         gnome_canvas_path_def_moveto (poly->path_def, points->coords[0], points->coords[1]);
178         
179         for (i = 1; i < points->num_points; i++) {
180                 gnome_canvas_path_def_lineto(poly->path_def, points->coords[i * 2], points->coords[(i * 2) + 1]);
181         }
182
183         gnome_canvas_path_def_closepath (poly->path_def);
184
185         gnome_canvas_shape_set_path_def (GNOME_CANVAS_SHAPE (poly), poly->path_def);
186 }
187
188
189 static void
190 gnome_canvas_polygon_set_property (GObject              *object,
191                                    guint                 param_id,
192                                    const GValue         *value,
193                                    GParamSpec           *pspec)
194 {
195         GnomeCanvasItem *item;
196         GnomeCanvasPolygon *poly;
197         GnomeCanvasPoints *points;
198
199         g_return_if_fail (object != NULL);
200         g_return_if_fail (GNOME_IS_CANVAS_POLYGON (object));
201
202         item = GNOME_CANVAS_ITEM (object);
203         poly = GNOME_CANVAS_POLYGON (object);
204
205         switch (param_id) {
206         case PROP_POINTS:
207                 points = g_value_get_boxed (value);
208
209                 set_points (poly, points);
210
211                 gnome_canvas_item_request_update (item);
212                 break;
213         default:
214                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
215                 break;
216         }
217 }
218
219
220 static void
221 gnome_canvas_polygon_get_property (GObject              *object,
222                                    guint                 param_id,
223                                    GValue               *value,
224                                    GParamSpec           *pspec)
225 {
226         g_return_if_fail (object != NULL);
227         g_return_if_fail (GNOME_IS_CANVAS_POLYGON (object));
228
229         switch (param_id) {
230         case PROP_POINTS:
231                 break;
232         default:
233                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
234                 break;
235         }
236 }
237
238
239 static void
240 gnome_canvas_polygon_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
241 {
242         /* Since the path has already been defined just pass the update up. */
243
244         if (parent_class->update)
245                 (* parent_class->update) (item, affine, clip_path, flags);
246 }