mirror of
https://github.com/storytold/designcraft.git
synced 2026-11-02 14:47:05 -06:00
idml: one unusable CJK metric no longer refuses the whole file
Composite-font and mojikumi metrics were taken from the file with no
sanity check, and Document::check rejects a zero, NaN or infinite
relative_size / horizontal_scale / vertical_scale / baseline_shift — so
one attribute anywhere in the package (RelativeSize="0",
BaselineShift="NaN") failed the import with "invalid composite font
metrics" and left the file unopenable. Every neighbouring number in this
importer already filters; the metrics now do too and fall back to a
usable value.
Regression test: unusable_cjk_metrics_do_not_refuse_the_whole_file —
fails on main with Invalid("invalid composite font metrics: Rubies"),
passes with the fallback.
This commit is contained in:
@@ -499,10 +499,12 @@ impl<'r> Importer<'r> {
|
||||
characters: c.get("CustomCharacters").unwrap_or("").into(),
|
||||
family: c.prop("AppliedFont").unwrap_or_default(),
|
||||
style: c.get("FontStyle").unwrap_or("Regular").trim_start_matches("$ID/").into(),
|
||||
relative_size: c.num("RelativeSize").unwrap_or(100.0) / 100.0,
|
||||
horizontal_scale: c.num("HorizontalScale").unwrap_or(100.0) / 100.0,
|
||||
vertical_scale: c.num("VerticalScale").unwrap_or(100.0) / 100.0,
|
||||
baseline_shift: c.num("BaselineShift").unwrap_or(0.0) / 100.0,
|
||||
// A metric `Document::check` refuses would make the whole file fail to
|
||||
// open, so one that is unusable here falls back to full size / no shift.
|
||||
relative_size: c.num("RelativeSize").filter(|v| v.is_finite() && *v > 0.0).unwrap_or(100.0) / 100.0,
|
||||
horizontal_scale: c.num("HorizontalScale").filter(|v| v.is_finite() && *v > 0.0).unwrap_or(100.0) / 100.0,
|
||||
vertical_scale: c.num("VerticalScale").filter(|v| v.is_finite() && *v > 0.0).unwrap_or(100.0) / 100.0,
|
||||
baseline_shift: c.num("BaselineShift").filter(|v| v.is_finite()).unwrap_or(0.0) / 100.0,
|
||||
scale_option: c.boolean("ScaleOption").unwrap_or(true),
|
||||
})
|
||||
.collect();
|
||||
@@ -531,9 +533,9 @@ impl<'r> Importer<'r> {
|
||||
target_class: r.num("TargetMojikumiClass").unwrap_or(0.0) as i16,
|
||||
side_class: r.num("SideMojikumiClass").unwrap_or(0.0) as i16,
|
||||
after: r.boolean("SideIsAfterTarget").unwrap_or(false),
|
||||
minimum: r.num("Minimum").unwrap_or(0.0),
|
||||
desired: r.num("Desired").unwrap_or(0.0),
|
||||
maximum: r.num("Maximum").unwrap_or(0.0),
|
||||
minimum: r.num("Minimum").filter(|v| v.is_finite()).unwrap_or(0.0),
|
||||
desired: r.num("Desired").filter(|v| v.is_finite()).unwrap_or(0.0),
|
||||
maximum: r.num("Maximum").filter(|v| v.is_finite()).unwrap_or(0.0),
|
||||
priority: r.num("CompressionPriority").unwrap_or(0.0) as i16,
|
||||
does_not_float: r.boolean("AkiDoesNotFloat").unwrap_or(false),
|
||||
})
|
||||
|
||||
@@ -2443,6 +2443,32 @@ fn the_default_cjk_leading_model_applies_only_with_a_japanese_composer() {
|
||||
assert_eq!(model("$ID/HL Single J"), Some(designcraft_doc::cjk::LeadingModel::AkiBelow));
|
||||
}
|
||||
|
||||
/// A composite-font or mojikumi metric `Document::check` refuses (zero, NaN, infinity) must
|
||||
/// not make the whole package fail to open: the entry falls back to a usable value instead.
|
||||
#[test]
|
||||
fn unusable_cjk_metrics_do_not_refuse_the_whole_file() {
|
||||
let designmap = r#"<Document xmlns:idPkg="http://ns.adobe.com/AdobeInDesign/idml/1.0/packaging" Self="d">
|
||||
<CompositeFont Self="cf" Name="Rubies">
|
||||
<CompositeFontEntry Self="e1" Name="Dot" AppliedFont="Myriad Pro" RelativeSize="0"/>
|
||||
<CompositeFontEntry Self="e2" Name="Bar" AppliedFont="Myriad Pro" BaselineShift="NaN"/>
|
||||
</CompositeFont>
|
||||
<MojikumiTable Self="mt" Name="Table">
|
||||
<Properties><OverrideMojikumiAkiList>
|
||||
<OverrideMojikumiAkiType Minimum="NaN" Desired="1" Maximum="2"/>
|
||||
</OverrideMojikumiAkiList></Properties>
|
||||
</MojikumiTable>
|
||||
<idPkg:Spread src="Spreads/Spread_s.xml"/>
|
||||
</Document>"#;
|
||||
let spread = r#"<idPkg:Spread xmlns:idPkg="http://ns.adobe.com/AdobeInDesign/idml/1.0/packaging">
|
||||
<Spread Self="s"><Page Self="p" GeometricBounds="0 0 100 100" ItemTransform="1 0 0 1 0 0"/></Spread>
|
||||
</idPkg:Spread>"#;
|
||||
let d = import_idml(&zip_files(&[("designmap.xml", &designmap), ("Spreads/Spread_s.xml", &spread)])).unwrap();
|
||||
let entries = &d.styles.composite_fonts[0].entries;
|
||||
assert_eq!(entries[0].relative_size, 1.0, "an unusable relative size falls back to full size");
|
||||
assert_eq!(entries[1].baseline_shift, 0.0, "an unusable shift falls back to none");
|
||||
assert_eq!(d.styles.mojikumi_tables[0].overrides[0].minimum, 0.0);
|
||||
}
|
||||
|
||||
mod liquid_page_rules {
|
||||
use super::*;
|
||||
use designcraft_doc::LiquidRule as R;
|
||||
|
||||
Reference in New Issue
Block a user