beta-0.89.2
[luatex.git] / source / libs / cairo / cairo-src / src / cairo-surface-offset.c
blob98f57f298041a7ef00cd2fe44f84dabe4bffafbe
1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2005 Red Hat, Inc
4 * Copyright © 2007 Adrian Johnson
5 * Copyright © 2009 Chris Wilson
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.
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
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/
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.
30 * The Original Code is the cairo graphics library.
32 * The Initial Developer of the Original Code is Red Hat, Inc.
34 * Contributor(s):
35 * Chris Wilson <chris@chris-wilson.co.uk>
38 #include "cairoint.h"
40 #include "cairo-clip-inline.h"
41 #include "cairo-error-private.h"
42 #include "cairo-pattern-private.h"
43 #include "cairo-surface-offset-private.h"
45 /* A collection of routines to facilitate drawing to an alternate surface. */
47 static void
48 _copy_transformed_pattern (cairo_pattern_t *pattern,
49 const cairo_pattern_t *original,
50 const cairo_matrix_t *ctm_inverse)
52 _cairo_pattern_init_static_copy (pattern, original);
54 if (! _cairo_matrix_is_identity (ctm_inverse))
55 _cairo_pattern_transform (pattern, ctm_inverse);
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,
63 const cairo_clip_t *clip)
65 cairo_status_t status;
66 cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
67 cairo_pattern_union_t source_copy;
69 if (unlikely (target->status))
70 return target->status;
72 if (_cairo_clip_is_all_clipped (clip))
73 return CAIRO_STATUS_SUCCESS;
75 if (x | y) {
76 cairo_matrix_t m;
78 dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
80 cairo_matrix_init_translate (&m, x, y);
81 _copy_transformed_pattern (&source_copy.base, source, &m);
82 source = &source_copy.base;
85 status = _cairo_surface_paint (target, op, source, dev_clip);
87 if (dev_clip != clip)
88 _cairo_clip_destroy (dev_clip);
90 return status;
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,
99 const cairo_clip_t *clip)
101 cairo_status_t status;
102 cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
103 cairo_pattern_union_t source_copy;
104 cairo_pattern_union_t mask_copy;
106 if (unlikely (target->status))
107 return target->status;
109 if (_cairo_clip_is_all_clipped (clip))
110 return CAIRO_STATUS_SUCCESS;
112 if (x | y) {
113 cairo_matrix_t m;
115 dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
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;
124 status = _cairo_surface_mask (target, op,
125 source, mask,
126 dev_clip);
128 if (dev_clip != clip)
129 _cairo_clip_destroy (dev_clip);
131 return status;
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,
139 const cairo_path_fixed_t *path,
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,
145 const cairo_clip_t *clip)
147 cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
148 cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
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;
154 if (unlikely (surface->status))
155 return surface->status;
157 if (_cairo_clip_is_all_clipped (clip))
158 return CAIRO_STATUS_SUCCESS;
160 if (x | y) {
161 cairo_matrix_t m;
163 dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
165 status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
166 if (unlikely (status))
167 goto FINISH;
169 _cairo_path_fixed_translate (&path_copy,
170 _cairo_fixed_from_int (-x),
171 _cairo_fixed_from_int (-y));
172 dev_path = &path_copy;
174 cairo_matrix_init_translate (&m, -x, -y);
175 cairo_matrix_multiply (&dev_ctm, &dev_ctm, &m);
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);
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);
189 FINISH:
190 if (dev_path != path)
191 _cairo_path_fixed_fini (dev_path);
192 if (dev_clip != clip)
193 _cairo_clip_destroy (dev_clip);
195 return status;
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,
203 const cairo_path_fixed_t *path,
204 cairo_fill_rule_t fill_rule,
205 double tolerance,
206 cairo_antialias_t antialias,
207 const cairo_clip_t *clip)
209 cairo_status_t status;
210 cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *) path;
211 cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
212 cairo_pattern_union_t source_copy;
214 if (unlikely (surface->status))
215 return surface->status;
217 if (_cairo_clip_is_all_clipped (clip))
218 return CAIRO_STATUS_SUCCESS;
220 if (x | y) {
221 cairo_matrix_t m;
223 dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
225 status = _cairo_path_fixed_init_copy (&path_copy, dev_path);
226 if (unlikely (status))
227 goto FINISH;
229 _cairo_path_fixed_translate (&path_copy,
230 _cairo_fixed_from_int (-x),
231 _cairo_fixed_from_int (-y));
232 dev_path = &path_copy;
234 cairo_matrix_init_translate (&m, x, y);
235 _copy_transformed_pattern (&source_copy.base, source, &m);
236 source = &source_copy.base;
239 status = _cairo_surface_fill (surface, op, source,
240 dev_path, fill_rule,
241 tolerance, antialias,
242 dev_clip);
244 FINISH:
245 if (dev_path != path)
246 _cairo_path_fixed_fini (dev_path);
247 if (dev_clip != clip)
248 _cairo_clip_destroy (dev_clip);
250 return status;
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,
261 const cairo_clip_t *clip)
263 cairo_status_t status;
264 cairo_clip_t *dev_clip = (cairo_clip_t *) clip;
265 cairo_pattern_union_t source_copy;
266 cairo_glyph_t *dev_glyphs;
267 int i;
269 if (unlikely (surface->status))
270 return surface->status;
272 if (_cairo_clip_is_all_clipped (clip))
273 return CAIRO_STATUS_SUCCESS;
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);
279 memcpy (dev_glyphs, glyphs, sizeof (cairo_glyph_t) * num_glyphs);
281 if (x | y) {
282 cairo_matrix_t m;
284 dev_clip = _cairo_clip_copy_with_translation (clip, -x, -y);
286 cairo_matrix_init_translate (&m, x, y);
287 _copy_transformed_pattern (&source_copy.base, source, &m);
288 source = &source_copy.base;
290 for (i = 0; i < num_glyphs; i++) {
291 dev_glyphs[i].x -= x;
292 dev_glyphs[i].y -= y;
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);
303 if (dev_clip != clip)
304 _cairo_clip_destroy (dev_clip);
305 free (dev_glyphs);
307 return status;