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
;
54 TRACE ((stderr
, "%s\n", __FUNCTION__
));
55 status
= _cairo_composite_rectangles_init_for_paint (&extents
, surface
,
58 if (unlikely (status
))
62 while (compositor
->paint
== NULL
)
63 compositor
= compositor
->delegate
;
65 status
= compositor
->paint (compositor
, &extents
);
67 compositor
= compositor
->delegate
;
68 } while (status
== CAIRO_INT_STATUS_UNSUPPORTED
);
70 if (status
== CAIRO_INT_STATUS_SUCCESS
&& surface
->damage
) {
71 TRACE ((stderr
, "%s: applying damage (%d,%d)x(%d, %d)\n",
73 extents
.unbounded
.x
, extents
.unbounded
.y
,
74 extents
.unbounded
.width
, extents
.unbounded
.height
));
75 surface
->damage
= _cairo_damage_add_rectangle (surface
->damage
,
79 _cairo_composite_rectangles_fini (&extents
);
85 _cairo_compositor_mask (const cairo_compositor_t
*compositor
,
86 cairo_surface_t
*surface
,
88 const cairo_pattern_t
*source
,
89 const cairo_pattern_t
*mask
,
90 const cairo_clip_t
*clip
)
92 cairo_composite_rectangles_t extents
;
93 cairo_int_status_t status
;
95 TRACE ((stderr
, "%s\n", __FUNCTION__
));
96 status
= _cairo_composite_rectangles_init_for_mask (&extents
, surface
,
99 if (unlikely (status
))
103 while (compositor
->mask
== NULL
)
104 compositor
= compositor
->delegate
;
106 status
= compositor
->mask (compositor
, &extents
);
108 compositor
= compositor
->delegate
;
109 } while (status
== CAIRO_INT_STATUS_UNSUPPORTED
);
111 if (status
== CAIRO_INT_STATUS_SUCCESS
&& surface
->damage
) {
112 TRACE ((stderr
, "%s: applying damage (%d,%d)x(%d, %d)\n",
114 extents
.unbounded
.x
, extents
.unbounded
.y
,
115 extents
.unbounded
.width
, extents
.unbounded
.height
));
116 surface
->damage
= _cairo_damage_add_rectangle (surface
->damage
,
120 _cairo_composite_rectangles_fini (&extents
);
126 _cairo_compositor_stroke (const cairo_compositor_t
*compositor
,
127 cairo_surface_t
*surface
,
129 const cairo_pattern_t
*source
,
130 const cairo_path_fixed_t
*path
,
131 const cairo_stroke_style_t
*style
,
132 const cairo_matrix_t
*ctm
,
133 const cairo_matrix_t
*ctm_inverse
,
135 cairo_antialias_t antialias
,
136 const cairo_clip_t
*clip
)
138 cairo_composite_rectangles_t extents
;
139 cairo_int_status_t status
;
141 TRACE ((stderr
, "%s\n", __FUNCTION__
));
143 if (_cairo_pen_vertices_needed (tolerance
, style
->line_width
/2, ctm
) <= 1)
144 return CAIRO_INT_STATUS_NOTHING_TO_DO
;
146 status
= _cairo_composite_rectangles_init_for_stroke (&extents
, surface
,
150 if (unlikely (status
))
154 while (compositor
->stroke
== NULL
)
155 compositor
= compositor
->delegate
;
157 status
= compositor
->stroke (compositor
, &extents
,
158 path
, style
, ctm
, ctm_inverse
,
159 tolerance
, antialias
);
161 compositor
= compositor
->delegate
;
162 } while (status
== CAIRO_INT_STATUS_UNSUPPORTED
);
164 if (status
== CAIRO_INT_STATUS_SUCCESS
&& surface
->damage
) {
165 TRACE ((stderr
, "%s: applying damage (%d,%d)x(%d, %d)\n",
167 extents
.unbounded
.x
, extents
.unbounded
.y
,
168 extents
.unbounded
.width
, extents
.unbounded
.height
));
169 surface
->damage
= _cairo_damage_add_rectangle (surface
->damage
,
173 _cairo_composite_rectangles_fini (&extents
);
179 _cairo_compositor_fill (const cairo_compositor_t
*compositor
,
180 cairo_surface_t
*surface
,
182 const cairo_pattern_t
*source
,
183 const cairo_path_fixed_t
*path
,
184 cairo_fill_rule_t fill_rule
,
186 cairo_antialias_t antialias
,
187 const cairo_clip_t
*clip
)
189 cairo_composite_rectangles_t extents
;
190 cairo_int_status_t status
;
192 TRACE ((stderr
, "%s\n", __FUNCTION__
));
193 status
= _cairo_composite_rectangles_init_for_fill (&extents
, surface
,
196 if (unlikely (status
))
200 while (compositor
->fill
== NULL
)
201 compositor
= compositor
->delegate
;
203 status
= compositor
->fill (compositor
, &extents
,
204 path
, fill_rule
, tolerance
, antialias
);
206 compositor
= compositor
->delegate
;
207 } while (status
== CAIRO_INT_STATUS_UNSUPPORTED
);
209 if (status
== CAIRO_INT_STATUS_SUCCESS
&& surface
->damage
) {
210 TRACE ((stderr
, "%s: applying damage (%d,%d)x(%d, %d)\n",
212 extents
.unbounded
.x
, extents
.unbounded
.y
,
213 extents
.unbounded
.width
, extents
.unbounded
.height
));
214 surface
->damage
= _cairo_damage_add_rectangle (surface
->damage
,
218 _cairo_composite_rectangles_fini (&extents
);
224 _cairo_compositor_glyphs (const cairo_compositor_t
*compositor
,
225 cairo_surface_t
*surface
,
227 const cairo_pattern_t
*source
,
228 cairo_glyph_t
*glyphs
,
230 cairo_scaled_font_t
*scaled_font
,
231 const cairo_clip_t
*clip
)
233 cairo_composite_rectangles_t extents
;
234 cairo_bool_t overlap
;
235 cairo_int_status_t status
;
237 TRACE ((stderr
, "%s\n", __FUNCTION__
));
238 status
= _cairo_composite_rectangles_init_for_glyphs (&extents
, surface
,
243 if (unlikely (status
))
247 while (compositor
->glyphs
== NULL
)
248 compositor
= compositor
->delegate
;
250 status
= compositor
->glyphs (compositor
, &extents
,
251 scaled_font
, glyphs
, num_glyphs
, overlap
);
253 compositor
= compositor
->delegate
;
254 } while (status
== CAIRO_INT_STATUS_UNSUPPORTED
);
256 if (status
== CAIRO_INT_STATUS_SUCCESS
&& surface
->damage
) {
257 TRACE ((stderr
, "%s: applying damage (%d,%d)x(%d, %d)\n",
259 extents
.unbounded
.x
, extents
.unbounded
.y
,
260 extents
.unbounded
.width
, extents
.unbounded
.height
));
261 surface
->damage
= _cairo_damage_add_rectangle (surface
->damage
,
265 _cairo_composite_rectangles_fini (&extents
);