diff options
author | M Joonas Pihlaja <jpihlaja@cc.helsinki.fi> | 2008-08-01 23:28:15 +0300 |
---|---|---|
committer | M Joonas Pihlaja <jpihlaja@cc.helsinki.fi> | 2008-12-07 03:51:07 +0200 |
commit | 5e06085b483dcaaa7b1b29b13cd2813c7e51e02a (patch) | |
tree | 7fb49587e52ba34e7209178cc8d329152b1e9665 | |
parent | 18634c37026a2d6147443cb6d991576f62b07e6d (diff) |
[cairo-spans] Render clip mask surfaces with spans if we can.
Generating surface masks for clipping can also benefit from span
rendering sometimes.
49 files changed, 140 insertions, 0 deletions
diff --git a/src/cairo-clip.c b/src/cairo-clip.c index 4303b605..cd423a44 100644 --- a/src/cairo-clip.c +++ b/src/cairo-clip.c @@ -534,6 +534,133 @@ _cairo_clip_intersect_mask (cairo_clip_t *clip, return status; } +static cairo_status_t +_cairo_clip_intersect_mask_using_spans (cairo_clip_t *clip, + cairo_path_fixed_t *path, + cairo_fill_rule_t fill_rule, + double tolerance, + cairo_antialias_t antialias, + cairo_surface_t *target) +{ + cairo_span_renderer_t *renderer = NULL; + cairo_pattern_union_t pattern; + cairo_rectangle_int_t surface_rect; + cairo_surface_t *surface = NULL; + cairo_status_t status; + cairo_operator_t op; + cairo_composite_rectangles_t rects; + + if (clip->all_clipped) + return CAIRO_STATUS_SUCCESS; + + _cairo_pattern_init_solid (&pattern.solid, CAIRO_COLOR_WHITE, + CAIRO_CONTENT_COLOR); + + /* If we have a clip surface we're going to use IN to combine our + * new clip with the old clip. The ADD is done to a transparent + * surface, as that's a fast way of doing it currently. We should + * really be using SOURCE instead, but _cairo_surface_composite() + * checks that it's not called with SOURCE or DEST. */ + op = clip->surface ? CAIRO_OPERATOR_IN : CAIRO_OPERATOR_ADD; + + /* Test if the target can composite spans. We're going to assume + * this is a good indicator of whether a similar surface is going + * to be able to composite spans too. */ + if ( !_cairo_surface_check_span_renderer (op, + &pattern.base, + target, + antialias, + NULL)) + { + status = CAIRO_INT_STATUS_UNSUPPORTED; + goto BAIL; + } + + /* We'll create a new surface the size of the intersection of the + * old mask surface and the extents of the new clip path. */ + { + cairo_rectangle_int_t target_rect; + + _cairo_path_fixed_approximate_extents (path, &surface_rect); + + if (clip->surface != NULL && + !_cairo_rectangle_intersect (&surface_rect, &clip->surface_rect)) + goto SUCCESS; + + status = _cairo_surface_get_extents (target, &target_rect); + if (status != CAIRO_STATUS_SUCCESS && + !_cairo_rectangle_intersect (&surface_rect, &target_rect)) + goto SUCCESS; + } + + /* Make the new mask surface and optionally initialise it from the + * previous clip if we have one. */ + surface = _cairo_surface_create_similar_solid (target, + CAIRO_CONTENT_ALPHA, + surface_rect.width, + surface_rect.height, + CAIRO_COLOR_TRANSPARENT); + if (surface->status) { + _cairo_pattern_fini (&pattern.base); + return surface->status; + } + + if (clip->surface) { + cairo_surface_pattern_t old_clip; + _cairo_pattern_init_for_surface (&old_clip, clip->surface); + status = _cairo_surface_composite (CAIRO_OPERATOR_ADD, + &old_clip.base, + NULL, + surface, + surface_rect.x - clip->surface_rect.x, + surface_rect.y - clip->surface_rect.y, + 0, 0, + 0, 0, + surface_rect.width, + surface_rect.height); + _cairo_pattern_fini (&old_clip.base); + if (status) + goto BAIL; + } + + _cairo_composite_rectangles_init (&rects, + surface_rect.x, + surface_rect.y, + surface_rect.width, + surface_rect.height); + rects.dst.x = 0; + rects.dst.y = 0; + + /* Render the new clipping path into the new mask surface. We've + * chosen op to either combine the new clip path with the existing + * clip mask (if there is one) or just render it. */ + status =_cairo_path_fixed_fill_using_spans (op, &pattern.base, + path, surface, + fill_rule, tolerance, + antialias, &rects); + if (status) + goto BAIL; + + SUCCESS: + if (clip->surface != NULL) + cairo_surface_destroy (clip->surface); + clip->surface = surface; + clip->surface_rect = surface_rect; + clip->serial = _cairo_surface_allocate_clip_serial (target); + surface = NULL; + + if (surface_rect.width == 0 || surface_rect.height == 0) + _cairo_clip_set_all_clipped (clip, target); + + BAIL: + if (renderer) + renderer->destroy(renderer); + if (surface) + cairo_surface_destroy (surface); + _cairo_pattern_fini (&pattern.base); + return status; +} + cairo_status_t _cairo_clip_clip (cairo_clip_t *clip, cairo_path_fixed_t *path, @@ -545,6 +672,7 @@ _cairo_clip_clip (cairo_clip_t *clip, cairo_status_t status; cairo_rectangle_int_t rectangle; cairo_traps_t traps; + cairo_box_t ignored_box; if (clip->all_clipped) return CAIRO_STATUS_SUCCESS; @@ -564,6 +692,18 @@ _cairo_clip_clip (cairo_clip_t *clip, if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; + /* TODO: allow ANTIALIAS_NONE when we have a mono scan converter + * again. */ + if (antialias != CAIRO_ANTIALIAS_NONE && + !_cairo_path_fixed_is_box (path, &ignored_box) && + !_cairo_path_fixed_is_region (path)) + { + status = _cairo_clip_intersect_mask_using_spans ( + clip, path, fill_rule, tolerance, antialias, target); + if (status != CAIRO_INT_STATUS_UNSUPPORTED) + return status; + } + _cairo_traps_init (&traps); /* Limit the traps to the target surface diff --git a/test/clip-fill-rule.pdf.argb32.ref.png b/test/clip-fill-rule.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..0d9938e7 --- /dev/null +++ b/test/clip-fill-rule.pdf.argb32.ref.png diff --git a/test/clip-fill-rule.rgb24.ref.png b/test/clip-fill-rule.rgb24.ref.png Binary files differindex a969e367..050bd666 100644 --- a/test/clip-fill-rule.rgb24.ref.png +++ b/test/clip-fill-rule.rgb24.ref.png diff --git a/test/clip-fill-rule.test-paginated.rgb24.ref.png b/test/clip-fill-rule.test-paginated.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d21472dc --- /dev/null +++ b/test/clip-fill-rule.test-paginated.rgb24.ref.png diff --git a/test/clip-fill-rule.xlib.rgb24.ref.png b/test/clip-fill-rule.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..a969e367 --- /dev/null +++ b/test/clip-fill-rule.xlib.rgb24.ref.png diff --git a/test/clip-nesting.pdf.argb32.ref.png b/test/clip-nesting.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..78ae6e08 --- /dev/null +++ b/test/clip-nesting.pdf.argb32.ref.png diff --git a/test/clip-nesting.rgb24.ref.png b/test/clip-nesting.rgb24.ref.png Binary files differindex e2488f34..a014763d 100644 --- a/test/clip-nesting.rgb24.ref.png +++ b/test/clip-nesting.rgb24.ref.png diff --git a/test/clip-nesting.test-fallback.rgb24.ref.png b/test/clip-nesting.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d087ab6c --- /dev/null +++ b/test/clip-nesting.test-fallback.rgb24.ref.png diff --git a/test/clip-nesting.test-paginated.rgb24.ref.png b/test/clip-nesting.test-paginated.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..d087ab6c --- /dev/null +++ b/test/clip-nesting.test-paginated.rgb24.ref.png diff --git a/test/clip-nesting.xlib.rgb24.ref.png b/test/clip-nesting.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..e2488f34 --- /dev/null +++ b/test/clip-nesting.xlib.rgb24.ref.png diff --git a/test/clip-operator.pdf.argb32.ref.png b/test/clip-operator.pdf.argb32.ref.png Binary files differindex 4bf79c4c..e2fdc8d1 100644 --- a/test/clip-operator.pdf.argb32.ref.png +++ b/test/clip-operator.pdf.argb32.ref.png diff --git a/test/clip-operator.ps3.argb32.ref.png b/test/clip-operator.ps3.argb32.ref.png Binary files differindex 638831ce..cd207d92 100644 --- a/test/clip-operator.ps3.argb32.ref.png +++ b/test/clip-operator.ps3.argb32.ref.png diff --git a/test/clip-operator.ref.png b/test/clip-operator.ref.png Binary files differindex 22e080a2..3a685f5e 100644 --- a/test/clip-operator.ref.png +++ b/test/clip-operator.ref.png diff --git a/test/clip-operator.test-paginated.argb32.ref.png b/test/clip-operator.test-paginated.argb32.ref.png Binary files differnew file mode 100644 index 00000000..22e080a2 --- /dev/null +++ b/test/clip-operator.test-paginated.argb32.ref.png diff --git a/test/clip-twice.pdf.argb32.ref.png b/test/clip-twice.pdf.argb32.ref.png Binary files differindex 589dfc97..2a7541fe 100644 --- a/test/clip-twice.pdf.argb32.ref.png +++ b/test/clip-twice.pdf.argb32.ref.png diff --git a/test/clip-twice.ref.png b/test/clip-twice.ref.png Binary files differindex 8dc86f30..4aafc9ac 100644 --- a/test/clip-twice.ref.png +++ b/test/clip-twice.ref.png diff --git a/test/clip-twice.rgb24.ref.png b/test/clip-twice.rgb24.ref.png Binary files differindex 3f1c013b..25c44ef7 100644 --- a/test/clip-twice.rgb24.ref.png +++ b/test/clip-twice.rgb24.ref.png diff --git a/test/clip-twice.test-fallback.argb32.ref.png b/test/clip-twice.test-fallback.argb32.ref.png Binary files differnew file mode 100644 index 00000000..ba621807 --- /dev/null +++ b/test/clip-twice.test-fallback.argb32.ref.png diff --git a/test/clip-twice.test-fallback.rgb24.ref.png b/test/clip-twice.test-fallback.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..9cbdc4d4 --- /dev/null +++ b/test/clip-twice.test-fallback.rgb24.ref.png diff --git a/test/clip-twice.test-paginated.argb32.ref.png b/test/clip-twice.test-paginated.argb32.ref.png Binary files differnew file mode 100644 index 00000000..ffd59aaf --- /dev/null +++ b/test/clip-twice.test-paginated.argb32.ref.png diff --git a/test/clip-twice.test-paginated.rgb24.ref.png b/test/clip-twice.test-paginated.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..e3d0ae49 --- /dev/null +++ b/test/clip-twice.test-paginated.rgb24.ref.png diff --git a/test/clip-twice.xlib.ref.png b/test/clip-twice.xlib.ref.png Binary files differnew file mode 100644 index 00000000..8dc86f30 --- /dev/null +++ b/test/clip-twice.xlib.ref.png diff --git a/test/clip-twice.xlib.rgb24.ref.png b/test/clip-twice.xlib.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3f1c013b --- /dev/null +++ b/test/clip-twice.xlib.rgb24.ref.png diff --git a/test/device-offset-fractional.pdf.argb32.ref.png b/test/device-offset-fractional.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..c076932c --- /dev/null +++ b/test/device-offset-fractional.pdf.argb32.ref.png diff --git a/test/device-offset-fractional.pdf.rgb24.ref.png b/test/device-offset-fractional.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..c076932c --- /dev/null +++ b/test/device-offset-fractional.pdf.rgb24.ref.png diff --git a/test/filter-nearest-offset.pdf.argb32.ref.png b/test/filter-nearest-offset.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..3475cb6e --- /dev/null +++ b/test/filter-nearest-offset.pdf.argb32.ref.png diff --git a/test/filter-nearest-offset.pdf.rgb24.ref.png b/test/filter-nearest-offset.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..3475cb6e --- /dev/null +++ b/test/filter-nearest-offset.pdf.rgb24.ref.png diff --git a/test/filter-nearest-transformed.pdf.argb32.ref.png b/test/filter-nearest-transformed.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..40169593 --- /dev/null +++ b/test/filter-nearest-transformed.pdf.argb32.ref.png diff --git a/test/filter-nearest-transformed.pdf.rgb24.ref.png b/test/filter-nearest-transformed.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..40169593 --- /dev/null +++ b/test/filter-nearest-transformed.pdf.rgb24.ref.png diff --git a/test/linear-gradient.pdf.argb32.ref.png b/test/linear-gradient.pdf.argb32.ref.png Binary files differindex bddb681c..f820c374 100644 --- a/test/linear-gradient.pdf.argb32.ref.png +++ b/test/linear-gradient.pdf.argb32.ref.png diff --git a/test/linear-gradient.pdf.rgb24.ref.png b/test/linear-gradient.pdf.rgb24.ref.png Binary files differindex bddb681c..f820c374 100644 --- a/test/linear-gradient.pdf.rgb24.ref.png +++ b/test/linear-gradient.pdf.rgb24.ref.png diff --git a/test/mask.pdf.argb32.ref.png b/test/mask.pdf.argb32.ref.png Binary files differindex d1cc8ff7..8bd8f140 100644 --- a/test/mask.pdf.argb32.ref.png +++ b/test/mask.pdf.argb32.ref.png diff --git a/test/mask.ref.png b/test/mask.ref.png Binary files differindex f5d30c53..2c2fa117 100644 --- a/test/mask.ref.png +++ b/test/mask.ref.png diff --git a/test/mask.svg11.argb32.ref.png b/test/mask.svg11.argb32.ref.png Binary files differindex e48e47bf..3ce4d53f 100644 --- a/test/mask.svg11.argb32.ref.png +++ b/test/mask.svg11.argb32.ref.png diff --git a/test/mask.svg12.argb32.ref.png b/test/mask.svg12.argb32.ref.png Binary files differindex e48e47bf..3ce4d53f 100644 --- a/test/mask.svg12.argb32.ref.png +++ b/test/mask.svg12.argb32.ref.png diff --git a/test/meta-surface-pattern.pdf.argb32.ref.png b/test/meta-surface-pattern.pdf.argb32.ref.png Binary files differindex a842b6fa..2ee9b7da 100644 --- a/test/meta-surface-pattern.pdf.argb32.ref.png +++ b/test/meta-surface-pattern.pdf.argb32.ref.png diff --git a/test/meta-surface-pattern.svg11.argb32.ref.png b/test/meta-surface-pattern.svg11.argb32.ref.png Binary files differindex 3a6836dc..99695748 100644 --- a/test/meta-surface-pattern.svg11.argb32.ref.png +++ b/test/meta-surface-pattern.svg11.argb32.ref.png diff --git a/test/meta-surface-pattern.svg12.argb32.ref.png b/test/meta-surface-pattern.svg12.argb32.ref.png Binary files differindex 3a6836dc..99695748 100644 --- a/test/meta-surface-pattern.svg12.argb32.ref.png +++ b/test/meta-surface-pattern.svg12.argb32.ref.png diff --git a/test/rotate-image-surface-paint.pdf.argb32.ref.png b/test/rotate-image-surface-paint.pdf.argb32.ref.png Binary files differindex c12ae8fd..93fab525 100644 --- a/test/rotate-image-surface-paint.pdf.argb32.ref.png +++ b/test/rotate-image-surface-paint.pdf.argb32.ref.png diff --git a/test/rotate-image-surface-paint.pdf.rgb24.ref.png b/test/rotate-image-surface-paint.pdf.rgb24.ref.png Binary files differindex 5cd7bf61..93fab525 100644 --- a/test/rotate-image-surface-paint.pdf.rgb24.ref.png +++ b/test/rotate-image-surface-paint.pdf.rgb24.ref.png diff --git a/test/surface-pattern-scale-down.pdf.argb32.ref.png b/test/surface-pattern-scale-down.pdf.argb32.ref.png Binary files differindex c29d804c..dc4b3a31 100644 --- a/test/surface-pattern-scale-down.pdf.argb32.ref.png +++ b/test/surface-pattern-scale-down.pdf.argb32.ref.png diff --git a/test/surface-pattern-scale-down.pdf.rgb24.ref.png b/test/surface-pattern-scale-down.pdf.rgb24.ref.png Binary files differindex c29d804c..dc4b3a31 100644 --- a/test/surface-pattern-scale-down.pdf.rgb24.ref.png +++ b/test/surface-pattern-scale-down.pdf.rgb24.ref.png diff --git a/test/surface-pattern-scale-up.pdf.argb32.ref.png b/test/surface-pattern-scale-up.pdf.argb32.ref.png Binary files differindex 6f3a53c5..c0a2896a 100644 --- a/test/surface-pattern-scale-up.pdf.argb32.ref.png +++ b/test/surface-pattern-scale-up.pdf.argb32.ref.png diff --git a/test/surface-pattern-scale-up.pdf.rgb24.ref.png b/test/surface-pattern-scale-up.pdf.rgb24.ref.png Binary files differindex 6f3a53c5..c0a2896a 100644 --- a/test/surface-pattern-scale-up.pdf.rgb24.ref.png +++ b/test/surface-pattern-scale-up.pdf.rgb24.ref.png diff --git a/test/surface-pattern.pdf.argb32.ref.png b/test/surface-pattern.pdf.argb32.ref.png Binary files differnew file mode 100644 index 00000000..70a44767 --- /dev/null +++ b/test/surface-pattern.pdf.argb32.ref.png diff --git a/test/surface-pattern.pdf.rgb24.ref.png b/test/surface-pattern.pdf.rgb24.ref.png Binary files differnew file mode 100644 index 00000000..70a44767 --- /dev/null +++ b/test/surface-pattern.pdf.rgb24.ref.png diff --git a/test/trap-clip.pdf.rgb24.ref.png b/test/trap-clip.pdf.rgb24.ref.png Binary files differindex 90b476b5..06163675 100644 --- a/test/trap-clip.pdf.rgb24.ref.png +++ b/test/trap-clip.pdf.rgb24.ref.png diff --git a/test/trap-clip.ref.png b/test/trap-clip.ref.png Binary files differindex dee57e7b..e8c26d32 100644 --- a/test/trap-clip.ref.png +++ b/test/trap-clip.ref.png diff --git a/test/trap-clip.test-paginated.argb32.ref.png b/test/trap-clip.test-paginated.argb32.ref.png Binary files differnew file mode 100644 index 00000000..dee57e7b --- /dev/null +++ b/test/trap-clip.test-paginated.argb32.ref.png |