📄 t1decode.c
字号:
/***************************************************************************/
/* */
/* t1decode.c */
/* */
/* PostScript Type 1 decoding routines (body). */
/* */
/* Copyright 2000-2001, 2002, 2003, 2004, 2005, 2006 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
/* modified, and distributed under the terms of the FreeType project */
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */
/* this file you indicate that you have read the license and */
/* understand and accept it fully. */
/* */
/***************************************************************************/
#include <ft2build.h>
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_POSTSCRIPT_HINTS_H
#include FT_OUTLINE_H
#include "t1decode.h"
#include "psobjs.h"
#include "psauxerr.h"
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
/* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
/* messages during execution. */
/* */
#undef FT_COMPONENT
#define FT_COMPONENT trace_t1decode
typedef enum T1_Operator_
{
op_none = 0,
op_endchar,
op_hsbw,
op_seac,
op_sbw,
op_closepath,
op_hlineto,
op_hmoveto,
op_hvcurveto,
op_rlineto,
op_rmoveto,
op_rrcurveto,
op_vhcurveto,
op_vlineto,
op_vmoveto,
op_dotsection,
op_hstem,
op_hstem3,
op_vstem,
op_vstem3,
op_div,
op_callothersubr,
op_callsubr,
op_pop,
op_return,
op_setcurrentpoint,
op_unknown15,
op_max /* never remove this one */
} T1_Operator;
static
const FT_Int t1_args_count[op_max] =
{
0, /* none */
0, /* endchar */
2, /* hsbw */
5, /* seac */
4, /* sbw */
0, /* closepath */
1, /* hlineto */
1, /* hmoveto */
4, /* hvcurveto */
2, /* rlineto */
2, /* rmoveto */
6, /* rrcurveto */
4, /* vhcurveto */
1, /* vlineto */
1, /* vmoveto */
0, /* dotsection */
2, /* hstem */
6, /* hstem3 */
2, /* vstem */
6, /* vstem3 */
2, /* div */
-1, /* callothersubr */
1, /* callsubr */
0, /* pop */
0, /* return */
2, /* setcurrentpoint */
2 /* opcode 15 (undocumented and obsolete) */
};
/*************************************************************************/
/* */
/* <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;
FT_Int known_othersubr_result_cnt = 0;
FT_Int unknown_othersubr_result_cnt = 0;
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;
/* a font that reads BuildCharArray without setting */
/* its values first is buggy, but ... */
FT_ASSERT( ( decoder->len_buildchar == 0 ) ==
( decoder->buildchar == NULL ) );
if ( decoder->len_buildchar > 0 )
memset( &decoder->buildchar[0],
0,
sizeof( decoder->buildchar[0] ) *
decoder->len_buildchar );
FT_TRACE4(( "\nStart charstring\n" ));
zone->base = charstring_base;
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
error = PSaux_Err_Ok;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -