From 5007ce85a452ddefb9f23b6bd4af1932f0aedb5f Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Fri, 13 Nov 2026 08:11:48 -0500 Subject: [PATCH] Parse CJK paragraph settings in shared IDML model --- crates/idml/src/model/mod.rs | 14 +++++----- crates/idml/src/model/resources.rs | 41 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/crates/idml/src/model/mod.rs b/crates/idml/src/model/mod.rs index 89d061e84..e49c6ab0f 100644 --- a/crates/idml/src/model/mod.rs +++ b/crates/idml/src/model/mod.rs @@ -26,13 +26,13 @@ pub use effects::{DirectionalFeatherValues, DropShadowValues, FeatherValues, Gra pub use geometry::{MAX_PATH_POINTS, PathGeometry, PathGeometryError, PathPoint, SubPath}; pub use preferences::TextFramePreferences; pub use resources::{ - CharacterAppearanceValues, CharacterSpecialValues, CharacterTypographyValues, CjkCharacterValues, ColorDefinition, ColorGroup, - ColorGroupDefinition, ColorGroupMember, ColorSpace, CompositeFontDefinition, CompositeFontEntryDefinition, EpubExportTagMap, FontDefinition, - FontFamilyDefinition, FontsPart, GradientDefinition, GradientStop, GradientStopDefinition, GradientStopValue, GraphicPart, GrepStyleValue, Ink, - InkDefinition, MojikumiRow, NestedLineStyleValue, NestedStyleValue, NestedStyleValues, OpenTypeFeatureValues, ParagraphAlignmentValues, - ParagraphBoxValues, ParagraphFlowValues, ParagraphListValues, RubyValues, StrokeDefinition, StrokeStyle, StrokeStyleKind, Style, StyleGroup, - StyleGroupWriter, StyleKind, StyleNode, Swatch, SwatchKind, TabStopValues, TextDecorationValues, TintDefinition, color_groups, inks, named, - preference, stroke_styles, style_groups, swatches, + CharacterAppearanceValues, CharacterSpecialValues, CharacterTypographyValues, CjkCharacterValues, CjkParagraphValues, ColorDefinition, + ColorGroup, ColorGroupDefinition, ColorGroupMember, ColorSpace, CompositeFontDefinition, CompositeFontEntryDefinition, EpubExportTagMap, + FontDefinition, FontFamilyDefinition, FontsPart, GradientDefinition, GradientStop, GradientStopDefinition, GradientStopValue, GraphicPart, + GrepStyleValue, Ink, InkDefinition, MojikumiRow, NestedLineStyleValue, NestedStyleValue, NestedStyleValues, OpenTypeFeatureValues, + ParagraphAlignmentValues, ParagraphBoxValues, ParagraphFlowValues, ParagraphListValues, RubyValues, StrokeDefinition, StrokeStyle, + StrokeStyleKind, Style, StyleGroup, StyleGroupWriter, StyleKind, StyleNode, Swatch, SwatchKind, TabStopValues, TextDecorationValues, + TintDefinition, color_groups, inks, named, preference, stroke_styles, style_groups, swatches, }; pub use spread::{ ClippingPathValues, Graphic, GraphicChild, GraphicKind, GraphicLayerOptions, Guide, ItemChild, ItemKind, Link, MarginPreference, Page, PageChild, diff --git a/crates/idml/src/model/resources.rs b/crates/idml/src/model/resources.rs index 241db2836..4b94e3a48 100644 --- a/crates/idml/src/model/resources.rs +++ b/crates/idml/src/model/resources.rs @@ -67,6 +67,47 @@ pub struct ParagraphBoxValues { pub shading_corners: Option<[(String, f64); 4]>, } +/// CJK paragraph composition settings read from an IDML style or text range. +#[derive(Clone, Debug, Default, PartialEq)] +pub struct CjkParagraphValues { + pub kinsoku_hang: Option, + pub mojikumi: Option, + pub kinsoku_type: Option, + pub bunri_kinshi: Option, + pub rensuuji: Option, + pub treat_ideographic_space_as_space: Option, + pub kinsoku_set: Option, + pub auto_tcy: Option, + pub auto_tcy_include_roman: Option, + pub rotate_single_byte_characters: Option, + pub allow_arbitrary_hyphenation: Option, + pub grid_gyoudori: Option, + pub paragraph_gyoudori: Option, +} + +impl CjkParagraphValues { + /// Reads CJK paragraph composition properties from IDML. + pub fn from_el(el: &El) -> Self { + let values = Values::of(el); + let bounded_count = |key: &str| values.num(key).map(|value| value.clamp(0.0, 1000.0)); + Self { + kinsoku_hang: values.prop("KinsokuHangType"), + mojikumi: values.prop("Mojikumi"), + kinsoku_type: values.prop("KinsokuType"), + bunri_kinshi: values.boolean("BunriKinshi"), + rensuuji: values.boolean("Rensuuji"), + treat_ideographic_space_as_space: values.boolean("TreatIdeographicSpaceAsSpace"), + kinsoku_set: values.prop("KinsokuSet"), + auto_tcy: bounded_count("AutoTcy"), + auto_tcy_include_roman: values.boolean("AutoTcyIncludeRoman"), + rotate_single_byte_characters: values.boolean("RotateSingleByteCharacters"), + allow_arbitrary_hyphenation: values.boolean("AllowArbitraryHyphenation"), + grid_gyoudori: bounded_count("GridGyoudori"), + paragraph_gyoudori: values.boolean("ParagraphGyoudori"), + } + } +} + /// Paragraph alignment, spacing, drop cap, baseline grid and composer values after the caller /// maps application semantics to IDML enumerations. #[derive(Clone, Debug, Default, PartialEq)]