mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 20:34:22 +00:00
Dashes fitted to corners take a subpath with no segments
An HP-GL wedge of almost no radius drawn with an adaptive line type (LT-1;EW0.000001,0,0;) leaves a lone moveto. Fitting the dashes to its corners indexed the empty segment list and panicked while rendering. Such a subpath now uses the exact plan, which has no runs to fit. Found by import_fuzz::random_hpgl_instructions_never_panic.
This commit is contained in:
@@ -134,6 +134,10 @@ impl Plan {
|
||||
|
||||
fn fitted(mut segs: Vec<PathSeg>, mut lens: Vec<f64>, closed: bool, period: f64) -> Self {
|
||||
let n = segs.len();
|
||||
// A subpath with no segments (a lone moveto) has no runs to fit.
|
||||
if n == 0 {
|
||||
return Self::exact(segs, lens, closed, period);
|
||||
}
|
||||
// Corners: where segments with length meet at a kink (zero-length ones have no direction).
|
||||
let live: Vec<usize> = (0..n).filter(|&i| lens[i] > EPS).collect();
|
||||
let mut corners: Vec<usize> = live.windows(2).filter(|w| kink(&segs[w[0]], &segs[w[1]])).map(|w| w[1]).collect();
|
||||
|
||||
@@ -37,6 +37,20 @@ fn near(a: f64, b: f64, tol: f64) -> bool {
|
||||
|
||||
// ---------------------------------------------------------------- dashes fitted to corners
|
||||
|
||||
/// A subpath with no segments (a lone moveto, as an HP-GL wedge of almost no radius gives) is
|
||||
/// dashed fitted to corners without a panic, and the other subpaths keep their dashes.
|
||||
#[test]
|
||||
fn fitted_dashes_take_a_subpath_with_no_segments() {
|
||||
let mut b = BezPath::new();
|
||||
b.move_to((5.0, 5.0));
|
||||
b.extend(line(100.0));
|
||||
let d = dash(&b, &fitted(&[10.0, 5.0], 0.0)).expect("dashed");
|
||||
assert!(moves(&d.path) > 1 && length(&d.path) > 0.0, "{:?}", d.path);
|
||||
let mut lone = BezPath::new();
|
||||
lone.move_to((0.0, 0.0));
|
||||
assert!(dash(&lone, &fitted(&[10.0, 5.0], 0.0)).is_some_and(|d| d.path.elements().is_empty()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_corner_of_a_rectangle_falls_mid_dash() {
|
||||
// 100 × 50 with 12/6: the long sides hold 6 periods (scaled by 100/108), the short ones 3
|
||||
|
||||
@@ -2958,6 +2958,13 @@ fn the_hpgl_sample_opens() {
|
||||
assert!(paths > 15, "{paths} paths, warnings {:?}", l.warnings);
|
||||
}
|
||||
|
||||
/// A wedge drawn with the adaptive line type `LT-1` and a near-zero radius (a case the fuzz test
|
||||
/// found) opens and places without a panic.
|
||||
#[test]
|
||||
fn an_adaptive_line_type_wedge_of_almost_no_radius_opens() {
|
||||
survive_metafile("HP-GL tiny adaptive wedge", "x.plt", b"IN;SP1;LT-1;EW0.000001,0,0;").unwrap();
|
||||
}
|
||||
|
||||
/// A random instruction: a mnemonic the reader plays (or one it doesn't) with hostile numbers.
|
||||
fn arb_hpgl_instruction() -> impl Strategy<Value = String> {
|
||||
let op = prop::sample::select(vec![
|
||||
|
||||
Reference in New Issue
Block a user