5.8. Text   

5.8.1. What are Fonts   

There is often confusion between fonts and typefaces. A typeface is a particular style or character set, such as Geneva, Helvetia, Times or Symbol. Note typefaces are often owned by companies and thus subject to copyright. Because of this you sometimes see similar typefaces under slightly different names, eg Times and Helvetia look-alikes might be called Tymes and Helv, or Swiss and Dutch.

A font is all the characters in the typeface in a particular size (eg 12 point) and style (eg. bold, italic). In practise, the word font is often used where the term typeface would be more correct.

In the world of X, fonts have the following characteristics.


Typeface- the family that the font belongs to, eg Geneva
Weight - normally bold or medium.
Slant - italic,oblique,roman,reverse italic,reverse oblique or other.
Width - condensed, semi-condensed, narrow, normal, or double-wide.
Size - in the printing industry size is sometimes measured in
points (1/72 of an inch). This text is 10 point.
In X fonts are often measured in tenths of a point,
this allows a good degree of flexibility whilst avoiding
floating point numbers.
Spacing - normally proportional or monospaced.

Fonts are frequently named to describe their characteristics. Eg the font
  -adobe-courier-bold-r-normal-11-80-100-100-m-60-iso8559-1

is an example of how fonts are often named in X. The information
given is


font company adobe
typeface courier
weight bold
slant medium
width normal
pixel size 11 (11 pixels. A zero would indicate a scalable font)
point size 80 (indicates 8 point font).
dpi in X dirn 100
dpi in Y dirn 100
spacing m (monospaced)
average width 60 (6 pixels)
character set iso8859-1 (a superset of ASCII)

Be warned that the dot per inch (dpi) figures often cannot be relied upon because you can use different size monitors with the one graphics card.

To get a listing of available fonts you can use the xlsfonts program. To see a sample of the fonts, use the xfd program (xfd -fn fontname).

5.8.1.1. Loading Fonts   

Before we can use a font it must be loaded. Your application requests that a font be loaded into the X server. When you are finished with a font, your application should inform the X server so that it can be unloaded. Note that loaded fonts may be shared by several programs. Your X server will manage this, but it does mean that there are advantages to sticking to commonly used fonts.

If you try to have too many fonts loaded at the one time, it is possible that the X server will run out of resources (eg RAM). Also be warned that the fonts available are to an extent implementation dependant.

The recommended way to load a font is to use the XLoadQueryFont function. This will return a pointer to a XFontStruct object if successful, or a null pointer if unsuccessful. It is possible to just call XLoadFont, but if the call fails it generates an X error rather than letting you handle the problem gracefully (like by asking for another font).

To load a font we would then use a segment of code similar to that below:

     #include <X11/Xlib.h>

Display display;
XFontStruct * font_struct;
char * fontname = times-bold.24;
font_struct = XLoadQueryFont( display, fontname );
if ( font_struct == ( XFontStruct *) NULL)
/* An error occurred and the font wasn't loaded.
Typically, we would then try to load another font. */

The fields of interest in the XFontStruct object are fid (font id), ascent and descent. We will ignore the other fields in this course, though the diligent student may wish to check the definition in Xlib.h.

Ascent and descent allow us to calculate the height of the font. To calculate the width of a string use the XTextWidth function, shown below. width = XTextWidth( font_struct, string, string_length );

5.8.2. Displaying Text   

Having loaded our font, we now wish to use it. Before doing so, though, it is necessary to load it into our graphics context using the following code.

     #include <X11/Xlib.h>

Display * display;
XFontStruct * font_struct;
GC gc;
XSetFont( display, gc, font_struct->fid );

There are two functions that we can use for displaying text, XDrawString and XDrawImageString. XDrawString just paints the foreground pixels in the characters. XDrawImageString paints in both the foreground and the background pixels.

The syntax of these functions is shown below.

     #include <X11/Xlib.h>

Display * display;
Drawable window_id;
GC gc;
int x, y;
char * string;
int str_size;
str_size = strlen( string );
XDrawImageString( display, window_id, gc, x, y. string, str_size);
XDrawString( display, window_id, gc, x, y. string, str_size);

The x, y position give the pixel coordinates of the start of the base line. There will be ascenders (eg. body of O) and descenders (eg. tail of g) from this line. Note that the string size should be the correct length of your string, not just the declared size of the character array. When you have finished with the font it should be released using the XFreeFont function.

     Display        * display;

XFontStruct * font_struct;
XFreeFont( display, font_struct );