Repository: typst/typst
File: crates/typst/src/visualize/path.rs (Rust)

Code before:
        size.x.set_max(Abs::raw(extrema.x1));
        size.y.set_max(Abs::raw(extrema.y1));
    };

    for (vertex_window, point_window) in vertices.windows(2).zip(points.windows(2)) {
        let from = vertex_window[0];
        let to = vertex_window[1];
        let from_point = point_window[0];
        let to_point = point_window[1];

        add_cubic(from_point, to_point, from, to);
    }

    if elem.closed(styles) {
        let from = *vertices.last().unwrap(); // We checked that we have at least one element.
        let to = vertices[0];
        let from_point = *points.last().unwrap();
        let to_point = points[0];

        add_cubic(from_point, to_point, from, to);
        path.close_path();
    }

    // Prepare fill and stroke.
    let fill = elem.fill(styles);
    let fill_rule = elem.fill_rule.unwrap_or_default();
    let stroke = match elem.stroke(styles) {
        Smart::Auto if fill.is_none() => Some(FixedStroke::default()),
        Smart::Auto => None,
        Smart::Custom(stroke) => stroke.map(Stroke::unwrap_or_default),
    };

    let mut frame = Frame::soft(size);
    let shape = Shape {
        geometry: Geometry::Path(path),
        stroke,
        fill,
        fill_rule,
    };
    frame.push(Point::zero(), FrameItem::Shape(shape, elem.span()));
    Ok(frame)
}

/// A component used for path creation.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum PathVertex {
    Vertex(Axes<Rel<Length>>),
    MirroredControlPoint(Axes<Rel<Length>>, Axes<Rel<Length>>),
    AllControlPoints(Axes<Rel<Length>>, Axes<Rel<Length>>, Axes<Rel<Length>>),
}


Review comment (suggestion):
```suggestion
    let fill_rule = elem.fill_rule(styles);
```
otherwise, set rules won't work

Code after:
        size.x.set_max(Abs::raw(extrema.x1));
        size.y.set_max(Abs::raw(extrema.y1));
    };

    for (vertex_window, point_window) in vertices.windows(2).zip(points.windows(2)) {
        let from = vertex_window[0];
        let to = vertex_window[1];
        let from_point = point_window[0];
        let to_point = point_window[1];

        add_cubic(from_point, to_point, from, to);
    }

    if elem.closed(styles) {
        let from = *vertices.last().unwrap(); // We checked that we have at least one element.
        let to = vertices[0];
        let from_point = *points.last().unwrap();
        let to_point = points[0];

        add_cubic(from_point, to_point, from, to);
        path.close_path();
    }

    // Prepare fill and stroke.
    let fill = elem.fill(styles);
    let fill_rule = elem.fill_rule(styles);
    let stroke = match elem.stroke(styles) {
        Smart::Auto if fill.is_none() => Some(FixedStroke::default()),
        Smart::Auto => None,
        Smart::Custom(stroke) => stroke.map(Stroke::unwrap_or_default),
    };

    let mut frame = Frame::soft(size);
    let shape = Shape {
        geometry: Geometry::Path(path),
        stroke,
        fill,
        fill_rule,
    };
    frame.push(Point::zero(), FrameItem::Shape(shape, elem.span()));
    Ok(frame)
}

/// A component used for path creation.
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum PathVertex {
    Vertex(Axes<Rel<Length>>),
    MirroredControlPoint(Axes<Rel<Length>>, Axes<Rel<Length>>),
    AllControlPoints(Axes<Rel<Length>>, Axes<Rel<Length>>, Axes<Rel<Length>>),
}