📄 ttload.c
字号:
/* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_face_load_names( TT_Face face, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_ULong table_pos, table_len; FT_ULong storage_start, storage_limit; FT_UInt count; TT_NameTable table; static const FT_Frame_Field name_table_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_NameTableRec FT_FRAME_START( 6 ), FT_FRAME_USHORT( format ), FT_FRAME_USHORT( numNameRecords ), FT_FRAME_USHORT( storageOffset ), FT_FRAME_END }; static const FT_Frame_Field name_record_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_NameEntryRec /* 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 }; table = &face->name_table; table->stream = stream; 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 = FT_STREAM_POS(); if ( FT_STREAM_READ_FIELDS( name_table_fields, table ) ) goto Exit; /* Some popular Asian fonts have an invalid `storageOffset' value */ /* (it should be at least "6 + 12*num_names"). However, the string */ /* offsets, computed as "storageOffset + entry->stringOffset", are */ /* valid pointers within the name table... */ /* */ /* We thus can't check `storageOffset' right now. */ /* */ storage_start = table_pos + 6 + 12*table->numNameRecords; storage_limit = table_pos + table_len; if ( storage_start > storage_limit ) { FT_ERROR(( "tt_face_load_names: invalid `name' table\n" )); error = SFNT_Err_Name_Table_Missing; goto Exit; } /* Allocate the array of name records. */ count = table->numNameRecords; table->numNameRecords = 0; if ( FT_NEW_ARRAY( table->names, count ) || FT_FRAME_ENTER( count * 12 ) ) goto Exit; /* Load the name records and determine how much storage is needed */ /* to hold the strings themselves. */ { TT_NameEntryRec* entry = table->names; for ( ; count > 0; count-- ) { if ( FT_STREAM_READ_FIELDS( name_record_fields, entry ) ) continue; /* check that the name is not empty */ if ( entry->stringLength == 0 ) continue; /* check that the name string is within the table */ entry->stringOffset += table_pos + table->storageOffset; if ( entry->stringOffset < storage_start || entry->stringOffset + entry->stringLength > storage_limit ) { /* invalid entry - ignore it */ entry->stringOffset = 0; entry->stringLength = 0; continue; } entry++; } table->numNameRecords = (FT_UInt)( entry - table->names ); } FT_FRAME_EXIT(); FT_TRACE2(( "loaded\n" )); /* everything went well, update face->num_names */ face->num_names = (FT_UShort) table->numNameRecords; Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_free_names */ /* */ /* <Description> */ /* Frees the name records. */ /* */ /* <Input> */ /* face :: A handle to the target face object. */ /* */ FT_LOCAL_DEF( void ) tt_face_free_names( TT_Face face ) { FT_Memory memory = face->root.driver->root.memory; TT_NameTable table = &face->name_table; TT_NameEntry entry = table->names; FT_UInt count = table->numNameRecords; for ( ; count > 0; count--, entry++ ) { FT_FREE( entry->string ); entry->stringLength = 0; } /* free strings table */ FT_FREE( table->names ); table->numNameRecords = 0; table->format = 0; table->storageOffset = 0; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_load_cmap */ /* */ /* <Description> */ /* Loads the cmap directory in a face object. The cmaps itselves are */ /* loaded on demand in the `ttcmap.c' module. */ /* */ /* <Input> */ /* face :: A handle to the target face object. */ /* */ /* stream :: A handle to the input stream. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_face_load_cmap( TT_Face face, FT_Stream stream ) { FT_Error error; error = face->goto_table( face, TTAG_cmap, stream, &face->cmap_size ); if ( error ) { FT_TRACE2(( "No `cmap' table in font !\n" )); error = SFNT_Err_CMap_Table_Missing; goto Exit; } if ( !FT_FRAME_EXTRACT( face->cmap_size, face->cmap_table ) ) FT_TRACE2(( "`cmap' table loaded\n" )); else { FT_ERROR(( "`cmap' table is too short!\n" )); face->cmap_size = 0; } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_load_os2 */ /* */ /* <Description> */ /* Loads the OS2 table. */ /* */ /* <Input> */ /* face :: A handle to the target face object. */ /* */ /* stream :: A handle to the input stream. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_face_load_os2( TT_Face face, FT_Stream stream ) { FT_Error error; TT_OS2* os2; const FT_Frame_Field os2_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_OS2 FT_FRAME_START( 78 ), FT_FRAME_USHORT( version ), FT_FRAME_SHORT ( xAvgCharWidth ), FT_FRAME_USHORT( usWeightClass ), FT_FRAME_USHORT( usWidthClass ), FT_FRAME_SHORT ( fsType ), FT_FRAME_SHORT ( ySubscriptXSize ), FT_FRAME_SHORT ( ySubscriptYSize ), FT_FRAME_SHORT ( ySubscriptXOffset ), FT_FRAME_SHORT ( ySubscriptYOffset ), FT_FRAME_SHORT ( ySuperscriptXSize ), FT_FRAME_SHORT ( ySuperscriptYSize ), FT_FRAME_SHORT ( ySuperscriptXOffset ), FT_FRAME_SHORT ( ySuperscriptYOffset ), FT_FRAME_SHORT ( yStrikeoutSize ), FT_FRAME_SHORT ( yStrikeoutPosition ), FT_FRAME_SHORT ( sFamilyClass ), FT_FRAME_BYTE ( panose[0] ), FT_FRAME_BYTE ( panose[1] ), FT_FRAME_BYTE ( panose[2] ), FT_FRAME_BYTE ( panose[3] ), FT_FRAME_BYTE ( panose[4] ), FT_FRAME_BYTE ( panose[5] ), FT_FRAME_BYTE ( panose[6] ), FT_FRAME_BYTE ( panose[7] ), FT_FRAME_BYTE ( panose[8] ), FT_FRAME_BYTE ( panose[9] ), FT_FRAME_ULONG ( ulUnicodeRange1 ), FT_FRAME_ULONG ( ulUnicodeRange2 ), FT_FRAME_ULONG ( ulUnicodeRange3 ), FT_FRAME_ULONG ( ulUnicodeRange4 ), FT_FRAME_BYTE ( achVendID[0] ), FT_FRAME_BYTE ( achVendID[1] ), FT_FRAME_BYTE ( achVendID[2] ), FT_FRAME_BYTE ( achVendID[3] ), FT_FRAME_USHORT( fsSelection ), FT_FRAME_USHORT( usFirstCharIndex ), FT_FRAME_USHORT( usLastCharIndex ), FT_FRAME_SHORT ( sTypoAscender ), FT_FRAME_SHORT ( sTypoDescender ), FT_FRAME_SHORT ( sTypoLineGap ), FT_FRAME_USHORT( usWinAscent ), FT_FRAME_USHORT( usWinDescent ), FT_FRAME_END }; const FT_Frame_Field os2_fields_extra[] = { FT_FRAME_START( 8 ), FT_FRAME_ULONG( ulCodePageRange1 ), FT_FRAME_ULONG( ulCodePageRange2 ), FT_FRAME_END }; const FT_Frame_Field os2_fields_extra2[] = { FT_FRAME_START( 10 ), FT_FRAME_SHORT ( sxHeight ), FT_FRAME_SHORT ( sCapHeight ), FT_FRAME_USHORT( usDefaultChar ), FT_FRAME_USHORT( usBreakChar ), FT_FRAME_USHORT( usMaxContext ), FT_FRAME_END }; FT_TRACE2(( "OS/2 Table " )); /* We now support old Mac fonts where the OS/2 table doesn't */ /* exist. Simply put, we set the `version' field to 0xFFFF */ /* and test this value each time we need to access the table. */ error = face->goto_table( face, TTAG_OS2, stream, 0 ); if ( error ) { FT_TRACE2(( "is missing!\n" )); face->os2.version = 0xFFFFU; error = SFNT_Err_Ok; goto Exit; } os2 = &face->os2; if ( FT_STREAM_READ_FIELDS( os2_fields, os2 ) ) goto Exit; os2->ulCodePageRange1 = 0; os2->ulCodePageRange2 = 0; os2->sxHeight = 0; os2->sCapHeight = 0; os2->usDefaultChar = 0; os2->usBreakChar = 0; os2->usMaxContext = 0; if ( os2->version >= 0x0001 ) { /* only version 1 tables */ if ( FT_STREAM_READ_FIELDS( os2_fields_extra, os2 ) ) goto Exit; if ( os2->version >= 0x0002 ) { /* only version 2 tables */ if ( FT_STREAM_READ_FIELDS( os2_fields_extra2, os2 ) ) goto Exit; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -