From ce746528b38e1a2ab9c1ee79b23d5b399ffe75d3 Mon Sep 17 00:00:00 2001 From: mkorje Date: Sat, 31 May 2025 00:12:53 +1000 Subject: [PATCH] Add support for fractional spacing in inline math --- crates/typst-layout/src/math/run.rs | 18 ++++++++++++++++++ tests/ref/math-spacing-fractional-inline.png | Bin 0 -> 1655 bytes tests/ref/math-spacing-mixed-inline.png | Bin 0 -> 1313 bytes tests/suite/math/spacing.typ | 16 ++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 tests/ref/math-spacing-fractional-inline.png create mode 100644 tests/ref/math-spacing-mixed-inline.png diff --git a/crates/typst-layout/src/math/run.rs b/crates/typst-layout/src/math/run.rs index b5e855188..c9772c66f 100644 --- a/crates/typst-layout/src/math/run.rs +++ b/crates/typst-layout/src/math/run.rs @@ -319,6 +319,24 @@ impl MathRun { let mut iter = self.0.into_iter().peekable(); while let Some(fragment) = iter.next() { + if let MathFragment::Fractional(fr) = fragment { + if !empty { + let mut frame_prev = + std::mem::replace(&mut frame, Frame::soft(Size::zero())); + + finalize_frame(&mut frame_prev, x, ascent, descent); + items.push(InlineItem::Frame(frame_prev)); + empty = true; + + x = Abs::zero(); + ascent = Abs::zero(); + descent = Abs::zero(); + } + + items.push(InlineItem::Fractional(fr)); + continue; + } + let class = fragment.class(); let y = fragment.ascent(); diff --git a/tests/ref/math-spacing-fractional-inline.png b/tests/ref/math-spacing-fractional-inline.png new file mode 100644 index 0000000000000000000000000000000000000000..7ca0a5c59cbe17dfcbea9e6da240ff165cd51f9e GIT binary patch literal 1655 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 XUe|(