📄 t1load.c
字号:
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;
goto Exit;
}
/* now read each axis token into the design position */
for ( axis = 0; axis < n_axis; axis++ )
{
T1_Token token2 = axis_tokens + axis;
parser->root.cursor = token2->start;
parser->root.limit = token2->limit;
blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
}
}
loader->parser.root.cursor = old_cursor;
loader->parser.root.limit = old_limit;
}
Exit:
loader->parser.root.error = error;
}
static void
parse_blend_design_map( T1_Face face,
T1_Loader loader )
{
FT_Error error = T1_Err_Ok;
T1_Parser parser = &loader->parser;
PS_Blend blend;
T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
FT_Int n, num_axis;
FT_Byte* old_cursor;
FT_Byte* old_limit;
FT_Memory memory = face->root.memory;
T1_ToTokenArray( 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_design_map: incorrect number of axes: %d\n",
num_axis ));
error = T1_Err_Invalid_File_Format;
goto Exit;
}
old_cursor = parser->root.cursor;
old_limit = parser->root.limit;
error = t1_allocate_blend( face, 0, num_axis );
if ( error )
goto Exit;
blend = face->blend;
/* now read each axis design map */
for ( n = 0; n < num_axis; n++ )
{
PS_DesignMap map = blend->design_map + n;
T1_Token axis_token;
T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS];
FT_Int p, num_points;
axis_token = axis_tokens + n;
parser->root.cursor = axis_token->start;
parser->root.limit = axis_token->limit;
T1_ToTokenArray( parser, point_tokens,
T1_MAX_MM_MAP_POINTS, &num_points );
if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )
{
FT_ERROR(( "parse_blend_design_map: incorrect table\n" ));
error = T1_Err_Invalid_File_Format;
goto Exit;
}
/* allocate design map data */
if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) )
goto Exit;
map->blend_points = map->design_points + num_points;
map->num_points = (FT_Byte)num_points;
for ( p = 0; p < num_points; p++ )
{
T1_Token point_token;
point_token = point_tokens + p;
/* don't include delimiting brackets */
parser->root.cursor = point_token->start + 1;
parser->root.limit = point_token->limit - 1;
map->design_points[p] = T1_ToInt( parser );
map->blend_points [p] = T1_ToFixed( parser, 0 );
}
}
parser->root.cursor = old_cursor;
parser->root.limit = old_limit;
Exit:
parser->root.error = error;
}
static void
parse_weight_vector( T1_Face face,
T1_Loader loader )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -