On this page:
3.2.1 Wildcards
3.2.2 References
3.2.3 Variables
3.2.4 Wildcarding References
3.2.5 Internal Preferences
3.2.6 Post Script Fonts

3.2 Font Configuration

This chapter describes how to set up face mappings for screen and PostScript fonts via preferences (see Preferences). The font-configuration system is overkill; it was designed to handle especially complex X font mappings before fontconfig/Xft solved the problem.

An implementor for a GRacket-based program may find it easier to use the set-screen-name and set-post-script-name methods provided by the-font-name-directory. As a user of a GRacket-based program, preferences provide a mechanism for setting default mappings.

Whether a programmer or a user, see font-name-directory<%> for an overview of the font mapping system.

To find a font name for a family, GRacket looks for a preference name by concatenating MrEd:, a ‹dest›, a ‹type›, a ‹weight›, and a ‹style›, where

Furthermore, any of the latter three parts can be wildcarded with _, as described below. The concatenated string is converted to a symbol (preserving case), and the associated preference value must be a string.

The value of the preference is parsed as described in font-name-directory<%> for parsing face names, except that the string can contain references and other tricks described below.

3.2.1 Wildcards

Building items names by concatenating ‹dest›, ‹type›, ‹weight›, and ‹style› can create a large number of preference entries, and the ‹weight› and ‹style› parts are useful only for X screen fonts. To avoid an explosion of preferences, GRacket finds preferences via a wildcarding search.

The ‹type›, ‹weight›, and ‹style› parts of a preference name can be wildcarded by using _. Thus, to set the default font in X for all types, weights, and styles, use the following preference entry:

  (MrEd:Screen___ "+-*-*-medium-r-normal-*-*-%d-*-*-*-*-*-*")

Wildcarded preference entries are used only when un-wildcarded values cannot be found. If two preference names both match for some search, then the one with the “earliest” (i.e., closest to the beginning of the preference name) non-wildcarded part will prevail.

The default GRacket preferences for Windows uses wildcarding to specify the basic font mapping, as if written as:

  (MrEd:ScreenSystem__ "MS Sans Serif")
  (MrEd:ScreenRoman__ "Times New Roman")
  (MrEd:ScreenDecorative__ "Modern")
  ....

Wildcarding in the preference name naturally leads to references, variables, and wildcarding references in the preference value. These features are described in the following few sections.

3.2.2 References

Suppose we define the mapping for variants of "Default", and then we want "Roman" to use this setting, too. We could copy the preference entry, as in the following example:

  (MrEd:ScreenDefault__ "+-*-*-medium-r-normal-*-*-%d-*-*-*-*-*-*")
  (MrEd:ScreenRoman__ "+-*-*-medium-r-normal-*-*-%d-*-*-*-*-*-*")

but the GRacket font-reading system provides a better syntax for referencing another preference entry. When a preference value contains ${x}, then the ${x} fragment is replaced by the preference value of x. Thus, the above can be re-written:

  (MrEd:ScreenDefault__ "+-*-*-medium-r-normal-*-*-%d-*-*-*-*-*-*")
  (MrEd:ScreenRoman__ "${ScreenDefault__}")

A mini-language of ${x} is used within the string (instead of an S-expression format) for historical reasons.

3.2.3 Variables

Variables can be used with referencing to configure default values based on the weight and style that is needed. When a preference value contains $[weight], then $[weight] is replaced with a string for the desired font weight. Similarly, $[style] is replaced with the desired style. Variable expressions can be embedded within referencing expressions, as in the following example:

  (MrEd:ScreenDefault__
   "+-*-*-${Def$[weight]}-r-normal-*-*-%d-*-*-*-*-*-*")
  (MrEd:DefMedium "medium")
  (MrEd:DefBold "bold")
  (MrEd:DefLight "medium")

Now, when the 'GRacket:ScreenDefault__ preference value is used for different weights, it will return different values; the ${Def$[weight]} expression will turn into ${DefMedium} for a medium-weight lookup, or ${DefBold} for a bold-weight lookup. These references will in turn give either medium or bold.

3.2.4 Wildcarding References

Consider the following preference configuration:

  (MrEd:ScreenDefault__ "+-*-*-medium-r-normal-*-*-%d-*-*-*-*-*-*")
  (MrEd:ScreenDefaultBold_ "+-*-*-bold-r-normal-*-*-%d-*-*-*-*-*-*")
  (MrEd:ScreenRoman__ "${ScreenDefault__}")

The effect of this statement is probably not what was intended; when a bold version of the Roman font is needed, the 'GRacket:ScreenRoman__ preference value references the 'GRacket:ScreenDefault__ preference value, which does not specify a bold font. We could try to remedy the situation as follows:

  (MrEd:ScreenDefault__ "+-*-*-medium-r-normal-*-*-%d-*-*-*-*-*-*")
  (MrEd:ScreenDefaultBold_ "+-*-*-bold-r-normal-*-*-%d-*-*-*-*-*-*")
  (MrEd:ScreenRoman__ "${ScreenDefault$[weight]_}")

but this does not work either. It works fine for bold Roman, now, but medium Roman will cause a reference to the 'GRacket:ScreenDefaultMedium_ preference, which doesn’t exist. The problem is that our reference does not use wildcarding like the original medium Roman lookup did.

Wildcarding can be specified in a reference by separating each wildcardable field with a comma. The following preference specification does what we want:

  (MrEd:ScreenDefault__ "+-*-*-medium-r-normal-*-*-%d-*-*-*-*-*-*")
  (MrEd:ScreenDefaultBold_ "+-*-*-bold-r-normal-*-*-%d-*-*-*-*-*-*")
  (MrEd:ScreenRoman__ "${ScreenDefault,$[weight],_}")

Since $[weight] is between commas, it can be wildcarded if no name exactly matching ScreenDefault$[weight]_ is found. In this case ScreenDefault and _ can also be wildcarded, but this will have no effect.

The wildcarding used in references need not reflect the wildcarding GRacket initial uses for finding fonts. In other words, a number of comma-separated selects can appear between the curly braces.

3.2.5 Internal Preferences

The initial font setup is built into GRacket through a built-in preference table. The table is shown at the end of this section. When font information is computed, it is almost as if this table were installed into your preferences file; the difference is that preference specifications in your file override specifications in the built-in table, even when the wildcarding of your preference provides a weaker match.

When no information is available for mapping a face name to a font, GRacket falls back to the system described in font-name-directory<%>. (Since a mapping is built into GRacket for every family, information is always available for the default font of a family.)

Internal preferences for all platforms:

  (MrEd:PostScriptMediumStraight "")
  (MrEd:PostScriptMediumItalic "-Oblique")
  (MrEd:PostScriptMediumSlant "-Oblique")
  (MrEd:PostScriptLightStraight "")
  (MrEd:PostScriptLightItalic "-Oblique")
  (MrEd:PostScriptLightSlant "-Oblique")
  (MrEd:PostScriptBoldStraight "-Bold")
  (MrEd:PostScriptBoldItalic "-BoldOblique")
  (MrEd:PostScriptBoldSlant "-BoldOblique")
  
  (MrEd:PostScript___ "${PostScript$[family],$[weight],$[style]}")
  
  (MrEd:PostScriptSystem__ "${PostScriptTimes,$[weight],$[style]}")
  (MrEd:PostScriptRoman__ "${PostScriptTimes,$[weight],$[style]}")
  (MrEd:PostScriptDecorative__ "${PostScriptTimes,$[weight],$[style]}")
  (MrEd:PostScriptScript__ "ZapfChancery-MediumItalic")
  
  (MrEd:PostScriptTimesMedium "")
  (MrEd:PostScriptTimesLight "")
  (MrEd:PostScriptTimesBold "Bold")
  
  (MrEd:PostScriptTimes__ "Times${PostScript$[weight]$[style]}")
  (MrEd:PostScriptTimesMediumStraight "Times-Roman")
  (MrEd:PostScriptTimesLightStraight "Times-Roman")
  (MrEd:PostScriptTimes_Slant
   "Times-${PostScriptTimes$[weight]}Italic")
  (MrEd:PostScriptTimes_Italic
   "Times-${PostScriptTimes$[weight]}Italic")
  
  (MrEd:PostScriptDefault__ "Helvetica${PostScript$[weight]$[style]}")
  (MrEd:PostScriptSwiss__ "Helvetica${PostScript$[weight]$[style]}")
  (MrEd:PostScriptModern__ "Courier${PostScript$[weight]$[style]}")
  (MrEd:PostScriptSymbol__ "Symbol")

Internal preferences for X with fontconfig/Xft/RENDER only:

  (MrEd:ScreenSystem__ " Sans")
  (MrEd:ScreenDefault__ " Sans")
  (MrEd:ScreenRoman__ " Serif")
  (MrEd:ScreenDecorative__ " Nimbus Sans L")
  (MrEd:ScreenModern__ " Monospace")
  (MrEd:ScreenSwiss__ " Nimbus Sans L")
  (MrEd:ScreenScript__ " URW Chancery L")
  (MrEd:ScreenSymbolBase " Standard Symbols L,Nimbus Sans L")

Internal preferences for X only (except those overridden for fontconfig/Xft/RENDER):

  (MrEd:ScreenMedium "medium")
  (MrEd:ScreenBold "bold")
  (MrEd:ScreenLight "light")
  (MrEd:ScreenStraight "r")
  (MrEd:ScreenItalic "i")
  (MrEd:ScreenSlant "o")
  
  (MrEd:ScreenSystemBase "*-lucida")
  (MrEd:ScreenDefaultBase "*-lucida")
  (MrEd:ScreenRomanBase "*-times")
  (MrEd:ScreenDecorativeBase "*-helvetica")
  (MrEd:ScreenModernBase "*-courier")
  (MrEd:ScreenSwissBase "*-lucida")
  (MrEd:ScreenScriptBase "*-zapfchancery")
  (MrEd:ScreenSymbolBase "*-symbol")
  
  (MrEd:ScreenStdSuffix
   "-${Screen$[weight]}-${Screen$[style]}-normal-*-*-%d-*-*-*-*-*-*")
  
  (MrEd:ScreenSystem__ "+-${ScreenSystemBase}${ScreenStdSuffix}")
  (MrEd:ScreenDefault__ "+-${ScreenDefaultBase}${ScreenStdSuffix}")
  (MrEd:ScreenRoman__ "+-${ScreenRomanBase}${ScreenStdSuffix}")
  (MrEd:ScreenDecorative__
   "+-${ScreenDecorativeBase}${ScreenStdSuffix}")
  (MrEd:ScreenModern__ "+-${ScreenModernBase}${ScreenStdSuffix}")
  (MrEd:ScreenSwiss__ "+-${ScreenSwissBase}${ScreenStdSuffix}")
  (MrEd:ScreenScript__ "+-${ScreenScriptBase}${ScreenStdSuffix}")
  (MrEd:ScreenSymbol__
   "+-${ScreenSymbolBase}-medium-r-normal-*-*-%d-*-*-*-*-*-*")

Internal preferences for Windows only:

  (MrEd:ScreenSystem__ "MS Sans Serif")
  (MrEd:ScreenDefault__ "MS Sans Serif")
  (MrEd:ScreenRoman__ "Times New Roman")
  (MrEd:ScreenDecorative__ "Arial")
  (MrEd:ScreenModern__ "Courier New")
  (MrEd:ScreenSwiss__ "Arial")
  (MrEd:ScreenScript__ "Arial")
  (MrEd:ScreenSymbol__ "Symbol")

Internal preferences for Mac OS X only:

  (MrEd:ScreenDefault__ "Lucida Grande")
  (MrEd:ScreenSystem__ "Lucida Grande")
  (MrEd:ScreenRoman__ "Times")
  (MrEd:ScreenDecorative__ "Arial")
  (MrEd:ScreenModern__ "Courier New")
  (MrEd:ScreenSwiss__ "Helvetica")
  (MrEd:ScreenScript__ "Apple Chancery")
  (MrEd:ScreenSymbol__ "Symbol")

3.2.6 PostScript Fonts

To generate PostScript output, GRacket must be able to find an Adobe Font Metrics (AFM) file corresponding to the PostScript font. An AFM file typically uses the suffix ".afm", and several AFM files are distributed with GRacket in the "afm" collection.

GRacket finds an AFM file by adding a ".afm" suffix to the PostScript name of the font, and checking all directories specified by the current-ps-afm-file-paths parameter. The initial value of this parameter is determined by the PLTAFMPATHS environment variable; the environment variable’s setting is parsed with path-list-string->path-list using (list (collection-path "afm")) as the default list.

Depending on whether the font is CID-based (typically for the Chinese, Japanese, Korean, and Vietnamese language families, and as indicated in the AFM file), GRacket must find additional files:

When drawing or measuring text using a particular PostScript font, if the font does not contain a glyph for a character (or if a relevant AFM file cannot be found for the font), then GRacket attempts to substitute another PostScript font. A substitute font is selected by checking all ".afm" files in the directories specified by current-ps-afm-file-paths (in order), and choosing the first discovered match.