From 0a9d06e2b5cf75c3d6ba958026bfdf4745f576d6 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Wed, 18 Mar 2009 22:20:25 -0700 Subject: auto import //branches/master/...@140412 --- src/sfnt/sfobjs.c | 278 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 146 insertions(+), 132 deletions(-) (limited to 'src/sfnt/sfobjs.c') diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index c25b87d..c826b92 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -123,14 +123,20 @@ /* */ /* nameid :: The name id of the name record to return. */ /* */ + /* */ + /* name :: The address of a string pointer. NULL if no name is */ + /* present. */ + /* */ /* */ - /* Character string. NULL if no name is present. */ + /* FreeType error code. 0 means success. */ /* */ - static FT_String* - tt_face_get_name( TT_Face face, - FT_UShort nameid ) + static FT_Error + tt_face_get_name( TT_Face face, + FT_UShort nameid, + FT_String** name ) { FT_Memory memory = face->root.memory; + FT_Error error = SFNT_Err_Ok; FT_String* result = NULL; FT_UShort n; TT_NameEntryRec* rec; @@ -145,6 +151,8 @@ TT_NameEntry_ConvertFunc convert; + FT_ASSERT( name ); + rec = face->name_table.names; for ( n = 0; n < face->num_names; n++, rec++ ) { @@ -256,11 +264,8 @@ { if ( rec->string == NULL ) { - FT_Error error = SFNT_Err_Ok; FT_Stream stream = face->name_table.stream; - FT_UNUSED( error ); - if ( FT_QNEW_ARRAY ( rec->string, rec->stringLength ) || FT_STREAM_SEEK( rec->stringOffset ) || @@ -277,7 +282,8 @@ } Exit: - return result; + *name = result; + return error; } @@ -363,11 +369,12 @@ if ( FT_READ_ULONG( tag ) ) return error; - if ( tag != 0x00010000UL && - tag != TTAG_ttcf && - tag != FT_MAKE_TAG( 'O', 'T', 'T', 'O' ) && - tag != TTAG_true && - tag != 0x00020000UL ) + if ( tag != 0x00010000UL && + tag != TTAG_ttcf && + tag != TTAG_OTTO && + tag != TTAG_true && + tag != TTAG_typ1 && + tag != 0x00020000UL ) return SFNT_Err_Unknown_File_Format; face->ttc_header.tag = TTAG_ttcf; @@ -401,7 +408,7 @@ face->ttc_header.version = 1 << 16; face->ttc_header.count = 1; - if ( FT_NEW( face->ttc_header.offsets) ) + if ( FT_NEW( face->ttc_header.offsets ) ) return error; face->ttc_header.offsets[0] = offset; @@ -451,7 +458,7 @@ face_index = 0; if ( face_index >= face->ttc_header.count ) - return SFNT_Err_Bad_Argument; + return SFNT_Err_Invalid_Argument; if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) return error; @@ -461,7 +468,8 @@ if ( error ) return error; - face->root.num_faces = face->ttc_header.count; + face->root.num_faces = face->ttc_header.count; + face->root.face_index = face_index; return error; } @@ -498,6 +506,13 @@ FT_TRACE3(( "\n" )); \ } while ( 0 ) +#define GET_NAME( id, field ) \ + do { \ + error = tt_face_get_name( face, TT_NAME_ID_##id, field ); \ + if ( error ) \ + goto Exit; \ + } while ( 0 ) + FT_LOCAL_DEF( FT_Error ) sfnt_load_face( FT_Stream stream, @@ -506,7 +521,10 @@ FT_Int num_params, FT_Parameter* params ) { - FT_Error error, psnames_error; + FT_Error error; +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES + FT_Error psnames_error; +#endif FT_Bool has_outline; FT_Bool is_apple_sbit; @@ -581,7 +599,10 @@ /* don't check for errors */ LOAD_( name ); LOAD_( post ); + +#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES psnames_error = error; +#endif /* do not load the metrics headers and tables if this is an Apple */ /* sbit font file */ @@ -660,19 +681,20 @@ face->os2.version = 0xFFFFU; } - } /* the optional tables */ - /* embedded bitmap support. */ + /* embedded bitmap support */ if ( sfnt->load_eblc ) { LOAD_( eblc ); if ( error ) { - /* return an error if this font file has no outlines */ - if ( error == SFNT_Err_Table_Missing && has_outline ) + /* a font which contains neither bitmaps nor outlines is */ + /* still valid (although rather useless in most cases); */ + /* however, you can find such stripped fonts in PDFs */ + if ( error == SFNT_Err_Table_Missing ) error = SFNT_Err_Ok; else goto Exit; @@ -692,59 +714,38 @@ LOAD_( gasp ); LOAD_( kern ); - error = SFNT_Err_Ok; - face->root.num_glyphs = face->max_profile.numGlyphs; -#if 0 /* Bit 8 of the `fsSelection' field in the `OS/2' table denotes */ /* a WWS-only font face. `WWS' stands for `weight', width', and */ /* `slope', a term used by Microsoft's Windows Presentation */ - /* Foundation (WPF). This flag will be introduced in version */ - /* 1.5 of the OpenType specification (but is already in use). */ + /* Foundation (WPF). This flag has been introduced in version */ + /* 1.5 of the OpenType specification (May 2008). */ if ( face->os2.version != 0xFFFFU && face->os2.fsSelection & 256 ) -#endif { - face->root.family_name = - tt_face_get_name( face, TT_NAME_ID_PREFERRED_FAMILY ); + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) - face->root.family_name = - tt_face_get_name( face, TT_NAME_ID_FONT_FAMILY ); + GET_NAME( FONT_FAMILY, &face->root.family_name ); - face->root.style_name = - tt_face_get_name( face, TT_NAME_ID_PREFERRED_SUBFAMILY ); + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) - face->root.style_name = - tt_face_get_name( face, TT_NAME_ID_FONT_SUBFAMILY ); + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); } -#if 0 else { - /* Support for `name' table ID 21 (WWS family) and 22 (WWS */ - /* subfamily) is still under consideration by Microsoft and */ - /* not implemented in the current version of WPF. */ - - face->root.family_name = - tt_face_get_name( face, TT_NAME_ID_WWS_FAMILY ); + GET_NAME( WWS_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) - face->root.family_name = - tt_face_get_name( face, TT_NAME_ID_PREFERRED_FAMILY ); + GET_NAME( PREFERRED_FAMILY, &face->root.family_name ); if ( !face->root.family_name ) - face->root.family_name = - tt_face_get_name( face, TT_NAME_ID_FONT_FAMILY ); + GET_NAME( FONT_FAMILY, &face->root.family_name ); - face->root.style_name = - tt_face_get_name( face, TT_NAME_ID_WWS_SUBFAMILY ); + GET_NAME( WWS_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) - face->root.style_name = - tt_face_get_name( face, TT_NAME_ID_PREFERRED_SUBFAMILY ); + GET_NAME( PREFERRED_SUBFAMILY, &face->root.style_name ); if ( !face->root.style_name ) - face->root.style_name = - tt_face_get_name( face, TT_NAME_ID_FONT_SUBFAMILY ); + GET_NAME( FONT_SUBFAMILY, &face->root.style_name ); } -#endif - /* now set up root fields */ { @@ -801,10 +802,9 @@ flags = 0; if ( has_outline == TRUE && face->os2.version != 0xFFFFU ) { - /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ - /* indicates an oblique font face. This flag will be */ - /* introduced in version 1.5 of the OpenType specification (but */ - /* is already in use). */ + /* We have an OS/2 table; use the `fsSelection' field. Bit 9 */ + /* indicates an oblique font face. This flag has been */ + /* introduced in version 1.5 of the OpenType specification. */ if ( face->os2.fsSelection & 512 ) /* bit 9 */ flags |= FT_STYLE_FLAG_ITALIC; @@ -817,6 +817,7 @@ else { /* this is an old Mac font, use the header field */ + if ( face->header.Mac_Style & 1 ) flags |= FT_STYLE_FLAG_BOLD; @@ -861,12 +862,78 @@ } } +#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS + + /* + * Now allocate the root array of FT_Bitmap_Size records and + * populate them. Unfortunately, it isn't possible to indicate bit + * depths in the FT_Bitmap_Size record. This is a design error. + */ + { + FT_UInt i, count; + + +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS + count = face->sbit_num_strikes; +#else + count = (FT_UInt)face->num_sbit_strikes; +#endif + + if ( count > 0 ) + { + FT_Memory memory = face->root.stream->memory; + FT_UShort em_size = face->header.Units_Per_EM; + FT_Short avgwidth = face->os2.xAvgCharWidth; + FT_Size_Metrics metrics; + + + if ( em_size == 0 || face->os2.version == 0xFFFFU ) + { + avgwidth = 0; + em_size = 1; + } + + if ( FT_NEW_ARRAY( root->available_sizes, count ) ) + goto Exit; + + for ( i = 0; i < count; i++ ) + { + FT_Bitmap_Size* bsize = root->available_sizes + i; + + + error = sfnt->load_strike_metrics( face, i, &metrics ); + if ( error ) + goto Exit; + + bsize->height = (FT_Short)( metrics.height >> 6 ); + bsize->width = (FT_Short)( + ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); + + bsize->x_ppem = metrics.x_ppem << 6; + bsize->y_ppem = metrics.y_ppem << 6; + + /* assume 72dpi */ + bsize->size = metrics.y_ppem << 6; + } + + root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; + root->num_fixed_sizes = (FT_Int)count; + } + } + +#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ + + /* a font with no bitmaps and no outlines is scalable; */ + /* it has only empty glyphs then */ + if ( !FT_HAS_FIXED_SIZES( root ) && !FT_IS_SCALABLE( root ) ) + root->face_flags |= FT_FACE_FLAG_SCALABLE; + /*********************************************************************/ /* */ /* Set up metrics. */ /* */ - if ( has_outline == TRUE ) + if ( FT_IS_SCALABLE( root ) ) { /* XXX What about if outline header is missing */ /* (e.g. sfnt wrapped bitmap)? */ @@ -919,10 +986,9 @@ /* this computation is based on various versions of Times New Roman */ if ( face->horizontal.Line_Gap == 0 ) root->height = (FT_Short)( ( root->height * 115 + 50 ) / 100 ); -#endif +#endif /* 0 */ #if 0 - /* some fonts have the OS/2 "sTypoAscender", "sTypoDescender" & */ /* "sTypoLineGap" fields set to 0, like ARIALNB.TTF */ if ( face->os2.version != 0xFFFFU && root->ascender ) @@ -937,80 +1003,21 @@ if ( height > root->height ) root->height = height; } - #endif /* 0 */ - root->max_advance_width = face->horizontal.advance_Width_Max; + root->max_advance_width = face->horizontal.advance_Width_Max; + root->max_advance_height = (FT_Short)( face->vertical_info + ? face->vertical.advance_Height_Max + : root->height ); - root->max_advance_height = (FT_Short)( face->vertical_info - ? face->vertical.advance_Height_Max - : root->height ); - - root->underline_position = face->postscript.underlinePosition; + /* See http://www.microsoft.com/OpenType/OTSpec/post.htm -- */ + /* Adjust underline position from top edge to centre of */ + /* stroke to convert TrueType meaning to FreeType meaning. */ + root->underline_position = face->postscript.underlinePosition - + face->postscript.underlineThickness / 2; root->underline_thickness = face->postscript.underlineThickness; } -#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS - - /* - * Now allocate the root array of FT_Bitmap_Size records and - * populate them. Unfortunately, it isn't possible to indicate bit - * depths in the FT_Bitmap_Size record. This is a design error. - */ - { - FT_UInt i, count; - - -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS - count = face->sbit_num_strikes; -#else - count = (FT_UInt)face->num_sbit_strikes; -#endif - - if ( count > 0 ) - { - FT_Memory memory = face->root.stream->memory; - FT_UShort em_size = face->header.Units_Per_EM; - FT_Short avgwidth = face->os2.xAvgCharWidth; - FT_Size_Metrics metrics; - - - if ( em_size == 0 || face->os2.version == 0xFFFFU ) - { - avgwidth = 0; - em_size = 1; - } - - if ( FT_NEW_ARRAY( root->available_sizes, count ) ) - goto Exit; - - for ( i = 0; i < count; i++ ) - { - FT_Bitmap_Size* bsize = root->available_sizes + i; - - - error = sfnt->load_strike_metrics( face, i, &metrics ); - if ( error ) - goto Exit; - - bsize->height = (FT_Short)( metrics.height >> 6 ); - bsize->width = (FT_Short)( - ( avgwidth * metrics.x_ppem + em_size / 2 ) / em_size ); - - bsize->x_ppem = metrics.x_ppem << 6; - bsize->y_ppem = metrics.y_ppem << 6; - - /* assume 72dpi */ - bsize->size = metrics.y_ppem << 6; - } - - root->face_flags |= FT_FACE_FLAG_FIXED_SIZES; - root->num_fixed_sizes = (FT_Int)count; - } - } - -#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ - } Exit: @@ -1022,14 +1029,21 @@ #undef LOAD_ #undef LOADM_ +#undef GET_NAME FT_LOCAL_DEF( void ) sfnt_done_face( TT_Face face ) { - FT_Memory memory = face->root.memory; - SFNT_Service sfnt = (SFNT_Service)face->sfnt; + FT_Memory memory; + SFNT_Service sfnt; + + + if ( !face ) + return; + memory = face->root.memory; + sfnt = (SFNT_Service)face->sfnt; if ( sfnt ) { @@ -1068,7 +1082,7 @@ } /* freeing the horizontal metrics */ -#if !defined FT_CONFIG_OPTION_OLD_INTERNALS +#ifndef FT_CONFIG_OPTION_OLD_INTERNALS { FT_Stream stream = FT_FACE_STREAM( face ); -- cgit v1.2.3