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