summaryrefslogtreecommitdiff
path: root/libs/canvas
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-09-28 13:37:19 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2016-09-28 13:37:19 -0500
commitc8ae41d598ce9ee4bdd24edabb00e07c9b8610ee (patch)
tree8fe6cce69a34ccca5f4d005940cfcb940d6fb846 /libs/canvas
parent67e415e14ca8cbd07da02d5ac5f82fa8e24d0fea (diff)
fix errors reported by pixman for meter redraws (and add more comments to help the coordinate challenged
Diffstat (limited to 'libs/canvas')
-rw-r--r--libs/canvas/meter.cc68
1 files changed, 54 insertions, 14 deletions
diff --git a/libs/canvas/meter.cc b/libs/canvas/meter.cc
index dc22a930e8..a87bfe7d04 100644
--- a/libs/canvas/meter.cc
+++ b/libs/canvas/meter.cc
@@ -140,9 +140,6 @@ Meter::init (int clr0, int clr1, int clr2, int clr3,
_stp[2] = stp2;
_stp[3] = stp3;
- pixrect.x = 1;
- pixrect.y = 1;
-
if (!len) {
len = 250;
}
@@ -159,8 +156,16 @@ Meter::init (int clr0, int clr1, int clr2, int clr3,
bgpattern = horizontal_background (pixwidth + 2, pixheight + 2, _bgc, false);
}
- pixrect.width = pixwidth;
pixrect.height = pixheight;
+ pixrect.x = 1;
+
+ if (orientation == Vertical) {
+ pixrect.width = pixwidth;
+ pixrect.y = pixheight; /* bottom of meter, so essentially "show zero" */
+ } else {
+ pixrect.width = 0; /* right of meter, so essentially "show zero" */
+ pixrect.y = 1;
+ }
}
void
@@ -519,10 +524,17 @@ Meter::vertical_expose (ArdourCanvas::Rect const & area, Cairo::RefPtr<Cairo::Co
top_of_meter = (gint) floor (pixheight * current_level);
- /* reset the height & origin of the rect that needs to show the pixbuf
+ /* reset the height & origin of the rect that needs to show the meter pattern
*/
-
pixrect.height = top_of_meter;
+
+ /* X/cairo coordinates; y grows down so y origin of pixrect (pattern
+ fill area) is the TOP of the pattern area, which we compute like this:
+
+ - start at 1
+ - go to bottom of meter (pixheight)
+ - back up by current meter height (top_of_meter)
+ */
pixrect.y = 1 + pixheight - top_of_meter;
background.x = 1;
@@ -728,19 +740,47 @@ Meter::queue_vertical_redraw (float old_level)
{
Cairo::RectangleInt rect;
- gint new_top = (gint) floor (pixheight * current_level);
+ gint new_height = (gint) floor (pixheight * current_level);
+
+ /* this is the nominal area that needs to be filled by the meter
+ * pattern
+ */
rect.x = 1;
rect.width = pixwidth;
- rect.height = new_top;
- rect.y = 1 + pixheight - new_top;
+
+ /* compute new top of meter (rect.y) by starting at one (border
+ * offset), go down the full height of the meter (X/Cairo coordinates
+ * grow down) to get to the bottom coordinate, then back up by the
+ * height of the patterned area.
+ */
+ rect.y = 1 + pixheight - new_height;
+ /* remember: height extends DOWN thanks to X/Cairo */
+ rect.height = new_height;
+
+ /* now lets optimize redrawing by figuring out which part needs to be
+ actually redrawn (i.e. re-use the last drawn state).
+ */
if (current_level > old_level) {
- /* colored/pixbuf got larger, just draw the new section */
- /* rect.y stays where it is because of X coordinates */
- /* height of invalidated area is between new.y (smaller) and old.y
- (larger).
- X coordinates just make my brain hurt.
+ /* filled area got taller, just draw the new section */
+
+ /* rect.y (new y origin) is smaller or equal to pixrect.y (old
+ * y origin) because the top of the meter is higher (X/Cairo:
+ * coordinates grow down).
+ *
+ * Leave rect.y alone, and recompute the height to be just the
+ * difference between the new bottom and the top of the previous
+ * pattern area.
+ *
+ * The old pattern area extended DOWN from pixrect.y to
+ * pixrect.y + pixrect.height.
+ *
+ * The new pattern area extends DOWN from rect.y to
+ * rect.y + rect.height
+ *
+ * The area needing to be drawn is the difference between the
+ * old top (pixrect.y) and the new top (rect.y)
*/
rect.height = pixrect.y - rect.y;
} else {