image: Special case wholly unbounded fixups.

In the event of an empty bounded rectangle, the computation of the
unbounded - bounded rectangles leads to negative areas, integer overflow
and death.

[And similarly for the derived surfaces.]
This commit is contained in:
Chris Wilson 2010-03-22 10:48:48 +00:00
parent 844d8ea57d
commit e961cdf568
4 changed files with 145 additions and 98 deletions

View file

@ -1486,6 +1486,30 @@ _cairo_image_surface_fixup_unbounded (cairo_image_surface_t *dst,
}
}
/* wholly unbounded? */
if (rects->bounded.width == 0 || rects->bounded.height == 0) {
int x = rects->unbounded.x;
int y = rects->unbounded.y;
int width = rects->unbounded.width;
int height = rects->unbounded.height;
if (mask != NULL) {
pixman_image_composite (PIXMAN_OP_OUT_REVERSE,
mask, NULL, dst->pixman_image,
x + mask_x, y + mask_y,
0, 0,
x, y,
width, height);
} else {
pixman_fill ((uint32_t *) dst->data, dst->stride / sizeof (uint32_t),
PIXMAN_FORMAT_BPP (dst->pixman_format),
x, y, width, height,
0);
}
return;
}
/* top */
if (rects->bounded.y != rects->unbounded.y) {
int x = rects->unbounded.x;

View file

@ -2101,37 +2101,45 @@ _cairo_xcb_surface_fixup_unbounded (cairo_xcb_surface_t *dst,
}
n = 0;
/* top */
if (rects->bounded.y != rects->unbounded.y) {
if (rects->bounded.width == 0 || rects->bounded.height == 0) {
xrects[n].x = rects->unbounded.x;
xrects[n].width = rects->unbounded.width;
xrects[n].y = rects->unbounded.y;
xrects[n].height = rects->bounded.y - rects->unbounded.y;
n++;
}
/* left */
if (rects->bounded.x != rects->unbounded.x) {
xrects[n].x = rects->unbounded.x;
xrects[n].width = rects->bounded.x - rects->unbounded.x;
xrects[n].y = rects->bounded.y;
xrects[n].height = rects->bounded.height;
n++;
}
/* right */
if (rects->bounded.x + rects->bounded.width != rects->unbounded.x + rects->unbounded.width) {
xrects[n].x = rects->bounded.x + rects->bounded.width;
xrects[n].width = rects->unbounded.x + rects->unbounded.width - xrects[n].x;
xrects[n].y = rects->bounded.y;
xrects[n].height = rects->bounded.height;
n++;
}
/* bottom */
if (rects->bounded.y + rects->bounded.height != rects->unbounded.y + rects->unbounded.height) {
xrects[n].x = rects->unbounded.x;
xrects[n].width = rects->unbounded.width;
xrects[n].y = rects->bounded.y + rects->bounded.height;
xrects[n].height = rects->unbounded.y + rects->unbounded.height - xrects[n].y;
xrects[n].height = rects->unbounded.height;
n++;
} else {
/* top */
if (rects->bounded.y != rects->unbounded.y) {
xrects[n].x = rects->unbounded.x;
xrects[n].width = rects->unbounded.width;
xrects[n].y = rects->unbounded.y;
xrects[n].height = rects->bounded.y - rects->unbounded.y;
n++;
}
/* left */
if (rects->bounded.x != rects->unbounded.x) {
xrects[n].x = rects->unbounded.x;
xrects[n].width = rects->bounded.x - rects->unbounded.x;
xrects[n].y = rects->bounded.y;
xrects[n].height = rects->bounded.height;
n++;
}
/* right */
if (rects->bounded.x + rects->bounded.width != rects->unbounded.x + rects->unbounded.width) {
xrects[n].x = rects->bounded.x + rects->bounded.width;
xrects[n].width = rects->unbounded.x + rects->unbounded.width - xrects[n].x;
xrects[n].y = rects->bounded.y;
xrects[n].height = rects->bounded.height;
n++;
}
/* bottom */
if (rects->bounded.y + rects->bounded.height != rects->unbounded.y + rects->unbounded.height) {
xrects[n].x = rects->unbounded.x;
xrects[n].width = rects->unbounded.width;
xrects[n].y = rects->bounded.y + rects->bounded.height;
xrects[n].height = rects->unbounded.y + rects->unbounded.height - xrects[n].y;
n++;
}
}
if (dst->flags & CAIRO_XCB_RENDER_HAS_FILL_RECTANGLES) {

View file

@ -705,40 +705,48 @@ i915_fixup_unbounded (i915_surface_t *dst,
if (unlikely (status))
goto BAIL;
/* top */
if (extents->bounded.y != extents->unbounded.y) {
if (extents->bounded.width == 0 || extents->bounded.height == 0) {
shader.add_rectangle (&shader,
extents->unbounded.x,
extents->unbounded.y,
extents->unbounded.width,
extents->bounded.y - extents->unbounded.y);
}
extents->unbounded.height);
} else {
/* top */
if (extents->bounded.y != extents->unbounded.y) {
shader.add_rectangle (&shader,
extents->unbounded.x,
extents->unbounded.y,
extents->unbounded.width,
extents->bounded.y - extents->unbounded.y);
}
/* left */
if (extents->bounded.x != extents->unbounded.x) {
shader.add_rectangle (&shader,
extents->unbounded.x,
extents->bounded.y,
extents->bounded.x - extents->unbounded.x,
extents->bounded.height);
}
/* left */
if (extents->bounded.x != extents->unbounded.x) {
shader.add_rectangle (&shader,
extents->unbounded.x,
extents->bounded.y,
extents->bounded.x - extents->unbounded.x,
extents->bounded.height);
}
/* right */
if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) {
shader.add_rectangle (&shader,
extents->bounded.x + extents->bounded.width,
extents->bounded.y,
extents->unbounded.x + extents->unbounded.width - (extents->bounded.x + extents->bounded.width),
extents->bounded.height);
}
/* right */
if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) {
shader.add_rectangle (&shader,
extents->bounded.x + extents->bounded.width,
extents->bounded.y,
extents->unbounded.x + extents->unbounded.width - (extents->bounded.x + extents->bounded.width),
extents->bounded.height);
}
/* bottom */
if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) {
shader.add_rectangle (&shader,
extents->unbounded.x,
extents->bounded.y + extents->bounded.height,
extents->unbounded.width,
extents->unbounded.y + extents->unbounded.height - (extents->bounded.y + extents->bounded.height));
/* bottom */
if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) {
shader.add_rectangle (&shader,
extents->unbounded.x,
extents->bounded.y + extents->bounded.height,
extents->unbounded.width,
extents->unbounded.y + extents->unbounded.height - (extents->bounded.y + extents->bounded.height));
}
}
i915_shader_fini (&shader);

View file

@ -766,60 +766,67 @@ i965_fixup_unbounded (i965_surface_t *dst,
goto BAIL;
}
/* top */
if (extents->bounded.y != extents->unbounded.y) {
cairo_rectangle_int_t rect;
rect.x = extents->unbounded.x;
rect.y = extents->unbounded.y;
rect.width = extents->unbounded.width;
rect.height = extents->bounded.y - rect.y;
if (extents->bounded.width == 0 || extents->bounded.height == 0) {
i965_shader_add_rectangle (&shader,
rect.x, rect.y,
rect.width, rect.height);
}
extents->unbounded.x,
extents->unbounded.y,
extents->unbounded.width,
extents->unbounded.height);
} else { /* top */
if (extents->bounded.y != extents->unbounded.y) {
cairo_rectangle_int_t rect;
/* left */
if (extents->bounded.x != extents->unbounded.x) {
cairo_rectangle_int_t rect;
rect.x = extents->unbounded.x;
rect.y = extents->unbounded.y;
rect.width = extents->unbounded.width;
rect.height = extents->bounded.y - rect.y;
rect.x = extents->unbounded.x;
rect.y = extents->bounded.y;
rect.width = extents->bounded.x - extents->unbounded.x;
rect.height = extents->bounded.height;
i965_shader_add_rectangle (&shader,
rect.x, rect.y,
rect.width, rect.height);
}
i965_shader_add_rectangle (&shader,
rect.x, rect.y,
rect.width, rect.height);
}
/* left */
if (extents->bounded.x != extents->unbounded.x) {
cairo_rectangle_int_t rect;
/* right */
if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) {
cairo_rectangle_int_t rect;
rect.x = extents->unbounded.x;
rect.y = extents->bounded.y;
rect.width = extents->bounded.x - extents->unbounded.x;
rect.height = extents->bounded.height;
rect.x = extents->bounded.x + extents->bounded.width;
rect.y = extents->bounded.y;
rect.width = extents->unbounded.x + extents->unbounded.width - rect.x;
rect.height = extents->bounded.height;
i965_shader_add_rectangle (&shader,
rect.x, rect.y,
rect.width, rect.height);
}
i965_shader_add_rectangle (&shader,
rect.x, rect.y,
rect.width, rect.height);
}
/* right */
if (extents->bounded.x + extents->bounded.width != extents->unbounded.x + extents->unbounded.width) {
cairo_rectangle_int_t rect;
/* bottom */
if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) {
cairo_rectangle_int_t rect;
rect.x = extents->bounded.x + extents->bounded.width;
rect.y = extents->bounded.y;
rect.width = extents->unbounded.x + extents->unbounded.width - rect.x;
rect.height = extents->bounded.height;
rect.x = extents->unbounded.x;
rect.y = extents->bounded.y + extents->bounded.height;
rect.width = extents->unbounded.width;
rect.height = extents->unbounded.y + extents->unbounded.height - rect.y;
i965_shader_add_rectangle (&shader,
rect.x, rect.y,
rect.width, rect.height);
}
i965_shader_add_rectangle (&shader,
rect.x, rect.y,
rect.width, rect.height);
/* bottom */
if (extents->bounded.y + extents->bounded.height != extents->unbounded.y + extents->unbounded.height) {
cairo_rectangle_int_t rect;
rect.x = extents->unbounded.x;
rect.y = extents->bounded.y + extents->bounded.height;
rect.width = extents->unbounded.width;
rect.height = extents->unbounded.y + extents->unbounded.height - rect.y;
i965_shader_add_rectangle (&shader,
rect.x, rect.y,
rect.width, rect.height);
}
}
i965_shader_fini (&shader);