📄 ttgxvar.c
字号:
if ( master != NULL ) { FT_UInt n; if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) ) goto Exit; FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len ); mmvar->axis = (FT_Var_Axis*)&(mmvar[1]); mmvar->namedstyle = (FT_Var_Named_Style*)&(mmvar->axis[mmvar->num_axis]); next_coords = (FT_Fixed*)&(mmvar->namedstyle[mmvar->num_namedstyles]); for ( n = 0; n < mmvar->num_namedstyles; ++n ) { mmvar->namedstyle[n].coords = next_coords; next_coords += mmvar->num_axis; } a = mmvar->axis; next_name = (FT_String*)next_coords; for ( n = 0; n < mmvar->num_axis; ++n ) { a->name = next_name; /* standard PostScript names for some standard apple tags */ if ( a->tag == TTAG_wght ) a->name = (char *)"Weight"; else if ( a->tag == TTAG_wdth ) a->name = (char *)"Width"; else if ( a->tag == TTAG_opsz ) a->name = (char *)"OpticalSize"; else if ( a->tag == TTAG_slnt ) a->name = (char *)"Slant"; next_name += 5; ++a; } *master = mmvar; } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Set_MM_Blend */ /* */ /* <Description> */ /* Set the blend (normalized) coordinates for this instance of the */ /* font. Check that the `gvar' table is reasonable and does some */ /* initial preparation. */ /* */ /* <InOut> */ /* face :: The font. */ /* Initialize the blend structure with `gvar' data. */ /* */ /* <Input> */ /* num_coords :: Must be the axis count of the font. */ /* */ /* coords :: An array of num_coords, each between [-1,1]. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) TT_Set_MM_Blend( TT_Face face, FT_UInt num_coords, FT_Fixed* coords ) { FT_Error error = TT_Err_Ok; GX_Blend blend; FT_MM_Var* mmvar; FT_UInt i; FT_Memory memory = face->root.memory; enum { mcvt_retain, mcvt_modify, mcvt_load } manageCvt; face->doblend = FALSE; if ( face->blend == NULL ) { if ( (error = TT_Get_MM_Var( face, NULL)) != 0 ) goto Exit; } blend = face->blend; mmvar = blend->mmvar; if ( num_coords != mmvar->num_axis ) { error = TT_Err_Invalid_Argument; goto Exit; } for ( i = 0; i < num_coords; ++i ) if ( coords[i] < -0x00010000L || coords[i] > 0x00010000L ) { error = TT_Err_Invalid_Argument; goto Exit; } if ( blend->glyphoffsets == NULL ) if ( (error = ft_var_load_gvar( face )) != 0 ) goto Exit; if ( blend->normalizedcoords == NULL ) { if ( FT_NEW_ARRAY( blend->normalizedcoords, num_coords ) ) goto Exit; manageCvt = mcvt_modify; /* If we have not set the blend coordinates before this, then the */ /* cvt table will still be what we read from the `cvt ' table and */ /* we don't need to reload it. We may need to change it though... */ } else { for ( i = 0; i < num_coords && blend->normalizedcoords[i] == coords[i]; ++i ); if ( i == num_coords ) manageCvt = mcvt_retain; else manageCvt = mcvt_load; /* If we don't change the blend coords then we don't need to do */ /* anything to the cvt table. It will be correct. Otherwise we */ /* no longer have the original cvt (it was modified when we set */ /* the blend last time), so we must reload and then modify it. */ } blend->num_axis = num_coords; FT_MEM_COPY( blend->normalizedcoords, coords, num_coords * sizeof ( FT_Fixed ) ); face->doblend = TRUE; if ( face->cvt != NULL ) { switch ( manageCvt ) { case mcvt_load: /* The cvt table has been loaded already; every time we change the */ /* blend we may need to reload and remodify the cvt table. */ FT_FREE( face->cvt ); face->cvt = NULL; tt_face_load_cvt( face, face->root.stream ); break; case mcvt_modify: /* The original cvt table is in memory. All we need to do is */ /* apply the `cvar' table (if any). */ tt_face_vary_cvt( face, face->root.stream ); break; case mcvt_retain: /* The cvt table is correct for this set of coordinates. */ break; } } Exit: return error; } /*************************************************************************/ /* */ /* <Function> */ /* TT_Set_Var_Design */ /* */ /* <Description> */ /* Set the coordinates for the instance, measured in the user */ /* coordinate system. Parse the `avar' table (if present) to convert */ /* from user to normalized coordinates. */ /* */ /* <InOut> */ /* face :: The font face. */ /* Initialize the blend struct with `gvar' data. */ /* */ /* <Input> */ /* num_coords :: This must be the axis count of the font. */ /* */ /* coords :: A coordinate array with `num_coords' elements. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ FT_LOCAL_DEF( FT_Error ) TT_Set_Var_Design( TT_Face face, FT_UInt num_coords, FT_Fixed* coords ) { FT_Error error = TT_Err_Ok; FT_Fixed* normalized = NULL; GX_Blend blend; FT_MM_Var* mmvar; FT_UInt i, j; FT_Var_Axis* a; GX_AVarSegment av; FT_Memory memory = face->root.memory; if ( face->blend == NULL ) { if ( (error = TT_Get_MM_Var( face, NULL )) != 0 ) goto Exit; } blend = face->blend; mmvar = blend->mmvar; if ( num_coords != mmvar->num_axis ) { error = TT_Err_Invalid_Argument; goto Exit; } /* Axis normalization is a two stage process. First we normalize */ /* based on the [min,def,max] values for the axis to be [-1,0,1]. */ /* Then, if there's an `avar' table, we renormalize this range. */ if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) ) goto Exit; a = mmvar->axis; for ( i = 0; i < mmvar->num_axis; ++i, ++a ) { if ( coords[i] > a->maximum || coords[i] < a->minimum ) { error = TT_Err_Invalid_Argument; goto Exit; } if ( coords[i] < a->def ) { normalized[i] = -FT_MulDiv( coords[i] - a->def, 0x10000L, a->minimum - a->def ); } else if ( a->maximum == a->def ) normalized[i] = 0; else { normalized[i] = FT_MulDiv( coords[i] - a->def, 0x10000L, a->maximum - a->def ); } } if ( !blend->avar_checked ) ft_var_load_avar( face ); if ( blend->avar_segment != NULL ) { av = blend->avar_segment; for ( i = 0; i < mmvar->num_axis; ++i, ++av ) { for ( j = 1; j < (FT_UInt)av->pairCount; ++j ) if ( normalized[i] < av->correspondence[j].fromCoord ) { normalized[i] = FT_MulDiv( FT_MulDiv( normalized[i] - av->correspondence[j - 1].fromCoord, 0x10000L, av->correspondence[j].fromCoord - av->correspondence[j - 1].fromCoord ), av->correspondence[j].toCoord - av->correspondence[j - 1].toCoord, 0x10000L ) + av->correspondence[j - 1].toCoord; break; } } } error = TT_Set_MM_Blend( face, num_coords, normalized ); Exit: FT_FREE( normalized ); return error; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** GX VAR PARSING ROUTINES *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /* */ /* <Function> */ /* tt_face_vary_cvt */ /* */ /* <Description> */ /* Modify the loaded cvt table according to the `cvar' table and the */ /* font's blend. */ /* */ /* <InOut> */ /* face :: A handle to the target face object. */ /* */ /* <Input> */ /* stream :: A handle to the input stream. */ /* */ /* <Return> */ /* FreeType error code. 0 means success. */ /* */ /* Most errors are ignored. It is perfectly valid not to have a */ /* `cvar' table even if there is a `gvar' and `fvar' table. */ /* */ FT_LOCAL_DEF( FT_Error ) tt_face_vary_cvt( TT_Face face, FT_Stream stream ) { FT_Error error; FT_Memory memory = stream->memory; FT_ULong table_start; FT_ULong table_len; 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; GX_Blend blend = face->blend; FT_UInt point_count; FT_UShort* localpoints; FT_Short* deltas; FT_TRACE2(( "CVAR " )); if ( blend == NULL ) { FT_TRACE2(( "no blend specified!\n" )); error = TT_Err_Ok; goto Exit; } if ( face->cvt == NULL ) { FT_TRACE2(( "no `cvt ' table!\n" )); error = TT_Err_Ok; goto Exit; } error = face->goto_table( face, TTAG_cvar, stream, &table_len ); if ( error ) { FT_TRACE2(( "is missing!\n" )); error = TT_Err_Ok; goto Exit; } if ( FT_FRAME_ENTER( table_len ) ) { error = TT_Err_Ok;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -