From e6c3efdd650a4eadceb003a5e1bf9d871f61a48f Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Sat, 27 Nov 2010 21:52:59 +0100 Subject: [PATCH] xcb: Work around wrong extent computation in the X server The X server calculates the bounding box for traps and then allocates a temporary picture for this. When the X server calculates different values than cairo got in extents->bounded, unbounded operators will have wrong results. The X server only ever calculates bounds that are larger than the correct values. Fix this by explicitly clipping the drawing to the expected bounds. Fixes clip-fill-{eo,nz}-unbounded and clip-stroke-unbounded. Signed-off-by: Uli Schlachter Reviewed-by: Andrea Canciani --- src/cairo-xcb-surface-render.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c index f71281810..f90d6c8d9 100644 --- a/src/cairo-xcb-surface-render.c +++ b/src/cairo-xcb-surface-render.c @@ -2391,6 +2391,7 @@ _clip_and_composite (cairo_xcb_surface_t *dst, { cairo_status_t status; cairo_region_t *clip_region = NULL; + cairo_region_t extents_region; cairo_bool_t need_clip_surface = FALSE; if (clip != NULL) { @@ -2414,6 +2415,14 @@ _clip_and_composite (cairo_xcb_surface_t *dst, if (unlikely (is_empty && extents->is_bounded)) return CAIRO_STATUS_SUCCESS; } + } else if (!extents->is_bounded) { + /* The X server will estimate the affected region of the unbounded + * operation and will apply the operation to that rectangle. + * However, there are cases where this estimate is too high (e.g. + * the test suite's clip-fill-{eo,nz}-unbounded tests). + */ + _cairo_region_init_rectangle (&extents_region, &extents->unbounded); + clip_region = &extents_region; } status = _cairo_xcb_connection_acquire (dst->connection); @@ -2482,6 +2491,8 @@ _clip_and_composite (cairo_xcb_surface_t *dst, if (clip_region != NULL) _cairo_xcb_surface_clear_clip_region (dst); + if (clip_region == &extents_region) + _cairo_region_fini (&extents_region); _cairo_xcb_connection_release (dst->connection);