VMS DECwindows Guide to Xlib (Release 4) Programming: MIT C Binding


Previous Contents Index


Chapter 8
Writing Text

This chapter describes writing text using Xlib. The chapter includes the following topics:

VMS DECwindows provides a font compiler to enable programmers to convert ASCII files into binary form. For a guide to using the font compiler, see Appendix A.

8.1 Characters and Fonts

The smallest unit of text the server displays on a screen is a character. Pixels that form a character are enclosed within a bounding box that defines the number of pixels the server turns on or off to represent the character on the screen. For example, Figure 8-1 illustrates the bounding box that encloses the character y.

The server turns each pixel within the bounding box either on or off, depending on the character. Consequently, bounding box size affects performance. Larger bounding boxes require more server time to process than do smaller boxes.

The character is positioned relative to the baseline and the character origin. The baseline is logically viewed as the x-axis that runs just below nondescending characters. The character origin is a point along the baseline. The left bearing of the character is the distance from the origin to the left edge of the bounding box; the right bearing is the distance from the origin to the right edge. Ascent and descent measure the distance from the baseline to the top and bottom of the bounding box, respectively. Character width is the distance from the origin to the next character origin ( x+ width , y ).

Figure 8-1 Composition of a Character


Figure 8-2 illustrates that the bounding box of a character can extend beyond the character origin. The bounding box of the slash extends one pixel to the left of the origin of the slash, giving the character a left bearing of -1 . The slash is also unusual because its bounding box extends to the right of the next character. The width of the slash, measured from origin to origin, is 5; the right bearing, measured from origin to the right edge of the bounding box, is 6.

Figure 8-2 Composition of a Slash


The left bearing, right bearing, ascent, descent, and width of a character are character metrics. Xlib maintains information about character metrics in a char struct data structure. The following illustrates the data structure:


typedef struct { 
    short       lbearing;   
    short       rbearing;       
    short       width;          
    short       ascent;         
    short       descent;        
    unsigned short attributes;          
} XCharStruct; 

Table 8-1 describes members of the char struct data structure. Any member of the data structure can have a negative value, except the attributes member.

Table 8-1 Char Struct Data Structure Members
Member Name Contents
lbearing Distance from the origin to the left edge of the bounding box. When the value of this member is zero, the server draws only pixels whose x-coordinates are less than the value of the origin x-coordinate.
rbearing Distance from the origin to the right edge of the bounding box.
width Distance from the current origin to the origin of the next character. Text written right-to-left, such as Arabic, uses a negative width to place the next character to the left of the current origin.
ascent Distance from the baseline to the top of the bounding box.
descent Distance from the baseline to the bottom of the bounding box.
attributes Attributes of the character defined in the bitmap distribution format (BDF) file. A character is not guaranteed to have any attributes.

A font is a group of characters that have the same style and size. Xlib supports both fixed and proportional fonts. A fixed font has equal metrics. For example, all characters in the font have the same value for left bearing. Consequently, the bounding box for all characters is the same. All metrics in a proportional font can vary from character to character. A monospaced font is a special type of proportional font in which only the width of all characters must be equal. Bounding boxes of characters in a monospaced font vary depending on the size of characters. If the same font is compiled as a monospaced font and a fixed font, the bounding boxes of the monospaced font are typically smaller than the bounding box that encloses fixed-font characters. For information about compiling fonts, see Appendix A.

Xlib uses indexes to refer to characters that compose a font. The indexes, each defined by a byte, are arranged in one or more rows of up to 256 indexes. A font can contain as many as 256 rows of character indexes, used contiguously. Fonts seldom use all possible indexes.

For example, the font illustrated in Figure 8-3, comprises 219 characters in columns 32 through 250, one column for each character index. Columns 0 through 31 and 251 through 255 are undefined. The first character of the font is located at column 32; the last character is located at column 250. Because all characters are defined in one row of 256 indexes, the font is a single-row font. In the illustration, character "A" is located at column 65.

Figure 8-3 Single-Row Font


Multiple-row fonts, such as Kanji, comprise more characters than can be indexed by a single row of 256 bytes. Figure 8-4 illustrates the configuration of a multiple-row font. Byte 1 refers to the row. Byte 2 refers to the column in the row. In Figure 8-4, the character is located at column 36 in row 17. Note that each row of a multiple-row font has the same number of undefined bytes at the beginning and end. In each row, characters begin at column 32 and end at column 250.

Figure 8-4 Multiple-Row Font


Xlib provides a char 2B data structure to enable clients to index multiple-row fonts easily. The following illustrates the data structure:


typedef struct {         
    unsigned char byte1; 
    unsigned char byte2; 
} XChar2b; 

Table 8-2 describes members of the data structure.

Table 8-2 Char 2B Data Structure Members
Member Name Contents
byte1 Row in which the character is indexed
byte2 Position of the character in the row

Xlib maintains a record of the characteristics of a font in the font struct data structure. The following illustrates the font struct data structure:


typedef struct { 
    XExtData    *ext_data;               
    Font        fid;            
    unsigned    direction;          
    unsigned    min_char_or_byte2; 
    unsigned    max_char_or_byte2;                       
    unsigned    min_byte1;      
    unsigned    max_byte1;      
    Bool        all_chars_exist; 
    unsigned    default_char;   
    int         n_properties;   
    XFontProp   *properties;    
    XCharStruct min_bounds;     
    XCharStruct max_bounds;     
    XCharStruct *per_char;      
    int         ascent;         
    int         descent;        
} XFontStruct; 

Table 8-3 describes members of the data structure.

Table 8-3 Font Struct Data Structure Members
Member Name Contents
ext_data Data used by extensions.
fid Identifier of the font.
direction Hint about the direction in which the font is painted. The direction can be either left-to-right, specified by the constant FontLeftToRight, or right-to-left, specified by the constant FontRightToLeft. The core protocol does not support vertical text.
min_char_or_byte2 First character in the font.
max_char_or_byte2 Last character in the font.
min_byte1 First row that exists.
max_byte1 Last row that exists.
all_chars_exist If the value of this member is true, all characters in the array pointed to by per_char have nonzero bounding boxes.
default_char Character used when an undefined or nonexistent character is printed.
n_properties Number of properties associated with the font.
properties Address of an array of additional font properties.
min_bounds The minimum bounding box value of all the elements in the array of char struct data structures that define each character in the font. For a description of the use of min_bounds, see max_bounds.
max_bounds Maximum metrics values of all the characters in the font.
per_char Address of an array of char struct data structures that define each character in the font.
ascent Distance from the baseline to the top of the bounding box. With descent, ascent is used to determine line spacing.
descent Distance from the baseline to the bottom of the bounding box. With ascent, descent is used to determine line spacing.

As Table 8-3 indicates, Xlib records metrics for each character in an array of char struct data structures specified by the font struct per_char member. The array comprises as many char struct data structures as there are characters in the font. However, the indexes that refer to the location of characters in the array differ from the indexes to characters in the font. For example, 32 indexes the first character of the font illustrated in Figure 8-5, whereas 0 indexes its char struct data structure in the array.

Figure 8-5 Indexing Single-Row Font Character Metrics


To locate the char struct data structure that defines the metrics of any character in a single-row font, subtract the value of the column that indexes the first character in the font, specified by min_char_or_byte2, from the position of the character. For instance, in Figure 8-5 the metrics of character "A" are located at index 33 in the array of char struct data structures specified by the per_char member.

To locate the char struct data structure that defines the metrics of a character of a multiple-row font, use the following formula to adjust for both the number of rows in the font and the position of the character in a row:
( row - first row of characters )*N+ ( position in column - first column )

N is equal to the last column minus the first column plus 1.

For example, the array index of the character specified in Figure 8-6 is 442.

Figure 8-6 Indexing Multiple-Row Font Character Metrics


Like windows, fonts may have properties associated with them. However, font properties differ from window properties. Window properties are data associated with windows; font properties describe font characteristics, such as spacing between words. When the font is compiled, its properties are defined in an array of font prop data structures.

Just as atoms name window properties, atoms name font properties. If the atoms are predefined, they have associated literals. For example, the predefined atom that identifies the height of capitalized letters is referred to by the literal XA_CAP_HEIGHT.

When working with properties, clients must know beforehand how to interpret the font property identified by an atom. Figure 8-7 illustrates this concept.

The server maintains an atom table for font properties. The table associates values with strings. For example, the atom table illustrated in Figure 8-7 defines two atoms. One associates the string FULL_NAME with the value 41. The other associates the string CAP_HEIGHT with the value 42. Notice that the string in the atom table is different from XA_FULL_NAME, the literal that refers to the atom.

Both atoms uniquely identify different types of data. FULL_NAME identifies string data that names the font. CAP_HEIGHT identifies integer data that defines the height of capitalized letters.

Although the atoms identify different types of data, the property table illustrated in Figure 8-7 associates both atoms with integers. The integer associated with CAP_HEIGHT defines without further interpretation the height of capitalized letters. However, the integer listed with FULL_NAME is an atom value. This integer, 90, corresponds to a value in the atom table that has an associated string, HELVETICA BOLD. To use the string, the client must know that the value associated with the atom is itself an atom value.

Figure 8-7 Atoms and Font Properties


Xlib lists each font property and its corresponding atom in a font prop data structure. The property value table in Figure 8-7 is an array of font prop data structures.

The following illustrates the data structure:


typedef struct { 
    Atom name; 
    unsigned long card32; 
} XFontProp; 

Table 8-4 describes members of the data structure.

Table 8-4 Font Prop Data Structure Members
Member Name Contents
name String of characters that names the property
card32 A 32-bit value that defines the font property

8.2 Specifying Fonts

To specify a font for writing text, first load the font and then associate the loaded font with a graphics context. The font files are stored in:

Appendix C lists VMS DECwindows font names.

To load a font, use either the LOAD FONT or the LOAD QUERY FONT routine. LOAD FONT loads the specified font and returns a font identifier. LOAD QUERY FONT loads the specified font and returns information about the font to a font struct data structure.

Because LOAD QUERY FONT returns information to a font struct data structure, calling the routine takes significantly longer than calling LOAD FONT, which returns only the font identifier.

When using either routine, pass the display identifier and font name. Xlib font names consist of the following fields, in left-to-right order:

  1. Foundry that supplied the font, or the font designer
  2. Typeface family of the font
  3. Weight (Book, Demi, Medium, Bold, Light)
  4. Slant (R (roman), I (italic), O (oblique))
  5. Width per horizontal unit of the font (Normal, Wide, Double Wide, Narrow)
  6. Additional style font identifier
  7. Pixel font size
  8. Point size (80, 100, 120, 140, 180, 240) in decipoints (for example, 120 means 12.0 points)
  9. X resolution in pixels (dots) per inch
  10. Y resolution in pixels (dots) per inch
  11. Spacing (M (monospaced), P (proportional), or C (character cell))
  12. Average width of all characters in the font in decipixels
  13. Character set registry
  14. Character set encoding

For more information about font names, see the X Logical Font Description (XLFD) in the X Window System.

The full XLFD name of a representative font is as follows:


-Adobe-ITC Avant Garde Gothic-Book-R-Normal--14-100-100-100-P-80-ISO8859-1 

The font foundry is Adobe. The font family is ITC Avant Garde Gothic. Font weight is Book, font slant is R (roman), and width between font units is Normal.

The pixel size is 14 and the decipoint size is 100. (The actual point size is 10.)

Horizontal and vertical resolution in dots per inch (dpi) is 100. When the dpi is 100, 14 pixels are required to be a 10-point font.

The font is proportionally spaced. Average width of characters is 80 decipixels. Character encoding is ISO Latin-1.

The following designates the full XLFD name of the comparable font designed for a 75 dpi monitor:


-Adobe-ITC Avant Garde Gothic-Book-R-Normal--10-100-75-75-P-59-ISO8859-1 

Unlike the previous font, this font requires only 10 pixels to be 10 points. Note that this font differs from the previous font only in pixel size, resolution, and average character width.

Xlib enables clients to substitute a question mark for a single character and an asterisk (*) for one or more fields in a font name. The following illustrates using the asterisk to specify a 10-point ITC Avant Garde Gothic font of book weight, roman style, and normal spacing for display on either 75 or 100 dpi monitors:


-Adobe-ITC Avant Garde Gothic-Book-R-Normal--*-100-*-*-P-*-ISO8859-1  

See Section 8.7 for more information about using asterisks in font names.

The following example illustrates loading the 10-point font:


    #define FontName\ 
    "-Adobe-ITC Avant Garde Gothic-Book-R-Normal--*-100-*-*-P-*-ISO8859-1" 
                        .
                        .
                        .
    font = XLoadFont(dpy, FontName); 
                        .
                        .
                        .

After loading a font, associate it with a graphics context by calling the SET FONT routine. Specify the font identifier that either LOAD FONT or LOAD QUERY FONT returned and a graphics context, as in the following example:


XSetFont(dpy, gc, font); 

The call associates font with gc.

When loading fonts, note that the LOAD FONT routine is an asychronous routine and does not return an error if the call is unsuccessful. Use one of the following three methods to determine the validity of the font id:

8.3 Getting Information About a Font

Xlib provides clients with routines that list available fonts, get font information with or without character metrics, and return the value of a specified font property.

To get a list of available fonts, use the LIST FONTS routine, specifying the font searched for.

LIST FONTS returns a list of available fonts that match the specified font name. When the client no longer needs the list of font names, call the FREE FONT NAMES routine to free storage allocated for the font list.

To receive both a list of fonts and information about the fonts, use the LIST FONTS WITH INFO routine. LIST FONTS WITH INFO returns both a list of fonts that match the font specified by the client and the address of a font struct data structure for each font listed. Each data structure contains information about the font. The data structure does not include character metrics in the per_char member. For a description of the information returned, see Table 8-3.

To receive information about a font, including character metrics, use the QUERY FONT routine. Because the server returns character metrics, calling QUERY FONT takes approximately eight times longer than calling LIST FONTS WITH INFO. To get the value of a specified property, use the GET FONT PROPERTY routine.

Although a font is not guaranteed to have any properties, it should have at least the properties described in Table 8-5. The table lists properties by atom name and data type. For information about properties, see Section 3.5.

Table 8-5 Atom Names of Font Properties
Atom Data Type Description of the Property
XA_MIN_SPACE unsigned Minimum spacing between words, in pixels.
XA_NORMAL_SPACE unsigned Normal spacing between words, in pixels.
XA_MAX_SPACE unsigned Maximum spacing between words, in pixels.
XA_END_SPACE unsigned Additional spacing at the end of a sentence, in pixels.
XA_SUPERSCRIPT_X signed With XA_SUPERSCRIPT_Y, the offset from the character origin where superscripts should begin, in pixels. If the origin is [x, y], superscripts should begin at the following coordinates:
x + XA_SUPERSCRIPT_X,

y - XA_SUPERSCRIPT_Y
XA_SUPERSCRIPT_Y signed With XA_SUPERSCRIPT_X, the offset from the character origin where superscripts should begin, in pixels. See the description under XA_SUPERSCRIPT_X.
XA_SUBSCRIPT_X signed With XA_SUBSCRIPT_Y, the offset from the character origin where subscripts should begin, in pixels. If the origin is [x, y], subscripts should begin at the following coordinates:
x + XA_SUBSCRIPT_X,

y + XA_SUBSCRIPT_Y
XA_SUBSCRIPT_Y signed With XA_SUBSCRIPT_X, the offset from the character origin where subscripts should begin, in pixels. See the description under XA_SUBSCRIPT_X.
XA_UNDERLINE_POSITION signed The y offset from the baseline to the top of an underline, in pixels. If the baseline y-coordinate is y, then the top of the underline is at y + XA_UNDERLINE_POSITION.
XA_UNDERLINE_THICKNESS unsigned Thickness of the underline, in pixels.
XA_STRIKEOUT_ASCENT signed With XA_STRIKEOUT_DESCENT, the vertical extent for boxing or voiding characters, in pixels. If the baseline y-coordinate is y, the top of the strikeout box is y - XA_STRIKEOUT_ASCENT. The height of the box is as follows:
XA_STRIKEOUT_ASCENT +

XA_STRIKEOUT_DESCENT
XA_STRIKEOUT_DESCENT signed With XA_STRIKEOUT_ASCENT, the vertical extent for boxing or voiding characters, in pixels. See the description under XA_STRIKEOUT_ASCENT.
XA_ITALIC_ANGLE signed The angle of the dominant staffs of characters in the font, in degrees scaled by 64, relative to the 3 o'clock position from the character origin. Positive values indicate counterclockwise motion.
XA_X_HEIGHT signed One ex, as in TeX, but expressed in units of pixels. Often the height of lowercase x.
XA_QUAD_WIDTH signed One em, as in TeX, but expressed in units of pixels. Often the width of the digits 0 to 9.
XA_CAP_HEIGHT signed The y offset from the baseline to the top of capital letters, ignoring ascents. If the baseline y-coordinate is y, the top of the capitals is at
y - XA_CAP_HEIGHT.
XA_WEIGHT unsigned Weight or boldness of the font, expressed as a value between 0 and 1000.
XA_POINT_SIZE unsigned Point size of the font at ideal resolution, expressed in 1/10 points.
XA_RESOLUTION unsigned Number of pixels per point, expressed in 1/100, at which the font was created.
XA_COPYRIGHT unsigned Copyright date of the font.
XA_NOTICE unsigned Copyright date of the font name.
XA_FONT_NAME atom Font name. For example: -Adobe-Helvetica-Bold-R-Normal--10-100-75-75-P-60-ISO8859-1
XA_FAMILY_NAME atom Name of the font family. For example: Helvetica
XA_FULL_NAME atom Full name of the font. For example: Helvetica Bold


Previous Next Contents Index