[ Previous | Next | Contents | Glossary | Home | Search ]
GL3.2 Version 4.1 for AIX: Programming Concepts

Creating Text Characters

This section includes the following aspects of character creation in GL:

The GL supports the rapid display of rasterized characters in multiple fonts. The fonts can be fixed or variable pitch and can be different point sizes. You can design and use your own fonts or make use of the Enhanced X-Windows fonts supplied with the system. The system also provides query functions to determine information about the currently defined font.

For information on getting a list of available fonts, see the XListFonts function.

List of GL Text Subroutines

charstr
                          Draws a string of raster characters on the screen.
cmov
                          Moves the current character position.
defrasterfont
                          Defines bitmaps for a raster font.
font
                          Selects a raster font.
getcpos
                          Returns the current character position.
getdescender
                          Returns the baseline extent of the longest character descender.
getfont
                          Returns the current raster font number.
getfontencoding
                          Returns the font encoding of the current raster font.
getfonttype
                          Returns the font type of the current raster font.
getheight
                          Returns the maximum character height in the current raster font.
loadXfont
                          Loads an Enhanced X-Windows font into the font table.
strwidth
                          Returns the width of a specified text string.

Character Strings

The cmov subroutine determines where the system draws text on the screen, and the charstr subroutine draws a string of characters. The strwidth subroutine returns the width of a text string.

The system draws the character string in the current font, which, by default, is a fixed-width, sans-serif font nine pixels wide. Strings drawn with raster fonts are not scaled, therefore although a labeled object shrinks as it moves away from the viewer, the label stays the same size. Similarly, no matter what rotation is in effect, the character string maintains the same orientation (horizontal for any standard font) because fonts are defined in 2-D with respect to the raster display. Scaling, rotating, or translating such 2-D primitives has no meaning in a 3-D context.

cmov Subroutine

The current character position determines where the system draws text on the screen. The cmov subroutine moves the current character position to a specified point in the same way that the move subroutine sets the current line-drawing position. The x, y, and z parameters are given as integers, short integers, or real numbers in 2-D or 3-D and specify a point in world coordinates.

The cmov subroutine transforms the world coordinates into window coordinates, which become the new character position. The cmov subroutine does not affect the current graphics position.

If the current character position is clipped out by the current viewing transformation, the character position is set to invalid, and any character strings that are drawn do not appear. The cmov subroutine does not cause anything to be drawn. It simply sets the current character position where drawing occurs when the charstr subroutine is issued.

The parameters are (x, y) for the cmov2 subroutines and (x, y, z) for the cmov subroutines. The syntax for the cmov and cmov2 subroutines is as follows:

void cmov(Coord x, Coord y, Coord z)
void cmov2(Coord x, Coord y)

Forms of the cmov Subroutine
Parameter Type 2-D 3-D
Int16 cmov2s cmovs
Int32 cmov2i cmovi
Float cmov2 cmov

charstr Subroutine

The charstr subroutine draws a string of raster characters. The origin of the first character in the string is the current character position. After the system draws the string, it updates the current character position to the pixel to the right of the last character in the string. Character strings are null-terminated in C. The text string is drawn in the current font and color. The syntax is as follows:

void charstr(Char8 *string)

If the origin of a character string lies outside the viewport, none of the characters in the string are drawn. If the origin is inside the viewport, the characters are individually clipped to the screenmask. The screenmask is normally set to the same size as the viewport, although it can be set smaller than the viewport to enable two kinds of clipping, as illustrated in the Gross and Fine Clipping figure .

Gross clipping removes all strings that start outside the viewport. Fine clipping trims individual characters to the screenmask. Viewport clipping and screenmask clipping apply to all drawing primitives as well. However, the difference between these two types of clipping is usually not important, except for character strings.

Characters are drawn in the current color. Unless the font is specifically changed in the program, character strings are drawn in the current font. The default font is font0 , defined when the winopen subroutine is called. The following example program, rasterchars , draws two lines of text. The program assumes the default font is less than 12 pixels high.

#include <gl/gl.h>
main()
{   prefposition(100, 500, 100, 500);
   winopen("rasterchars");
   color(BLACK);
   clear();
   color(RED);
   cmov2i(50,80);
   charstr("The first line is drawn ");
   charstr("in two parts. ");
   cmov2i(50, 66);
   charstr("This line is 14 pixels lower. ");
   sleep(10); /* pause for ten seconds */
}

The rasterchars program illustrates the following:

Example Program Using the rotate Subroutine

The following example uses the rotate subroutine and illustrates that character strings are drawn in the same orientation no matter where they move, and that the current character move function of the cmov subroutine is transformed like any other geometry. In the example, the rotate subroutine rotates the polygon about the z axis (coming directly out of the screen) by 5 degrees each time. The rotation is about the origin, so vertex p1 should remain fixed. The vertex callouts rotate with the vertices.

#include <gl/gl.h>
float p1[] = {0.0, 0.0};
float p2[] = {0.6, 0.0};
float p3[] = {0.0, 0.6};
main()
{
   long i;
   prefposition(100, 500, 100, 500);
   winopen("rasterchars");
   ortho2(-1.0, 1.0, -1.0, 1.0);
   for (i = 0; i < 40; i++) {
      color(BLACK);
      clear();
      rotate(50, 'z');
      color(RED);
      bgnpolygon();
      v2f(p1); v2f(p2); v2f(p3);
      endpolygon();
      color(GREEN);
      cmov2(0.0, 0.0);
      charstr("vert1");
      cmov2(0.6, 0.0);
      charstr("vert2");
      cmov2(0.0, 0.6);
      charstr("vert3");
      sleep(1);
   }
}

International Text Support

The charstr subroutine supports both single-and double-byte raster character rendering.

If the current font is a double-byte font, this subroutine expects the first two bytes to represent the first character, the second two bytes to represent the next character, and so on. Double-byte fonts are useful in languages with extremely large character sets such as Japanese and Chinese.

If the current font is a single-byte font, each byte represents one character. The ASCII code set is an example of a single-byte font.

It is the user's responsibility to determine if the currently bound font is a single- or double-byte font and to pass the appropriate string. To determine the font type, use the getfonttype subroutine.

Using Double-Byte Character Sets

Currently, the winopen subroutine does not support double-byte character set (DBCS) window titles. To set the name of a GL window to a DBCS string, use the XSetWMName subroutine. The window id of a GL window can be obtained with the getXwid subroutine. To use DBCS strings in a pop-up menu, redefine the default font (font id 0) to be a DBCS font. This can be done with the loadXfont subroutine. Note that only loadXfont can be used to redefine font id 0; the defrasterfont subroutine does not allow font id 0 to be redefined. Be sure to specify pop-up menu entries as DBCS strings. The charstr subroutine does support DBCS output, provided that the current font is a DBCS font.

Using the charstr Subroutine to Render Japanese and Asian Fonts

The following code fragment demonstrates how double-byte fonts can be loaded and used for rendering in GL. An example program illustrating this use can be found in the /usr/lpp/GL/examples/jischarstr.c file.

char* jisX0201 =
 "-ibm_aix-gothic-medium-r-normal--35-230-100-100-m-170-jisx0201.1976-0";
     
char* jisX0208 =
 "-ibm_aix-gothic-medium-r-normal--35-230-100-100-m-340-jisx0208.1983-0";   char* ibmUDC   =
   "-ibm_aix-gothic-medium-r-normal--35-230-100-100-m-340-ibm-udcjp";   loadXfont( 2, jisX0201);   /* Kana Font */
   loadXfont( 3, jisX0208);   /* Kanji Font */
   loadXfont( 4, ibmUDC);     /* IBM User Defined Chars */
 
 font(2)
 charstr("k1k2k300");      /* Draw Kana Character */
 
 font(3);
 charstr("K1K2K300");      /* Draw Kanji string */

Note: The two null bytes are required to terminate a DBCS string. A single null byte is not sufficient; a short word whose first byte is null, but whose second byte is not is still a valid glyph index.

strwidth Subroutine

The strwidth subroutine returns the width of a text string in pixels, using the character-spacing parameters in the current raster font. This text string can be any null-terminated ASCII string of characters. Characters in some fonts may not be all the same width, so the strwidth subroutine does not necessarily return the width of a character times the number of characters in the string. The syntax is as follows:

Int32 strwidth(Char8 *string)

Fonts

A GL raster font is a collection of up to 255 rectangular arrays of masks. If a 1 (one) appears in a mask, then the corresponding pixel is turned on to the current color. If a 0 (zero) appears, the pixel remains as it is. For example, the following bitmasks might be used to draw the character A:

Binary      Hexadecimal
0000011000000000 = 0x0600
0000011000000000 = 0x0600
0000111100000000 = 0x0F00
0000111100000000 = 0x0F00
0001100110000000 = 0x1980
0001100110000000 = 0x1980
0011000011000000 = 0x30C0
0011111111000000 = 0x3FC0
0110000001100000 = 0x6060
0110000001100000 = 0x6060
1100000000110000 = 0xC030
1100000000110000 = 0xC030

To define a single character, you need the following variables:

The defrasterfont subroutine allows you to define a collection of characters with these variables.

Raster font characters are defined by a bitmap, 1 bit per pixel. The width and height of the character, the number of bits in one row of the bitmap, and the baseline position are also specified.

Each array of bitmasks defining an ASCII character makes up a bitmask entry for that character. For the previous example, the ASCII value of A is 65 (decimal), so entry 65 in the font is associated with the bitmask. If such a font were defined, the string AAA would draw three copies of the character shown in this bitmask.

In addition to the bitmask information for each character, you need to know the width and height of the character in pixels. The width cannot be inferred from the bitmask, because all bitmask data comes in 16-bit words. In the previous example, the width of the A is 12 bits; that is, a maximum of 12 bits would be written horizontally for this character. The height is also 12 bits.

Normally, a character's origin is at the lower-left corner of the bitmask, and this is the case for the previous example. The origin for a character is what is put at the current character position. For a character with a descender, such as g, (see illustration), you need extra bits that lie below the current character position. Therefore, the origin should not be at the lower-left corner. Two values, xoffset and yoffset, tell how far the character's origin must be moved to bring it to the lower-left corner. For characters with descenders, the yoffset value is typically negative.

Finally, another number for each character indicates how far to the right the current character position must be advanced after drawing the character. This number is usually different from the width and is labeled the x increment. In the previous example of the bitmap for the letter A, the character position is advanced by about 14 pixels to leave a little space between characters.

To simplify matters, the character bitmasks are packed together in one array of 16-bit values, so the bitmask is determined by the offset into the bitmask array. For example, if the font contained the A example previously described as its first character, and a bitmask for the letter B as its second, the offset for the letter B would be 12 short integers (the length of the bitmask definition of the letter A). The length and width together determine the number of short integers in a character's definition.

The font subroutine selects the font for use when drawing a character string and this font remains the current font until changed by another call to the font subroutine.

Default Font (font 0)

The default font is that font associated with font index 0. The user cannot use the defrasterfont subroutine to redefine this font. The user can, however, change this font by setting the $GLFONT0 environment variable.

The default font for the AIX version 3.2 operating system supports ISO8859-1 encoding. This font is a fixed-width font, X pixels high, Y pixels wide, and is a euro-sans-serif type font.

defrasterfont Subroutine

The defrasterfont subroutine defines bitmaps for a raster font. The chars parameter contains a description of each character in the font. The figure Using the defrasterfont Subroutine to Describe a Character includes:

The chars parameter is an array of structures of type Fontchar , defined in the standard /usr/include/gl/gl.h file. The syntax is as follows:

void defrasterfont(Int32 index, Int16 height, 
                   Int16 numchars, Fontchar chars[], 
                   Int16 numraster, Int16 raster[]) 

The raster parameter is an array of bitmap-information shorts given in the numraster parameter. It is a one-dimensional array of bitmask bytes ordered from left to right, then bottom to top. Mask bits are left justified in the character's bounding box.

The following code fragment draws the g character (as illustrated in the following figure):

defrasterfont (n, ht, nc, chars, nr, rasters);
chars [`g'] = {  724,       8,  9,   0,     -2       9  }
              byte offset   w   h  xoffset yoffset  xinc
              into rasterarray
Int16        []  = {...
rasterarray         ...
position 724 >
       0x7E00, 0xC300, 0x0300, 0x0300,
                     0x7F00, 0xC300, 0xC300, 0xC300,
                     0x7E00,
                    ...
                   }


font Subroutine

The font subroutine selects the font the system uses whenever the charstr subroutine draws a text string. The fontnum parameter is an index into the font table built by the defrasterfont subroutine or loaded with the loadXfont subroutine. This font remains the current font until you use the font subroutine to select another font. The syntax is as follows:

void font(Int32 fontnum)

The font3.c example program defines a font with three characters: a lowercase j, an arrow, and the Greek letter sigma. The j is assigned to the ASCII value of j, and the arrow and sigma are assigned to ASCII values 1 and 2 (written \001 and \002 in the C code). Two sample strings are then written out, the first of which contains only characters that are defined, while the second contains undefined characters.

Note: When characters are not defined, no error occurs but nothing is printed out for them.

loadXfont Subroutine

The loadXfont subroutine loads an Enhanced X-Windows font so that it can be used by GL applications for rendering text. The application must provide a valid font name. There are several ways to obtain a valid font name. The easiest way is to use Enhanced X-Windows subroutines that return lists of installed fonts, with the assumption that a font file is already installed on the system. The xfonts.c example program (found in in GL3.2 Version 4 for AIX: Graphics Library (GL) Technical Reference) shows subroutines that can be used.

Given a font name, this subroutine searches the file system (along the font path) for that font. If the font name is found, the subroutine loads it into the GL table of defined fonts. In other words, the loadXfont subroutine works much like the defrasterfont subroutine, except that the character bitmaps are obtained from pre-installed files. The directory path that is searched for fonts can be controlled with Enhanced X-Windows routines. The syntax is as follows:

void loadXfont(Int32 id_num, Char8 *name)

Font Query Subroutines

The following subroutines return information about the current font (what number it is, how high the characters are, and how long a descender any character has).

getfont Subroutine

The getfont subroutine returns the index of the current raster font. The syntax is as follows:

Int32 getfont()

getheight Subroutine

The getheight subroutine returns the maximum height of a character in the current raster font, including ascenders (present in such characters as the letters t and h, which ascend above the baseline) and descenders (present in such characters as the letters y and p, which descend below the baseline). It returns the height in pixels. The syntax is as follows:

Int32 getheight()

getcpos Subroutine

The getcpos subroutine gets the current character position, in screen coordinates relative to the lower-left corner of the window, and writes it into the parameters. The syntax is as follows:

void getcpos(Screencoord *ix, Screencoord *iy)

getdescender Subroutine

The getdescender subroutine returns the longest descender in the current font. It returns the number of pixels that the longest descender goes below the baseline. The syntax is as follows:

Int32 getdescender()

getfontencoding

The getfontencoding subroutine returns the font encoding of the current raster font. The syntax is as follows:

void getfontencoding (char * end)

getfonttype

The getfonttype subroutine returns the font type of the current raster font. Fonts may be either single-byte character set (SBCS) or double-byte character set (DBCS) fonts. The syntax is as follows:

int getfonttype()

[ Previous | Next | Contents | Glossary | Home | Search ]