3

As explained in the TeXbook, p. 433, each TeX font has at least 7 parameters: slant, space, stretch, shrink, x-height, quad width, extra space.

Is there some way to change these parameters when loading a font in XeLaTeX with \setmainfont?

I know that TrueType/OpenType fonts have no TFM file anymore, but when I did a

\the\fontdimen1\font
\the\fontdimen2\font
\the\fontdimen3\font
\the\fontdimen4\font

I did get some reasonable values for the current font (an OpenType font). So if these values exist in the system, this means that they are calculated at some point from the data stored in the font, and maybe there is some way to change them when loading the font? I'm particularly interested in playing around with stretch and shrink, to optimize the document's appearance.

2
  • 1
    WordSpace can be used to set inter word space. – Ulrike Fischer Jan 5 at 23:02
  • while @UlrikeFischer's suggestions does indeed alter the fontdimens 2, 3, and 4, this fontspec interface only allows scaling them. To change the values directly, you could simply do this after loading the fonts, e.g. {\normalfont\fontdimen2\font=3pt} {\itshape\fontdimen2\font=2.5pt} (note that fontdimens are global). – Robert Jan 6 at 0:49
2

Most fontdimens are either not important for OpenType fonts or can be influenced using higher-level options.

Let's look at the 7 standard font dimensions:

  • 1 (slant) and 5 (x-height): Used for placing accents using the \accent primitive. This primitive isn't used for OpenType fonts, therefore the font dimensions aren't normally used. (The x-height additionally determines the length of 1ex, but you normally don't want to change that.)
  • 2-4 (interword space, stretch, shrink): Can be scaled using fontspec's WordSpace. E.g. setting Wordspace=2 doubles all three values, but you can also set e.g.WordSpace={1, 2, 0.5} to double the stretch, half the shrink and keep space the same.
  • 6 (quad width): Used for setting 1em. There is little reason to change this in most circumstances.
  • 7 (extra space): Can be scaled with PunctuationSpace=<factor>

Sometimes you might have special requirements where you want to adjust these \fontdimens in special ways. For these cases, you can use the undocumented FontAdjustment option to run some custom code whenever a low-level TeX font gets defined for the font (The argument gets appended to the last argument of \DeclareFontShape). Here you can rewrite fontdimens without worrying that you might have missed some sizes.

3
  • Thanks for the information. What I need is separate access to space, stretch and shrink, instead of changing them all together as you suggest with WordSpace=. My request may sound absurd, what where can I get documentation on the undocumented feature FontAdjustment? When you say "whenever a low-level TeX font gets defined for the font", do you mean that in these cases only the system will create a TFM file on the fly? Or do you mean I have to create a TFM file and the system will read it instead of getting metric information from the OpenType font? Or something else? – yannis Jan 6 at 11:58
  • @yannis Noone is creating any TFM files. Whenever a font is selected for the first time, the FontAdjustment is executed. (A "low-level TeX font" was referring to a individual font defined with the \font primitive instead of a NFSS font family) – Marcel Krüger Jan 6 at 12:43
  • As for most (arguably all) undocumented things, there is no documentation for FontAdjustment. (The source code calls it a "Secret hook into the font-adjustment code") But it ends up getting appended to the last argument to \DeclareFontShape, so if you want to know more about it, look for documentation about \DeclareFontShape. – Marcel Krüger Jan 6 at 12:54
1

It is possible to set the equivalent of most of those parameters. For example, the Scale= font option can change the height of a font. This will scale all the letters, not change the ratio of x-height to cap-height, but I have for instance used Scale= to fake small caps by scaling capitalized letters to the ratio of the x-height and the cap-height. You can also combine Scale= with FakeStretch= to scale the font by different horizontal and vertical values. (Note that the TeXbook parameter of x-height affects the positioning of accents, and does not scale the font.)

The equivalent I normally use for the stretch parameter in LaTeX 3 is \emergencystretch, which will reduce terrible hyphenation in difficult paragraphs, but not ruin good paragraphs. Another package that’s useful here, but doesn’t do exactly the same thing, is microtype. In LuaTeX (but not XeTeX), it enables font expansion.

Interword space can be set individually with the TeX \spaceskip command, or with the WordSpace= font option in fontspec. The triplet form of WordSpace sets the interword space, stretch and shrink at the same time.

The slant parameter in TeX, as you know, affects the placement of accents over italic and slanted letters. In an OpenType font, this should not need to change, as you will notmally be using combining accents. In the event you need to compose a base character with non-combining accent, you will probably set a skew character for the font, setting the default accent placement appropriately. You can still manually adjust accent placement with \skew, as I’ve occasionally had to do to fake a caron in a font with non-combining but not combining accents, or even create a poor man’s slanted font with FakeSlant=.

The default definition of \quad and \qquad in the LaTeX kernel is (as of the first source I looked up),

\def\quad{\hskip1em\relax}
\def\qquad{\hskip2em\relax}

You can change these values if you so choose. What the TeX parameter does is change the width of one em.

14
  • 2
    I think you can assume that Yannis knows a bit about fonts. Beside this: fontspec sets the standard fontdimens when loading a font. – Ulrike Fischer Jan 5 at 23:17
  • @UlrikeFischer Okay, I removed the paragraph that I think came across as condescending. – Davislor Jan 5 at 23:27
  • Thanks Ulrike! Yes I know about fonts (TFM, VF, OFM, OVF), but I was wondering if something can be done about the way XeTeX assigns values to the shrink, stretch, etc. parameters. And from your answer I deduce that WordSpacesets font parameter 2 (space). Shall I also assume that theer is no way to change the values of the other parameters (other than writing \fontdimen3\font=2pt\fontdimen4\font=1pt which will work for the current font, but has to be set explicitly for each font when using it? – yannis Jan 5 at 23:32
  • 1
    @Davislor, to my knowledge Scale= scales the font. This has nothing to do with the x-height of the font. x-height is the standard height of lowercase letters, it is independent of the font size (compare standard Computer Modern and Computer Modern Dunhill both at 10 points, they have different x-heights) – yannis Jan 5 at 23:42
  • 1
    @Davislor still, I find your answer more confusing than helpful TBH. (1) Both xetex and luatex still set and use TeX's fontdimens in the same way, even for Opentype fonts, and they can be changed in the same way. (2) Changing fontdimens doesn't change the appearance of the fonts (as your mention of Scale and FakeSlant would suggest) – Robert Jan 6 at 0:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.