/work/workdir/UnpackedTarball/cairo/src/cairo-composite-rectangles.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* cairo - a vector graphics library with display and print output |
2 | | * |
3 | | * Copyright © 2009 Intel Corporation |
4 | | * |
5 | | * This library is free software; you can redistribute it and/or |
6 | | * modify it either under the terms of the GNU Lesser General Public |
7 | | * License version 2.1 as published by the Free Software Foundation |
8 | | * (the "LGPL") or, at your option, under the terms of the Mozilla |
9 | | * Public License Version 1.1 (the "MPL"). If you do not alter this |
10 | | * notice, a recipient may use your version of this file under either |
11 | | * the MPL or the LGPL. |
12 | | * |
13 | | * You should have received a copy of the LGPL along with this library |
14 | | * in the file COPYING-LGPL-2.1; if not, write to the Free Software |
15 | | * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA |
16 | | * You should have received a copy of the MPL along with this library |
17 | | * in the file COPYING-MPL-1.1 |
18 | | * |
19 | | * The contents of this file are subject to the Mozilla Public License |
20 | | * Version 1.1 (the "License"); you may not use this file except in |
21 | | * compliance with the License. You may obtain a copy of the License at |
22 | | * http://www.mozilla.org/MPL/ |
23 | | * |
24 | | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY |
25 | | * OF ANY KIND, either express or implied. See the LGPL or the MPL for |
26 | | * the specific language governing rights and limitations. |
27 | | * |
28 | | * The Original Code is the cairo graphics library. |
29 | | * |
30 | | * The Initial Developer of the Original Code is Red Hat, Inc. |
31 | | * |
32 | | * Contributor(s): |
33 | | * Chris Wilson <chris@chris-wilson.co.uk> |
34 | | */ |
35 | | |
36 | | #include "cairoint.h" |
37 | | |
38 | | #include "cairo-clip-inline.h" |
39 | | #include "cairo-error-private.h" |
40 | | #include "cairo-composite-rectangles-private.h" |
41 | | #include "cairo-pattern-private.h" |
42 | | |
43 | | /* A collection of routines to facilitate writing compositors. */ |
44 | | |
45 | | void _cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents) |
46 | 8.49M | { |
47 | | /* If adding further free() code here, make sure those fields are inited by |
48 | | * _cairo_composite_rectangles_init IN ALL CASES |
49 | | */ |
50 | 8.49M | _cairo_clip_destroy (extents->clip); |
51 | 8.49M | extents->clip = NULL; |
52 | 8.49M | } |
53 | | |
54 | | static void |
55 | | _cairo_composite_reduce_pattern (const cairo_pattern_t *src, |
56 | | cairo_pattern_union_t *dst) |
57 | 8.49M | { |
58 | 8.49M | int tx, ty; |
59 | | |
60 | 8.49M | _cairo_pattern_init_static_copy (&dst->base, src); |
61 | 8.49M | if (dst->base.type == CAIRO_PATTERN_TYPE_SOLID) |
62 | 7.95M | return; |
63 | | |
64 | 543k | dst->base.filter = _cairo_pattern_analyze_filter (&dst->base); |
65 | | |
66 | 543k | tx = ty = 0; |
67 | 543k | if (_cairo_matrix_is_pixman_translation (&dst->base.matrix, |
68 | 543k | dst->base.filter, |
69 | 543k | &tx, &ty)) |
70 | 542k | { |
71 | 542k | dst->base.matrix.x0 = tx; |
72 | 542k | dst->base.matrix.y0 = ty; |
73 | 542k | } |
74 | 543k | } |
75 | | |
76 | | static inline cairo_bool_t |
77 | | _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents, |
78 | | cairo_surface_t *surface, |
79 | | cairo_operator_t op, |
80 | | const cairo_pattern_t *source, |
81 | | const cairo_clip_t *clip) |
82 | 8.49M | { |
83 | | /* Always set the clip so that a _cairo_composite_rectangles_init can ALWAYS be |
84 | | * balanced by a _cairo_composite_rectangles_fini */ |
85 | 8.49M | extents->clip = NULL; |
86 | | |
87 | 8.49M | if (_cairo_clip_is_all_clipped (clip)) |
88 | 0 | return FALSE; |
89 | 8.49M | extents->surface = surface; |
90 | 8.49M | extents->op = op; |
91 | | |
92 | 8.49M | _cairo_surface_get_extents (surface, &extents->destination); |
93 | | |
94 | 8.49M | extents->unbounded = extents->destination; |
95 | 8.49M | if (clip && ! _cairo_rectangle_intersect (&extents->unbounded, |
96 | 327k | _cairo_clip_get_extents (clip))) |
97 | 2.45k | return FALSE; |
98 | | |
99 | 8.49M | extents->bounded = extents->unbounded; |
100 | 8.49M | extents->is_bounded = _cairo_operator_bounded_by_either (op); |
101 | | |
102 | 8.49M | extents->original_source_pattern = source; |
103 | 8.49M | _cairo_composite_reduce_pattern (source, &extents->source_pattern); |
104 | | |
105 | 8.49M | _cairo_pattern_get_extents (&extents->source_pattern.base, |
106 | 8.49M | &extents->source, |
107 | 8.49M | surface->is_vector); |
108 | 8.49M | if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) { |
109 | 8.47M | if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source)) |
110 | 0 | return FALSE; |
111 | 8.47M | } |
112 | | |
113 | 8.49M | extents->original_mask_pattern = NULL; |
114 | 8.49M | extents->mask_pattern.base.type = CAIRO_PATTERN_TYPE_SOLID; |
115 | 8.49M | extents->mask_pattern.solid.color.alpha = 1.; /* XXX full initialisation? */ |
116 | 8.49M | extents->mask_pattern.solid.color.alpha_short = 0xffff; |
117 | | |
118 | 8.49M | return TRUE; |
119 | 8.49M | } |
120 | | |
121 | | cairo_int_status_t |
122 | | _cairo_composite_rectangles_init_for_paint (cairo_composite_rectangles_t *extents, |
123 | | cairo_surface_t *surface, |
124 | | cairo_operator_t op, |
125 | | const cairo_pattern_t *source, |
126 | | const cairo_clip_t *clip) |
127 | 689k | { |
128 | 689k | if (! _cairo_composite_rectangles_init (extents, |
129 | 689k | surface, op, source, clip)) |
130 | 2.24k | { |
131 | 2.24k | goto NOTHING_TO_DO; |
132 | 2.24k | } |
133 | | |
134 | 686k | extents->mask = extents->destination; |
135 | | |
136 | 686k | extents->clip = _cairo_clip_reduce_for_composite (clip, extents); |
137 | 686k | if (_cairo_clip_is_all_clipped (extents->clip)) |
138 | 0 | goto NOTHING_TO_DO; |
139 | | |
140 | 686k | if (! _cairo_rectangle_intersect (&extents->unbounded, |
141 | 686k | _cairo_clip_get_extents (extents->clip))) |
142 | 0 | goto NOTHING_TO_DO; |
143 | | |
144 | 686k | if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) |
145 | 543k | _cairo_pattern_sampled_area (&extents->source_pattern.base, |
146 | 543k | &extents->bounded, |
147 | 543k | &extents->source_sample_area); |
148 | | |
149 | 686k | return CAIRO_INT_STATUS_SUCCESS; |
150 | 2.24k | NOTHING_TO_DO: |
151 | 2.24k | _cairo_composite_rectangles_fini(extents); |
152 | 2.24k | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
153 | 686k | } |
154 | | |
155 | | static cairo_int_status_t |
156 | | _cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents, |
157 | | const cairo_clip_t *clip) |
158 | 7.80M | { |
159 | 7.80M | if ((!_cairo_rectangle_intersect (&extents->bounded, &extents->mask)) && |
160 | 7.80M | (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)) |
161 | 7.21M | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
162 | | |
163 | 591k | if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) { |
164 | 591k | extents->unbounded = extents->bounded; |
165 | 591k | } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) { |
166 | 0 | if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask)) |
167 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
168 | 0 | } |
169 | | |
170 | 591k | extents->clip = _cairo_clip_reduce_for_composite (clip, extents); |
171 | 591k | if (_cairo_clip_is_all_clipped (extents->clip)) |
172 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
173 | | |
174 | 591k | if (! _cairo_rectangle_intersect (&extents->unbounded, |
175 | 591k | _cairo_clip_get_extents (extents->clip))) |
176 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
177 | | |
178 | 591k | if (! _cairo_rectangle_intersect (&extents->bounded, |
179 | 591k | _cairo_clip_get_extents (extents->clip)) && |
180 | 591k | extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) |
181 | 0 | { |
182 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
183 | 0 | } |
184 | | |
185 | 591k | if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) |
186 | 4 | _cairo_pattern_sampled_area (&extents->source_pattern.base, |
187 | 4 | &extents->bounded, |
188 | 4 | &extents->source_sample_area); |
189 | 591k | if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) { |
190 | 4 | _cairo_pattern_sampled_area (&extents->mask_pattern.base, |
191 | 4 | &extents->bounded, |
192 | 4 | &extents->mask_sample_area); |
193 | 4 | if (extents->mask_sample_area.width == 0 || |
194 | 4 | extents->mask_sample_area.height == 0) { |
195 | 0 | _cairo_composite_rectangles_fini (extents); |
196 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
197 | 0 | } |
198 | 4 | } |
199 | | |
200 | 591k | return CAIRO_INT_STATUS_SUCCESS; |
201 | 591k | } |
202 | | |
203 | | cairo_int_status_t |
204 | | _cairo_composite_rectangles_intersect_source_extents (cairo_composite_rectangles_t *extents, |
205 | | const cairo_box_t *box) |
206 | 0 | { |
207 | 0 | cairo_rectangle_int_t rect; |
208 | 0 | cairo_clip_t *clip; |
209 | |
|
210 | 0 | _cairo_box_round_to_rectangle (box, &rect); |
211 | 0 | if (rect.x == extents->source.x && |
212 | 0 | rect.y == extents->source.y && |
213 | 0 | rect.width == extents->source.width && |
214 | 0 | rect.height == extents->source.height) |
215 | 0 | { |
216 | 0 | return CAIRO_INT_STATUS_SUCCESS; |
217 | 0 | } |
218 | | |
219 | 0 | _cairo_rectangle_intersect (&extents->source, &rect); |
220 | |
|
221 | 0 | rect = extents->bounded; |
222 | 0 | if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source) && |
223 | 0 | extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) |
224 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
225 | | |
226 | 0 | if (rect.width == extents->bounded.width && |
227 | 0 | rect.height == extents->bounded.height) |
228 | 0 | return CAIRO_INT_STATUS_SUCCESS; |
229 | | |
230 | 0 | if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) { |
231 | 0 | extents->unbounded = extents->bounded; |
232 | 0 | } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) { |
233 | 0 | if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask)) |
234 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
235 | 0 | } |
236 | | |
237 | 0 | clip = extents->clip; |
238 | 0 | extents->clip = _cairo_clip_reduce_for_composite (clip, extents); |
239 | 0 | if (clip != extents->clip) |
240 | 0 | _cairo_clip_destroy (clip); |
241 | |
|
242 | 0 | if (_cairo_clip_is_all_clipped (extents->clip)) |
243 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
244 | | |
245 | 0 | if (! _cairo_rectangle_intersect (&extents->unbounded, |
246 | 0 | _cairo_clip_get_extents (extents->clip))) |
247 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
248 | | |
249 | 0 | if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) |
250 | 0 | _cairo_pattern_sampled_area (&extents->source_pattern.base, |
251 | 0 | &extents->bounded, |
252 | 0 | &extents->source_sample_area); |
253 | 0 | if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) { |
254 | 0 | _cairo_pattern_sampled_area (&extents->mask_pattern.base, |
255 | 0 | &extents->bounded, |
256 | 0 | &extents->mask_sample_area); |
257 | 0 | if (extents->mask_sample_area.width == 0 || |
258 | 0 | extents->mask_sample_area.height == 0) |
259 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
260 | 0 | } |
261 | | |
262 | 0 | return CAIRO_INT_STATUS_SUCCESS; |
263 | 0 | } |
264 | | |
265 | | cairo_int_status_t |
266 | | _cairo_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t *extents, |
267 | | const cairo_box_t *box) |
268 | 1.26M | { |
269 | 1.26M | cairo_rectangle_int_t mask; |
270 | 1.26M | cairo_clip_t *clip; |
271 | | |
272 | 1.26M | _cairo_box_round_to_rectangle (box, &mask); |
273 | 1.26M | if (mask.x == extents->mask.x && |
274 | 1.26M | mask.y == extents->mask.y && |
275 | 1.26M | mask.width == extents->mask.width && |
276 | 1.26M | mask.height == extents->mask.height) |
277 | 1.19M | { |
278 | 1.19M | return CAIRO_INT_STATUS_SUCCESS; |
279 | 1.19M | } |
280 | | |
281 | 66.5k | _cairo_rectangle_intersect (&extents->mask, &mask); |
282 | | |
283 | 66.5k | mask = extents->bounded; |
284 | 66.5k | if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask) && |
285 | 66.5k | extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) |
286 | 30.4k | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
287 | | |
288 | 36.0k | if (mask.width == extents->bounded.width && |
289 | 36.0k | mask.height == extents->bounded.height) |
290 | 36.0k | return CAIRO_INT_STATUS_SUCCESS; |
291 | | |
292 | 0 | if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) { |
293 | 0 | extents->unbounded = extents->bounded; |
294 | 0 | } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) { |
295 | 0 | if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask)) |
296 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
297 | 0 | } |
298 | | |
299 | 0 | clip = extents->clip; |
300 | 0 | extents->clip = _cairo_clip_reduce_for_composite (clip, extents); |
301 | 0 | if (clip != extents->clip) |
302 | 0 | _cairo_clip_destroy (clip); |
303 | |
|
304 | 0 | if (_cairo_clip_is_all_clipped (extents->clip)) |
305 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
306 | | |
307 | 0 | if (! _cairo_rectangle_intersect (&extents->unbounded, |
308 | 0 | _cairo_clip_get_extents (extents->clip))) |
309 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
310 | | |
311 | 0 | if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) |
312 | 0 | _cairo_pattern_sampled_area (&extents->source_pattern.base, |
313 | 0 | &extents->bounded, |
314 | 0 | &extents->source_sample_area); |
315 | 0 | if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) { |
316 | 0 | _cairo_pattern_sampled_area (&extents->mask_pattern.base, |
317 | 0 | &extents->bounded, |
318 | 0 | &extents->mask_sample_area); |
319 | 0 | if (extents->mask_sample_area.width == 0 || |
320 | 0 | extents->mask_sample_area.height == 0) |
321 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
322 | 0 | } |
323 | | |
324 | 0 | return CAIRO_INT_STATUS_SUCCESS; |
325 | 0 | } |
326 | | |
327 | | cairo_int_status_t |
328 | | _cairo_composite_rectangles_init_for_mask (cairo_composite_rectangles_t *extents, |
329 | | cairo_surface_t *surface, |
330 | | cairo_operator_t op, |
331 | | const cairo_pattern_t *source, |
332 | | const cairo_pattern_t *mask, |
333 | | const cairo_clip_t *clip) |
334 | 4 | { |
335 | 4 | cairo_int_status_t status; |
336 | 4 | if (! _cairo_composite_rectangles_init (extents, |
337 | 4 | surface, op, source, clip)) |
338 | 0 | { |
339 | 0 | _cairo_composite_rectangles_fini(extents); |
340 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
341 | 0 | } |
342 | | |
343 | 4 | extents->original_mask_pattern = mask; |
344 | 4 | _cairo_composite_reduce_pattern (mask, &extents->mask_pattern); |
345 | 4 | _cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask, surface->is_vector); |
346 | | |
347 | 4 | status = _cairo_composite_rectangles_intersect (extents, clip); |
348 | 4 | if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
349 | 0 | _cairo_composite_rectangles_fini(extents); |
350 | 0 | } |
351 | 4 | return status; |
352 | 4 | } |
353 | | |
354 | | cairo_int_status_t |
355 | | _cairo_composite_rectangles_init_for_stroke (cairo_composite_rectangles_t *extents, |
356 | | cairo_surface_t *surface, |
357 | | cairo_operator_t op, |
358 | | const cairo_pattern_t *source, |
359 | | const cairo_path_fixed_t *path, |
360 | | const cairo_stroke_style_t *style, |
361 | | const cairo_matrix_t *ctm, |
362 | | const cairo_clip_t *clip) |
363 | 834k | { |
364 | 834k | cairo_int_status_t status; |
365 | 834k | if (! _cairo_composite_rectangles_init (extents, |
366 | 834k | surface, op, source, clip)) |
367 | 94 | { |
368 | 94 | _cairo_composite_rectangles_fini(extents); |
369 | 94 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
370 | 94 | } |
371 | | |
372 | 834k | _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, surface->is_vector, &extents->mask); |
373 | | |
374 | 834k | status = _cairo_composite_rectangles_intersect (extents, clip); |
375 | 834k | if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
376 | 809k | _cairo_composite_rectangles_fini(extents); |
377 | 809k | } |
378 | 834k | return status; |
379 | 834k | } |
380 | | |
381 | | cairo_int_status_t |
382 | | _cairo_composite_rectangles_init_for_fill (cairo_composite_rectangles_t *extents, |
383 | | cairo_surface_t *surface, |
384 | | cairo_operator_t op, |
385 | | const cairo_pattern_t *source, |
386 | | const cairo_path_fixed_t *path, |
387 | | const cairo_clip_t *clip) |
388 | 6.57M | { |
389 | 6.57M | cairo_int_status_t status; |
390 | 6.57M | if (! _cairo_composite_rectangles_init (extents, |
391 | 6.57M | surface, op, source, clip)) |
392 | 111 | { |
393 | 111 | _cairo_composite_rectangles_fini(extents); |
394 | 111 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
395 | 111 | } |
396 | | |
397 | 6.57M | _cairo_path_fixed_approximate_fill_extents (path, &extents->mask); |
398 | | |
399 | 6.57M | status = _cairo_composite_rectangles_intersect (extents, clip); |
400 | 6.57M | if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
401 | 6.02M | _cairo_composite_rectangles_fini(extents); |
402 | 6.02M | } |
403 | 6.57M | return status; |
404 | 6.57M | } |
405 | | |
406 | | cairo_int_status_t |
407 | | _cairo_composite_rectangles_init_for_polygon (cairo_composite_rectangles_t *extents, |
408 | | cairo_surface_t *surface, |
409 | | cairo_operator_t op, |
410 | | const cairo_pattern_t *source, |
411 | | const cairo_polygon_t *polygon, |
412 | | const cairo_clip_t *clip) |
413 | 0 | { |
414 | 0 | cairo_int_status_t status; |
415 | 0 | if (! _cairo_composite_rectangles_init (extents, |
416 | 0 | surface, op, source, clip)) |
417 | 0 | { |
418 | 0 | _cairo_composite_rectangles_fini(extents); |
419 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
420 | 0 | } |
421 | | |
422 | 0 | _cairo_box_round_to_rectangle (&polygon->extents, &extents->mask); |
423 | 0 | status = _cairo_composite_rectangles_intersect (extents, clip); |
424 | 0 | if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
425 | 0 | _cairo_composite_rectangles_fini(extents); |
426 | 0 | } |
427 | 0 | return status; |
428 | 0 | } |
429 | | |
430 | | cairo_int_status_t |
431 | | _cairo_composite_rectangles_init_for_boxes (cairo_composite_rectangles_t *extents, |
432 | | cairo_surface_t *surface, |
433 | | cairo_operator_t op, |
434 | | const cairo_pattern_t *source, |
435 | | const cairo_boxes_t *boxes, |
436 | | const cairo_clip_t *clip) |
437 | 0 | { |
438 | 0 | cairo_box_t box; |
439 | 0 | cairo_int_status_t status; |
440 | |
|
441 | 0 | if (! _cairo_composite_rectangles_init (extents, |
442 | 0 | surface, op, source, clip)) |
443 | 0 | { |
444 | 0 | _cairo_composite_rectangles_fini(extents); |
445 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
446 | 0 | } |
447 | | |
448 | 0 | _cairo_boxes_extents (boxes, &box); |
449 | 0 | _cairo_box_round_to_rectangle (&box, &extents->mask); |
450 | 0 | status = _cairo_composite_rectangles_intersect (extents, clip); |
451 | 0 | if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
452 | 0 | _cairo_composite_rectangles_fini(extents); |
453 | 0 | } |
454 | 0 | return status; |
455 | 0 | } |
456 | | |
457 | | cairo_int_status_t |
458 | | _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *extents, |
459 | | cairo_surface_t *surface, |
460 | | cairo_operator_t op, |
461 | | const cairo_pattern_t *source, |
462 | | cairo_scaled_font_t *scaled_font, |
463 | | cairo_glyph_t *glyphs, |
464 | | int num_glyphs, |
465 | | const cairo_clip_t *clip, |
466 | | cairo_bool_t *overlap) |
467 | 396k | { |
468 | 396k | cairo_status_t status; |
469 | 396k | cairo_int_status_t int_status; |
470 | | |
471 | 396k | if (! _cairo_composite_rectangles_init (extents, surface, op, source, clip)) { |
472 | 0 | _cairo_composite_rectangles_fini(extents); |
473 | 0 | return CAIRO_INT_STATUS_NOTHING_TO_DO; |
474 | 0 | } |
475 | | |
476 | 396k | status = _cairo_scaled_font_glyph_device_extents (scaled_font, |
477 | 396k | glyphs, num_glyphs, |
478 | 396k | &extents->mask, |
479 | 396k | overlap); |
480 | 396k | if (unlikely (status)) { |
481 | 0 | _cairo_composite_rectangles_fini(extents); |
482 | 0 | return status; |
483 | 0 | } |
484 | 396k | if (overlap && *overlap && |
485 | 396k | scaled_font->options.antialias == CAIRO_ANTIALIAS_NONE && |
486 | 396k | _cairo_pattern_is_opaque_solid (&extents->source_pattern.base)) |
487 | 0 | { |
488 | 0 | *overlap = FALSE; |
489 | 0 | } |
490 | | |
491 | 396k | int_status = _cairo_composite_rectangles_intersect (extents, clip); |
492 | 396k | if (int_status == CAIRO_INT_STATUS_NOTHING_TO_DO) { |
493 | 378k | _cairo_composite_rectangles_fini(extents); |
494 | 378k | } |
495 | 396k | return int_status; |
496 | 396k | } |
497 | | |
498 | | cairo_bool_t |
499 | | _cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite, |
500 | | cairo_clip_t *clip) |
501 | 0 | { |
502 | 0 | cairo_rectangle_int_t extents; |
503 | 0 | cairo_box_t box; |
504 | |
|
505 | 0 | if (clip == NULL) |
506 | 0 | return TRUE; |
507 | | |
508 | 0 | extents = composite->destination; |
509 | 0 | if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) |
510 | 0 | _cairo_rectangle_intersect (&extents, &composite->source); |
511 | 0 | if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) |
512 | 0 | _cairo_rectangle_intersect (&extents, &composite->mask); |
513 | |
|
514 | 0 | _cairo_box_from_rectangle (&box, &extents); |
515 | 0 | return _cairo_clip_contains_box (clip, &box); |
516 | 0 | } |
517 | | |
518 | | cairo_int_status_t |
519 | | _cairo_composite_rectangles_add_to_damage (cairo_composite_rectangles_t *composite, |
520 | | cairo_boxes_t *damage) |
521 | 0 | { |
522 | 0 | cairo_int_status_t status; |
523 | 0 | int n; |
524 | |
|
525 | 0 | for (n = 0; n < composite->clip->num_boxes; n++) { |
526 | 0 | status = _cairo_boxes_add (damage, |
527 | 0 | CAIRO_ANTIALIAS_NONE, |
528 | 0 | &composite->clip->boxes[n]); |
529 | 0 | if (unlikely (status)) |
530 | 0 | return status; |
531 | 0 | } |
532 | | |
533 | 0 | return CAIRO_INT_STATUS_SUCCESS; |
534 | 0 | } |