diff options
Diffstat (limited to 'src/winfonts/winfnt.c')
-rw-r--r-- | src/winfonts/winfnt.c | 249 |
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, |