static void _cairo_polygon_add_edge (cairo_polygon_t *polygon, const cairo_point_t *p1, const cairo_point_t *p2, int dir) { /* drop horizontal edges */ if (p1->y == p2->y) return; if (p1->y > p2->y) { const cairo_point_t *t; t = p1, p1 = p2, p2 = t; dir = -dir; } if (polygon->num_limits) { if (p2->y <= polygon->limit.p1.y) return; if (p1->y >= polygon->limit.p2.y) return; _add_clipped_edge (polygon, p1, p2, p1->y, p2->y, dir); } else _add_edge (polygon, p1, p2, p1->y, p2->y, dir); }
cairo_status_t _cairo_polygon_add_line (cairo_polygon_t *polygon, const cairo_line_t *line, int top, int bottom, int dir) { /* drop horizontal edges */ if (line->p1.y == line->p2.y) return CAIRO_STATUS_SUCCESS; if (bottom <= top) return CAIRO_STATUS_SUCCESS; if (polygon->num_limits) { if (line->p2.y <= polygon->limit.p1.y) return CAIRO_STATUS_SUCCESS; if (line->p1.y >= polygon->limit.p2.y) return CAIRO_STATUS_SUCCESS; _add_clipped_edge (polygon, &line->p1, &line->p2, top, bottom, dir); } else _add_edge (polygon, &line->p1, &line->p2, top, bottom, dir); return polygon->status; }
static void _add_edge (struct reduce *r, const cairo_point_t *p1, const cairo_point_t *p2) { int top, bottom; int top_y, bot_y; int n; if (p1->y < p2->y) { top = p1->y; bottom = p2->y; } else { top = p2->y; bottom = p1->y; } if (bottom < r->limit.p1.y || top > r->limit.p2.y) return; if (p1->x > p2->x) { const cairo_point_t *t = p1; p1 = p2; p2 = t; } if (p2->x <= r->limit.p1.x || p1->x >= r->limit.p2.x) return; for (n = 0; n < r->clip->num_boxes; n++) { const cairo_box_t *limits = &r->clip->boxes[n]; if (bottom < limits->p1.y || top > limits->p2.y) continue; if (p2->x <= limits->p1.x || p1->x >= limits->p2.x) continue; if (p1->x >= limits->p1.x && p2->x <= limits->p1.x) { top_y = top; bot_y = bottom; } else { int p1_y, p2_y; p1_y = _cairo_edge_compute_intersection_y_for_x (p1, p2, limits->p1.x); p2_y = _cairo_edge_compute_intersection_y_for_x (p1, p2, limits->p2.x); if (p1_y < p2_y) { top_y = p1_y; bot_y = p2_y; } else { top_y = p2_y; bot_y = p1_y; } if (top_y < top) top_y = top; if (bot_y > bottom) bot_y = bottom; } if (top_y < limits->p1.y) top_y = limits->p1.y; if (bot_y > limits->p2.y) bot_y = limits->p2.y; if (bot_y > top_y) _add_clipped_edge (r, p1, p2, top_y, bot_y); } }