mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-31 15:48:18 +00:00
Honor miter percentage schema bounds
This commit is contained in:
1 parent
479c3cc5ea
commit
1de0101ced
3 files changed
+30
-3
No files matched your search
@@ -234,7 +234,7 @@ pub fn line(imp: &mut Imp, part: &Part, ln: &El) -> Line {
|
||||
"bevel" => l.join = Some(LineJoin::Bevel),
|
||||
"miter" => {
|
||||
l.join = Some(LineJoin::Miter);
|
||||
l.miter_limit = e.attr("lim").and_then(|v| v.parse::<u32>().ok()).filter(|v| *v <= 1_000_000);
|
||||
l.miter_limit = e.attr("lim").and_then(parse_miter_limit);
|
||||
}
|
||||
"headEnd" => l.head = line_end(e),
|
||||
"tailEnd" => l.tail = line_end(e),
|
||||
@@ -244,6 +244,17 @@ pub fn line(imp: &mut Imp, part: &Part, ln: &El) -> Line {
|
||||
l
|
||||
}
|
||||
|
||||
fn parse_miter_limit(value: &str) -> Option<u32> {
|
||||
const MAX: u32 = i32::MAX as u32;
|
||||
let value = value.trim();
|
||||
if let Some(percent) = value.strip_suffix('%') {
|
||||
let units = percent.trim().parse::<f64>().ok()? * 1000.0;
|
||||
(units.is_finite() && (0.0..=MAX as f64).contains(&units)).then(|| units.round() as u32)
|
||||
} else {
|
||||
value.parse::<u32>().ok().filter(|limit| *limit <= MAX)
|
||||
}
|
||||
}
|
||||
|
||||
fn line_end(e: &El) -> Option<LineEnd> {
|
||||
let kind = e.attr("type").unwrap_or("none");
|
||||
Some(LineEnd { kind: kind.to_string(), w: e.attr("w").unwrap_or("med").to_string(), len: e.attr("len").unwrap_or("med").to_string() })
|
||||
@@ -671,6 +682,16 @@ mod tests {
|
||||
assert_eq!(color(&d.root).unwrap().base, ColorBase::Rgb { rgb: Rgba::rgb(255, 0, 0) });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn miter_limit_accepts_both_percentage_forms_with_schema_bounds() {
|
||||
assert_eq!(parse_miter_limit("200000"), Some(200_000));
|
||||
assert_eq!(parse_miter_limit("200%"), Some(200_000));
|
||||
assert_eq!(parse_miter_limit("1000001"), Some(1_000_001));
|
||||
assert_eq!(parse_miter_limit("malformed"), None);
|
||||
assert_eq!(parse_miter_limit("2147483648"), None);
|
||||
assert_eq!(parse_miter_limit("2147483.648%"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn body_props() {
|
||||
let d = parse(br#"<a:bodyPr lIns="91440" anchor="ctr" wrap="none" vert="vert270" numCol="2"><a:normAutofit fontScale="62500" lnSpcReduction="20000"/></a:bodyPr>"#).unwrap();
|
||||
|
||||
@@ -233,7 +233,10 @@ pub fn line(w: &mut W, x: &mut Exp, o: &mut Out, tag: &str, l: &Line) {
|
||||
match l.join {
|
||||
Some(LineJoin::Round) => w.empty0("a:round"),
|
||||
Some(LineJoin::Bevel) => w.empty0("a:bevel"),
|
||||
Some(LineJoin::Miter) => w.empty("a:miter", A::new().o("lim", l.miter_limit)),
|
||||
Some(LineJoin::Miter) => {
|
||||
let limit = l.miter_limit.filter(|limit| *limit <= i32::MAX as u32);
|
||||
w.empty("a:miter", A::new().o("lim", limit));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
for (t, e) in [("a:headEnd", &l.head), ("a:tailEnd", &l.tail)] {
|
||||
|
||||
@@ -495,11 +495,14 @@ fn line_miter_limit_survives_two_pptx_round_trips() {
|
||||
limited.line = Some(Line { join: Some(deckcraft_model::style::LineJoin::Miter), miter_limit: Some(200_000), ..Default::default() });
|
||||
let mut defaulted = shape(&mut p, "Default miter", 140.0, 20.0, 100.0, 100.0);
|
||||
defaulted.line = Some(Line { join: Some(deckcraft_model::style::LineJoin::Miter), ..Default::default() });
|
||||
Arc::make_mut(&mut p.slides[0]).shapes.extend([limited, defaulted]);
|
||||
let mut large = shape(&mut p, "Large miter", 260.0, 20.0, 100.0, 100.0);
|
||||
large.line = Some(Line { join: Some(deckcraft_model::style::LineJoin::Miter), miter_limit: Some(1_000_001), ..Default::default() });
|
||||
Arc::make_mut(&mut p.slides[0]).shapes.extend([limited, defaulted, large]);
|
||||
|
||||
let q = round(&round(&p));
|
||||
assert_eq!(by_name(&q.slides[0], "Limited miter").line.as_ref().and_then(|line| line.miter_limit), Some(200_000));
|
||||
assert_eq!(by_name(&q.slides[0], "Default miter").line.as_ref().and_then(|line| line.miter_limit), None);
|
||||
assert_eq!(by_name(&q.slides[0], "Large miter").line.as_ref().and_then(|line| line.miter_limit), Some(1_000_001));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user