ardour
canvas-simplerect.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <math.h>
3 #include <cairo.h>
4 #include <libgnomecanvas/libgnomecanvas.h>
5 
6 #include "canvas-simplerect.h"
7 #include "rgb_macros.h"
8 #include "gettext.h"
9 #define _(Text) dgettext (PACKAGE,Text)
10 
11 enum {
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
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,
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,
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,
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,
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
234 {
235  g_return_if_fail (object != NULL);
236  g_return_if_fail (GNOME_IS_CANVAS_SIMPLERECT (object));
237 
238  /* remember, destroy can be run multiple times! */
239 
240  if (GTK_OBJECT_CLASS (parent_class)->destroy)
241  (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
242 }
243 
244 static void
245 gnome_canvas_simplerect_bounds (GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
246 {
247  GnomeCanvasSimpleRect *simplerect = GNOME_CANVAS_SIMPLERECT (item);
248 
249  *x1 = simplerect->x1;
250  *y1 = simplerect->y1;
251  *x2 = simplerect->x2 + 1;
252  *y2 = simplerect->y2 + 1;
253 }
254 
255 
256 static void
258 {
259  GnomeCanvasSimpleRect* simplerect;
260  double x1, x2, y1, y2;
261  double old_x1, old_x2, old_y1, old_y2;
262  ArtDRect unionrect, old, new;
263 
264  old_x1 = item->x1;
265  old_y1 = item->y1;
266  old_x2 = item->x2;
267  old_y2 = item->y2;
268 
269  gnome_canvas_simplerect_bounds (item, &x1, &y1, &x2, &y2);
270  gnome_canvas_item_i2w (item, &x1, &y1);
271  gnome_canvas_item_i2w (item, &x2, &y2);
272 
273  item->x1 = x1;
274  item->y1 = y1;
275  item->x2 = x2;
276  item->y2 = y2;
277 
278  /* now compute bounding box in canvas units */
279 
280  simplerect = GNOME_CANVAS_SIMPLERECT (item);
281 
282  gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x1, y1, &simplerect->bbox_ulx, &simplerect->bbox_uly);
283  gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x2, y2, &simplerect->bbox_lrx, &simplerect->bbox_lry);
284 
285  /* now queue redraws for changed areas */
286 
287  if (item->x1 == old_x1 && item->x2 == old_x2) {
288 
289  /* no change in x-axis position */
290 
291  if (item->y1 == old_y1) {
292  /* top didn't change, so just draw bottom */
293 
294  double start_y = MIN (item->y2, old_y2);
295  double end_y = MAX (item->y2, old_y2);
296 
297  gnome_canvas_request_redraw (item->canvas, item->x1, start_y - 0.5, item->x2, end_y + 1.5);
298  return;
299 
300  } else if (item->y2 == old_y2) {
301 
302  /* bottom didn't change, just draw top */
303 
304  double start_y = MIN (item->y1, old_y1);
305  double end_y = MAX (item->y1, old_y1);
306 
307  gnome_canvas_request_redraw (item->canvas, item->x1, start_y - 0.5, item->x2, end_y + 1.5);
308  return;
309 
310  }
311 
312  } else if (item->y1 == old_y1 && item->y2 == old_y2) {
313 
314  /* no change in y-axis position */
315 
316  if (item->x1 == old_x1) {
317  /* start didn't change, so just draw at the end */
318 
319  double start_x = MIN (item->x2, old_x2);
320  double end_x = MAX (item->x2, old_x2);
321 
322  gnome_canvas_request_redraw (item->canvas, start_x - 0.5, item->y1, end_x + 1.5, item->y2 + 0.5);
323  return;
324 
325  } else if (item->x2 == old_x2) {
326 
327  /* end didn't change, so just draw at the start */
328 
329  double start_x = MIN (item->x1, old_x1);
330  double end_x = MAX (item->x1, old_x1);
331 
332  gnome_canvas_request_redraw (item->canvas, start_x - 0.5, item->y1, end_x + 1.5, item->y2 + 0.5);
333  return;
334 
335  }
336  }
337 
338  new.x0 = x1;
339  new.y0 = y1;
340  new.x1 = x2;
341  new.y1 = y2;
342 
343  old.x0 = old_x1;
344  old.y0 = old_y1;
345  old.x1 = old_x2;
346  old.y1 = old_y2;
347 
348  art_drect_union (&unionrect, &old, &new);
349  gnome_canvas_request_redraw (item->canvas,
350  unionrect.x0 - 0.5,
351  unionrect.y0 - 0.5,
352  unionrect.x1 + 1.5,
353  unionrect.y1 + 1.5);
354 }
355 
356 /*
357  * CANVAS CALLBACKS
358  */
359 
360 static void
362  guint prop_id,
363  const GValue *value,
364  GParamSpec *pspec)
365 
366 {
367  (void) pspec;
368 
369  GnomeCanvasSimpleRect *simplerect;
370  int update = FALSE;
371  int bounds_changed = FALSE;
372  g_return_if_fail (object != NULL);
373  g_return_if_fail (GNOME_IS_CANVAS_SIMPLERECT (object));
374 
375  simplerect = GNOME_CANVAS_SIMPLERECT (object);
376 
377  switch (prop_id) {
378  case PROP_X1:
379  if (simplerect->x1 != g_value_get_double (value)) {
380  simplerect->x1 = g_value_get_double (value);
381  bounds_changed = TRUE;
382  }
383  break;
384 
385  case PROP_Y1:
386  if (simplerect->y1 != g_value_get_double (value)) {
387  simplerect->y1 = g_value_get_double (value);
388  bounds_changed = TRUE;
389  }
390  break;
391 
392  case PROP_X2:
393  if (simplerect->x2 != g_value_get_double (value)) {
394  simplerect->x2 = g_value_get_double (value);
395  bounds_changed = TRUE;
396  }
397  break;
398 
399  case PROP_Y2:
400  if (simplerect->y2 != g_value_get_double (value)) {
401  simplerect->y2 = g_value_get_double (value);
402  bounds_changed = TRUE;
403  }
404  break;
405 
406  case PROP_DRAW:
407  if (simplerect->draw != g_value_get_boolean (value)) {
408  simplerect->draw = g_value_get_boolean (value);
409  update = TRUE;
410  }
411  break;
412 
413 
414  case PROP_FILL:
415  if (simplerect->fill != g_value_get_boolean (value)) {
416  simplerect->fill = g_value_get_boolean (value);
417  update = TRUE;
418  }
419  break;
420 
422  if (simplerect->fill_color != g_value_get_uint(value)) {
423  simplerect->fill_color = g_value_get_uint(value);
424  update = TRUE;
425  }
426  break;
427 
429  if (simplerect->outline_color != g_value_get_uint(value)) {
430  simplerect->outline_color = g_value_get_uint(value);
431  update = TRUE;
432  }
433  break;
434 
435  case PROP_OUTLINE_PIXELS:
436  if (simplerect->outline_pixels != g_value_get_uint(value)) {
437  simplerect->outline_pixels = g_value_get_uint(value);
438  update = TRUE;
439  }
440  break;
441 
442  case PROP_OUTLINE_WHAT:
443  if (simplerect->outline_what != g_value_get_uint(value)) {
444  simplerect->outline_what = g_value_get_uint(value);
445  update = TRUE;
446  }
447  break;
448 
449  default:
450  break;
451  }
452 
453  if (!simplerect->full_draw_on_update) {
454  /* XXX: not sure about this;
455  *
456  * I changed the next line to be conditional, rather than always
457  * being executed. Without the condition, the following bug occurs:
458  *
459  * caller sets a property (e.g. outline colour); this sets update = TRUE and hence full_draw_on_update = TRUE
460  * update is requested (and it is intended, I suppose, that during this update, full_draw_on_update is noted)
461  * ... update does not occur before ...
462  * caller sets the same property again to the same value; this sets update = FALSE and hence full_draw_on_update = FALSE
463  * update now occurs, but full_draw_on_update is FALSE, so the full redraw does not happen,
464  * which results in graphical glitches.
465  *
466  * (Carl, 2/1/2010)
467  */
468  simplerect->full_draw_on_update = update;
469  }
470 
471  if (update || bounds_changed) {
472  gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(object));
473  }
474 }
475 
476 static void
478  guint prop_id,
479  GValue *value,
480  GParamSpec *pspec)
481 {
482  GnomeCanvasSimpleRect *rect = GNOME_CANVAS_SIMPLERECT (object);
483 
484  g_return_if_fail (object != NULL);
485  g_return_if_fail (GNOME_IS_CANVAS_SIMPLERECT (object));
486 
487  switch (prop_id) {
488  case PROP_X1:
489  g_value_set_double (value, rect->x1);
490  break;
491  case PROP_X2:
492  g_value_set_double (value, rect->x2);
493  break;
494  case PROP_Y1:
495  g_value_set_double (value, rect->y1);
496  break;
497  case PROP_Y2:
498  g_value_set_double (value, rect->y2);
499  break;
500  case PROP_OUTLINE_WHAT:
501  g_value_set_uint (value, rect->outline_what);
502  break;
503  case PROP_FILL:
504  g_value_set_boolean (value, rect->fill);
505  break;
506  case PROP_OUTLINE_PIXELS:
507  g_value_set_uint (value, rect->outline_pixels);
508  break;
510  g_value_set_uint (value, rect->fill_color);
511  break;
513  g_value_set_uint (value, rect->outline_color);
514  break;
515  case PROP_DRAW:
516  g_value_set_boolean (value, rect->draw);
517  break;
518 
519  default:
520  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
521  break;
522  }
523 }
524 
525 
526 static void
527 gnome_canvas_simplerect_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
528 {
529  GnomeCanvasSimpleRect *simplerect;
530 
531  simplerect = GNOME_CANVAS_SIMPLERECT (item);
532 
533  if (parent_class->update)
534  (* parent_class->update) (item, affine, clip_path, flags);
535 
537 
538  if (simplerect->full_draw_on_update) {
539  gnome_canvas_request_redraw (item->canvas,
540  simplerect->bbox_ulx,
541  simplerect->bbox_uly,
542  simplerect->bbox_lrx+0.5,
543  simplerect->bbox_lry+0.5);
544  simplerect->full_draw_on_update = FALSE;
545  }
546 
547  UINT_TO_RGBA (simplerect->fill_color, &simplerect->fill_r, &simplerect->fill_g, &simplerect->fill_b, &simplerect->fill_a);
548  UINT_TO_RGBA (simplerect->outline_color, &simplerect->outline_r, &simplerect->outline_g, &simplerect->outline_b, &simplerect->outline_a);
549 }
550 
551 // this can be useful for debugging/understanding how the canvas redraws
552 // stuff.
553 
554 #undef HARLEQUIN_DEBUGGING
555 
556 #undef SIMPLERECT_FAST_RENDERER
557 #ifdef SIMPLERECT_FAST_RENDERER
558 
559 static void
560 gnome_canvas_simplerect_render (GnomeCanvasItem *item,
561  GnomeCanvasBuf *buf)
562 {
563  GnomeCanvasSimpleRect *simplerect;
564  int end, begin;
565  int ey, sy;
566  unsigned int i;
567  ArtIRect intersection;
568  ArtIRect self;
569 
570  simplerect = GNOME_CANVAS_SIMPLERECT (item);
571 
572  if (parent_class->render) {
573  (*parent_class->render) (item, buf);
574  }
575 
576  if (buf->is_bg) {
577 
578 #ifdef HARLEQUIN_DEBUGGING
579  gint randr, randg, randb;
580  randr = random() % 255;
581  randg = random() % 255;
582  randb = random() % 255;
583  PAINT_BOX(buf, randr, randg, randb, 255, buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1);
584 #endif
585  gnome_canvas_buf_ensure_buf (buf);
586  buf->is_bg = FALSE;
587  }
588 
589  if (!simplerect->draw) {
590  return;
591  }
592 
593  self.x0 = simplerect->bbox_ulx;
594  self.y0 = simplerect->bbox_uly;
595  self.x1 = simplerect->bbox_lrx;
596  self.y1 = simplerect->bbox_lry;
597 
598  art_irect_intersect (&intersection, &self, &buf->rect);
599 
600  begin = MAX(simplerect->bbox_ulx, buf->rect.x0);
601  end = MIN((simplerect->bbox_lrx-1), buf->rect.x1);
602 
603  sy = simplerect->bbox_uly;
604  ey = simplerect->bbox_lry-1;
605 
606  if (simplerect->fill) {
607 
608  // this can be useful for debugging/understanding how the canvas redraws
609  // stuff.
610 
611 #ifdef HARLEQUIN_DEBUGGING
612  gint randr, randg, randb;
613  randr = random() % 255;
614  randg = random() % 255;
615  randb = random() % 255;
616  PAINT_BOX(buf, randr, randg, randb, simplerect->fill_a, begin, sy, end, ey);
617 #else
618  PAINT_BOX (buf, simplerect->fill_r, simplerect->fill_g, simplerect->fill_b, simplerect->fill_a,
619  intersection.x0, intersection.y0,
620  intersection.x1, intersection.y1);
621 #endif
622 
623  }
624 
625  if (simplerect->outline_a > 0) {
626  for (i = 0; i < simplerect->outline_pixels; ++i) {
627 
628  if (simplerect->outline_what & 0x1) {
629  if (begin == simplerect->bbox_ulx) {
630  PAINT_VERTA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin + i, sy, ey);
631  }
632  }
633 
634  if (simplerect->outline_what & 0x2) {
635  if (end == (simplerect->bbox_lrx - 1)) {
636  PAINT_VERTA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, end - i, sy, ey + 1);
637  }
638  }
639 
640  if (simplerect->outline_what & 0x4) {
641  PAINT_HORIZA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin, end, sy+i);
642  }
643 
644  if (simplerect->outline_what & 0x8) {
645  PAINT_HORIZA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin, end + 1, ey-i);
646  }
647  }
648  }
649 }
650 
651 #else /* SIMPLERECT_FAST_RENDERER */
652 
653 static void
654 gnome_canvas_simplerect_render (GnomeCanvasItem *item,
655  GnomeCanvasBuf *buf)
656 {
657  GnomeCanvasSimpleRect *simplerect;
658  int end, begin;
659  int ey, sy;
660  int i;
661 
662  simplerect = GNOME_CANVAS_SIMPLERECT (item);
663 
664  if (parent_class->render) {
665  (*parent_class->render) (item, buf);
666  }
667 
668  if (buf->is_bg) {
669 
670 #ifdef HARLEQUIN_DEBUGGING
671  gint randr, randg, randb;
672  randr = random() % 255;
673  randg = random() % 255;
674  randb = random() % 255;
675  PAINT_BOX(buf, randr, randg, randb, 255, buf->rect.x0, buf->rect.y0, buf->rect.x1, buf->rect.y1);
676 #endif
677  gnome_canvas_buf_ensure_buf (buf);
678  buf->is_bg = FALSE;
679  }
680 
681  if (!simplerect->draw) {
682  return;
683  }
684 
685  begin = MAX(simplerect->bbox_ulx,buf->rect.x0);
686  end = MIN((simplerect->bbox_lrx-1),buf->rect.x1);
687 
688  sy = simplerect->bbox_uly;
689  ey = simplerect->bbox_lry-1;
690 
691  if (simplerect->fill) {
692 
693 #ifdef HARLEQUIN_DEBUGGING
694  gint randr, randg, randb;
695  randr = random() % 255;
696  randg = random() % 255;
697  randb = random() % 255;
698  PAINT_BOX(buf, randr, randg, randb, simplerect->fill_a, begin, sy, end, ey);
699 #else
700  PAINT_BOX(buf, simplerect->fill_r, simplerect->fill_g, simplerect->fill_b, simplerect->fill_a, begin, sy, end, ey);
701 #endif
702  }
703 
704  if (simplerect->outline_a) {
705  for (i = 0; i < (int) simplerect->outline_pixels; ++i) {
706 
707  if (simplerect->outline_what & 0x1) {
708  if (begin == simplerect->bbox_ulx) {
709  PAINT_VERTA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin + i, sy, ey);
710  }
711  }
712 
713  if (simplerect->outline_what & 0x2) {
714  if (end == (simplerect->bbox_lrx - 1)) {
715  PAINT_VERTA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, end - i, sy, ey + 1);
716  }
717  }
718 
719  if (simplerect->outline_what & 0x4) {
720  PAINT_HORIZA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin, end, sy+i);
721  }
722 
723  if (simplerect->outline_what & 0x8) {
724  PAINT_HORIZA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin, end + 1, ey-i);
725  }
726  }
727  }
728 }
729 #endif /* SIMPLERECT_FAST_RENDERER */
730 
731 static void
732 gnome_canvas_simplerect_draw (GnomeCanvasItem *item,
733  GdkDrawable *drawable,
734  int x, int y,
735  int width, int height)
736 {
737  GnomeCanvasSimpleRect *simplerect;
738  cairo_t* cr;
739  double ulx;
740  double uly;
741  double lrx;
742  double lry;
743 
744  simplerect = GNOME_CANVAS_SIMPLERECT (item);
745 
746  cr = gdk_cairo_create (drawable);
747 
748  if (x > simplerect->bbox_ulx) {
749  ulx = x;
750  } else {
751  ulx = simplerect->bbox_ulx;
752  }
753 
754  if (y > simplerect->bbox_uly) {
755  uly = y;
756  } else {
757  uly = simplerect->bbox_uly;
758  }
759 
760  if (x + width > simplerect->bbox_lrx) {
761  lrx = simplerect->bbox_lrx;
762  } else {
763  lrx = x + width;
764  }
765 
766  if (y + height > simplerect->bbox_lry) {
767  lry = simplerect->bbox_lry;
768  } else {
769  lry = y + height;
770  }
771 
772  ulx -= x;
773  uly -= y;
774  lrx -= x;
775  lry -= y;
776 
777  cairo_rectangle (cr, ulx, uly, lrx - ulx, lry - uly);
778 
779  if (simplerect->fill) {
780  cairo_set_source_rgba (cr,
781  simplerect->fill_r/255.0,
782  simplerect->fill_g/255.0,
783  simplerect->fill_b/255.0,
784  simplerect->fill_a/255.0);
785  cairo_fill (cr);
786  }
787 
788  if (simplerect->outline_what && simplerect->outline_pixels) {
789 
790 #define x_in_range(a) (x <= (a) && (a) < x + width)
791 #define y_in_range(a) (y <= (a) && (a) < y + height)
792 
793  cairo_set_line_width (cr, simplerect->outline_pixels);
794 
795  cairo_set_source_rgb (cr,
796  simplerect->outline_r/255.0,
797  simplerect->outline_g/255.0,
798  simplerect->outline_b/255.0);
799 
800  if (simplerect->outline_what & 0x1) {
801  /* left edge, if visible */
802  if (x_in_range (simplerect->bbox_ulx)) {
803  cairo_move_to (cr, ulx+0.5, uly+0.5);
804  cairo_line_to (cr, ulx+0.5, lry+0.5);
805  cairo_stroke (cr);
806  }
807  }
808 
809  if (simplerect->outline_what & 0x2) {
810  /* right edge, if visible */
811  if (x_in_range (simplerect->bbox_lrx)) {
812  cairo_move_to (cr, lrx+0.5, uly+0.5);
813  cairo_line_to (cr, lrx+0.5, lry+0.5);
814  cairo_stroke (cr);
815  }
816  }
817 
818  if (simplerect->outline_what & 0x4) {
819  /* top edge */
820  if (y_in_range (simplerect->bbox_uly)) {
821  cairo_move_to (cr, ulx+0.5, uly+0.5);
822  cairo_line_to (cr, lrx+0.5, uly+0.5);
823  cairo_stroke (cr);
824  }
825  }
826 
827  if (simplerect->outline_what & 0x8) {
828  /* bottom edge */
829  if (y_in_range (simplerect->bbox_lry)) {
830  cairo_move_to (cr, ulx+0.5, lry+0.5);
831  cairo_line_to (cr, lrx+0.5, lry+0.5);
832  cairo_stroke (cr);
833  }
834  }
835  }
836 
837  cairo_destroy (cr);
838 }
839 
840 static double
841 gnome_canvas_simplerect_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item)
842 {
843  (void) cx;
844  (void) cy;
845 
846  double x1, y1, x2, y2;
847  double dx, dy;
848 
849  *actual_item = item;
850 
851  /* Find the bounds for the rectangle plus its outline width */
852 
853  gnome_canvas_simplerect_bounds (item, &x1, &y1, &x2, &y2);
854 
855  /* Is point inside rectangle */
856 
857  if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) {
858  return 0.0;
859  }
860 
861  /* Point is outside rectangle */
862 
863  if (x < x1)
864  dx = x1 - x;
865  else if (x > x2)
866  dx = x - x2;
867  else
868  dx = 0.0;
869 
870  if (y < y1)
871  dy = y1 - y;
872  else if (y > y2)
873  dy = y - y2;
874  else
875  dy = 0.0;
876 
877  return sqrt (dx * dx + dy * dy);
878 }
#define MAX(a, b)
Definition: session_ltc.cc:42
#define y_in_range(a)
static void gnome_canvas_simplerect_class_init(GnomeCanvasSimpleRectClass *class)
#define UINT_TO_RGBA(u, r, g, b, a)
Definition: fastmeter.cc:35
static void gnome_canvas_simplerect_draw(GnomeCanvasItem *item, GdkDrawable *drawable, int x, int y, int w, int h)
#define PAINT_HORIZA(inbuf, colr, colg, colb, cola, ptx0, ptx1, pty)
Definition: rgb_macros.h:167
static void gnome_canvas_simplerect_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
#define _(Text)
static void gnome_canvas_simplerect_reset_bounds(GnomeCanvasItem *item)
static GnomeCanvasItemClass * parent_class
static void gnome_canvas_simplerect_destroy(GtkObject *object)
#define PAINT_VERTA(inbuf, colr, colg, colb, cola, ptx, pty0, pty1)
Definition: rgb_macros.h:222
static void gnome_canvas_simplerect_update(GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags)
static void gnome_canvas_simplerect_init(GnomeCanvasSimpleRect *simplerect)
GType gnome_canvas_simplerect_get_type(void)
#define x_in_range(a)
static double gnome_canvas_simplerect_point(GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item)
static void gnome_canvas_simplerect_render(GnomeCanvasItem *item, GnomeCanvasBuf *buf)
#define MIN(a, b)
Definition: session_ltc.cc:45
#define PAINT_BOX(inbuf, colr, colg, colb, cola, ptx0, pty0, ptx1, pty1)
Definition: rgb_macros.h:271
static void gnome_canvas_simplerect_bounds(GnomeCanvasItem *item, double *x1, double *y1, double *x2, double *y2)
static void gnome_canvas_simplerect_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)