Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/workdir/UnpackedTarball/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
13.1M
{
47
    /* If adding further free() code here, make sure those fields are inited by
48
     * _cairo_composite_rectangles_init IN ALL CASES
49
     */
50
13.1M
    _cairo_clip_destroy (extents->clip);
51
13.1M
    extents->clip = NULL;
52
13.1M
}
53
54
static void
55
_cairo_composite_reduce_pattern (const cairo_pattern_t *src,
56
         cairo_pattern_union_t *dst)
57
13.1M
{
58
13.1M
    int tx, ty;
59
60
13.1M
    _cairo_pattern_init_static_copy (&dst->base, src);
61
13.1M
    if (dst->base.type == CAIRO_PATTERN_TYPE_SOLID)
62
12.6M
  return;
63
64
515k
    dst->base.filter = _cairo_pattern_analyze_filter (&dst->base);
65
66
515k
    tx = ty = 0;
67
515k
    if (_cairo_matrix_is_pixman_translation (&dst->base.matrix,
68
515k
               dst->base.filter,
69
515k
               &tx, &ty))
70
515k
    {
71
515k
  dst->base.matrix.x0 = tx;
72
515k
  dst->base.matrix.y0 = ty;
73
515k
    }
74
515k
}
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
13.1M
{
83
    /* Always set the clip so that a _cairo_composite_rectangles_init can ALWAYS be
84
     * balanced by a _cairo_composite_rectangles_fini */
85
13.1M
    extents->clip = NULL;
86
87
13.1M
    if (_cairo_clip_is_all_clipped (clip))
88
0
  return FALSE;
89
13.1M
    extents->surface = surface;
90
13.1M
    extents->op = op;
91
92
13.1M
    _cairo_surface_get_extents (surface, &extents->destination);
93
94
13.1M
    extents->unbounded = extents->destination;
95
13.1M
    if (clip && ! _cairo_rectangle_intersect (&extents->unbounded,
96
1.46M
                _cairo_clip_get_extents (clip)))
97
2.43k
  return FALSE;
98
99
13.1M
    extents->bounded = extents->unbounded;
100
13.1M
    extents->is_bounded = _cairo_operator_bounded_by_either (op);
101
102
13.1M
    extents->original_source_pattern = source;
103
13.1M
    _cairo_composite_reduce_pattern (source, &extents->source_pattern);
104
105
13.1M
    _cairo_pattern_get_extents (&extents->source_pattern.base,
106
13.1M
        &extents->source,
107
13.1M
        surface->is_vector);
108
13.1M
    if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE) {
109
4.29M
  if (! _cairo_rectangle_intersect (&extents->bounded, &extents->source))
110
0
      return FALSE;
111
4.29M
    }
112
113
13.1M
    extents->original_mask_pattern = NULL;
114
13.1M
    extents->mask_pattern.base.type = CAIRO_PATTERN_TYPE_SOLID;
115
13.1M
    extents->mask_pattern.solid.color.alpha = 1.; /* XXX full initialisation? */
116
13.1M
    extents->mask_pattern.solid.color.alpha_short = 0xffff;
117
118
13.1M
    return TRUE;
119
13.1M
}
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
2.05M
{
128
2.05M
    if (! _cairo_composite_rectangles_init (extents,
129
2.05M
              surface, op, source, clip))
130
2.32k
    {
131
2.32k
  goto NOTHING_TO_DO;
132
2.32k
    }
133
134
2.05M
    extents->mask = extents->destination;
135
136
2.05M
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
137
2.05M
    if (_cairo_clip_is_all_clipped (extents->clip))
138
0
  goto NOTHING_TO_DO;
139
140
2.05M
    if (! _cairo_rectangle_intersect (&extents->unbounded,
141
2.05M
              _cairo_clip_get_extents (extents->clip)))
142
0
  goto NOTHING_TO_DO;
143
144
2.05M
    if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
145
515k
  _cairo_pattern_sampled_area (&extents->source_pattern.base,
146
515k
             &extents->bounded,
147
515k
             &extents->source_sample_area);
148
149
2.05M
    return CAIRO_INT_STATUS_SUCCESS;
150
2.32k
NOTHING_TO_DO:
151
2.32k
    _cairo_composite_rectangles_fini(extents);
152
2.32k
    return CAIRO_INT_STATUS_NOTHING_TO_DO;
153
2.05M
}
154
155
static cairo_int_status_t
156
_cairo_composite_rectangles_intersect (cairo_composite_rectangles_t *extents,
157
               const cairo_clip_t *clip)
158
11.1M
{
159
11.1M
    if ((!_cairo_rectangle_intersect (&extents->bounded, &extents->mask)) &&
160
10.3M
        (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK))
161
10.3M
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
162
163
811k
    if (extents->is_bounded == (CAIRO_OPERATOR_BOUND_BY_MASK | CAIRO_OPERATOR_BOUND_BY_SOURCE)) {
164
488k
  extents->unbounded = extents->bounded;
165
488k
    } else if (extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK) {
166
322k
  if (!_cairo_rectangle_intersect (&extents->unbounded, &extents->mask))
167
0
      return CAIRO_INT_STATUS_NOTHING_TO_DO;
168
322k
    }
169
170
811k
    extents->clip = _cairo_clip_reduce_for_composite (clip, extents);
171
811k
    if (_cairo_clip_is_all_clipped (extents->clip))
172
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
173
174
811k
    if (! _cairo_rectangle_intersect (&extents->unbounded,
175
811k
              _cairo_clip_get_extents (extents->clip)))
176
0
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
177
178
811k
    if (! _cairo_rectangle_intersect (&extents->bounded,
179
811k
              _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
811k
    if (extents->source_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID)
186
0
  _cairo_pattern_sampled_area (&extents->source_pattern.base,
187
0
             &extents->bounded,
188
0
             &extents->source_sample_area);
189
811k
    if (extents->mask_pattern.base.type != CAIRO_PATTERN_TYPE_SOLID) {
190
0
  _cairo_pattern_sampled_area (&extents->mask_pattern.base,
191
0
             &extents->bounded,
192
0
             &extents->mask_sample_area);
193
0
  if (extents->mask_sample_area.width == 0 ||
194
0
      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
0
    }
199
200
811k
    return CAIRO_INT_STATUS_SUCCESS;
201
811k
}
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
2.83M
{
269
2.83M
    cairo_rectangle_int_t mask;
270
2.83M
    cairo_clip_t *clip;
271
272
2.83M
    _cairo_box_round_to_rectangle (box, &mask);
273
2.83M
    if (mask.x == extents->mask.x &&
274
2.53M
  mask.y == extents->mask.y &&
275
2.53M
  mask.width  == extents->mask.width &&
276
2.51M
  mask.height == extents->mask.height)
277
2.51M
    {
278
2.51M
  return CAIRO_INT_STATUS_SUCCESS;
279
2.51M
    }
280
281
322k
    _cairo_rectangle_intersect (&extents->mask, &mask);
282
283
322k
    mask = extents->bounded;
284
322k
    if (! _cairo_rectangle_intersect (&extents->bounded, &extents->mask) &&
285
127k
  extents->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
286
127k
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
287
288
194k
    if (mask.width  == extents->bounded.width &&
289
194k
  mask.height == extents->bounded.height)
290
194k
  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
0
{
335
0
    cairo_int_status_t status;
336
0
    if (! _cairo_composite_rectangles_init (extents,
337
0
              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
0
    extents->original_mask_pattern = mask;
344
0
    _cairo_composite_reduce_pattern (mask, &extents->mask_pattern);
345
0
    _cairo_pattern_get_extents (&extents->mask_pattern.base, &extents->mask, surface->is_vector);
346
347
0
    status = _cairo_composite_rectangles_intersect (extents, clip);
348
0
    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
349
0
  _cairo_composite_rectangles_fini(extents);
350
0
    }
351
0
    return status;
352
0
}
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
1.04M
{
364
1.04M
    cairo_int_status_t status;
365
1.04M
    if (! _cairo_composite_rectangles_init (extents,
366
1.04M
              surface, op, source, clip))
367
52
    {
368
52
  _cairo_composite_rectangles_fini(extents);
369
52
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
370
52
    }
371
372
1.04M
    _cairo_path_fixed_approximate_stroke_extents (path, style, ctm, surface->is_vector, &extents->mask);
373
374
1.04M
    status = _cairo_composite_rectangles_intersect (extents, clip);
375
1.04M
    if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
376
955k
  _cairo_composite_rectangles_fini(extents);
377
955k
    }
378
1.04M
    return status;
379
1.04M
}
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
9.64M
{
389
9.64M
    cairo_int_status_t status;
390
9.64M
    if (! _cairo_composite_rectangles_init (extents,
391
9.64M
              surface, op, source, clip))
392
56
    {
393
56
  _cairo_composite_rectangles_fini(extents);
394
56
  return CAIRO_INT_STATUS_NOTHING_TO_DO;
395
56
    }
396
397
9.64M
    _cairo_path_fixed_approximate_fill_extents (path, &extents->mask);
398
399
9.64M
    status = _cairo_composite_rectangles_intersect (extents, clip);
400
9.64M
        if(status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
401
8.95M
    _cairo_composite_rectangles_fini(extents);
402
8.95M
    }
403
9.64M
    return status;
404
9.64M
}
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
429k
{
468
429k
    cairo_status_t status;
469
429k
    cairo_int_status_t int_status;
470
471
429k
    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
429k
    status = _cairo_scaled_font_glyph_device_extents (scaled_font,
477
429k
                  glyphs, num_glyphs,
478
429k
                  &extents->mask,
479
429k
                  overlap);
480
429k
    if (unlikely (status)) {
481
0
  _cairo_composite_rectangles_fini(extents);
482
0
  return status;
483
0
    }
484
429k
    if (overlap && *overlap &&
485
28.3k
  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
429k
    int_status = _cairo_composite_rectangles_intersect (extents, clip);
492
429k
    if (int_status == CAIRO_INT_STATUS_NOTHING_TO_DO) {
493
401k
  _cairo_composite_rectangles_fini(extents);
494
401k
    }
495
429k
    return int_status;
496
429k
}
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
}