📄 t1decode.c
字号:
case 6:
op = op_hlineto;
break;
case 7:
op = op_vlineto;
break;
case 8:
op = op_rrcurveto;
break;
case 9:
op = op_closepath;
break;
case 10:
op = op_callsubr;
break;
case 11:
op = op_return;
break;
case 13:
op = op_hsbw;
break;
case 14:
op = op_endchar;
break;
case 15: /* undocumented, obsolete operator */
op = op_none;
break;
case 21:
op = op_rmoveto;
break;
case 22:
op = op_hmoveto;
break;
case 30:
op = op_vhcurveto;
break;
case 31:
op = op_hvcurveto;
break;
case 12:
if ( ip > limit )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid escape (12+EOF)\n" ));
goto Syntax_Error;
}
switch ( *ip++ )
{
case 0:
op = op_dotsection;
break;
case 1:
op = op_vstem3;
break;
case 2:
op = op_hstem3;
break;
case 6:
op = op_seac;
break;
case 7:
op = op_sbw;
break;
case 12:
op = op_div;
break;
case 16:
op = op_callothersubr;
break;
case 17:
op = op_pop;
break;
case 33:
op = op_setcurrentpoint;
break;
default:
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid escape (12+%d)\n",
ip[-1] ));
goto Syntax_Error;
}
break;
case 255: /* four bytes integer */
if ( ip + 4 > limit )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"unexpected EOF in integer\n" ));
goto Syntax_Error;
}
value = (FT_Int32)( ((FT_Long)ip[0] << 24) |
((FT_Long)ip[1] << 16) |
((FT_Long)ip[2] << 8 ) |
ip[3] );
ip += 4;
break;
default:
if ( ip[-1] >= 32 )
{
if ( ip[-1] < 247 )
value = (FT_Long)ip[-1] - 139;
else
{
if ( ++ip > limit )
{
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "unexpected EOF in integer\n" ));
goto Syntax_Error;
}
if ( ip[-2] < 251 )
value = ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
else
value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
}
}
else
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid byte (%d)\n", ip[-1] ));
goto Syntax_Error;
}
}
/*********************************************************************/
/* */
/* Push value on stack, or process operator */
/* */
/* */
if ( op == op_none )
{
if ( top - decoder->stack >= T1_MAX_CHARSTRINGS_OPERANDS )
{
FT_ERROR(( "t1_decoder_parse_charstrings: stack overflow!\n" ));
goto Syntax_Error;
}
FT_TRACE4(( " %ld", value ));
*top++ = value;
decoder->top = top;
}
else if ( op == op_callothersubr ) /* callothersubr */
{
FT_TRACE4(( " callothersubr" ));
if ( top - decoder->stack < 2 )
goto Stack_Underflow;
top -= 2;
switch ( (FT_Int)top[1] )
{
case 1: /* start flex feature */
if ( top[0] != 0 )
goto Unexpected_OtherSubr;
decoder->flex_state = 1;
decoder->num_flex_vectors = 0;
if ( start_point( builder, x, y ) ||
check_points( builder, 6 ) )
goto Fail;
break;
case 2: /* add flex vectors */
{
FT_Int idx;
if ( top[0] != 0 )
goto Unexpected_OtherSubr;
/* note that we should not add a point for index 0; */
/* this will move our current position to the flex */
/* point without adding any point to the outline */
idx = decoder->num_flex_vectors++;
if ( idx > 0 && idx < 7 )
add_point( builder,
x,
y,
(FT_Byte)( idx == 3 || idx == 6 ) );
}
break;
case 0: /* end flex feature */
if ( top[0] != 3 )
goto Unexpected_OtherSubr;
if ( decoder->flex_state == 0 ||
decoder->num_flex_vectors != 7 )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"unexpected flex end\n" ));
goto Syntax_Error;
}
/* now consume the remaining `pop pop setcurpoint' */
if ( ip + 6 > limit ||
ip[0] != 12 || ip[1] != 17 || /* pop */
ip[2] != 12 || ip[3] != 17 || /* pop */
ip[4] != 12 || ip[5] != 33 ) /* setcurpoint */
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid flex charstring\n" ));
goto Syntax_Error;
}
ip += 6;
decoder->flex_state = 0;
break;
case 3: /* change hints */
if ( top[0] != 1 )
goto Unexpected_OtherSubr;
/* eat the following `pop' */
if ( ip + 2 > limit )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid escape (12+%d)\n", ip[-1] ));
goto Syntax_Error;
}
if ( ip[0] != 12 || ip[1] != 17 )
{
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "`pop' expected, found (%d %d)\n", ip[0], ip[1] ));
goto Syntax_Error;
}
ip += 2;
if ( hinter )
hinter->reset( hinter->hints, builder->current->n_points );
break;
case 12:
case 13:
/* counter control hints, clear stack */
top = decoder->stack;
break;
case 14:
case 15:
case 16:
case 17:
case 18: /* multiple masters */
{
PS_Blend blend = decoder->blend;
FT_UInt num_points, nn, mm;
FT_Long* delta;
FT_Long* values;
if ( !blend )
{
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "unexpected multiple masters operator!\n" ));
goto Syntax_Error;
}
num_points = (FT_UInt)top[1] - 13 + ( top[1] == 18 );
if ( top[0] != (FT_Int)( num_points * blend->num_designs ) )
{
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "incorrect number of mm arguments\n" ));
goto Syntax_Error;
}
top -= blend->num_designs * num_points;
if ( top < decoder->stack )
goto Stack_Underflow;
/* we want to compute: */
/* */
/* a0*w0 + a1*w1 + ... + ak*wk */
/* */
/* but we only have the a0, a1-a0, a2-a0, .. ak-a0 */
/* however, given that w0 + w1 + ... + wk == 1, we can */
/* rewrite it easily as: */
/* */
/* a0 + (a1-a0)*w1 + (a2-a0)*w2 + .. + (ak-a0)*wk */
/* */
/* where k == num_designs-1 */
/* */
/* I guess that's why it's written in this `compact' */
/* form. */
/* */
delta = top + num_points;
values = top;
for ( nn = 0; nn < num_points; nn++ )
{
FT_Long tmp = values[0];
for ( mm = 1; mm < blend->num_designs; mm++ )
tmp += FT_MulFix( *delta++, blend->weight_vector[mm] );
*values++ = tmp;
}
/* note that `top' will be incremented later by calls to `pop' */
break;
}
default:
Unexpected_OtherSubr:
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid othersubr [%d %d]!\n", top[0], top[1] ));
goto Syntax_Error;
}
decoder->top = top;
}
else /* general operator */
{
FT_Int num_args = t1_args_count[op];
if ( top - decoder->stack < num_args )
goto Stack_Underflow;
top -= num_args;
switch ( op )
{
case op_endchar:
FT_TRACE4(( " endchar" ));
close_contour( builder );
/* close hints recording session */
if ( hinter )
{
if (hinter->close( hinter->hints, builder->current->n_points ))
goto Syntax_Error;
/* apply hints to the loaded glyph outline now */
hinter->apply( hinter->hints,
builder->current,
(PSH_Globals) builder->hints_globals,
decoder->hint_mode );
}
/* add current outline to the glyph slot */
FT_GlyphLoader_Add( builder->loader );
/* return now! */
FT_TRACE4(( "\n\n" ));
return PSaux_Err_Ok;
case op_hsbw:
FT_TRACE4(( " hsbw" ));
builder->parse_state = T1_Parse_Have_Width;
builder->left_bearing.x += top[0];
builder->advance.x = top[1];
builder->advance.y = 0;
orig_x = builder->last.x = x = builder->pos_x + top[0];
orig_y = builder->last.y = y = builder->pos_y;
FT_UNUSED( orig_y );
/* the `metrics_only' indicates that we only want to compute */
/* the glyph's metrics (lsb + advance width), not load the */
/* rest of it; so exit immediately */
if ( builder->metrics_only )
return PSaux_Err_Ok;
break;
case op_seac:
/* return immediately after the processing */
return t1operator_seac( decoder, top[0], top[1], top[2],
(FT_Int)top[3], (FT_Int)top[4] );
case op_sbw:
FT_TRACE4(( " sbw" ));
builder->parse_state = T1_Parse_Have_Width;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -