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

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 From 108b1c7825116ed3f93aa57384bbd3290cdc9181 Mon Sep 17 00:00:00 2001
michael@0 2 From: Karl Tomlinson <karlt+@karlt.net>
michael@0 3 Date: Sat, 17 Jul 2010 01:08:53 +0000
michael@0 4 Subject: clip: consider gstate target extents in _cairo_gstate_copy_clip_rectangle_list
michael@0 5
michael@0 6 Fixes https://bugs.freedesktop.org/show_bug.cgi?id=29125
michael@0 7
michael@0 8 To be consistent with _cairo_gstate_clip_extents, the context's clip
michael@0 9 should be intersected with the target surface extents (instead of only
michael@0 10 using them when there is no clip).
michael@0 11
michael@0 12 Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
michael@0 13 ---
michael@0 14 diff --git a/src/cairo-clip.c b/src/cairo-clip.c
michael@0 15 index 77d8214..d5a2fab 100644
michael@0 16 --- a/src/cairo-clip.c
michael@0 17 +++ b/src/cairo-clip.c
michael@0 18 @@ -1495,7 +1495,7 @@ _cairo_rectangle_list_create_in_error (cairo_status_t status)
michael@0 19 cairo_rectangle_list_t *
michael@0 20 _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
michael@0 21 {
michael@0 22 -#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S));
michael@0 23 +#define ERROR_LIST(S) _cairo_rectangle_list_create_in_error (_cairo_error (S))
michael@0 24
michael@0 25 cairo_rectangle_list_t *list;
michael@0 26 cairo_rectangle_t *rectangles = NULL;
michael@0 27 @@ -1507,57 +1507,37 @@ _cairo_clip_copy_rectangle_list (cairo_clip_t *clip, cairo_gstate_t *gstate)
michael@0 28 if (clip->all_clipped)
michael@0 29 goto DONE;
michael@0 30
michael@0 31 - if (clip->path != NULL) {
michael@0 32 - status = _cairo_clip_get_region (clip, &region);
michael@0 33 - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
michael@0 34 - goto DONE;
michael@0 35 - } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
michael@0 36 - return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE)
michael@0 37 - } else if (unlikely (status)) {
michael@0 38 - return ERROR_LIST (status);
michael@0 39 - }
michael@0 40 - }
michael@0 41 -
michael@0 42 - if (region != NULL) {
michael@0 43 - n_rects = cairo_region_num_rectangles (region);
michael@0 44 - if (n_rects) {
michael@0 45 - rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
michael@0 46 - if (unlikely (rectangles == NULL)) {
michael@0 47 - return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
michael@0 48 - }
michael@0 49 + if (!clip->path)
michael@0 50 + return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
michael@0 51
michael@0 52 - for (i = 0; i < n_rects; ++i) {
michael@0 53 - cairo_rectangle_int_t clip_rect;
michael@0 54 -
michael@0 55 - cairo_region_get_rectangle (region, i, &clip_rect);
michael@0 56 + status = _cairo_clip_get_region (clip, &region);
michael@0 57 + if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
michael@0 58 + goto DONE;
michael@0 59 + } else if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
michael@0 60 + return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
michael@0 61 + } else if (unlikely (status)) {
michael@0 62 + return ERROR_LIST (status);
michael@0 63 + }
michael@0 64
michael@0 65 - if (! _cairo_clip_int_rect_to_user (gstate,
michael@0 66 - &clip_rect,
michael@0 67 - &rectangles[i]))
michael@0 68 - {
michael@0 69 - free (rectangles);
michael@0 70 - return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
michael@0 71 - }
michael@0 72 - }
michael@0 73 + n_rects = cairo_region_num_rectangles (region);
michael@0 74 + if (n_rects) {
michael@0 75 + rectangles = _cairo_malloc_ab (n_rects, sizeof (cairo_rectangle_t));
michael@0 76 + if (unlikely (rectangles == NULL)) {
michael@0 77 + return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
michael@0 78 }
michael@0 79 - } else {
michael@0 80 - cairo_rectangle_int_t extents;
michael@0 81
michael@0 82 - if (! _cairo_surface_get_extents (_cairo_gstate_get_target (gstate),
michael@0 83 - &extents))
michael@0 84 - {
michael@0 85 - /* unbounded surface -> unclipped */
michael@0 86 - goto DONE;
michael@0 87 - }
michael@0 88 + for (i = 0; i < n_rects; ++i) {
michael@0 89 + cairo_rectangle_int_t clip_rect;
michael@0 90
michael@0 91 - n_rects = 1;
michael@0 92 - rectangles = malloc(sizeof (cairo_rectangle_t));
michael@0 93 - if (unlikely (rectangles == NULL))
michael@0 94 - return ERROR_LIST (CAIRO_STATUS_NO_MEMORY);
michael@0 95 + cairo_region_get_rectangle (region, i, &clip_rect);
michael@0 96
michael@0 97 - if (! _cairo_clip_int_rect_to_user (gstate, &extents, rectangles)) {
michael@0 98 - free (rectangles);
michael@0 99 - return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
michael@0 100 + if (! _cairo_clip_int_rect_to_user (gstate,
michael@0 101 + &clip_rect,
michael@0 102 + &rectangles[i]))
michael@0 103 + {
michael@0 104 + free (rectangles);
michael@0 105 + return ERROR_LIST (CAIRO_STATUS_CLIP_NOT_REPRESENTABLE);
michael@0 106 + }
michael@0 107 }
michael@0 108 }
michael@0 109
michael@0 110 diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
michael@0 111 index baf6145..7caf624 100644
michael@0 112 --- a/src/cairo-gstate.c
michael@0 113 +++ b/src/cairo-gstate.c
michael@0 114 @@ -1555,7 +1555,19 @@ _cairo_gstate_clip_extents (cairo_gstate_t *gstate,
michael@0 115 cairo_rectangle_list_t*
michael@0 116 _cairo_gstate_copy_clip_rectangle_list (cairo_gstate_t *gstate)
michael@0 117 {
michael@0 118 - return _cairo_clip_copy_rectangle_list (&gstate->clip, gstate);
michael@0 119 + cairo_clip_t clip;
michael@0 120 + cairo_rectangle_int_t extents;
michael@0 121 + cairo_rectangle_list_t *list;
michael@0 122 +
michael@0 123 + _cairo_clip_init_copy (&clip, &gstate->clip);
michael@0 124 +
michael@0 125 + if (_cairo_surface_get_extents (gstate->target, &extents))
michael@0 126 + _cairo_clip_rectangle (&clip, &extents);
michael@0 127 +
michael@0 128 + list = _cairo_clip_copy_rectangle_list (&clip, gstate);
michael@0 129 + _cairo_clip_fini (&clip);
michael@0 130 +
michael@0 131 + return list;
michael@0 132 }
michael@0 133
michael@0 134 static void
michael@0 135 diff --git a/test/get-clip.c b/test/get-clip.c
michael@0 136 index f0477a1..f97db3f 100644
michael@0 137 --- a/test/get-clip.c
michael@0 138 +++ b/test/get-clip.c
michael@0 139 @@ -120,6 +120,22 @@ preamble (cairo_test_context_t *ctx)
michael@0 140 }
michael@0 141 cairo_rectangle_list_destroy (rectangle_list);
michael@0 142
michael@0 143 + /* We should get the same results after applying a clip that contains the
michael@0 144 + existing clip. */
michael@0 145 + phase = "Clip beyond surface extents";
michael@0 146 + cairo_save (cr);
michael@0 147 + cairo_rectangle (cr, -10, -10, SIZE + 20 , SIZE + 20);
michael@0 148 + cairo_clip (cr);
michael@0 149 + rectangle_list = cairo_copy_clip_rectangle_list (cr);
michael@0 150 + if (! check_count (ctx, phase, rectangle_list, 1) ||
michael@0 151 + ! check_clip_extents (ctx, phase, cr, 0, 0, SIZE, SIZE) ||
michael@0 152 + ! check_rectangles_contain (ctx, phase, rectangle_list, 0, 0, SIZE, SIZE))
michael@0 153 + {
michael@0 154 + goto FAIL;
michael@0 155 + }
michael@0 156 + cairo_rectangle_list_destroy (rectangle_list);
michael@0 157 + cairo_restore (cr);
michael@0 158 +
michael@0 159 /* Test simple clip rect. */
michael@0 160 phase = "Simple clip rect";
michael@0 161 cairo_save (cr);
michael@0 162 --
michael@0 163 cgit v0.8.3-6-g21f6

mercurial