diff options
Diffstat (limited to 'crates/typst-layout')
| -rw-r--r-- | crates/typst-layout/src/inline/shaping.rs | 4 | ||||
| -rw-r--r-- | crates/typst-layout/src/modifiers.rs | 48 |
2 files changed, 40 insertions, 12 deletions
diff --git a/crates/typst-layout/src/inline/shaping.rs b/crates/typst-layout/src/inline/shaping.rs index 8236d1e3..ca723c0a 100644 --- a/crates/typst-layout/src/inline/shaping.rs +++ b/crates/typst-layout/src/inline/shaping.rs @@ -20,7 +20,7 @@ use unicode_bidi::{BidiInfo, Level as BidiLevel}; use unicode_script::{Script, UnicodeScript}; use super::{decorate, Item, Range, SpanMapper}; -use crate::modifiers::{FrameModifiers, FrameModify}; +use crate::modifiers::FrameModifyText; /// The result of shaping text. /// @@ -327,7 +327,7 @@ impl<'a> ShapedText<'a> { offset += width; } - frame.modify(&FrameModifiers::get_in(self.styles)); + frame.modify_text(self.styles); frame } diff --git a/crates/typst-layout/src/modifiers.rs b/crates/typst-layout/src/modifiers.rs index ac5f40b0..b0371d63 100644 --- a/crates/typst-layout/src/modifiers.rs +++ b/crates/typst-layout/src/modifiers.rs @@ -1,6 +1,6 @@ use typst_library::foundations::StyleChain; -use typst_library::layout::{Fragment, Frame, FrameItem, HideElem, Point}; -use typst_library::model::{Destination, LinkElem}; +use typst_library::layout::{Abs, Fragment, Frame, FrameItem, HideElem, Point, Sides}; +use typst_library::model::{Destination, LinkElem, ParElem}; /// Frame-level modifications resulting from styles that do not impose any /// layout structure. @@ -52,14 +52,7 @@ pub trait FrameModify { impl FrameModify for Frame { fn modify(&mut self, modifiers: &FrameModifiers) { - if let Some(dest) = &modifiers.dest { - let size = self.size(); - self.push(Point::zero(), FrameItem::Link(dest.clone(), size)); - } - - if modifiers.hidden { - self.hide(); - } + modify_frame(self, modifiers, None); } } @@ -82,6 +75,41 @@ where } } +pub trait FrameModifyText { + /// Resolve and apply [`FrameModifiers`] for this text frame. + fn modify_text(&mut self, styles: StyleChain); +} + +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 outset = Sides::new(Abs::zero(), expand_y, Abs::zero(), expand_y); + modify_frame(self, &modifiers, Some(outset)); + } +} + +fn modify_frame( + frame: &mut Frame, + modifiers: &FrameModifiers, + link_box_outset: Option<Sides<Abs>>, +) { + if let Some(dest) = &modifiers.dest { + let mut pos = Point::zero(); + let mut size = frame.size(); + if let Some(outset) = link_box_outset { + pos.y -= outset.top; + pos.x -= outset.left; + size += outset.sum_by_axis(); + } + frame.push(pos, FrameItem::Link(dest.clone(), size)); + } + + if modifiers.hidden { + frame.hide(); + } +} + /// Performs layout and modification in one step. /// /// This just runs `layout(styles).modified(&FrameModifiers::get_in(styles))`, |
