1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2002 University of Southern California
5
 * Copyright © 2005 Red Hat, Inc.
6
 * Copyright © 2011 Intel Corporation
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it either under the terms of the GNU Lesser General Public
10
 * License version 2.1 as published by the Free Software Foundation
11
 * (the "LGPL") or, at your option, under the terms of the Mozilla
12
 * Public License Version 1.1 (the "MPL"). If you do not alter this
13
 * notice, a recipient may use your version of this file under either
14
 * the MPL or the LGPL.
15
 *
16
 * You should have received a copy of the LGPL along with this library
17
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
19
 * You should have received a copy of the MPL along with this library
20
 * in the file COPYING-MPL-1.1
21
 *
22
 * The contents of this file are subject to the Mozilla Public License
23
 * Version 1.1 (the "License"); you may not use this file except in
24
 * compliance with the License. You may obtain a copy of the License at
25
 * http://www.mozilla.org/MPL/
26
 *
27
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
28
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
29
 * the specific language governing rights and limitations.
30
 *
31
 * The Original Code is the cairo graphics library.
32
 *
33
 * The Initial Developer of the Original Code is University of Southern
34
 * California.
35
 *
36
 * Contributor(s):
37
 *	Carl D. Worth <cworth@cworth.org>
38
 *      Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
39
 *	Chris Wilson <chris@chris-wilson.co.uk>
40
 */
41

            
42
#include "cairoint.h"
43

            
44
#include "cairo-compositor-private.h"
45
#include "cairo-clip-inline.h"
46
#include "cairo-clip-private.h"
47
#include "cairo-image-surface-private.h"
48
#include "cairo-paginated-private.h"
49
#include "cairo-pattern-inline.h"
50
#include "cairo-region-private.h"
51
#include "cairo-recording-surface-inline.h"
52
#include "cairo-spans-compositor-private.h"
53
#include "cairo-surface-subsurface-private.h"
54
#include "cairo-surface-snapshot-private.h"
55
#include "cairo-surface-observer-private.h"
56

            
57
typedef struct {
58
    cairo_polygon_t	*polygon;
59
    cairo_fill_rule_t	 fill_rule;
60
    cairo_antialias_t	 antialias;
61
} composite_spans_info_t;
62

            
63
static cairo_int_status_t
64
composite_polygon (const cairo_spans_compositor_t	*compositor,
65
		   cairo_composite_rectangles_t		 *extents,
66
		   cairo_polygon_t			*polygon,
67
		   cairo_fill_rule_t			 fill_rule,
68
		   cairo_antialias_t			 antialias);
69

            
70
static cairo_int_status_t
71
composite_boxes (const cairo_spans_compositor_t *compositor,
72
		 cairo_composite_rectangles_t *extents,
73
		 cairo_boxes_t		*boxes);
74

            
75
static cairo_int_status_t
76
clip_and_composite_polygon (const cairo_spans_compositor_t	*compositor,
77
			    cairo_composite_rectangles_t	 *extents,
78
			    cairo_polygon_t			*polygon,
79
			    cairo_fill_rule_t			 fill_rule,
80
			    cairo_antialias_t			 antialias);
81
static cairo_surface_t *
82
54
get_clip_surface (const cairo_spans_compositor_t *compositor,
83
		  cairo_surface_t *dst,
84
		  const cairo_clip_t *clip,
85
		  const cairo_rectangle_int_t *extents)
86
{
87
    cairo_composite_rectangles_t composite;
88
    cairo_surface_t *surface;
89
    cairo_box_t box;
90
    cairo_polygon_t polygon;
91
    const cairo_clip_path_t *clip_path;
92
    cairo_antialias_t antialias;
93
    cairo_fill_rule_t fill_rule;
94
    cairo_int_status_t status;
95

            
96
54
    assert (clip->path);
97

            
98
54
    surface = _cairo_surface_create_scratch (dst,
99
					     CAIRO_CONTENT_ALPHA,
100
54
					     extents->width,
101
54
					     extents->height,
102
					     CAIRO_COLOR_TRANSPARENT);
103

            
104
54
    _cairo_box_from_rectangle (&box, extents);
105
54
    _cairo_polygon_init (&polygon, &box, 1);
106

            
107
54
    clip_path = clip->path;
108
54
    status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
109
54
						clip_path->tolerance,
110
						&polygon);
111
54
    if (unlikely (status))
112
	goto cleanup_polygon;
113

            
114
54
    polygon.num_limits = 0;
115

            
116
54
    antialias = clip_path->antialias;
117
54
    fill_rule = clip_path->fill_rule;
118

            
119
54
    if (clip->boxes) {
120
	cairo_polygon_t intersect;
121
	cairo_boxes_t tmp;
122

            
123
	_cairo_boxes_init_for_array (&tmp, clip->boxes, clip->num_boxes);
124
	status= _cairo_polygon_init_boxes (&intersect, &tmp);
125
	if (unlikely (status))
126
	    goto cleanup_polygon;
127

            
128
	status = _cairo_polygon_intersect (&polygon, fill_rule,
129
					   &intersect, CAIRO_FILL_RULE_WINDING);
130
	_cairo_polygon_fini (&intersect);
131

            
132
	if (unlikely (status))
133
	    goto cleanup_polygon;
134

            
135
	fill_rule = CAIRO_FILL_RULE_WINDING;
136
    }
137

            
138
54
    polygon.limits = NULL;
139
54
    polygon.num_limits = 0;
140

            
141
54
    clip_path = clip_path->prev;
142
60
    while (clip_path) {
143
6
	if (clip_path->antialias == antialias) {
144
	    cairo_polygon_t next;
145

            
146
	    _cairo_polygon_init (&next, NULL, 0);
147
	    status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
148
							clip_path->tolerance,
149
							&next);
150
	    if (likely (status == CAIRO_INT_STATUS_SUCCESS))
151
		status = _cairo_polygon_intersect (&polygon, fill_rule,
152
						   &next, clip_path->fill_rule);
153
	    _cairo_polygon_fini (&next);
154
	    if (unlikely (status))
155
		goto cleanup_polygon;
156

            
157
	    fill_rule = CAIRO_FILL_RULE_WINDING;
158
	}
159

            
160
6
	clip_path = clip_path->prev;
161
    }
162

            
163
54
    _cairo_polygon_translate (&polygon, -extents->x, -extents->y);
164
54
    status = _cairo_composite_rectangles_init_for_polygon (&composite, surface,
165
							   CAIRO_OPERATOR_ADD,
166
							   &_cairo_pattern_white.base,
167
							   &polygon,
168
							   NULL);
169
54
    if (unlikely (status))
170
	goto cleanup_polygon;
171

            
172
54
    status = composite_polygon (compositor, &composite,
173
				&polygon, fill_rule, antialias);
174
54
    _cairo_composite_rectangles_fini (&composite);
175
54
    _cairo_polygon_fini (&polygon);
176
54
    if (unlikely (status))
177
	goto error;
178

            
179
54
    _cairo_polygon_init (&polygon, &box, 1);
180

            
181
54
    clip_path = clip->path;
182
54
    antialias = clip_path->antialias == CAIRO_ANTIALIAS_DEFAULT ? CAIRO_ANTIALIAS_NONE : CAIRO_ANTIALIAS_DEFAULT;
183
54
    clip_path = clip_path->prev;
184
60
    while (clip_path) {
185
6
	if (clip_path->antialias == antialias) {
186
6
	    if (polygon.num_edges == 0) {
187
6
		status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
188
6
							    clip_path->tolerance,
189
							    &polygon);
190

            
191
6
		fill_rule = clip_path->fill_rule;
192
6
		polygon.limits = NULL;
193
6
		polygon.num_limits = 0;
194
	    } else {
195
		cairo_polygon_t next;
196

            
197
		_cairo_polygon_init (&next, NULL, 0);
198
		status = _cairo_path_fixed_fill_to_polygon (&clip_path->path,
199
							    clip_path->tolerance,
200
							    &next);
201
		if (likely (status == CAIRO_INT_STATUS_SUCCESS))
202
		    status = _cairo_polygon_intersect (&polygon, fill_rule,
203
						       &next, clip_path->fill_rule);
204
		_cairo_polygon_fini (&next);
205
		fill_rule = CAIRO_FILL_RULE_WINDING;
206
	    }
207
6
	    if (unlikely (status))
208
		goto error;
209
	}
210

            
211
6
	clip_path = clip_path->prev;
212
    }
213

            
214
54
    if (polygon.num_edges) {
215
6
	_cairo_polygon_translate (&polygon, -extents->x, -extents->y);
216
6
	status = _cairo_composite_rectangles_init_for_polygon (&composite, surface,
217
							       CAIRO_OPERATOR_IN,
218
							       &_cairo_pattern_white.base,
219
							       &polygon,
220
							       NULL);
221
6
	if (unlikely (status))
222
	    goto cleanup_polygon;
223

            
224
6
	status = composite_polygon (compositor, &composite,
225
				    &polygon, fill_rule, antialias);
226
6
	_cairo_composite_rectangles_fini (&composite);
227
6
	_cairo_polygon_fini (&polygon);
228
6
	if (unlikely (status))
229
	    goto error;
230
    }
231

            
232
54
    return surface;
233

            
234
cleanup_polygon:
235
    _cairo_polygon_fini (&polygon);
236
error:
237
    cairo_surface_destroy (surface);
238
    return _cairo_int_surface_create_in_error (status);
239
}
240

            
241
static cairo_int_status_t
242
fixup_unbounded_mask (const cairo_spans_compositor_t *compositor,
243
		      const cairo_composite_rectangles_t *extents,
244
		      cairo_boxes_t *boxes)
245
{
246
    cairo_composite_rectangles_t composite;
247
    cairo_surface_t *clip;
248
    cairo_int_status_t status;
249

            
250
    TRACE((stderr, "%s\n", __FUNCTION__));
251

            
252
    clip = get_clip_surface (compositor, extents->surface, extents->clip,
253
			     &extents->unbounded);
254
    if (unlikely (clip->status)) {
255
	if ((cairo_int_status_t)clip->status == CAIRO_INT_STATUS_NOTHING_TO_DO)
256
	    return CAIRO_STATUS_SUCCESS;
257

            
258
	return clip->status;
259
    }
260

            
261
    status = _cairo_composite_rectangles_init_for_boxes (&composite,
262
							 extents->surface,
263
							 CAIRO_OPERATOR_CLEAR,
264
							 &_cairo_pattern_clear.base,
265
							 boxes,
266
							 NULL);
267
    if (unlikely (status))
268
	goto cleanup_clip;
269

            
270
    _cairo_pattern_init_for_surface (&composite.mask_pattern.surface, clip);
271
    composite.mask_pattern.base.filter = CAIRO_FILTER_NEAREST;
272
    composite.mask_pattern.base.extend = CAIRO_EXTEND_NONE;
273

            
274
    status = composite_boxes (compositor, &composite, boxes);
275

            
276
    _cairo_pattern_fini (&composite.mask_pattern.base);
277
    _cairo_composite_rectangles_fini (&composite);
278

            
279
cleanup_clip:
280
    cairo_surface_destroy (clip);
281
    return status;
282
}
283

            
284
static cairo_int_status_t
285
36
fixup_unbounded_polygon (const cairo_spans_compositor_t *compositor,
286
			 const cairo_composite_rectangles_t *extents,
287
			 cairo_boxes_t *boxes)
288
{
289
    cairo_polygon_t polygon, intersect;
290
    cairo_composite_rectangles_t composite;
291
    cairo_fill_rule_t fill_rule;
292
    cairo_antialias_t antialias;
293
    cairo_int_status_t status;
294

            
295
    TRACE((stderr, "%s\n", __FUNCTION__));
296

            
297
    /* Can we treat the clip as a regular clear-polygon and use it to fill? */
298
36
    status = _cairo_clip_get_polygon (extents->clip, &polygon,
299
				      &fill_rule, &antialias);
300
36
    if (status == CAIRO_INT_STATUS_UNSUPPORTED)
301
	return status;
302

            
303
36
    status= _cairo_polygon_init_boxes (&intersect, boxes);
304
36
    if (unlikely (status))
305
	goto cleanup_polygon;
306

            
307
36
    status = _cairo_polygon_intersect (&polygon, fill_rule,
308
				       &intersect, CAIRO_FILL_RULE_WINDING);
309
36
    _cairo_polygon_fini (&intersect);
310

            
311
36
    if (unlikely (status))
312
	goto cleanup_polygon;
313

            
314
36
    status = _cairo_composite_rectangles_init_for_polygon (&composite,
315
36
							   extents->surface,
316
							   CAIRO_OPERATOR_CLEAR,
317
							   &_cairo_pattern_clear.base,
318
							   &polygon,
319
							   NULL);
320
36
    if (unlikely (status))
321
	goto cleanup_polygon;
322

            
323
36
    status = composite_polygon (compositor, &composite,
324
				&polygon, fill_rule, antialias);
325

            
326
36
    _cairo_composite_rectangles_fini (&composite);
327
36
cleanup_polygon:
328
36
    _cairo_polygon_fini (&polygon);
329

            
330
36
    return status;
331
}
332

            
333
static cairo_int_status_t
334
285
fixup_unbounded_boxes (const cairo_spans_compositor_t *compositor,
335
		       const cairo_composite_rectangles_t *extents,
336
		       cairo_boxes_t *boxes)
337
{
338
    cairo_boxes_t tmp, clear;
339
    cairo_box_t box;
340
    cairo_int_status_t status;
341

            
342
285
    assert (boxes->is_pixel_aligned);
343

            
344
    TRACE ((stderr, "%s\n", __FUNCTION__));
345
285
    if (extents->bounded.width  == extents->unbounded.width &&
346
96
	extents->bounded.height == extents->unbounded.height)
347
    {
348
90
	return CAIRO_STATUS_SUCCESS;
349
    }
350

            
351
    /* subtract the drawn boxes from the unbounded area */
352
195
    _cairo_boxes_init (&clear);
353

            
354
195
    box.p1.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width);
355
195
    box.p1.y = _cairo_fixed_from_int (extents->unbounded.y);
356
195
    box.p2.x = _cairo_fixed_from_int (extents->unbounded.x);
357
195
    box.p2.y = _cairo_fixed_from_int (extents->unbounded.y + extents->unbounded.height);
358

            
359
195
    if (boxes->num_boxes) {
360
96
	_cairo_boxes_init (&tmp);
361

            
362
96
	status = _cairo_boxes_add (&tmp, CAIRO_ANTIALIAS_DEFAULT, &box);
363
96
	assert (status == CAIRO_INT_STATUS_SUCCESS);
364

            
365
96
	tmp.chunks.next = &boxes->chunks;
366
96
	tmp.num_boxes += boxes->num_boxes;
367

            
368
96
	status = _cairo_bentley_ottmann_tessellate_boxes (&tmp,
369
							  CAIRO_FILL_RULE_WINDING,
370
							  &clear);
371
96
	tmp.chunks.next = NULL;
372
96
	if (unlikely (status))
373
	    goto error;
374
    } else {
375
99
	box.p1.x = _cairo_fixed_from_int (extents->unbounded.x);
376
99
	box.p2.x = _cairo_fixed_from_int (extents->unbounded.x + extents->unbounded.width);
377

            
378
99
	status = _cairo_boxes_add (&clear, CAIRO_ANTIALIAS_DEFAULT, &box);
379
99
	assert (status == CAIRO_INT_STATUS_SUCCESS);
380
    }
381

            
382
    /* If we have a clip polygon, we need to intersect with that as well */
383
195
    if (extents->clip->path) {
384
36
	status = fixup_unbounded_polygon (compositor, extents, &clear);
385
36
	if (status == CAIRO_INT_STATUS_UNSUPPORTED)
386
	    status = fixup_unbounded_mask (compositor, extents, &clear);
387
    } else {
388
	/* Otherwise just intersect with the clip boxes */
389
159
	if (extents->clip->num_boxes) {
390
141
	    _cairo_boxes_init_for_array (&tmp,
391
141
					 extents->clip->boxes,
392
141
					 extents->clip->num_boxes);
393
141
	    status = _cairo_boxes_intersect (&clear, &tmp, &clear);
394
141
	    if (unlikely (status))
395
		goto error;
396
	}
397

            
398
159
	if (clear.is_pixel_aligned) {
399
132
	    status = compositor->fill_boxes (extents->surface,
400
					     CAIRO_OPERATOR_CLEAR,
401
					     CAIRO_COLOR_TRANSPARENT,
402
					     &clear);
403
	} else {
404
	    cairo_composite_rectangles_t composite;
405

            
406
27
	    status = _cairo_composite_rectangles_init_for_boxes (&composite,
407
27
								 extents->surface,
408
								 CAIRO_OPERATOR_CLEAR,
409
								 &_cairo_pattern_clear.base,
410
								 &clear,
411
								 NULL);
412
27
	    if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
413
27
		status = composite_boxes (compositor, &composite, &clear);
414
27
		_cairo_composite_rectangles_fini (&composite);
415
	    }
416
	}
417
    }
418

            
419
195
error:
420
195
    _cairo_boxes_fini (&clear);
421
195
    return status;
422
}
423

            
424
static cairo_surface_t *
425
223299
unwrap_source (const cairo_pattern_t *pattern)
426
{
427
    cairo_rectangle_int_t limit;
428

            
429
223299
    return _cairo_pattern_get_source ((cairo_surface_pattern_t *)pattern,
430
				      &limit);
431
}
432

            
433
static cairo_bool_t
434
599743
is_recording_pattern (const cairo_pattern_t *pattern)
435
{
436
    cairo_surface_t *surface;
437

            
438
599743
    if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
439
332692
	return FALSE;
440

            
441
267051
    surface = ((const cairo_surface_pattern_t *) pattern)->surface;
442
267051
    return _cairo_surface_is_recording (surface);
443
}
444

            
445
static cairo_bool_t
446
599743
recording_pattern_contains_sample (const cairo_pattern_t *pattern,
447
				   const cairo_rectangle_int_t *sample)
448
{
449
    cairo_recording_surface_t *surface;
450

            
451
599743
    if (! is_recording_pattern (pattern))
452
376444
	return FALSE;
453

            
454
223299
    if (pattern->extend == CAIRO_EXTEND_NONE)
455
223290
	return TRUE;
456

            
457
9
    surface = (cairo_recording_surface_t *) unwrap_source (pattern);
458
9
    if (surface->unbounded)
459
	return TRUE;
460

            
461
9
    return _cairo_rectangle_contains_rectangle (&surface->extents, sample);
462
}
463

            
464
static cairo_bool_t
465
706622
op_reduces_to_source (const cairo_composite_rectangles_t *extents,
466
		      cairo_bool_t no_mask)
467
{
468
706622
    if (extents->op == CAIRO_OPERATOR_SOURCE)
469
227816
	return TRUE;
470

            
471
478806
    if (extents->surface->is_clear)
472
266641
	return extents->op == CAIRO_OPERATOR_OVER || extents->op == CAIRO_OPERATOR_ADD;
473

            
474
212165
    if (no_mask && extents->op == CAIRO_OPERATOR_OVER)
475
207485
	return _cairo_pattern_is_opaque (&extents->source_pattern.base,
476
					 &extents->source_sample_area);
477

            
478
4680
    return FALSE;
479
}
480

            
481
static cairo_status_t
482
43761
upload_boxes (const cairo_spans_compositor_t *compositor,
483
	      const cairo_composite_rectangles_t *extents,
484
	      cairo_boxes_t *boxes)
485
{
486
43761
    cairo_surface_t *dst = extents->surface;
487
43761
    const cairo_surface_pattern_t *source = &extents->source_pattern.surface;
488
    cairo_surface_t *src;
489
    cairo_rectangle_int_t limit;
490
    cairo_int_status_t status;
491
    int tx, ty;
492

            
493
    TRACE ((stderr, "%s\n", __FUNCTION__));
494

            
495
43761
    src = _cairo_pattern_get_source(source, &limit);
496
43761
    if (!(src->type == CAIRO_SURFACE_TYPE_IMAGE || src->type == dst->type))
497
11203
	return CAIRO_INT_STATUS_UNSUPPORTED;
498

            
499
32558
    if (! _cairo_matrix_is_integer_translation (&source->base.matrix, &tx, &ty))
500
15097
	return CAIRO_INT_STATUS_UNSUPPORTED;
501

            
502
    /* Check that the data is entirely within the image */
503
17461
    if (extents->bounded.x + tx < limit.x || extents->bounded.y + ty < limit.y)
504
8267
	return CAIRO_INT_STATUS_UNSUPPORTED;
505

            
506
9194
    if (extents->bounded.x + extents->bounded.width  + tx > limit.x + limit.width ||
507
4322
	extents->bounded.y + extents->bounded.height + ty > limit.y + limit.height)
508
5757
	return CAIRO_INT_STATUS_UNSUPPORTED;
509

            
510
3437
    tx += limit.x;
511
3437
    ty += limit.y;
512

            
513
3437
    if (src->type == CAIRO_SURFACE_TYPE_IMAGE)
514
3437
	status = compositor->draw_image_boxes (dst,
515
					       (cairo_image_surface_t *)src,
516
					       boxes, tx, ty);
517
    else
518
	status = compositor->copy_boxes (dst, src, boxes, &extents->bounded,
519
					 tx, ty);
520

            
521
3437
    return status;
522
}
523

            
524
static cairo_bool_t
525
707009
_clip_is_region (const cairo_clip_t *clip)
526
{
527
    int i;
528

            
529
707009
    if (clip->is_region)
530
705680
	return TRUE;
531

            
532
1329
    if (clip->path)
533
300
	return FALSE;
534

            
535
2163
    for (i = 0; i < clip->num_boxes; i++) {
536
1197
	const cairo_box_t *b = &clip->boxes[i];
537
1197
	if (!_cairo_fixed_is_integer (b->p1.x | b->p1.y |  b->p2.x | b->p2.y))
538
63
	    return FALSE;
539
    }
540

            
541
966
    return TRUE;
542
}
543

            
544
static cairo_int_status_t
545
706667
composite_aligned_boxes (const cairo_spans_compositor_t		*compositor,
546
			 const cairo_composite_rectangles_t	*extents,
547
			 cairo_boxes_t				*boxes)
548
{
549
706667
    cairo_surface_t *dst = extents->surface;
550
706667
    cairo_operator_t op = extents->op;
551
706667
    const cairo_pattern_t *source = &extents->source_pattern.base;
552
    cairo_int_status_t status;
553
706667
    cairo_bool_t need_clip_mask = ! _clip_is_region (extents->clip);
554
    cairo_bool_t op_is_source;
555
    cairo_bool_t no_mask;
556
    cairo_bool_t inplace;
557

            
558
    TRACE ((stderr, "%s: need_clip_mask=%d, is-bounded=%d\n",
559
	    __FUNCTION__, need_clip_mask, extents->is_bounded));
560
706667
    if (need_clip_mask && ! extents->is_bounded) {
561
	TRACE ((stderr, "%s: unsupported clip\n", __FUNCTION__));
562
45
	return CAIRO_INT_STATUS_UNSUPPORTED;
563
    }
564

            
565
1411816
    no_mask = extents->mask_pattern.base.type == CAIRO_PATTERN_TYPE_SOLID &&
566
705194
	CAIRO_COLOR_IS_OPAQUE (&extents->mask_pattern.solid.color);
567
706622
    op_is_source = op_reduces_to_source (extents, no_mask);
568
706622
    inplace = ! need_clip_mask && op_is_source && no_mask;
569

            
570
    TRACE ((stderr, "%s: op-is-source=%d [op=%d], no-mask=%d, inplace=%d\n",
571
	    __FUNCTION__, op_is_source, op, no_mask, inplace));
572

            
573
706622
    if (op == CAIRO_OPERATOR_SOURCE && (need_clip_mask || ! no_mask)) {
574
	/* SOURCE with a mask is actually a LERP in cairo semantics */
575
369
	if ((compositor->flags & CAIRO_SPANS_COMPOSITOR_HAS_LERP) == 0) {
576
	    TRACE ((stderr, "%s: unsupported lerp\n", __FUNCTION__));
577
369
	    return CAIRO_INT_STATUS_UNSUPPORTED;
578
	}
579
    }
580

            
581
    /* Are we just copying a recording surface? */
582
1305996
    if (inplace &&
583
599743
	recording_pattern_contains_sample (&extents->source_pattern.base,
584
					   &extents->source_sample_area))
585
    {
586
	cairo_clip_t *recording_clip;
587
223290
	const cairo_pattern_t *source = &extents->source_pattern.base;
588
	const cairo_matrix_t *m;
589
	cairo_matrix_t matrix;
590

            
591
	/* XXX could also do tiling repeat modes... */
592

            
593
	/* first clear the area about to be overwritten */
594
223290
	if (! dst->is_clear) {
595
223086
	    status = compositor->fill_boxes (dst,
596
					     CAIRO_OPERATOR_CLEAR,
597
					     CAIRO_COLOR_TRANSPARENT,
598
					     boxes);
599
223086
	    if (unlikely (status))
600
		return status;
601

            
602
223086
	    dst->is_clear = TRUE;
603
	}
604

            
605
223290
	m = &source->matrix;
606
223290
	if (_cairo_surface_has_device_transform (dst)) {
607
	    cairo_matrix_multiply (&matrix,
608
				   &source->matrix,
609
				   &dst->device_transform);
610
	    m = &matrix;
611
	}
612

            
613
223290
	recording_clip = _cairo_clip_from_boxes (boxes);
614
223290
	status = _cairo_recording_surface_replay_with_clip (unwrap_source (source),
615
							    m, dst, recording_clip);
616
223290
	_cairo_clip_destroy (recording_clip);
617

            
618
223290
	return status;
619
    }
620

            
621
482963
    status = CAIRO_INT_STATUS_UNSUPPORTED;
622
887652
    if (! need_clip_mask && no_mask && source->type == CAIRO_PATTERN_TYPE_SOLID) {
623
	const cairo_color_t *color;
624

            
625
404689
	color = &((cairo_solid_pattern_t *) source)->color;
626
404689
	if (op_is_source)
627
332389
	    op = CAIRO_OPERATOR_SOURCE;
628
404689
	status = compositor->fill_boxes (dst, op, color, boxes);
629
78274
    } else if (inplace && source->type == CAIRO_PATTERN_TYPE_SURFACE) {
630
43761
	status = upload_boxes (compositor, extents, boxes);
631
    }
632
482963
    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
633
	cairo_surface_t *src;
634
74837
	cairo_surface_t *mask = NULL;
635
	int src_x, src_y;
636
74837
	int mask_x = 0, mask_y = 0;
637

            
638
	/* All typical cases will have been resolved before now... */
639
74837
	if (need_clip_mask) {
640
54
	    mask = get_clip_surface (compositor, dst, extents->clip,
641
				     &extents->bounded);
642
54
	    if (unlikely (mask->status))
643
		return mask->status;
644

            
645
54
	    mask_x = -extents->bounded.x;
646
54
	    mask_y = -extents->bounded.y;
647
	}
648

            
649
	/* XXX but this is still ugly */
650
74837
	if (! no_mask) {
651
2634
	    src = compositor->pattern_to_surface (dst,
652
						  &extents->mask_pattern.base,
653
						  TRUE,
654
						  &extents->bounded,
655
						  &extents->mask_sample_area,
656
						  &src_x, &src_y);
657
2634
	    if (unlikely (src->status)) {
658
		cairo_surface_destroy (mask);
659
		return src->status;
660
	    }
661

            
662
2634
	    if (mask != NULL) {
663
48
		status = compositor->composite_boxes (mask, CAIRO_OPERATOR_IN,
664
						      src, NULL,
665
						      src_x, src_y,
666
						      0, 0,
667
						      mask_x, mask_y,
668
						      boxes, &extents->bounded);
669

            
670
48
		cairo_surface_destroy (src);
671
	    } else {
672
2586
		mask = src;
673
2586
		mask_x = src_x;
674
2586
		mask_y = src_y;
675
	    }
676
	}
677

            
678
74837
	src = compositor->pattern_to_surface (dst, source, FALSE,
679
					      &extents->bounded,
680
					      &extents->source_sample_area,
681
					      &src_x, &src_y);
682
74837
	if (likely (src->status == CAIRO_STATUS_SUCCESS)) {
683
74837
	    status = compositor->composite_boxes (dst, op, src, mask,
684
						  src_x, src_y,
685
						  mask_x, mask_y,
686
						  0, 0,
687
						  boxes, &extents->bounded);
688
74837
	    cairo_surface_destroy (src);
689
	} else
690
	    status = src->status;
691

            
692
74837
	cairo_surface_destroy (mask);
693
    }
694

            
695
482963
    if (status == CAIRO_INT_STATUS_SUCCESS && ! extents->is_bounded)
696
186
	status = fixup_unbounded_boxes (compositor, extents, boxes);
697

            
698
482963
    return status;
699
}
700

            
701
static cairo_bool_t
702
3021
composite_needs_clip (const cairo_composite_rectangles_t *composite,
703
		      const cairo_box_t *extents)
704
{
705
3021
    return !_cairo_clip_contains_box (composite->clip, extents);
706
}
707

            
708
static cairo_int_status_t
709
3021
composite_boxes (const cairo_spans_compositor_t *compositor,
710
		 cairo_composite_rectangles_t *extents,
711
		 cairo_boxes_t		*boxes)
712
{
713
    cairo_abstract_span_renderer_t renderer;
714
    cairo_rectangular_scan_converter_t converter;
715
    const struct _cairo_boxes_chunk *chunk;
716
    cairo_int_status_t status;
717
    cairo_box_t box;
718

            
719
    TRACE ((stderr, "%s\n", __FUNCTION__));
720
3021
    _cairo_box_from_rectangle (&box, &extents->unbounded);
721
3021
    if (composite_needs_clip (extents, &box)) {
722
	TRACE ((stderr, "%s: unsupported clip\n", __FUNCTION__));
723
90
	return CAIRO_INT_STATUS_UNSUPPORTED;
724
    }
725

            
726
2931
    _cairo_rectangular_scan_converter_init (&converter, &extents->unbounded);
727
5934
    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
728
3003
	const cairo_box_t *box = chunk->base;
729
	int i;
730

            
731
109035
	for (i = 0; i < chunk->count; i++) {
732
106032
	    status = _cairo_rectangular_scan_converter_add_box (&converter, &box[i], 1);
733
106032
	    if (unlikely (status))
734
		goto cleanup_converter;
735
	}
736
    }
737

            
738
2931
    status = compositor->renderer_init (&renderer, extents,
739
					CAIRO_ANTIALIAS_DEFAULT, FALSE);
740
2931
    if (likely (status == CAIRO_INT_STATUS_SUCCESS))
741
2574
	status = converter.base.generate (&converter.base, &renderer.base);
742
2931
    compositor->renderer_fini (&renderer, status);
743

            
744
2931
cleanup_converter:
745
2931
    converter.base.destroy (&converter.base);
746
2931
    return status;
747
}
748

            
749
static cairo_int_status_t
750
179999
composite_polygon (const cairo_spans_compositor_t	*compositor,
751
		   cairo_composite_rectangles_t		 *extents,
752
		   cairo_polygon_t			*polygon,
753
		   cairo_fill_rule_t			 fill_rule,
754
		   cairo_antialias_t			 antialias)
755
{
756
    cairo_abstract_span_renderer_t renderer;
757
    cairo_scan_converter_t *converter;
758
    cairo_bool_t needs_clip;
759
    cairo_int_status_t status;
760

            
761
179999
    if (extents->is_bounded)
762
179657
	needs_clip = extents->clip->path != NULL;
763
    else
764
342
	needs_clip = !_clip_is_region (extents->clip) || extents->clip->num_boxes > 1;
765
    TRACE ((stderr, "%s - needs_clip=%d\n", __FUNCTION__, needs_clip));
766
179999
    if (needs_clip) {
767
	TRACE ((stderr, "%s: unsupported clip\n", __FUNCTION__));
768
276
	return CAIRO_INT_STATUS_UNSUPPORTED;
769
	converter = _cairo_clip_tor_scan_converter_create (extents->clip,
770
							   polygon,
771
							   fill_rule, antialias);
772
    } else {
773
179723
	const cairo_rectangle_int_t *r = &extents->unbounded;
774

            
775
179723
	if (antialias == CAIRO_ANTIALIAS_FAST) {
776
3
	    converter = _cairo_tor22_scan_converter_create (r->x, r->y,
777
3
							    r->x + r->width,
778
3
							    r->y + r->height,
779
							    fill_rule, antialias);
780
3
	    status = _cairo_tor22_scan_converter_add_polygon (converter, polygon);
781
179720
	} else if (antialias == CAIRO_ANTIALIAS_NONE) {
782
786
	    converter = _cairo_mono_scan_converter_create (r->x, r->y,
783
786
							   r->x + r->width,
784
786
							   r->y + r->height,
785
							   fill_rule);
786
786
	    status = _cairo_mono_scan_converter_add_polygon (converter, polygon);
787
	} else {
788
178934
	    converter = _cairo_tor_scan_converter_create (r->x, r->y,
789
178934
							  r->x + r->width,
790
178934
							  r->y + r->height,
791
							  fill_rule, antialias);
792
178934
	    status = _cairo_tor_scan_converter_add_polygon (converter, polygon);
793
	}
794
    }
795
179723
    if (unlikely (status))
796
	goto cleanup_converter;
797

            
798
179723
    status = compositor->renderer_init (&renderer, extents,
799
					antialias, needs_clip);
800
179723
    if (likely (status == CAIRO_INT_STATUS_SUCCESS))
801
179315
	status = converter->generate (converter, &renderer.base);
802
179723
    compositor->renderer_fini (&renderer, status);
803

            
804
179723
cleanup_converter:
805
179723
    converter->destroy (converter);
806
179723
    return status;
807
}
808

            
809
static cairo_int_status_t
810
909242
trim_extents_to_boxes (cairo_composite_rectangles_t *extents,
811
		       cairo_boxes_t *boxes)
812
{
813
    cairo_box_t box;
814

            
815
909242
    _cairo_boxes_extents (boxes, &box);
816
909242
    return _cairo_composite_rectangles_intersect_mask_extents (extents, &box);
817
}
818

            
819
static cairo_int_status_t
820
198237
trim_extents_to_polygon (cairo_composite_rectangles_t *extents,
821
			 cairo_polygon_t *polygon)
822
{
823
396474
    return _cairo_composite_rectangles_intersect_mask_extents (extents,
824
198237
							       &polygon->extents);
825
}
826

            
827
static cairo_int_status_t
828
909242
clip_and_composite_boxes (const cairo_spans_compositor_t	*compositor,
829
			  cairo_composite_rectangles_t		*extents,
830
			  cairo_boxes_t				*boxes)
831
{
832
    cairo_int_status_t status;
833
    cairo_polygon_t polygon;
834

            
835
    TRACE ((stderr, "%s\n", __FUNCTION__));
836
909242
    status = trim_extents_to_boxes (extents, boxes);
837
909242
    if (unlikely (status))
838
197718
	return status;
839

            
840
711524
    if (boxes->num_boxes == 0) {
841
84
	if (extents->is_bounded)
842
	    return CAIRO_STATUS_SUCCESS;
843

            
844
84
	return fixup_unbounded_boxes (compositor, extents, boxes);
845
    }
846

            
847
    /* Can we reduce drawing through a clip-mask to simply drawing the clip? */
848
711440
    if (extents->clip->path != NULL && extents->is_bounded) {
849
	cairo_polygon_t polygon;
850
	cairo_fill_rule_t fill_rule;
851
	cairo_antialias_t antialias;
852
	cairo_clip_t *clip;
853

            
854
2250
	clip = _cairo_clip_copy (extents->clip);
855
2250
	clip = _cairo_clip_intersect_boxes (clip, boxes);
856
2250
	if (_cairo_clip_is_all_clipped (clip))
857
2193
	    return CAIRO_INT_STATUS_NOTHING_TO_DO;
858

            
859
2250
	status = _cairo_clip_get_polygon (clip, &polygon,
860
					  &fill_rule, &antialias);
861
2250
	_cairo_clip_path_destroy (clip->path);
862
2250
	clip->path = NULL;
863
2250
	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
864
2244
	    cairo_clip_t *saved_clip = extents->clip;
865
2244
	    extents->clip = clip;
866

            
867
2244
	    status = clip_and_composite_polygon (compositor, extents, &polygon,
868
						 fill_rule, antialias);
869

            
870
2244
	    clip = extents->clip;
871
2244
	    extents->clip = saved_clip;
872

            
873
2244
	    _cairo_polygon_fini (&polygon);
874
	}
875
2250
	_cairo_clip_destroy (clip);
876

            
877
2250
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
878
2193
	    return status;
879
    }
880

            
881
709247
    if (boxes->is_pixel_aligned) {
882
706667
	status = composite_aligned_boxes (compositor, extents, boxes);
883
706667
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
884
706253
	    return status;
885
    }
886

            
887
2994
    status = composite_boxes (compositor, extents, boxes);
888
2994
    if (status != CAIRO_INT_STATUS_UNSUPPORTED)
889
2547
	return status;
890

            
891
447
    status = _cairo_polygon_init_boxes (&polygon, boxes);
892
447
    if (unlikely (status))
893
	return status;
894

            
895
447
    status = composite_polygon (compositor, extents, &polygon,
896
				CAIRO_FILL_RULE_WINDING,
897
				CAIRO_ANTIALIAS_DEFAULT);
898
447
    _cairo_polygon_fini (&polygon);
899

            
900
447
    return status;
901
}
902

            
903
static cairo_int_status_t
904
198093
clip_and_composite_polygon (const cairo_spans_compositor_t	*compositor,
905
			    cairo_composite_rectangles_t	 *extents,
906
			    cairo_polygon_t			*polygon,
907
			    cairo_fill_rule_t			 fill_rule,
908
			    cairo_antialias_t			 antialias)
909
{
910
    cairo_int_status_t status;
911

            
912
    TRACE ((stderr, "%s\n", __FUNCTION__));
913

            
914
    /* XXX simply uses polygon limits.point extemities, tessellation? */
915
198093
    status = trim_extents_to_polygon (extents, polygon);
916
198093
    if (unlikely (status))
917
18613
	return status;
918

            
919
179480
    if (_cairo_polygon_is_empty (polygon)) {
920
	cairo_boxes_t boxes;
921

            
922
24
	if (extents->is_bounded)
923
9
	    return CAIRO_STATUS_SUCCESS;
924

            
925
15
	_cairo_boxes_init (&boxes);
926
15
	extents->bounded.width = extents->bounded.height = 0;
927
15
	return fixup_unbounded_boxes (compositor, extents, &boxes);
928
    }
929

            
930
179456
    if (extents->is_bounded && extents->clip->path) {
931
	cairo_polygon_t clipper;
932
	cairo_antialias_t clip_antialias;
933
	cairo_fill_rule_t clip_fill_rule;
934

            
935
	TRACE((stderr, "%s - combining shape with clip polygon\n",
936
	       __FUNCTION__));
937

            
938
144
	status = _cairo_clip_get_polygon (extents->clip,
939
					  &clipper,
940
					  &clip_fill_rule,
941
					  &clip_antialias);
942
144
	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
943
	    cairo_clip_t *old_clip;
944

            
945
144
	    if (clip_antialias == antialias) {
946
144
		status = _cairo_polygon_intersect (polygon, fill_rule,
947
						   &clipper, clip_fill_rule);
948
144
		_cairo_polygon_fini (&clipper);
949
144
		if (unlikely (status))
950
		    return status;
951

            
952
144
		old_clip = extents->clip;
953
144
		extents->clip = _cairo_clip_copy_region (extents->clip);
954
144
		_cairo_clip_destroy (old_clip);
955

            
956
144
		status = trim_extents_to_polygon (extents, polygon);
957
144
		if (unlikely (status))
958
		    return status;
959

            
960
144
		fill_rule = CAIRO_FILL_RULE_WINDING;
961
	    } else {
962
		_cairo_polygon_fini (&clipper);
963
	    }
964
	}
965
    }
966

            
967
179456
    return composite_polygon (compositor, extents,
968
			      polygon, fill_rule, antialias);
969
}
970

            
971
/* high-level compositor interface */
972

            
973
static cairo_int_status_t
974
562532
_cairo_spans_compositor_paint (const cairo_compositor_t		*_compositor,
975
			       cairo_composite_rectangles_t	*extents)
976
{
977
562532
    const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor;
978
    cairo_boxes_t boxes;
979
    cairo_int_status_t status;
980

            
981
    TRACE ((stderr, "%s\n", __FUNCTION__));
982
562532
    _cairo_clip_steal_boxes (extents->clip, &boxes);
983
562532
    status = clip_and_composite_boxes (compositor, extents, &boxes);
984
562532
    _cairo_clip_unsteal_boxes (extents->clip, &boxes);
985

            
986
562532
    return status;
987
}
988

            
989
static cairo_int_status_t
990
4566
_cairo_spans_compositor_mask (const cairo_compositor_t		*_compositor,
991
			      cairo_composite_rectangles_t	*extents)
992
{
993
4566
    const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor;
994
    cairo_int_status_t status;
995
    cairo_boxes_t boxes;
996

            
997
    TRACE ((stderr, "%s\n", __FUNCTION__));
998
4566
    _cairo_clip_steal_boxes (extents->clip, &boxes);
999
4566
    status = clip_and_composite_boxes (compositor, extents, &boxes);
4566
    _cairo_clip_unsteal_boxes (extents->clip, &boxes);
4566
    return status;
}
static cairo_int_status_t
39966
_cairo_spans_compositor_stroke (const cairo_compositor_t	*_compositor,
				cairo_composite_rectangles_t	 *extents,
				const cairo_path_fixed_t	*path,
				const cairo_stroke_style_t	*style,
				const cairo_matrix_t		*ctm,
				const cairo_matrix_t		*ctm_inverse,
				double				 tolerance,
				cairo_antialias_t		 antialias)
{
39966
    const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor;
    cairo_int_status_t status;
    TRACE ((stderr, "%s\n", __FUNCTION__));
    TRACE_ (_cairo_debug_print_path (stderr, path));
    TRACE_ (_cairo_debug_print_clip (stderr, extents->clip));
39966
    status = CAIRO_INT_STATUS_UNSUPPORTED;
39966
    if (_cairo_path_fixed_stroke_is_rectilinear (path)) {
	cairo_boxes_t boxes;
2925
	_cairo_boxes_init (&boxes);
2925
	if (! _cairo_clip_contains_rectangle (extents->clip, &extents->mask))
1266
	    _cairo_boxes_limit (&boxes,
1266
				extents->clip->boxes,
1266
				extents->clip->num_boxes);
2925
	status = _cairo_path_fixed_stroke_rectilinear_to_boxes (path,
								style,
								ctm,
								antialias,
								&boxes);
2925
	if (likely (status == CAIRO_INT_STATUS_SUCCESS))
2382
	    status = clip_and_composite_boxes (compositor, extents, &boxes);
2925
	_cairo_boxes_fini (&boxes);
    }
39966
    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
	cairo_polygon_t polygon;
	cairo_box_t limits;
37584
	cairo_fill_rule_t fill_rule = CAIRO_FILL_RULE_WINDING;
37584
	if (! _cairo_rectangle_contains_rectangle (&extents->unbounded,
37584
						   &extents->mask))
	{
34578
	    if (extents->clip->num_boxes == 1) {
34551
		_cairo_polygon_init (&polygon, extents->clip->boxes, 1);
	    } else {
27
		_cairo_box_from_rectangle (&limits, &extents->unbounded);
27
		_cairo_polygon_init (&polygon, &limits, 1);
	    }
	}
	else
	{
3006
	    _cairo_polygon_init (&polygon, NULL, 0);
	}
37584
	status = _cairo_path_fixed_stroke_to_polygon (path,
						      style,
						      ctm, ctm_inverse,
						      tolerance,
						      &polygon);
	TRACE_ (_cairo_debug_print_polygon (stderr, &polygon));
37584
	polygon.num_limits = 0;
37584
	if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) {
27
	    status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule,
27
							  extents->clip->boxes,
27
							  extents->clip->num_boxes);
	}
37584
	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
37584
	    cairo_clip_t *saved_clip = extents->clip;
37584
	    if (extents->is_bounded) {
37572
		extents->clip = _cairo_clip_copy_path (extents->clip);
37572
		extents->clip = _cairo_clip_intersect_box(extents->clip,
							  &polygon.extents);
	    }
37584
	    status = clip_and_composite_polygon (compositor, extents, &polygon,
						 fill_rule, antialias);
37584
	    if (extents->is_bounded) {
37572
		_cairo_clip_destroy (extents->clip);
37572
		extents->clip = saved_clip;
	    }
	}
37584
	_cairo_polygon_fini (&polygon);
    }
39966
    return status;
}
static cairo_int_status_t
497964
_cairo_spans_compositor_fill (const cairo_compositor_t		*_compositor,
			      cairo_composite_rectangles_t	 *extents,
			      const cairo_path_fixed_t		*path,
			      cairo_fill_rule_t			 fill_rule,
			      double				 tolerance,
			      cairo_antialias_t			 antialias)
{
497964
    const cairo_spans_compositor_t *compositor = (cairo_spans_compositor_t*)_compositor;
    cairo_int_status_t status;
    TRACE((stderr, "%s op=%d, antialias=%d\n", __FUNCTION__, extents->op, antialias));
497964
    status = CAIRO_INT_STATUS_UNSUPPORTED;
497964
    if (_cairo_path_fixed_fill_is_rectilinear (path)) {
	cairo_boxes_t boxes;
	TRACE((stderr, "%s - rectilinear\n", __FUNCTION__));
339762
	_cairo_boxes_init (&boxes);
339762
	if (! _cairo_clip_contains_rectangle (extents->clip, &extents->mask))
16767
	    _cairo_boxes_limit (&boxes,
16767
				extents->clip->boxes,
16767
				extents->clip->num_boxes);
339762
	status = _cairo_path_fixed_fill_rectilinear_to_boxes (path,
							      fill_rule,
							      antialias,
							      &boxes);
339762
	if (likely (status == CAIRO_INT_STATUS_SUCCESS))
339762
	    status = clip_and_composite_boxes (compositor, extents, &boxes);
339762
	_cairo_boxes_fini (&boxes);
    }
497964
    if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
	cairo_polygon_t polygon;
	cairo_box_t limits;
	TRACE((stderr, "%s - polygon\n", __FUNCTION__));
158265
	if (! _cairo_rectangle_contains_rectangle (&extents->unbounded,
158265
						   &extents->mask))
	{
	    TRACE((stderr, "%s - clipping to bounds\n", __FUNCTION__));
51835
	    if (extents->clip->num_boxes == 1) {
51793
		_cairo_polygon_init (&polygon, extents->clip->boxes, 1);
	    } else {
42
		_cairo_box_from_rectangle (&limits, &extents->unbounded);
42
		_cairo_polygon_init (&polygon, &limits, 1);
	    }
	}
	else
	{
106430
	    _cairo_polygon_init (&polygon, NULL, 0);
	}
158265
	status = _cairo_path_fixed_fill_to_polygon (path, tolerance, &polygon);
	TRACE_ (_cairo_debug_print_polygon (stderr, &polygon));
158265
	polygon.num_limits = 0;
158265
	if (status == CAIRO_INT_STATUS_SUCCESS && extents->clip->num_boxes > 1) {
	    TRACE((stderr, "%s - polygon intersect with %d clip boxes\n",
		   __FUNCTION__, extents->clip->num_boxes));
75
	    status = _cairo_polygon_intersect_with_boxes (&polygon, &fill_rule,
75
							  extents->clip->boxes,
75
							  extents->clip->num_boxes);
	}
	TRACE_ (_cairo_debug_print_polygon (stderr, &polygon));
158265
	if (likely (status == CAIRO_INT_STATUS_SUCCESS)) {
158265
	    cairo_clip_t *saved_clip = extents->clip;
158265
	    if (extents->is_bounded) {
		TRACE((stderr, "%s - polygon discard clip boxes\n",
		       __FUNCTION__));
158001
		extents->clip = _cairo_clip_copy_path (extents->clip);
158001
		extents->clip = _cairo_clip_intersect_box(extents->clip,
							  &polygon.extents);
	    }
158265
	    status = clip_and_composite_polygon (compositor, extents, &polygon,
						 fill_rule, antialias);
158265
	    if (extents->is_bounded) {
158001
		_cairo_clip_destroy (extents->clip);
158001
		extents->clip = saved_clip;
	    }
	}
158265
	_cairo_polygon_fini (&polygon);
	TRACE((stderr, "%s - polygon status=%d\n", __FUNCTION__, status));
    }
497964
    return status;
}
void
1742
_cairo_spans_compositor_init (cairo_spans_compositor_t *compositor,
			      const cairo_compositor_t  *delegate)
{
1742
    compositor->base.delegate = delegate;
1742
    compositor->base.paint  = _cairo_spans_compositor_paint;
1742
    compositor->base.mask   = _cairo_spans_compositor_mask;
1742
    compositor->base.fill   = _cairo_spans_compositor_fill;
1742
    compositor->base.stroke = _cairo_spans_compositor_stroke;
1742
    compositor->base.glyphs = NULL;
1742
}