📄 ttgxvar.c
字号:
goto Exit; } table_start = FT_Stream_FTell( stream ); if ( FT_GET_LONG() != 0x00010000L ) { FT_TRACE2(( "bad table version!\n" )); error = TT_Err_Ok; goto FExit; } if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) goto FExit; tupleCount = FT_GET_USHORT(); offsetToData = table_start + FT_GET_USHORT(); /* The documentation implies there are flags packed into the */ /* tuplecount, but John Jenkins says that shared points don't apply */ /* to `cvar', and no other flags are defined. */ for ( i = 0; i < ( tupleCount & 0xFFF ); ++i ) { FT_UInt tupleDataSize; FT_UInt tupleIndex; FT_Fixed apply; tupleDataSize = FT_GET_USHORT(); tupleIndex = FT_GET_USHORT(); /* There is no provision here for a global tuple coordinate section, */ /* so John says. There are no tuple indices, just embedded tuples. */ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; ++j ) tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ /* short frac to fixed */ } else { /* skip this tuple; it makes no sense */ if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) for ( j = 0; j < 2 * blend->num_axis; ++j ) (void)FT_GET_SHORT(); offsetToData += tupleDataSize; continue; } if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { for ( j = 0; j < blend->num_axis; ++j ) im_start_coords[j] = FT_GET_SHORT() << 2; for ( j = 0; j < blend->num_axis; ++j ) im_end_coords[j] = FT_GET_SHORT() << 2; } apply = ft_var_apply_tuple( blend, (FT_UShort)tupleIndex, tuple_coords, im_start_coords, im_end_coords ); if ( /* tuple isn't active for our blend */ apply == 0 || /* global points not allowed, */ /* if they aren't local, makes no sense */ !( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) ) { offsetToData += tupleDataSize; continue; } here = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, offsetToData ); localpoints = ft_var_readpackedpoints( stream, &point_count ); deltas = ft_var_readpackeddeltas( stream, point_count == 0 ? face->cvt_size : point_count ); if ( localpoints == NULL || deltas == NULL ) /* failure, ignore it */; else if ( localpoints == ALL_POINTS ) { /* this means that there are deltas for every entry in cvt */ for ( j = 0; j < face->cvt_size; ++j ) face->cvt[j] = (FT_Short)( face->cvt[j] + FT_MulFix( deltas[j], apply ) ); } else { for ( j = 0; j < point_count; ++j ) { int pindex = localpoints[j]; face->cvt[pindex] = (FT_Short)( face->cvt[pindex] + FT_MulFix( deltas[j], apply ) ); } } if ( localpoints != ALL_POINTS ) FT_FREE( localpoints ); FT_FREE( deltas ); offsetToData += tupleDataSize; FT_Stream_SeekSet( stream, here ); } FExit: FT_FRAME_EXIT(); Exit: FT_FREE( tuple_coords ); FT_FREE( im_start_coords ); FT_FREE( im_end_coords ); return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Vary_Get_Glyph_Deltas */ /* */ /* <Description> */ /* Load the appropriate deltas for the current glyph. */ /* */ /* <Input> */ /* face :: A handle to the target face object. */ /* */ /* glyph_index :: The index of the glyph being modified. */ /* */ /* n_points :: The number of the points in the glyph, including */ /* phantom points. */ /* */ /* <Output> */ /* deltas :: The array of points to change. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) TT_Vary_Get_Glyph_Deltas( TT_Face face, FT_UInt glyph_index, FT_Vector* *deltas, FT_UInt n_points ) { FT_Stream stream = face->root.stream; FT_Memory memory = stream->memory; GX_Blend blend = face->blend; FT_Vector* delta_xy; FT_Error error; FT_ULong glyph_start; FT_UInt tupleCount; FT_ULong offsetToData; FT_ULong here; FT_UInt i, j; FT_Fixed* tuple_coords = NULL; FT_Fixed* im_start_coords = NULL; FT_Fixed* im_end_coords = NULL; FT_UInt point_count, spoint_count = 0; FT_UShort* sharedpoints = NULL; FT_UShort* localpoints = NULL; FT_UShort* points; FT_Short *deltas_x, *deltas_y; if ( !face->doblend || blend == NULL ) return TT_Err_Invalid_Argument; /* to be freed by the caller */ if ( FT_NEW_ARRAY( delta_xy, n_points ) ) goto Exit; *deltas = delta_xy; if ( glyph_index >= blend->gv_glyphcnt || blend->glyphoffsets[glyph_index] == blend->glyphoffsets[glyph_index + 1] ) return TT_Err_Ok; /* no variation data for this glyph */ if ( FT_STREAM_SEEK( blend->glyphoffsets[glyph_index] ) || FT_FRAME_ENTER( blend->glyphoffsets[glyph_index + 1] - blend->glyphoffsets[glyph_index] ) ) goto Fail1; glyph_start = FT_Stream_FTell( stream ); /* each set of glyph variation data is formatted similarly to `cvar' */ /* (except we get shared points and global tuples) */ if ( FT_NEW_ARRAY( tuple_coords, blend->num_axis ) || FT_NEW_ARRAY( im_start_coords, blend->num_axis ) || FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) goto Fail2; tupleCount = FT_GET_USHORT(); offsetToData = glyph_start + FT_GET_USHORT(); if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) { here = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, offsetToData ); sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); offsetToData = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, here ); } for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); ++i ) { FT_UInt tupleDataSize; FT_UInt tupleIndex; FT_Fixed apply; tupleDataSize = FT_GET_USHORT(); tupleIndex = FT_GET_USHORT(); if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; ++j ) tuple_coords[j] = FT_GET_SHORT() << 2; /* convert from */ /* short frac to fixed */ } else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) { error = TT_Err_Invalid_Table; goto Fail3; } else { FT_MEM_COPY( tuple_coords, &blend->tuplecoords[(tupleIndex & 0xFFF) * blend->num_axis], blend->num_axis * sizeof ( FT_Fixed ) ); } if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { for ( j = 0; j < blend->num_axis; ++j ) im_start_coords[j] = FT_GET_SHORT() << 2; for ( j = 0; j < blend->num_axis; ++j ) im_end_coords[j] = FT_GET_SHORT() << 2; } apply = ft_var_apply_tuple( blend, (FT_UShort)tupleIndex, tuple_coords, im_start_coords, im_end_coords ); if ( apply == 0 ) /* tuple isn't active for our blend */ { offsetToData += tupleDataSize; continue; } here = FT_Stream_FTell( stream ); if ( tupleIndex & GX_TI_PRIVATE_POINT_NUMBERS ) { FT_Stream_SeekSet( stream, offsetToData ); localpoints = ft_var_readpackedpoints( stream, &point_count ); points = localpoints; } else { points = sharedpoints; point_count = spoint_count; } deltas_x = ft_var_readpackeddeltas( stream, point_count == 0 ? n_points : point_count ); deltas_y = ft_var_readpackeddeltas( stream, point_count == 0 ? n_points : point_count ); if ( points == NULL || deltas_y == NULL || deltas_x == NULL ) ; /* failure, ignore it */ else if ( points == ALL_POINTS ) { /* this means that there are deltas for every point in the glyph */ for ( j = 0; j < n_points; ++j ) { delta_xy[j].x += FT_MulFix( deltas_x[j], apply ); delta_xy[j].y += FT_MulFix( deltas_y[j], apply ); } } else { for ( j = 0; j < point_count; ++j ) { delta_xy[localpoints[j]].x += FT_MulFix( deltas_x[j], apply ); delta_xy[localpoints[j]].y += FT_MulFix( deltas_y[j], apply ); } } if ( localpoints != ALL_POINTS ) FT_FREE( localpoints ); FT_FREE( deltas_x ); FT_FREE( deltas_y ); offsetToData += tupleDataSize; FT_Stream_SeekSet( stream, here ); } Fail3: FT_FREE( tuple_coords ); FT_FREE( im_start_coords ); FT_FREE( im_end_coords ); Fail2: FT_FRAME_EXIT(); Fail1: if ( error ) { FT_FREE( delta_xy ); *deltas = NULL; } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* tt_done_blend */ /* */ /* <Description> */ /* Frees the blend internal data structure. */ /* */ FT_LOCAL_DEF( void ) tt_done_blend( FT_Memory memory, GX_Blend blend ) { if ( blend != NULL ) { FT_UInt i; FT_FREE( blend->normalizedcoords ); FT_FREE( blend->mmvar ); if ( blend->avar_segment != NULL ) { for ( i = 0; i < blend->num_axis; ++i ) FT_FREE( blend->avar_segment[i].correspondence ); FT_FREE( blend->avar_segment ); } FT_FREE( blend->tuplecoords ); FT_FREE( blend->glyphoffsets ); FT_FREE( blend ); } }#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT *//* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -