improve calltips in vala plugin
[anjuta.git] / libfoocanvas / foo-canvas-polygon.c
blob0e604b5887e996bd014c53c972ea35584d4df43e
1 /*
2 * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation
3 * All rights reserved.
5 * This file is part of the Gnome Library.
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.
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.
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.
23 @NOTATION@
25 /* Polygon item type for FooCanvas widget
27 * FooCanvas 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.
30 * Author: Federico Mena <federico@nuclecu.unam.mx>
33 #include <config.h>
34 #include <math.h>
35 #include <string.h>
36 #include "libfoocanvas.h"
39 #define NUM_STATIC_POINTS 256 /* Number of static points to use to avoid allocating arrays */
42 #define GROW_BOUNDS(bx1, by1, bx2, by2, x, y) { \
43 if (x < bx1) \
44 bx1 = x; \
46 if (x > bx2) \
47 bx2 = x; \
49 if (y < by1) \
50 by1 = y; \
52 if (y > by2) \
53 by2 = y; \
57 enum {
58 PROP_0,
59 PROP_POINTS,
60 PROP_FILL_COLOR,
61 PROP_FILL_COLOR_GDK,
62 PROP_FILL_COLOR_RGBA,
63 PROP_OUTLINE_COLOR,
64 PROP_OUTLINE_COLOR_GDK,
65 PROP_OUTLINE_COLOR_RGBA,
66 PROP_FILL_STIPPLE,
67 PROP_OUTLINE_STIPPLE,
68 PROP_WIDTH_PIXELS,
69 PROP_WIDTH_UNITS,
70 PROP_AA
74 static void foo_canvas_polygon_class_init (FooCanvasPolygonClass *klass);
75 static void foo_canvas_polygon_init (FooCanvasPolygon *poly);
76 static void foo_canvas_polygon_destroy (GtkObject *object);
77 static void foo_canvas_polygon_set_property (GObject *object,
78 guint param_id,
79 const GValue *value,
80 GParamSpec *pspec);
81 static void foo_canvas_polygon_get_property (GObject *object,
82 guint param_id,
83 GValue *value,
84 GParamSpec *pspec);
86 static void foo_canvas_polygon_update (FooCanvasItem *item,
87 double i2w_dx, double i2w_dy,
88 int flags);
89 static void foo_canvas_polygon_draw (FooCanvasItem *item, GdkDrawable *drawable,
90 GdkEventExpose *expose);
91 static double foo_canvas_polygon_point (FooCanvasItem *item, double x, double y,
92 int cx, int cy, FooCanvasItem **actual_item);
93 static void foo_canvas_polygon_translate (FooCanvasItem *item, double dx, double dy);
94 static void foo_canvas_polygon_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2);
97 static FooCanvasItemClass *parent_class;
99 G_DEFINE_TYPE (FooCanvasPolygon, foo_canvas_polygon, FOO_TYPE_CANVAS_ITEM)
101 static void
102 foo_canvas_polygon_class_init (FooCanvasPolygonClass *klass)
104 GObjectClass *gobject_class;
105 GtkObjectClass *object_class;
106 FooCanvasItemClass *item_class;
108 gobject_class = (GObjectClass *) klass;
109 object_class = (GtkObjectClass *) klass;
110 item_class = (FooCanvasItemClass *) klass;
112 parent_class = g_type_class_peek_parent (klass);
114 gobject_class->set_property = foo_canvas_polygon_set_property;
115 gobject_class->get_property = foo_canvas_polygon_get_property;
117 g_object_class_install_property
118 (gobject_class,
119 PROP_POINTS,
120 g_param_spec_boxed ("points", NULL, NULL,
121 FOO_TYPE_CANVAS_POINTS,
122 G_PARAM_READWRITE));
123 g_object_class_install_property
124 (gobject_class,
125 PROP_FILL_COLOR,
126 g_param_spec_string ("fill-color", NULL, NULL,
127 NULL,
128 G_PARAM_READWRITE));
129 g_object_class_install_property
130 (gobject_class,
131 PROP_FILL_COLOR_GDK,
132 g_param_spec_boxed ("fill-color-gdk", NULL, NULL,
133 GDK_TYPE_COLOR,
134 G_PARAM_READWRITE));
135 g_object_class_install_property
136 (gobject_class,
137 PROP_FILL_COLOR_RGBA,
138 g_param_spec_uint ("fill-color-rgba", NULL, NULL,
139 0, G_MAXUINT, 0,
140 G_PARAM_READWRITE));
141 g_object_class_install_property
142 (gobject_class,
143 PROP_OUTLINE_COLOR,
144 g_param_spec_string ("outline-color", NULL, NULL,
145 NULL,
146 G_PARAM_READWRITE));
147 g_object_class_install_property
148 (gobject_class,
149 PROP_OUTLINE_COLOR_GDK,
150 g_param_spec_boxed ("outline-color-gdk", NULL, NULL,
151 GDK_TYPE_COLOR,
152 G_PARAM_READWRITE));
153 g_object_class_install_property
154 (gobject_class,
155 PROP_OUTLINE_COLOR_RGBA,
156 g_param_spec_uint ("outline-color-rgba", NULL, NULL,
157 0, G_MAXUINT, 0,
158 G_PARAM_READWRITE));
159 g_object_class_install_property
160 (gobject_class,
161 PROP_FILL_STIPPLE,
162 g_param_spec_object ("fill-stipple", NULL, NULL,
163 GDK_TYPE_DRAWABLE,
164 G_PARAM_READWRITE));
165 g_object_class_install_property
166 (gobject_class,
167 PROP_OUTLINE_STIPPLE,
168 g_param_spec_object ("outline-stipple", NULL, NULL,
169 GDK_TYPE_DRAWABLE,
170 G_PARAM_READWRITE));
171 g_object_class_install_property
172 (gobject_class,
173 PROP_WIDTH_PIXELS,
174 g_param_spec_uint ("width-pixels", NULL, NULL,
175 0, G_MAXUINT, 0,
176 G_PARAM_READWRITE));
177 g_object_class_install_property
178 (gobject_class,
179 PROP_WIDTH_UNITS,
180 g_param_spec_double ("width-units", NULL, NULL,
181 0.0, G_MAXDOUBLE, 0.0,
182 G_PARAM_READWRITE));
183 g_object_class_install_property
184 (gobject_class,
185 PROP_AA,
186 g_param_spec_boolean ("aa", NULL, NULL,
187 FALSE,
188 G_PARAM_READWRITE));
190 object_class->destroy = foo_canvas_polygon_destroy;
192 item_class->update = foo_canvas_polygon_update;
193 item_class->draw = foo_canvas_polygon_draw;
194 item_class->point = foo_canvas_polygon_point;
195 item_class->translate = foo_canvas_polygon_translate;
196 item_class->bounds = foo_canvas_polygon_bounds;
199 static void
200 foo_canvas_polygon_init (FooCanvasPolygon *poly)
202 poly->width = 1.0;
203 poly->aa = TRUE;
206 static void
207 foo_canvas_polygon_destroy (GtkObject *object)
209 FooCanvasPolygon *poly;
211 g_return_if_fail (object != NULL);
212 g_return_if_fail (FOO_IS_CANVAS_POLYGON (object));
214 poly = FOO_CANVAS_POLYGON (object);
216 /* remember, destroy can be run multiple times! */
218 if (poly->coords)
219 g_free (poly->coords);
220 poly->coords = NULL;
222 if (poly->fill_stipple)
223 g_object_unref (poly->fill_stipple);
224 poly->fill_stipple = NULL;
226 if (poly->outline_stipple)
227 g_object_unref (poly->outline_stipple);
228 poly->outline_stipple = NULL;
230 if (GTK_OBJECT_CLASS (parent_class)->destroy)
231 (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
234 /* Computes the bounding box of the polygon. Assumes that the number of points in the polygon is
235 * not zero.
237 static gboolean
238 get_bounds (FooCanvasPolygon *poly, double *bx1, double *by1, double *bx2, double *by2)
240 double *coords;
241 double x1, y1, x2, y2;
242 double width;
243 int i;
245 if (poly->num_points == 0)
246 return FALSE;
248 /* Compute bounds of vertices */
250 x1 = x2 = poly->coords[0];
251 y1 = y2 = poly->coords[1];
253 for (i = 1, coords = poly->coords + 2; i < poly->num_points; i++, coords += 2) {
254 GROW_BOUNDS (x1, y1, x2, y2, coords[0], coords[1]);
257 /* Add outline width */
259 if (poly->width_pixels)
260 width = poly->width / poly->item.canvas->pixels_per_unit;
261 else
262 width = poly->width;
264 width /= 2.0;
266 x1 -= width;
267 y1 -= width;
268 x2 += width;
269 y2 += width;
271 /* Done */
273 *bx1 = x1;
274 *by1 = y1;
275 *bx2 = x2;
276 *by2 = y2;
277 return TRUE;
280 /* Computes the bounding box of the polygon, in canvas coordinates. Assumes that the number of points in the polygon is
281 * not zero.
283 static gboolean
284 get_bounds_canvas (FooCanvasPolygon *poly,
285 double *bx1, double *by1, double *bx2, double *by2,
286 double i2w_dx, double i2w_dy)
288 FooCanvasItem *item;
289 double bbox_x0, bbox_y0, bbox_x1, bbox_y1;
291 item = FOO_CANVAS_ITEM (poly);
293 if (!get_bounds (poly, &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1))
294 return FALSE;
296 bbox_x0 += i2w_dx;
297 bbox_y0 += i2w_dy;
298 bbox_x1 += i2w_dx;
299 bbox_y1 += i2w_dy;
301 foo_canvas_w2c_rect_d (item->canvas,
302 &bbox_x0, &bbox_y0, &bbox_x1, &bbox_y1);
304 /* include 1 pixel of fudge */
305 *bx1 = bbox_x0 - 1;
306 *by1 = bbox_y0 - 1;
307 *bx2 = bbox_x1 + 1;
308 *by2 = bbox_y1 + 1;
309 return TRUE;
312 /* Sets the points of the polygon item to the specified ones. If needed, it will add a point to
313 * close the polygon.
315 static void
316 set_points (FooCanvasPolygon *poly, FooCanvasPoints *points)
318 int duplicate;
320 /* See if we need to duplicate the first point */
322 duplicate = ((points->coords[0] != points->coords[2 * points->num_points - 2])
323 || (points->coords[1] != points->coords[2 * points->num_points - 1]));
325 if (duplicate)
326 poly->num_points = points->num_points + 1;
327 else
328 poly->num_points = points->num_points;
330 poly->coords = g_new (double, 2 * poly->num_points);
331 memcpy (poly->coords, points->coords, 2 * points->num_points * sizeof (double));
333 if (duplicate) {
334 poly->coords[2 * poly->num_points - 2] = poly->coords[0];
335 poly->coords[2 * poly->num_points - 1] = poly->coords[1];
339 static void
340 foo_canvas_polygon_set_property (GObject *object,
341 guint param_id,
342 const GValue *value,
343 GParamSpec *pspec)
345 FooCanvasItem *item;
346 FooCanvasPolygon *poly;
347 FooCanvasPoints *points;
348 GdkColor color = { 0, 0, 0, 0, };
349 GdkColor *pcolor;
350 int have_pixel;
352 g_return_if_fail (object != NULL);
353 g_return_if_fail (FOO_IS_CANVAS_POLYGON (object));
355 item = FOO_CANVAS_ITEM (object);
356 poly = FOO_CANVAS_POLYGON (object);
357 have_pixel = FALSE;
359 switch (param_id) {
360 case PROP_POINTS:
361 points = g_value_get_boxed (value);
363 if (poly->coords) {
364 g_free (poly->coords);
365 poly->coords = NULL;
368 if (!points)
369 poly->num_points = 0;
370 else
371 set_points (poly, points);
373 foo_canvas_item_request_update (item);
374 break;
376 case PROP_FILL_COLOR:
377 case PROP_FILL_COLOR_GDK:
378 case PROP_FILL_COLOR_RGBA:
379 switch (param_id) {
380 case PROP_FILL_COLOR:
381 if (g_value_get_string (value) &&
382 gdk_color_parse (g_value_get_string (value), &color))
383 poly->fill_set = TRUE;
384 else
385 poly->fill_set = FALSE;
387 poly->fill_color = ((color.red & 0xff00) << 16 |
388 (color.green & 0xff00) << 8 |
389 (color.blue & 0xff00) |
390 0xff);
391 break;
393 case PROP_FILL_COLOR_GDK:
394 pcolor = g_value_get_boxed (value);
395 poly->fill_set = pcolor != NULL;
397 if (pcolor) {
398 GdkColormap *colormap;
400 color = *pcolor;
401 colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
402 gdk_rgb_find_color (colormap, &color);
403 have_pixel = TRUE;
406 poly->fill_color = ((color.red & 0xff00) << 16 |
407 (color.green & 0xff00) << 8 |
408 (color.blue & 0xff00) |
409 0xff);
410 break;
412 case PROP_FILL_COLOR_RGBA:
413 poly->fill_set = TRUE;
414 poly->fill_color = g_value_get_uint (value);
415 break;
417 #ifdef VERBOSE
418 g_print ("poly fill color = %08x\n", poly->fill_color);
419 #endif
420 if (have_pixel)
421 poly->fill_pixel = color.pixel;
422 else
423 poly->fill_pixel = foo_canvas_get_color_pixel (item->canvas,
424 poly->fill_color);
426 foo_canvas_item_request_redraw (item);
427 break;
429 case PROP_OUTLINE_COLOR:
430 case PROP_OUTLINE_COLOR_GDK:
431 case PROP_OUTLINE_COLOR_RGBA:
432 switch (param_id) {
433 case PROP_OUTLINE_COLOR:
434 if (g_value_get_string (value) &&
435 gdk_color_parse (g_value_get_string (value), &color))
436 poly->outline_set = TRUE;
437 else
438 poly->outline_set = FALSE;
440 poly->outline_color = ((color.red & 0xff00) << 16 |
441 (color.green & 0xff00) << 8 |
442 (color.blue & 0xff00) |
443 0xff);
444 break;
446 case PROP_OUTLINE_COLOR_GDK:
447 pcolor = g_value_get_boxed (value);
448 poly->outline_set = pcolor != NULL;
450 if (pcolor) {
451 GdkColormap *colormap;
453 color = *pcolor;
454 colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas));
455 gdk_rgb_find_color (colormap, &color);
456 have_pixel = TRUE;
459 poly->outline_color = ((color.red & 0xff00) << 16 |
460 (color.green & 0xff00) << 8 |
461 (color.blue & 0xff00) |
462 0xff);
463 break;
465 case PROP_OUTLINE_COLOR_RGBA:
466 poly->outline_set = TRUE;
467 poly->outline_color = g_value_get_uint (value);
468 break;
470 #ifdef VERBOSE
471 g_print ("poly outline color = %08x\n", poly->outline_color);
472 #endif
473 if (have_pixel)
474 poly->outline_pixel = color.pixel;
475 else
476 poly->outline_pixel = foo_canvas_get_color_pixel (item->canvas,
477 poly->outline_color);
479 foo_canvas_item_request_redraw (item);
480 break;
482 case PROP_FILL_STIPPLE:
483 if (poly->fill_stipple)
484 g_object_unref (poly->fill_stipple);
485 poly->fill_stipple = (GdkBitmap *) g_value_get_object (value);
486 g_object_ref (poly->fill_stipple);
487 foo_canvas_item_request_update (item);
488 break;
490 case PROP_OUTLINE_STIPPLE:
491 if (poly->outline_stipple)
492 g_object_unref (poly->outline_stipple);
493 poly->outline_stipple = (GdkBitmap *) g_value_get_object (value);
494 g_object_ref (poly->outline_stipple);
495 foo_canvas_item_request_update (item);
496 break;
498 case PROP_WIDTH_PIXELS:
499 poly->width = g_value_get_uint (value);
500 poly->width_pixels = TRUE;
501 #ifdef OLD_XFORM
502 recalc_bounds (poly);
503 #else
504 foo_canvas_item_request_update (item);
505 #endif
506 break;
508 case PROP_WIDTH_UNITS:
509 poly->width = fabs (g_value_get_double (value));
510 poly->width_pixels = FALSE;
511 #ifdef OLD_XFORM
512 recalc_bounds (poly);
513 #else
514 foo_canvas_item_request_update (item);
515 #endif
516 break;
517 case PROP_AA:
518 poly->aa = g_value_get_boolean (value);
519 foo_canvas_item_request_update (item);
520 break;
522 default:
523 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
524 break;
528 /* Allocates a GdkColor structure filled with the specified pixel, and puts it into the specified
529 * value for returning it in the get_property method.
531 static void
532 get_color_value (FooCanvasPolygon *poly, gulong pixel, GValue *value)
534 GdkColor *color;
535 GdkColormap *colormap;
537 color = g_new (GdkColor, 1);
538 color->pixel = pixel;
540 colormap = gtk_widget_get_colormap (GTK_WIDGET (poly));
541 gdk_rgb_find_color (colormap, color);
542 g_value_set_boxed (value, color);
545 static void
546 foo_canvas_polygon_get_property (GObject *object,
547 guint param_id,
548 GValue *value,
549 GParamSpec *pspec)
551 FooCanvasPolygon *poly;
552 FooCanvasPoints *points;
554 g_return_if_fail (object != NULL);
555 g_return_if_fail (FOO_IS_CANVAS_POLYGON (object));
557 poly = FOO_CANVAS_POLYGON (object);
559 switch (param_id) {
560 case PROP_POINTS:
561 if (poly->num_points != 0) {
562 points = foo_canvas_points_new (poly->num_points);
563 memcpy (points->coords, poly->coords, 2 * poly->num_points * sizeof (double));
564 g_value_set_boxed (value, points);
565 } else
566 g_value_set_boxed (value, NULL);
567 break;
569 case PROP_FILL_COLOR_GDK:
570 get_color_value (poly, poly->fill_pixel, value);
571 break;
573 case PROP_OUTLINE_COLOR_GDK:
574 get_color_value (poly, poly->outline_pixel, value);
575 break;
577 case PROP_FILL_COLOR_RGBA:
578 g_value_set_uint (value, poly->fill_color);
579 break;
581 case PROP_OUTLINE_COLOR_RGBA:
582 g_value_set_uint (value, poly->outline_color);
583 break;
585 case PROP_FILL_STIPPLE:
586 g_value_set_object (value, (GObject *) poly->fill_stipple);
587 break;
589 case PROP_OUTLINE_STIPPLE:
590 g_value_set_object (value, (GObject *) poly->outline_stipple);
591 break;
593 case PROP_AA:
594 g_value_set_boolean (value, poly->aa);
595 break;
597 default:
598 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
599 break;
603 static void
604 foo_canvas_polygon_update (FooCanvasItem *item,
605 double i2w_dx, double i2w_dy,
606 int flags)
608 FooCanvasPolygon *poly;
609 double x1, y1, x2, y2;
611 poly = FOO_CANVAS_POLYGON (item);
613 if (parent_class->update)
614 (* parent_class->update) (item, i2w_dx, i2w_dy, flags);
616 if (get_bounds_canvas (poly, &x1, &y1, &x2, &y2, i2w_dx, i2w_dy))
617 foo_canvas_update_bbox (item, x1, y1, x2, y2);
620 /* Converts an array of world coordinates into an array of canvas pixel coordinates. Takes in the
621 * item->world deltas and the drawable deltas.
623 static void
624 item_to_canvas (FooCanvas *canvas, double *item_coords, GdkPoint *canvas_coords, int num_points,
625 double i2w_dx, double i2w_dy)
627 int i;
629 for (i = 0; i < num_points; i++) {
630 foo_canvas_w2c (canvas,
631 item_coords[i*2] + i2w_dx,
632 item_coords[i*2+1] + i2w_dy,
633 &canvas_coords->x, &canvas_coords->y);
634 canvas_coords++;
638 static void
639 foo_canvas_polygon_draw (FooCanvasItem *item, GdkDrawable *drawable,
640 GdkEventExpose *expose)
642 cairo_t *cr;
643 FooCanvasPolygon *poly;
644 GdkPoint static_points[NUM_STATIC_POINTS];
645 GdkPoint *points;
646 double i2w_dx, i2w_dy;
647 double width;
648 gint i;
650 poly = FOO_CANVAS_POLYGON (item);
652 if (poly->num_points == 0)
653 return;
655 /* Build array of canvas pixel coordinates */
657 if (poly->num_points <= NUM_STATIC_POINTS)
658 points = static_points;
659 else
660 points = g_new (GdkPoint, poly->num_points);
662 i2w_dx = 0.0;
663 i2w_dy = 0.0;
664 foo_canvas_item_i2w (item, &i2w_dx, &i2w_dy);
666 item_to_canvas (item->canvas,
667 poly->coords, points, poly->num_points,
668 i2w_dx, i2w_dy);
670 if (poly->width_pixels)
671 width = poly->width;
672 else
673 width = poly->width * poly->item.canvas->pixels_per_unit;
675 cr = gdk_cairo_create (drawable);
676 if (!poly->aa)
677 cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
678 cairo_set_line_width (cr, width);
680 cairo_move_to (cr, points[0].x, points[0].y);
681 for(i = 1; i < poly->num_points - 1; i++)
683 cairo_line_to (cr, points[i].x, points[i].y);
685 cairo_close_path (cr);
687 if (poly->fill_set) {
688 /* FIXME: Set stripple */
689 cairo_set_source_rgba (cr,
690 ((double) ((poly->fill_color & 0xff000000) >> 24)) / 255,
691 ((double) ((poly->fill_color & 0xff0000) >> 16)) / 255,
692 ((double) ((poly->fill_color & 0xff00) >> 8)) / 255,
693 ((double) ((poly->fill_color & 0xff))) / 255);
694 cairo_fill_preserve (cr);
697 if (poly->outline_set) {
698 /* FIXME: Set stripple */
699 cairo_set_source_rgba (cr,
700 ((double) ((poly->outline_color & 0xff000000) >> 24)) / 255,
701 ((double) ((poly->outline_color & 0xff0000) >> 16)) / 255,
702 ((double) ((poly->outline_color & 0xff00) >> 8)) / 255,
703 ((double) ((poly->outline_color & 0xff))) / 255);
704 cairo_stroke (cr);
707 /* Done */
709 if (points != static_points)
710 g_free (points);
713 static double
714 foo_canvas_polygon_point (FooCanvasItem *item, double x, double y,
715 int cx, int cy, FooCanvasItem **actual_item)
717 FooCanvasPolygon *poly;
718 double dist;
719 double width;
721 poly = FOO_CANVAS_POLYGON (item);
723 *actual_item = item;
725 dist = foo_canvas_polygon_to_point (poly->coords, poly->num_points, x, y);
727 if (poly->outline_set) {
728 if (poly->width_pixels)
729 width = poly->width / item->canvas->pixels_per_unit;
730 else
731 width = poly->width;
733 dist -= width / 2.0;
735 if (dist < 0.0)
736 dist = 0.0;
739 return dist;
742 static void
743 foo_canvas_polygon_translate (FooCanvasItem *item, double dx, double dy)
745 FooCanvasPolygon *poly;
746 int i;
747 double *coords;
749 poly = FOO_CANVAS_POLYGON (item);
751 for (i = 0, coords = poly->coords; i < poly->num_points; i++, coords += 2) {
752 coords[0] += dx;
753 coords[1] += dy;
758 static void
759 foo_canvas_polygon_bounds (FooCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
761 FooCanvasPolygon *poly;
763 g_return_if_fail (item != NULL);
764 g_return_if_fail (FOO_IS_CANVAS_POLYGON (item));
766 poly = FOO_CANVAS_POLYGON (item);
768 if (poly->num_points == 0) {
769 *x1 = *y1 = *x2 = *y2 = 0.0;
770 return;
773 get_bounds (poly, x1, y1, x2, y2);