From 59374f737079472aa5694b69ebced8c4cd5f9dfc Mon Sep 17 00:00:00 2001 From: Eric Biedert Date: Sat, 6 Jul 2024 15:45:19 +0200 Subject: [PATCH] Avoid spaces around ignorant and invisible elements in math (#4348) --- crates/typst/src/math/fragment.rs | 13 +++++++++++++ crates/typst/src/math/mod.rs | 13 +++++++++++-- crates/typst/src/math/row.rs | 13 ++++++++----- tests/ref/math-spacing-ignorant.png | Bin 0 -> 686 bytes tests/suite/math/spacing.typ | 10 ++++++++++ 5 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 tests/ref/math-spacing-ignorant.png diff --git a/crates/typst/src/math/fragment.rs b/crates/typst/src/math/fragment.rs index da4cb0adc..c6de24863 100644 --- a/crates/typst/src/math/fragment.rs +++ b/crates/typst/src/math/fragment.rs @@ -71,6 +71,13 @@ impl MathFragment { } } + pub fn is_ignorant(&self) -> bool { + match self { + Self::Frame(fragment) => fragment.ignorant, + _ => false, + } + } + pub fn class(&self) -> MathClass { match self { Self::Glyph(glyph) => glyph.class, @@ -441,6 +448,7 @@ pub struct FrameFragment { pub italics_correction: Abs, pub accent_attach: Abs, pub text_like: bool, + pub ignorant: bool, } impl FrameFragment { @@ -459,6 +467,7 @@ impl FrameFragment { italics_correction: Abs::zero(), accent_attach, text_like: false, + ignorant: false, } } @@ -489,6 +498,10 @@ impl FrameFragment { pub fn with_text_like(self, text_like: bool) -> Self { Self { text_like, ..self } } + + pub fn with_ignorant(self, ignorant: bool) -> Self { + Self { ignorant, ..self } + } } #[derive(Debug, Clone)] diff --git a/crates/typst/src/math/mod.rs b/crates/typst/src/math/mod.rs index dc79f48b4..04db9efb1 100644 --- a/crates/typst/src/math/mod.rs +++ b/crates/typst/src/math/mod.rs @@ -49,6 +49,7 @@ use crate::foundations::{ }; use crate::introspection::TagElem; use crate::layout::{BoxElem, Frame, FrameItem, HElem, Point, Size, Spacing, VAlignment}; +use crate::realize::Behaviour; use crate::realize::{process, BehavedBuilder}; use crate::text::{LinebreakElem, SpaceElem, TextElem}; @@ -299,7 +300,7 @@ impl LayoutMath for Content { if let Some(elem) = self.to_packed::() { let mut frame = Frame::soft(Size::zero()); frame.push(Point::zero(), FrameItem::Tag(elem.tag.clone())); - ctx.push(FrameFragment::new(ctx, styles, frame)); + ctx.push(FrameFragment::new(ctx, styles, frame).with_ignorant(true)); return Ok(()); } @@ -312,7 +313,15 @@ impl LayoutMath for Content { let axis = scaled!(ctx, styles, axis_height); frame.set_baseline(frame.height() / 2.0 + axis); } - ctx.push(FrameFragment::new(ctx, styles, frame).with_spaced(true)); + + ctx.push( + FrameFragment::new(ctx, styles, frame) + .with_spaced(true) + .with_ignorant(matches!( + self.behaviour(), + Behaviour::Invisible | Behaviour::Ignorant + )), + ); Ok(()) } diff --git a/crates/typst/src/math/row.rs b/crates/typst/src/math/row.rs index cb909b0bc..5234ca2cd 100644 --- a/crates/typst/src/math/row.rs +++ b/crates/typst/src/math/row.rs @@ -77,14 +77,17 @@ impl MathRun { fragment.set_class(MathClass::Binary); } - // Insert spacing between the last and this item. - if let Some(i) = last { - if let Some(s) = spacing(&resolved[i], space.take(), &fragment) { - resolved.insert(i + 1, s); + // Insert spacing between the last and this non-ignorant item. + if !fragment.is_ignorant() { + if let Some(i) = last { + if let Some(s) = spacing(&resolved[i], space.take(), &fragment) { + resolved.insert(i + 1, s); + } } + + last = Some(resolved.len()); } - last = Some(resolved.len()); resolved.push(fragment); } diff --git a/tests/ref/math-spacing-ignorant.png b/tests/ref/math-spacing-ignorant.png new file mode 100644 index 0000000000000000000000000000000000000000..6fead62e3ddd4b6d94806163e1449108ca7dc2e7 GIT binary patch literal 686 zcmV;f0#W^mP)00000a_RRq!CI(CPiUWyPO52Q3KOy{FS^Jh0j8cGa01vX;lCS6!gCLwNlMKP?NWkHu%Mq$h{6fls}&eYn2Ty-@X|t;Y4SA%ojhJp%0d z;!cNgJR3N;1o$jbW-0v3;fFnx5o{=qreL|E(TDK{@%y!#!w)gSR~F><9amqIS%DPX z$vo>q{%^bbmLhP$wGSxDF{}dq!X2&mJEHjjEsl?X6vjJqYruo)7DwB)V4ir*>`|A@$ZW?e)ul}Hj28>mAFwE5=2X8m{550WD UMs>5TMgRZ+07*qoM6N<$f?+H|K>z>% literal 0 HcmV?d00001 diff --git a/tests/suite/math/spacing.typ b/tests/suite/math/spacing.typ index 2a387f929..707c09bb8 100644 --- a/tests/suite/math/spacing.typ +++ b/tests/suite/math/spacing.typ @@ -49,6 +49,16 @@ $integral f(x) thin dif x$, // Both are weak, collide $integral f(x) #h(0.166em, weak: true)dif x$ +--- math-spacing-ignorant --- +// Test spacing with ignorant elements +$#metadata(none) "text"$ \ +$#place(dx: 5em)[Placed] "text"$ \ +// Operator spacing +$#counter("test").update(3) + b$ \ +$#place(dx: 5em)[a] + b$ +// Validate that ignorant elements are layouted +#context test(counter("test").get(), (3,)) + --- issue-1052-math-number-spacing --- // Test spacing after numbers in math. $