feat: use old cap behavior for corners with radius < stroke-width

This commit is contained in:
Tobias Schmitz 2025-07-09 15:53:25 +02:00
parent c85240a8fe
commit 25ef7119e6
No known key found for this signature in database

View File

@ -1162,19 +1162,31 @@ impl ControlPoints {
} }
} }
/// If no stroke is specified before and there is a radius, use the same /// Whether to use the [`Self::stroke_after`] if [`Self::stroke_before`] is
/// width as on the side after. Otherwise default to zero. /// missing to compute the control points. If the radius is too small, caps
/// other than the [`LineCap::Butt`] might be misshaped.
fn reuse_stroke_after_for_cap(&self) -> Option<Abs> {
self.stroke_after.filter(|s| 2.0 * *s < self.radius)
}
/// Either fall back to [`Self::reuse_stroke_after_for_cap`] or zero.
fn stroke_width_before(&self) -> Abs { fn stroke_width_before(&self) -> Abs {
self.stroke_before self.stroke_before
.or(self.stroke_after.filter(|_| self.radius != Abs::zero())) .or(self.reuse_stroke_after_for_cap())
.unwrap_or(Abs::zero()) .unwrap_or(Abs::zero())
} }
/// If no stroke is specified after and there is a radius, use the same /// Whether to use the [`Self::stroke_before`] if [`Self::stroke_after`] is
/// width as on the side before. Otherwise default to zero. /// missing to compute the control points. If the radius is too small, caps
/// other than the [`LineCap::Butt`] might be misshaped.
fn reuse_stroke_before_for_cap(&self) -> Option<Abs> {
self.stroke_before.filter(|s| 2.0 * *s < self.radius)
}
/// Either fall back to [`Self::reuse_stroke_before_for_cap`] or zero.
fn stroke_width_after(&self) -> Abs { fn stroke_width_after(&self) -> Abs {
self.stroke_after self.stroke_after
.or(self.stroke_before.filter(|_| self.radius != Abs::zero())) .or(self.reuse_stroke_before_for_cap())
.unwrap_or(Abs::zero()) .unwrap_or(Abs::zero())
} }
@ -1324,9 +1336,9 @@ impl ControlPoints {
/// a default "butt" cap is used. /// a default "butt" cap is used.
pub fn start_cap(&self, curve: &mut Curve, cap_type: LineCap) { pub fn start_cap(&self, curve: &mut Curve, cap_type: LineCap) {
// Avoid misshaped caps on small radii. // Avoid misshaped caps on small radii.
let small_radius = self.radius < 2.0 * self.stroke_width_after(); let small_radius = self.reuse_stroke_after_for_cap().is_none();
if self.stroke_before.is_some() if cap_type == LineCap::Butt
|| cap_type == LineCap::Butt || self.stroke_before.is_some()
|| self.radius != Abs::zero() && small_radius || self.radius != Abs::zero() && small_radius
{ {
// Just the default cap. // Just the default cap.
@ -1359,9 +1371,9 @@ impl ControlPoints {
/// a default "butt" cap is used. /// a default "butt" cap is used.
pub fn end_cap(&self, curve: &mut Curve, cap_type: LineCap) { pub fn end_cap(&self, curve: &mut Curve, cap_type: LineCap) {
// Avoid misshaped caps on small radii. // Avoid misshaped caps on small radii.
let small_radius = self.radius < 2.0 * self.stroke_width_before(); let small_radius = self.reuse_stroke_before_for_cap().is_none();
if self.stroke_after.is_some() if cap_type == LineCap::Butt
|| cap_type == LineCap::Butt || self.stroke_after.is_some()
|| self.radius != Abs::zero() && small_radius || self.radius != Abs::zero() && small_radius
{ {
// Just the default cap. // Just the default cap.