mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-07 02:51:41 +00:00
fix(pathops): sanitize a brush's width profile once before sampling (#1948)
This commit is contained in:
1 parent
35684eaa02
commit
53ebf1f39c
2 files changed
+14
-1
No files matched your search
@@ -131,7 +131,9 @@ pub fn outline(path: &BezPath, width: f64, props: &StrokeProps, brush: &Brush) -
|
||||
let p = preset(&brush.preset)?;
|
||||
let unit = shape(p.id)?;
|
||||
let lines = polylines(path)?;
|
||||
let scale = |t: f64| width * props.profile().map_or(1.0, |pr| pr.scale_at(t));
|
||||
// Sanitized once: at most 64 points, so each sample's symmetry scan stays cheap.
|
||||
let profile = props.profile().map(|pr| pr.sanitized());
|
||||
let scale = |t: f64| width * profile.as_ref().map_or(1.0, |pr| pr.scale_at(t));
|
||||
let mut out = BezPath::new();
|
||||
match p.kind {
|
||||
BrushKind::Stretch => {
|
||||
|
||||
@@ -72,3 +72,14 @@ fn a_width_profile_scales_the_brush() {
|
||||
let (first, last) = (parts.first().unwrap().bounding_box(), parts.last().unwrap().bounding_box());
|
||||
assert!(last.width() > first.width() * 3.0, "{first:?} {last:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_unsanitized_profile_is_bounded_before_sampling() {
|
||||
// 100k points, all past the 64-point cap and out of range: the brush reads the clamped profile.
|
||||
let raw = WidthProfile { points: (0..100_000).map(|i| figcraft_doc::WidthPoint::new(f64::from(i), 1e300)).collect() };
|
||||
let b = brush("taper");
|
||||
let mut p = props(1.0, &b);
|
||||
p.width_profile = Some(raw);
|
||||
let out = outline(&line(50.0), 1.0, &p, &b).unwrap();
|
||||
assert!(out.bounding_box().height() <= 2.0 * WidthProfile::MAX_SCALE);
|
||||
}
|
||||
Reference in new issue
Block a user