X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Fcanvas-simplerect.c;h=fe6e1855be03848cd092b7699c31b3032a8a3f52;hb=54fd56de755a44420d906ad660b18c2d671f1057;hp=d50943f0c3dfc55ba9b3868898eabb0f8d483d3b;hpb=767984b486086e3682e521179c2fb8364b3bba76;p=ardour.git diff --git a/gtk2_ardour/canvas-simplerect.c b/gtk2_ardour/canvas-simplerect.c index d50943f0c3..fe6e1855be 100644 --- a/gtk2_ardour/canvas-simplerect.c +++ b/gtk2_ardour/canvas-simplerect.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "canvas-simplerect.h" @@ -19,7 +20,6 @@ enum { PROP_FILL_COLOR_RGBA, PROP_OUTLINE_COLOR_RGBA, PROP_DRAW - }; static void gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class); @@ -94,12 +94,12 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) gobject_class = (GObjectClass *) class; object_class = (GtkObjectClass *) class; item_class = (GnomeCanvasItemClass *) class; - + parent_class = g_type_class_peek_parent (class); gobject_class->set_property = gnome_canvas_simplerect_set_property; gobject_class->get_property = gnome_canvas_simplerect_get_property; - + g_object_class_install_property (gobject_class, PROP_X1, g_param_spec_double ("x1", @@ -108,8 +108,8 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_Y1, g_param_spec_double ("y1", @@ -118,8 +118,8 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_X2, @@ -129,8 +129,8 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_Y2, g_param_spec_double ("y2", @@ -139,8 +139,8 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, - G_PARAM_READWRITE)); - + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_OUTLINE_PIXELS, @@ -150,8 +150,8 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) 0, G_MAXUINT, 0, - G_PARAM_READWRITE)); - + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_OUTLINE_WHAT, @@ -161,8 +161,8 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) 0, G_MAXUINT, 0, - G_PARAM_READWRITE)); - + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, @@ -171,16 +171,16 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) _("fill"), _("fill rectangle"), TRUE, - G_PARAM_READWRITE)); - + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_DRAW, g_param_spec_boolean ("draw", _("draw"), _("draw rectangle"), TRUE, - G_PARAM_READWRITE)); - + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_OUTLINE_COLOR_RGBA, @@ -190,8 +190,8 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) 0, G_MAXUINT, 0, - G_PARAM_READWRITE)); - + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_FILL_COLOR_RGBA, @@ -201,7 +201,7 @@ gnome_canvas_simplerect_class_init (GnomeCanvasSimpleRectClass *class) 0, G_MAXUINT, 0, - G_PARAM_READWRITE)); + G_PARAM_READWRITE)); object_class->destroy = gnome_canvas_simplerect_destroy; @@ -232,13 +232,9 @@ gnome_canvas_simplerect_init (GnomeCanvasSimpleRect *simplerect) static void gnome_canvas_simplerect_destroy (GtkObject *object) { - GnomeCanvasSimpleRect *rect; - g_return_if_fail (object != NULL); g_return_if_fail (GNOME_IS_CANVAS_SIMPLERECT (object)); - rect = GNOME_CANVAS_SIMPLERECT (object); - /* remember, destroy can be run multiple times! */ if (GTK_OBJECT_CLASS (parent_class)->destroy) @@ -254,11 +250,10 @@ gnome_canvas_simplerect_bounds (GnomeCanvasItem *item, double *x1, double *y1, d *y1 = simplerect->y1; *x2 = simplerect->x2 + 1; *y2 = simplerect->y2 + 1; - } -static void +static void gnome_canvas_simplerect_reset_bounds (GnomeCanvasItem *item) { GnomeCanvasSimpleRect* simplerect; @@ -270,7 +265,7 @@ gnome_canvas_simplerect_reset_bounds (GnomeCanvasItem *item) old_y1 = item->y1; old_x2 = item->x2; old_y2 = item->y2; - + gnome_canvas_simplerect_bounds (item, &x1, &y1, &x2, &y2); gnome_canvas_item_i2w (item, &x1, &y1); gnome_canvas_item_i2w (item, &x2, &y2); @@ -287,7 +282,7 @@ gnome_canvas_simplerect_reset_bounds (GnomeCanvasItem *item) gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x1, y1, &simplerect->bbox_ulx, &simplerect->bbox_uly); gnome_canvas_w2c (GNOME_CANVAS(item->canvas), x2, y2, &simplerect->bbox_lrx, &simplerect->bbox_lry); - /* now queue redraws for changed areas */ + /* now queue redraws for changed areas */ if (item->x1 == old_x1 && item->x2 == old_x2) { @@ -324,13 +319,13 @@ gnome_canvas_simplerect_reset_bounds (GnomeCanvasItem *item) double start_x = MIN (item->x2, old_x2); double end_x = MAX (item->x2, old_x2); - gnome_canvas_request_redraw (item->canvas, start_x - 0.5, item->y1, end_x + 1.5, item->y2); + gnome_canvas_request_redraw (item->canvas, start_x - 0.5, item->y1, end_x + 1.5, item->y2 + 0.5); return; } else if (item->x2 == old_x2) { /* end didn't change, so just draw at the start */ - + double start_x = MIN (item->x1, old_x1); double end_x = MAX (item->x1, old_x1); @@ -338,7 +333,7 @@ gnome_canvas_simplerect_reset_bounds (GnomeCanvasItem *item) return; } - } + } new.x0 = x1; new.y0 = y1; @@ -351,15 +346,15 @@ gnome_canvas_simplerect_reset_bounds (GnomeCanvasItem *item) old.y1 = old_y2; art_drect_union (&unionrect, &old, &new); - gnome_canvas_request_redraw (item->canvas, + gnome_canvas_request_redraw (item->canvas, unionrect.x0 - 0.5, unionrect.y0 - 0.5, unionrect.x1 + 1.5, unionrect.y1 + 1.5); } -/* - * CANVAS CALLBACKS +/* + * CANVAS CALLBACKS */ static void @@ -369,6 +364,8 @@ gnome_canvas_simplerect_set_property (GObject *object, GParamSpec *pspec) { + (void) pspec; + GnomeCanvasSimpleRect *simplerect; int update = FALSE; int bounds_changed = FALSE; @@ -453,7 +450,23 @@ gnome_canvas_simplerect_set_property (GObject *object, break; } - simplerect->full_draw_on_update = update; + if (!simplerect->full_draw_on_update) { + /* XXX: not sure about this; + * + * I changed the next line to be conditional, rather than always + * being executed. Without the condition, the following bug occurs: + * + * caller sets a property (e.g. outline colour); this sets update = TRUE and hence full_draw_on_update = TRUE + * update is requested (and it is intended, I suppose, that during this update, full_draw_on_update is noted) + * ... update does not occur before ... + * caller sets the same property again to the same value; this sets update = FALSE and hence full_draw_on_update = FALSE + * update now occurs, but full_draw_on_update is FALSE, so the full redraw does not happen, + * which results in graphical glitches. + * + * (Carl, 2/1/2010) + */ + simplerect->full_draw_on_update = update; + } if (update || bounds_changed) { gnome_canvas_item_request_update (GNOME_CANVAS_ITEM(object)); @@ -467,7 +480,7 @@ gnome_canvas_simplerect_get_property (GObject *object, GParamSpec *pspec) { GnomeCanvasSimpleRect *rect = GNOME_CANVAS_SIMPLERECT (object); - + g_return_if_fail (object != NULL); g_return_if_fail (GNOME_IS_CANVAS_SIMPLERECT (object)); @@ -502,7 +515,7 @@ gnome_canvas_simplerect_get_property (GObject *object, case PROP_DRAW: g_value_set_boolean (value, rect->draw); break; - + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -514,7 +527,6 @@ static void gnome_canvas_simplerect_update (GnomeCanvasItem *item, double *affine, ArtSVP *clip_path, int flags) { GnomeCanvasSimpleRect *simplerect; - unsigned char foo; simplerect = GNOME_CANVAS_SIMPLERECT (item); @@ -524,16 +536,16 @@ gnome_canvas_simplerect_update (GnomeCanvasItem *item, double *affine, ArtSVP *c gnome_canvas_simplerect_reset_bounds (item); if (simplerect->full_draw_on_update) { - gnome_canvas_request_redraw (item->canvas, - simplerect->bbox_ulx, - simplerect->bbox_uly, - simplerect->bbox_lrx+0.5, - simplerect->bbox_lry+0.5); + gnome_canvas_request_redraw (item->canvas, + simplerect->bbox_ulx, + simplerect->bbox_uly, + simplerect->bbox_lrx+0.5, + simplerect->bbox_lry+0.5); simplerect->full_draw_on_update = FALSE; } UINT_TO_RGBA (simplerect->fill_color, &simplerect->fill_r, &simplerect->fill_g, &simplerect->fill_b, &simplerect->fill_a); - UINT_TO_RGBA (simplerect->outline_color, &simplerect->outline_r, &simplerect->outline_g, &simplerect->outline_b, &foo); + UINT_TO_RGBA (simplerect->outline_color, &simplerect->outline_r, &simplerect->outline_g, &simplerect->outline_b, &simplerect->outline_a); } // this can be useful for debugging/understanding how the canvas redraws @@ -560,7 +572,7 @@ gnome_canvas_simplerect_render (GnomeCanvasItem *item, if (parent_class->render) { (*parent_class->render) (item, buf); } - + if (buf->is_bg) { #ifdef HARLEQUIN_DEBUGGING @@ -577,7 +589,7 @@ gnome_canvas_simplerect_render (GnomeCanvasItem *item, if (!simplerect->draw) { return; } - + self.x0 = simplerect->bbox_ulx; self.y0 = simplerect->bbox_uly; self.x1 = simplerect->bbox_lrx; @@ -592,7 +604,7 @@ gnome_canvas_simplerect_render (GnomeCanvasItem *item, ey = simplerect->bbox_lry-1; if (simplerect->fill) { - + // this can be useful for debugging/understanding how the canvas redraws // stuff. @@ -602,36 +614,38 @@ gnome_canvas_simplerect_render (GnomeCanvasItem *item, randg = random() % 255; randb = random() % 255; PAINT_BOX(buf, randr, randg, randb, simplerect->fill_a, begin, sy, end, ey); -#else - PAINT_BOX (buf, simplerect->fill_r, simplerect->fill_g, simplerect->fill_b, simplerect->fill_a, +#else + PAINT_BOX (buf, simplerect->fill_r, simplerect->fill_g, simplerect->fill_b, simplerect->fill_a, intersection.x0, intersection.y0, intersection.x1, intersection.y1); #endif - - } - - for (i = 0; i < simplerect->outline_pixels; ++i) { - - if (simplerect->outline_what & 0x1) { - if (begin == simplerect->bbox_ulx) { - PAINT_VERT(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin + i, sy, ey); - } - } - if (simplerect->outline_what & 0x2) { - if (end == (simplerect->bbox_lrx - 1)) { - PAINT_VERT(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, end - i, sy, ey + 1); - } - } - - if (simplerect->outline_what & 0x4) { - PAINT_HORIZ(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin, end, sy+i); - } - - if (simplerect->outline_what & 0x8) { - PAINT_HORIZ(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin, end + 1, ey-i); - } } + + if (simplerect->outline_a > 0) { + for (i = 0; i < simplerect->outline_pixels; ++i) { + + if (simplerect->outline_what & 0x1) { + if (begin == simplerect->bbox_ulx) { + PAINT_VERTA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin + i, sy, ey); + } + } + + if (simplerect->outline_what & 0x2) { + if (end == (simplerect->bbox_lrx - 1)) { + PAINT_VERTA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, end - i, sy, ey + 1); + } + } + + if (simplerect->outline_what & 0x4) { + PAINT_HORIZA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin, end, sy+i); + } + + if (simplerect->outline_what & 0x8) { + PAINT_HORIZA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin, end + 1, ey-i); + } + } + } } #else /* SIMPLERECT_FAST_RENDERER */ @@ -643,7 +657,7 @@ gnome_canvas_simplerect_render (GnomeCanvasItem *item, GnomeCanvasSimpleRect *simplerect; int end, begin; int ey, sy; - unsigned int i; + int i; simplerect = GNOME_CANVAS_SIMPLERECT (item); @@ -675,62 +689,163 @@ gnome_canvas_simplerect_render (GnomeCanvasItem *item, ey = simplerect->bbox_lry-1; if (simplerect->fill) { - + #ifdef HARLEQUIN_DEBUGGING gint randr, randg, randb; randr = random() % 255; randg = random() % 255; randb = random() % 255; PAINT_BOX(buf, randr, randg, randb, simplerect->fill_a, begin, sy, end, ey); -#else +#else PAINT_BOX(buf, simplerect->fill_r, simplerect->fill_g, simplerect->fill_b, simplerect->fill_a, begin, sy, end, ey); #endif } - for (i = 0; i < simplerect->outline_pixels; ++i) { + if (simplerect->outline_a) { + for (i = 0; i < (int) simplerect->outline_pixels; ++i) { + + if (simplerect->outline_what & 0x1) { + if (begin == simplerect->bbox_ulx) { + PAINT_VERTA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin + i, sy, ey); + } + } + + if (simplerect->outline_what & 0x2) { + if (end == (simplerect->bbox_lrx - 1)) { + PAINT_VERTA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, end - i, sy, ey + 1); + } + } + + if (simplerect->outline_what & 0x4) { + PAINT_HORIZA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin, end, sy+i); + } + + if (simplerect->outline_what & 0x8) { + PAINT_HORIZA(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, simplerect->outline_a, begin, end + 1, ey-i); + } + } + } +} +#endif /* SIMPLERECT_FAST_RENDERER */ + +static void +gnome_canvas_simplerect_draw (GnomeCanvasItem *item, + GdkDrawable *drawable, + int x, int y, + int width, int height) +{ + GnomeCanvasSimpleRect *simplerect; + cairo_t* cr; + double ulx; + double uly; + double lrx; + double lry; + + simplerect = GNOME_CANVAS_SIMPLERECT (item); + + cr = gdk_cairo_create (drawable); + + if (x > simplerect->bbox_ulx) { + ulx = x; + } else { + ulx = simplerect->bbox_ulx; + } + + if (y > simplerect->bbox_uly) { + uly = y; + } else { + uly = simplerect->bbox_uly; + } + + if (x + width > simplerect->bbox_lrx) { + lrx = simplerect->bbox_lrx; + } else { + lrx = x + width; + } + + if (y + height > simplerect->bbox_lry) { + lry = simplerect->bbox_lry; + } else { + lry = y + height; + } + + ulx -= x; + uly -= y; + lrx -= x; + lry -= y; + + cairo_rectangle (cr, ulx, uly, lrx - ulx, lry - uly); + + if (simplerect->fill) { + cairo_set_source_rgba (cr, + simplerect->fill_r/255.0, + simplerect->fill_g/255.0, + simplerect->fill_b/255.0, + simplerect->fill_a/255.0); + cairo_fill (cr); + } + + if (simplerect->outline_what && simplerect->outline_pixels) { + +#define x_in_range(a) (x <= (a) && (a) < x + width) +#define y_in_range(a) (y <= (a) && (a) < y + height) + + cairo_set_line_width (cr, simplerect->outline_pixels); + + cairo_set_source_rgb (cr, + simplerect->outline_r/255.0, + simplerect->outline_g/255.0, + simplerect->outline_b/255.0); if (simplerect->outline_what & 0x1) { - if (begin == simplerect->bbox_ulx) { - PAINT_VERT(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin + i, sy, ey); + /* left edge, if visible */ + if (x_in_range (simplerect->bbox_ulx)) { + cairo_move_to (cr, ulx+0.5, uly+0.5); + cairo_line_to (cr, ulx+0.5, lry+0.5); + cairo_stroke (cr); } } if (simplerect->outline_what & 0x2) { - if (end == (simplerect->bbox_lrx - 1)) { - PAINT_VERT(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, end - i, sy, ey + 1); + /* right edge, if visible */ + if (x_in_range (simplerect->bbox_lrx)) { + cairo_move_to (cr, lrx+0.5, uly+0.5); + cairo_line_to (cr, lrx+0.5, lry+0.5); + cairo_stroke (cr); } } if (simplerect->outline_what & 0x4) { - PAINT_HORIZ(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin, end, sy+i); + /* top edge */ + if (y_in_range (simplerect->bbox_uly)) { + cairo_move_to (cr, ulx+0.5, uly+0.5); + cairo_line_to (cr, lrx+0.5, uly+0.5); + cairo_stroke (cr); + } } - + if (simplerect->outline_what & 0x8) { - PAINT_HORIZ(buf, simplerect->outline_r, simplerect->outline_g, simplerect->outline_b, begin, end + 1, ey-i); + /* bottom edge */ + if (y_in_range (simplerect->bbox_lry)) { + cairo_move_to (cr, ulx+0.5, lry+0.5); + cairo_line_to (cr, lrx+0.5, lry+0.5); + cairo_stroke (cr); + } } } -} -#endif /* SIMPLERECT_FAST_RENDERER */ -static void -gnome_canvas_simplerect_draw (GnomeCanvasItem *item, - GdkDrawable *drawable, - int x, int y, - int width, int height) -{ - fprintf (stderr, "please don't use the CanvasSimpleRect item in a non-aa Canvas\n"); - abort (); + cairo_destroy (cr); } static double gnome_canvas_simplerect_point (GnomeCanvasItem *item, double x, double y, int cx, int cy, GnomeCanvasItem **actual_item) { - GnomeCanvasSimpleRect *simplerect; + (void) cx; + (void) cy; + double x1, y1, x2, y2; double dx, dy; - simplerect = GNOME_CANVAS_SIMPLERECT (item); - *actual_item = item; /* Find the bounds for the rectangle plus its outline width */ @@ -738,7 +853,7 @@ gnome_canvas_simplerect_point (GnomeCanvasItem *item, double x, double y, int cx gnome_canvas_simplerect_bounds (item, &x1, &y1, &x2, &y2); /* Is point inside rectangle */ - + if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) { return 0.0; }