[XeTeX] XeTeX, fontspec, OTF, and fontdimens

mskala at ansuz.sooke.bc.ca mskala at ansuz.sooke.bc.ca
Sun Feb 20 02:12:30 CET 2011


On Sun, 20 Feb 2011, Peter Dyballa wrote:
> My suggestion was not that you change the font for productive work but that
> you (and we) can test your theory of the different behaviour of TT and OT
> fonts. Which I could not find.

I see.  I'm not claiming a difference between TrueType and OpenType, but
between OpenType and traditional TeX.  TrueType isn't in the picture at
font - what I thought you were saying was so inappropriate it was hard to
take seriously.

I tried it just now with a couple of TrueType fonts and my results are the
same as yours on TrueType fonts.  The spacing gets reset to XeTeX's
default, which is stretchable, on every font size change.

However, if I use XeTeX's default Computer Modern typewriter font by means
of the \ttfamily macro, without loading fontspec, then the spaces scale
and are not stretchable by default; it's resetting the fontdimens on every
size change but that's not a problem because the defaults are correct.
Loading fontspec causes it to use Latin Modern and we're back where we
started.

These results make it look like what's going on is related to fontspec.  I
think the issue is the implementation of WordSpace.  WordSpace is
documented as setting multipliers which are applied to XeTeX's defaults.
Since XeTeX resets all the fontdimens to values that may be wrong every
time the size changes, fontspec must apply the changes made by WordSpace
on every size change - even though size changes can happen without a new
invocation of the \fontspec macro.  So fontspec must remember the
WordSpace settings and re-apply them, and it does.

The bug is that what WordSpace remembers is the actual dimensions, not the
multipliers.  So we have a scenario like this (assuming for simplicity
that the space width is half the design size), with WordSpace:

* I invoke \fontspec[WordSpace={1,0,0}] and load a font at 12 point.
* XeTeX sets the fontdimens to 6pt,6pt,6pt
* fontspec sets them to 6pt,0pt,0pt; fine.  But it remembers 6pt,0pt,0pt,
  not the multipliers 1,0,0.
* Later the \Large command changes the font size to 17 points.
* XeTeX sets the fontdimens to 8.5pt,8.5pt,8.5pt
* fontspec applies the remembered WordSpace settings, which are
  6pt,0pt,0pt.
* Now the result is wrong - the space is non-stretchable, but has the
  wrong basic width.

If I don't use WordSpace but set the fontdimens manually, something like
this happens:

* I invoke \fontspec to load the 12-point font.
* XeTeX sets the fontdimens to 6pt,6pt,6pt
* I set them by some other means to 6pt,0pt,0pt.
* Later the \Large command changes the font size to 17 points.
* XeTeX sets the fontdimens to 8.5pt,8.5pt,8.5pt
* Now the result is wrong - the space is the right basic width, but it's
  stretchable.
* I can fix it by manually setting the fontdimens again, but must do so on
  every size change, which is tricky because some (indeed, almost all)
  size changes are done by class files instead of by me directly.  The
  everysel package makes this process less painful.

The correct behaviour would be:

* I invoke \fontspec to load the 12-point font.
* Ideally the fact that the font is monospace is auto-detected, but if
  that is difficult or impossible, it would be reasonable that I set some
  option to let the system know that spaces should not stretch.
* Either XeTeX or fontspec sets the fontdimens to 6pt,0pt,0pt.
* Later the \Large command changes the font size to 17 points.
* Either XeTeX or fontspec sets the fontdimens to 8.5pt,0pt,0pt.

XeTeX behaves that way with Computer Modern Typewriter, which is a
traditional TeX font, because it is able to detect from the TeX metrics
that Computer Modern Typewriter is monospace.  I don't have an instance of
fontspec behaving that way at all.  In order for it to work, either XeTeX
or fontspec would have to know that it's a monospace font; and in the
absence of a TFM file it looks to me like WordSpace={1,0,0} would be a
reasonable way for it to know.  But in that case, WordSpace would have to
remember its settings as multipliers and do the multiplication each time
it applies; not its current behaviour of doing the multiplication once and
then remembering the point sizes.

> A fix is desirable – have you tested zhspacing
> (http://code.google.com/p/zhspacing/)? Maybe it has a solution for you...

The "everysel" package seems to be the best fit so far.  zhspacing may be
useful for other reasons, but it seems its main purpose is for controlling
the spacing within runs of CJK text, where interword spaces aren't used
anyway.  The issue I'm facing involves interword spaces in segments of
English in a mixed document.  I also couldn't get zhspacing to load at
first attempt - it seems to require a Chinese font called SimSun which I
don't have - but it may be possible to configure it to use something else.
-- 
Matthew Skala
mskala at ansuz.sooke.bc.ca                 People before principles.
http://ansuz.sooke.bc.ca/


More information about the XeTeX mailing list