[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