📄 t1decode.c
字号:
x = orig_x = builder->pos_x;
y = orig_y = builder->pos_y;
/* begin hints recording session, if any */
if ( hinter )
hinter->open( hinter->hints );
/* now, execute loop */
while ( ip < limit )
{
FT_Long* top = decoder->top;
T1_Operator op = op_none;
FT_Long value = 0;
FT_ASSERT( known_othersubr_result_cnt == 0 ||
unknown_othersubr_result_cnt == 0 );
FT_TRACE5(( " (%d)", decoder->top - decoder->stack ));
/*********************************************************************/
/* */
/* Decode operator or operand */
/* */
/* */
/* first of all, decompress operator or value */
switch ( *ip++ )
{
case 1:
op = op_hstem;
break;
case 3:
op = op_vstem;
break;
case 4:
op = op_vmoveto;
break;
case 5:
op = op_rlineto;
break;
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_unknown15;
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;
}
}
if ( unknown_othersubr_result_cnt > 0 )
{
switch ( op )
{
case op_callsubr:
case op_return:
case op_none:
case op_pop:
break;
default:
/* all operands have been transferred by previous pops */
unknown_othersubr_result_cnt = 0;
break;
}
}
/*********************************************************************/
/* */
/* 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_Int subr_no;
FT_Int arg_cnt;
FT_TRACE4(( " callothersubr" ));
if ( top - decoder->stack < 2 )
goto Stack_Underflow;
top -= 2;
subr_no = (FT_Int)top[1];
arg_cnt = (FT_Int)top[0];
/***********************************************************/
/* */
/* remove all operands to callothersubr from the stack */
/* */
/* for handled othersubrs, where we know the number of */
/* arguments, we increase the stack by the value of */
/* known_othersubr_result_cnt */
/* */
/* for unhandled othersubrs the following pops adjust the */
/* stack pointer as necessary */
if ( arg_cnt > top - decoder->stack )
goto Stack_Underflow;
top -= arg_cnt;
known_othersubr_result_cnt = 0;
unknown_othersubr_result_cnt = 0;
/* XXX TODO: The checks to `arg_count == <whatever>' */
/* might not be correct; an othersubr expects a certain */
/* number of operands on the PostScript stack (as opposed */
/* to the T1 stack) but it doesn't have to put them there */
/* by itself; previous othersubrs might have left the */
/* operands there if they were not followed by an */
/* appropriate number of pops */
/* */
/* On the other hand, Adobe Reader 7.0.8 for Linux doesn't */
/* accept a font that contains charstrings like */
/* */
/* 100 200 2 20 callothersubr */
/* 300 1 20 callothersubr pop */
/* */
/* Perhaps this is the reason why BuildCharArray exists. */
switch ( subr_no )
{
case 1: /* start flex feature */
if ( arg_cnt != 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 ( arg_cnt != 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 ( arg_cnt != 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;
}
/* the two `results' are popped by the following setcurrentpoint */
known_othersubr_result_cnt = 2;
break;
case 3: /* change hints */
if ( arg_cnt != 1 )
goto Unexpected_OtherSubr;
known_othersubr_result_cnt = 1;
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)subr_no - 13 + ( subr_no == 18 );
if ( arg_cnt != (FT_Int)( num_points * blend->num_designs ) )
{
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "incorrect number of mm arguments\n" ));
goto Syntax_Error;
}
/* 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. */
/* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -