📄 ttload.c
字号:
{#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 }; FT_TRACE2(( "Load_TT_MaxProfile: %08p\n", face )); error = face->goto_table( face, TTAG_maxp, stream, 0 ); if ( error ) goto Exit; if ( FT_STREAM_READ_FIELDS( maxp_fields, maxProfile ) ) goto Exit; face->root.num_glyphs = maxProfile->numGlyphs; 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; face->root.internal->max_points = (FT_UShort)FT_MAX( maxProfile->maxCompositePoints, maxProfile->maxPoints ); face->root.internal->max_contours = (FT_Short)FT_MAX( maxProfile->maxCompositeContours, maxProfile->maxContours ); face->max_components = (FT_ULong)maxProfile->maxComponentElements + maxProfile->maxComponentDepth; /* XXX: some fonts have maxComponents set to 0; we will */ /* then use 16 of them by default. */ if ( face->max_components == 0 ) face->max_components = 16; /* We also increase maxPoints and maxContours in order to support */ /* some broken fonts. */ face->root.internal->max_points += (FT_UShort)8; face->root.internal->max_contours += (FT_Short) 4; } FT_TRACE2(( "MAXP loaded.\n" )); Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_face_load_metrics */ /* */ /* <Description> */ /* Loads the horizontal or vertical metrics table into 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. */ /* */#ifdef FT_OPTIMIZE_MEMORY static FT_Error tt_face_load_metrics( TT_Face face, FT_Stream stream, FT_Bool vertical ) { FT_Error error; FT_ULong table_size; FT_Byte** ptable; FT_ULong* ptable_size; FT_TRACE2(( "TT_Load_%s_Metrics: %08p\n", vertical ? "Vertical" : "Horizontal", face )); if ( vertical ) { ptable = &face->vert_metrics; ptable_size = &face->vert_metrics_size; /* The table is optional, quit silently if it wasn't found. */ /* */ /* XXX: Some fonts have a valid vertical header with a non-null */ /* `number_of_VMetrics' fields, but no corresponding `vmtx' */ /* table to get the metrics from (e.g. mingliu). */ /* */ /* For safety, we set the field to 0! */ /* */ error = face->goto_table( face, TTAG_vmtx, stream, &table_size ); if ( error ) { /* Set number_Of_VMetrics to 0! */ FT_TRACE2(( " no vertical header in file.\n" )); error = SFNT_Err_Ok; goto Exit; } } else { ptable = &face->horz_metrics; ptable_size = &face->horz_metrics_size; error = face->goto_table( face, TTAG_hmtx, stream, &table_size ); if ( error ) {#ifdef FT_CONFIG_OPTION_INCREMENTAL /* If this is an incrementally loaded font and there are */ /* overriding metrics, tolerate a missing `hmtx' table. */ if ( face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs-> get_glyph_metrics ) { face->horizontal.number_Of_HMetrics = 0; error = SFNT_Err_Ok; goto Exit; }#endif FT_ERROR(( " no horizontal metrics in file!\n" )); error = SFNT_Err_Hmtx_Table_Missing; goto Exit; } } if ( FT_FRAME_EXTRACT( table_size, *ptable ) ) goto Exit; *ptable_size = table_size; Exit: return error; }#else /* !OPTIMIZE_MEMORY */ static FT_Error tt_face_load_metrics( TT_Face face, FT_Stream stream, FT_Bool vertical ) { FT_Error error; FT_Memory memory = stream->memory; FT_ULong table_len; FT_Long num_shorts, num_longs, num_shorts_checked; TT_LongMetrics * longs; TT_ShortMetrics** shorts; FT_TRACE2(( "TT_Load_%s_Metrics: %08p\n", vertical ? "Vertical" : "Horizontal", face )); if ( vertical ) { /* The table is optional, quit silently if it wasn't found. */ /* */ /* XXX: Some fonts have a valid vertical header with a non-null */ /* `number_of_VMetrics' fields, but no corresponding `vmtx' */ /* table to get the metrics from (e.g. mingliu). */ /* */ /* For safety, we set the field to 0! */ /* */ error = face->goto_table( face, TTAG_vmtx, stream, &table_len ); if ( error ) { /* Set number_Of_VMetrics to 0! */ FT_TRACE2(( " no vertical header in file.\n" )); face->vertical.number_Of_VMetrics = 0; error = SFNT_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 ) {#ifdef FT_CONFIG_OPTION_INCREMENTAL /* If this is an incrementally loaded font and there are */ /* overriding metrics, tolerate a missing `hmtx' table. */ if ( face->root.internal->incremental_interface && face->root.internal->incremental_interface->funcs-> get_glyph_metrics ) { face->horizontal.number_Of_HMetrics = 0; error = SFNT_Err_Ok; goto Exit; }#endif 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 ( FT_QNEW_ARRAY( *longs, num_longs ) || FT_QNEW_ARRAY( *shorts, num_shorts ) ) goto Exit; if ( FT_FRAME_ENTER( table_len ) ) goto Exit; { TT_LongMetrics cur = *longs; TT_LongMetrics limit = cur + num_longs; for ( ; cur < limit; cur++ ) { cur->advance = FT_GET_USHORT(); cur->bearing = FT_GET_SHORT(); } } /* do we have an inconsistent number of metric values? */ { TT_ShortMetrics* cur = *shorts; TT_ShortMetrics* limit = cur + FT_MIN( num_shorts, num_shorts_checked ); for ( ; cur < limit; cur++ ) *cur = FT_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; } } FT_FRAME_EXIT(); FT_TRACE2(( "loaded\n" )); Exit: return error; }#endif /* !FT_OPTIMIZE_METRICS */ /*************************************************************************/ /* */ /* <Function> */ /* tt_face_load_metrics_header */ /* */ /* <Description> */ /* Loads the horizontal or vertical header in a face object. */ /* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -