Line data Source code
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
3 : *
4 : * Copyright (c) 2008 M Joonas Pihlaja
5 : *
6 : * Permission is hereby granted, free of charge, to any person
7 : * obtaining a copy of this software and associated documentation
8 : * files (the "Software"), to deal in the Software without
9 : * restriction, including without limitation the rights to use,
10 : * copy, modify, merge, publish, distribute, sublicense, and/or sell
11 : * copies of the Software, and to permit persons to whom the
12 : * Software is furnished to do so, subject to the following
13 : * conditions:
14 : *
15 : * The above copyright notice and this permission notice shall be
16 : * included in all copies or substantial portions of the Software.
17 : *
18 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 : * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 : * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 : * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 : * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 : * OTHER DEALINGS IN THE SOFTWARE.
26 : */
27 : #include "cairoint.h"
28 :
29 : #include "cairo-composite-rectangles-private.h"
30 : #include "cairo-fixed-private.h"
31 :
32 : static cairo_scan_converter_t *
33 0 : _create_scan_converter (cairo_fill_rule_t fill_rule,
34 : cairo_antialias_t antialias,
35 : const cairo_composite_rectangles_t *rects)
36 : {
37 0 : if (antialias == CAIRO_ANTIALIAS_NONE) {
38 0 : ASSERT_NOT_REACHED;
39 0 : return NULL;
40 : }
41 :
42 0 : return _cairo_tor_scan_converter_create (rects->bounded.x,
43 : rects->bounded.y,
44 0 : rects->bounded.x + rects->bounded.width,
45 0 : rects->bounded.y + rects->bounded.height,
46 : fill_rule);
47 : }
48 :
49 : /* XXX Add me to the compositor interface. Ok, first create the compositor
50 : * interface, and then add this with associated fallback!
51 : */
52 : cairo_status_t
53 0 : _cairo_surface_composite_polygon (cairo_surface_t *surface,
54 : cairo_operator_t op,
55 : const cairo_pattern_t *pattern,
56 : cairo_fill_rule_t fill_rule,
57 : cairo_antialias_t antialias,
58 : const cairo_composite_rectangles_t *rects,
59 : cairo_polygon_t *polygon,
60 : cairo_region_t *clip_region)
61 : {
62 : cairo_span_renderer_t *renderer;
63 : cairo_scan_converter_t *converter;
64 : cairo_status_t status;
65 :
66 0 : converter = _create_scan_converter (fill_rule, antialias, rects);
67 0 : status = converter->add_polygon (converter, polygon);
68 0 : if (unlikely (status))
69 0 : goto CLEANUP_CONVERTER;
70 :
71 0 : renderer = _cairo_surface_create_span_renderer (op, pattern, surface,
72 : antialias, rects,
73 : clip_region);
74 0 : status = converter->generate (converter, renderer);
75 0 : if (unlikely (status))
76 0 : goto CLEANUP_RENDERER;
77 :
78 0 : status = renderer->finish (renderer);
79 :
80 : CLEANUP_RENDERER:
81 0 : renderer->destroy (renderer);
82 : CLEANUP_CONVERTER:
83 0 : converter->destroy (converter);
84 0 : return status;
85 : }
86 :
87 : static void
88 0 : _cairo_nil_destroy (void *abstract)
89 : {
90 : (void) abstract;
91 0 : }
92 :
93 : static cairo_status_t
94 0 : _cairo_nil_scan_converter_add_polygon (void *abstract_converter,
95 : const cairo_polygon_t *polygon)
96 : {
97 : (void) abstract_converter;
98 : (void) polygon;
99 0 : return _cairo_scan_converter_status (abstract_converter);
100 : }
101 :
102 : static cairo_status_t
103 0 : _cairo_nil_scan_converter_add_edge (void *abstract_converter,
104 : const cairo_point_t *p1,
105 : const cairo_point_t *p2,
106 : int top, int bottom,
107 : int dir)
108 : {
109 : (void) abstract_converter;
110 : (void) p1;
111 : (void) p2;
112 : (void) top;
113 : (void) bottom;
114 : (void) dir;
115 0 : return _cairo_scan_converter_status (abstract_converter);
116 : }
117 :
118 : static cairo_status_t
119 0 : _cairo_nil_scan_converter_generate (void *abstract_converter,
120 : cairo_span_renderer_t *renderer)
121 : {
122 : (void) abstract_converter;
123 : (void) renderer;
124 0 : return _cairo_scan_converter_status (abstract_converter);
125 : }
126 :
127 : cairo_status_t
128 0 : _cairo_scan_converter_status (void *abstract_converter)
129 : {
130 0 : cairo_scan_converter_t *converter = abstract_converter;
131 0 : return converter->status;
132 : }
133 :
134 : cairo_status_t
135 0 : _cairo_scan_converter_set_error (void *abstract_converter,
136 : cairo_status_t error)
137 : {
138 0 : cairo_scan_converter_t *converter = abstract_converter;
139 0 : if (error == CAIRO_STATUS_SUCCESS)
140 0 : ASSERT_NOT_REACHED;
141 0 : if (converter->status == CAIRO_STATUS_SUCCESS) {
142 0 : converter->add_polygon = _cairo_nil_scan_converter_add_polygon;
143 0 : converter->add_edge = _cairo_nil_scan_converter_add_edge;
144 0 : converter->generate = _cairo_nil_scan_converter_generate;
145 0 : converter->status = error;
146 : }
147 0 : return converter->status;
148 : }
149 :
150 : static void
151 0 : _cairo_nil_scan_converter_init (cairo_scan_converter_t *converter,
152 : cairo_status_t status)
153 : {
154 0 : converter->destroy = _cairo_nil_destroy;
155 0 : converter->status = CAIRO_STATUS_SUCCESS;
156 0 : status = _cairo_scan_converter_set_error (converter, status);
157 0 : }
158 :
159 : cairo_scan_converter_t *
160 0 : _cairo_scan_converter_create_in_error (cairo_status_t status)
161 : {
162 : #define RETURN_NIL {\
163 : static cairo_scan_converter_t nil;\
164 : _cairo_nil_scan_converter_init (&nil, status);\
165 : return &nil;\
166 : }
167 0 : switch (status) {
168 : case CAIRO_STATUS_SUCCESS:
169 : case CAIRO_STATUS_LAST_STATUS:
170 0 : ASSERT_NOT_REACHED;
171 0 : break;
172 0 : case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL;
173 0 : case CAIRO_STATUS_INVALID_POP_GROUP: RETURN_NIL;
174 0 : case CAIRO_STATUS_NO_CURRENT_POINT: RETURN_NIL;
175 0 : case CAIRO_STATUS_INVALID_MATRIX: RETURN_NIL;
176 0 : case CAIRO_STATUS_INVALID_STATUS: RETURN_NIL;
177 0 : case CAIRO_STATUS_NULL_POINTER: RETURN_NIL;
178 0 : case CAIRO_STATUS_INVALID_STRING: RETURN_NIL;
179 0 : case CAIRO_STATUS_INVALID_PATH_DATA: RETURN_NIL;
180 0 : case CAIRO_STATUS_READ_ERROR: RETURN_NIL;
181 0 : case CAIRO_STATUS_WRITE_ERROR: RETURN_NIL;
182 0 : case CAIRO_STATUS_SURFACE_FINISHED: RETURN_NIL;
183 0 : case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: RETURN_NIL;
184 0 : case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: RETURN_NIL;
185 0 : case CAIRO_STATUS_INVALID_CONTENT: RETURN_NIL;
186 0 : case CAIRO_STATUS_INVALID_FORMAT: RETURN_NIL;
187 0 : case CAIRO_STATUS_INVALID_VISUAL: RETURN_NIL;
188 0 : case CAIRO_STATUS_FILE_NOT_FOUND: RETURN_NIL;
189 0 : case CAIRO_STATUS_INVALID_DASH: RETURN_NIL;
190 0 : case CAIRO_STATUS_INVALID_DSC_COMMENT: RETURN_NIL;
191 0 : case CAIRO_STATUS_INVALID_INDEX: RETURN_NIL;
192 0 : case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: RETURN_NIL;
193 0 : case CAIRO_STATUS_TEMP_FILE_ERROR: RETURN_NIL;
194 0 : case CAIRO_STATUS_INVALID_STRIDE: RETURN_NIL;
195 0 : case CAIRO_STATUS_FONT_TYPE_MISMATCH: RETURN_NIL;
196 0 : case CAIRO_STATUS_USER_FONT_IMMUTABLE: RETURN_NIL;
197 0 : case CAIRO_STATUS_USER_FONT_ERROR: RETURN_NIL;
198 0 : case CAIRO_STATUS_NEGATIVE_COUNT: RETURN_NIL;
199 0 : case CAIRO_STATUS_INVALID_CLUSTERS: RETURN_NIL;
200 0 : case CAIRO_STATUS_INVALID_SLANT: RETURN_NIL;
201 0 : case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL;
202 0 : case CAIRO_STATUS_NO_MEMORY: RETURN_NIL;
203 0 : case CAIRO_STATUS_INVALID_SIZE: RETURN_NIL;
204 0 : case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: RETURN_NIL;
205 0 : case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: RETURN_NIL;
206 0 : case CAIRO_STATUS_DEVICE_ERROR: RETURN_NIL;
207 : default:
208 0 : break;
209 : }
210 0 : status = CAIRO_STATUS_NO_MEMORY;
211 0 : RETURN_NIL;
212 : #undef RETURN_NIL
213 : }
214 :
215 : static cairo_status_t
216 0 : _cairo_nil_span_renderer_render_rows (
217 : void *abstract_renderer,
218 : int y,
219 : int height,
220 : const cairo_half_open_span_t *coverages,
221 : unsigned num_coverages)
222 : {
223 : (void) y;
224 : (void) height;
225 : (void) coverages;
226 : (void) num_coverages;
227 0 : return _cairo_span_renderer_status (abstract_renderer);
228 : }
229 :
230 : static cairo_status_t
231 0 : _cairo_nil_span_renderer_finish (void *abstract_renderer)
232 : {
233 0 : return _cairo_span_renderer_status (abstract_renderer);
234 : }
235 :
236 : cairo_status_t
237 0 : _cairo_span_renderer_status (void *abstract_renderer)
238 : {
239 0 : cairo_span_renderer_t *renderer = abstract_renderer;
240 0 : return renderer->status;
241 : }
242 :
243 : cairo_status_t
244 0 : _cairo_span_renderer_set_error (
245 : void *abstract_renderer,
246 : cairo_status_t error)
247 : {
248 0 : cairo_span_renderer_t *renderer = abstract_renderer;
249 0 : if (error == CAIRO_STATUS_SUCCESS) {
250 0 : ASSERT_NOT_REACHED;
251 : }
252 0 : if (renderer->status == CAIRO_STATUS_SUCCESS) {
253 0 : renderer->render_rows = _cairo_nil_span_renderer_render_rows;
254 0 : renderer->finish = _cairo_nil_span_renderer_finish;
255 0 : renderer->status = error;
256 : }
257 0 : return renderer->status;
258 : }
259 :
260 : static void
261 0 : _cairo_nil_span_renderer_init (cairo_span_renderer_t *renderer,
262 : cairo_status_t status)
263 : {
264 0 : renderer->destroy = _cairo_nil_destroy;
265 0 : renderer->status = CAIRO_STATUS_SUCCESS;
266 0 : status = _cairo_span_renderer_set_error (renderer, status);
267 0 : }
268 :
269 : cairo_span_renderer_t *
270 0 : _cairo_span_renderer_create_in_error (cairo_status_t status)
271 : {
272 : #define RETURN_NIL {\
273 : static cairo_span_renderer_t nil;\
274 : _cairo_nil_span_renderer_init (&nil, status);\
275 : return &nil;\
276 : }
277 0 : switch (status) {
278 : case CAIRO_STATUS_SUCCESS:
279 : case CAIRO_STATUS_LAST_STATUS:
280 0 : ASSERT_NOT_REACHED;
281 0 : break;
282 0 : case CAIRO_STATUS_INVALID_RESTORE: RETURN_NIL;
283 0 : case CAIRO_STATUS_INVALID_POP_GROUP: RETURN_NIL;
284 0 : case CAIRO_STATUS_NO_CURRENT_POINT: RETURN_NIL;
285 0 : case CAIRO_STATUS_INVALID_MATRIX: RETURN_NIL;
286 0 : case CAIRO_STATUS_INVALID_STATUS: RETURN_NIL;
287 0 : case CAIRO_STATUS_NULL_POINTER: RETURN_NIL;
288 0 : case CAIRO_STATUS_INVALID_STRING: RETURN_NIL;
289 0 : case CAIRO_STATUS_INVALID_PATH_DATA: RETURN_NIL;
290 0 : case CAIRO_STATUS_READ_ERROR: RETURN_NIL;
291 0 : case CAIRO_STATUS_WRITE_ERROR: RETURN_NIL;
292 0 : case CAIRO_STATUS_SURFACE_FINISHED: RETURN_NIL;
293 0 : case CAIRO_STATUS_SURFACE_TYPE_MISMATCH: RETURN_NIL;
294 0 : case CAIRO_STATUS_PATTERN_TYPE_MISMATCH: RETURN_NIL;
295 0 : case CAIRO_STATUS_INVALID_CONTENT: RETURN_NIL;
296 0 : case CAIRO_STATUS_INVALID_FORMAT: RETURN_NIL;
297 0 : case CAIRO_STATUS_INVALID_VISUAL: RETURN_NIL;
298 0 : case CAIRO_STATUS_FILE_NOT_FOUND: RETURN_NIL;
299 0 : case CAIRO_STATUS_INVALID_DASH: RETURN_NIL;
300 0 : case CAIRO_STATUS_INVALID_DSC_COMMENT: RETURN_NIL;
301 0 : case CAIRO_STATUS_INVALID_INDEX: RETURN_NIL;
302 0 : case CAIRO_STATUS_CLIP_NOT_REPRESENTABLE: RETURN_NIL;
303 0 : case CAIRO_STATUS_TEMP_FILE_ERROR: RETURN_NIL;
304 0 : case CAIRO_STATUS_INVALID_STRIDE: RETURN_NIL;
305 0 : case CAIRO_STATUS_FONT_TYPE_MISMATCH: RETURN_NIL;
306 0 : case CAIRO_STATUS_USER_FONT_IMMUTABLE: RETURN_NIL;
307 0 : case CAIRO_STATUS_USER_FONT_ERROR: RETURN_NIL;
308 0 : case CAIRO_STATUS_NEGATIVE_COUNT: RETURN_NIL;
309 0 : case CAIRO_STATUS_INVALID_CLUSTERS: RETURN_NIL;
310 0 : case CAIRO_STATUS_INVALID_SLANT: RETURN_NIL;
311 0 : case CAIRO_STATUS_INVALID_WEIGHT: RETURN_NIL;
312 0 : case CAIRO_STATUS_NO_MEMORY: RETURN_NIL;
313 0 : case CAIRO_STATUS_INVALID_SIZE: RETURN_NIL;
314 0 : case CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED: RETURN_NIL;
315 0 : case CAIRO_STATUS_DEVICE_TYPE_MISMATCH: RETURN_NIL;
316 0 : case CAIRO_STATUS_DEVICE_ERROR: RETURN_NIL;
317 : default:
318 0 : break;
319 : }
320 0 : status = CAIRO_STATUS_NO_MEMORY;
321 0 : RETURN_NIL;
322 : #undef RETURN_NIL
323 : }
|