| /* |
| * Copyright 2022 Rive |
| */ |
| |
| #ifndef _RIVE_RAW_PATH_UTILS_HPP_ |
| #define _RIVE_RAW_PATH_UTILS_HPP_ |
| |
| #include "rive/math/vec2d.hpp" |
| |
| namespace rive { |
| static inline Vec2D two(Vec2D v) { return v + v; } |
| |
| // Caches the setup to evaluate a quadratic bezier. Useful if you |
| // want to evaluate the save curve at multiple t values. |
| // clang-format off |
| struct EvalQuad { |
| const Vec2D a, b, c; // at^2 + bt + c |
| |
| // pts are the 3 quadratic bezier control points |
| EvalQuad(const Vec2D pts[3]) : |
| a(pts[0] - two(pts[1]) + pts[2]), |
| b(two(pts[1] - pts[0])), |
| c(pts[0]) {} |
| |
| Vec2D operator()(float t) const { return (a * t + b) * t + c; } |
| }; |
| // clang-format on |
| |
| // Caches the setup to evaluate a cubic bezier. Useful if you |
| // want to evaluate the save curve at multiple t values. |
| struct EvalCubic { |
| const Vec2D a, b, c, d; // at^3 + bt^2 + ct + d |
| |
| // pts are the 4 cubic bezier control points |
| EvalCubic(const Vec2D pts[4]) : |
| a(pts[3] + 3 * (pts[1] - pts[2]) - pts[0]), |
| b(3 * (pts[2] - two(pts[1]) + pts[0])), |
| c(3 * (pts[1] - pts[0])), |
| d(pts[0]) {} |
| |
| Vec2D operator()(float t) const { return ((a * t + b) * t + c) * t + d; } |
| }; |
| |
| // These compute the number of line segments need to apprixmate the bezier |
| // curve to the specified inverse-tolerance. We take inverse since we need |
| // to divide by the "tolerance", and we want to save the cost of the divide. |
| // |
| // At "standard" tolerance might be 0.5 (half a pixel error), so the caller |
| // would base 2.0 as its inverse. |
| // |
| // These always return at least 1 |
| // |
| |
| extern int computeApproximatingQuadLineSegments(const Vec2D bezier[3], float invTolerance); |
| |
| extern int computeApproximatingCubicLineSegments(const Vec2D bezier[4], float invTolerance); |
| |
| // Extract a subcurve from the curve (given start and end t-values) |
| |
| extern void quad_subdivide(const Vec2D src[3], float t, Vec2D dst[5]); |
| extern void cubic_subdivide(const Vec2D src[4], float t, Vec2D dst[7]); |
| |
| extern void line_extract(const Vec2D src[2], float startT, float endT, Vec2D dst[2]); |
| extern void quad_extract(const Vec2D src[3], float startT, float endT, Vec2D dst[3]); |
| extern void cubic_extract(const Vec2D src[4], float startT, float endT, Vec2D dst[4]); |
| |
| } // namespace rive |
| |
| #endif |