M4: editing the Dash of an odd-length dash pattern keeps its gaps (#1681)

An odd-length pattern is drawn repeated ([4, 2, 1] as [4, 2, 1, 4, 2, 1]),
so editing its Dash as three values changed the second gap. The pattern is
written out repeated first and only the edited entry changes.
This commit is contained in:
saimskywalker
2026-10-31 02:47:17 +08:00
parent f4e34bac71
commit 391982aab6
2 changed files with 17 additions and 5 deletions
+11
View File
@@ -53,3 +53,14 @@ fn a_single_value_pattern_is_the_dash_and_the_gap() {
type_into(&mut u, "stroke_gap", "2");
assert_eq!(dashes(&u, r), [5.0, 2.0]);
}
/// An odd-length pattern draws twice over (`[4, 2, 1]` is `[4, 2, 1, 4, 2, 1]`): editing its Dash
/// writes the repeat out, so only the first dash changes and every gap stays as drawn.
#[test]
fn an_odd_length_pattern_keeps_its_repeat() {
let (mut u, r) = scene(json!([4, 2, 1]));
type_into(&mut u, "stroke_dash", "6");
assert_eq!(dashes(&u, r), [6.0, 2.0, 1.0, 4.0, 2.0, 1.0]);
type_into(&mut u, "stroke_gap", "3");
assert_eq!(dashes(&u, r), [6.0, 3.0, 1.0, 4.0, 2.0, 1.0]);
}
+6 -5
View File
@@ -189,12 +189,13 @@ fn brush_row(app: &mut FigApp, ui: &mut Ui, ids: &[NodeId], brush: Option<Option
/// Dash pattern `dashes` with its first dash (`i` 0) or first gap (`i` 1) set to `v`, keeping the
/// rest of the pattern: the panel shows only the first pair, and editing it must not collapse an
/// imported `[4, 2, 1, 2]` to two values (#1681). A single value is the dash and the gap alike.
/// imported `[4, 2, 1, 2]` to two values (#1681). An odd-length pattern is drawn repeated
/// (`figcraft_pathops::width::dash_pattern`: `[4, 2, 1]` is `[4, 2, 1, 4, 2, 1]`), so it is
/// written out that way first and only the edited entry changes; `[5]` becomes `[5, 5]`.
fn set_dash(dashes: &[f64], i: usize, v: f64) -> Vec<f64> {
let mut d = dashes.to_vec();
if d.len() < 2 {
let first = d.first().copied().unwrap_or(4.0);
d = vec![first, first];
let mut d = if dashes.is_empty() { vec![4.0] } else { dashes.to_vec() };
if d.len() % 2 == 1 {
d = d.repeat(2);
}
if let Some(x) = d.get_mut(i) {
*x = v.max(0.0);