cffgload.c.svn-base
来自「SumatraPDF是一款小型开源的pdf阅读工具。虽然玲珑小巧(只有800多K」· SVN-BASE 代码 · 共 2,212 行 · 第 1/5 页
SVN-BASE
2,212 行
/********************************************************************/
/* */
/* Decode operator or operand */
/* */
v = *ip++;
if ( v >= 32 || v == 28 )
{
FT_Int shift = 16;
FT_Int32 val;
/* this is an operand, push it on the stack */
if ( v == 28 )
{
if ( ip + 1 >= limit )
goto Syntax_Error;
val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] );
ip += 2;
}
else if ( v < 247 )
val = (FT_Long)v - 139;
else if ( v < 251 )
{
if ( ip >= limit )
goto Syntax_Error;
val = ( (FT_Long)v - 247 ) * 256 + *ip++ + 108;
}
else if ( v < 255 )
{
if ( ip >= limit )
goto Syntax_Error;
val = -( (FT_Long)v - 251 ) * 256 - *ip++ - 108;
}
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 9:
op = cff_op_closepath;
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 13:
op = cff_op_hsbw;
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 &= 0x000F;
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 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?