summaryrefslogtreecommitdiff
path: root/crates/typst-layout/src/inline
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2025-01-22 14:24:14 +0100
committerGitHub <noreply@github.com>2025-01-22 13:24:14 +0000
commit6fcc4322845482c1810c26ee7f6fc8f6fed20d7d (patch)
tree93f20518774529d90d7f07b6de5122fe64218748 /crates/typst-layout/src/inline
parentb45f574703f674c962e8678b4af0aabe081216a1 (diff)
Don't link items if container is already linked (#5732)
Diffstat (limited to 'crates/typst-layout/src/inline')
-rw-r--r--crates/typst-layout/src/inline/collect.rs20
-rw-r--r--crates/typst-layout/src/inline/line.rs25
-rw-r--r--crates/typst-layout/src/inline/mod.rs2
-rw-r--r--crates/typst-layout/src/inline/shaping.rs2
4 files changed, 31 insertions, 18 deletions
diff --git a/crates/typst-layout/src/inline/collect.rs b/crates/typst-layout/src/inline/collect.rs
index fcf7508e..6023f5c6 100644
--- a/crates/typst-layout/src/inline/collect.rs
+++ b/crates/typst-layout/src/inline/collect.rs
@@ -13,6 +13,7 @@ use typst_syntax::Span;
use typst_utils::Numeric;
use super::*;
+use crate::modifiers::{layout_and_modify, FrameModifiers, FrameModify};
// The characters by which spacing, inline content and pins are replaced in the
// paragraph's full text.
@@ -36,7 +37,7 @@ pub enum Item<'a> {
/// Fractional spacing between other items.
Fractional(Fr, Option<(&'a Packed<BoxElem>, Locator<'a>, StyleChain<'a>)>),
/// Layouted inline-level content.
- Frame(Frame, StyleChain<'a>),
+ Frame(Frame),
/// A tag.
Tag(&'a Tag),
/// An item that is invisible and needs to be skipped, e.g. a Unicode
@@ -67,7 +68,7 @@ impl<'a> Item<'a> {
match self {
Self::Text(shaped) => shaped.text,
Self::Absolute(_, _) | Self::Fractional(_, _) => SPACING_REPLACE,
- Self::Frame(_, _) => OBJ_REPLACE,
+ Self::Frame(_) => OBJ_REPLACE,
Self::Tag(_) => "",
Self::Skip(s) => s,
}
@@ -83,7 +84,7 @@ impl<'a> Item<'a> {
match self {
Self::Text(shaped) => shaped.width,
Self::Absolute(v, _) => *v,
- Self::Frame(frame, _) => frame.width(),
+ Self::Frame(frame) => frame.width(),
Self::Fractional(_, _) | Self::Tag(_) => Abs::zero(),
Self::Skip(_) => Abs::zero(),
}
@@ -210,8 +211,10 @@ pub fn collect<'a>(
InlineItem::Space(space, weak) => {
collector.push_item(Item::Absolute(space, weak));
}
- InlineItem::Frame(frame) => {
- collector.push_item(Item::Frame(frame, styles));
+ InlineItem::Frame(mut frame) => {
+ frame.modify(&FrameModifiers::get_in(styles));
+ apply_baseline_shift(&mut frame, styles);
+ collector.push_item(Item::Frame(frame));
}
}
}
@@ -222,8 +225,11 @@ pub fn collect<'a>(
if let Sizing::Fr(v) = elem.width(styles) {
collector.push_item(Item::Fractional(v, Some((elem, loc, styles))));
} else {
- let frame = layout_box(elem, engine, loc, styles, region)?;
- collector.push_item(Item::Frame(frame, styles));
+ let mut frame = layout_and_modify(styles, |styles| {
+ layout_box(elem, engine, loc, styles, region)
+ })?;
+ apply_baseline_shift(&mut frame, styles);
+ collector.push_item(Item::Frame(frame));
}
} else if let Some(elem) = child.to_packed::<TagElem>() {
collector.push_item(Item::Tag(&elem.tag));
diff --git a/crates/typst-layout/src/inline/line.rs b/crates/typst-layout/src/inline/line.rs
index ef7e26c3..fba4bef8 100644
--- a/crates/typst-layout/src/inline/line.rs
+++ b/crates/typst-layout/src/inline/line.rs
@@ -10,6 +10,7 @@ use typst_library::text::{Lang, TextElem};
use typst_utils::Numeric;
use super::*;
+use crate::modifiers::layout_and_modify;
const SHY: char = '\u{ad}';
const HYPHEN: char = '-';
@@ -93,7 +94,7 @@ impl Line<'_> {
pub fn has_negative_width_items(&self) -> bool {
self.items.iter().any(|item| match item {
Item::Absolute(amount, _) => *amount < Abs::zero(),
- Item::Frame(frame, _) => frame.width() < Abs::zero(),
+ Item::Frame(frame) => frame.width() < Abs::zero(),
_ => false,
})
}
@@ -409,6 +410,11 @@ fn should_repeat_hyphen(pred_line: &Line, text: &str) -> bool {
}
}
+/// Apply the current baseline shift to a frame.
+pub fn apply_baseline_shift(frame: &mut Frame, styles: StyleChain) {
+ frame.translate(Point::with_y(TextElem::baseline_in(styles)));
+}
+
/// Commit to a line and build its frame.
#[allow(clippy::too_many_arguments)]
pub fn commit(
@@ -509,10 +515,11 @@ pub fn commit(
let amount = v.share(fr, remaining);
if let Some((elem, loc, styles)) = elem {
let region = Size::new(amount, full);
- let mut frame =
- layout_box(elem, engine, loc.relayout(), *styles, region)?;
- frame.translate(Point::with_y(TextElem::baseline_in(*styles)));
- push(&mut offset, frame.post_processed(*styles));
+ let mut frame = layout_and_modify(*styles, |styles| {
+ layout_box(elem, engine, loc.relayout(), styles, region)
+ })?;
+ apply_baseline_shift(&mut frame, *styles);
+ push(&mut offset, frame);
} else {
offset += amount;
}
@@ -524,12 +531,10 @@ pub fn commit(
justification_ratio,
extra_justification,
);
- push(&mut offset, frame.post_processed(shaped.styles));
+ push(&mut offset, frame);
}
- Item::Frame(frame, styles) => {
- let mut frame = frame.clone();
- frame.translate(Point::with_y(TextElem::baseline_in(*styles)));
- push(&mut offset, frame.post_processed(*styles));
+ Item::Frame(frame) => {
+ push(&mut offset, frame.clone());
}
Item::Tag(tag) => {
let mut frame = Frame::soft(Size::zero());
diff --git a/crates/typst-layout/src/inline/mod.rs b/crates/typst-layout/src/inline/mod.rs
index 658e3084..bedc54d6 100644
--- a/crates/typst-layout/src/inline/mod.rs
+++ b/crates/typst-layout/src/inline/mod.rs
@@ -23,7 +23,7 @@ use typst_library::World;
use self::collect::{collect, Item, Segment, SpanMapper};
use self::deco::decorate;
use self::finalize::finalize;
-use self::line::{commit, line, Line};
+use self::line::{apply_baseline_shift, commit, line, Line};
use self::linebreak::{linebreak, Breakpoint};
use self::prepare::{prepare, Preparation};
use self::shaping::{
diff --git a/crates/typst-layout/src/inline/shaping.rs b/crates/typst-layout/src/inline/shaping.rs
index d6b7632b..2ed95f14 100644
--- a/crates/typst-layout/src/inline/shaping.rs
+++ b/crates/typst-layout/src/inline/shaping.rs
@@ -20,6 +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};
/// The result of shaping text.
///
@@ -326,6 +327,7 @@ impl<'a> ShapedText<'a> {
offset += width;
}
+ frame.modify(&FrameModifiers::get_in(self.styles));
frame
}