diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2007-09-08 16:39:55 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2007-09-08 16:39:55 +0000 |
commit | fdc39c7e9488fb0441bfade6d614661d6d8fb8ad (patch) | |
tree | b93b72ce25b3acd111507da4ac00cad11a8e3e65 /lib/freetype/src | |
parent | d5cbccbea2f75d2267c1b19ff04f73213b56eb5f (diff) |
Merge freetype 2.3.5. Tested by naddy@ and mbalmer@.
Diffstat (limited to 'lib/freetype/src')
-rw-r--r-- | lib/freetype/src/bdf/bdflib.c | 65 | ||||
-rw-r--r-- | lib/freetype/src/sfnt/ttsbit0.h | 7 | ||||
-rw-r--r-- | lib/freetype/src/truetype/ttgload.c | 363 |
3 files changed, 256 insertions, 179 deletions
diff --git a/lib/freetype/src/bdf/bdflib.c b/lib/freetype/src/bdf/bdflib.c index 743c9c677..512cd62c3 100644 --- a/lib/freetype/src/bdf/bdflib.c +++ b/lib/freetype/src/bdf/bdflib.c @@ -1,6 +1,7 @@ /* * Copyright 2000 Computing Research Labs, New Mexico State University - * Copyright 2001, 2002, 2003, 2004, 2005, 2006 Francesco Zappa Nardelli + * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 + * Francesco Zappa Nardelli * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -1262,7 +1263,6 @@ { unsigned long propid; hashnode hn; - int len; bdf_property_t *prop, *fp; FT_Memory memory = font->memory; FT_Error error = BDF_Err_Ok; @@ -1281,19 +1281,11 @@ /* Delete the current atom if it exists. */ FT_FREE( fp->value.atom ); - if ( value == 0 ) - len = 1; - else - len = ft_strlen( value ) + 1; - - if ( len > 1 ) + if ( value && value[0] != 0 ) { - if ( FT_NEW_ARRAY( fp->value.atom, len ) ) + if ( FT_STRDUP( fp->value.atom, value ) ) goto Exit; - FT_MEM_COPY( fp->value.atom, value, len ); } - else - fp->value.atom = 0; break; case BDF_INTEGER: @@ -1358,19 +1350,12 @@ switch ( prop->format ) { case BDF_ATOM: - if ( value == 0 ) - len = 1; - else - len = ft_strlen( value ) + 1; - - if ( len > 1 ) + fp->value.atom = 0; + if ( value != 0 && value[0] ) { - if ( FT_NEW_ARRAY( fp->value.atom, len ) ) + if ( FT_STRDUP( fp->value.atom, value ) ) goto Exit; - FT_MEM_COPY( fp->value.atom, value, len ); } - else - fp->value.atom = 0; break; case BDF_INTEGER: @@ -1552,6 +1537,12 @@ s = _bdf_list_join( &p->list, ' ', &slen ); + if ( !s ) + { + error = BDF_Err_Invalid_File_Format; + goto Exit; + } + if ( FT_NEW_ARRAY( p->glyph_name, slen + 1 ) ) goto Exit; @@ -2132,6 +2123,13 @@ _bdf_list_shift( &p->list, 1 ); s = _bdf_list_join( &p->list, ' ', &slen ); + + if ( !s ) + { + error = BDF_Err_Invalid_File_Format; + goto Exit; + } + if ( FT_NEW_ARRAY( p->font->name, slen + 1 ) ) goto Exit; FT_MEM_COPY( p->font->name, s, slen + 1 ); @@ -2221,7 +2219,7 @@ bdf_options_t* opts, bdf_font_t* *font ) { - unsigned long lineno; + unsigned long lineno = 0; /* make compiler happy */ _bdf_parse_t *p; FT_Memory memory = extmemory; @@ -2241,7 +2239,7 @@ error = _bdf_readstream( stream, _bdf_parse_start, (void *)p, &lineno ); if ( error ) - goto Exit; + goto Fail; if ( p->font != 0 ) { @@ -2316,11 +2314,19 @@ { /* The ENDFONT field was never reached or did not exist. */ if ( !( p->flags & _BDF_GLYPHS ) ) + { /* Error happened while parsing header. */ FT_ERROR(( "bdf_load_font: " ERRMSG2, lineno )); + error = BDF_Err_Corrupted_Font_Header; + goto Exit; + } else + { /* Error happened when parsing glyphs. */ FT_ERROR(( "bdf_load_font: " ERRMSG3, lineno )); + error = BDF_Err_Corrupted_Font_Glyphs; + goto Exit; + } } } @@ -2333,7 +2339,7 @@ if ( FT_RENEW_ARRAY( p->font->comments, p->font->comments_len, p->font->comments_len + 1 ) ) - goto Exit; + goto Fail; p->font->comments[p->font->comments_len] = 0; } @@ -2354,6 +2360,15 @@ } return error; + + Fail: + bdf_free_font( p->font ); + + memory = extmemory; + + FT_FREE( p->font ); + + goto Exit; } diff --git a/lib/freetype/src/sfnt/ttsbit0.h b/lib/freetype/src/sfnt/ttsbit0.h deleted file mode 100644 index 396ddc555..000000000 --- a/lib/freetype/src/sfnt/ttsbit0.h +++ /dev/null @@ -1,7 +0,0 @@ -/* - * ttsbit0.h - * - * This is a dummy file, used to please the build system. It is never - * included by the sfnt sources. - * - */ diff --git a/lib/freetype/src/truetype/ttgload.c b/lib/freetype/src/truetype/ttgload.c index deb6b978b..d41b2ee82 100644 --- a/lib/freetype/src/truetype/ttgload.c +++ b/lib/freetype/src/truetype/ttgload.c @@ -4,7 +4,7 @@ /* */ /* TrueType Glyph Loader (body). */ /* */ -/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 by */ +/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ @@ -108,7 +108,7 @@ if ( face->vertical_info ) ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah ); -#if 1 /* Emperically determined, at variance with what MS said */ +#if 1 /* Empirically determined, at variance with what MS said */ else { @@ -188,6 +188,9 @@ if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) ) return error; + loader->cursor = stream->cursor; + loader->limit = stream->limit; + return TT_Err_Ok; } @@ -205,26 +208,26 @@ FT_CALLBACK_DEF( FT_Error ) TT_Load_Glyph_Header( TT_Loader loader ) { - FT_Stream stream = loader->stream; - FT_Int byte_len = loader->byte_len - 10; + FT_Byte* p = loader->cursor; + FT_Byte* limit = loader->limit; - if ( byte_len < 0 ) + if ( p + 10 > limit ) return TT_Err_Invalid_Outline; - loader->n_contours = FT_GET_SHORT(); + loader->n_contours = FT_NEXT_SHORT( p ); - loader->bbox.xMin = FT_GET_SHORT(); - loader->bbox.yMin = FT_GET_SHORT(); - loader->bbox.xMax = FT_GET_SHORT(); - loader->bbox.yMax = FT_GET_SHORT(); + loader->bbox.xMin = FT_NEXT_SHORT( p ); + loader->bbox.yMin = FT_NEXT_SHORT( p ); + loader->bbox.xMax = FT_NEXT_SHORT( p ); + loader->bbox.yMax = FT_NEXT_SHORT( p ); FT_TRACE5(( " # of contours: %d\n", loader->n_contours )); FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin, loader->bbox.xMax )); FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin, loader->bbox.yMax )); - loader->byte_len = byte_len; + loader->cursor = p; return TT_Err_Ok; } @@ -234,20 +237,21 @@ TT_Load_Simple_Glyph( TT_Loader load ) { FT_Error error; - FT_Stream stream = load->stream; + FT_Byte* p = load->cursor; + FT_Byte* limit = load->limit; FT_GlyphLoader gloader = load->gloader; FT_Int n_contours = load->n_contours; FT_Outline* outline; TT_Face face = (TT_Face)load->face; FT_UShort n_ins; - FT_Int n, n_points; - FT_Int byte_len = load->byte_len; + FT_Int n_points; FT_Byte *flag, *flag_limit; FT_Byte c, count; FT_Vector *vec, *vec_limit; FT_Pos x; - FT_Short *cont, *cont_limit; + FT_Short *cont, *cont_limit, prev_cont; + FT_Int xy_size = 0; /* check that we can add the contours to the glyph */ @@ -260,12 +264,21 @@ cont_limit = cont + n_contours; /* check space for contours array + instructions count */ - byte_len -= 2 * ( n_contours + 1 ); - if ( byte_len < 0 ) + if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit ) goto Invalid_Outline; - for ( ; cont < cont_limit; cont++ ) - cont[0] = FT_GET_USHORT(); + cont[0] = prev_cont = FT_NEXT_USHORT( p ); + for ( cont++; cont < cont_limit; cont++ ) + { + cont[0] = FT_NEXT_USHORT( p ); + if ( cont[0] <= prev_cont ) + { + /* unordered contours: this is invalid */ + error = FT_Err_Invalid_Table; + goto Fail; + } + prev_cont = cont[0]; + } n_points = 0; if ( n_contours > 0 ) @@ -291,38 +304,41 @@ load->glyph->control_len = 0; load->glyph->control_data = 0; - n_ins = FT_GET_USHORT(); + if ( p + 2 > limit ) + goto Invalid_Outline; + + n_ins = FT_NEXT_USHORT( p ); FT_TRACE5(( " Instructions size: %u\n", n_ins )); if ( n_ins > face->max_profile.maxSizeOfInstructions ) { - FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions!\n" )); + FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions (%d)\n", + n_ins )); error = TT_Err_Too_Many_Hints; goto Fail; } - byte_len -= (FT_Int)n_ins; - if ( byte_len < 0 ) + if ( ( limit - p ) < n_ins ) { FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" )); error = TT_Err_Too_Many_Hints; goto Fail; } -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER if ( IS_HINTED( load->load_flags ) ) { load->glyph->control_len = n_ins; load->glyph->control_data = load->exec->glyphIns; - FT_MEM_COPY( load->exec->glyphIns, stream->cursor, (FT_Long)n_ins ); + FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins ); } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ - stream->cursor += (FT_Int)n_ins; + p += n_ins; /* reading the point tags */ flag = (FT_Byte*)outline->tags; @@ -332,16 +348,16 @@ while ( flag < flag_limit ) { - if ( --byte_len < 0 ) + if ( p + 1 > limit ) goto Invalid_Outline; - *flag++ = c = FT_GET_BYTE(); + *flag++ = c = FT_NEXT_BYTE( p ); if ( c & 8 ) { - if ( --byte_len < 0 ) + if ( p + 1 > limit ) goto Invalid_Outline; - count = FT_GET_BYTE(); + count = FT_NEXT_BYTE( p ); if ( flag + (FT_Int)count > flag_limit ) goto Invalid_Outline; @@ -350,23 +366,6 @@ } } - /* check that there is enough room to load the coordinates */ - for ( flag = (FT_Byte*)outline->tags; flag < flag_limit; flag++ ) - { - if ( *flag & 2 ) - byte_len -= 1; - else if ( ( *flag & 16 ) == 0 ) - byte_len -= 2; - - if ( *flag & 4 ) - byte_len -= 1; - else if ( ( *flag & 32 ) == 0 ) - byte_len -= 2; - } - - if ( byte_len < 0 ) - goto Invalid_Outline; - /* reading the X coordinates */ vec = outline->points; @@ -374,22 +373,35 @@ flag = (FT_Byte*)outline->tags; x = 0; + if ( p + xy_size > limit ) + goto Invalid_Outline; + for ( ; vec < vec_limit; vec++, flag++ ) { FT_Pos y = 0; + FT_Byte f = *flag; - if ( *flag & 2 ) + if ( f & 2 ) { - y = (FT_Pos)FT_GET_BYTE(); - if ( ( *flag & 16 ) == 0 ) + if ( p + 1 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_BYTE( p ); + if ( ( f & 16 ) == 0 ) y = -y; } - else if ( ( *flag & 16 ) == 0 ) - y = (FT_Pos)FT_GET_SHORT(); + else if ( ( f & 16 ) == 0 ) + { + if ( p + 2 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_SHORT( p ); + } x += y; vec->x = x; + *flag = f & ~( 2 | 16 ); } /* reading the Y coordinates */ @@ -402,29 +414,35 @@ for ( ; vec < vec_limit; vec++, flag++ ) { FT_Pos y = 0; + FT_Byte f = *flag; - if ( *flag & 4 ) + if ( f & 4 ) { - y = (FT_Pos)FT_GET_BYTE(); - if ( ( *flag & 32 ) == 0 ) + if ( p + 1 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_BYTE( p ); + if ( ( f & 32 ) == 0 ) y = -y; } - else if ( ( *flag & 32 ) == 0 ) - y = (FT_Pos)FT_GET_SHORT(); + else if ( ( f & 32 ) == 0 ) + { + if ( p + 2 > limit ) + goto Invalid_Outline; + + y = (FT_Pos)FT_NEXT_SHORT( p ); + } x += y; vec->y = x; + *flag = f & FT_CURVE_TAG_ON; } - /* clear the touch tags */ - for ( n = 0; n < n_points; n++ ) - outline->tags[n] &= FT_CURVE_TAG_ON; - outline->n_points = (FT_UShort)n_points; outline->n_contours = (FT_Short) n_contours; - load->byte_len = byte_len; + load->cursor = p; Fail: return error; @@ -439,11 +457,11 @@ TT_Load_Composite_Glyph( TT_Loader loader ) { FT_Error error; - FT_Stream stream = loader->stream; + FT_Byte* p = loader->cursor; + FT_Byte* limit = loader->limit; FT_GlyphLoader gloader = loader->gloader; FT_SubGlyph subglyph; FT_UInt num_subglyphs; - FT_Int byte_len = loader->byte_len; num_subglyphs = 0; @@ -451,6 +469,7 @@ do { FT_Fixed xx, xy, yy, yx; + FT_UInt count; /* check that we can load a new subglyph */ @@ -459,41 +478,40 @@ goto Fail; /* check space */ - byte_len -= 4; - if ( byte_len < 0 ) + if ( p + 4 > limit ) goto Invalid_Composite; subglyph = gloader->current.subglyphs + num_subglyphs; subglyph->arg1 = subglyph->arg2 = 0; - subglyph->flags = FT_GET_USHORT(); - subglyph->index = FT_GET_USHORT(); + subglyph->flags = FT_NEXT_USHORT( p ); + subglyph->index = FT_NEXT_USHORT( p ); /* check space */ - byte_len -= 2; + count = 2; if ( subglyph->flags & ARGS_ARE_WORDS ) - byte_len -= 2; + count += 2; if ( subglyph->flags & WE_HAVE_A_SCALE ) - byte_len -= 2; + count += 2; else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) - byte_len -= 4; + count += 4; else if ( subglyph->flags & WE_HAVE_A_2X2 ) - byte_len -= 8; + count += 8; - if ( byte_len < 0 ) + if ( p + count > limit ) goto Invalid_Composite; /* read arguments */ if ( subglyph->flags & ARGS_ARE_WORDS ) { - subglyph->arg1 = FT_GET_SHORT(); - subglyph->arg2 = FT_GET_SHORT(); + subglyph->arg1 = FT_NEXT_SHORT( p ); + subglyph->arg2 = FT_NEXT_SHORT( p ); } else { - subglyph->arg1 = FT_GET_CHAR(); - subglyph->arg2 = FT_GET_CHAR(); + subglyph->arg1 = FT_NEXT_CHAR( p ); + subglyph->arg2 = FT_NEXT_CHAR( p ); } /* read transform */ @@ -502,20 +520,20 @@ if ( subglyph->flags & WE_HAVE_A_SCALE ) { - xx = (FT_Fixed)FT_GET_SHORT() << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; yy = xx; } else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE ) { - xx = (FT_Fixed)FT_GET_SHORT() << 2; - yy = (FT_Fixed)FT_GET_SHORT() << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; } else if ( subglyph->flags & WE_HAVE_A_2X2 ) { - xx = (FT_Fixed)FT_GET_SHORT() << 2; - yx = (FT_Fixed)FT_GET_SHORT() << 2; - xy = (FT_Fixed)FT_GET_SHORT() << 2; - yy = (FT_Fixed)FT_GET_SHORT() << 2; + xx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yx = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + xy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; + yy = (FT_Fixed)FT_NEXT_SHORT( p ) << 2; } subglyph->transform.xx = xx; @@ -529,20 +547,23 @@ gloader->current.num_subglyphs = num_subglyphs; -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER { + FT_Stream stream = loader->stream; + + /* we must undo the FT_FRAME_ENTER in order to point to the */ /* composite instructions, if we find some. */ /* we will process them later... */ /* */ loader->ins_pos = (FT_ULong)( FT_STREAM_POS() + - stream->cursor - stream->limit ); + p - limit ); } #endif - loader->byte_len = byte_len; + loader->cursor = p; Fail: return error; @@ -570,12 +591,15 @@ FT_UInt start_point, FT_UInt start_contour ) { - zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); - zone->n_contours = (FT_Short) ( load->outline.n_contours - start_contour ); - zone->org = load->extra_points + start_point; - zone->cur = load->outline.points + start_point; - zone->tags = (FT_Byte*)load->outline.tags + start_point; - zone->contours = (FT_UShort*)load->outline.contours + start_contour; + zone->n_points = (FT_UShort)( load->outline.n_points - start_point ); + zone->n_contours = (FT_Short) ( load->outline.n_contours - + start_contour ); + zone->org = load->extra_points + start_point; + zone->cur = load->outline.points + start_point; + zone->orus = load->extra_points2 + start_point; + zone->tags = (FT_Byte*)load->outline.tags + start_point; + zone->contours = (FT_UShort*)load->outline.contours + start_contour; + zone->first_point = (FT_UShort)start_point; } @@ -588,9 +612,6 @@ /* Hint the glyph using the zone prepared by the caller. Note that */ /* the zone is supposed to include four phantom points. */ /* */ -#define cur_to_org( n, zone ) \ - FT_ARRAY_COPY( (zone)->org, (zone)->cur, (n) ) - static FT_Error TT_Hint_Glyph( TT_Loader loader, FT_Bool is_composite ) @@ -598,14 +619,14 @@ TT_GlyphZone zone = &loader->zone; FT_Pos origin; -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER FT_UInt n_ins; #else FT_UNUSED( is_composite ); #endif -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER n_ins = loader->glyph->control_len; #endif @@ -614,10 +635,10 @@ if ( origin ) translate_array( zone->n_points, zone->cur, origin, 0 ); -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER - /* save original point positioin in org */ +#ifdef TT_USE_BYTECODE_INTERPRETER + /* save original point position in org */ if ( n_ins > 0 ) - cur_to_org( zone->n_points, zone ); + FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points ); #endif /* round pp2 and pp4 */ @@ -626,7 +647,7 @@ zone->cur[zone->n_points - 1].y = FT_PIX_ROUND( zone->cur[zone->n_points - 1].y ); -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER if ( n_ins > 0 ) { @@ -642,8 +663,8 @@ loader->exec->is_composite = is_composite; loader->exec->pts = *zone; - debug = !( loader->load_flags & FT_LOAD_NO_SCALE ) && - ( (TT_Size)loader->size )->debug; + debug = FT_BOOL( !( loader->load_flags & FT_LOAD_NO_SCALE ) && + ((TT_Size)loader->size)->debug ); error = TT_Run_Context( loader->exec, debug ); if ( error && loader->exec->pedantic_hinting ) @@ -729,6 +750,14 @@ #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + if ( IS_HINTED( loader->load_flags ) ) + { + tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); + + FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur, + loader->zone.n_points + 4 ); + } + /* scale the glyph */ if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ) { @@ -752,7 +781,6 @@ if ( IS_HINTED( loader->load_flags ) ) { - tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 ); loader->zone.n_points += 4; error = TT_Hint_Glyph( loader, 0 ); @@ -926,7 +954,7 @@ /* */ /* <Description> */ /* This is slightly different from TT_Process_Simple_Glyph, in that */ - /* it's sole purpose is to hint the glyph. Thus this function is */ + /* its sole purpose is to hint the glyph. Thus this function is */ /* only available when bytecode interpreter is enabled. */ /* */ static FT_Error @@ -936,6 +964,7 @@ { FT_Error error; FT_Outline* outline; + FT_UInt i; outline = &loader->gloader->base.outline; @@ -957,7 +986,7 @@ outline->tags[outline->n_points + 2] = 0; outline->tags[outline->n_points + 3] = 0; -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER { FT_Stream stream = loader->stream; @@ -975,7 +1004,8 @@ /* check it */ if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions ) { - FT_TRACE0(( "Too many instructions (%d)\n", n_ins )); + FT_TRACE0(( "TT_Process_Composite_Glyph: Too many instructions (%d)\n", + n_ins )); return TT_Err_Too_Many_Hints; } @@ -993,6 +1023,13 @@ tt_prepare_zone( &loader->zone, &loader->gloader->base, start_point, start_contour ); + + /* Some points are likely touched during execution of */ + /* instructions on components. So let's untouch them. */ + for ( i = start_point; i < loader->zone.n_points; i++ ) + loader->zone.tags[i] &= ~( FT_CURVE_TAG_TOUCH_X | + FT_CURVE_TAG_TOUCH_Y ); + loader->zone.n_points += 4; return TT_Hint_Glyph( loader, 1 ); @@ -1268,9 +1305,9 @@ /* otherwise, load a composite! */ else if ( loader->n_contours == -1 ) { - FT_UInt start_point; - FT_UInt start_contour; - FT_ULong ins_pos; /* position of composite instructions, if any */ + FT_UInt start_point; + FT_UInt start_contour; + FT_ULong ins_pos; /* position of composite instructions, if any */ start_point = gloader->base.outline.n_points; @@ -1300,11 +1337,11 @@ /* this provides additional offsets */ /* for each component's translation */ - if ( (error = TT_Vary_Get_Glyph_Deltas( - face, - glyph_index, - &deltas, - gloader->current.num_subglyphs + 4 )) != 0 ) + if ( ( error = TT_Vary_Get_Glyph_Deltas( + face, + glyph_index, + &deltas, + gloader->current.num_subglyphs + 4 )) != 0 ) goto Exit; subglyph = gloader->current.subglyphs + gloader->base.num_subglyphs; @@ -1340,7 +1377,6 @@ /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */ /* `as is' in the glyph slot (the client application will be */ /* responsible for interpreting these data)... */ - /* */ if ( loader->load_flags & FT_LOAD_NO_RECURSE ) { FT_GlyphLoader_Add( gloader ); @@ -1354,14 +1390,21 @@ /*********************************************************************/ { - FT_UInt n, num_base_points; - FT_SubGlyph subglyph = 0; + FT_UInt n, num_base_points; + FT_SubGlyph subglyph = 0; + + FT_UInt num_points = start_point; + FT_UInt num_subglyphs = gloader->current.num_subglyphs; + FT_UInt num_base_subgs = gloader->base.num_subglyphs; + + FT_Stream old_stream = loader->stream; - FT_UInt num_points = start_point; - FT_UInt num_subglyphs = gloader->current.num_subglyphs; - FT_UInt num_base_subgs = gloader->base.num_subglyphs; + TT_GraphicsState saved_GS; + if ( loader->exec ) + saved_GS = loader->exec->GS; + FT_GlyphLoader_Add( gloader ); /* read each subglyph independently */ @@ -1370,6 +1413,10 @@ FT_Vector pp[4]; + /* reinitialize graphics state */ + if ( loader->exec ) + loader->exec->GS = saved_GS; + /* Each time we call load_truetype_glyph in this loop, the */ /* value of `gloader.base.subglyphs' can change due to table */ /* reallocations. We thus need to recompute the subglyph */ @@ -1404,22 +1451,23 @@ if ( num_points == num_base_points ) continue; - /* gloader->base.outline consists of three part: */ - /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */ - /* */ - /* (1): exist from the beginning */ - /* (2): components that have been loaded so far */ - /* (3): the newly loaded component */ + /* gloader->base.outline consists of three parts: */ + /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */ + /* */ + /* (1): exists from the beginning */ + /* (2): components that have been loaded so far */ + /* (3): the newly loaded component */ TT_Process_Composite_Component( loader, subglyph, start_point, num_base_points ); } + loader->stream = old_stream; /* process the glyph */ loader->ins_pos = ins_pos; if ( IS_HINTED( loader->load_flags ) && -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER subglyph->flags & WE_HAVE_INSTR && @@ -1432,7 +1480,7 @@ } else { - /* invalid composite count ( negative but not -1 ) */ + /* invalid composite count (negative but not -1) */ error = TT_Err_Invalid_Outline; goto Exit; } @@ -1460,8 +1508,8 @@ static FT_Error - compute_glyph_metrics( TT_Loader loader, - FT_UInt glyph_index ) + compute_glyph_metrics( TT_Loader loader, + FT_UInt glyph_index ) { FT_BBox bbox; TT_Face face = (TT_Face)loader->face; @@ -1479,8 +1527,8 @@ else bbox = loader->bbox; - /* get the device-independent horizontal advance. It is scaled later */ - /* by the base layer. */ + /* get the device-independent horizontal advance; it is scaled later */ + /* by the base layer. */ { FT_Pos advance = loader->linear; @@ -1699,40 +1747,63 @@ FT_MEM_ZERO( loader, sizeof ( TT_LoaderRec ) ); -#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER +#ifdef TT_USE_BYTECODE_INTERPRETER /* load execution context */ + if ( IS_HINTED( load_flags ) ) { TT_ExecContext exec; + FT_Bool grayscale; + if ( !size->cvt_ready ) + { + FT_Error error = tt_size_ready_bytecode( size ); + if ( error ) + return error; + } + /* query new execution context */ exec = size->debug ? size->context : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context; if ( !exec ) return TT_Err_Could_Not_Find_Context; + grayscale = + FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_RENDER_MODE_MONO ); + TT_Load_Context( exec, face, size ); - /* see if the cvt program has disabled hinting */ + /* a change from mono to grayscale rendering (and vice versa) */ + /* requires a re-execution of the CVT program */ + if ( grayscale != exec->grayscale ) + { + FT_UInt i; + + + exec->grayscale = grayscale; + + for ( i = 0; i < size->cvt_size; i++ ) + size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); + tt_size_run_prep( size ); + } + + /* see whether the cvt program has disabled hinting */ if ( exec->GS.instruct_control & 1 ) load_flags |= FT_LOAD_NO_HINTING; - /* load default graphics state - if needed */ + /* load default graphics state -- if needed */ if ( exec->GS.instruct_control & 2 ) exec->GS = tt_default_graphics_state; exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC ); - exec->grayscale = - FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) != FT_LOAD_TARGET_MONO ); - loader->exec = exec; loader->instructions = exec->glyphIns; } -#endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */ +#endif /* TT_USE_BYTECODE_INTERPRETER */ - /* seek to the beginning of the glyph table. For Type 42 fonts */ + /* seek to the beginning of the glyph table -- for Type 42 fonts */ /* the table might be accessed from a Postscript stream or something */ /* else... */ @@ -1810,13 +1881,11 @@ FT_Int32 load_flags ) { TT_Face face; - FT_Stream stream; FT_Error error; TT_LoaderRec loader; face = (TT_Face)glyph->face; - stream = face->root.stream; error = TT_Err_Ok; #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS @@ -1850,7 +1919,7 @@ glyph->num_subglyphs = 0; glyph->outline.flags = 0; - /* Main loading loop */ + /* main loading loop */ error = load_truetype_glyph( &loader, glyph_index, 0 ); if ( !error ) { |