vin.ingine.nl
a blog by Vincent van Ingen
10 Aug 2009
 

UPDATE: Today I use Cairo. Which is not only a font renderer but a full blown vector graphics library. They are now building support for OpenGL. Sweet!

Made me some nice wrapper functions. It's much more readable now. You can use it as a basis for your own font drawing routines.

TODO: Some better error handling.

 
FT_Face g_ftFace;
FT_Library g_ftLib;
FT_Matrix g_ftMatrix;
FT_Vector g_ftPen;
int g_ftBoxWidth;
int g_ftBoxHeight;
 
 
void ftBox( int width, int height )
{
    g_ftBoxWidth = width;
    g_ftBoxHeight = height;
}
 
void ftInit()
{
    g_ftMatrix.xx = 0x10000;
    g_ftMatrix.xy = 0;
    g_ftMatrix.yx = 0;
    g_ftMatrix.yy = 0x10000;
 
    g_ftBoxWidth = 0;
    g_ftBoxHeight = 0;
 
    if( FT_Init_FreeType( &g_ftLib ) ) {
        printf( "Error: could not initialize FreeType library\n" );
    }
}
 
void ftFace( char *face )
{
    FT_Error error = FT_New_Face( g_ftLib, face, 0, &g_ftFace );
 
    if( error == FT_Err_Unknown_File_Format ) {
        printf( "Error: Unknown font file format\n" );
    }
    else if( error ) {
        printf( "Error: Unknown error loading font\n" );
    }
}
 
void ftMatrix( int xx, int xy, int yx, int yy )
{
    g_ftMatrix.xx = xx;
    g_ftMatrix.xy = xy;
    g_ftMatrix.yx = yx;
    g_ftMatrix.yy = yy;
}
 
void ftSize( int width, int height )
{
    if( FT_Set_Pixel_Sizes( g_ftFace, 80, 80 ) ) {
        printf( "Error: Could not set font pixel size\n" );
    }
}
 
void ftText( char *image, char *text )
{
    int num_chars = strlen( text );
    int x, y, i, j, p, q, x_max, y_max, pixel;
    char color;
 
    FT_Bitmap *bitmap;
    FT_GlyphSlot slot = g_ftFace->glyph;
 
    int n = 0;
 
    for( ; n < num_chars; n++ )
    {
        FT_Set_Transform( g_ftFace, &g_ftMatrix, &g_ftPen );
 
        if( FT_Load_Char( g_ftFace, text[n], FT_LOAD_RENDER ) ) {
            continue;
        }
 
        bitmap = &slot->bitmap;
        x = slot->bitmap_left;
        y = g_ftBoxHeight - slot->bitmap_top;
        x_max = x + bitmap->width;
        y_max = y + bitmap->rows;
 
        for( i = x, p = 0; i < x_max; i++, p++ )
        {
            for( j = y, q = 0; j < y_max; j++, q++ )
            {
                if( i < 0 || j < 0 || i >= g_ftBoxWidth || j >= g_ftBoxHeight ) {
                    continue;
                }
 
                color = bitmap->buffer[q * bitmap->width + p];
                pixel = ( j * g_ftBoxHeight + i ) * 4;
                image[pixel++] = 0xff;   // R
                image[pixel++] = 0xff;   // G
                image[pixel++] = 0xff;   // B
                image[pixel] |= color;   // A
            }
        }
 
        g_ftPen.x += slot->advance.x;
        g_ftPen.y += slot->advance.y;
    }
}
 
void ftTranslate( int x, int y )
{
    g_ftPen.x = x << 6;
    g_ftPen.y = ( g_ftBoxHeight - y ) << 6;
}


This is how you use the new functions. Much nicer now!

 
#define IMG_WIDTH 512
#define IMG_HEIGHT 512
 
 
 
// create a bitmap
unsigned char *image = malloc( IMG_WIDTH * IMG_HEIGHT * 4 );
 
if( image == NULL ) {
    printf( "Error: malloc()\n" ); return 0;
}
 
memset( image, 0, IMG_WIDTH * IMG_HEIGHT * 4 );
 
 
 
// draw our text using our awesome functions!
ftInit();
ftFace( "c:/windows/fonts/verdana.ttf" );
ftSize( 80, 80 );
ftBox( IMG_WIDTH, IMG_HEIGHT );
 
double angle = ( -30.0 / 180.0 ) * 3.14159;
ftMatrix(
    (FT_Fixed)( cos( angle ) * 0x10000L ),
    (FT_Fixed)(-sin( angle ) * 0x10000L ),
    (FT_Fixed)( sin( angle ) * 0x10000L ),
    (FT_Fixed)( cos( angle ) * 0x10000L )
);
 
ftTranslate( 50, 100 );
ftText( image, "Hello, world!" );
ftTranslate( 50, 200 );
ftText( image, "Hello, world!" );
ftTranslate( 50, 300 );
ftText( image, "Hello, world!" );
 
 
 
// ...and create a OpenGL texture of it
GLint img;
 
glGenTextures( 1, &img );
glBindTexture( GL_TEXTURE_2D, img );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, IMG_WIDTH, IMG_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, image );
 
Tags: C, Development, OpenGL, Other.
 
 
 
 
 
Comments 
 
No comments yet.