Пример #1
0
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;
}
Пример #2
0
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);
}
Пример #3
0
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;
    }
}