cairo_status_t _cairo_path_fixed_stroke_dashed_to_polygon (const cairo_path_fixed_t *path, const cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, const cairo_matrix_t *ctm_inverse, double tolerance, cairo_polygon_t *polygon) { cairo_stroker_t stroker; cairo_status_t status; status = _cairo_stroker_init (&stroker, stroke_style, ctm, ctm_inverse, tolerance); if (unlikely (status)) return status; stroker.add_external_edge = _cairo_polygon_add_external_edge, stroker.closure = polygon; if (polygon->num_limits) _cairo_stroker_limit (&stroker, path, polygon->limits, polygon->num_limits); status = _cairo_path_fixed_interpret (path, _cairo_stroker_move_to, stroker.dash.dashed ? _cairo_stroker_line_to_dashed : _cairo_stroker_line_to, _cairo_stroker_curve_to, _cairo_stroker_close_path, &stroker); if (unlikely (status)) goto BAIL; /* Cap the start and end of the final sub path as needed */ status = _cairo_stroker_add_caps (&stroker); BAIL: _cairo_stroker_fini (&stroker); return status; }
static cairo_status_t _cairo_stroker_init (cairo_stroker_t *stroker, const cairo_path_fixed_t *path, const cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, const cairo_matrix_t *ctm_inverse, double tolerance, const cairo_box_t *limits, int num_limits) { cairo_status_t status; stroker->style = *stroke_style; stroker->ctm = ctm; stroker->ctm_inverse = ctm_inverse; stroker->tolerance = tolerance; stroker->ctm_determinant = _cairo_matrix_compute_determinant (stroker->ctm); stroker->ctm_det_positive = stroker->ctm_determinant >= 0.0; status = _cairo_pen_init (&stroker->pen, stroke_style->line_width / 2.0, tolerance, ctm); if (unlikely (status)) return status; stroker->has_current_face = FALSE; stroker->has_first_face = FALSE; stroker->has_initial_sub_path = FALSE; _cairo_stroker_dash_init (&stroker->dash, stroke_style); stroker->add_external_edge = NULL; stroker->has_bounds = FALSE; if (num_limits) _cairo_stroker_limit (stroker, path, limits, num_limits); return CAIRO_STATUS_SUCCESS; }