📄 cffgload.c
字号:
}
else
{
if ( ip + 3 >= limit )
goto Syntax_Error;
val = ( (FT_Int32)ip[0] << 24 ) |
( (FT_Int32)ip[1] << 16 ) |
( (FT_Int32)ip[2] << 8 ) |
ip[3];
ip += 4;
shift = 0;
}
if ( decoder->top - stack >= CFF_MAX_OPERANDS )
goto Stack_Overflow;
val <<= shift;
*decoder->top++ = val;
#ifdef FT_DEBUG_LEVEL_TRACE
if ( !( val & 0xFFFFL ) )
FT_TRACE4(( " %ld", (FT_Int32)( val >> 16 ) ));
else
FT_TRACE4(( " %.2f", val / 65536.0 ));
#endif
}
else
{
FT_Fixed* args = decoder->top;
FT_Int num_args = (FT_Int)( args - decoder->stack );
FT_Int req_args;
/* find operator */
op = cff_op_unknown;
switch ( v )
{
case 1:
op = cff_op_hstem;
break;
case 3:
op = cff_op_vstem;
break;
case 4:
op = cff_op_vmoveto;
break;
case 5:
op = cff_op_rlineto;
break;
case 6:
op = cff_op_hlineto;
break;
case 7:
op = cff_op_vlineto;
break;
case 8:
op = cff_op_rrcurveto;
break;
case 10:
op = cff_op_callsubr;
break;
case 11:
op = cff_op_return;
break;
case 12:
{
if ( ip >= limit )
goto Syntax_Error;
v = *ip++;
switch ( v )
{
case 0:
op = cff_op_dotsection;
break;
case 3:
op = cff_op_and;
break;
case 4:
op = cff_op_or;
break;
case 5:
op = cff_op_not;
break;
case 8:
op = cff_op_store;
break;
case 9:
op = cff_op_abs;
break;
case 10:
op = cff_op_add;
break;
case 11:
op = cff_op_sub;
break;
case 12:
op = cff_op_div;
break;
case 13:
op = cff_op_load;
break;
case 14:
op = cff_op_neg;
break;
case 15:
op = cff_op_eq;
break;
case 18:
op = cff_op_drop;
break;
case 20:
op = cff_op_put;
break;
case 21:
op = cff_op_get;
break;
case 22:
op = cff_op_ifelse;
break;
case 23:
op = cff_op_random;
break;
case 24:
op = cff_op_mul;
break;
case 26:
op = cff_op_sqrt;
break;
case 27:
op = cff_op_dup;
break;
case 28:
op = cff_op_exch;
break;
case 29:
op = cff_op_index;
break;
case 30:
op = cff_op_roll;
break;
case 34:
op = cff_op_hflex;
break;
case 35:
op = cff_op_flex;
break;
case 36:
op = cff_op_hflex1;
break;
case 37:
op = cff_op_flex1;
break;
default:
/* decrement ip for syntax error message */
ip--;
}
}
break;
case 14:
op = cff_op_endchar;
break;
case 16:
op = cff_op_blend;
break;
case 18:
op = cff_op_hstemhm;
break;
case 19:
op = cff_op_hintmask;
break;
case 20:
op = cff_op_cntrmask;
break;
case 21:
op = cff_op_rmoveto;
break;
case 22:
op = cff_op_hmoveto;
break;
case 23:
op = cff_op_vstemhm;
break;
case 24:
op = cff_op_rcurveline;
break;
case 25:
op = cff_op_rlinecurve;
break;
case 26:
op = cff_op_vvcurveto;
break;
case 27:
op = cff_op_hhcurveto;
break;
case 29:
op = cff_op_callgsubr;
break;
case 30:
op = cff_op_vhcurveto;
break;
case 31:
op = cff_op_hvcurveto;
break;
default:
;
}
if ( op == cff_op_unknown )
goto Syntax_Error;
/* check arguments */
req_args = cff_argument_counts[op];
if ( req_args & CFF_COUNT_CHECK_WIDTH )
{
args = stack;
if ( num_args > 0 && decoder->read_width )
{
/* If `nominal_width' is non-zero, the number is really a */
/* difference against `nominal_width'. Else, the number here */
/* is truly a width, not a difference against `nominal_width'. */
/* If the font does not set `nominal_width', then */
/* `nominal_width' defaults to zero, and so we can set */
/* `glyph_width' to `nominal_width' plus number on the stack */
/* -- for either case. */
FT_Int set_width_ok;
switch ( op )
{
case cff_op_hmoveto:
case cff_op_vmoveto:
set_width_ok = num_args & 2;
break;
case cff_op_hstem:
case cff_op_vstem:
case cff_op_hstemhm:
case cff_op_vstemhm:
case cff_op_rmoveto:
case cff_op_hintmask:
case cff_op_cntrmask:
set_width_ok = num_args & 1;
break;
case cff_op_endchar:
/* If there is a width specified for endchar, we either have */
/* 1 argument or 5 arguments. We like to argue. */
set_width_ok = ( ( num_args == 5 ) || ( num_args == 1 ) );
break;
default:
set_width_ok = 0;
break;
}
if ( set_width_ok )
{
decoder->glyph_width = decoder->nominal_width +
( stack[0] >> 16 );
/* Consumed an argument. */
num_args--;
args++;
}
}
decoder->read_width = 0;
req_args = 0;
}
req_args &= 15;
if ( num_args < req_args )
goto Stack_Underflow;
args -= req_args;
num_args -= req_args;
switch ( op )
{
case cff_op_hstem:
case cff_op_vstem:
case cff_op_hstemhm:
case cff_op_vstemhm:
/* the number of arguments is always even here */
FT_TRACE4(( op == cff_op_hstem ? " hstem" :
( op == cff_op_vstem ? " vstem" :
( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) ));
if ( hinter )
hinter->stems( hinter->hints,
( op == cff_op_hstem || op == cff_op_hstemhm ),
num_args / 2,
args );
decoder->num_hints += num_args / 2;
args = stack;
break;
case cff_op_hintmask:
case cff_op_cntrmask:
FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
/* implement vstem when needed -- */
/* the specification doesn't say it, but this also works */
/* with the 'cntrmask' operator */
/* */
if ( num_args > 0 )
{
if ( hinter )
hinter->stems( hinter->hints,
0,
num_args / 2,
args );
decoder->num_hints += num_args / 2;
}
if ( hinter )
{
if ( op == cff_op_hintmask )
hinter->hintmask( hinter->hints,
builder->current->n_points,
decoder->num_hints,
ip );
else
hinter->counter( hinter->hints,
decoder->num_hints,
ip );
}
#ifdef FT_DEBUG_LEVEL_TRACE
{
FT_UInt maskbyte;
FT_TRACE4(( " " ));
for ( maskbyte = 0;
maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3);
maskbyte++, ip++ )
FT_TRACE4(( "0x%02X", *ip ));
}
#else
ip += ( decoder->num_hints + 7 ) >> 3;
#endif
if ( ip >= limit )
goto Syntax_Error;
args = stack;
break;
case cff_op_rmoveto:
FT_TRACE4(( " rmoveto" ));
cff_builder_close_contour( builder );
builder->path_begun = 0;
x += args[0];
y += args[1];
args = stack;
break;
case cff_op_vmoveto:
FT_TRACE4(( " vmoveto" ));
cff_builder_close_contour( builder );
builder->path_begun = 0;
y += args[0];
args = stack;
break;
case cff_op_hmoveto:
FT_TRACE4(( " hmoveto" ));
cff_builder_close_contour( builder );
builder->path_begun = 0;
x += args[0];
args = stack;
break;
case cff_op_rlineto:
FT_TRACE4(( " rlineto" ));
if ( cff_builder_start_point ( builder, x, y ) ||
check_points( builder, num_args / 2 ) )
goto Fail;
if ( num_args < 2 || num_args & 1 )
goto Stack_Underflow;
args = stack;
while ( args < decoder->top )
{
x += args[0];
y += args[1];
cff_builder_add_point( builder, x, y, 1 );
args += 2;
}
args = stack;
break;
case cff_op_hlineto:
case cff_op_vlineto:
{
FT_Int phase = ( op == cff_op_hlineto );
FT_TRACE4(( op == cff_op_hlineto ? " hlineto"
: " vlineto" ));
if ( cff_builder_start_point ( builder, x, y ) ||
check_points( builder, num_args ) )
goto Fail;
args = stack;
while ( args < decoder->top )
{
if ( phase )
x += args[0];
else
y += args[0];
if ( cff_builder_add_point1( builder, x, y ) )
goto Fail;
args++;
phase ^= 1;
}
args = stack;
}
break;
case cff_op_rrcurveto:
FT_TRACE4(( " rrcurveto" ));
/* check number of arguments; must be a multiple of 6 */
if ( num_args % 6 != 0 )
goto Stack_Underflow;
if ( cff_builder_start_point ( builder, x, y ) ||
check_points( builder, num_args / 2 ) )
goto Fail;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -