summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic/texdimens/texdimens.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/generic/texdimens/texdimens.tex')
-rw-r--r--Master/texmf-dist/tex/generic/texdimens/texdimens.tex62
1 files changed, 47 insertions, 15 deletions
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