| Index: src/cff/cffgload.c
|
| diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
|
| index 84847fda57029861ac9e135af87f394f776bf469..1904ca019a6945875110ffa35d584de67c49c69d 100644
|
| --- a/src/cff/cffgload.c
|
| +++ b/src/cff/cffgload.c
|
| @@ -4,7 +4,7 @@
|
| /* */
|
| /* OpenType Glyph Loader (body). */
|
| /* */
|
| -/* Copyright 1996-2012 by */
|
| +/* Copyright 1996-2013 by */
|
| /* David Turner, Robert Wilhelm, and Werner Lemberg. */
|
| /* */
|
| /* This file is part of the FreeType project, and may only be used, */
|
| @@ -21,10 +21,12 @@
|
| #include FT_INTERNAL_STREAM_H
|
| #include FT_INTERNAL_SFNT_H
|
| #include FT_OUTLINE_H
|
| +#include FT_CFF_DRIVER_H
|
|
|
| #include "cffobjs.h"
|
| #include "cffload.h"
|
| #include "cffgload.h"
|
| +#include "cf2ft.h" /* for cf2_decoder_parse_charstrings */
|
|
|
| #include "cfferrs.h"
|
|
|
| @@ -39,6 +41,8 @@
|
| #define FT_COMPONENT trace_cffgload
|
|
|
|
|
| +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
| +
|
| typedef enum CFF_Operator_
|
| {
|
| cff_op_unknown = 0,
|
| @@ -209,6 +213,8 @@
|
| 2 /* setcurrentpoint */
|
| };
|
|
|
| +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
|
| +
|
|
|
| /*************************************************************************/
|
| /*************************************************************************/
|
| @@ -412,7 +418,7 @@
|
| CFF_Builder *builder = &decoder->builder;
|
| CFF_Font cff = (CFF_Font)builder->face->extra.data;
|
| CFF_SubFont sub = &cff->top_font;
|
| - FT_Error error = CFF_Err_Ok;
|
| + FT_Error error = FT_Err_Ok;
|
|
|
|
|
| /* manage CID fonts */
|
| @@ -424,7 +430,7 @@
|
| if ( fd_index >= cff->num_subfonts )
|
| {
|
| FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
|
| - error = CFF_Err_Invalid_File_Format;
|
| + error = FT_THROW( Invalid_File_Format );
|
| goto Exit;
|
| }
|
|
|
| @@ -455,22 +461,24 @@
|
| decoder->glyph_width = sub->private_dict.default_width;
|
| decoder->nominal_width = sub->private_dict.nominal_width;
|
|
|
| + decoder->current_subfont = sub; /* for Adobe's CFF handler */
|
| +
|
| Exit:
|
| return error;
|
| }
|
|
|
|
|
| /* check that there is enough space for `count' more points */
|
| - static FT_Error
|
| - check_points( CFF_Builder* builder,
|
| - FT_Int count )
|
| + 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 */
|
| - static void
|
| + FT_LOCAL_DEF( void )
|
| cff_builder_add_point( CFF_Builder* builder,
|
| FT_Pos x,
|
| FT_Pos y,
|
| @@ -484,9 +492,22 @@
|
| 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 );
|
| +
|
|
|
| - point->x = x >> 16;
|
| - point->y = y >> 16;
|
| + 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 );
|
| }
|
|
|
| @@ -495,7 +516,7 @@
|
|
|
|
|
| /* check space for a new on-curve point, then add it */
|
| - static FT_Error
|
| + FT_LOCAL_DEF( FT_Error )
|
| cff_builder_add_point1( CFF_Builder* builder,
|
| FT_Pos x,
|
| FT_Pos y )
|
| @@ -503,7 +524,7 @@
|
| FT_Error error;
|
|
|
|
|
| - error = check_points( builder, 1 );
|
| + error = cff_check_points( builder, 1 );
|
| if ( !error )
|
| cff_builder_add_point( builder, x, y, 1 );
|
|
|
| @@ -522,7 +543,7 @@
|
| if ( !builder->load_points )
|
| {
|
| outline->n_contours++;
|
| - return CFF_Err_Ok;
|
| + return FT_Err_Ok;
|
| }
|
|
|
| error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
|
| @@ -540,12 +561,12 @@
|
|
|
|
|
| /* if a path was begun, add its first on-curve point */
|
| - static FT_Error
|
| + FT_LOCAL_DEF( FT_Error )
|
| cff_builder_start_point( CFF_Builder* builder,
|
| FT_Pos x,
|
| FT_Pos y )
|
| {
|
| - FT_Error error = CFF_Err_Ok;
|
| + FT_Error error = FT_Err_Ok;
|
|
|
|
|
| /* test whether we are building a new contour */
|
| @@ -562,7 +583,7 @@
|
|
|
|
|
| /* close the current contour */
|
| - static void
|
| + FT_LOCAL_DEF( void )
|
| cff_builder_close_contour( CFF_Builder* builder )
|
| {
|
| FT_Outline* outline = builder->current;
|
| @@ -607,7 +628,7 @@
|
| }
|
|
|
|
|
| - static FT_Int
|
| + FT_LOCAL_DEF( FT_Int )
|
| cff_lookup_glyph_by_stdcharcode( CFF_Font cff,
|
| FT_Int charcode )
|
| {
|
| @@ -636,7 +657,7 @@
|
| }
|
|
|
|
|
| - static FT_Error
|
| + FT_LOCAL_DEF( FT_Error )
|
| cff_get_glyph_data( TT_Face face,
|
| FT_UInt glyph_index,
|
| FT_Byte** pointer,
|
| @@ -672,7 +693,7 @@
|
| }
|
|
|
|
|
| - static void
|
| + FT_LOCAL_DEF( void )
|
| cff_free_glyph_data( TT_Face face,
|
| FT_Byte** pointer,
|
| FT_ULong length )
|
| @@ -707,6 +728,8 @@
|
| }
|
|
|
|
|
| +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
| +
|
| static FT_Error
|
| cff_operator_seac( CFF_Decoder* decoder,
|
| FT_Pos asb,
|
| @@ -728,7 +751,7 @@
|
| if ( decoder->seac )
|
| {
|
| FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
|
| - return CFF_Err_Syntax_Error;
|
| + return FT_THROW( Syntax_Error );
|
| }
|
|
|
| adx += decoder->builder.left_bearing.x;
|
| @@ -756,7 +779,7 @@
|
| {
|
| FT_ERROR(( "cff_operator_seac:"
|
| " invalid seac character code arguments\n" ));
|
| - return CFF_Err_Syntax_Error;
|
| + return FT_THROW( Syntax_Error );
|
| }
|
|
|
| /* If we are trying to load a composite glyph, do not load the */
|
| @@ -925,7 +948,7 @@
|
| limit = zone->limit = charstring_base + charstring_len;
|
| ip = zone->cursor = zone->base;
|
|
|
| - error = CFF_Err_Ok;
|
| + error = FT_Err_Ok;
|
|
|
| x = builder->pos_x;
|
| y = builder->pos_y;
|
| @@ -953,11 +976,14 @@
|
|
|
|
|
| /* this is an operand, push it on the stack */
|
| +
|
| + /* if we use shifts, all computations are done with unsigned */
|
| + /* values; the conversion to a signed value is the last step */
|
| if ( v == 28 )
|
| {
|
| if ( ip + 1 >= limit )
|
| goto Syntax_Error;
|
| - val = (FT_Short)( ( (FT_Short)ip[0] << 8 ) | ip[1] );
|
| + val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
|
| ip += 2;
|
| }
|
| else if ( v < 247 )
|
| @@ -978,10 +1004,10 @@
|
| {
|
| if ( ip + 3 >= limit )
|
| goto Syntax_Error;
|
| - val = ( (FT_Int32)ip[0] << 24 ) |
|
| - ( (FT_Int32)ip[1] << 16 ) |
|
| - ( (FT_Int32)ip[2] << 8 ) |
|
| - ip[3];
|
| + val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
|
| + ( (FT_UInt32)ip[1] << 16 ) |
|
| + ( (FT_UInt32)ip[2] << 8 ) |
|
| + (FT_UInt32)ip[3] );
|
| ip += 4;
|
| if ( charstring_type == 2 )
|
| shift = 0;
|
| @@ -989,12 +1015,12 @@
|
| if ( decoder->top - stack >= CFF_MAX_OPERANDS )
|
| goto Stack_Overflow;
|
|
|
| - val <<= shift;
|
| + val = (FT_Int32)( (FT_UInt32)val << shift );
|
| *decoder->top++ = val;
|
|
|
| #ifdef FT_DEBUG_LEVEL_TRACE
|
| if ( !( val & 0xFFFFL ) )
|
| - FT_TRACE4(( " %ld", (FT_Int32)( val >> 16 ) ));
|
| + FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
|
| else
|
| FT_TRACE4(( " %.2f", val / 65536.0 ));
|
| #endif
|
| @@ -1411,8 +1437,8 @@
|
| case cff_op_rlineto:
|
| FT_TRACE4(( " rlineto\n" ));
|
|
|
| - if ( cff_builder_start_point ( builder, x, y ) ||
|
| - check_points( builder, num_args / 2 ) )
|
| + if ( cff_builder_start_point( builder, x, y ) ||
|
| + cff_check_points( builder, num_args / 2 ) )
|
| goto Fail;
|
|
|
| if ( num_args < 2 )
|
| @@ -1446,8 +1472,8 @@
|
| if ( num_args == 0 )
|
| break;
|
|
|
| - if ( cff_builder_start_point ( builder, x, y ) ||
|
| - check_points( builder, num_args ) )
|
| + if ( cff_builder_start_point( builder, x, y ) ||
|
| + cff_check_points( builder, num_args ) )
|
| goto Fail;
|
|
|
| args = stack;
|
| @@ -1480,8 +1506,8 @@
|
|
|
| nargs = num_args - num_args % 6;
|
|
|
| - if ( cff_builder_start_point ( builder, x, y ) ||
|
| - check_points( builder, nargs / 2 ) )
|
| + if ( cff_builder_start_point( builder, x, y ) ||
|
| + cff_check_points( builder, nargs / 2 ) )
|
| goto Fail;
|
|
|
| args -= nargs;
|
| @@ -1529,7 +1555,7 @@
|
| nargs--;
|
| }
|
|
|
| - if ( check_points( builder, 3 * ( nargs / 4 ) ) )
|
| + if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
|
| goto Fail;
|
|
|
| while ( args < decoder->top )
|
| @@ -1573,7 +1599,7 @@
|
| nargs--;
|
| }
|
|
|
| - if ( check_points( builder, 3 * ( nargs / 4 ) ) )
|
| + if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
|
| goto Fail;
|
|
|
| while ( args < decoder->top )
|
| @@ -1613,7 +1639,7 @@
|
| nargs = num_args & ~2;
|
|
|
| args -= nargs;
|
| - if ( check_points( builder, ( nargs / 4 ) * 3 ) )
|
| + if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
|
| goto Stack_Underflow;
|
|
|
| phase = ( op == cff_op_hvcurveto );
|
| @@ -1666,8 +1692,8 @@
|
| nargs = num_args & ~1;
|
| num_lines = ( nargs - 6 ) / 2;
|
|
|
| - if ( cff_builder_start_point( builder, x, y ) ||
|
| - check_points( builder, num_lines + 3 ) )
|
| + if ( cff_builder_start_point( builder, x, y ) ||
|
| + cff_check_points( builder, num_lines + 3 ) )
|
| goto Fail;
|
|
|
| args -= nargs;
|
| @@ -1711,8 +1737,8 @@
|
| nargs = nargs - nargs % 6 + 2;
|
| num_curves = ( nargs - 2 ) / 6;
|
|
|
| - if ( cff_builder_start_point ( builder, x, y ) ||
|
| - check_points( builder, num_curves * 3 + 2 ) )
|
| + if ( cff_builder_start_point( builder, x, y ) ||
|
| + cff_check_points( builder, num_curves * 3 + 2 ) )
|
| goto Fail;
|
|
|
| args -= nargs;
|
| @@ -1752,7 +1778,7 @@
|
| /* -- make sure we have enough space for the start point if it */
|
| /* needs to be added */
|
| if ( cff_builder_start_point( builder, x, y ) ||
|
| - check_points( builder, 6 ) )
|
| + cff_check_points( builder, 6 ) )
|
| goto Fail;
|
|
|
| /* record the starting point's y position for later use */
|
| @@ -1801,7 +1827,7 @@
|
|
|
| /* adding six more points; 4 control points, 2 on-curve points */
|
| if ( cff_builder_start_point( builder, x, y ) ||
|
| - check_points( builder, 6 ) )
|
| + cff_check_points( builder, 6 ) )
|
| goto Fail;
|
|
|
| /* record the starting point's y-position for later use */
|
| @@ -1854,7 +1880,7 @@
|
|
|
| /* adding six more points; 4 control points, 2 on-curve points */
|
| if ( cff_builder_start_point( builder, x, y ) ||
|
| - check_points( builder, 6 ) )
|
| + cff_check_points( builder, 6 ) )
|
| goto Fail;
|
|
|
| /* record the starting point's x, y position for later use */
|
| @@ -1917,7 +1943,7 @@
|
| FT_TRACE4(( " flex\n" ));
|
|
|
| if ( cff_builder_start_point( builder, x, y ) ||
|
| - check_points( builder, 6 ) )
|
| + cff_check_points( builder, 6 ) )
|
| goto Fail;
|
|
|
| for ( count = 6; count > 0; count-- )
|
| @@ -1968,7 +1994,7 @@
|
| else
|
| {
|
| if ( !error )
|
| - error = CFF_Err_Ok;
|
| + error = FT_Err_Ok;
|
|
|
| cff_builder_close_contour( builder );
|
|
|
| @@ -2470,7 +2496,7 @@
|
| FT_ERROR(( " %d", ip[0] ));
|
| FT_ERROR(( "\n" ));
|
|
|
| - return CFF_Err_Unimplemented_Feature;
|
| + return FT_THROW( Unimplemented_Feature );
|
| }
|
|
|
| decoder->top = args;
|
| @@ -2489,17 +2515,19 @@
|
|
|
| Syntax_Error:
|
| FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
|
| - return CFF_Err_Invalid_File_Format;
|
| + return FT_THROW( Invalid_File_Format );
|
|
|
| Stack_Underflow:
|
| FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
|
| - return CFF_Err_Too_Few_Arguments;
|
| + return FT_THROW( Too_Few_Arguments );
|
|
|
| Stack_Overflow:
|
| FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
|
| - return CFF_Err_Stack_Overflow;
|
| + return FT_THROW( Stack_Overflow );
|
| }
|
|
|
| +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
|
| +
|
|
|
| /*************************************************************************/
|
| /*************************************************************************/
|
| @@ -2526,7 +2554,7 @@
|
| cff_compute_max_advance( TT_Face face,
|
| FT_Int* max_advance )
|
| {
|
| - FT_Error error = CFF_Err_Ok;
|
| + FT_Error error = FT_Err_Ok;
|
| CFF_Decoder decoder;
|
| FT_Int glyph_index;
|
| CFF_Font cff = (CFF_Font)face->other;
|
| @@ -2564,12 +2592,12 @@
|
| }
|
|
|
| /* ignore the error if one has occurred -- skip to next glyph */
|
| - error = CFF_Err_Ok;
|
| + error = FT_Err_Ok;
|
| }
|
|
|
| *max_advance = decoder.builder.advance.x;
|
|
|
| - return CFF_Err_Ok;
|
| + return FT_Err_Ok;
|
| }
|
|
|
|
|
| @@ -2585,7 +2613,7 @@
|
| FT_Error error;
|
| CFF_Decoder decoder;
|
| TT_Face face = (TT_Face)glyph->root.face;
|
| - FT_Bool hinting, force_scaling;
|
| + FT_Bool hinting, scaled, force_scaling;
|
| CFF_Font cff = (CFF_Font)face->extra.data;
|
|
|
| FT_Matrix font_matrix;
|
| @@ -2606,11 +2634,11 @@
|
| glyph_index = cff_charset_cid_to_gindex( &cff->charset,
|
| glyph_index );
|
| if ( glyph_index == 0 )
|
| - return CFF_Err_Invalid_Argument;
|
| + return FT_THROW( Invalid_Argument );
|
| }
|
| }
|
| else if ( glyph_index >= cff->num_glyphs )
|
| - return CFF_Err_Invalid_Argument;
|
| + return FT_THROW( Invalid_Argument );
|
|
|
| if ( load_flags & FT_LOAD_NO_RECURSE )
|
| load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
|
| @@ -2653,6 +2681,11 @@
|
|
|
| if ( !error )
|
| {
|
| + FT_Bool has_vertical_info;
|
| + FT_UShort advance;
|
| + FT_Short dummy;
|
| +
|
| +
|
| glyph->root.outline.n_points = 0;
|
| glyph->root.outline.n_contours = 0;
|
|
|
| @@ -2679,6 +2712,39 @@
|
| glyph->root.bitmap_left = metrics.horiBearingX;
|
| glyph->root.bitmap_top = metrics.horiBearingY;
|
| }
|
| +
|
| + /* compute linear advance widths */
|
| +
|
| + ( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
|
| + glyph_index,
|
| + &dummy,
|
| + &advance );
|
| + glyph->root.linearHoriAdvance = advance;
|
| +
|
| + has_vertical_info = FT_BOOL(
|
| + face->vertical_info &&
|
| + face->vertical.number_Of_VMetrics > 0 );
|
| +
|
| + /* get the vertical metrics from the vtmx table if we have one */
|
| + if ( has_vertical_info )
|
| + {
|
| + ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
|
| + glyph_index,
|
| + &dummy,
|
| + &advance );
|
| + glyph->root.linearVertAdvance = advance;
|
| + }
|
| + else
|
| + {
|
| + /* make up vertical ones */
|
| + if ( face->os2.version != 0xFFFFU )
|
| + glyph->root.linearVertAdvance = (FT_Pos)
|
| + ( face->os2.sTypoAscender - face->os2.sTypoDescender );
|
| + else
|
| + glyph->root.linearVertAdvance = (FT_Pos)
|
| + ( face->horizontal.Ascender - face->horizontal.Descender );
|
| + }
|
| +
|
| return error;
|
| }
|
| }
|
| @@ -2688,7 +2754,7 @@
|
|
|
| /* return immediately if we only want the embedded bitmaps */
|
| if ( load_flags & FT_LOAD_SBITS_ONLY )
|
| - return CFF_Err_Invalid_Argument;
|
| + return FT_THROW( Invalid_Argument );
|
|
|
| /* if we have a CID subfont, use its matrix (which has already */
|
| /* been multiplied with the root matrix) */
|
| @@ -2700,6 +2766,7 @@
|
| FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
|
| glyph_index );
|
|
|
| +
|
| if ( fd_index >= cff->num_subfonts )
|
| fd_index = (FT_Byte)( cff->num_subfonts - 1 );
|
|
|
| @@ -2727,12 +2794,21 @@
|
| glyph->root.outline.n_points = 0;
|
| glyph->root.outline.n_contours = 0;
|
|
|
| - hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
|
| - ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
|
| + /* top-level code ensures that FT_LOAD_NO_HINTING is set */
|
| + /* if FT_LOAD_NO_SCALE is active */
|
| + hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
|
| + scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
|
|
|
| + glyph->hint = hinting;
|
| + glyph->scaled = scaled;
|
| glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */
|
|
|
| {
|
| +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
| + CFF_Driver driver = (CFF_Driver)FT_FACE_DRIVER( face );
|
| +#endif
|
| +
|
| +
|
| FT_Byte* charstring;
|
| FT_ULong charstring_len;
|
|
|
| @@ -2756,9 +2832,26 @@
|
| if ( error )
|
| goto Glyph_Build_Finished;
|
|
|
| - error = cff_decoder_parse_charstrings( &decoder,
|
| - charstring,
|
| - charstring_len );
|
| +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
|
| + /* choose which CFF renderer to use */
|
| + if ( driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
|
| + error = cff_decoder_parse_charstrings( &decoder,
|
| + charstring,
|
| + charstring_len );
|
| + else
|
| +#endif
|
| + {
|
| + error = cf2_decoder_parse_charstrings( &decoder,
|
| + charstring,
|
| + charstring_len );
|
| +
|
| + /* Adobe's engine uses 16.16 numbers everywhere; */
|
| + /* as a consequence, glyphs larger than 2000ppem get rejected */
|
| + if ( FT_ERR_EQ( error, Glyph_Too_Big ) )
|
| + {
|
| + /* XXX to be implemented */
|
| + }
|
| + }
|
|
|
| cff_free_glyph_data( face, &charstring, charstring_len );
|
|
|
| @@ -2856,14 +2949,8 @@
|
| glyph->root.linearHoriAdvance = decoder.glyph_width;
|
| glyph->root.internal->glyph_transformed = 0;
|
|
|
| -#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
|
| - has_vertical_info = FT_BOOL( face->vertical_info &&
|
| - face->vertical.number_Of_VMetrics > 0 &&
|
| - face->vertical.long_metrics );
|
| -#else
|
| has_vertical_info = FT_BOOL( face->vertical_info &&
|
| face->vertical.number_Of_VMetrics > 0 );
|
| -#endif
|
|
|
| /* get the vertical metrics from the vtmx table if we have one */
|
| if ( has_vertical_info )
|
|
|