mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-24 09:46:59 -06:00
AF.5: cap dash patterns at 64 lengths
A line style's `Patn` was copied twice (filtered, then scaled) whatever its length, before any budget saw it. Patterns longer than 64 lengths now import as solid lines, with a warning. Addresses CodeRabbit's third review on #3548. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
b3ccdf01a7
commit
2d7004f972
@@ -126,6 +126,9 @@ pub struct Stroke {
|
||||
/// Gradient stops per gradient.
|
||||
const MAX_STOPS: usize = 1024;
|
||||
|
||||
/// Dash and gap lengths per dash pattern (a pattern has a few; strokes and text runs copy theirs).
|
||||
const MAX_DASHES: usize = 64;
|
||||
|
||||
fn floats(v: &Value) -> Option<Vec<f64>> {
|
||||
match v {
|
||||
Value::Floats(f) => Some(f.clone()),
|
||||
@@ -319,6 +322,10 @@ pub(crate) fn stroke(r: &mut Reader, pen: ObjId, ldsc: ObjId, local: Affine, beh
|
||||
_ => Align::Center,
|
||||
};
|
||||
let dash = match s.field(lsty, b"Patn") {
|
||||
Some(Value::Array(a)) if a.len() > MAX_DASHES => {
|
||||
r.warn("dash patterns of more than 64 lengths (imported as solid lines)");
|
||||
None
|
||||
}
|
||||
Some(Value::Array(a)) if data.get(10) == Some(&2) || !a.is_empty() => {
|
||||
let mut v: Vec<f64> = a.iter().filter_map(|x| if let Value::Float(f) = x { Some(*f) } else { None }).collect();
|
||||
while v.len() >= 2 && v.iter().rev().take(2).all(|x| *x == 0.0) {
|
||||
|
||||
@@ -391,6 +391,19 @@ fn master_pages_of_embedded_documents_are_left_out() {
|
||||
named(&loaded.doc, "Page box");
|
||||
}
|
||||
|
||||
/// A dash pattern has a few lengths; a crafted one of thousands would be copied with every stroke.
|
||||
#[test]
|
||||
fn dash_patterns_of_more_than_64_lengths_import_as_solid_lines() {
|
||||
use vectorcraft_affinity::model::Kind;
|
||||
for (lengths, dashed) in [(64, true), (65, false)] {
|
||||
let dash: Vec<f64> = (0..lengths).map(|i| 1.0 + f64::from(i)).collect();
|
||||
let d = vectorcraft_affinity::read(&canvas_with(vec![stroked(10, 2, &dash)], None), vectorcraft_affinity::Limits::default()).unwrap();
|
||||
let Kind::Shape { strokes, .. } = &d.spreads[0].nodes[0].kind else { panic!("{:?}", d.spreads[0].nodes[0].kind) };
|
||||
assert_eq!(strokes[0].dash.as_ref().map(|(d, _)| d.len()), dashed.then_some(64));
|
||||
assert_eq!(d.warnings.iter().any(|w| w.contains("dash patterns of more than 64")), !dashed, "{:?}", d.warnings);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn master_pages_show_on_the_pages_that_use_them() {
|
||||
let loaded = open("master.afpub", &with_master(1));
|
||||
|
||||
Reference in New Issue
Block a user