📄 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 + -