OpenGLEAN gleanfonts User Support
Home page | Introduction | Documentation | Files | Examples | Proposals | Authors | Links

OpenGLEAN gleanfonts development
Summary | CVS | (discussion via home page) | (contact via home page) | (suggestion box) | License | Todo | Bugs

Font Handling API Proposal

This proposal was originally authored for OpenGLUT.

There is an unreleased GLUT version 3.8 (included in the SGI Linux distribution) which apparently is a small change that provides glutStrokeWidthf() and glutStrokeLengthf() to return float values, and deprecates the existing integer function. The new functions are not required in OpenGLEAN, as OpenGLEAN has changed glutStrokeWidth() and glutStrokeLength() to return floating point values. PyOpenGL has man pages for these GLUT 3.8 functions:
    float glutStrokeWidthf( void *font, int character );
    float glutStrokeLengthf( void *font, const unsigned char *string );


There are several aspects of text handling that are lacking in the GLUT API. The most important areas for improvement are font extensibility and efficient rendering of character strings. Additional area for improvement include text layout issues, texture-based font rendering, and solid (space-filling) fonts.

Text rendering issues can become very complex, especially with international character support. It is certainly beyond the scope of OpenGLEAN to provide all of these features, but it is reasonable to support text rendering in such a way that the user can manage the high-level issues within the OpenGLEAN API.

Font Extensibility

Fonts have always been extensible in the original X11 implementation, where font data is passed as a pointer, and may represent font data generated by the user. However, this was never developed much due to the desire of avoiding data structures in the overall GLUT design concept. Win32 GLUT never supported user font data pointers.

There are two related issues with extensibility. First, additional fonts will normally come from through the native OS. This is important to support, particulary for access to non-ASCII fonts. How are platform-dependent fonts accessed in a platform independent way?

Second, if custom fonts are used, they need to be included with the application, which means defining a portable font file format. It would be possible to include the FreeType library, and directly support TrueType fonts, but OpenGLEAN wants to minimize library dependencies. However, it is reasonable to have an external utility that generates OpenGLEAN font files via TruType.

Specifying a System Font

[NB: This is a deficient proposal. A more general one has been discussed in the past. I thought that it had been incorporated here, but can find no trace of it in the CVS history from OpenGLEAN/OpenGLUT. Basically, the PostScript naming scheme is not appropriate since "system fonts" are not necessarily PostScript fonts. A system based on enumerating the system fonts, providing a "system" string name (format unspecified, but uniquely identifying each font), and a query-font-attribute-by-font-id API entry to ask about things such as boldface, italics, etc.]

Font specifications are passed as a single string, generally following the Postscript naming scheme.


FAMILY_NAME is the common font name like "Courier" or "Helvetica", or may be a generic name such as "Serif" or "SansSerif". ATTRIBUTES is a concatenated collection of font specifications, from the following list (which may already be excessive): Roman, Italic, Oblique, Condensed, Narrow, Wide, DoubleWide, Light, Medium, Bold, Demi, Fixed, Proportional, Underline, StrikeOut, SmallCaps SIZE is the "Point Size" of the font. Pixel size may be more useful, but point size is far more conventional.

Selection by pixel size can be derived from the screen resolution: PointSize = 2.845 * PixelSize * glutGet(GLUT_SCREEN_HEIGHT_MM) / glutGet(GLUT_SCREEN_HEIGHT) QUESTION: Should there be a method of pixel-size selection, or is the above method sufficient? Maybe include a glutSetOption()?

It is also reasonable to simultaneously support alternate font specification formats, such as the following CSS specification example: { font: 800 14pt/16.5pt "Li Sung", serif }

Some common fonts are guaranteed to be available, provided either by built-in system fonts, or by font data compiled into the GLUT library. This is the list of standard, guaranteed fonts, and is the same as the 14 standard PDF fonts:

        Courier     Courier-Bold   Courier-Oblique   Courier-BoldOblique
        Helvetica   Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique
        Times-Roman Times-Bold     Times-Italic      Times-BoldItalic
        Symbol      ZapfDingbats
The following standard font Point sizes (based on HTML standards) are required to be available: 8, 10, 12, 14, 18, 24 and 36.

(N.B.: OpenGLEAN now provides all of these except the 36-pixel sized versions and the ZapfDigbat fonts. These missing fonts are not defined in a manner that is readily extracted by the OpenGLEAN genfonts tool, and may require determining new copyright/license information.)

The data for all of the above fonts can fit in 400K with compression. This is small enough that compiling the entire set of standard fonts into the OpenGLEAN library is not unreasonable.

API functions

When considering access to System fonts, an obvious function for the OpenGLEAN API is an OS-independent version of the existing OS-dependent bitmap font functions: wglUseFontBitmaps, glXUseXFont, aglUseFont.

    GLboolean glutUseFontBitmaps (
        char *name, int first, int count, int listbase

In addition to providing cross-platform support to exsiting functions, this can be used as the core function for extracting OpenGLEAN bitmap fonts from the operating system fonts, in a manner similar to GLUT's capturexfont and OpenGLEAN's genfont, but in an OS indepenent fashion.

The following function extracts bitmap font data from the native OS, and makes it available for use in the same manner as a regular GLUT font:

int glutCreateBitmapFont(char *name);


Returns an integer font ID usable in glutBitmapCharacter(), etc., or zero if unsuccessful.

void glutDestroyBitmapFont(int font_id);


Note that these functions also suggests the use of integer identifiers instead of data pointers to represent OpenGLEAN fonts. This change is proposed for existing font functions in the GLUT API as well:

    void glutBitmapCharacter( int font_id, int character );
    int glutBitmapWidth( int font_id, int character );
    void glutStrokeCharacter( int font_id, int character );
    int glutStrokeWidth( int font_id, int character );
    int glutBitmapLength( int font_id, const unsigned char *string );
    int glutStrokeLength( int font_id, const unsigned char *string );

Use of glLists to render fonts.

A question for discussion: OpenGLEAN should be able to extract list-embedded fonts in order to save and include unusual fonts with an OpenGLEAN application. However, it seems pointless to de-listify fonts. Furthermore, one must at least create temporary lists in order to use the well-defined OS-dependent font functions.

Therefore, OpenGLEAN should be able to use lists internally, initially set to start at some high value, such as ${\pi\over4} {\rm MAXVAL}$ . Additionally, on can redirect the OpenGLEAN list base using glutSetOption(). It would also be possible for glutSetOption to disable OpenGLEAN list usage. But, this would prevent access to the OS-dependet OpenGL font functions. In this case, one would be restricted to OpenGLEAN built-in fonts, or be required to create OpenGLEAN fonts at program initialization.

Support for Outline Fonts.

Win32 also has a built-in function for solid space-filling fonts, wglUseFontOutlines(). This could be included and emulated for X11/Mac. In addition, a Stroke font version could be included:

    GLboolean glutUseFontOutlines (
        char *name, int first, int count, int listbase
    int glutCreateOutlineFont (char *name);
    int glutDestroyOutlineFont (int font_id);

    GLboolean glutUseFontStrokes (
        char *name, int first, int count, int listbase
    int glutCreateStrokeFont (char *name);
    int glutDestroyStrokeFont (int font_id);

String Rendering

Rendering a string of characters is inefficient when rendered one character at a time, primarily due to OpenGL state changes. OpenGLEAN currently implements glutBitmapString(), but it only supports 8-bit character sets. See the Unicode proposal for the definition of a Unicode compatible version.

glutBitmapString() attempts to handle newline characters to support rendering of multiple lines of code. This approach does not work if one intends to render text with more than one font, which includes changes in attributes such as bold or italics. Switching fonts also results in additional and unnecessary state changes. This can be alleviated by defining functions for entering and leaving a text-rendering state.

It is also useful to include an OpenGLEAN API call that is used instead of glRasterPos*() functions. This has a few benefits, including the ability to support a "newline" control based on an initial text position, better handling of texture-based fonts which do not use the rester coordinates, and the ability to track the raster position without using glGet*().

Without proceeeding to a detailed API definition, this section ends (for now) by presenting an example of text rendering that demonstrates the general intent of String Rendering:

    Times       = glutCreateFont ("Times 12");
    TimesBold   = glutCreateFont ("Times-Bold 12");
    TimesItalic = glutCreateFont ("Times-Italic 12");
    glutBeginText2i (100, 10);
    glutBitmapString (Times, "Hey, I can draw some ");
    glutBitmapString (TimesBold, "bold letters");
    glutBitmapString (Times, " with this ");
    glutBitmapString (TimesItalic, "cool new");
    glutBitmapString (Times, " OpenGLEAN API, and still\n");
    glutBitmapString (Times, " use a newline with mixed fonts.");
    glutEndText ();

Font Data and File Formats

Just getting started here. In general, data should be stored in a format consistent with the OpenGL functions used to render the data. It should have a human-readable header, with binary data (meaning no XML).

Bitmap font data will include with each character, all parameters to the glBitmap() function, including both xmove and ymove. This allows for "control codes" like backspace, and allows for nonstandard font orientations (i.e. international character support).

It would be convenient if bitmap characters were set onto a 2-dimensional grid so that one could just view the image to see the font set. This would result in disjoint data for each character, so it would probably need to be shuffled during I/O. However, such a layout would not be a problem for texture-based fonts. Logo Supported in part by

Generated on Sun Sep 18 12:47:35 2005 for gleanfonts by doxygen 1.4.3
The OpenGLEAN Fonts project is hosted by SourceForge.