file_id.diz
MOPPI FONT CONVERTER version 1.0
Copyright (c) 2000 Moppi Productions.
All Rights Reserved.
<memon@inside.org>
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.
12/31/2000
MOPPI FONT CONVERTER v1.0
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:
12/31/2000
- first release
http://moppi.inside.org/demopaja/
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] );
}