Coverage Report

Created: 2025-07-23 08:13

/src/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
1.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
1.49M
    _cairo_clip_destroy (extents->clip);
51
1.49M
    extents->clip = NULL;
52
1.49M
}
53
54
static void
55
_cairo_composite_reduce_pattern (const cairo_pattern_t *src,
56
         cairo_pattern_union_t *dst)
57
1.49M
{
58
1.49M
    int tx, ty;
59
60
1.49M
    _cairo_pattern_init_static_copy (&dst->base, src);
61
1.49M
    if (dst->base.type == CAIRO_PATTERN_TYPE_SOLID)
62
1.48M
  return;
63
64
11.0k
    dst->base.filter = _cairo_pattern_analyze_filter (&dst->base);
65
66
11.0k
    tx = ty = 0;
67
11.0k
    if (_cairo_matrix_is_pixman_translation (&dst->base.matrix,
68
11.0k
               dst->base.filter,
69
11.0k
               &tx, &ty))
70
170
    {
71
170
  dst->base.matrix.x0 = tx;
72
170
  dst->base.matrix.y0 = ty;
73
170
    }
74
11.0k
}
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
1.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
1.49M
    extents->clip = NULL;
86
87
1.49M
    if (_cairo_clip_is_all_clipped (clip))
88
0
  return FALSE;
89
1.49M
    extents->surface = surface;
90
1.49M
    extents->op = op;
91
92
1.49M
    _cairo_surface_get_extents (surface, &extents->destination);
93
94
1.49M
    extents->unbounded = extents->destination;
95
1.49M
    if (clip && ! _cairo_rectangle_intersect (&extents->unbounded,
96
1.49M
                _cairo_clip_get_extents (clip)))
97
0
  return FALSE;
98
99
1.49M
    extents->bounded = extents->unbounded;
100
1.49M
    extents->is_bounded = _cairo_operator_bounded_by_either (op);
101
102
1.49M
    extents->original_source_pattern = source;
103
1.49M
    _cairo_composite_reduce_pattern (source, &extents->source_pattern);
104
105
1.49M
    _cairo_pattern_get_extents (&extents->source_pattern.base,
106
1.49M
        &extents->source,
107
1.49M
        surface->is_vector);
108
1.49M
    if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) {
109
1.49M
  if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source))
110
0
      return FALSE;
111
1.49M
    }
112
113
1.49M
    extents->original_mask_pattern = NULL;
114
1.49M
    extents->mask_pattern.base.type = CAIRO_PATTERN_TYPE_SOLID;
115
1.49M
    extents->mask_pattern.solid.color.alpha = 1.; /* XXX full initialisation? */
116
1.49M
    extents->mask_pattern.solid.color.alpha_short = 0xffff;
117
118
1.49M
    return TRUE;
119
1.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
1.01k
{
128
1.01k
    if (! _cairo_composite_rectangles_init (extents,
129
1.01k
              surface, op, source, clip))
130
0
    {
131
0
  goto NOTHING_TO_DO;
132
0
    }
133
134
1.01k
    extents->mask = extents->destination;
135
136
1.01k
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
137
1.01k
    if (_cairo_clip_is_all_clipped (extents->clip))
138
0
  goto NOTHING_TO_DO;
139
140
1.01k
    if (! _cairo_rectangle_intersect (&extents->unbounded,
141
1.01k
              _cairo_clip_get_extents (extents->clip)))
142
0
  goto NOTHING_TO_DO;
143
144
1.01k
    if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
145
988
  _cairo_pattern_sampled_area (&extents->source_pattern.base,
146
988
             &extents->bounded,
147
988
             &extents->source_sample_area);
148
149
1.01k
    return CAIRO_INT_STATUS_SUCCESS;
150
0
NOTHING_TO_DO:
151
0
    _cairo_composite_rectangles_fini(extents);
152
0
    return CAIRO_INT_STATUS_NOTHING_TO_DO;
153
1.01k
}
154
155
static cairo_int_status_t
156
_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents,
157
               const cairo_clip_t *clip)
158
1.49M
{
159
1.49M
    if ((!_cairo_rectangle_intersect (&extents->bounded, &extents->mask)) &&
160
1.49M
        (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK))
161
540
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
162
163
1.49M
    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
164
1.49M
  extents->unbounded = extents->bounded;
165
1.49M
    } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) {
166
912
  if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask))
167
0
      return CAIRO_INT_STATUS_NOTHING_TO_DO;
168
912
    }
169
170
1.49M
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
171
1.49M
    if (_cairo_clip_is_all_clipped (extents->clip))
172
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
173
174
1.49M
    if (! _cairo_rectangle_intersect (&extents->unbounded,
175
1.49M
              _cairo_clip_get_extents (extents->clip)))
176
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
177
178
1.49M
    if (! _cairo_rectangle_intersect (&extents->bounded,
179
1.49M
              _cairo_clip_get_extents (extents->clip)) &&
180
1.49M
  extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
181
0
    {
182
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
183
0
    }
184
185
1.49M
    if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
186
6.65k
  _cairo_pattern_sampled_area (&extents->source_pattern.base,
187
6.65k
             &extents->bounded,
188
6.65k
             &extents->source_sample_area);
189
1.49M
    if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) {
190
3.45k
  _cairo_pattern_sampled_area (&extents->mask_pattern.base,
191
3.45k
             &extents->bounded,
192
3.45k
             &extents->mask_sample_area);
193
3.45k
  if (extents->mask_sample_area.width == 0 ||
194
3.45k
      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
3.45k
    }
199
200
1.49M
    return CAIRO_INT_STATUS_SUCCESS;
201
1.49M
}
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
1.17k
{
207
1.17k
    cairo_rectangle_int_t rect;
208
1.17k
    cairo_clip_t *clip;
209
210
1.17k
    _cairo_box_round_to_rectangle (box, &rect);
211
1.17k
    if (rect.x == extents->source.x &&
212
1.17k
  rect.y == extents->source.y &&
213
1.17k
  rect.width  == extents->source.width &&
214
1.17k
  rect.height == extents->source.height)
215
1.16k
    {
216
1.16k
  return CAIRO_INT_STATUS_SUCCESS;
217
1.16k
    }
218
219
4
    _cairo_rectangle_intersect (&extents->source, &rect);
220
221
4
    rect = extents->bounded;
222
4
    if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source) &&
223
4
  extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE)
224
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
225
226
4
    if (rect.width  == extents->bounded.width &&
227
4
  rect.height == extents->bounded.height)
228
0
  return CAIRO_INT_STATUS_SUCCESS;
229
230
4
    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
231
4
  extents->unbounded = extents->bounded;
232
4
    } 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
4
    clip = extents->clip;
238
4
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
239
4
    if (clip != extents->clip)
240
4
  _cairo_clip_destroy (clip);
241
242
4
    if (_cairo_clip_is_all_clipped (extents->clip))
243
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
244
245
4
    if (! _cairo_rectangle_intersect (&extents->unbounded,
246
4
              _cairo_clip_get_extents (extents->clip)))
247
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
248
249
4
    if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
250
4
  _cairo_pattern_sampled_area (&extents->source_pattern.base,
251
4
             &extents->bounded,
252
4
             &extents->source_sample_area);
253
4
    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
4
    return CAIRO_INT_STATUS_SUCCESS;
263
4
}
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
26.6k
{
269
26.6k
    cairo_rectangle_int_t mask;
270
26.6k
    cairo_clip_t *clip;
271
272
26.6k
    _cairo_box_round_to_rectangle (box, &mask);
273
26.6k
    if (mask.x == extents->mask.x &&
274
26.6k
  mask.y == extents->mask.y &&
275
26.6k
  mask.width  == extents->mask.width &&
276
26.6k
  mask.height == extents->mask.height)
277
15.2k
    {
278
15.2k
  return CAIRO_INT_STATUS_SUCCESS;
279
15.2k
    }
280
281
11.3k
    _cairo_rectangle_intersect (&extents->mask, &mask);
282
283
11.3k
    mask = extents->bounded;
284
11.3k
    if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask) &&
285
11.3k
  extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
286
26
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
287
288
11.3k
    if (mask.width  == extents->bounded.width &&
289
11.3k
  mask.height == extents->bounded.height)
290
3.05k
  return CAIRO_INT_STATUS_SUCCESS;
291
292
8.30k
    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
293
8.30k
  extents->unbounded = extents->bounded;
294
8.30k
    } 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
8.30k
    clip = extents->clip;
300
8.30k
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
301
8.30k
    if (clip != extents->clip)
302
8.30k
  _cairo_clip_destroy (clip);
303
304
8.30k
    if (_cairo_clip_is_all_clipped (extents->clip))
305
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
306
307
8.30k
    if (! _cairo_rectangle_intersect (&extents->unbounded,
308
8.30k
              _cairo_clip_get_extents (extents->clip)))
309
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
310
311
8.30k
    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
8.30k
    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
8.30k
    return CAIRO_INT_STATUS_SUCCESS;
325
8.30k
}
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
3.52k
{
335
3.52k
    cairo_int_status_t status;
336
3.52k
    if (! _cairo_composite_rectangles_init (extents,
337
3.52k
              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
3.52k
    extents->original_mask_pattern = mask;
344
3.52k
    _cairo_composite_reduce_pattern (mask, &extents->mask_pattern);
345
3.52k
    _cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask, surface->is_vector);
346
347
3.52k
    status = _cairo_composite_rectangles_intersect (extents, clip);
348
3.52k
    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
349
0
  _cairo_composite_rectangles_fini(extents);
350
0
    }
351
3.52k
    return status;
352
3.52k
}
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
21.6k
{
364
21.6k
    cairo_int_status_t status;
365
21.6k
    if (! _cairo_composite_rectangles_init (extents,
366
21.6k
              surface, op, source, clip))
367
0
    {
368
0
  _cairo_composite_rectangles_fini(extents);
369
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
370
0
    }
371
372
21.6k
    _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, surface->is_vector, &extents->mask);
373
374
21.6k
    status = _cairo_composite_rectangles_intersect (extents, clip);
375
21.6k
    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
376
3
  _cairo_composite_rectangles_fini(extents);
377
3
    }
378
21.6k
    return status;
379
21.6k
}
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
14.9k
{
389
14.9k
    cairo_int_status_t status;
390
14.9k
    if (! _cairo_composite_rectangles_init (extents,
391
14.9k
              surface, op, source, clip))
392
0
    {
393
0
  _cairo_composite_rectangles_fini(extents);
394
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
395
0
    }
396
397
14.9k
    _cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
398
399
14.9k
    status = _cairo_composite_rectangles_intersect (extents, clip);
400
14.9k
        if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
401
0
    _cairo_composite_rectangles_fini(extents);
402
0
    }
403
14.9k
    return status;
404
14.9k
}
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
1.45M
{
468
1.45M
    cairo_status_t status;
469
1.45M
    cairo_int_status_t int_status;
470
471
1.45M
    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
1.45M
    status = _cairo_scaled_font_glyph_device_extents (scaled_font,
477
1.45M
                  glyphs, num_glyphs,
478
1.45M
                  &extents->mask,
479
1.45M
                  overlap);
480
1.45M
    if (unlikely (status)) {
481
0
  _cairo_composite_rectangles_fini(extents);
482
0
  return status;
483
0
    }
484
1.45M
    if (overlap && *overlap &&
485
1.45M
  scaled_font->options.antialias == CAIRO_ANTIALIAS_NONE &&
486
1.45M
  _cairo_pattern_is_opaque_solid (&extents->source_pattern.base))
487
0
    {
488
0
  *overlap = FALSE;
489
0
    }
490
491
1.45M
    int_status = _cairo_composite_rectangles_intersect (extents, clip);
492
1.45M
    if (int_status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
493
537
  _cairo_composite_rectangles_fini(extents);
494
537
    }
495
1.45M
    return int_status;
496
1.45M
}
497
498
cairo_bool_t
499
_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite,
500
               cairo_clip_t *clip)
501
1.49M
{
502
1.49M
    cairo_rectangle_int_t extents;
503
1.49M
    cairo_box_t box;
504
505
1.49M
    if (clip == NULL)
506
482k
  return TRUE;
507
508
1.00M
    extents = composite->destination;
509
1.00M
    if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE)
510
1.00M
  _cairo_rectangle_intersect (&extents, &composite->source);
511
1.00M
    if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
512
1.00M
  _cairo_rectangle_intersect (&extents, &composite->mask);
513
514
1.00M
    _cairo_box_from_rectangle (&box, &extents);
515
1.00M
    return _cairo_clip_contains_box (clip, &box);
516
1.49M
}
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
}