diff options
| author | Laurenz <laurmaedje@gmail.com> | 2025-07-08 10:52:43 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-08 08:52:43 +0000 |
| commit | 0a3c6939dd274f40672484695d909c2cc0d0d755 (patch) | |
| tree | 465c10338230b895fdd06c8b3491f1734e8a2932 /crates/typst-layout/src | |
| parent | 36ecbb2c8dccc1a31c43fee1466f1425844d8607 (diff) | |
Rewrite foundations of native elements (#6547)
Diffstat (limited to 'crates/typst-layout/src')
35 files changed, 403 insertions, 359 deletions
diff --git a/crates/typst-layout/src/flow/block.rs b/crates/typst-layout/src/flow/block.rs index 6c2c3923..d6cfe3a9 100644 --- a/crates/typst-layout/src/flow/block.rs +++ b/crates/typst-layout/src/flow/block.rs @@ -24,15 +24,15 @@ pub fn layout_single_block( region: Region, ) -> SourceResult<Frame> { // Fetch sizing properties. - let width = elem.width(styles); - let height = elem.height(styles); - let inset = elem.inset(styles).unwrap_or_default(); + let width = elem.width.get(styles); + let height = elem.height.get(styles); + let inset = elem.inset.resolve(styles).unwrap_or_default(); // Build the pod regions. let pod = unbreakable_pod(&width.into(), &height, &inset, styles, region.size); // Layout the body. - let body = elem.body(styles); + let body = elem.body.get_ref(styles); let mut frame = match body { // If we have no body, just create one frame. Its size will be // adjusted below. @@ -73,18 +73,19 @@ pub fn layout_single_block( } // Prepare fill and stroke. - let fill = elem.fill(styles); + let fill = elem.fill.get_cloned(styles); let stroke = elem - .stroke(styles) + .stroke + .resolve(styles) .unwrap_or_default() .map(|s| s.map(Stroke::unwrap_or_default)); // Only fetch these if necessary (for clipping or filling/stroking). - let outset = LazyCell::new(|| elem.outset(styles).unwrap_or_default()); - let radius = LazyCell::new(|| elem.radius(styles).unwrap_or_default()); + let outset = LazyCell::new(|| elem.outset.resolve(styles).unwrap_or_default()); + let radius = LazyCell::new(|| elem.radius.resolve(styles).unwrap_or_default()); // Clip the contents, if requested. - if elem.clip(styles) { + if elem.clip.get(styles) { frame.clip(clip_rect(frame.size(), &radius, &stroke, &outset)); } @@ -111,9 +112,9 @@ pub fn layout_multi_block( regions: Regions, ) -> SourceResult<Fragment> { // Fetch sizing properties. - let width = elem.width(styles); - let height = elem.height(styles); - let inset = elem.inset(styles).unwrap_or_default(); + let width = elem.width.get(styles); + let height = elem.height.get(styles); + let inset = elem.inset.resolve(styles).unwrap_or_default(); // Allocate a small vector for backlogs. let mut buf = SmallVec::<[Abs; 2]>::new(); @@ -122,7 +123,7 @@ pub fn layout_multi_block( let pod = breakable_pod(&width.into(), &height, &inset, styles, regions, &mut buf); // Layout the body. - let body = elem.body(styles); + let body = elem.body.get_ref(styles); let mut fragment = match body { // If we have no body, just create one frame plus one per backlog // region. We create them zero-sized; if necessary, their size will @@ -188,18 +189,19 @@ pub fn layout_multi_block( }; // Prepare fill and stroke. - let fill = elem.fill(styles); + let fill = elem.fill.get_ref(styles); let stroke = elem - .stroke(styles) + .stroke + .resolve(styles) .unwrap_or_default() .map(|s| s.map(Stroke::unwrap_or_default)); // Only fetch these if necessary (for clipping or filling/stroking). - let outset = LazyCell::new(|| elem.outset(styles).unwrap_or_default()); - let radius = LazyCell::new(|| elem.radius(styles).unwrap_or_default()); + let outset = LazyCell::new(|| elem.outset.resolve(styles).unwrap_or_default()); + let radius = LazyCell::new(|| elem.radius.resolve(styles).unwrap_or_default()); // Fetch/compute these outside of the loop. - let clip = elem.clip(styles); + let clip = elem.clip.get(styles); let has_fill_or_stroke = fill.is_some() || stroke.iter().any(Option::is_some); let has_inset = !inset.is_zero(); let is_explicit = matches!(body, None | Some(BlockBody::Content(_))); diff --git a/crates/typst-layout/src/flow/collect.rs b/crates/typst-layout/src/flow/collect.rs index 2c14f7a3..76268b59 100644 --- a/crates/typst-layout/src/flow/collect.rs +++ b/crates/typst-layout/src/flow/collect.rs @@ -89,7 +89,7 @@ impl<'a> Collector<'a, '_, '_> { } else if child.is::<FlushElem>() { self.output.push(Child::Flush); } else if let Some(elem) = child.to_packed::<ColbreakElem>() { - self.output.push(Child::Break(elem.weak(styles))); + self.output.push(Child::Break(elem.weak.get(styles))); } else if child.is::<PagebreakElem>() { bail!( child.span(), "pagebreaks are not allowed inside of containers"; @@ -132,7 +132,7 @@ impl<'a> Collector<'a, '_, '_> { self.output.push(Child::Tag(&elem.tag)); } - let leading = ParElem::leading_in(styles); + let leading = styles.resolve(ParElem::leading); self.lines(lines, leading, styles); for (c, _) in &self.children[end..] { @@ -146,7 +146,9 @@ impl<'a> Collector<'a, '_, '_> { /// Collect vertical spacing into a relative or fractional child. fn v(&mut self, elem: &'a Packed<VElem>, styles: StyleChain<'a>) { self.output.push(match elem.amount { - Spacing::Rel(rel) => Child::Rel(rel.resolve(styles), elem.weak(styles) as u8), + Spacing::Rel(rel) => { + Child::Rel(rel.resolve(styles), elem.weak.get(styles) as u8) + } Spacing::Fr(fr) => Child::Fr(fr), }); } @@ -169,8 +171,8 @@ impl<'a> Collector<'a, '_, '_> { )? .into_frames(); - let spacing = elem.spacing(styles); - let leading = elem.leading(styles); + let spacing = elem.spacing.resolve(styles); + let leading = elem.leading.resolve(styles); self.output.push(Child::Rel(spacing.into(), 4)); @@ -184,8 +186,8 @@ impl<'a> Collector<'a, '_, '_> { /// Collect laid-out lines. fn lines(&mut self, lines: Vec<Frame>, leading: Abs, styles: StyleChain<'a>) { - let align = AlignElem::alignment_in(styles).resolve(styles); - let costs = TextElem::costs_in(styles); + let align = styles.resolve(AlignElem::alignment); + let costs = styles.get(TextElem::costs); // Determine whether to prevent widow and orphans. let len = lines.len(); @@ -231,23 +233,23 @@ impl<'a> Collector<'a, '_, '_> { /// whether it is breakable. fn block(&mut self, elem: &'a Packed<BlockElem>, styles: StyleChain<'a>) { let locator = self.locator.next(&elem.span()); - let align = AlignElem::alignment_in(styles).resolve(styles); + let align = styles.resolve(AlignElem::alignment); let alone = self.children.len() == 1; - let sticky = elem.sticky(styles); - let breakable = elem.breakable(styles); - let fr = match elem.height(styles) { + let sticky = elem.sticky.get(styles); + let breakable = elem.breakable.get(styles); + let fr = match elem.height.get(styles) { Sizing::Fr(fr) => Some(fr), _ => None, }; - let fallback = LazyCell::new(|| ParElem::spacing_in(styles)); + let fallback = LazyCell::new(|| styles.resolve(ParElem::spacing)); let spacing = |amount| match amount { Smart::Auto => Child::Rel((*fallback).into(), 4), Smart::Custom(Spacing::Rel(rel)) => Child::Rel(rel.resolve(styles), 3), Smart::Custom(Spacing::Fr(fr)) => Child::Fr(fr), }; - self.output.push(spacing(elem.above(styles))); + self.output.push(spacing(elem.above.get(styles))); if !breakable || fr.is_some() { self.output.push(Child::Single(self.boxed(SingleChild { @@ -272,7 +274,7 @@ impl<'a> Collector<'a, '_, '_> { }))); }; - self.output.push(spacing(elem.below(styles))); + self.output.push(spacing(elem.below.get(styles))); self.par_situation = ParSituation::Other; } @@ -282,13 +284,13 @@ impl<'a> Collector<'a, '_, '_> { elem: &'a Packed<PlaceElem>, styles: StyleChain<'a>, ) -> SourceResult<()> { - let alignment = elem.alignment(styles); + let alignment = elem.alignment.get(styles); let align_x = alignment.map_or(FixedAlignment::Center, |align| { align.x().unwrap_or_default().resolve(styles) }); let align_y = alignment.map(|align| align.y().map(|y| y.resolve(styles))); - let scope = elem.scope(styles); - let float = elem.float(styles); + let scope = elem.scope.get(styles); + let float = elem.float.get(styles); match (float, align_y) { (true, Smart::Custom(None | Some(FixedAlignment::Center))) => bail!( @@ -312,8 +314,8 @@ impl<'a> Collector<'a, '_, '_> { } let locator = self.locator.next(&elem.span()); - let clearance = elem.clearance(styles); - let delta = Axes::new(elem.dx(styles), elem.dy(styles)).resolve(styles); + let clearance = elem.clearance.resolve(styles); + let delta = Axes::new(elem.dx.get(styles), elem.dy.get(styles)).resolve(styles); self.output.push(Child::Placed(self.boxed(PlacedChild { align_x, align_y, @@ -631,7 +633,7 @@ impl PlacedChild<'_> { pub fn layout(&self, engine: &mut Engine, base: Size) -> SourceResult<Frame> { self.cell.get_or_init(base, |base| { let align = self.alignment.unwrap_or_else(|| Alignment::CENTER); - let aligned = AlignElem::set_alignment(align).wrap(); + let aligned = AlignElem::alignment.set(align).wrap(); let styles = self.styles.chain(&aligned); let mut frame = layout_and_modify(styles, |styles| { diff --git a/crates/typst-layout/src/flow/compose.rs b/crates/typst-layout/src/flow/compose.rs index 54dc487a..ed514a24 100644 --- a/crates/typst-layout/src/flow/compose.rs +++ b/crates/typst-layout/src/flow/compose.rs @@ -851,7 +851,7 @@ fn layout_line_number_reset( config: &Config, locator: &mut SplitLocator, ) -> SourceResult<Frame> { - let counter = Counter::of(ParLineMarker::elem()); + let counter = Counter::of(ParLineMarker::ELEM); let update = CounterUpdate::Set(CounterState::init(false)); let content = counter.update(Span::detached(), update); crate::layout_frame( @@ -879,7 +879,7 @@ fn layout_line_number( locator: &mut SplitLocator, numbering: &Numbering, ) -> SourceResult<Frame> { - let counter = Counter::of(ParLineMarker::elem()); + let counter = Counter::of(ParLineMarker::ELEM); let update = CounterUpdate::Step(NonZeroUsize::ONE); let numbering = Smart::Custom(numbering.clone()); diff --git a/crates/typst-layout/src/flow/mod.rs b/crates/typst-layout/src/flow/mod.rs index cba228bc..f4f1c091 100644 --- a/crates/typst-layout/src/flow/mod.rs +++ b/crates/typst-layout/src/flow/mod.rs @@ -98,8 +98,8 @@ pub fn layout_columns( locator.track(), styles, regions, - elem.count(styles), - elem.gutter(styles), + elem.count.get(styles), + elem.gutter.resolve(styles), ) } @@ -251,22 +251,22 @@ fn configuration<'x>( let gutter = column_gutter.relative_to(regions.base().x); let width = (regions.size.x - gutter * (count - 1) as f64) / count as f64; - let dir = TextElem::dir_in(shared); + let dir = shared.resolve(TextElem::dir); ColumnConfig { count, width, gutter, dir } }, footnote: FootnoteConfig { - separator: FootnoteEntry::separator_in(shared), - clearance: FootnoteEntry::clearance_in(shared), - gap: FootnoteEntry::gap_in(shared), + separator: shared.get_cloned(FootnoteEntry::separator), + clearance: shared.resolve(FootnoteEntry::clearance), + gap: shared.resolve(FootnoteEntry::gap), expand: regions.expand.x, }, line_numbers: (mode == FlowMode::Root).then(|| LineNumberConfig { - scope: ParLine::numbering_scope_in(shared), + scope: shared.get(ParLine::numbering_scope), default_clearance: { - let width = if PageElem::flipped_in(shared) { - PageElem::height_in(shared) + let width = if shared.get(PageElem::flipped) { + shared.resolve(PageElem::height) } else { - PageElem::width_in(shared) + shared.resolve(PageElem::width) }; // Clamp below is safe (min <= max): if the font size is diff --git a/crates/typst-layout/src/grid/layouter.rs b/crates/typst-layout/src/grid/layouter.rs index 42fe38db..d4f11f47 100644 --- a/crates/typst-layout/src/grid/layouter.rs +++ b/crates/typst-layout/src/grid/layouter.rs @@ -249,7 +249,7 @@ impl<'a> GridLayouter<'a> { rowspans: vec![], finished: vec![], finished_header_rows: vec![], - is_rtl: TextElem::dir_in(styles) == Dir::RTL, + is_rtl: styles.resolve(TextElem::dir) == Dir::RTL, repeating_headers: vec![], upcoming_headers: &grid.headers, pending_headers: Default::default(), diff --git a/crates/typst-layout/src/image.rs b/crates/typst-layout/src/image.rs index a8f4a0c8..261a58fa 100644 --- a/crates/typst-layout/src/image.rs +++ b/crates/typst-layout/src/image.rs @@ -28,7 +28,7 @@ pub fn layout_image( // Take the format that was explicitly defined, or parse the extension, // or try to detect the format. let Derived { source, derived: loaded } = &elem.source; - let format = match elem.format(styles) { + let format = match elem.format.get(styles) { Smart::Custom(v) => v, Smart::Auto => determine_format(source, &loaded.data).at(span)?, }; @@ -55,7 +55,7 @@ pub fn layout_image( RasterImage::new( loaded.data.clone(), format, - elem.icc(styles).as_ref().map(|icc| icc.derived.clone()), + elem.icc.get_ref(styles).as_ref().map(|icc| icc.derived.clone()), ) .at(span)?, ), @@ -69,7 +69,7 @@ pub fn layout_image( ), }; - let image = Image::new(kind, elem.alt(styles), elem.scaling(styles)); + let image = Image::new(kind, elem.alt.get_cloned(styles), elem.scaling.get(styles)); // Determine the image's pixel aspect ratio. let pxw = image.width(); @@ -106,7 +106,7 @@ pub fn layout_image( }; // Compute the actual size of the fitted image. - let fit = elem.fit(styles); + let fit = elem.fit.get(styles); let fitted = match fit { ImageFit::Cover | ImageFit::Contain => { if wide == (fit == ImageFit::Contain) { diff --git a/crates/typst-layout/src/inline/box.rs b/crates/typst-layout/src/inline/box.rs index e21928d3..65b02533 100644 --- a/crates/typst-layout/src/inline/box.rs +++ b/crates/typst-layout/src/inline/box.rs @@ -21,15 +21,15 @@ pub fn layout_box( region: Size, ) -> SourceResult<Frame> { // Fetch sizing properties. - let width = elem.width(styles); - let height = elem.height(styles); - let inset = elem.inset(styles).unwrap_or_default(); + let width = elem.width.get(styles); + let height = elem.height.get(styles); + let inset = elem.inset.resolve(styles).unwrap_or_default(); // Build the pod region. let pod = unbreakable_pod(&width, &height.into(), &inset, styles, region); // Layout the body. - let mut frame = match elem.body(styles) { + let mut frame = match elem.body.get_ref(styles) { // If we have no body, just create an empty frame. If necessary, // its size will be adjusted below. None => Frame::hard(Size::zero()), @@ -50,18 +50,19 @@ pub fn layout_box( } // Prepare fill and stroke. - let fill = elem.fill(styles); + let fill = elem.fill.get_cloned(styles); let stroke = elem - .stroke(styles) + .stroke + .resolve(styles) .unwrap_or_default() .map(|s| s.map(Stroke::unwrap_or_default)); // Only fetch these if necessary (for clipping or filling/stroking). - let outset = LazyCell::new(|| elem.outset(styles).unwrap_or_default()); - let radius = LazyCell::new(|| elem.radius(styles).unwrap_or_default()); + let outset = LazyCell::new(|| elem.outset.resolve(styles).unwrap_or_default()); + let radius = LazyCell::new(|| elem.radius.resolve(styles).unwrap_or_default()); // Clip the contents, if requested. - if elem.clip(styles) { + if elem.clip.get(styles) { frame.clip(clip_rect(frame.size(), &radius, &stroke, &outset)); } @@ -78,7 +79,7 @@ pub fn layout_box( // Apply baseline shift. Do this after setting the size and applying the // inset, so that a relative shift is resolved relative to the final // height. - let shift = elem.baseline(styles).relative_to(frame.height()); + let shift = elem.baseline.resolve(styles).relative_to(frame.height()); if !shift.is_zero() { frame.set_baseline(frame.baseline() - shift); } diff --git a/crates/typst-layout/src/inline/collect.rs b/crates/typst-layout/src/inline/collect.rs index 829f64b6..2744b31e 100644 --- a/crates/typst-layout/src/inline/collect.rs +++ b/crates/typst-layout/src/inline/collect.rs @@ -144,7 +144,7 @@ pub fn collect<'a>( collector.push_text(" ", styles); } else if let Some(elem) = child.to_packed::<TextElem>() { collector.build_text(styles, |full| { - let dir = TextElem::dir_in(styles); + let dir = styles.resolve(TextElem::dir); if dir != config.dir { // Insert "Explicit Directional Embedding". match dir { @@ -154,7 +154,7 @@ pub fn collect<'a>( } } - if let Some(case) = TextElem::case_in(styles) { + if let Some(case) = styles.get(TextElem::case) { full.push_str(&case.apply(&elem.text)); } else { full.push_str(&elem.text); @@ -174,20 +174,22 @@ pub fn collect<'a>( Spacing::Fr(fr) => Item::Fractional(fr, None), Spacing::Rel(rel) => Item::Absolute( rel.resolve(styles).relative_to(region.x), - elem.weak(styles), + elem.weak.get(styles), ), }); } else if let Some(elem) = child.to_packed::<LinebreakElem>() { - collector - .push_text(if elem.justify(styles) { "\u{2028}" } else { "\n" }, styles); + collector.push_text( + if elem.justify.get(styles) { "\u{2028}" } else { "\n" }, + styles, + ); } else if let Some(elem) = child.to_packed::<SmartQuoteElem>() { - let double = elem.double(styles); - if elem.enabled(styles) { + let double = elem.double.get(styles); + if elem.enabled.get(styles) { let quotes = SmartQuotes::get( - elem.quotes(styles), - TextElem::lang_in(styles), - TextElem::region_in(styles), - elem.alternative(styles), + elem.quotes.get_ref(styles), + styles.get(TextElem::lang), + styles.get(TextElem::region), + elem.alternative.get(styles), ); let before = collector.full.chars().rev().find(|&c| !is_default_ignorable(c)); @@ -215,7 +217,7 @@ pub fn collect<'a>( collector.push_item(Item::Skip(POP_ISOLATE)); } else if let Some(elem) = child.to_packed::<BoxElem>() { let loc = locator.next(&elem.span()); - if let Sizing::Fr(v) = elem.width(styles) { + if let Sizing::Fr(v) = elem.width.get(styles) { collector.push_item(Item::Fractional(v, Some((elem, loc, styles)))); } else { let mut frame = layout_and_modify(styles, |styles| { diff --git a/crates/typst-layout/src/inline/line.rs b/crates/typst-layout/src/inline/line.rs index b850e50e..58162d12 100644 --- a/crates/typst-layout/src/inline/line.rs +++ b/crates/typst-layout/src/inline/line.rs @@ -2,6 +2,7 @@ use std::fmt::{self, Debug, Formatter}; use std::ops::{Deref, DerefMut}; use typst_library::engine::Engine; +use typst_library::foundations::Resolve; use typst_library::introspection::{SplitLocator, Tag}; use typst_library::layout::{Abs, Dir, Em, Fr, Frame, FrameItem, Point}; use typst_library::model::ParLineMarker; @@ -418,10 +419,11 @@ pub fn apply_shift<'a>( frame: &mut Frame, styles: StyleChain, ) { - let mut baseline = TextElem::baseline_in(styles); + let mut baseline = styles.resolve(TextElem::baseline); let mut compensation = Abs::zero(); - if let Some(scripts) = TextElem::shift_settings_in(styles) { - let font_metrics = TextElem::font_in(styles) + if let Some(scripts) = styles.get_ref(TextElem::shift_settings) { + let font_metrics = styles + .get_ref(TextElem::font) .into_iter() .find_map(|family| { world @@ -462,7 +464,7 @@ pub fn commit( if let Some(Item::Text(text)) = line.items.first() { if let Some(glyph) = text.glyphs.first() { if !text.dir.is_positive() - && TextElem::overhang_in(text.styles) + && text.styles.get(TextElem::overhang) && (line.items.len() > 1 || text.glyphs.len() > 1) { let amount = overhang(glyph.c) * glyph.x_advance.at(glyph.size); @@ -476,7 +478,7 @@ pub fn commit( if let Some(Item::Text(text)) = line.items.last() { if let Some(glyph) = text.glyphs.last() { if text.dir.is_positive() - && TextElem::overhang_in(text.styles) + && text.styles.get(TextElem::overhang) && (line.items.len() > 1 || text.glyphs.len() > 1) { let amount = overhang(glyph.c) * glyph.x_advance.at(glyph.size); diff --git a/crates/typst-layout/src/inline/linebreak.rs b/crates/typst-layout/src/inline/linebreak.rs index 709745ed..955360df 100644 --- a/crates/typst-layout/src/inline/linebreak.rs +++ b/crates/typst-layout/src/inline/linebreak.rs @@ -846,7 +846,9 @@ fn hyphenate_at(p: &Preparation, offset: usize) -> bool { p.config.hyphenate.unwrap_or_else(|| { let (_, item) = p.get(offset); match item.text() { - Some(text) => TextElem::hyphenate_in(text.styles).unwrap_or(p.config.justify), + Some(text) => { + text.styles.get(TextElem::hyphenate).unwrap_or(p.config.justify) + } None => false, } }) @@ -857,7 +859,7 @@ fn lang_at(p: &Preparation, offset: usize) -> Option<hypher::Lang> { let lang = p.config.lang.or_else(|| { let (_, item) = p.get(offset); let styles = item.text()?.styles; - Some(TextElem::lang_in(styles)) + Some(styles.get(TextElem::lang)) })?; let bytes = lang.as_str().as_bytes().try_into().ok()?; diff --git a/crates/typst-layout/src/inline/mod.rs b/crates/typst-layout/src/inline/mod.rs index 506fa5ea..06223ceb 100644 --- a/crates/typst-layout/src/inline/mod.rs +++ b/crates/typst-layout/src/inline/mod.rs @@ -14,7 +14,7 @@ pub use self::shaping::create_shape_plan; use comemo::{Track, Tracked, TrackedMut}; use typst_library::diag::SourceResult; use typst_library::engine::{Engine, Route, Sink, Traced}; -use typst_library::foundations::{Packed, Resolve, Smart, StyleChain}; +use typst_library::foundations::{Packed, Smart, StyleChain}; use typst_library::introspection::{Introspector, Locator, LocatorLink, SplitLocator}; use typst_library::layout::{Abs, AlignElem, Dir, FixedAlignment, Fragment, Size}; use typst_library::model::{ @@ -113,10 +113,10 @@ fn layout_par_impl( expand, Some(situation), &ConfigBase { - justify: elem.justify(styles), - linebreaks: elem.linebreaks(styles), - first_line_indent: elem.first_line_indent(styles), - hanging_indent: elem.hanging_indent(styles), + justify: elem.justify.get(styles), + linebreaks: elem.linebreaks.get(styles), + first_line_indent: elem.first_line_indent.get(styles), + hanging_indent: elem.hanging_indent.resolve(styles), }, ) } @@ -139,10 +139,10 @@ pub fn layout_inline<'a>( expand, None, &ConfigBase { - justify: ParElem::justify_in(shared), - linebreaks: ParElem::linebreaks_in(shared), - first_line_indent: ParElem::first_line_indent_in(shared), - hanging_indent: ParElem::hanging_indent_in(shared), + justify: shared.get(ParElem::justify), + linebreaks: shared.get(ParElem::linebreaks), + first_line_indent: shared.get(ParElem::first_line_indent), + hanging_indent: shared.resolve(ParElem::hanging_indent), }, ) } @@ -184,8 +184,8 @@ fn configuration( situation: Option<ParSituation>, ) -> Config { let justify = base.justify; - let font_size = TextElem::size_in(shared); - let dir = TextElem::dir_in(shared); + let font_size = shared.resolve(TextElem::size); + let dir = shared.resolve(TextElem::dir); Config { justify, @@ -207,7 +207,7 @@ fn configuration( Some(ParSituation::Other) => all, None => false, } - && AlignElem::alignment_in(shared).resolve(shared).x == dir.start().into() + && shared.resolve(AlignElem::alignment).x == dir.start().into() { amount.at(font_size) } else { @@ -219,26 +219,26 @@ fn configuration( } else { Abs::zero() }, - numbering_marker: ParLine::numbering_in(shared).map(|numbering| { + numbering_marker: shared.get_cloned(ParLine::numbering).map(|numbering| { Packed::new(ParLineMarker::new( numbering, - ParLine::number_align_in(shared), - ParLine::number_margin_in(shared), + shared.get(ParLine::number_align), + shared.get(ParLine::number_margin), // Delay resolving the number clearance until line numbers are // laid out to avoid inconsistent spacing depending on varying // font size. - ParLine::number_clearance_in(shared), + shared.get(ParLine::number_clearance), )) }), - align: AlignElem::alignment_in(shared).fix(dir).x, + align: shared.get(AlignElem::alignment).fix(dir).x, font_size, dir, - hyphenate: shared_get(children, shared, TextElem::hyphenate_in) + hyphenate: shared_get(children, shared, |s| s.get(TextElem::hyphenate)) .map(|uniform| uniform.unwrap_or(justify)), - lang: shared_get(children, shared, TextElem::lang_in), - fallback: TextElem::fallback_in(shared), - cjk_latin_spacing: TextElem::cjk_latin_spacing_in(shared).is_auto(), - costs: TextElem::costs_in(shared), + lang: shared_get(children, shared, |s| s.get(TextElem::lang)), + fallback: shared.get(TextElem::fallback), + cjk_latin_spacing: shared.get(TextElem::cjk_latin_spacing).is_auto(), + costs: shared.get(TextElem::costs), } } @@ -314,7 +314,7 @@ fn shared_get<T: PartialEq>( /// When we support some kind of more general ancestry mechanism, this can /// become more elegant. fn in_list(styles: StyleChain) -> bool { - ListElem::depth_in(styles).0 > 0 - || !EnumElem::parents_in(styles).is_empty() - || TermsElem::within_in(styles) + styles.get(ListElem::depth).0 > 0 + || !styles.get_cloned(EnumElem::parents).is_empty() + || styles.get(TermsElem::within) } diff --git a/crates/typst-layout/src/inline/shaping.rs b/crates/typst-layout/src/inline/shaping.rs index 48747cd5..d1e748da 100644 --- a/crates/typst-layout/src/inline/shaping.rs +++ b/crates/typst-layout/src/inline/shaping.rs @@ -223,12 +223,12 @@ impl<'a> ShapedText<'a> { let mut frame = Frame::soft(size); frame.set_baseline(top); - let size = TextElem::size_in(self.styles); - let shift = TextElem::baseline_in(self.styles); - let decos = TextElem::deco_in(self.styles); - let fill = TextElem::fill_in(self.styles); - let stroke = TextElem::stroke_in(self.styles); - let span_offset = TextElem::span_offset_in(self.styles); + let size = self.styles.resolve(TextElem::size); + let shift = self.styles.resolve(TextElem::baseline); + let decos = self.styles.get_cloned(TextElem::deco); + let fill = self.styles.get_ref(TextElem::fill); + let stroke = self.styles.resolve(TextElem::stroke); + let span_offset = self.styles.get(TextElem::span_offset); for ((font, y_offset, glyph_size), group) in self .glyphs @@ -340,9 +340,9 @@ impl<'a> ShapedText<'a> { let mut top = Abs::zero(); let mut bottom = Abs::zero(); - let size = TextElem::size_in(self.styles); - let top_edge = TextElem::top_edge_in(self.styles); - let bottom_edge = TextElem::bottom_edge_in(self.styles); + let size = self.styles.resolve(TextElem::size); + let top_edge = self.styles.get(TextElem::top_edge); + let bottom_edge = self.styles.get(TextElem::bottom_edge); // Expand top and bottom by reading the font's vertical metrics. let mut expand = |font: &Font, bounds: TextEdgeBounds| { @@ -486,7 +486,7 @@ impl<'a> ShapedText<'a> { // that subtracting either of the endpoints by self.base doesn't // underflow. See <https://github.com/typst/typst/issues/2283>. .unwrap_or_else(|| self.base..self.base); - let size = TextElem::size_in(self.styles); + let size = self.styles.resolve(TextElem::size); self.width += x_advance.at(size); let glyph = ShapedGlyph { font, @@ -603,9 +603,9 @@ pub fn shape_range<'a>( range: Range, styles: StyleChain<'a>, ) { - let script = TextElem::script_in(styles); - let lang = TextElem::lang_in(styles); - let region = TextElem::region_in(styles); + let script = styles.get(TextElem::script); + let lang = styles.get(TextElem::lang); + let region = styles.get(TextElem::region); let mut process = |range: Range, level: BidiLevel| { let dir = if level.is_ltr() { Dir::LTR } else { Dir::RTL }; let shaped = @@ -669,8 +669,8 @@ fn shape<'a>( lang: Lang, region: Option<Region>, ) -> ShapedText<'a> { - let size = TextElem::size_in(styles); - let shift_settings = TextElem::shift_settings_in(styles); + let size = styles.resolve(TextElem::size); + let shift_settings = styles.get(TextElem::shift_settings); let mut ctx = ShapingContext { engine, size, @@ -679,7 +679,7 @@ fn shape<'a>( styles, variant: variant(styles), features: features(styles), - fallback: TextElem::fallback_in(styles), + fallback: styles.get(TextElem::fallback), dir, shift_settings, }; @@ -783,7 +783,7 @@ fn shape_segment<'a>( let mut buffer = UnicodeBuffer::new(); buffer.push_str(text); buffer.set_language(language(ctx.styles)); - if let Some(script) = TextElem::script_in(ctx.styles).custom().and_then(|script| { + if let Some(script) = ctx.styles.get(TextElem::script).custom().and_then(|script| { rustybuzz::Script::from_iso15924_tag(Tag::from_bytes(script.as_bytes())) }) { buffer.set_script(script) @@ -1073,8 +1073,11 @@ fn shape_tofus(ctx: &mut ShapingContext, base: usize, text: &str, font: Font) { /// Apply tracking and spacing to the shaped glyphs. fn track_and_space(ctx: &mut ShapingContext) { - let tracking = Em::from_abs(TextElem::tracking_in(ctx.styles), ctx.size); - let spacing = TextElem::spacing_in(ctx.styles).map(|abs| Em::from_abs(abs, ctx.size)); + let tracking = Em::from_abs(ctx.styles.resolve(TextElem::tracking), ctx.size); + let spacing = ctx + .styles + .resolve(TextElem::spacing) + .map(|abs| Em::from_abs(abs, ctx.size)); let mut glyphs = ctx.glyphs.iter_mut().peekable(); while let Some(glyph) = glyphs.next() { diff --git a/crates/typst-layout/src/lists.rs b/crates/typst-layout/src/lists.rs index 974788a7..adb793fb 100644 --- a/crates/typst-layout/src/lists.rs +++ b/crates/typst-layout/src/lists.rs @@ -20,20 +20,21 @@ pub fn layout_list( styles: StyleChain, regions: Regions, ) -> SourceResult<Fragment> { - let indent = elem.indent(styles); - let body_indent = elem.body_indent(styles); - let tight = elem.tight(styles); - let gutter = elem.spacing(styles).unwrap_or_else(|| { + let indent = elem.indent.get(styles); + let body_indent = elem.body_indent.get(styles); + let tight = elem.tight.get(styles); + let gutter = elem.spacing.get(styles).unwrap_or_else(|| { if tight { - ParElem::leading_in(styles).into() + styles.get(ParElem::leading) } else { - ParElem::spacing_in(styles).into() + styles.get(ParElem::spacing) } }); - let Depth(depth) = ListElem::depth_in(styles); + let Depth(depth) = styles.get(ListElem::depth); let marker = elem - .marker(styles) + .marker + .get_ref(styles) .resolve(engine, styles, depth)? // avoid '#set align' interference with the list .aligned(HAlignment::Start + VAlignment::Top); @@ -52,7 +53,7 @@ pub fn layout_list( cells.push(Cell::new(marker.clone(), locator.next(&marker.span()))); cells.push(Cell::new(Content::empty(), locator.next(&()))); cells.push(Cell::new( - body.styled(ListElem::set_depth(Depth(1))), + body.set(ListElem::depth, Depth(1)), locator.next(&item.body.span()), )); } @@ -81,40 +82,40 @@ pub fn layout_enum( styles: StyleChain, regions: Regions, ) -> SourceResult<Fragment> { - let numbering = elem.numbering(styles); - let reversed = elem.reversed(styles); - let indent = elem.indent(styles); - let body_indent = elem.body_indent(styles); - let tight = elem.tight(styles); - let gutter = elem.spacing(styles).unwrap_or_else(|| { + let numbering = elem.numbering.get_ref(styles); + let reversed = elem.reversed.get(styles); + let indent = elem.indent.get(styles); + let body_indent = elem.body_indent.get(styles); + let tight = elem.tight.get(styles); + let gutter = elem.spacing.get(styles).unwrap_or_else(|| { if tight { - ParElem::leading_in(styles).into() + styles.get(ParElem::leading) } else { - ParElem::spacing_in(styles).into() + styles.get(ParElem::spacing) } }); let mut cells = vec![]; let mut locator = locator.split(); - let mut number = elem.start(styles).unwrap_or_else(|| { + let mut number = elem.start.get(styles).unwrap_or_else(|| { if reversed { elem.children.len() as u64 } else { 1 } }); - let mut parents = EnumElem::parents_in(styles); + let mut parents = styles.get_cloned(EnumElem::parents); - let full = elem.full(styles); + let full = elem.full.get(styles); // Horizontally align based on the given respective parameter. // Vertically align to the top to avoid inheriting `horizon` or `bottom` // alignment from the context and having the number be displaced in // relation to the item it refers to. - let number_align = elem.number_align(styles); + let number_align = elem.number_align.get(styles); for item in &elem.children { - number = item.number(styles).unwrap_or(number); + number = item.number.get(styles).unwrap_or(number); let context = Context::new(None, Some(styles)); let resolved = if full { @@ -133,8 +134,7 @@ pub fn layout_enum( // Disable overhang as a workaround to end-aligned dots glitching // and decreasing spacing between numbers and items. - let resolved = - resolved.aligned(number_align).styled(TextElem::set_overhang(false)); + let resolved = resolved.aligned(number_align).set(TextElem::overhang, false); // Text in wide enums shall always turn into paragraphs. let mut body = item.body.clone(); @@ -146,7 +146,7 @@ pub fn layout_enum( cells.push(Cell::new(resolved, locator.next(&()))); cells.push(Cell::new(Content::empty(), locator.next(&()))); cells.push(Cell::new( - body.styled(EnumElem::set_parents(smallvec![number])), + body.set(EnumElem::parents, smallvec![number]), locator.next(&item.body.span()), )); number = diff --git a/crates/typst-layout/src/math/accent.rs b/crates/typst-layout/src/math/accent.rs index 159703b8..e7f051ac 100644 --- a/crates/typst-layout/src/math/accent.rs +++ b/crates/typst-layout/src/math/accent.rs @@ -24,7 +24,7 @@ pub fn layout_accent( // Try to replace the base glyph with its dotless variant. let dtls = style_dtls(); let base_styles = - if top_accent && elem.dotless(styles) { styles.chain(&dtls) } else { styles }; + if top_accent && elem.dotless.get(styles) { styles.chain(&dtls) } else { styles }; let cramped = style_cramped(); let base = ctx.layout_into_fragment(&elem.base, base_styles.chain(&cramped))?; @@ -47,7 +47,7 @@ pub fn layout_accent( // Forcing the accent to be at least as large as the base makes it too wide // in many cases. - let width = elem.size(styles).relative_to(base.width()); + let width = elem.size.resolve(styles).relative_to(base.width()); let short_fall = ACCENT_SHORT_FALL.at(glyph.item.size); glyph.stretch_horizontal(ctx, width - short_fall); let accent_attach = glyph.accent_attach.0; diff --git a/crates/typst-layout/src/math/attach.rs b/crates/typst-layout/src/math/attach.rs index a7f3cad5..78b6f551 100644 --- a/crates/typst-layout/src/math/attach.rs +++ b/crates/typst-layout/src/math/attach.rs @@ -31,16 +31,16 @@ pub fn layout_attach( let mut base = ctx.layout_into_fragment(&elem.base, styles)?; let sup_style = style_for_superscript(styles); let sup_style_chain = styles.chain(&sup_style); - let tl = elem.tl(sup_style_chain); - let tr = elem.tr(sup_style_chain); + let tl = elem.tl.get_cloned(sup_style_chain); + let tr = elem.tr.get_cloned(sup_style_chain); let primed = tr.as_ref().is_some_and(|content| content.is::<PrimesElem>()); - let t = elem.t(sup_style_chain); + let t = elem.t.get_cloned(sup_style_chain); let sub_style = style_for_subscript(styles); let sub_style_chain = styles.chain(&sub_style); - let bl = elem.bl(sub_style_chain); - let br = elem.br(sub_style_chain); - let b = elem.b(sub_style_chain); + let bl = elem.bl.get_cloned(sub_style_chain); + let br = elem.br.get_cloned(sub_style_chain); + let b = elem.b.get_cloned(sub_style_chain); let limits = base.limits().active(styles); let (t, tr) = match (t, tr) { @@ -146,7 +146,7 @@ pub fn layout_limits( ctx: &mut MathContext, styles: StyleChain, ) -> SourceResult<()> { - let limits = if elem.inline(styles) { Limits::Always } else { Limits::Display }; + let limits = if elem.inline.get(styles) { Limits::Always } else { Limits::Display }; let mut fragment = ctx.layout_into_fragment(&elem.body, styles)?; fragment.set_limits(limits); ctx.push(fragment); @@ -161,7 +161,8 @@ fn stretch_size(styles: StyleChain, elem: &Packed<AttachElem>) -> Option<Rel<Abs base = &equation.body; } - base.to_packed::<StretchElem>().map(|stretch| stretch.size(styles)) + base.to_packed::<StretchElem>() + .map(|stretch| stretch.size.resolve(styles)) } /// Lay out the attachments. @@ -397,7 +398,7 @@ fn compute_script_shifts( base: &MathFragment, [tl, tr, bl, br]: [&Option<MathFragment>; 4], ) -> (Abs, Abs) { - let sup_shift_up = if EquationElem::cramped_in(styles) { + let sup_shift_up = if styles.get(EquationElem::cramped) { scaled!(ctx, styles, superscript_shift_up_cramped) } else { scaled!(ctx, styles, superscript_shift_up) diff --git a/crates/typst-layout/src/math/cancel.rs b/crates/typst-layout/src/math/cancel.rs index 9826397f..57a32ca2 100644 --- a/crates/typst-layout/src/math/cancel.rs +++ b/crates/typst-layout/src/math/cancel.rs @@ -27,16 +27,16 @@ pub fn layout_cancel( let mut body = body.into_frame(); let body_size = body.size(); let span = elem.span(); - let length = elem.length(styles); + let length = elem.length.resolve(styles); - let stroke = elem.stroke(styles).unwrap_or(FixedStroke { - paint: TextElem::fill_in(styles).as_decoration(), + let stroke = elem.stroke.resolve(styles).unwrap_or(FixedStroke { + paint: styles.get_ref(TextElem::fill).as_decoration(), ..Default::default() }); - let invert = elem.inverted(styles); - let cross = elem.cross(styles); - let angle = elem.angle(styles); + let invert = elem.inverted.get(styles); + let cross = elem.cross.get(styles); + let angle = elem.angle.get_ref(styles); let invert_first_line = !cross && invert; let first_line = draw_cancel_line( @@ -44,7 +44,7 @@ pub fn layout_cancel( length, stroke.clone(), invert_first_line, - &angle, + angle, body_size, styles, span, @@ -57,7 +57,7 @@ pub fn layout_cancel( if cross { // Draw the second line. let second_line = - draw_cancel_line(ctx, length, stroke, true, &angle, body_size, styles, span)?; + draw_cancel_line(ctx, length, stroke, true, angle, body_size, styles, span)?; body.push_frame(center, second_line); } diff --git a/crates/typst-layout/src/math/frac.rs b/crates/typst-layout/src/math/frac.rs index 091f328f..12a2c6fd 100644 --- a/crates/typst-layout/src/math/frac.rs +++ b/crates/typst-layout/src/math/frac.rs @@ -124,7 +124,7 @@ fn layout_frac_like( FrameItem::Shape( Geometry::Line(Point::with_x(line_width)).stroked( FixedStroke::from_pair( - TextElem::fill_in(styles).as_decoration(), + styles.get_ref(TextElem::fill).as_decoration(), thickness, ), ), diff --git a/crates/typst-layout/src/math/fragment.rs b/crates/typst-layout/src/math/fragment.rs index c5891f7d..758dd401 100644 --- a/crates/typst-layout/src/math/fragment.rs +++ b/crates/typst-layout/src/math/fragment.rs @@ -315,7 +315,8 @@ impl GlyphFragment { let cluster = info.cluster as usize; let c = text[cluster..].chars().next().unwrap(); let limits = Limits::for_char(c); - let class = EquationElem::class_in(styles) + let class = styles + .get(EquationElem::class) .or_else(|| default_math_class(c)) .unwrap_or(MathClass::Normal); @@ -331,11 +332,11 @@ impl GlyphFragment { let item = TextItem { font: font.clone(), - size: TextElem::size_in(styles), - fill: TextElem::fill_in(styles).as_decoration(), - stroke: TextElem::stroke_in(styles).map(|s| s.unwrap_or_default()), - lang: TextElem::lang_in(styles), - region: TextElem::region_in(styles), + size: styles.resolve(TextElem::size), + fill: styles.get_ref(TextElem::fill).as_decoration(), + stroke: styles.resolve(TextElem::stroke).map(|s| s.unwrap_or_default()), + lang: styles.get(TextElem::lang), + region: styles.get(TextElem::region), text: text.into(), glyphs: vec![glyph.clone()], }; @@ -344,7 +345,7 @@ impl GlyphFragment { item, base_glyph: glyph, // Math - math_size: EquationElem::size_in(styles), + math_size: styles.get(EquationElem::size), class, limits, mid_stretched: None, @@ -356,7 +357,7 @@ impl GlyphFragment { baseline: None, // Misc align: Abs::zero(), - shift: TextElem::baseline_in(styles), + shift: styles.resolve(TextElem::baseline), modifiers: FrameModifiers::get_in(styles), }; fragment.update_glyph(); @@ -541,9 +542,9 @@ impl FrameFragment { let accent_attach = frame.width() / 2.0; Self { frame: frame.modified(&FrameModifiers::get_in(styles)), - font_size: TextElem::size_in(styles), - class: EquationElem::class_in(styles).unwrap_or(MathClass::Normal), - math_size: EquationElem::size_in(styles), + font_size: styles.resolve(TextElem::size), + class: styles.get(EquationElem::class).unwrap_or(MathClass::Normal), + math_size: styles.get(EquationElem::size), limits: Limits::Never, spaced: false, base_ascent, @@ -864,7 +865,7 @@ impl Limits { pub fn active(&self, styles: StyleChain) -> bool { match self { Self::Always => true, - Self::Display => EquationElem::size_in(styles) == MathSize::Display, + Self::Display => styles.get(EquationElem::size) == MathSize::Display, Self::Never => false, } } diff --git a/crates/typst-layout/src/math/lr.rs b/crates/typst-layout/src/math/lr.rs index a3b5cb05..2348025e 100644 --- a/crates/typst-layout/src/math/lr.rs +++ b/crates/typst-layout/src/math/lr.rs @@ -22,7 +22,7 @@ pub fn layout_lr( // Extract implicit LrElem. if let Some(lr) = body.to_packed::<LrElem>() { - if lr.size(styles).is_one() { + if lr.size.get(styles).is_one() { body = &lr.body; } } @@ -41,7 +41,7 @@ pub fn layout_lr( .unwrap_or_default(); let relative_to = 2.0 * max_extent; - let height = elem.size(styles); + let height = elem.size.resolve(styles); // Scale up fragments at both ends. match inner_fragments { diff --git a/crates/typst-layout/src/math/mat.rs b/crates/typst-layout/src/math/mat.rs index 278b1343..4a897a03 100644 --- a/crates/typst-layout/src/math/mat.rs +++ b/crates/typst-layout/src/math/mat.rs @@ -30,15 +30,15 @@ pub fn layout_vec( ctx, styles, &[column], - elem.align(styles), + elem.align.resolve(styles), LeftRightAlternator::Right, None, - Axes::with_y(elem.gap(styles)), + Axes::with_y(elem.gap.resolve(styles)), span, "elements", )?; - let delim = elem.delim(styles); + let delim = elem.delim.get(styles); layout_delimiters(ctx, styles, frame, delim.open(), delim.close(), span) } @@ -59,14 +59,17 @@ pub fn layout_cases( FixedAlignment::Start, LeftRightAlternator::None, None, - Axes::with_y(elem.gap(styles)), + Axes::with_y(elem.gap.resolve(styles)), span, "branches", )?; - let delim = elem.delim(styles); - let (open, close) = - if elem.reverse(styles) { (None, delim.close()) } else { (delim.open(), None) }; + let delim = elem.delim.get(styles); + let (open, close) = if elem.reverse.get(styles) { + (None, delim.close()) + } else { + (delim.open(), None) + }; layout_delimiters(ctx, styles, frame, open, close, span) } @@ -81,7 +84,7 @@ pub fn layout_mat( let rows = &elem.rows; let ncols = rows.first().map_or(0, |row| row.len()); - let augment = elem.augment(styles); + let augment = elem.augment.resolve(styles); if let Some(aug) = &augment { for &offset in &aug.hline.0 { if offset == 0 || offset.unsigned_abs() >= rows.len() { @@ -116,15 +119,15 @@ pub fn layout_mat( ctx, styles, &columns, - elem.align(styles), + elem.align.resolve(styles), LeftRightAlternator::Right, augment, - Axes::new(elem.column_gap(styles), elem.row_gap(styles)), + Axes::new(elem.column_gap.resolve(styles), elem.row_gap.resolve(styles)), span, "cells", )?; - let delim = elem.delim(styles); + let delim = elem.delim.get(styles); layout_delimiters(ctx, styles, frame, delim.open(), delim.close(), span) } @@ -157,7 +160,7 @@ fn layout_body( let default_stroke_thickness = DEFAULT_STROKE_THICKNESS.resolve(styles); let default_stroke = FixedStroke { thickness: default_stroke_thickness, - paint: TextElem::fill_in(styles).as_decoration(), + paint: styles.get_ref(TextElem::fill).as_decoration(), cap: LineCap::Square, ..Default::default() }; diff --git a/crates/typst-layout/src/math/mod.rs b/crates/typst-layout/src/math/mod.rs index 5fd22e57..39083506 100644 --- a/crates/typst-layout/src/math/mod.rs +++ b/crates/typst-layout/src/math/mod.rs @@ -51,7 +51,7 @@ pub fn layout_equation_inline( styles: StyleChain, region: Size, ) -> SourceResult<Vec<InlineItem>> { - assert!(!elem.block(styles)); + assert!(!elem.block.get(styles)); let font = find_math_font(engine, styles, elem.span())?; @@ -78,12 +78,12 @@ pub fn layout_equation_inline( for item in &mut items { let InlineItem::Frame(frame) = item else { continue }; - let slack = ParElem::leading_in(styles) * 0.7; + let slack = styles.resolve(ParElem::leading) * 0.7; let (t, b) = font.edges( - TextElem::top_edge_in(styles), - TextElem::bottom_edge_in(styles), - TextElem::size_in(styles), + styles.get(TextElem::top_edge), + styles.get(TextElem::bottom_edge), + styles.resolve(TextElem::size), TextEdgeBounds::Frame(frame), ); @@ -105,7 +105,7 @@ pub fn layout_equation_block( styles: StyleChain, regions: Regions, ) -> SourceResult<Fragment> { - assert!(elem.block(styles)); + assert!(elem.block.get(styles)); let span = elem.span(); let font = find_math_font(engine, styles, span)?; @@ -121,7 +121,7 @@ pub fn layout_equation_block( .multiline_frame_builder(styles); let width = full_equation_builder.size.x; - let equation_builders = if BlockElem::breakable_in(styles) { + let equation_builders = if styles.get(BlockElem::breakable) { let mut rows = full_equation_builder.frames.into_iter().peekable(); let mut equation_builders = vec![]; let mut last_first_pos = Point::zero(); @@ -188,7 +188,7 @@ pub fn layout_equation_block( vec![full_equation_builder] }; - let Some(numbering) = (**elem).numbering(styles) else { + let Some(numbering) = elem.numbering.get_ref(styles) else { let frames = equation_builders .into_iter() .map(MathRunFrameBuilder::build) @@ -197,7 +197,7 @@ pub fn layout_equation_block( }; let pod = Region::new(regions.base(), Axes::splat(false)); - let counter = Counter::of(EquationElem::elem()) + let counter = Counter::of(EquationElem::ELEM) .display_at_loc(engine, elem.location().unwrap(), styles, numbering)? .spanned(span); let number = crate::layout_frame(engine, &counter, locator.next(&()), styles, pod)?; @@ -205,7 +205,7 @@ pub fn layout_equation_block( static NUMBER_GUTTER: Em = Em::new(0.5); let full_number_width = number.width() + NUMBER_GUTTER.resolve(styles); - let number_align = match elem.number_align(styles) { + let number_align = match elem.number_align.get(styles) { SpecificAlignment::H(h) => SpecificAlignment::Both(h, VAlignment::Horizon), SpecificAlignment::V(v) => SpecificAlignment::Both(OuterHAlignment::End, v), SpecificAlignment::Both(h, v) => SpecificAlignment::Both(h, v), @@ -224,7 +224,7 @@ pub fn layout_equation_block( builder, number.clone(), number_align.resolve(styles), - AlignElem::alignment_in(styles).resolve(styles).x, + styles.get(AlignElem::alignment).resolve(styles).x, regions.size.x, full_number_width, ) @@ -472,7 +472,9 @@ impl<'a, 'v, 'e> MathContext<'a, 'v, 'e> { let outer = styles; for (elem, styles) in pairs { // Hack because the font is fixed in math. - if styles != outer && TextElem::font_in(styles) != TextElem::font_in(outer) { + if styles != outer + && styles.get_ref(TextElem::font) != outer.get_ref(TextElem::font) + { let frame = layout_external(elem, self, styles)?; self.push(FrameFragment::new(styles, frame).with_spaced(true)); continue; @@ -603,7 +605,10 @@ fn layout_h( ) -> SourceResult<()> { if let Spacing::Rel(rel) = elem.amount { if rel.rel.is_zero() { - ctx.push(MathFragment::Spacing(rel.abs.resolve(styles), elem.weak(styles))); + ctx.push(MathFragment::Spacing( + rel.abs.resolve(styles), + elem.weak.get(styles), + )); } } Ok(()) @@ -616,7 +621,7 @@ fn layout_class( ctx: &mut MathContext, styles: StyleChain, ) -> SourceResult<()> { - let style = EquationElem::set_class(Some(elem.class)).wrap(); + let style = EquationElem::class.set(Some(elem.class)).wrap(); let mut fragment = ctx.layout_into_fragment(&elem.body, styles.chain(&style))?; fragment.set_class(elem.class); fragment.set_limits(Limits::for_class(elem.class)); @@ -642,7 +647,7 @@ fn layout_op( .with_italics_correction(italics) .with_accent_attach(accent_attach) .with_text_like(text_like) - .with_limits(if elem.limits(styles) { + .with_limits(if elem.limits.get(styles) { Limits::Display } else { Limits::Never diff --git a/crates/typst-layout/src/math/root.rs b/crates/typst-layout/src/math/root.rs index 91b9b16a..30948e08 100644 --- a/crates/typst-layout/src/math/root.rs +++ b/crates/typst-layout/src/math/root.rs @@ -17,7 +17,7 @@ pub fn layout_root( ctx: &mut MathContext, styles: StyleChain, ) -> SourceResult<()> { - let index = elem.index(styles); + let index = elem.index.get_ref(styles); let span = elem.span(); let gap = scaled!( @@ -54,7 +54,7 @@ pub fn layout_root( let sqrt = sqrt.into_frame(); // Layout the index. - let sscript = EquationElem::set_size(MathSize::ScriptScript).wrap(); + let sscript = EquationElem::size.set(MathSize::ScriptScript).wrap(); let index = index .as_ref() .map(|elem| ctx.layout_into_frame(elem, styles.chain(&sscript))) @@ -112,7 +112,7 @@ pub fn layout_root( FrameItem::Shape( Geometry::Line(Point::with_x(radicand.width())).stroked( FixedStroke::from_pair( - TextElem::fill_in(styles).as_decoration(), + styles.get_ref(TextElem::fill).as_decoration(), thickness, ), ), diff --git a/crates/typst-layout/src/math/run.rs b/crates/typst-layout/src/math/run.rs index 4ec76c25..161fa106 100644 --- a/crates/typst-layout/src/math/run.rs +++ b/crates/typst-layout/src/math/run.rs @@ -194,13 +194,13 @@ impl MathRun { let row_count = rows.len(); let alignments = alignments(&rows); - let leading = if EquationElem::size_in(styles) >= MathSize::Text { - ParElem::leading_in(styles) + let leading = if styles.get(EquationElem::size) >= MathSize::Text { + styles.resolve(ParElem::leading) } else { TIGHT_LEADING.resolve(styles) }; - let align = AlignElem::alignment_in(styles).resolve(styles).x; + let align = styles.resolve(AlignElem::alignment).x; let mut frames: Vec<(Frame, Point)> = vec![]; let mut size = Size::zero(); for (i, row) in rows.into_iter().enumerate() { diff --git a/crates/typst-layout/src/math/shared.rs b/crates/typst-layout/src/math/shared.rs index 1f88d2dd..c9d20aa6 100644 --- a/crates/typst-layout/src/math/shared.rs +++ b/crates/typst-layout/src/math/shared.rs @@ -10,7 +10,7 @@ use super::{LeftRightAlternator, MathContext, MathFragment, MathRun}; macro_rules! scaled { ($ctx:expr, $styles:expr, text: $text:ident, display: $display:ident $(,)?) => { - match typst_library::math::EquationElem::size_in($styles) { + match $styles.get(typst_library::math::EquationElem::size) { typst_library::math::MathSize::Display => scaled!($ctx, $styles, $display), _ => scaled!($ctx, $styles, $text), } @@ -19,7 +19,7 @@ macro_rules! scaled { $crate::math::Scaled::scaled( $ctx.constants.$name(), $ctx, - typst_library::text::TextElem::size_in($styles), + $styles.resolve(typst_library::text::TextElem::size), ) }; } @@ -58,55 +58,62 @@ impl Scaled for MathValue<'_> { /// Styles something as cramped. pub fn style_cramped() -> LazyHash<Style> { - EquationElem::set_cramped(true).wrap() + EquationElem::cramped.set(true).wrap() } /// Sets flac OpenType feature. pub fn style_flac() -> LazyHash<Style> { - TextElem::set_features(FontFeatures(vec![(Tag::from_bytes(b"flac"), 1)])).wrap() + TextElem::features + .set(FontFeatures(vec![(Tag::from_bytes(b"flac"), 1)])) + .wrap() } /// Sets dtls OpenType feature. pub fn style_dtls() -> LazyHash<Style> { - TextElem::set_features(FontFeatures(vec![(Tag::from_bytes(b"dtls"), 1)])).wrap() + TextElem::features + .set(FontFeatures(vec![(Tag::from_bytes(b"dtls"), 1)])) + .wrap() } /// The style for subscripts in the current style. pub fn style_for_subscript(styles: StyleChain) -> [LazyHash<Style>; 2] { - [style_for_superscript(styles), EquationElem::set_cramped(true).wrap()] + [style_for_superscript(styles), EquationElem::cramped.set(true).wrap()] } /// The style for superscripts in the current style. pub fn style_for_superscript(styles: StyleChain) -> LazyHash<Style> { - EquationElem::set_size(match EquationElem::size_in(styles) { - MathSize::Display | MathSize::Text => MathSize::Script, - MathSize::Script | MathSize::ScriptScript => MathSize::ScriptScript, - }) - .wrap() + EquationElem::size + .set(match styles.get(EquationElem::size) { + MathSize::Display | MathSize::Text => MathSize::Script, + MathSize::Script | MathSize::ScriptScript => MathSize::ScriptScript, + }) + .wrap() } /// The style for numerators in the current style. pub fn style_for_numerator(styles: StyleChain) -> LazyHash<Style> { - EquationElem::set_size(match EquationElem::size_in(styles) { - MathSize::Display => MathSize::Text, - MathSize::Text => MathSize::Script, - MathSize::Script | MathSize::ScriptScript => MathSize::ScriptScript, - }) - .wrap() + EquationElem::size + .set(match styles.get(EquationElem::size) { + MathSize::Display => MathSize::Text, + MathSize::Text => MathSize::Script, + MathSize::Script | MathSize::ScriptScript => MathSize::ScriptScript, + }) + .wrap() } /// The style for denominators in the current style. pub fn style_for_denominator(styles: StyleChain) -> [LazyHash<Style>; 2] { - [style_for_numerator(styles), EquationElem::set_cramped(true).wrap()] + [style_for_numerator(styles), EquationElem::cramped.set(true).wrap()] } /// Styles to add font constants to the style chain. pub fn style_for_script_scale(ctx: &MathContext) -> LazyHash<Style> { - EquationElem::set_script_scale(( - ctx.constants.script_percent_scale_down(), - ctx.constants.script_script_percent_scale_down(), - )) - .wrap() + EquationElem::script_scale + .set(( + ctx.constants.script_percent_scale_down(), + ctx.constants.script_script_percent_scale_down(), + )) + .wrap() } /// Stack rows on top of each other. diff --git a/crates/typst-layout/src/math/stretch.rs b/crates/typst-layout/src/math/stretch.rs index d4370e7b..f1a22a81 100644 --- a/crates/typst-layout/src/math/stretch.rs +++ b/crates/typst-layout/src/math/stretch.rs @@ -14,7 +14,14 @@ pub fn layout_stretch( styles: StyleChain, ) -> SourceResult<()> { let mut fragment = ctx.layout_into_fragment(&elem.body, styles)?; - stretch_fragment(ctx, &mut fragment, None, None, elem.size(styles), Abs::zero()); + stretch_fragment( + ctx, + &mut fragment, + None, + None, + elem.size.resolve(styles), + Abs::zero(), + ); ctx.push(fragment); Ok(()) } diff --git a/crates/typst-layout/src/math/text.rs b/crates/typst-layout/src/math/text.rs index 67dc0a2c..53f88f2b 100644 --- a/crates/typst-layout/src/math/text.rs +++ b/crates/typst-layout/src/math/text.rs @@ -77,8 +77,8 @@ fn layout_inline_text( Ok(FrameFragment::new(styles, frame).with_text_like(true)) } else { let local = [ - TextElem::set_top_edge(TopEdge::Metric(TopEdgeMetric::Bounds)), - TextElem::set_bottom_edge(BottomEdge::Metric(BottomEdgeMetric::Bounds)), + TextElem::top_edge.set(TopEdge::Metric(TopEdgeMetric::Bounds)), + TextElem::bottom_edge.set(BottomEdge::Metric(BottomEdgeMetric::Bounds)), ] .map(|p| p.wrap()); @@ -150,7 +150,7 @@ fn adjust_glyph_layout( styles: StyleChain, ) { if glyph.class == MathClass::Large { - if EquationElem::size_in(styles) == MathSize::Display { + if styles.get(EquationElem::size) == MathSize::Display { let height = scaled!(ctx, styles, display_operator_min_height) .max(SQRT_2 * glyph.size.y); glyph.stretch_vertical(ctx, height); @@ -169,9 +169,9 @@ fn adjust_glyph_layout( fn styled_char(styles: StyleChain, c: char, auto_italic: bool) -> char { use MathVariant::*; - let variant = EquationElem::variant_in(styles); - let bold = EquationElem::bold_in(styles); - let italic = EquationElem::italic_in(styles).unwrap_or( + let variant = styles.get(EquationElem::variant); + let bold = styles.get(EquationElem::bold); + let italic = styles.get(EquationElem::italic).unwrap_or( auto_italic && matches!( c, diff --git a/crates/typst-layout/src/math/underover.rs b/crates/typst-layout/src/math/underover.rs index c29d9947..1e1aeb41 100644 --- a/crates/typst-layout/src/math/underover.rs +++ b/crates/typst-layout/src/math/underover.rs @@ -56,7 +56,7 @@ pub fn layout_underbrace( ctx, styles, &elem.body, - &elem.annotation(styles), + elem.annotation.get_ref(styles), '⏟', BRACE_GAP, Position::Under, @@ -75,7 +75,7 @@ pub fn layout_overbrace( ctx, styles, &elem.body, - &elem.annotation(styles), + elem.annotation.get_ref(styles), '⏞', BRACE_GAP, Position::Over, @@ -94,7 +94,7 @@ pub fn layout_underbracket( ctx, styles, &elem.body, - &elem.annotation(styles), + elem.annotation.get_ref(styles), '⎵', BRACKET_GAP, Position::Under, @@ -113,7 +113,7 @@ pub fn layout_overbracket( ctx, styles, &elem.body, - &elem.annotation(styles), + elem.annotation.get_ref(styles), '⎴', BRACKET_GAP, Position::Over, @@ -132,7 +132,7 @@ pub fn layout_underparen( ctx, styles, &elem.body, - &elem.annotation(styles), + elem.annotation.get_ref(styles), '⏝', PAREN_GAP, Position::Under, @@ -151,7 +151,7 @@ pub fn layout_overparen( ctx, styles, &elem.body, - &elem.annotation(styles), + elem.annotation.get_ref(styles), '⏜', PAREN_GAP, Position::Over, @@ -170,7 +170,7 @@ pub fn layout_undershell( ctx, styles, &elem.body, - &elem.annotation(styles), + elem.annotation.get_ref(styles), '⏡', SHELL_GAP, Position::Under, @@ -189,7 +189,7 @@ pub fn layout_overshell( ctx, styles, &elem.body, - &elem.annotation(styles), + elem.annotation.get_ref(styles), '⏠', SHELL_GAP, Position::Over, @@ -251,7 +251,7 @@ fn layout_underoverline( line_pos, FrameItem::Shape( Geometry::Line(Point::with_x(line_width)).stroked(FixedStroke { - paint: TextElem::fill_in(styles).as_decoration(), + paint: styles.get_ref(TextElem::fill).as_decoration(), thickness: bar_height, ..FixedStroke::default() }), diff --git a/crates/typst-layout/src/modifiers.rs b/crates/typst-layout/src/modifiers.rs index b0371d63..57d70302 100644 --- a/crates/typst-layout/src/modifiers.rs +++ b/crates/typst-layout/src/modifiers.rs @@ -29,8 +29,8 @@ impl FrameModifiers { /// Retrieve all modifications that should be applied per-frame. pub fn get_in(styles: StyleChain) -> Self { Self { - dest: LinkElem::current_in(styles), - hidden: HideElem::hidden_in(styles), + dest: styles.get_cloned(LinkElem::current), + hidden: styles.get(HideElem::hidden), } } } @@ -83,7 +83,7 @@ pub trait FrameModifyText { impl FrameModifyText for Frame { fn modify_text(&mut self, styles: StyleChain) { let modifiers = FrameModifiers::get_in(styles); - let expand_y = 0.5 * ParElem::leading_in(styles); + let expand_y = 0.5 * styles.resolve(ParElem::leading); let outset = Sides::new(Abs::zero(), expand_y, Abs::zero(), expand_y); modify_frame(self, &modifiers, Some(outset)); } @@ -130,7 +130,7 @@ where let outer = styles; let mut styles = styles; if modifiers.dest.is_some() { - reset = LinkElem::set_current(None).wrap(); + reset = LinkElem::current.set(None).wrap(); styles = outer.chain(&reset); } diff --git a/crates/typst-layout/src/pad.rs b/crates/typst-layout/src/pad.rs index 00badcdb..b69e0de4 100644 --- a/crates/typst-layout/src/pad.rs +++ b/crates/typst-layout/src/pad.rs @@ -1,6 +1,6 @@ use typst_library::diag::SourceResult; use typst_library::engine::Engine; -use typst_library::foundations::{Packed, Resolve, StyleChain}; +use typst_library::foundations::{Packed, StyleChain}; use typst_library::introspection::Locator; use typst_library::layout::{ Abs, Fragment, Frame, PadElem, Point, Regions, Rel, Sides, Size, @@ -16,10 +16,10 @@ pub fn layout_pad( regions: Regions, ) -> SourceResult<Fragment> { let padding = Sides::new( - elem.left(styles).resolve(styles), - elem.top(styles).resolve(styles), - elem.right(styles).resolve(styles), - elem.bottom(styles).resolve(styles), + elem.left.resolve(styles), + elem.top.resolve(styles), + elem.right.resolve(styles), + elem.bottom.resolve(styles), ); let mut backlog = vec![]; diff --git a/crates/typst-layout/src/pages/collect.rs b/crates/typst-layout/src/pages/collect.rs index 8eab18a6..64167d08 100644 --- a/crates/typst-layout/src/pages/collect.rs +++ b/crates/typst-layout/src/pages/collect.rs @@ -39,14 +39,14 @@ pub fn collect<'a>( if let Some(pagebreak) = elem.to_packed::<PagebreakElem>() { // Add a blank page if we encounter a strong pagebreak and there was // a staged empty page. - let strong = !pagebreak.weak(styles); + let strong = !pagebreak.weak.get(styles); if strong && staged_empty_page { let locator = locator.next(&elem.span()); items.push(Item::Run(&[], initial, locator)); } // Add an instruction to adjust the page parity if requested. - if let Some(parity) = pagebreak.to(styles) { + if let Some(parity) = pagebreak.to.get(styles) { let locator = locator.next(&elem.span()); items.push(Item::Parity(parity, styles, locator)); } @@ -56,7 +56,7 @@ pub fn collect<'a>( // the scope of a page set rule to ensure a page boundary. Its // styles correspond to the styles _before_ the page set rule, so we // don't want to apply it to a potential empty page. - if !pagebreak.boundary(styles) { + if !pagebreak.boundary.get(styles) { initial = styles; } @@ -94,7 +94,7 @@ pub fn collect<'a>( if group.iter().all(|(c, _)| c.is::<TagElem>()) && !(staged_empty_page && children.iter().all(|&(c, s)| { - c.to_packed::<PagebreakElem>().is_some_and(|c| c.boundary(s)) + c.to_packed::<PagebreakElem>().is_some_and(|c| c.boundary.get(s)) })) { items.push(Item::Tags(group)); diff --git a/crates/typst-layout/src/pages/run.rs b/crates/typst-layout/src/pages/run.rs index 6d2d29da..8c1a34ed 100644 --- a/crates/typst-layout/src/pages/run.rs +++ b/crates/typst-layout/src/pages/run.rs @@ -101,10 +101,10 @@ fn layout_page_run_impl( // When one of the lengths is infinite the page fits its content along // that axis. - let width = PageElem::width_in(styles).unwrap_or(Abs::inf()); - let height = PageElem::height_in(styles).unwrap_or(Abs::inf()); + let width = styles.resolve(PageElem::width).unwrap_or(Abs::inf()); + let height = styles.resolve(PageElem::height).unwrap_or(Abs::inf()); let mut size = Size::new(width, height); - if PageElem::flipped_in(styles) { + if styles.get(PageElem::flipped) { std::mem::swap(&mut size.x, &mut size.y); } @@ -115,7 +115,7 @@ fn layout_page_run_impl( // Determine the margins. let default = Rel::<Length>::from((2.5 / 21.0) * min); - let margin = PageElem::margin_in(styles); + let margin = styles.get(PageElem::margin); let two_sided = margin.two_sided.unwrap_or(false); let margin = margin .sides @@ -123,22 +123,24 @@ fn layout_page_run_impl( .resolve(styles) .relative_to(size); - let fill = PageElem::fill_in(styles); - let foreground = PageElem::foreground_in(styles); - let background = PageElem::background_in(styles); - let header_ascent = PageElem::header_ascent_in(styles).relative_to(margin.top); - let footer_descent = PageElem::footer_descent_in(styles).relative_to(margin.bottom); - let numbering = PageElem::numbering_in(styles); - let supplement = match PageElem::supplement_in(styles) { + let fill = styles.get_cloned(PageElem::fill); + let foreground = styles.get_ref(PageElem::foreground); + let background = styles.get_ref(PageElem::background); + let header_ascent = styles.resolve(PageElem::header_ascent).relative_to(margin.top); + let footer_descent = + styles.resolve(PageElem::footer_descent).relative_to(margin.bottom); + let numbering = styles.get_ref(PageElem::numbering); + let supplement = match styles.get_cloned(PageElem::supplement) { Smart::Auto => TextElem::packed(PageElem::local_name_in(styles)), Smart::Custom(content) => content.unwrap_or_default(), }; - let number_align = PageElem::number_align_in(styles); - let binding = - PageElem::binding_in(styles).unwrap_or_else(|| match TextElem::dir_in(styles) { + let number_align = styles.get(PageElem::number_align); + let binding = styles.get(PageElem::binding).unwrap_or_else(|| { + match styles.resolve(TextElem::dir) { Dir::LTR => Binding::Left, _ => Binding::Right, - }); + } + }); // Construct the numbering (for header or footer). let numbering_marginal = numbering.as_ref().map(|numbering| { @@ -163,8 +165,8 @@ fn layout_page_run_impl( counter }); - let header = PageElem::header_in(styles); - let footer = PageElem::footer_in(styles); + let header = styles.get_ref(PageElem::header); + let footer = styles.get_ref(PageElem::footer); let (header, footer) = if matches!(number_align.y(), Some(OuterVAlignment::Top)) { (header.as_ref().unwrap_or(&numbering_marginal), footer.as_ref().unwrap_or(&None)) } else { @@ -179,15 +181,15 @@ fn layout_page_run_impl( &mut locator, styles, Regions::repeat(area, area.map(Abs::is_finite)), - PageElem::columns_in(styles), - ColumnsElem::gutter_in(styles), + styles.get(PageElem::columns), + styles.get(ColumnsElem::gutter).resolve(styles), FlowMode::Root, )?; // Layouts a single marginal. let mut layout_marginal = |content: &Option<Content>, area, align| { let Some(content) = content else { return Ok(None) }; - let aligned = content.clone().styled(AlignElem::set_alignment(align)); + let aligned = content.clone().set(AlignElem::alignment, align); crate::layout_frame( &mut engine, &aligned, diff --git a/crates/typst-layout/src/repeat.rs b/crates/typst-layout/src/repeat.rs index bfc7b32c..40179c34 100644 --- a/crates/typst-layout/src/repeat.rs +++ b/crates/typst-layout/src/repeat.rs @@ -29,7 +29,7 @@ pub fn layout_repeat( frame.set_baseline(piece.baseline()); } - let mut gap = elem.gap(styles).resolve(styles); + let mut gap = elem.gap.resolve(styles); let fill = region.size.x; let width = piece.width(); @@ -47,12 +47,12 @@ pub fn layout_repeat( let count = ((fill + gap) / (width + gap)).floor(); let remaining = (fill + gap) % (width + gap); - let justify = elem.justify(styles); + let justify = elem.justify.get(styles); if justify { gap += remaining / (count - 1.0); } - let align = AlignElem::alignment_in(styles).resolve(styles); + let align = styles.get(AlignElem::alignment).resolve(styles); let mut offset = Abs::zero(); if count == 1.0 || !justify { offset += align.x.position(remaining); diff --git a/crates/typst-layout/src/shapes.rs b/crates/typst-layout/src/shapes.rs index 0616b4ce..1a9b38f2 100644 --- a/crates/typst-layout/src/shapes.rs +++ b/crates/typst-layout/src/shapes.rs @@ -27,16 +27,20 @@ pub fn layout_line( region: Region, ) -> SourceResult<Frame> { let resolve = |axes: Axes<Rel<Abs>>| axes.zip_map(region.size, Rel::relative_to); - let start = resolve(elem.start(styles)); - let delta = elem.end(styles).map(|end| resolve(end) - start).unwrap_or_else(|| { - let length = elem.length(styles); - let angle = elem.angle(styles); - let x = angle.cos() * length; - let y = angle.sin() * length; - resolve(Axes::new(x, y)) - }); - - let stroke = elem.stroke(styles).unwrap_or_default(); + let start = resolve(elem.start.resolve(styles)); + let delta = elem + .end + .resolve(styles) + .map(|end| resolve(end) - start) + .unwrap_or_else(|| { + let length = elem.length.resolve(styles); + let angle = elem.angle.get(styles); + let x = angle.cos() * length; + let y = angle.sin() * length; + resolve(Axes::new(x, y)) + }); + + let stroke = elem.stroke.resolve(styles).unwrap_or_default(); let size = start.max(start + delta).max(Size::zero()); if !size.is_finite() { @@ -105,7 +109,7 @@ pub fn layout_path( add_cubic(from_point, to_point, from, to); } - if elem.closed(styles) { + if elem.closed.get(styles) { let from = *vertices.last().unwrap(); // We checked that we have at least one element. let to = vertices[0]; let from_point = *points.last().unwrap(); @@ -120,9 +124,9 @@ pub fn layout_path( } // Prepare fill and stroke. - let fill = elem.fill(styles); - let fill_rule = elem.fill_rule(styles); - let stroke = match elem.stroke(styles) { + let fill = elem.fill.get_cloned(styles); + let fill_rule = elem.fill_rule.get(styles); + let stroke = match elem.stroke.resolve(styles) { Smart::Auto if fill.is_none() => Some(FixedStroke::default()), Smart::Auto => None, Smart::Custom(stroke) => stroke.map(Stroke::unwrap_or_default), @@ -153,19 +157,19 @@ pub fn layout_curve( for item in &elem.components { match item { CurveComponent::Move(element) => { - let relative = element.relative(styles); + let relative = element.relative.get(styles); let point = builder.resolve_point(element.start, relative); builder.move_(point); } CurveComponent::Line(element) => { - let relative = element.relative(styles); + let relative = element.relative.get(styles); let point = builder.resolve_point(element.end, relative); builder.line(point); } CurveComponent::Quad(element) => { - let relative = element.relative(styles); + let relative = element.relative.get(styles); let end = builder.resolve_point(element.end, relative); let control = match element.control { Smart::Auto => { @@ -178,7 +182,7 @@ pub fn layout_curve( } CurveComponent::Cubic(element) => { - let relative = element.relative(styles); + let relative = element.relative.get(styles); let end = builder.resolve_point(element.end, relative); let c1 = match element.control_start { Some(Smart::Custom(p)) => builder.resolve_point(p, relative), @@ -193,7 +197,7 @@ pub fn layout_curve( } CurveComponent::Close(element) => { - builder.close(element.mode(styles)); + builder.close(element.mode.get(styles)); } } } @@ -208,9 +212,9 @@ pub fn layout_curve( } // Prepare fill and stroke. - let fill = elem.fill(styles); - let fill_rule = elem.fill_rule(styles); - let stroke = match elem.stroke(styles) { + let fill = elem.fill.get_cloned(styles); + let fill_rule = elem.fill_rule.get(styles); + let stroke = match elem.stroke.resolve(styles) { Smart::Auto if fill.is_none() => Some(FixedStroke::default()), Smart::Auto => None, Smart::Custom(stroke) => stroke.map(Stroke::unwrap_or_default), @@ -418,9 +422,9 @@ pub fn layout_polygon( } // Prepare fill and stroke. - let fill = elem.fill(styles); - let fill_rule = elem.fill_rule(styles); - let stroke = match elem.stroke(styles) { + let fill = elem.fill.get_cloned(styles); + let fill_rule = elem.fill_rule.get(styles); + let stroke = match elem.stroke.resolve(styles) { Smart::Auto if fill.is_none() => Some(FixedStroke::default()), Smart::Auto => None, Smart::Custom(stroke) => stroke.map(Stroke::unwrap_or_default), @@ -459,12 +463,12 @@ pub fn layout_rect( styles, region, ShapeKind::Rect, - elem.body(styles), - elem.fill(styles), - elem.stroke(styles), - elem.inset(styles), - elem.outset(styles), - elem.radius(styles), + elem.body.get_ref(styles), + elem.fill.get_cloned(styles), + elem.stroke.resolve(styles), + elem.inset.resolve(styles), + elem.outset.resolve(styles), + elem.radius.resolve(styles), elem.span(), ) } @@ -484,12 +488,12 @@ pub fn layout_square( styles, region, ShapeKind::Square, - elem.body(styles), - elem.fill(styles), - elem.stroke(styles), - elem.inset(styles), - elem.outset(styles), - elem.radius(styles), + elem.body.get_ref(styles), + elem.fill.get_cloned(styles), + elem.stroke.resolve(styles), + elem.inset.resolve(styles), + elem.outset.resolve(styles), + elem.radius.resolve(styles), elem.span(), ) } @@ -509,11 +513,11 @@ pub fn layout_ellipse( styles, region, ShapeKind::Ellipse, - elem.body(styles), - elem.fill(styles), - elem.stroke(styles).map(|s| Sides::splat(Some(s))), - elem.inset(styles), - elem.outset(styles), + elem.body.get_ref(styles), + elem.fill.get_cloned(styles), + elem.stroke.resolve(styles).map(|s| Sides::splat(Some(s))), + elem.inset.resolve(styles), + elem.outset.resolve(styles), Corners::splat(None), elem.span(), ) @@ -534,11 +538,11 @@ pub fn layout_circle( styles, region, ShapeKind::Circle, - elem.body(styles), - elem.fill(styles), - elem.stroke(styles).map(|s| Sides::splat(Some(s))), - elem.inset(styles), - elem.outset(styles), + elem.body.get_ref(styles), + elem.fill.get_cloned(styles), + elem.stroke.resolve(styles).map(|s| Sides::splat(Some(s))), + elem.inset.resolve(styles), + elem.outset.resolve(styles), Corners::splat(None), elem.span(), ) diff --git a/crates/typst-layout/src/stack.rs b/crates/typst-layout/src/stack.rs index c468945e..5df626fd 100644 --- a/crates/typst-layout/src/stack.rs +++ b/crates/typst-layout/src/stack.rs @@ -19,12 +19,12 @@ pub fn layout_stack( regions: Regions, ) -> SourceResult<Fragment> { let mut layouter = - StackLayouter::new(elem.span(), elem.dir(styles), locator, styles, regions); + StackLayouter::new(elem.span(), elem.dir.get(styles), locator, styles, regions); let axis = layouter.dir.axis(); // Spacing to insert before the next block. - let spacing = elem.spacing(styles); + let spacing = elem.spacing.get(styles); let mut deferred = None; for child in &elem.children { @@ -167,11 +167,11 @@ impl<'a> StackLayouter<'a> { // Block-axis alignment of the `AlignElem` is respected by stacks. let align = if let Some(align) = block.to_packed::<AlignElem>() { - align.alignment(styles) + align.alignment.get(styles) } else if let Some(styled) = block.to_packed::<StyledElem>() { - AlignElem::alignment_in(styles.chain(&styled.styles)) + styles.chain(&styled.styles).get(AlignElem::alignment) } else { - AlignElem::alignment_in(styles) + styles.get(AlignElem::alignment) } .resolve(styles); diff --git a/crates/typst-layout/src/transforms.rs b/crates/typst-layout/src/transforms.rs index f4526dd0..e545dd51 100644 --- a/crates/typst-layout/src/transforms.rs +++ b/crates/typst-layout/src/transforms.rs @@ -20,7 +20,7 @@ pub fn layout_move( region: Region, ) -> SourceResult<Frame> { let mut frame = crate::layout_frame(engine, &elem.body, locator, styles, region)?; - let delta = Axes::new(elem.dx(styles), elem.dy(styles)).resolve(styles); + let delta = Axes::new(elem.dx.resolve(styles), elem.dy.resolve(styles)); let delta = delta.zip_map(region.size, Rel::relative_to); frame.translate(delta.to_point()); Ok(frame) @@ -35,8 +35,8 @@ pub fn layout_rotate( styles: StyleChain, region: Region, ) -> SourceResult<Frame> { - let angle = elem.angle(styles); - let align = elem.origin(styles).resolve(styles); + let angle = elem.angle.get(styles); + let align = elem.origin.resolve(styles); // Compute the new region's approximate size. let is_finite = region.size.is_finite(); @@ -55,7 +55,7 @@ pub fn layout_rotate( &elem.body, Transform::rotate(angle), align, - elem.reflow(styles), + elem.reflow.get(styles), ) } @@ -83,8 +83,8 @@ pub fn layout_scale( styles, &elem.body, Transform::scale(scale.x, scale.y), - elem.origin(styles).resolve(styles), - elem.reflow(styles), + elem.origin.resolve(styles), + elem.reflow.get(styles), ) } @@ -121,13 +121,13 @@ fn resolve_scale( }); let x = resolve_axis( - elem.x(styles), + elem.x.get(styles), || size.as_ref().map(|size| size.x).map_err(Clone::clone), styles, )?; let y = resolve_axis( - elem.y(styles), + elem.y.get(styles), || size.as_ref().map(|size| size.y).map_err(Clone::clone), styles, )?; @@ -152,9 +152,9 @@ pub fn layout_skew( styles: StyleChain, region: Region, ) -> SourceResult<Frame> { - let ax = elem.ax(styles); - let ay = elem.ay(styles); - let align = elem.origin(styles).resolve(styles); + let ax = elem.ax.get(styles); + let ay = elem.ay.get(styles); + let align = elem.origin.resolve(styles); // Compute the new region's approximate size. let size = if region.size.is_finite() { @@ -172,7 +172,7 @@ pub fn layout_skew( &elem.body, Transform::skew(ax, ay), align, - elem.reflow(styles), + elem.reflow.get(styles), ) } |
