diff --git a/crates/idml/src/model/mod.rs b/crates/idml/src/model/mod.rs index 56fa5ff12..0ffa32724 100644 --- a/crates/idml/src/model/mod.rs +++ b/crates/idml/src/model/mod.rs @@ -34,8 +34,8 @@ pub use resources::{ style_groups, swatches, }; pub use spread::{ - Graphic, GraphicChild, GraphicKind, Guide, ItemChild, ItemKind, Link, MarginPreference, Page, PageChild, PageItem, Spread, SpreadChild, TextPath, - TextWrapPreference, spreads, + ClippingPathValues, Graphic, GraphicChild, GraphicKind, Guide, ItemChild, ItemKind, Link, MarginPreference, Page, PageChild, PageItem, Spread, + SpreadChild, TextPath, TextWrapPreference, spreads, }; pub use story::{ Ace, CONTAINERS, Cell, CellOptions, Container, ContainerKind, ContentPart, PageReference, Range, SavedCrossReference, SavedCrossReferencePart, diff --git a/crates/idml/src/model/spread.rs b/crates/idml/src/model/spread.rs index f0b1842da..873248978 100644 --- a/crates/idml/src/model/spread.rs +++ b/crates/idml/src/model/spread.rs @@ -17,6 +17,60 @@ fn with_children(mut el: El, children: impl IntoIterator) -> El { el } +/// Raw clip-path settings attached to a placed graphic, before the caller maps type and +/// coordinates into its scene model. +#[derive(Clone, Debug, Default, PartialEq)] +pub struct ClippingPathValues { + pub clipping_type: Option, + pub geometry: PathGeometry, + pub invert: Option, + pub include_inside_edges: Option, + pub restrict_to_frame: Option, + pub use_high_resolution: Option, + pub threshold: Option, + pub tolerance: Option, + pub inset: Option, + pub source_name: Option, + pub index: Option, +} + +impl ClippingPathValues { + /// Reads a graphic's `ClippingPathSettings` and saved geometry, with the caller's point cap. + pub fn from_graphic(graphic: &El, max_points: usize) -> Option { + let settings = graphic.find("ClippingPathSettings")?; + let settings_values = Values::of(settings); + let graphic_values = Values::of(graphic); + let clipping_type = settings_values.get("ClippingType").map(str::to_owned); + let invert = settings_values.boolean("InvertPath"); + let include_inside_edges = settings_values.boolean("IncludeInsideEdges"); + let restrict_to_frame = settings_values.boolean("RestrictToFrame"); + let use_high_resolution = settings_values.boolean("UseHighResolutionImage"); + let threshold = settings_values.num("Threshold"); + let tolerance = settings_values.num("Tolerance"); + let inset = settings_values.num("InsetFrame"); + let source_name = settings_values.get("AppliedPathName").map(str::to_owned); + let index = settings_values.num("Index"); + let geometry = settings_values + .prop_el("ClippingPathGeometry") + .or_else(|| settings.find("ClippingPathGeometry")) + .or_else(|| graphic_values.prop_el("ClippingPathGeometry"))?; + let geometry = PathGeometry::from_el_capped(geometry, max_points); + Some(Self { + clipping_type, + geometry, + invert, + include_inside_edges, + restrict_to_frame, + use_high_resolution, + threshold, + tolerance, + inset, + source_name, + index, + }) + } +} + /// A spread (`Spread`) or a parent spread (`MasterSpread`). #[derive(Clone, Debug, Default, PartialEq)] pub struct Spread {