Tue, 06 Jan 2015 21:39:09 +0100
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 768775. Improve the precision of the calculation of the number of stops that need to be added to handle 'repeat' and 'reflect', when we're filling a path. r=bas |
michael@0 | 3 | |
michael@0 | 4 | diff --git a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp |
michael@0 | 5 | --- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp |
michael@0 | 6 | +++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp |
michael@0 | 7 | @@ -1411,17 +1411,17 @@ static RefPtr<ID2D1Brush> |
michael@0 | 8 | |
michael@0 | 9 | gradient_center.x = _cairo_fixed_to_float(source_pattern->c1.x); |
michael@0 | 10 | gradient_center.y = _cairo_fixed_to_float(source_pattern->c1.y); |
michael@0 | 11 | |
michael@0 | 12 | // Transform surface corners into pattern coordinates. |
michael@0 | 13 | cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y); |
michael@0 | 14 | cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y); |
michael@0 | 15 | cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y); |
michael@0 | 16 | - cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &top_left.y); |
michael@0 | 17 | + cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &bottom_right.y); |
michael@0 | 18 | |
michael@0 | 19 | // Find the corner furthest away from the gradient center in pattern space. |
michael@0 | 20 | double largest = MAX(_cairo_d2d_point_dist(top_left, gradient_center), _cairo_d2d_point_dist(top_right, gradient_center)); |
michael@0 | 21 | largest = MAX(largest, _cairo_d2d_point_dist(bottom_left, gradient_center)); |
michael@0 | 22 | largest = MAX(largest, _cairo_d2d_point_dist(bottom_right, gradient_center)); |
michael@0 | 23 | |
michael@0 | 24 | unsigned int minSize = (unsigned int)ceil(largest); |
michael@0 | 25 | |
michael@0 | 26 | @@ -1531,16 +1531,17 @@ static RefPtr<ID2D1Brush> |
michael@0 | 27 | stopCollection, |
michael@0 | 28 | &brush); |
michael@0 | 29 | delete [] stops; |
michael@0 | 30 | return brush; |
michael@0 | 31 | } |
michael@0 | 32 | |
michael@0 | 33 | static RefPtr<ID2D1Brush> |
michael@0 | 34 | _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf, |
michael@0 | 35 | + cairo_path_fixed_t *fill_path, |
michael@0 | 36 | cairo_linear_pattern_t *source_pattern) |
michael@0 | 37 | { |
michael@0 | 38 | if (source_pattern->p1.x == source_pattern->p2.x && |
michael@0 | 39 | source_pattern->p1.y == source_pattern->p2.y) { |
michael@0 | 40 | // Cairo behavior in this situation is to draw a solid color the size of the last stop. |
michael@0 | 41 | RefPtr<ID2D1SolidColorBrush> brush; |
michael@0 | 42 | d2dsurf->rt->CreateSolidColorBrush( |
michael@0 | 43 | _cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[source_pattern->base.n_stops - 1].color), |
michael@0 | 44 | @@ -1564,35 +1565,46 @@ static RefPtr<ID2D1Brush> |
michael@0 | 45 | p1.x = _cairo_fixed_to_float(source_pattern->p1.x); |
michael@0 | 46 | p1.y = _cairo_fixed_to_float(source_pattern->p1.y); |
michael@0 | 47 | p2.x = _cairo_fixed_to_float(source_pattern->p2.x); |
michael@0 | 48 | p2.y = _cairo_fixed_to_float(source_pattern->p2.y); |
michael@0 | 49 | |
michael@0 | 50 | D2D1_GRADIENT_STOP *stops; |
michael@0 | 51 | int num_stops = source_pattern->base.n_stops; |
michael@0 | 52 | if (source_pattern->base.base.extend == CAIRO_EXTEND_REPEAT || source_pattern->base.base.extend == CAIRO_EXTEND_REFLECT) { |
michael@0 | 53 | - |
michael@0 | 54 | - RefPtr<IDXGISurface> surf; |
michael@0 | 55 | - d2dsurf->surface->QueryInterface(&surf); |
michael@0 | 56 | - DXGI_SURFACE_DESC desc; |
michael@0 | 57 | - surf->GetDesc(&desc); |
michael@0 | 58 | - |
michael@0 | 59 | // Get this when the points are not transformed yet. |
michael@0 | 60 | double gradient_length = _cairo_d2d_point_dist(p1, p2); |
michael@0 | 61 | - |
michael@0 | 62 | - // Calculate the repeat count needed; |
michael@0 | 63 | - cairo_point_double_t top_left, top_right, bottom_left, bottom_right; |
michael@0 | 64 | - top_left.x = bottom_left.x = top_left.y = top_right.y = 0; |
michael@0 | 65 | - top_right.x = bottom_right.x = desc.Width; |
michael@0 | 66 | - bottom_right.y = bottom_left.y = desc.Height; |
michael@0 | 67 | + cairo_point_double_t top_left, top_right, bottom_left, bottom_right; |
michael@0 | 68 | + |
michael@0 | 69 | + if (fill_path) { |
michael@0 | 70 | + // Calculate the repeat count needed; |
michael@0 | 71 | + cairo_box_t fill_extents; |
michael@0 | 72 | + _cairo_path_fixed_extents (fill_path, &fill_extents); |
michael@0 | 73 | + |
michael@0 | 74 | + top_left.x = bottom_left.x = _cairo_fixed_to_double (fill_extents.p1.x); |
michael@0 | 75 | + top_left.y = top_right.y = _cairo_fixed_to_double (fill_extents.p1.y); |
michael@0 | 76 | + top_right.x = bottom_right.x = _cairo_fixed_to_double (fill_extents.p2.x); |
michael@0 | 77 | + bottom_right.y = bottom_left.y = _cairo_fixed_to_double (fill_extents.p2.y); |
michael@0 | 78 | + } else { |
michael@0 | 79 | + RefPtr<IDXGISurface> surf; |
michael@0 | 80 | + d2dsurf->surface->QueryInterface(&surf); |
michael@0 | 81 | + DXGI_SURFACE_DESC desc; |
michael@0 | 82 | + surf->GetDesc(&desc); |
michael@0 | 83 | + |
michael@0 | 84 | + top_left.x = bottom_left.x = 0; |
michael@0 | 85 | + top_left.y = top_right.y = 0; |
michael@0 | 86 | + top_right.x = bottom_right.x = desc.Width; |
michael@0 | 87 | + bottom_right.y = bottom_left.y = desc.Height; |
michael@0 | 88 | + } |
michael@0 | 89 | + |
michael@0 | 90 | // Transform the corners of our surface to pattern space. |
michael@0 | 91 | cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y); |
michael@0 | 92 | cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y); |
michael@0 | 93 | cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y); |
michael@0 | 94 | - cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &top_left.y); |
michael@0 | 95 | + cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &bottom_right.y); |
michael@0 | 96 | |
michael@0 | 97 | cairo_point_double_t u; |
michael@0 | 98 | // Unit vector of the gradient direction. |
michael@0 | 99 | u = _cairo_d2d_subtract_point(p2, p1); |
michael@0 | 100 | _cairo_d2d_normalize_point(&u); |
michael@0 | 101 | |
michael@0 | 102 | // (corner - p1) . u = |corner - p1| cos(a) where a is the angle between the two vectors. |
michael@0 | 103 | // Coincidentally |corner - p1| cos(a) is actually also the distance our gradient needs to cover since |
michael@0 | 104 | @@ -1701,17 +1713,18 @@ static RefPtr<ID2D1Brush> |
michael@0 | 105 | * \param d2dsurf Surface to create a brush for |
michael@0 | 106 | * \param pattern The pattern to create a brush for |
michael@0 | 107 | * \param unique We cache the bitmap/color brush for speed. If this |
michael@0 | 108 | * needs a brush that is unique (i.e. when more than one is needed), |
michael@0 | 109 | * this will make the function return a seperate brush. |
michael@0 | 110 | * \return A brush object |
michael@0 | 111 | */ |
michael@0 | 112 | static RefPtr<ID2D1Brush> |
michael@0 | 113 | -_cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf, |
michael@0 | 114 | +_cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf, |
michael@0 | 115 | + cairo_path_fixed_t *fill_path, |
michael@0 | 116 | const cairo_pattern_t *pattern, |
michael@0 | 117 | bool unique = false) |
michael@0 | 118 | { |
michael@0 | 119 | HRESULT hr; |
michael@0 | 120 | |
michael@0 | 121 | if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) { |
michael@0 | 122 | cairo_solid_pattern_t *sourcePattern = |
michael@0 | 123 | (cairo_solid_pattern_t*)pattern; |
michael@0 | 124 | @@ -1729,17 +1742,17 @@ static RefPtr<ID2D1Brush> |
michael@0 | 125 | d2dsurf->solidColorBrush->SetColor(color); |
michael@0 | 126 | } |
michael@0 | 127 | return d2dsurf->solidColorBrush; |
michael@0 | 128 | } |
michael@0 | 129 | |
michael@0 | 130 | } else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) { |
michael@0 | 131 | cairo_linear_pattern_t *source_pattern = |
michael@0 | 132 | (cairo_linear_pattern_t*)pattern; |
michael@0 | 133 | - return _cairo_d2d_create_linear_gradient_brush(d2dsurf, source_pattern); |
michael@0 | 134 | + return _cairo_d2d_create_linear_gradient_brush(d2dsurf, fill_path, source_pattern); |
michael@0 | 135 | } else if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL) { |
michael@0 | 136 | cairo_radial_pattern_t *source_pattern = |
michael@0 | 137 | (cairo_radial_pattern_t*)pattern; |
michael@0 | 138 | return _cairo_d2d_create_radial_gradient_brush(d2dsurf, source_pattern); |
michael@0 | 139 | } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) { |
michael@0 | 140 | cairo_matrix_t mat = pattern->matrix; |
michael@0 | 141 | cairo_matrix_invert(&mat); |
michael@0 | 142 | |
michael@0 | 143 | @@ -3228,17 +3241,17 @@ static cairo_int_status_t |
michael@0 | 144 | |
michael@0 | 145 | if (unlikely(status)) |
michael@0 | 146 | return status; |
michael@0 | 147 | } |
michael@0 | 148 | #endif |
michael@0 | 149 | |
michael@0 | 150 | target_rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); |
michael@0 | 151 | |
michael@0 | 152 | - RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, |
michael@0 | 153 | + RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, |
michael@0 | 154 | source); |
michael@0 | 155 | |
michael@0 | 156 | if (!brush) { |
michael@0 | 157 | return CAIRO_INT_STATUS_UNSUPPORTED; |
michael@0 | 158 | } |
michael@0 | 159 | |
michael@0 | 160 | D2D1_SIZE_F size = target_rt->GetSize(); |
michael@0 | 161 | target_rt->FillRectangle(D2D1::RectF((FLOAT)0, |
michael@0 | 162 | @@ -3349,17 +3362,17 @@ static cairo_int_status_t |
michael@0 | 163 | source->filter, |
michael@0 | 164 | solidAlphaValue); |
michael@0 | 165 | if (rv != CAIRO_INT_STATUS_UNSUPPORTED) { |
michael@0 | 166 | return rv; |
michael@0 | 167 | } |
michael@0 | 168 | } |
michael@0 | 169 | } |
michael@0 | 170 | |
michael@0 | 171 | - RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, source); |
michael@0 | 172 | + RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, source); |
michael@0 | 173 | if (!brush) { |
michael@0 | 174 | return CAIRO_INT_STATUS_UNSUPPORTED; |
michael@0 | 175 | } |
michael@0 | 176 | |
michael@0 | 177 | RefPtr<ID2D1RenderTarget> target_rt = d2dsurf->rt; |
michael@0 | 178 | #ifndef ALWAYS_MANUAL_COMPOSITE |
michael@0 | 179 | if (op != CAIRO_OPERATOR_OVER) { |
michael@0 | 180 | #endif |
michael@0 | 181 | @@ -3389,17 +3402,17 @@ static cairo_int_status_t |
michael@0 | 182 | brush->SetOpacity(1.0); |
michael@0 | 183 | |
michael@0 | 184 | if (target_rt.get() != d2dsurf->rt.get()) { |
michael@0 | 185 | return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip); |
michael@0 | 186 | } |
michael@0 | 187 | return CAIRO_INT_STATUS_SUCCESS; |
michael@0 | 188 | } |
michael@0 | 189 | |
michael@0 | 190 | - RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, mask, true); |
michael@0 | 191 | + RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, mask, true); |
michael@0 | 192 | if (!opacityBrush) { |
michael@0 | 193 | return CAIRO_INT_STATUS_UNSUPPORTED; |
michael@0 | 194 | } |
michael@0 | 195 | |
michael@0 | 196 | if (!d2dsurf->maskLayer) { |
michael@0 | 197 | d2dsurf->rt->CreateLayer(&d2dsurf->maskLayer); |
michael@0 | 198 | } |
michael@0 | 199 | target_rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(), |
michael@0 | 200 | @@ -3475,17 +3488,17 @@ static cairo_int_status_t |
michael@0 | 201 | D2D1_FIGURE_BEGIN_FILLED); |
michael@0 | 202 | |
michael@0 | 203 | bool transformed = true; |
michael@0 | 204 | |
michael@0 | 205 | if (_cairo_matrix_is_identity(ctm)) { |
michael@0 | 206 | transformed = false; |
michael@0 | 207 | } |
michael@0 | 208 | |
michael@0 | 209 | - RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, |
michael@0 | 210 | + RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, |
michael@0 | 211 | source); |
michael@0 | 212 | if (!brush) { |
michael@0 | 213 | return CAIRO_INT_STATUS_UNSUPPORTED; |
michael@0 | 214 | } |
michael@0 | 215 | |
michael@0 | 216 | D2D1::Matrix3x2F mat; |
michael@0 | 217 | if (transformed) { |
michael@0 | 218 | // If we are transformed we will draw the geometry multiplied by the |
michael@0 | 219 | @@ -3602,31 +3615,31 @@ static cairo_int_status_t |
michael@0 | 220 | } |
michael@0 | 221 | |
michael@0 | 222 | if (is_box) { |
michael@0 | 223 | float x1 = _cairo_fixed_to_float(box.p1.x); |
michael@0 | 224 | float y1 = _cairo_fixed_to_float(box.p1.y); |
michael@0 | 225 | float x2 = _cairo_fixed_to_float(box.p2.x); |
michael@0 | 226 | float y2 = _cairo_fixed_to_float(box.p2.y); |
michael@0 | 227 | RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, |
michael@0 | 228 | - source); |
michael@0 | 229 | + path, source); |
michael@0 | 230 | if (!brush) { |
michael@0 | 231 | return CAIRO_INT_STATUS_UNSUPPORTED; |
michael@0 | 232 | } |
michael@0 | 233 | |
michael@0 | 234 | target_rt->FillRectangle(D2D1::RectF(x1, |
michael@0 | 235 | y1, |
michael@0 | 236 | x2, |
michael@0 | 237 | y2), |
michael@0 | 238 | brush); |
michael@0 | 239 | } else { |
michael@0 | 240 | RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED); |
michael@0 | 241 | |
michael@0 | 242 | RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, |
michael@0 | 243 | - source); |
michael@0 | 244 | + path, source); |
michael@0 | 245 | if (!brush) { |
michael@0 | 246 | return CAIRO_INT_STATUS_UNSUPPORTED; |
michael@0 | 247 | } |
michael@0 | 248 | target_rt->FillGeometry(d2dpath, brush); |
michael@0 | 249 | } |
michael@0 | 250 | |
michael@0 | 251 | if (target_rt.get() != d2dsurf->rt.get()) { |
michael@0 | 252 | double x1, y1, x2, y2; |
michael@0 | 253 | @@ -4138,17 +4151,17 @@ static cairo_int_status_t |
michael@0 | 254 | DWRITE_TEXTURE_ALIASED_1x1 : DWRITE_TEXTURE_CLEARTYPE_3x1, |
michael@0 | 255 | &bounds); |
michael@0 | 256 | fontArea.x = bounds.left; |
michael@0 | 257 | fontArea.y = bounds.top; |
michael@0 | 258 | fontArea.width = bounds.right - bounds.left; |
michael@0 | 259 | fontArea.height = bounds.bottom - bounds.top; |
michael@0 | 260 | } |
michael@0 | 261 | |
michael@0 | 262 | - RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(dst, |
michael@0 | 263 | + RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(dst, NULL, |
michael@0 | 264 | source); |
michael@0 | 265 | |
michael@0 | 266 | if (!brush) { |
michael@0 | 267 | return CAIRO_INT_STATUS_UNSUPPORTED; |
michael@0 | 268 | } |
michael@0 | 269 | |
michael@0 | 270 | if (transform) { |
michael@0 | 271 | D2D1::Matrix3x2F mat_inverse = _cairo_d2d_matrix_from_matrix(&dwritesf->mat_inverse); |