cairo_status_t _cairo_path_fixed_fill_to_polygon (const cairo_path_fixed_t *path, double tolerance, cairo_polygon_t *polygon) { cairo_filler_t filler; cairo_status_t status; _cairo_filler_init (&filler, tolerance, polygon); status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, _cairo_filler_move_to, _cairo_filler_line_to, _cairo_filler_curve_to, _cairo_filler_close_path, &filler); if (unlikely (status)) return status; _cairo_polygon_close (polygon); status = _cairo_polygon_status (polygon); _cairo_filler_fini (&filler); return status; }
/* Compute outline of a given spline using the pen. The trapezoids needed to fill that outline will be added to traps */ cairo_status_t _cairo_pen_stroke_spline (cairo_pen_t *pen, cairo_spline_t *spline, double tolerance, cairo_traps_t *traps) { cairo_status_t status; cairo_polygon_t polygon; /* If the line width is so small that the pen is reduced to a single point, then we have nothing to do. */ if (pen->num_vertices <= 1) return CAIRO_STATUS_SUCCESS; _cairo_polygon_init (&polygon); status = _cairo_spline_decompose (spline, tolerance); if (status) return status; status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_FORWARD, &polygon); if (status) return status; status = _cairo_pen_stroke_spline_half (pen, spline, CAIRO_DIRECTION_REVERSE, &polygon); if (status) return status; _cairo_polygon_close (&polygon); _cairo_traps_tessellate_polygon (traps, &polygon, CAIRO_FILL_RULE_WINDING); _cairo_polygon_fini (&polygon); return CAIRO_STATUS_SUCCESS; }
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_close_path (void *closure) { cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; _cairo_polygon_close (polygon); return _cairo_polygon_status (polygon); }
static cairo_status_t _cairo_filler_close_path (void *closure) { cairo_status_t status; cairo_filler_t *filler = closure; cairo_polygon_t *polygon = &filler->polygon; status = _cairo_polygon_close (polygon); if (status) return status; return CAIRO_STATUS_SUCCESS; }
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; }
cairo_status_t _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_traps_t *traps) { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_filler_t filler; /* Before we do anything else, we use a special-case filler for * a device-axis aligned rectangle if possible. */ status = _cairo_path_fixed_fill_rectangle (path, traps); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; _cairo_filler_init (&filler, tolerance, traps); status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, _cairo_filler_move_to, _cairo_filler_line_to, _cairo_filler_curve_to, _cairo_filler_close_path, &filler); if (status) goto BAIL; _cairo_polygon_close (&filler.polygon); status = _cairo_polygon_status (&filler.polygon); if (status) goto BAIL; status = _cairo_bentley_ottmann_tessellate_polygon (filler.traps, &filler.polygon, fill_rule); if (status) goto BAIL; BAIL: _cairo_filler_fini (&filler); return status; }
cairo_status_t _cairo_path_fixed_fill_to_traps (cairo_path_fixed_t *path, cairo_fill_rule_t fill_rule, double tolerance, cairo_traps_t *traps) { cairo_status_t status = CAIRO_STATUS_SUCCESS; cairo_filler_t filler; _cairo_filler_init (&filler, tolerance, traps); status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, _cairo_filler_move_to, _cairo_filler_line_to, _cairo_filler_curve_to, _cairo_filler_close_path, &filler); if (status) goto BAIL; status = _cairo_polygon_close (&filler.polygon); if (status) goto BAIL; status = _cairo_traps_tessellate_polygon (filler.traps, &filler.polygon, fill_rule); if (status) goto BAIL; BAIL: _cairo_filler_fini (&filler); return status; }
static cairo_status_t _cairo_filler_close_path (void *closure) { cairo_filler_t *filler = closure; return _cairo_polygon_close (filler->polygon); }
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; } }