static int _cairo_bo_sweep_line_compare_edges (cairo_bo_sweep_line_t *sweep_line, const cairo_bo_edge_t *a, const cairo_bo_edge_t *b) { int cmp; /* compare the edges if not identical */ if (! _line_equal (&a->edge.line, &b->edge.line)) { cmp = edges_compare_x_for_y (a, b, sweep_line->current_y); if (cmp) return cmp; /* The two edges intersect exactly at y, so fall back on slope * comparison. We know that this compare_edges function will be * called only when starting a new edge, (not when stopping an * edge), so we don't have to worry about conditionally inverting * the sense of _slope_compare. */ cmp = _slope_compare (a, b); if (cmp) return cmp; } /* We've got two collinear edges now. */ return b->edge.bottom - a->edge.bottom; }
static inline cairo_status_t event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_t *event_queue, cairo_bo_edge_t *left, cairo_bo_edge_t *right) { cairo_bo_intersect_point_t intersection; if (_line_equal (&left->edge.line, &right->edge.line)) return CAIRO_STATUS_SUCCESS; /* The names "left" and "right" here are correct descriptions of * the order of the two edges within the active edge list. So if a * slope comparison also puts left less than right, then we know * that the intersection of these two segments has already * occurred before the current sweep line position. */ if (_slope_compare (left, right) <= 0) return CAIRO_STATUS_SUCCESS; if (! _cairo_bo_edge_intersect (left, right, &intersection)) return CAIRO_STATUS_SUCCESS; return _cairo_bo_event_queue_insert (event_queue, CAIRO_BO_EVENT_TYPE_INTERSECTION, left, right, &intersection); }
static inline cairo_bool_t edges_colinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b) { if (_line_equal (&a->edge.line, &b->edge.line)) return TRUE; if (_slope_compare (a, b)) return FALSE; /* The choice of y is not truly arbitrary since we must guarantee that it * is greater than the start of either line. */ if (a->edge.line.p1.y == b->edge.line.p1.y) { return a->edge.line.p1.x == b->edge.line.p1.x; } else if (a->edge.line.p2.y == b->edge.line.p2.y) { return a->edge.line.p2.x == b->edge.line.p2.x; } else if (a->edge.line.p1.y < b->edge.line.p1.y) { return edge_compare_for_y_against_x (b, a->edge.line.p1.y, a->edge.line.p1.x) == 0; } else { return edge_compare_for_y_against_x (a, b->edge.line.p1.y, b->edge.line.p1.x) == 0; } }