Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1892 Rev 3959
Line 35... Line 35...
35
 */
35
 */
Line 36... Line 36...
36
 
36
 
Line 37... Line 37...
37
#include "cairoint.h"
37
#include "cairoint.h"
-
 
38
 
-
 
39
#include "cairo-analysis-surface-private.h"
38
 
40
#include "cairo-box-inline.h"
39
#include "cairo-analysis-surface-private.h"
41
#include "cairo-default-context-private.h"
40
#include "cairo-error-private.h"
42
#include "cairo-error-private.h"
-
 
43
#include "cairo-paginated-private.h"
41
#include "cairo-paginated-private.h"
44
#include "cairo-recording-surface-inline.h"
42
#include "cairo-recording-surface-private.h"
45
#include "cairo-surface-snapshot-inline.h"
Line 43... Line 46...
43
#include "cairo-surface-subsurface-private.h"
46
#include "cairo-surface-subsurface-inline.h"
44
#include "cairo-region-private.h"
47
#include "cairo-region-private.h"
Line 64... Line 67...
64
cairo_int_status_t
67
cairo_int_status_t
65
_cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
68
_cairo_analysis_surface_merge_status (cairo_int_status_t status_a,
66
				      cairo_int_status_t status_b)
69
				      cairo_int_status_t status_b)
67
{
70
{
68
    /* fatal errors should be checked and propagated at source */
71
    /* fatal errors should be checked and propagated at source */
69
    assert (! _cairo_status_is_error (status_a));
72
    assert (! _cairo_int_status_is_error (status_a));
70
    assert (! _cairo_status_is_error (status_b));
73
    assert (! _cairo_int_status_is_error (status_b));
Line 71... Line 74...
71
 
74
 
72
    /* return the most important status */
75
    /* return the most important status */
73
    if (status_a == CAIRO_INT_STATUS_UNSUPPORTED ||
76
    if (status_a == CAIRO_INT_STATUS_UNSUPPORTED ||
74
	status_b == CAIRO_INT_STATUS_UNSUPPORTED)
77
	status_b == CAIRO_INT_STATUS_UNSUPPORTED)
Line 85... Line 88...
85
    if (status_a == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY ||
88
    if (status_a == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY ||
86
	status_b == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
89
	status_b == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
87
	return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
90
	return CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY;
Line 88... Line 91...
88
 
91
 
89
    /* at this point we have checked all the valid internal codes, so... */
92
    /* at this point we have checked all the valid internal codes, so... */
90
    assert (status_a == CAIRO_STATUS_SUCCESS &&
93
    assert (status_a == CAIRO_INT_STATUS_SUCCESS &&
Line -... Line 94...
-
 
94
	    status_b == CAIRO_INT_STATUS_SUCCESS);
-
 
95
 
-
 
96
    return CAIRO_INT_STATUS_SUCCESS;
-
 
97
}
-
 
98
 
-
 
99
struct proxy {
-
 
100
    cairo_surface_t base;
-
 
101
    cairo_surface_t *target;
-
 
102
};
-
 
103
 
-
 
104
static cairo_status_t
91
	    status_b == CAIRO_STATUS_SUCCESS);
105
proxy_finish (void *abstract_surface)
92
 
106
{
Line -... Line 107...
-
 
107
    return CAIRO_STATUS_SUCCESS;
-
 
108
}
-
 
109
 
-
 
110
static const cairo_surface_backend_t proxy_backend  = {
-
 
111
    CAIRO_INTERNAL_SURFACE_TYPE_NULL,
-
 
112
    proxy_finish,
-
 
113
};
-
 
114
 
-
 
115
static cairo_surface_t *
-
 
116
attach_proxy (cairo_surface_t *source,
-
 
117
	      cairo_surface_t *target)
-
 
118
{
-
 
119
    struct proxy *proxy;
-
 
120
 
-
 
121
    proxy = malloc (sizeof (*proxy));
-
 
122
    if (unlikely (proxy == NULL))
-
 
123
	return _cairo_surface_create_in_error (CAIRO_STATUS_NO_MEMORY);
-
 
124
 
-
 
125
    _cairo_surface_init (&proxy->base, &proxy_backend, NULL, target->content);
-
 
126
 
-
 
127
    proxy->target = target;
-
 
128
    _cairo_surface_attach_snapshot (source, &proxy->base, NULL);
-
 
129
 
-
 
130
    return &proxy->base;
-
 
131
}
-
 
132
 
-
 
133
static void
-
 
134
detach_proxy (cairo_surface_t *proxy)
-
 
135
{
-
 
136
    cairo_surface_finish (proxy);
93
    return CAIRO_STATUS_SUCCESS;
137
    cairo_surface_destroy (proxy);
94
}
138
}
95
 
139
 
96
static cairo_int_status_t
140
static cairo_int_status_t
97
_analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
141
_analyze_recording_surface_pattern (cairo_analysis_surface_t *surface,
98
				    const cairo_pattern_t    *pattern)
142
				    const cairo_pattern_t    *pattern)
99
{
143
{
100
    const cairo_surface_pattern_t *surface_pattern;
144
    const cairo_surface_pattern_t *surface_pattern;
101
    cairo_bool_t old_has_ctm;
145
    cairo_analysis_surface_t *tmp;
Line 102... Line 146...
102
    cairo_matrix_t old_ctm, p2d;
146
    cairo_surface_t *source, *proxy;
103
    cairo_status_t status;
147
    cairo_matrix_t p2d;
104
    cairo_surface_t *source;
148
    cairo_status_t status, analysis_status;
-
 
149
 
-
 
150
    assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
-
 
151
    surface_pattern = (const cairo_surface_pattern_t *) pattern;
-
 
152
    assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING);
-
 
153
    source = surface_pattern->surface;
-
 
154
 
-
 
155
    proxy = _cairo_surface_has_snapshot (source, &proxy_backend);
Line 105... Line 156...
105
 
156
    if (proxy != NULL) {
106
    assert (pattern->type == CAIRO_PATTERN_TYPE_SURFACE);
157
	/* nothing untoward found so far */
-
 
158
	return CAIRO_STATUS_SUCCESS;
-
 
159
    }
-
 
160
 
Line 107... Line 161...
107
    surface_pattern = (const cairo_surface_pattern_t *) pattern;
161
    tmp = (cairo_analysis_surface_t *)
108
    assert (surface_pattern->surface->type == CAIRO_SURFACE_TYPE_RECORDING);
162
	_cairo_analysis_surface_create (surface->target);
109
 
163
    if (unlikely (tmp->base.status))
Line 110... Line 164...
110
    old_ctm = surface->ctm;
164
	return tmp->base.status;
111
    old_has_ctm = surface->has_ctm;
165
    proxy = attach_proxy (source, &tmp->base);
112
 
-
 
113
    p2d = pattern->matrix;
-
 
114
    status = cairo_matrix_invert (&p2d);
-
 
115
    assert (status == CAIRO_STATUS_SUCCESS);
-
 
116
 
-
 
117
    cairo_matrix_multiply (&surface->ctm, &p2d, &surface->ctm);
-
 
118
    surface->has_ctm = ! _cairo_matrix_is_identity (&surface->ctm);
-
 
119
 
-
 
Line -... Line 166...
-
 
166
 
-
 
167
    p2d = pattern->matrix;
-
 
168
    status = cairo_matrix_invert (&p2d);
-
 
169
    assert (status == CAIRO_STATUS_SUCCESS);
120
    source = surface_pattern->surface;
170
 
121
    if (source->backend->type == CAIRO_SURFACE_TYPE_SUBSURFACE) {
171
    cairo_matrix_multiply (&tmp->ctm, &p2d, &surface->ctm);
Line -... Line 172...
-
 
172
    tmp->has_ctm = ! _cairo_matrix_is_identity (&tmp->ctm);
122
	cairo_surface_subsurface_t *sub = (cairo_surface_subsurface_t *) source;
173
 
-
 
174
    source = _cairo_surface_get_source (source, NULL);
-
 
175
    status = _cairo_recording_surface_replay_and_create_regions (source,
123
	source = sub->target;
176
								 &tmp->base);
Line 124... Line 177...
124
    }
177
    analysis_status = tmp->has_unsupported ? CAIRO_INT_STATUS_IMAGE_FALLBACK : CAIRO_INT_STATUS_SUCCESS;
125
 
178
    detach_proxy (proxy);
126
    status = _cairo_recording_surface_replay_and_create_regions (source, &surface->base);
179
    cairo_surface_destroy (&tmp->base);
Line 141... Line 194...
141
 
194
 
142
    if (rect->width == 0 || rect->height == 0) {
195
    if (rect->width == 0 || rect->height == 0) {
143
	/* Even though the operation is not visible we must be careful
196
	/* Even though the operation is not visible we must be careful
144
	 * to not allow unsupported operations to be replayed to the
197
	 * to not allow unsupported operations to be replayed to the
145
	 * backend during CAIRO_PAGINATED_MODE_RENDER */
198
	 * backend during CAIRO_PAGINATED_MODE_RENDER */
146
	if (backend_status == CAIRO_STATUS_SUCCESS ||
199
	if (backend_status == CAIRO_INT_STATUS_SUCCESS ||
-
 
200
	    backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY ||
147
	    backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
201
	    backend_status == CAIRO_INT_STATUS_NOTHING_TO_DO)
148
	{
202
	{
149
	    return CAIRO_STATUS_SUCCESS;
203
	    return CAIRO_INT_STATUS_SUCCESS;
150
	}
204
	}
151
	else
205
	else
152
	{
206
	{
153
	    return CAIRO_INT_STATUS_IMAGE_FALLBACK;
207
	    return CAIRO_INT_STATUS_IMAGE_FALLBACK;
Line 160... Line 214...
160
	int tx, ty;
214
	int tx, ty;
Line 161... Line 215...
161
 
215
 
162
	if (_cairo_matrix_is_integer_translation (&surface->ctm, &tx, &ty)) {
216
	if (_cairo_matrix_is_integer_translation (&surface->ctm, &tx, &ty)) {
163
	    rect->x += tx;
217
	    rect->x += tx;
-
 
218
	    rect->y += ty;
-
 
219
 
-
 
220
	    tx = _cairo_fixed_from_int (tx);
-
 
221
	    bbox.p1.x += tx;
-
 
222
	    bbox.p2.x += tx;
-
 
223
 
-
 
224
	    ty = _cairo_fixed_from_int (ty);
-
 
225
	    bbox.p1.y += ty;
164
	    rect->y += ty;
226
	    bbox.p2.y += ty;
165
	} else {
227
	} else {
166
	    _cairo_matrix_transform_bounding_box_fixed (&surface->ctm,
228
	    _cairo_matrix_transform_bounding_box_fixed (&surface->ctm,
Line 167... Line 229...
167
							&bbox, NULL);
229
							&bbox, NULL);
168
 
230
 
169
	    if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) {
231
	    if (bbox.p1.x == bbox.p2.x || bbox.p1.y == bbox.p2.y) {
170
		/* Even though the operation is not visible we must be
232
		/* Even though the operation is not visible we must be
171
		 * careful to not allow unsupported operations to be
233
		 * careful to not allow unsupported operations to be
172
		 * replayed to the backend during
234
		 * replayed to the backend during
173
		 * CAIRO_PAGINATED_MODE_RENDER */
235
		 * CAIRO_PAGINATED_MODE_RENDER */
-
 
236
		if (backend_status == CAIRO_INT_STATUS_SUCCESS ||
174
		if (backend_status == CAIRO_STATUS_SUCCESS ||
237
		    backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY ||
175
		    backend_status == CAIRO_INT_STATUS_FLATTEN_TRANSPARENCY)
238
		    backend_status == CAIRO_INT_STATUS_NOTHING_TO_DO)
176
		{
239
		{
177
		    return CAIRO_STATUS_SUCCESS;
240
		    return CAIRO_INT_STATUS_SUCCESS;
178
		}
241
		}
179
		else
242
		else
180
		{
243
		{
Line 187... Line 250...
187
    }
250
    }
Line 188... Line 251...
188
 
251
 
189
    if (surface->first_op) {
252
    if (surface->first_op) {
190
	surface->first_op = FALSE;
253
	surface->first_op = FALSE;
191
	surface->page_bbox = bbox;
254
	surface->page_bbox = bbox;
192
    } else {
-
 
193
	if (bbox.p1.x < surface->page_bbox.p1.x)
-
 
194
	    surface->page_bbox.p1.x = bbox.p1.x;
-
 
195
	if (bbox.p1.y < surface->page_bbox.p1.y)
-
 
196
	    surface->page_bbox.p1.y = bbox.p1.y;
255
    } else
197
	if (bbox.p2.x > surface->page_bbox.p2.x)
-
 
198
	    surface->page_bbox.p2.x = bbox.p2.x;
-
 
199
	if (bbox.p2.y > surface->page_bbox.p2.y)
-
 
200
	    surface->page_bbox.p2.y = bbox.p2.y;
-
 
Line 201... Line 256...
201
    }
256
	_cairo_box_add_box(&surface->page_bbox, &bbox);
202
 
257
 
203
    /* If the operation is completely enclosed within the fallback
258
    /* If the operation is completely enclosed within the fallback
204
     * region there is no benefit in emitting a native operation as
259
     * region there is no benefit in emitting a native operation as
Line 214... Line 269...
214
	 * not intersect any other native operation, the operation is
269
	 * not intersect any other native operation, the operation is
215
	 * natively supported and the backend will blend the
270
	 * natively supported and the backend will blend the
216
	 * transparency into the white background.
271
	 * transparency into the white background.
217
	 */
272
	 */
218
	if (cairo_region_contains_rectangle (&surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT)
273
	if (cairo_region_contains_rectangle (&surface->supported_region, rect) == CAIRO_REGION_OVERLAP_OUT)
219
	    backend_status = CAIRO_STATUS_SUCCESS;
274
	    backend_status = CAIRO_INT_STATUS_SUCCESS;
220
    }
275
    }
Line 221... Line 276...
221
 
276
 
222
    if (backend_status == CAIRO_STATUS_SUCCESS) {
277
    if (backend_status == CAIRO_INT_STATUS_SUCCESS) {
223
	/* Add the operation to the supported region. Operations in
278
	/* Add the operation to the supported region. Operations in
224
	 * this region will be emitted as native operations.
279
	 * this region will be emitted as native operations.
225
	 */
280
	 */
226
	surface->has_supported = TRUE;
281
	surface->has_supported = TRUE;
Line 238... Line 293...
238
     * unsupported operations to the recording surface as using
293
     * unsupported operations to the recording surface as using
239
     * CAIRO_INT_STATUS_UNSUPPORTED would cause cairo-surface to
294
     * CAIRO_INT_STATUS_UNSUPPORTED would cause cairo-surface to
240
     * invoke the cairo-surface-fallback path then return
295
     * invoke the cairo-surface-fallback path then return
241
     * CAIRO_STATUS_SUCCESS.
296
     * CAIRO_STATUS_SUCCESS.
242
     */
297
     */
243
    if (status == CAIRO_STATUS_SUCCESS)
298
    if (status == CAIRO_INT_STATUS_SUCCESS)
244
	return CAIRO_INT_STATUS_IMAGE_FALLBACK;
299
	return CAIRO_INT_STATUS_IMAGE_FALLBACK;
245
    else
300
    else
246
	return status;
301
	return status;
247
}
302
}
Line 267... Line 322...
267
 
322
 
268
    return _cairo_surface_get_extents (surface->target, rectangle);
323
    return _cairo_surface_get_extents (surface->target, rectangle);
Line 269... Line 324...
269
}
324
}
270
 
325
 
271
static void
326
static void
272
_rectangle_intersect_clip (cairo_rectangle_int_t *extents, cairo_clip_t *clip)
-
 
273
{
-
 
274
    const cairo_rectangle_int_t *clip_extents;
-
 
275
    cairo_bool_t is_empty;
-
 
276
 
327
_rectangle_intersect_clip (cairo_rectangle_int_t *extents, const cairo_clip_t *clip)
277
    clip_extents = NULL;
-
 
278
    if (clip != NULL)
-
 
279
	clip_extents = _cairo_clip_get_extents (clip);
-
 
280
 
328
{
281
    if (clip_extents != NULL)
329
    if (clip != NULL)
Line 282... Line 330...
282
	is_empty = _cairo_rectangle_intersect (extents, clip_extents);
330
	_cairo_rectangle_intersect (extents, _cairo_clip_get_extents (clip));
283
}
331
}
284
 
332
 
285
static void
333
static void
286
_cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface,
334
_cairo_analysis_surface_operation_extents (cairo_analysis_surface_t *surface,
287
					   cairo_operator_t op,
335
					   cairo_operator_t op,
288
					   const cairo_pattern_t *source,
336
					   const cairo_pattern_t *source,
289
					   cairo_clip_t *clip,
337
					   const cairo_clip_t *clip,
Line 290... Line 338...
290
					   cairo_rectangle_int_t *extents)
338
					   cairo_rectangle_int_t *extents)
Line 291... Line 339...
291
{
339
{
292
    cairo_bool_t is_empty;
340
    cairo_bool_t is_empty;
Line 293... Line 341...
293
 
341
 
294
    is_empty = _cairo_surface_get_extents (&surface->base, extents);
342
    is_empty = _cairo_surface_get_extents (&surface->base, extents);
295
 
343
 
Line 296... Line 344...
296
    if (_cairo_operator_bounded_by_source (op)) {
344
    if (_cairo_operator_bounded_by_source (op)) {
297
	cairo_rectangle_int_t source_extents;
345
	cairo_rectangle_int_t source_extents;
Line 298... Line 346...
298
 
346
 
299
	_cairo_pattern_get_extents (source, &source_extents);
347
	_cairo_pattern_get_extents (source, &source_extents);
300
	is_empty = _cairo_rectangle_intersect (extents, &source_extents);
348
	_cairo_rectangle_intersect (extents, &source_extents);
301
    }
349
    }
302
 
350
 
303
    _rectangle_intersect_clip (extents, clip);
351
    _rectangle_intersect_clip (extents, clip);
304
}
352
}
305
 
353
 
306
static cairo_int_status_t
354
static cairo_int_status_t
Line 307... Line 355...
307
_cairo_analysis_surface_paint (void			*abstract_surface,
355
_cairo_analysis_surface_paint (void			*abstract_surface,
308
			       cairo_operator_t		op,
356
			       cairo_operator_t		op,
309
			       const cairo_pattern_t	*source,
357
			       const cairo_pattern_t	*source,
310
			       cairo_clip_t		*clip)
358
			       const cairo_clip_t		*clip)
311
{
359
{
312
    cairo_analysis_surface_t *surface = abstract_surface;
360
    cairo_analysis_surface_t *surface = abstract_surface;
313
    cairo_status_t	     backend_status;
361
    cairo_int_status_t	     backend_status;
314
    cairo_rectangle_int_t  extents;
362
    cairo_rectangle_int_t  extents;
315
 
363
 
Line 316... Line 364...
316
    if (surface->target->backend->paint == NULL) {
364
    if (surface->target->backend->paint == NULL) {
317
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
365
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
Line 336... Line 384...
336
static cairo_int_status_t
384
static cairo_int_status_t
337
_cairo_analysis_surface_mask (void			*abstract_surface,
385
_cairo_analysis_surface_mask (void			*abstract_surface,
338
			      cairo_operator_t		 op,
386
			      cairo_operator_t		 op,
339
			      const cairo_pattern_t	*source,
387
			      const cairo_pattern_t	*source,
340
			      const cairo_pattern_t	*mask,
388
			      const cairo_pattern_t	*mask,
341
			      cairo_clip_t		*clip)
389
			      const cairo_clip_t		*clip)
342
{
390
{
343
    cairo_analysis_surface_t *surface = abstract_surface;
391
    cairo_analysis_surface_t *surface = abstract_surface;
344
    cairo_int_status_t	      backend_status;
392
    cairo_int_status_t	      backend_status;
345
    cairo_rectangle_int_t   extents;
393
    cairo_rectangle_int_t   extents;
346
    cairo_bool_t is_empty;
-
 
Line 347... Line 394...
347
 
394
 
348
    if (surface->target->backend->mask == NULL) {
395
    if (surface->target->backend->mask == NULL) {
349
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
396
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
350
    } else {
397
    } else {
351
	backend_status =
398
	backend_status =
352
	    surface->target->backend->mask (surface->target,
399
	    surface->target->backend->mask (surface->target,
353
					    op, source, mask, clip);
400
					    op, source, mask, clip);
354
	if (_cairo_status_is_error (backend_status))
401
	if (_cairo_int_status_is_error (backend_status))
355
	    return backend_status;
402
	    return backend_status;
Line 356... Line 403...
356
    }
403
    }
357
 
404
 
358
    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
405
    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN) {
Line 359... Line 406...
359
	cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
406
	cairo_int_status_t backend_source_status = CAIRO_STATUS_SUCCESS;
360
	cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS;
407
	cairo_int_status_t backend_mask_status = CAIRO_STATUS_SUCCESS;
-
 
408
 
361
 
409
	if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
362
	if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
410
	    cairo_surface_t *src_surface = ((cairo_surface_pattern_t *)source)->surface;
363
	    const cairo_surface_pattern_t *surface_pattern = (const cairo_surface_pattern_t *) source;
411
	    src_surface = _cairo_surface_get_source (src_surface, NULL);
364
	    if (_cairo_surface_is_recording (surface_pattern->surface)) {
412
	    if (_cairo_surface_is_recording (src_surface)) {
365
		backend_source_status =
413
		backend_source_status =
366
		    _analyze_recording_surface_pattern (surface, source);
414
		    _analyze_recording_surface_pattern (surface, source);
367
		if (_cairo_status_is_error (backend_source_status))
415
		if (_cairo_int_status_is_error (backend_source_status))
Line 368... Line 416...
368
		    return backend_source_status;
416
		    return backend_source_status;
369
	    }
417
	    }
-
 
418
	}
370
	}
419
 
371
 
420
	if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
372
	if (mask->type == CAIRO_PATTERN_TYPE_SURFACE) {
421
	    cairo_surface_t *mask_surface = ((cairo_surface_pattern_t *)mask)->surface;
373
	    cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *) mask;
422
	    mask_surface = _cairo_surface_get_source (mask_surface, NULL);
374
	    if (_cairo_surface_is_recording (surface_pattern->surface)) {
423
	    if (_cairo_surface_is_recording (mask_surface)) {
375
		backend_mask_status =
424
		backend_mask_status =
376
		    _analyze_recording_surface_pattern (surface, mask);
425
		    _analyze_recording_surface_pattern (surface, mask);
Line 377... Line 426...
377
		if (_cairo_status_is_error (backend_mask_status))
426
		if (_cairo_int_status_is_error (backend_mask_status))
Line 390... Line 439...
390
 
439
 
391
    if (_cairo_operator_bounded_by_mask (op)) {
440
    if (_cairo_operator_bounded_by_mask (op)) {
Line 392... Line 441...
392
	cairo_rectangle_int_t mask_extents;
441
	cairo_rectangle_int_t mask_extents;
393
 
442
 
394
	_cairo_pattern_get_extents (mask, &mask_extents);
-
 
395
	is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
443
	_cairo_pattern_get_extents (mask, &mask_extents);
Line 396... Line 444...
396
 
444
	_cairo_rectangle_intersect (&extents, &mask_extents);
397
    }
445
    }
Line 398... Line 446...
398
 
446
 
399
    return _add_operation (surface, &extents, backend_status);
447
    return _add_operation (surface, &extents, backend_status);
400
}
448
}
401
 
449
 
402
static cairo_int_status_t
450
static cairo_int_status_t
403
_cairo_analysis_surface_stroke (void			*abstract_surface,
451
_cairo_analysis_surface_stroke (void			*abstract_surface,
404
				cairo_operator_t	 op,
452
				cairo_operator_t	 op,
405
				const cairo_pattern_t	*source,
453
				const cairo_pattern_t	*source,
406
				cairo_path_fixed_t	*path,
454
				const cairo_path_fixed_t	*path,
407
				const cairo_stroke_style_t	*style,
455
				const cairo_stroke_style_t	*style,
408
				const cairo_matrix_t		*ctm,
456
				const cairo_matrix_t		*ctm,
409
				const cairo_matrix_t		*ctm_inverse,
457
				const cairo_matrix_t		*ctm_inverse,
410
				double			 tolerance,
458
				double			 tolerance,
411
				cairo_antialias_t	 antialias,
459
				cairo_antialias_t	 antialias,
412
				cairo_clip_t		*clip)
460
				const cairo_clip_t		*clip)
413
{
-
 
Line 414... Line 461...
414
    cairo_analysis_surface_t *surface = abstract_surface;
461
{
415
    cairo_status_t	     backend_status;
462
    cairo_analysis_surface_t *surface = abstract_surface;
416
    cairo_rectangle_int_t    extents;
463
    cairo_int_status_t	     backend_status;
417
    cairo_bool_t             is_empty;
464
    cairo_rectangle_int_t    extents;
418
 
465
 
419
    if (surface->target->backend->stroke == NULL) {
466
    if (surface->target->backend->stroke == NULL) {
420
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
467
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
421
    } else {
468
    } else {
422
	backend_status =
469
	backend_status =
423
	    surface->target->backend->stroke (surface->target, op,
470
	    surface->target->backend->stroke (surface->target, op,
424
					      source, path, style,
471
					      source, path, style,
425
					      ctm, ctm_inverse,
472
					      ctm, ctm_inverse,
Line 426... Line 473...
426
					      tolerance, antialias,
473
					      tolerance, antialias,
427
					      clip);
474
					      clip);
Line 436... Line 483...
436
					       op, source, clip,
483
					       op, source, clip,
437
					       &extents);
484
					       &extents);
Line 438... Line 485...
438
 
485
 
439
    if (_cairo_operator_bounded_by_mask (op)) {
486
    if (_cairo_operator_bounded_by_mask (op)) {
440
	cairo_rectangle_int_t mask_extents;
487
	cairo_rectangle_int_t mask_extents;
Line 441... Line 488...
441
	cairo_status_t status;
488
	cairo_int_status_t status;
442
 
489
 
443
	status = _cairo_path_fixed_stroke_extents (path, style,
490
	status = _cairo_path_fixed_stroke_extents (path, style,
444
						   ctm, ctm_inverse,
491
						   ctm, ctm_inverse,
445
						   tolerance,
492
						   tolerance,
446
						   &mask_extents);
493
						   &mask_extents);
Line 447... Line 494...
447
	if (unlikely (status))
494
	if (unlikely (status))
448
	    return status;
495
	    return status;
Line 449... Line 496...
449
 
496
 
450
	is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
497
	_cairo_rectangle_intersect (&extents, &mask_extents);
Line 451... Line 498...
451
    }
498
    }
452
 
499
 
453
    return _add_operation (surface, &extents, backend_status);
500
    return _add_operation (surface, &extents, backend_status);
454
}
501
}
455
 
502
 
456
static cairo_int_status_t
503
static cairo_int_status_t
457
_cairo_analysis_surface_fill (void			*abstract_surface,
504
_cairo_analysis_surface_fill (void			*abstract_surface,
458
			      cairo_operator_t		 op,
505
			      cairo_operator_t		 op,
459
			      const cairo_pattern_t	*source,
506
			      const cairo_pattern_t	*source,
460
			      cairo_path_fixed_t	*path,
507
			      const cairo_path_fixed_t	*path,
461
			      cairo_fill_rule_t		 fill_rule,
508
			      cairo_fill_rule_t		 fill_rule,
462
			      double			 tolerance,
509
			      double			 tolerance,
463
			      cairo_antialias_t		 antialias,
510
			      cairo_antialias_t		 antialias,
464
			      cairo_clip_t		*clip)
-
 
Line 465... Line 511...
465
{
511
			      const cairo_clip_t		*clip)
466
    cairo_analysis_surface_t *surface = abstract_surface;
512
{
467
    cairo_status_t	     backend_status;
513
    cairo_analysis_surface_t *surface = abstract_surface;
468
    cairo_rectangle_int_t    extents;
514
    cairo_int_status_t	     backend_status;
469
    cairo_bool_t             is_empty;
515
    cairo_rectangle_int_t    extents;
470
 
516
 
471
    if (surface->target->backend->fill == NULL) {
517
    if (surface->target->backend->fill == NULL) {
472
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
518
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
473
    } else {
519
    } else {
474
	backend_status =
520
	backend_status =
475
	    surface->target->backend->fill (surface->target, op,
521
	    surface->target->backend->fill (surface->target, op,
Line 476... Line 522...
476
					    source, path, fill_rule,
522
					    source, path, fill_rule,
477
					    tolerance, antialias,
523
					    tolerance, antialias,
Line 491... Line 537...
491
	cairo_rectangle_int_t mask_extents;
537
	cairo_rectangle_int_t mask_extents;
Line 492... Line 538...
492
 
538
 
493
	_cairo_path_fixed_fill_extents (path, fill_rule, tolerance,
539
	_cairo_path_fixed_fill_extents (path, fill_rule, tolerance,
Line 494... Line 540...
494
					&mask_extents);
540
					&mask_extents);
495
 
541
 
Line 496... Line 542...
496
	is_empty = _cairo_rectangle_intersect (&extents, &mask_extents);
542
	_cairo_rectangle_intersect (&extents, &mask_extents);
497
    }
543
    }
Line 504... Line 550...
504
				     cairo_operator_t	   op,
550
				     cairo_operator_t	   op,
505
				     const cairo_pattern_t *source,
551
				     const cairo_pattern_t *source,
506
				     cairo_glyph_t	  *glyphs,
552
				     cairo_glyph_t	  *glyphs,
507
				     int		   num_glyphs,
553
				     int		   num_glyphs,
508
				     cairo_scaled_font_t  *scaled_font,
554
				     cairo_scaled_font_t  *scaled_font,
509
				     cairo_clip_t         *clip,
555
				     const cairo_clip_t         *clip)
510
				     int                  *remaining_glyphs)
-
 
511
{
556
{
512
    cairo_analysis_surface_t *surface = abstract_surface;
557
    cairo_analysis_surface_t *surface = abstract_surface;
513
    cairo_status_t	     status, backend_status;
558
    cairo_int_status_t	     status, backend_status;
514
    cairo_rectangle_int_t    extents, glyph_extents;
559
    cairo_rectangle_int_t    extents, glyph_extents;
515
    cairo_bool_t             is_empty;
-
 
Line 516... Line 560...
516
 
560
 
517
    /* Adapted from _cairo_surface_show_glyphs */
561
    /* Adapted from _cairo_surface_show_glyphs */
518
    if (surface->target->backend->show_glyphs != NULL) {
562
    if (surface->target->backend->show_glyphs != NULL) {
519
	backend_status =
563
	backend_status =
520
	    surface->target->backend->show_glyphs (surface->target, op,
564
	    surface->target->backend->show_glyphs (surface->target, op,
521
						   source,
565
						   source,
522
						   glyphs, num_glyphs,
566
						   glyphs, num_glyphs,
523
						   scaled_font,
567
						   scaled_font,
524
						   clip,
-
 
525
						   remaining_glyphs);
568
						   clip);
526
	if (_cairo_status_is_error (backend_status))
569
	if (_cairo_int_status_is_error (backend_status))
527
	    return backend_status;
570
	    return backend_status;
528
    }
571
    }
529
    else if (surface->target->backend->show_text_glyphs != NULL)
572
    else if (surface->target->backend->show_text_glyphs != NULL)
530
    {
573
    {
Line 535... Line 578...
535
							glyphs, num_glyphs,
578
							glyphs, num_glyphs,
536
							NULL, 0,
579
							NULL, 0,
537
							FALSE,
580
							FALSE,
538
							scaled_font,
581
							scaled_font,
539
							clip);
582
							clip);
540
	if (_cairo_status_is_error (backend_status))
583
	if (_cairo_int_status_is_error (backend_status))
541
	    return backend_status;
584
	    return backend_status;
542
    }
585
    }
543
    else
586
    else
544
    {
587
    {
545
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
588
	backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
Line 559... Line 602...
559
							  &glyph_extents,
602
							  &glyph_extents,
560
							  NULL);
603
							  NULL);
561
	if (unlikely (status))
604
	if (unlikely (status))
562
	    return status;
605
	    return status;
Line 563... Line 606...
563
 
606
 
564
	is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
607
	_cairo_rectangle_intersect (&extents, &glyph_extents);
Line 565... Line 608...
565
    }
608
    }
566
 
609
 
Line 585... Line 628...
585
					  int			     num_glyphs,
628
					  int			     num_glyphs,
586
					  const cairo_text_cluster_t *clusters,
629
					  const cairo_text_cluster_t *clusters,
587
					  int			     num_clusters,
630
					  int			     num_clusters,
588
					  cairo_text_cluster_flags_t cluster_flags,
631
					  cairo_text_cluster_flags_t cluster_flags,
589
					  cairo_scaled_font_t	    *scaled_font,
632
					  cairo_scaled_font_t	    *scaled_font,
590
					  cairo_clip_t		    *clip)
633
					  const cairo_clip_t		    *clip)
591
{
634
{
592
    cairo_analysis_surface_t *surface = abstract_surface;
635
    cairo_analysis_surface_t *surface = abstract_surface;
593
    cairo_status_t	     status, backend_status;
636
    cairo_int_status_t	     status, backend_status;
594
    cairo_rectangle_int_t    extents, glyph_extents;
637
    cairo_rectangle_int_t    extents, glyph_extents;
595
    cairo_bool_t             is_empty;
-
 
Line 596... Line 638...
596
 
638
 
597
    /* Adapted from _cairo_surface_show_glyphs */
639
    /* Adapted from _cairo_surface_show_glyphs */
598
    backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
640
    backend_status = CAIRO_INT_STATUS_UNSUPPORTED;
599
    if (surface->target->backend->show_text_glyphs != NULL) {
641
    if (surface->target->backend->show_text_glyphs != NULL) {
Line 604... Line 646...
604
							glyphs, num_glyphs,
646
							glyphs, num_glyphs,
605
							clusters, num_clusters,
647
							clusters, num_clusters,
606
							cluster_flags,
648
							cluster_flags,
607
							scaled_font,
649
							scaled_font,
608
							clip);
650
							clip);
609
	if (_cairo_status_is_error (backend_status))
651
	if (_cairo_int_status_is_error (backend_status))
610
	    return backend_status;
652
	    return backend_status;
611
    }
653
    }
612
    if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED &&
654
    if (backend_status == CAIRO_INT_STATUS_UNSUPPORTED &&
613
	surface->target->backend->show_glyphs != NULL)
655
	surface->target->backend->show_glyphs != NULL)
614
    {
656
    {
615
	int remaining_glyphs = num_glyphs;
-
 
616
	backend_status =
657
	backend_status =
617
	    surface->target->backend->show_glyphs (surface->target, op,
658
	    surface->target->backend->show_glyphs (surface->target, op,
618
						   source,
659
						   source,
619
						   glyphs, num_glyphs,
660
						   glyphs, num_glyphs,
620
						   scaled_font,
661
						   scaled_font,
621
						   clip,
662
						   clip);
622
						   &remaining_glyphs);
-
 
623
	if (_cairo_status_is_error (backend_status))
663
	if (_cairo_int_status_is_error (backend_status))
624
	    return backend_status;
664
	    return backend_status;
625
 
-
 
626
	glyphs += num_glyphs - remaining_glyphs;
-
 
627
	num_glyphs = remaining_glyphs;
-
 
628
	if (remaining_glyphs == 0)
-
 
629
	    backend_status = CAIRO_STATUS_SUCCESS;
-
 
630
    }
665
    }
Line 631... Line 666...
631
 
666
 
632
    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
667
    if (backend_status == CAIRO_INT_STATUS_ANALYZE_RECORDING_SURFACE_PATTERN)
Line 643... Line 678...
643
							  &glyph_extents,
678
							  &glyph_extents,
644
							  NULL);
679
							  NULL);
645
	if (unlikely (status))
680
	if (unlikely (status))
646
	    return status;
681
	    return status;
Line 647... Line 682...
647
 
682
 
648
	is_empty = _cairo_rectangle_intersect (&extents, &glyph_extents);
683
	_cairo_rectangle_intersect (&extents, &glyph_extents);
Line 649... Line 684...
649
    }
684
    }
650
 
685
 
Line 651... Line 686...
651
    return _add_operation (surface, &extents, backend_status);
686
    return _add_operation (surface, &extents, backend_status);
652
}
687
}
653
 
-
 
-
 
688
 
654
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
689
static const cairo_surface_backend_t cairo_analysis_surface_backend = {
-
 
690
    CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
-
 
691
 
-
 
692
    _cairo_analysis_surface_finish,
-
 
693
    NULL,
-
 
694
 
-
 
695
    NULL, /* create_similar */
-
 
696
    NULL, /* create_similar_image */
-
 
697
    NULL, /* map_to_image */
655
    CAIRO_INTERNAL_SURFACE_TYPE_ANALYSIS,
698
    NULL, /* unmap */
656
    NULL, /* create_similar */
699
 
657
    _cairo_analysis_surface_finish,
-
 
658
    NULL, /* acquire_source_image */
-
 
659
    NULL, /* release_source_image */
-
 
660
    NULL, /* acquire_dest_image */
700
    NULL, /* source */
661
    NULL, /* release_dest_image */
-
 
662
    NULL, /* clone_similar */
-
 
663
    NULL, /* composite */
-
 
664
    NULL, /* fill_rectangles */
-
 
-
 
701
    NULL, /* acquire_source_image */
665
    NULL, /* composite_trapezoids */
702
    NULL, /* release_source_image */
666
    NULL, /* create_span_renderer */
703
    NULL, /* snapshot */
-
 
704
 
667
    NULL, /* check_span_renderer */
705
    NULL, /* copy_page */
668
    NULL, /* copy_page */
-
 
669
    NULL, /* show_page */
706
    NULL, /* show_page */
-
 
707
 
670
    _cairo_analysis_surface_get_extents,
708
    _cairo_analysis_surface_get_extents,
671
    NULL, /* old_show_glyphs */
709
    NULL, /* get_font_options */
672
    NULL, /* get_font_options */
-
 
673
    NULL, /* flush */
-
 
-
 
710
 
674
    NULL, /* mark_dirty_rectangle */
711
    NULL, /* flush */
675
    NULL, /* scaled_font_fini */
712
    NULL, /* mark_dirty_rectangle */
676
    NULL, /* scaled_glyph_fini */
713
 
677
    _cairo_analysis_surface_paint,
714
    _cairo_analysis_surface_paint,
678
    _cairo_analysis_surface_mask,
-
 
679
    _cairo_analysis_surface_stroke,
-
 
680
    _cairo_analysis_surface_fill,
-
 
681
    _cairo_analysis_surface_show_glyphs,
715
    _cairo_analysis_surface_mask,
682
    NULL, /* snapshot */
-
 
683
    NULL, /* is_similar */
716
    _cairo_analysis_surface_stroke,
684
    NULL, /* fill_stroke */
717
    _cairo_analysis_surface_fill,
685
    NULL, /* create_solid_pattern_surface */
718
    NULL, /* fill_stroke */
686
    NULL, /* can_repaint_solid_pattern_surface */
719
    _cairo_analysis_surface_show_glyphs,
Line 687... Line 720...
687
    _cairo_analysis_surface_has_show_text_glyphs,
720
    _cairo_analysis_surface_has_show_text_glyphs,
Line 805... Line 838...
805
/* These typedefs are just to silence the compiler... */
838
/* These typedefs are just to silence the compiler... */
806
typedef cairo_int_status_t
839
typedef cairo_int_status_t
807
(*_paint_func)			(void			*surface,
840
(*_paint_func)			(void			*surface,
808
			         cairo_operator_t	 op,
841
			         cairo_operator_t	 op,
809
				 const cairo_pattern_t	*source,
842
				 const cairo_pattern_t	*source,
810
				 cairo_clip_t		*clip);
843
				 const cairo_clip_t		*clip);
Line 811... Line 844...
811
 
844
 
812
typedef cairo_int_status_t
845
typedef cairo_int_status_t
813
(*_mask_func)			(void			*surface,
846
(*_mask_func)			(void			*surface,
814
			         cairo_operator_t	 op,
847
			         cairo_operator_t	 op,
815
				 const cairo_pattern_t	*source,
848
				 const cairo_pattern_t	*source,
816
				 const cairo_pattern_t	*mask,
849
				 const cairo_pattern_t	*mask,
Line 817... Line 850...
817
				 cairo_clip_t		*clip);
850
				 const cairo_clip_t		*clip);
818
 
851
 
819
typedef cairo_int_status_t
852
typedef cairo_int_status_t
820
(*_stroke_func)			(void			*surface,
853
(*_stroke_func)			(void			*surface,
821
			         cairo_operator_t	 op,
854
			         cairo_operator_t	 op,
822
				 const cairo_pattern_t	*source,
855
				 const cairo_pattern_t	*source,
823
				 cairo_path_fixed_t	*path,
856
				 const cairo_path_fixed_t	*path,
824
				 const cairo_stroke_style_t	*style,
857
				 const cairo_stroke_style_t	*style,
825
				 const cairo_matrix_t		*ctm,
858
				 const cairo_matrix_t		*ctm,
826
				 const cairo_matrix_t		*ctm_inverse,
859
				 const cairo_matrix_t		*ctm_inverse,
827
				 double			 tolerance,
860
				 double			 tolerance,
Line 828... Line 861...
828
				 cairo_antialias_t	 antialias,
861
				 cairo_antialias_t	 antialias,
829
				 cairo_clip_t		*clip);
862
				 const cairo_clip_t		*clip);
830
 
863
 
831
typedef cairo_int_status_t
864
typedef cairo_int_status_t
832
(*_fill_func)			(void			*surface,
865
(*_fill_func)			(void			*surface,
833
			         cairo_operator_t	 op,
866
			         cairo_operator_t	 op,
834
				 const cairo_pattern_t	*source,
867
				 const cairo_pattern_t	*source,
835
				 cairo_path_fixed_t	*path,
868
				 const cairo_path_fixed_t	*path,
836
				 cairo_fill_rule_t	 fill_rule,
869
				 cairo_fill_rule_t	 fill_rule,
Line 837... Line 870...
837
				 double			 tolerance,
870
				 double			 tolerance,
838
				 cairo_antialias_t	 antialias,
871
				 cairo_antialias_t	 antialias,
839
				 cairo_clip_t		*clip);
872
				 const cairo_clip_t		*clip);
840
 
873
 
841
typedef cairo_int_status_t
874
typedef cairo_int_status_t
842
(*_show_glyphs_func)		(void			*surface,
875
(*_show_glyphs_func)		(void			*surface,
843
			         cairo_operator_t	 op,
876
			         cairo_operator_t	 op,
844
				 const cairo_pattern_t	*source,
877
				 const cairo_pattern_t	*source,
845
				 cairo_glyph_t		*glyphs,
-
 
Line 846... Line 878...
846
				 int			 num_glyphs,
878
				 cairo_glyph_t		*glyphs,
847
				 cairo_scaled_font_t	*scaled_font,
879
				 int			 num_glyphs,
-
 
880
				 cairo_scaled_font_t	*scaled_font,
-
 
881
				 const cairo_clip_t		*clip);
-
 
882
 
Line 848... Line 883...
848
				 cairo_clip_t		*clip,
883
static const cairo_surface_backend_t cairo_null_surface_backend = {
-
 
884
    CAIRO_INTERNAL_SURFACE_TYPE_NULL,
-
 
885
    NULL, /* finish */
-
 
886
 
-
 
887
    NULL, /* only accessed through the surface functions */
849
				 int			*remaining_glyphs);
888
 
850
 
889
    NULL, /* create_similar */
851
static const cairo_surface_backend_t cairo_null_surface_backend = {
890
    NULL, /* create similar image */
852
    CAIRO_INTERNAL_SURFACE_TYPE_NULL,
-
 
853
 
-
 
854
    NULL, /* create_similar */
-
 
855
    NULL, /* finish */
891
    NULL, /* map to image */
856
    NULL, /* acquire_source_image */
-
 
857
    NULL, /* release_source_image */
-
 
858
    NULL, /* acquire_dest_image */
-
 
859
    NULL, /* release_dest_image */
-
 
-
 
892
    NULL, /* unmap image*/
860
    NULL, /* clone_similar */
893
 
861
    NULL, /* composite */
894
    NULL, /* source */
-
 
895
    NULL, /* acquire_source_image */
862
    NULL, /* fill_rectangles */
896
    NULL, /* release_source_image */
863
    NULL, /* composite_trapezoids */
-
 
864
    NULL, /* create_span_renderer */
897
    NULL, /* snapshot */
-
 
898
 
865
    NULL, /* check_span_renderer */
899
    NULL, /* copy_page */
866
    NULL, /* copy_page */
900
    NULL, /* show_page */
867
    NULL, /* show_page */
-
 
868
    NULL, /* get_extents */
-
 
-
 
901
 
869
    NULL, /* old_show_glyphs */
902
    NULL, /* get_extents */
870
    NULL, /* get_font_options */
903
    NULL, /* get_font_options */
871
    NULL, /* flush */
904
 
872
    NULL, /* mark_dirty_rectangle */
905
    NULL, /* flush */
873
    NULL, /* scaled_font_fini */
-
 
874
    NULL, /* scaled_glyph_fini */
-
 
875
    (_paint_func) _return_success,	    /* paint */
-
 
876
    (_mask_func) _return_success,	    /* mask */
906
    NULL, /* mark_dirty_rectangle */
877
    (_stroke_func) _return_success,	    /* stroke */
-
 
878
    (_fill_func) _return_success,	    /* fill */
907
 
879
    (_show_glyphs_func) _return_success,    /* show_glyphs */
908
    (_paint_func) _return_success,	    /* paint */
880
    NULL, /* snapshot */
909
    (_mask_func) _return_success,	    /* mask */
881
    NULL, /* is_similar */
910
    (_stroke_func) _return_success,	    /* stroke */
Line 882... Line 911...
882
    NULL, /* fill_stroke */
911
    (_fill_func) _return_success,	    /* fill */