📄 cffgload.c
字号:
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 error;
case cff_op_abs:
FT_TRACE4(( " abs" ));
if ( args[0] < 0 )
args[0] = -args[0];
args++;
break;
case cff_op_add:
FT_TRACE4(( " add" ));
args[0] += args[1];
args++;
break;
case cff_op_sub:
FT_TRACE4(( " sub" ));
args[0] -= args[1];
args++;
break;
case cff_op_div:
FT_TRACE4(( " div" ));
args[0] = FT_DivFix( args[0], args[1] );
args++;
break;
case cff_op_neg:
FT_TRACE4(( " neg" ));
args[0] = -args[0];
args++;
break;
case cff_op_random:
{
FT_Fixed Rand;
FT_TRACE4(( " rand" ));
Rand = seed;
if ( Rand >= 0x8000L )
Rand++;
args[0] = Rand;
seed = FT_MulFix( seed, 0x10000L - seed );
if ( seed == 0 )
seed += 0x2873;
args++;
}
break;
case cff_op_mul:
FT_TRACE4(( " mul" ));
args[0] = FT_MulFix( args[0], args[1] );
args++;
break;
case cff_op_sqrt:
FT_TRACE4(( " sqrt" ));
if ( args[0] > 0 )
{
FT_Int count = 9;
FT_Fixed root = args[0];
FT_Fixed new_root;
for (;;)
{
new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
if ( new_root == root || count <= 0 )
break;
root = new_root;
}
args[0] = new_root;
}
else
args[0] = 0;
args++;
break;
case cff_op_drop:
/* nothing */
FT_TRACE4(( " drop" ));
break;
case cff_op_exch:
{
FT_Fixed tmp;
FT_TRACE4(( " exch" ));
tmp = args[0];
args[0] = args[1];
args[1] = tmp;
args += 2;
}
break;
case cff_op_index:
{
FT_Int idx = (FT_Int)( args[0] >> 16 );
FT_TRACE4(( " index" ));
if ( idx < 0 )
idx = 0;
else if ( idx > num_args - 2 )
idx = num_args - 2;
args[0] = args[-( idx + 1 )];
args++;
}
break;
case cff_op_roll:
{
FT_Int count = (FT_Int)( args[0] >> 16 );
FT_Int idx = (FT_Int)( args[1] >> 16 );
FT_TRACE4(( " roll" ));
if ( count <= 0 )
count = 1;
args -= count;
if ( args < stack )
goto Stack_Underflow;
if ( idx >= 0 )
{
while ( idx > 0 )
{
FT_Fixed tmp = args[count - 1];
FT_Int i;
for ( i = count - 2; i >= 0; i-- )
args[i + 1] = args[i];
args[0] = tmp;
idx--;
}
}
else
{
while ( idx < 0 )
{
FT_Fixed tmp = args[0];
FT_Int i;
for ( i = 0; i < count - 1; i++ )
args[i] = args[i + 1];
args[count - 1] = tmp;
idx++;
}
}
args += count;
}
break;
case cff_op_dup:
FT_TRACE4(( " dup" ));
args[1] = args[0];
args++;
break;
case cff_op_put:
{
FT_Fixed val = args[0];
FT_Int idx = (FT_Int)( args[1] >> 16 );
FT_TRACE4(( " put" ));
if ( idx >= 0 && idx < decoder->len_buildchar )
decoder->buildchar[idx] = val;
}
break;
case cff_op_get:
{
FT_Int idx = (FT_Int)( args[0] >> 16 );
FT_Fixed val = 0;
FT_TRACE4(( " get" ));
if ( idx >= 0 && idx < decoder->len_buildchar )
val = decoder->buildchar[idx];
args[0] = val;
args++;
}
break;
case cff_op_store:
FT_TRACE4(( " store "));
goto Unimplemented;
case cff_op_load:
FT_TRACE4(( " load" ));
goto Unimplemented;
case cff_op_dotsection:
/* this operator is deprecated and ignored by the parser */
FT_TRACE4(( " dotsection" ));
break;
case cff_op_and:
{
FT_Fixed cond = args[0] && args[1];
FT_TRACE4(( " and" ));
args[0] = cond ? 0x10000L : 0;
args++;
}
break;
case cff_op_or:
{
FT_Fixed cond = args[0] || args[1];
FT_TRACE4(( " or" ));
args[0] = cond ? 0x10000L : 0;
args++;
}
break;
case cff_op_eq:
{
FT_Fixed cond = !args[0];
FT_TRACE4(( " eq" ));
args[0] = cond ? 0x10000L : 0;
args++;
}
break;
case cff_op_ifelse:
{
FT_Fixed cond = ( args[2] <= args[3] );
FT_TRACE4(( " ifelse" ));
if ( !cond )
args[0] = args[1];
args++;
}
break;
case cff_op_callsubr:
{
FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
decoder->locals_bias );
FT_TRACE4(( " callsubr(%d)", idx ));
if ( idx >= decoder->num_locals )
{
FT_ERROR(( "cff_decoder_parse_charstrings:" ));
FT_ERROR(( " invalid local subr index\n" ));
goto Syntax_Error;
}
if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
{
FT_ERROR(( "cff_decoder_parse_charstrings:"
" too many nested subrs\n" ));
goto Syntax_Error;
}
zone->cursor = ip; /* save current instruction pointer */
zone++;
zone->base = decoder->locals[idx];
zone->limit = decoder->locals[idx + 1];
zone->cursor = zone->base;
if ( !zone->base )
{
FT_ERROR(( "cff_decoder_parse_charstrings:"
" invoking empty subrs!\n" ));
goto Syntax_Error;
}
decoder->zone = zone;
ip = zone->base;
limit = zone->limit;
}
break;
case cff_op_callgsubr:
{
FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
decoder->globals_bias );
FT_TRACE4(( " callgsubr(%d)", idx ));
if ( idx >= decoder->num_globals )
{
FT_ERROR(( "cff_decoder_parse_charstrings:" ));
FT_ERROR(( " invalid global subr index\n" ));
goto Syntax_Error;
}
if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
{
FT_ERROR(( "cff_decoder_parse_charstrings:"
" too many nested subrs\n" ));
goto Syntax_Error;
}
zone->cursor = ip; /* save current instruction pointer */
zone++;
zone->base = decoder->globals[idx];
zone->limit = decoder->globals[idx + 1];
zone->cursor = zone->base;
if ( !zone->base )
{
FT_ERROR(( "cff_decoder_parse_charstrings:"
" invoking empty subrs!\n" ));
goto Syntax_Error;
}
decoder->zone = zone;
ip = zone->base;
limit = zone->limit;
}
break;
case cff_op_return:
FT_TRACE4(( " return" ));
if ( decoder->zone <= decoder->zones )
{
FT_ERROR(( "cff_decoder_parse_charstrings:"
" unexpected return\n" ));
goto Syntax_Error;
}
decoder->zone--;
zone = decoder->zone;
ip = zone->cursor;
limit = zone->limit;
break;
default:
Unimplemented:
FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
if ( ip[-1] == 12 )
FT_ERROR(( " %d", ip[0] ));
FT_ERROR(( "\n" ));
return CFF_Err_Unimplemented_Feature;
}
decoder->top = args;
} /* general operator processing */
} /* while ip < limit */
FT_TRACE4(( "..end..\n\n" ));
Fail:
return error;
Syntax_Error:
FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!" ));
return CFF_Err_Invalid_File_Format;
Stack_Underflow:
FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!" ));
return CFF_Err_Too_Few_Arguments;
Stack_Overflow:
FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!" ));
return CFF_Err_Stack_Overflow;
}
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/********** *********/
/********** *********/
/********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
/********** *********/
/********** The following code is in charge of computing *********/
/********** the maximum advance width of the font. It *********/
/********** quickly processes each glyph charstring to *********/
/********** extract the value from either a `sbw' or `seac' *********/
/********** operator. *********/
/********** *********/
/*************************************************************************/
/*****
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -