From 9a798ce6f6e734a02764473891632c071fed41ee Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 17 Aug 2021 00:17:28 +0200 Subject: [PATCH] Make percentages for h and v relative to area instead of font size --- src/exec/context.rs | 4 ++-- src/exec/mod.rs | 2 +- src/layout/par.rs | 5 +++-- src/layout/stack.rs | 10 +++++++--- src/library/layout.rs | 15 ++++++--------- tests/ref/layout/spacing.png | Bin 2527 -> 1864 bytes tests/typ/layout/spacing.typ | 5 +++-- 7 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/exec/context.rs b/src/exec/context.rs index 9b235c294..2b0ef9faf 100644 --- a/src/exec/context.rs +++ b/src/exec/context.rs @@ -93,7 +93,7 @@ impl ExecContext { } /// Push spacing into the active paragraph or stack depending on the `axis`. - pub fn push_spacing(&mut self, axis: GenAxis, amount: Length) { + pub fn push_spacing(&mut self, axis: GenAxis, amount: Linear) { match axis { GenAxis::Main => { self.stack.finish_par(&self.state); @@ -114,7 +114,7 @@ impl ExecContext { pub fn parbreak(&mut self) { let amount = self.state.par_spacing(); self.stack.finish_par(&self.state); - self.stack.push_soft(StackChild::Spacing(amount)); + self.stack.push_soft(StackChild::Spacing(amount.into())); } /// Apply a forced page break. diff --git a/src/exec/mod.rs b/src/exec/mod.rs index dc3054d27..63e479959 100644 --- a/src/exec/mod.rs +++ b/src/exec/mod.rs @@ -119,7 +119,7 @@ fn exec_item(ctx: &mut ExecContext, label: EcoString, body: &SyntaxTree, map: &E aspect: None, children: vec![ StackChild::Any(label.into(), Gen::default()), - StackChild::Spacing(ctx.state.font.size / 2.0), + StackChild::Spacing((ctx.state.font.size / 2.0).into()), StackChild::Any(body.into(), Gen::default()), ], }); diff --git a/src/layout/par.rs b/src/layout/par.rs index a88a0f0bf..c8512243f 100644 --- a/src/layout/par.rs +++ b/src/layout/par.rs @@ -27,7 +27,7 @@ pub struct ParNode { #[cfg_attr(feature = "layout-cache", derive(Hash))] pub enum ParChild { /// Spacing between other nodes. - Spacing(Length), + Spacing(Linear), /// A run of text and how to align it in its line. Text(EcoString, Align, Rc), /// Any child node and how to align it in its line. @@ -137,7 +137,8 @@ impl<'a> ParLayouter<'a> { for (range, child) in par.ranges().zip(&par.children) { match *child { ParChild::Spacing(amount) => { - items.push(ParItem::Spacing(amount)); + let resolved = amount.resolve(regions.current.width); + items.push(ParItem::Spacing(resolved)); ranges.push(range); } ParChild::Text(_, align, ref state) => { diff --git a/src/layout/stack.rs b/src/layout/stack.rs index 7f0f2b9d1..504c64aaf 100644 --- a/src/layout/stack.rs +++ b/src/layout/stack.rs @@ -24,7 +24,7 @@ pub struct StackNode { #[cfg_attr(feature = "layout-cache", derive(Hash))] pub enum StackChild { /// Spacing between other nodes. - Spacing(Length), + Spacing(Linear), /// Any child node and how to align it in the stack. Any(LayoutNode, Gen), } @@ -125,11 +125,15 @@ impl<'a> StackLayouter<'a> { } /// Add main-axis spacing into the current region. - fn space(&mut self, amount: Length) { + fn space(&mut self, amount: Linear) { + // Resolve the linear. + let full = self.full.get(self.main); + let resolved = amount.resolve(full); + // Cap the spacing to the remaining available space. This action does // not directly affect the constraints because of the cap. let remaining = self.regions.current.get_mut(self.main); - let capped = amount.min(*remaining); + let capped = resolved.min(*remaining); // Grow our size and shrink the available space in the region. self.used.main += capped; diff --git a/src/library/layout.rs b/src/library/layout.rs index 977b3153d..67e58606c 100644 --- a/src/library/layout.rs +++ b/src/library/layout.rs @@ -80,20 +80,17 @@ pub fn pagebreak(_: &mut EvalContext, _: &mut Arguments) -> TypResult { /// `h`: Horizontal spacing. pub fn h(_: &mut EvalContext, args: &mut Arguments) -> TypResult { - spacing_impl(args, GenAxis::Cross) + let spacing = args.expect("spacing")?; + Ok(Value::template(move |ctx| { + ctx.push_spacing(GenAxis::Cross, spacing); + })) } /// `v`: Vertical spacing. pub fn v(_: &mut EvalContext, args: &mut Arguments) -> TypResult { - spacing_impl(args, GenAxis::Main) -} - -fn spacing_impl(args: &mut Arguments, axis: GenAxis) -> TypResult { - let spacing = args.expect::("spacing")?; + let spacing = args.expect("spacing")?; Ok(Value::template(move |ctx| { - // TODO: Should this really always be font-size relative? - let amount = spacing.resolve(ctx.state.font.size); - ctx.push_spacing(axis, amount); + ctx.push_spacing(GenAxis::Main, spacing); })) } diff --git a/tests/ref/layout/spacing.png b/tests/ref/layout/spacing.png index b2b8707d42e7c1d2d13764a7ef32864664e26845..c5a1bb806360ca665211d57ce1972021448b7ded 100644 GIT binary patch literal 1864 zcmZ{lX*Ao30>zU^>u;MRVpJ%y)D~+?TT6??lAu*vM2D(nTKi5hEfS@eU{a=~s`N_G>zkQ#-up18bINg>Mx~3I_m~X=?$FdGKx)Jb#I@6nmd_~C+b}S^1rz{1=SH88A>3g=Z(cxy>Vo`DBj69_N zoVk8p)n**ZQ+e}?T1hF%!hFiZ^$^e)O$bYydvMVtk&G|S#x^^{<2;q$DxfL#|mk^0=e9TZqsk<~C7n>Rs4 z$XS&qcfj7qSC3L+hlxMyKP5jt%yzP5 z$(0L!>?J!400Aq;?HJ>TONO$%1m+wwT1zD^-oYi}dYG($0cQl%Y|be^aNhs0Q^C8A zxLf)X`3pR}eeu$G8_;v)>glsY^3Y^h8j);9A`0F$gIB+z$nn>{w(SWGFC%Av+N-SN ziV>4!zwX?I^K1%U#Hyj_+=xE#tg>0+E;Eo&v4-$(%PtoyUE8j0f5ji^3Ze4UPckDj z8kKBCx8(ELD2##Fic~L!6$n}P0*t@hBB7iVpBa&Z)Z}%cFlNK#4O2fAi|?MzG68%P zb=W9>Q0cg*&cNrI>9Vq<@Hd*6bWzWT&#Rlo^?7>gJD z$6Py?B3>L}Ia?eFS7FfJO8Khcn10}VIpOPjk1*+tD;}z)E<-}+2*uT$OWRF1U1h{) zk@&vN5Rt4#UEM61JwA!wjCmh3yamlHyYDj#IcIMRvk=bfeSI+?R(+vNbVVo3i9gFv zLpC*uiAq`MK`pjaQkI_J;DJI;ZBFXCALgi$WC#48O#BCtSaY!ozG=$eb%pu}z9bwB zHs)%$`<145@zYpMnOXzbsYl1AhXNK#vU;n4%ibPK)xg^G&PNB*o<+`#_DhT5S}CMd zy7zCZ(BumObrA) zig8;TM#g3IsxwXU@4n|pSUU_-2$Ln6+uX2Nj`EB%Dx9X;Wo61Io^j27vqnAP)%7e&<`?uM>Y!{kt9Eu><1`Oa>-#9DVtfOUm5tJ^{vMrbhgDB5f_|6C2s zlSsJC}|UhHptRP7BOJ3k{!k6A9= z)wY{mV?<}wURFymYleT*0(3roOe94FjBnYo6c><(k7X-fRI!Q&y zzO$L+BhZwddAt?m&Z!Q=)0vdyInk+6{<010qkHWxT zs~DL%58h>w*9Pwg0N4vc4)SzzVME@$A1avWKp6npP$(w}M{i_WK+Hw$o2ieCDC>(0MemAI1M;Mn=TYCB`<>SfdDKNtTI0Wr-|9_GGNStIQ%#O04GdM46OhF1o^4o zLVq5Bnll&(0Ne$ph6Xo7CRSMIam(7m#93?eb%5KNACXe~tU;m3w;{3$>SvyzAS z=0f3~Ts?fBCGgz07+8khLqo**@|n12Q)2IC6-Z;LzkXIT?VWp{WRf7Rb$6~i31yrh zUcuXfy-ki!6i`KDx}l;-)c+U@BW7#Ef+Wn}Qx-HqSb&C&e-vi+5*D#68r! z`f2JB@tHui4{k4UwhXHDF?S{M1|X-%i9&b%ZbgnioOCO9M$wK(YtYQwD z6S$pqZk|=yq{4^@9$d2@*+v*GbPfrqpPlbIF&)!pPbaVkV8WsSdnL0D5D`y8LS_77 zBsqsTRt?HIU3=*FO`EKlVx@~AYIegEdKQDM*bx!bC_zUpd6D}e_;rMnv}75*7KfK$ z=!C7-x}6JI1^b~+TPZI~sqUGqO&c@EcYclX?u?&pf%St|qIUC>*mI2X*!m5(^=2r| zxfZv|%3n~|!x3y}o1uH7|Es$>+1jhch3D6$n6#HkR6P5=dX0=B%>qWj(Z?`FfQzV zO$PyaYeF>5IzbMW8E!%TUUv`jz|dlW{~Qn+3n0Hh

G*!@P=EfNX%aGhK{%+#O%h z*;#b4E%)AVyi{itHCP>^Z3d-Dy<5Tr!YhmrwyKJ>VuKPm{+R7~7~~~#Q;cM@X4HuC z7RvIfd9d*{@!PmireUSzYu?f@-_~F$Tn0S~ znUc8gkpGOHW=k37>8ji`TTWNB4ntf7Xnw_9slM82-M7+1J!xk5)A~4CE)D}Nf(p1F zQ*B%Qa!uRbF7w_+5j*uWOV#KsY|p=p&wpoWR!x9manu|DAM5dYk4K}(a5WJxOhs9#1B6N_l#pd;&PsSI)uFvNr_vwnQ35MR<3AesaT85|h5=t_g%OZIH(4+!bjZ^^ z^CsD;(L@U)tkBpWJ2rZl_6YHfx$!EEGfzI-Jlhj5MB19(1D2Y%rWHHK-)buAXTI=i zDb_Mx;0R|m+{AzPny0fEeILBM8t?r53~qnHU&fZMYlr z2^t7?vb$Iy)i0;NTaiIsD@d)p3ZBTe>)77uvEFItS)us{aJV%VSnCX+*j}Tcp_kjP z5FZ?;TUeJ1a!v8L%zlqfY6(n<_)A1=j!W6*kz-FxsSl^bWpiUQ=$dAkzW4IrBBTXV zI5>z7(Yf4Jy^>#}Yi7)R$K^g@{>0j3Rn>@1;|f|^*Ob`edekwvPz`Y@xW+j4DZMu> zw#RbW4JrrI8&JsTqMnmjs5KbM+zUSDwr%^md<7iKAG4 zPPHie0JcSkj`!#77tO@02tL0XF=>QZD8<&WoKtUFdaa6gRoYP(Jtj7-+-kJ zYqnDF&=#Z2?Si=Qg3eQiEDsLa=NiXXT2dkd0>omuj55{ne83&a?}IlrRSJU}JLF!v zvKBT!)53E!wCl^lIsuAr*d0R_Om<$)II88P)R5H_|Myj

  • t{}5HYI9QLC7proA1tR&c4yp{-5*XR{JeIhKUIdQ#Y!oW2vB@7$mM?J-3PvND!C7X2HWLt zXd6j&f}@lWE6)yb5K>@&J!hMkf_Q1yn0`>dmdNA5VNK@yF_9O6=Ag~&ale4wYfc<9 zPnx-|tBI*$^uyk$JQoU5?^--O*ROTTJ~J?@9+ngeZLO8rU#eR}%~|2o4s?V)_sgNg z-_`W@6IH1$LT-B3KcHI`IVML1*t*iJ#Z=hDE?r8I{Bq;-?RsShy(?{W6CXXIe!w-n t(QEzn|Dot-L#AUA|Hh|(IO>zmAwQ1Ue5r6vP3CWMGc__dEJwSN{sQQIuy+6e diff --git a/tests/typ/layout/spacing.typ b/tests/typ/layout/spacing.typ index bd670edb8..3794612cc 100644 --- a/tests/typ/layout/spacing.typ +++ b/tests/typ/layout/spacing.typ @@ -10,8 +10,9 @@ Inv #h(0pt) isible // Multiple spacings in a row. Add #h(10pt) #h(10pt) up -// Relative to font size. -Relative #h(100%) spacing +// Relative to area. +#let x = 25% - 4pt +| #h(x) | #h(x) | #h(x) | #h(x) | --- // Missing spacing.