📄 t1decode.c
字号:
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;
}
known_othersubr_result_cnt = num_points;
break;
}
#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
/* We cannot yet enable these since currently */
/* our T1 stack stores integers which lack the */
/* precision to express the values */
case 19:
/* <idx> 1 19 callothersubr */
/* => replace elements starting from index cvi( <idx> ) */
/* of BuildCharArray with WeightVector */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
if ( arg_cnt != 1 || blend == NULL )
goto Unexpected_OtherSubr;
idx = top[0];
if ( idx < 0 ||
idx + blend->num_designs > decoder->face->len_buildchar )
goto Unexpected_OtherSubr;
memcpy( &decoder->buildchar[idx],
blend->weight_vector,
blend->num_designs *
sizeof( blend->weight_vector[ 0 ] ) );
}
break;
case 20:
/* <arg1> <arg2> 2 20 callothersubr pop */
/* ==> push <arg1> + <arg2> onto T1 stack */
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
top[0] += top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
case 21:
/* <arg1> <arg2> 2 21 callothersubr pop */
/* ==> push <arg1> - <arg2> onto T1 stack */
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
top[0] -= top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
case 22:
/* <arg1> <arg2> 2 22 callothersubr pop */
/* ==> push <arg1> * <arg2> onto T1 stack */
if ( arg_cnt != 2 )
goto Unexpected_OtherSubr;
top[0] *= top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
case 23:
/* <arg1> <arg2> 2 23 callothersubr pop */
/* ==> push <arg1> / <arg2> onto T1 stack */
if ( arg_cnt != 2 || top[1] == 0 )
goto Unexpected_OtherSubr;
top[0] /= top[1]; /* XXX (over|under)flow */
known_othersubr_result_cnt = 1;
break;
#endif /* CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS */
case 24:
/* <val> <idx> 2 24 callothersubr */
/* => set BuildCharArray[cvi( <idx> )] = <val> */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
if ( arg_cnt != 2 || blend == NULL )
goto Unexpected_OtherSubr;
idx = top[1];
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
goto Unexpected_OtherSubr;
decoder->buildchar[idx] = top[0];
}
break;
case 25:
/* <idx> 1 25 callothersubr pop */
/* => push BuildCharArray[cvi( idx )] */
/* onto T1 stack */
{
FT_Int idx;
PS_Blend blend = decoder->blend;
if ( arg_cnt != 1 || blend == NULL )
goto Unexpected_OtherSubr;
idx = top[0];
if ( idx < 0 || (FT_UInt) idx >= decoder->len_buildchar )
goto Unexpected_OtherSubr;
top[0] = decoder->buildchar[idx];
}
known_othersubr_result_cnt = 1;
break;
#if 0
case 26:
/* <val> mark <idx> ==> set BuildCharArray[cvi( <idx> )] = <val>, */
/* leave mark on T1 stack */
/* <val> <idx> ==> set BuildCharArray[cvi( <idx> )] = <val> */
XXX who has left his mark on the (PostScript) stack ?;
break;
#endif
case 27:
/* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
/* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
/* otherwise push <res2> */
if ( arg_cnt != 4 )
goto Unexpected_OtherSubr;
if ( top[2] > top[3] )
top[0] = top[1];
known_othersubr_result_cnt = 1;
break;
#ifdef CAN_HANDLE_NON_INTEGRAL_T1_OPERANDS
case 28:
/* 0 28 callothersubr pop */
/* => push random value from interval [0, 1) onto stack */
if ( arg_cnt != 0 )
goto Unexpected_OtherSubr;
top[0] = FT_rand();
known_othersubr_result_cnt = 1;
break;
#endif
default:
FT_ERROR(( "t1_decoder_parse_charstrings: "
"unknown othersubr [%d %d], wish me luck!\n",
arg_cnt, subr_no ));
unknown_othersubr_result_cnt = arg_cnt;
break;
Unexpected_OtherSubr:
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid othersubr [%d %d]!\n", arg_cnt, subr_no ));
goto Syntax_Error;
}
top += known_othersubr_result_cnt;
decoder->top = top;
}
else /* general operator */
{
FT_Int num_args = t1_args_count[op];
FT_ASSERT( num_args >= 0 );
if ( top - decoder->stack < num_args )
goto Stack_Underflow;
/* XXX Operators usually take their operands from the */
/* bottom of the stack, i.e., the operands are */
/* decoder->stack[0], ..., decoder->stack[num_args - 1]; */
/* only div, callsubr, and callothersubr are different. */
/* In practice it doesn't matter (?). */
#ifdef FT_DEBUG_LEVEL_TRACE
switch ( op )
{
case op_callsubr:
case op_div:
case op_callothersubr:
case op_pop:
case op_return:
break;
default:
if ( top - decoder->stack != num_args )
FT_TRACE0(( "\nMore operands on the stack than expected "
"(have %d, expected %d)\n",
top - decoder->stack, num_args ));
break;
}
#endif /* FT_DEBUG_LEVEL_TRACE */
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 );
FT_TRACE4(( "\n" ));
/* the compiler should optimize away this empty loop but ... */
#ifdef FT_DEBUG_LEVEL_TRACE
if ( decoder->len_buildchar > 0 )
{
FT_UInt i;
FT_TRACE4(( "BuildCharArray = [ " ));
for ( i = 0; i < decoder->len_buildchar; ++i )
FT_TRACE4(( "%d ", decoder->buildchar[ i ] ));
FT_TRACE4(( "]\n" ));
}
#endif /* FT_DEBUG_LEVEL_TRACE */
FT_TRACE4(( "\n" ));
/* return now! */
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;
builder->left_bearing.x += top[0];
builder->left_bearing.y += top[1];
builder->advance.x = top[2];
builder->advance.y = top[3];
builder->last.x = x = builder->pos_x + top[0];
builder->last.y = y = builder->pos_y + top[1];
/* 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_closepath:
FT_TRACE4(( " closepath" ));
close_contour( builder );
if ( !( builder->parse_state == T1_Parse_Have_Path ||
builder->parse_state == T1_Parse_Have_Moveto ) )
goto Syntax_Error;
builder->parse_state = T1_Parse_Have_Width;
break;
case op_hlineto:
FT_TRACE4(( " hlineto" ));
if ( start_point( builder, x, y ) )
goto Fail;
x += top[0];
goto Add_Line;
case op_hmoveto:
FT_TRACE4(( " hmoveto" ));
x += top[0];
if ( !decoder->flex_state )
{
if ( builder->parse_state == T1_Parse_Start )
goto Syntax_Error;
builder->parse_state = T1_Parse_Have_Moveto;
}
break;
case op_hvcurveto:
FT_TRACE4(( " hvcurveto" ));
if ( start_point( builder, x, y ) ||
check_points( builder, 3 ) )
goto Fail;
x += top[0];
add_point( builder, x, y, 0 );
x += top[1];
y += top[2];
add_point( builder, x, y, 0 );
y += top[3];
add_point( builder, x, y, 1 );
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -