From aad210a77768f33034e16880ec1aeb458c86ff15 Mon Sep 17 00:00:00 2001 From: Johannes Wolf <519002+johannes-wolf@users.noreply.github.com> Date: Thu, 23 Jan 2025 20:59:03 +0100 Subject: [PATCH] Content Auto-Scaling (#799) * content: Support canvas scaling * content: Scaling tests --- src/draw/shapes.typ | 10 ++++++++++ src/styles.typ | 2 ++ tests/content/ref/1.png | Bin 51430 -> 55265 bytes tests/content/test.typ | 10 ++++++++++ 4 files changed, 22 insertions(+) diff --git a/src/draw/shapes.typ b/src/draw/shapes.typ index 3bc93686a..a93712ab7 100644 --- a/src/draw/shapes.typ +++ b/src/draw/shapes.typ @@ -819,6 +819,7 @@ /// *Root*: `content` /// - padding (number, dictionary) = 0: Sets the spacing around content. Can be a single number to set padding on all sides or a dictionary to specify each side specifically. The dictionary follows Typst's `pad` function: https://typst.app/docs/reference/layout/pad/ /// - frame (str, none) = none: Sets the frame style. Can be {{none}}, `"rect"` or `"circle"` and inherits the `stroke` and `fill` style. +/// - auto-scale (bool): If `true`, apply current canvas scaling to the content. Defaults to `false`. /// /// ## Anchors /// Supports border anchors, the default anchor is set to **center**. @@ -857,6 +858,7 @@ } return (ctx => { + let body = body let style = styles.resolve(ctx.style, merge: style, root: "content") let padding = util.as-padding-dict(style.padding) for (k, v) in padding { @@ -881,6 +883,14 @@ // Typst's `rotate` function is clockwise relative to x-axis, which is backwards from us angle = angle * -1 + // Optionally scale content with current canvas scaling + if style.auto-scale == true { + let sx = vector.len(matrix.column(ctx.transform, 0)) + let sy = vector.len(matrix.column(ctx.transform, 1)) + + body = std.scale(x: sx * 100%, y: sy * 100%, body, reflow: true) + } + // Height from the baseline to content-north let (content-width, baseline-height) = util.measure(ctx, text(top-edge: "cap-height", bottom-edge: "baseline", body)) diff --git a/src/styles.typ b/src/styles.typ index 7ae71ed82..a64a8fd1a 100644 --- a/src/styles.typ +++ b/src/styles.typ @@ -138,6 +138,8 @@ frame: none, fill: auto, stroke: auto, + // Apply canvas scaling to content + auto-scale: false, ), ) diff --git a/tests/content/ref/1.png b/tests/content/ref/1.png index 3bb1afe89f9cc121cf2620eb5162c64a8974ab9c..e90d46fa33c6ab432d199d96ca45dbb8f453a69b 100644 GIT binary patch delta 5815 zcmb_gc|6o>+aGn3iVVpXS?X9Kj4(otWJ?ptK1r7Bnh|5j_KV1#GGXkgj3g!r$9^nh zl5jLhmPwNsOJkRv_czix=Xsvb`@GNRec$`~F_nbzj@}o{{@I>7CCPS9X1isL4qS6lNE;C@|%D_Dy#xSqV^*%v8smwF|I&)lzl{odGwTT@=Dvd|X) zeR|~kdSEGT22#O}W>XG*OqG+CyhcWiT#G+H=JF5OjM`AX5?pW*3r{Gg2&<8pIfCl~j$|`h;NT&l|Lv zIg>4BzM1=9UYY&W2&|1-m{^c%yL!_juIfZ{3d-y7H=PiQEX{SJYCq2e& zP1f?w>U}ACh{uChY1Xj0M$ecxQI_&@Z5`upIwwf->t&CBMb%ZD?8?fiD73f1B4{@i zEtB)$U1f03o;<|rrG-A#-nhrZnhS^cjrFh6-a$|4t*E}^=Dnmk^LAfOMfWMonnzO7 z*{@>|HZN!KDHq1pJH~d4qN+dIG`=v*Kg@cUgjta z(MBphBpgOs?l#?PV)II-v{qr++ltXp8}#Vri`wJ-al8CcSIn1|va=0vQ{(9CHl-dG zN=^NWIk6kxLe#zsylUx_F8t&fI)I_Ic zo(|E_IEDLWtq!0E>qHYNw`HTa#rUb<6}zCFR`gvxUGA0CS1ALTwA`~%;qFI{9HG-} z>qAe$;T07X@Jy?;w6ul?b##2R?Er}wWuKx3*UG{xto;{5=NF?&f zr2=m|XIIzVW_QI93M`}61%ej$zcYlgduPTQ-CJsu%+!H$@`sE6Vj6Ll7|Hmg9utTSzZtxr#X zURjMS` z$2Xl1@|W$%`THS;&;^7R}0R8J#@>wd?GOdcjJac9H@DZnUdfG zvQF;3ZjXcMoeVrV321#nLtEVzNli_i6+>OVoR;>(Ema~0jgC-LQO*yTqN+Xwx zi>sA4Ok3McRaKSlZOu=}&hC&_|8eu?4oGfp?tRRa6;$YxiV7>jrGf|Yu#+ccRr0B6 z#`$x;-Q(Aso%M{)A$LL`j=~m#R1*^uor%%Wi@<7YH|35)O-+p!0x<}FXtYS3+{sC_ zLoC_xrS4JQl76PnTwv|^*M)_$f`V2ij^T3>tT?dbo^}vE4Gi!N8y@AIJ;Gox8nJlaTF7{rWjD)O@=GYF|a>G&%ludMwcF9S5X~*2ikkd&C)%KDZ$5uI(ycRsf$-cO_m}F%7 z0Mmk%;nUd$H5Q{DPBh>}74d7zry-N8}>q|vf^s<53l=Oy)`)RE7-LckdK0!fpd+r-Xgve&JC*A4xU}80pPSrFb z)%|hT(@&?SWRs10dU|xt6;gXoA0AFjOiYT+|Blsg&MC2$7i+JzRX|ADKbLCC8LWqH zU-Kpp6#%buw`Uoutk>&FL%rZ^YckziJ)`~A;u}+9!?dvb!-OhTFp=U?nx+o3%5EDDto?+pa1sXVh1br` z&I{LfNI(0LV+@ZX(NRFaUb&zKV_mBoHqHhDCJ&49cE6b2dwJJe zHMWL(=I3~_^9A{F`=^zIPmo9pfwgOsr`Lg?n_GQ+gyK~7{HsS9YPmxo|Gh+nOR3E= zvaq{vYOz9-hOU?eEgwMOt(M;oaV!k`6m)xRPO1ne%mjG7-3bO~?NjT#Ph~tXq<$`` z-Q|GJM<(uOHm0IqzU`gL@y!mG(z)f})ps)iBKxCi?MO7Vfhl-+e^e8*VGN5Zvb0GV zzG+u{F6k{}PWd55EcOw>I6saod4USmsVuVXneY>#^h_+wgpJF@YGfJL59T1H^h^n0 zb7@vVh){vM`=Ym)KpdV-<~s~F5pg09b!(7DyKk+?ufSS?QXNsqo%qQnAv{8A*De$? z&K-geYZB&QP3$;uBfg(31b|z><_~s!7PSC(Xd{mh$tsZP4zwr-n1>L^a=n^Pq)Q;t zwd$D%(KV1*_{^m$Eqe@HWQ?U1Z!eyKzkrMMF_z?68k)5`eGEKRxV`x6C~MbW0^m>3 zZ4G||-PZ6EbX&t;XMY0yG%n+xRsR(H8>@l;%uB1qetfiHN}3)4~ZUZO&lj zUQKTw2|hiwxLRO79tzl!dMX$qiInwF#Vt-X(TpYa6n1;mD~gGUNkq`li|X0N`PTBd zsc-!U*l#ziuC8J=Kw1m3RX@i-t;3ss6X5By9E`c;9_5U7wTyP=9wu&;$-G`-9nH$e zxi{R<12MWBbf3zB4LaBwHq7#=m6UmpGF}h`AdG0X%#UHgN{-Z#$mwMGRMNedJ|0TY zKgt`U{}^n1%4q|s=!#YA(+J?DCqmIE;)Vz%q>f$rK@tM>;pic^{--aRs_=qm?ATjw zi~f>!o84}&W>u7eWS5vYr>XqMD`%=Bqm0Sl&+3HhKGD%_z8&!T_qc~=sb=^ud9|+_ zfyPifttiIwX^nv3BfhC(P9=nXrc3;c1Q4JuGQw@}a|T>Qw!M5V6T7@(P+;yDe{k=v zxo6h$;DuXQv=3cVo(a(E_UN{LJ?x_!0c_70X&6y1c`uJ@#)UccEaU5H89fuK{Ikni zJl!6ubtd`LVV^V%lnQ_)dW*o`{E8<*pNR`nPBXVqJ)9^PtD_6H8*4%*qrv_U#+-Y4 zO1sPQFD$+Rrh+!|P*w39I_0RllHmO6x*e&9iPOyL@K#r`eAR#b3^dc2;iYzV%W_s{ z0pcl6lDv9d>hIlDW>?qaVPKzP%>Y(X%>xL9)VOF=QOb;1RdL(P0XG%imHk0BO zY^~i-_wPC*2Tg>oo+j0+ZQ$mXKDUp1PuayrOIBA?O~g{0dR9AAR=tibe|5Nn39Sp7 zSVXfcU@n{%k;jO+9)@-m=J#nJIJb>ge@3ta{B+>in5#$QB1wQj=+xpx?L@s7+`rQtYfF}7a3As$lw-0>TH>Ke3XX{MuH#He91w=uMquo8=#Ipy)TDsh& z{8G+|lDq7xHvMi+E>60l>7kO<_;K1Ovr4GFM!wzr1BRkZPaaYaBnWe*V&vxNn$kCp z$=|^*CP%(lO1`XRXpj*?^B+1ZR+)3~2Q-Z6$pe68Do!k5%X3@~u4kj(NRf`Vue`5L&-OySYDoQUq?HSM$7mF#p{Xm{fZqA5mT6@nG8%$`}`&>O|+2P zT)SpgQP?)LCY5KNGttgX>FE^vR7e-&Z8^>YMgHdXJ?TuD77VatYX9}117pZD(}I4L)}dQ zjjX%SFWpJHi9pkN?Xf0d!>sZ!NI{b*7EO*o{fWe6pDeW zNxs=ZDoDRPvXN5h#61!s`zc`mP0-I|)gY95CvI#x7+qqmps3iBQCKJ^p{tQ)>04l) zbg9_*ak8y~K!Sdc^oN=ekmZ8vG>CJ{HPA2f^Ya@U8O@VCuZA6@dJ<5GaLr z2g&=~@%@hJ2AnML=J_PbkZIdBI3VDU%_pd$yOg2s z=kDpffLFP-df)N`bR(0=G$ejuJwm#wA>5# zu3~Y5o-WM#xJyHFwA+VkH+JbaxK(gS-L{c_t64*DeeSSSr)1mV-S#Bsz=-s*<-pp| zs6@)pa&U_S$f$>^dnURk7QO{n(+*ua))Cqq6~8cU?0p`md+^s*6bB&pqxEM%@TNgGyhI-tm9#1DSUA=9PdFERr#Ds(;%`z?>v&x z;8nrq?zc8=h!_5Y?R*xD=Ncc+D~VjjSJ|cICcPi5?G}Nb8tsmMPnH&7@q>S21kvu& zP<$5|gU@dgz^6A!vv1MB<9MLy5UBsq&Q}C}ykWBpexgYNU)C(JgZv8rtXUQmDQPWB z5mQg*H+?c;k%y`x!r>KkT!YbttyLO!>rr;=%*KZpzQ$sUEReiuP%SL{K+5>+#1#t*kU>7{ zz*_t%=mz=azX-;WRu=yt_zCe3g1=+`5C9<7-@*TnT07={`C52Zik%H MV>i|<*0B%&FEaH%q5uE@ delta 2262 zcmb7F2~-p38Xctv@c{yg1S+e7V8a$g1PoxMir4@?1wo?$f_<`uuqjIja?*d8L7077IDutHb@%DxD1@Ep!j`ubiw=iGnhpZ}YC?%ey$KLce_ zZ@-sHQBl}dC9@R(fV?9%Jpj;HTCP|43pgoqQI-y}a3qi%v&~BhruPYg&bdlQ|5As< zqD6y53Z=kl$KXG?@kO_@lOAfb#d|sI18j?g2QrCC46EfkltC&&2fTS_F47`)s&C%- z>XJO-7>4PK>W$C}S0xYW$>*}`R6p}u__XsadC z(j>cMlMcOLg`m1uLLv?as6>%)FTZMf;K0wcgNty}%ju}Zrc2;j3??ulQ87QQ`m-8$Xc9IYDjbnR$p;qyD(;KhYT z&+;;QYBSC#8T5B~Iwj_@bDK3aH072ZhA-!TwIBM|oTrynAl`R19CH*qwD3#{;G5w^NuOY70c2Y1#&ATXkGZGOQf1KI9hyPmb>0led0Nq1z$9h#Pre@X+&% z6Ss@vZzUNU-!f>r?Y>=Rhw*{!O(}X!X;g>CnwQ=t=(88U<{L)#Hw=VG9?u7aF9cgc z)DA7MB~f*W8HB!C(leE?1;9tmM$Nu=op9?XG^!#|f9nT_cEK`d{F20dWsjQO)$m^e zib6dl;cq%D^VFqaySHuW`G*5VY@1k@3*Ae}$Az@}HPJlk=+OI!S1Wb&ci#;J_W~CC!zcYwE+3sMV!{n&~sm#FlMC)ygLW zd{FX0ym)7#IB`Z)JE>9kn?xc}6{eeb7&GJ)6!I-YX;U~{O^n8IAAf)3kJ2Bj1&Ly! zZIfZL80p5~XYitC{RZq*)z#&6-h^1f1=_T4t!NDm4bFM!?zXm|@vd^PAz2HNmYJ0` zIyx$>Z*OlIDvd__pw*ghix2_;p7RE8rP)F&LNg=QS-ubQ#G>Nqse-ZEVo%CpURKURNiR$%G9& zhDpDKne1ljXSb+;L~pA&#V8VK2)#;7!b*C%>F7l09NkH8no6ZA*1jmP*O&&@J^xZ@ zf~%I%2@4DB;gOf?@9%lZxJ)5vxJh~*L+baEu-C`CQ0C_6d-l@Ec;H5cijbIN3);j6 z!Rzj=<#b|SwHm~s)AjQnI^is$7lL|NfxVncu(EPszzbzW+XBGD+O?vgZsyfHRiuR} zuN6y;`Ly)(;ps@!#Cj9_oDoyNWFCqQnj7z~T~kw2%goO=(adn73t21{UZgJ#r}YCx zEQ>IPosW2j_sZ0F&WlwvC-&v!jGcN0A1y6)4#w%Esn=fz|H5DdHm4aigWjCSk1t@P z;AdSmg|f1;-2vwHVRC~OCWhxcJhYB?RT8i^`T03H(MvPFc6LukMtq{f2KfoS+;9_P z$2JmUd)H6fI&FntgNhv`_p-O zd4pr+sm}Q}8s4X@a-G~6T06bKX`AV#|mG~Ip#@)aN4N=Gg%ANP2-F~+aOb}NS-s9* z_cLVMsIirA2H_gjAes6W+nJY0Ly){H}EY&-c=j zsTyPdK8t}P#4o*+AWJBESvyvL6x&}X13$6t zQ(YU^|HU#`8gioZrW~Bv6K!ye6n#Po(1y3Z4cvf}-VETNJn%a-n!)$hhYf5nY@AII Yz0C!l#H#4I^#*Y`;q(pTxaY0^0CDPu