summaryrefslogtreecommitdiff
path: root/crates/typst-layout/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2025-07-08 10:52:43 +0200
committerGitHub <noreply@github.com>2025-07-08 08:52:43 +0000
commit0a3c6939dd274f40672484695d909c2cc0d0d755 (patch)
tree465c10338230b895fdd06c8b3491f1734e8a2932 /crates/typst-layout/src
parent36ecbb2c8dccc1a31c43fee1466f1425844d8607 (diff)
Rewrite foundations of native elements (#6547)
Diffstat (limited to 'crates/typst-layout/src')
-rw-r--r--crates/typst-layout/src/flow/block.rs38
-rw-r--r--crates/typst-layout/src/flow/collect.rs42
-rw-r--r--crates/typst-layout/src/flow/compose.rs4
-rw-r--r--crates/typst-layout/src/flow/mod.rs20
-rw-r--r--crates/typst-layout/src/grid/layouter.rs2
-rw-r--r--crates/typst-layout/src/image.rs8
-rw-r--r--crates/typst-layout/src/inline/box.rs21
-rw-r--r--crates/typst-layout/src/inline/collect.rs26
-rw-r--r--crates/typst-layout/src/inline/line.rs12
-rw-r--r--crates/typst-layout/src/inline/linebreak.rs6
-rw-r--r--crates/typst-layout/src/inline/mod.rs50
-rw-r--r--crates/typst-layout/src/inline/shaping.rs41
-rw-r--r--crates/typst-layout/src/lists.rs50
-rw-r--r--crates/typst-layout/src/math/accent.rs4
-rw-r--r--crates/typst-layout/src/math/attach.rs19
-rw-r--r--crates/typst-layout/src/math/cancel.rs16
-rw-r--r--crates/typst-layout/src/math/frac.rs2
-rw-r--r--crates/typst-layout/src/math/fragment.rs25
-rw-r--r--crates/typst-layout/src/math/lr.rs4
-rw-r--r--crates/typst-layout/src/math/mat.rs27
-rw-r--r--crates/typst-layout/src/math/mod.rs35
-rw-r--r--crates/typst-layout/src/math/root.rs6
-rw-r--r--crates/typst-layout/src/math/run.rs6
-rw-r--r--crates/typst-layout/src/math/shared.rs53
-rw-r--r--crates/typst-layout/src/math/stretch.rs9
-rw-r--r--crates/typst-layout/src/math/text.rs12
-rw-r--r--crates/typst-layout/src/math/underover.rs18
-rw-r--r--crates/typst-layout/src/modifiers.rs8
-rw-r--r--crates/typst-layout/src/pad.rs10
-rw-r--r--crates/typst-layout/src/pages/collect.rs8
-rw-r--r--crates/typst-layout/src/pages/run.rs42
-rw-r--r--crates/typst-layout/src/repeat.rs6
-rw-r--r--crates/typst-layout/src/shapes.rs98
-rw-r--r--crates/typst-layout/src/stack.rs10
-rw-r--r--crates/typst-layout/src/transforms.rs24
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),
)
}