static void _cairo_polygon_add_edge (cairo_polygon_t *polygon, const cairo_point_t *p1, const cairo_point_t *p2) { cairo_edge_t *edge; /* drop horizontal edges */ if (p1->y == p2->y) goto DONE; if (polygon->num_edges == polygon->edges_size) { if (! _cairo_polygon_grow (polygon)) return; } edge = &polygon->edges[polygon->num_edges++]; if (p1->y < p2->y) { edge->edge.p1 = *p1; edge->edge.p2 = *p2; edge->clockWise = 1; } else { edge->edge.p1 = *p2; edge->edge.p2 = *p1; edge->clockWise = 0; } DONE: _cairo_polygon_move_to (polygon, p2); }
void _cairo_polygon_line_to (cairo_polygon_t *polygon, const cairo_point_t *point) { if (polygon->has_current_point) _cairo_polygon_add_edge (polygon, &polygon->current_point, point); else _cairo_polygon_move_to (polygon, point); }
static cairo_status_t _cairo_filler_move_to (void *closure, const cairo_point_t *point) { cairo_filler_t *filler = closure; cairo_polygon_t *polygon = filler->polygon; _cairo_polygon_close (polygon); return _cairo_polygon_move_to (polygon, point); }
static cairo_status_t _cairo_filler_move_to (void *closure, cairo_point_t *point) { cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; _cairo_polygon_close (polygon); _cairo_polygon_move_to (polygon, point); filler->current_point = *point; return _cairo_polygon_status (&filler->polygon); }
static cairo_status_t _cairo_filler_move_to (void *closure, cairo_point_t *point) { cairo_status_t status; cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; status = _cairo_polygon_close (polygon); if (status) return status; status = _cairo_polygon_move_to (polygon, point); if (status) return status; filler->current_point = *point; return CAIRO_STATUS_SUCCESS; }
static cairo_status_t _cairo_stroker_add_cap (cairo_stroker_t *stroker, cairo_stroke_face_t *f) { cairo_status_t status; if (stroker->style->line_cap == CAIRO_LINE_CAP_BUTT) return CAIRO_STATUS_SUCCESS; switch (stroker->style->line_cap) { case CAIRO_LINE_CAP_ROUND: { int i; int start, stop; cairo_slope_t slope; cairo_point_t tri[3]; cairo_pen_t *pen = &stroker->pen; slope = f->dev_vector; start = _cairo_pen_find_active_cw_vertex_index (pen, &slope); slope.dx = -slope.dx; slope.dy = -slope.dy; stop = _cairo_pen_find_active_cw_vertex_index (pen, &slope); tri[0] = f->point; tri[1] = f->cw; for (i=start; i != stop; i = (i+1) % pen->num_vertices) { tri[2] = f->point; _translate_point (&tri[2], &pen->vertices[i].point); status = _cairo_traps_tessellate_triangle (stroker->traps, tri); if (unlikely (status)) return status; tri[1] = tri[2]; } tri[2] = f->ccw; return _cairo_traps_tessellate_triangle (stroker->traps, tri); } case CAIRO_LINE_CAP_SQUARE: { double dx, dy; cairo_slope_t fvector; cairo_point_t occw, ocw; cairo_polygon_t polygon; dx = f->usr_vector.x; dy = f->usr_vector.y; dx *= stroker->style->line_width / 2.0; dy *= stroker->style->line_width / 2.0; cairo_matrix_transform_distance (stroker->ctm, &dx, &dy); fvector.dx = _cairo_fixed_from_double (dx); fvector.dy = _cairo_fixed_from_double (dy); occw.x = f->ccw.x + fvector.dx; occw.y = f->ccw.y + fvector.dy; ocw.x = f->cw.x + fvector.dx; ocw.y = f->cw.y + fvector.dy; _cairo_polygon_init (&polygon); _cairo_polygon_move_to (&polygon, &f->cw); _cairo_polygon_line_to (&polygon, &ocw); _cairo_polygon_line_to (&polygon, &occw); _cairo_polygon_line_to (&polygon, &f->ccw); _cairo_polygon_close (&polygon); status = _cairo_polygon_status (&polygon); if (status == CAIRO_STATUS_SUCCESS) { status = _cairo_bentley_ottmann_tessellate_polygon (stroker->traps, &polygon, CAIRO_FILL_RULE_WINDING); } _cairo_polygon_fini (&polygon); return status; } case CAIRO_LINE_CAP_BUTT: default: return CAIRO_STATUS_SUCCESS; } }