Repository: typst/typst
File: crates/typst-svg/src/shape.rs (Rust)

Code before:
        }
    }
}

/// Convert a geometry to an SVG path.
#[comemo::memoize]
fn convert_geometry_to_path(geometry: &Geometry) -> EcoString {
    let mut builder =
        SvgPathBuilder::with_translate(Point::new(Abs::zero(), Abs::zero()));

    match geometry {
        Geometry::Line(t) => {
            builder.move_to(0.0, 0.0);
            builder.line_to(t.x.to_pt() as f32, t.y.to_pt() as f32);
        }
        Geometry::Rect(rect) => {
            let x = rect.x.to_pt() as f32;
            let y = rect.y.to_pt() as f32;
            builder.rect(x, y);
        }
        Geometry::Curve(p) => return convert_curve(&Transform::identity(), p),
    };
    builder.path
}

pub fn convert_curve(transform: &Transform, curve: &Curve) -> EcoString {
    let mut builder =
        SvgPathBuilder::with_translate(Point::new(transform.tx, transform.ty));
    for item in &curve.0 {
        match item {
            CurveItem::Move(m) => builder.move_to(m.x.to_pt() as f32, m.y.to_pt() as f32),
            CurveItem::Line(l) => builder.line_to(l.x.to_pt() as f32, l.y.to_pt() as f32),
            CurveItem::Cubic(c1, c2, t) => builder.curve_to(
                c1.x.to_pt() as f32,
                c1.y.to_pt() as f32,
                c2.x.to_pt() as f32,
                c2.y.to_pt() as f32,
                t.x.to_pt() as f32,
                t.y.to_pt() as f32,
            ),
            CurveItem::Close => builder.close(),
        }
    }
    builder.path
}


Review comment (bug):
I think it's a bit misleading that the entire `transform` is passed, but only the translation is used. I wonder whether the could even mask a bug for clip paths?

Code after:
        }
    }
}

/// Convert a geometry to an SVG path.
#[comemo::memoize]
fn convert_geometry_to_path(geometry: &Geometry) -> EcoString {
    let mut builder =
        SvgPathBuilder::with_translate(Point::new(Abs::zero(), Abs::zero()));

    match geometry {
        Geometry::Line(t) => {
            builder.move_to(0.0, 0.0);
            builder.line_to(t.x.to_pt() as f32, t.y.to_pt() as f32);
        }
        Geometry::Rect(rect) => {
            let x = rect.x.to_pt() as f32;
            let y = rect.y.to_pt() as f32;
            builder.rect(x, y);
        }
        Geometry::Curve(p) => {
            return convert_curve(Point::new(Abs::zero(), Abs::zero()), p);
        }
    };
    builder.path
}

pub fn convert_curve(initial_point: Point, curve: &Curve) -> EcoString {
    let mut builder = SvgPathBuilder::with_translate(initial_point);
    for item in &curve.0 {
        match item {
            CurveItem::Move(m) => builder.move_to(m.x.to_pt() as f32, m.y.to_pt() as f32),
            CurveItem::Line(l) => builder.line_to(l.x.to_pt() as f32, l.y.to_pt() as f32),
            CurveItem::Cubic(c1, c2, t) => builder.curve_to(
                c1.x.to_pt() as f32,
                c1.y.to_pt() as f32,
                c2.x.to_pt() as f32,
                c2.y.to_pt() as f32,
                t.x.to_pt() as f32,
                t.y.to_pt() as f32,
            ),
            CurveItem::Close => builder.close(),
        }
    }
    builder.path
}