gfx/cairo/clip-rects-surface-extents.patch

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/cairo/clip-rects-surface-extents.patch	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,163 @@
     1.4 +From 108b1c7825116ed3f93aa57384bbd3290cdc9181 Mon Sep 17 00:00:00 2001
     1.5 +From: Karl Tomlinson <karlt+@karlt.net>
     1.6 +Date: Sat, 17 Jul 2010 01:08:53 +0000
     1.7 +Subject: clip: consider gstate target extents in _cairo_gstate_copy_clip_rectangle_list
     1.8 +
     1.9 +Fixes https://bugs.freedesktop.org/show_bug.cgi?id=29125
    1.10 +
    1.11 +To be consistent with _cairo_gstate_clip_extents, the context's clip
    1.12 +should be intersected with the target surface extents (instead of only
    1.13 +using them when there is no clip).
    1.14 +
    1.15 +Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
    1.16 +---
    1.17 +diff --git a/src/cairo-clip.c b/src/cairo-clip.c
    1.18 +index 77d8214..d5a2fab 100644
    1.19 +--- a/src/cairo-clip.c
    1.20 ++++ b/src/cairo-clip.c
    1.21 +@@ -1495,7 +1495,7 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status)
    1.22 + cairo_rectangle_list_t *
    1.23 + _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
    1.24 + {
    1.25 +-#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S));
    1.26 ++#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S))
    1.27 + 
    1.28 +     cairo_rectangle_list_t *list;
    1.29 +     cairo_rectangle_t *rectangles = NULL;
    1.30 +@@ -1507,57 +1507,37 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
    1.31 +     if (clip->all_clipped)
    1.32 + 	goto DONE;
    1.33 + 
    1.34 +-    if (clip->path != NULL) {
    1.35 +-	status = _cairo_clip_get_region (clip, &region);
    1.36 +-	if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
    1.37 +-	    goto DONE;
    1.38 +-	} else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
    1.39 +-	    return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
    1.40 +-	} else if (unlikely (status)) {
    1.41 +-	    return ERROR_LIST (status);
    1.42 +-	}
    1.43 +-    }
    1.44 +-
    1.45 +-    if (region != NULL) {
    1.46 +-	n_rects = cairo_region_num_rectangles (region);
    1.47 +-	if (n_rects) {
    1.48 +-	    rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
    1.49 +-	    if (unlikely (rectangles == NULL)) {
    1.50 +-		return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
    1.51 +-	    }
    1.52 ++    if (!clip->path)
    1.53 ++	return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
    1.54 + 
    1.55 +-	    for (i = 0; i < n_rects; ++i) {
    1.56 +-		cairo_rectangle_int_t clip_rect;
    1.57 +-
    1.58 +-		cairo_region_get_rectangle (region, i, &clip_rect);
    1.59 ++    status = _cairo_clip_get_region (clip, &region);
    1.60 ++    if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
    1.61 ++	goto DONE;
    1.62 ++    } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
    1.63 ++	return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
    1.64 ++    } else if (unlikely (status)) {
    1.65 ++	return ERROR_LIST (status);
    1.66 ++    }
    1.67 + 
    1.68 +-		if (! _cairo_clip_int_rect_to_user (gstate,
    1.69 +-						    &clip_rect,
    1.70 +-						    &rectangles[i]))
    1.71 +-		{
    1.72 +-		    free (rectangles);
    1.73 +-		    return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
    1.74 +-		}
    1.75 +-	    }
    1.76 ++    n_rects = cairo_region_num_rectangles (region);
    1.77 ++    if (n_rects) {
    1.78 ++	rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
    1.79 ++	if (unlikely (rectangles == NULL)) {
    1.80 ++	    return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
    1.81 + 	}
    1.82 +-    } else {
    1.83 +-        cairo_rectangle_int_t extents;
    1.84 + 
    1.85 +-	if (! _cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
    1.86 +-					  &extents))
    1.87 +-	{
    1.88 +-	    /* unbounded surface -> unclipped */
    1.89 +-	    goto DONE;
    1.90 +-	}
    1.91 ++	for (i = 0; i < n_rects; ++i) {
    1.92 ++	    cairo_rectangle_int_t clip_rect;
    1.93 + 
    1.94 +-	n_rects = 1;
    1.95 +-	rectangles = malloc(sizeof (cairo_rectangle_t));
    1.96 +-	if (unlikely (rectangles == NULL))
    1.97 +-	    return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
    1.98 ++	    cairo_region_get_rectangle (region, i, &clip_rect);
    1.99 + 
   1.100 +-	if (! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles)) {
   1.101 +-	    free (rectangles);
   1.102 +-	    return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
   1.103 ++	    if (! _cairo_clip_int_rect_to_user (gstate,
   1.104 ++						&clip_rect,
   1.105 ++						&rectangles[i]))
   1.106 ++	    {
   1.107 ++		free (rectangles);
   1.108 ++		return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
   1.109 ++	    }
   1.110 + 	}
   1.111 +     }
   1.112 + 
   1.113 +diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
   1.114 +index baf6145..7caf624 100644
   1.115 +--- a/src/cairo-gstate.c
   1.116 ++++ b/src/cairo-gstate.c
   1.117 +@@ -1555,7 +1555,19 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
   1.118 + cairo_rectangle_list_t*
   1.119 + _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
   1.120 + {
   1.121 +-    return _cairo_clip_copy_rectangle_list (&gstate->clip, gstate);
   1.122 ++    cairo_clip_t clip;
   1.123 ++    cairo_rectangle_int_t extents;
   1.124 ++    cairo_rectangle_list_t *list;
   1.125 ++
   1.126 ++    _cairo_clip_init_copy (&clip, &gstate->clip);
   1.127 ++
   1.128 ++    if (_cairo_surface_get_extents (gstate->target, &extents))
   1.129 ++        _cairo_clip_rectangle (&clip, &extents);
   1.130 ++
   1.131 ++    list = _cairo_clip_copy_rectangle_list (&clip, gstate);
   1.132 ++    _cairo_clip_fini (&clip);
   1.133 ++
   1.134 ++    return list;
   1.135 + }
   1.136 + 
   1.137 + static void
   1.138 +diff --git a/test/get-clip.c b/test/get-clip.c
   1.139 +index f0477a1..f97db3f 100644
   1.140 +--- a/test/get-clip.c
   1.141 ++++ b/test/get-clip.c
   1.142 +@@ -120,6 +120,22 @@ preamble (cairo_test_context_t *ctx)
   1.143 +     }
   1.144 +     cairo_rectangle_list_destroy (rectangle_list);
   1.145 + 
   1.146 ++    /* We should get the same results after applying a clip that contains the
   1.147 ++       existing clip. */
   1.148 ++    phase = "Clip beyond surface extents";
   1.149 ++    cairo_save (cr);
   1.150 ++    cairo_rectangle (cr, -10, -10, SIZE + 20 , SIZE + 20);
   1.151 ++    cairo_clip (cr);
   1.152 ++    rectangle_list = cairo_copy_clip_rectangle_list (cr);
   1.153 ++    if (! check_count (ctx, phase, rectangle_list, 1) ||
   1.154 ++        ! check_clip_extents (ctx, phase, cr, 0, 0, SIZE, SIZE) ||
   1.155 ++        ! check_rectangles_contain (ctx, phase, rectangle_list, 0, 0, SIZE, SIZE))
   1.156 ++    {
   1.157 ++	goto FAIL;
   1.158 ++    }
   1.159 ++    cairo_rectangle_list_destroy (rectangle_list);
   1.160 ++    cairo_restore (cr);
   1.161 ++
   1.162 +     /* Test simple clip rect. */
   1.163 +     phase = "Simple clip rect";
   1.164 +     cairo_save (cr);
   1.165 +--
   1.166 +cgit v0.8.3-6-g21f6

mercurial