Programming in XPCE/Prolog: Section 10.9

## 10.9 Specifying fonts

XPCE's font specification is a two-stage process. In the first stage, XPCE physical fonts are mapped to fonts of the underlying windowing system. In this stage, fonts are identified by their family, style and size. For example

    font(screen, roman, 13)

Refers to a fixed-width font designed for use on the screen that has normal weight, not slanted and 13-pixels high characters.

In the second stage, logical font-names are mapped to their physical implementation. At this level, fonts are identified by a single name from an extensible, but preferably small set.

See section B.5 for a description of Windows specific font issues.

### 10.9.1 Physical fonts

The default physical font set is built when the first font object is opened (i.e. its window counterpart is located and made available to the text-drawing functions). This set is created from class-variables on the display object. The first class-variable is display.font_families, which defines a chain with names of the font-families. The default value is:11See section 8 for the default syntax.

    display.font_families: \
            [ screen_fonts, \
              courier_fonts, \
              helvetica_fonts, \
              times_fonts, \
              symbol_fonts
            ]

Each of these names refers to the name of another resource of class display, enumerating the members of this font family. The default value can be examined using the online manual. Below is the default value for the `screen_fonts` font-set for X11:

    display.screen_fonts: \
            [ font(screen, roman, 10, "6x10"), \
              font(screen, roman, 12, "6x12"), \
              font(screen, roman, 13, "8x13"), \
              font(screen, roman, 14, "7x14"), \
              font(screen, roman, 15, "9x15"), \
              font(screen, bold, 13, "8x13bold"), \
              font(screen, bold, 14, "7x14bold"), \
              font(screen, bold, 15, "9x15bold") \
            ]

The set of predefined physical fonts can be examined using the FontViewer demo application accessible through the online manual tools.

#### 10.9.1.1 Defining additional fonts

If an application needs additional fonts, such fonts can be declared using directives. The fourth initialisation argument of class font determines the window-system font that will be mapped. The syntax for this argument depends on the window-system used. For this Unix/X11 version it is a string consisting of 15 `-' separated fields. A font can be searched using xfontsel(1) or the much better GNOME-project gfontsel(1).

For example, the 14-points `courier new' TrueType font can be registered using:

    :- initialization
       new(_, font(courier, roman, 14,
                   '-winfonts-courier new-medium-r-normal-*-*-140-*-*-m-*-iso8859-1')).

This specification has various drawbacks. For example, another library or application loaded on top of the same XPCE process may be using the symbol,roman,14 specification, but bound to another window-system font. A user may try to run your application on an environment that does not have this font. Part of these problems can be eliminated by binding the font to a logical font name. See also section 10.9.2.

    :- initialization
       send(@display, font_alias,
            adobesymbol,
            font(symbol, roman, 14,
                 '-*-symbol-*-*-*-*-14-*-*-*-*-*-adobe-*')).

The application will refer to this font using the font-alias. user has other preferences or the font is not available, the user may specify the font using the display.user_fonts class-variable described in section 10.9.2.

### 10.9.2 Logical fonts

.

It is not wise let your application code speak about physical fonts as the user or interface guidelines may prefer using a different font-palette. For this reason the display defines a mapping between logical font names and physical fonts. Applications are encouraged to use logical font names as much as possible and leave the assignment to physical fonts to the users preferences. XPCE predefines the following logical font-names. The value gives the default assignment for these fonts.

`normal`font(helvetica, roman, 12)
  The default font. Normally a proportional roman font. Should be easy to read.
`bold`font(helvetica, bold, 12)
  Bold version of the normal font.
`italic`font(helvetica, oblique, 12)
  Slanted version of the normal font. Note that italic fonts should not be used for long text as italics is generally not easy to read on most displays.
`small`font(helvetica, roman, 10)
  Small version of the normal font. To be used in notes, subscripts, etc. May not be so easy to read, so avoid using it for long texts.
`large`font(helvetica, roman, 14)
  Slightly larger version of the normal font.
`boldlarge`font(helvetica, bold, 14)
  Bold version of large.
`huge`font(helvetica, roman, 18)
  Even larger font. To be used for titles, etc.
`boldhuge`font(helvetica, bold, 18)
  Bold version of huge.
`fixed`font(screen, roman, 13)
  Terminal font. To be used for code fragments, code editors, etc. Should be easy to read.
`tt`font(screen, roman, 13)
  Same as `fixed`.
`boldtt`font(screen, bold, 13)
  Bold terminal font.
`symbol`font(symbol, roman, 12)
  Symbol font using the adobe symbol-font encoding. This font provides many mathematical symbols.

The end-user of an XPCE application can define the class-variable display.user_fonts to overrule fonts. The example below re-binds the most commonly used fonts to be slightly larger and choose from the Times font family rather than the Helvetica fonts.

    display.user_fonts: \
            [ normal := font(times, roman, 14), \
              bold   := font(times, bold, 14), \
              italic := font(times, italic, 14) \
            ]

The mapping between logical font names and physical fonts is realised by the methods `display`<->`font_alias' additional font aliases may be loaded using `display`->`load_font_aliases'.

Class font's predefined conversion will translate names to font objects. This implies that for any method expecting a font object the programmer can specify the font-name instead. In those (rare) cases where a font needs to be passed, but the type-specification does not require this, the conversion must be done explicitly. The preferred way to make the conversion is using the font type object:

            ...,
            get(type(font), check, bold, BoldFont),
            ...,