Coverage Report

Created: 2026-08-14 08:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cairo/src/cairo-composite-rectangles.c
Line
Count
Source
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
4.23M
{
47
    /* If adding further free() code here, make sure those fields are inited by
48
     * _cairo_composite_rectangles_init IN ALL CASES
49
     */
50
4.23M
    _cairo_clip_destroy (extents->clip);
51
4.23M
    extents->clip = NULL;
52
4.23M
}
53
54
static void
55
_cairo_composite_reduce_pattern (const cairo_pattern_t *src,
56
         cairo_pattern_union_t *dst)
57
4.26M
{
58
4.26M
    int tx, ty;
59
60
4.26M
    _cairo_pattern_init_static_copy (&dst->base, src);
61
4.26M
    if (dst->base.type == CAIRO_PATTERN_TYPE_SOLID)
62
4.20M
  return;
63
64
52.9k
    dst->base.filter = _cairo_pattern_analyze_filter (&dst->base);
65
66
52.9k
    tx = ty = 0;
67
52.9k
    if (_cairo_matrix_is_pixman_translation (&dst->base.matrix,
68
52.9k
               dst->base.filter,
69
52.9k
               &tx, &ty))
70
7.08k
    {
71
7.08k
  dst->base.matrix.x0 = tx;
72
7.08k
  dst->base.matrix.y0 = ty;
73
7.08k
    }
74
52.9k
}
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
4.23M
{
83
    /* Always set the clip so that a _cairo_composite_rectangles_init can ALWAYS be
84
     * balanced by a _cairo_composite_rectangles_fini */
85
4.23M
    extents->clip = NULL;
86
87
4.23M
    if (_cairo_clip_is_all_clipped (clip))
88
0
  return FALSE;
89
4.23M
    extents->surface = surface;
90
4.23M
    extents->op = op;
91
92
4.23M
    _cairo_surface_get_extents (surface, &extents->destination);
93
94
4.23M
    extents->unbounded = extents->destination;
95
4.23M
    if (clip && ! _cairo_rectangle_intersect (&extents->unbounded,
96
4.21M
                _cairo_clip_get_extents (clip)))
97
6
  return FALSE;
98
99
4.23M
    extents->bounded = extents->unbounded;
100
4.23M
    extents->is_bounded = _cairo_operator_bounded_by_either (op);
101
102
4.23M
    extents->original_source_pattern = source;
103
4.23M
    _cairo_composite_reduce_pattern (source, &extents->source_pattern);
104
105
4.23M
    _cairo_pattern_get_extents (&extents->source_pattern.base,
106
4.23M
        &extents->source,
107
4.23M
        surface->is_vector);
108
4.23M
    if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) {
109
4.23M
  if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source))
110
67
      return FALSE;
111
4.23M
    }
112
113
4.23M
    extents->original_mask_pattern = NULL;
114
4.23M
    extents->mask_pattern.base.type = CAIRO_PATTERN_TYPE_SOLID;
115
4.23M
    extents->mask_pattern.solid.color.alpha = 1.; /* XXX full initialisation? */
116
4.23M
    extents->mask_pattern.solid.color.alpha_short = 0xffff;
117
118
4.23M
    return TRUE;
119
4.23M
}
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
15.2k
{
128
15.2k
    if (! _cairo_composite_rectangles_init (extents,
129
15.2k
              surface, op, source, clip))
130
36
    {
131
36
  goto NOTHING_TO_DO;
132
36
    }
133
134
15.2k
    extents->mask = extents->destination;
135
136
15.2k
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
137
15.2k
    if (_cairo_clip_is_all_clipped (extents->clip))
138
0
  goto NOTHING_TO_DO;
139
140
15.2k
    if (! _cairo_rectangle_intersect (&extents->unbounded,
141
15.2k
              _cairo_clip_get_extents (extents->clip)))
142
0
  goto NOTHING_TO_DO;
143
144
15.2k
    if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
145
13.5k
  _cairo_pattern_sampled_area (&extents->source_pattern.base,
146
13.5k
             &extents->bounded,
147
13.5k
             &extents->source_sample_area);
148
149
15.2k
    return CAIRO_INT_STATUS_SUCCESS;
150
36
NOTHING_TO_DO:
151
36
    _cairo_composite_rectangles_fini(extents);
152
36
    return CAIRO_INT_STATUS_NOTHING_TO_DO;
153
15.2k
}
154
155
static cairo_int_status_t
156
_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents,
157
               const cairo_clip_t *clip)
158
4.22M
{
159
4.22M
    if ((!_cairo_rectangle_intersect (&extents->bounded, &extents->mask)) &&
160
23.1k
        (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK))
161
23.1k
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
162
163
4.19M
    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
164
4.19M
  extents->unbounded = extents->bounded;
165
4.19M
    } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) {
166
1.14k
  if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask))
167
0
      return CAIRO_INT_STATUS_NOTHING_TO_DO;
168
1.14k
    }
169
170
4.19M
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
171
4.19M
    if (_cairo_clip_is_all_clipped (extents->clip))
172
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
173
174
4.19M
    if (! _cairo_rectangle_intersect (&extents->unbounded,
175
4.19M
              _cairo_clip_get_extents (extents->clip)))
176
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
177
178
4.19M
    if (! _cairo_rectangle_intersect (&extents->bounded,
179
4.19M
              _cairo_clip_get_extents (extents->clip)) &&
180
0
  extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
181
0
    {
182
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
183
0
    }
184
185
4.19M
    if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
186
17.0k
  _cairo_pattern_sampled_area (&extents->source_pattern.base,
187
17.0k
             &extents->bounded,
188
17.0k
             &extents->source_sample_area);
189
4.19M
    if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) {
190
22.1k
  _cairo_pattern_sampled_area (&extents->mask_pattern.base,
191
22.1k
             &extents->bounded,
192
22.1k
             &extents->mask_sample_area);
193
22.1k
  if (extents->mask_sample_area.width == 0 ||
194
22.1k
      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
22.1k
    }
199
200
4.19M
    return CAIRO_INT_STATUS_SUCCESS;
201
4.19M
}
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
3.47k
{
207
3.47k
    cairo_rectangle_int_t rect;
208
3.47k
    cairo_clip_t *clip;
209
210
3.47k
    _cairo_box_round_to_rectangle (box, &rect);
211
3.47k
    if (rect.x == extents->source.x &&
212
3.23k
  rect.y == extents->source.y &&
213
2.95k
  rect.width  == extents->source.width &&
214
2.92k
  rect.height == extents->source.height)
215
2.92k
    {
216
2.92k
  return CAIRO_INT_STATUS_SUCCESS;
217
2.92k
    }
218
219
548
    _cairo_rectangle_intersect (&extents->source, &rect);
220
221
548
    rect = extents->bounded;
222
548
    if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source) &&
223
274
  extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE)
224
274
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
225
226
274
    if (rect.width  == extents->bounded.width &&
227
27
  rect.height == extents->bounded.height)
228
24
  return CAIRO_INT_STATUS_SUCCESS;
229
230
250
    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
231
250
  extents->unbounded = extents->bounded;
232
250
    } 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
250
    clip = extents->clip;
238
250
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
239
250
    if (clip != extents->clip)
240
250
  _cairo_clip_destroy (clip);
241
242
250
    if (_cairo_clip_is_all_clipped (extents->clip))
243
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
244
245
250
    if (! _cairo_rectangle_intersect (&extents->unbounded,
246
250
              _cairo_clip_get_extents (extents->clip)))
247
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
248
249
250
    if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
250
250
  _cairo_pattern_sampled_area (&extents->source_pattern.base,
251
250
             &extents->bounded,
252
250
             &extents->source_sample_area);
253
250
    if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) {
254
65
  _cairo_pattern_sampled_area (&extents->mask_pattern.base,
255
65
             &extents->bounded,
256
65
             &extents->mask_sample_area);
257
65
  if (extents->mask_sample_area.width == 0 ||
258
65
      extents->mask_sample_area.height == 0)
259
0
      return CAIRO_INT_STATUS_NOTHING_TO_DO;
260
65
    }
261
262
250
    return CAIRO_INT_STATUS_SUCCESS;
263
250
}
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
379k
{
269
379k
    cairo_rectangle_int_t mask;
270
379k
    cairo_clip_t *clip;
271
272
379k
    _cairo_box_round_to_rectangle (box, &mask);
273
379k
    if (mask.x == extents->mask.x &&
274
287k
  mask.y == extents->mask.y &&
275
239k
  mask.width  == extents->mask.width &&
276
202k
  mask.height == extents->mask.height)
277
175k
    {
278
175k
  return CAIRO_INT_STATUS_SUCCESS;
279
175k
    }
280
281
203k
    _cairo_rectangle_intersect (&extents->mask, &mask);
282
283
203k
    mask = extents->bounded;
284
203k
    if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask) &&
285
917
  extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
286
917
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
287
288
202k
    if (mask.width  == extents->bounded.width &&
289
179k
  mask.height == extents->bounded.height)
290
175k
  return CAIRO_INT_STATUS_SUCCESS;
291
292
27.3k
    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
293
27.3k
  extents->unbounded = extents->bounded;
294
27.3k
    } 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
27.3k
    clip = extents->clip;
300
27.3k
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
301
27.3k
    if (clip != extents->clip)
302
27.3k
  _cairo_clip_destroy (clip);
303
304
27.3k
    if (_cairo_clip_is_all_clipped (extents->clip))
305
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
306
307
27.3k
    if (! _cairo_rectangle_intersect (&extents->unbounded,
308
27.3k
              _cairo_clip_get_extents (extents->clip)))
309
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
310
311
27.3k
    if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
312
106
  _cairo_pattern_sampled_area (&extents->source_pattern.base,
313
106
             &extents->bounded,
314
106
             &extents->source_sample_area);
315
27.3k
    if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) {
316
9
  _cairo_pattern_sampled_area (&extents->mask_pattern.base,
317
9
             &extents->bounded,
318
9
             &extents->mask_sample_area);
319
9
  if (extents->mask_sample_area.width == 0 ||
320
9
      extents->mask_sample_area.height == 0)
321
0
      return CAIRO_INT_STATUS_NOTHING_TO_DO;
322
9
    }
323
324
27.3k
    return CAIRO_INT_STATUS_SUCCESS;
325
27.3k
}
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
24.2k
{
335
24.2k
    cairo_int_status_t status;
336
24.2k
    if (! _cairo_composite_rectangles_init (extents,
337
24.2k
              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
24.2k
    extents->original_mask_pattern = mask;
344
24.2k
    _cairo_composite_reduce_pattern (mask, &extents->mask_pattern);
345
24.2k
    _cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask, surface->is_vector);
346
347
24.2k
    status = _cairo_composite_rectangles_intersect (extents, clip);
348
24.2k
    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
349
91
  _cairo_composite_rectangles_fini(extents);
350
91
    }
351
24.2k
    return status;
352
24.2k
}
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
409k
{
364
409k
    cairo_int_status_t status;
365
409k
    if (! _cairo_composite_rectangles_init (extents,
366
409k
              surface, op, source, clip))
367
36
    {
368
36
  _cairo_composite_rectangles_fini(extents);
369
36
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
370
36
    }
371
372
409k
    _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, surface->is_vector, &extents->mask);
373
374
409k
    status = _cairo_composite_rectangles_intersect (extents, clip);
375
409k
    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
376
4.25k
  _cairo_composite_rectangles_fini(extents);
377
4.25k
    }
378
409k
    return status;
379
409k
}
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
160k
{
389
160k
    cairo_int_status_t status;
390
160k
    if (! _cairo_composite_rectangles_init (extents,
391
160k
              surface, op, source, clip))
392
1
    {
393
1
  _cairo_composite_rectangles_fini(extents);
394
1
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
395
1
    }
396
397
160k
    _cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
398
399
160k
    status = _cairo_composite_rectangles_intersect (extents, clip);
400
160k
        if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
401
11.5k
    _cairo_composite_rectangles_fini(extents);
402
11.5k
    }
403
160k
    return status;
404
160k
}
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
3.62M
{
468
3.62M
    cairo_status_t status;
469
3.62M
    cairo_int_status_t int_status;
470
471
3.62M
    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
3.62M
    status = _cairo_scaled_font_glyph_device_extents (scaled_font,
477
3.62M
                  glyphs, num_glyphs,
478
3.62M
                  &extents->mask,
479
3.62M
                  overlap);
480
3.62M
    if (unlikely (status)) {
481
0
  _cairo_composite_rectangles_fini(extents);
482
0
  return status;
483
0
    }
484
3.62M
    if (overlap && *overlap &&
485
547k
  scaled_font->options.antialias == CAIRO_ANTIALIAS_NONE &&
486
0
  _cairo_pattern_is_opaque_solid (&extents->source_pattern.base))
487
0
    {
488
0
  *overlap = FALSE;
489
0
    }
490
491
3.62M
    int_status = _cairo_composite_rectangles_intersect (extents, clip);
492
3.62M
    if (int_status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
493
7.22k
  _cairo_composite_rectangles_fini(extents);
494
7.22k
    }
495
3.62M
    return int_status;
496
3.62M
}
497
498
cairo_bool_t
499
_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite,
500
               cairo_clip_t *clip)
501
4.16M
{
502
4.16M
    cairo_rectangle_int_t extents;
503
4.16M
    cairo_box_t box;
504
505
4.16M
    if (clip == NULL)
506
1.32M
  return TRUE;
507
508
2.84M
    extents = composite->destination;
509
2.84M
    if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE)
510
2.84M
  _cairo_rectangle_intersect (&extents, &composite->source);
511
2.84M
    if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
512
2.84M
  _cairo_rectangle_intersect (&extents, &composite->mask);
513
514
2.84M
    _cairo_box_from_rectangle (&box, &extents);
515
2.84M
    return _cairo_clip_contains_box (clip, &box);
516
4.16M
}
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
}