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"
43 #include "cairo-ttrace.h"
46 _cairo_compositor_paint (const cairo_compositor_t *compositor,
47 cairo_surface_t *surface,
49 const cairo_pattern_t *source,
50 const cairo_clip_t *clip)
52 CAIRO_TRACE_BEGIN (__func__);
53 cairo_composite_rectangles_t extents;
54 cairo_int_status_t status;
55 cairo_bool_t initialized = TRUE;
57 TRACE ((stderr, "%s\n", __FUNCTION__));
59 if (compositor->lazy_init) {
60 status = _cairo_composite_rectangles_lazy_init_for_paint (&extents,
67 status = _cairo_composite_rectangles_init_for_paint (&extents,
71 if (unlikely (status)) {
72 CAIRO_TRACE_END (__func__);
77 while (compositor->paint == NULL)
78 compositor = compositor->delegate;
80 if (! compositor->lazy_init && ! initialized) {
81 /* XXX: we should do better instead of re-init */
82 _cairo_composite_rectangles_fini (&extents);
83 status = _cairo_composite_rectangles_init_for_paint (&extents,
89 if (unlikely (status)) {
90 CAIRO_TRACE_END (__func__);
95 status = compositor->paint (compositor, &extents);
97 compositor = compositor->delegate;
98 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
100 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
101 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
103 extents.unbounded.x, extents.unbounded.y,
104 extents.unbounded.width, extents.unbounded.height));
105 surface->damage = _cairo_damage_add_rectangle (surface->damage,
109 _cairo_composite_rectangles_fini (&extents);
111 CAIRO_TRACE_END (__func__);
116 _cairo_compositor_mask (const cairo_compositor_t *compositor,
117 cairo_surface_t *surface,
119 const cairo_pattern_t *source,
120 const cairo_pattern_t *mask,
121 const cairo_clip_t *clip)
123 CAIRO_TRACE_BEGIN (__func__);
124 cairo_composite_rectangles_t extents;
125 cairo_int_status_t status;
126 cairo_bool_t initialized = TRUE;
128 TRACE ((stderr, "%s\n", __FUNCTION__));
130 if (compositor->lazy_init) {
131 status = _cairo_composite_rectangles_lazy_init_for_mask (&extents,
137 status = _cairo_composite_rectangles_init_for_mask (&extents,
141 if (unlikely (status)) {
142 CAIRO_TRACE_END (__func__);
147 while (compositor->mask == NULL)
148 compositor = compositor->delegate;
150 if (! compositor->lazy_init && ! initialized) {
151 /* XXX: we should do better instead of re-init */
152 _cairo_composite_rectangles_fini (&extents);
153 status = _cairo_composite_rectangles_init_for_mask (&extents,
159 if (unlikely (status)) {
160 CAIRO_TRACE_END (__func__);
165 status = compositor->mask (compositor, &extents);
167 compositor = compositor->delegate;
168 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
170 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
171 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
173 extents.unbounded.x, extents.unbounded.y,
174 extents.unbounded.width, extents.unbounded.height));
175 surface->damage = _cairo_damage_add_rectangle (surface->damage,
179 _cairo_composite_rectangles_fini (&extents);
181 CAIRO_TRACE_END (__func__);
186 _cairo_compositor_stroke (const cairo_compositor_t *compositor,
187 cairo_surface_t *surface,
189 const cairo_pattern_t *source,
190 const cairo_path_fixed_t *path,
191 const cairo_stroke_style_t *style,
192 const cairo_matrix_t *ctm,
193 const cairo_matrix_t *ctm_inverse,
195 cairo_antialias_t antialias,
196 const cairo_clip_t *clip)
198 CAIRO_TRACE_BEGIN (__func__);
199 cairo_composite_rectangles_t extents;
200 cairo_int_status_t status;
201 cairo_bool_t initialized = TRUE;
203 TRACE ((stderr, "%s\n", __FUNCTION__));
205 if (_cairo_pen_vertices_needed (tolerance, style->line_width/2, ctm) <= 1) {
206 CAIRO_TRACE_END (__func__);
207 return CAIRO_INT_STATUS_NOTHING_TO_DO;
210 if (compositor->lazy_init) {
211 status = _cairo_composite_rectangles_lazy_init_for_stroke (&extents,
219 status = _cairo_composite_rectangles_init_for_stroke (&extents,
224 if (unlikely (status)) {
225 CAIRO_TRACE_END (__func__);
230 while (compositor->stroke == NULL)
231 compositor = compositor->delegate;
233 if (! compositor->lazy_init && ! initialized) {
234 /* XXX: we should do better instead of re-init */
235 _cairo_composite_rectangles_fini (&extents);
236 status = _cairo_composite_rectangles_init_for_stroke (&extents,
246 if (unlikely (status)) {
247 CAIRO_TRACE_END (__func__);
252 status = compositor->stroke (compositor, &extents,
253 path, style, ctm, ctm_inverse,
254 tolerance, antialias);
256 compositor = compositor->delegate;
257 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
259 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
260 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
262 extents.unbounded.x, extents.unbounded.y,
263 extents.unbounded.width, extents.unbounded.height));
264 surface->damage = _cairo_damage_add_rectangle (surface->damage,
268 _cairo_composite_rectangles_fini (&extents);
270 CAIRO_TRACE_END (__func__);
275 _cairo_compositor_fill (const cairo_compositor_t *compositor,
276 cairo_surface_t *surface,
278 const cairo_pattern_t *source,
279 const cairo_path_fixed_t *path,
280 cairo_fill_rule_t fill_rule,
282 cairo_antialias_t antialias,
283 const cairo_clip_t *clip)
285 CAIRO_TRACE_BEGIN (__func__);
286 cairo_composite_rectangles_t extents;
287 cairo_int_status_t status;
288 cairo_bool_t initialized = TRUE;
290 TRACE ((stderr, "%s\n", __FUNCTION__));
292 if (compositor->lazy_init) {
293 status = _cairo_composite_rectangles_lazy_init_for_fill (&extents,
300 status = _cairo_composite_rectangles_init_for_fill (&extents,
304 if (unlikely (status)) {
305 CAIRO_TRACE_END (__func__);
310 while (compositor->fill == NULL)
311 compositor = compositor->delegate;
313 if (! compositor->lazy_init && ! initialized) {
314 /* XXX: we should do better instead of re-init */
315 _cairo_composite_rectangles_fini (&extents);
316 status = _cairo_composite_rectangles_init_for_fill (&extents,
322 if (unlikely (status)) {
323 CAIRO_TRACE_END (__func__);
328 status = compositor->fill (compositor, &extents,
329 path, fill_rule, tolerance, antialias);
331 compositor = compositor->delegate;
332 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
334 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
335 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
337 extents.unbounded.x, extents.unbounded.y,
338 extents.unbounded.width, extents.unbounded.height));
339 surface->damage = _cairo_damage_add_rectangle (surface->damage,
343 _cairo_composite_rectangles_fini (&extents);
345 CAIRO_TRACE_END (__func__);
350 _cairo_compositor_glyphs (const cairo_compositor_t *compositor,
351 cairo_surface_t *surface,
353 const cairo_pattern_t *source,
354 cairo_glyph_t *glyphs,
356 cairo_scaled_font_t *scaled_font,
357 const cairo_clip_t *clip)
359 CAIRO_TRACE_BEGIN (__func__);
360 cairo_composite_rectangles_t extents;
361 cairo_bool_t overlap;
362 cairo_int_status_t status;
363 cairo_bool_t initialized = TRUE;
365 TRACE ((stderr, "%s\n", __FUNCTION__));
367 if (compositor->lazy_init) {
368 status = _cairo_composite_rectangles_lazy_init_for_glyphs (&extents, surface,
375 status = _cairo_composite_rectangles_init_for_glyphs (&extents, surface,
380 if (unlikely (status)) {
381 CAIRO_TRACE_END (__func__);
386 while (compositor->glyphs == NULL)
387 compositor = compositor->delegate;
389 if (! compositor->lazy_init && ! initialized) {
390 /* XXX: we should do better instead of re-init */
391 _cairo_composite_rectangles_fini (&extents);
392 status = _cairo_composite_rectangles_init_for_glyphs (&extents, surface,
399 if (unlikely (status)) {
400 CAIRO_TRACE_END (__func__);
405 status = compositor->glyphs (compositor, &extents,
406 scaled_font, glyphs, num_glyphs, overlap);
408 compositor = compositor->delegate;
409 } while (status == CAIRO_INT_STATUS_UNSUPPORTED);
411 if (status == CAIRO_INT_STATUS_SUCCESS && surface->damage) {
412 TRACE ((stderr, "%s: applying damage (%d,%d)x(%d, %d)\n",
414 extents.unbounded.x, extents.unbounded.y,
415 extents.unbounded.width, extents.unbounded.height));
416 surface->damage = _cairo_damage_add_rectangle (surface->damage,
420 _cairo_composite_rectangles_fini (&extents);
422 CAIRO_TRACE_END (__func__);