📄 type1.c
字号:
/* */
/* Just a wrapper around T1_Get_Multi_Master to support the different */
/* arguments needed by the GX var distortable fonts. */
/* */
FT_LOCAL_DEF( FT_Error )
T1_Get_MM_Var( T1_Face face,
FT_MM_Var* *master )
{
FT_Memory memory = face->root.memory;
FT_MM_Var *mmvar;
FT_Multi_Master mmaster;
FT_Error error;
FT_UInt i;
FT_Fixed axiscoords[T1_MAX_MM_AXIS];
PS_Blend blend = face->blend;
error = T1_Get_Multi_Master( face, &mmaster );
if ( error )
goto Exit;
if ( FT_ALLOC( mmvar,
sizeof ( FT_MM_Var ) +
mmaster.num_axis * sizeof ( FT_Var_Axis ) ) )
goto Exit;
mmvar->num_axis = mmaster.num_axis;
mmvar->num_designs = mmaster.num_designs;
mmvar->num_namedstyles = (FT_UInt)-1; /* Does not apply */
mmvar->axis = (FT_Var_Axis*)&mmvar[1];
/* Point to axes after MM_Var struct */
mmvar->namedstyle = NULL;
for ( i = 0 ; i < mmaster.num_axis; ++i )
{
mmvar->axis[i].name = mmaster.axis[i].name;
mmvar->axis[i].minimum = FT_INT_TO_FIXED( mmaster.axis[i].minimum);
mmvar->axis[i].maximum = FT_INT_TO_FIXED( mmaster.axis[i].maximum);
mmvar->axis[i].def = ( mmvar->axis[i].minimum +
mmvar->axis[i].maximum ) / 2;
/* Does not apply. But this value is in range */
mmvar->axis[i].strid = 0xFFFFFFFFUL; /* Does not apply */
mmvar->axis[i].tag = 0xFFFFFFFFUL; /* Does not apply */
if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 )
mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' );
else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 )
mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );
else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )
mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );
}
if ( blend->num_designs == 1U << blend->num_axis )
{
mm_weights_unmap( blend->default_weight_vector,
axiscoords,
blend->num_axis );
for ( i = 0; i < mmaster.num_axis; ++i )
mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],
axiscoords[i] );
}
*master = mmvar;
Exit:
return error;
}
FT_LOCAL_DEF( FT_Error )
T1_Set_MM_Blend( T1_Face face,
FT_UInt num_coords,
FT_Fixed* coords )
{
PS_Blend blend = face->blend;
FT_Error error;
FT_UInt n, m;
error = T1_Err_Invalid_Argument;
if ( blend && blend->num_axis == num_coords )
{
/* recompute the weight vector from the blend coordinates */
error = T1_Err_Ok;
for ( n = 0; n < blend->num_designs; n++ )
{
FT_Fixed result = 0x10000L; /* 1.0 fixed */
for ( m = 0; m < blend->num_axis; m++ )
{
FT_Fixed factor;
/* get current blend axis position */
factor = coords[m];
if ( factor < 0 ) factor = 0;
if ( factor > 0x10000L ) factor = 0x10000L;
if ( ( n & ( 1 << m ) ) == 0 )
factor = 0x10000L - factor;
result = FT_MulFix( result, factor );
}
blend->weight_vector[n] = result;
}
error = T1_Err_Ok;
}
return error;
}
FT_LOCAL_DEF( FT_Error )
T1_Set_MM_Design( T1_Face face,
FT_UInt num_coords,
FT_Long* coords )
{
PS_Blend blend = face->blend;
FT_Error error;
FT_UInt n, p;
error = T1_Err_Invalid_Argument;
if ( blend && blend->num_axis == num_coords )
{
/* compute the blend coordinates through the blend design map */
FT_Fixed final_blends[T1_MAX_MM_DESIGNS];
for ( n = 0; n < blend->num_axis; n++ )
{
FT_Long design = coords[n];
FT_Fixed the_blend;
PS_DesignMap map = blend->design_map + n;
FT_Long* designs = map->design_points;
FT_Fixed* blends = map->blend_points;
FT_Int before = -1, after = -1;
for ( p = 0; p < (FT_UInt)map->num_points; p++ )
{
FT_Long p_design = designs[p];
/* exact match? */
if ( design == p_design )
{
the_blend = blends[p];
goto Found;
}
if ( design < p_design )
{
after = p;
break;
}
before = p;
}
/* now interpolate if necessary */
if ( before < 0 )
the_blend = blends[0];
else if ( after < 0 )
the_blend = blends[map->num_points - 1];
else
the_blend = FT_MulDiv( design - designs[before],
blends [after] - blends [before],
designs[after] - designs[before] );
Found:
final_blends[n] = the_blend;
}
error = T1_Set_MM_Blend( face, num_coords, final_blends );
}
return error;
}
/*************************************************************************/
/* */
/* Just a wrapper around T1_Set_MM_Design to support the different */
/* arguments needed by the GX var distortable fonts. */
/* */
FT_LOCAL_DEF( FT_Error )
T1_Set_Var_Design( T1_Face face,
FT_UInt num_coords,
FT_Fixed* coords )
{
FT_Long lcoords[4]; /* maximum axis count is 4 */
FT_UInt i;
FT_Error error;
error = T1_Err_Invalid_Argument;
if ( num_coords <= 4 && num_coords > 0 )
{
for ( i = 0; i < num_coords; ++i )
lcoords[i] = FT_FIXED_TO_INT( coords[i] );
error = T1_Set_MM_Design( face, num_coords, lcoords );
}
return error;
}
FT_LOCAL_DEF( void )
T1_Done_Blend( T1_Face face )
{
FT_Memory memory = face->root.memory;
PS_Blend blend = face->blend;
if ( blend )
{
FT_UInt num_designs = blend->num_designs;
FT_UInt num_axis = blend->num_axis;
FT_UInt n;
/* release design pos table */
FT_FREE( blend->design_pos[0] );
for ( n = 1; n < num_designs; n++ )
blend->design_pos[n] = 0;
/* release blend `private' and `font info' dictionaries */
FT_FREE( blend->privates[1] );
FT_FREE( blend->font_infos[1] );
FT_FREE( blend->bboxes[1] );
for ( n = 0; n < num_designs; n++ )
{
blend->privates [n] = 0;
blend->font_infos[n] = 0;
blend->bboxes [n] = 0;
}
/* release weight vectors */
FT_FREE( blend->weight_vector );
blend->default_weight_vector = 0;
/* release axis names */
for ( n = 0; n < num_axis; n++ )
FT_FREE( blend->axis_names[n] );
/* release design map */
for ( n = 0; n < num_axis; n++ )
{
PS_DesignMap dmap = blend->design_map + n;
FT_FREE( dmap->design_points );
dmap->num_points = 0;
}
FT_FREE( face->blend );
}
}
static void
parse_blend_axis_types( T1_Face face,
T1_Loader loader )
{
T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
FT_Int n, num_axis;
FT_Error error = T1_Err_Ok;
PS_Blend blend;
FT_Memory memory;
/* take an array of objects */
T1_ToTokenArray( &loader->parser, axis_tokens,
T1_MAX_MM_AXIS, &num_axis );
if ( num_axis < 0 )
{
error = T1_Err_Ignore;
goto Exit;
}
if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
{
FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n",
num_axis ));
error = T1_Err_Invalid_File_Format;
goto Exit;
}
/* allocate blend if necessary */
error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
if ( error )
goto Exit;
blend = face->blend;
memory = face->root.memory;
/* each token is an immediate containing the name of the axis */
for ( n = 0; n < num_axis; n++ )
{
T1_Token token = axis_tokens + n;
FT_Byte* name;
FT_PtrDist len;
/* skip first slash, if any */
if ( token->start[0] == '/' )
token->start++;
len = token->limit - token->start;
if ( len == 0 )
{
error = T1_Err_Invalid_File_Format;
goto Exit;
}
if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )
goto Exit;
name = (FT_Byte*)blend->axis_names[n];
FT_MEM_COPY( name, token->start, len );
name[len] = 0;
}
Exit:
loader->parser.root.error = error;
}
static void
parse_blend_design_positions( T1_Face face,
T1_Loader loader )
{
T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
FT_Int num_designs;
FT_Int num_axis;
T1_Parser parser = &loader->parser;
FT_Error error = T1_Err_Ok;
PS_Blend blend;
/* get the array of design tokens -- compute number of designs */
T1_ToTokenArray( parser, design_tokens,
T1_MAX_MM_DESIGNS, &num_designs );
if ( num_designs < 0 )
{
error = T1_Err_Ignore;
goto Exit;
}
if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
{
FT_ERROR(( "parse_blend_design_positions:" ));
FT_ERROR(( " incorrect number of designs: %d\n",
num_designs ));
error = T1_Err_Invalid_File_Format;
goto Exit;
}
{
FT_Byte* old_cursor = parser->root.cursor;
FT_Byte* old_limit = parser->root.limit;
FT_Int n;
blend = face->blend;
num_axis = 0; /* make compiler happy */
for ( n = 0; n < num_designs; n++ )
{
T1_TokenRec axis_tokens[T1_MAX_MM_DESIGNS];
T1_Token token;
FT_Int axis, n_axis;
/* read axis/coordinates tokens */
token = design_tokens + n;
parser->root.cursor = token->start;
parser->root.limit = token->limit;
T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
if ( n == 0 )
{
num_axis = n_axis;
error = t1_allocate_blend( face, num_designs, num_axis );
if ( error )
goto Exit;
blend = face->blend;
}
else if ( n_axis != num_axis )
{
FT_ERROR(( "parse_blend_design_positions: incorrect table\n" ));
error = T1_Err_Invalid_File_Format;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -