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