Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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. }
  1533.