📄 ttload.c
字号:
goto Exit; } num_longs = face->vertical.number_Of_VMetrics; longs = (TT_LongMetrics**)&face->vertical.long_metrics; shorts = (TT_ShortMetrics**)&face->vertical.short_metrics; } else { error = face->goto_table( face, TTAG_hmtx, stream, &table_len ); if ( error ) { FT_ERROR(( " no horizontal metrics in file!\n" )); error = SFNT_Err_Hmtx_Table_Missing; goto Exit; } num_longs = face->horizontal.number_Of_HMetrics; longs = (TT_LongMetrics**)&face->horizontal.long_metrics; shorts = (TT_ShortMetrics**)&face->horizontal.short_metrics; } /* never trust derived values */ num_shorts = face->max_profile.numGlyphs - num_longs; num_shorts_checked = ( table_len - num_longs * 4L ) / 2; if ( num_shorts < 0 ) { FT_ERROR(( "TT_Load_%s_Metrics: more metrics than glyphs!\n", vertical ? "Vertical" : "Horizontal" )); error = vertical ? SFNT_Err_Invalid_Vert_Metrics : SFNT_Err_Invalid_Horiz_Metrics; goto Exit; } if ( ALLOC_ARRAY( *longs, num_longs, TT_LongMetrics ) || ALLOC_ARRAY( *shorts, num_shorts, TT_ShortMetrics ) ) goto Exit; if ( ACCESS_Frame( table_len ) ) goto Exit; { TT_LongMetrics* cur = *longs; TT_LongMetrics* limit = cur + num_longs; for ( ; cur < limit; cur++ ) { cur->advance = GET_UShort(); cur->bearing = GET_Short(); } } /* do we have an inconsistent number of metric values? */ { TT_ShortMetrics* cur = *shorts; TT_ShortMetrics* limit = cur + MIN( num_shorts, num_shorts_checked ); for ( ; cur < limit; cur++ ) *cur = GET_Short(); /* we fill up the missing left side bearings with the */ /* last valid value. Since this will occur for buggy CJK */ /* fonts usually only, nothing serious will happen */ if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 ) { FT_Short val = (*shorts)[num_shorts_checked - 1]; limit = *shorts + num_shorts; for ( ; cur < limit; cur++ ) *cur = val; } } FORGET_Frame(); FT_TRACE2(( "loaded\n" )); Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_Metrics_Header */ /* */ /* <Description> */ /* Loads the horizontal or vertical header in a face object. */ /* */ /* <Input> */ /* face :: A handle to the target face object. */ /* stream :: The input stream. */ /* vertical :: A boolean flag. If set, load vertical metrics. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF FT_Error TT_Load_Metrics_Header( TT_Face face, FT_Stream stream, FT_Bool vertical ) { FT_Error error; TT_HoriHeader* header; const FT_Frame_Field metrics_header_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_HoriHeader FT_FRAME_START( 36 ), FT_FRAME_ULONG ( Version ), FT_FRAME_SHORT ( Ascender ), FT_FRAME_SHORT ( Descender ), FT_FRAME_SHORT ( Line_Gap ), FT_FRAME_USHORT( advance_Width_Max ), FT_FRAME_SHORT ( min_Left_Side_Bearing ), FT_FRAME_SHORT ( min_Right_Side_Bearing ), FT_FRAME_SHORT ( xMax_Extent ), FT_FRAME_SHORT ( caret_Slope_Rise ), FT_FRAME_SHORT ( caret_Slope_Run ), FT_FRAME_SHORT ( caret_Offset ), FT_FRAME_SHORT ( Reserved[0] ), FT_FRAME_SHORT ( Reserved[1] ), FT_FRAME_SHORT ( Reserved[2] ), FT_FRAME_SHORT ( Reserved[3] ), FT_FRAME_SHORT ( metric_Data_Format ), FT_FRAME_USHORT( number_Of_HMetrics ), FT_FRAME_END }; FT_TRACE2(( vertical ? "Vertical header " : "Horizontal header " )); if ( vertical ) { face->vertical_info = 0; /* The vertical header table is optional, so return quietly if */ /* we don't find it. */ error = face->goto_table( face, TTAG_vhea, stream, 0 ); if ( error ) { error = SFNT_Err_Ok; goto Exit; } face->vertical_info = 1; header = (TT_HoriHeader*)&face->vertical; } else { /* The horizontal header is mandatory; return an error if we */ /* don't find it. */ error = face->goto_table( face, TTAG_hhea, stream, 0 ); if ( error ) { error = SFNT_Err_Horiz_Header_Missing; goto Exit; } header = &face->horizontal; } if ( READ_Fields( metrics_header_fields, header ) ) goto Exit; header->long_metrics = NULL; header->short_metrics = NULL; FT_TRACE2(( "loaded\n" )); /* Now try to load the corresponding metrics */ error = TT_Load_Metrics( face, stream, vertical ); Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Load_Names */ /* */ /* <Description> */ /* Loads the name records. */ /* */ /* <Input> */ /* face :: A handle to the target face object. */ /* stream :: The input stream. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF FT_Error TT_Load_Names( TT_Face face, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_ULong table_pos, table_len; FT_ULong storageSize, storageOffset; FT_Byte* storage; TT_NameTable* table; TT_NameRec* names; FT_UInt num_names; const FT_Frame_Field name_table_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_NameTable FT_FRAME_START( 6 ), FT_FRAME_USHORT( format ), FT_FRAME_USHORT( numNameRecords ), FT_FRAME_USHORT( storageOffset ), FT_FRAME_END }; const FT_Frame_Field name_record_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_NameRec /* no FT_FRAME_START */ FT_FRAME_USHORT( platformID ), FT_FRAME_USHORT( encodingID ), FT_FRAME_USHORT( languageID ), FT_FRAME_USHORT( nameID ), FT_FRAME_USHORT( stringLength ), FT_FRAME_USHORT( stringOffset ), FT_FRAME_END }; FT_TRACE2(( "Names " )); error = face->goto_table( face, TTAG_name, stream, &table_len ); if ( error ) { /* The name table is required so indicate failure. */ FT_TRACE2(( "is missing!\n" )); error = SFNT_Err_Name_Table_Missing; goto Exit; } table_pos = FILE_Pos(); table = &face->name_table; if ( READ_Fields( name_table_fields, table ) ) goto Exit; num_names = (FT_UInt) table->numNameRecords; storageOffset = table->storageOffset; storageSize = (FT_ULong)( table_len - storageOffset ); /* check the storage offset field */ if ( storageOffset < 6 + 12*num_names || table_len < storageOffset ) { FT_TRACE2(( "table is broken.. Ignoring !!\n" )); table->numNameRecords = 0; table->storageOffset = 0; error = SFNT_Err_Name_Table_Missing; goto Exit; } /* Allocate the array of name records. */ if ( ALLOC( table->names, num_names*sizeof(table->names[0]) + storageSize ) || ACCESS_Frame( num_names*12L ) ) goto Exit; names = table->names; storage = (FT_Byte*)(names + num_names); /* Load the name records and determine how much storage is needed */ /* to hold the strings themselves. */ { TT_NameRec* cur = names; TT_NameRec* limit = cur + num_names; for ( ; cur < limit; cur ++ ) { if ( READ_Fields( name_record_fields, cur ) ) break; /* check the fields */ if ( cur->stringOffset + cur->stringLength <= (FT_Long)storageSize ) cur->string = storage + cur->stringOffset; else { /* that's an invalid entry !! */ cur->stringOffset = 0; cur->string = NULL; } } } FORGET_Frame(); if ( error ) goto Exit; storageOffset -= 6 + 12*num_names; if ( FILE_Skip( storageOffset ) || FILE_Read( storage, storageSize ) ) goto Exit; /* Print Name Record Table in case of debugging */ if ( FT_TRACE_TEST(3) ) { TT_NameRec* cur = table->names; TT_NameRec* limit = cur + num_names; for ( ; cur < limit; cur++ ) { FT_UInt j; printf( "%2d %2d %4x %2d:", cur->platformID, cur->encodingID, cur->languageID, cur->nameID ); /* printf name id */ switch ( cur->nameID ) { case 0: printf( " copyright" ); break; case 1: printf( " font_family" ); break; case 2: printf( " style" ); break; case 3: printf( " unique_id" ); break; case 4: printf( " full_name" ); break; case 5: printf( " version" ); break; case 6: printf( " postscript" ); break; case 7: printf( " trademark" ); break; case 8: printf( " manufacturer" ); break; case 9: printf( " designer" ); break; case 10: printf( " description" ); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -