summaryrefslogtreecommitdiff
path: root/lib/freetype/src
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2007-09-08 16:39:55 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2007-09-08 16:39:55 +0000
commitfdc39c7e9488fb0441bfade6d614661d6d8fb8ad (patch)
treeb93b72ce25b3acd111507da4ac00cad11a8e3e65 /lib/freetype/src
parentd5cbccbea2f75d2267c1b19ff04f73213b56eb5f (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.c65
-rw-r--r--lib/freetype/src/sfnt/ttsbit0.h7
-rw-r--r--lib/freetype/src/truetype/ttgload.c363
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 )
{