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
 *      Chris Wilson 
35
 *      Chris Wilson 
36
 */
36
 */
Line 37... Line 37...
37
 
37
 
Line -... Line 38...
-
 
38
#include "cairoint.h"
38
#include "cairoint.h"
39
 
-
 
40
#include "cairo-clip-inline.h"
39
 
41
#include "cairo-error-private.h"
Line 40... Line 42...
40
#include "cairo-error-private.h"
42
#include "cairo-pattern-private.h"
Line 41... Line 43...
41
#include "cairo-surface-wrapper-private.h"
43
#include "cairo-surface-wrapper-private.h"
Line 47... Line 49...
47
			   const cairo_pattern_t *original,
49
			   const cairo_pattern_t *original,
48
			   const cairo_matrix_t  *ctm_inverse)
50
			   const cairo_matrix_t  *ctm_inverse)
49
{
51
{
50
    _cairo_pattern_init_static_copy (pattern, original);
52
    _cairo_pattern_init_static_copy (pattern, original);
Line 51... Line -...
51
 
-
 
52
    /* apply device_transform first so that it is transformed by ctm_inverse */
-
 
53
    if (original->type == CAIRO_PATTERN_TYPE_SURFACE) {
-
 
54
	cairo_surface_pattern_t *surface_pattern;
-
 
55
	cairo_surface_t *surface;
-
 
56
 
-
 
57
        surface_pattern = (cairo_surface_pattern_t *) original;
-
 
58
        surface = surface_pattern->surface;
-
 
59
 
-
 
60
	if (_cairo_surface_has_device_transform (surface))
-
 
61
	    _cairo_pattern_transform (pattern, &surface->device_transform);
-
 
62
    }
-
 
63
 
53
 
64
    if (! _cairo_matrix_is_identity (ctm_inverse))
54
    if (! _cairo_matrix_is_identity (ctm_inverse))
65
	_cairo_pattern_transform (pattern, ctm_inverse);
55
	_cairo_pattern_transform (pattern, ctm_inverse);
Line 66... Line -...
66
}
-
 
67
 
-
 
68
static inline cairo_bool_t
-
 
69
_cairo_surface_wrapper_needs_device_transform (cairo_surface_wrapper_t *wrapper)
-
 
70
{
-
 
71
    return ! _cairo_matrix_is_identity (&wrapper->target->device_transform);
-
 
72
}
-
 
73
 
-
 
74
static cairo_bool_t
-
 
75
_cairo_surface_wrapper_needs_extents_transform (cairo_surface_wrapper_t *wrapper)
-
 
76
{
-
 
77
    return wrapper->has_extents && (wrapper->extents.x | wrapper->extents.y);
-
 
78
}
56
}
79
 
57
 
80
cairo_status_t
58
cairo_status_t
81
_cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper,
59
_cairo_surface_wrapper_acquire_source_image (cairo_surface_wrapper_t *wrapper,
82
					     cairo_image_surface_t  **image_out,
60
					     cairo_image_surface_t  **image_out,
Line 95... Line 73...
95
					     void                   *image_extra)
73
					     void                   *image_extra)
96
{
74
{
97
    _cairo_surface_release_source_image (wrapper->target, image, image_extra);
75
    _cairo_surface_release_source_image (wrapper->target, image, image_extra);
98
}
76
}
Line 99... Line 77...
99
 
77
 
100
cairo_status_t
78
static void
101
_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
79
_cairo_surface_wrapper_get_transform (cairo_surface_wrapper_t *wrapper,
102
			      cairo_operator_t	 op,
-
 
103
			      const cairo_pattern_t *source,
-
 
104
			      cairo_clip_t	    *clip)
80
				      cairo_matrix_t *m)
105
{
-
 
106
    cairo_status_t status;
-
 
107
    cairo_clip_t clip_copy, *dev_clip = clip;
81
{
108
    cairo_pattern_union_t source_copy;
-
 
Line 109... Line 82...
109
    cairo_clip_t target_clip;
82
    cairo_matrix_init_identity (m);
110
 
83
 
Line 111... Line -...
111
    if (unlikely (wrapper->target->status))
-
 
112
	return wrapper->target->status;
84
    if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y))
113
 
85
	cairo_matrix_translate (m, -wrapper->extents.x, -wrapper->extents.y);
114
    if (wrapper->has_extents) {
-
 
115
	_cairo_clip_init_copy (&target_clip, clip);
-
 
Line -... Line 86...
-
 
86
 
116
	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
87
    if (! _cairo_matrix_is_identity (&wrapper->transform))
117
	if (unlikely (status))
88
	cairo_matrix_multiply (m, &wrapper->transform, m);
Line -... Line 89...
-
 
89
 
-
 
90
    if (! _cairo_matrix_is_identity (&wrapper->target->device_transform))
-
 
91
	cairo_matrix_multiply (m, &wrapper->target->device_transform, m);
-
 
92
}
118
	    goto FINISH;
93
 
-
 
94
static void
-
 
95
_cairo_surface_wrapper_get_inverse_transform (cairo_surface_wrapper_t *wrapper,
-
 
96
					      cairo_matrix_t *m)
-
 
97
{
-
 
98
    cairo_matrix_init_identity (m);
-
 
99
 
-
 
100
    if (! _cairo_matrix_is_identity (&wrapper->target->device_transform_inverse))
-
 
101
	cairo_matrix_multiply (m, &wrapper->target->device_transform_inverse, m);
-
 
102
 
-
 
103
    if (! _cairo_matrix_is_identity (&wrapper->transform)) {
119
 
104
	cairo_matrix_t inv;
120
	dev_clip = clip = &target_clip;
105
	cairo_status_t status;
121
    }
106
 
Line 122... Line 107...
122
 
107
	inv = wrapper->transform;
-
 
108
	status = cairo_matrix_invert (&inv);
-
 
109
	assert (status == CAIRO_STATUS_SUCCESS);
-
 
110
	cairo_matrix_multiply (m, &inv, m);
-
 
111
    }
123
    if (clip && clip->all_clipped) {
112
 
-
 
113
    if (wrapper->has_extents && (wrapper->extents.x || wrapper->extents.y))
124
	status = CAIRO_STATUS_SUCCESS;
114
	cairo_matrix_translate (m, wrapper->extents.x, wrapper->extents.y);
125
	goto FINISH;
115
}
-
 
116
 
-
 
117
static cairo_clip_t *
-
 
118
_cairo_surface_wrapper_get_clip (cairo_surface_wrapper_t *wrapper,
-
 
119
				 const cairo_clip_t *clip)
-
 
120
{
-
 
121
    cairo_clip_t *copy;
-
 
122
 
-
 
123
    copy = _cairo_clip_copy (clip);
-
 
124
    if (wrapper->has_extents) {
-
 
125
	copy = _cairo_clip_intersect_rectangle (copy, &wrapper->extents);
Line 126... Line 126...
126
    }
126
    }
-
 
127
    copy = _cairo_clip_transform (copy, &wrapper->transform);
Line -... Line 128...
-
 
128
    if (! _cairo_matrix_is_identity (&wrapper->target->device_transform))
127
 
129
	copy = _cairo_clip_transform (copy, &wrapper->target->device_transform);
-
 
130
    if (wrapper->clip)
-
 
131
	copy = _cairo_clip_intersect_clip (copy, wrapper->clip);
-
 
132
 
-
 
133
    return copy;
-
 
134
}
-
 
135
 
128
    if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
136
cairo_status_t
Line 129... Line 137...
129
	_cairo_surface_wrapper_needs_extents_transform (wrapper))
137
_cairo_surface_wrapper_paint (cairo_surface_wrapper_t *wrapper,
130
    {
138
			      cairo_operator_t	 op,
Line 131... Line -...
131
	cairo_matrix_t m;
-
 
132
 
139
			      const cairo_pattern_t *source,
133
	cairo_matrix_init_identity (&m);
140
			      const cairo_clip_t    *clip)
134
 
141
{
Line -... Line 142...
-
 
142
    cairo_status_t status;
135
	if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
143
    cairo_clip_t *dev_clip;
136
	    cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
144
    cairo_pattern_union_t source_copy;
-
 
145
 
Line 137... Line 146...
137
 
146
    if (unlikely (wrapper->target->status))
138
	if (_cairo_surface_wrapper_needs_device_transform (wrapper))
147
	return wrapper->target->status;
Line 139... Line 148...
139
	    cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
148
 
140
 
149
    dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip);
141
	if (clip != NULL) {
150
    if (_cairo_clip_is_all_clipped (dev_clip))
Line 142... Line 151...
142
	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
151
	return CAIRO_INT_STATUS_NOTHING_TO_DO;
Line 143... Line -...
143
	    if (unlikely (status))
-
 
144
		goto FINISH;
-
 
145
 
-
 
146
	    dev_clip = &clip_copy;
-
 
147
	}
152
 
148
 
153
    if (wrapper->needs_transform) {
149
	status = cairo_matrix_invert (&m);
154
	cairo_matrix_t m;
Line -... Line 155...
-
 
155
 
150
	assert (status == CAIRO_STATUS_SUCCESS);
156
	_cairo_surface_wrapper_get_transform (wrapper, &m);
151
 
157
 
152
	_copy_transformed_pattern (&source_copy.base, source, &m);
158
	status = cairo_matrix_invert (&m);
153
	source = &source_copy.base;
159
	assert (status == CAIRO_STATUS_SUCCESS);
154
    }
160
 
155
 
161
	_copy_transformed_pattern (&source_copy.base, source, &m);
156
    status = _cairo_surface_paint (wrapper->target, op, source, dev_clip);
162
	source = &source_copy.base;
157
 
163
    }
158
  FINISH:
164
 
159
    if (wrapper->has_extents)
165
    status = _cairo_surface_paint (wrapper->target, op, source, dev_clip);
160
	_cairo_clip_reset (&target_clip);
166
 
161
    if (dev_clip != clip)
-
 
Line 162... Line 167...
162
	_cairo_clip_reset (dev_clip);
167
    _cairo_clip_destroy (dev_clip);
163
    return status;
168
    return status;
Line 164... Line -...
164
}
-
 
165
 
169
}
166
cairo_status_t
170
 
167
_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
-
 
168
			     cairo_operator_t	 op,
171
 
Line 169... Line -...
169
			     const cairo_pattern_t *source,
-
 
170
			     const cairo_pattern_t *mask,
-
 
171
			     cairo_clip_t	    *clip)
-
 
172
{
172
cairo_status_t
173
    cairo_status_t status;
-
 
174
    cairo_clip_t clip_copy, *dev_clip = clip;
-
 
175
    cairo_pattern_union_t source_copy;
-
 
176
    cairo_pattern_union_t mask_copy;
-
 
177
    cairo_clip_t target_clip;
-
 
178
 
-
 
179
    if (unlikely (wrapper->target->status))
-
 
180
	return wrapper->target->status;
173
_cairo_surface_wrapper_mask (cairo_surface_wrapper_t *wrapper,
Line 181... Line -...
181
 
-
 
182
    if (wrapper->has_extents) {
-
 
183
	_cairo_clip_init_copy (&target_clip, clip);
174
			     cairo_operator_t	 op,
184
	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-
 
185
	if (unlikely (status))
-
 
186
	    goto FINISH;
-
 
187
 
-
 
188
	dev_clip = clip = &target_clip;
-
 
189
    }
-
 
190
 
-
 
191
    if (clip && clip->all_clipped) {
-
 
192
	status = CAIRO_STATUS_SUCCESS;
-
 
193
	goto FINISH;
-
 
194
    }
-
 
195
 
-
 
Line 196... Line 175...
196
    if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
175
			     const cairo_pattern_t *source,
197
	_cairo_surface_wrapper_needs_extents_transform (wrapper))
176
			     const cairo_pattern_t *mask,
Line 198... Line 177...
198
    {
177
			     const cairo_clip_t	    *clip)
Line 224... Line 203...
224
	mask = &mask_copy.base;
203
	mask = &mask_copy.base;
225
    }
204
    }
Line 226... Line 205...
226
 
205
 
Line 227... Line -...
227
    status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip);
-
 
228
 
-
 
229
  FINISH:
-
 
230
    if (wrapper->has_extents)
-
 
231
	_cairo_clip_reset (&target_clip);
206
    status = _cairo_surface_mask (wrapper->target, op, source, mask, dev_clip);
232
    if (dev_clip != clip)
207
 
233
	_cairo_clip_reset (dev_clip);
208
    _cairo_clip_destroy (dev_clip);
Line 234... Line 209...
234
    return status;
209
    return status;
235
}
210
}
236
 
211
 
237
cairo_status_t
212
cairo_status_t
238
_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
213
_cairo_surface_wrapper_stroke (cairo_surface_wrapper_t *wrapper,
239
			       cairo_operator_t		 op,
214
			       cairo_operator_t		 op,
240
			       const cairo_pattern_t	*source,
215
			       const cairo_pattern_t	*source,
241
			       cairo_path_fixed_t	*path,
216
			       const cairo_path_fixed_t	*path,
242
			       const cairo_stroke_style_t	*stroke_style,
217
			       const cairo_stroke_style_t	*stroke_style,
243
			       const cairo_matrix_t		*ctm,
218
			       const cairo_matrix_t		*ctm,
244
			       const cairo_matrix_t		*ctm_inverse,
219
			       const cairo_matrix_t		*ctm_inverse,
245
			       double			 tolerance,
220
			       double			 tolerance,
246
			       cairo_antialias_t	 antialias,
221
			       cairo_antialias_t	 antialias,
247
			       cairo_clip_t		*clip)
222
			       const cairo_clip_t		*clip)
248
{
223
{
249
    cairo_status_t status;
224
    cairo_status_t status;
250
    cairo_path_fixed_t path_copy, *dev_path = path;
225
    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
251
    cairo_clip_t clip_copy, *dev_clip = clip;
226
    cairo_clip_t *dev_clip;
252
    cairo_matrix_t dev_ctm = *ctm;
-
 
Line 253... Line 227...
253
    cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
227
    cairo_matrix_t dev_ctm = *ctm;
254
    cairo_pattern_union_t source_copy;
228
    cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
Line 255... Line -...
255
    cairo_clip_t target_clip;
-
 
256
 
-
 
257
    if (unlikely (wrapper->target->status))
229
    cairo_pattern_union_t source_copy;
258
	return wrapper->target->status;
-
 
259
 
-
 
260
    if (wrapper->has_extents) {
-
 
261
	_cairo_clip_init_copy (&target_clip, clip);
-
 
262
	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-
 
263
	if (unlikely (status))
-
 
264
	    goto FINISH;
230
 
265
 
231
    if (unlikely (wrapper->target->status))
266
	dev_clip = clip = &target_clip;
-
 
267
    }
-
 
Line 268... Line 232...
268
 
232
	return wrapper->target->status;
269
    if (clip && clip->all_clipped) {
-
 
270
	status = CAIRO_STATUS_SUCCESS;
-
 
271
	goto FINISH;
233
 
Line 272... Line -...
272
    }
-
 
273
 
-
 
274
    if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
234
    dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip);
275
	_cairo_surface_wrapper_needs_extents_transform (wrapper))
-
 
276
    {
-
 
277
	cairo_matrix_t m;
-
 
278
 
-
 
Line 279... Line 235...
279
	cairo_matrix_init_identity (&m);
235
    if (_cairo_clip_is_all_clipped (dev_clip))
280
 
236
	return CAIRO_INT_STATUS_NOTHING_TO_DO;
281
	if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
237
 
Line 282... Line 238...
282
	    cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
238
    if (wrapper->needs_transform) {
283
 
239
	cairo_matrix_t m;
Line 284... Line -...
284
	if (_cairo_surface_wrapper_needs_device_transform (wrapper))
-
 
285
	    cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
-
 
286
 
-
 
287
	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
-
 
288
	if (unlikely (status))
-
 
289
	    goto FINISH;
-
 
290
 
-
 
291
	_cairo_path_fixed_transform (&path_copy, &m);
-
 
292
	dev_path = &path_copy;
240
 
Line 293... Line 241...
293
 
241
	_cairo_surface_wrapper_get_transform (wrapper, &m);
294
	if (clip != NULL) {
242
 
Line 295... Line 243...
295
	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
243
	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
Line 296... Line 244...
296
	    if (unlikely (status))
244
	if (unlikely (status))
297
		goto FINISH;
245
	    goto FINISH;
298
 
246
 
299
	    dev_clip = &clip_copy;
-
 
300
	}
-
 
301
 
-
 
302
	cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
-
 
303
 
-
 
304
	status = cairo_matrix_invert (&m);
-
 
305
	assert (status == CAIRO_STATUS_SUCCESS);
-
 
Line 306... Line 247...
306
 
247
	_cairo_path_fixed_transform (&path_copy, &m);
307
	cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse);
248
	dev_path = &path_copy;
308
 
249
 
309
	_copy_transformed_pattern (&source_copy.base, source, &m);
250
	cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
310
	source = &source_copy.base;
251
 
Line 311... Line 252...
311
    }
252
	status = cairo_matrix_invert (&m);
312
    else
253
	assert (status == CAIRO_STATUS_SUCCESS);
313
    {
254
 
314
	if (clip != NULL) {
-
 
315
	    dev_clip = &clip_copy;
-
 
316
	    _cairo_clip_init_copy (&clip_copy, clip);
-
 
317
	}
255
	cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse);
318
    }
256
 
319
 
257
	_copy_transformed_pattern (&source_copy.base, source, &m);
Line 320... Line 258...
320
    status = _cairo_surface_stroke (wrapper->target, op, source,
258
	source = &source_copy.base;
321
				    dev_path, stroke_style,
259
    }
322
				    &dev_ctm, &dev_ctm_inverse,
260
 
323
				    tolerance, antialias,
261
    status = _cairo_surface_stroke (wrapper->target, op, source,
324
				    dev_clip);
262
				    dev_path, stroke_style,
325
 
263
				    &dev_ctm, &dev_ctm_inverse,
326
 FINISH:
264
				    tolerance, antialias,
327
    if (dev_path != path)
265
				    dev_clip);
328
	_cairo_path_fixed_fini (dev_path);
266
 
329
    if (wrapper->has_extents)
267
 FINISH:
330
	_cairo_clip_reset (&target_clip);
268
    if (dev_path != path)
331
    if (dev_clip != clip)
269
	_cairo_path_fixed_fini (dev_path);
332
	_cairo_clip_reset (dev_clip);
270
    _cairo_clip_destroy (dev_clip);
333
    return status;
271
    return status;
334
}
272
}
335
 
273
 
336
cairo_status_t
274
cairo_status_t
337
_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
275
_cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
338
				    cairo_operator_t	     fill_op,
276
				    cairo_operator_t	     fill_op,
339
				    const cairo_pattern_t   *fill_source,
-
 
340
				    cairo_fill_rule_t	     fill_rule,
277
				    const cairo_pattern_t   *fill_source,
341
				    double		     fill_tolerance,
278
				    cairo_fill_rule_t	     fill_rule,
-
 
279
				    double		     fill_tolerance,
342
				    cairo_antialias_t	     fill_antialias,
280
				    cairo_antialias_t	     fill_antialias,
343
				    cairo_path_fixed_t	    *path,
281
				    const cairo_path_fixed_t*path,
344
				    cairo_operator_t	     stroke_op,
-
 
Line 345... Line 282...
345
				    const cairo_pattern_t   *stroke_source,
282
				    cairo_operator_t	     stroke_op,
346
				    const cairo_stroke_style_t    *stroke_style,
283
				    const cairo_pattern_t   *stroke_source,
Line 347... Line -...
347
				    const cairo_matrix_t	    *stroke_ctm,
-
 
348
				    const cairo_matrix_t	    *stroke_ctm_inverse,
284
				    const cairo_stroke_style_t    *stroke_style,
349
				    double		     stroke_tolerance,
285
				    const cairo_matrix_t	    *stroke_ctm,
350
				    cairo_antialias_t	     stroke_antialias,
-
 
351
				    cairo_clip_t	    *clip)
286
				    const cairo_matrix_t	    *stroke_ctm_inverse,
Line 352... Line -...
352
{
-
 
353
    cairo_status_t status;
-
 
354
    cairo_path_fixed_t path_copy, *dev_path = path;
-
 
355
    cairo_clip_t clip_copy, *dev_clip = clip;
287
				    double		     stroke_tolerance,
356
    cairo_matrix_t dev_ctm = *stroke_ctm;
-
 
357
    cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
-
 
358
    cairo_pattern_union_t stroke_source_copy;
-
 
359
    cairo_pattern_union_t fill_source_copy;
-
 
360
    cairo_clip_t target_clip;
-
 
361
 
-
 
362
    if (unlikely (wrapper->target->status))
-
 
363
	return wrapper->target->status;
288
				    cairo_antialias_t	     stroke_antialias,
Line 364... Line -...
364
 
-
 
365
    if (wrapper->has_extents) {
-
 
366
	_cairo_clip_init_copy (&target_clip, clip);
289
				    const cairo_clip_t	    *clip)
367
	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-
 
368
	if (unlikely (status))
-
 
369
	    goto FINISH;
-
 
370
 
-
 
Line 371... Line 290...
371
	dev_clip = clip = &target_clip;
290
{
372
    }
291
    cairo_status_t status;
373
 
292
    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *)path;
Line 374... Line 293...
374
    if (clip && clip->all_clipped) {
293
    cairo_matrix_t dev_ctm = *stroke_ctm;
375
	status = CAIRO_STATUS_SUCCESS;
294
    cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
Line 376... Line -...
376
	goto FINISH;
-
 
377
    }
-
 
378
 
-
 
379
    if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
-
 
380
	_cairo_surface_wrapper_needs_extents_transform (wrapper))
-
 
381
    {
-
 
382
	cairo_matrix_t m;
-
 
383
 
-
 
384
	cairo_matrix_init_identity (&m);
295
    cairo_clip_t *dev_clip;
Line 385... Line 296...
385
 
296
    cairo_pattern_union_t stroke_source_copy;
386
	if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
297
    cairo_pattern_union_t fill_source_copy;
Line 415... Line 326...
415
	stroke_source = &stroke_source_copy.base;
326
	stroke_source = &stroke_source_copy.base;
Line 416... Line 327...
416
 
327
 
417
	_copy_transformed_pattern (&fill_source_copy.base, fill_source, &m);
328
	_copy_transformed_pattern (&fill_source_copy.base, fill_source, &m);
418
	fill_source = &fill_source_copy.base;
329
	fill_source = &fill_source_copy.base;
419
    }
-
 
420
    else
-
 
421
    {
-
 
422
	if (clip != NULL) {
-
 
423
	    dev_clip = &clip_copy;
-
 
424
	    _cairo_clip_init_copy (&clip_copy, clip);
-
 
425
	}
-
 
Line 426... Line 330...
426
    }
330
    }
427
 
331
 
428
    status = _cairo_surface_fill_stroke (wrapper->target,
332
    status = _cairo_surface_fill_stroke (wrapper->target,
429
					 fill_op, fill_source, fill_rule,
333
					 fill_op, fill_source, fill_rule,
Line 436... Line 340...
436
					 dev_clip);
340
					 dev_clip);
Line 437... Line 341...
437
 
341
 
438
  FINISH:
342
  FINISH:
439
    if (dev_path != path)
343
    if (dev_path != path)
440
	_cairo_path_fixed_fini (dev_path);
-
 
441
    if (wrapper->has_extents)
-
 
442
	_cairo_clip_reset (&target_clip);
-
 
443
    if (dev_clip != clip)
344
	_cairo_path_fixed_fini (dev_path);
444
	_cairo_clip_reset (dev_clip);
345
    _cairo_clip_destroy (dev_clip);
445
    return status;
346
    return status;
Line 446... Line 347...
446
}
347
}
447
 
348
 
448
cairo_status_t
349
cairo_status_t
449
_cairo_surface_wrapper_fill (cairo_surface_wrapper_t	*wrapper,
350
_cairo_surface_wrapper_fill (cairo_surface_wrapper_t	*wrapper,
450
			     cairo_operator_t	 op,
351
			     cairo_operator_t	 op,
451
			     const cairo_pattern_t *source,
352
			     const cairo_pattern_t *source,
452
			     cairo_path_fixed_t	*path,
353
			     const cairo_path_fixed_t	*path,
453
			     cairo_fill_rule_t	 fill_rule,
354
			     cairo_fill_rule_t	 fill_rule,
454
			     double		 tolerance,
355
			     double		 tolerance,
455
			     cairo_antialias_t	 antialias,
356
			     cairo_antialias_t	 antialias,
456
			     cairo_clip_t	*clip)
357
			     const cairo_clip_t	*clip)
457
{
358
{
458
    cairo_status_t status;
-
 
459
    cairo_path_fixed_t path_copy, *dev_path = path;
359
    cairo_status_t status;
460
    cairo_clip_t clip_copy, *dev_clip = clip;
360
    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
Line 461... Line 361...
461
    cairo_pattern_union_t source_copy;
361
    cairo_pattern_union_t source_copy;
462
    cairo_clip_t target_clip;
362
    cairo_clip_t *dev_clip;
Line 463... Line -...
463
 
-
 
464
    if (unlikely (wrapper->target->status))
-
 
465
	return wrapper->target->status;
363
 
466
 
-
 
467
    if (wrapper->has_extents) {
-
 
468
	_cairo_clip_init_copy (&target_clip, clip);
-
 
469
	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-
 
470
	if (unlikely (status))
-
 
471
	    goto FINISH;
-
 
472
 
364
    if (unlikely (wrapper->target->status))
473
	dev_clip = clip = &target_clip;
365
	return wrapper->target->status;
474
    }
-
 
475
 
-
 
Line 476... Line 366...
476
    if (clip && clip->all_clipped) {
366
 
477
	status = CAIRO_STATUS_SUCCESS;
-
 
478
	goto FINISH;
-
 
479
    }
367
    dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip);
Line 480... Line -...
480
 
-
 
481
    if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
-
 
482
	_cairo_surface_wrapper_needs_extents_transform (wrapper))
368
    if (_cairo_clip_is_all_clipped (dev_clip))
483
    {
-
 
484
	cairo_matrix_t m;
-
 
485
 
-
 
486
	cairo_matrix_init_identity (&m);
-
 
Line 487... Line 369...
487
 
369
	return CAIRO_INT_STATUS_NOTHING_TO_DO;
488
	if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
370
 
489
	    cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
371
    if (wrapper->needs_transform) {
Line 490... Line 372...
490
 
372
	cairo_matrix_t m;
491
	if (_cairo_surface_wrapper_needs_device_transform (wrapper))
373
 
Line 492... Line -...
492
	    cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
-
 
493
 
-
 
494
	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
-
 
495
	if (unlikely (status))
-
 
496
	    goto FINISH;
-
 
497
 
-
 
498
	_cairo_path_fixed_transform (&path_copy, &m);
-
 
499
	dev_path = &path_copy;
-
 
500
 
374
	_cairo_surface_wrapper_get_transform (wrapper, &m);
501
	if (clip != NULL) {
375
 
Line 502... Line 376...
502
	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
376
	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
503
	    if (unlikely (status))
377
	if (unlikely (status))
504
		goto FINISH;
378
	    goto FINISH;
505
 
-
 
506
	    dev_clip = &clip_copy;
-
 
507
	}
-
 
508
 
-
 
509
	status = cairo_matrix_invert (&m);
-
 
510
	assert (status == CAIRO_STATUS_SUCCESS);
-
 
511
 
-
 
Line 512... Line 379...
512
	_copy_transformed_pattern (&source_copy.base, source, &m);
379
 
513
	source = &source_copy.base;
380
	_cairo_path_fixed_transform (&path_copy, &m);
514
    }
381
	dev_path = &path_copy;
515
    else
382
 
Line 516... Line 383...
516
    {
383
	status = cairo_matrix_invert (&m);
517
	if (clip != NULL) {
384
	assert (status == CAIRO_STATUS_SUCCESS);
518
	    dev_clip = &clip_copy;
385
 
519
	    _cairo_clip_init_copy (&clip_copy, clip);
-
 
520
	}
-
 
521
    }
-
 
522
 
386
	_copy_transformed_pattern (&source_copy.base, source, &m);
523
    status = _cairo_surface_fill (wrapper->target, op, source,
387
	source = &source_copy.base;
524
				  dev_path, fill_rule,
388
    }
Line 525... Line 389...
525
				  tolerance, antialias,
389
 
526
				  dev_clip);
390
    status = _cairo_surface_fill (wrapper->target, op, source,
527
 
391
				  dev_path, fill_rule,
528
 FINISH:
392
				  tolerance, antialias,
529
    if (dev_path != path)
393
				  dev_clip);
530
	_cairo_path_fixed_fini (dev_path);
394
 
531
    if (wrapper->has_extents)
395
 FINISH:
532
	_cairo_clip_reset (&target_clip);
396
    if (dev_path != path)
533
    if (dev_clip != clip)
397
	_cairo_path_fixed_fini (dev_path);
534
	_cairo_clip_reset (dev_clip);
398
    _cairo_clip_destroy (dev_clip);
535
    return status;
399
    return status;
536
}
400
}
537
 
401
 
538
cairo_status_t
402
cairo_status_t
539
_cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
403
_cairo_surface_wrapper_show_text_glyphs (cairo_surface_wrapper_t *wrapper,
540
					 cairo_operator_t	     op,
404
					 cairo_operator_t	     op,
-
 
405
					 const cairo_pattern_t	    *source,
541
					 const cairo_pattern_t	    *source,
406
					 const char		    *utf8,
-
 
407
					 int			     utf8_len,
542
					 const char		    *utf8,
408
					 const cairo_glyph_t	    *glyphs,
543
					 int			     utf8_len,
409
					 int			     num_glyphs,
Line 544... Line 410...
544
					 cairo_glyph_t		    *glyphs,
410
					 const cairo_text_cluster_t *clusters,
545
					 int			     num_glyphs,
411
					 int			     num_clusters,
Line -... Line 412...
-
 
412
					 cairo_text_cluster_flags_t  cluster_flags,
546
					 const cairo_text_cluster_t *clusters,
413
					 cairo_scaled_font_t	    *scaled_font,
547
					 int			     num_clusters,
414
					 const cairo_clip_t	    *clip)
Line 548... Line -...
548
					 cairo_text_cluster_flags_t  cluster_flags,
-
 
549
					 cairo_scaled_font_t	    *scaled_font,
415
{
550
					 cairo_clip_t		    *clip)
416
    cairo_status_t status;
551
{
-
 
552
    cairo_status_t status;
-
 
553
    cairo_clip_t clip_copy, *dev_clip = clip;
-
 
554
    cairo_glyph_t *dev_glyphs = glyphs;
-
 
555
    cairo_pattern_union_t source_copy;
-
 
Line 556... Line 417...
556
    cairo_clip_t target_clip;
417
    cairo_clip_t *dev_clip;
557
 
-
 
558
    if (unlikely (wrapper->target->status))
-
 
559
	return wrapper->target->status;
-
 
560
 
-
 
561
    if (glyphs == NULL || num_glyphs == 0)
-
 
562
	return CAIRO_STATUS_SUCCESS;
-
 
563
 
-
 
564
    if (wrapper->has_extents) {
418
    cairo_glyph_t stack_glyphs [CAIRO_STACK_ARRAY_LENGTH(cairo_glyph_t)];
565
	_cairo_clip_init_copy (&target_clip, clip);
419
    cairo_glyph_t *dev_glyphs = stack_glyphs;
Line 566... Line -...
566
	status = _cairo_clip_rectangle (&target_clip, &wrapper->extents);
-
 
567
	if (unlikely (status))
-
 
568
	    goto FINISH;
420
    cairo_scaled_font_t *dev_scaled_font = scaled_font;
569
 
-
 
570
	dev_clip = clip = &target_clip;
-
 
571
    }
-
 
572
 
-
 
Line 573... Line -...
573
    if (clip && clip->all_clipped) {
-
 
574
	status = CAIRO_STATUS_SUCCESS;
421
    cairo_pattern_union_t source_copy;
575
	goto FINISH;
422
    cairo_font_options_t options;
576
    }
-
 
Line -... Line 423...
-
 
423
 
-
 
424
    if (unlikely (wrapper->target->status))
-
 
425
	return wrapper->target->status;
577
 
426
 
-
 
427
    dev_clip = _cairo_surface_wrapper_get_clip (wrapper, clip);
-
 
428
    if (_cairo_clip_is_all_clipped (dev_clip))
-
 
429
	return CAIRO_INT_STATUS_NOTHING_TO_DO;
578
    if (_cairo_surface_wrapper_needs_device_transform (wrapper) ||
430
 
Line -... Line 431...
-
 
431
    cairo_surface_get_font_options (wrapper->target, &options);
579
	_cairo_surface_wrapper_needs_extents_transform (wrapper))
432
    cairo_font_options_merge (&options, &scaled_font->options);
580
    {
433
 
581
	cairo_matrix_t m;
434
    if (wrapper->needs_transform) {
582
	int i;
435
	cairo_matrix_t m;
583
 
436
	int i;
-
 
437
 
Line 584... Line 438...
584
	cairo_matrix_init_identity (&m);
438
	_cairo_surface_wrapper_get_transform (wrapper, &m);
585
 
439
 
586
	if (_cairo_surface_wrapper_needs_extents_transform (wrapper))
440
	if (! _cairo_matrix_is_translation (&wrapper->transform)) {
-
 
441
	    cairo_matrix_t ctm;
-
 
442
 
587
	    cairo_matrix_translate (&m, -wrapper->extents.x, -wrapper->extents.y);
443
	    /* XXX No device-transform? A bug in the tangle of layers? */
Line 588... Line 444...
588
 
444
	    _cairo_matrix_multiply (&ctm,
589
	if (_cairo_surface_wrapper_needs_device_transform (wrapper))
445
				    &wrapper->transform,
Line 590... Line 446...
590
	    cairo_matrix_multiply (&m, &wrapper->target->device_transform, &m);
446
				    &scaled_font->ctm);
591
 
447
	    dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face,
-
 
448
							&scaled_font->font_matrix,
-
 
449
							&ctm, &options);
-
 
450
	}
-
 
451
 
-
 
452
	if (num_glyphs > ARRAY_LENGTH (stack_glyphs)) {
-
 
453
	    dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
-
 
454
	    if (unlikely (dev_glyphs == NULL)) {
-
 
455
		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
-
 
456
		goto FINISH;
-
 
457
	    }
-
 
458
	}
-
 
459
 
-
 
460
	for (i = 0; i < num_glyphs; i++) {
-
 
461
	    dev_glyphs[i] = glyphs[i];
-
 
462
	    cairo_matrix_transform_point (&m,
-
 
463
					  &dev_glyphs[i].x,
-
 
464
					  &dev_glyphs[i].y);
592
	if (clip != NULL) {
465
	}
593
	    status = _cairo_clip_init_copy_transformed (&clip_copy, clip, &m);
-
 
594
	    if (unlikely (status))
-
 
595
		goto FINISH;
-
 
596
 
-
 
597
	    dev_clip = &clip_copy;
-
 
598
	}
466
 
-
 
467
	status = cairo_matrix_invert (&m);
-
 
468
	assert (status == CAIRO_STATUS_SUCCESS);
599
 
469
 
Line 600... Line 470...
600
	dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
470
	_copy_transformed_pattern (&source_copy.base, source, &m);
601
	if (dev_glyphs == NULL) {
471
	source = &source_copy.base;
602
	    status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
472
    } else {
603
	    goto FINISH;
473
	if (! cairo_font_options_equal (&options, &scaled_font->options)) {
604
	}
474
	    dev_scaled_font = cairo_scaled_font_create (scaled_font->font_face,
605
 
475
							&scaled_font->font_matrix,
606
	for (i = 0; i < num_glyphs; i++) {
476
							&scaled_font->ctm,
607
	    dev_glyphs[i] = glyphs[i];
-
 
608
	    cairo_matrix_transform_point (&m, &dev_glyphs[i].x, &dev_glyphs[i].y);
477
							&options);
609
	}
-
 
610
 
478
	}
611
	status = cairo_matrix_invert (&m);
-
 
612
	assert (status == CAIRO_STATUS_SUCCESS);
-
 
613
 
479
 
614
	_copy_transformed_pattern (&source_copy.base, source, &m);
480
	/* show_text_glyphs is special because _cairo_surface_show_text_glyphs is allowed
-
 
481
	 * to modify the glyph array that's passed in.  We must always
-
 
482
	 * copy the array before handing it to the backend.
615
	source = &source_copy.base;
483
	 */
616
    }
484
	if (num_glyphs > ARRAY_LENGTH (stack_glyphs)) {
Line 617... Line 485...
617
    else
485
	    dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
618
    {
486
	    if (unlikely (dev_glyphs == NULL)) {
Line 664... Line 532...
664
    } else {
532
    } else {
665
	return _cairo_surface_get_extents (wrapper->target, extents);
533
	return _cairo_surface_get_extents (wrapper->target, extents);
666
    }
534
    }
667
}
535
}
Line -... Line 536...
-
 
536
 
-
 
537
static cairo_bool_t
-
 
538
_cairo_surface_wrapper_needs_device_transform (cairo_surface_wrapper_t *wrapper)
-
 
539
{
-
 
540
    return
-
 
541
	(wrapper->has_extents && (wrapper->extents.x | wrapper->extents.y)) ||
-
 
542
	! _cairo_matrix_is_identity (&wrapper->transform) ||
-
 
543
	! _cairo_matrix_is_identity (&wrapper->target->device_transform);
-
 
544
}
668
 
545
 
669
void
546
void
670
_cairo_surface_wrapper_set_extents (cairo_surface_wrapper_t *wrapper,
547
_cairo_surface_wrapper_intersect_extents (cairo_surface_wrapper_t *wrapper,
671
				    const cairo_rectangle_int_t *extents)
548
					  const cairo_rectangle_int_t *extents)
672
{
549
{
673
    if (extents != NULL) {
550
    if (! wrapper->has_extents) {
674
	wrapper->extents = *extents;
551
	wrapper->extents = *extents;
-
 
552
	wrapper->has_extents = TRUE;
-
 
553
    } else
-
 
554
	_cairo_rectangle_intersect (&wrapper->extents, extents);
-
 
555
 
-
 
556
    wrapper->needs_transform =
-
 
557
	_cairo_surface_wrapper_needs_device_transform (wrapper);
-
 
558
}
-
 
559
 
-
 
560
void
-
 
561
_cairo_surface_wrapper_set_inverse_transform (cairo_surface_wrapper_t *wrapper,
-
 
562
					      const cairo_matrix_t *transform)
-
 
563
{
-
 
564
    cairo_status_t status;
-
 
565
 
-
 
566
    if (transform == NULL || _cairo_matrix_is_identity (transform)) {
-
 
567
	cairo_matrix_init_identity (&wrapper->transform);
-
 
568
 
-
 
569
	wrapper->needs_transform =
675
	wrapper->has_extents = TRUE;
570
	    _cairo_surface_wrapper_needs_device_transform (wrapper);
-
 
571
    } else {
-
 
572
	wrapper->transform = *transform;
-
 
573
	status = cairo_matrix_invert (&wrapper->transform);
-
 
574
	/* should always be invertible unless given pathological input */
-
 
575
	assert (status == CAIRO_STATUS_SUCCESS);
676
    } else {
576
 
677
	wrapper->has_extents = FALSE;
577
	wrapper->needs_transform = TRUE;
678
    }
578
    }
Line 679... Line 579...
679
}
579
}
-
 
580
 
-
 
581
void
-
 
582
_cairo_surface_wrapper_set_clip (cairo_surface_wrapper_t *wrapper,
-
 
583
				 const cairo_clip_t *clip)
-
 
584
{
-
 
585
    wrapper->clip = clip;
-
 
586
}
680
 
587
 
681
void
588
void
682
_cairo_surface_wrapper_get_font_options (cairo_surface_wrapper_t    *wrapper,
589
_cairo_surface_wrapper_get_font_options (cairo_surface_wrapper_t    *wrapper,
683
					 cairo_font_options_t	    *options)
590
					 cairo_font_options_t	    *options)
684
{
591
{
Line 685... Line 592...
685
    cairo_surface_get_font_options (wrapper->target, options);
592
    cairo_surface_get_font_options (wrapper->target, options);
686
}
593
}
687
 
594
 
-
 
595
cairo_surface_t *
688
cairo_surface_t *
596
_cairo_surface_wrapper_snapshot (cairo_surface_wrapper_t *wrapper)
-
 
597
{
-
 
598
    if (wrapper->target->backend->snapshot)
689
_cairo_surface_wrapper_snapshot (cairo_surface_wrapper_t *wrapper)
599
	return wrapper->target->backend->snapshot (wrapper->target);
Line 690... Line 600...
690
{
600
 
691
    return _cairo_surface_snapshot (wrapper->target);
601
    return NULL;
692
}
602
}
Line 700... Line 610...
700
void
610
void
701
_cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper,
611
_cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper,
702
			     cairo_surface_t *target)
612
			     cairo_surface_t *target)
703
{
613
{
704
    wrapper->target = cairo_surface_reference (target);
614
    wrapper->target = cairo_surface_reference (target);
-
 
615
    cairo_matrix_init_identity (&wrapper->transform);
705
    wrapper->has_extents = FALSE;
616
    wrapper->has_extents = FALSE;
-
 
617
    wrapper->extents.x = wrapper->extents.y = 0;
-
 
618
    wrapper->clip = NULL;
-
 
619
 
-
 
620
    wrapper->needs_transform = FALSE;
-
 
621
    if (target) {
-
 
622
	wrapper->needs_transform =
-
 
623
	    ! _cairo_matrix_is_identity (&target->device_transform);
-
 
624
    }
706
}
625
}
Line 707... Line 626...
707
 
626
 
708
void
627
void
709
_cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper)
628
_cairo_surface_wrapper_fini (cairo_surface_wrapper_t *wrapper)
710
{
629
{
711
    cairo_surface_destroy (wrapper->target);
630
    cairo_surface_destroy (wrapper->target);
-
 
631
}
-
 
632
 
-
 
633
cairo_bool_t
-
 
634
_cairo_surface_wrapper_get_target_extents (cairo_surface_wrapper_t *wrapper,
-
 
635
					   cairo_rectangle_int_t *extents)
-
 
636
{
-
 
637
    cairo_rectangle_int_t clip;
-
 
638
    cairo_bool_t has_clip;
-
 
639
 
-
 
640
    has_clip = _cairo_surface_get_extents (wrapper->target, &clip);
-
 
641
    if (wrapper->clip) {
-
 
642
	if (has_clip) {
-
 
643
	    if (! _cairo_rectangle_intersect (&clip,
-
 
644
					      _cairo_clip_get_extents (wrapper->clip)))
-
 
645
		return FALSE;
-
 
646
	} else {
-
 
647
	    has_clip = TRUE;
-
 
648
	    clip = *_cairo_clip_get_extents (wrapper->clip);
-
 
649
	}
-
 
650
    }
-
 
651
 
-
 
652
    if (has_clip && wrapper->needs_transform) {
-
 
653
	cairo_matrix_t m;
-
 
654
	double x1, y1, x2, y2;
-
 
655
 
-
 
656
	_cairo_surface_wrapper_get_inverse_transform (wrapper, &m);
-
 
657
 
-
 
658
	x1 = clip.x;
-
 
659
	y1 = clip.y;
-
 
660
	x2 = clip.x + clip.width;
-
 
661
	y2 = clip.y + clip.height;
-
 
662
 
-
 
663
	_cairo_matrix_transform_bounding_box (&m, &x1, &y1, &x2, &y2, NULL);
-
 
664
 
-
 
665
	clip.x = floor (x1);
-
 
666
	clip.y = floor (y1);
-
 
667
	clip.width  = ceil (x2) - clip.x;
-
 
668
	clip.height = ceil (y2) - clip.y;
-
 
669
    }
-
 
670
 
-
 
671
    if (has_clip) {
-
 
672
	if (wrapper->has_extents) {
-
 
673
	    *extents = wrapper->extents;
-
 
674
	    return _cairo_rectangle_intersect (extents, &clip);
-
 
675
	} else {
-
 
676
	    *extents = clip;
-
 
677
	    return TRUE;
-
 
678
	}
-
 
679
    } else if (wrapper->has_extents) {
-
 
680
	*extents = wrapper->extents;
-
 
681
	return TRUE;
-
 
682
    } else {
-
 
683
	_cairo_unbounded_rectangle_init (extents);
-
 
684
	return TRUE;
-
 
685
    }