mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-09 09:38:11 +02:00
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:
parent
844d8ea57d
commit
e961cdf568
4 changed files with 145 additions and 98 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue