summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2009-10-15 14:05:37 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2009-10-15 14:08:01 +0100
commit79190d89853958ee8252440d35a662fabf122afd (patch)
treea7107198374f6d27d3a5b3bcf79651194085dfca
parentade55037ffa596b690c6a1051394589f76eb1f48 (diff)
[surface] Avoid double application of device offset when calling fill()
_cairo_surface_fallback_paint() attempts to avoid a clipped operation if we can convert the paint into a fill of the clipmask. However by calling _cairo_surface_fill() we incur a double application of device offset to the source, triggering various failures. Company spotted this and managed to extract an excellent minimal test case, test/clip-device-offset. This commit fixes that failure.
-rw-r--r--src/cairo-surface-fallback.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/src/cairo-surface-fallback.c b/src/cairo-surface-fallback.c
index 77ae0ede..068f06dc 100644
--- a/src/cairo-surface-fallback.c
+++ b/src/cairo-surface-fallback.c
@@ -982,6 +982,35 @@ _clip_to_boxes (cairo_clip_t **clip,
return status;
}
+/* XXX _cairo_surface_backend_fill? */
+static cairo_status_t
+_wrap_surface_fill (cairo_surface_t *surface,
+ cairo_operator_t op,
+ const cairo_pattern_t *source,
+ cairo_path_fixed_t *path,
+ cairo_fill_rule_t fill_rule,
+ double tolerance,
+ cairo_antialias_t antialias,
+ cairo_clip_t *clip)
+{
+ if (surface->backend->fill != NULL) {
+ cairo_status_t status;
+
+ status = surface->backend->fill (surface, op, source,
+ path, fill_rule,
+ tolerance, antialias,
+ clip);
+
+ if (status != CAIRO_INT_STATUS_UNSUPPORTED)
+ return status;
+ }
+
+ return _cairo_surface_fallback_fill (surface, op, source,
+ path, fill_rule,
+ tolerance, antialias,
+ clip);
+}
+
cairo_status_t
_cairo_surface_fallback_paint (cairo_surface_t *surface,
cairo_operator_t op,
@@ -1035,12 +1064,12 @@ _cairo_surface_fallback_paint (cairo_surface_t *surface,
if (clip != NULL && clip_path->prev == NULL &&
_cairo_operator_bounded_by_mask (op))
{
- return _cairo_surface_fill (surface, op, source,
- &clip_path->path,
- clip_path->fill_rule,
- clip_path->tolerance,
- clip_path->antialias,
- NULL);
+ return _wrap_surface_fill (surface, op, source,
+ &clip_path->path,
+ clip_path->fill_rule,
+ clip_path->tolerance,
+ clip_path->antialias,
+ NULL);
}
status = _cairo_traps_init_boxes (&traps, boxes, num_boxes);