|
|
|
@ -43,277 +43,6 @@ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/********** *********/ |
|
|
|
|
/********** *********/ |
|
|
|
|
/********** GENERIC CHARSTRING PARSING *********/ |
|
|
|
|
/********** *********/ |
|
|
|
|
/********** *********/ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/* */ |
|
|
|
|
/* <Function> */ |
|
|
|
|
/* cff_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 is active. */ |
|
|
|
|
/* */ |
|
|
|
|
static void |
|
|
|
|
cff_builder_init( CFF_Builder* builder, |
|
|
|
|
TT_Face face, |
|
|
|
|
CFF_Size size, |
|
|
|
|
CFF_GlyphSlot glyph, |
|
|
|
|
FT_Bool hinting ) |
|
|
|
|
{ |
|
|
|
|
builder->path_begun = 0; |
|
|
|
|
builder->load_points = 1; |
|
|
|
|
|
|
|
|
|
builder->face = face; |
|
|
|
|
builder->glyph = glyph; |
|
|
|
|
builder->memory = face->root.memory; |
|
|
|
|
|
|
|
|
|
if ( glyph ) |
|
|
|
|
{ |
|
|
|
|
FT_GlyphLoader loader = glyph->root.internal->loader; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
builder->loader = loader; |
|
|
|
|
builder->base = &loader->base.outline; |
|
|
|
|
builder->current = &loader->current.outline; |
|
|
|
|
FT_GlyphLoader_Rewind( loader ); |
|
|
|
|
|
|
|
|
|
builder->hints_globals = NULL; |
|
|
|
|
builder->hints_funcs = NULL; |
|
|
|
|
|
|
|
|
|
if ( hinting && size ) |
|
|
|
|
{ |
|
|
|
|
FT_Size ftsize = FT_SIZE( size ); |
|
|
|
|
CFF_Internal internal = (CFF_Internal)ftsize->internal->module_data; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ( internal ) |
|
|
|
|
{ |
|
|
|
|
builder->hints_globals = (void *)internal->topfont; |
|
|
|
|
builder->hints_funcs = glyph->root.internal->glyph_hints; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
builder->pos_x = 0; |
|
|
|
|
builder->pos_y = 0; |
|
|
|
|
|
|
|
|
|
builder->left_bearing.x = 0; |
|
|
|
|
builder->left_bearing.y = 0; |
|
|
|
|
builder->advance.x = 0; |
|
|
|
|
builder->advance.y = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/* */ |
|
|
|
|
/* <Function> */ |
|
|
|
|
/* cff_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. */ |
|
|
|
|
/* */ |
|
|
|
|
static void |
|
|
|
|
cff_builder_done( CFF_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 ) |
|
|
|
|
cff_check_points( CFF_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 ) |
|
|
|
|
cff_builder_add_point( CFF_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 |
|
|
|
|
{ |
|
|
|
|
/* 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 ) |
|
|
|
|
cff_builder_add_point1( CFF_Builder* builder, |
|
|
|
|
FT_Pos x, |
|
|
|
|
FT_Pos y ) |
|
|
|
|
{ |
|
|
|
|
FT_Error error; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
error = cff_check_points( builder, 1 ); |
|
|
|
|
if ( !error ) |
|
|
|
|
cff_builder_add_point( builder, x, y, 1 ); |
|
|
|
|
|
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* check space for a new contour, then add it */ |
|
|
|
|
static FT_Error |
|
|
|
|
cff_builder_add_contour( CFF_Builder* builder ) |
|
|
|
|
{ |
|
|
|
|
FT_Outline* outline = builder->current; |
|
|
|
|
FT_Error error; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 ) |
|
|
|
|
cff_builder_start_point( CFF_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 = cff_builder_add_contour( builder ); |
|
|
|
|
if ( !error ) |
|
|
|
|
error = cff_builder_add_point1( builder, x, y ); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return error; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* close the current contour */ |
|
|
|
|
FT_LOCAL_DEF( void ) |
|
|
|
|
cff_builder_close_contour( CFF_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; |
|
|
|
|
|
|
|
|
|
/* 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 if 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 begin point and last point are 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 ); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FT_LOCAL_DEF( FT_Error ) |
|
|
|
|
cff_get_glyph_data( TT_Face face, |
|
|
|
|
FT_UInt glyph_index, |
|
|
|
@ -385,9 +114,6 @@ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|
/*************************************************************************/ |
|
|
|
|