IDML: Q ruler units are Q, as InDesign writes them (#1360)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013phQ3ekq6uGBEWD6FjFYG2
This commit is contained in:
con3codeandClaude Opus 5.5 committed 2026-10-20 21:31:22 +09:00
1 parent 443ea4640c
commit 92bcf7c1ae
3 files changed
+50 -23

No files matched your search

+11 -5
View File
@@ -593,11 +593,17 @@ impl<'r> Importer<'r> {
self.default_margins = Some((m, c));
}
"ViewPreference" => {
if let Some(u) = e.get("HorizontalMeasurementUnits") {
self.settings.horizontal_units = names::unit_in(u);
}
if let Some(u) = e.get("VerticalMeasurementUnits") {
self.settings.vertical_units = names::unit_in(u);
for (attr, ruler) in [("HorizontalMeasurementUnits", "horizontal"), ("VerticalMeasurementUnits", "vertical")] {
let Some(u) = e.get(attr) else { continue };
let unit = names::unit_in(u).unwrap_or_else(|| {
self.warnings.push(format!("{ruler} ruler units `{u}` are not available; read as points"));
designcraft_geom::Unit::Points
});
if ruler == "horizontal" {
self.settings.horizontal_units = unit;
} else {
self.settings.vertical_units = unit;
}
}
if let Some(v) = e.num("CursorKeyIncrement") {
self.settings.keyboard_increment = v;
+7 -18
View File
@@ -634,6 +634,8 @@ pub fn number_style_in(s: &str) -> NumberStyle {
}
}
/// IDML `MeasurementUnits` of a unit. Q is `Q`; `U` is a different unit, which DesignCraft
/// doesn't have.
pub fn unit_out(u: Unit) -> &'static str {
match u {
Unit::Points => "Points",
@@ -645,27 +647,14 @@ pub fn unit_out(u: Unit) -> &'static str {
Unit::Ciceros => "Ciceros",
Unit::Agates => "Agates",
Unit::Pixels => "Pixels",
Unit::Q => "U",
Unit::Q => "Q",
Unit::Ha => "Ha",
}
}
pub fn unit_in(s: &str) -> Unit {
[
Unit::Points,
Unit::Picas,
Unit::Inches,
Unit::InchesDecimal,
Unit::Millimeters,
Unit::Centimeters,
Unit::Ciceros,
Unit::Agates,
Unit::Pixels,
Unit::Q,
Unit::Ha,
]
.into_iter()
.find(|u| unit_out(*u) == s)
.unwrap_or(Unit::Points)
/// The unit an IDML `MeasurementUnits` value names, if DesignCraft has it (not `U`, `Bai`,
/// `Mils`, `AmericanPoints` or `Custom`).
pub fn unit_in(s: &str) -> Option<Unit> {
Unit::ALL.into_iter().find(|u| unit_out(*u) == s)
}
/// IDML layer colour enumeration names for our layer colour table.
+32
View File
@@ -2773,6 +2773,38 @@ fn round_trips_the_zero_point_and_ruler_origin() {
assert_eq!(fixture("NaN 4").settings.zero_point, [0.0, 0.0]);
}
/// Q is `Q` in IDML, as InDesign writes it (`U` is another unit). Units DesignCraft lacks are
/// read as points, and the import report says so.
#[test]
fn ruler_units_in_q_and_ha_round_trip_and_unknown_units_are_reported() {
use designcraft_geom::Unit;
let mut d = Document::new(&NewDocument::default());
for (h, v) in [(Unit::Q, Unit::Ha), (Unit::Ha, Unit::Q), (Unit::Millimeters, Unit::Points)] {
(d.settings.horizontal_units, d.settings.vertical_units) = (h, v);
let bytes = export_idml(&d);
let back = import_idml(&bytes).unwrap();
assert_eq!((back.settings.horizontal_units, back.settings.vertical_units), (h, v));
}
d.settings.horizontal_units = Unit::Q;
let prefs = zip_text(&export_idml(&d), "Resources/Preferences.xml");
assert!(prefs.contains(r#"HorizontalMeasurementUnits="Q""#), "{prefs}");
let prefs =
PREFS.replace("<MarginPreference", r#"<ViewPreference HorizontalMeasurementUnits="U" VerticalMeasurementUnits="Q"/><MarginPreference"#);
let zip = zip_files(&[
("designmap.xml", DESIGNMAP),
("Resources/Graphic.xml", GRAPHIC),
("Resources/Styles.xml", STYLES),
("Resources/Preferences.xml", &prefs),
("MasterSpreads/MasterSpread_m1.xml", MASTER),
("Spreads/Spread_sp1.xml", SPREAD),
("Stories/Story_s1.xml", STORY),
]);
let r = import_idml_report(&zip, &|_| None).unwrap();
assert_eq!((r.document.settings.horizontal_units, r.document.settings.vertical_units), (Unit::Points, Unit::Q));
assert!(r.warnings.iter().any(|w| w.contains("horizontal ruler units `U`")), "{:?}", r.warnings);
}
#[test]
fn kenten_shatai_and_grid_settings_import_and_round_trip() {
use designcraft_doc::cjk::CharacterAlignment;