[psaux] Add objects for new interpreter

Introduce PS_Decoder and PS_Builder which include all fields from either
Type 1 or CFF decoders/builders.

* include/freetype/internal/psaux.h: Added new structs.

* src/psaux/psobjs.c, src/psaux/psobjs.h: Added PS_Builder functions.
* src/psaux/psdecode.c, src/psaux/psdecode.h: New file to hold decoder
initialization functions.

* src/psaux/psaux.c, src/psaux/Jamfile, src/psaux/rules.mk: Updated.
This commit is contained in:
Ewald Hew 2017-07-20 13:46:56 +08:00
parent 214dd85d0a
commit 71c3ce153f
8 changed files with 561 additions and 0 deletions

View File

@ -443,6 +443,204 @@ FT_BEGIN_HEADER
} PS_ParserRec;
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** PS BUILDER *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
typedef struct PS_Builder_ PS_Builder;
typedef const struct PS_Builder_FuncsRec_* PS_Builder_Funcs;
typedef struct PS_Builder_FuncsRec_
{
void
(*init)( PS_Builder builder,
FT_Face face,
FT_Size size,
FT_GlyphSlot slot,
FT_Bool hinting );
void
(*done)( PS_Builder builder );
} PS_Builder_FuncsRec;
/*************************************************************************/
/* */
/* <Structure> */
/* PS_Builder */
/* */
/* <Description> */
/* A structure used during glyph loading to store its outline. */
/* */
/* <Fields> */
/* memory :: The current memory object. */
/* */
/* face :: The current face object. */
/* */
/* glyph :: The current glyph slot. */
/* */
/* loader :: XXX */
/* */
/* base :: The base glyph outline. */
/* */
/* current :: The current glyph outline. */
/* */
/* pos_x :: The horizontal translation (if composite glyph). */
/* */
/* pos_y :: The vertical translation (if composite glyph). */
/* */
/* left_bearing :: The left side bearing point. */
/* */
/* advance :: The horizontal advance vector. */
/* */
/* bbox :: Unused. */
/* */
/* path_begun :: A flag which indicates that a new path has begun. */
/* */
/* load_points :: If this flag is not set, no points are loaded. */
/* */
/* no_recurse :: Set but not used. */
/* */
/* metrics_only :: A boolean indicating that we only want to compute */
/* the metrics of a given glyph, not load all of its */
/* points. */
/* */
/* funcs :: An array of function pointers for the builder. */
/* */
struct PS_Builder_
{
FT_Memory memory;
TT_Face face;
CFF_GlyphSlot glyph;
FT_GlyphLoader loader;
FT_Outline* base;
FT_Outline* current;
FT_Pos pos_x;
FT_Pos pos_y;
FT_Vector left_bearing;
FT_Vector advance;
FT_BBox bbox; /* bounding box */
FT_Bool path_begun;
FT_Bool load_points;
FT_Bool no_recurse;
FT_Bool metrics_only;
void* hints_funcs; /* hinter-specific */
void* hints_globals; /* hinter-specific */
PS_Builder_FuncsRec funcs;
};
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** PS DECODER *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
#define PS_MAX_OPERANDS 48
#define PS_MAX_SUBRS_CALLS 16 /* maximum subroutine nesting; */
/* only 10 are allowed but there exist */
/* fonts like `HiraKakuProN-W3.ttf' */
/* (Hiragino Kaku Gothic ProN W3; */
/* 8.2d6e1; 2014-12-19) that exceed */
/* this limit */
/* execution context charstring zone */
typedef struct PS_Decoder_Zone_
{
FT_Byte* base;
FT_Byte* limit;
FT_Byte* cursor;
} PS_Decoder_Zone;
typedef FT_Error
(*PS_Decoder_Get_Glyph_Callback)( TT_Face face,
FT_UInt glyph_index,
FT_Byte** pointer,
FT_ULong* length );
typedef void
(*PS_Decoder_Free_Glyph_Callback)( TT_Face face,
FT_Byte** pointer,
FT_ULong length );
typedef struct PS_Decoder_
{
PS_Builder builder;
FT_Fixed stack[PS_MAX_OPERANDS + 1];
FT_Fixed* top;
PS_Decoder_Zone zones[PS_MAX_SUBRS_CALLS + 1];
PS_Decoder_Zone* zone;
FT_Int flex_state;
FT_Int num_flex_vectors;
FT_Vector flex_vectors[7];
CFF_Font cff;
CFF_SubFont current_subfont; /* for current glyph_index */
FT_Pos glyph_width;
FT_Pos nominal_width;
FT_Bool read_width;
FT_Bool width_only;
FT_Int num_hints;
FT_UInt num_locals;
FT_UInt num_globals;
FT_Int locals_bias;
FT_Int globals_bias;
FT_Byte** locals;
FT_Byte** globals;
FT_Byte** glyph_names; /* for pure CFF fonts only */
FT_UInt num_glyphs; /* number of glyphs in font */
FT_Render_Mode hint_mode;
FT_Bool seac;
PS_Decoder_Get_Glyph_Callback get_glyph_callback;
PS_Decoder_Free_Glyph_Callback free_glyph_callback;
/* Type 1 stuff */
FT_Service_PsCMaps psnames; /* for seac */
FT_Int lenIV; /* internal for sub routine calls */
FT_UInt* locals_len; /* array of subrs length (optional) */
FT_Hash locals_hash; /* used if `num_subrs' was massaged */
FT_Matrix font_matrix;
FT_Vector font_offset;
PS_Blend blend; /* for multiple master support */
FT_Long* buildchar;
FT_UInt len_buildchar;
} PS_Decoder;
/*************************************************************************/
/*************************************************************************/
/***** *****/

View File

@ -22,6 +22,8 @@ SubDir FT2_TOP $(FT2_SRC_DIR) psaux ;
psobjs
t1cmap
t1decode
cffdecode
psdecode
psarrst
psblues
pserror

View File

@ -26,6 +26,7 @@
#include "t1cmap.c"
#include "t1decode.c"
#include "cffdecode.c"
#include "psdecode.c"
#include "psarrst.c"
#include "psblues.c"

57
src/psaux/psdecode.c Normal file
View File

@ -0,0 +1,57 @@
#include <ft2build.h>
#include FT_INTERNAL_SERVICE_H
#include FT_SERVICE_CFF_TABLE_LOAD_H
#include "psdecode.h"
#include "psobjs.h"
#include "psauxerr.h"
/*************************************************************************/
/* */
/* <Function> */
/* ps_decoder_init */
/* */
/* <Description> */
/* Initializes a given glyph decoder. */
/* */
/* <InOut> */
/* decoder :: A pointer to the glyph builder to initialize. */
/* */
/* <Input> */
/* face :: The current face object. */
/* */
/* size :: The current size object. */
/* */
/* slot :: The current glyph object. */
/* */
/* hinting :: Whether hinting is active. */
/* */
/* hint_mode :: The hinting mode. */
/* */
FT_LOCAL_DEF( void )
ps_decoder_init( PS_Decoder* decoder,
TT_Face face,
FT_Size size,
CFF_GlyphSlot slot,
FT_Byte** glyph_names,
PS_Blend blend,
FT_Bool hinting,
FT_Render_Mode hint_mode,
PS_Decoder_Get_Glyph_Callback get_callback,
PS_Decoder_Free_Glyph_Callback free_callback )
{
}
/* this function is used to select the subfont */
/* and the locals subrs array */
FT_LOCAL_DEF( FT_Error )
ps_decoder_prepare( PS_Decoder* decoder,
FT_Size size,
FT_UInt glyph_index )
{
}

13
src/psaux/psdecode.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef PSDECODE_H_
#define PSDECODE_H_
#include <ft2build.h>
#include FT_INTERNAL_POSTSCRIPT_AUX_H
#include "cffdecode.h"
#include "t1decode.h"
#endif

View File

@ -2023,6 +2023,250 @@
}
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** PS BUILDER *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* */
/* <Function> */
/* ps_builder_init */
/* */
/* <Description> */
/* Initializes a given glyph builder. */
/* */
/* <InOut> */
/* builder :: A pointer to the glyph builder to initialize. */
/* */
/* <Input> */
/* face :: The current face object. */
/* */
/* size :: The current size object. */
/* */
/* glyph :: The current glyph object. */
/* */
/* hinting :: Whether hinting should be applied. */
/* */
FT_LOCAL_DEF( void )
ps_builder_init( PS_Builder* builder,
TT_Face face,
FT_Size size,
CFF_GlyphSlot glyph,
FT_Bool hinting )
{
}
/*************************************************************************/
/* */
/* <Function> */
/* ps_builder_done */
/* */
/* <Description> */
/* Finalizes a given glyph builder. Its contents can still be used */
/* after the call, but the function saves important information */
/* within the corresponding glyph slot. */
/* */
/* <Input> */
/* builder :: A pointer to the glyph builder to finalize. */
/* */
FT_LOCAL_DEF( void )
ps_builder_done( PS_Builder* builder )
{
CFF_GlyphSlot glyph = builder->glyph;
if ( glyph )
glyph->root.outline = *builder->base;
}
/* check that there is enough space for `count' more points */
FT_LOCAL_DEF( FT_Error )
ps_builder_check_points( PS_Builder* builder,
FT_Int count )
{
return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
}
/* add a new point, do not check space */
FT_LOCAL_DEF( void )
ps_builder_add_point( PS_Builder* builder,
FT_Pos x,
FT_Pos y,
FT_Byte flag )
{
FT_Outline* outline = builder->current;
if ( builder->load_points )
{
FT_Vector* point = outline->points + outline->n_points;
FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( builder->face );
if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
{
point->x = x >> 16;
point->y = y >> 16;
}
else
#endif
#ifdef T1_CONFIG_OPTION_OLD_ENGINE
if ( builder->face->is_t1 )
{
point->x = FIXED_TO_INT( x );
point->y = FIXED_TO_INT( y );
}
else
#endif
{
/* cf2_decoder_parse_charstrings uses 16.16 coordinates */
point->x = x >> 10;
point->y = y >> 10;
}
*control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
}
outline->n_points++;
}
/* check space for a new on-curve point, then add it */
FT_LOCAL_DEF( FT_Error )
ps_builder_add_point1( PS_Builder* builder,
FT_Pos x,
FT_Pos y )
{
FT_Error error;
error = ps_builder_check_points( builder, 1 );
if ( !error )
ps_builder_add_point( builder, x, y, 1 );
return error;
}
/* check space for a new contour, then add it */
FT_LOCAL_DEF( FT_Error )
ps_builder_add_contour( PS_Builder* builder )
{
FT_Outline* outline = builder->current;
FT_Error error;
/* this might happen in invalid fonts */
if ( !outline )
{
FT_ERROR(( "t1_builder_add_contour: no outline to add points to\n" ));
return FT_THROW( Invalid_File_Format );
}
if ( !builder->load_points )
{
outline->n_contours++;
return FT_Err_Ok;
}
error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
if ( !error )
{
if ( outline->n_contours > 0 )
outline->contours[outline->n_contours - 1] =
(short)( outline->n_points - 1 );
outline->n_contours++;
}
return error;
}
/* if a path was begun, add its first on-curve point */
FT_LOCAL_DEF( FT_Error )
ps_builder_start_point( PS_Builder* builder,
FT_Pos x,
FT_Pos y )
{
FT_Error error = FT_Err_Ok;
/* test whether we are building a new contour */
if ( !builder->path_begun )
{
builder->path_begun = 1;
error = ps_builder_add_contour( builder );
if ( !error )
error = ps_builder_add_point1( builder, x, y );
}
return error;
}
/* close the current contour */
FT_LOCAL_DEF( void )
ps_builder_close_contour( PS_Builder* builder )
{
FT_Outline* outline = builder->current;
FT_Int first;
if ( !outline )
return;
first = outline->n_contours <= 1
? 0 : outline->contours[outline->n_contours - 2] + 1;
/* in malformed fonts it can happen that a contour was started */
/* but no points were added */
if ( outline->n_contours && first == outline->n_points )
{
outline->n_contours--;
return;
}
/* We must not include the last point in the path if it */
/* is located on the first point. */
if ( outline->n_points > 1 )
{
FT_Vector* p1 = outline->points + first;
FT_Vector* p2 = outline->points + outline->n_points - 1;
FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
/* `delete' last point only if it coincides with the first */
/* point and it is not a control point (which can happen). */
if ( p1->x == p2->x && p1->y == p2->y )
if ( *control == FT_CURVE_TAG_ON )
outline->n_points--;
}
if ( outline->n_contours > 0 )
{
/* Don't add contours only consisting of one point, i.e., */
/* check whether the first and the last point is the same. */
if ( first == outline->n_points - 1 )
{
outline->n_contours--;
outline->n_points--;
}
else
outline->contours[outline->n_contours - 1] =
(short)( outline->n_points - 1 );
}
}
/*************************************************************************/
/*************************************************************************/
/***** *****/

View File

@ -233,6 +233,51 @@ FT_BEGIN_HEADER
cff_builder_add_contour( CFF_Builder* builder );
/*************************************************************************/
/*************************************************************************/
/***** *****/
/***** PS BUILDER *****/
/***** *****/
/*************************************************************************/
/*************************************************************************/
FT_LOCAL( void )
ps_builder_init( PS_Builder* builder,
TT_Face face,
FT_Size size,
CFF_GlyphSlot glyph,
FT_Bool hinting );
FT_LOCAL( void )
ps_builder_done( PS_Builder* builder );
FT_LOCAL( FT_Error )
ps_builder_check_points( PS_Builder* builder,
FT_Int count );
FT_LOCAL( void )
ps_builder_add_point( PS_Builder* builder,
FT_Pos x,
FT_Pos y,
FT_Byte flag );
FT_LOCAL( FT_Error )
ps_builder_add_point1( PS_Builder* builder,
FT_Pos x,
FT_Pos y );
FT_LOCAL( FT_Error )
ps_builder_add_contour( PS_Builder* builder );
FT_LOCAL( FT_Error )
ps_builder_start_point( PS_Builder* builder,
FT_Pos x,
FT_Pos y );
FT_LOCAL( void )
ps_builder_close_contour( PS_Builder* builder );
/*************************************************************************/
/*************************************************************************/
/***** *****/

View File

@ -36,6 +36,7 @@ PSAUX_DRV_SRC := $(PSAUX_DIR)/psobjs.c \
$(PSAUX_DIR)/psauxmod.c \
$(PSAUX_DIR)/psarrst.c \
$(PSAUX_DIR)/psblues.c \
$(PSAUX_DIR)/psdecode.c \
$(PSAUX_DIR)/pserror.c \
$(PSAUX_DIR)/psfont.c \
$(PSAUX_DIR)/psft.c \