Repository: typst/typst
File: crates/typst-layout/src/shapes.rs (Rust)

Code before:
        })
    }

    /// End of the corner in the center of the stroke.
    pub fn end(&self) -> Point {
        self.rotate(Point::with_x(self.radius()))
    }

    /// End of the corner on the inside of the stroke.
    pub fn end_inner(&self) -> Point {
        self.rotate(Point {
            x: self.stroke_before + self.radius_inner(),
            y: self.stroke_after,
        })
    }

    /// Draw the cap at the beginning of the segment.
    ///
    /// If this corner has a radius, or has a stroke before it,
    /// a default "butt" cap is used.
    pub fn start_cap(&self, curve: &mut Curve, cap_type: LineCap) {
        if self.stroke_before != Abs::zero()
            || self.radius != Abs::zero()
            || cap_type == LineCap::Butt
        {
            // Just the default cap.
            curve.line(self.outer());
        } else if cap_type == LineCap::Square {
            // Extend by the stroke width.
            let offset =
                self.rotate_centered(Point { x: -self.stroke_after, y: Abs::zero() });
            curve.line(self.end_inner() + offset);
            curve.line(self.outer() + offset);
        } else if cap_type == LineCap::Round {
            // We push the center by a little bit to ensure the correct
            // half of the circle gets drawn. If it is perfectly centered
            // the `arc` function just degenerates into a line, which we
            // do not want in this case.
            curve.arc(
                self.end_inner(),
                (self.end_inner()
                    + self.rotate_centered(Point { x: Abs::raw(1.0), y: Abs::zero() })
                    + self.outer())
                    / 2.,
                self.outer(),
            );
        }
        curve.line(self.end_outer());
    }

    /// Draw the cap at the end of the segment.

Review comment (bug):
I think this is a bit misleading, because if there was a radius:
1. this function wouldn't get called, because `arc_outer()` would return true
2. the butt linecap that is drawn here would be incorrect

Maybe just document that currently no radius is supported?

Code after:
            y: -self.stroke_after,
        })
    }

    /// End of the corner in the center of the stroke.
    pub fn end(&self) -> Point {
        self.rotate(Point::with_x(self.radius()))
    }

    /// End of the corner on the inside of the stroke.
    pub fn end_inner(&self) -> Point {
        self.rotate(Point {
            x: self.stroke_before + self.radius_inner(),
            y: self.stroke_after,
        })
    }

    /// Draw the cap at the beginning of the segment.
    ///
    /// If this corner has a stroke before it,
    /// a default "butt" cap is used.
    ///
    /// NOTE: doesn't support the case where the corner has a radius.
    pub fn start_cap(&self, curve: &mut Curve, cap_type: LineCap) {
        if self.stroke_before != Abs::zero()
            || self.radius != Abs::zero()
            || cap_type == LineCap::Butt
        {
            // Just the default cap.
            curve.line(self.outer());
        } else if cap_type == LineCap::Square {
            // Extend by the stroke width.
            let offset =
                self.rotate_centered(Point { x: -self.stroke_after, y: Abs::zero() });
            curve.line(self.end_inner() + offset);
            curve.line(self.outer() + offset);
        } else if cap_type == LineCap::Round {
            // We push the center by a little bit to ensure the correct
            // half of the circle gets drawn. If it is perfectly centered
            // the `arc` function just degenerates into a line, which we
            // do not want in this case.
            curve.arc(
                self.end_inner(),
                (self.end_inner()
                    + self.rotate_centered(Point { x: Abs::raw(1.0), y: Abs::zero() })
                    + self.outer())
                    / 2.,
                self.outer(),
            );
        }
        curve.line(self.end_outer());