MOPPI FONT fileformat The font is saved in the Moppi Font format as bitmap. Also texture coordinate information and the number of pixels to advance after each character is written to the file. The number of pixels to advance is important for fonts which are not monospaced. ** FILE LAYOUT Data types: char is a 8-bit character BYTE is a 8-bit unsigned integer WORD is a 16-bit unsigned integer Size: Description: char[4] Header, should read "mofo". Should be tested. BYTE First character. This is index in ASCII table. BYTE Last character. There will be (last_char - first_char) characters in this file. WORD Max font height in pixels WORD Texture width. This is quaranteed to be power of 2. WORD Texture height. This most likely is not power of 2. for each char WORD Number of pixels to advance after this char. for each char WORD Min X. Coordinates in the texture. WORD Min Y. WORD Max X. WORD Max Y. BYTE[TW * TH] The font data. (TW = texture width, TH = texture height). ** EXAMPLE CODE uint8* g_pData = 0; uint16* g_pWidths = 0; uint16* g_pCoords = 0; uint32 g_ui32FirstGlyph; uint32 g_ui32LastGlyph; uint32 g_ui32FontHeight; uint32 g_ui32GlyphCount; uint32 g_ui32TexWidth; uint32 g_ui32TexHeight; // // Loads a font file from specified file. // bool load_mofo( const char* szName ) { FILE* fp; if( (fp = fopen( szName, "rb" )) == 0 ) { return false; } uint8 ui8Header[4]; uint8 ui8Tmp; uint16 ui16Tmp; // Read and test header. fread( ui8Header, sizeof( ui8Header ), 1, fp ); if( ui8Header[0] != 'm' || ui8Header[1] != 'o' || ui8Header[2] != 'f' || ui8Header[3] != 'o' ) return false; // Read first char. fread( &ui8Tmp, sizeof( ui8Tmp ), 1, fp ); g_ui32FirstGlyph = ui8Tmp; // Read last char. fread( &ui8Tmp, sizeof( ui8Tmp ), 1, fp ); g_ui32LastGlyph = ui8Tmp; // Calculate number of characters and allocate space for texture coords // and character advances. g_ui32GlyphCount = g_ui32LastGlyph - g_ui32FirstGlyph; g_pWidths = new uint16[g_ui32GlyphCount]; g_pCoords = new uint16[g_ui32GlyphCount * 4]; // Read font height. fread( &ui16Tmp, sizeof( ui16Tmp ), 1, fp ); g_ui32FontHeight = ui16Tmp; // Read texture size. fread( &ui16Tmp, sizeof( ui16Tmp ), 1, fp ); g_ui32TexWidth = ui16Tmp; fread( &ui16Tmp, sizeof( ui16Tmp ), 1, fp ); g_ui32TexHeight = ui16Tmp; // Widths fread( g_pWidths, g_ui32GlyphCount * sizeof( uint16 ), 1, fp ); // Tex coords fread( g_pCoords, g_ui32GlyphCount * 4 * sizeof( uint16 ), 1, fp ); // Allocate the texture data. // nearest_power function returns nearest power of 2 value of the // argument. uint32 ui32DataSize = g_ui32TexWidth * nearest_power( g_ui32TexHeight ); delete g_pData; g_pData = new uint8[ui32DataSize]; if( !g_pData ) { fclose( fp ); return false; } memset( g_pData, 0, ui32DataSize ); fread( g_pData, g_ui32TexWidth * g_ui32TexHeight, 1, fp ); fclose( fp ); g_ui32TexHeight = nearest_power( g_ui32TexHeight ); return true; } // // Returns the width of a character. // uint16 get_glyph_width( uint32 ui32Index ) { if( ui32Index >= g_ui32FirstGlyph && ui32Index < g_ui32LastGlyph ) { uint32 ui32Offset = (ui32Index - g_ui32FirstGlyph) * 4; return g_pCoords[ui32Offset + 2] - g_pCoords[ui32Offset + 0]; } return 0; } // // Returns the advance of a character. // uint16 get_glyph_advance( uint32 ui32Index ) { if( ui32Index >= g_ui32FirstGlyph && ui32Index < g_ui32LastGlyph ) return g_pWidths[ui32Index - g_ui32FirstGlyph]; return g_ui32FontHeight / 2; } // // Scales the texture coordinates from the file to range 0..1. // void get_glyph_coords( uint32 ui32Index, float32& f32U0, float32& f32V0, float32& f32U1, float32& f32V1 ) { if( ui32Index >= g_ui32FirstGlyph && ui32Index < g_ui32LastGlyph ) { float32 f32MultX = 1.0f / (float)g_ui32TexWidth; float32 f32MultY = 1.0f / (float)g_ui32TexHeight; uint32 ui32Offset = (ui32Index - g_ui32FirstGlyph) * 4; f32U0 = (float32)g_pCoords[ui32Offset] * f32MultX; f32V0 = (float32)g_pCoords[ui32Offset + 1] * f32MultY; f32U1 = (float32)g_pCoords[ui32Offset + 2] * f32MultX; f32V1 = (float32)g_pCoords[ui32Offset + 3] * f32MultY; } else f32U0 = f32V0 = f32U1 = f32V1 = 0; } // // Draw character // int32 draw_char( int32 i32X, int32 i32Y, char cChar ) { int32 i32Width, i32Height; float32 f32U0, f32V0, f32U1, f32V1; // Get character texture coordinates get_glyph_coords( cChar, f32U0, f32V0, f32U1, f32V1 ); // Get size of the character i32Width = get_glyph_width( cChar ); i32Height = g_ui32FontHeight; // Draw the character as quad glBegin( GL_QUADS ); glTexCoord2f( f32U0, f32V1 ); glVertex2i( i32X, i32Y ); glTexCoord2f( f32U1, f32V1 ); glVertex2i( i32X + i32Width, i32Y ); glTexCoord2f( f32U1, f32V0 ); glVertex2i( i32X + i32Width, i32Y + i32Height ); glTexCoord2f( f32U0, f32V0 ); glVertex2i( i32X, i32Y + i32Height ); glEnd(); // Return how much we advanced. return get_glyph_advance( cChar ); } // // Draw string // void draw_text( int32 i32X, int32 i32Y, const char* szText ) { for( uint32 i = 0; i < strlen( szText ); i++ ) i32X += draw_char( i32X, i32Y, szText[i] ); } MOPPI FONT CONVERTER version 1.0 Copyright (c) 2000 Moppi Productions. All Rights Reserved. http://moppi.inside.org/demopaja/ LICENSE AND WARRANTY The Moppi Font Converter is free software. This software is provided "AS IS", with out warranty of any kind, either expressed or implied, including but not limited to the implied warranties of merchanbility and/or fitness for a particular purpose. The author shall not be held liable for any damage to you, your computer, or to anyone or anything else, that may result from its use or misuse. You use this software at your own risk. Usage of this software indicates your acceptance of this license agreement and warranty. This software can be distributed unmodified with no restrictions, provided any charge is to cover distribution costs only. This software can be freely placed on CDs or magazine floppy disks, etc. with a permission of the author. All trademarks and other registered names contained in the Moppi Font Converter package are the property of their respective owners. 1/1/2001 MOPPI FONT CONVERTER v1.01 The Moppi Font Converter converts True Type Fonts to bitmap fonts. The file format it saves is .mofo. This file format can be used in the Moppi Demopaja. The Moppi Font Converter uses it's own rasterizer to convert the files so the antialiasing should be a little better than using using plain GDI calls. The rasterizer is not very good at very small font sizes (< 10). This package also includes description of the file format used, so feel free to use the files created with this software on your own projects, etc. History: Version 1.01 1/1/2001 - corrected bug which caused the last character index to be 0 when all characters was visible Version 1.0 12/31/2000 - first release http://moppi.inside.org/demopaja/