remove old a-Hi/Low pass
[ardour.git] / gtk2_ardour / canvas-simplerect.c
index d50943f0c3dfc55ba9b3868898eabb0f8d483d3b..fe6e1855be03848cd092b7699c31b3032a8a3f52 100644 (file)
@@ -1,5 +1,6 @@
 #include <stdio.h>
 #include <math.h>
+#include <cairo.h>
 #include <libgnomecanvas/libgnomecanvas.h>
 
 #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;
        }