Merged with trunk R1622.
[ardour.git] / gtk2_ardour / canvas-simplerect.c
1 #include <stdio.h>
2 #include <math.h>
3 #include <libgnomecanvas/libgnomecanvas.h>
4
5 #include "canvas-simplerect.h"
6 #include "rgb_macros.h"
7 #include "gettext.h"
8 #define _(Text)  dgettext (PACKAGE,Text)
9
10 enum {
11         PROP_0,
12         PROP_X1,
13         PROP_Y1,
14         PROP_X2,
15         PROP_Y2,
16         PROP_OUTLINE_PIXELS,
17         PROP_OUTLINE_WHAT,
18         PROP_FILL,
19         PROP_FILL_COLOR_RGBA,
20         PROP_OUTLINE_COLOR_RGBA,
21         PROP_DRAW
22         
23 };
24
25 static void   gnome_canvas_simplerect_class_init    (GnomeCanvasSimpleRectClass *class);
26
27 static void   gnome_canvas_simplerect_init          (GnomeCanvasSimpleRect      *simplerect);
28
29 static void   gnome_canvas_simplerect_destroy       (GtkObject                  *object);
30
31 static void   gnome_canvas_simplerect_set_property  (GObject        *object,
32                                                      guint            prop_id,
33                                                      const GValue   *value,
34                                                      GParamSpec     *pspec);
35
36 static void   gnome_canvas_simplerect_get_property  (GObject        *object,
37                                                      guint           prop_id,
38                                                      GValue         *value,
39                                                      GParamSpec     *pspec);
40
41 static void   gnome_canvas_simplerect_update        (GnomeCanvasItem *item,
42                                                      double          *affine,
43                                                      ArtSVP          *clip_path,
44                                                      int              flags);
45
46 static void   gnome_canvas_simplerect_bounds        (GnomeCanvasItem *item,
47                                                      double          *x1,
48                                                      double          *y1,
49                                                      double          *x2,
50                                                      double          *y2);
51
52 static double gnome_canvas_simplerect_point         (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item);
53
54 static void   gnome_canvas_simplerect_render        (GnomeCanvasItem *item, GnomeCanvasBuf *buf);
55
56 static void   gnome_canvas_simplerect_draw          (GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int w, int h);
57
58 static GnomeCanvasItemClass *parent_class;
59
60
61 GType
62 gnome_canvas_simplerect_get_type (void)
63 {
64         static GType simplerect_type;
65
66         if (!simplerect_type) {
67                 static const GTypeInfo object_info = {
68                         sizeof (GnomeCanvasSimpleRectClass),
69                         (GBaseInitFunc) NULL,
70                         (GBaseFinalizeFunc) NULL,
71                         (GClassInitFunc) gnome_canvas_simplerect_class_init,
72                         (GClassFinalizeFunc) NULL,
73                         NULL,                   /* class_data */
74                         sizeof (GnomeCanvasSimpleRect),
75                         0,                      /* n_preallocs */
76                         (GInstanceInitFunc) gnome_canvas_simplerect_init,
77                         NULL                    /* value_table */
78                 };
79
80                 simplerect_type = g_type_register_static (GNOME_TYPE_CANVAS_ITEM, "GnomeCanvasSimpleRect",
81                                                           &object_info, 0);
82         }
83
84         return simplerect_type;
85 }
86
87 static void
88 gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class)
89 {
90         GObjectClass *gobject_class;
91         GtkObjectClass *object_class;
92         GnomeCanvasItemClass *item_class;
93
94         gobject_class = (GObjectClass *) class;
95         object_class = (GtkObjectClass *) class;
96         item_class = (GnomeCanvasItemClass *) class;
97         
98         parent_class = g_type_class_peek_parent (class);
99
100         gobject_class->set_property = gnome_canvas_simplerect_set_property;
101         gobject_class->get_property = gnome_canvas_simplerect_get_property;
102         
103         g_object_class_install_property (gobject_class,
104                                          PROP_X1,
105                                          g_param_spec_double ("x1",
106                                                               _("x1"),
107                                                               _("x coordinate of upper left corner of rect"),
108                                                               -G_MAXDOUBLE,
109                                                               G_MAXDOUBLE,
110                                                               0.0,
111                                                               G_PARAM_READWRITE));  
112         
113         g_object_class_install_property (gobject_class,
114                                          PROP_Y1,
115                                          g_param_spec_double ("y1",
116                                                               _("y1"),
117                                                               _("y coordinate of upper left corner of rect "),
118                                                               -G_MAXDOUBLE,
119                                                               G_MAXDOUBLE,
120                                                               0.0,
121                                                               G_PARAM_READWRITE));  
122         
123
124         g_object_class_install_property (gobject_class,
125                                          PROP_X2,
126                                          g_param_spec_double ("x2",
127                                                               _("x2"),
128                                                               _("x coordinate of lower right corner of rect"),
129                                                               -G_MAXDOUBLE,
130                                                               G_MAXDOUBLE,
131                                                               0.0,
132                                                               G_PARAM_READWRITE));  
133         
134         g_object_class_install_property (gobject_class,
135                                          PROP_Y2,
136                                          g_param_spec_double ("y2",
137                                                               _("y2"),
138                                                               _("y coordinate of lower right corner of rect "),
139                                                               -G_MAXDOUBLE,
140                                                               G_MAXDOUBLE,
141                                                               0.0,
142                                                               G_PARAM_READWRITE));  
143         
144
145         g_object_class_install_property (gobject_class,
146                                          PROP_OUTLINE_PIXELS,
147                                          g_param_spec_uint ("outline_pixels",
148                                                               _("outline pixels"),
149                                                               _("width in pixels of outline"),
150                                                               0,
151                                                               G_MAXUINT,
152                                                               0,
153                                                               G_PARAM_READWRITE));  
154         
155
156         g_object_class_install_property (gobject_class,
157                                          PROP_OUTLINE_WHAT,
158                                          g_param_spec_uint ("outline_what",
159                                                               _("outline what"),
160                                                               _("which boundaries to outline (mask)"),
161                                                               0,
162                                                               G_MAXUINT,
163                                                               0,
164                                                               G_PARAM_READWRITE));  
165         
166
167
168         g_object_class_install_property (gobject_class,
169                                          PROP_FILL,
170                                          g_param_spec_boolean ("fill",
171                                                                _("fill"),
172                                                                _("fill rectangle"),
173                                                                TRUE,
174                                                                G_PARAM_READWRITE));  
175         
176         g_object_class_install_property (gobject_class,
177                                          PROP_DRAW,
178                                          g_param_spec_boolean ("draw",
179                                                                _("draw"),
180                                                                _("draw rectangle"),
181                                                                TRUE,
182                                                                G_PARAM_READWRITE));  
183         
184
185         g_object_class_install_property (gobject_class,
186                                          PROP_OUTLINE_COLOR_RGBA,
187                                          g_param_spec_uint ("outline_color_rgba",
188                                                             _("outline color rgba"),
189                                                             _("color of outline"),
190                                                             0,
191                                                             G_MAXUINT,
192                                                             0,
193                                                             G_PARAM_READWRITE));  
194         
195
196         g_object_class_install_property (gobject_class,
197                                          PROP_FILL_COLOR_RGBA,
198                                          g_param_spec_uint ("fill_color_rgba",
199                                                             _("fill color rgba"),
200                                                             _("color of fill"),
201                                                             0,
202                                                             G_MAXUINT,
203                                                             0,
204                                                             G_PARAM_READWRITE));  
205
206         object_class->destroy = gnome_canvas_simplerect_destroy;
207
208         item_class->update = gnome_canvas_simplerect_update;
209         item_class->draw = gnome_canvas_simplerect_draw;
210         item_class->bounds = gnome_canvas_simplerect_bounds;
211         item_class->point = gnome_canvas_simplerect_point;
212         item_class->render = gnome_canvas_simplerect_render;
213
214 }
215
216 static void
217 gnome_canvas_simplerect_init (GnomeCanvasSimpleRect *simplerect)
218 {
219         simplerect->x1 = 0.0;
220         simplerect->y1 = 0.0;
221         simplerect->x2 = 0.0;
222         simplerect->y2 = 0.0;
223         simplerect->fill = TRUE;
224         simplerect->draw = TRUE;
225         simplerect->full_draw_on_update = TRUE;
226         simplerect->fill_color = 0;
227         simplerect->outline_color = 0;
228         simplerect->outline_pixels = 1;
229         simplerect->outline_what = 0xf;
230 }
231
232 static void
233 gnome_canvas_simplerect_destroy (GtkObject *object)
234 {
235         GnomeCanvasSimpleRect *rect;
236         
237         g_return_if_fail (object != NULL);
238         g_return_if_fail (GNOME_IS_CANVAS_SIMPLERECT (object));
239
240         rect = GNOME_CANVAS_SIMPLERECT (object);
241
242         /* remember, destroy can be run multiple times! */
243
244         if (GTK_OBJECT_CLASS (parent_class)->destroy)
245               (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
246 }
247
248 static void
249 gnome_canvas_simplerect_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
250 {
251         GnomeCanvasSimpleRect *simplerect = GNOME_CANVAS_SIMPLERECT (item);
252
253         *x1 = simplerect->x1;
254         *y1 = simplerect->y1;
255         *x2 = simplerect->x2 + 1;
256         *y2 = simplerect->y2 + 1;
257
258 }
259
260
261 static void 
262 gnome_canvas_simplerect_reset_bounds (GnomeCanvasItem *item)
263 {
264         GnomeCanvasSimpleRect* simplerect;
265         double x1, x2, y1, y2;
266         double old_x1, old_x2, old_y1, old_y2;
267         ArtDRect unionrect, old, new;
268
269         old_x1 = item->x1;
270         old_y1 = item->y1;
271         old_x2 = item->x2;
272         old_y2 = item->y2;
273         
274         gnome_canvas_simplerect_bounds (item, &x1, &y1, &x2, &y2);
275         gnome_canvas_item_i2w (item, &x1, &y1);
276         gnome_canvas_item_i2w (item, &x2, &y2);
277
278         item->x1 = x1;
279         item->y1 = y1;
280         item->x2 = x2;
281         item->y2 = y2;
282
283         /* now compute bounding box in canvas units */
284
285         simplerect = GNOME_CANVAS_SIMPLERECT (item);
286
287         gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x1, y1, &simplerect->bbox_ulx, &simplerect->bbox_uly);
288         gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x2, y2, &simplerect->bbox_lrx, &simplerect->bbox_lry);
289
290         /* now queue redraws for changed areas */
291
292         if (item->x1 == old_x1 && item->x2 == old_x2) {
293
294                 /* no change in x-axis position */
295
296                 if (item->y1 == old_y1) {
297                         /* top didn't change, so just draw bottom */
298
299                         double start_y = MIN (item->y2, old_y2);
300                         double end_y = MAX (item->y2, old_y2);
301
302                         gnome_canvas_request_redraw (item->canvas, item->x1, start_y - 0.5, item->x2, end_y + 1.5);
303                         return;
304
305                 } else if (item->y2 == old_y2) {
306
307                         /* bottom didn't change, just draw top */
308
309                         double start_y = MIN (item->y1, old_y1);
310                         double end_y = MAX (item->y1, old_y1);
311
312                         gnome_canvas_request_redraw (item->canvas, item->x1, start_y - 0.5, item->x2, end_y + 1.5);
313                         return;
314
315                 }
316
317         } else if (item->y1 == old_y1 && item->y2 == old_y2) {
318
319                 /* no change in y-axis position */
320
321                 if (item->x1 == old_x1) {
322                         /* start didn't change, so just draw at the end */
323
324                         double start_x = MIN (item->x2, old_x2);
325                         double end_x = MAX (item->x2, old_x2);
326
327                         gnome_canvas_request_redraw (item->canvas, start_x - 0.5, item->y1, end_x + 1.5, item->y2);
328                         return;
329
330                 } else if (item->x2 == old_x2) {
331
332                         /* end didn't change, so just draw at the start */
333                         
334                         double start_x = MIN (item->x1, old_x1);
335                         double end_x = MAX (item->x1, old_x1);
336
337                         gnome_canvas_request_redraw (item->canvas, start_x - 0.5, item->y1, end_x + 1.5, item->y2 + 0.5);
338                         return;
339
340                 }
341         } 
342
343         new.x0 = x1;
344         new.y0 = y1;
345         new.x1 = x2;
346         new.y1 = y2;
347
348         old.x0 = old_x1;
349         old.y0 = old_y1;
350         old.x1 = old_x2;
351         old.y1 = old_y2;
352
353         art_drect_union (&unionrect, &old, &new);
354         gnome_canvas_request_redraw (item->canvas, 
355                                      unionrect.x0 - 0.5,
356                                      unionrect.y0 - 0.5,
357                                      unionrect.x1 + 0.5,
358                                      unionrect.y1 + 0.5);
359 }
360
361 /* 
362  * CANVAS CALLBACKS 
363  */
364
365 static void
366 gnome_canvas_simplerect_set_property (GObject      *object,
367                                       guint         prop_id,
368                                       const GValue *value,
369                                       GParamSpec   *pspec)
370
371 {
372         GnomeCanvasSimpleRect *simplerect;
373         int update = FALSE;
374         int bounds_changed = FALSE;
375         g_return_if_fail (object != NULL);
376         g_return_if_fail (GNOME_IS_CANVAS_SIMPLERECT (object));
377
378         simplerect = GNOME_CANVAS_SIMPLERECT (object);
379
380         switch (prop_id) {
381         case PROP_X1:
382                 if (simplerect->x1 != g_value_get_double (value)) {
383                         simplerect->x1 = g_value_get_double (value);
384                         bounds_changed = TRUE;
385                 }
386                 break;
387
388         case PROP_Y1:
389                 if (simplerect->y1 != g_value_get_double (value)) {
390                         simplerect->y1 = g_value_get_double (value);
391                         bounds_changed = TRUE;
392                 }
393                 break;
394
395         case PROP_X2:
396                 if (simplerect->x2 != g_value_get_double (value)) {
397                         simplerect->x2 = g_value_get_double (value);
398                         bounds_changed = TRUE;
399                 }
400                 break;
401
402         case PROP_Y2:
403                 if (simplerect->y2 != g_value_get_double (value)) {
404                         simplerect->y2 = g_value_get_double (value);
405                         bounds_changed = TRUE;
406                 }
407                 break;
408
409         case PROP_DRAW:
410                 if (simplerect->draw != g_value_get_boolean (value)) {
411                         simplerect->draw = g_value_get_boolean (value);
412                         update = TRUE;
413                 }
414                 break;
415
416
417         case PROP_FILL:
418                 if (simplerect->fill != g_value_get_boolean (value)) {
419                         simplerect->fill = g_value_get_boolean (value);
420                         update = TRUE;
421                 }
422                 break;
423
424         case PROP_FILL_COLOR_RGBA:
425                 if (simplerect->fill_color != g_value_get_uint(value)) {
426                         simplerect->fill_color = g_value_get_uint(value);
427                         update = TRUE;
428                 }
429                 break;
430
431         case PROP_OUTLINE_COLOR_RGBA:
432                 if (simplerect->outline_color != g_value_get_uint(value)) {
433                         simplerect->outline_color = g_value_get_uint(value);
434                         update = TRUE;
435                 }
436                 break;
437
438         case PROP_OUTLINE_PIXELS:
439                 if (simplerect->outline_pixels != g_value_get_uint(value)) {
440                         simplerect->outline_pixels = g_value_get_uint(value);
441                         update = TRUE;
442                 }
443                 break;
444
445         case PROP_OUTLINE_WHAT:
446                 if (simplerect->outline_what != g_value_get_uint(value)) {
447                         simplerect->outline_what = g_value_get_uint(value);
448                         update = TRUE;
449                 }
450                 break;
451
452         default:
453                 break;
454         }
455
456         simplerect->full_draw_on_update = update;
457
458         if (update || bounds_changed) {
459                 gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(object));
460         }
461 }
462
463 static void
464 gnome_canvas_simplerect_get_property (GObject      *object,
465                                       guint         prop_id,
466                                       GValue       *value,
467                                       GParamSpec   *pspec)
468 {
469         GnomeCanvasSimpleRect *rect = GNOME_CANVAS_SIMPLERECT (object);
470         
471         g_return_if_fail (object != NULL);
472         g_return_if_fail (GNOME_IS_CANVAS_SIMPLERECT (object));
473
474         switch (prop_id) {
475         case PROP_X1:
476                 g_value_set_double (value, rect->x1);
477                 break;
478         case PROP_X2:
479                 g_value_set_double (value, rect->x2);
480                 break;
481         case PROP_Y1:
482                 g_value_set_double (value, rect->y1);
483                 break;
484         case PROP_Y2:
485                 g_value_set_double (value, rect->y2);
486                 break;
487         case PROP_OUTLINE_WHAT:
488                 g_value_set_uint (value, rect->outline_what);
489                 break;
490         case PROP_FILL:
491                 g_value_set_boolean (value, rect->fill);
492                 break;
493         case PROP_OUTLINE_PIXELS:
494                 g_value_set_uint (value, rect->outline_pixels);
495                 break;
496         case PROP_FILL_COLOR_RGBA:
497                 g_value_set_uint (value, rect->fill_color);
498                 break;
499         case PROP_OUTLINE_COLOR_RGBA:
500                 g_value_set_uint (value, rect->outline_color);
501                 break;
502         case PROP_DRAW:
503                 g_value_set_boolean (value, rect->draw);
504                 break;
505                 
506         default:
507                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
508                 break;
509         }
510 }
511
512
513 static void
514 gnome_canvas_simplerect_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
515 {
516         GnomeCanvasSimpleRect *simplerect;
517         unsigned char foo;
518
519         simplerect = GNOME_CANVAS_SIMPLERECT (item);
520
521         if (parent_class->update)
522                 (* parent_class->update) (item, affine, clip_path, flags);
523
524         gnome_canvas_simplerect_reset_bounds (item);
525
526         if (simplerect->full_draw_on_update) {
527                 gnome_canvas_request_redraw (item->canvas, 
528                                            simplerect->bbox_ulx,
529                                            simplerect->bbox_uly,
530                                            simplerect->bbox_lrx+0.5,
531                                            simplerect->bbox_lry+0.5);
532                 simplerect->full_draw_on_update = FALSE;
533         }
534
535         UINT_TO_RGBA (simplerect->fill_color, &simplerect->fill_r, &simplerect->fill_g, &simplerect->fill_b, &simplerect->fill_a);
536         UINT_TO_RGBA (simplerect->outline_color, &simplerect->outline_r, &simplerect->outline_g, &simplerect->outline_b, &foo);
537 }
538
539 // this can be useful for debugging/understanding how the canvas redraws
540 // stuff.
541
542 #undef HARLEQUIN_DEBUGGING
543
544 #undef SIMPLERECT_FAST_RENDERER
545 #ifdef SIMPLERECT_FAST_RENDERER
546
547 static void
548 gnome_canvas_simplerect_render (GnomeCanvasItem *item,
549                               GnomeCanvasBuf *buf)
550 {
551         GnomeCanvasSimpleRect *simplerect;
552         int end, begin;
553         int ey, sy;
554         unsigned int i;
555         ArtIRect intersection;
556         ArtIRect self;
557
558         simplerect = GNOME_CANVAS_SIMPLERECT (item);
559
560         if (parent_class->render) {
561                 (*parent_class->render) (item, buf);
562         }
563         
564         if (buf->is_bg) {
565
566 #ifdef HARLEQUIN_DEBUGGING
567                 gint randr, randg, randb;
568                 randr = random() % 255;
569                 randg = random() % 255;
570                 randb = random() % 255;
571                 PAINT_BOX(buf, randr, randg, randb, 255, buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1);
572 #endif
573                 gnome_canvas_buf_ensure_buf (buf);
574                 buf->is_bg = FALSE;
575         }
576
577         if (!simplerect->draw) {
578                 return;
579         }
580         
581         self.x0 = simplerect->bbox_ulx;
582         self.y0 = simplerect->bbox_uly;
583         self.x1 = simplerect->bbox_lrx;
584         self.y1 = simplerect->bbox_lry;
585
586         art_irect_intersect (&intersection, &self, &buf->rect);
587
588         begin = MAX(simplerect->bbox_ulx, buf->rect.x0);
589         end = MIN((simplerect->bbox_lrx-1), buf->rect.x1);
590
591         sy = simplerect->bbox_uly;
592         ey = simplerect->bbox_lry-1;
593
594         if (simplerect->fill) {
595                 
596                 // this can be useful for debugging/understanding how the canvas redraws
597                 // stuff.
598
599 #ifdef HARLEQUIN_DEBUGGING
600                 gint randr, randg, randb;
601                 randr = random() % 255;
602                 randg = random() % 255;
603                 randb = random() % 255;
604                 PAINT_BOX(buf, randr, randg, randb, simplerect->fill_a, begin, sy, end, ey);
605 #else           
606                 PAINT_BOX (buf, simplerect->fill_r, simplerect->fill_g, simplerect->fill_b, simplerect->fill_a, 
607                            intersection.x0, intersection.y0,
608                            intersection.x1, intersection.y1);
609 #endif
610                 
611         }
612
613         for (i = 0; i < simplerect->outline_pixels; ++i) {
614
615                 if (simplerect->outline_what & 0x1) {
616                         if (begin == simplerect->bbox_ulx) {
617                                 PAINT_VERT(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin + i, sy, ey);
618                         }
619                 }
620
621                 if (simplerect->outline_what & 0x2) {
622                         if (end == (simplerect->bbox_lrx - 1)) {
623                                 PAINT_VERT(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, end - i, sy, ey + 1);
624                         }
625                 }
626
627                 if (simplerect->outline_what & 0x4) {
628                         PAINT_HORIZ(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin, end, sy+i);
629                 }
630         
631                 if (simplerect->outline_what & 0x8) {
632                         PAINT_HORIZ(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin, end + 1, ey-i);
633                 }
634         }
635 }
636
637 #else /* SIMPLERECT_FAST_RENDERER */
638
639 static void
640 gnome_canvas_simplerect_render (GnomeCanvasItem *item,
641                               GnomeCanvasBuf *buf)
642 {
643         GnomeCanvasSimpleRect *simplerect;
644         int end, begin;
645         int ey, sy;
646         unsigned int i;
647
648         simplerect = GNOME_CANVAS_SIMPLERECT (item);
649
650         if (parent_class->render) {
651                 (*parent_class->render) (item, buf);
652         }
653
654         if (buf->is_bg) {
655
656 #ifdef HARLEQUIN_DEBUGGING
657                 gint randr, randg, randb;
658                 randr = random() % 255;
659                 randg = random() % 255;
660                 randb = random() % 255;
661                 PAINT_BOX(buf, randr, randg, randb, 255, buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1);
662 #endif
663                 gnome_canvas_buf_ensure_buf (buf);
664                 buf->is_bg = FALSE;
665         }
666
667         if (!simplerect->draw) {
668                 return;
669         }
670
671         begin = MAX(simplerect->bbox_ulx,buf->rect.x0);
672         end = MIN((simplerect->bbox_lrx-1),buf->rect.x1);
673
674         sy = simplerect->bbox_uly;
675         ey = simplerect->bbox_lry-1;
676
677         if (simplerect->fill) {
678                 
679 #ifdef HARLEQUIN_DEBUGGING
680                 gint randr, randg, randb;
681                 randr = random() % 255;
682                 randg = random() % 255;
683                 randb = random() % 255;
684                 PAINT_BOX(buf, randr, randg, randb, simplerect->fill_a, begin, sy, end, ey);
685 #else           
686                 PAINT_BOX(buf, simplerect->fill_r, simplerect->fill_g, simplerect->fill_b, simplerect->fill_a, begin, sy, end, ey);
687 #endif
688         }
689
690         for (i = 0; i < simplerect->outline_pixels; ++i) {
691
692                 if (simplerect->outline_what & 0x1) {
693                         if (begin == simplerect->bbox_ulx) {
694                                 PAINT_VERT(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin + i, sy, ey);
695                         }
696                 }
697
698                 if (simplerect->outline_what & 0x2) {
699                         if (end == (simplerect->bbox_lrx - 1)) {
700                                 PAINT_VERT(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, end - i, sy, ey + 1);
701                         }
702                 }
703
704                 if (simplerect->outline_what & 0x4) {
705                         PAINT_HORIZ(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin, end, sy+i);
706                 }
707         
708                 if (simplerect->outline_what & 0x8) {
709                         PAINT_HORIZ(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin, end + 1, ey-i);
710                 }
711         }
712 }
713 #endif /* SIMPLERECT_FAST_RENDERER */
714
715 static void
716 gnome_canvas_simplerect_draw (GnomeCanvasItem *item,
717                             GdkDrawable *drawable,
718                             int x, int y,
719                             int width, int height)
720 {
721         fprintf (stderr, "please don't use the CanvasSimpleRect item in a non-aa Canvas\n");
722         abort ();
723 }
724
725 static double
726 gnome_canvas_simplerect_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item)
727 {
728         GnomeCanvasSimpleRect *simplerect;
729         double x1, y1, x2, y2;
730         double dx, dy;
731
732         simplerect = GNOME_CANVAS_SIMPLERECT (item);
733
734         *actual_item = item;
735
736         /* Find the bounds for the rectangle plus its outline width */
737
738         gnome_canvas_simplerect_bounds (item, &x1, &y1, &x2, &y2);
739
740         /* Is point inside rectangle */
741         
742         if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
743                 return 0.0;
744         }
745
746         /* Point is outside rectangle */
747
748         if (x < x1)
749                 dx = x1 - x;
750         else if (x > x2)
751                 dx = x - x2;
752         else
753                 dx = 0.0;
754
755         if (y < y1)
756                 dy = y1 - y;
757         else if (y > y2)
758                 dy = y - y2;
759         else
760                 dy = 0.0;
761
762         return sqrt (dx * dx + dy * dy);
763 }