1 /* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2 /* cairo - a vector graphics library with display and print output
4 * Copyright © 2011 Intel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it either under the terms of the GNU Lesser General Public
8 * License version 2.1 as published by the Free Software Foundation
9 * (the "LGPL") or, at your option, under the terms of the Mozilla
10 * Public License Version 1.1 (the "MPL"). If you do not alter this
11 * notice, a recipient may use your version of this file under either
12 * the MPL or the LGPL.
14 * You should have received a copy of the LGPL along with this library
15 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17 * You should have received a copy of the MPL along with this library
18 * in the file COPYING-MPL-1.1
20 * The contents of this file are subject to the Mozilla Public License
21 * Version 1.1 (the "License"); you may not use this file except in
22 * compliance with the License. You may obtain a copy of the License at
23 * http://www.mozilla.org/MPL/
25 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27 * the specific language governing rights and limitations.
29 * The Original Code is the cairo graphics library.
31 * The Initial Developer of the Original Code is University of Southern
35 * Chris Wilson <chris@chris-wilson.co.uk>
40 #include "cairo-compositor-private.h"
41 #include "cairo-damage-private.h"
42 #include "cairo-error-private.h"
45 _cairo_compositor_paint (const cairo_compositor_t *compositor,
46 cairo_surface_t *surface,
48 const cairo_pattern_t *source,
49 const cairo_clip_t *clip)
51 cairo_composite_rectangles_t extents;
52 cairo_int_status_t status;
53 cairo_bool_t initialized = TRUE;
55 TRACE ((stderr, "%s\n", __FUNCTION__));
57 if (compositor->lazy_init) {
58 status = _cairo_composite_rectangles_lazy_init_for_paint (&extents,
65 status = _cairo_composite_rectangles_init_for_paint (&extents,
69 if (unlikely (status))
73 while (compositor->paint == NULL)
74 compositor = compositor->delegate;
76 if (! compositor->lazy_init && ! initialized) {
77 /* XXX: we should do better instead of re-init */
78 _cairo_composite_rectangles_fini (&extents);
79 status = _cairo_composite_rectangles_init_for_paint (&extents,
85 if (unlikely (status))
89 status = compositor->paint (compositor, &extents);
91 compositor = compositor->delegate;
92 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
94 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
95 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
97 extents.unbounded.x, extents.unbounded.y,
98 extents.unbounded.width, extents.unbounded.height));
99 surface->damage = _cairo_damage_add_rectangle (surface->damage,
103 _cairo_composite_rectangles_fini (&extents);
109 _cairo_compositor_mask (const cairo_compositor_t *compositor,
110 cairo_surface_t *surface,
112 const cairo_pattern_t *source,
113 const cairo_pattern_t *mask,
114 const cairo_clip_t *clip)
116 cairo_composite_rectangles_t extents;
117 cairo_int_status_t status;
118 cairo_bool_t initialized = TRUE;
120 TRACE ((stderr, "%s\n", __FUNCTION__));
122 if (compositor->lazy_init) {
123 status = _cairo_composite_rectangles_lazy_init_for_mask (&extents,
129 status = _cairo_composite_rectangles_init_for_mask (&extents,
133 if (unlikely (status))
137 while (compositor->mask == NULL)
138 compositor = compositor->delegate;
140 if (! compositor->lazy_init && ! initialized) {
141 /* XXX: we should do better instead of re-init */
142 _cairo_composite_rectangles_fini (&extents);
143 status = _cairo_composite_rectangles_init_for_mask (&extents,
149 if (unlikely (status))
153 status = compositor->mask (compositor, &extents);
155 compositor = compositor->delegate;
156 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
158 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
159 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
161 extents.unbounded.x, extents.unbounded.y,
162 extents.unbounded.width, extents.unbounded.height));
163 surface->damage = _cairo_damage_add_rectangle (surface->damage,
167 _cairo_composite_rectangles_fini (&extents);
173 _cairo_compositor_stroke (const cairo_compositor_t *compositor,
174 cairo_surface_t *surface,
176 const cairo_pattern_t *source,
177 const cairo_path_fixed_t *path,
178 const cairo_stroke_style_t *style,
179 const cairo_matrix_t *ctm,
180 const cairo_matrix_t *ctm_inverse,
182 cairo_antialias_t antialias,
183 const cairo_clip_t *clip)
185 cairo_composite_rectangles_t extents;
186 cairo_int_status_t status;
187 cairo_bool_t initialized = TRUE;
189 TRACE ((stderr, "%s\n", __FUNCTION__));
191 if (_cairo_pen_vertices_needed (tolerance, style->line_width/2, ctm) <= 1)
192 return CAIRO_INT_STATUS_NOTHING_TO_DO;
194 if (compositor->lazy_init) {
195 status = _cairo_composite_rectangles_lazy_init_for_stroke (&extents,
203 status = _cairo_composite_rectangles_init_for_stroke (&extents,
208 if (unlikely (status))
212 while (compositor->stroke == NULL)
213 compositor = compositor->delegate;
215 if (! compositor->lazy_init && ! initialized) {
216 /* XXX: we should do better instead of re-init */
217 _cairo_composite_rectangles_fini (&extents);
218 status = _cairo_composite_rectangles_init_for_stroke (&extents,
228 if (unlikely (status))
232 status = compositor->stroke (compositor, &extents,
233 path, style, ctm, ctm_inverse,
234 tolerance, antialias);
236 compositor = compositor->delegate;
237 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
239 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
240 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
242 extents.unbounded.x, extents.unbounded.y,
243 extents.unbounded.width, extents.unbounded.height));
244 surface->damage = _cairo_damage_add_rectangle (surface->damage,
248 _cairo_composite_rectangles_fini (&extents);
254 _cairo_compositor_fill (const cairo_compositor_t *compositor,
255 cairo_surface_t *surface,
257 const cairo_pattern_t *source,
258 const cairo_path_fixed_t *path,
259 cairo_fill_rule_t fill_rule,
261 cairo_antialias_t antialias,
262 const cairo_clip_t *clip)
264 cairo_composite_rectangles_t extents;
265 cairo_int_status_t status;
266 cairo_bool_t initialized = TRUE;
268 TRACE ((stderr, "%s\n", __FUNCTION__));
270 if (compositor->lazy_init) {
271 status = _cairo_composite_rectangles_lazy_init_for_fill (&extents,
278 status = _cairo_composite_rectangles_init_for_fill (&extents,
282 if (unlikely (status))
286 while (compositor->fill == NULL)
287 compositor = compositor->delegate;
289 if (! compositor->lazy_init && ! initialized) {
290 /* XXX: we should do better instead of re-init */
291 _cairo_composite_rectangles_fini (&extents);
292 status = _cairo_composite_rectangles_init_for_fill (&extents,
298 if (unlikely (status))
302 status = compositor->fill (compositor, &extents,
303 path, fill_rule, tolerance, antialias);
305 compositor = compositor->delegate;
306 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
308 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
309 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
311 extents.unbounded.x, extents.unbounded.y,
312 extents.unbounded.width, extents.unbounded.height));
313 surface->damage = _cairo_damage_add_rectangle (surface->damage,
317 _cairo_composite_rectangles_fini (&extents);
323 _cairo_compositor_glyphs (const cairo_compositor_t *compositor,
324 cairo_surface_t *surface,
326 const cairo_pattern_t *source,
327 cairo_glyph_t *glyphs,
329 cairo_scaled_font_t *scaled_font,
330 const cairo_clip_t *clip)
332 cairo_composite_rectangles_t extents;
333 cairo_bool_t overlap;
334 cairo_int_status_t status;
335 cairo_bool_t initialized = TRUE;
337 TRACE ((stderr, "%s\n", __FUNCTION__));
339 if (compositor->lazy_init) {
340 status = _cairo_composite_rectangles_lazy_init_for_glyphs (&extents, surface,
347 status = _cairo_composite_rectangles_init_for_glyphs (&extents, surface,
352 if (unlikely (status))
356 while (compositor->glyphs == NULL)
357 compositor = compositor->delegate;
359 if (! compositor->lazy_init && ! initialized) {
360 /* XXX: we should do better instead of re-init */
361 _cairo_composite_rectangles_fini (&extents);
362 status = _cairo_composite_rectangles_init_for_glyphs (&extents, surface,
369 if (unlikely (status))
373 status = compositor->glyphs (compositor, &extents,
374 scaled_font, glyphs, num_glyphs, overlap);
376 compositor = compositor->delegate;
377 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
379 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
380 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
382 extents.unbounded.x, extents.unbounded.y,
383 extents.unbounded.width, extents.unbounded.height));
384 surface->damage = _cairo_damage_add_rectangle (surface->damage,
388 _cairo_composite_rectangles_fini (&extents);