summaryrefslogtreecommitdiff
path: root/crates/typst-layout
diff options
context:
space:
mode:
authorTobias Schmitz <tobiasschmitz2001@gmail.com>2025-05-12 20:12:35 +0200
committerGitHub <noreply@github.com>2025-05-12 18:12:35 +0000
commitd204a28818c78cbbd66e2ffcc8d2e7a8c57b411d (patch)
tree33fc75e4e8739765cdc7b895bd716fd44b8d8fbe /crates/typst-layout
parent22a117a091f2d5936533d361098e7483f2997568 (diff)
Expand text link boxes vertically by half the leading spacing (#6252)
Diffstat (limited to 'crates/typst-layout')
-rw-r--r--crates/typst-layout/src/inline/shaping.rs4
-rw-r--r--crates/typst-layout/src/modifiers.rs48
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))`,