Rev 1892 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1892 | Rev 3959 | ||
---|---|---|---|
Line -... | Line 1... | ||
- | 1 | /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */ |
|
1 | /* cairo - a vector graphics library with display and print output |
2 | /* cairo - a vector graphics library with display and print output |
2 | * |
3 | * |
3 | * Copyright © 2002 University of Southern California |
4 | * Copyright © 2002 University of Southern California |
4 | * |
5 | * |
5 | * This library is free software; you can redistribute it and/or |
6 | * This library is free software; you can redistribute it and/or |
Line 37... | Line 38... | ||
37 | #include "cairoint.h" |
38 | #include "cairoint.h" |
38 | #include "cairo-boxes-private.h" |
39 | #include "cairo-boxes-private.h" |
39 | #include "cairo-error-private.h" |
40 | #include "cairo-error-private.h" |
40 | #include "cairo-path-fixed-private.h" |
41 | #include "cairo-path-fixed-private.h" |
41 | #include "cairo-region-private.h" |
42 | #include "cairo-region-private.h" |
- | 43 | #include "cairo-traps-private.h" |
|
Line 42... | Line 44... | ||
42 | 44 | ||
43 | typedef struct cairo_filler { |
- | |
44 | double tolerance; |
45 | typedef struct cairo_filler { |
- | 46 | cairo_polygon_t *polygon; |
|
- | 47 | double tolerance; |
|
- | 48 | ||
- | 49 | cairo_box_t limit; |
|
- | 50 | cairo_bool_t has_limits; |
|
- | 51 | ||
- | 52 | cairo_point_t current_point; |
|
45 | cairo_polygon_t *polygon; |
53 | cairo_point_t last_move_to; |
Line 46... | Line 54... | ||
46 | } cairo_filler_t; |
54 | } cairo_filler_t; |
47 | 55 | ||
48 | static void |
- | |
49 | _cairo_filler_init (cairo_filler_t *filler, |
56 | static cairo_status_t |
50 | double tolerance, |
57 | _cairo_filler_line_to (void *closure, |
51 | cairo_polygon_t *polygon) |
58 | const cairo_point_t *point) |
52 | { |
59 | { |
53 | filler->tolerance = tolerance; |
- | |
Line -... | Line 60... | ||
- | 60 | cairo_filler_t *filler = closure; |
|
- | 61 | cairo_status_t status; |
|
54 | filler->polygon = polygon; |
62 | |
- | 63 | status = _cairo_polygon_add_external_edge (filler->polygon, |
|
55 | } |
64 | &filler->current_point, |
56 | 65 | point); |
|
- | 66 | ||
57 | static void |
67 | filler->current_point = *point; |
Line 58... | Line 68... | ||
58 | _cairo_filler_fini (cairo_filler_t *filler) |
68 | |
59 | { |
69 | return status; |
60 | } |
- | |
61 | 70 | } |
|
62 | static cairo_status_t |
71 | |
63 | _cairo_filler_move_to (void *closure, |
- | |
Line 64... | Line 72... | ||
64 | const cairo_point_t *point) |
72 | static cairo_status_t |
65 | { |
73 | _cairo_filler_close (void *closure) |
66 | cairo_filler_t *filler = closure; |
74 | { |
Line 67... | Line 75... | ||
67 | cairo_polygon_t *polygon = filler->polygon; |
75 | cairo_filler_t *filler = closure; |
68 | 76 | ||
69 | return _cairo_polygon_close (polygon) || |
77 | /* close the subpath */ |
70 | _cairo_polygon_move_to (polygon, point); |
78 | return _cairo_filler_line_to (closure, &filler->last_move_to); |
71 | } |
79 | } |
- | 80 | ||
- | 81 | static cairo_status_t |
|
- | 82 | _cairo_filler_move_to (void *closure, |
|
72 | 83 | const cairo_point_t *point) |
|
- | 84 | { |
|
- | 85 | cairo_filler_t *filler = closure; |
|
- | 86 | cairo_status_t status; |
|
- | 87 | ||
- | 88 | /* close current subpath */ |
|
- | 89 | status = _cairo_filler_close (closure); |
|
- | 90 | if (unlikely (status)) |
|
- | 91 | return status; |
|
73 | static cairo_status_t |
92 | |
Line 74... | Line 93... | ||
74 | _cairo_filler_line_to (void *closure, |
93 | /* make sure that the closure represents a degenerate path */ |
75 | const cairo_point_t *point) |
94 | filler->current_point = *point; |
76 | { |
95 | filler->last_move_to = *point; |
77 | cairo_filler_t *filler = closure; |
96 | |
78 | return _cairo_polygon_line_to (filler->polygon, point); |
97 | return CAIRO_STATUS_SUCCESS; |
79 | } |
98 | } |
80 | 99 | ||
81 | static cairo_status_t |
100 | static cairo_status_t |
Line -... | Line 101... | ||
- | 101 | _cairo_filler_curve_to (void *closure, |
|
- | 102 | const cairo_point_t *p1, |
|
- | 103 | const cairo_point_t *p2, |
|
- | 104 | const cairo_point_t *p3) |
|
- | 105 | { |
|
- | 106 | cairo_filler_t *filler = closure; |
|
82 | _cairo_filler_curve_to (void *closure, |
107 | cairo_spline_t spline; |
83 | const cairo_point_t *b, |
108 | |
84 | const cairo_point_t *c, |
109 | if (filler->has_limits) { |
85 | const cairo_point_t *d) |
110 | if (! _cairo_spline_intersects (&filler->current_point, p1, p2, p3, |
86 | { |
111 | &filler->limit)) |
87 | cairo_filler_t *filler = closure; |
112 | return _cairo_filler_line_to (filler, p3); |
Line 88... | Line 113... | ||
88 | cairo_spline_t spline; |
113 | } |
89 | 114 | ||
Line 90... | Line -... | ||
90 | if (! _cairo_spline_init (&spline, |
- | |
91 | _cairo_filler_line_to, filler, |
- | |
92 | &filler->polygon->current_point, b, c, d)) |
- | |
93 | { |
- | |
94 | return _cairo_filler_line_to (closure, d); |
- | |
95 | } |
- | |
96 | - | ||
97 | return _cairo_spline_decompose (&spline, filler->tolerance); |
115 | if (! _cairo_spline_init (&spline, |
98 | } |
116 | (cairo_spline_add_point_func_t)_cairo_filler_line_to, filler, |
99 | 117 | &filler->current_point, p1, p2, p3)) |
|
100 | static cairo_status_t |
118 | { |
101 | _cairo_filler_close_path (void *closure) |
119 | return _cairo_filler_line_to (closure, p3); |
102 | { |
120 | } |
103 | cairo_filler_t *filler = closure; |
121 | |
Line -... | Line 122... | ||
- | 122 | return _cairo_spline_decompose (&spline, filler->tolerance); |
|
104 | return _cairo_polygon_close (filler->polygon); |
123 | } |
- | 124 | ||
- | 125 | cairo_status_t |
|
- | 126 | _cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path, |
|
- | 127 | double tolerance, |
|
- | 128 | cairo_polygon_t *polygon) |
|
- | 129 | { |
|
- | 130 | cairo_filler_t filler; |
|
- | 131 | cairo_status_t status; |
|
- | 132 | ||
- | 133 | filler.polygon = polygon; |
|
- | 134 | filler.tolerance = tolerance; |
|
Line 105... | Line 135... | ||
105 | } |
135 | |
106 | - | ||
107 | cairo_status_t |
136 | filler.has_limits = FALSE; |
108 | _cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path, |
137 | if (polygon->num_limits) { |
109 | double tolerance, |
138 | filler.has_limits = TRUE; |
110 | cairo_polygon_t *polygon) |
139 | filler.limit = polygon->limit; |
111 | { |
140 | } |
112 | cairo_filler_t filler; |
141 | |
113 | cairo_status_t status; |
142 | /* make sure that the closure represents a degenerate path */ |
Line 114... | Line -... | ||
114 | - | ||
115 | _cairo_filler_init (&filler, tolerance, polygon); |
143 | filler.current_point.x = 0; |
116 | - | ||
117 | status = _cairo_path_fixed_interpret (path, |
- | |
118 | CAIRO_DIRECTION_FORWARD, |
144 | filler.current_point.y = 0; |
Line -... | Line 145... | ||
- | 145 | filler.last_move_to = filler.current_point; |
|
119 | _cairo_filler_move_to, |
146 | |
- | 147 | status = _cairo_path_fixed_interpret (path, |
|
120 | _cairo_filler_line_to, |
148 | _cairo_filler_move_to, |
121 | _cairo_filler_curve_to, |
149 | _cairo_filler_line_to, |
122 | _cairo_filler_close_path, |
150 | _cairo_filler_curve_to, |
- | 151 | _cairo_filler_close, |
|
- | 152 | &filler); |
|
- | 153 | if (unlikely (status)) |
|
123 | &filler); |
154 | return status; |
124 | if (unlikely (status)) |
155 | |
125 | return status; |
156 | return _cairo_filler_close (&filler); |
126 | 157 | } |
|
- | 158 | ||
Line 127... | Line 159... | ||
127 | status = _cairo_polygon_close (polygon); |
159 | typedef struct cairo_filler_rectilinear_aligned { |
128 | _cairo_filler_fini (&filler); |
160 | cairo_polygon_t *polygon; |
Line 129... | Line -... | ||
129 | - | ||
130 | return status; |
- | |
131 | } |
- | |
132 | - | ||
133 | cairo_status_t |
161 | |
134 | _cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path, |
162 | cairo_point_t current_point; |
135 | cairo_fill_rule_t fill_rule, |
163 | cairo_point_t last_move_to; |
136 | double tolerance, |
- | |
137 | cairo_traps_t *traps) |
- | |
Line 138... | Line 164... | ||
138 | { |
164 | } cairo_filler_ra_t; |
139 | cairo_polygon_t polygon; |
- | |
140 | cairo_status_t status; |
- | |
141 | - | ||
142 | if (path->is_empty_fill) |
- | |
143 | return CAIRO_STATUS_SUCCESS; |
- | |
144 | - | ||
145 | _cairo_polygon_init (&polygon); |
- | |
146 | if (traps->num_limits) |
- | |
Line 147... | Line -... | ||
147 | _cairo_polygon_limit (&polygon, traps->limits, traps->num_limits); |
- | |
148 | - | ||
149 | status = _cairo_path_fixed_fill_to_polygon (path, |
165 | |
150 | tolerance, |
166 | static cairo_status_t |
Line 151... | Line 167... | ||
151 | &polygon); |
167 | _cairo_filler_ra_line_to (void *closure, |
152 | if (unlikely (status || polygon.num_edges == 0)) |
- | |
153 | goto CLEANUP; |
168 | const cairo_point_t *point) |
154 | - | ||
155 | if (path->is_rectilinear) { |
169 | { |
156 | status = _cairo_bentley_ottmann_tessellate_rectilinear_polygon (traps, |
- | |
157 | &polygon, |
- | |
158 | fill_rule); |
- | |
159 | } else { |
- | |
160 | status = _cairo_bentley_ottmann_tessellate_polygon (traps, |
170 | cairo_filler_ra_t *filler = closure; |
161 | &polygon, |
- | |
162 | fill_rule); |
- | |
163 | } |
- | |
164 | 171 | cairo_status_t status; |
|
165 | CLEANUP: |
- | |
166 | _cairo_polygon_fini (&polygon); |
- | |
167 | return status; |
- | |
168 | } |
- | |
169 | - | ||
170 | static cairo_region_t * |
- | |
171 | _cairo_path_fixed_fill_rectilinear_tessellate_to_region (const cairo_path_fixed_t *path, |
- | |
172 | cairo_fill_rule_t fill_rule, |
- | |
173 | const cairo_rectangle_int_t *extents) |
172 | cairo_point_t p; |
Line 174... | Line 173... | ||
174 | { |
173 | |
175 | cairo_box_t box; |
174 | p.x = _cairo_fixed_round_down (point->x); |
176 | cairo_polygon_t polygon; |
175 | p.y = _cairo_fixed_round_down (point->y); |
- | 176 | ||
177 | cairo_traps_t traps; |
177 | status = _cairo_polygon_add_external_edge (filler->polygon, |
178 | cairo_status_t status; |
178 | &filler->current_point, |
179 | cairo_region_t *region; |
179 | &p); |
Line 180... | Line 180... | ||
180 | 180 | ||
181 | /* first try to bypass fill-to-polygon */ |
181 | filler->current_point = p; |
182 | _cairo_traps_init (&traps); |
182 | |
183 | status = _cairo_path_fixed_fill_rectilinear_to_traps (path, |
- | |
184 | fill_rule, |
- | |
185 | &traps); |
- | |
186 | if (_cairo_status_is_error (status)) |
- | |
187 | goto CLEANUP_TRAPS; |
- | |
188 | 183 | return status; |
|
189 | if (status == CAIRO_STATUS_SUCCESS) { |
- | |
190 | status = _cairo_traps_extract_region (&traps, ®ion); |
- | |
191 | goto CLEANUP_TRAPS; |
- | |
192 | } |
- | |
193 | - | ||
194 | /* path is not rectangular, try extracting clipped rectilinear edges */ |
- | |
195 | _cairo_polygon_init (&polygon); |
- | |
196 | if (extents != NULL) { |
- | |
197 | _cairo_box_from_rectangle (&box, extents); |
- | |
Line 198... | Line 184... | ||
198 | _cairo_polygon_limit (&polygon, &box, 1); |
184 | } |
199 | } |
185 | |
Line -... | Line 186... | ||
- | 186 | static cairo_status_t |
|
200 | 187 | _cairo_filler_ra_close (void *closure) |
|
201 | /* tolerance will be ignored as the path is rectilinear */ |
188 | { |
Line 202... | Line 189... | ||
202 | status = _cairo_path_fixed_fill_to_polygon (path, 0., &polygon); |
189 | cairo_filler_ra_t *filler = closure; |
203 | if (unlikely (status)) |
190 | return _cairo_filler_ra_line_to (closure, &filler->last_move_to); |
Line 204... | Line -... | ||
204 | goto CLEANUP_POLYGON; |
- | |
205 | - | ||
206 | if (polygon.num_edges == 0) { |
- | |
207 | region = cairo_region_create (); |
- | |
208 | } else { |
- | |
209 | status = |
- | |
210 | _cairo_bentley_ottmann_tessellate_rectilinear_polygon (&traps, |
- | |
211 | &polygon, |
191 | } |
212 | fill_rule); |
192 | |
213 | if (likely (status == CAIRO_STATUS_SUCCESS)) |
193 | static cairo_status_t |
214 | status = _cairo_traps_extract_region (&traps, ®ion); |
194 | _cairo_filler_ra_move_to (void *closure, |
215 | } |
195 | const cairo_point_t *point) |
216 | - | ||
217 | CLEANUP_POLYGON: |
196 | { |
218 | _cairo_polygon_fini (&polygon); |
- | |
219 | - | ||
220 | CLEANUP_TRAPS: |
- | |
221 | _cairo_traps_fini (&traps); |
- | |
222 | - | ||
223 | if (unlikely (status)) |
- | |
224 | region = _cairo_region_create_in_error (status); |
- | |
225 | - | ||
226 | return region; |
- | |
227 | } |
- | |
228 | - | ||
229 | /* This special-case filler supports only a path that describes a |
- | |
230 | * device-axis aligned rectangle. It exists to avoid the overhead of |
- | |
231 | * the general tessellator when drawing very common rectangles. |
- | |
232 | * |
- | |
233 | * If the path described anything but a device-axis aligned rectangle, |
- | |
234 | * this function will abort. |
- | |
235 | */ |
- | |
236 | cairo_region_t * |
- | |
237 | _cairo_path_fixed_fill_rectilinear_to_region (const cairo_path_fixed_t *path, |
- | |
238 | cairo_fill_rule_t fill_rule, |
- | |
239 | const cairo_rectangle_int_t *extents) |
- | |
240 | { |
- | |
241 | cairo_rectangle_int_t rectangle_stack[CAIRO_STACK_ARRAY_LENGTH (cairo_rectangle_int_t)]; |
- | |
242 | cairo_box_t box; |
- | |
243 | cairo_region_t *region = NULL; |
- | |
244 | - | ||
245 | assert (path->maybe_fill_region); |
- | |
246 | assert (! path->is_empty_fill); |
- | |
247 | - | ||
248 | if (_cairo_path_fixed_is_box (path, &box)) { |
- | |
249 | rectangle_stack[0].x = _cairo_fixed_integer_part (box.p1.x); |
- | |
250 | rectangle_stack[0].y = _cairo_fixed_integer_part (box.p1.y); |
- | |
251 | rectangle_stack[0].width = _cairo_fixed_integer_part (box.p2.x) - |
- | |
252 | rectangle_stack[0].x; |
- | |
253 | rectangle_stack[0].height = _cairo_fixed_integer_part (box.p2.y) - |
- | |
254 | rectangle_stack[0].y; |
- | |
255 | if (! _cairo_rectangle_intersect (&rectangle_stack[0], extents)) |
- | |
256 | region = cairo_region_create (); |
- | |
257 | else |
- | |
258 | region = cairo_region_create_rectangle (&rectangle_stack[0]); |
- | |
259 | } else if (fill_rule == CAIRO_FILL_RULE_WINDING) { |
197 | cairo_filler_ra_t *filler = closure; |
260 | cairo_rectangle_int_t *rects = rectangle_stack; |
- | |
261 | cairo_path_fixed_iter_t iter; |
- | |
262 | int last_cw = -1; |
- | |
263 | int size = ARRAY_LENGTH (rectangle_stack); |
- | |
264 | int count = 0; |
- | |
265 | - | ||
266 | /* Support a series of rectangles as can be expected to describe a |
- | |
267 | * GdkRegion clip region during exposes. |
- | |
268 | */ |
- | |
269 | _cairo_path_fixed_iter_init (&iter, path); |
- | |
270 | while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) { |
- | |
271 | int cw = 0; |
- | |
272 | - | ||
273 | if (box.p1.x > box.p2.x) { |
- | |
274 | cairo_fixed_t t; |
- | |
275 | - | ||
276 | t = box.p1.x; |
- | |
277 | box.p1.x = box.p2.x; |
- | |
278 | box.p2.x = t; |
- | |
279 | - | ||
280 | cw = ! cw; |
- | |
281 | } |
- | |
282 | - | ||
283 | if (box.p1.y > box.p2.y) { |
- | |
284 | cairo_fixed_t t; |
- | |
285 | - | ||
286 | t = box.p1.y; |
- | |
287 | box.p1.y = box.p2.y; |
- | |
288 | box.p2.y = t; |
- | |
289 | - | ||
290 | cw = ! cw; |
- | |
291 | } |
- | |
292 | - | ||
293 | if (last_cw < 0) |
- | |
294 | last_cw = cw; |
- | |
295 | else if (last_cw != cw) |
- | |
296 | goto TESSELLATE; |
- | |
297 | - | ||
298 | if (count == size) { |
- | |
299 | cairo_rectangle_int_t *new_rects; |
- | |
300 | - | ||
301 | size *= 4; |
- | |
302 | if (rects == rectangle_stack) { |
- | |
303 | new_rects = _cairo_malloc_ab (size, |
- | |
304 | sizeof (cairo_rectangle_int_t)); |
- | |
305 | if (unlikely (new_rects == NULL)) { |
- | |
306 | /* XXX _cairo_region_nil */ |
- | |
307 | break; |
- | |
308 | } |
- | |
309 | memcpy (new_rects, rects, sizeof (rectangle_stack)); |
- | |
310 | } else { |
- | |
Line 311... | Line 198... | ||
311 | new_rects = _cairo_realloc_ab (rects, size, |
198 | cairo_status_t status; |
312 | sizeof (cairo_rectangle_int_t)); |
- | |
313 | if (unlikely (new_rects == NULL)) { |
199 | cairo_point_t p; |
314 | /* XXX _cairo_region_nil */ |
- | |
315 | break; |
- | |
Line -... | Line 200... | ||
- | 200 | ||
Line -... | Line 201... | ||
- | 201 | /* close current subpath */ |
|
- | 202 | status = _cairo_filler_ra_close (closure); |
|
- | 203 | if (unlikely (status)) |
|
- | 204 | return status; |
|
- | 205 | ||
- | 206 | p.x = _cairo_fixed_round_down (point->x); |
|
- | 207 | p.y = _cairo_fixed_round_down (point->y); |
|
- | 208 | ||
- | 209 | /* make sure that the closure represents a degenerate path */ |
|
- | 210 | filler->current_point = p; |
|
316 | } |
211 | filler->last_move_to = p; |
- | 212 | ||
- | 213 | return CAIRO_STATUS_SUCCESS; |
|
Line 317... | Line 214... | ||
317 | } |
214 | } |
318 | rects = new_rects; |
215 | |
Line 319... | Line 216... | ||
319 | } |
216 | cairo_status_t |
320 | 217 | _cairo_path_fixed_fill_rectilinear_to_polygon (const cairo_path_fixed_t *path, |
|
321 | rects[count].x = _cairo_fixed_integer_part (box.p1.x); |
218 | cairo_antialias_t antialias, |
- | 219 | cairo_polygon_t *polygon) |
|
322 | rects[count].y = _cairo_fixed_integer_part (box.p1.y); |
220 | { |
323 | rects[count].width = _cairo_fixed_integer_part (box.p2.x) - rects[count].x; |
221 | cairo_filler_ra_t filler; |
324 | rects[count].height = _cairo_fixed_integer_part (box.p2.y) - rects[count].y; |
222 | cairo_status_t status; |
325 | if (_cairo_rectangle_intersect (&rects[count], extents)) |
223 | |
Line 326... | Line -... | ||
326 | count++; |
- | |
327 | } |
- | |
328 | - | ||
329 | if (_cairo_path_fixed_iter_at_end (&iter)) |
224 | if (antialias != CAIRO_ANTIALIAS_NONE) |
330 | region = cairo_region_create_rectangles (rects, count); |
- | |
331 | - | ||
332 | TESSELLATE: |
225 | return _cairo_path_fixed_fill_to_polygon (path, 0., polygon); |
333 | if (rects != rectangle_stack) |
- | |
334 | free (rects); |
- | |
335 | } |
- | |
336 | - | ||
337 | if (region == NULL) { |
- | |
Line -... | Line 226... | ||
- | 226 | ||
338 | /* Hmm, complex polygon */ |
227 | filler.polygon = polygon; |
339 | region = _cairo_path_fixed_fill_rectilinear_tessellate_to_region (path, |
228 | |
340 | fill_rule, |
229 | /* make sure that the closure represents a degenerate path */ |
Line 341... | Line 230... | ||
341 | extents); |
230 | filler.current_point.x = 0; |
342 | 231 | filler.current_point.y = 0; |
|
343 | - | ||
344 | } |
- | |
Line 345... | Line -... | ||
345 | - | ||
346 | return region; |
232 | filler.last_move_to = filler.current_point; |
347 | } |
- | |
348 | 233 | ||
349 | cairo_int_status_t |
234 | status = _cairo_path_fixed_interpret_flat (path, |
350 | _cairo_path_fixed_fill_rectilinear_to_traps (const cairo_path_fixed_t *path, |
235 | _cairo_filler_ra_move_to, |
351 | cairo_fill_rule_t fill_rule, |
- | |
352 | cairo_traps_t *traps) |
- | |
353 | { |
- | |
354 | cairo_box_t box; |
- | |
355 | cairo_status_t status; |
- | |
356 | - | ||
357 | traps->is_rectilinear = TRUE; |
- | |
358 | traps->is_rectangular = TRUE; |
- | |
359 | - | ||
Line 360... | Line 236... | ||
360 | if (_cairo_path_fixed_is_box (path, &box)) { |
236 | _cairo_filler_ra_line_to, |
361 | return _cairo_traps_tessellate_rectangle (traps, &box.p1, &box.p2); |
237 | _cairo_filler_ra_close, |
362 | } else { |
238 | &filler, |
- | 239 | 0.); |
|
363 | cairo_path_fixed_iter_t iter; |
240 | if (unlikely (status)) |
364 | 241 | return status; |
|
365 | _cairo_path_fixed_iter_init (&iter, path); |
242 | |
366 | while (_cairo_path_fixed_iter_is_fill_box (&iter, &box)) { |
243 | return _cairo_filler_ra_close (&filler); |
Line 367... | Line -... | ||
367 | if (box.p1.y > box.p2.y) { |
- | |
368 | cairo_fixed_t t; |
- | |
369 | 244 | } |
|
370 | t = box.p1.y; |
245 | |
371 | box.p1.y = box.p2.y; |
- | |
Line 372... | Line 246... | ||
372 | box.p2.y = t; |
246 | cairo_status_t |
373 | 247 | _cairo_path_fixed_fill_to_traps (const cairo_path_fixed_t *path, |
|
374 | t = box.p1.x; |
248 | cairo_fill_rule_t fill_rule, |
375 | box.p1.x = box.p2.x; |
249 | double tolerance, |
376 | box.p2.x = t; |
250 | cairo_traps_t *traps) |
377 | } |
251 | { |
378 | 252 | cairo_polygon_t polygon; |
|
Line 421... | Line 295... | ||
421 | } |
295 | } |
Line 422... | Line 296... | ||
422 | 296 | ||
423 | cairo_status_t |
297 | cairo_status_t |
424 | _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path, |
298 | _cairo_path_fixed_fill_rectilinear_to_boxes (const cairo_path_fixed_t *path, |
- | 299 | cairo_fill_rule_t fill_rule, |
|
425 | cairo_fill_rule_t fill_rule, |
300 | cairo_antialias_t antialias, |
426 | cairo_boxes_t *boxes) |
301 | cairo_boxes_t *boxes) |
427 | { |
302 | { |
428 | cairo_path_fixed_iter_t iter; |
303 | cairo_path_fixed_iter_t iter; |
429 | cairo_status_t status; |
304 | cairo_status_t status; |
Line 430... | Line 305... | ||
430 | cairo_box_t box; |
305 | cairo_box_t box; |
431 | 306 | ||
Line 432... | Line 307... | ||
432 | if (_cairo_path_fixed_is_box (path, &box)) |
307 | if (_cairo_path_fixed_is_box (path, &box)) |
433 | return _cairo_boxes_add (boxes, &box); |
308 | return _cairo_boxes_add (boxes, antialias, &box); |
434 | 309 | ||
435 | _cairo_path_fixed_iter_init (&iter, path); |
310 | _cairo_path_fixed_iter_init (&iter, path); |
Line 447... | Line 322... | ||
447 | t = box.p1.x; |
322 | t = box.p1.x; |
448 | box.p1.x = box.p2.x; |
323 | box.p1.x = box.p2.x; |
449 | box.p2.x = t; |
324 | box.p2.x = t; |
450 | } |
325 | } |
Line 451... | Line 326... | ||
451 | 326 | ||
452 | status = _cairo_boxes_add (boxes, &box); |
327 | status = _cairo_boxes_add (boxes, antialias, &box); |
453 | if (unlikely (status)) |
328 | if (unlikely (status)) |
454 | return status; |
329 | return status; |
Line 455... | Line 330... | ||
455 | } |
330 | } |
Line 459... | Line 334... | ||
459 | 334 | ||
460 | /* path is not rectangular, try extracting clipped rectilinear edges */ |
335 | /* path is not rectangular, try extracting clipped rectilinear edges */ |
461 | _cairo_boxes_clear (boxes); |
336 | _cairo_boxes_clear (boxes); |
462 | return _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (path, |
337 | return _cairo_path_fixed_fill_rectilinear_tessellate_to_boxes (path, |
- | 338 | fill_rule, |
|
463 | fill_rule, |
339 | antialias, |
464 | boxes); |
340 | boxes); |