From d4d3d5534869ca1d1e0763bee5a12cd0825e2d46 Mon Sep 17 00:00:00 2001 From: mkorje Date: Fri, 25 Apr 2025 15:15:56 +1000 Subject: [PATCH 1/5] Subtract short fall from target size in glyph assemblies Previously the short fall was only considered when selecting a pre-made variant glyph and was not propogated to the target size in a glyph assembly. --- crates/typst-layout/src/math/stretch.rs | 2 +- tests/ref/gradient-math-conic.png | Bin 1721 -> 1642 bytes tests/ref/gradient-math-dir.png | Bin 2615 -> 2575 bytes tests/ref/gradient-math-mat.png | Bin 1560 -> 1557 bytes tests/ref/gradient-math-misc.png | Bin 2993 -> 3138 bytes tests/ref/gradient-math-radial.png | Bin 1641 -> 1606 bytes tests/ref/issue-1617-mat-align.png | Bin 3354 -> 3335 bytes .../issue-3774-math-call-empty-2d-args.png | Bin 1315 -> 1334 bytes tests/ref/math-accent-wide-base.png | Bin 510 -> 506 bytes tests/ref/math-cases-gap.png | Bin 340 -> 354 bytes tests/ref/math-cases-linebreaks.png | Bin 506 -> 492 bytes tests/ref/math-cases.png | Bin 1281 -> 1228 bytes .../math-mat-align-explicit-alternating.png | Bin 1035 -> 927 bytes tests/ref/math-mat-align-explicit-left.png | Bin 989 -> 903 bytes tests/ref/math-mat-align-explicit-mixed.png | Bin 2523 -> 2454 bytes tests/ref/math-mat-align-explicit-right.png | Bin 976 -> 875 bytes tests/ref/math-mat-align-implicit.png | Bin 1046 -> 954 bytes tests/ref/math-mat-align-signed-numbers.png | Bin 2036 -> 2024 bytes tests/ref/math-mat-align.png | Bin 1564 -> 1531 bytes tests/ref/math-mat-augment-set.png | Bin 1810 -> 1714 bytes tests/ref/math-mat-augment.png | Bin 3631 -> 3563 bytes tests/ref/math-mat-baseline.png | Bin 818 -> 816 bytes tests/ref/math-mat-gap.png | Bin 496 -> 526 bytes tests/ref/math-mat-gaps.png | Bin 1309 -> 1311 bytes tests/ref/math-mat-linebreaks.png | Bin 651 -> 648 bytes tests/ref/math-mat-sparse.png | Bin 882 -> 956 bytes tests/ref/math-mat-spread.png | Bin 1814 -> 1796 bytes tests/ref/math-shorthands.png | Bin 1231 -> 1173 bytes .../math-vec-align-explicit-alternating.png | Bin 1035 -> 927 bytes tests/ref/math-vec-align.png | Bin 1098 -> 1126 bytes tests/ref/math-vec-gap.png | Bin 420 -> 436 bytes tests/ref/math-vec-linebreaks.png | Bin 651 -> 648 bytes tests/ref/math-vec-wide.png | Bin 620 -> 630 bytes 33 files changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/typst-layout/src/math/stretch.rs b/crates/typst-layout/src/math/stretch.rs index f45035e27..33367ac29 100644 --- a/crates/typst-layout/src/math/stretch.rs +++ b/crates/typst-layout/src/math/stretch.rs @@ -166,7 +166,7 @@ pub fn stretch_glyph( // Assemble from parts. let assembly = construction.assembly.unwrap(); - assemble(ctx, base, assembly, min_overlap, target, axis) + assemble(ctx, base, assembly, min_overlap, short_target, axis) } /// Assemble a glyph from parts. diff --git a/tests/ref/gradient-math-conic.png b/tests/ref/gradient-math-conic.png index ffd3e8068f65a6c50e76af647605aa5b21005338..9bac6c3d4ced5297eabd91af61bcd7addfb2d4a8 100644 GIT binary patch delta 1638 zcmV-s2ATP}4eAV#7k@Yi0ssI2xn8U3000ItNkl&$@C`$=+QAxUFYZ{WKY11r?vo@~dI9}p?x8r>q$74HQ#vaf1 zBaw2L(U__gNu+3=j~-c;Y+t_f*W(#!<|PoP;w6%RgeIX05`UV6CZP!unuI1uXcGE= znqJRRSSz_o@@!tQj*lHw9pL z(&z9{P)ek#(|F_!9NI%NYRA6S`Dx<%>-Kccy$UZxP*; zE3LsHt0Wuu(P2xi*4BFH?*~JLGW+b%>f8gPPEnMg!Z4h{5ZCE~JTC%A0=~l1qF>XY z8!h3JJ}-dh56yOjxus}_6F5$U(!to)8!UjyNr!zW1AiP51gYA*>O3u+gownW1n(k!Rn&VY~0mu=ufW&t>GF@ zo_i-XGkP^@+PP@PTp>a8XM4SG&Ca9GWUJSIThwT1YM*<(*Mn10 zt1^Fl`{2xnmb`AfxLk#M^*bNXoghd!KK1=pU+?`h9=cXz-+%Am6)(u1Y`xOsM>iDR z9-IzCMUrswf^M+i@My{|Nl*)VGImpRecst(I)9KUq|3jbpE%p0`Najc=L;zr#|uhU z_?N#8qnn58>4Awr*YjxeX0%yn|7(Aky}Jb<>`5QIS57o@xp(pmhZds|F%o7k{VF)@ z%KSV!9mNtw)!Y`uciw=CB~VS|nl~qWP?1E*ub9yqyU*xzH;TOv9lVQH*InH4eqJF^;ci#!L%Y`sU+sI z@+DQPP!j$A+BUe=An}G zrKn^PfPQK#AEQ)$iIbH5!^P(UDI+$Ej#mnryXms5M6@laJGlsM)>YO)0DQxr^?yP7xbh3ZA=I}y> zwz+{r)V5P-vrwW#iHz9`An%IQvU^YpZ#bfxZUDX&Yax_|jALQjrL$-^G=Hr(TP%fty#|%o z)MIodNwF1^wSUTVd0gmlP^zRU_l#cPc;l@(?_-nfSD5{2R1!rEg;opxd_`bdiu!al zFffj8GDb(USOyS(VojUeP=BfA>8va2oi`?}0pJLoC~S@B0BAZiZQ7w$4UnmL!_o0s zbQ51PHu5C^_1s?CXSU7!|m$rku~eS?0=GNv`mBZcW^sHv4Td}{M4rkbNN5t8 kAfZWU5}F{PNoWGVzrc)+4>46(^b07*qoM6N<$f=GfJZvX%Q delta 1718 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 Z`7hW!#nL9z|C0a!002ovPDHLkV1jBn2Ydhk diff --git a/tests/ref/gradient-math-mat.png b/tests/ref/gradient-math-mat.png index ecf9530389ebe41ea2ccc67c00a20bce7c8c416d..d003d6d03a21e22a04c21308f168a31c09f9551e 100644 GIT binary patch delta 1553 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 literal 2993 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 diff --git a/tests/ref/gradient-math-radial.png b/tests/ref/gradient-math-radial.png index 8d0047bbe491b86029ba81088f498b5361008a15..97fb17e6fbb1778200ae2fc10226d5d4c74f190a 100644 GIT binary patch delta 1602 zcmV-I2EF;|48{zQ7k@Yi0ssI2xn8U3000IJNkl5RxiT#iA)y)?hFmuq!0CsYvZup#(Prp!&w^ix||+;rPh^a5rk1~?2c3mc0`1m z147-9P~BeAGHbXXt$C#AZU9vYg-*GF){R zy&(ncAX<5VM2h2*W%zqUWGCaL9<9DTDgNE?c!(L|x zJ>i3v8nBp(9tAr(;QH11h$uuj$&(both+Wc)|Dhf{iVQ2M*grutTf+u~jKLb{H@fK&F{ma(@|ip8r+4@#>6ogI+t-1o2had7*Lk-U**mgGM;FzaB&tc3yg^RC&bf(4e)P z$Q^tHyJ9UXo&UIZ&j-CGPs7$>hJ(*;!zM5w*gnOaeD>h0y&bfSOD^UR(u%NEp(K2M z0_-SCGRRiirH{Xfx1I@4+**w5U}MJ1kb~WeyMG~}sDc66$WQO@+1o(}kn1&njzdw{ zDwc)gN5M|4Q0p&Uw>?L979s_tf}KKECMRez%nmT5E8eLmI)S4}9PW~DWKaN%Fak{m zO#!s=qwAK&Vc^;UuwcdEq88~FZ`ua^l!;E{OVg|b7M`YP+wFyEPiAf~`%YB{25=(} z0)Mq#eK?Ey!JwG$EhQU-XuY!3fEF6`*+xi=S`uC0>)y9)*lZ5XmT>l&atrK)c@Y4v z4CPk^9n3naf}PdD@_Mr5Uj>6qnEUy|JzE_H|0GH07n`BsDI}F-3~0 zVhjl}U17mYDozFm-vcwBTsMvS`ceB$<$vO`z6@p|P6!nxGCcJ0T~iX6^*srfH}B#0 zgsXN543fd(=?}X1WY8>yJtG3x8GVuTy-azVV|$>ZcTEaM zPD)2$$LxWQ-W?3i9^=o#uE?)QXAZa=8Z@hOUuSA|Z3TC3bx6AQNx-ecZdeI(m%s2h zG-%?}?r>h#%tsN>F}xkt;VpCxgMY=sNUrLKQRfDIw0?CthrpoUFMV6Fa_W4l;+L4K zg9S6B=)UfM@5FeUqF|xQI@wufJdE{KEID73?cBLRS3W9?%}8J{K3rTMdNZMsB z6RtEFW(OJ424F_sf0I?Eytyn+tb#%JgGI8!I5+5l-h69a+O|?jrnb-QwSU82PgB&> z7}YHmLtYh-$8Oi#@cY`_@Ebpz7f&JCKlb8JN95Ev8~>G6fB%@)60QYg0s*#N$ZGB*@^2Mef42_5&g|wL*x)_pKO9BhdU6A=~pW({VR(a zY#-9j^vgo@TUithng&hLplQ%FXo?0+gQfuB9}DrB4(bZ{wEzGB07*qoM6N<$g8JnB AsQ>@~ delta 1637 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 RGY$X%002ovPDHLkV1glBKE(h4 literal 3354 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 diff --git a/tests/ref/issue-3774-math-call-empty-2d-args.png b/tests/ref/issue-3774-math-call-empty-2d-args.png index c1bf52d0040aee18b7b00eefb7ba55ab48dafe9d..52472d8dbeed2803c9dd5d075f7244d213abef66 100644 GIT binary patch delta 1328 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 WXFuwI9Dtbs0000Q3X&G8t1#Sh&ok!r5uIL^?b zFFj)e*4coE&ZNoVIwvq*w>ee5`y(Gnxl!?{hY<_*^)mrq>Y7OPX8}e%RtprMmx3+6 zuS`C*o%AQw&3{b5^QVc53J#Smp=1QWDJ7a*G;pyn(g>>VN`}|T2;Bw&r>zWCdy!$K z%_#6w(W}7(s&MWiGqAs9s-~8X+Lj6ZVC0B?z{7DB%^Y_RjP|1<_?bQ_WCos)ahD*g z;JsuB+0VdiDEh=b8*=_0uETWJ=d8fyf^Dqlbe;9&OGQ*z>;U>C!NXqUEz11Cm_*U=Bz0nP(taZ%d`Ak#ovs=F!>WNeN(!Cr(^RXN&JBe;=UU;@pHk1Jq63 mojp1tFlzCr#iJIF1d9PQ^aSoH$y^8k00000 zpzKtY2V;$_vik0{%7=8e*wF+;rvAHZN@t7f3P5D}w;y73wm8xoLNBfvn8bCbYG4xA ztJ(jz(%ItVP(KjquchTmXNxB#3{XD4qx^kbP{gRkqZW@^JQ6Gh Y0KklU)%RWnK>z>%07*qoM6N<$g3u(OEdT%j diff --git a/tests/ref/math-cases-linebreaks.png b/tests/ref/math-cases-linebreaks.png index eb4971c46fb2d2a36a8b95324d3d1e08b7d99319..65b4e402575de10ef2513bb25a1d21443f3235ca 100644 GIT binary patch delta 479 zcmV<50U-YR1MCBk7k@Yi000006IWwm0005ANklj3#$+rU#$G;b@ow$+iiEDsTwfrU+i|&bQfPXCJn=_yV$c3vg{+E59 zA&f`8S7>Un>Uj`3qZP*gYV{7vdKO1Zi{DHC15u5LwCw_8dA-~Zx+zwQ4|U+~}Kuj{)#d;k9rxk@vO zU-;|<)2D0yCx0CItMUIt&HscKAC311fko>l(=Mq0cHnuJ zIM?w1#l`>M185n?H+8|(${BC||KG83-Ly|P)~xvdf8D;#v`$?AW$)pV`4}-UmBgFI zH8izYVkHiV@BfBrB_XI0gB`E zP5&QVq_f3FdqL#peLLyxO4Tp)o(#}X#O;7R12y>acyzdF)Z$T#M=c&$ivjQ3 V%;jb2;!OYm002ovPDHLkV1n{o0g(Uz delta 493 zcmVVP4Bt@3Ph~{FOY>~-6-Ym~#Fk@(%=gn7d8s##_ z|N9-h|Ka!jzuw_<_^dgPGQ4DaHy6D zPTURhgFj~rC+X$d*Zcb|6!U@Jf`%y^^#b7U_EF#qbX=t@;hh41RPS2=ydL}DDms+_ z!Qf*H+cWR{nSXlP#p9skEE^kT_Bu?A%yIA*vV%==kNz}Qp>q`(??MII3`luOhtmxV zHZX&+S@xjHmcBS8ICMZZCNQe*yTvW{Ia zo?K$2M~*ie0O?xdfm<&i8Ue;I67~?JUDnVX5>L}kre<*X_7pVUfpwTU6oFEhiU{JM6vkUXP!URf!8x6Ff_6g` zbvV!h9hAa&IY3*W?K4l>oV2AYB%IPL>*wzD=E>>#<(re7MSq0JqDVLrj)WuOg%0aK z8wpGJ>^qYLF@XSBjl&;mgkhbmVQoi#CzYq&*IR z8)`cjNd7B!8jq2~WZf0f10Kk3&yE|kL zA2>7`y`v2zx__$6h#nC00ort+w>J$Tcc=_?r6Logk@8pgk?w0g`-xo`cyRTjdJZ zyaKS{7R$OpGEGrE_=nTV*;pg*sqV1zw18w^`e<}a8(`O@mFynJ6CUX2y({wGG32NN zZT0oZeSh`WU7oOby_KNhaToMi@Ff_794>vuq!1ts>n1=7n^ahWgr_l7Cz$KO~kGacLmP@+&Ig5}2jRnVcu=9xpME02WmU!4}!B6}ykZ&@} zHNYn5a<1Yx>`q`UhqVyx0CID@?if{qjNybkKn!fjk1aQFOa-LqmXAOT!1OfU*60zr z1b_VKPZP+E8Uw;feSom_&Srr6c03Hws(-W{`YM1hrExc6b1 zfdoT<@ShtS5f!>T*ZuHoj%EZju74enV(sLUcyXes$48}7r5XmtH=a-m$1Oo7)Al#M z1R=tmFkm=A!sOTirC3)Ns=UBs4uX zi5MpN#v3w(zk34U>=4hi1>R~aqPReMKhGa?8%?Cu$r&)95wNp1+LwdN>X(0Kk2`z83 z-O-z$RZK%D!^R_7_mMa%DtmuFq&{ubowre2bw4EG=I6pRAk!;a!xQHAYEyW^^z0mo jd<=<%BjHH+{}%oSB0>?K?nN@?00000NkvXXu0mjf|ENs2 delta 1274 zcmVrYc>9Kdn^1CwRhJB?Y) zF5a>&ZrPTxON^VuOZ3Imd5g=y&27eLM1iP7MMRt(193zc-UUIFyL1d?C^8r#av3Tx zF4cmiEiKTN_O$)ZbCUI-bR7w&HjDk_MaCW&kcmQl}@0oH~Im24}LD++si+O zYyg#)x+fIQdmo_v%wmu=WK(#qL;5;Vd-nbG&&wVAb;t(*S8*!+-VTm0c^D{1;V}^ zYzHLQ)S@9J7D&`&{!40Ii62(xuIIqFjvYG+@XGI_hQNjY@>6&ueOR(|;>SIzx~ZM!J$RY(UfX`0u05Qdlzbu1?ue+VZC4uzZv#0Ta}!@-dqxEm z>3Q7n1s~xgb62OAu#FJz%Hi{OxaupMeEc|f%Xm^vEn}Tt0kG%QxzlZU#D3hfF02<= zbN18Ha!|I_$n!Y$Fs?MR6DE0=*x@I(6RY@TMmHMnd^cXemCLEv)iO zIAJP4y7l~iCmvJO>Yaq5ervn=y>oNwt$qoo&j!fK+_>s49&-lJ5=t?-KQ6DP*N>y7 zYwfaDJg)7|FRGti7+!MWR{PeXGyV#DGXmgtxdAJF3D?XB&;k)=-40Bc#t-iYCX8mY kDfkyA7!HPm;b$%UH_GKbHUIzs07*qoM6N<$g1Z$_L;wH) diff --git a/tests/ref/math-mat-align-explicit-alternating.png b/tests/ref/math-mat-align-explicit-alternating.png index 1ebcc7b6847d96c69e3e5787510299955d3c7003..52a51378be2516fb650de8c05e6d4e71b8ccac96 100644 GIT binary patch delta 918 zcmV;H18Mw=2%iU#7k@Yi000006IWwm000AKNkl^q*=mxlCou4 zip~<-_UZQp!9j=dQ+|*ad)>S*Kb&(ozl+~E{3qiQ!-?Uf>;_yG91_z zg(#VA{KMhRAqewZ5#=5>TOm;SHQwRKsxbcb#aZ|f#NqIQJd!R)sqN*LIuNVQqX&6= zJMSAycu9nF*r|pLM|H;*>K7%JN5JeD)K*h1b%C9TrGVN`)z`l~Kt1i|98P-y83C0o zl{#?FIxhs~W`F*E8};=ma~fh57w&RXU!FFkQ=8WE4Tq;jA!AK*d#a!H##tnJS-a*S zyYwM|EeObl}kKV1qrew!z|k+nnbDm8(*Dpj5N&RS!y zINyX}(aTb$x(7hjO|QBc%*uMM;UWbDJ9vd_I3ojsU4J;nHLTD>Fw<79;T3KO=2^it zoLm9HDw4T|C#WEpYQh+JV*cSeN&AQT$(|nou{vBJwNh>b@wDC2c8p|rk_NF3gbYq< z`TgJ~YVgF+S-pEOw-WJOf8MeWL^FwNczh;em1z$fsjV5dRBHdpp|jeYM`v{$4JQrh zAerMw@qeoOW+2bt1F-tl`xL4v3v(pa?{jg!xDIj54>oM|js6=KOTMg5*7~wL`Aw`} zjjr2PFlMPX>nGyyIqzv&!9P4j2f=hxxQ3H#5X_b|w*TX_5(sAAz%_hO2f@^bxQ2B~ z2(~kiYq)v?1WWO94fjq4F*z+DcRg7H)DI=Ot$!d!hYfO~2D=kP@@OK|7RSYQkmeEj*TXrCqc4DNi|f7xj8l4?)5Y58 zs48k^?XtS6%OK;c)#WV*Qz|{whFG86sx4?^QGs{3XFCMi{DXTKm1Phn=Pvk%VXlE7 scl6*MCY=zZGjZLN7)}f)hDG}ezuAM7E-%;Wc1a95W(nsUK|L$s|}skSC}!)2i!}m zFekIQy_!xO3VTgCH$Q6(5$<{z%WEMC&FcSdIIA{IR zGZY+7B)ve+xj_>8$2lITIY%X~s6dRXY9EzYRm)o3P(&qOX=W|Hv64!hZDB38WK)S3 zRR!m|i^n@Vyjzof5hBIAN@vOYIYT`oBiJ`9s+Nu*G0G2@I(NYk{aJSn5eB zK5y4vNq z7Avo^7V8SB#2V)JxN;|zxMnYF@s?9m;=6?eK6{vOs?9@)9FHZwy%#~U^|~!e7`FQf z`3?sm`ujGOIPxQGKNdyu$#7#((+4z~?o|PUo5E{kz1)A}1thGEZ+-_nbKiIgh<=Vx ziGR^DI8AKRFAu@!xoKAeaI97OR`YiKlDM3B&Zhr`gzlzN3vj6A;zpo13(<*B*Wryb zUr_cY5E7OQ8tZ-V52%eQfE|UxDwmx2zDmsUVn%-roo;=PLy5&-3}@8VP>Lh)+O_X+ zeiF?h5IXT+@Q6N@;^#0PErF#rGn07*qoM6N<$g0=VWJ^%m! diff --git a/tests/ref/math-mat-align-explicit-left.png b/tests/ref/math-mat-align-explicit-left.png index cb9819248275a76b4ae40dff2472c993c64ee49d..09c5cb3d40a77a2dff1e7180a98355f326a8c716 100644 GIT binary patch delta 893 zcmV-@1A_eB2Zslc7k@Yi000006IWwm0009{NklPaYw zE|eh^(FM9-J=hg{u!|H5QV-dpEGlMV>NcChT*GX0Zd06kDle%`QnM66(oBt*Q%C9) zFO^R4()R8AKsd)Za1M43^{~&w@AG^3!-t*2`9Ew0{t+ue;eSv#6b^-D4NqN%jNF=* z8V*EzAtMv<0g2&9jgXc18foF-Gmx2BucWZ*BRiTHeE`BZ9OWPy7(F!O2wxqs(g-YGJ-&8RKgg5YuAEFpZpksbccLH*OW5aO8{JIh&*??9@x9>Brg zo|ANx+YB0Pa)C#6jD+yoF`7oE>cKFC7<%Hg=F*bQR6L-wHTD+|+X3D-kW*~7g2#__ z;$h!PD8Twb(QxZVD8SAZ(QwHjD8MnNXgE6t3J{Ym8h_5Z00p>^B^r)a~MmpWwZe-!BeOmSa$eIIEZV0V-dNy+V{s(^4(dytK;XjudoDb zy(boegkKR2pAG|I%SbelyKfg9#S&)jF5cC7I=ZX*bR^MTEkxL9iH~}EGjv85eSlqk zN5~wxDSz0(upSG?LrWd_9O&yh;rh#WY++m}qpUyJUS_s~&xpxcVx}dJsZE&#p9V*{ zrgORBxCkgfM4V_?9R&r5Qj3NS%6!KL(Xj0V6yUf`G+e(M3b3_NG~62o1z6oD8eUj4 z2icigwICYCv1Xc8Wht}d{(NmW2$Q3L#BBn6wST3%$w8yN2n17>79e*-LOiU~(Ny`3 z4sxl>cb4o^1PA?(siKLmEt}>C^RraIgDV2GbAKWHL z>rKlk^7k8-?Lk_!`uI}vVYh@Z&U%39EzsoD0EqnJK1|L{#Wp9vZ9?q#eu|>QS$b@! zV0P`@k6ZcgfYEc15^hdnM-kJQKF+$$QIXThdfe=+v;o{EL`%_YLpSRYv$MPyELNsI z!w)33NeUxj2(mI53u)nr1jxx;^n}DPJ|{y)ZgxOw7^9Gp(a_&bp>QZ13d_rHWFl3R TCZHZ^00000NkvXXu0mjf-nOI{ delta 980 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 U)b8MD5dZ)H07*qoM6N<$f^EX9@Bjb+ literal 2523 zcmV<12_*K3P)ZylHX;L)+<x3`=5vXw#RKd20!d{eC6uou{ZfqP)Cfdes*dm!Y&DKwn(cgp%Lq!tkUMXefMwFgzk24c+*?F#K#G z8Y+BN7#>=LhKhy?!-JBMiw!ELn=$589U?i!*r4-{11=i?N%EipK5@uCi;EeMtjN)g zMj-m1L0G%%-7)hlr#{dNo>&~7a)TuafF!*x-5HU+w!)dq2wVa)><=%FVR8`N(#DtD z7Y06!8esV0Xn+cTNmJz)hsJ(Gk8j7I5GCCgr3@dJwzJ{#f02iy9~Op(9Y}P`Syp=HV+8W%E-k{!4{uDGu$QD!2deFT$Cjj9 zfW!dVF=hnnDk|!+VkjvoX`!;BysiK6W65YJ`LPG@%k_-5;b(;5S2NI1%B#ZgUm_9d zjQXYtO0FR-66s3CoeN3Gg^m-3=O0C6o8GvToIS2ci$uB-Gq`c&Ix@Q#2*cam5%~Zn z7)f;nX^}`*Lec-Ga1k=gw+X}P;}CfbrWV>2KD>*v@yJY07lzF*m=PEbQ%dX#AKit1 z3cWgiWf6v1n25k1ER5~6D|~GO87t&}&qo~2n~N>FC0q>GeL<=FhY3iFM7k1NSGBH$ zUamToFjMbgODELig0Z2o5owV~S1K|a=~dx^TKL;_XkZBhRKxp&=}~cPG!zD={|6xUM655NksH?1*NtV{L9PrSWK0PP=e^a!9ZnX- z^w#$xJ6ZuJm}Gvh!u-p2`Z}|HfYaOeJ5<5}2T_EpUs@gn@FqClt>)e<+;4c-QI+tR z@08(+U9(1;ftO)wKDec-hOb0M&X0^NvKg)#B@Wk*Kp9@wg=ZA-7JS@H@XczITKHR? z&P}JQwHf9&_k`iF1<09Rht+op%(;7~g z!dlC&#Bo`KysHN!c~1`TsAnefk6VD`Q2y=F_RXu~=5xsHz6Rwk$;=I-Tkf*!_JwI? zv(Es-k0t@sL`qsyHYL9sLO0{lRVbuM_oXSrSETJC(9bi=!%2?{!-H-DbXH0%)D_Ms z=y|9X%P(r^t5LeIQ5mk0w%cgf)>R@8-yG<#FoCBl7a%DMz^S?P1rq{a`(VxFvd8NH zmcM1&{f--t`52Hi-=yNa=XVIiA3K(cm2!W7{{q5}1?u|`KaquovYrrzhv?9dZpef8 z$$a4!8p?iA82)24LY21xOC{1G(@}$fC8G_w^Y016E2+i2b_7;d zZ7xUVz)WFy;|@eVf(c!U>8<39D4gQ17^|({APirbhR6tTF0(5fw3E`Q$jpioh7H3I zc?Fyc>InA485 z^yu*0pgANVojQxcTb1Tt6 zjjI9m@TzPy@%;+*@YS#BQFUxSG=+qP0F)dKP9)7|Q8?DFt%;vLULG0P_cJER@!>8)|BS~%uQ<=9yF+C@)*(J;C8g0bWI zF7fb1eNetUP9;1!QyDfde`zhi%kW7q>^q2BxWi=HYBE`DhVv$i!={%}hCOQArey(d zz{DC-{W~pc;e%dY6TG}qY=(KUT^NpY0l9bJa|0Kn40*V;;Kc2{r3X#6!Y8ec`VLl{ z za|IwtALtO(EsA;NfMj`M>F?~DS0`*__on+Aluu6K^Ye7G?DMrR+?dSXF9#SNoC$zQ z!jXX1caGC7ebqS>x}^KMl;I9(+X8Ll>*V3g!NTw(i2#+yCCywtH7f~_WLbN~=)a~LA|{vnsh*|`yE=_`8aS#0pT=-H0U;iQlUI&elYy;c8Y7Of$9 zCo)@>3Bw@^5g7$js_hD&-A>6YWEKVq!_~tP`87<#<^JX0aZ^DE+ zyTYNK6waep<=cqEKKrqy={lb_FcDIgAT0`ePGIfsQX>55b$Fjj*zh5?d>=?%XmC0O zo@*kI7UbeLZ%M^kT;xGBy(St}!g$7_k%%3rg}df-qKUTI9jamS+|k5m`KX7n7-;i@FjL zf{HSvA}XN++J$Asg6tq21nH()l$~dGFsJD-!_2nkw#21xrIjlsvx5;t+QA~$%vH8T z?O+C#ZQlrQ_P`78Q@k(U>~rF77c4edDM~*#lP+S)Zw^jnY*k6%` z;Jd{!Edt;u-hW&JaKJ7RUfY6-vleF739D}gN1e?;((4z?ZxPLw&*Vnn-5mD0TY-jj ziSYPdRCJ&6I?KgXqSPPk1$^#HhuetORa$L#0uh^X<b~FJCI-f6VM9tf| zWLMt%zkg?Z-*vgL4ft5*y=X^Jq1?#*1l;!2FJ+^6vUCS`QQkQ19c{T=^+M*eL9ftwNc4~%)#{EQh17n6X!=$thU)kIr0B_D) zI{+y2RHE*cE6*>k$Z2;K07~ugFhF}U+Tnr%0Dtq~X%9e6V`vpX$ijl(sPfzmtQS|; zapnS$Mb1rtf+C4bk8%SRd`)x@rKY(tKhNwm*^zlhuu`-e({e?$1I`KTZ9TVV>on rqn+)@hUq~^J+aSCv2ZLL3+w9-Nq<$6)q=x?00000NkvXXu0mjf6dj#3 delta 967 zcmV;&133Ka2G9qP7k@bj00000*bA`7000A*NklZzc& z2&#z%U8rH%1+z&vODj#XizG=2-4G(EEVT$KEpSUqTTU>iWLE0jNb`mxX*sXkbenTt zwxe^KzyANTr~mlJ`6uU)5Bolx&-c&H;j?r2opazUf&Y{x5r1(+91%yvqKc=kh^e?X z%_S(nd^u(Ho7TDTTsI;MS^NAzgMoyE0+cAtd z8*R=nA4R1mkwLuDNfWEHd$!yq+Qbga)eIdfhucf#6~xZU9OI@(h<3TB}7X-2V}hUmQZPJ`^jZbV_*zRqWhjx}4s%z~Sn1j|VU(%zifz2^a$ozVuGIf_>q`tk1^V{`t@_ zjd(pgy|#HT&|~GM! diff --git a/tests/ref/math-mat-align-implicit.png b/tests/ref/math-mat-align-implicit.png index b184d9140a7eff77e8b69b544ddb31dabbe3f794..cd683315593520675aaf57c37cb30f714926a9e7 100644 GIT binary patch delta 945 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 FV1m!*%4h%p delta 2035 zcmV?)IPfYNzuA8}O z=6>{RZ0^p+xuWa3o4N74ygRK-%#5Uslq@l^RGQ2mgjoot0Xhx3RwJZDESX6DTz`ZR z#ZN)lRarJ+VSxZ)mjzj1cVEpn#@+pXcbDPwd4IFnneX#2{(pdZ%;)$^mc92XkLo5TCzpW& z8wl{#5b)-hc$EMn%=6XlM9qsS{|*yj}J z7hLdUg`|-|Na_QCm%7MsOat82B*jCVR+R&BpFZ*(fR?3H*sx5zy$!Sxklr$%zeI#% ztNGxPmuc|eJpgd!tWYrvjKB1g;1e$bfTdBWi3xuG7ztjx2i_GegQV1tASqG@q1_22 z_M7uEN;Lt#5Kb7G7lLtQn!~`|T(V%i@S!{*of}?MN`goJ>>MX-vkDDghaGo2Nq;aB z55beO@Hsm~4JT$eAnMxOZ(IP*Yyb`ZJ`$cT=V?wtRH;T&1yO~Xye0q(yNED0RD+|^ zb)drb7#EluSZpW5&~E^1u9tM6!?o=brhSb-Jz#=_0*V65FF2Ye-F1dNTW zZlc2@&t3&{!zu?E-lB!Oy0m17JAeE75s1rsrX4_WG8MKw0Z&e!Tc*?JUhN#cWj@|R zgx@*FccK3*nFhP=9pZzBr#ne-<$SMSWoLmguZ#r0n+DN|SNg#Fec(n2r6iN!*$3g3 z{_W+`MfsX_(nWb}iV*9C&iw=jAFTsE07GRuN-WHwC&ci~M0 zcxb{9IO`+*{20G&fmb!}t$&9&?aI#~?$f!g5YpWN3jDVU-jR9yVG{i6hrICKcoKYg z$#`LFuh5Vijw>X=*6HJg3-X2ZZg^Th2}Vq%XjZ=hNok)z(jo%@=oW(p*Dix6eah?7 zS-mkyI;&T2Hv(8yM}!gG364xrpu(-Iz|ry+G7L=)nA@fS9fqa_jDMMOl|7dNE3g79 z@C|}(AZFu(PwoJ*%u_tDeksUps$+*8k#>k{de08uoceV5X|Oa0fIZ5|4DZ_uN#|yE z!?)h52jQnHhgATue-A6{`kw>R=J9!g0AuK%E=Ks^8pr`7;V>f{bIN`8kJUmt zKKM*DBYgL;JSQIbJ%1ZqcOQJpzJF^Ae6sHTgL())88-Y~1EB}&nPAPMkf}wvOz`_l zAXD+%nc&wFAyZpkWrCx3LZ)^`v%$L{Q@hyUh&TwDGV2kz;ffUasZYBPp5h{SPF$bx zB?4!?7y&=Eo>YlW%mZVy8)lgu1UNEPE;u!k3BGgT7;u;R$A7xU1uwjl364sa>%{3% zJn#6#{1w#*n05CwzhipSzciwE92DQj55+;I;vNc)6F-*$naWTx!E2KsQ|l9$;Iudh z8FthnaQ33N;HRE~J@BN;V1o0Xf>7g|Um|d}<_P$yqgVw`GY>Ms#_4hmkb4>!Z<)RF zzys632FD&{hHQ0ep^sf6xbS60_^ajeoH$O)2xF!Vz=@~h$DGwO{Lbpc*&2BMVJ9n` zmkH3@@dY!C7%RwG7K0sbUJGiDs8$Xbwdo+1dLBG5Tp;FB7HkTvzzY0R^aE_NnIYHk R4VnM|002ovPDHLkV1fsk zELW@C+|1c@u9cG(WhvFnOvN;eOw3<13)iFs!)Z2^Wom!;1BJ<$R0EVS5Jcn1tv39Qa{sc_D2 zh`{(Zn+Pwo0dVz5^(ukyyhDQiyTMPJGsvT~4K?MPp#QP(JFJ?#?-Ehkc(BR{V0N|PhuEO>3 z(o!P;oPRz>gu6olG$d~2zQ?dPCLKeTvg2nn(EnBs5yqKh2z2Tss4$`$p*Z7O(BZaC zPAKf&+E&nEbhJWYtsUyRNrhEdg;n_B!Wqi<)tSD4FMJ2ZC1%m#`qeJDb7m%k)tJhE zz4f3O4_enih9ivZY)Oj-%lK;oHXa@m4~s-4P(`9BD}U#3@-SB z26sLW05^_Gom2wjl{ON5;d8JQ!K*S!@Yde|mSJ0HI{Tzq_hAlX{S~%Jhk=f4Bf;}B zAXxES68ww~g4w20;NHib5Uk6uhX7ljfN;UqQMj*WOH|-~#vyoCl~@SY?L8(REm3by zf`7aE>*4Us9G?W1F*=WZm~_)exB70l*L^iVKjgQQdwSL`o6k6 zSp15E%YE~VEpe|)23PKi$Re;=y?Cq6H_y0qB7~b*N`Q+4AzWbbXq;U3AP5)WAi(|p ztq`o<-$j7&tQi9}rS9YB^pP}pc6Cc5q<^kY0|j1i83Q%z!y&KcbOJoHd~Al)`8P>$ z?7m?JNNU0``|5+cNN~XiqVUo}65RW8{|MoeN2PAK;lAhkNie=YFLuS3VnBoI+?*vo zl$+I>4J&itQA*eklKfEv5k^cY1S;GCD%=&}g5uhjcadQjVxTnFIz8wxZrhMY+*|{t> z8uGGNB|+ZVd1e6l@l@FP9$3Tt#+ZNEThvU1cV~*hDe*MeHNBhdtChe#Gx|wz$r6ZN zG2XvMg5wSVtj5Ge6_90(+F^&Rn}73@oB;4sJP8g>16cLiat^L4FRz9yeYv(70R9Oj z!P7Mmta2I&o=^+HTE@EwaP0&L7f>_Wwmxi$%4#kKS49=Layvm^qG|#$xU$_IvwF41 zte$TMqyjaxTP-p`=(k!wSsb3Mr|+wInBQ0PFnwQrEkOK=1Fre*8Q1QATYt;_!I~{q zkfoXXdn5fB8$vL+W>cjVvK*C_b&z$Z($oT}5CZ|u8wcUW<&DP4Wtjxwf-MBN+pimf zwUGXsil?hFI7b1vZkWK8(E%y_R8ZhK8u`z;J!W-e66B@4VTM%JYb5yVU9>edonn$k1)8R5${eQRB@1SAkot$9C~`1C6QL6#7m=HYB1b!i zBZtco0)fLt;9NiL*%{}#oXdEA-;?dQ=l$33zt?`hXZ!Bi?|(dJ82+b*DX;=7umb;w z@UD8utYM!&;C<sxI7ws9c9uLpSBKsF_mO^z6q|Xc1KB8eCpLH;Ok#Vg>&~n zP)U?@#TPGx@q?NOzt_M9-(Nt3+ol7+&7)k&a$wACCc&q-f^El$N+H3klOU+&m-lar zSA4qgO$G=`U4KJ@XIz1x4z120Uhx@qx)un!HJt=Mrvqax&r;w=PxXT_+lXEQte*hp zCg=&Ub|RRYs3pKf!2nm^C3vYyCtmRd7twcYRLz9v)N51tm2}5+7~o;AV2TAwy;5qBLUT`&x1qFWfE&v!W%!IhAxF~oo zeU2Vn*IpyRi?h58kP>e&mO0_nk4f;a(X4RnVG^vFJybaPDA!FFJo|3~%!yrWJMNwa z8hrc+0Dn`;*-VOxfED|6H!3C{Tf08F)923hc`%Ov=_-ykes^u$wk zK~hu>220#bg5S=9AWdRICR~*#B;-QW9|?)ofU~lM;(Z8VUQQN^b%L8FF2@>0G9=OflUv%OupdYGCv*l-FXhUw>trXA};#>85>R{ zrNXVNNl7Jem6dd&+COmRSTHxXk^tWhC4Y>}+krSTjUixe%mV^!59)!dCP=ch!b1-n z;A#zW5MaEh_dctOBM-p6Gqd#Ix-kV5cy@u0k(qwL$9;9iyCitmAy)Ws3<)m!WTkl^=PWWsr4R%a5v%!{Wb`o5% zNbo7U92g&!lHk2@5LOcD2A^_+Yr(ZYmITlJ9fCAJMr1%_YH8 z%fVRf6cRkT1&no%auDE_(O_;&b0FUO)Qksn<7)_Tc`$_C`Z)&T{@R!caet|ci~v_~ zIq|3&CKrFy0SDg*@dDe-TsB{D$PEHqFwzU0o6ME#3m#eE$D_U;2}yCMAZcl>|DUmD z?|SL1-Wn~P)n6af(_szezc3mCTsnp@GD`z-WE#eSxljWEHjglav2N1u$9TRGf~tPn z4sq(pa}alCK@+%YCV>LKS%1ztGP7rq;0?!F;bT!G_`>Hyg}XYr%r5w=izK*f+EC%l zbS{kxex;WLBdkI+tG|JyxRa2yLWzo=0M=I%VXSBc zLk-J7g`3ucp@>E@4Ap7K?w|^E7^+6u2c4?ib1AR_EAW#D{|hH5KoR-wtoI-Q0000< KMNUMnLSTZSpzF8* diff --git a/tests/ref/math-mat-augment-set.png b/tests/ref/math-mat-augment-set.png index c5881b13976e15a853483b70e227573be1a4f367..1a66761591388a4bcd58dafec8824598b6a0000c 100644 GIT binary patch delta 1711 zcmV;g22lBu4zdl97k_C80{{R3#xNJ&0006#P)t-s|Ns9k%s`2WiL9)w>+9?N{r&s< z`@OxroSdA?%ggxq_^Yd{@bK{W_xJ7X?WLuqt*x!#;NYjHr@XwpOiWDW<>gjZR`K!i z+}zwlp`n-MppA`T4)zw>DTRS^D^z`(vudk}As-&c(prD|!v9Y$cwm3LA?(XijwY6DU zS?K8KXMbmBSXfx;>FN6V`ebBePEJlhKtMh|KHA#aLPA39?Ci?Q%1=*EP*6}eH#he7 z_B=d1Qc_YnIyyZ)J!oiXhK7dk@9#A=H90vsHa0f?{{H;@{D>*M#sB~WFiAu~RCwC$ z*=J8w2^5F%$B~&~7*UX-QUrE!7nNdRbrpNx-hX@Vz4x`3wZO{iBCLpt$bd@kAk55X z+uV|zT!t}olarX3`-?CBId7gg6Rzfh$K&xlxZ00m*|m%0RxUtUp#B(^dGknaNntm- zDh8nZ)e<}W@S^mG01{VaHL8l=2AJ=&!$ZWzFeI+dUNpV-7DzZY4&xXSS7j%PN^1ZK zr+>}B^j%=C)su#vl1+|qAPP}{xmMLP=ot%P2>)t@8I1iqh$(TscmOr=k9PxvDvk!N z@X~P8B}|Dc^K(C1mVSgV!uRyWmuPwSLpR}xAX>K7xe3>|p~Y9|CVbk5mZ?cM;mIkq z965~PkwxhPR=B+4S&*A^9X_J{H@*!+Mt|6Tl*mn%{EZdE{&ARzNmy>Ol*5r0c^XSt zZqC&bLCb}U0P!e9k+9sH>*59N?|96gF=mIuRUkLV(*KUh&U&=h3WusU29cXA<#2P4 zo1f#JX0$X!+=L?yXqoB+R?JJm3ZQceEyp|Dgijnt%Z)xaANBQL&~oZ448g_etACBK zy-ejR9|Pz5`Wv*2yypkVh1+J>ULcPWS%E#fQB$)4h|k#1YI`LK_x7Nty4LZmwpNmG z?OF6(8Up;&FpLqlR+4btDHP@A0r`QEd?RcxOY0Pl)qVg?Ih%mIb6pnY?M1NUjRVv|)1E}jF1zq0DB9F)8xt~gyZTog+TZ6i% z$`DEao!U@=vT!=|&)?|hY!oG?*Asuu)X9){#`Wrt~vfk zIRO)9*j{qu>J*AHTL1~SUx(-tBWy3Z;g5EsC;XfvJTeUb#Er1MKvu&(^nVm?afIoC zI~ZYmfvlJJqG$g?fY9msAf{_q+b)}7dx5O9Cs3334mf3GVutMn$lCuBTHgPFM0PmQ z@M^T|d(%z0ZarFdta20HyF>AB5xv!bvMEH(8?{XgSx6;e34L z7N%Er`mC_rWHq1DewR546Mx|NotxZbDSp(Axd01iAiBUAmYb~HM&(~$I`F=AbJeQM%TYp5)!A>9}3e$dM%^f~} z5Jlr7Kp#8~V6VBu@tPQl(wl&?@S3%Ny{vGkU|A58y>@OxQ}>Ag5Q|~3mKjbED2k)% z&~K?dK>j?0vZj-%gece5qArKowr*v%wcfiTkH_->`yczQPidWJ{mTFV002ovPDHLk FV1jcOdR+hj delta 1808 zcmV+r2k-c@4U!I!7k_IA0{{R3i}<$H00075P)t-s|NsB~{{H>_{rvp=`}_O)`uh3# z`S|$w_xJbq_V)Gl_4M@g^Yioa^78TV@$m5Q@9*#K?(XgF?d+9?4>gws~>FDU_ z=jZ3<=H}()<>ch#(^($dk<(a+D%&d$!w&CSfr%*)Hm%F4>g$;rsb$j8UW#>U2% z<)D`3pT)(+#KgqI!^6VD!ok78zrVk|y}i7=yt})*y1Kf#xw*KwxVN{rwzjslwY9Ue zv$C?Xv9YnQuYa$uuCA@Et*or9tE;Q3s;a4}sbbh~sHmu>rlzH(rK6*xp`oFmprD_h zpPrtcot>SWoSd4PnwgoIn3$NCmzS27mXwr~l9G~_eSCa;dwY9&dU|#NEijSF z1TSe?wrLugCSnCGl!O_gQcA@oyU}J|l3cTLkzxh9(8cclTlJmu&AfAjZFXng8E2gH z{PfKG!#=b7&Axl)TYP+cd~RLxk6M{Ei^RO1i!$kFW?E}#ATc>TL3C*;2Z|TkaIk7k z0DoYtEo(-VIUfTR$HF$;QZ(lk3}dZp9-6#$55SW)%w_l*!&qC^g(5RzfP}N-Fq8?5 zXZ?lfQG37>&WXcF1~8sA?njTaWu7p@FaR)~J#r2;0)J-#%x?W~z8ijV!O}*6@hszy zG_;ue7lvu2rMJ0Z7B0s!)_$Ik7OTHUFn{6ykyTfSF)R{`S zvk5JFV;C~lZ3x=%-Ah1bUW@f=zvI?|;#b{pMOzqTCMNG#GaQ4l7waEwb3YA9FAZZf&nBfGp|JsYoBr5(g*9^@Z9!K79lf_>3^Rw zlrF{%=M@(hA~P}NaBqJq3#4E9dt9>8rJ-SEVoH=h>Mo$NAqgshF1_&H2vAb#^53f` zrUW>>7cDk^g&}L>=1Jy^t-0J+4ql5tiWZB0#BemX=#U9pbEs$ugV%mrh!&ZDrg?U? zHIP*zmVP}8HDZhH1MKi*6Lu{@cz<3$dNkMBNA{74ChS^*aNW!3vEVa+I9$PmT}u$| zTZAH?7X!OjRPQ%oYYz9meYVVF`RCB2`T)S}QcT#ILsnki6py{O3RT`MOm0^fM$l!( ziKN1T$aIuh)@Y@&lEfS;N1Y;)pvb?a^6~NUxtY|G1ka&P`znNlKah)CP=6-02bhqJ zB|p~Z7xa?RT+Tw(*$&63)&?LOU^F(ah@eGx6vGG%;(raxOf1^1ea0QR zh40|9>!1^snV9|=lesRGgF{(OO_d4DOiVM}aXys=a=rsCj+{y*eCmkeM}3o4<_jOB z68`9UwAd2G;jTMC%nb*p;UE@!94*Sf!%+Lc+MS3w;fjth4r0IDj}}vZ$M7Y5ftdF{ zH?iweQR9a@fk|-~3V$Ltet706dc3h6#_Z(;;irzF$J#C!vzHTu-(QO&-(~{s1=EiM z*4%KQwk?Q*wLokFitO19OssxlGGNUOFA0Sn#=+XNHE0q%ou1qRNsk6lW%*0Vg%2)A ynca_ZBipudBhS>KPBlre#=oTU@$tEZ`4`!{o0>hWUX}m=00{s|MNUMnLSTZElAMwN diff --git a/tests/ref/math-mat-augment.png b/tests/ref/math-mat-augment.png index 0e2a42a241c8195744b2442e32bbaaffa1920ffe..306c4b1995f82e367be5442de9253dd9ae69e78e 100644 GIT binary patch literal 3563 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 B_7MO8 diff --git a/tests/ref/math-mat-baseline.png b/tests/ref/math-mat-baseline.png index d2f26621306cf21c89c4b80a0892857274b9da7a..01928f724d2784e7e1f60f56d014fb76371596d3 100644 GIT binary patch delta 806 zcmV+>1KIqt2CxQ@7k@qo00000#SVaf0008_Nklv8auqR4}@0$s&ViDZ+Jh%-!GRuWM%NT@n19-Xk4q&xgEPS;9J=@bR4025+J}UCn zIImFJy=o<%@*#mJlA>3p7jeM8c_Yghw%7} zST3BoxWnykw`IiI38MB;QzXKyzYIXkXRUMIO4V z^Xh#7%*_%BUyngk9@B-&=B(<2CQDk<*+u{wb~yps>_ihbo>=i4C0Fksg`wt!h-|nHg_^UAZetpP)Kb zb?QJNfPZK>WfH2w#{js}(e$<|O`vhmPQOVhl8ft3c6WDoe7iTLh7ToLf_~=B4H-D2$1uckbaCuCV#x{IeOo+8Gt3{QilW8>ja^2S~7Y` z3Sd-}NU13c)#(hOaN}b1b})doMbu1hMm4`tC`>{PI%~cIM*ACiwy_HU#~P%<Dtwi=ZyLD!Pp* z=pv#>Dq4l2E{deps34<_ii{Ss!oU_=h$4j2v7Eu0Qo_ozaw;{8)KpwT%TO^bmvTYP z(e#^{Cpdw8>Zsqqs}j!d`oP2goSQR>VKREuF!6@HVQ+ZEgnzX_&EUZxhru$2?8?WW zia-o87LKvfzruS^XbUa^;;eFE`w9lo;tQ|aA4LGHZ4nD!f64%If&s_zCV>0bq{7-P zCpztyENAKAYVh40%~YQb&@tB`6i(fW-kvONIX(C_lBf$$RKHXOMn| z9##=|8bFCUA%7H}lZ%dP69*Dr(A_~cQ~@YOb7jJ=v32O>BxIZ0=`KIEm@dw-PLXic zI6O4zyGS^5Iv$#tArgMP1P?8JEE10Q#Y4XFBH`!-7*lu>lm*d4y!gCsv0QlH%CNAo z&_lDQJLt=~K?zq+Ed#)mh@|*Ld@GdONBc!BQ9HwU_1JSh2(c(B$0h1Yr9Q zP<)!2*Fkk$@!*8ZFQVkW-k;nF4}Z<(5sDw?D~VV_--?E<3sLOH)K2nRORHOegogA9J zj6EXzbmNeP^};^+GX!CCukia9k^P6wgS0s16$TdnzaIhHJUrxM6A2ehp@*~zjs8sj zED~-RPj@x9!oSgvjxntwVJ0=Ar(M8}&g23>DSw-YOnB2v^vosn_Iqc2RFVxPWus6y zG6cOq+&C3U{^qABp;1EN%4O*JV#SI5wcy^U5E07r7f!UX(8=gWgM`d00aT)5^CdJg*L+EF7ICiMmeg(M>x=A(uo mS|KJz!_vHAZ`d0iG2y>=uN^j*@}lej0000r? zk^Cr1TpUC+Bsqv2{5*(@+CfZTMaz%!v&blgG7d^3cCh)eS{v@sgDwP8OMyJSNCC^$n zo5|p^J=S_sN`D6D7+C9VHW{4hVy*5>GFV|{tyTpY%$ZoLi6etEJgn7|k$x~|WUWSy z3|81!t4%=$XSrCbGm8w)yeu*zU2CzRu2>a>)s5eogmDa~{;WqgQVf31T$l=_Uw0&#lb-;BWDB<_^ zUxujil@x|W delta 483 zcmV<90UZ901n>ip7k@Pf00000ugP${0005ENklkhtA}BDSI(WNFGPnp&K8<^TWhCk#-+VCR3gL;wHZ zPoky8kK@3U39{Jk<^PLk0_ngJHlcF_-Xe7NNz2mp?}3HKd@QcbOA*EQKX&4 z7rp;uv3TXJ|2sgm(*>GY++7Ox+H8fX?~vkHMoV=kh*8r^GmB#<;gek!MKg=-*W;7j zV@orOmCoRky{t$xi#ea*lYPobGmF`u)!|3vWJt z%tbScmGRa;r+-vvX0gLAFtuaV0ul}3 z(qC0+*x0LE10-77{%1BJ#7=CQZ+H?&Z>pf7#V>t;#9aA#>)nt`lHaW+yMa{1OIr3M za>4QV{2!*w>3o`YVLm3{koXt-p0>Tk-P5s)SL~&A|9I;$to`FnqeBs+7LQsyYVq*5 Z7ywe-VaC$1f7Ac~002ovPDHLkV1ig@`9%N# diff --git a/tests/ref/math-mat-gaps.png b/tests/ref/math-mat-gaps.png index 405358776c3c42f9e20a7ac48ae152506cf3dfa1..95cd6cf113bbbedcb2fda0ac1af1bd39509cc87e 100644 GIT binary patch delta 1305 zcmV+!1?Kvl3ZDv)7k_IA00000nN1lx000E$Nkl1Kqlgn}bE5TV+*)YqC|&Q%k_VSfTVhfsVx5s7g5BlY2$nHYp` zHZwIB2(DHhjyz-(hLfKFWGzr0_U|wZ*Thl>xCW^XmrO!8(v8UV=_%Xy08BWeI2^MO zz_s-|TQdU1(SOm=)d0(56^CcUBW2eIio@eGkn-zT#o@ulNI5%5akx({QtJ9B4*On2 z%0*wrVV_c@l=>(R_pV1ueee4v>{Ei264g`tRv@LqS8>>{7AZA;io-+BAmy~b;&4z7 z8u$5b5UWCy{)*~HA_bs!Wy#np2$fAnW1XcqykQZ*`F}XZmm=b}SOUQ+yNYsaKgmO3CGg?dtlbZm>mK?^6Fj)l{%Fp!v z2zbNZuzxq~4c~*|Zj8B23U|$K!O+%Y=7htG!PtsYGs0PQ);L{c{IE@tZvguRjcDS6v2=Y=7(We;}+0(0yw)40mpD{#6dR`niw~ z+dl>_&OM1o^-`=$p(+f}S+W6Yz8RN{NL1i({|_aZc_+vK z2!BsQQy74pU2jN->xZM+KV^xX+Zsj=AGRJ~=R7n8fymiykq+;D9Rue^pgH&?ayE{U z4#&*FK%1XwC;oIbM*JGh3I}h)$iOpZg@ckX;-3eQ=Z~DEAn9=52#oZy0c1XgoY<$N z!_UTJr2j#)rncYEJ*T|hdLvx`oJ-R@4$X_7YQvh7U_4t4it%XM_Y#_I%P?zd#+^fB3v0zAwObD}{Wmm4vQsBdmJeGu0<^O^lG{$Cmw%16 z1MUDPn!1OP6CEZWZW{+2wUBDzw!crE8dL-vS%uEss{`Q5&xv~wE8l`9e2sjVg@xd- z?S1EW@JN3l5qPT^bOS2^qLN(?btBUK;W{)^l8_I#%mi@qUq{yfx{&<Q`1e3*<>gsx3<0lLJ+Xv#x#5PzvWen1a90_aJYgj@u=X4i2`?`i3Y91zpv1Mbd?cEkr!fb89(2jcV@2xlN4SU1)PxxO4781yvCZZiu P00000NkvXXu0mjfPUvZF delta 1303 zcmV+y1?c*p3Y`j&7k_OC00000PZatl000E!NklcPa0;jeqW?GhtmxUHynDfG;a*KJ19c7$ zXhcfm0G-2@a-@`7`fSH$*gRuD!vXh@QXimmctjaeE(Pfvo^S?5{?UVoxxPn{IZ@~E z{1kxSqM1;FP^uM0!a|+HJ68g@nq6Z%5V=*LhFPAVbAPzr}&7Z|EFm z#A8(9c?cY-xihgHaEwIn@Y)O@ZWGb#5h%?*5ONX7UZs1uc?NLRmSt^3#JMrl4$N-W zJE8K6);;0#OeE)z$><@TtPi`+(~u7k~2M%1?pglS_TO@ukxX;cgV5vgV_> z9p*&j+}v$3e*#P@K|UN&3$UaVd?$Ny4zTDts0OPq^(krTh@7?A4xspaw|ux}9{&i_ z$&YcsrA4TEp7{$Y->#MquS^kyX`0;w@MbHD+UJpzxIjJ}@<0%FZ0xQ9h{-@v5{#U~ zQ-7tyjiXVx7v_VP`{ONJ;{j5mQ526tPP$b(d~6DeQ)#J{cs;b)Y-Ipduc9anL5^*T zbT~c|4IKf7?Re=rv;?#m6%J2AOJJE%VQV^CMim69&OzH609cUSx z+h?PG>cYViXKY9~bSGMdzLYgz;iF?{3sCqSD)+P907uiWh9dUECKNGo z@?m02fQqyf4?fNuKLNbo3aY?50Q>nzLp_MxUZaM2?-26gwgn*eOB|q@a}vePFY*vd zJ*9>jQ;B?-tTcok%yt2){a>QGG=CM5>~=LwS1|sB*=8rnZV_b}lO zdbRG10paW4(3`u_7!YPpKH54yYBMCvzBV)+Y&3rxn_)9-hM%7B-&bRxJ`iZnT1o%_ N002ovPDHLkV1kEeWrhF% diff --git a/tests/ref/math-mat-linebreaks.png b/tests/ref/math-mat-linebreaks.png index 52ff0a8bbc61bba3604655887b7aeb893fc9115d..6666749dabf1fb1a75f67347472ee189f775a5eb 100644 GIT binary patch delta 636 zcmV-?0)zdF1&9TZ7k@Yi000006IWwm0006{Nkl? zsKBDYB3961&CpaTy2!Paixvn$vlz`*I53(naujW`)#wCE(FNJeUnvw43h7vwrO6`5 zwSg_SJ@TISz~Q|=`+9Spi|@1N>ccq~gRKIalnNczVI9_C5`TF9E^qe|Eu60V2RV7m zDk*&S7nFRnQ^Ngj^|N!75H{ujyRX4`OlDhVL9mkLf*$`z9Q&%m0#(%f#61&+EzLtlhlnMj$QxNsCupZIGC zJTq6JK9Y3izjeDjmdz<@b*TzPGwgPfaP!%fQ!KBd33yk0e`V;&Tash_Lt{Xx8Tl8^;Neo zVBAyMKe^I^rex;`KK(|tuRQQ)NrDPbyhbVfDiFhPWDKj(#2DbtY7AGmio3p+-3Ne} zk`Efg$2{V8G_yND4lzQSci3ZGvN*K WN34eLR6y+j0000Fp_9-l zGDtAGC{c8XR6@&wB3QQ48A}g}S`?Zq2AQdpA-F(8@h}obL~bT61Y6V&wl$2HZaQ@> zHn6R^Z-?Juy|=>c@!;=!d7j&c_c^=;Y*9N3wkRFeVIAIPuz&x)Haiz(;Ydq^wlv=T zDGE3B@6wi?&Fux7j(={VBfGavv&sGgK9vAi`3|s9E(ben0mdGU8UQNh#9*Txh!^wP z0$^(vgZC!@w~=P|3J@rkf&+yB@f+TwwkW{fA42eW82~YVJP1IkQwV-|5v8*>A=uoC zlBq)ou6c~oZGV#xT-}e-o$COEQ48lBE~*D0czO*0s>=Z0`T=033N2?KUoSrP_lr|K zXvNNemNifCQq9Lq7Ph|u=I1lKw0s8Ud|+A34?KE#*_4HwBGCKdxrxSZ_Y=(1bwMV^ zat!aQ0ie#8F49hZ0H}pfDZ_&t&v-74mjm2QA)7pnmFYhv*5Er3HQegV`v#Nc$v24I<; z90F1&5QDMW0m4auz7at*X7QFz>CPW%z<5%=m~ltqx>imX#p_tLd-~>#z<3 Ze*pLZl?g+Rl0X0e002ovPDHLkV1l@1Bn|)o diff --git a/tests/ref/math-mat-sparse.png b/tests/ref/math-mat-sparse.png index e9f0d948c363f982089c2fc19e5e2c57f3ae5ef1..c255fe3e59f72eeb47e723c5008be892d96f64da 100644 GIT binary patch delta 947 zcmV;k15Et#2D}H57k@kv;Lm;zwPk+tI!dW;AXW_R6-`|E( zbpbs%v@(iP$v=Zy@aj>FdPuMPR0Q)9_kdnc5}vQofm=2MFmiAKX*G9V`7(-Gy|q?o zb%oXe^)3y#a1x_rI*hZ0rJb18Z-s&xtj}OPPaVGKzzl}CC6XEb49c$o<(HM=-%n+Dqe`ffrI3b6{|Oky{Ik;`cm7|i0%C0Fqcj!x z2cxM|dBYq%7yS)@xdV#uiSNPaMTh4iAiCpryOUxJ#OY(^Ax2L-JY8_>^f&+|#}wgR zWoY%sPDQx#KeXCZp$PxH8?73xig4*(wAx#$2+yw+Cx36#7=SdTVt&AXJ`OJiRAWc(vQH-C00M$!$A9d?udr?1NHvhiIid0_(Mv5a88*x1=oT|oEsIEx=QO6LO&41`3)6ewZF(ZW_k|&G;qQVhvc;R}q zTE9>cE^a`phT;$H%Cv7stF3lLc;h;Zx`PmI^MEv^UU&e{=?DPMYDM@!82~LM?ckg_ zdyLnnTyKLF4tt|c09G7QguUNkRMpP#YG(40rsXKPhrhf;MR|*!h3cI=}{>Y%K&-G@Zu>}hJc#g%J9pt z0eXt7hWYo|{&ql~_S<}ux@*H|bl-w2xSK*wfMpZPFdI66Cqsi{aP0wrJR>j;5sW4V zhlU~OO#m1EM;#9TigLwc8ZgaAP^|tWIxH~tmr$y03wkhql=5f)lgPqZI19hEUIFYz VPg@A2?~4Ec002ovPDHLkV1ide%=Z8Q delta 872 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 delta 1812 zcmV+v2kZER4wep(7k^y{0{{R3S=&-&0008_P)t-s|NsB2tgMNNiTC&S?Ck9R{{H&< z`uX|!tE;R1{r%C=(aOroprD|GgM;|^_|nqSV`F2jt*vNiXyoMN)6>(>&(DjCi~IZg z#>U2deSN;ZzOS#Z{QUgj;NY5?nlm#qDk>_vy1Hg&X4~7_$bZPlgoK28dV2Qu_VMxY zLqkJlWo5Lqw8Fx|adC0f)YM&FUB$)4larI~?(XH~CcUe0+d_fbhxN;h4Mm>+;J9Nb_tjODgt?t6t z{PXwgxX|ODzxU$o%S(vjo4wzTwB@A3@y*`VY@XYItLwSZ?7r0f_xj$AwDQs5?ZMXC zeyaA~>F~a;E-o%5B_-9>)sc~r>bB3Rsi~KjmmeP=qN1Xno}OuGY0%KnS65f_)#Kse z;p5}uwY9aCm6hh^=IZL|etv#TOiWQxQJ9#RR8&-CWMm;BA#`+fv$M0nz`%lnf?;7{ z$H&Lk*4AojY91aQHa0ddFE3tRUZ|+3s;a8SIe&ajO--YtquScqIyySc%*=3baHOQ9 zIXO9xkB^3ihMk?Ay}iB3$;l%lBSAqyOG``H+1cys>nSNIb#--{o0~sBKc%ImH8nNC z!NJ7D#5XrL^z`&nQc|(8v9hwVU|?WxZ*Q)yuHxe2G&D5J%ggEM>Fw?9@bK{R^78NR z?|(QrIP>%KK0ZG6_4Qa-SZL#rg8%>n+DSw~RCwC$*mqEqX8_0XFOZNy0)h%ELzyZd z?k!k5?QYfDz4zXG@4ffld)hs!nO0oGFud7=L@H8In-Uxi)y`UC^)81=a&AK*-9>9&d-l zBhap2B0!%s5Q;`pT>z$1v@6IB4cq!MwHWx!i)QZOsIb!5ngpzfp>XPJgG% zLl3?OW(SfyeD3)d=yL0Avmm$}=s$ocmV8dPR@OtR6WBHx&YCrQ9-ut(@E^c2Q&5&C z@Zz&qUNId|Zn=3MU|A3-A&TGqbZh5!$X_Q8rZ8hRH{L)95x#6H%BCFdy^oof(`C8{ zJ5B+nW%VGOw+7eOxJgr9hlyKavRm!AeK{DSU%D8q+YKxvoZ9WclN6tu(K3(u{BR&~vORYz7q*=Ur5 zQhEBR$M3v@)U%N;zG&{Tke3cD%AtGfUjfV`D!y+<@-IdBZVhBPfr&@M`F|J80nffj zGb$@9p>zyN*Ru}7id9HdJsD`&z<7GNMzy!k3%*~R89NKHP3rGCIM6i7!ZEGL9H z8&KMiI_!i9o(wGhlqhN)0Ji*}{2-*PT8(fbKu$LQPf{7tv`s)*wWwZRX+?x_pMYk; z@j!b5jyDjjKh(`{0wzsHw}1T`pm_unUPqY^@S`8yD!v8Es}D#IYs4@7 z>u;?cAk-~>`6WPY+QUJww-c$o5I}93!_gVxJt`3Ev@RQf&K+$*5Nt)Gkkqz8>#g49 zcW(xvzBmy;ZQ8%%0Bj9=Y^Y6l*dw0M{;;sxG>2RMf!)brVYO)vvmOG3h1I4zyzZBu zw}4>pv$7dboAxlSzJEx`mShW{Hm%{mVx88-7vr??Be6%rNrSc_jmfrl0&>$I?w^^6 zG;XM8Eg-jezU&1c&>Qd7ULP#!?1gYpKB40uW_5gTb;r(4e}b?g-}(`tHqGHM9+UBU ztIJ@g(?k>|r*km6q}lB@qOjTRX~zFz27@6k{sVi|V->VecMYBZ0000MgpLj9Kv)$9%njG2?82_3 zZY;aFv2}A>wmPXR9RrJe{|1{yjav(|>dhQ8FhMj)i04Sa`<6 z`Q;obC7?uK#h~8IMD`rL{*q1EaK1L3I3EGE>vAn@vJxV->BOl7gQDSeotUc$vTiKc zJ(emFaJvJUuC<8lBT9yE%r!8Iuyzcv<{Ycnj0?NI_J_~@8vm1$Vd*UbS`cB9D;G#W zdx?aBTP>t*c8hS)?)^hbhEL=XkmdxM4@1pziGaI1 zkZC(F{+X5HR4^RhMS#%@d4jsF0QU4lKX}XsYZVLkq^P1ZAnwzB(FxaFi->X` zbz@aTnqqIKSU48Gw>vwUqZ000coX<`n-N*zwnQcwntze-+vfoG?!|XK-X|``>q&?B zRo&cMXVz6{KYMa8!tn5;9)H-|@v3K1*ip*OJ&ae{M(<_FkwCEOv=GPWh6uyW&j9}3 zg2~}?IjB~Z1H(D}`6d8QcADLk*xH>`2ttk)_ab;L!f@r|Q-&{EgjKdQCFt6iXI{kZmbV0^IXxOl{EopTVFtiP`x(cwWF1s?cl2P4< zP_h2wGK!2x%BCL`tRY!X94c&)F&b6dg0z41Zyg6THVb=f8-&{*u1g+zQevzWPjmj{19MY z9j{mjn(NNmiZEuTVGp6ccOcuJ+eX;1skp>22z2Km`v$*dWdK)iu(BB73^E6w7a^Se z(SN_ywiCUEYxpH2=zp&a8y>wpugiRZV7Nl#1#o_m4uW;51Vdk{56BfxudyLGf?Iuf zhwpuW>l)1`pK1;QT(ITq!-cu^83%un!>csHbHxDqcO(Q?!VtizdAppz-<(?=GMQ3b zuXhOuyS)fCSQmv2>+)IN+8aEvt_q=KnST#iro(;}Z0C2@H9+Hhisw(>>eA$DapL3^ z8gXK09Iea3hLZk$+(p!VnV9%cL%THhu_%hW8!CvU2vqgW19$Wa+3~KcivGlmB|+Diua8;OoLM zNS{;raLdyGBUuZxU5t0UFj)e6HgF}AJr&A_rN@S&^BnVCVwA$(%_**^grTY<_IFb( g91F+7|C{hXi6?DL=0_CF00000Ne4wvM6N<$g7?%qvj6}9 delta 1224 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 diff --git a/tests/ref/math-vec-align.png b/tests/ref/math-vec-align.png index 680d0936d936349a26c04c5dfe416595c6f9be56..07d58df722224d48cc19c4a5ef0fbed5e6d819c2 100644 GIT binary patch delta 1118 zcmV-k1fl!N2<8Zo7k@Yi000006IWwm000CnNklQDi|$ zVy}M+!-`OdNV0-n_ApZ_HMQk>kdGEUEF*er>tO{!!%4KttZ6Te9uQ&=3TazSvj`up zmBV~A-FDmW+}*o#<}W=$P=DAq zSaT6$yHzgQx_16z;^Rifo~Y*se_P(o?s#yHcF86-ZC29m>}57}DO#3h=7q)ve z`-5*!ahY$sYJ0gy4VQd-jN7SgO}0m^sl4EO2WS^(^N4+^?Co)MTBrkEX_I#>qsM1X zB9m?41TSgt1Ai7WYbAfEsxP?wpyXd>3w^+C^ZCHfQb2oqpt&XR+cnaaH67GRQl|uV z&2V_*6?GnQleAX?3ma;>&z}i!B_b){k8V~CvW$sNhU4D}TtVu-sn#06F zj1bTkCQihJ7igMM!~xF9L;JQ3aYLz|j)P}bkutOuP4{MVfRhUGLn~~cx;Q+I(}CI) zcv_Ui0e?=^;GILPpxQ-vx=0IZ4Z%}QA_q7;ft1RWYQJBaK$W5Lj^}%*Qw&vtn%Kh` zPpia@gz!O(INvbPh_4?RXvF3uX~h3Ccv>0`4z35y4adRZxuEsII5=$@2Y7ru4h}Mc zrjNwIBh$&E2I1iN@q?J^eYXdiYW?AXrrNk}@PBK3Kkwk{{=qNu)z$rjEys4~`N5Hy z0@{KbK-ClRbfOxxAsA0HBRRl}3;yurY6d+MgQqcPK%4*Yy$@DbY;y-+Hm z@k7t90PRt9py_@U2l%K8?OQj7l(!K$cx)Xhp&!vS{Sl%n<(1JFMAh~MLYUCmB}xApGS#yeJT0?nf#jPWiPZF z1LtbJ*Pa0bKU(XZpDYaQ9Ovc%uX+mF(gdwb21mAt>18!&8%f(_u=EBksGE&>AIh%S>--oda4+(tlbR9M$TLqhX_wq<7`_>bz1euxqxHwy{>w zvwF#=zM|8UWCbj#lD~e4PTwVhx?`Pu|D6hN&{uU%(HB8*#LBB=OsCSv`2{teve6=+ z^*m}hEhl!t`IesN{L|L6rq3B_%6;2A-}|TLExzrFV*k{+)WQ4zxb~?3Ew+U+9apI? zHtmS-q}b%707*qoM6N<$f-FQWvj6}9 delta 1090 zcmV-I1iky_2+9bM7k@bj00000*bA`7000CLNkl+L8T)LAxuVK z&8){V`#qTM%I5$dJdB_+k9WyZwFm|;sl+nD0H#N?IlxJI2rPw3?&?@LjaB1KRlsR} z5(hZ30DplMY?Qld6`Zb8$=w)?4X}M2;BY0;x9vXQCb{Q?dPkZ*d!Ivd@Q4rC^n$1| zoPWlT5;Y^txccDP5oWBtltjO4|J1V(p90wdjj0iG2PgM+kqw?bfWh!U@D5Dbo= z#Q|QO3xgG%a=#o6gQG9Yy;A{$b64{(^_RFq&42!vx-l!^oByRYpeE=^`d{U zS+DQ*54LpZJNdz3N(9z8a*pT1>0EM-$HA#GY|MVS{$+4RE`mx_49Zdwg}{oekh@)B z0n=ld9N=^8hwPyCoIKk-MIo~6;hccElC!1O}^iyuH9`}8t%fIl>h($07*qo IM6N<$g8pp?od5s; diff --git a/tests/ref/math-vec-gap.png b/tests/ref/math-vec-gap.png index e48b3e9022b8742f1a3c1557e809c8a1ddee127f..ccfb217111766e8c1f7ac89688022582a4b0cfcc 100644 GIT binary patch delta 423 zcmV;Y0a*T|1GEE>7k@Me00000WR;^C0004dNklUnzH-(~#KmFch!>#z<>!x@LRlP|LHS6>RqLDuvs3V+X>!`YY@h&d(U+hKq` z4}j%H5Vl{H;Fv`YerTlx)AA?=2j+gmi+(Y=V zZmUdoObhWtl6wuDCdw{I7jr6qmeiV?nINn|R@qPnTzU^K*S-j8}l^?u-P8N5jqVm%^>11(B8k)r|bh6k}7nQH;Nhgcj zGEn&$Z3AZUaF1gz^f>k!?m^v!mXA}q=w$KYK(wG=La(yg3QXOcTKNnT#|PeTQMJecg2JwEfL~ z1!3Ha{72vZ@%L5;-SBO6C}Py&QHw_{9x)aJ05|AziVz_-XVd@y002ovPDHLkV1ma0 B%pw2) diff --git a/tests/ref/math-vec-linebreaks.png b/tests/ref/math-vec-linebreaks.png index 52ff0a8bbc61bba3604655887b7aeb893fc9115d..6666749dabf1fb1a75f67347472ee189f775a5eb 100644 GIT binary patch delta 636 zcmV-?0)zdF1&9TZ7k@Yi000006IWwm0006{Nkl? zsKBDYB3961&CpaTy2!Paixvn$vlz`*I53(naujW`)#wCE(FNJeUnvw43h7vwrO6`5 zwSg_SJ@TISz~Q|=`+9Spi|@1N>ccq~gRKIalnNczVI9_C5`TF9E^qe|Eu60V2RV7m zDk*&S7nFRnQ^Ngj^|N!75H{ujyRX4`OlDhVL9mkLf*$`z9Q&%m0#(%f#61&+EzLtlhlnMj$QxNsCupZIGC zJTq6JK9Y3izjeDjmdz<@b*TzPGwgPfaP!%fQ!KBd33yk0e`V;&Tash_Lt{Xx8Tl8^;Neo zVBAyMKe^I^rex;`KK(|tuRQQ)NrDPbyhbVfDiFhPWDKj(#2DbtY7AGmio3p+-3Ne} zk`Efg$2{V8G_yND4lzQSci3ZGvN*K WN34eLR6y+j0000Fp_9-l zGDtAGC{c8XR6@&wB3QQ48A}g}S`?Zq2AQdpA-F(8@h}obL~bT61Y6V&wl$2HZaQ@> zHn6R^Z-?Juy|=>c@!;=!d7j&c_c^=;Y*9N3wkRFeVIAIPuz&x)Haiz(;Ydq^wlv=T zDGE3B@6wi?&Fux7j(={VBfGavv&sGgK9vAi`3|s9E(ben0mdGU8UQNh#9*Txh!^wP z0$^(vgZC!@w~=P|3J@rkf&+yB@f+TwwkW{fA42eW82~YVJP1IkQwV-|5v8*>A=uoC zlBq)ou6c~oZGV#xT-}e-o$COEQ48lBE~*D0czO*0s>=Z0`T=033N2?KUoSrP_lr|K zXvNNemNifCQq9Lq7Ph|u=I1lKw0s8Ud|+A34?KE#*_4HwBGCKdxrxSZ_Y=(1bwMV^ zat!aQ0ie#8F49hZ0H}pfDZ_&t&v-74mjm2QA)7pnmFYhv*5Er3HQegV`v#Nc$v24I<; z90F1&5QDMW0m4auz7at*X7QFz>CPW%z<5%=m~ltqx>imX#p_tLd-~>#z<3 Ze*pLZl?g+Rl0X0e002ovPDHLkV1l@1Bn|)o diff --git a/tests/ref/math-vec-wide.png b/tests/ref/math-vec-wide.png index 9dc887a8cd7640ae9f0ba0c7707c6bfca25d0c52..000e3cf2a6f608878d55cfe87a78114e69a49222 100644 GIT binary patch delta 618 zcmV-w0+s#j1oi}w7k@Yi000006IWwm0006#Nkl=?-`3T7r@lqvMXjke}0$Sz{GgsfIt(T}Y}GhJmd(-Ah( z<$k!mV>^AH;hu~8 z{t7f%FABj;X4D4j%x$PW-YEnhu1B}A)k1KI8{LwNV>0kYFZ!(v$iPKI=vUk$0~dZl zzYSg)c%c^{(tmK?G)1OqGTGaYegt6oRmq8M*EoIyfN?tj$t~2L%h$vsjlLhvz|3^I zxC)Q;V|J-9Oq6}i7yO{*ZlVTw(v;3krX{b)^nG_67!CRwg25O-+p*686guY&vu85e z0fYwAjgV=Dqjetu%bMp7mw(b31^n&ly46)DPrP{9s;=5w zM$6uOt(w~%!zd|mugPTct1$Q6RX;_4r=_pa6c3=S$Rz`>7(lNyoOv!F z2UGW!9F3NzBwVbKQid9@n>tlkpKVy07*qoM6N<$ Ef_r}@Z2$lO delta 608 zcmV-m0-yc%1ndNm7k@bj00000*bA`70006rNklygdj{E$oyo{@e?5QG%;J|3DBMfQ zDBKB4Xl8N6I(!ztv!d2HcsNxSdZ-rD%B1>rL+HyTu#3|JU_G zitc&Py7GU~N`Gouym|J5`$<50cQ**kM~h?Et0)%#pB+cFIDT4u;r~K(LB>N+d)5Mp zAMI^b!EJ32C)7cLnqwN}LGAwk<~4L5^IQj0`}h4nj_l)$>HpW;gIS6@DYrQC#zq{8 z>yoaI$0}rtpO?IeolUjG_5CicRQ>VZy?Z|(74T}P+JD{GXq%7OP7x~FmJG9!i?GE< zXk)R`c>)T=uhGV0d-UA$5Vbb?!Tg0b7Dq2a6Np%V!o4FzqZUYOBPxGeJF3O|Eofx% zaSzlc*6vxT7SFAwk;Q-HP$uq5R2?XUW8T3LJ{5j9bV zrM^Jo?pbc3U2oCvJxY20?k#eA*5?E5EWT2STW)7JEk^{}&*GAK7Wt2+V<2_cv5Wsm uensO^9~|cY{4hGsHEQvw#iJI}7ytl}=_J?)Agx#c0000 Date: Fri, 25 Apr 2025 22:14:57 +1000 Subject: [PATCH 2/5] Allow a function as an argument to `size` in `stretch` and `lr` Previously there was always a short fall when scaling delimiters, even if the user requested a specific size. This is no longer the case; the short fall is only present in the default for `lr` (`x => x - 0.1em`), and is the reason for the updated tests - the size of the delimiters is now actually what was specified in the size argument. This also makes the default for `lr` much clearer to the user. A slight hack was used by exploiting the `name` property in the `func` attribute macro so that the default value in the docs for `lr.size` would clearly show what the default function was (instead of just its name `default_lr_size` which is meaningless and inaccessible to the user). --- crates/typst-layout/src/math/attach.rs | 18 +-- crates/typst-layout/src/math/fragment.rs | 2 +- crates/typst-layout/src/math/lr.rs | 32 ++--- crates/typst-layout/src/math/stretch.rs | 56 ++++---- crates/typst-library/src/math/attach.rs | 29 ---- crates/typst-library/src/math/lr.rs | 69 +++++++--- crates/typst-library/src/math/mod.rs | 2 + crates/typst-library/src/math/stretch.rs | 125 ++++++++++++++++++ .../math-attach-scripts-extended-shapes.png | Bin 1057 -> 1035 bytes .../ref/math-lr-mid-size-nested-equation.png | Bin 900 -> 906 bytes tests/ref/math-lr-mid-size.png | Bin 2210 -> 2223 bytes tests/ref/math-lr-size-function.png | Bin 0 -> 603 bytes tests/ref/math-lr-size.png | Bin 663 -> 685 bytes tests/ref/math-stretch-function.png | Bin 0 -> 291 bytes tests/suite/math/delimited.typ | 5 + tests/suite/math/stretch.typ | 6 + 16 files changed, 232 insertions(+), 112 deletions(-) create mode 100644 crates/typst-library/src/math/stretch.rs create mode 100644 tests/ref/math-lr-size-function.png create mode 100644 tests/ref/math-stretch-function.png diff --git a/crates/typst-layout/src/math/attach.rs b/crates/typst-layout/src/math/attach.rs index e1d7d7c9d..bf74cc77a 100644 --- a/crates/typst-layout/src/math/attach.rs +++ b/crates/typst-layout/src/math/attach.rs @@ -1,8 +1,9 @@ use typst_library::diag::SourceResult; use typst_library::foundations::{Packed, StyleChain, SymbolElem}; -use typst_library::layout::{Abs, Axis, Corner, Frame, Point, Rel, Size}; +use typst_library::layout::{Abs, Axis, Corner, Frame, Point, Size}; use typst_library::math::{ AttachElem, EquationElem, LimitsElem, PrimesElem, ScriptsElem, StretchElem, + StretchSize, }; use typst_utils::OptionExt; @@ -63,16 +64,9 @@ pub fn layout_attach( let t = layout!(t, sup_style_chain)?; let b = layout!(b, sub_style_chain)?; if let Some(stretch) = stretch { - let relative_to_width = measure!(t, width).max(measure!(b, width)); - stretch_fragment( - ctx, - styles, - &mut base, - Some(Axis::X), - Some(relative_to_width), - stretch, - Abs::zero(), - ); + let relative_to = measure!(t, width).max(measure!(b, width)); + let width = stretch.resolve(ctx.engine, styles, relative_to)?; + stretch_fragment(ctx, styles, &mut base, Axis::X, width); } let fragments = [ @@ -155,7 +149,7 @@ pub fn layout_limits( } /// Get the size to stretch the base to. -fn stretch_size(styles: StyleChain, elem: &Packed) -> Option> { +fn stretch_size(styles: StyleChain, elem: &Packed) -> Option { // Extract from an EquationElem. let mut base = &elem.base; while let Some(equation) = base.to_packed::() { diff --git a/crates/typst-layout/src/math/fragment.rs b/crates/typst-layout/src/math/fragment.rs index 1b508a349..98b2c88a8 100644 --- a/crates/typst-layout/src/math/fragment.rs +++ b/crates/typst-layout/src/math/fragment.rs @@ -305,7 +305,7 @@ impl GlyphFragment { } /// Apply GSUB substitutions. - fn adjust_glyph_index(ctx: &MathContext, id: GlyphId) -> GlyphId { + pub fn adjust_glyph_index(ctx: &MathContext, id: GlyphId) -> GlyphId { if let Some(glyphwise_tables) = &ctx.glyphwise_tables { glyphwise_tables.iter().fold(id, |id, table| table.apply(id)) } else { diff --git a/crates/typst-layout/src/math/lr.rs b/crates/typst-layout/src/math/lr.rs index bf8235411..e2e0eb8ba 100644 --- a/crates/typst-layout/src/math/lr.rs +++ b/crates/typst-layout/src/math/lr.rs @@ -1,11 +1,11 @@ use typst_library::diag::SourceResult; use typst_library::foundations::{Packed, StyleChain}; -use typst_library::layout::{Abs, Axis, Rel}; +use typst_library::layout::{Abs, Axis}; use typst_library::math::{EquationElem, LrElem, MidElem}; use typst_utils::SliceExt; use unicode_math_class::MathClass; -use super::{stretch_fragment, MathContext, MathFragment, DELIM_SHORT_FALL}; +use super::{stretch_fragment, MathContext, MathFragment}; /// Lays out an [`LrElem`]. #[typst_macros::time(name = "math.lr", span = elem.span())] @@ -22,7 +22,7 @@ pub fn layout_lr( // Extract implicit LrElem. if let Some(lr) = body.to_packed::() { - if lr.size(styles).is_one() { + if lr.size(styles).is_lr_default() { body = &lr.body; } } @@ -41,14 +41,14 @@ pub fn layout_lr( .unwrap_or_default(); let relative_to = 2.0 * max_extent; - let height = elem.size(styles); + let height = elem.size(styles).resolve(ctx.engine, styles, relative_to)?; // Scale up fragments at both ends. match inner_fragments { - [one] => scale(ctx, styles, one, relative_to, height, None), + [one] => scale(ctx, styles, one, height, None), [first, .., last] => { - scale(ctx, styles, first, relative_to, height, Some(MathClass::Opening)); - scale(ctx, styles, last, relative_to, height, Some(MathClass::Closing)); + scale(ctx, styles, first, height, Some(MathClass::Opening)); + scale(ctx, styles, last, height, Some(MathClass::Closing)); } _ => {} } @@ -58,7 +58,7 @@ pub fn layout_lr( if let MathFragment::Variant(ref mut variant) = fragment { if variant.mid_stretched == Some(false) { variant.mid_stretched = Some(true); - scale(ctx, styles, fragment, relative_to, height, Some(MathClass::Large)); + scale(ctx, styles, fragment, height, Some(MathClass::Large)); } } } @@ -119,26 +119,14 @@ fn scale( ctx: &mut MathContext, styles: StyleChain, fragment: &mut MathFragment, - relative_to: Abs, - height: Rel, + height: Abs, apply: Option, ) { if matches!( fragment.class(), MathClass::Opening | MathClass::Closing | MathClass::Fence ) { - // This unwrap doesn't really matter. If it is None, then the fragment - // won't be stretchable anyways. - let short_fall = DELIM_SHORT_FALL.at(fragment.font_size().unwrap_or_default()); - stretch_fragment( - ctx, - styles, - fragment, - Some(Axis::Y), - Some(relative_to), - height, - short_fall, - ); + stretch_fragment(ctx, styles, fragment, Axis::Y, height); if let Some(class) = apply { fragment.set_class(class); diff --git a/crates/typst-layout/src/math/stretch.rs b/crates/typst-layout/src/math/stretch.rs index 33367ac29..fd34be0ad 100644 --- a/crates/typst-layout/src/math/stretch.rs +++ b/crates/typst-layout/src/math/stretch.rs @@ -2,7 +2,7 @@ use ttf_parser::math::{GlyphAssembly, GlyphConstruction, GlyphPart}; use ttf_parser::LazyArray16; use typst_library::diag::{warning, SourceResult}; use typst_library::foundations::{Packed, StyleChain}; -use typst_library::layout::{Abs, Axis, Frame, Point, Rel, Size}; +use typst_library::layout::{Abs, Axis, Frame, Point, Size}; use typst_library::math::StretchElem; use typst_utils::Get; @@ -23,15 +23,13 @@ pub fn layout_stretch( styles: StyleChain, ) -> SourceResult<()> { let mut fragment = ctx.layout_into_fragment(&elem.body, styles)?; - stretch_fragment( - ctx, - styles, - &mut fragment, - None, - None, - elem.size(styles), - Abs::zero(), - ); + + if let Some(axis) = stretch_axis(ctx, &fragment) { + let relative_to = fragment.size().get(axis); + let target = elem.size(styles).resolve(ctx.engine, styles, relative_to)?; + stretch_fragment(ctx, styles, &mut fragment, axis, target); + } + ctx.push(fragment); Ok(()) } @@ -41,10 +39,8 @@ pub fn stretch_fragment( ctx: &mut MathContext, styles: StyleChain, fragment: &mut MathFragment, - axis: Option, - relative_to: Option, - stretch: Rel, - short_fall: Abs, + axis: Axis, + target: Abs, ) { let glyph = match fragment { MathFragment::Glyph(glyph) => glyph.clone(), @@ -56,21 +52,12 @@ pub fn stretch_fragment( // Return if we attempt to stretch along an axis which isn't stretchable, // so that the original fragment isn't modified. - let Some(stretch_axis) = stretch_axis(ctx, &glyph) else { return }; - let axis = axis.unwrap_or(stretch_axis); + let Some(stretch_axis) = stretch_axis(ctx, fragment) else { return }; if axis != stretch_axis { return; } - let relative_to_size = relative_to.unwrap_or_else(|| fragment.size().get(axis)); - - let mut variant = stretch_glyph( - ctx, - glyph, - stretch.relative_to(relative_to_size), - short_fall, - axis, - ); + let mut variant = stretch_glyph(ctx, glyph, target, Abs::zero(), axis); if axis == Axis::Y { variant.align_on_axis(ctx, delimiter_alignment(variant.c)); @@ -81,17 +68,26 @@ pub fn stretch_fragment( /// Return whether the glyph is stretchable and if it is, along which axis it /// can be stretched. -fn stretch_axis(ctx: &mut MathContext, base: &GlyphFragment) -> Option { - let base_id = base.id; +fn stretch_axis(ctx: &mut MathContext, fragment: &MathFragment) -> Option { + let (id, span) = match fragment { + MathFragment::Glyph(glyph) => (glyph.id, glyph.span), + MathFragment::Variant(variant) => { + let id = ctx.ttf.glyph_index(variant.c).unwrap_or_default(); + let id = GlyphFragment::adjust_glyph_index(ctx, id); + (id, variant.span) + } + _ => return None, + }; + let vertical = ctx .table .variants - .and_then(|variants| variants.vertical_constructions.get(base_id)) + .and_then(|variants| variants.vertical_constructions.get(id)) .map(|_| Axis::Y); let horizontal = ctx .table .variants - .and_then(|variants| variants.horizontal_constructions.get(base_id)) + .and_then(|variants| variants.horizontal_constructions.get(id)) .map(|_| Axis::X); match (vertical, horizontal) { @@ -102,7 +98,7 @@ fn stretch_axis(ctx: &mut MathContext, base: &GlyphFragment) -> Option { // vertical and horizontal constructions. So for the time being, we // will assume that a glyph cannot have both. ctx.engine.sink.warn(warning!( - base.span, + span, "glyph has both vertical and horizontal constructions"; hint: "this is probably a font bug"; hint: "please file an issue at https://github.com/typst/typst/issues" diff --git a/crates/typst-library/src/math/attach.rs b/crates/typst-library/src/math/attach.rs index d526aba57..c367b6f4f 100644 --- a/crates/typst-library/src/math/attach.rs +++ b/crates/typst-library/src/math/attach.rs @@ -1,5 +1,4 @@ use crate::foundations::{elem, Content, Packed}; -use crate::layout::{Length, Rel}; use crate::math::{EquationElem, Mathy}; /// A base with optional attachments. @@ -128,31 +127,3 @@ pub struct LimitsElem { #[default(true)] pub inline: bool, } - -/// Stretches a glyph. -/// -/// This function can also be used to automatically stretch the base of an -/// attachment, so that it fits the top and bottom attachments. -/// -/// Note that only some glyphs can be stretched, and which ones can depend on -/// the math font being used. However, most math fonts are the same in this -/// regard. -/// -/// ```example -/// $ H stretch(=)^"define" U + p V $ -/// $ f : X stretch(->>, size: #150%)_"surjective" Y $ -/// $ x stretch(harpoons.ltrb, size: #3em) y -/// stretch(\[, size: #150%) z $ -/// ``` -#[elem(Mathy)] -pub struct StretchElem { - /// The glyph to stretch. - #[required] - pub body: Content, - - /// The size to stretch to, relative to the maximum size of the glyph and - /// its attachments. - #[resolve] - #[default(Rel::one())] - pub size: Rel, -} diff --git a/crates/typst-library/src/math/lr.rs b/crates/typst-library/src/math/lr.rs index 7558717af..6da348832 100644 --- a/crates/typst-library/src/math/lr.rs +++ b/crates/typst-library/src/math/lr.rs @@ -1,6 +1,16 @@ -use crate::foundations::{elem, func, Content, NativeElement, SymbolElem}; -use crate::layout::{Length, Rel}; -use crate::math::Mathy; +use crate::foundations::{elem, func, Content, NativeElement, NativeFunc, SymbolElem}; +use crate::layout::{Em, Length, Ratio, Rel}; +use crate::math::{Mathy, StretchSize}; + +const DELIM_SHORT_FALL: Em = Em::new(-0.1); + +#[func(name = "x => x - 0.1em")] +pub const fn default_lr_size(base: Length) -> Rel { + Rel { + rel: Ratio::zero(), + abs: Length { abs: base.abs, em: DELIM_SHORT_FALL }, + } +} /// Scales delimiters. /// @@ -8,10 +18,13 @@ use crate::math::Mathy; /// unmatched delimiters and to control the delimiter scaling more precisely. #[elem(title = "Left/Right", Mathy)] pub struct LrElem { - /// The size of the brackets, relative to the height of the wrapped content. - #[resolve] - #[default(Rel::one())] - pub size: Rel, + /// The size of the delimiters, relative to the height of the wrapped + /// content. + /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. + #[default(::data().into())] + pub size: StretchSize, /// The delimited content, including the delimiters. #[required] @@ -43,9 +56,13 @@ pub struct MidElem { /// ``` #[func] pub fn floor( - /// The size of the brackets, relative to the height of the wrapped content. + /// The size of the delimiters, relative to the height of the wrapped + /// content. + /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. #[named] - size: Option>, + size: Option, /// The expression to floor. body: Content, ) -> Content { @@ -59,9 +76,13 @@ pub fn floor( /// ``` #[func] pub fn ceil( - /// The size of the brackets, relative to the height of the wrapped content. + /// The size of the delimiters, relative to the height of the wrapped + /// content. + /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. #[named] - size: Option>, + size: Option, /// The expression to ceil. body: Content, ) -> Content { @@ -75,9 +96,13 @@ pub fn ceil( /// ``` #[func] pub fn round( - /// The size of the brackets, relative to the height of the wrapped content. + /// The size of the delimiters, relative to the height of the wrapped + /// content. + /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. #[named] - size: Option>, + size: Option, /// The expression to round. body: Content, ) -> Content { @@ -91,9 +116,13 @@ pub fn round( /// ``` #[func] pub fn abs( - /// The size of the brackets, relative to the height of the wrapped content. + /// The size of the delimiters, relative to the height of the wrapped + /// content. + /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. #[named] - size: Option>, + size: Option, /// The expression to take the absolute value of. body: Content, ) -> Content { @@ -107,9 +136,13 @@ pub fn abs( /// ``` #[func] pub fn norm( - /// The size of the brackets, relative to the height of the wrapped content. + /// The size of the delimiters, relative to the height of the wrapped + /// content. + /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. #[named] - size: Option>, + size: Option, /// The expression to take the norm of. body: Content, ) -> Content { @@ -120,7 +153,7 @@ fn delimited( body: Content, left: char, right: char, - size: Option>, + size: Option, ) -> Content { let span = body.span(); let mut elem = LrElem::new(Content::sequence([ diff --git a/crates/typst-library/src/math/mod.rs b/crates/typst-library/src/math/mod.rs index 2e6d42b13..4f4bbb03b 100644 --- a/crates/typst-library/src/math/mod.rs +++ b/crates/typst-library/src/math/mod.rs @@ -9,6 +9,7 @@ mod lr; mod matrix; mod op; mod root; +mod stretch; mod style; mod underover; @@ -21,6 +22,7 @@ pub use self::lr::*; pub use self::matrix::*; pub use self::op::*; pub use self::root::*; +pub use self::stretch::*; pub use self::style::*; pub use self::underover::*; diff --git a/crates/typst-library/src/math/stretch.rs b/crates/typst-library/src/math/stretch.rs new file mode 100644 index 000000000..899234fa9 --- /dev/null +++ b/crates/typst-library/src/math/stretch.rs @@ -0,0 +1,125 @@ +use comemo::Track; + +use crate::diag::{At, SourceResult}; +use crate::engine::Engine; +use crate::foundations::{ + cast, elem, Content, Context, Func, NativeFunc, NativeFuncData, Resolve, StyleChain, +}; +use crate::layout::{Abs, Rel}; +use crate::math::{default_lr_size, Mathy}; + +/// Stretches a glyph. +/// +/// This function can also be used to automatically stretch the base of an +/// attachment, so that it fits the top and bottom attachments. +/// +/// Note that only some glyphs can be stretched, and which ones can depend on +/// the math font being used. However, most math fonts are the same in this +/// regard. +/// +/// ```example +/// $ H stretch(=)^"define" U + p V $ +/// $ f : X stretch(->>, size: #150%)_"surjective" Y $ +/// $ x stretch(harpoons.ltrb, size: #3em) y +/// stretch(\[, size: #150%) z $ +/// ``` +#[elem(Mathy)] +pub struct StretchElem { + /// The glyph to stretch. + #[required] + pub body: Content, + + /// The size to stretch to, relative to the maximum size of the glyph and + /// its attachments. + /// + /// This value can be given as a [relative length]($relative), or a + /// [function]($function) that receives the size of the glyph as a + /// parameter (an absolute length) and should return a (relative) length. + /// For example, `{x => x * 80%}` would be equivalent to just specifying `{80%}`. + /// + /// Note that the sizes of glyphs in math fonts come about in two ways: + /// + /// - First, there are pre-made variants at specific sizes. This means you + /// will see discrete jumps in the stretched glyph's size as you increase + /// the size parameter. It is up to the font how many pre-made variants + /// there are and what their sizes are. + /// + /// - Then, if the pre-made variants are all too small, a glyph of the + /// desired size is assembled from parts. The stretched glyph's size will + /// now be the exact size requested. + /// + /// It could be the case that only one of the above exist for a glyph in + /// the font. + /// + /// The value given here is really a minimum (but if there is no assembly + /// for the glyph, this minimum may not be reached), so the actual size of + /// the stretched glyph may not match what you specified. + /// + /// ```example + /// #for i in range(0, 15) { + /// $stretch(\[, size: #(10pt + i * 2pt))$ + /// } + /// + /// #set math.stretch(size: x => x + 0.5em) + /// $x stretch(=)^"def" y$ + /// ``` + #[default(Rel::one().into())] + pub size: StretchSize, +} + +/// How to size a stretched glyph. +#[derive(Debug, Clone, PartialEq, Hash)] +pub enum StretchSize { + /// Sized by the specified length. + Rel(Rel), + /// Resolve the size for the given base size through the specified + /// function. + Func(Func), +} + +impl StretchSize { + /// Resolve the stretch size given the base size. + pub fn resolve( + &self, + engine: &mut Engine, + styles: StyleChain, + base: Abs, + ) -> SourceResult { + Ok(match self { + Self::Rel(rel) => *rel, + Self::Func(func) => func + .call(engine, Context::new(None, Some(styles)).track(), [base])? + .cast() + .at(func.span())?, + } + .resolve(styles) + .relative_to(base)) + } + + /// Whether the size is the default used by `LrElem`. + pub fn is_lr_default(self) -> bool { + self == ::data().into() + } +} + +impl From for StretchSize { + fn from(rel: Rel) -> Self { + Self::Rel(rel) + } +} + +impl From<&'static NativeFuncData> for StretchSize { + fn from(data: &'static NativeFuncData) -> Self { + Self::Func(Func::from(data)) + } +} + +cast! { + StretchSize, + self => match self { + Self::Rel(v) => v.into_value(), + Self::Func(v) => v.into_value(), + }, + v: Rel => Self::Rel(v), + v: Func => Self::Func(v), +} diff --git a/tests/ref/math-attach-scripts-extended-shapes.png b/tests/ref/math-attach-scripts-extended-shapes.png index c99d3c7fdbf1ece5e07dc52ebaf6ae8359dcfd37..16bad11579963f26d2b27205a01275d7dc79dae0 100644 GIT binary patch delta 1026 zcmV+d1pWJ=2#W}i7k?}W00000ix4C4000BhNkll5~K;Du|O)X-R}3?c}hIK{Oes?%iaRlN*N? z)>77S=z)F>?=$Etg`{sy%7uI`nkR35$v3~`eVVj~*e8b$!hiqcu%mvT!V9P47jD-F z0C-e22_(laoH~ZgYcj+)oB_gs0j7`tfo#=|%>5K+VJEWLMMh71QRqDbO7qw5#~Ajy zo+Ill2>>8{1;4ffh?VEW8n6?p?);mQ`b&Z!0{}ZbI-M!%MH_ zK0@QnQez@sV_iT+c&aq}R?lQOoaWyQPnKuacTb}wXMc6z7Bxe1I1SwdIZJTKteG{x zyhbYST%hYZbQ}p}`TGni!ojxbwjsh{y<;;RZ2h}+7_^+ieid6A;#_N?eHiWy_H{D+ z9SH=#ffuIR1dS%?6jA}PU#FgbU#IhasRH|qd`_nFAyyEc<#A4oBb*IB_$juq(>wwm zpg$u3fPXa|TVt6E4^XGW*i{yi&qDbfBP_FRpt;l&TlfmuYw`N7{_K0P+fb^3P!few zyu$7UWIo6GW;kz#|LA2D;Rty%g{bsbB}&2OG&SMrMFjgg5hCZ5){;SK`Lc@e9VxdJ z!Rusqjuo&-Ic)$87QEsBMYz89rn>NiulYv=J%2=6DD#0H#(jor035H|0Z)HYkutpT z2~X99d7d9c)-r*DG>Xjpwi}+bD&{)g@&i!C(7V5bU{3;?D#xM;uUghSp0N03rwLgK zxO=>}pCPmMAslxDDT+BRUL=A!J^Jg^ke9W5lELcg31o@z%b6Q%CwB`cZq7|2_z(Za zPJdO!(T80L^BeCIrUBQnz|sj|uAm@UBfma~um+{E!|ZgWHu^9}>CPQR5F4+2NKMV? zt{W>g+-0XPEYXLj&eQa@6@Y>Yv6b~(ighC>!#}@KIJ>=Zeigt2`I8X1fH&6xPDs&* z3Bn4p(4T-|nowx_k?k>I<0i$NGaFeh`g?&Q7zh9y^&y$3q6#ZLasuet%T2{x;Pc73 zx!K{CcZ#{dWjEcx93Qh%#3j{X!Q*6i^DhW{oc+q2`z)C=0G#`whd~_)@%nvyfpmlo wu$7>RS6J#EAuMaWJTBo#_JjXG4#NB5AFBkl%0aBLIRF3v07*qoM6N<$g5$X7;Q#;t delta 1049 zcmV+!1m^pT2%!j&7k?@U00000T}i<5000B%Nkl2JqPVzZ7IXTTa#6ETC0DnG!_Z(i+*6t6?NYUQG znYR#Cr#=Us(IIE*MUm&8jgY3BRlw)v2PJ%^3xFq?|1fcOla2Aa&07`M&%+wbq%ns4QSWnZM?{2w)zzqqd>rgtU5A1#E6fHxg`} zXSXKJ8v?-A8EhlueD1!}t`6>4Z@Pw5l^b?v41cg*{dAtLK>B^Ssi&u_@%tmCA+W~P zp$=y2n-0tg*6i$r#O!RF3@4(jZ6Z@F-EY^pvoCm#Wx z3Z7T_refZOIRJawIldy*&3yo(@#T86RKwCIjN5s3^An1Bf4`^EXyV^FdURyv3(h?j z?~>YXV*Y_o_vq5*KTV1cfCV%3{Yd;C!PK=kAm>Zr!v0)S9WCyIi}?Y(AN>!ldlJf6 T;%)5K00000NkvXXu0mjf`#=RV diff --git a/tests/ref/math-lr-mid-size-nested-equation.png b/tests/ref/math-lr-mid-size-nested-equation.png index df0106689f081bd938addaf1acf938687152625f..5fd22ae34a132c23614bfe8dc5cfc0e2adb8df9c 100644 GIT binary patch delta 883 zcmV-(1C0EH2Z{%fB!5v!L_t(|+U?g}NK;_|#_?_{y67SZiLL|<5(2FtEXyph$j?f{ zh$zDn6_ZRwtjx*~BelT7a%uTRkYy@tW|$UY7KoOi)BH$nO~pt}O}FWJg7>VQckZ2g zCqZ4D|HYo&jPv7s!It5FY?-W*RkBJ}$*RAo>TicsDd@DV|9?uAmNWyY+b~uA3PNVA z9(=u4g1^znn#EO$7=Wp2yB=ZyauUFmCN5$G+=W%C70J3TwPPbR`dAN zw_saWaL*enDi;9&hS!5D_c7S2cpAnOnM+mmc*73W{14Rz8V2$C95E2kW|vW+7rT| zN~|?gIe%oUVw%b5+yOuVW1i&r%CrTlYLK+PW~$=DWO{?Gt9CYnq;@Z)Roaz$vJ>lI zp8q_VLI)kC(yh{xABD43Sx#oEGgob?rnW;Y_vQ^+^?%$AVh4Lzs)6dQ1C;8$16Znr zS~87oYt2-ym1G73t*PdsRUjz`OU}`%)G&yBI64Koz2q|&{_iMNo)4L6KhRC>(vf2* z;5<&LbSwHn^3hmP`6)q~KARsON~?ly!B~fz0j7kLB>+%=CEv4xQbi|%lob!D@y%+o zMcMfq)PIz!Wevne-MZN-T|_O}2YPgP(kjP#h_#1~S)40fK9G`2sdki-`E>wv-@Oa~ zhRcB?^^~f>3u3-~V5>0U0l<*FAIM(!R#N>~J_)gqPK*1hbDsi3K>;Hsm9V;-d0(Bc z0~)t9K8X0YbtoOLQDW8RlO_3et)u`L6S+;`}Ss!LIJUr7Ggn1J*pvJ@KiWWCO`u^w#xS< zLu{39RylYxBdyuqQm8)u=4`w}L=*u7ZTD7__o7QA&`EUD&E;lgG80#)l% zjmaD_0~@K!KZ84=Oa(3#y4oOB2s%xZ{NGtt$tqbTt7O%Z`wiS1Nm==3uyOzZ002ov JPDHLkV1i{fqX_^2 delta 877 zcmV-z1CsoT2ZRTZB!5duL_t(|+U?g{NK}EGA((Gy! z5oK6XVUnqcm01~Lq$XHcE-g(7vP^}|4AVl)1k*BfnwQkpRE*Trbeo=E@c$on{?q^5 z|42{|=lk;8%Q&B%8*B#t$7X0MO{J+cm8SZOs`h#)<$%px`+u)gv5_NCN`}3n*N_rI ztPtys9^&;rF-@(~1p{1F-3@;mkP;4|Orb$N5H6q~Wonggu@lwlT5@?kAk=j|#QT20 z)fL?Q)`@DV1OVL&A(U4i#M32ASJko=DpZ5Zz^gJ1N*~4`ceETpu3;Lghv8~e#Ye#D zWgwU`1|heIe1D3&BcK|W98@Q=_$r&;OqZNc$X$*H&{izLp(q1rHbte}t1bQls)!N? zmB%N(D!7`A#R~v*kn<+T*T+s!711^OIH(@)C)0YsxoUkiU87eft1{2Fk{wt8$99dA z$#keGy6QNiU|PiH4qyy2ZjB0HTncq9X_G6O`KzAN+ zu#8b_)&a0Z?EsP%yi-&^XAXkq-#F>MYTT|v*B-wfyGokd%)PHJlmZni z%VG2i8dX#wk#xWL!I=u{YC)3#MOC&Ov|pTOP=85QHMs%&XOQ<6-Ix#g8C3gjPd)?i z-&dzUPgXtMO}8XQL^ZExx~jk|XR6UWGwe0eiH;}JRyZc0>U0OKMYU>mD__NLUpcrH zp5dtU$3RO;QmL{nfg06PEBKY(hfF3Z$GJj+%HsP2YNQiXmEkRW$21TKoJ2^@uJO_#EZL{zwV#X3P%`^;oF2aUi* z#=I{OPRcbvNQI_4C}o1pRH^-U)>N8GQ)wzqHSPWY6A4O~_iB**00000NkvXXu0mjf DRdS$< diff --git a/tests/ref/math-lr-mid-size.png b/tests/ref/math-lr-mid-size.png index 12b4c0868d133a99f8973511888564a83dafb329..c0e191a153b6e88f189abfae1694d2f17af2a421 100644 GIT binary patch delta 2211 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 delta 2198 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 literal 0 HcmV?d00001 diff --git a/tests/ref/math-lr-size.png b/tests/ref/math-lr-size.png index 09d2442152852b6e5e4e503605d178d0316980f5..f3259ac3c5d0e6dbb6fa15263d3bbadb03f45d34 100644 GIT binary patch delta 661 zcmV;G0&4x21+4{;B!6^CL_t(|+U?i>OA~P%$8i(t=YFXEf__>*6a+!gFP2dK5ClQ8 z3JV#;W{uIP7VL+iBhpPY);CN0MX=^bB`xRNWKpH8+fH?MvHU?T+qt z++Fv>XJkKk&)?pk`{BX8xz7(*ga1^G49l<#%kaO07q9kO7k}0d&JEb3pvzuPSVG|R z-EPl8qzG?bA%Y7NMh`%z!G$q!T63LRg)r|h@4)9ETeX9MvqiQ7qG;gsx z2*CK97{+Mr4Y0-g9t_;%zp!d^Y+Y=2f&aJN2Mc4QusXcMTc~IAq6)tL0JAc2x0TK z{Z#vQZhx)a)Gi56-iEO8Zc_Nm$4VJV7)=nS&Jn`gGLVMdBjER;2i3!$RY7SOT_N5< zyafbsN_BP)_%=E9v=}Xyhn0mtH8mz7l8ZNc3j{D@yzdOBr^+QLm>^PkzGEivW3b!` vEb9t;{NoAGE#L3Y$^T9=EWL_t(|+GF@XK!9P?;!%r7EgrR)b{5|)pWAb1AT0h-`mXyn zF-AQ@<3Fb~sI&g(Y$w9rspzhobB!#EyTkUwy!`(Qip;(AC@kt%9>EZ*`9hYDcW=fi zm5V9#I|ozjK?m6uhihdO0YP50ySCP9ycW;diN%PNkK|f>gnu;;=K2;#ycP#wGh+1; zvV*#rX$y>h_#_^S-vwba;zb167XNb+gXfZecr4!33MBq6a`^$_?wXdk6-1knpSYfh zy8OeJxVBD*$J4>RaAm2u;6D zy2T*Res@7>cBH_=^4E=f*qUZFKhQ*uFDJjv^4K#TE$Pbbmiih{=8 z&5QjHz8(XDcR-8j*}T2ld*;%|bwKd^e>Yt%-g{!_I|%F1tYtq(`%a@4k6Jux@d&pV Y0L@qOW1fjjkpKVy07*qoM6N<$f@48II{*Lx diff --git a/tests/ref/math-stretch-function.png b/tests/ref/math-stretch-function.png new file mode 100644 index 0000000000000000000000000000000000000000..8e1daa46ce75ce760822f770c986b6667088e28b GIT binary patch literal 291 zcmV+;0o?wHP)MSv+CXV)|NqVxTOZO*4z%4wS_e17q>O_M-!1@j=D5wzkZ+ob0y1 zwu1Dwj8-7`7+r$;%+!I3V?q`Wv+Q)?$-r2Af5j~X=kMA7+y7!%{F){fFYGydWY>l5 zn>YS`wdcyzt`8Ic-8}N(?DB1|Xb9WBy zEq>d7c=_42+YaabeQ|up)s~-i|I2?gKAZuPTuMWWcdq)sdGowIYc}qDaq#ZHweM!$ py1ehs002ovPDHLkV1kUKl9vDg literal 0 HcmV?d00001 diff --git a/tests/suite/math/delimited.typ b/tests/suite/math/delimited.typ index 794ffd8aa..06e3e0d20 100644 --- a/tests/suite/math/delimited.typ +++ b/tests/suite/math/delimited.typ @@ -34,6 +34,11 @@ $ lr(a/b\]) = a = lr(\{a/b) $ $ lr(]sum_(x=1)^n x], size: #70%) < lr((1, 2), size: #200%) $ +--- math-lr-size-function --- +// Test using a function as an argument to size. +#set math.lr(size: x => if x > 10pt { 1em } else { 4 * x }) +$ (a) (1/2) $ + --- math-lr-shorthands --- // Test predefined delimiter pairings. $floor(x/2), ceil(x/2), abs(x), norm(x)$ diff --git a/tests/suite/math/stretch.typ b/tests/suite/math/stretch.typ index d145f72a1..f5ee05af6 100644 --- a/tests/suite/math/stretch.typ +++ b/tests/suite/math/stretch.typ @@ -91,3 +91,9 @@ $ body^"text" $ } $body^"long text"$ } + +--- math-stretch-function --- +// Test using a function as an argument to size. +$stretch(<-, size: #(x => x - 0.5em))_"function"$ +#set math.stretch(size: x => x + 0.5em) +$stretch(|) |$ From 92d06fbd9a49ece409c96d39eaaa13263adda311 Mon Sep 17 00:00:00 2001 From: mkorje Date: Fri, 25 Apr 2025 22:36:21 +1000 Subject: [PATCH 3/5] Allow a function as an argument to size in `accent` The short fall is now only applied in the default for `accent` (`x => x - 0.5em`). This is the reason for the updated tests. --- crates/typst-layout/src/math/accent.rs | 10 +++----- crates/typst-library/src/math/accent.rs | 31 ++++++++++++++++++----- tests/ref/math-accent-sized-function.png | Bin 0 -> 417 bytes tests/ref/math-accent-sized-script.png | Bin 331 -> 355 bytes tests/suite/math/accent.typ | 8 +++++- 5 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 tests/ref/math-accent-sized-function.png diff --git a/crates/typst-layout/src/math/accent.rs b/crates/typst-layout/src/math/accent.rs index 73d821019..70c34e611 100644 --- a/crates/typst-layout/src/math/accent.rs +++ b/crates/typst-layout/src/math/accent.rs @@ -1,13 +1,10 @@ use typst_library::diag::SourceResult; use typst_library::foundations::{Packed, StyleChain}; -use typst_library::layout::{Em, Frame, Point, Size}; +use typst_library::layout::{Abs, Frame, Point, Size}; use typst_library::math::{Accent, AccentElem}; use super::{style_cramped, FrameFragment, GlyphFragment, MathContext, MathFragment}; -/// How much the accent can be shorter than the base. -const ACCENT_SHORT_FALL: Em = Em::new(0.5); - /// Lays out an [`AccentElem`]. #[typst_macros::time(name = "math.accent", span = elem.span())] pub fn layout_accent( @@ -29,7 +26,7 @@ pub fn layout_accent( let base_class = base.class(); let base_attach = base.accent_attach(); - let width = elem.size(styles).relative_to(base.width()); + let width = elem.size(styles).resolve(ctx.engine, styles, base.width())?; let Accent(c) = elem.accent; let mut glyph = GlyphFragment::new(ctx, styles, c, elem.span()); @@ -42,8 +39,7 @@ pub fn layout_accent( // Forcing the accent to be at least as large as the base makes it too // wide in many case. - let short_fall = ACCENT_SHORT_FALL.at(glyph.font_size); - let variant = glyph.stretch_horizontal(ctx, width, short_fall); + let variant = glyph.stretch_horizontal(ctx, width, Abs::zero()); let accent = variant.frame; let accent_attach = variant.accent_attach; diff --git a/crates/typst-library/src/math/accent.rs b/crates/typst-library/src/math/accent.rs index e62b63872..a6b7e29a5 100644 --- a/crates/typst-library/src/math/accent.rs +++ b/crates/typst-library/src/math/accent.rs @@ -1,7 +1,19 @@ use crate::diag::bail; -use crate::foundations::{cast, elem, func, Content, NativeElement, SymbolElem}; -use crate::layout::{Length, Rel}; -use crate::math::Mathy; +use crate::foundations::{ + cast, elem, func, Content, NativeElement, NativeFunc, SymbolElem, +}; +use crate::layout::{Em, Length, Ratio, Rel}; +use crate::math::{Mathy, StretchSize}; + +const ACCENT_SHORT_FALL: Em = Em::new(-0.5); + +#[func(name = "x => x - 0.5em")] +const fn default_accent_size(base: Length) -> Rel { + Rel { + rel: Ratio::zero(), + abs: Length { abs: base.abs, em: ACCENT_SHORT_FALL }, + } +} /// Attaches an accent to a base. /// @@ -52,12 +64,14 @@ pub struct AccentElem { /// The size of the accent, relative to the width of the base. /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. + /// /// ```example /// $dash(A, size: #150%)$ /// ``` - #[resolve] - #[default(Rel::one())] - pub size: Rel, + #[default(::data().into())] + pub size: StretchSize, /// Whether to remove the dot on top of lowercase i and j when adding a top /// accent. @@ -116,8 +130,11 @@ macro_rules! accents { /// The base to which the accent is applied. base: Content, /// The size of the accent, relative to the width of the base. + /// + /// See the [stretch documentation]($math.stretch.size) for + /// more information on sizes. #[named] - size: Option>, + size: Option, /// Whether to remove the dot on top of lowercase i and j when /// adding a top accent. #[named] diff --git a/tests/ref/math-accent-sized-function.png b/tests/ref/math-accent-sized-function.png new file mode 100644 index 0000000000000000000000000000000000000000..9bd52a6e72aa76c5c5d481bc93fecec24637de1b GIT binary patch literal 417 zcmV;S0bc%zP)adD!gD3XJNhl2?xdCJ3T2enOEEf1Grd7SoJN!nA| z+FCTNv9X7upX|+F@ul_q`~$DP-^1rq#vi3jgEhFs;h4!}iUD~Ka4&sv(PrH-z^d^= z5`F~Wqrhi|gdptK10nrjoNRx~ks!QO1<;%VMt6~e4-=KZYZHL(Sq{!yXm|m~Fpz0L z4&K@_H~L`24(t!Y-Mb9zJA>Y1(4~Me8|pM7u)Ez&sC&Gyu6Kg7WpS;0PwVQEgX4rNGzi;5P{eC|FDW8NT z+)miS>sr~&T4u5=7Ot#}4EhfZ-q%&!ZqDqtWN@R1P`D7daDT{!hKFXaz{{9V5RM}j zwrEkG&Au%dhVQYi6notneyjF_ig1`21)h#+bQ-`ppixZ_+>?W_2>=ffEp}O&{*2ZE zK;7NmN$6r=vjbSeEmG;cjZ;kHRSo9vqlkf115jJV%{iasPvc}i1i|T12<5>k!PoPg zs=wk^HsEE6BS8eg&V;g@0Umonn_5`h!Yk$nOF6j{1%m?s8ck{K+3I?;qZi~YN?5`Y aZqW}GA9G2VYDcL60000h5s+Up^?QWvi|>{{sd^} ztN;H$J!skT=qXg<^Vk3XA5Q+imsW}EU+J`&pd@|Q>;L~V)qVYoVG^rq|Ns9z?Z8bM zS&T@wXV4X$p(#%R@(10XN6$yA#Zik#EgrQP3jhGnEO*GWH diff --git a/tests/suite/math/accent.typ b/tests/suite/math/accent.typ index ecc0588c5..23e11a697 100644 --- a/tests/suite/math/accent.typ +++ b/tests/suite/math/accent.typ @@ -30,12 +30,18 @@ $ tilde(integral), tilde(integral)_a^b, tilde(integral_a^b) $ --- math-accent-sized --- // Test accent size. -$tilde(sum), tilde(sum, size: #50%), accent(H, hat, size: #200%)$ +$tilde(sum), tilde(sum, size: #25%), accent(H, hat, size: #125%)$ --- math-accent-sized-script --- // Test accent size in script size. $tilde(U, size: #1.1em), x^tilde(U, size: #1.1em), sscript(tilde(U, size: #1.1em))$ +--- math-accent-sized-function --- +// Test accent size with a function. +$dash(A) arrow(I) hat(L)$ \ +#set math.accent(size: x => x - 0.1em) +$dash(A) arrow(I) hat(L)$ + --- math-accent-dotless --- // Test dotless glyph variants. #let test(c) = $grave(#c), acute(sans(#c)), hat(frak(#c)), tilde(mono(#c)), From b30a38046c8bbd3a7f2d6f1a8b47356382078a60 Mon Sep 17 00:00:00 2001 From: mkorje Date: Sun, 27 Apr 2025 21:04:39 +1000 Subject: [PATCH 4/5] Add `delim-size` parameter to `mat`, `vec`, and `cases` Takes either a function or a relative length, just like with `lr`, `stretch`, and `accent` which was changed in the previous two commits. The short fall was changed in the first commit, so no test updates here. The default is now much clearer to the user: `x => x * 1.1 - 0.1em`. --- crates/typst-layout/src/math/frac.rs | 7 ++-- crates/typst-layout/src/math/mat.rs | 50 ++++++++++++++++++------ crates/typst-layout/src/math/shared.rs | 5 +-- crates/typst-library/src/math/lr.rs | 2 +- crates/typst-library/src/math/matrix.rs | 41 +++++++++++++++++-- tests/ref/math-cases-delim-size.png | Bin 0 -> 1005 bytes tests/ref/math-mat-delim-size.png | Bin 0 -> 1327 bytes tests/ref/math-vec-delim-size.png | Bin 0 -> 1340 bytes tests/suite/math/cases.typ | 6 +++ tests/suite/math/mat.typ | 8 +++- tests/suite/math/vec.typ | 6 +++ 11 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 tests/ref/math-cases-delim-size.png create mode 100644 tests/ref/math-mat-delim-size.png create mode 100644 tests/ref/math-vec-delim-size.png diff --git a/crates/typst-layout/src/math/frac.rs b/crates/typst-layout/src/math/frac.rs index 6d3caac45..c1bfab034 100644 --- a/crates/typst-layout/src/math/frac.rs +++ b/crates/typst-layout/src/math/frac.rs @@ -1,14 +1,13 @@ use typst_library::diag::SourceResult; use typst_library::foundations::{Content, Packed, Resolve, StyleChain, SymbolElem}; use typst_library::layout::{Em, Frame, FrameItem, Point, Size}; -use typst_library::math::{BinomElem, FracElem}; +use typst_library::math::{BinomElem, FracElem, DELIM_SHORT_FALL}; use typst_library::text::TextElem; use typst_library::visualize::{FixedStroke, Geometry}; use typst_syntax::Span; use super::{ - style_for_denominator, style_for_numerator, FrameFragment, GlyphFragment, - MathContext, DELIM_SHORT_FALL, + style_for_denominator, style_for_numerator, FrameFragment, GlyphFragment, MathContext, }; const FRAC_AROUND: Em = Em::new(0.1); @@ -49,7 +48,7 @@ fn layout_frac_like( binom: bool, span: Span, ) -> SourceResult<()> { - let short_fall = DELIM_SHORT_FALL.resolve(styles); + let short_fall = DELIM_SHORT_FALL.abs().resolve(styles); let axis = scaled!(ctx, styles, axis_height); let thickness = scaled!(ctx, styles, fraction_rule_thickness); let shift_up = scaled!( diff --git a/crates/typst-layout/src/math/mat.rs b/crates/typst-layout/src/math/mat.rs index d678f8658..ef4466d2c 100644 --- a/crates/typst-layout/src/math/mat.rs +++ b/crates/typst-layout/src/math/mat.rs @@ -1,19 +1,20 @@ use typst_library::diag::{bail, warning, SourceResult}; use typst_library::foundations::{Content, Packed, Resolve, StyleChain}; use typst_library::layout::{ - Abs, Axes, Em, FixedAlignment, Frame, FrameItem, Point, Ratio, Rel, Size, + Abs, Axes, Em, FixedAlignment, Frame, FrameItem, Point, Rel, Size, +}; +use typst_library::math::{ + Augment, AugmentOffsets, CasesElem, MatElem, StretchSize, VecElem, }; -use typst_library::math::{Augment, AugmentOffsets, CasesElem, MatElem, VecElem}; use typst_library::text::TextElem; use typst_library::visualize::{FillRule, FixedStroke, Geometry, LineCap, Shape}; use typst_syntax::Span; use super::{ alignments, delimiter_alignment, style_for_denominator, AlignmentResult, - FrameFragment, GlyphFragment, LeftRightAlternator, MathContext, DELIM_SHORT_FALL, + FrameFragment, GlyphFragment, LeftRightAlternator, MathContext, }; -const VERTICAL_PADDING: Ratio = Ratio::new(0.1); const DEFAULT_STROKE_THICKNESS: Em = Em::new(0.05); /// Lays out a [`VecElem`]. @@ -39,7 +40,15 @@ pub fn layout_vec( )?; let delim = elem.delim(styles); - layout_delimiters(ctx, styles, frame, delim.open(), delim.close(), span) + layout_delimiters( + ctx, + styles, + frame, + elem.delim_size(styles), + delim.open(), + delim.close(), + span, + ) } /// Lays out a [`CasesElem`]. @@ -67,7 +76,7 @@ pub fn layout_cases( let delim = elem.delim(styles); let (open, close) = if elem.reverse(styles) { (None, delim.close()) } else { (delim.open(), None) }; - layout_delimiters(ctx, styles, frame, open, close, span) + layout_delimiters(ctx, styles, frame, elem.delim_size(styles), open, close, span) } /// Lays out a [`MatElem`]. @@ -125,7 +134,15 @@ pub fn layout_mat( )?; let delim = elem.delim(styles); - layout_delimiters(ctx, styles, frame, delim.open(), delim.close(), span) + layout_delimiters( + ctx, + styles, + frame, + elem.delim_size(styles), + delim.open(), + delim.close(), + span, + ) } /// Layout the inner contents of a matrix, vector, or cases. @@ -302,19 +319,23 @@ fn layout_delimiters( ctx: &mut MathContext, styles: StyleChain, mut frame: Frame, + size: StretchSize, left: Option, right: Option, span: Span, ) -> SourceResult<()> { - let short_fall = DELIM_SHORT_FALL.resolve(styles); let axis = scaled!(ctx, styles, axis_height); let height = frame.height(); - let target = height + VERTICAL_PADDING.of(height); frame.set_baseline(height / 2.0 + axis); + let target = size.resolve(ctx.engine, styles, height)?; + if let Some(left) = left { - let mut left = GlyphFragment::new(ctx, styles, left, span) - .stretch_vertical(ctx, target, short_fall); + let mut left = GlyphFragment::new(ctx, styles, left, span).stretch_vertical( + ctx, + target, + Abs::zero(), + ); left.align_on_axis(ctx, delimiter_alignment(left.c)); ctx.push(left); } @@ -322,8 +343,11 @@ fn layout_delimiters( ctx.push(FrameFragment::new(styles, frame)); if let Some(right) = right { - let mut right = GlyphFragment::new(ctx, styles, right, span) - .stretch_vertical(ctx, target, short_fall); + let mut right = GlyphFragment::new(ctx, styles, right, span).stretch_vertical( + ctx, + target, + Abs::zero(), + ); right.align_on_axis(ctx, delimiter_alignment(right.c)); ctx.push(right); } diff --git a/crates/typst-layout/src/math/shared.rs b/crates/typst-layout/src/math/shared.rs index 600c130d4..77d1ab4a8 100644 --- a/crates/typst-layout/src/math/shared.rs +++ b/crates/typst-layout/src/math/shared.rs @@ -1,6 +1,6 @@ use ttf_parser::math::MathValue; use typst_library::foundations::{Style, StyleChain}; -use typst_library::layout::{Abs, Em, FixedAlignment, Frame, Point, Size, VAlignment}; +use typst_library::layout::{Abs, FixedAlignment, Frame, Point, Size, VAlignment}; use typst_library::math::{EquationElem, MathSize}; use typst_utils::LazyHash; @@ -28,9 +28,6 @@ macro_rules! percent { }; } -/// How much less high scaled delimiters can be than what they wrap. -pub const DELIM_SHORT_FALL: Em = Em::new(0.1); - /// Converts some unit to an absolute length with the current font & font size. pub trait Scaled { fn scaled(self, ctx: &MathContext, font_size: Abs) -> Abs; diff --git a/crates/typst-library/src/math/lr.rs b/crates/typst-library/src/math/lr.rs index 6da348832..34745bd24 100644 --- a/crates/typst-library/src/math/lr.rs +++ b/crates/typst-library/src/math/lr.rs @@ -2,7 +2,7 @@ use crate::foundations::{elem, func, Content, NativeElement, NativeFunc, SymbolE use crate::layout::{Em, Length, Ratio, Rel}; use crate::math::{Mathy, StretchSize}; -const DELIM_SHORT_FALL: Em = Em::new(-0.1); +pub const DELIM_SHORT_FALL: Em = Em::new(-0.1); #[func(name = "x => x - 0.1em")] pub const fn default_lr_size(base: Length) -> Rel { diff --git a/crates/typst-library/src/math/matrix.rs b/crates/typst-library/src/math/matrix.rs index b6c4654ed..8ab19040c 100644 --- a/crates/typst-library/src/math/matrix.rs +++ b/crates/typst-library/src/math/matrix.rs @@ -5,15 +5,27 @@ use unicode_math_class::MathClass; use crate::diag::{bail, At, HintedStrResult, StrResult}; use crate::foundations::{ - array, cast, dict, elem, Array, Content, Dict, Fold, NoneValue, Resolve, Smart, - StyleChain, Symbol, Value, + array, cast, dict, elem, func, Array, Content, Dict, Fold, NativeFunc, NoneValue, + Resolve, Smart, StyleChain, Symbol, Value, }; -use crate::layout::{Abs, Em, HAlignment, Length, Rel}; -use crate::math::Mathy; +use crate::layout::{Abs, Em, HAlignment, Length, Ratio, Rel}; +use crate::math::{Mathy, StretchSize, DELIM_SHORT_FALL}; use crate::visualize::Stroke; const DEFAULT_ROW_GAP: Em = Em::new(0.2); const DEFAULT_COL_GAP: Em = Em::new(0.5); +const VERTICAL_PADDING: Ratio = Ratio::new(1.1); + +#[func(name = "x => x * 1.1 - 0.1em")] +const fn default_mat_size(base: Length) -> Rel { + Rel { + rel: Ratio::zero(), + abs: Length { + abs: Abs::raw(base.abs.to_raw() * VERTICAL_PADDING.get()), + em: DELIM_SHORT_FALL, + }, + } +} /// A column vector. /// @@ -40,6 +52,13 @@ pub struct VecElem { #[default(DelimiterPair::PAREN)] pub delim: DelimiterPair, + /// The size of the delimiters, relative to the elements' total height. + /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. + #[default(::data().into())] + pub delim_size: StretchSize, + /// The horizontal alignment that each element should have. /// /// ```example @@ -101,6 +120,13 @@ pub struct MatElem { #[default(DelimiterPair::PAREN)] pub delim: DelimiterPair, + /// The size of the delimiters, relative to the cells' total height. + /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. + #[default(::data().into())] + pub delim_size: StretchSize, + /// The horizontal alignment that each cell should have. /// /// ```example @@ -244,6 +270,13 @@ pub struct CasesElem { #[default(DelimiterPair::BRACE)] pub delim: DelimiterPair, + /// The size of the delimiters, relative to the branches' total height. + /// + /// See the [stretch documentation]($math.stretch.size) for more + /// information on sizes. + #[default(::data().into())] + pub delim_size: StretchSize, + /// Whether the direction of cases should be reversed. /// /// ```example diff --git a/tests/ref/math-cases-delim-size.png b/tests/ref/math-cases-delim-size.png new file mode 100644 index 0000000000000000000000000000000000000000..92231d6915396867ab906a7d7afa70f0f6173d40 GIT binary patch literal 1005 zcmVjz3W6@sgSLbbmSwSKm(6sM zGNLP4pn1a-O%cfrS6kC|-Dw^7HaqUluXASBZNeUUIlqCLefa*)`N8sG_slsn3w!AUUg8b`QM6nOMX{yvdZX~vk^7@HxH3|_JB z4KanUR)EDp2kYw8M%_A^x9`BAyG&uX6SAKvV2VtOoKi>2P!AlaWW2_oGvZ1u%kcsD za>^3z{;lI|Vc~+Pu5Nc~8$erXx7rS#505d0rIXDKRdnDs^R)10H!ZQ#jZGCy;rAAc zrI!w}6H8i|O|zb~yHNJAJlCrZymMvj10?w%fC~G$Fw&8!|4kyUBtP+s!yK=+8N+EpW1wJv>_rb8e-0H-wO3 z_2L>o%SUyA^E;j8IIwKXygovzG%ZB3F)b~vnK>-Y*G$@0;XQLz=V>O}pQFLAvOLLg z;AkPB!C9IO+q%|?2gCW>n$y$#4G$h(Od@>sQf`D)$8Oq++^@lp<1Iy=HJ02;Ed8Tg4r}I+5ab<|-ind*mHLNJ->V1Jl|*ge)s$S^VxmQ zxz9N}tH4cKrGYiD2G+nX0Xx1~z?g}4HTZDXa`wakugn?rg)}m-ArB;-ujjcL%h~t? z5qRFm36hrlgq6B46eK0L(ty)S(SIv8GS?ecYX2E#4Tchc#Q=cw^OJJEZT3|kJh|4%kB-$2F}HN` z?Su8|gS%dk&rgq_JJ(JCuk|ykgH2xYd21{B_~Y_+%MI1RmEQ8%qXoU=MS1&%S#@yS z2Kl`1XY>{idFx&2qF-!&PTqRvkb%pJOE_@j77%4N6o~m+vFc#mCNc6;;3S})D&)4> z908G3TOIYJ7_W{<^O_6}?At+pjROFFm$sS%2hX#X7Tj$z-{Qa(n*n95s2u>5XS(WO z{qyp9Ly?RAP6fN<^X4n)ty|@-SC#5uqqltC)`D)^C~seCR~_86Lq2c3iEdvl$j`I8 zs)I+K0bX;D&58N!INwgJ1J%KfHB0aSBTkRy^ z3t4T$0H&Agpua87ER_jtLBGLlXn?%Y%yAlU3;N&@^h+}EuY%`jH8r?6QwfHyFaT7p(5 zHYNDSq;wAa7F&`IwH~-Z34TWa4t#(uNpU?9RuXVX5qgzp9rLI({u*~1N(*Y}uJK11 z=mTG)A3nu{D;zs-U!ensmZ2AAqbFwZU}!%~lEPYhWtxLIGG*5hsn{(K}2Y(X_}a_h8d@txNb}ef<(1~NXT$e3=>1-G6Y?aTR;o0 z8z3yo2pa@iU?BzUz=|S7Nd`KCh};(hcK7T)o%cQL+4C}fJnuH+ocF{3_dNeEzj@Ej zoSivq;D0)6B(Wrx#FE%9;wuFh(@Ay~-`ve$LfFPX+Dzeh=I37!L}`=}29@-7O! z3K%Ml09cHgp(Cy+LK&lF!|cuQ^*}ruliqBMM$-{{8+kEgtNGe@+A4;xnrVpZj(|-( zGr; zll!`xC@qhT6YY^S(Z$}CYc}CUA(!tlqv6}vL>F&KA@`@M`5W_x%8lPtko%@)l-jLiTjeFX*i%jJ zE*&U`9LP3DF1k2aLGBLMQ5x1VL>r$Zx;P~>e(OjEt$d|Re8}F_TfPu(E(v!2lQ`RWP`CQV_seQNU7#)AX8QinYVnnD z@M@zi2E(4Kq!{Hb8ADI}QYyx|{R0Ru9~X#c3J%|=Cr(Ia!_*6nUTAaG*~DX`5K&A| zJo>^EK>xd-*^ch*2R3m=K7^j2Cx$McYXCK8BL4v>->J8XRo%B{DvJ*pZ+EL{iDCX1 yjsT0AslWpzql1SGK}mc){n!ubys literal 0 HcmV?d00001 diff --git a/tests/suite/math/cases.typ b/tests/suite/math/cases.typ index 306c1ae80..3765561ea 100644 --- a/tests/suite/math/cases.typ +++ b/tests/suite/math/cases.typ @@ -16,6 +16,12 @@ $ x = cases(1, 2) $ #set math.cases(delim: sym.angle.l) $ cases(a, b, c) $ +--- math-cases-delim-size --- +// Test setting delimiter size. +$ cases(reverse: #true, 1, 2, 3) cases(delim-size: #100%, 1, 2, 3) $ +#set math.cases(delim-size: x => calc.max(x - 5pt, x * 0.901)) +$ cases(1, 2) cases(1, 2, 3, 4) $ + --- math-cases-linebreaks --- // Warning: 40-49 linebreaks are ignored in branches // Hint: 40-49 use commas instead to separate each line diff --git a/tests/suite/math/mat.typ b/tests/suite/math/mat.typ index 80f190605..cde0eae98 100644 --- a/tests/suite/math/mat.typ +++ b/tests/suite/math/mat.typ @@ -54,6 +54,12 @@ $ a + mat(delim: #none, 1, 2; 3, 4) + b $ $ mat(1, 2; 3, 4; delim: "[") $, ) +--- math-mat-delim-size --- +// Test setting delimiter size. +$ mat(c; c; c) mat(delim-size: #100%, c; c; c) $ +#set math.mat(delim-size: x => calc.max(x - 5pt, x * 0.901)) +$ mat(delim: "[", f; f; f; f) mat(delim: ||, x; x; x; x) $ + --- math-mat-spread --- // Test argument spreading in matrix. $ mat(..#range(1, 5).chunks(2)) @@ -263,7 +269,7 @@ $ mat(a; b; c) mat(a \ b \ c) $ --- math-mat-vec-cases-unity --- // Test that matrices, vectors, and cases are all laid out the same. $ mat(z_(n_p); a^2) - vec(z_(n_p), a^2) + vec(z_(n_p), a^2) cases(reverse: #true, delim: \(, z_(n_p), a^2) cases(delim: \(, z_(n_p), a^2) $ diff --git a/tests/suite/math/vec.typ b/tests/suite/math/vec.typ index e5ee409ec..e976ca645 100644 --- a/tests/suite/math/vec.typ +++ b/tests/suite/math/vec.typ @@ -50,6 +50,12 @@ $ vec(1, 2) $ // Error: 22-33 invalid delimiter: "%" #set math.vec(delim: (none, "%")) +--- math-vec-delim-size --- +// Test setting delimiter size. +$ vec(1, 2, 3) vec(delim-size: #100%, 1, 2, 3) $ +#set math.vec(delim-size: x => calc.max(x - 5pt, x * 0.901)) +$ vec(delim: "{", 1, 2, 3) vec(delim: "[", 1, 2, 3) $ + --- math-vec-linebreaks --- // Warning: 20-29 linebreaks are ignored in elements // Hint: 20-29 use commas instead to separate each line From 570909285641efa8905ece78a3be8638fe0eab6f Mon Sep 17 00:00:00 2001 From: mkorje Date: Sun, 27 Apr 2025 21:13:16 +1000 Subject: [PATCH 5/5] Remove obsolete `short_fall` parameter from stretch functions --- crates/typst-layout/src/math/accent.rs | 4 ++-- crates/typst-layout/src/math/frac.rs | 4 ++-- crates/typst-layout/src/math/fragment.rs | 12 +++--------- crates/typst-layout/src/math/mat.rs | 14 ++++---------- crates/typst-layout/src/math/root.rs | 2 +- crates/typst-layout/src/math/stretch.rs | 12 +++++------- crates/typst-layout/src/math/text.rs | 2 +- crates/typst-layout/src/math/underover.rs | 2 +- 8 files changed, 19 insertions(+), 33 deletions(-) diff --git a/crates/typst-layout/src/math/accent.rs b/crates/typst-layout/src/math/accent.rs index 70c34e611..724e78355 100644 --- a/crates/typst-layout/src/math/accent.rs +++ b/crates/typst-layout/src/math/accent.rs @@ -1,6 +1,6 @@ use typst_library::diag::SourceResult; use typst_library::foundations::{Packed, StyleChain}; -use typst_library::layout::{Abs, Frame, Point, Size}; +use typst_library::layout::{Frame, Point, Size}; use typst_library::math::{Accent, AccentElem}; use super::{style_cramped, FrameFragment, GlyphFragment, MathContext, MathFragment}; @@ -39,7 +39,7 @@ pub fn layout_accent( // Forcing the accent to be at least as large as the base makes it too // wide in many case. - let variant = glyph.stretch_horizontal(ctx, width, Abs::zero()); + let variant = glyph.stretch_horizontal(ctx, width); let accent = variant.frame; let accent_attach = variant.accent_attach; diff --git a/crates/typst-layout/src/math/frac.rs b/crates/typst-layout/src/math/frac.rs index c1bfab034..172cdf7ad 100644 --- a/crates/typst-layout/src/math/frac.rs +++ b/crates/typst-layout/src/math/frac.rs @@ -109,12 +109,12 @@ fn layout_frac_like( if binom { let mut left = GlyphFragment::new(ctx, styles, '(', span) - .stretch_vertical(ctx, height, short_fall); + .stretch_vertical(ctx, height - short_fall); left.center_on_axis(ctx); ctx.push(left); ctx.push(FrameFragment::new(styles, frame)); let mut right = GlyphFragment::new(ctx, styles, ')', span) - .stretch_vertical(ctx, height, short_fall); + .stretch_vertical(ctx, height - short_fall); right.center_on_axis(ctx); ctx.push(right); } else { diff --git a/crates/typst-layout/src/math/fragment.rs b/crates/typst-layout/src/math/fragment.rs index 98b2c88a8..4e5253d02 100644 --- a/crates/typst-layout/src/math/fragment.rs +++ b/crates/typst-layout/src/math/fragment.rs @@ -427,13 +427,8 @@ impl GlyphFragment { } /// Try to stretch a glyph to a desired height. - pub fn stretch_vertical( - self, - ctx: &mut MathContext, - height: Abs, - short_fall: Abs, - ) -> VariantFragment { - stretch_glyph(ctx, self, height, short_fall, Axis::Y) + pub fn stretch_vertical(self, ctx: &mut MathContext, height: Abs) -> VariantFragment { + stretch_glyph(ctx, self, height, Axis::Y) } /// Try to stretch a glyph to a desired width. @@ -441,9 +436,8 @@ impl GlyphFragment { self, ctx: &mut MathContext, width: Abs, - short_fall: Abs, ) -> VariantFragment { - stretch_glyph(ctx, self, width, short_fall, Axis::X) + stretch_glyph(ctx, self, width, Axis::X) } } diff --git a/crates/typst-layout/src/math/mat.rs b/crates/typst-layout/src/math/mat.rs index ef4466d2c..3d10fde57 100644 --- a/crates/typst-layout/src/math/mat.rs +++ b/crates/typst-layout/src/math/mat.rs @@ -331,11 +331,8 @@ fn layout_delimiters( let target = size.resolve(ctx.engine, styles, height)?; if let Some(left) = left { - let mut left = GlyphFragment::new(ctx, styles, left, span).stretch_vertical( - ctx, - target, - Abs::zero(), - ); + let mut left = + GlyphFragment::new(ctx, styles, left, span).stretch_vertical(ctx, target); left.align_on_axis(ctx, delimiter_alignment(left.c)); ctx.push(left); } @@ -343,11 +340,8 @@ fn layout_delimiters( ctx.push(FrameFragment::new(styles, frame)); if let Some(right) = right { - let mut right = GlyphFragment::new(ctx, styles, right, span).stretch_vertical( - ctx, - target, - Abs::zero(), - ); + let mut right = + GlyphFragment::new(ctx, styles, right, span).stretch_vertical(ctx, target); right.align_on_axis(ctx, delimiter_alignment(right.c)); ctx.push(right); } diff --git a/crates/typst-layout/src/math/root.rs b/crates/typst-layout/src/math/root.rs index c7f41488e..32f527198 100644 --- a/crates/typst-layout/src/math/root.rs +++ b/crates/typst-layout/src/math/root.rs @@ -50,7 +50,7 @@ pub fn layout_root( // Layout root symbol. let target = radicand.height() + thickness + gap; let sqrt = GlyphFragment::new(ctx, styles, '√', span) - .stretch_vertical(ctx, target, Abs::zero()) + .stretch_vertical(ctx, target) .frame; // Layout the index. diff --git a/crates/typst-layout/src/math/stretch.rs b/crates/typst-layout/src/math/stretch.rs index fd34be0ad..95ca2b6c2 100644 --- a/crates/typst-layout/src/math/stretch.rs +++ b/crates/typst-layout/src/math/stretch.rs @@ -57,7 +57,7 @@ pub fn stretch_fragment( return; } - let mut variant = stretch_glyph(ctx, glyph, target, Abs::zero(), axis); + let mut variant = stretch_glyph(ctx, glyph, target, axis); if axis == Axis::Y { variant.align_on_axis(ctx, delimiter_alignment(variant.c)); @@ -116,7 +116,6 @@ pub fn stretch_glyph( ctx: &mut MathContext, mut base: GlyphFragment, target: Abs, - short_fall: Abs, axis: Axis, ) -> VariantFragment { // If the base glyph is good enough, use it. @@ -124,8 +123,7 @@ pub fn stretch_glyph( Axis::X => base.width, Axis::Y => base.height(), }; - let short_target = target - short_fall; - if short_target <= advance { + if target <= advance { return base.into_variant(); } @@ -149,20 +147,20 @@ pub fn stretch_glyph( for variant in construction.variants { best_id = variant.variant_glyph; best_advance = base.font.to_em(variant.advance_measurement).at(base.font_size); - if short_target <= best_advance { + if target <= best_advance { break; } } // This is either good or the best we've got. - if short_target <= best_advance || construction.assembly.is_none() { + if target <= best_advance || construction.assembly.is_none() { base.set_id(ctx, best_id); return base.into_variant(); } // Assemble from parts. let assembly = construction.assembly.unwrap(); - assemble(ctx, base, assembly, min_overlap, short_target, axis) + assemble(ctx, base, assembly, min_overlap, target, axis) } /// Assemble a glyph from parts. diff --git a/crates/typst-layout/src/math/text.rs b/crates/typst-layout/src/math/text.rs index 59ac5b089..64d167a76 100644 --- a/crates/typst-layout/src/math/text.rs +++ b/crates/typst-layout/src/math/text.rs @@ -164,7 +164,7 @@ fn layout_glyph( let mut variant = if math_size == MathSize::Display { let height = scaled!(ctx, styles, display_operator_min_height) .max(SQRT_2 * glyph.height()); - glyph.stretch_vertical(ctx, height, Abs::zero()) + glyph.stretch_vertical(ctx, height) } else { glyph.into_variant() }; diff --git a/crates/typst-layout/src/math/underover.rs b/crates/typst-layout/src/math/underover.rs index 5b6bd40eb..a24113c81 100644 --- a/crates/typst-layout/src/math/underover.rs +++ b/crates/typst-layout/src/math/underover.rs @@ -286,7 +286,7 @@ fn layout_underoverspreader( let body_class = body.class(); let body = body.into_fragment(styles); let glyph = GlyphFragment::new(ctx, styles, c, span); - let stretched = glyph.stretch_horizontal(ctx, body.width(), Abs::zero()); + let stretched = glyph.stretch_horizontal(ctx, body.width()); let mut rows = vec![]; let baseline = match position {