cairo_status_t _cairo_path_fixed_stroke_to_traps (cairo_path_fixed_t *path, cairo_stroke_style_t *stroke_style, const cairo_matrix_t *ctm, const cairo_matrix_t *ctm_inverse, double tolerance, cairo_traps_t *traps) { cairo_status_t status; cairo_stroker_t stroker; /* Before we do anything else, we attempt the rectilinear * stroker. It's careful to generate trapezoids that align to * device-pixel boundaries when possible. Many backends can render * those much faster than non-aligned trapezoids, (by using clip * regions, etc.) */ status = _cairo_path_fixed_stroke_rectilinear (path, stroke_style, ctm, traps); if (status != CAIRO_INT_STATUS_UNSUPPORTED) return status; status = _cairo_stroker_init (&stroker, stroke_style, ctm, ctm_inverse, tolerance, traps); if (unlikely (status)) return status; if (stroker.style->dash) status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, _cairo_stroker_move_to_dashed, _cairo_stroker_line_to_dashed, _cairo_stroker_curve_to_dashed, _cairo_stroker_close_path, &stroker); else status = _cairo_path_fixed_interpret (path, CAIRO_DIRECTION_FORWARD, _cairo_stroker_move_to, _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; }
cairo_status_t _cairo_path_fixed_stroke_to_shaper (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_status_t (*add_triangle) (void *closure, const cairo_point_t triangle[3]), cairo_status_t (*add_triangle_fan) (void *closure, const cairo_point_t *midpt, const cairo_point_t *points, int npoints), cairo_status_t (*add_convex_quad) (void *closure, const cairo_point_t quad[4]), void *closure) { cairo_stroker_t stroker; cairo_status_t status; status = _cairo_stroker_init (&stroker, path, stroke_style, ctm, ctm_inverse, tolerance, NULL, 0); if (unlikely (status)) return status; stroker.add_triangle = add_triangle; stroker.add_triangle_fan = add_triangle_fan; stroker.add_convex_quad = add_convex_quad; stroker.closure = closure; 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; }
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; }