📄 psaux.c
字号:
0, /* dotsection */
2, /* hstem */
6, /* hstem3 */
2, /* vstem */
6, /* vstem3 */
2, /* div */
-1, /* callothersubr */
1, /* callsubr */
0, /* pop */
0, /* return */
2 /* setcurrentpoint */
};
/*************************************************************************/
/* */
/* <Function> */
/* t1_lookup_glyph_by_stdcharcode */
/* */
/* <Description> */
/* Looks up a given glyph by its StandardEncoding charcode. Used to */
/* implement the SEAC Type 1 operator. */
/* */
/* <Input> */
/* face :: The current face object. */
/* */
/* charcode :: The character code to look for. */
/* */
/* <Return> */
/* A glyph index in the font face. Returns -1 if the corresponding */
/* glyph wasn't found. */
/* */
static FT_Int
t1_lookup_glyph_by_stdcharcode( T1_Decoder decoder,
FT_Int charcode )
{
FT_UInt n;
const FT_String* glyph_name;
FT_Service_PsCMaps psnames = decoder->psnames;
/* check range of standard char code */
if ( charcode < 0 || charcode > 255 )
return -1;
glyph_name = psnames->adobe_std_strings(
psnames->adobe_std_encoding[charcode]);
for ( n = 0; n < decoder->num_glyphs; n++ )
{
FT_String* name = (FT_String*)decoder->glyph_names[n];
if ( name && name[0] == glyph_name[0] &&
ft_strcmp( name, glyph_name ) == 0 )
return n;
}
return -1;
}
/*************************************************************************/
/* */
/* <Function> */
/* t1operator_seac */
/* */
/* <Description> */
/* Implements the `seac' Type 1 operator for a Type 1 decoder. */
/* */
/* <Input> */
/* decoder :: The current CID decoder. */
/* */
/* asb :: The accent's side bearing. */
/* */
/* adx :: The horizontal offset of the accent. */
/* */
/* ady :: The vertical offset of the accent. */
/* */
/* bchar :: The base character's StandardEncoding charcode. */
/* */
/* achar :: The accent character's StandardEncoding charcode. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
static FT_Error
t1operator_seac( T1_Decoder decoder,
FT_Pos asb,
FT_Pos adx,
FT_Pos ady,
FT_Int bchar,
FT_Int achar )
{
FT_Error error;
FT_Int bchar_index, achar_index;
#if 0
FT_Int n_base_points;
FT_Outline* base = decoder->builder.base;
#endif
FT_Vector left_bearing, advance;
/* seac weirdness */
adx += decoder->builder.left_bearing.x;
/* `glyph_names' is set to 0 for CID fonts which do not */
/* include an encoding. How can we deal with these? */
if ( decoder->glyph_names == 0 )
{
FT_ERROR(( "t1operator_seac:" ));
FT_ERROR(( " glyph names table not available in this font!\n" ));
return PSaux_Err_Syntax_Error;
}
bchar_index = t1_lookup_glyph_by_stdcharcode( decoder, bchar );
achar_index = t1_lookup_glyph_by_stdcharcode( decoder, achar );
if ( bchar_index < 0 || achar_index < 0 )
{
FT_ERROR(( "t1operator_seac:" ));
FT_ERROR(( " invalid seac character code arguments\n" ));
return PSaux_Err_Syntax_Error;
}
/* if we are trying to load a composite glyph, do not load the */
/* accent character and return the array of subglyphs. */
if ( decoder->builder.no_recurse )
{
FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
FT_GlyphLoader loader = glyph->internal->loader;
FT_SubGlyph subg;
/* reallocate subglyph array if necessary */
error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
if ( error )
goto Exit;
subg = loader->current.subglyphs;
/* subglyph 0 = base character */
subg->index = bchar_index;
subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
FT_SUBGLYPH_FLAG_USE_MY_METRICS;
subg->arg1 = 0;
subg->arg2 = 0;
subg++;
/* subglyph 1 = accent character */
subg->index = achar_index;
subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES;
subg->arg1 = (FT_Int)( adx - asb );
subg->arg2 = (FT_Int)ady;
/* set up remaining glyph fields */
glyph->num_subglyphs = 2;
glyph->subglyphs = loader->base.subglyphs;
glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
loader->current.num_subglyphs = 2;
goto Exit;
}
/* First load `bchar' in builder */
/* now load the unscaled outline */
FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */
error = t1_decoder_parse_glyph( decoder, bchar_index );
if ( error )
goto Exit;
/* save the left bearing and width of the base character */
/* as they will be erased by the next load. */
left_bearing = decoder->builder.left_bearing;
advance = decoder->builder.advance;
decoder->builder.left_bearing.x = 0;
decoder->builder.left_bearing.y = 0;
decoder->builder.pos_x = adx - asb;
decoder->builder.pos_y = ady;
/* Now load `achar' on top of */
/* the base outline */
error = t1_decoder_parse_glyph( decoder, achar_index );
if ( error )
goto Exit;
/* restore the left side bearing and */
/* advance width of the base character */
decoder->builder.left_bearing = left_bearing;
decoder->builder.advance = advance;
decoder->builder.pos_x = 0;
decoder->builder.pos_y = 0;
Exit:
return error;
}
/*************************************************************************/
/* */
/* <Function> */
/* t1_decoder_parse_charstrings */
/* */
/* <Description> */
/* Parses a given Type 1 charstrings program. */
/* */
/* <Input> */
/* decoder :: The current Type 1 decoder. */
/* */
/* charstring_base :: The base address of the charstring stream. */
/* */
/* charstring_len :: The length in bytes of the charstring stream. */
/* */
/* <Return> */
/* FreeType error code. 0 means success. */
/* */
FT_LOCAL_DEF( FT_Error )
t1_decoder_parse_charstrings( T1_Decoder decoder,
FT_Byte* charstring_base,
FT_UInt charstring_len )
{
FT_Error error;
T1_Decoder_Zone zone;
FT_Byte* ip;
FT_Byte* limit;
T1_Builder builder = &decoder->builder;
FT_Pos x, y, orig_x, orig_y;
T1_Hints_Funcs hinter;
/* we don't want to touch the source code -- use macro trick */
#define start_point t1_builder_start_point
#define check_points t1_builder_check_points
#define add_point t1_builder_add_point
#define add_point1 t1_builder_add_point1
#define add_contour t1_builder_add_contour
#define close_contour t1_builder_close_contour
/* First of all, initialize the decoder */
decoder->top = decoder->stack;
decoder->zone = decoder->zones;
zone = decoder->zones;
builder->parse_state = T1_Parse_Start;
hinter = (T1_Hints_Funcs)builder->hints_funcs;
zone->base = charstring_base;
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
error = PSaux_Err_Ok;
x = orig_x = builder->pos_x;
y = orig_y = builder->pos_y;
/* begin hints recording session, if any */
if ( hinter )
hinter->open( hinter->hints );
/* now, execute loop */
while ( ip < limit )
{
FT_Long* top = decoder->top;
T1_Operator op = op_none;
FT_Long value = 0;
/*********************************************************************/
/* */
/* Decode operator or operand */
/* */
/* */
/* first of all, decompress operator or value */
switch ( *ip++ )
{
case 1:
op = op_hstem;
break;
case 3:
op = op_vstem;
break;
case 4:
op = op_vmoveto;
break;
case 5:
op = op_rlineto;
break;
case 6:
op = op_hlineto;
break;
case 7:
op = op_vlineto;
break;
case 8:
op = op_rrcurveto;
break;
case 9:
op = op_closepath;
break;
case 10:
op = op_callsubr;
break;
case 11:
op = op_return;
break;
case 13:
op = op_hsbw;
break;
case 14:
op = op_endchar;
break;
case 15: /* undocumented, obsolete operator */
op = op_none;
break;
case 21:
op = op_rmoveto;
break;
case 22:
op = op_hmoveto;
break;
case 30:
op = op_vhcurveto;
break;
case 31:
op = op_hvcurveto;
break;
case 12:
if ( ip > limit )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid escape (12+EOF)\n" ));
goto Syntax_Error;
}
switch ( *ip++ )
{
case 0:
op = op_dotsection;
break;
case 1:
op = op_vstem3;
break;
case 2:
op = op_hstem3;
break;
case 6:
op = op_seac;
break;
case 7:
op = op_sbw;
break;
case 12:
op = op_div;
break;
case 16:
op = op_callothersubr;
break;
case 17:
op = op_pop;
break;
case 33:
op = op_setcurrentpoint;
break;
default:
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid escape (12+%d)\n",
ip[-1] ));
goto Syntax_Error;
}
break;
case 255: /* four bytes integer */
if ( ip + 4 > limit )
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"unexpected EOF in integer\n" ));
goto Syntax_Error;
}
value = (FT_Int32)( ((FT_Long)ip[0] << 24) |
((FT_Long)ip[1] << 16) |
((FT_Long)ip[2] << 8 ) |
ip[3] );
ip += 4;
break;
default:
if ( ip[-1] >= 32 )
{
if ( ip[-1] < 247 )
value = (FT_Long)ip[-1] - 139;
else
{
if ( ++ip > limit )
{
FT_ERROR(( "t1_decoder_parse_charstrings: " ));
FT_ERROR(( "unexpected EOF in integer\n" ));
goto Syntax_Error;
}
if ( ip[-2] < 251 )
value = ( ( (FT_Long)ip[-2] - 247 ) << 8 ) + ip[-1] + 108;
else
value = -( ( ( (FT_Long)ip[-2] - 251 ) << 8 ) + ip[-1] + 108 );
}
}
else
{
FT_ERROR(( "t1_decoder_parse_charstrings: "
"invalid byte (%d)\n", ip[-1] ));
goto Syntax_Error;
}
}
/*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -