Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1892 | Rev 3959 | ||
---|---|---|---|
Line 35... | Line 35... | ||
35 | * Chris Wilson |
35 | * Chris Wilson |
36 | */ |
36 | */ |
Line 37... | Line 37... | ||
37 | 37 | ||
Line -... | Line 38... | ||
- | 38 | #include "cairoint.h" |
|
38 | #include "cairoint.h" |
39 | |
- | 40 | #include "cairo-clip-inline.h" |
|
39 | 41 | #include "cairo-error-private.h" |
|
Line 40... | Line 42... | ||
40 | #include "cairo-error-private.h" |
42 | #include "cairo-pattern-private.h" |
Line 41... | Line 43... | ||
41 | #include "cairo-surface-wrapper-private.h" |
43 | #include "cairo-surface-wrapper-private.h" |
Line 47... | Line 49... | ||
47 | const cairo_pattern_t *original, |
49 | const cairo_pattern_t *original, |
48 | const cairo_matrix_t *ctm_inverse) |
50 | const cairo_matrix_t *ctm_inverse) |
49 | { |
51 | { |
50 | _cairo_pattern_init_static_copy (pattern, original); |
52 | _cairo_pattern_init_static_copy (pattern, original); |
Line 51... | Line -... | ||
51 | - | ||
52 | /* apply device_transform first so that it is transformed by ctm_inverse */ |
- | |
53 | if (original->type == CAIRO_PATTERN_TYPE_SURFACE) { |
- | |
54 | cairo_surface_pattern_t *surface_pattern; |
- | |
55 | cairo_surface_t *surface; |
- | |
56 | - | ||
57 | surface_pattern = (cairo_surface_pattern_t *) original; |
- | |
58 | surface = surface_pattern->surface; |
- | |
59 | - | ||
60 | if (_cairo_surface_has_device_transform (surface)) |
- | |
61 | _cairo_pattern_transform (pattern, &surface->device_transform); |
- | |
62 | } |
- | |
63 | 53 | ||
64 | if (! _cairo_matrix_is_identity (ctm_inverse)) |
54 | if (! _cairo_matrix_is_identity (ctm_inverse)) |
65 | _cairo_pattern_transform (pattern, ctm_inverse); |
55 | _cairo_pattern_transform (pattern, ctm_inverse); |
Line 66... | Line -... | ||
66 | } |
- | |
67 | - | ||
68 | static inline cairo_bool_t |
- | |
69 | _cairo_surface_wrapper_needs_device_transform (cairo_surface_wrapper_t *wrapper) |
- | |
70 | { |
- | |
71 | return ! _cairo_matrix_is_identity (&wrapper->target->device_transform); |
- | |
72 | } |
- | |
73 | - | ||
74 | static cairo_bool_t |
- | |
75 | _cairo_surface_wrapper_needs_extents_transform (cairo_surface_wrapper_t *wrapper) |
- | |
76 | { |
- | |
77 | return wrapper->has_extents && (wrapper->extents.x | wrapper->extents.y); |
- | |
78 | } |
56 | } |
79 | 57 | ||
80 | cairo_status_t |
58 | cairo_status_t |
81 | _cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper, |
59 | _cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper, |
82 | cairo_image_surface_t **image_out, |
60 | cairo_image_surface_t **image_out, |
Line 95... | Line 73... | ||
95 | void *image_extra) |
73 | void *image_extra) |
96 | { |
74 | { |
97 | _cairo_surface_release_source_image (wrapper->target, image, image_extra); |
75 | _cairo_surface_release_source_image (wrapper->target, image, image_extra); |
98 | } |
76 | } |
Line 99... | Line 77... | ||
99 | 77 | ||
100 | cairo_status_t |
78 | static void |
101 | _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper, |
79 | _cairo_surface_wrapper_get_transform (cairo_surface_wrapper_t *wrapper, |
102 | cairo_operator_t op, |
- | |
103 | const cairo_pattern_t *source, |
- | |
104 | cairo_clip_t *clip) |
80 | cairo_matrix_t *m) |
105 | { |
- | |
106 | cairo_status_t status; |
- | |
107 | cairo_clip_t clip_copy, *dev_clip = clip; |
81 | { |
108 | cairo_pattern_union_t source_copy; |
- | |
Line 109... | Line 82... | ||
109 | cairo_clip_t target_clip; |
82 | cairo_matrix_init_identity (m); |
110 | 83 | ||
Line 111... | Line -... | ||
111 | if (unlikely (wrapper->target->status)) |
- | |
112 | return wrapper->target->status; |
84 | if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y)) |
113 | 85 | cairo_matrix_translate (m, -wrapper->extents.x, -wrapper->extents.y); |
|
114 | if (wrapper->has_extents) { |
- | |
115 | _cairo_clip_init_copy (&target_clip, clip); |
- | |
Line -... | Line 86... | ||
- | 86 | ||
116 | status = _cairo_clip_rectangle (&target_clip, &wrapper->extents); |
87 | if (! _cairo_matrix_is_identity (&wrapper->transform)) |
117 | if (unlikely (status)) |
88 | cairo_matrix_multiply (m, &wrapper->transform, m); |
Line -... | Line 89... | ||
- | 89 | ||
- | 90 | if (! _cairo_matrix_is_identity (&wrapper->target->device_transform)) |
|
- | 91 | cairo_matrix_multiply (m, &wrapper->target->device_transform, m); |
|
- | 92 | } |
|
118 | goto FINISH; |
93 | |
- | 94 | static void |
|
- | 95 | _cairo_surface_wrapper_get_inverse_transform (cairo_surface_wrapper_t *wrapper, |
|
- | 96 | cairo_matrix_t *m) |
|
- | 97 | { |
|
- | 98 | cairo_matrix_init_identity (m); |
|
- | 99 | ||
- | 100 | if (! _cairo_matrix_is_identity (&wrapper->target->device_transform_inverse)) |
|
- | 101 | cairo_matrix_multiply (m, &wrapper->target->device_transform_inverse, m); |
|
- | 102 | ||
- | 103 | if (! _cairo_matrix_is_identity (&wrapper->transform)) { |
|
119 | 104 | cairo_matrix_t inv; |
|
120 | dev_clip = clip = &target_clip; |
105 | cairo_status_t status; |
121 | } |
106 | |
Line 122... | Line 107... | ||
122 | 107 | inv = wrapper->transform; |
|
- | 108 | status = cairo_matrix_invert (&inv); |
|
- | 109 | assert (status == CAIRO_STATUS_SUCCESS); |
|
- | 110 | cairo_matrix_multiply (m, &inv, m); |
|
- | 111 | } |
|
123 | if (clip && clip->all_clipped) { |
112 | |
- | 113 | if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y)) |
|
124 | status = CAIRO_STATUS_SUCCESS; |
114 | cairo_matrix_translate (m, wrapper->extents.x, wrapper->extents.y); |
125 | goto FINISH; |
115 | } |
- | 116 | ||
- | 117 | static cairo_clip_t * |
|
- | 118 | _cairo_surface_wrapper_get_clip (cairo_surface_wrapper_t *wrapper, |
|
- | 119 | const cairo_clip_t *clip) |
|
- | 120 | { |
|
- | 121 | cairo_clip_t *copy; |
|
- | 122 | ||
- | 123 | copy = _cairo_clip_copy (clip); |
|
- | 124 | if (wrapper->has_extents) { |
|
- | 125 | copy = _cairo_clip_intersect_rectangle (copy, &wrapper->extents); |
|
Line 126... | Line 126... | ||
126 | } |
126 | } |
- | 127 | copy = _cairo_clip_transform (copy, &wrapper->transform); |
|
Line -... | Line 128... | ||
- | 128 | if (! _cairo_matrix_is_identity (&wrapper->target->device_transform)) |
|
127 | 129 | copy = _cairo_clip_transform (copy, &wrapper->target->device_transform); |
|
- | 130 | if (wrapper->clip) |
|
- | 131 | copy = _cairo_clip_intersect_clip (copy, wrapper->clip); |
|
- | 132 | ||
- | 133 | return copy; |
|
- | 134 | } |
|
- | 135 | ||
128 | if (_cairo_surface_wrapper_needs_device_transform (wrapper) || |
136 | cairo_status_t |
Line 129... | Line 137... | ||
129 | _cairo_surface_wrapper_needs_extents_transform (wrapper)) |
137 | _cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper, |
130 | { |
138 | cairo_operator_t op, |
Line 131... | Line -... | ||
131 | cairo_matrix_t m; |
- | |
132 | 139 | const cairo_pattern_t *source, |
|
133 | cairo_matrix_init_identity (&m); |
140 | const cairo_clip_t *clip) |
134 | 141 | { |
|
Line -... | Line 142... | ||
- | 142 | cairo_status_t status; |
|
135 | if (_cairo_surface_wrapper_needs_extents_transform (wrapper)) |
143 | cairo_clip_t *dev_clip; |
136 | cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y); |
144 | cairo_pattern_union_t source_copy; |
- | 145 | ||
Line 137... | Line 146... | ||
137 | 146 | if (unlikely (wrapper->target->status)) |
|
138 | if (_cairo_surface_wrapper_needs_device_transform (wrapper)) |
147 | return wrapper->target->status; |
Line 139... | Line 148... | ||
139 | cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m); |
148 | |
140 | 149 | dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); |
|
141 | if (clip != NULL) { |
150 | if (_cairo_clip_is_all_clipped (dev_clip)) |
Line 142... | Line 151... | ||
142 | status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m); |
151 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
Line 143... | Line -... | ||
143 | if (unlikely (status)) |
- | |
144 | goto FINISH; |
- | |
145 | - | ||
146 | dev_clip = &clip_copy; |
- | |
147 | } |
152 | |
148 | 153 | if (wrapper->needs_transform) { |
|
149 | status = cairo_matrix_invert (&m); |
154 | cairo_matrix_t m; |
Line -... | Line 155... | ||
- | 155 | ||
150 | assert (status == CAIRO_STATUS_SUCCESS); |
156 | _cairo_surface_wrapper_get_transform (wrapper, &m); |
151 | 157 | ||
152 | _copy_transformed_pattern (&source_copy.base, source, &m); |
158 | status = cairo_matrix_invert (&m); |
153 | source = &source_copy.base; |
159 | assert (status == CAIRO_STATUS_SUCCESS); |
154 | } |
160 | |
155 | 161 | _copy_transformed_pattern (&source_copy.base, source, &m); |
|
156 | status = _cairo_surface_paint (wrapper->target, op, source, dev_clip); |
162 | source = &source_copy.base; |
157 | 163 | } |
|
158 | FINISH: |
164 | |
159 | if (wrapper->has_extents) |
165 | status = _cairo_surface_paint (wrapper->target, op, source, dev_clip); |
160 | _cairo_clip_reset (&target_clip); |
166 | |
161 | if (dev_clip != clip) |
- | |
Line 162... | Line 167... | ||
162 | _cairo_clip_reset (dev_clip); |
167 | _cairo_clip_destroy (dev_clip); |
163 | return status; |
168 | return status; |
Line 164... | Line -... | ||
164 | } |
- | |
165 | 169 | } |
|
166 | cairo_status_t |
170 | |
167 | _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper, |
- | |
168 | cairo_operator_t op, |
171 | |
Line 169... | Line -... | ||
169 | const cairo_pattern_t *source, |
- | |
170 | const cairo_pattern_t *mask, |
- | |
171 | cairo_clip_t *clip) |
- | |
172 | { |
172 | cairo_status_t |
173 | cairo_status_t status; |
- | |
174 | cairo_clip_t clip_copy, *dev_clip = clip; |
- | |
175 | cairo_pattern_union_t source_copy; |
- | |
176 | cairo_pattern_union_t mask_copy; |
- | |
177 | cairo_clip_t target_clip; |
- | |
178 | - | ||
179 | if (unlikely (wrapper->target->status)) |
- | |
180 | return wrapper->target->status; |
173 | _cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper, |
Line 181... | Line -... | ||
181 | - | ||
182 | if (wrapper->has_extents) { |
- | |
183 | _cairo_clip_init_copy (&target_clip, clip); |
174 | cairo_operator_t op, |
184 | status = _cairo_clip_rectangle (&target_clip, &wrapper->extents); |
- | |
185 | if (unlikely (status)) |
- | |
186 | goto FINISH; |
- | |
187 | - | ||
188 | dev_clip = clip = &target_clip; |
- | |
189 | } |
- | |
190 | - | ||
191 | if (clip && clip->all_clipped) { |
- | |
192 | status = CAIRO_STATUS_SUCCESS; |
- | |
193 | goto FINISH; |
- | |
194 | } |
- | |
195 | - | ||
Line 196... | Line 175... | ||
196 | if (_cairo_surface_wrapper_needs_device_transform (wrapper) || |
175 | const cairo_pattern_t *source, |
197 | _cairo_surface_wrapper_needs_extents_transform (wrapper)) |
176 | const cairo_pattern_t *mask, |
Line 198... | Line 177... | ||
198 | { |
177 | const cairo_clip_t *clip) |
Line 224... | Line 203... | ||
224 | mask = &mask_copy.base; |
203 | mask = &mask_copy.base; |
225 | } |
204 | } |
Line 226... | Line 205... | ||
226 | 205 | ||
Line 227... | Line -... | ||
227 | status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip); |
- | |
228 | - | ||
229 | FINISH: |
- | |
230 | if (wrapper->has_extents) |
- | |
231 | _cairo_clip_reset (&target_clip); |
206 | status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip); |
232 | if (dev_clip != clip) |
207 | |
233 | _cairo_clip_reset (dev_clip); |
208 | _cairo_clip_destroy (dev_clip); |
Line 234... | Line 209... | ||
234 | return status; |
209 | return status; |
235 | } |
210 | } |
236 | 211 | ||
237 | cairo_status_t |
212 | cairo_status_t |
238 | _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper, |
213 | _cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper, |
239 | cairo_operator_t op, |
214 | cairo_operator_t op, |
240 | const cairo_pattern_t *source, |
215 | const cairo_pattern_t *source, |
241 | cairo_path_fixed_t *path, |
216 | const cairo_path_fixed_t *path, |
242 | const cairo_stroke_style_t *stroke_style, |
217 | const cairo_stroke_style_t *stroke_style, |
243 | const cairo_matrix_t *ctm, |
218 | const cairo_matrix_t *ctm, |
244 | const cairo_matrix_t *ctm_inverse, |
219 | const cairo_matrix_t *ctm_inverse, |
245 | double tolerance, |
220 | double tolerance, |
246 | cairo_antialias_t antialias, |
221 | cairo_antialias_t antialias, |
247 | cairo_clip_t *clip) |
222 | const cairo_clip_t *clip) |
248 | { |
223 | { |
249 | cairo_status_t status; |
224 | cairo_status_t status; |
250 | cairo_path_fixed_t path_copy, *dev_path = path; |
225 | cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path; |
251 | cairo_clip_t clip_copy, *dev_clip = clip; |
226 | cairo_clip_t *dev_clip; |
252 | cairo_matrix_t dev_ctm = *ctm; |
- | |
Line 253... | Line 227... | ||
253 | cairo_matrix_t dev_ctm_inverse = *ctm_inverse; |
227 | cairo_matrix_t dev_ctm = *ctm; |
254 | cairo_pattern_union_t source_copy; |
228 | cairo_matrix_t dev_ctm_inverse = *ctm_inverse; |
Line 255... | Line -... | ||
255 | cairo_clip_t target_clip; |
- | |
256 | - | ||
257 | if (unlikely (wrapper->target->status)) |
229 | cairo_pattern_union_t source_copy; |
258 | return wrapper->target->status; |
- | |
259 | - | ||
260 | if (wrapper->has_extents) { |
- | |
261 | _cairo_clip_init_copy (&target_clip, clip); |
- | |
262 | status = _cairo_clip_rectangle (&target_clip, &wrapper->extents); |
- | |
263 | if (unlikely (status)) |
- | |
264 | goto FINISH; |
230 | |
265 | 231 | if (unlikely (wrapper->target->status)) |
|
266 | dev_clip = clip = &target_clip; |
- | |
267 | } |
- | |
Line 268... | Line 232... | ||
268 | 232 | return wrapper->target->status; |
|
269 | if (clip && clip->all_clipped) { |
- | |
270 | status = CAIRO_STATUS_SUCCESS; |
- | |
271 | goto FINISH; |
233 | |
Line 272... | Line -... | ||
272 | } |
- | |
273 | - | ||
274 | if (_cairo_surface_wrapper_needs_device_transform (wrapper) || |
234 | dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); |
275 | _cairo_surface_wrapper_needs_extents_transform (wrapper)) |
- | |
276 | { |
- | |
277 | cairo_matrix_t m; |
- | |
278 | - | ||
Line 279... | Line 235... | ||
279 | cairo_matrix_init_identity (&m); |
235 | if (_cairo_clip_is_all_clipped (dev_clip)) |
280 | 236 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
281 | if (_cairo_surface_wrapper_needs_extents_transform (wrapper)) |
237 | |
Line 282... | Line 238... | ||
282 | cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y); |
238 | if (wrapper->needs_transform) { |
283 | 239 | cairo_matrix_t m; |
|
Line 284... | Line -... | ||
284 | if (_cairo_surface_wrapper_needs_device_transform (wrapper)) |
- | |
285 | cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m); |
- | |
286 | - | ||
287 | status = _cairo_path_fixed_init_copy (&path_copy, dev_path); |
- | |
288 | if (unlikely (status)) |
- | |
289 | goto FINISH; |
- | |
290 | - | ||
291 | _cairo_path_fixed_transform (&path_copy, &m); |
- | |
292 | dev_path = &path_copy; |
240 | |
Line 293... | Line 241... | ||
293 | 241 | _cairo_surface_wrapper_get_transform (wrapper, &m); |
|
294 | if (clip != NULL) { |
242 | |
Line 295... | Line 243... | ||
295 | status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m); |
243 | status = _cairo_path_fixed_init_copy (&path_copy, dev_path); |
Line 296... | Line 244... | ||
296 | if (unlikely (status)) |
244 | if (unlikely (status)) |
297 | goto FINISH; |
245 | goto FINISH; |
298 | 246 | ||
299 | dev_clip = &clip_copy; |
- | |
300 | } |
- | |
301 | - | ||
302 | cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m); |
- | |
303 | - | ||
304 | status = cairo_matrix_invert (&m); |
- | |
305 | assert (status == CAIRO_STATUS_SUCCESS); |
- | |
Line 306... | Line 247... | ||
306 | 247 | _cairo_path_fixed_transform (&path_copy, &m); |
|
307 | cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse); |
248 | dev_path = &path_copy; |
308 | 249 | ||
309 | _copy_transformed_pattern (&source_copy.base, source, &m); |
250 | cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m); |
310 | source = &source_copy.base; |
251 | |
Line 311... | Line 252... | ||
311 | } |
252 | status = cairo_matrix_invert (&m); |
312 | else |
253 | assert (status == CAIRO_STATUS_SUCCESS); |
313 | { |
254 | |
314 | if (clip != NULL) { |
- | |
315 | dev_clip = &clip_copy; |
- | |
316 | _cairo_clip_init_copy (&clip_copy, clip); |
- | |
317 | } |
255 | cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse); |
318 | } |
256 | |
319 | 257 | _copy_transformed_pattern (&source_copy.base, source, &m); |
|
Line 320... | Line 258... | ||
320 | status = _cairo_surface_stroke (wrapper->target, op, source, |
258 | source = &source_copy.base; |
321 | dev_path, stroke_style, |
259 | } |
322 | &dev_ctm, &dev_ctm_inverse, |
260 | |
323 | tolerance, antialias, |
261 | status = _cairo_surface_stroke (wrapper->target, op, source, |
324 | dev_clip); |
262 | dev_path, stroke_style, |
325 | 263 | &dev_ctm, &dev_ctm_inverse, |
|
326 | FINISH: |
264 | tolerance, antialias, |
327 | if (dev_path != path) |
265 | dev_clip); |
328 | _cairo_path_fixed_fini (dev_path); |
266 | |
329 | if (wrapper->has_extents) |
267 | FINISH: |
330 | _cairo_clip_reset (&target_clip); |
268 | if (dev_path != path) |
331 | if (dev_clip != clip) |
269 | _cairo_path_fixed_fini (dev_path); |
332 | _cairo_clip_reset (dev_clip); |
270 | _cairo_clip_destroy (dev_clip); |
333 | return status; |
271 | return status; |
334 | } |
272 | } |
335 | 273 | ||
336 | cairo_status_t |
274 | cairo_status_t |
337 | _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper, |
275 | _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper, |
338 | cairo_operator_t fill_op, |
276 | cairo_operator_t fill_op, |
339 | const cairo_pattern_t *fill_source, |
- | |
340 | cairo_fill_rule_t fill_rule, |
277 | const cairo_pattern_t *fill_source, |
341 | double fill_tolerance, |
278 | cairo_fill_rule_t fill_rule, |
- | 279 | double fill_tolerance, |
|
342 | cairo_antialias_t fill_antialias, |
280 | cairo_antialias_t fill_antialias, |
343 | cairo_path_fixed_t *path, |
281 | const cairo_path_fixed_t*path, |
344 | cairo_operator_t stroke_op, |
- | |
Line 345... | Line 282... | ||
345 | const cairo_pattern_t *stroke_source, |
282 | cairo_operator_t stroke_op, |
346 | const cairo_stroke_style_t *stroke_style, |
283 | const cairo_pattern_t *stroke_source, |
Line 347... | Line -... | ||
347 | const cairo_matrix_t *stroke_ctm, |
- | |
348 | const cairo_matrix_t *stroke_ctm_inverse, |
284 | const cairo_stroke_style_t *stroke_style, |
349 | double stroke_tolerance, |
285 | const cairo_matrix_t *stroke_ctm, |
350 | cairo_antialias_t stroke_antialias, |
- | |
351 | cairo_clip_t *clip) |
286 | const cairo_matrix_t *stroke_ctm_inverse, |
Line 352... | Line -... | ||
352 | { |
- | |
353 | cairo_status_t status; |
- | |
354 | cairo_path_fixed_t path_copy, *dev_path = path; |
- | |
355 | cairo_clip_t clip_copy, *dev_clip = clip; |
287 | double stroke_tolerance, |
356 | cairo_matrix_t dev_ctm = *stroke_ctm; |
- | |
357 | cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse; |
- | |
358 | cairo_pattern_union_t stroke_source_copy; |
- | |
359 | cairo_pattern_union_t fill_source_copy; |
- | |
360 | cairo_clip_t target_clip; |
- | |
361 | - | ||
362 | if (unlikely (wrapper->target->status)) |
- | |
363 | return wrapper->target->status; |
288 | cairo_antialias_t stroke_antialias, |
Line 364... | Line -... | ||
364 | - | ||
365 | if (wrapper->has_extents) { |
- | |
366 | _cairo_clip_init_copy (&target_clip, clip); |
289 | const cairo_clip_t *clip) |
367 | status = _cairo_clip_rectangle (&target_clip, &wrapper->extents); |
- | |
368 | if (unlikely (status)) |
- | |
369 | goto FINISH; |
- | |
370 | - | ||
Line 371... | Line 290... | ||
371 | dev_clip = clip = &target_clip; |
290 | { |
372 | } |
291 | cairo_status_t status; |
373 | 292 | cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *)path; |
|
Line 374... | Line 293... | ||
374 | if (clip && clip->all_clipped) { |
293 | cairo_matrix_t dev_ctm = *stroke_ctm; |
375 | status = CAIRO_STATUS_SUCCESS; |
294 | cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse; |
Line 376... | Line -... | ||
376 | goto FINISH; |
- | |
377 | } |
- | |
378 | - | ||
379 | if (_cairo_surface_wrapper_needs_device_transform (wrapper) || |
- | |
380 | _cairo_surface_wrapper_needs_extents_transform (wrapper)) |
- | |
381 | { |
- | |
382 | cairo_matrix_t m; |
- | |
383 | - | ||
384 | cairo_matrix_init_identity (&m); |
295 | cairo_clip_t *dev_clip; |
Line 385... | Line 296... | ||
385 | 296 | cairo_pattern_union_t stroke_source_copy; |
|
386 | if (_cairo_surface_wrapper_needs_extents_transform (wrapper)) |
297 | cairo_pattern_union_t fill_source_copy; |
Line 415... | Line 326... | ||
415 | stroke_source = &stroke_source_copy.base; |
326 | stroke_source = &stroke_source_copy.base; |
Line 416... | Line 327... | ||
416 | 327 | ||
417 | _copy_transformed_pattern (&fill_source_copy.base, fill_source, &m); |
328 | _copy_transformed_pattern (&fill_source_copy.base, fill_source, &m); |
418 | fill_source = &fill_source_copy.base; |
329 | fill_source = &fill_source_copy.base; |
419 | } |
- | |
420 | else |
- | |
421 | { |
- | |
422 | if (clip != NULL) { |
- | |
423 | dev_clip = &clip_copy; |
- | |
424 | _cairo_clip_init_copy (&clip_copy, clip); |
- | |
425 | } |
- | |
Line 426... | Line 330... | ||
426 | } |
330 | } |
427 | 331 | ||
428 | status = _cairo_surface_fill_stroke (wrapper->target, |
332 | status = _cairo_surface_fill_stroke (wrapper->target, |
429 | fill_op, fill_source, fill_rule, |
333 | fill_op, fill_source, fill_rule, |
Line 436... | Line 340... | ||
436 | dev_clip); |
340 | dev_clip); |
Line 437... | Line 341... | ||
437 | 341 | ||
438 | FINISH: |
342 | FINISH: |
439 | if (dev_path != path) |
343 | if (dev_path != path) |
440 | _cairo_path_fixed_fini (dev_path); |
- | |
441 | if (wrapper->has_extents) |
- | |
442 | _cairo_clip_reset (&target_clip); |
- | |
443 | if (dev_clip != clip) |
344 | _cairo_path_fixed_fini (dev_path); |
444 | _cairo_clip_reset (dev_clip); |
345 | _cairo_clip_destroy (dev_clip); |
445 | return status; |
346 | return status; |
Line 446... | Line 347... | ||
446 | } |
347 | } |
447 | 348 | ||
448 | cairo_status_t |
349 | cairo_status_t |
449 | _cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper, |
350 | _cairo_surface_wrapper_fill (cairo_surface_wrapper_t *wrapper, |
450 | cairo_operator_t op, |
351 | cairo_operator_t op, |
451 | const cairo_pattern_t *source, |
352 | const cairo_pattern_t *source, |
452 | cairo_path_fixed_t *path, |
353 | const cairo_path_fixed_t *path, |
453 | cairo_fill_rule_t fill_rule, |
354 | cairo_fill_rule_t fill_rule, |
454 | double tolerance, |
355 | double tolerance, |
455 | cairo_antialias_t antialias, |
356 | cairo_antialias_t antialias, |
456 | cairo_clip_t *clip) |
357 | const cairo_clip_t *clip) |
457 | { |
358 | { |
458 | cairo_status_t status; |
- | |
459 | cairo_path_fixed_t path_copy, *dev_path = path; |
359 | cairo_status_t status; |
460 | cairo_clip_t clip_copy, *dev_clip = clip; |
360 | cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path; |
Line 461... | Line 361... | ||
461 | cairo_pattern_union_t source_copy; |
361 | cairo_pattern_union_t source_copy; |
462 | cairo_clip_t target_clip; |
362 | cairo_clip_t *dev_clip; |
Line 463... | Line -... | ||
463 | - | ||
464 | if (unlikely (wrapper->target->status)) |
- | |
465 | return wrapper->target->status; |
363 | |
466 | - | ||
467 | if (wrapper->has_extents) { |
- | |
468 | _cairo_clip_init_copy (&target_clip, clip); |
- | |
469 | status = _cairo_clip_rectangle (&target_clip, &wrapper->extents); |
- | |
470 | if (unlikely (status)) |
- | |
471 | goto FINISH; |
- | |
472 | 364 | if (unlikely (wrapper->target->status)) |
|
473 | dev_clip = clip = &target_clip; |
365 | return wrapper->target->status; |
474 | } |
- | |
475 | - | ||
Line 476... | Line 366... | ||
476 | if (clip && clip->all_clipped) { |
366 | |
477 | status = CAIRO_STATUS_SUCCESS; |
- | |
478 | goto FINISH; |
- | |
479 | } |
367 | dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); |
Line 480... | Line -... | ||
480 | - | ||
481 | if (_cairo_surface_wrapper_needs_device_transform (wrapper) || |
- | |
482 | _cairo_surface_wrapper_needs_extents_transform (wrapper)) |
368 | if (_cairo_clip_is_all_clipped (dev_clip)) |
483 | { |
- | |
484 | cairo_matrix_t m; |
- | |
485 | - | ||
486 | cairo_matrix_init_identity (&m); |
- | |
Line 487... | Line 369... | ||
487 | 369 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
488 | if (_cairo_surface_wrapper_needs_extents_transform (wrapper)) |
370 | |
489 | cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y); |
371 | if (wrapper->needs_transform) { |
Line 490... | Line 372... | ||
490 | 372 | cairo_matrix_t m; |
|
491 | if (_cairo_surface_wrapper_needs_device_transform (wrapper)) |
373 | |
Line 492... | Line -... | ||
492 | cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m); |
- | |
493 | - | ||
494 | status = _cairo_path_fixed_init_copy (&path_copy, dev_path); |
- | |
495 | if (unlikely (status)) |
- | |
496 | goto FINISH; |
- | |
497 | - | ||
498 | _cairo_path_fixed_transform (&path_copy, &m); |
- | |
499 | dev_path = &path_copy; |
- | |
500 | 374 | _cairo_surface_wrapper_get_transform (wrapper, &m); |
|
501 | if (clip != NULL) { |
375 | |
Line 502... | Line 376... | ||
502 | status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m); |
376 | status = _cairo_path_fixed_init_copy (&path_copy, dev_path); |
503 | if (unlikely (status)) |
377 | if (unlikely (status)) |
504 | goto FINISH; |
378 | goto FINISH; |
505 | - | ||
506 | dev_clip = &clip_copy; |
- | |
507 | } |
- | |
508 | - | ||
509 | status = cairo_matrix_invert (&m); |
- | |
510 | assert (status == CAIRO_STATUS_SUCCESS); |
- | |
511 | - | ||
Line 512... | Line 379... | ||
512 | _copy_transformed_pattern (&source_copy.base, source, &m); |
379 | |
513 | source = &source_copy.base; |
380 | _cairo_path_fixed_transform (&path_copy, &m); |
514 | } |
381 | dev_path = &path_copy; |
515 | else |
382 | |
Line 516... | Line 383... | ||
516 | { |
383 | status = cairo_matrix_invert (&m); |
517 | if (clip != NULL) { |
384 | assert (status == CAIRO_STATUS_SUCCESS); |
518 | dev_clip = &clip_copy; |
385 | |
519 | _cairo_clip_init_copy (&clip_copy, clip); |
- | |
520 | } |
- | |
521 | } |
- | |
522 | 386 | _copy_transformed_pattern (&source_copy.base, source, &m); |
|
523 | status = _cairo_surface_fill (wrapper->target, op, source, |
387 | source = &source_copy.base; |
524 | dev_path, fill_rule, |
388 | } |
Line 525... | Line 389... | ||
525 | tolerance, antialias, |
389 | |
526 | dev_clip); |
390 | status = _cairo_surface_fill (wrapper->target, op, source, |
527 | 391 | dev_path, fill_rule, |
|
528 | FINISH: |
392 | tolerance, antialias, |
529 | if (dev_path != path) |
393 | dev_clip); |
530 | _cairo_path_fixed_fini (dev_path); |
394 | |
531 | if (wrapper->has_extents) |
395 | FINISH: |
532 | _cairo_clip_reset (&target_clip); |
396 | if (dev_path != path) |
533 | if (dev_clip != clip) |
397 | _cairo_path_fixed_fini (dev_path); |
534 | _cairo_clip_reset (dev_clip); |
398 | _cairo_clip_destroy (dev_clip); |
535 | return status; |
399 | return status; |
536 | } |
400 | } |
537 | 401 | ||
538 | cairo_status_t |
402 | cairo_status_t |
539 | _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper, |
403 | _cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper, |
540 | cairo_operator_t op, |
404 | cairo_operator_t op, |
- | 405 | const cairo_pattern_t *source, |
|
541 | const cairo_pattern_t *source, |
406 | const char *utf8, |
- | 407 | int utf8_len, |
|
542 | const char *utf8, |
408 | const cairo_glyph_t *glyphs, |
543 | int utf8_len, |
409 | int num_glyphs, |
Line 544... | Line 410... | ||
544 | cairo_glyph_t *glyphs, |
410 | const cairo_text_cluster_t *clusters, |
545 | int num_glyphs, |
411 | int num_clusters, |
Line -... | Line 412... | ||
- | 412 | cairo_text_cluster_flags_t cluster_flags, |
|
546 | const cairo_text_cluster_t *clusters, |
413 | cairo_scaled_font_t *scaled_font, |
547 | int num_clusters, |
414 | const cairo_clip_t *clip) |
Line 548... | Line -... | ||
548 | cairo_text_cluster_flags_t cluster_flags, |
- | |
549 | cairo_scaled_font_t *scaled_font, |
415 | { |
550 | cairo_clip_t *clip) |
416 | cairo_status_t status; |
551 | { |
- | |
552 | cairo_status_t status; |
- | |
553 | cairo_clip_t clip_copy, *dev_clip = clip; |
- | |
554 | cairo_glyph_t *dev_glyphs = glyphs; |
- | |
555 | cairo_pattern_union_t source_copy; |
- | |
Line 556... | Line 417... | ||
556 | cairo_clip_t target_clip; |
417 | cairo_clip_t *dev_clip; |
557 | - | ||
558 | if (unlikely (wrapper->target->status)) |
- | |
559 | return wrapper->target->status; |
- | |
560 | - | ||
561 | if (glyphs == NULL || num_glyphs == 0) |
- | |
562 | return CAIRO_STATUS_SUCCESS; |
- | |
563 | - | ||
564 | if (wrapper->has_extents) { |
418 | cairo_glyph_t stack_glyphs [CAIRO_STACK_ARRAY_LENGTH(cairo_glyph_t)]; |
565 | _cairo_clip_init_copy (&target_clip, clip); |
419 | cairo_glyph_t *dev_glyphs = stack_glyphs; |
Line 566... | Line -... | ||
566 | status = _cairo_clip_rectangle (&target_clip, &wrapper->extents); |
- | |
567 | if (unlikely (status)) |
- | |
568 | goto FINISH; |
420 | cairo_scaled_font_t *dev_scaled_font = scaled_font; |
569 | - | ||
570 | dev_clip = clip = &target_clip; |
- | |
571 | } |
- | |
572 | - | ||
Line 573... | Line -... | ||
573 | if (clip && clip->all_clipped) { |
- | |
574 | status = CAIRO_STATUS_SUCCESS; |
421 | cairo_pattern_union_t source_copy; |
575 | goto FINISH; |
422 | cairo_font_options_t options; |
576 | } |
- | |
Line -... | Line 423... | ||
- | 423 | ||
- | 424 | if (unlikely (wrapper->target->status)) |
|
- | 425 | return wrapper->target->status; |
|
577 | 426 | ||
- | 427 | dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip); |
|
- | 428 | if (_cairo_clip_is_all_clipped (dev_clip)) |
|
- | 429 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
|
578 | if (_cairo_surface_wrapper_needs_device_transform (wrapper) || |
430 | |
Line -... | Line 431... | ||
- | 431 | cairo_surface_get_font_options (wrapper->target, &options); |
|
579 | _cairo_surface_wrapper_needs_extents_transform (wrapper)) |
432 | cairo_font_options_merge (&options, &scaled_font->options); |
580 | { |
433 | |
581 | cairo_matrix_t m; |
434 | if (wrapper->needs_transform) { |
582 | int i; |
435 | cairo_matrix_t m; |
583 | 436 | int i; |
|
- | 437 | ||
Line 584... | Line 438... | ||
584 | cairo_matrix_init_identity (&m); |
438 | _cairo_surface_wrapper_get_transform (wrapper, &m); |
585 | 439 | ||
586 | if (_cairo_surface_wrapper_needs_extents_transform (wrapper)) |
440 | if (! _cairo_matrix_is_translation (&wrapper->transform)) { |
- | 441 | cairo_matrix_t ctm; |
|
- | 442 | ||
587 | cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y); |
443 | /* XXX No device-transform? A bug in the tangle of layers? */ |
Line 588... | Line 444... | ||
588 | 444 | _cairo_matrix_multiply (&ctm, |
|
589 | if (_cairo_surface_wrapper_needs_device_transform (wrapper)) |
445 | &wrapper->transform, |
Line 590... | Line 446... | ||
590 | cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m); |
446 | &scaled_font->ctm); |
591 | 447 | dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face, |
|
- | 448 | &scaled_font->font_matrix, |
|
- | 449 | &ctm, &options); |
|
- | 450 | } |
|
- | 451 | ||
- | 452 | if (num_glyphs > ARRAY_LENGTH (stack_glyphs)) { |
|
- | 453 | dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); |
|
- | 454 | if (unlikely (dev_glyphs == NULL)) { |
|
- | 455 | status = _cairo_error (CAIRO_STATUS_NO_MEMORY); |
|
- | 456 | goto FINISH; |
|
- | 457 | } |
|
- | 458 | } |
|
- | 459 | ||
- | 460 | for (i = 0; i < num_glyphs; i++) { |
|
- | 461 | dev_glyphs[i] = glyphs[i]; |
|
- | 462 | cairo_matrix_transform_point (&m, |
|
- | 463 | &dev_glyphs[i].x, |
|
- | 464 | &dev_glyphs[i].y); |
|
592 | if (clip != NULL) { |
465 | } |
593 | status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m); |
- | |
594 | if (unlikely (status)) |
- | |
595 | goto FINISH; |
- | |
596 | - | ||
597 | dev_clip = &clip_copy; |
- | |
598 | } |
466 | |
- | 467 | status = cairo_matrix_invert (&m); |
|
- | 468 | assert (status == CAIRO_STATUS_SUCCESS); |
|
599 | 469 | ||
Line 600... | Line 470... | ||
600 | dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); |
470 | _copy_transformed_pattern (&source_copy.base, source, &m); |
601 | if (dev_glyphs == NULL) { |
471 | source = &source_copy.base; |
602 | status = _cairo_error (CAIRO_STATUS_NO_MEMORY); |
472 | } else { |
603 | goto FINISH; |
473 | if (! cairo_font_options_equal (&options, &scaled_font->options)) { |
604 | } |
474 | dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face, |
605 | 475 | &scaled_font->font_matrix, |
|
606 | for (i = 0; i < num_glyphs; i++) { |
476 | &scaled_font->ctm, |
607 | dev_glyphs[i] = glyphs[i]; |
- | |
608 | cairo_matrix_transform_point (&m, &dev_glyphs[i].x, &dev_glyphs[i].y); |
477 | &options); |
609 | } |
- | |
610 | 478 | } |
|
611 | status = cairo_matrix_invert (&m); |
- | |
612 | assert (status == CAIRO_STATUS_SUCCESS); |
- | |
613 | 479 | ||
614 | _copy_transformed_pattern (&source_copy.base, source, &m); |
480 | /* show_text_glyphs is special because _cairo_surface_show_text_glyphs is allowed |
- | 481 | * to modify the glyph array that's passed in. We must always |
|
- | 482 | * copy the array before handing it to the backend. |
|
615 | source = &source_copy.base; |
483 | */ |
616 | } |
484 | if (num_glyphs > ARRAY_LENGTH (stack_glyphs)) { |
Line 617... | Line 485... | ||
617 | else |
485 | dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t)); |
618 | { |
486 | if (unlikely (dev_glyphs == NULL)) { |
Line 664... | Line 532... | ||
664 | } else { |
532 | } else { |
665 | return _cairo_surface_get_extents (wrapper->target, extents); |
533 | return _cairo_surface_get_extents (wrapper->target, extents); |
666 | } |
534 | } |
667 | } |
535 | } |
Line -... | Line 536... | ||
- | 536 | ||
- | 537 | static cairo_bool_t |
|
- | 538 | _cairo_surface_wrapper_needs_device_transform (cairo_surface_wrapper_t *wrapper) |
|
- | 539 | { |
|
- | 540 | return |
|
- | 541 | (wrapper->has_extents && (wrapper->extents.x | wrapper->extents.y)) || |
|
- | 542 | ! _cairo_matrix_is_identity (&wrapper->transform) || |
|
- | 543 | ! _cairo_matrix_is_identity (&wrapper->target->device_transform); |
|
- | 544 | } |
|
668 | 545 | ||
669 | void |
546 | void |
670 | _cairo_surface_wrapper_set_extents (cairo_surface_wrapper_t *wrapper, |
547 | _cairo_surface_wrapper_intersect_extents (cairo_surface_wrapper_t *wrapper, |
671 | const cairo_rectangle_int_t *extents) |
548 | const cairo_rectangle_int_t *extents) |
672 | { |
549 | { |
673 | if (extents != NULL) { |
550 | if (! wrapper->has_extents) { |
674 | wrapper->extents = *extents; |
551 | wrapper->extents = *extents; |
- | 552 | wrapper->has_extents = TRUE; |
|
- | 553 | } else |
|
- | 554 | _cairo_rectangle_intersect (&wrapper->extents, extents); |
|
- | 555 | ||
- | 556 | wrapper->needs_transform = |
|
- | 557 | _cairo_surface_wrapper_needs_device_transform (wrapper); |
|
- | 558 | } |
|
- | 559 | ||
- | 560 | void |
|
- | 561 | _cairo_surface_wrapper_set_inverse_transform (cairo_surface_wrapper_t *wrapper, |
|
- | 562 | const cairo_matrix_t *transform) |
|
- | 563 | { |
|
- | 564 | cairo_status_t status; |
|
- | 565 | ||
- | 566 | if (transform == NULL || _cairo_matrix_is_identity (transform)) { |
|
- | 567 | cairo_matrix_init_identity (&wrapper->transform); |
|
- | 568 | ||
- | 569 | wrapper->needs_transform = |
|
675 | wrapper->has_extents = TRUE; |
570 | _cairo_surface_wrapper_needs_device_transform (wrapper); |
- | 571 | } else { |
|
- | 572 | wrapper->transform = *transform; |
|
- | 573 | status = cairo_matrix_invert (&wrapper->transform); |
|
- | 574 | /* should always be invertible unless given pathological input */ |
|
- | 575 | assert (status == CAIRO_STATUS_SUCCESS); |
|
676 | } else { |
576 | |
677 | wrapper->has_extents = FALSE; |
577 | wrapper->needs_transform = TRUE; |
678 | } |
578 | } |
Line 679... | Line 579... | ||
679 | } |
579 | } |
- | 580 | ||
- | 581 | void |
|
- | 582 | _cairo_surface_wrapper_set_clip (cairo_surface_wrapper_t *wrapper, |
|
- | 583 | const cairo_clip_t *clip) |
|
- | 584 | { |
|
- | 585 | wrapper->clip = clip; |
|
- | 586 | } |
|
680 | 587 | ||
681 | void |
588 | void |
682 | _cairo_surface_wrapper_get_font_options (cairo_surface_wrapper_t *wrapper, |
589 | _cairo_surface_wrapper_get_font_options (cairo_surface_wrapper_t *wrapper, |
683 | cairo_font_options_t *options) |
590 | cairo_font_options_t *options) |
684 | { |
591 | { |
Line 685... | Line 592... | ||
685 | cairo_surface_get_font_options (wrapper->target, options); |
592 | cairo_surface_get_font_options (wrapper->target, options); |
686 | } |
593 | } |
687 | 594 | ||
- | 595 | cairo_surface_t * |
|
688 | cairo_surface_t * |
596 | _cairo_surface_wrapper_snapshot (cairo_surface_wrapper_t *wrapper) |
- | 597 | { |
|
- | 598 | if (wrapper->target->backend->snapshot) |
|
689 | _cairo_surface_wrapper_snapshot (cairo_surface_wrapper_t *wrapper) |
599 | return wrapper->target->backend->snapshot (wrapper->target); |
Line 690... | Line 600... | ||
690 | { |
600 | |
691 | return _cairo_surface_snapshot (wrapper->target); |
601 | return NULL; |
692 | } |
602 | } |
Line 700... | Line 610... | ||
700 | void |
610 | void |
701 | _cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper, |
611 | _cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper, |
702 | cairo_surface_t *target) |
612 | cairo_surface_t *target) |
703 | { |
613 | { |
704 | wrapper->target = cairo_surface_reference (target); |
614 | wrapper->target = cairo_surface_reference (target); |
- | 615 | cairo_matrix_init_identity (&wrapper->transform); |
|
705 | wrapper->has_extents = FALSE; |
616 | wrapper->has_extents = FALSE; |
- | 617 | wrapper->extents.x = wrapper->extents.y = 0; |
|
- | 618 | wrapper->clip = NULL; |
|
- | 619 | ||
- | 620 | wrapper->needs_transform = FALSE; |
|
- | 621 | if (target) { |
|
- | 622 | wrapper->needs_transform = |
|
- | 623 | ! _cairo_matrix_is_identity (&target->device_transform); |
|
- | 624 | } |
|
706 | } |
625 | } |
Line 707... | Line 626... | ||
707 | 626 | ||
708 | void |
627 | void |
709 | _cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper) |
628 | _cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper) |
710 | { |
629 | { |
711 | cairo_surface_destroy (wrapper->target); |
630 | cairo_surface_destroy (wrapper->target); |
- | 631 | } |
|
- | 632 | ||
- | 633 | cairo_bool_t |
|
- | 634 | _cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper, |
|
- | 635 | cairo_rectangle_int_t *extents) |
|
- | 636 | { |
|
- | 637 | cairo_rectangle_int_t clip; |
|
- | 638 | cairo_bool_t has_clip; |
|
- | 639 | ||
- | 640 | has_clip = _cairo_surface_get_extents (wrapper->target, &clip); |
|
- | 641 | if (wrapper->clip) { |
|
- | 642 | if (has_clip) { |
|
- | 643 | if (! _cairo_rectangle_intersect (&clip, |
|
- | 644 | _cairo_clip_get_extents (wrapper->clip))) |
|
- | 645 | return FALSE; |
|
- | 646 | } else { |
|
- | 647 | has_clip = TRUE; |
|
- | 648 | clip = *_cairo_clip_get_extents (wrapper->clip); |
|
- | 649 | } |
|
- | 650 | } |
|
- | 651 | ||
- | 652 | if (has_clip && wrapper->needs_transform) { |
|
- | 653 | cairo_matrix_t m; |
|
- | 654 | double x1, y1, x2, y2; |
|
- | 655 | ||
- | 656 | _cairo_surface_wrapper_get_inverse_transform (wrapper, &m); |
|
- | 657 | ||
- | 658 | x1 = clip.x; |
|
- | 659 | y1 = clip.y; |
|
- | 660 | x2 = clip.x + clip.width; |
|
- | 661 | y2 = clip.y + clip.height; |
|
- | 662 | ||
- | 663 | _cairo_matrix_transform_bounding_box (&m, &x1, &y1, &x2, &y2, NULL); |
|
- | 664 | ||
- | 665 | clip.x = floor (x1); |
|
- | 666 | clip.y = floor (y1); |
|
- | 667 | clip.width = ceil (x2) - clip.x; |
|
- | 668 | clip.height = ceil (y2) - clip.y; |
|
- | 669 | } |
|
- | 670 | ||
- | 671 | if (has_clip) { |
|
- | 672 | if (wrapper->has_extents) { |
|
- | 673 | *extents = wrapper->extents; |
|
- | 674 | return _cairo_rectangle_intersect (extents, &clip); |
|
- | 675 | } else { |
|
- | 676 | *extents = clip; |
|
- | 677 | return TRUE; |
|
- | 678 | } |
|
- | 679 | } else if (wrapper->has_extents) { |
|
- | 680 | *extents = wrapper->extents; |
|
- | 681 | return TRUE; |
|
- | 682 | } else { |
|
- | 683 | _cairo_unbounded_rectangle_init (extents); |
|
- | 684 | return TRUE; |
|
- | 685 | } |