/work/workdir/UnpackedTarball/cairo/src/cairo-polygon-reduce.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright © 2004 Carl Worth |
3 | | * Copyright © 2006 Red Hat, Inc. |
4 | | * Copyright © 2008 Chris Wilson |
5 | | * |
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. |
13 | | * |
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 |
19 | | * |
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/ |
24 | | * |
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. |
28 | | * |
29 | | * The Original Code is the cairo graphics library. |
30 | | * |
31 | | * The Initial Developer of the Original Code is Carl Worth |
32 | | * |
33 | | * Contributor(s): |
34 | | * Carl D. Worth <cworth@cworth.org> |
35 | | * Chris Wilson <chris@chris-wilson.co.uk> |
36 | | */ |
37 | | |
38 | | /* Provide definitions for standalone compilation */ |
39 | | #include "cairoint.h" |
40 | | |
41 | | #include "cairo-error-private.h" |
42 | | #include "cairo-freelist-private.h" |
43 | | #include "cairo-combsort-inline.h" |
44 | | |
45 | 0 | #define DEBUG_POLYGON 0 |
46 | | |
47 | | typedef cairo_point_t cairo_bo_point32_t; |
48 | | |
49 | | typedef struct _cairo_bo_intersect_ordinate { |
50 | | int32_t ordinate; |
51 | | enum { EXACT, INEXACT } exactness; |
52 | | } cairo_bo_intersect_ordinate_t; |
53 | | |
54 | | typedef struct _cairo_bo_intersect_point { |
55 | | cairo_bo_intersect_ordinate_t x; |
56 | | cairo_bo_intersect_ordinate_t y; |
57 | | } cairo_bo_intersect_point_t; |
58 | | |
59 | | typedef struct _cairo_bo_edge cairo_bo_edge_t; |
60 | | |
61 | | typedef struct _cairo_bo_deferred { |
62 | | cairo_bo_edge_t *right; |
63 | | int32_t top; |
64 | | } cairo_bo_deferred_t; |
65 | | |
66 | | struct _cairo_bo_edge { |
67 | | cairo_edge_t edge; |
68 | | cairo_bo_edge_t *prev; |
69 | | cairo_bo_edge_t *next; |
70 | | cairo_bo_deferred_t deferred; |
71 | | }; |
72 | | |
73 | | /* the parent is always given by index/2 */ |
74 | 0 | #define PQ_PARENT_INDEX(i) ((i) >> 1) |
75 | 0 | #define PQ_FIRST_ENTRY 1 |
76 | | |
77 | | /* left and right children are index * 2 and (index * 2) +1 respectively */ |
78 | 0 | #define PQ_LEFT_CHILD_INDEX(i) ((i) << 1) |
79 | | |
80 | | typedef enum { |
81 | | CAIRO_BO_EVENT_TYPE_STOP, |
82 | | CAIRO_BO_EVENT_TYPE_INTERSECTION, |
83 | | CAIRO_BO_EVENT_TYPE_START |
84 | | } cairo_bo_event_type_t; |
85 | | |
86 | | typedef struct _cairo_bo_event { |
87 | | cairo_bo_event_type_t type; |
88 | | cairo_point_t point; |
89 | | } cairo_bo_event_t; |
90 | | |
91 | | typedef struct _cairo_bo_start_event { |
92 | | cairo_bo_event_type_t type; |
93 | | cairo_point_t point; |
94 | | cairo_bo_edge_t edge; |
95 | | } cairo_bo_start_event_t; |
96 | | |
97 | | typedef struct _cairo_bo_queue_event { |
98 | | cairo_bo_event_type_t type; |
99 | | cairo_point_t point; |
100 | | cairo_bo_edge_t *e1; |
101 | | cairo_bo_edge_t *e2; |
102 | | } cairo_bo_queue_event_t; |
103 | | |
104 | | typedef struct _pqueue { |
105 | | int size, max_size; |
106 | | |
107 | | cairo_bo_event_t **elements; |
108 | | cairo_bo_event_t *elements_embedded[1024]; |
109 | | } pqueue_t; |
110 | | |
111 | | typedef struct _cairo_bo_event_queue { |
112 | | cairo_freepool_t pool; |
113 | | pqueue_t pqueue; |
114 | | cairo_bo_event_t **start_events; |
115 | | } cairo_bo_event_queue_t; |
116 | | |
117 | | typedef struct _cairo_bo_sweep_line { |
118 | | cairo_bo_edge_t *head; |
119 | | int32_t current_y; |
120 | | cairo_bo_edge_t *current_edge; |
121 | | } cairo_bo_sweep_line_t; |
122 | | |
123 | | static cairo_fixed_t |
124 | | _line_compute_intersection_x_for_y (const cairo_line_t *line, |
125 | | cairo_fixed_t y) |
126 | 0 | { |
127 | 0 | cairo_fixed_t x, dy; |
128 | |
|
129 | 0 | if (y == line->p1.y) |
130 | 0 | return line->p1.x; |
131 | 0 | if (y == line->p2.y) |
132 | 0 | return line->p2.x; |
133 | | |
134 | 0 | x = line->p1.x; |
135 | 0 | dy = line->p2.y - line->p1.y; |
136 | 0 | if (dy != 0) { |
137 | 0 | x += _cairo_fixed_mul_div_floor (y - line->p1.y, |
138 | 0 | line->p2.x - line->p1.x, |
139 | 0 | dy); |
140 | 0 | } |
141 | |
|
142 | 0 | return x; |
143 | 0 | } |
144 | | |
145 | | static inline int |
146 | | _cairo_bo_point32_compare (cairo_bo_point32_t const *a, |
147 | | cairo_bo_point32_t const *b) |
148 | 0 | { |
149 | 0 | int cmp; |
150 | |
|
151 | 0 | cmp = a->y - b->y; |
152 | 0 | if (cmp) |
153 | 0 | return cmp; |
154 | | |
155 | 0 | return a->x - b->x; |
156 | 0 | } |
157 | | |
158 | | /* Compare the slope of a to the slope of b, returning 1, 0, -1 if the |
159 | | * slope a is respectively greater than, equal to, or less than the |
160 | | * slope of b. |
161 | | * |
162 | | * For each edge, consider the direction vector formed from: |
163 | | * |
164 | | * top -> bottom |
165 | | * |
166 | | * which is: |
167 | | * |
168 | | * (dx, dy) = (line.p2.x - line.p1.x, line.p2.y - line.p1.y) |
169 | | * |
170 | | * We then define the slope of each edge as dx/dy, (which is the |
171 | | * inverse of the slope typically used in math instruction). We never |
172 | | * compute a slope directly as the value approaches infinity, but we |
173 | | * can derive a slope comparison without division as follows, (where |
174 | | * the ? represents our compare operator). |
175 | | * |
176 | | * 1. slope(a) ? slope(b) |
177 | | * 2. adx/ady ? bdx/bdy |
178 | | * 3. (adx * bdy) ? (bdx * ady) |
179 | | * |
180 | | * Note that from step 2 to step 3 there is no change needed in the |
181 | | * sign of the result since both ady and bdy are guaranteed to be |
182 | | * greater than or equal to 0. |
183 | | * |
184 | | * When using this slope comparison to sort edges, some care is needed |
185 | | * when interpreting the results. Since the slope compare operates on |
186 | | * distance vectors from top to bottom it gives a correct left to |
187 | | * right sort for edges that have a common top point, (such as two |
188 | | * edges with start events at the same location). On the other hand, |
189 | | * the sense of the result will be exactly reversed for two edges that |
190 | | * have a common stop point. |
191 | | */ |
192 | | static inline int |
193 | | _slope_compare (const cairo_bo_edge_t *a, |
194 | | const cairo_bo_edge_t *b) |
195 | 0 | { |
196 | | /* XXX: We're assuming here that dx and dy will still fit in 32 |
197 | | * bits. That's not true in general as there could be overflow. We |
198 | | * should prevent that before the tessellation algorithm |
199 | | * begins. |
200 | | */ |
201 | 0 | int32_t adx = a->edge.line.p2.x - a->edge.line.p1.x; |
202 | 0 | int32_t bdx = b->edge.line.p2.x - b->edge.line.p1.x; |
203 | | |
204 | | /* Since the dy's are all positive by construction we can fast |
205 | | * path several common cases. |
206 | | */ |
207 | | |
208 | | /* First check for vertical lines. */ |
209 | 0 | if (adx == 0) |
210 | 0 | return -bdx; |
211 | 0 | if (bdx == 0) |
212 | 0 | return adx; |
213 | | |
214 | | /* Then where the two edges point in different directions wrt x. */ |
215 | 0 | if ((adx ^ bdx) < 0) |
216 | 0 | return adx; |
217 | | |
218 | | /* Finally we actually need to do the general comparison. */ |
219 | 0 | { |
220 | 0 | int32_t ady = a->edge.line.p2.y - a->edge.line.p1.y; |
221 | 0 | int32_t bdy = b->edge.line.p2.y - b->edge.line.p1.y; |
222 | 0 | cairo_int64_t adx_bdy = _cairo_int32x32_64_mul (adx, bdy); |
223 | 0 | cairo_int64_t bdx_ady = _cairo_int32x32_64_mul (bdx, ady); |
224 | |
|
225 | 0 | return _cairo_int64_cmp (adx_bdy, bdx_ady); |
226 | 0 | } |
227 | 0 | } |
228 | | |
229 | | /* |
230 | | * We need to compare the x-coordinates of a pair of lines for a particular y, |
231 | | * without loss of precision. |
232 | | * |
233 | | * The x-coordinate along an edge for a given y is: |
234 | | * X = A_x + (Y - A_y) * A_dx / A_dy |
235 | | * |
236 | | * So the inequality we wish to test is: |
237 | | * A_x + (Y - A_y) * A_dx / A_dy ∘ B_x + (Y - B_y) * B_dx / B_dy, |
238 | | * where ∘ is our inequality operator. |
239 | | * |
240 | | * By construction, we know that A_dy and B_dy (and (Y - A_y), (Y - B_y)) are |
241 | | * all positive, so we can rearrange it thus without causing a sign change: |
242 | | * A_dy * B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx * A_dy |
243 | | * - (Y - A_y) * A_dx * B_dy |
244 | | * |
245 | | * Given the assumption that all the deltas fit within 32 bits, we can compute |
246 | | * this comparison directly using 128 bit arithmetic. For certain, but common, |
247 | | * input we can reduce this down to a single 32 bit compare by inspecting the |
248 | | * deltas. |
249 | | * |
250 | | * (And put the burden of the work on developing fast 128 bit ops, which are |
251 | | * required throughout the tessellator.) |
252 | | * |
253 | | * See the similar discussion for _slope_compare(). |
254 | | */ |
255 | | static int |
256 | | edges_compare_x_for_y_general (const cairo_bo_edge_t *a, |
257 | | const cairo_bo_edge_t *b, |
258 | | int32_t y) |
259 | 0 | { |
260 | | /* XXX: We're assuming here that dx and dy will still fit in 32 |
261 | | * bits. That's not true in general as there could be overflow. We |
262 | | * should prevent that before the tessellation algorithm |
263 | | * begins. |
264 | | */ |
265 | 0 | int32_t dx; |
266 | 0 | int32_t adx, ady; |
267 | 0 | int32_t bdx, bdy; |
268 | 0 | enum { |
269 | 0 | HAVE_NONE = 0x0, |
270 | 0 | HAVE_DX = 0x1, |
271 | 0 | HAVE_ADX = 0x2, |
272 | 0 | HAVE_DX_ADX = HAVE_DX | HAVE_ADX, |
273 | 0 | HAVE_BDX = 0x4, |
274 | 0 | HAVE_DX_BDX = HAVE_DX | HAVE_BDX, |
275 | 0 | HAVE_ADX_BDX = HAVE_ADX | HAVE_BDX, |
276 | 0 | HAVE_ALL = HAVE_DX | HAVE_ADX | HAVE_BDX |
277 | 0 | } have_dx_adx_bdx = HAVE_ALL; |
278 | | |
279 | | /* don't bother solving for abscissa if the edges' bounding boxes |
280 | | * can be used to order them. */ |
281 | 0 | { |
282 | 0 | int32_t amin, amax; |
283 | 0 | int32_t bmin, bmax; |
284 | 0 | if (a->edge.line.p1.x < a->edge.line.p2.x) { |
285 | 0 | amin = a->edge.line.p1.x; |
286 | 0 | amax = a->edge.line.p2.x; |
287 | 0 | } else { |
288 | 0 | amin = a->edge.line.p2.x; |
289 | 0 | amax = a->edge.line.p1.x; |
290 | 0 | } |
291 | 0 | if (b->edge.line.p1.x < b->edge.line.p2.x) { |
292 | 0 | bmin = b->edge.line.p1.x; |
293 | 0 | bmax = b->edge.line.p2.x; |
294 | 0 | } else { |
295 | 0 | bmin = b->edge.line.p2.x; |
296 | 0 | bmax = b->edge.line.p1.x; |
297 | 0 | } |
298 | 0 | if (amax < bmin) return -1; |
299 | 0 | if (amin > bmax) return +1; |
300 | 0 | } |
301 | | |
302 | 0 | ady = a->edge.line.p2.y - a->edge.line.p1.y; |
303 | 0 | adx = a->edge.line.p2.x - a->edge.line.p1.x; |
304 | 0 | if (adx == 0) |
305 | 0 | have_dx_adx_bdx &= ~HAVE_ADX; |
306 | |
|
307 | 0 | bdy = b->edge.line.p2.y - b->edge.line.p1.y; |
308 | 0 | bdx = b->edge.line.p2.x - b->edge.line.p1.x; |
309 | 0 | if (bdx == 0) |
310 | 0 | have_dx_adx_bdx &= ~HAVE_BDX; |
311 | |
|
312 | 0 | dx = a->edge.line.p1.x - b->edge.line.p1.x; |
313 | 0 | if (dx == 0) |
314 | 0 | have_dx_adx_bdx &= ~HAVE_DX; |
315 | |
|
316 | 0 | #define L _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (ady, bdy), dx) |
317 | 0 | #define A _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (adx, bdy), y - a->edge.line.p1.y) |
318 | 0 | #define B _cairo_int64x32_128_mul (_cairo_int32x32_64_mul (bdx, ady), y - b->edge.line.p1.y) |
319 | 0 | switch (have_dx_adx_bdx) { |
320 | 0 | default: |
321 | 0 | case HAVE_NONE: |
322 | 0 | return 0; |
323 | 0 | case HAVE_DX: |
324 | | /* A_dy * B_dy * (A_x - B_x) ∘ 0 */ |
325 | 0 | return dx; /* ady * bdy is positive definite */ |
326 | 0 | case HAVE_ADX: |
327 | | /* 0 ∘ - (Y - A_y) * A_dx * B_dy */ |
328 | 0 | return adx; /* bdy * (y - a->top.y) is positive definite */ |
329 | 0 | case HAVE_BDX: |
330 | | /* 0 ∘ (Y - B_y) * B_dx * A_dy */ |
331 | 0 | return -bdx; /* ady * (y - b->top.y) is positive definite */ |
332 | 0 | case HAVE_ADX_BDX: |
333 | | /* 0 ∘ (Y - B_y) * B_dx * A_dy - (Y - A_y) * A_dx * B_dy */ |
334 | 0 | if ((adx ^ bdx) < 0) { |
335 | 0 | return adx; |
336 | 0 | } else if (a->edge.line.p1.y == b->edge.line.p1.y) { /* common origin */ |
337 | 0 | cairo_int64_t adx_bdy, bdx_ady; |
338 | | |
339 | | /* ∴ A_dx * B_dy ∘ B_dx * A_dy */ |
340 | |
|
341 | 0 | adx_bdy = _cairo_int32x32_64_mul (adx, bdy); |
342 | 0 | bdx_ady = _cairo_int32x32_64_mul (bdx, ady); |
343 | |
|
344 | 0 | return _cairo_int64_cmp (adx_bdy, bdx_ady); |
345 | 0 | } else |
346 | 0 | return _cairo_int128_cmp (A, B); |
347 | 0 | case HAVE_DX_ADX: |
348 | | /* A_dy * (A_x - B_x) ∘ - (Y - A_y) * A_dx */ |
349 | 0 | if ((-adx ^ dx) < 0) { |
350 | 0 | return dx; |
351 | 0 | } else { |
352 | 0 | cairo_int64_t ady_dx, dy_adx; |
353 | |
|
354 | 0 | ady_dx = _cairo_int32x32_64_mul (ady, dx); |
355 | 0 | dy_adx = _cairo_int32x32_64_mul (a->edge.line.p1.y - y, adx); |
356 | |
|
357 | 0 | return _cairo_int64_cmp (ady_dx, dy_adx); |
358 | 0 | } |
359 | 0 | case HAVE_DX_BDX: |
360 | | /* B_dy * (A_x - B_x) ∘ (Y - B_y) * B_dx */ |
361 | 0 | if ((bdx ^ dx) < 0) { |
362 | 0 | return dx; |
363 | 0 | } else { |
364 | 0 | cairo_int64_t bdy_dx, dy_bdx; |
365 | |
|
366 | 0 | bdy_dx = _cairo_int32x32_64_mul (bdy, dx); |
367 | 0 | dy_bdx = _cairo_int32x32_64_mul (y - b->edge.line.p1.y, bdx); |
368 | |
|
369 | 0 | return _cairo_int64_cmp (bdy_dx, dy_bdx); |
370 | 0 | } |
371 | 0 | case HAVE_ALL: |
372 | | /* XXX try comparing (a->edge.line.p2.x - b->edge.line.p2.x) et al */ |
373 | 0 | return _cairo_int128_cmp (L, _cairo_int128_sub (B, A)); |
374 | 0 | } |
375 | 0 | #undef B |
376 | 0 | #undef A |
377 | 0 | #undef L |
378 | 0 | } |
379 | | |
380 | | /* |
381 | | * We need to compare the x-coordinate of a line for a particular y wrt to a |
382 | | * given x, without loss of precision. |
383 | | * |
384 | | * The x-coordinate along an edge for a given y is: |
385 | | * X = A_x + (Y - A_y) * A_dx / A_dy |
386 | | * |
387 | | * So the inequality we wish to test is: |
388 | | * A_x + (Y - A_y) * A_dx / A_dy ∘ X |
389 | | * where ∘ is our inequality operator. |
390 | | * |
391 | | * By construction, we know that A_dy (and (Y - A_y)) are |
392 | | * all positive, so we can rearrange it thus without causing a sign change: |
393 | | * (Y - A_y) * A_dx ∘ (X - A_x) * A_dy |
394 | | * |
395 | | * Given the assumption that all the deltas fit within 32 bits, we can compute |
396 | | * this comparison directly using 64 bit arithmetic. |
397 | | * |
398 | | * See the similar discussion for _slope_compare() and |
399 | | * edges_compare_x_for_y_general(). |
400 | | */ |
401 | | static int |
402 | | edge_compare_for_y_against_x (const cairo_bo_edge_t *a, |
403 | | int32_t y, |
404 | | int32_t x) |
405 | 0 | { |
406 | 0 | int32_t adx, ady; |
407 | 0 | int32_t dx, dy; |
408 | 0 | cairo_int64_t L, R; |
409 | |
|
410 | 0 | if (x < a->edge.line.p1.x && x < a->edge.line.p2.x) |
411 | 0 | return 1; |
412 | 0 | if (x > a->edge.line.p1.x && x > a->edge.line.p2.x) |
413 | 0 | return -1; |
414 | | |
415 | 0 | adx = a->edge.line.p2.x - a->edge.line.p1.x; |
416 | 0 | dx = x - a->edge.line.p1.x; |
417 | |
|
418 | 0 | if (adx == 0) |
419 | 0 | return -dx; |
420 | 0 | if (dx == 0 || (adx ^ dx) < 0) |
421 | 0 | return adx; |
422 | | |
423 | 0 | dy = y - a->edge.line.p1.y; |
424 | 0 | ady = a->edge.line.p2.y - a->edge.line.p1.y; |
425 | |
|
426 | 0 | L = _cairo_int32x32_64_mul (dy, adx); |
427 | 0 | R = _cairo_int32x32_64_mul (dx, ady); |
428 | |
|
429 | 0 | return _cairo_int64_cmp (L, R); |
430 | 0 | } |
431 | | |
432 | | static int |
433 | | edges_compare_x_for_y (const cairo_bo_edge_t *a, |
434 | | const cairo_bo_edge_t *b, |
435 | | int32_t y) |
436 | 0 | { |
437 | | /* If the sweep-line is currently on an end-point of a line, |
438 | | * then we know its precise x value (and considering that we often need to |
439 | | * compare events at end-points, this happens frequently enough to warrant |
440 | | * special casing). |
441 | | */ |
442 | 0 | enum { |
443 | 0 | HAVE_NEITHER = 0x0, |
444 | 0 | HAVE_AX = 0x1, |
445 | 0 | HAVE_BX = 0x2, |
446 | 0 | HAVE_BOTH = HAVE_AX | HAVE_BX |
447 | 0 | } have_ax_bx = HAVE_BOTH; |
448 | 0 | int32_t ax = 0, bx = 0; |
449 | |
|
450 | 0 | if (y == a->edge.line.p1.y) |
451 | 0 | ax = a->edge.line.p1.x; |
452 | 0 | else if (y == a->edge.line.p2.y) |
453 | 0 | ax = a->edge.line.p2.x; |
454 | 0 | else |
455 | 0 | have_ax_bx &= ~HAVE_AX; |
456 | |
|
457 | 0 | if (y == b->edge.line.p1.y) |
458 | 0 | bx = b->edge.line.p1.x; |
459 | 0 | else if (y == b->edge.line.p2.y) |
460 | 0 | bx = b->edge.line.p2.x; |
461 | 0 | else |
462 | 0 | have_ax_bx &= ~HAVE_BX; |
463 | |
|
464 | 0 | switch (have_ax_bx) { |
465 | 0 | default: |
466 | 0 | case HAVE_NEITHER: |
467 | 0 | return edges_compare_x_for_y_general (a, b, y); |
468 | 0 | case HAVE_AX: |
469 | 0 | return -edge_compare_for_y_against_x (b, y, ax); |
470 | 0 | case HAVE_BX: |
471 | 0 | return edge_compare_for_y_against_x (a, y, bx); |
472 | 0 | case HAVE_BOTH: |
473 | 0 | return ax - bx; |
474 | 0 | } |
475 | 0 | } |
476 | | |
477 | | static inline int |
478 | | _line_equal (const cairo_line_t *a, const cairo_line_t *b) |
479 | 0 | { |
480 | 0 | return (a->p1.x == b->p1.x && a->p1.y == b->p1.y && |
481 | 0 | a->p2.x == b->p2.x && a->p2.y == b->p2.y); |
482 | 0 | } |
483 | | |
484 | | static int |
485 | | _cairo_bo_sweep_line_compare_edges (cairo_bo_sweep_line_t *sweep_line, |
486 | | const cairo_bo_edge_t *a, |
487 | | const cairo_bo_edge_t *b) |
488 | 0 | { |
489 | 0 | int cmp; |
490 | | |
491 | | /* compare the edges if not identical */ |
492 | 0 | if (! _line_equal (&a->edge.line, &b->edge.line)) { |
493 | 0 | cmp = edges_compare_x_for_y (a, b, sweep_line->current_y); |
494 | 0 | if (cmp) |
495 | 0 | return cmp; |
496 | | |
497 | | /* The two edges intersect exactly at y, so fall back on slope |
498 | | * comparison. We know that this compare_edges function will be |
499 | | * called only when starting a new edge, (not when stopping an |
500 | | * edge), so we don't have to worry about conditionally inverting |
501 | | * the sense of _slope_compare. */ |
502 | 0 | cmp = _slope_compare (a, b); |
503 | 0 | if (cmp) |
504 | 0 | return cmp; |
505 | 0 | } |
506 | | |
507 | | /* We've got two collinear edges now. */ |
508 | 0 | return b->edge.bottom - a->edge.bottom; |
509 | 0 | } |
510 | | |
511 | | static inline cairo_int64_t |
512 | | det32_64 (int32_t a, int32_t b, |
513 | | int32_t c, int32_t d) |
514 | 0 | { |
515 | | /* det = a * d - b * c */ |
516 | 0 | return _cairo_int64_sub (_cairo_int32x32_64_mul (a, d), |
517 | 0 | _cairo_int32x32_64_mul (b, c)); |
518 | 0 | } |
519 | | |
520 | | static inline cairo_int128_t |
521 | | det64x32_128 (cairo_int64_t a, int32_t b, |
522 | | cairo_int64_t c, int32_t d) |
523 | 0 | { |
524 | | /* det = a * d - b * c */ |
525 | 0 | return _cairo_int128_sub (_cairo_int64x32_128_mul (a, d), |
526 | 0 | _cairo_int64x32_128_mul (c, b)); |
527 | 0 | } |
528 | | |
529 | | /* Compute the intersection of two lines as defined by two edges. The |
530 | | * result is provided as a coordinate pair of 128-bit integers. |
531 | | * |
532 | | * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection or |
533 | | * %CAIRO_BO_STATUS_PARALLEL if the two lines are exactly parallel. |
534 | | */ |
535 | | static cairo_bool_t |
536 | | intersect_lines (cairo_bo_edge_t *a, |
537 | | cairo_bo_edge_t *b, |
538 | | cairo_bo_intersect_point_t *intersection) |
539 | 0 | { |
540 | 0 | cairo_int64_t a_det, b_det; |
541 | | |
542 | | /* XXX: We're assuming here that dx and dy will still fit in 32 |
543 | | * bits. That's not true in general as there could be overflow. We |
544 | | * should prevent that before the tessellation algorithm begins. |
545 | | * What we're doing to mitigate this is to perform clamping in |
546 | | * cairo_bo_tessellate_polygon(). |
547 | | */ |
548 | 0 | int32_t dx1 = a->edge.line.p1.x - a->edge.line.p2.x; |
549 | 0 | int32_t dy1 = a->edge.line.p1.y - a->edge.line.p2.y; |
550 | |
|
551 | 0 | int32_t dx2 = b->edge.line.p1.x - b->edge.line.p2.x; |
552 | 0 | int32_t dy2 = b->edge.line.p1.y - b->edge.line.p2.y; |
553 | |
|
554 | 0 | cairo_int64_t den_det; |
555 | 0 | cairo_int64_t R; |
556 | 0 | cairo_quorem64_t qr; |
557 | |
|
558 | 0 | den_det = det32_64 (dx1, dy1, dx2, dy2); |
559 | | |
560 | | /* Q: Can we determine that the lines do not intersect (within range) |
561 | | * much more cheaply than computing the intersection point i.e. by |
562 | | * avoiding the division? |
563 | | * |
564 | | * X = ax + t * adx = bx + s * bdx; |
565 | | * Y = ay + t * ady = by + s * bdy; |
566 | | * ∴ t * (ady*bdx - bdy*adx) = bdx * (by - ay) + bdy * (ax - bx) |
567 | | * => t * L = R |
568 | | * |
569 | | * Therefore we can reject any intersection (under the criteria for |
570 | | * valid intersection events) if: |
571 | | * L^R < 0 => t < 0, or |
572 | | * L<R => t > 1 |
573 | | * |
574 | | * (where top/bottom must at least extend to the line endpoints). |
575 | | * |
576 | | * A similar substitution can be performed for s, yielding: |
577 | | * s * (ady*bdx - bdy*adx) = ady * (ax - bx) - adx * (ay - by) |
578 | | */ |
579 | 0 | R = det32_64 (dx2, dy2, |
580 | 0 | b->edge.line.p1.x - a->edge.line.p1.x, |
581 | 0 | b->edge.line.p1.y - a->edge.line.p1.y); |
582 | 0 | if (_cairo_int64_negative (den_det)) { |
583 | 0 | if (_cairo_int64_ge (den_det, R)) |
584 | 0 | return FALSE; |
585 | 0 | } else { |
586 | 0 | if (_cairo_int64_le (den_det, R)) |
587 | 0 | return FALSE; |
588 | 0 | } |
589 | | |
590 | 0 | R = det32_64 (dy1, dx1, |
591 | 0 | a->edge.line.p1.y - b->edge.line.p1.y, |
592 | 0 | a->edge.line.p1.x - b->edge.line.p1.x); |
593 | 0 | if (_cairo_int64_negative (den_det)) { |
594 | 0 | if (_cairo_int64_ge (den_det, R)) |
595 | 0 | return FALSE; |
596 | 0 | } else { |
597 | 0 | if (_cairo_int64_le (den_det, R)) |
598 | 0 | return FALSE; |
599 | 0 | } |
600 | | |
601 | | /* We now know that the two lines should intersect within range. */ |
602 | | |
603 | 0 | a_det = det32_64 (a->edge.line.p1.x, a->edge.line.p1.y, |
604 | 0 | a->edge.line.p2.x, a->edge.line.p2.y); |
605 | 0 | b_det = det32_64 (b->edge.line.p1.x, b->edge.line.p1.y, |
606 | 0 | b->edge.line.p2.x, b->edge.line.p2.y); |
607 | | |
608 | | /* x = det (a_det, dx1, b_det, dx2) / den_det */ |
609 | 0 | qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dx1, |
610 | 0 | b_det, dx2), |
611 | 0 | den_det); |
612 | 0 | if (_cairo_int64_eq (qr.rem, den_det)) |
613 | 0 | return FALSE; |
614 | | #if 0 |
615 | | intersection->x.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT; |
616 | | #else |
617 | 0 | intersection->x.exactness = EXACT; |
618 | 0 | if (! _cairo_int64_is_zero (qr.rem)) { |
619 | 0 | if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem)) |
620 | 0 | qr.rem = _cairo_int64_negate (qr.rem); |
621 | 0 | qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2)); |
622 | 0 | if (_cairo_int64_ge (qr.rem, den_det)) { |
623 | 0 | qr.quo = _cairo_int64_add (qr.quo, |
624 | 0 | _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1)); |
625 | 0 | } else |
626 | 0 | intersection->x.exactness = INEXACT; |
627 | 0 | } |
628 | 0 | #endif |
629 | 0 | intersection->x.ordinate = _cairo_int64_to_int32 (qr.quo); |
630 | | |
631 | | /* y = det (a_det, dy1, b_det, dy2) / den_det */ |
632 | 0 | qr = _cairo_int_96by64_32x64_divrem (det64x32_128 (a_det, dy1, |
633 | 0 | b_det, dy2), |
634 | 0 | den_det); |
635 | 0 | if (_cairo_int64_eq (qr.rem, den_det)) |
636 | 0 | return FALSE; |
637 | | #if 0 |
638 | | intersection->y.exactness = _cairo_int64_is_zero (qr.rem) ? EXACT : INEXACT; |
639 | | #else |
640 | 0 | intersection->y.exactness = EXACT; |
641 | 0 | if (! _cairo_int64_is_zero (qr.rem)) { |
642 | 0 | if (_cairo_int64_negative (den_det) ^ _cairo_int64_negative (qr.rem)) |
643 | 0 | qr.rem = _cairo_int64_negate (qr.rem); |
644 | 0 | qr.rem = _cairo_int64_mul (qr.rem, _cairo_int32_to_int64 (2)); |
645 | 0 | if (_cairo_int64_ge (qr.rem, den_det)) { |
646 | 0 | qr.quo = _cairo_int64_add (qr.quo, |
647 | 0 | _cairo_int32_to_int64 (_cairo_int64_negative (qr.quo) ? -1 : 1)); |
648 | 0 | } else |
649 | 0 | intersection->y.exactness = INEXACT; |
650 | 0 | } |
651 | 0 | #endif |
652 | 0 | intersection->y.ordinate = _cairo_int64_to_int32 (qr.quo); |
653 | |
|
654 | 0 | return TRUE; |
655 | 0 | } |
656 | | |
657 | | static int |
658 | | _cairo_bo_intersect_ordinate_32_compare (cairo_bo_intersect_ordinate_t a, |
659 | | int32_t b) |
660 | 0 | { |
661 | | /* First compare the quotient */ |
662 | 0 | if (a.ordinate > b) |
663 | 0 | return +1; |
664 | 0 | if (a.ordinate < b) |
665 | 0 | return -1; |
666 | | /* With quotient identical, if remainder is 0 then compare equal */ |
667 | | /* Otherwise, the non-zero remainder makes a > b */ |
668 | 0 | return INEXACT == a.exactness; |
669 | 0 | } |
670 | | |
671 | | /* Does the given edge contain the given point. The point must already |
672 | | * be known to be contained within the line determined by the edge, |
673 | | * (most likely the point results from an intersection of this edge |
674 | | * with another). |
675 | | * |
676 | | * If we had exact arithmetic, then this function would simply be a |
677 | | * matter of examining whether the y value of the point lies within |
678 | | * the range of y values of the edge. But since intersection points |
679 | | * are not exact due to being rounded to the nearest integer within |
680 | | * the available precision, we must also examine the x value of the |
681 | | * point. |
682 | | * |
683 | | * The definition of "contains" here is that the given intersection |
684 | | * point will be seen by the sweep line after the start event for the |
685 | | * given edge and before the stop event for the edge. See the comments |
686 | | * in the implementation for more details. |
687 | | */ |
688 | | static cairo_bool_t |
689 | | _cairo_bo_edge_contains_intersect_point (cairo_bo_edge_t *edge, |
690 | | cairo_bo_intersect_point_t *point) |
691 | 0 | { |
692 | 0 | int cmp_top, cmp_bottom; |
693 | | |
694 | | /* XXX: When running the actual algorithm, we don't actually need to |
695 | | * compare against edge->top at all here, since any intersection above |
696 | | * top is eliminated early via a slope comparison. We're leaving these |
697 | | * here for now only for the sake of the quadratic-time intersection |
698 | | * finder which needs them. |
699 | | */ |
700 | |
|
701 | 0 | cmp_top = _cairo_bo_intersect_ordinate_32_compare (point->y, |
702 | 0 | edge->edge.top); |
703 | 0 | cmp_bottom = _cairo_bo_intersect_ordinate_32_compare (point->y, |
704 | 0 | edge->edge.bottom); |
705 | |
|
706 | 0 | if (cmp_top < 0 || cmp_bottom > 0) |
707 | 0 | { |
708 | 0 | return FALSE; |
709 | 0 | } |
710 | | |
711 | 0 | if (cmp_top > 0 && cmp_bottom < 0) |
712 | 0 | { |
713 | 0 | return TRUE; |
714 | 0 | } |
715 | | |
716 | | /* At this stage, the point lies on the same y value as either |
717 | | * edge->top or edge->bottom, so we have to examine the x value in |
718 | | * order to properly determine containment. */ |
719 | | |
720 | | /* If the y value of the point is the same as the y value of the |
721 | | * top of the edge, then the x value of the point must be greater |
722 | | * to be considered as inside the edge. Similarly, if the y value |
723 | | * of the point is the same as the y value of the bottom of the |
724 | | * edge, then the x value of the point must be less to be |
725 | | * considered as inside. */ |
726 | | |
727 | 0 | if (cmp_top == 0) { |
728 | 0 | cairo_fixed_t top_x; |
729 | |
|
730 | 0 | top_x = _line_compute_intersection_x_for_y (&edge->edge.line, |
731 | 0 | edge->edge.top); |
732 | 0 | return _cairo_bo_intersect_ordinate_32_compare (point->x, top_x) > 0; |
733 | 0 | } else { /* cmp_bottom == 0 */ |
734 | 0 | cairo_fixed_t bot_x; |
735 | |
|
736 | 0 | bot_x = _line_compute_intersection_x_for_y (&edge->edge.line, |
737 | 0 | edge->edge.bottom); |
738 | 0 | return _cairo_bo_intersect_ordinate_32_compare (point->x, bot_x) < 0; |
739 | 0 | } |
740 | 0 | } |
741 | | |
742 | | /* Compute the intersection of two edges. The result is provided as a |
743 | | * coordinate pair of 128-bit integers. |
744 | | * |
745 | | * Returns %CAIRO_BO_STATUS_INTERSECTION if there is an intersection |
746 | | * that is within both edges, %CAIRO_BO_STATUS_NO_INTERSECTION if the |
747 | | * intersection of the lines defined by the edges occurs outside of |
748 | | * one or both edges, and %CAIRO_BO_STATUS_PARALLEL if the two edges |
749 | | * are exactly parallel. |
750 | | * |
751 | | * Note that when determining if a candidate intersection is "inside" |
752 | | * an edge, we consider both the infinitesimal shortening and the |
753 | | * infinitesimal tilt rules described by John Hobby. Specifically, if |
754 | | * the intersection is exactly the same as an edge point, it is |
755 | | * effectively outside (no intersection is returned). Also, if the |
756 | | * intersection point has the same |
757 | | */ |
758 | | static cairo_bool_t |
759 | | _cairo_bo_edge_intersect (cairo_bo_edge_t *a, |
760 | | cairo_bo_edge_t *b, |
761 | | cairo_bo_point32_t *intersection) |
762 | 0 | { |
763 | 0 | cairo_bo_intersect_point_t quorem; |
764 | |
|
765 | 0 | if (! intersect_lines (a, b, &quorem)) |
766 | 0 | return FALSE; |
767 | | |
768 | 0 | if (! _cairo_bo_edge_contains_intersect_point (a, &quorem)) |
769 | 0 | return FALSE; |
770 | | |
771 | 0 | if (! _cairo_bo_edge_contains_intersect_point (b, &quorem)) |
772 | 0 | return FALSE; |
773 | | |
774 | | /* Now that we've correctly compared the intersection point and |
775 | | * determined that it lies within the edge, then we know that we |
776 | | * no longer need any more bits of storage for the intersection |
777 | | * than we do for our edge coordinates. We also no longer need the |
778 | | * remainder from the division. */ |
779 | 0 | intersection->x = quorem.x.ordinate; |
780 | 0 | intersection->y = quorem.y.ordinate; |
781 | |
|
782 | 0 | return TRUE; |
783 | 0 | } |
784 | | |
785 | | static inline int |
786 | | cairo_bo_event_compare (const cairo_bo_event_t *a, |
787 | | const cairo_bo_event_t *b) |
788 | 0 | { |
789 | 0 | int cmp; |
790 | |
|
791 | 0 | cmp = _cairo_bo_point32_compare (&a->point, &b->point); |
792 | 0 | if (cmp) |
793 | 0 | return cmp; |
794 | | |
795 | 0 | cmp = a->type - b->type; |
796 | 0 | if (cmp) |
797 | 0 | return cmp; |
798 | | |
799 | 0 | return a - b; |
800 | 0 | } |
801 | | |
802 | | static inline void |
803 | | _pqueue_init (pqueue_t *pq) |
804 | 0 | { |
805 | 0 | pq->max_size = ARRAY_LENGTH (pq->elements_embedded); |
806 | 0 | pq->size = 0; |
807 | |
|
808 | 0 | pq->elements = pq->elements_embedded; |
809 | 0 | } |
810 | | |
811 | | static inline void |
812 | | _pqueue_fini (pqueue_t *pq) |
813 | 0 | { |
814 | 0 | if (pq->elements != pq->elements_embedded) |
815 | 0 | free (pq->elements); |
816 | 0 | } |
817 | | |
818 | | static cairo_status_t |
819 | | _pqueue_grow (pqueue_t *pq) |
820 | 0 | { |
821 | 0 | cairo_bo_event_t **new_elements; |
822 | 0 | pq->max_size *= 2; |
823 | |
|
824 | 0 | if (pq->elements == pq->elements_embedded) { |
825 | 0 | new_elements = _cairo_malloc_ab (pq->max_size, |
826 | 0 | sizeof (cairo_bo_event_t *)); |
827 | 0 | if (unlikely (new_elements == NULL)) |
828 | 0 | return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
829 | | |
830 | 0 | memcpy (new_elements, pq->elements_embedded, |
831 | 0 | sizeof (pq->elements_embedded)); |
832 | 0 | } else { |
833 | 0 | new_elements = _cairo_realloc_ab (pq->elements, |
834 | 0 | pq->max_size, |
835 | 0 | sizeof (cairo_bo_event_t *)); |
836 | 0 | if (unlikely (new_elements == NULL)) |
837 | 0 | return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
838 | 0 | } |
839 | | |
840 | 0 | pq->elements = new_elements; |
841 | 0 | return CAIRO_STATUS_SUCCESS; |
842 | 0 | } |
843 | | |
844 | | static inline cairo_status_t |
845 | | _pqueue_push (pqueue_t *pq, cairo_bo_event_t *event) |
846 | 0 | { |
847 | 0 | cairo_bo_event_t **elements; |
848 | 0 | int i, parent; |
849 | |
|
850 | 0 | if (unlikely (pq->size + 1 == pq->max_size)) { |
851 | 0 | cairo_status_t status; |
852 | |
|
853 | 0 | status = _pqueue_grow (pq); |
854 | 0 | if (unlikely (status)) |
855 | 0 | return status; |
856 | 0 | } |
857 | | |
858 | 0 | elements = pq->elements; |
859 | |
|
860 | 0 | for (i = ++pq->size; |
861 | 0 | i != PQ_FIRST_ENTRY && |
862 | 0 | cairo_bo_event_compare (event, |
863 | 0 | elements[parent = PQ_PARENT_INDEX (i)]) < 0; |
864 | 0 | i = parent) |
865 | 0 | { |
866 | 0 | elements[i] = elements[parent]; |
867 | 0 | } |
868 | |
|
869 | 0 | elements[i] = event; |
870 | |
|
871 | 0 | return CAIRO_STATUS_SUCCESS; |
872 | 0 | } |
873 | | |
874 | | static inline void |
875 | | _pqueue_pop (pqueue_t *pq) |
876 | 0 | { |
877 | 0 | cairo_bo_event_t **elements = pq->elements; |
878 | 0 | cairo_bo_event_t *tail; |
879 | 0 | int child, i; |
880 | |
|
881 | 0 | tail = elements[pq->size--]; |
882 | 0 | if (pq->size == 0) { |
883 | 0 | elements[PQ_FIRST_ENTRY] = NULL; |
884 | 0 | return; |
885 | 0 | } |
886 | | |
887 | 0 | for (i = PQ_FIRST_ENTRY; |
888 | 0 | (child = PQ_LEFT_CHILD_INDEX (i)) <= pq->size; |
889 | 0 | i = child) |
890 | 0 | { |
891 | 0 | if (child != pq->size && |
892 | 0 | cairo_bo_event_compare (elements[child+1], |
893 | 0 | elements[child]) < 0) |
894 | 0 | { |
895 | 0 | child++; |
896 | 0 | } |
897 | |
|
898 | 0 | if (cairo_bo_event_compare (elements[child], tail) >= 0) |
899 | 0 | break; |
900 | | |
901 | 0 | elements[i] = elements[child]; |
902 | 0 | } |
903 | 0 | elements[i] = tail; |
904 | 0 | } |
905 | | |
906 | | static inline cairo_status_t |
907 | | _cairo_bo_event_queue_insert (cairo_bo_event_queue_t *queue, |
908 | | cairo_bo_event_type_t type, |
909 | | cairo_bo_edge_t *e1, |
910 | | cairo_bo_edge_t *e2, |
911 | | const cairo_point_t *point) |
912 | 0 | { |
913 | 0 | cairo_bo_queue_event_t *event; |
914 | |
|
915 | 0 | event = _cairo_freepool_alloc (&queue->pool); |
916 | 0 | if (unlikely (event == NULL)) |
917 | 0 | return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
918 | | |
919 | 0 | event->type = type; |
920 | 0 | event->e1 = e1; |
921 | 0 | event->e2 = e2; |
922 | 0 | event->point = *point; |
923 | |
|
924 | 0 | return _pqueue_push (&queue->pqueue, (cairo_bo_event_t *) event); |
925 | 0 | } |
926 | | |
927 | | static void |
928 | | _cairo_bo_event_queue_delete (cairo_bo_event_queue_t *queue, |
929 | | cairo_bo_event_t *event) |
930 | 0 | { |
931 | 0 | _cairo_freepool_free (&queue->pool, event); |
932 | 0 | } |
933 | | |
934 | | static cairo_bo_event_t * |
935 | | _cairo_bo_event_dequeue (cairo_bo_event_queue_t *event_queue) |
936 | 0 | { |
937 | 0 | cairo_bo_event_t *event, *cmp; |
938 | |
|
939 | 0 | event = event_queue->pqueue.elements[PQ_FIRST_ENTRY]; |
940 | 0 | cmp = *event_queue->start_events; |
941 | 0 | if (event == NULL || |
942 | 0 | (cmp != NULL && cairo_bo_event_compare (cmp, event) < 0)) |
943 | 0 | { |
944 | 0 | event = cmp; |
945 | 0 | event_queue->start_events++; |
946 | 0 | } |
947 | 0 | else |
948 | 0 | { |
949 | 0 | _pqueue_pop (&event_queue->pqueue); |
950 | 0 | } |
951 | |
|
952 | 0 | return event; |
953 | 0 | } |
954 | | |
955 | | CAIRO_COMBSORT_DECLARE (_cairo_bo_event_queue_sort, |
956 | | cairo_bo_event_t *, |
957 | | cairo_bo_event_compare) |
958 | | |
959 | | static void |
960 | | _cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue, |
961 | | cairo_bo_event_t **start_events, |
962 | | int num_events) |
963 | 0 | { |
964 | 0 | _cairo_bo_event_queue_sort (start_events, num_events); |
965 | 0 | start_events[num_events] = NULL; |
966 | |
|
967 | 0 | event_queue->start_events = start_events; |
968 | |
|
969 | 0 | _cairo_freepool_init (&event_queue->pool, |
970 | 0 | sizeof (cairo_bo_queue_event_t)); |
971 | 0 | _pqueue_init (&event_queue->pqueue); |
972 | 0 | event_queue->pqueue.elements[PQ_FIRST_ENTRY] = NULL; |
973 | 0 | } |
974 | | |
975 | | static cairo_status_t |
976 | | _cairo_bo_event_queue_insert_stop (cairo_bo_event_queue_t *event_queue, |
977 | | cairo_bo_edge_t *edge) |
978 | 0 | { |
979 | 0 | cairo_bo_point32_t point; |
980 | |
|
981 | 0 | point.y = edge->edge.bottom; |
982 | 0 | point.x = _line_compute_intersection_x_for_y (&edge->edge.line, |
983 | 0 | point.y); |
984 | 0 | return _cairo_bo_event_queue_insert (event_queue, |
985 | 0 | CAIRO_BO_EVENT_TYPE_STOP, |
986 | 0 | edge, NULL, |
987 | 0 | &point); |
988 | 0 | } |
989 | | |
990 | | static void |
991 | | _cairo_bo_event_queue_fini (cairo_bo_event_queue_t *event_queue) |
992 | 0 | { |
993 | 0 | _pqueue_fini (&event_queue->pqueue); |
994 | 0 | _cairo_freepool_fini (&event_queue->pool); |
995 | 0 | } |
996 | | |
997 | | static inline cairo_status_t |
998 | | _cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_t *event_queue, |
999 | | cairo_bo_edge_t *left, |
1000 | | cairo_bo_edge_t *right) |
1001 | 0 | { |
1002 | 0 | cairo_bo_point32_t intersection; |
1003 | |
|
1004 | 0 | if (_line_equal (&left->edge.line, &right->edge.line)) |
1005 | 0 | return CAIRO_STATUS_SUCCESS; |
1006 | | |
1007 | | /* The names "left" and "right" here are correct descriptions of |
1008 | | * the order of the two edges within the active edge list. So if a |
1009 | | * slope comparison also puts left less than right, then we know |
1010 | | * that the intersection of these two segments has already |
1011 | | * occurred before the current sweep line position. */ |
1012 | 0 | if (_slope_compare (left, right) <= 0) |
1013 | 0 | return CAIRO_STATUS_SUCCESS; |
1014 | | |
1015 | 0 | if (! _cairo_bo_edge_intersect (left, right, &intersection)) |
1016 | 0 | return CAIRO_STATUS_SUCCESS; |
1017 | | |
1018 | 0 | return _cairo_bo_event_queue_insert (event_queue, |
1019 | 0 | CAIRO_BO_EVENT_TYPE_INTERSECTION, |
1020 | 0 | left, right, |
1021 | 0 | &intersection); |
1022 | 0 | } |
1023 | | |
1024 | | static void |
1025 | | _cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line) |
1026 | 0 | { |
1027 | 0 | sweep_line->head = NULL; |
1028 | 0 | sweep_line->current_y = INT32_MIN; |
1029 | 0 | sweep_line->current_edge = NULL; |
1030 | 0 | } |
1031 | | |
1032 | | static cairo_status_t |
1033 | | _cairo_bo_sweep_line_insert (cairo_bo_sweep_line_t *sweep_line, |
1034 | | cairo_bo_edge_t *edge) |
1035 | 0 | { |
1036 | 0 | if (sweep_line->current_edge != NULL) { |
1037 | 0 | cairo_bo_edge_t *prev, *next; |
1038 | 0 | int cmp; |
1039 | |
|
1040 | 0 | cmp = _cairo_bo_sweep_line_compare_edges (sweep_line, |
1041 | 0 | sweep_line->current_edge, |
1042 | 0 | edge); |
1043 | 0 | if (cmp < 0) { |
1044 | 0 | prev = sweep_line->current_edge; |
1045 | 0 | next = prev->next; |
1046 | 0 | while (next != NULL && |
1047 | 0 | _cairo_bo_sweep_line_compare_edges (sweep_line, |
1048 | 0 | next, edge) < 0) |
1049 | 0 | { |
1050 | 0 | prev = next, next = prev->next; |
1051 | 0 | } |
1052 | |
|
1053 | 0 | prev->next = edge; |
1054 | 0 | edge->prev = prev; |
1055 | 0 | edge->next = next; |
1056 | 0 | if (next != NULL) |
1057 | 0 | next->prev = edge; |
1058 | 0 | } else if (cmp > 0) { |
1059 | 0 | next = sweep_line->current_edge; |
1060 | 0 | prev = next->prev; |
1061 | 0 | while (prev != NULL && |
1062 | 0 | _cairo_bo_sweep_line_compare_edges (sweep_line, |
1063 | 0 | prev, edge) > 0) |
1064 | 0 | { |
1065 | 0 | next = prev, prev = next->prev; |
1066 | 0 | } |
1067 | |
|
1068 | 0 | next->prev = edge; |
1069 | 0 | edge->next = next; |
1070 | 0 | edge->prev = prev; |
1071 | 0 | if (prev != NULL) |
1072 | 0 | prev->next = edge; |
1073 | 0 | else |
1074 | 0 | sweep_line->head = edge; |
1075 | 0 | } else { |
1076 | 0 | prev = sweep_line->current_edge; |
1077 | 0 | edge->prev = prev; |
1078 | 0 | edge->next = prev->next; |
1079 | 0 | if (prev->next != NULL) |
1080 | 0 | prev->next->prev = edge; |
1081 | 0 | prev->next = edge; |
1082 | 0 | } |
1083 | 0 | } else { |
1084 | 0 | sweep_line->head = edge; |
1085 | 0 | } |
1086 | |
|
1087 | 0 | sweep_line->current_edge = edge; |
1088 | |
|
1089 | 0 | return CAIRO_STATUS_SUCCESS; |
1090 | 0 | } |
1091 | | |
1092 | | static void |
1093 | | _cairo_bo_sweep_line_delete (cairo_bo_sweep_line_t *sweep_line, |
1094 | | cairo_bo_edge_t *edge) |
1095 | 0 | { |
1096 | 0 | if (edge->prev != NULL) |
1097 | 0 | edge->prev->next = edge->next; |
1098 | 0 | else |
1099 | 0 | sweep_line->head = edge->next; |
1100 | |
|
1101 | 0 | if (edge->next != NULL) |
1102 | 0 | edge->next->prev = edge->prev; |
1103 | |
|
1104 | 0 | if (sweep_line->current_edge == edge) |
1105 | 0 | sweep_line->current_edge = edge->prev ? edge->prev : edge->next; |
1106 | 0 | } |
1107 | | |
1108 | | static void |
1109 | | _cairo_bo_sweep_line_swap (cairo_bo_sweep_line_t *sweep_line, |
1110 | | cairo_bo_edge_t *left, |
1111 | | cairo_bo_edge_t *right) |
1112 | 0 | { |
1113 | 0 | if (left->prev != NULL) |
1114 | 0 | left->prev->next = right; |
1115 | 0 | else |
1116 | 0 | sweep_line->head = right; |
1117 | |
|
1118 | 0 | if (right->next != NULL) |
1119 | 0 | right->next->prev = left; |
1120 | |
|
1121 | 0 | left->next = right->next; |
1122 | 0 | right->next = left; |
1123 | |
|
1124 | 0 | right->prev = left->prev; |
1125 | 0 | left->prev = right; |
1126 | 0 | } |
1127 | | |
1128 | | static inline cairo_bool_t |
1129 | | edges_colinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b) |
1130 | 0 | { |
1131 | 0 | if (_line_equal (&a->edge.line, &b->edge.line)) |
1132 | 0 | return TRUE; |
1133 | | |
1134 | 0 | if (_slope_compare (a, b)) |
1135 | 0 | return FALSE; |
1136 | | |
1137 | | /* The choice of y is not truly arbitrary since we must guarantee that it |
1138 | | * is greater than the start of either line. |
1139 | | */ |
1140 | 0 | if (a->edge.line.p1.y == b->edge.line.p1.y) { |
1141 | 0 | return a->edge.line.p1.x == b->edge.line.p1.x; |
1142 | 0 | } else if (a->edge.line.p2.y == b->edge.line.p2.y) { |
1143 | 0 | return a->edge.line.p2.x == b->edge.line.p2.x; |
1144 | 0 | } else if (a->edge.line.p1.y < b->edge.line.p1.y) { |
1145 | 0 | return edge_compare_for_y_against_x (b, |
1146 | 0 | a->edge.line.p1.y, |
1147 | 0 | a->edge.line.p1.x) == 0; |
1148 | 0 | } else { |
1149 | 0 | return edge_compare_for_y_against_x (a, |
1150 | 0 | b->edge.line.p1.y, |
1151 | 0 | b->edge.line.p1.x) == 0; |
1152 | 0 | } |
1153 | 0 | } |
1154 | | |
1155 | | static void |
1156 | | _cairo_bo_edge_end (cairo_bo_edge_t *left, |
1157 | | int32_t bot, |
1158 | | cairo_polygon_t *polygon) |
1159 | 0 | { |
1160 | 0 | cairo_bo_deferred_t *d = &left->deferred; |
1161 | |
|
1162 | 0 | if (likely (d->top < bot)) { |
1163 | 0 | _cairo_polygon_add_line (polygon, |
1164 | 0 | &left->edge.line, |
1165 | 0 | d->top, bot, |
1166 | 0 | 1); |
1167 | 0 | _cairo_polygon_add_line (polygon, |
1168 | 0 | &d->right->edge.line, |
1169 | 0 | d->top, bot, |
1170 | 0 | -1); |
1171 | 0 | } |
1172 | |
|
1173 | 0 | d->right = NULL; |
1174 | 0 | } |
1175 | | |
1176 | | |
1177 | | static inline void |
1178 | | _cairo_bo_edge_start_or_continue (cairo_bo_edge_t *left, |
1179 | | cairo_bo_edge_t *right, |
1180 | | int top, |
1181 | | cairo_polygon_t *polygon) |
1182 | 0 | { |
1183 | 0 | if (left->deferred.right == right) |
1184 | 0 | return; |
1185 | | |
1186 | 0 | if (left->deferred.right != NULL) { |
1187 | 0 | if (right != NULL && edges_colinear (left->deferred.right, right)) |
1188 | 0 | { |
1189 | | /* continuation on right, so just swap edges */ |
1190 | 0 | left->deferred.right = right; |
1191 | 0 | return; |
1192 | 0 | } |
1193 | | |
1194 | 0 | _cairo_bo_edge_end (left, top, polygon); |
1195 | 0 | } |
1196 | | |
1197 | 0 | if (right != NULL && ! edges_colinear (left, right)) { |
1198 | 0 | left->deferred.top = top; |
1199 | 0 | left->deferred.right = right; |
1200 | 0 | } |
1201 | 0 | } |
1202 | | |
1203 | | static inline void |
1204 | | _active_edges_to_polygon (cairo_bo_edge_t *left, |
1205 | | int32_t top, |
1206 | | cairo_fill_rule_t fill_rule, |
1207 | | cairo_polygon_t *polygon) |
1208 | 0 | { |
1209 | 0 | cairo_bo_edge_t *right; |
1210 | 0 | unsigned int mask; |
1211 | |
|
1212 | 0 | if (fill_rule == CAIRO_FILL_RULE_WINDING) |
1213 | 0 | mask = ~0; |
1214 | 0 | else |
1215 | 0 | mask = 1; |
1216 | |
|
1217 | 0 | while (left != NULL) { |
1218 | 0 | int in_out = left->edge.dir; |
1219 | |
|
1220 | 0 | right = left->next; |
1221 | 0 | if (left->deferred.right == NULL) { |
1222 | 0 | while (right != NULL && right->deferred.right == NULL) |
1223 | 0 | right = right->next; |
1224 | |
|
1225 | 0 | if (right != NULL && edges_colinear (left, right)) { |
1226 | | /* continuation on left */ |
1227 | 0 | left->deferred = right->deferred; |
1228 | 0 | right->deferred.right = NULL; |
1229 | 0 | } |
1230 | 0 | } |
1231 | |
|
1232 | 0 | right = left->next; |
1233 | 0 | while (right != NULL) { |
1234 | 0 | if (right->deferred.right != NULL) |
1235 | 0 | _cairo_bo_edge_end (right, top, polygon); |
1236 | |
|
1237 | 0 | in_out += right->edge.dir; |
1238 | 0 | if ((in_out & mask) == 0) { |
1239 | | /* skip co-linear edges */ |
1240 | 0 | if (right->next == NULL || !edges_colinear (right, right->next)) |
1241 | 0 | break; |
1242 | 0 | } |
1243 | | |
1244 | 0 | right = right->next; |
1245 | 0 | } |
1246 | |
|
1247 | 0 | _cairo_bo_edge_start_or_continue (left, right, top, polygon); |
1248 | |
|
1249 | 0 | left = right; |
1250 | 0 | if (left != NULL) |
1251 | 0 | left = left->next; |
1252 | 0 | } |
1253 | 0 | } |
1254 | | |
1255 | | |
1256 | | static cairo_status_t |
1257 | | _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t **start_events, |
1258 | | int num_events, |
1259 | | cairo_fill_rule_t fill_rule, |
1260 | | cairo_polygon_t *polygon) |
1261 | 0 | { |
1262 | 0 | cairo_status_t status = CAIRO_STATUS_SUCCESS; /* silence compiler */ |
1263 | 0 | cairo_bo_event_queue_t event_queue; |
1264 | 0 | cairo_bo_sweep_line_t sweep_line; |
1265 | 0 | cairo_bo_event_t *event; |
1266 | 0 | cairo_bo_edge_t *left, *right; |
1267 | 0 | cairo_bo_edge_t *e1, *e2; |
1268 | |
|
1269 | 0 | _cairo_bo_event_queue_init (&event_queue, start_events, num_events); |
1270 | 0 | _cairo_bo_sweep_line_init (&sweep_line); |
1271 | |
|
1272 | 0 | while ((event = _cairo_bo_event_dequeue (&event_queue))) { |
1273 | 0 | if (event->point.y != sweep_line.current_y) { |
1274 | 0 | _active_edges_to_polygon (sweep_line.head, |
1275 | 0 | sweep_line.current_y, |
1276 | 0 | fill_rule, polygon); |
1277 | |
|
1278 | 0 | sweep_line.current_y = event->point.y; |
1279 | 0 | } |
1280 | |
|
1281 | 0 | switch (event->type) { |
1282 | 0 | case CAIRO_BO_EVENT_TYPE_START: |
1283 | 0 | e1 = &((cairo_bo_start_event_t *) event)->edge; |
1284 | |
|
1285 | 0 | status = _cairo_bo_sweep_line_insert (&sweep_line, e1); |
1286 | 0 | if (unlikely (status)) |
1287 | 0 | goto unwind; |
1288 | | |
1289 | 0 | status = _cairo_bo_event_queue_insert_stop (&event_queue, e1); |
1290 | 0 | if (unlikely (status)) |
1291 | 0 | goto unwind; |
1292 | | |
1293 | 0 | left = e1->prev; |
1294 | 0 | right = e1->next; |
1295 | |
|
1296 | 0 | if (left != NULL) { |
1297 | 0 | status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, e1); |
1298 | 0 | if (unlikely (status)) |
1299 | 0 | goto unwind; |
1300 | 0 | } |
1301 | | |
1302 | 0 | if (right != NULL) { |
1303 | 0 | status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right); |
1304 | 0 | if (unlikely (status)) |
1305 | 0 | goto unwind; |
1306 | 0 | } |
1307 | | |
1308 | 0 | break; |
1309 | | |
1310 | 0 | case CAIRO_BO_EVENT_TYPE_STOP: |
1311 | 0 | e1 = ((cairo_bo_queue_event_t *) event)->e1; |
1312 | 0 | _cairo_bo_event_queue_delete (&event_queue, event); |
1313 | |
|
1314 | 0 | left = e1->prev; |
1315 | 0 | right = e1->next; |
1316 | |
|
1317 | 0 | _cairo_bo_sweep_line_delete (&sweep_line, e1); |
1318 | |
|
1319 | 0 | if (e1->deferred.right != NULL) |
1320 | 0 | _cairo_bo_edge_end (e1, e1->edge.bottom, polygon); |
1321 | |
|
1322 | 0 | if (left != NULL && right != NULL) { |
1323 | 0 | status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right); |
1324 | 0 | if (unlikely (status)) |
1325 | 0 | goto unwind; |
1326 | 0 | } |
1327 | | |
1328 | 0 | break; |
1329 | | |
1330 | 0 | case CAIRO_BO_EVENT_TYPE_INTERSECTION: |
1331 | 0 | e1 = ((cairo_bo_queue_event_t *) event)->e1; |
1332 | 0 | e2 = ((cairo_bo_queue_event_t *) event)->e2; |
1333 | 0 | _cairo_bo_event_queue_delete (&event_queue, event); |
1334 | | |
1335 | | /* skip this intersection if its edges are not adjacent */ |
1336 | 0 | if (e2 != e1->next) |
1337 | 0 | break; |
1338 | | |
1339 | 0 | left = e1->prev; |
1340 | 0 | right = e2->next; |
1341 | |
|
1342 | 0 | _cairo_bo_sweep_line_swap (&sweep_line, e1, e2); |
1343 | | |
1344 | | /* after the swap e2 is left of e1 */ |
1345 | |
|
1346 | 0 | if (left != NULL) { |
1347 | 0 | status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, e2); |
1348 | 0 | if (unlikely (status)) |
1349 | 0 | goto unwind; |
1350 | 0 | } |
1351 | | |
1352 | 0 | if (right != NULL) { |
1353 | 0 | status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, e1, right); |
1354 | 0 | if (unlikely (status)) |
1355 | 0 | goto unwind; |
1356 | 0 | } |
1357 | | |
1358 | 0 | break; |
1359 | 0 | } |
1360 | 0 | } |
1361 | | |
1362 | 0 | unwind: |
1363 | 0 | _cairo_bo_event_queue_fini (&event_queue); |
1364 | |
|
1365 | 0 | return status; |
1366 | 0 | } |
1367 | | |
1368 | | cairo_status_t |
1369 | | _cairo_polygon_reduce (cairo_polygon_t *polygon, |
1370 | | cairo_fill_rule_t fill_rule) |
1371 | 0 | { |
1372 | 0 | cairo_status_t status; |
1373 | 0 | cairo_bo_start_event_t stack_events[CAIRO_STACK_ARRAY_LENGTH (cairo_bo_start_event_t)]; |
1374 | 0 | cairo_bo_start_event_t *events; |
1375 | 0 | cairo_bo_event_t *stack_event_ptrs[ARRAY_LENGTH (stack_events) + 1]; |
1376 | 0 | cairo_bo_event_t **event_ptrs; |
1377 | 0 | int num_limits; |
1378 | 0 | int num_events; |
1379 | 0 | int i; |
1380 | |
|
1381 | 0 | num_events = polygon->num_edges; |
1382 | 0 | if (unlikely (0 == num_events)) |
1383 | 0 | return CAIRO_STATUS_SUCCESS; |
1384 | | |
1385 | 0 | if (DEBUG_POLYGON) { |
1386 | 0 | FILE *file = fopen ("reduce_in.txt", "w"); |
1387 | 0 | _cairo_debug_print_polygon (file, polygon); |
1388 | 0 | fclose (file); |
1389 | 0 | } |
1390 | |
|
1391 | 0 | events = stack_events; |
1392 | 0 | event_ptrs = stack_event_ptrs; |
1393 | 0 | if (num_events > ARRAY_LENGTH (stack_events)) { |
1394 | 0 | events = _cairo_malloc_ab_plus_c (num_events, |
1395 | 0 | sizeof (cairo_bo_start_event_t) + |
1396 | 0 | sizeof (cairo_bo_event_t *), |
1397 | 0 | sizeof (cairo_bo_event_t *)); |
1398 | 0 | if (unlikely (events == NULL)) |
1399 | 0 | return _cairo_error (CAIRO_STATUS_NO_MEMORY); |
1400 | | |
1401 | 0 | event_ptrs = (cairo_bo_event_t **) (events + num_events); |
1402 | 0 | } |
1403 | | |
1404 | 0 | for (i = 0; i < num_events; i++) { |
1405 | 0 | event_ptrs[i] = (cairo_bo_event_t *) &events[i]; |
1406 | |
|
1407 | 0 | events[i].type = CAIRO_BO_EVENT_TYPE_START; |
1408 | 0 | events[i].point.y = polygon->edges[i].top; |
1409 | 0 | events[i].point.x = |
1410 | 0 | _line_compute_intersection_x_for_y (&polygon->edges[i].line, |
1411 | 0 | events[i].point.y); |
1412 | |
|
1413 | 0 | events[i].edge.edge = polygon->edges[i]; |
1414 | 0 | events[i].edge.deferred.right = NULL; |
1415 | 0 | events[i].edge.prev = NULL; |
1416 | 0 | events[i].edge.next = NULL; |
1417 | 0 | } |
1418 | |
|
1419 | 0 | num_limits = polygon->num_limits; polygon->num_limits = 0; |
1420 | 0 | polygon->num_edges = 0; |
1421 | |
|
1422 | 0 | status = _cairo_bentley_ottmann_tessellate_bo_edges (event_ptrs, |
1423 | 0 | num_events, |
1424 | 0 | fill_rule, |
1425 | 0 | polygon); |
1426 | 0 | polygon->num_limits = num_limits; |
1427 | |
|
1428 | 0 | if (events != stack_events) |
1429 | 0 | free (events); |
1430 | |
|
1431 | 0 | if (DEBUG_POLYGON) { |
1432 | 0 | FILE *file = fopen ("reduce_out.txt", "w"); |
1433 | 0 | _cairo_debug_print_polygon (file, polygon); |
1434 | 0 | fclose (file); |
1435 | 0 | } |
1436 | |
|
1437 | 0 | return status; |
1438 | 0 | } |