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, ®ion); 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, ®ion); 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