summaryrefslogtreecommitdiff
path: root/src/winfonts/winfnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/winfonts/winfnt.c')
-rw-r--r--src/winfonts/winfnt.c249
1 files changed, 101 insertions, 148 deletions
diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c
index 70d097282..b2e315f63 100644
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -113,14 +113,21 @@
static void
- fnt_font_done( FNT_Font font,
- FT_Stream stream )
+ fnt_font_done( FNT_Face face )
{
+ FT_Memory memory = FT_FACE( face )->memory;
+ FT_Stream stream = FT_FACE( face )->stream;
+ FNT_Font font = face->font;
+
+
+ if ( !font )
+ return;
+
if ( font->fnt_frame )
FT_FRAME_RELEASE( font->fnt_frame );
- font->fnt_size = 0;
- font->fnt_frame = 0;
+ FT_FREE( font );
+ face->font = 0;
}
@@ -164,11 +171,7 @@
goto Exit;
}
- /* small fixup -- some fonts have the `pixel_width' field set to 0 */
- if ( header->pixel_width == 0 )
- header->pixel_width = header->pixel_height;
-
- /* this is a FNT file/table, we now extract its frame */
+ /* this is a FNT file/table; extract its frame */
if ( FT_STREAM_SEEK( font->offset ) ||
FT_FRAME_EXTRACT( header->file_size, font->fnt_frame ) )
goto Exit;
@@ -178,25 +181,9 @@
}
- static void
- fnt_face_done_fonts( FNT_Face face )
- {
- FT_Memory memory = FT_FACE( face )->memory;
- FT_Stream stream = FT_FACE( face )->stream;
- FNT_Font cur = face->fonts;
- FNT_Font limit = cur + face->num_fonts;
-
-
- for ( ; cur < limit; cur++ )
- fnt_font_done( cur, stream );
-
- FT_FREE( face->fonts );
- face->num_fonts = 0;
- }
-
-
static FT_Error
- fnt_face_get_dll_fonts( FNT_Face face )
+ fnt_face_get_dll_font( FNT_Face face,
+ FT_Int face_index )
{
FT_Error error;
FT_Stream stream = FT_FACE( face )->stream;
@@ -204,10 +191,9 @@
WinMZ_HeaderRec mz_header;
- face->fonts = 0;
- face->num_fonts = 0;
+ face->font = 0;
- /* does it begin with a MZ header? */
+ /* does it begin with an MZ header? */
if ( FT_STREAM_SEEK( 0 ) ||
FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) )
goto Exit;
@@ -215,7 +201,7 @@
error = FNT_Err_Unknown_File_Format;
if ( mz_header.magic == WINFNT_MZ_MAGIC )
{
- /* yes, now look for a NE header in the file */
+ /* yes, now look for an NE header in the file */
WinNE_HeaderRec ne_header;
@@ -226,16 +212,15 @@
error = FNT_Err_Unknown_File_Format;
if ( ne_header.magic == WINFNT_NE_MAGIC )
{
- /* good, now look in the resource table for each FNT resource */
- FT_ULong res_offset = mz_header.lfanew +
- ne_header.resource_tab_offset;
-
+ /* good, now look into the resource table for each FNT resource */
+ FT_ULong res_offset = mz_header.lfanew +
+ ne_header.resource_tab_offset;
FT_UShort size_shift;
FT_UShort font_count = 0;
FT_ULong font_offset = 0;
- if ( FT_STREAM_SEEK( res_offset ) ||
+ if ( FT_STREAM_SEEK( res_offset ) ||
FT_FRAME_ENTER( ne_header.rname_tab_offset -
ne_header.resource_tab_offset ) )
goto Exit;
@@ -253,7 +238,7 @@
count = FT_GET_USHORT_LE();
- if ( type_id == 0x8008 )
+ if ( type_id == 0x8008U )
{
font_count = count;
font_offset = (FT_ULong)( FT_STREAM_POS() + 4 +
@@ -263,6 +248,7 @@
stream->cursor += 4 + count * 12;
}
+
FT_FRAME_EXIT();
if ( !font_count || !font_offset )
@@ -272,50 +258,36 @@
goto Exit;
}
- if ( FT_STREAM_SEEK( font_offset ) ||
- FT_NEW_ARRAY( face->fonts, font_count ) )
- goto Exit;
+ face->root.num_faces = font_count;
- face->num_fonts = font_count;
-
- if ( FT_FRAME_ENTER( (FT_Long)font_count * 12 ) )
+ if ( face_index >= font_count )
+ {
+ error = FNT_Err_Bad_Argument;
goto Exit;
+ }
- /* now read the offset and position of each FNT font */
- {
- FNT_Font cur = face->fonts;
- FNT_Font limit = cur + font_count;
+ if ( FT_NEW( face->font ) )
+ goto Exit;
+ if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) ||
+ FT_FRAME_ENTER( 12 ) )
+ goto Fail;
- for ( ; cur < limit; cur++ )
- {
- cur->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
- cur->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
- cur->size_shift = size_shift;
- stream->cursor += 8;
- }
- }
- FT_FRAME_EXIT();
+ face->font->offset = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
+ face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
+ face->font->size_shift = size_shift;
- /* finally, try to load each font there */
- {
- FNT_Font cur = face->fonts;
- FNT_Font limit = cur + font_count;
+ stream->cursor += 8;
+ FT_FRAME_EXIT();
- for ( ; cur < limit; cur++ )
- {
- error = fnt_font_load( cur, stream );
- if ( error )
- goto Fail;
- }
- }
+ error = fnt_font_load( face->font, stream );
}
}
Fail:
if ( error )
- fnt_face_done_fonts( face );
+ fnt_font_done( face );
Exit:
return error;
@@ -335,7 +307,7 @@
fnt_cmap_init( FNT_CMap cmap )
{
FNT_Face face = (FNT_Face)FT_CMAP_FACE( cmap );
- FNT_Font font = face->fonts;
+ FNT_Font font = face->font;
cmap->first = (FT_UInt32) font->header.first_char;
@@ -354,8 +326,8 @@
char_code -= cmap->first;
if ( char_code < cmap->count )
- gindex = char_code + 1;
-
+ gindex = char_code + 1; /* we artificially increase the glyph index; */
+ /* FNT_Load_Glyph reverts to the right one */
return gindex;
}
@@ -408,7 +380,7 @@
FT_Memory memory = FT_FACE_MEMORY( face );
- fnt_face_done_fonts( face );
+ fnt_font_done( face );
FT_FREE( face->root.available_sizes );
face->root.num_fixed_sizes = 0;
@@ -427,23 +399,22 @@
FT_UNUSED( num_params );
FT_UNUSED( params );
- FT_UNUSED( face_index );
- /* try to load several fonts from a DLL */
- error = fnt_face_get_dll_fonts( face );
+ /* try to load font from a DLL */
+ error = fnt_face_get_dll_font( face, face_index );
if ( error )
{
- /* this didn't work, now try to load a single FNT font */
+ /* this didn't work; try to load a single FNT font */
FNT_Font font;
- if ( FT_NEW( face->fonts ) )
+ if ( FT_NEW( face->font ) )
goto Exit;
- face->num_fonts = 1;
- font = face->fonts;
+ face->root.num_faces = 1;
+ font = face->font;
font->offset = 0;
font->fnt_size = stream->size;
@@ -452,43 +423,45 @@
goto Fail;
}
- /* all right, one or more fonts were loaded; we now need to */
- /* fill the root FT_Face fields with relevant information */
+ /* we now need to fill the root FT_Face fields */
+ /* with relevant information */
{
- FT_Face root = FT_FACE( face );
- FNT_Font fonts = face->fonts;
- FNT_Font limit = fonts + face->num_fonts;
- FNT_Font cur;
+ FT_Face root = FT_FACE( face );
+ FNT_Font font = face->font;
- root->num_faces = 1;
root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
FT_FACE_FLAG_HORIZONTAL;
- if ( fonts->header.avg_width == fonts->header.max_width )
+ if ( font->header.avg_width == font->header.max_width )
root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
- if ( fonts->header.italic )
+ if ( font->header.italic )
root->style_flags |= FT_STYLE_FLAG_ITALIC;
- if ( fonts->header.weight >= 800 )
+ if ( font->header.weight >= 800 )
root->style_flags |= FT_STYLE_FLAG_BOLD;
- /* Setup the `fixed_sizes' array */
- if ( FT_NEW_ARRAY( root->available_sizes, face->num_fonts ) )
+ /* set up the `fixed_sizes' array */
+ if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
goto Fail;
- root->num_fixed_sizes = face->num_fonts;
+ root->num_fixed_sizes = 1;
{
- FT_Bitmap_Size* size = root->available_sizes;
-
-
- for ( cur = fonts; cur < limit; cur++, size++ )
- {
- size->width = cur->header.pixel_width;
- size->height = cur->header.pixel_height;
- }
+ FT_Bitmap_Size* bsize = root->available_sizes;
+
+
+ bsize->width = font->header.avg_width;
+ bsize->height =
+ font->header.pixel_height + font->header.external_leading;
+ bsize->size = font->header.nominal_point_size << 6;
+ bsize->x_ppem =
+ (FT_Pos)( ( font->header.horizontal_resolution * bsize->size + 36 )
+ / 72 );
+ bsize->y_ppem =
+ (FT_Pos)( ( font->header.vertical_resolution* bsize->size + 36 )
+ / 72 );
}
{
@@ -513,11 +486,13 @@
}
/* setup remaining flags */
- root->num_glyphs = fonts->header.last_char -
- fonts->header.first_char + 1;
- root->family_name = (FT_String*)fonts->fnt_frame +
- fonts->header.face_name_offset;
+ /* reserve one slot for the .notdef glyph at index 0 */
+ root->num_glyphs = font->header.last_char -
+ font->header.first_char + 1 + 1;
+
+ root->family_name = (FT_String*)font->fnt_frame +
+ font->header.face_name_offset;
root->style_name = (char *)"Regular";
if ( root->style_flags & FT_STYLE_FLAG_BOLD )
@@ -541,80 +516,58 @@
static FT_Error
- FNT_Size_Set_Pixels( FNT_Size size )
+ FNT_Size_Set_Pixels( FT_Size size )
{
- /* look up a font corresponding to the current pixel size */
- FNT_Face face = (FNT_Face)FT_SIZE_FACE( size );
- FNT_Font cur = face->fonts;
- FNT_Font limit = cur + face->num_fonts;
- FNT_Font hit;
-
+ FNT_Face face = (FNT_Face)FT_SIZE_FACE( size );
+ FT_Face root = FT_FACE( face );
- size->font = 0;
- hit = 0;
- for ( ; cur < limit; cur++ )
+ if ( size->metrics.y_ppem == root->available_sizes->height )
{
- if ( cur->header.pixel_height == size->root.metrics.y_ppem )
- {
- hit = cur;
- break;
- }
- }
+ FNT_Font font = face->font;
- /* try to find a better hit */
- for ( ; cur < limit; cur++ )
- {
- if ( cur->header.pixel_height == size->root.metrics.y_ppem &&
- cur->header.pixel_width == size->root.metrics.x_ppem )
- {
- hit = cur;
- break;
- }
- }
- if ( hit ) {
- size->font = hit;
- size->root.metrics.ascender = hit->header.ascent * 64;
- size->root.metrics.descender = ( hit->header.pixel_height -
- hit->header.ascent ) * 64;
- size->root.metrics.height = hit->header.pixel_height * 64;
- size->root.metrics.max_advance = hit->header.max_width * 64;
- }
+ size->metrics.ascender = font->header.ascent * 64;
+ size->metrics.descender = ( font->header.pixel_height -
+ font->header.ascent ) * 64;
+ size->metrics.height = font->header.pixel_height * 64;
+ size->metrics.max_advance = font->header.max_width * 64;
- return ( size->font ? FNT_Err_Ok : FNT_Err_Invalid_Pixel_Size );
+ return FNT_Err_Ok;
+ }
+ else
+ return FNT_Err_Invalid_Pixel_Size;
}
static FT_Error
FNT_Load_Glyph( FT_GlyphSlot slot,
- FNT_Size size,
+ FT_Size size,
FT_UInt glyph_index,
FT_Int32 load_flags )
{
- FNT_Font font = size->font;
- FT_Error error = 0;
+ FNT_Face face = (FNT_Face)FT_SIZE_FACE( size );
+ FNT_Font font = face->font;
+ FT_Error error = FNT_Err_Ok;
FT_Byte* p;
FT_Int len;
FT_Bitmap* bitmap = &slot->bitmap;
FT_ULong offset;
FT_Bool new_format;
- FT_UNUSED( slot );
FT_UNUSED( load_flags );
- if ( !font )
+ if ( !face || !font )
{
error = FNT_Err_Invalid_Argument;
goto Exit;
}
if ( glyph_index > 0 )
- glyph_index--;
+ glyph_index--; /* revert to real index */
else
- glyph_index = font->header.default_char;
- glyph_index -= font->header.first_char;
+ glyph_index = font->header.default_char; /* the .notdef glyph */
new_format = FT_BOOL( font->header.version == 0x300 );
len = new_format ? 6 : 4;
@@ -699,7 +652,7 @@
},
sizeof( FNT_FaceRec ),
- sizeof( FNT_SizeRec ),
+ sizeof( FT_SizeRec ),
sizeof( FT_GlyphSlotRec ),
(FT_Face_InitFunc) FNT_Face_Init,