gfx/cairo/quartz-refactor-surface-setup.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: Robert O'Callahan <robert@ocallahan.org>
michael@0 2 Bug 593270. Part 1: Move surface setup code to a helper function. r=jrmuizel,a=joe
michael@0 3
michael@0 4 diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c
michael@0 5 --- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
michael@0 6 +++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
michael@0 7 @@ -1455,16 +1455,147 @@ _cairo_quartz_setup_radial_source (cairo
michael@0 8 extend, extend);
michael@0 9
michael@0 10 CGColorSpaceRelease(rgb);
michael@0 11 CGFunctionRelease(gradFunc);
michael@0 12
michael@0 13 state->action = DO_SHADING;
michael@0 14 }
michael@0 15
michael@0 16 +static void
michael@0 17 +_cairo_quartz_setup_surface_source (cairo_quartz_surface_t *surface,
michael@0 18 + const cairo_surface_pattern_t *spat,
michael@0 19 + cairo_rectangle_int_t *extents,
michael@0 20 + cairo_quartz_drawing_state_t *state)
michael@0 21 +{
michael@0 22 + const cairo_pattern_t *source = &spat->base;
michael@0 23 + CGContextRef context = state->context;
michael@0 24 +
michael@0 25 + if (source->extend == CAIRO_EXTEND_NONE ||
michael@0 26 + (CGContextDrawTiledImagePtr && source->extend == CAIRO_EXTEND_REPEAT))
michael@0 27 + {
michael@0 28 + cairo_surface_t *pat_surf = spat->surface;
michael@0 29 + CGImageRef img;
michael@0 30 + cairo_matrix_t m = spat->base.matrix;
michael@0 31 + cairo_rectangle_int_t extents;
michael@0 32 + CGAffineTransform xform;
michael@0 33 + CGRect srcRect;
michael@0 34 + cairo_fixed_t fw, fh;
michael@0 35 + cairo_bool_t is_bounded;
michael@0 36 + cairo_status_t status;
michael@0 37 +
michael@0 38 + cairo_matrix_invert(&m);
michael@0 39 + _cairo_quartz_cairo_matrix_to_quartz (&m, &state->transform);
michael@0 40 +
michael@0 41 + /* Draw nonrepeating CGLayer surface using DO_LAYER */
michael@0 42 + if (source->extend == CAIRO_EXTEND_NONE ||
michael@0 43 + (CGContextDrawTiledImagePtr && source->extend == CAIRO_EXTEND_REPEAT))
michael@0 44 + cairo_quartz_surface_t *quartz_surf = (cairo_quartz_surface_t *) pat_surf;
michael@0 45 + if (quartz_surf->cgLayer) {
michael@0 46 + state->imageRect = CGRectMake (0, 0, quartz_surf->extents.width, quartz_surf->extents.height);
michael@0 47 + state->layer = quartz_surf->cgLayer;
michael@0 48 + state->action = DO_LAYER;
michael@0 49 + return;
michael@0 50 + }
michael@0 51 + }
michael@0 52 +
michael@0 53 + status = _cairo_surface_to_cgimage (pat_surf, &img);
michael@0 54 + if (status) {
michael@0 55 + state->action = DO_UNSUPPORTED;
michael@0 56 + return;
michael@0 57 + }
michael@0 58 + if (img == NULL) {
michael@0 59 + state->action = DO_NOTHING;
michael@0 60 + return;
michael@0 61 + }
michael@0 62 +
michael@0 63 + /* XXXroc what is this for? */
michael@0 64 + CGContextSetRGBFillColor (surface->cgContext, 0, 0, 0, 1);
michael@0 65 +
michael@0 66 + state->image = img;
michael@0 67 +
michael@0 68 + is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
michael@0 69 + assert (is_bounded);
michael@0 70 +
michael@0 71 + if (source->extend == CAIRO_EXTEND_NONE) {
michael@0 72 + state->imageRect = CGRectMake (0, 0, extents.width, extents.height);
michael@0 73 + state->action = DO_IMAGE;
michael@0 74 + return;
michael@0 75 + }
michael@0 76 +
michael@0 77 + /* Quartz seems to tile images at pixel-aligned regions only -- this
michael@0 78 + * leads to seams if the image doesn't end up scaling to fill the
michael@0 79 + * space exactly. The CGPattern tiling approach doesn't have this
michael@0 80 + * problem. Check if we're going to fill up the space (within some
michael@0 81 + * epsilon), and if not, fall back to the CGPattern type.
michael@0 82 + */
michael@0 83 +
michael@0 84 + xform = CGAffineTransformConcat (CGContextGetCTM (context),
michael@0 85 + state->transform);
michael@0 86 +
michael@0 87 + srcRect = CGRectMake (0, 0, extents.width, extents.height);
michael@0 88 + srcRect = CGRectApplyAffineTransform (srcRect, xform);
michael@0 89 +
michael@0 90 + fw = _cairo_fixed_from_double (srcRect.size.width);
michael@0 91 + fh = _cairo_fixed_from_double (srcRect.size.height);
michael@0 92 +
michael@0 93 + if ((fw & CAIRO_FIXED_FRAC_MASK) <= CAIRO_FIXED_EPSILON &&
michael@0 94 + (fh & CAIRO_FIXED_FRAC_MASK) <= CAIRO_FIXED_EPSILON)
michael@0 95 + {
michael@0 96 + /* We're good to use DrawTiledImage, but ensure that
michael@0 97 + * the math works out */
michael@0 98 +
michael@0 99 + srcRect.size.width = round(srcRect.size.width);
michael@0 100 + srcRect.size.height = round(srcRect.size.height);
michael@0 101 +
michael@0 102 + xform = CGAffineTransformInvert (xform);
michael@0 103 +
michael@0 104 + srcRect = CGRectApplyAffineTransform (srcRect, xform);
michael@0 105 +
michael@0 106 + state->imageRect = srcRect;
michael@0 107 + state->action = DO_TILED_IMAGE;
michael@0 108 + return;
michael@0 109 + }
michael@0 110 +
michael@0 111 + /* Fall through to generic SURFACE case */
michael@0 112 + }
michael@0 113 +
michael@0 114 + CGFloat patternAlpha = 1.0f;
michael@0 115 + CGColorSpaceRef patternSpace;
michael@0 116 + CGPatternRef pattern;
michael@0 117 + cairo_int_status_t status;
michael@0 118 +
michael@0 119 + status = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source, &pattern);
michael@0 120 + if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
michael@0 121 + state->action = DO_NOTHING;
michael@0 122 + return;
michael@0 123 + }
michael@0 124 + if (status) {
michael@0 125 + state->action = DO_UNSUPPORTED;
michael@0 126 + return;
michael@0 127 + }
michael@0 128 +
michael@0 129 + patternSpace = CGColorSpaceCreatePattern (NULL);
michael@0 130 + CGContextSetFillColorSpace (context, patternSpace);
michael@0 131 + CGContextSetFillPattern (context, pattern, &patternAlpha);
michael@0 132 + CGContextSetStrokeColorSpace (context, patternSpace);
michael@0 133 + CGContextSetStrokePattern (context, pattern, &patternAlpha);
michael@0 134 + CGColorSpaceRelease (patternSpace);
michael@0 135 +
michael@0 136 + /* Quartz likes to munge the pattern phase (as yet unexplained
michael@0 137 + * why); force it to 0,0 as we've already baked in the correct
michael@0 138 + * pattern translation into the pattern matrix
michael@0 139 + */
michael@0 140 + CGContextSetPatternPhase (context, CGSizeMake(0,0));
michael@0 141 +
michael@0 142 + state->pattern = pattern;
michael@0 143 + state->action = DO_PATTERN;
michael@0 144 + return;
michael@0 145 +}
michael@0 146 +
michael@0 147 /**
michael@0 148 * Call this before any operation that can modify the contents of a
michael@0 149 * cairo_quartz_surface_t.
michael@0 150 */
michael@0 151 static void
michael@0 152 _cairo_quartz_surface_will_change (cairo_quartz_surface_t *surface)
michael@0 153 {
michael@0 154 if (surface->bitmapContextImage) {
michael@0 155 @@ -1566,133 +1697,19 @@ _cairo_quartz_setup_state (cairo_quartz_
michael@0 156 }
michael@0 157
michael@0 158 if (source->type == CAIRO_PATTERN_TYPE_RADIAL) {
michael@0 159 const cairo_radial_pattern_t *rpat = (const cairo_radial_pattern_t *)source;
michael@0 160 _cairo_quartz_setup_radial_source (surface, rpat, extents, &state);
michael@0 161 return state;
michael@0 162 }
michael@0 163
michael@0 164 - if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
michael@0 165 - (source->extend == CAIRO_EXTEND_NONE || (CGContextDrawTiledImagePtr && source->extend == CAIRO_EXTEND_REPEAT)))
michael@0 166 - {
michael@0 167 + if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
michael@0 168 const cairo_surface_pattern_t *spat = (const cairo_surface_pattern_t *) source;
michael@0 169 - cairo_surface_t *pat_surf = spat->surface;
michael@0 170 - CGImageRef img;
michael@0 171 - cairo_matrix_t m = spat->base.matrix;
michael@0 172 - cairo_rectangle_int_t extents;
michael@0 173 - CGAffineTransform xform;
michael@0 174 - CGRect srcRect;
michael@0 175 - cairo_fixed_t fw, fh;
michael@0 176 - cairo_bool_t is_bounded;
michael@0 177 -
michael@0 178 - cairo_matrix_invert(&m);
michael@0 179 - _cairo_quartz_cairo_matrix_to_quartz (&m, &state.transform);
michael@0 180 -
michael@0 181 - if (cairo_surface_get_type (pat_surf) == CAIRO_SURFACE_TYPE_QUARTZ) {
michael@0 182 - cairo_quartz_surface_t *quartz_surf = (cairo_quartz_surface_t *) pat_surf;
michael@0 183 - if (quartz_surf->cgLayer && source->extend == CAIRO_EXTEND_NONE) {
michael@0 184 - state.imageRect = CGRectMake (0, 0, quartz_surf->extents.width, quartz_surf->extents.height);
michael@0 185 - state.layer = quartz_surf->cgLayer;
michael@0 186 - state.action = DO_LAYER;
michael@0 187 - return state;
michael@0 188 - }
michael@0 189 - }
michael@0 190 -
michael@0 191 - status = _cairo_surface_to_cgimage (pat_surf, &img);
michael@0 192 - if (status) {
michael@0 193 - state.action = DO_UNSUPPORTED;
michael@0 194 - return state;
michael@0 195 - }
michael@0 196 - if (img == NULL) {
michael@0 197 - state.action = DO_NOTHING;
michael@0 198 - return state;
michael@0 199 - }
michael@0 200 -
michael@0 201 - CGContextSetRGBFillColor (surface->cgContext, 0, 0, 0, 1);
michael@0 202 -
michael@0 203 - state.image = img;
michael@0 204 -
michael@0 205 - is_bounded = _cairo_surface_get_extents (pat_surf, &extents);
michael@0 206 - assert (is_bounded);
michael@0 207 -
michael@0 208 - if (source->extend == CAIRO_EXTEND_NONE) {
michael@0 209 - state.imageRect = CGRectMake (0, 0, extents.width, extents.height);
michael@0 210 - state.action = DO_IMAGE;
michael@0 211 - return state;
michael@0 212 - }
michael@0 213 -
michael@0 214 - /* Quartz seems to tile images at pixel-aligned regions only -- this
michael@0 215 - * leads to seams if the image doesn't end up scaling to fill the
michael@0 216 - * space exactly. The CGPattern tiling approach doesn't have this
michael@0 217 - * problem. Check if we're going to fill up the space (within some
michael@0 218 - * epsilon), and if not, fall back to the CGPattern type.
michael@0 219 - */
michael@0 220 -
michael@0 221 - xform = CGAffineTransformConcat (CGContextGetCTM (context),
michael@0 222 - state.transform);
michael@0 223 -
michael@0 224 - srcRect = CGRectMake (0, 0, extents.width, extents.height);
michael@0 225 - srcRect = CGRectApplyAffineTransform (srcRect, xform);
michael@0 226 -
michael@0 227 - fw = _cairo_fixed_from_double (srcRect.size.width);
michael@0 228 - fh = _cairo_fixed_from_double (srcRect.size.height);
michael@0 229 -
michael@0 230 - if ((fw & CAIRO_FIXED_FRAC_MASK) <= CAIRO_FIXED_EPSILON &&
michael@0 231 - (fh & CAIRO_FIXED_FRAC_MASK) <= CAIRO_FIXED_EPSILON)
michael@0 232 - {
michael@0 233 - /* We're good to use DrawTiledImage, but ensure that
michael@0 234 - * the math works out */
michael@0 235 -
michael@0 236 - srcRect.size.width = round(srcRect.size.width);
michael@0 237 - srcRect.size.height = round(srcRect.size.height);
michael@0 238 -
michael@0 239 - xform = CGAffineTransformInvert (xform);
michael@0 240 -
michael@0 241 - srcRect = CGRectApplyAffineTransform (srcRect, xform);
michael@0 242 -
michael@0 243 - state.imageRect = srcRect;
michael@0 244 - state.action = DO_TILED_IMAGE;
michael@0 245 - return state;
michael@0 246 - }
michael@0 247 -
michael@0 248 - /* Fall through to generic SURFACE case */
michael@0 249 - }
michael@0 250 -
michael@0 251 - if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
michael@0 252 - CGFloat patternAlpha = 1.0f;
michael@0 253 - CGColorSpaceRef patternSpace;
michael@0 254 - CGPatternRef pattern;
michael@0 255 - cairo_int_status_t status;
michael@0 256 -
michael@0 257 - status = _cairo_quartz_cairo_repeating_surface_pattern_to_quartz (surface, source, &pattern);
michael@0 258 - if (status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
michael@0 259 - state.action = DO_NOTHING;
michael@0 260 - return state;
michael@0 261 - }
michael@0 262 - if (status) {
michael@0 263 - state.action = DO_UNSUPPORTED;
michael@0 264 - return state;
michael@0 265 - }
michael@0 266 -
michael@0 267 - patternSpace = CGColorSpaceCreatePattern (NULL);
michael@0 268 - CGContextSetFillColorSpace (context, patternSpace);
michael@0 269 - CGContextSetFillPattern (context, pattern, &patternAlpha);
michael@0 270 - CGContextSetStrokeColorSpace (context, patternSpace);
michael@0 271 - CGContextSetStrokePattern (context, pattern, &patternAlpha);
michael@0 272 - CGColorSpaceRelease (patternSpace);
michael@0 273 -
michael@0 274 - /* Quartz likes to munge the pattern phase (as yet unexplained
michael@0 275 - * why); force it to 0,0 as we've already baked in the correct
michael@0 276 - * pattern translation into the pattern matrix
michael@0 277 - */
michael@0 278 - CGContextSetPatternPhase (context, CGSizeMake(0,0));
michael@0 279 -
michael@0 280 - state.pattern = pattern;
michael@0 281 - state.action = DO_PATTERN;
michael@0 282 + _cairo_quartz_setup_surface_source (surface, spat, extents, &state);
michael@0 283 return state;
michael@0 284 }
michael@0 285
michael@0 286 state.action = DO_UNSUPPORTED;
michael@0 287 return state;
michael@0 288 }
michael@0 289
michael@0 290 /**

mercurial