Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1892 serge 1
/* cairo - a vector graphics library with display and print output
2
 *
3
 * Copyright © 2005 Red Hat, Inc
4
 * Copyright © 2007 Adrian Johnson
5
 * Copyright © 2009 Chris Wilson
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it either under the terms of the GNU Lesser General Public
9
 * License version 2.1 as published by the Free Software Foundation
10
 * (the "LGPL") or, at your option, under the terms of the Mozilla
11
 * Public License Version 1.1 (the "MPL"). If you do not alter this
12
 * notice, a recipient may use your version of this file under either
13
 * the MPL or the LGPL.
14
 *
15
 * You should have received a copy of the LGPL along with this library
16
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18
 * You should have received a copy of the MPL along with this library
19
 * in the file COPYING-MPL-1.1
20
 *
21
 * The contents of this file are subject to the Mozilla Public License
22
 * Version 1.1 (the "License"); you may not use this file except in
23
 * compliance with the License. You may obtain a copy of the License at
24
 * http://www.mozilla.org/MPL/
25
 *
26
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28
 * the specific language governing rights and limitations.
29
 *
30
 * The Original Code is the cairo graphics library.
31
 *
32
 * The Initial Developer of the Original Code is Red Hat, Inc.
33
 *
34
 * Contributor(s):
35
 *      Chris Wilson 
36
 */
37
 
38
#include "cairoint.h"
39
 
3959 Serge 40
#include "cairo-clip-inline.h"
1892 serge 41
#include "cairo-error-private.h"
3959 Serge 42
#include "cairo-pattern-private.h"
1892 serge 43
#include "cairo-surface-offset-private.h"
44
 
45
/* A collection of routines to facilitate drawing to an alternate surface. */
46
 
47
static void
48
_copy_transformed_pattern (cairo_pattern_t *pattern,
49
			   const cairo_pattern_t *original,
50
			   const cairo_matrix_t  *ctm_inverse)
51
{
52
    _cairo_pattern_init_static_copy (pattern, original);
53
 
54
    if (! _cairo_matrix_is_identity (ctm_inverse))
55
	_cairo_pattern_transform (pattern, ctm_inverse);
56
}
57
 
58
cairo_status_t
59
_cairo_surface_offset_paint (cairo_surface_t		*target,
60
			     int x, int y,
61
			     cairo_operator_t		 op,
62
			     const cairo_pattern_t	*source,
3959 Serge 63
			     const cairo_clip_t		*clip)
1892 serge 64
{
65
    cairo_status_t status;
3959 Serge 66
    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
1892 serge 67
    cairo_pattern_union_t source_copy;
68
 
69
    if (unlikely (target->status))
70
	return target->status;
71
 
3959 Serge 72
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 73
	return CAIRO_STATUS_SUCCESS;
74
 
75
    if (x | y) {
76
	cairo_matrix_t m;
77
 
3959 Serge 78
	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
1892 serge 79
 
80
	cairo_matrix_init_translate (&m, x, y);
81
	_copy_transformed_pattern (&source_copy.base, source, &m);
82
	source = &source_copy.base;
83
    }
84
 
85
    status = _cairo_surface_paint (target, op, source, dev_clip);
86
 
87
    if (dev_clip != clip)
3959 Serge 88
	_cairo_clip_destroy (dev_clip);
1892 serge 89
 
90
    return status;
91
}
92
 
93
cairo_status_t
94
_cairo_surface_offset_mask (cairo_surface_t		*target,
95
			    int x, int y,
96
			    cairo_operator_t		 op,
97
			    const cairo_pattern_t	*source,
98
			    const cairo_pattern_t	*mask,
3959 Serge 99
			    const cairo_clip_t		*clip)
1892 serge 100
{
101
    cairo_status_t status;
3959 Serge 102
    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
1892 serge 103
    cairo_pattern_union_t source_copy;
104
    cairo_pattern_union_t mask_copy;
105
 
106
    if (unlikely (target->status))
107
	return target->status;
108
 
3959 Serge 109
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 110
	return CAIRO_STATUS_SUCCESS;
111
 
112
    if (x | y) {
113
	cairo_matrix_t m;
114
 
3959 Serge 115
	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
1892 serge 116
 
117
	cairo_matrix_init_translate (&m, x, y);
118
	_copy_transformed_pattern (&source_copy.base, source, &m);
119
	_copy_transformed_pattern (&mask_copy.base, mask, &m);
120
	source = &source_copy.base;
121
	mask = &mask_copy.base;
122
    }
123
 
124
    status = _cairo_surface_mask (target, op,
125
				  source, mask,
126
				  dev_clip);
127
 
128
    if (dev_clip != clip)
3959 Serge 129
	_cairo_clip_destroy (dev_clip);
1892 serge 130
 
131
    return status;
132
}
133
 
134
cairo_status_t
135
_cairo_surface_offset_stroke (cairo_surface_t		*surface,
136
			      int x, int y,
137
			      cairo_operator_t		 op,
138
			      const cairo_pattern_t	*source,
3959 Serge 139
			      const cairo_path_fixed_t	*path,
1892 serge 140
			      const cairo_stroke_style_t*stroke_style,
141
			      const cairo_matrix_t	*ctm,
142
			      const cairo_matrix_t	*ctm_inverse,
143
			      double			 tolerance,
144
			      cairo_antialias_t		 antialias,
3959 Serge 145
			      const cairo_clip_t		*clip)
1892 serge 146
{
3959 Serge 147
    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
148
    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
1892 serge 149
    cairo_matrix_t dev_ctm = *ctm;
150
    cairo_matrix_t dev_ctm_inverse = *ctm_inverse;
151
    cairo_pattern_union_t source_copy;
152
    cairo_status_t status;
153
 
154
    if (unlikely (surface->status))
155
	return surface->status;
156
 
3959 Serge 157
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 158
	return CAIRO_STATUS_SUCCESS;
159
 
160
    if (x | y) {
161
	cairo_matrix_t m;
162
 
3959 Serge 163
	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
164
 
1892 serge 165
	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
166
	if (unlikely (status))
167
	    goto FINISH;
168
 
169
	_cairo_path_fixed_translate (&path_copy,
170
				     _cairo_fixed_from_int (-x),
171
				     _cairo_fixed_from_int (-y));
172
	dev_path = &path_copy;
173
 
174
	cairo_matrix_init_translate (&m, -x, -y);
175
	cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
176
 
177
	cairo_matrix_init_translate (&m, x, y);
178
	_copy_transformed_pattern (&source_copy.base, source, &m);
179
	source = &source_copy.base;
180
	cairo_matrix_multiply (&dev_ctm_inverse, &m, &dev_ctm_inverse);
181
    }
182
 
183
    status = _cairo_surface_stroke (surface, op, source,
184
				    dev_path, stroke_style,
185
				    &dev_ctm, &dev_ctm_inverse,
186
				    tolerance, antialias,
187
				    dev_clip);
188
 
3959 Serge 189
FINISH:
1892 serge 190
    if (dev_path != path)
191
	_cairo_path_fixed_fini (dev_path);
192
    if (dev_clip != clip)
3959 Serge 193
	_cairo_clip_destroy (dev_clip);
1892 serge 194
 
195
    return status;
196
}
197
 
198
cairo_status_t
199
_cairo_surface_offset_fill (cairo_surface_t	*surface,
200
			    int x, int y,
201
			    cairo_operator_t	 op,
202
			    const cairo_pattern_t*source,
3959 Serge 203
			    const cairo_path_fixed_t	*path,
1892 serge 204
			    cairo_fill_rule_t	 fill_rule,
205
			    double		 tolerance,
206
			    cairo_antialias_t	 antialias,
3959 Serge 207
			    const cairo_clip_t	*clip)
1892 serge 208
{
209
    cairo_status_t status;
3959 Serge 210
    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
211
    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
1892 serge 212
    cairo_pattern_union_t source_copy;
213
 
214
    if (unlikely (surface->status))
215
	return surface->status;
216
 
3959 Serge 217
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 218
	return CAIRO_STATUS_SUCCESS;
219
 
220
    if (x | y) {
221
	cairo_matrix_t m;
222
 
3959 Serge 223
	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
224
 
1892 serge 225
	status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
226
	if (unlikely (status))
227
	    goto FINISH;
228
 
229
	_cairo_path_fixed_translate (&path_copy,
230
				     _cairo_fixed_from_int (-x),
231
				     _cairo_fixed_from_int (-y));
232
	dev_path = &path_copy;
233
 
234
	cairo_matrix_init_translate (&m, x, y);
235
	_copy_transformed_pattern (&source_copy.base, source, &m);
236
	source = &source_copy.base;
237
    }
238
 
239
    status = _cairo_surface_fill (surface, op, source,
240
				  dev_path, fill_rule,
241
				  tolerance, antialias,
242
				  dev_clip);
243
 
3959 Serge 244
FINISH:
1892 serge 245
    if (dev_path != path)
246
	_cairo_path_fixed_fini (dev_path);
247
    if (dev_clip != clip)
3959 Serge 248
	_cairo_clip_destroy (dev_clip);
1892 serge 249
 
250
    return status;
251
}
252
 
253
cairo_status_t
254
_cairo_surface_offset_glyphs (cairo_surface_t		*surface,
255
			      int x, int y,
256
			      cairo_operator_t		 op,
257
			      const cairo_pattern_t	*source,
258
			      cairo_scaled_font_t	*scaled_font,
259
			      cairo_glyph_t		*glyphs,
260
			      int			 num_glyphs,
3959 Serge 261
			      const cairo_clip_t	*clip)
1892 serge 262
{
263
    cairo_status_t status;
3959 Serge 264
    cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
1892 serge 265
    cairo_pattern_union_t source_copy;
266
    cairo_glyph_t *dev_glyphs;
267
    int i;
268
 
269
    if (unlikely (surface->status))
270
	return surface->status;
271
 
3959 Serge 272
    if (_cairo_clip_is_all_clipped (clip))
1892 serge 273
	return CAIRO_STATUS_SUCCESS;
274
 
275
    dev_glyphs = _cairo_malloc_ab (num_glyphs, sizeof (cairo_glyph_t));
276
    if (dev_glyphs == NULL)
277
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
278
 
279
    memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
280
 
281
    if (x | y) {
282
	cairo_matrix_t m;
283
 
3959 Serge 284
	dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
1892 serge 285
 
286
	cairo_matrix_init_translate (&m, x, y);
287
	_copy_transformed_pattern (&source_copy.base, source, &m);
288
	source = &source_copy.base;
289
 
290
	for (i = 0; i < num_glyphs; i++) {
291
	    dev_glyphs[i].x -= x;
292
	    dev_glyphs[i].y -= y;
293
	}
294
    }
295
 
296
    status = _cairo_surface_show_text_glyphs (surface, op, source,
297
					      NULL, 0,
298
					      dev_glyphs, num_glyphs,
299
					      NULL, 0, 0,
300
					      scaled_font,
301
					      dev_clip);
302
 
303
    if (dev_clip != clip)
3959 Serge 304
	_cairo_clip_destroy (dev_clip);
1892 serge 305
    free (dev_glyphs);
306
 
307
    return status;
308
}