velato 0.10.0

A Lottie integration for vello.
Documentation
// Copyright 2024 the Velato Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT

use kurbo::{PathEl, Point};

/// Helper trait for converting cubic splines to paths.
pub trait SplineToPath {
    fn get(&self, index: usize) -> Point;
    fn len(&self) -> usize;

    fn to_path(&self, is_closed: bool, path: &mut Vec<PathEl>) -> Option<()> {
        use PathEl::*;
        if self.len() == 0 {
            return None;
        }
        path.push(MoveTo(self.get(0)));
        let n_vertices = self.len() / 3;
        let mut add_element = |from_vertex, to_vertex| {
            let from_index = 3 * from_vertex;
            let to_index = 3 * to_vertex;
            let p0: Point = self.get(from_index);
            let p1: Point = self.get(to_index);
            let mut c0: Point = self.get(from_index + 2);
            c0.x += p0.x;
            c0.y += p0.y;
            let mut c1: Point = self.get(to_index + 1);
            c1.x += p1.x;
            c1.y += p1.y;
            if c0 == p0 && c1 == p1 {
                path.push(LineTo(p1));
            } else {
                path.push(CurveTo(c0, c1, p1));
            }
        };
        for i in 1..n_vertices {
            add_element(i - 1, i);
        }
        if is_closed && n_vertices != 0 {
            add_element(n_vertices - 1, 0);
            path.push(ClosePath);
        }
        Some(())
    }
}

/// Converts a static spline to a path.
impl SplineToPath for &'_ [Point] {
    fn len(&self) -> usize {
        self.as_ref().len()
    }

    fn get(&self, index: usize) -> Point {
        self[index]
    }
}

/// Produces a path by lerping between two sets of points.
impl SplineToPath for (&'_ [Point], &'_ [Point], f64) {
    fn len(&self) -> usize {
        self.0.len().min(self.1.len())
    }

    fn get(&self, index: usize) -> Point {
        // TODO: This definitely shouldn't be a lerp
        self.0[index].lerp(self.1[index], self.2)
    }
}