From 468a60103dca9c6788be2207c9785d5ba771c800 Mon Sep 17 00:00:00 2001 From: Max Date: Sun, 8 Dec 2024 16:55:34 +0000 Subject: [PATCH] Fix multiline annotations in over- elems in math changing the baseline (#5459) --- crates/typst-layout/src/math/mat.rs | 4 +++- crates/typst-layout/src/math/shared.rs | 1 - crates/typst-layout/src/math/underover.rs | 4 ++-- tests/ref/math-cases-linebreaks.png | Bin 0 -> 570 bytes tests/ref/math-mat-linebreaks.png | Bin 0 -> 651 bytes .../ref/math-underover-multiline-annotation.png | Bin 0 -> 1672 bytes tests/ref/math-vec-linebreaks.png | Bin 0 -> 856 bytes tests/suite/math/cases.typ | 5 +++++ tests/suite/math/mat.typ | 5 +++++ tests/suite/math/underover.typ | 7 +++++++ tests/suite/math/vec.typ | 5 +++++ 11 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 tests/ref/math-cases-linebreaks.png create mode 100644 tests/ref/math-mat-linebreaks.png create mode 100644 tests/ref/math-underover-multiline-annotation.png create mode 100644 tests/ref/math-vec-linebreaks.png diff --git a/crates/typst-layout/src/math/mat.rs b/crates/typst-layout/src/math/mat.rs index 6c8b04553..24104f4ee 100644 --- a/crates/typst-layout/src/math/mat.rs +++ b/crates/typst-layout/src/math/mat.rs @@ -127,7 +127,9 @@ fn layout_vec_body( let denom_style = style_for_denominator(styles); let mut flat = vec![]; for child in column { - flat.push(ctx.layout_into_run(child, styles.chain(&denom_style))?); + // We allow linebreaks in cases and vectors, which are functionally + // identical to commas. + flat.extend(ctx.layout_into_run(child, styles.chain(&denom_style))?.rows()); } // We pad ascent and descent with the ascent and descent of the paren // to ensure that normal vectors are aligned with others unless they are diff --git a/crates/typst-layout/src/math/shared.rs b/crates/typst-layout/src/math/shared.rs index 13477c10b..74e62e8f0 100644 --- a/crates/typst-layout/src/math/shared.rs +++ b/crates/typst-layout/src/math/shared.rs @@ -121,7 +121,6 @@ pub fn stack( alternator: LeftRightAlternator, minimum_ascent_descent: Option<(Abs, Abs)>, ) -> Frame { - let rows: Vec<_> = rows.into_iter().flat_map(|r| r.rows()).collect(); let AlignmentResult { points, width } = alignments(&rows); let rows: Vec<_> = rows .into_iter() diff --git a/crates/typst-layout/src/math/underover.rs b/crates/typst-layout/src/math/underover.rs index b1d4825b6..1a2c8db66 100644 --- a/crates/typst-layout/src/math/underover.rs +++ b/crates/typst-layout/src/math/underover.rs @@ -297,7 +297,7 @@ fn layout_underoverspreader( if let Some(annotation) = annotation { let under_style = style_for_subscript(styles); let annotation_styles = styles.chain(&under_style); - rows.push(ctx.layout_into_run(annotation, annotation_styles)?); + rows.extend(ctx.layout_into_run(annotation, annotation_styles)?.rows()); } 0 } @@ -305,7 +305,7 @@ fn layout_underoverspreader( if let Some(annotation) = annotation { let over_style = style_for_superscript(styles); let annotation_styles = styles.chain(&over_style); - rows.push(ctx.layout_into_run(annotation, annotation_styles)?); + rows.extend(ctx.layout_into_run(annotation, annotation_styles)?.rows()); } rows.push(stretched.into()); rows.push(MathRun::new(vec![body])); diff --git a/tests/ref/math-cases-linebreaks.png b/tests/ref/math-cases-linebreaks.png new file mode 100644 index 0000000000000000000000000000000000000000..543d5384c11a270a8a56f95e91e4f5ec7ac64d3f GIT binary patch literal 570 zcmV-A0>%A_P)lQAABqA!TMHEz9cRe8qCP#{hjKH8aMcJl}i-<6+$P9wogh3C2 z9$-Qlq}1S~m52`p2z#sqtf$p4{Ie*W;1j*P)1M%KUG3EJzHddF`rhwFq zuOWb2FNlT)?nE^_rf7H3syuj!rM6+>S%~W1hNYHWQX0%!Bp-Yg8enf7IwDfGunL3Y zMi=#7I5NY+by_FYE@NEjPc3Le#1;UFH5nkO(Sdec{YUT# zJ7W;TJ1$!tQGFT&m~jJSNvgAwue8zdeq&V|NR+h#*S(L+V=G2w<)zTV7>r zI0P`vTFV>jEY2Hi_@%07*qo IM6N<$g7^yiXaE2J literal 0 HcmV?d00001 diff --git a/tests/ref/math-mat-linebreaks.png b/tests/ref/math-mat-linebreaks.png new file mode 100644 index 0000000000000000000000000000000000000000..52ff0a8bbc61bba3604655887b7aeb893fc9115d GIT binary patch literal 651 zcmV;60(AX}P)Fp_9-lGDtAGC{c8XR6@&wB3QQ48A}g}S`?Zq2AQdpA-F(8@h}ob zL~bT61Y6V&wl$2HZaQ@>Hn6R^Z-?Juy|=>c@!;=!d7j&c_c^=;Y*9N3wkRFeVIAIP zu>Za`I~Qf)NK1pZG~WFw3ODud(w3dg?FE~Te{P~9ySGiV$^HXAl>k`z4zN%z2Rmy4 z#vY9t04nChV51#~7xUTzU~3kG_a^|ik!JS_5Ga;{1BC$b8{VU~D8SwyLhyJQ05N|& z2tcV*2!41GrL#66*xZVesY3{^d5qF+lMr0pkJ6p%0EAHs=NvAo2OxNQ4FIak0N(lm zV5SN!XCPlMKKA#EQ$1+K&VZIRPw-OB$4nNszX9gwGrY8X2IhQVSjm2QA)7pnmFYhv*5Er3HQ zegV`v#Nc$v24I<;90F1&5QDMW0m4auz7at*X7QFz>CPW%z<5%=m~ltqx>i lmX#p_tLd-~>#z<3e*pLZl?g+Rl0X0e002ovPDHLkV1mb*BP##^ literal 0 HcmV?d00001 diff --git a/tests/ref/math-underover-multiline-annotation.png b/tests/ref/math-underover-multiline-annotation.png new file mode 100644 index 0000000000000000000000000000000000000000..ad8f0c80250910c87ad9ae023ff3cb1c76cd2205 GIT binary patch literal 1672 zcmV;326y?1P)9k`JtF@vwIs|DIqvB(cfUQIcLWN}s zZxGle5!r!^DyX+-}OO8*UtBUMO(l%CZZg?z>R@H9J{7F8V*wpZ>yq!O{ z%80Sb9Ge>Eo&`O6q_)}b!Kyas@X2ZZ7Qzb`thM+s5#g?QA>qy@dvRSQhOS9Krfq5~ zt+bjuhIuBLu4_QkVCR9+ukdhz^HS-}Wc`7zOMuK4XFS!ZJlTBKOPF)cpmBLh@BjP? zYn028Wi4r=5tsnkV%($n-uzRN$y->)>6!Rb-F<$Asje}pDl?l08VxX%piRA(Qky?h zHO#Z%SP&r>qB76;ec zVedP6OAf8s?eD_B$V<8+YUi>tVzUReN9OYVd# z3Gr@*qGY42v^Bjru@Q}mxu`4PY!=~-Y#=rB060?dSWdx<@q-A7d}CUzOV{fum0#90&)(f$$3qPiL0(v5K+ebI^5zP$B^ge%#y# z9ZmJDZLSUmYwegD8l)1R;o)%0gEv{JU&#qb!NZ&f-1+bFCm}HO!(rBz49vcM9%pzP z19iT_VI7dnN@=+EQPK9)Df72BoF7ANFl!sh1`MiKo#X-MeTCzE z;1JCJW|==^LPHKX6>seUb_@aF9uph@BmW{u`YdcJJXMqfG7tFgFP{0K#zv z8wqi8Th7!^ZIE8apX}5}!<}GO*{hy^qe6=9hrwzn5;IOtc@JmG6EE3W!IGYT)c}QB z+@%#QWh#(4-Kp^j*I_6&c8ybJR*9k&Z6R|pAA##0z?qF~AfD6pvK$YG0xxuj5t8_Z zp=2ZBArQ1$5DJ&@qPr16{~35lxq-bJ-{FbH=YAH#7;BqaT4&fD6J1=d?fKgM1qA0% zk4I}+Qp7km z%7L1t7QKJr+jRy-QHHCvs~eDYsu~iC3?t3W-u^9Ss}GH}$GR`u{Ry{!%IUHy#n`^C zG|$hFi#-LQ>I9xeuNYa}e=V5^;->uxk1OWlN}CmyzR2_YEORbypCte9izy3 zlm0t*@h8kctNU)#Ew#193`50zW!;~)SGik^fiDU07)x?@yp%99W?oWw^h{4s;qA7{ zoXrj+BVs20SchtJ!(SXQgc$yzK7O~Nb#ue^8S7Wq!VDI7;I$YC2f~5yi}fWyLVz@{ S>l_mR00006nP)L;@+%=DDnTU^m zbxqq|-Z|}IoD1vXScnIY;p(4-l$SfPq8O6z=AmK-7>JYJLZ0YIt`y1;>cqiQLQEv~ z?9vL|ltN!@+r-23T|)6Aa7J{CxPLcfS~c2(&y75Faoa)2ldULh6vmZ&5f|Qo+&Qn0 z!#GMsU3@tkQc?RNrVK_yw1}gsAu~03X)j@1%b_kl@DP`Ja)^W0trzizFStHidU03A zP!|W+5vSG53dMUF3EZ}Wx_E6LdHeo=)T|)s&>Gren}?AEo7*AV14wH0uu&FUmrar& zNCl}1BI)EZD`m08Q;+-ADF^UXKq`F2>-t@>^_~_+Pu!K^_KEL5C!Uyr_*S{vojCT> zC}VNV>#_zn;%z;dV{F7`*$D1%RB;s#?-IxoZ+r}D2f9Yi+RdowDKo;`>7%O*OBzwDnwhnrIR@4Jm#Qgm)i;4vX#0xqJ}sJ{KQ`U zo4}>}sEg0s5nJ2LK`BGTGxVd_eQmgMQ>lxq;&3T$H_D+)vP7I!fGfKuzZp8Iin@3@ z0MZnMxM>)N-if&7Fr;cfGVw41XQ+!&lv;?+c!bPC^MSlbt=la^-YXJuZv>(*Zagc5 z{q*4DE}`G#I&ofw5Snatkyhv&B?B=EH$!Uhj+}B*V>F~i2RRjqScu=}xn`|=0T(v7 zW=;zeF*-ls7}_KD1!_;2aje#Jh>e&}AI3eOK>TVLQs;4hPq8u*BilGG&O~Aphilv> i{m&(dC9x!4lGh&#Ht1u*xA0;B0000