summaryrefslogtreecommitdiff
path: root/src/cairo-xcb-surface-render.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-08-23 14:16:55 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-08-23 14:20:43 +0100
commit13a09526d2120c244471e03b6ae979016ef88e83 (patch)
tree3707d27adb048cbc518e68d023bc8fde413c11ff /src/cairo-xcb-surface-render.c
parent545444ec1f79eab268647e9859efc9c8d1a10391 (diff)
downloadcairo-13a09526d2120c244471e03b6ae979016ef88e83.tar.gz
traps,xcb: Prefilter zero-area boxes when converting traps
The rectangular tesselation routines rely on the presuming that all the boxes it has to handle are already filtered to remove empty boxes. << /width 800 /height 600 >> surface context 0.0848671 0 0 0.0848671 39.907812 5.608896 matrix transform 8 0 m 12.417969 0 16 3.582031 16 8 c 16 12.417969 12.417969 16 8 16 c 3.582031 16 0 12.417969 0 8 c 0 3.582031 3.582031 0 8 0 c h clip 16 0 m 8 8 l 16 16 l h clip 0 0 16 16 rectangle fill Triggers the error given a traps tesselator like cairo-xlib. Reported-by: Henrique Lengler <henriqueleng@openmailbox.org> Analyzed-by: Massimo <sixtysix@inwind.it> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=81699 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-xcb-surface-render.c')
-rw-r--r--src/cairo-xcb-surface-render.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 163bc4111..3361f9cbc 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -2902,7 +2902,7 @@ _boxes_for_traps (cairo_boxes_t *boxes,
cairo_traps_t *traps,
cairo_antialias_t antialias)
{
- int i;
+ int i, j;
_cairo_boxes_init (boxes);
@@ -2912,17 +2912,21 @@ _boxes_for_traps (cairo_boxes_t *boxes,
boxes->chunks.size = traps->num_traps;
if (antialias != CAIRO_ANTIALIAS_NONE) {
- for (i = 0; i < traps->num_traps; i++) {
+ for (i = j = 0; i < traps->num_traps; i++) {
/* Note the traps and boxes alias so we need to take the local copies first. */
cairo_fixed_t x1 = traps->traps[i].left.p1.x;
cairo_fixed_t x2 = traps->traps[i].right.p1.x;
cairo_fixed_t y1 = traps->traps[i].top;
cairo_fixed_t y2 = traps->traps[i].bottom;
- boxes->chunks.base[i].p1.x = x1;
- boxes->chunks.base[i].p1.y = y1;
- boxes->chunks.base[i].p2.x = x2;
- boxes->chunks.base[i].p2.y = y2;
+ if (x1 == x2 || y1 == y2)
+ continue;
+
+ boxes->chunks.base[j].p1.x = x1;
+ boxes->chunks.base[j].p1.y = y1;
+ boxes->chunks.base[j].p2.x = x2;
+ boxes->chunks.base[j].p2.y = y2;
+ j++;
if (boxes->is_pixel_aligned) {
boxes->is_pixel_aligned =
@@ -2933,7 +2937,7 @@ _boxes_for_traps (cairo_boxes_t *boxes,
} else {
boxes->is_pixel_aligned = TRUE;
- for (i = 0; i < traps->num_traps; i++) {
+ for (i = j = 0; i < traps->num_traps; i++) {
/* Note the traps and boxes alias so we need to take the local copies first. */
cairo_fixed_t x1 = traps->traps[i].left.p1.x;
cairo_fixed_t x2 = traps->traps[i].right.p1.x;
@@ -2941,10 +2945,13 @@ _boxes_for_traps (cairo_boxes_t *boxes,
cairo_fixed_t y2 = traps->traps[i].bottom;
/* round down here to match Pixman's behavior when using traps. */
- boxes->chunks.base[i].p1.x = _cairo_fixed_round_down (x1);
- boxes->chunks.base[i].p1.y = _cairo_fixed_round_down (y1);
- boxes->chunks.base[i].p2.x = _cairo_fixed_round_down (x2);
- boxes->chunks.base[i].p2.y = _cairo_fixed_round_down (y2);
+ boxes->chunks.base[j].p1.x = _cairo_fixed_round_down (x1);
+ boxes->chunks.base[j].p1.y = _cairo_fixed_round_down (y1);
+ boxes->chunks.base[j].p2.x = _cairo_fixed_round_down (x2);
+ boxes->chunks.base[j].p2.y = _cairo_fixed_round_down (y2);
+
+ j += (boxes->chunks.base[j].p1.x != boxes->chunks.base[j].p2.x &&
+ boxes->chunks.base[j].p1.y != boxes->chunks.base[j].p2.y);
}
}
}