📄 ttload.c
字号:
/* For safety, we set the field to 0! */ /* */ error = face->goto_table( face, TTAG_vmtx, stream, &table_len ); if ( error ) { /* Set the number_Of_VMetrics to 0! */ FT_TRACE2(( " no vertical header in file.\n" )); face->vertical.number_Of_VMetrics = 0; error = TT_Err_Ok; 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 = TT_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(( "!! more metrics than glyphs!\n" )); error = ( vertical ? TT_Err_Invalid_Vert_Metrics : TT_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, nothing serious will happen */ if ( num_shorts > num_shorts_checked && num_shorts_checked > 0 ) { TT_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> */ /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC TT_Error TT_Load_Metrics_Header( TT_Face face, FT_Stream stream, TT_Bool vertical ) { TT_Error error; TT_HoriHeader* header;#ifdef READ_FIELDS const FT_Frame_Field metrics_header_fields[] = { { ft_frame_start, 0, 36 }, FT_FRAME_ULONG( TT_HoriHeader, Version ), FT_FRAME_SHORT( TT_HoriHeader, Ascender ), FT_FRAME_SHORT( TT_HoriHeader, Descender ), FT_FRAME_SHORT( TT_HoriHeader, Line_Gap ), FT_FRAME_USHORT( TT_HoriHeader, advance_Width_Max ), FT_FRAME_SHORT( TT_HoriHeader, min_Left_Side_Bearing ), FT_FRAME_SHORT( TT_HoriHeader, min_Right_Side_Bearing ), FT_FRAME_SHORT( TT_HoriHeader, xMax_Extent ), FT_FRAME_SHORT( TT_HoriHeader, caret_Slope_Rise ), FT_FRAME_SHORT( TT_HoriHeader, caret_Slope_Run ), FT_FRAME_SHORT( TT_HoriHeader, Reserved[0] ), FT_FRAME_SHORT( TT_HoriHeader, Reserved[1] ), FT_FRAME_SHORT( TT_HoriHeader, Reserved[2] ), FT_FRAME_SHORT( TT_HoriHeader, Reserved[3] ), FT_FRAME_SHORT( TT_HoriHeader, Reserved[4] ), FT_FRAME_SHORT( TT_HoriHeader, metric_Data_Format ), FT_FRAME_USHORT( TT_HoriHeader, number_Of_HMetrics ), { ft_frame_end } };#endif 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 = TT_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 = TT_Err_Horiz_Header_Missing; goto Exit; } header = &face->horizontal; }#ifdef READ_FIELDS if ( READ_Fields( metrics_header_fields, header ) ) goto Exit;#else if ( ACCESS_Frame( 36L ) ) goto Exit; header->Version = GET_ULong(); header->Ascender = GET_Short(); header->Descender = GET_Short(); header->Line_Gap = GET_Short(); header->advance_Width_Max = GET_UShort(); header->min_Left_Side_Bearing = GET_Short(); header->min_Right_Side_Bearing = GET_Short(); header->xMax_Extent = GET_Short(); header->caret_Slope_Rise = GET_Short(); header->caret_Slope_Run = GET_Short(); header->Reserved[0] = GET_Short(); /* this is caret_Offset for vertical headers */ header->Reserved[1] = GET_Short(); header->Reserved[2] = GET_Short(); header->Reserved[3] = GET_Short(); header->Reserved[4] = GET_Short(); header->metric_Data_Format = GET_Short(); header->number_Of_HMetrics = GET_UShort(); FORGET_Frame();#endif 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> */ /* TrueType error code. 0 means success. */ /* */ LOCAL_FUNC TT_Error TT_Load_Names( TT_Face face, FT_Stream stream ) { TT_Error error; FT_Memory memory = stream->memory; TT_ULong table_pos, table_len; TT_ULong storageSize; TT_NameTable* names;#ifdef READ_FIELDS const FT_Frame_Field name_table_fields[] = { { ft_frame_start, 0, 6 }, FT_FRAME_USHORT( TT_NameTable, format ), FT_FRAME_USHORT( TT_NameTable, numNameRecords ), FT_FRAME_USHORT( TT_NameTable, storageOffset ), { ft_frame_end } }; const FT_Frame_Field name_record_fields[] = { FT_FRAME_USHORT( TT_NameRec, platformID ), FT_FRAME_USHORT( TT_NameRec, encodingID ), FT_FRAME_USHORT( TT_NameRec, languageID ), FT_FRAME_USHORT( TT_NameRec, nameID ), FT_FRAME_USHORT( TT_NameRec, stringLength ), FT_FRAME_USHORT( TT_NameRec, stringOffset ), { ft_frame_end } };#endif 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 = TT_Err_Name_Table_Missing; goto Exit; } table_pos = FILE_Pos(); names = &face->name_table;#ifdef READ_FIELDS if ( READ_Fields( name_table_fields, names ) ) goto Exit;#else if ( ACCESS_Frame( 6L ) ) goto Exit; /* Load the initial names data. */ names->format = GET_UShort(); names->numNameRecords = GET_UShort(); names->storageOffset = GET_UShort(); FORGET_Frame();#endif /* Allocate the array of name records. */ if ( ALLOC_ARRAY( names->names, names->numNameRecords, TT_NameRec ) || ACCESS_Frame( names->numNameRecords * 12L ) ) goto Exit; /* Load the name records and determine how much storage is needed */ /* to hold the strings themselves. */ { TT_NameRec* cur = names->names; TT_NameRec* limit = cur + names->numNameRecords; storageSize = 0; for ( ; cur < limit; cur ++ ) { TT_ULong upper;#ifdef READ_FIELDS (void)READ_Fields( name_record_fields, cur );#else cur->platformID = GET_UShort(); cur->encodingID = GET_UShort(); cur->languageID = GET_UShort(); cur->nameID = GET_UShort(); cur->stringLength = GET_UShort(); cur->stringOffset = GET_UShort();#endif upper = (TT_ULong)(cur->stringOffset + cur->stringLength); if ( upper > storageSize ) storageSize = upper; } } FORGET_Frame(); if (storageSize > 0) { /* allocate the name storage area in memory, then read it */ if ( ALLOC( names->storage, storageSize ) || FILE_Read_At( table_pos + names->storageOffset, (void*)names->storage, storageSize ) ) goto Exit; /* Go through and assign the string pointers to the name records. */ { TT_NameRec* cur = names->names; TT_NameRec* limit = cur + names->numNameRecords;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -