diff --git a/ChangeLog b/ChangeLog index fc5d99865..595870061 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,60 @@ +2003-06-30 Werner Lemberg + + A new try to synchronize bitmap font access. + + include/freetype/freetype.h (FT_Bitmap_Size): `height' is now + defined to return the baseline-to-baseline distance. This was + already the value returned by the BDF and PCF drivers. + + The `width' field now gives the average width. I wasn't able to + find something better. It should be taken as informative only. + + New fields `size', `x_ppem', and `y_ppem'. + + * src/pcf/pcfread.c (pcf_load_font): Updated to properly fill + FT_Bitmap_Size. + Do proper rounding and conversion from 72.27 to 72 points. + + * src/bdf/bdfdrivr.c (BDF_Face_Init): Updated to properly fill + FT_Bitmap_Size. + Do proper rounding and conversion from 72.27 to 72 points. + + * src/sfnt/sfobjs.c (sfnt_load_face): Updated to properly fill + FT_Bitmap_Size. + + * src/winfonts/winfnt.c (FNT_Face_Init): Updated to properly fill + FT_Bitmap_Size. + +2003-06-29 Werner Lemberg + + Redesigning the FNT driver to return multiple faces, not multiple + strikes. At least one font (app850.fon from WinME) contains + different FNT charmaps for its subfonts. Consequently, the previous + design of having multiple bitmap strikes in a single font face fails + since we have only one charmap per face. + + * include/freetype/internal/fnttypes.h (FNT_Size_Rec): Removed. + (FNT_FaceRec): Remove `num_fonts' field and replace `fonts' with + `font'. + + * src/base/ftwinfnt.c (FT_Get_WinFNT_Header): Updated. + + * src/winfonts/winfnt.c (fnt_font_load): Don't set pixel_width equal + to pixel_height. + (fnt_face_done_fonts): Removed. + (fnt_face_get_dll_fonts): Renamed to... + (fnt_face_get_dll_font): This. Add second function argument to + select face index. + Updated to load just one subfont. + (fnt_font_done, FNT_Face_Done): Updated. + (FNT_Face_Init): Handle `face_index'. + Updated. + (FNT_Size_Set_Pixels): Simplified; similar to BDF and PCF, the + bitmap width is now ignored. + (FNT_Load_Glyph): Updated. + Fix glyph index computation. + (winfnt_driver_class): Updated. + 2003-06-25 Owen Taylor * src/sfnt/ttload.c (tt_face_load_hdmx): Don't assign diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 241298f0a..f4c3e6188 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -210,26 +210,62 @@ FT_BEGIN_HEADER /* FT_Bitmap_Size */ /* */ /* */ - /* An extremely simple structure used to model the size of a bitmap */ - /* strike (i.e., a bitmap instance of the font for a given */ - /* resolution) in a fixed-size font face. This is used for the */ - /* `available_sizes' field of the @FT_FaceRec structure. */ + /* This structure models the size of a bitmap strike (i.e., a bitmap */ + /* instance of the font for a given resolution) in a fixed-size font */ + /* face. It is used for the `available_sizes' field of the */ + /* @FT_FaceRec structure. */ /* */ /* */ - /* height :: The character height in pixels. */ + /* height :: The (vertical) baseline-to-baseline distance in pixels. */ + /* It makes most sense to define the height of a bitmap */ + /* font in this way. */ /* */ - /* width :: The character width in pixels. For drivers which */ - /* contain a single bitmap strike only (BDF, PCF) this */ - /* field is always equal to `height'. To get the */ - /* (maximum) width of a bitmap strike use */ - /* `face->size->metrics.max_advance' after a call to */ - /* @FT_Set_Pixel_Sizes. */ + /* width :: The average width of the font (in pixels). Since the */ + /* algorithms to compute this value are different for the */ + /* various bitmap formats, it can only give an additional */ + /* hint if the `height' value isn't sufficient to select */ + /* the proper font. For monospaced fonts the average width */ + /* is the same as the maximum width. */ + /* */ + /* size :: The point size in 26.6 fractional format this font shall */ + /* represent (for a given vertical resolution). */ + /* */ + /* x_ppem :: The horizontal ppem value (in 26.6 fractional format). */ + /* */ + /* y_ppem :: The vertical ppem value (in 26.6 fractional format). */ + /* */ + /* */ + /* The values in this structure are taken from the bitmap font. If */ + /* the font doesn't provide a parameter it is set to zero to indicate */ + /* that the information is not available. */ + /* */ + /* The following formula converts from dpi to ppem: */ + /* */ + /* ppem = size * dpi / 72 */ + /* */ + /* where `size' is in points. */ + /* */ + /* Windows FNT: */ + /* The `size', `x_ppem', and `y_ppem' parameters are not reliable: */ + /* There exist fonts (e.g. app850.fon) which have a wrong size for */ + /* some subfonts; since FNT files don't contain ppem but dpi values */ + /* the computed x_ppem and y_ppem numbers are thus wrong also. */ + /* */ + /* TrueType embedded bitmaps: */ + /* `size', `width', and `height' values are not contained in the */ + /* bitmap strike itself. They are computed from the global font */ + /* parameters. */ /* */ typedef struct FT_Bitmap_Size_ { FT_Short height; FT_Short width; + FT_Pos size; + + FT_Pos x_ppem; + FT_Pos y_ppem; + } FT_Bitmap_Size; @@ -1911,7 +1947,6 @@ FT_BEGIN_HEADER /* */ /* FreeType error code. 0 means success. */ /* */ - /* */ /* */ /* The values of `pixel_width' and `pixel_height' correspond to the */ /* pixel values of the _typographic_ character size, which are NOT */ @@ -1929,8 +1964,9 @@ FT_BEGIN_HEADER /* */ /* For bitmap fonts, `pixel_height' usually is a reliable value for */ /* the height of the bitmap cell. Drivers for bitmap font formats */ - /* which contain a single bitmap strike only (BDF, PCF) ignore */ + /* which contain a single bitmap strike only (BDF, PCF, FNT) ignore */ /* `pixel_width'. */ + /* */ FT_EXPORT( FT_Error ) FT_Set_Pixel_Sizes( FT_Face face, FT_UInt pixel_width, @@ -2217,6 +2253,10 @@ FT_BEGIN_HEADER /* conversion performed on the outline, as well as specific */ /* hinting optimizations. */ /* */ + /* For bitmap fonts the `bitmap->pixel_mode' field in the */ + /* @FT_GlyphSlotRec structure gives the format of the returned */ + /* bitmap. */ + /* */ /* */ /* FT_RENDER_MODE_NORMAL :: */ /* This is the default render mode; it corresponds to 8-bit */ diff --git a/include/freetype/ftimage.h b/include/freetype/ftimage.h index 7115a0643..b2a0a6871 100644 --- a/include/freetype/ftimage.h +++ b/include/freetype/ftimage.h @@ -261,7 +261,8 @@ FT_BEGIN_HEADER /* `FT_PIXEL_MODE_GRAY'; it gives the number of gray */ /* levels used in the bitmap. */ /* */ - /* pixel_mode :: The pixel_mode, i.e., how pixel bits are stored. */ + /* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. */ + /* See @FT_Pixel_Mode for possible values. */ /* */ /* palette_mode :: This field is only used with paletted pixel modes; */ /* it indicates how the palette is stored. */ diff --git a/include/freetype/internal/fnttypes.h b/include/freetype/internal/fnttypes.h index 65881888f..3efa86092 100644 --- a/include/freetype/internal/fnttypes.h +++ b/include/freetype/internal/fnttypes.h @@ -85,20 +85,10 @@ FT_BEGIN_HEADER } FNT_FontRec, *FNT_Font; - typedef struct FNT_SizeRec_ - { - FT_SizeRec root; - FNT_Font font; - - } FNT_SizeRec, *FNT_Size; - - typedef struct FNT_FaceRec_ { FT_FaceRec root; - - FT_UInt num_fonts; - FNT_Font fonts; + FNT_Font font; FT_CharMap charmap_handle; FT_CharMapRec charmap; /* a single charmap per face */ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 59169d4ef..f862df9df 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -833,7 +833,7 @@ FT_Long face_index, FT_Int num_params, FT_Parameter* params, - FT_Face* aface ) + FT_Face *aface ) { FT_Memory memory; FT_Driver_Class clazz; @@ -882,11 +882,10 @@ /* select Unicode charmap by default */ error2 = find_unicode_charmap( face ); - /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle is - * returned. - */ + /* if no Unicode charmap can be found, FT_Err_Invalid_CharMap_Handle */ + /* is returned. */ - /* no error should happen, but we want to play safe. */ + /* no error should happen, but we want to play safe */ if ( error2 && error2 != FT_Err_Invalid_CharMap_Handle ) { error = error2; diff --git a/src/base/ftwinfnt.c b/src/base/ftwinfnt.c index d55597a02..2cbe343d1 100644 --- a/src/base/ftwinfnt.c +++ b/src/base/ftwinfnt.c @@ -39,8 +39,8 @@ if ( driver->clazz && driver->clazz->module_name && ft_strcmp( driver->clazz->module_name, "winfonts" ) == 0 ) { - FNT_Size size = (FNT_Size)face->size; - FNT_Font font = size->font; + FNT_Face fnt_face = (FNT_Face)face; + FNT_Font font = fnt_face->font; if ( font ) diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c index 0bd479ce2..fab1450d0 100644 --- a/src/bdf/bdfdrivr.c +++ b/src/bdf/bdfdrivr.c @@ -305,40 +305,48 @@ THE SOFTWARE. if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Exit; - prop = bdf_get_font_property( font, "PIXEL_SIZE" ); - if ( prop != NULL ) - root->available_sizes->height = (short) prop->value.int32; - else { + FT_Bitmap_Size* bsize = root->available_sizes; + + + FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + + prop = bdf_get_font_property( font, "PIXEL_SIZE" ); + if ( prop != NULL ) + bsize->height = (FT_Short)prop->value.int32; + + prop = bdf_get_font_property( font, "AVERAGE_WIDTH" ); + if ( prop != NULL ) + bsize->width = (FT_Short)( ( prop->value.int32 + 5 ) / 10 ); + prop = bdf_get_font_property( font, "POINT_SIZE" ); if ( prop != NULL ) + /* convert from 722,7 decipoints to 72 points per inch */ + bsize->size = + (FT_Pos)( ( prop->value.int32 * 64 * 7200 + 36135L ) / 72270L ); + + prop = bdf_get_font_property( font, "RESOLUTION_X" ); + if ( prop != NULL ) + bsize->x_ppem = + (FT_Pos)( ( prop->value.int32 * bsize->size + 36 ) / 72 ); + + prop = bdf_get_font_property( font, "RESOLUTION_Y" ); + if ( prop != NULL ) + bsize->y_ppem = + (FT_Pos)( ( prop->value.int32 * bsize->size + 36 ) / 72 ); + + if ( bsize->height == 0 ) + bsize->height = + (FT_Short)( ( bsize->size * bsize->y_ppem + 2048 ) / 64 / 64 ); + + if ( bsize->height == 0 ) { - bdf_property_t *yres; - - - yres = bdf_get_font_property( font, "RESOLUTION_Y" ); - if ( yres != NULL ) - { - FT_TRACE4(( "POINT_SIZE: %d RESOLUTION_Y: %d\n", - prop->value.int32, yres->value.int32 )); - root->available_sizes->height = - (FT_Short)( prop->value.int32 * yres->value.int32 / 720 ); - } + /* some fonts have a broken SIZE declaration (jiskan24.bdf) */ + FT_ERROR(( "BDF_Face_Init: reading size\n" )); + bsize->height = (FT_Short)font->point_size; } } - if ( root->available_sizes->height == 0 ) - { - /* some fonts have broken SIZE declaration (jiskan24.bdf) */ - FT_ERROR(( "BDF_Face_Init: reading size\n" )); - root->available_sizes->height = (FT_Short)font->point_size; - } - - /* `width' is just an enumeration value for different bitmap strikes */ - /* in a single font. Since a BDF font has a single strike only, */ - /* make this value the same as the height. */ - root->available_sizes->width = root->available_sizes->height; - /* encoding table */ { bdf_glyph_t* cur = font->glyphs; diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c index 1738840d9..54929b715 100644 --- a/src/cff/cffdrivr.c +++ b/src/cff/cffdrivr.c @@ -165,7 +165,7 @@ /* glyph_index :: The index of the glyph in the font file. */ /* */ /* load_flags :: A flag indicating what to load for this glyph. The */ - /* FTLOAD_??? constants can be used to control the */ + /* FT_LOAD_??? constants can be used to control the */ /* glyph loading process (e.g., whether the outline */ /* should be scaled, whether to load bitmaps or not, */ /* whether to hint the outline, etc). */ @@ -267,7 +267,7 @@ ((FT_Byte*)buffer)[len] = 0; } - FT_FREE ( gname ); + FT_FREE( gname ); error = CFF_Err_Ok; Exit: diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c index 46002f9d8..df8f5fd29 100644 --- a/src/pcf/pcfread.c +++ b/src/pcf/pcfread.c @@ -921,7 +921,7 @@ THE SOFTWARE. PCF_Property prop; - root->num_faces = 1; + root->num_faces = 1; root->face_index = 0; root->face_flags = FT_FACE_FLAG_FIXED_SIZES | FT_FACE_FLAG_HORIZONTAL | @@ -983,33 +983,44 @@ THE SOFTWARE. if ( FT_NEW_ARRAY( root->available_sizes, 1 ) ) goto Exit; - prop = pcf_find_property( face, "PIXEL_SIZE" ); - if ( prop != NULL ) - root->available_sizes->height = (FT_Short)( prop->value.integer ); - else { + FT_Bitmap_Size* bsize = root->available_sizes; + + + FT_MEM_ZERO( bsize, sizeof ( FT_Bitmap_Size ) ); + + prop = pcf_find_property( face, "PIXEL_SIZE" ); + if ( prop != NULL ) + bsize->height = (FT_Short)prop->value.integer; + + prop = pcf_find_property( face, "AVERAGE_WIDTH" ); + if ( prop != NULL ) + bsize->width = (FT_Short)( ( prop->value.integer + 5 ) / 10 ); + prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop != NULL ) - { - PCF_Property yres; + /* convert from 722,7 decipoints to 72 points per inch */ + bsize->size = + (FT_Pos)( ( prop->value.integer * 64 * 7200 + 36135L ) / 72270L ); + prop = pcf_find_property( face, "RESOLUTION_X" ); + if ( prop != NULL ) + bsize->x_ppem = + (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 ); - yres = pcf_find_property( face, "RESOLUTION_Y" ); - if ( yres != NULL ) - root->available_sizes->height = - (FT_Short)( prop->value.integer * - yres->value.integer / 720 ); - } + prop = pcf_find_property( face, "RESOLUTION_Y" ); + if ( prop != NULL ) + bsize->y_ppem = + (FT_Pos)( ( prop->value.integer * bsize->size + 36 ) / 72 ); + + if ( bsize->height == 0 ) + bsize->height = + (FT_Short)( ( bsize->size * bsize->y_ppem + 2048 ) / 64 / 64 ); + + if ( bsize->height == 0 ) + bsize->height = 12; } - if ( root->available_sizes->height == 0 ) - root->available_sizes->height = 12; - - /* `width' is just an enumeration value for different bitmap strikes */ - /* in a single font. Since a PCF font has a single strike only, */ - /* make this value the same as the height. */ - root->available_sizes->width = root->available_sizes->height; - /* set up charset */ { PCF_Property charset_registry = 0, charset_encoding = 0; diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index 796d747cd..bfb079459 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -640,11 +640,23 @@ for ( n = 0 ; n < face->num_sbit_strikes ; n++ ) { - root->available_sizes[n].width = - face->sbit_strikes[n].x_ppem; + FT_Bitmap_Size* bsize = root->available_sizes + n; + TT_SBit_Strike strike = face->sbit_strikes + n; + FT_UShort fupem = face->header.Units_Per_EM; + FT_Short height = face->horizontal.Ascender - + face->horizontal.Descender + + face->horizontal.Line_Gap; + FT_Short avg = face->os2.xAvgCharWidth; - root->available_sizes[n].height = - face->sbit_strikes[n].y_ppem; + + /* assume 72dpi */ + bsize->height = + (FT_Short)( ( height * strike->y_ppem + fupem/2 ) / fupem ); + bsize->width = + (FT_Short)( ( avg * strike->y_ppem + fupem/2 ) / fupem ); + bsize->size = strike->y_ppem << 6; + bsize->x_ppem = strike->x_ppem << 6; + bsize->y_ppem = strike->y_ppem << 6; } } else @@ -663,7 +675,7 @@ if ( has_outline == TRUE ) { /* XXX What about if outline header is missing */ - /* (e.g. sfnt wrapped outline)? */ + /* (e.g. sfnt wrapped bitmap)? */ root->bbox.xMin = face->header.xMin; root->bbox.yMin = face->header.yMin; root->bbox.xMax = face->header.xMax; 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 ) ) - goto Exit; - - /* now read the offset and position of each FNT font */ + if ( face_index >= font_count ) { - FNT_Font cur = face->fonts; - FNT_Font limit = cur + font_count; - - - 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; - } + error = FNT_Err_Bad_Argument; + goto Exit; } + + if ( FT_NEW( face->font ) ) + goto Exit; + + if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) || + FT_FRAME_ENTER( 12 ) ) + goto Fail; + + 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; + + stream->cursor += 8; + FT_FRAME_EXIT(); - /* finally, try to load each font there */ - { - FNT_Font cur = face->fonts; - FNT_Font limit = cur + font_count; - - - 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; + FT_Bitmap_Size* bsize = root->available_sizes; - for ( cur = fonts; cur < limit; cur++, size++ ) - { - size->width = cur->header.pixel_width; - size->height = cur->header.pixel_height; - } + 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,