summaryrefslogtreecommitdiff
path: root/gsk/gskspline.c
diff options
context:
space:
mode:
Diffstat (limited to 'gsk/gskspline.c')
-rw-r--r--gsk/gskspline.c378
1 files changed, 0 insertions, 378 deletions
diff --git a/gsk/gskspline.c b/gsk/gskspline.c
index 711226229c..5590c7f7e0 100644
--- a/gsk/gskspline.c
+++ b/gsk/gskspline.c
@@ -25,384 +25,6 @@
#include <math.h>
-#define MIN_PROGRESS (1/1024.f)
-
-typedef struct
-{
- graphene_point_t last_point;
- float last_progress;
- GskSplineAddPointFunc func;
- gpointer user_data;
-} GskSplineDecompose;
-
-static void
-gsk_spline_decompose_add_point (GskSplineDecompose *decomp,
- const graphene_point_t *pt,
- float progress)
-{
- if (graphene_point_equal (&decomp->last_point, pt))
- return;
-
- decomp->func (&decomp->last_point, pt, decomp->last_progress, decomp->last_progress + progress, decomp->user_data);
- decomp->last_point = *pt;
- decomp->last_progress += progress;
-}
-
-static void
-gsk_spline_decompose_finish (GskSplineDecompose *decomp,
- const graphene_point_t *end_point)
-{
- g_assert (graphene_point_equal (&decomp->last_point, end_point));
- g_assert (decomp->last_progress == 1.0f || decomp->last_progress == 0.0f);
-}
-
-typedef struct
-{
- GskSplineDecompose decomp;
- float tolerance;
-} GskCubicDecomposition;
-
-static void
-gsk_spline_cubic_get_coefficients (graphene_point_t coeffs[4],
- const graphene_point_t pts[4])
-{
- coeffs[0] = GRAPHENE_POINT_INIT (pts[3].x - 3.0f * pts[2].x + 3.0f * pts[1].x - pts[0].x,
- pts[3].y - 3.0f * pts[2].y + 3.0f * pts[1].y - pts[0].y);
- coeffs[1] = GRAPHENE_POINT_INIT (3.0f * pts[2].x - 6.0f * pts[1].x + 3.0f * pts[0].x,
- 3.0f * pts[2].y - 6.0f * pts[1].y + 3.0f * pts[0].y);
- coeffs[2] = GRAPHENE_POINT_INIT (3.0f * pts[1].x - 3.0f * pts[0].x,
- 3.0f * pts[1].y - 3.0f * pts[0].y);
- coeffs[3] = pts[0];
-}
-
-void
-gsk_spline_get_point_cubic (const graphene_point_t pts[4],
- float progress,
- graphene_point_t *pos,
- graphene_vec2_t *tangent)
-{
- graphene_point_t c[4];
-
- gsk_spline_cubic_get_coefficients (c, pts);
-
- if (pos)
- *pos = GRAPHENE_POINT_INIT (((c[0].x * progress + c[1].x) * progress +c[2].x) * progress + c[3].x,
- ((c[0].y * progress + c[1].y) * progress +c[2].y) * progress + c[3].y);
- if (tangent)
- {
- graphene_vec2_init (tangent,
- (3.0f * c[0].x * progress + 2.0f * c[1].x) * progress + c[2].x,
- (3.0f * c[0].y * progress + 2.0f * c[1].y) * progress + c[2].y);
- graphene_vec2_normalize (tangent, tangent);
- }
-}
-
-void
-gsk_spline_split_cubic (const graphene_point_t pts[4],
- graphene_point_t result1[4],
- graphene_point_t result2[4],
- float progress)
-{
- graphene_point_t ab, bc, cd;
- graphene_point_t abbc, bccd;
- graphene_point_t final;
-
- graphene_point_interpolate (&pts[0], &pts[1], progress, &ab);
- graphene_point_interpolate (&pts[1], &pts[2], progress, &bc);
- graphene_point_interpolate (&pts[2], &pts[3], progress, &cd);
- graphene_point_interpolate (&ab, &bc, progress, &abbc);
- graphene_point_interpolate (&bc, &cd, progress, &bccd);
- graphene_point_interpolate (&abbc, &bccd, progress, &final);
-
- memcpy (result1, (graphene_point_t[4]) { pts[0], ab, abbc, final }, sizeof (graphene_point_t[4]));
- memcpy (result2, (graphene_point_t[4]) { final, bccd, cd, pts[3] }, sizeof (graphene_point_t[4]));
-}
-
-#if 0
-/* Return an upper bound on the error (squared) that could result from
- * approximating a spline as a line segment connecting the two endpoints. */
-static float
-gsk_spline_error_squared (const graphene_point_t pts[4])
-{
- float bdx, bdy, berr;
- float cdx, cdy, cerr;
-
- /* We are going to compute the distance (squared) between each of the the b
- * and c control points and the segment a-b. The maximum of these two
- * distances will be our approximation error. */
-
- bdx = pts[1].x - pts[0].x;
- bdy = pts[1].y - pts[0].y;
-
- cdx = pts[2].x - pts[0].x;
- cdy = pts[2].y - pts[0].y;
-
- if (!graphene_point_equal (&pts[0], &pts[3]))
- {
- float dx, dy, u, v;
-
- /* Intersection point (px):
- * px = p1 + u(p2 - p1)
- * (p - px) ∙ (p2 - p1) = 0
- * Thus:
- * u = ((p - p1) ∙ (p2 - p1)) / ∥p2 - p1∥²;
- */
-
- dx = pts[3].x - pts[0].x;
- dy = pts[3].y - pts[0].y;
- v = dx * dx + dy * dy;
-
- u = bdx * dx + bdy * dy;
- if (u <= 0)
- {
- /* bdx -= 0;
- * bdy -= 0;
- */
- }
- else if (u >= v)
- {
- bdx -= dx;
- bdy -= dy;
- }
- else
- {
- bdx -= u/v * dx;
- bdy -= u/v * dy;
- }
-
- u = cdx * dx + cdy * dy;
- if (u <= 0)
- {
- /* cdx -= 0;
- * cdy -= 0;
- */
- }
- else if (u >= v)
- {
- cdx -= dx;
- cdy -= dy;
- }
- else
- {
- cdx -= u/v * dx;
- cdy -= u/v * dy;
- }
- }
-
- berr = bdx * bdx + bdy * bdy;
- cerr = cdx * cdx + cdy * cdy;
- if (berr > cerr)
- return berr;
- else
- return cerr;
-}
-#endif
-
-/* taken from Skia, including the very descriptive name */
-static gboolean
-gsk_spline_cubic_too_curvy (const graphene_point_t pts[4],
- float tolerance)
-{
- graphene_point_t p;
-
- graphene_point_interpolate (&pts[0], &pts[3], 1.0f / 3, &p);
- if (ABS (p.x - pts[1].x) + ABS (p.y - pts[1].y) > tolerance)
- return TRUE;
-
- graphene_point_interpolate (&pts[0], &pts[3], 2.0f / 3, &p);
- if (ABS (p.x - pts[2].x) + ABS (p.y - pts[2].y) > tolerance)
- return TRUE;
-
- return FALSE;
-}
-
-static void
-gsk_spline_cubic_decompose (GskCubicDecomposition *d,
- const graphene_point_t pts[4],
- float progress)
-{
- graphene_point_t left[4], right[4];
-
- if (!gsk_spline_cubic_too_curvy (pts, d->tolerance) || progress < MIN_PROGRESS)
- {
- gsk_spline_decompose_add_point (&d->decomp, &pts[3], progress);
- return;
- }
-
- gsk_spline_split_cubic (pts, left, right, 0.5);
-
- gsk_spline_cubic_decompose (d, left, progress / 2);
- gsk_spline_cubic_decompose (d, right, progress / 2);
-}
-
-void
-gsk_spline_decompose_cubic (const graphene_point_t pts[4],
- float tolerance,
- GskSplineAddPointFunc add_point_func,
- gpointer user_data)
-{
- GskCubicDecomposition decomp = { { pts[0], 0.0f, add_point_func, user_data }, tolerance };
-
- gsk_spline_cubic_decompose (&decomp, pts, 1.0f);
-
- gsk_spline_decompose_finish (&decomp.decomp, &pts[3]);
-}
-
-/* CONIC */
-
-typedef struct {
- graphene_point_t num[3];
- graphene_point_t denom[3];
-} ConicCoefficients;
-
-typedef struct
-{
- GskSplineDecompose decomp;
- float tolerance;
- ConicCoefficients c;
-} GskConicDecomposition;
-
-
-static void
-gsk_spline_conic_get_coefficents (ConicCoefficients *c,
- const graphene_point_t pts[4])
-{
- float w = pts[2].x;
- graphene_point_t pw = GRAPHENE_POINT_INIT (w * pts[1].x, w * pts[1].y);
-
- c->num[2] = pts[0];
- c->num[1] = GRAPHENE_POINT_INIT (2 * (pw.x - pts[0].x),
- 2 * (pw.y - pts[0].y));
- c->num[0] = GRAPHENE_POINT_INIT (pts[3].x - 2 * pw.x + pts[0].x,
- pts[3].y - 2 * pw.y + pts[0].y);
-
- c->denom[2] = GRAPHENE_POINT_INIT (1, 1);
- c->denom[1] = GRAPHENE_POINT_INIT (2 * (w - 1), 2 * (w - 1));
- c->denom[0] = GRAPHENE_POINT_INIT (-c->denom[1].x, -c->denom[1].y);
-}
-
-static inline void
-gsk_spline_eval_quad (const graphene_point_t quad[3],
- float progress,
- graphene_point_t *result)
-{
- *result = GRAPHENE_POINT_INIT ((quad[0].x * progress + quad[1].x) * progress + quad[2].x,
- (quad[0].y * progress + quad[1].y) * progress + quad[2].y);
-}
-
-static inline void
-gsk_spline_eval_conic (const ConicCoefficients *c,
- float progress,
- graphene_point_t *result)
-{
- graphene_point_t num, denom;
-
- gsk_spline_eval_quad (c->num, progress, &num);
- gsk_spline_eval_quad (c->denom, progress, &denom);
- *result = GRAPHENE_POINT_INIT (num.x / denom.x, num.y / denom.y);
-}
-
-void
-gsk_spline_get_point_conic (const graphene_point_t pts[4],
- float progress,
- graphene_point_t *pos,
- graphene_vec2_t *tangent)
-{
- ConicCoefficients c;
-
- gsk_spline_conic_get_coefficents (&c, pts);
-
- if (pos)
- gsk_spline_eval_conic (&c, progress, pos);
-
- if (tangent)
- {
- graphene_point_t tmp;
- float w = pts[2].x;
-
- /* The tangent will be 0 in these corner cases, just
- * treat it like a line here. */
- if ((progress <= 0.f && graphene_point_equal (&pts[0], &pts[1])) ||
- (progress >= 1.f && graphene_point_equal (&pts[1], &pts[3])))
- {
- graphene_vec2_init (tangent, pts[3].x - pts[0].x, pts[3].y - pts[0].y);
- return;
- }
-
- gsk_spline_eval_quad ((graphene_point_t[3]) {
- GRAPHENE_POINT_INIT ((w - 1) * (pts[3].x - pts[0].x),
- (w - 1) * (pts[3].y - pts[0].y)),
- GRAPHENE_POINT_INIT (pts[3].x - pts[0].x - 2 * w * (pts[1].x - pts[0].x),
- pts[3].y - pts[0].y - 2 * w * (pts[1].y - pts[0].y)),
- GRAPHENE_POINT_INIT (w * (pts[1].x - pts[0].x),
- w * (pts[1].y - pts[0].y))
- },
- progress,
- &tmp);
- graphene_vec2_init (tangent, tmp.x, tmp.y);
- graphene_vec2_normalize (tangent, tangent);
- }
-}
-
-void
-gsk_spline_split_conic (const graphene_point_t pts[4],
- graphene_point_t result1[4],
- graphene_point_t result2[4],
- float progress)
-{
- g_warning ("FIXME: Stop treating conics as lines");
-}
-
-/* taken from Skia, including the very descriptive name */
-static gboolean
-gsk_spline_conic_too_curvy (const graphene_point_t *start,
- const graphene_point_t *mid,
- const graphene_point_t *end,
- float tolerance)
-{
- return fabs ((start->x + end->x) * 0.5 - mid->x) > tolerance
- || fabs ((start->y + end->y) * 0.5 - mid->y) > tolerance;
-}
-
-static void
-gsk_spline_decompose_conic_subdivide (GskConicDecomposition *d,
- const graphene_point_t *start,
- float start_progress,
- const graphene_point_t *end,
- float end_progress)
-{
- graphene_point_t mid;
- float mid_progress;
-
- mid_progress = (start_progress + end_progress) / 2;
- gsk_spline_eval_conic (&d->c, mid_progress, &mid);
-
- if (end_progress - start_progress < MIN_PROGRESS ||
- !gsk_spline_conic_too_curvy (start, &mid, end, d->tolerance))
- {
- gsk_spline_decompose_add_point (&d->decomp, end, end_progress - start_progress);
- return;
- }
-
- gsk_spline_decompose_conic_subdivide (d, start, start_progress, &mid, mid_progress);
- gsk_spline_decompose_conic_subdivide (d, &mid, mid_progress, end, end_progress);
-}
-
-void
-gsk_spline_decompose_conic (const graphene_point_t pts[4],
- float tolerance,
- GskSplineAddPointFunc add_point_func,
- gpointer user_data)
-{
- GskConicDecomposition d = { { pts[0], 0.0f, add_point_func, user_data }, tolerance, };
-
- gsk_spline_conic_get_coefficents (&d.c, pts);
-
- gsk_spline_decompose_conic_subdivide (&d, &pts[0], 0.0f, &pts[3], 1.0f);
-
- gsk_spline_decompose_finish (&d.decomp, &pts[3]);
-}
-
/* Spline deviation from the circle in radius would be given by:
error = sqrt (x**2 + y**2) - 1