[cairo-commit] 3 commits - src/cairo-clip.c src/cairo-surface-fallback.c src/cairo-xcb-surface-render.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Jul 29 04:36:42 PDT 2011
src/cairo-clip.c | 10 +++
src/cairo-surface-fallback.c | 129 ++++++++++++++++++++++++++++++++++-------
src/cairo-xcb-surface-render.c | 3
3 files changed, 122 insertions(+), 20 deletions(-)
New commits:
commit fb9ed9bb0d3a4d4ac71f5d472f63a04ffbc4c110
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 29 12:35:36 2011 +0100
clip: Fix clip-equal to handle one or the other being NULL/all-clipped
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index b01093e..4058879 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -346,6 +346,16 @@ _cairo_clip_equal (const cairo_clip_t *clip_a,
if (clip_a == clip_b)
return TRUE;
+ /* or just one of them? */
+ if (clip_a == NULL || clip_b == NULL ||
+ _cairo_clip_is_all_clipped (clip_a) ||
+ _cairo_clip_is_all_clipped (clip_b))
+ {
+ return FALSE;
+ }
+
+ /* We have a pair of normal clips, check their contents */
+
if (clip_a->num_boxes != clip_b->num_boxes)
return FALSE;
commit 7c6e1b8db89420fa69ebd8d2ba12dde1aeb47ea8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 29 12:33:07 2011 +0100
xcb: Short-circuit multiplying the alpha mask by 1.0
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 586b9fe..9830617 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -1666,6 +1666,9 @@ static void blt_in(void *closure,
xcb_render_color_t color;
xcb_rectangle_t rect;
+ if (coverage == 0xffff)
+ return;
+
color.red = color.green = color.blue = 0;
color.alpha = coverage;
commit 4032c86127a5f1658c2bddbf1c642fb62e21a208
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jul 29 12:31:14 2011 +0100
fallback: Prevent recursion when combining with the clip
We need to special case the handling of unaligned clip regions in order
to prevent the treatment of those as a general path requiring a
clip+mask...
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index bd03274..95d3c17 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -119,6 +119,84 @@ typedef cairo_status_t
const cairo_rectangle_int_t *extents,
cairo_region_t *clip_region);
+static void do_unaligned_row(void (*blt)(void *closure,
+ int16_t x, int16_t y,
+ int16_t w, int16_t h,
+ uint16_t coverage),
+ void *closure,
+ const cairo_box_t *b,
+ int tx, int y, int h,
+ uint16_t coverage)
+{
+ int x1 = _cairo_fixed_integer_part (b->p1.x) - tx;
+ int x2 = _cairo_fixed_integer_part (b->p2.x) - tx;
+ if (x2 > x1) {
+ if (! _cairo_fixed_is_integer (b->p1.x)) {
+ blt(closure, x1, y, 1, h,
+ coverage * (256 - _cairo_fixed_fractional_part (b->p1.x)));
+ x1++;
+ }
+
+ if (x2 > x1)
+ blt(closure, x1, y, x2-x1, h, (coverage << 8) - (coverage >> 8));
+
+ if (! _cairo_fixed_is_integer (b->p2.x))
+ blt(closure, x2, y, 1, h,
+ coverage * _cairo_fixed_fractional_part (b->p2.x));
+ } else
+ blt(closure, x1, y, 1, h,
+ coverage * (b->p2.x - b->p1.x));
+}
+
+static void do_unaligned_box(void (*blt)(void *closure,
+ int16_t x, int16_t y,
+ int16_t w, int16_t h,
+ uint16_t coverage),
+ void *closure,
+ const cairo_box_t *b, int tx, int ty)
+{
+ int y1 = _cairo_fixed_integer_part (b->p1.y) - ty;
+ int y2 = _cairo_fixed_integer_part (b->p2.y) - ty;
+ if (y2 > y1) {
+ if (! _cairo_fixed_is_integer (b->p1.y)) {
+ do_unaligned_row(blt, closure, b, tx, y1, 1,
+ 256 - _cairo_fixed_fractional_part (b->p1.y));
+ y1++;
+ }
+
+ if (y2 > y1)
+ do_unaligned_row(blt, closure, b, tx, y1, y2-y1, 256);
+
+ if (! _cairo_fixed_is_integer (b->p2.y))
+ do_unaligned_row(blt, closure, b, tx, y2, 1,
+ _cairo_fixed_fractional_part (b->p2.y));
+ } else
+ do_unaligned_row(blt, closure, b, tx, y1, 1,
+ b->p2.y - b->p1.y);
+}
+
+static void blt_in(void *closure,
+ int16_t x, int16_t y,
+ int16_t w, int16_t h,
+ uint16_t coverage)
+{
+ cairo_color_t color;
+ cairo_rectangle_int_t rect;
+
+ if (coverage == 0xffff)
+ return;
+
+ _cairo_color_init_rgba (&color, 0, 0, 0, coverage / (double) 0xffff);
+
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+
+ _cairo_surface_fill_rectangles (closure, CAIRO_OPERATOR_IN,
+ &color, &rect, 1);
+}
+
static cairo_status_t
_create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
cairo_clip_t *clip,
@@ -129,9 +207,8 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
{
cairo_surface_t *mask;
cairo_status_t status;
- cairo_region_t *clip_region = _cairo_clip_get_region (clip);
- cairo_bool_t clip_surface = ! _cairo_clip_is_region (clip);
- cairo_region_t *fallback_region = NULL;
+ cairo_region_t *clip_region;
+ int i;
/* We need to use solid here, because to use CAIRO_OPERATOR_SOURCE with
* a mask (as called via _cairo_surface_mask) triggers assertion failures.
@@ -145,34 +222,46 @@ _create_composite_mask_pattern (cairo_surface_pattern_t *mask_pattern,
if (unlikely (mask->status))
return mask->status;
- if (clip_region && (extents->x || extents->y)) {
- fallback_region = cairo_region_copy (clip_region);
- status = fallback_region->status;
- if (unlikely (status))
- goto CLEANUP_SURFACE;
-
- cairo_region_translate (fallback_region,
- -extents->x,
- -extents->y);
- clip_region = fallback_region;
- }
+ clip_region = _cairo_clip_get_region (clip);
+ if (clip_region && (extents->x | extents->y))
+ cairo_region_translate (clip_region, -extents->x, -extents->y);
status = draw_func (draw_closure, CAIRO_OPERATOR_ADD,
&_cairo_pattern_white.base, mask,
extents->x, extents->y,
extents,
clip_region);
+
+ if (clip_region && (extents->x | extents->y))
+ cairo_region_translate (clip_region, extents->x, extents->y);
+
if (unlikely (status))
- goto CLEANUP_SURFACE;
+ goto CLEANUP;
+
+ if (clip) {
+ for (i = 0; i < clip->num_boxes; i++) {
+ cairo_box_t *b = &clip->boxes[i];
+
+ if (! _cairo_fixed_is_integer (b->p1.x) ||
+ ! _cairo_fixed_is_integer (b->p1.y) ||
+ ! _cairo_fixed_is_integer (b->p2.x) ||
+ ! _cairo_fixed_is_integer (b->p2.y))
+ {
+ do_unaligned_box(blt_in, mask, b, extents->x, extents->y);
+ }
+ }
- if (clip_surface)
- status = _cairo_clip_combine_with_surface (clip, mask, extents->x, extents->y);
+ if (clip->path != NULL) {
+ status = _cairo_clip_combine_with_surface (clip, mask,
+ extents->x, extents->y);
+ if (unlikely (status))
+ goto CLEANUP;
+ }
+ }
_cairo_pattern_init_for_surface (mask_pattern, mask);
- CLEANUP_SURFACE:
- if (fallback_region)
- cairo_region_destroy (fallback_region);
+ CLEANUP:
cairo_surface_destroy (mask);
return status;
More information about the cairo-commit
mailing list