📄 ttload.c
字号:
tt_face_load_any( TT_Face face, FT_ULong tag, FT_Long offset, FT_Byte* buffer, FT_ULong* length ) { FT_Error error; FT_Stream stream; TT_Table table; FT_ULong size; if ( tag != 0 ) { /* look for tag in font directory */ table = tt_face_lookup_table( face, tag ); if ( !table ) { error = SFNT_Err_Table_Missing; goto Exit; } offset += table->Offset; size = table->Length; } else /* tag == 0 -- the user wants to access the font file directly */ size = face->root.stream->size; if ( length && *length == 0 ) { *length = size; return SFNT_Err_Ok; } if ( length ) size = *length; stream = face->root.stream; /* the `if' is syntactic sugar for picky compilers */ if ( FT_STREAM_READ_AT( offset, buffer, size ) ) goto Exit; Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_load_generic_header */ /* */ /* <Description> */ /* Loads the TrueType table `head' or `bhed'. */ /* */ /* <Input> */ /* face :: A handle to the target face object. */ /* */ /* stream :: The input stream. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ static FT_Error tt_face_load_generic_header( TT_Face face, FT_Stream stream, FT_ULong tag ) { FT_Error error; TT_Header* header; static const FT_Frame_Field header_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_Header FT_FRAME_START( 54 ), FT_FRAME_ULONG ( Table_Version ), FT_FRAME_ULONG ( Font_Revision ), FT_FRAME_LONG ( CheckSum_Adjust ), FT_FRAME_LONG ( Magic_Number ), FT_FRAME_USHORT( Flags ), FT_FRAME_USHORT( Units_Per_EM ), FT_FRAME_LONG ( Created[0] ), FT_FRAME_LONG ( Created[1] ), FT_FRAME_LONG ( Modified[0] ), FT_FRAME_LONG ( Modified[1] ), FT_FRAME_SHORT ( xMin ), FT_FRAME_SHORT ( yMin ), FT_FRAME_SHORT ( xMax ), FT_FRAME_SHORT ( yMax ), FT_FRAME_USHORT( Mac_Style ), FT_FRAME_USHORT( Lowest_Rec_PPEM ), FT_FRAME_SHORT ( Font_Direction ), FT_FRAME_SHORT ( Index_To_Loc_Format ), FT_FRAME_SHORT ( Glyph_Data_Format ), FT_FRAME_END }; error = face->goto_table( face, tag, stream, 0 ); if ( error ) goto Exit; header = &face->header; if ( FT_STREAM_READ_FIELDS( header_fields, header ) ) goto Exit; FT_TRACE3(( "Units per EM: %4u\n", header->Units_Per_EM )); FT_TRACE3(( "IndexToLoc: %4d\n", header->Index_To_Loc_Format )); Exit: return error; } FT_LOCAL_DEF( FT_Error ) tt_face_load_head( TT_Face face, FT_Stream stream ) { return tt_face_load_generic_header( face, stream, TTAG_head ); }#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS FT_LOCAL_DEF( FT_Error ) tt_face_load_bhed( TT_Face face, FT_Stream stream ) { return tt_face_load_generic_header( face, stream, TTAG_bhed ); }#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */ /*************************************************************************/ /* */ /* <Function> */ /* tt_face_load_max_profile */ /* */ /* <Description> */ /* Loads the maximum profile into a face object. */ /* */ /* <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_face_load_maxp( TT_Face face, FT_Stream stream ) { FT_Error error; TT_MaxProfile* maxProfile = &face->max_profile; const FT_Frame_Field maxp_fields[] = {#undef FT_STRUCTURE#define FT_STRUCTURE TT_MaxProfile FT_FRAME_START( 6 ), FT_FRAME_LONG ( version ), FT_FRAME_USHORT( numGlyphs ), FT_FRAME_END }; const FT_Frame_Field maxp_fields_extra[] = { FT_FRAME_START( 26 ), FT_FRAME_USHORT( maxPoints ), FT_FRAME_USHORT( maxContours ), FT_FRAME_USHORT( maxCompositePoints ), FT_FRAME_USHORT( maxCompositeContours ), FT_FRAME_USHORT( maxZones ), FT_FRAME_USHORT( maxTwilightPoints ), FT_FRAME_USHORT( maxStorage ), FT_FRAME_USHORT( maxFunctionDefs ), FT_FRAME_USHORT( maxInstructionDefs ), FT_FRAME_USHORT( maxStackElements ), FT_FRAME_USHORT( maxSizeOfInstructions ), FT_FRAME_USHORT( maxComponentElements ), FT_FRAME_USHORT( maxComponentDepth ), FT_FRAME_END }; error = face->goto_table( face, TTAG_maxp, stream, 0 ); if ( error ) goto Exit; if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) ) goto Exit; maxProfile->maxPoints = 0; maxProfile->maxContours = 0; maxProfile->maxCompositePoints = 0; maxProfile->maxCompositeContours = 0; maxProfile->maxZones = 0; maxProfile->maxTwilightPoints = 0; maxProfile->maxStorage = 0; maxProfile->maxFunctionDefs = 0; maxProfile->maxInstructionDefs = 0; maxProfile->maxStackElements = 0; maxProfile->maxSizeOfInstructions = 0; maxProfile->maxComponentElements = 0; maxProfile->maxComponentDepth = 0; if ( maxProfile->version >= 0x10000L ) { if ( FT_STREAM_READ_FIELDS( maxp_fields_extra, maxProfile ) ) goto Exit; /* XXX: an adjustment that is necessary to load certain */ /* broken fonts like `Keystrokes MT' :-( */ /* */ /* We allocate 64 function entries by default when */ /* the maxFunctionDefs field is null. */ if ( maxProfile->maxFunctionDefs == 0 ) maxProfile->maxFunctionDefs = 64; } FT_TRACE3(( "numGlyphs: %u\n", maxProfile->numGlyphs )); Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_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_face_load_name( 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; error = face->goto_table( face, TTAG_name, stream, &table_len ); if ( error ) 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(( "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(); /* 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_name( 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; if ( table->names ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -