diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-07-29 23:06:48 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-07-31 08:12:54 +0100 |
commit | 5e223c1c73a7c3af550987a30246e7f1761808f5 (patch) | |
tree | 312be95dc0242b6dedf7412657d0bce366282fa8 /src/cairo-image-surface.c | |
parent | 7ca1d87645930a2f5e4be36819859928f4e6e601 (diff) | |
download | cairo-5e223c1c73a7c3af550987a30246e7f1761808f5.tar.gz |
image: Reduce compositing bounded boxes with a clip-mask to a polygon
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-image-surface.c')
-rw-r--r-- | src/cairo-image-surface.c | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c index dc0320aba..fd2ec824e 100644 --- a/src/cairo-image-surface.c +++ b/src/cairo-image-surface.c @@ -3163,6 +3163,15 @@ _composite_boxes (cairo_image_surface_t *dst, } static cairo_status_t +_clip_and_composite_polygon (cairo_image_surface_t *dst, + cairo_operator_t op, + const cairo_pattern_t *src, + cairo_polygon_t *polygon, + cairo_fill_rule_t fill_rule, + cairo_antialias_t antialias, + cairo_composite_rectangles_t *extents); + +static cairo_status_t _clip_and_composite_boxes (cairo_image_surface_t *dst, cairo_operator_t op, const cairo_pattern_t *src, @@ -3176,6 +3185,39 @@ _clip_and_composite_boxes (cairo_image_surface_t *dst, if (boxes->num_boxes == 0 && extents->is_bounded) return CAIRO_STATUS_SUCCESS; + /* Can we reduce drawing through a clip-mask to simply drawing the clip? */ + if (extents->clip->path != NULL && extents->is_bounded) { + cairo_polygon_t polygon; + cairo_fill_rule_t fill_rule; + cairo_antialias_t antialias; + cairo_clip_t *clip; + + clip = _cairo_clip_copy (extents->clip); + clip = _cairo_clip_intersect_boxes (clip, boxes); + status = _cairo_clip_get_polygon (clip, &polygon, + &fill_rule, &antialias); + _cairo_clip_path_destroy (clip->path); + clip->path = NULL; + if (likely (status == CAIRO_INT_STATUS_SUCCESS)) { + cairo_clip_t *saved_clip = extents->clip; + extents->clip = clip; + status = _clip_and_composite_polygon (dst, op, src, + &polygon, + fill_rule, + antialias, + extents); + if (extents->clip != clip) + clip = NULL; + extents->clip = saved_clip; + _cairo_polygon_fini (&polygon); + } + if (clip) + _cairo_clip_destroy (clip); + + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; + } + /* Use a fast path if the boxes are pixel aligned */ status = _composite_boxes (dst, op, src, boxes, extents); if (status != CAIRO_INT_STATUS_UNSUPPORTED) |