source: trunk/third/libgnomecanvas/libgnomecanvas/gnome-canvas-rect-ellipse.c @ 20821

Revision 20821, 11.5 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20820, which included commits to RCS files with non-trunk default branches.
Line 
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/* Rectangle and ellipse item types 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 *
31 * Authors: Federico Mena <federico@nuclecu.unam.mx>
32 *          Rusty Conover <rconover@bangtail.net>
33 */
34
35#include <config.h>
36#include <math.h>
37#include "gnome-canvas-rect-ellipse.h"
38#include "gnome-canvas-util.h"
39#include "gnome-canvas-shape.h"
40
41
42#include "libart_lgpl/art_vpath.h"
43#include "libart_lgpl/art_svp.h"
44#include "libart_lgpl/art_svp_vpath.h"
45#include "libart_lgpl/art_rgb_svp.h"
46
47/* Base class for rectangle and ellipse item types */
48
49#define noVERBOSE
50
51enum {
52        PROP_0,
53        PROP_X1,
54        PROP_Y1,
55        PROP_X2,
56        PROP_Y2
57};
58
59
60static void gnome_canvas_re_class_init (GnomeCanvasREClass *class);
61static void gnome_canvas_re_init       (GnomeCanvasRE      *re);
62static void gnome_canvas_re_destroy    (GtkObject          *object);
63static void gnome_canvas_re_set_property (GObject              *object,
64                                          guint                 param_id,
65                                          const GValue         *value,
66                                          GParamSpec           *pspec);
67static void gnome_canvas_re_get_property (GObject              *object,
68                                          guint                 param_id,
69                                          GValue               *value,
70                                          GParamSpec           *pspec);
71
72static void gnome_canvas_rect_update      (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags);
73static void gnome_canvas_ellipse_update      (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags);
74
75static GnomeCanvasItemClass *re_parent_class;
76
77
78GType
79gnome_canvas_re_get_type (void)
80{
81        static GType re_type;
82
83        if (!re_type) {
84                static const GTypeInfo object_info = {
85                        sizeof (GnomeCanvasREClass),
86                        (GBaseInitFunc) NULL,
87                        (GBaseFinalizeFunc) NULL,
88                        (GClassInitFunc) gnome_canvas_re_class_init,
89                        (GClassFinalizeFunc) NULL,
90                        NULL,                   /* class_data */
91                        sizeof (GnomeCanvasRE),
92                        0,                      /* n_preallocs */
93                        (GInstanceInitFunc) gnome_canvas_re_init,
94                        NULL                    /* value_table */
95                };
96
97                re_type = g_type_register_static (GNOME_TYPE_CANVAS_SHAPE, "GnomeCanvasRE",
98                                                  &object_info, 0);
99        }
100
101        return re_type;
102}
103
104static void
105gnome_canvas_re_class_init (GnomeCanvasREClass *class)
106{
107        GObjectClass *gobject_class;
108        GtkObjectClass *object_class;
109        GnomeCanvasItemClass *item_class;
110
111        gobject_class = (GObjectClass *) class;
112        object_class = (GtkObjectClass *) class;
113        item_class = (GnomeCanvasItemClass *) class;
114
115        re_parent_class = g_type_class_peek_parent (class);
116
117        gobject_class->set_property = gnome_canvas_re_set_property;
118        gobject_class->get_property = gnome_canvas_re_get_property;
119
120        g_object_class_install_property
121                (gobject_class,
122                 PROP_X1,
123                 g_param_spec_double ("x1", NULL, NULL,
124                                      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
125                                      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
126        g_object_class_install_property
127                (gobject_class,
128                 PROP_Y1,
129                 g_param_spec_double ("y1", NULL, NULL,
130                                      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
131                                      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
132        g_object_class_install_property
133                (gobject_class,
134                 PROP_X2,
135                 g_param_spec_double ("x2", NULL, NULL,
136                                      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
137                                      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
138        g_object_class_install_property
139                (gobject_class,
140                 PROP_Y2,
141                 g_param_spec_double ("y2", NULL, NULL,
142                                      -G_MAXDOUBLE, G_MAXDOUBLE, 0,
143                                      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
144
145        object_class->destroy = gnome_canvas_re_destroy;
146}
147
148static void
149gnome_canvas_re_init (GnomeCanvasRE *re)
150{
151        re->x1 = 0.0;
152        re->y1 = 0.0;
153        re->x2 = 0.0;
154        re->y2 = 0.0;
155        re->path_dirty = 0;
156}
157
158static void
159gnome_canvas_re_destroy (GtkObject *object)
160{
161        GnomeCanvasRE *re;
162
163        g_return_if_fail (object != NULL);
164        g_return_if_fail (GNOME_IS_CANVAS_RE (object));
165
166        re = GNOME_CANVAS_RE (object);
167
168        if (GTK_OBJECT_CLASS (re_parent_class)->destroy)
169                (* GTK_OBJECT_CLASS (re_parent_class)->destroy) (object);
170}
171
172static void
173gnome_canvas_re_set_property (GObject              *object,
174                              guint                 param_id,
175                              const GValue         *value,
176                              GParamSpec           *pspec)
177{
178        GnomeCanvasItem *item;
179        GnomeCanvasRE *re;
180
181        g_return_if_fail (object != NULL);
182        g_return_if_fail (GNOME_IS_CANVAS_RE (object));
183
184        item = GNOME_CANVAS_ITEM (object);
185        re = GNOME_CANVAS_RE (object);
186
187        switch (param_id) {
188        case PROP_X1:
189                re->x1 = g_value_get_double (value);
190                re->path_dirty = 1;
191                gnome_canvas_item_request_update (item);
192                break;
193
194        case PROP_Y1:
195                re->y1 = g_value_get_double (value);
196                re->path_dirty = 1;
197                gnome_canvas_item_request_update (item);
198                break;
199
200        case PROP_X2:
201                re->x2 = g_value_get_double (value);
202                re->path_dirty = 1;
203                gnome_canvas_item_request_update (item);
204                break;
205
206        case PROP_Y2:
207                re->y2 = g_value_get_double (value);
208                re->path_dirty = 1;
209                gnome_canvas_item_request_update (item);
210                break;
211
212        default:
213                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
214                break;
215        }
216}
217
218static void
219gnome_canvas_re_get_property (GObject              *object,
220                              guint                 param_id,
221                              GValue               *value,
222                              GParamSpec           *pspec)
223{
224        GnomeCanvasRE *re;
225
226        g_return_if_fail (object != NULL);
227        g_return_if_fail (GNOME_IS_CANVAS_RE (object));
228
229        re = GNOME_CANVAS_RE (object);
230
231        switch (param_id) {
232        case PROP_X1:
233                g_value_set_double (value,  re->x1);
234                break;
235
236        case PROP_Y1:
237                g_value_set_double (value,  re->y1);
238                break;
239
240        case PROP_X2:
241                g_value_set_double (value,  re->x2);
242                break;
243
244        case PROP_Y2:
245                g_value_set_double (value,  re->y2);
246                break;
247
248        default:
249                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
250                break;
251        }
252}
253
254/* Rectangle item */
255static void gnome_canvas_rect_class_init (GnomeCanvasRectClass *class);
256
257
258
259GType
260gnome_canvas_rect_get_type (void)
261{
262        static GType rect_type;
263
264        if (!rect_type) {
265                static const GTypeInfo object_info = {
266                        sizeof (GnomeCanvasRectClass),
267                        (GBaseInitFunc) NULL,
268                        (GBaseFinalizeFunc) NULL,
269                        (GClassInitFunc) gnome_canvas_rect_class_init,
270                        (GClassFinalizeFunc) NULL,
271                        NULL,                   /* class_data */
272                        sizeof (GnomeCanvasRect),
273                        0,                      /* n_preallocs */
274                        (GInstanceInitFunc) NULL,
275                        NULL                    /* value_table */
276                };
277
278                rect_type = g_type_register_static (GNOME_TYPE_CANVAS_RE, "GnomeCanvasRect",
279                                                    &object_info, 0);
280        }
281
282        return rect_type;
283}
284
285static void
286gnome_canvas_rect_class_init (GnomeCanvasRectClass *class)
287{
288        GnomeCanvasItemClass *item_class;
289
290        item_class = (GnomeCanvasItemClass *) class;
291
292        item_class->update = gnome_canvas_rect_update;
293}
294
295static void
296gnome_canvas_rect_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags)
297{       GnomeCanvasRE *re;     
298
299        GnomeCanvasPathDef *path_def;
300
301        re = GNOME_CANVAS_RE(item);
302
303        if (re->path_dirty) {           
304                path_def = gnome_canvas_path_def_new ();
305               
306                gnome_canvas_path_def_moveto(path_def, re->x1, re->y1);
307                gnome_canvas_path_def_lineto(path_def, re->x2, re->y1);
308                gnome_canvas_path_def_lineto(path_def, re->x2, re->y2);
309                gnome_canvas_path_def_lineto(path_def, re->x1, re->y2);
310                gnome_canvas_path_def_lineto(path_def, re->x1, re->y1);         
311                gnome_canvas_path_def_closepath_current(path_def);             
312                gnome_canvas_shape_set_path_def (GNOME_CANVAS_SHAPE (item), path_def);
313                gnome_canvas_path_def_unref(path_def);
314                re->path_dirty = 0;
315        }
316
317        if (re_parent_class->update)
318                (* re_parent_class->update) (item, affine, clip_path, flags);
319}
320
321/* Ellipse item */
322
323
324static void gnome_canvas_ellipse_class_init (GnomeCanvasEllipseClass *class);
325
326
327GType
328gnome_canvas_ellipse_get_type (void)
329{
330        static GType ellipse_type;
331
332        if (!ellipse_type) {
333                static const GTypeInfo object_info = {
334                        sizeof (GnomeCanvasEllipseClass),
335                        (GBaseInitFunc) NULL,
336                        (GBaseFinalizeFunc) NULL,
337                        (GClassInitFunc) gnome_canvas_ellipse_class_init,
338                        (GClassFinalizeFunc) NULL,
339                        NULL,                   /* class_data */
340                        sizeof (GnomeCanvasEllipse),
341                        0,                      /* n_preallocs */
342                        (GInstanceInitFunc) NULL,
343                        NULL                    /* value_table */
344                };
345
346                ellipse_type = g_type_register_static (GNOME_TYPE_CANVAS_RE, "GnomeCanvasEllipse",
347                                                       &object_info, 0);
348        }
349
350        return ellipse_type;
351}
352
353static void
354gnome_canvas_ellipse_class_init (GnomeCanvasEllipseClass *class)
355{
356        GnomeCanvasItemClass *item_class;
357
358        item_class = (GnomeCanvasItemClass *) class;
359
360        item_class->update = gnome_canvas_ellipse_update;
361}
362
363#define N_PTS 90
364
365static void
366gnome_canvas_ellipse_update (GnomeCanvasItem *item, double affine[6], ArtSVP *clip_path, gint flags) {
367        GnomeCanvasPathDef *path_def;
368        GnomeCanvasRE *re;
369
370        re = GNOME_CANVAS_RE(item);
371
372        if (re->path_dirty) {
373                gdouble cx, cy, rx, ry;
374                gdouble beta = 0.26521648983954400922; /* 4*(1-cos(pi/8))/(3*sin(pi/8)) */
375                gdouble sincosA = 0.70710678118654752440; /* sin (pi/4), cos (pi/4) */
376                gdouble dx1, dy1, dx2, dy2;
377                gdouble mx, my;
378
379                path_def = gnome_canvas_path_def_new();
380
381                cx = (re->x2 + re->x1) * 0.5;
382                cy = (re->y2 + re->y1) * 0.5;
383                rx = re->x2 - cx;
384                ry = re->y2 - cy;
385
386                dx1 = beta * rx;
387                dy1 = beta * ry;
388                dx2 = beta * rx * sincosA;
389                dy2 = beta * ry * sincosA;
390                mx = rx * sincosA;
391                my = ry * sincosA;
392
393                gnome_canvas_path_def_moveto (path_def, cx + rx, cy);
394                gnome_canvas_path_def_curveto (path_def,
395                                               cx + rx, cy - dy1,
396                                               cx + mx + dx2, cy - my + dy2,
397                                               cx + mx, cy - my);
398                gnome_canvas_path_def_curveto (path_def,
399                                               cx + mx - dx2, cy - my - dy2,
400                                               cx + dx1, cy - ry,
401                                               cx, cy - ry);
402                gnome_canvas_path_def_curveto (path_def,
403                                               cx - dx1, cy - ry,
404                                               cx - mx + dx2, cy - my - dy2,
405                                               cx - mx, cy - my);
406                gnome_canvas_path_def_curveto (path_def,
407                                               cx - mx - dx2, cy - my + dy2,
408                                               cx - rx, cy - dy1,
409                                               cx - rx, cy);
410               
411                gnome_canvas_path_def_curveto (path_def,
412                                               cx - rx, cy + dy1,
413                                               cx - mx - dx2, cy + my - dy2,
414                                               cx - mx, cy + my);
415                gnome_canvas_path_def_curveto (path_def,
416                                               cx - mx + dx2, cy + my + dy2,
417                                               cx - dx1, cy + ry,
418                                               cx, cy + ry);
419                gnome_canvas_path_def_curveto (path_def,
420                                               cx + dx1, cy + ry,
421                                               cx + mx - dx2, cy + my + dy2,
422                                               cx + mx, cy + my);
423                gnome_canvas_path_def_curveto (path_def,
424                                               cx + mx + dx2, cy + my - dy2,
425                                               cx + rx, cy + dy1,
426                                               cx + rx, cy);
427               
428                gnome_canvas_path_def_closepath_current(path_def);
429               
430                gnome_canvas_shape_set_path_def (GNOME_CANVAS_SHAPE (item), path_def);
431                gnome_canvas_path_def_unref(path_def);
432                re->path_dirty = 0;
433        }
434
435        if (re_parent_class->update)
436                (* re_parent_class->update) (item, affine, clip_path, flags);
437}
Note: See TracBrowser for help on using the repository browser.