From 50ab02b7ea81260bd2b6acdcbbfa322cc8b1e3ad Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Fri, 5 Nov 2021 22:02:06 +0000 Subject: texdimens (5nov21) git-svn-id: svn://tug.org/texlive/trunk@60960 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/generic/texdimens/README.md | 2 +- .../texmf-dist/doc/generic/texdimens/texdimens.md | 7 +-- .../texmf-dist/doc/generic/texdimens/texdimens.pdf | Bin 48342 -> 48310 bytes .../texmf-dist/tex/generic/texdimens/texdimens.sty | 2 +- .../texmf-dist/tex/generic/texdimens/texdimens.tex | 62 ++++++++++++++++----- 5 files changed, 52 insertions(+), 21 deletions(-) (limited to 'Master') diff --git a/Master/texmf-dist/doc/generic/texdimens/README.md b/Master/texmf-dist/doc/generic/texdimens/README.md index 00482af6f17..c0ba961f303 100644 --- a/Master/texmf-dist/doc/generic/texdimens/README.md +++ b/Master/texmf-dist/doc/generic/texdimens/README.md @@ -10,7 +10,7 @@ LPPL 1.3c. See file LICENSE.md. Repository: https://github.com/jfbu/texdimens -Release: `0.99a 2021/11/04` +Release: `0.99d 2021/11/04` ## Usage diff --git a/Master/texmf-dist/doc/generic/texdimens/texdimens.md b/Master/texmf-dist/doc/generic/texdimens/texdimens.md index 62a99856ad0..98ae9f5b3b9 100644 --- a/Master/texmf-dist/doc/generic/texdimens/texdimens.md +++ b/Master/texmf-dist/doc/generic/texdimens/texdimens.md @@ -10,7 +10,7 @@ LPPL 1.3c. See file LICENSE.md. Repository: https://github.com/jfbu/texdimens -Release: `0.99a 2021/11/04` +Release: `0.99d 2021/11/04` ## Usage @@ -115,7 +115,7 @@ which is a conversion factor. For the internal dimensions `ex`, `em`, `px` or in the case of multiplying a dimension by a decimal, this `phi` is morally `f/65536` where `f` is the integer such that `1 uu=f sp`. For core units however, the hard-coded ratio `n/d` never has a -denominator `d` whici is a power of `2`, except for the `pc` whose +denominator `d` which is a power of `2`, except for the `pc` whose associated ratio factor is `12/1` (and arguably for the `sp` for which morally `phi` is `1/65536` but we keep it separate from the general discussion). @@ -240,7 +240,7 @@ Remarks about "Dimension too large" issues: is not representable exactly by `dimen2` used as a base dimension, (which may happen only if `dimen2>1pt`): it is possible that the output `D`, if consequently used as `D\dimexpr dimen2\relax` will - will trigger "Dimension too large". + trigger "Dimension too large". 3. For `dd`, `nc` and `in`, and input `X` equal to (or sufficiently close to) `\maxdimen` it turns out that `\texdimen{X}` produces an output `D` such that `Duu` is the first "virtually attainable" TeX @@ -249,7 +249,6 @@ Remarks about "Dimension too large" issues: 4. Again for the `dd`, `nc` and `in` units, both the "down" and "up" macros will trigger "Dimension too large" *during their execution* if used with an input equal to (or sufficiently close to) `\maxdimen`. - made. `\texdimenpt{}` diff --git a/Master/texmf-dist/doc/generic/texdimens/texdimens.pdf b/Master/texmf-dist/doc/generic/texdimens/texdimens.pdf index b96d6fc6900..95e97ee2934 100644 Binary files a/Master/texmf-dist/doc/generic/texdimens/texdimens.pdf and b/Master/texmf-dist/doc/generic/texdimens/texdimens.pdf differ diff --git a/Master/texmf-dist/tex/generic/texdimens/texdimens.sty b/Master/texmf-dist/tex/generic/texdimens/texdimens.sty index 88e67741e00..e906d11fa3d 100644 --- a/Master/texmf-dist/tex/generic/texdimens/texdimens.sty +++ b/Master/texmf-dist/tex/generic/texdimens/texdimens.sty @@ -1,5 +1,5 @@ % This is file texdimens.tex, part of texdimens package, which % is distributed under the LPPL 1.3c. Copyright (c) 2021 Jean-François Burnol -\ProvidesPackage{texdimens}[2021/11/04 v0.99a conversion of TeX dimensions to decimals (JFB)] +\ProvidesPackage{texdimens}[2021/11/04 v0.99d conversion of TeX dimensions to decimals (JFB)] \@@input texdimens.tex\relax \endinput \ No newline at end of file diff --git a/Master/texmf-dist/tex/generic/texdimens/texdimens.tex b/Master/texmf-dist/tex/generic/texdimens/texdimens.tex index bc4acf26485..61086d138dd 100644 --- a/Master/texmf-dist/tex/generic/texdimens/texdimens.tex +++ b/Master/texmf-dist/tex/generic/texdimens/texdimens.tex @@ -1,6 +1,6 @@ % This is file texdimens.tex, part of texdimens package, which % is distributed under the LPPL 1.3c. Copyright (c) 2021 Jean-François Burnol -% 2021/11/04 v0.99a +% 2021/11/04 v0.99d \edef\texdimensendinput{\endlinechar\the\endlinechar% \catcode`\noexpand _=\the\catcode`\_% \catcode`\noexpand @=\the\catcode`\@\relax\noexpand\endinput}% @@ -393,28 +393,46 @@ % are not attainable as D uu, but the formula % N=round((2T+1)*32768/f) % will give a suitable decimal D via \the\dimexpr N sp\relax. +% (if T=0, we get N=0 as 32768/f<0.5) % This D will let TeX convert D uu into T sp, if the dimension % is attainable else it will be a closest match % either from above or below (not necessarily nearest overall). % +% If f/65536=1, attention that above formula would give N=1 for +% T=0 (was bug #4). +% % If f/65536<1, all dimensions Tsp are attainable as D uu. Indeed % D uu is parsed by TeX via N=round(D*65536), then T=trunc(N*phi), % with phi=f/65536. Starting from T we need to find an N such that % T/phi <= N< (T+1)/phi. We first consider v=(T+0.5)/phi. As its -% distance to the extremities is 0.5/phi>0.5, its rounding M +% distance to the extremities is 0.5/phi>0.5,(*) its rounding M % to an integer verifies automatically T/phi < M < (T+1)/phi, so % is a candidate. The TeX core conversion of Msp to a Dpt with % D a decimal of at most 5 fractional digits will provide a D % such that indeed M=round(D*65536). % +% (*) attention that this fails if phi=1, we definitely can not +% use the N=round((2T+1)*32768/f) formula for f=65536, it gives +% N=T+1 in place of N=T... It is funny the formula works for all +% f apart from f=65536... +% +% Attention that if T=0, the M=round(0.5/phi) will be at least 1, +% so the produced decimal D will not be 0.0, although it will +% be true that D \dimexpr f sp\relax produces the zero dimension, +% the above analysis being correct even for T=0. +% % Implementation % ============== % % \texdimenwithunit{dim1}{dim2}. dim2>0 assumed. -% We first get f from dim2 and branch according to whether f>=65536 or -% f<65536. We will also need to check the sign of T (dim1=T sp). +% We first get f from dim2 and branch according to whether f>65536, +% f=65536 or f<65536. +% We will also need to check the sign of T (dim1=T sp). % We then compute in both branches round((2T+1)*32768/f), but % in an indirect way in the f<65536 branch to avoid overflow. +% We will need also to intercept T=0 to avoid producing a non +% pleasing positive D in that case (still correct for f<65536; +% this is issue #3). % % In the f<65536 branch we first do the Euclidean division % 2T+1 = k*2*f + R with 0<=R<2f. The k is obtained as round((2T+1-f)/(2f)) @@ -431,22 +449,36 @@ % k.ddddd with k as obtained earlier. This procedure has no possible % arithmetic overflow. % -% #2 is assumed positive. +% #2 is assumed positive. The case #2=1pt=65536sp is special, and +% must be filtered out (issues #4, #6). % pre-multiplication of #1 by 2 here \def\texdimenwithunit#1#2{\expandafter\texdimenwithunit_ \the\numexpr\dimexpr#2\expandafter;\the\numexpr2*\dimexpr#1;}% -\def\texdimenwithunit_#1;#2{\ifnum#1<\p@ - \expandafter\texdimenwithunit_B\else\expandafter\texdimenwithunit_A\fi - #2#1;% +\let\texdimenorthat\texdimenfirstofone +\def\texdimendothis#1#2\texdimenorthat#3{\fi#1}% +\def\texdimenwithunit_#1;#2{% + \ifnum#1=\p@\texdimendothis\texdimenwithunit_p@\fi + \ifnum#1>\p@\texdimendothis\texdimenwithunit_A\fi + \texdimenorthat\texdimenwithunit_B#2#1;% }% -% unit>=1pt, handle this as for bp +% we premultiplied the first argument by 2... must be undone now! +% and we must avoid overflow. Very underoptimal, but user is not +% supposed to do something as silly as actually using this unit=1pt case! +\def\texdimenwithunit_p@#1#2;#3;{\expandafter\texdimenstrippt\the\dimexpr\numexpr#1#3/2sp\relax}% +% unit>1pt, handle this as for bp. Attention it would be wrong for unit=1pt! \def\texdimenwithunit_A#1#2;#3;{\expandafter\texdimenstrippt \the\dimexpr\numexpr(#1#3+\if-#1-\fi1)*32768/#2sp\relax }% -% unit<1pt +% unit<1pt. Attention it would be wrong for unit=1pt! % if dim1<0, simply negate result for dim1>0 as it can not possibly be 0.0 % Indeed (2T+1)*32768/f will be at least 3*32768/f so its rounding at least 2. -\def\texdimenwithunit_B#1{\if-#1\expandafter\texdimenwithunit_Bneg\fi\texdimenwithunit_Ba#1}% +% Add a check for dim1=0 to fix issue #3 +\def\texdimenzerominusfork #10-#2#3\krof {#2}% +\def\texdimenwithunit_B#1{\texdimenzerominusfork + #1-\texdimenwithunit_Bzero + 0#1\texdimenwithunit_Bneg + 0-\texdimenwithunit_Ba + \krof#1}% \def\texdimenwithunit_Ba#1#2;#3;{\expandafter\texdimenwithunit_Bb\the\numexpr#1#3+1;#2;}% \def\texdimenwithunit_Bb#1;#2;{\expandafter\texdimenwithunit_Bc\the\numexpr(#1-#2)/(2*#2);#1;#2;}% % I was hesitating between leaving k in the stream (breaking f-expandability) @@ -455,13 +487,13 @@ % recycling strippt here with no need of another utility. % % This means (see the nota bene above) that we could apply this procedure -% also for f>=65536, because at worst we will get a \the\numexprk+1.0, which +% also for f>65536, because at worst we will get a \the\numexprk+1.0, which % gives the correct result. I tested and found about 39% longer execution time % if dim2>1pt does same calculations as for dim2<1pt, and at the same time % dim2<1pt was improved about 11% from skipping the conditional \def\texdimenwithunit_Bc#1;#2;#3;{\the\numexpr#1+\expandafter\texdimenstrippt \the\dimexpr\numexpr(#2-#1*2*#3)*32768/#3sp\relax}% -% Here, definitely not caring about f-expandability -\def\texdimenwithunit_Bneg\texdimenwithunit_Ba-#1;#2;% - {-\expandafter\texdimenwithunit_Bb\the\numexpr#2+1;#1;}% +% Here, definitely not caring about f-expandability. Or efficiency. +\def\texdimenwithunit_Bneg-{-\texdimenwithunit_Ba{}}% +\def\texdimenwithunit_Bzero#1;#2;{0.0}% \texdimensendinput -- cgit v1.2.3