[tex-k] dvitomp rounding flaw
Hartmut Henkel
hartmut_henkel at gmx.de
Sun Mar 7 22:38:57 CET 2004
There is an implementation flaw with the zround() function used by
dvitomp: Characters with width zero get a rounded width of -1 sp,
negative! This might be disturbing, e. g. when using the "Special Fonts"
of Boguslaw Jackowski and Krzysztof Leszczynski.
E. g. if you have a font where some character, say char 254, is given
width 0 in the .vpl file, then try the following mpost code:
% file xx.mp
verbatimtex \font\aaa pplr8t at 20pt etex
beginfig(1)
label (btex \aaa A%
\char254\char254\char254\char254\char254\char254\char254\char254%
\char254\char254\char254\char254\char254\char254\char254\char254%
\char254\char254\char254\char254\char254\char254\char254\char254%
\char254\char254\char254\char254\char254\char254\char254\char254%
\char254\char254\char254\char254\char254\char254\char254\char254%
\char254\char254\char254\char254\char254\char254\char254\char254%
B etex,(100,100)); endfig; end;
Do:
$ mpto xx.mp > xx.tex ; tex xx.tex ; dvitomp xx.dvi
The file xx.mpx shows a line with a separate letter "B",
_s("B",_n1,2.00000,15.5009,0.0000);
where the value 15.5009 changes depending on how many lines \char254...
you comment out in the file xx.mp.
John Hobby writes in dvitomp.web: "...Nevertheless, the width compution
will be precise if reals have at least 46-bit mantissas and
|round(x-.5)| is equivalent to $\lfloor x\rfloor$. It may be a good idea
to modify this computation if these conditions are not met. @^system
dependencies@>"
Currently this is not given with function zround() in file
web2c/lib/zround.c, as zround(0 - 0.5) = -1 instead of 0. This function
is used by the following dvitomp.web lines:
@<Width of character |c| in font |f|@>=
round(dvi_scale*font_scaled_size[f]*char_width(f)(c)-0.5)
@ @<Width of character |p| in font |cur_font|@>=
round(dvi_scale*font_scaled_size[cur_font]*char_width(cur_font)(p)-0.5)
For zero width characters this gives (int)(0 - 0.5 - 0.5) = -1. The
problem seems to be solved by using a custom zfloor() function:
integer zfloor P1C(double, r)
{
integer i, j;
if (r >= 0)
i = (integer) r;
else {
j = (integer) r;
i = (integer) (r + 1 - j) - 1 + j;
}
return i;
}
This does 1 -> 1; 0.5 -> 0 ; 0 -> 0 ; -0.5 -> -1 ; -1 -> -1; -1.5 -> -2.
I put this function into file zround.c, added (always near corresponding
zround or round lines)
#define floor(x) zfloor ((double) (x))
and
extern integer zfloor P1H(double);
to cpascal.h, added
@define function floor ();
to web2c/web2c/common.defines
and changed the lines from dvitomp.web to
@<Width of character |c| in font |f|@>=
floor(dvi_scale*font_scaled_size[f]*char_width(f)(c))
@ @<Width of character |p| in font |cur_font|@>=
floor(dvi_scale*font_scaled_size[cur_font]*char_width(cur_font)(p))
This should be done by the dvitomp.ch file. With this patch one gets
_s("AB",_n1,2.00000,0.0000,0.0000);
in the xx.mpx file; there is now nothing left between A and B, so they
are typeset together, independent from the amount of \char254 letters
inbetween.
Regards, Hartmut
------------------------------------------------------------------------
Hartmut Henkel, Oftersheim, Germany
------------------------------------------------------------------------
More information about the tex-k
mailing list