|
1 # HG changeset patch |
|
2 # User Robert O'Callahan <robert@ocallahan.org> |
|
3 # Date 1294019288 -46800 |
|
4 # Node ID bacc54d452a9fddb5a0d6a1442ec7be4de81ffa7 |
|
5 # Parent ccba8826be1451d0e61d0df38363dadffb20ba48 |
|
6 Bug 593604. Part 2: When compositing a tee surface into another tee surface, try to compose the subsurfaces pointwise. r=jrmuizel,a=blocking |
|
7 |
|
8 diff --git a/gfx/cairo/cairo/src/cairo-tee-surface.c b/gfx/cairo/cairo/src/cairo-tee-surface.c |
|
9 --- a/gfx/cairo/cairo/src/cairo-tee-surface.c |
|
10 +++ b/gfx/cairo/cairo/src/cairo-tee-surface.c |
|
11 @@ -186,35 +186,72 @@ static void |
|
12 _cairo_tee_surface_get_font_options (void *abstract_surface, |
|
13 cairo_font_options_t *options) |
|
14 { |
|
15 cairo_tee_surface_t *surface = abstract_surface; |
|
16 |
|
17 _cairo_surface_wrapper_get_font_options (&surface->master, options); |
|
18 } |
|
19 |
|
20 +static const cairo_pattern_t * |
|
21 +_cairo_tee_surface_match_source (cairo_tee_surface_t *surface, |
|
22 + const cairo_pattern_t *source, |
|
23 + int index, |
|
24 + cairo_surface_wrapper_t *dest, |
|
25 + cairo_surface_pattern_t *temp) |
|
26 +{ |
|
27 + cairo_surface_t *s; |
|
28 + cairo_status_t status = cairo_pattern_get_surface ((cairo_pattern_t *)source, &s); |
|
29 + if (status == CAIRO_STATUS_SUCCESS && |
|
30 + cairo_surface_get_type (s) == CAIRO_SURFACE_TYPE_TEE) { |
|
31 + cairo_surface_t *tee_surf = cairo_tee_surface_index (s, index); |
|
32 + if (tee_surf->status == CAIRO_STATUS_SUCCESS && |
|
33 + tee_surf->backend == dest->target->backend) { |
|
34 + status = _cairo_pattern_init_copy (&temp->base, source); |
|
35 + if (status == CAIRO_STATUS_SUCCESS) { |
|
36 + cairo_surface_destroy (temp->surface); |
|
37 + temp->surface = tee_surf; |
|
38 + cairo_surface_reference (temp->surface); |
|
39 + return &temp->base; |
|
40 + } |
|
41 + } |
|
42 + } |
|
43 + |
|
44 + return source; |
|
45 +} |
|
46 + |
|
47 static cairo_int_status_t |
|
48 _cairo_tee_surface_paint (void *abstract_surface, |
|
49 cairo_operator_t op, |
|
50 const cairo_pattern_t *source, |
|
51 cairo_clip_t *clip) |
|
52 { |
|
53 cairo_tee_surface_t *surface = abstract_surface; |
|
54 cairo_surface_wrapper_t *slaves; |
|
55 int n, num_slaves; |
|
56 cairo_status_t status; |
|
57 + const cairo_pattern_t *matched_source; |
|
58 + cairo_surface_pattern_t temp; |
|
59 |
|
60 - status = _cairo_surface_wrapper_paint (&surface->master, op, source, clip); |
|
61 + matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); |
|
62 + status = _cairo_surface_wrapper_paint (&surface->master, op, matched_source, clip); |
|
63 + if (matched_source == &temp.base) { |
|
64 + _cairo_pattern_fini (&temp.base); |
|
65 + } |
|
66 if (unlikely (status)) |
|
67 return status; |
|
68 |
|
69 num_slaves = _cairo_array_num_elements (&surface->slaves); |
|
70 slaves = _cairo_array_index (&surface->slaves, 0); |
|
71 for (n = 0; n < num_slaves; n++) { |
|
72 - status = _cairo_surface_wrapper_paint (&slaves[n], op, source, clip); |
|
73 + matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); |
|
74 + status = _cairo_surface_wrapper_paint (&slaves[n], op, matched_source, clip); |
|
75 + if (matched_source == &temp.base) { |
|
76 + _cairo_pattern_fini (&temp.base); |
|
77 + } |
|
78 if (unlikely (status)) |
|
79 return status; |
|
80 } |
|
81 |
|
82 return CAIRO_STATUS_SUCCESS; |
|
83 } |
|
84 |
|
85 static cairo_int_status_t |
|
86 @@ -223,27 +260,37 @@ _cairo_tee_surface_mask (void *abstrac |
|
87 const cairo_pattern_t *source, |
|
88 const cairo_pattern_t *mask, |
|
89 cairo_clip_t *clip) |
|
90 { |
|
91 cairo_tee_surface_t *surface = abstract_surface; |
|
92 cairo_surface_wrapper_t *slaves; |
|
93 int n, num_slaves; |
|
94 cairo_status_t status; |
|
95 + const cairo_pattern_t *matched_source; |
|
96 + cairo_surface_pattern_t temp; |
|
97 |
|
98 + matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); |
|
99 status = _cairo_surface_wrapper_mask (&surface->master, |
|
100 - op, source, mask, clip); |
|
101 + op, matched_source, mask, clip); |
|
102 + if (matched_source == &temp.base) { |
|
103 + _cairo_pattern_fini (&temp.base); |
|
104 + } |
|
105 if (unlikely (status)) |
|
106 return status; |
|
107 |
|
108 num_slaves = _cairo_array_num_elements (&surface->slaves); |
|
109 slaves = _cairo_array_index (&surface->slaves, 0); |
|
110 for (n = 0; n < num_slaves; n++) { |
|
111 + matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); |
|
112 status = _cairo_surface_wrapper_mask (&slaves[n], |
|
113 - op, source, mask, clip); |
|
114 + op, matched_source, mask, clip); |
|
115 + if (matched_source == &temp.base) { |
|
116 + _cairo_pattern_fini (&temp.base); |
|
117 + } |
|
118 if (unlikely (status)) |
|
119 return status; |
|
120 } |
|
121 |
|
122 return CAIRO_STATUS_SUCCESS; |
|
123 } |
|
124 |
|
125 static cairo_int_status_t |
|
126 @@ -257,35 +304,45 @@ _cairo_tee_surface_stroke (void *abst |
|
127 double tolerance, |
|
128 cairo_antialias_t antialias, |
|
129 cairo_clip_t *clip) |
|
130 { |
|
131 cairo_tee_surface_t *surface = abstract_surface; |
|
132 cairo_surface_wrapper_t *slaves; |
|
133 int n, num_slaves; |
|
134 cairo_status_t status; |
|
135 + const cairo_pattern_t *matched_source; |
|
136 + cairo_surface_pattern_t temp; |
|
137 |
|
138 + matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); |
|
139 status = _cairo_surface_wrapper_stroke (&surface->master, |
|
140 - op, source, |
|
141 + op, matched_source, |
|
142 path, style, |
|
143 ctm, ctm_inverse, |
|
144 tolerance, antialias, |
|
145 clip); |
|
146 + if (matched_source == &temp.base) { |
|
147 + _cairo_pattern_fini (&temp.base); |
|
148 + } |
|
149 if (unlikely (status)) |
|
150 return status; |
|
151 |
|
152 num_slaves = _cairo_array_num_elements (&surface->slaves); |
|
153 slaves = _cairo_array_index (&surface->slaves, 0); |
|
154 for (n = 0; n < num_slaves; n++) { |
|
155 + matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); |
|
156 status = _cairo_surface_wrapper_stroke (&slaves[n], |
|
157 - op, source, |
|
158 + op, matched_source, |
|
159 path, style, |
|
160 ctm, ctm_inverse, |
|
161 tolerance, antialias, |
|
162 clip); |
|
163 + if (matched_source == &temp.base) { |
|
164 + _cairo_pattern_fini (&temp.base); |
|
165 + } |
|
166 if (unlikely (status)) |
|
167 return status; |
|
168 } |
|
169 |
|
170 return CAIRO_STATUS_SUCCESS; |
|
171 } |
|
172 |
|
173 static cairo_int_status_t |
|
174 @@ -297,33 +354,43 @@ _cairo_tee_surface_fill (void *abstra |
|
175 double tolerance, |
|
176 cairo_antialias_t antialias, |
|
177 cairo_clip_t *clip) |
|
178 { |
|
179 cairo_tee_surface_t *surface = abstract_surface; |
|
180 cairo_surface_wrapper_t *slaves; |
|
181 int n, num_slaves; |
|
182 cairo_status_t status; |
|
183 + const cairo_pattern_t *matched_source; |
|
184 + cairo_surface_pattern_t temp; |
|
185 |
|
186 + matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); |
|
187 status = _cairo_surface_wrapper_fill (&surface->master, |
|
188 - op, source, |
|
189 + op, matched_source, |
|
190 path, fill_rule, |
|
191 tolerance, antialias, |
|
192 clip); |
|
193 + if (matched_source == &temp.base) { |
|
194 + _cairo_pattern_fini (&temp.base); |
|
195 + } |
|
196 if (unlikely (status)) |
|
197 return status; |
|
198 |
|
199 num_slaves = _cairo_array_num_elements (&surface->slaves); |
|
200 slaves = _cairo_array_index (&surface->slaves, 0); |
|
201 for (n = 0; n < num_slaves; n++) { |
|
202 + matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); |
|
203 status = _cairo_surface_wrapper_fill (&slaves[n], |
|
204 - op, source, |
|
205 + op, matched_source, |
|
206 path, fill_rule, |
|
207 tolerance, antialias, |
|
208 clip); |
|
209 + if (matched_source == &temp.base) { |
|
210 + _cairo_pattern_fini (&temp.base); |
|
211 + } |
|
212 if (unlikely (status)) |
|
213 return status; |
|
214 } |
|
215 |
|
216 return CAIRO_STATUS_SUCCESS; |
|
217 } |
|
218 |
|
219 static cairo_bool_t |
|
220 @@ -346,46 +413,56 @@ _cairo_tee_surface_show_text_glyphs (voi |
|
221 cairo_scaled_font_t *scaled_font, |
|
222 cairo_clip_t *clip) |
|
223 { |
|
224 cairo_tee_surface_t *surface = abstract_surface; |
|
225 cairo_surface_wrapper_t *slaves; |
|
226 int n, num_slaves; |
|
227 cairo_status_t status; |
|
228 cairo_glyph_t *glyphs_copy; |
|
229 + const cairo_pattern_t *matched_source; |
|
230 + cairo_surface_pattern_t temp; |
|
231 |
|
232 /* XXX: This copying is ugly. */ |
|
233 glyphs_copy = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); |
|
234 if (unlikely (glyphs_copy == NULL)) |
|
235 return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
|
236 |
|
237 memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); |
|
238 + matched_source = _cairo_tee_surface_match_source (surface, source, 0, &surface->master, &temp); |
|
239 status = _cairo_surface_wrapper_show_text_glyphs (&surface->master, op, |
|
240 - source, |
|
241 + matched_source, |
|
242 utf8, utf8_len, |
|
243 glyphs_copy, num_glyphs, |
|
244 clusters, num_clusters, |
|
245 cluster_flags, |
|
246 scaled_font, |
|
247 clip); |
|
248 + if (matched_source == &temp.base) { |
|
249 + _cairo_pattern_fini (&temp.base); |
|
250 + } |
|
251 if (unlikely (status)) |
|
252 goto CLEANUP; |
|
253 |
|
254 num_slaves = _cairo_array_num_elements (&surface->slaves); |
|
255 slaves = _cairo_array_index (&surface->slaves, 0); |
|
256 for (n = 0; n < num_slaves; n++) { |
|
257 memcpy (glyphs_copy, glyphs, sizeof (cairo_glyph_t) * num_glyphs); |
|
258 + matched_source = _cairo_tee_surface_match_source (surface, source, n + 1, &slaves[n], &temp); |
|
259 status = _cairo_surface_wrapper_show_text_glyphs (&slaves[n], op, |
|
260 - source, |
|
261 + matched_source, |
|
262 utf8, utf8_len, |
|
263 glyphs_copy, num_glyphs, |
|
264 clusters, num_clusters, |
|
265 cluster_flags, |
|
266 scaled_font, |
|
267 clip); |
|
268 + if (matched_source == &temp.base) { |
|
269 + _cairo_pattern_fini (&temp.base); |
|
270 + } |
|
271 if (unlikely (status)) |
|
272 goto CLEANUP; |
|
273 } |
|
274 |
|
275 CLEANUP: |
|
276 free (glyphs_copy); |
|
277 return status; |
|
278 } |