📄 t1decode.c
字号:
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;
case op_rlineto:
FT_TRACE4(( " rlineto" ));
if ( start_point( builder, x, y ) )
goto Fail;
x += top[0];
y += top[1];
Add_Line:
if ( add_point1( builder, x, y ) )
goto Fail;
break;
case op_rmoveto:
FT_TRACE4(( " rmoveto" ));
x += top[0];
y += top[1];
if ( !decoder->flex_state )
{
if ( builder->parse_state == T1_Parse_Start )
goto Syntax_Error;
builder->parse_state = T1_Parse_Have_Moveto;
}
break;
case op_rrcurveto:
FT_TRACE4(( " rcurveto" ));
if ( start_point( builder, x, y ) ||
check_points( builder, 3 ) )
goto Fail;
x += top[0];
y += top[1];
add_point( builder, x, y, 0 );
x += top[2];
y += top[3];
add_point( builder, x, y, 0 );
x += top[4];
y += top[5];
add_point( builder, x, y, 1 );
break;
case op_vhcurveto:
FT_TRACE4(( " vhcurveto" ));
if ( start_point( builder, x, y ) ||
check_points( builder, 3 ) )
goto Fail;
y += top[0];
add_point( builder, x, y, 0 );
x += top[1];
y += top[2];
add_point( builder, x, y, 0 );
x += top[3];
add_point( builder, x, y, 1 );
break;
case op_vlineto:
FT_TRACE4(( " vlineto" ));
if ( start_point( builder, x, y ) )
goto Fail;
y += top[0];
goto Add_Line;
case op_vmoveto:
FT_TRACE4(( " vmoveto" ));
y += 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_div:
FT_TRACE4(( " div" ));
if ( top[1] )
{
*top = top[0] / top[1];
++top;
}
else
{
FT_ERROR(( "t1_decoder_parse_charstrings: division by 0\n" ));
goto Syntax_Error;
}
break;
case op_callsubr:
{
FT_Int idx;
FT_TRACE4(( " callsubr" ));
idx = (FT_Int)top[0];
if ( idx < 0 || idx >= (FT_Int)decoder->num_subrs )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid subrs index\n" ));
goto Syntax_Error;
}
if ( zone - decoder->zones >= T1_MAX_SUBRS_CALLS )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"too many nested subrs\n" ));
goto Syntax_Error;
}
zone->cursor = ip; /* save current instruction pointer */
zone++;
/* The Type 1 driver stores subroutines without the seed bytes. */
/* The CID driver stores subroutines with seed bytes. This */
/* case is taken care of when decoder->subrs_len == 0. */
zone->base = decoder->subrs[idx];
if ( decoder->subrs_len )
zone->limit = zone->base + decoder->subrs_len[idx];
else
{
/* We are using subroutines from a CID font. We must adjust */
/* for the seed bytes. */
zone->base += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
zone->limit = decoder->subrs[idx + 1];
}
zone->cursor = zone->base;
if ( !zone->base )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invoking empty subrs!\n" ));
goto Syntax_Error;
}
decoder->zone = zone;
ip = zone->base;
limit = zone->limit;
break;
}
case op_pop:
FT_TRACE4(( " pop" ));
/* theoretically, the arguments are already on the stack */
top++;
break;
case op_return:
FT_TRACE4(( " return" ));
if ( zone <= decoder->zones )
{
FT_ERROR(( "t1_decoder_parse_charstrings: unexpected return\n" ));
goto Syntax_Error;
}
zone--;
ip = zone->cursor;
limit = zone->limit;
decoder->zone = zone;
break;
case op_dotsection:
FT_TRACE4(( " dotsection" ));
break;
case op_hstem:
FT_TRACE4(( " hstem" ));
/* record horizontal hint */
if ( hinter )
{
/* top[0] += builder->left_bearing.y; */
hinter->stem( hinter->hints, 1, top );
}
break;
case op_hstem3:
FT_TRACE4(( " hstem3" ));
/* record horizontal counter-controlled hints */
if ( hinter )
hinter->stem3( hinter->hints, 1, top );
break;
case op_vstem:
FT_TRACE4(( " vstem" ));
/* record vertical hint */
if ( hinter )
{
top[0] += orig_x;
hinter->stem( hinter->hints, 0, top );
}
break;
case op_vstem3:
FT_TRACE4(( " vstem3" ));
/* record vertical counter-controlled hints */
if ( hinter )
{
FT_Pos dx = orig_x;
top[0] += dx;
top[2] += dx;
top[4] += dx;
hinter->stem3( hinter->hints, 0, top );
}
break;
case op_setcurrentpoint:
FT_TRACE4(( " setcurrentpoint" ));
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "unexpected `setcurrentpoint'\n" ));
goto Syntax_Error;
default:
FT_ERROR(( "t1_decoder_parse_charstrings: "
"unhandled opcode %d\n", op ));
goto Syntax_Error;
}
decoder->top = top;
} /* general operator processing */
} /* while ip < limit */
FT_TRACE4(( "..end..\n\n" ));
Fail:
return error;
Syntax_Error:
return PSaux_Err_Syntax_Error;
Stack_Underflow:
return PSaux_Err_Stack_Underflow;
}
/* parse a single Type 1 glyph */
FT_LOCAL_DEF( FT_Error )
t1_decoder_parse_glyph( T1_Decoder decoder,
FT_UInt glyph )
{
return decoder->parse_callback( decoder, glyph );
}
/* initialize T1 decoder */
FT_LOCAL_DEF( FT_Error )
t1_decoder_init( T1_Decoder decoder,
FT_Face face,
FT_Size size,
FT_GlyphSlot slot,
FT_Byte** glyph_names,
PS_Blend blend,
FT_Bool hinting,
FT_Render_Mode hint_mode,
T1_Decoder_Callback parse_callback )
{
FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
/* retrieve PSNames interface from list of current modules */
{
FT_Service_PsCMaps psnames = 0;
FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
if ( !psnames )
{
FT_ERROR(( "t1_decoder_init: " ));
FT_ERROR(( "the `psnames' module is not available\n" ));
return PSaux_Err_Unimplemented_Feature;
}
decoder->psnames = psnames;
}
t1_builder_init( &decoder->builder, face, size, slot, hinting );
decoder->num_glyphs = (FT_UInt)face->num_glyphs;
decoder->glyph_names = glyph_names;
decoder->hint_mode = hint_mode;
decoder->blend = blend;
decoder->parse_callback = parse_callback;
decoder->funcs = t1_decoder_funcs;
return 0;
}
/* finalize T1 decoder */
FT_LOCAL_DEF( void )
t1_decoder_done( T1_Decoder decoder )
{
t1_builder_done( &decoder->builder );
}
/* END */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -