static inline void edges_start_or_continue (cairo_bo_edge_t *left, cairo_bo_edge_t *right, int top, cairo_polygon_t *polygon) { assert (right->deferred.other == NULL); if (left->deferred.other == right) return; if (left->deferred.other != NULL) { if (right != NULL && edges_colinear (left->deferred.other, right)) { cairo_bo_edge_t *old = left->deferred.other; /* continuation on right, extend right to cover both */ assert (old->deferred.other == NULL); assert (old->edge.line.p2.y > old->edge.line.p1.y); if (old->edge.line.p1.y < right->edge.line.p1.y) right->edge.line.p1 = old->edge.line.p1; if (old->edge.line.p2.y > right->edge.line.p2.y) right->edge.line.p2 = old->edge.line.p2; left->deferred.other = right; return; } edges_end (left, top, polygon); } if (right != NULL && ! edges_colinear (left, right)) { left->deferred.top = top; left->deferred.other = right; } }
static inline void _cairo_bo_edge_start_or_continue (cairo_bo_edge_t *left, cairo_bo_edge_t *right, int top, cairo_polygon_t *polygon) { if (left->deferred.right == right) return; if (left->deferred.right != NULL) { if (right != NULL && edges_colinear (left->deferred.right, right)) { /* continuation on right, so just swap edges */ left->deferred.right = right; return; } _cairo_bo_edge_end (left, top, polygon); } if (right != NULL && ! edges_colinear (left, right)) { left->deferred.top = top; left->deferred.right = right; } }
static inline void _active_edges_to_polygon (cairo_bo_edge_t *left, int32_t top, cairo_fill_rule_t fill_rule, cairo_polygon_t *polygon) { cairo_bo_edge_t *right; unsigned int mask; if (fill_rule == CAIRO_FILL_RULE_WINDING) mask = ~0; else mask = 1; while (left != NULL) { int in_out = left->edge.dir; right = left->next; if (left->deferred.right == NULL) { while (right != NULL && right->deferred.right == NULL) right = right->next; if (right != NULL && edges_colinear (left, right)) { /* continuation on left */ left->deferred = right->deferred; right->deferred.right = NULL; } } right = left->next; while (right != NULL) { if (right->deferred.right != NULL) _cairo_bo_edge_end (right, top, polygon); in_out += right->edge.dir; if ((in_out & mask) == 0) { /* skip co-linear edges */ if (right->next == NULL || !edges_colinear (right, right->next)) break; } right = right->next; } _cairo_bo_edge_start_or_continue (left, right, top, polygon); left = right; if (left != NULL) left = left->next; } }
static inline void active_edges (cairo_bo_edge_t *left, int32_t top, cairo_polygon_t *polygon) { cairo_bo_edge_t *right; int winding[2] = {0, 0}; /* Yes, this is naive. Consider this a placeholder. */ while (left != NULL) { assert (is_zero (winding)); do { winding[left->a_or_b] += left->edge.dir; if (! is_zero (winding)) break; if unlikely ((left->deferred.other)) edges_end (left, top, polygon); left = left->next; if (! left) return; } while (1); right = left->next; do { if unlikely ((right->deferred.other)) edges_end (right, top, polygon); winding[right->a_or_b] += right->edge.dir; if (is_zero (winding)) { if (right->next == NULL || ! edges_colinear (right, right->next)) break; } right = right->next; } while (1); edges_start_or_continue (left, right, top, polygon); left = right->next; } }