Commit 08fdac98 authored by David Turner's avatar David Turner
Browse files

fixed a bug in the glyph loader that caused a memory

block to be freed twice. Also performed changes to use
the new glyph zone object that has appeared in ftobjs.h
parent cbfaedce
......@@ -153,8 +153,8 @@
/* assemble composite glyphs. */
/* */
static
void mount_zone( TT_GlyphZone* source,
TT_GlyphZone* target )
void mount_zone( FT_GlyphZone* source,
FT_GlyphZone* target )
{
TT_UInt np;
TT_Int nc;
......@@ -164,7 +164,7 @@
target->org = source->org + np;
target->cur = source->cur + np;
target->touch = source->touch + np;
target->flags = source->flags + np;
target->contours = source->contours + nc;
......@@ -194,7 +194,7 @@
{
TT_Error error;
FT_Stream stream = load->stream;
TT_GlyphZone* zone = &load->zone;
FT_GlyphZone* zone = &load->zone;
TT_Face face = load->face;
TT_UShort n_ins;
......@@ -258,11 +258,14 @@
}
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
MEM_Copy( load->exec->glyphIns, stream->cursor, n_ins );
if ( (load->load_flags & (FT_LOAD_NO_SCALE|FT_LOAD_NO_HINTING))==0 )
{
MEM_Copy( load->exec->glyphIns, stream->cursor, n_ins );
error = TT_Set_CodeRange( load->exec, tt_coderange_glyph,
load->exec->glyphIns, n_ins );
if (error) goto Fail;
error = TT_Set_CodeRange( load->exec, tt_coderange_glyph,
load->exec->glyphIns, n_ins );
if (error) goto Fail;
}
#endif
stream->cursor += n_ins;
......@@ -271,7 +274,7 @@
/* reading the point flags */
{
TT_Byte* flag = load->zone.touch;
TT_Byte* flag = load->zone.flags;
TT_Byte* limit = flag + n_points;
TT_Byte c, count;
......@@ -292,7 +295,7 @@
{
TT_Vector* vec = zone->org;
TT_Vector* limit = vec + n_points;
TT_Byte* flag = zone->touch;
TT_Byte* flag = zone->flags;
TT_Pos x = 0;
for ( ; vec < limit; vec++, flag++ )
......@@ -313,12 +316,12 @@
}
/*********************************************************************/
/* reading the YX coordinates */
/* reading the Y coordinates */
{
TT_Vector* vec = zone->org;
TT_Vector* limit = vec + n_points;
TT_Byte* flag = zone->touch;
TT_Byte* flag = zone->flags;
TT_Pos x = 0;
for ( ; vec < limit; vec++, flag++ )
......@@ -362,10 +365,10 @@
/* clear the touch flags */
for ( n = 0; n < n_points; n++ )
zone->touch[n] &= FT_Curve_Tag_On;
zone->flags[n] &= FT_Curve_Tag_On;
zone->touch[n_points ] = 0;
zone->touch[n_points + 1] = 0;
zone->flags[n_points ] = 0;
zone->flags[n_points + 1] = 0;
}
/* Note that we return two more points that are not */
/* part of the glyph outline. */
......@@ -418,7 +421,7 @@
load->exec->is_composite = FALSE;
load->exec->pedantic_hinting = (TT_Bool)(load->load_flags & FT_LOAD_PEDANTIC);
load->exec->pts = *zone;
load->exec->pts.n_points += 2;
load->exec->pts.n_points += 2;
error = TT_Run_Context( load->exec, debug );
if ( error && load->exec->pedantic_hinting )
......@@ -485,6 +488,7 @@
x_scale = 0x10000;
y_scale = 0x10000;
if ( (loader->load_flags & FT_LOAD_NO_SCALE)==0 )
{
x_scale = loader->size->root.metrics.x_scale;
y_scale = loader->size->root.metrics.y_scale;
......@@ -819,7 +823,7 @@
TT_UShort n_ins;
TT_ExecContext exec = loader->exec;
TT_UInt n_points = loader->base.n_points;
TT_GlyphZone* pts;
FT_GlyphZone* pts;
TT_Vector* pp1;
/* read size of instructions */
......@@ -857,8 +861,8 @@
pp1[0] = loader->pp1;
pp1[1] = loader->pp2;
pts->touch[num_points - 1] = 0;
pts->touch[num_points - 2] = 0;
pts->flags[num_points + 1] = 0;
pts->flags[num_points + 2] = 0;
/* if hinting, round the phantom points */
if ( IS_HINTED(loader->load_flags) )
......@@ -870,7 +874,7 @@
{
TT_UInt k;
for ( k = 0; k < n_points; k++ )
pts->touch[k] &= FT_Curve_Tag_On;
pts->flags[k] &= FT_Curve_Tag_On;
}
cur_to_org( n_points, pts );
......@@ -946,7 +950,7 @@
for ( u = 0; u < num_points + 2; u++ )
{
glyph->outline.points[u] = loader->base.cur[u];
glyph->outline.flags [u] = loader->base.touch[u];
glyph->outline.flags [u] = loader->base.flags[u];
}
for ( u = 0; u < num_contours; u++ )
......@@ -1148,6 +1152,7 @@
FT_Memory memory;
TT_Error error;
TT_Loader loader;
FT_GlyphZone* zone;
face = (TT_Face)glyph->face;
sfnt = (SFNT_Interface*)face->sfnt;
......@@ -1209,11 +1214,23 @@
if (error)
{
FT_ERROR(( "TT.GLoad: could not access glyph table\n" ));
return error;
goto Exit;
}
MEM_Set( &loader, 0, sizeof(loader) );
/* update the glyph zone bounds */
zone = &((TT_Driver)face->root.driver)->zone;
error = FT_Update_GlyphZone( zone,
face->root.max_points,
face->root.max_contours );
if (error)
{
FT_ERROR(( "TT.GLoad: could not update loader glyph zone\n" ));
goto Exit;
}
loader.base = *zone;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
if ( size )
{
......@@ -1234,11 +1251,7 @@
glyph->outline.high_precision = ( size->root.metrics.y_ppem < 24 );
/************************************************************************/
/* let's initialise our loader now */
error = TT_New_GlyphZone( memory, &loader.base,
face->root.max_points, face->root.max_contours );
if (error) return error;
/* let's initialise the rest of our loader now */
loader.left_points = face->root.max_points;
loader.left_contours = face->root.max_contours;
loader.load_flags = load_flags;
......@@ -1267,7 +1280,7 @@
TT_Done_Context( loader.exec );
#endif
TT_Done_GlyphZone( memory, &loader.base );
Exit:
return error;
}
......
......@@ -53,8 +53,8 @@
TT_ULong glyf_offset;
/* the zone where we load our glyphs */
TT_GlyphZone base;
TT_GlyphZone zone;
FT_GlyphZone base;
FT_GlyphZone zone;
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
TT_ExecContext exec;
......
......@@ -383,7 +383,6 @@
exec->loadSize = 0;
/* points zone */
TT_Done_GlyphZone( exec->memory, &exec->pts );
exec->maxPoints = 0;
exec->maxContours = 0;
......@@ -518,57 +517,6 @@
}
/*************************************************************************/
/* */
/* <Function> */
/* Update_Zone */
/* */
/* <Description> */
/* Checks the size of a zone and reallocates it if necessary. */
/* */
/* <Input> */
/* newPoints :: The new capacity for points. We add two slots for */
/* phantom points. */
/* */
/* newContours :: The new capacity for contours. */
/* */
/* <InOut> */
/* zone :: The address of the target zone. */
/* */
/* maxPoints :: The address of the zone's current capacity for */
/* points. */
/* */
/* maxContours :: The address of the zone's current capacity for */
/* contours. */
/* */
static
TT_Error Update_Zone( FT_Memory memory,
TT_GlyphZone* zone,
TT_UShort* maxPoints,
TT_Short* maxContours,
TT_UShort newPoints,
TT_Short newContours )
{
newPoints += 2;
if ( *maxPoints < newPoints || *maxContours < newContours )
{
TT_Error error;
TT_Done_GlyphZone( memory, zone );
error = TT_New_GlyphZone( memory, zone, newPoints, newContours );
if ( error )
return error;
*maxPoints = newPoints;
*maxContours = newContours;
}
return TT_Err_Ok;
}
/*************************************************************************/
/* */
......@@ -601,7 +549,6 @@
TT_MaxProfile* maxp;
TT_Error error;
exec->face = face;
maxp = &face->max_profile;
exec->size = size;
......@@ -665,16 +612,6 @@
if ( error )
return error;
/* XXX: Update_Zone() reserves two positions for the phantom points! */
error = Update_Zone( exec->memory,
&exec->pts,
&exec->maxPoints,
&exec->maxContours,
exec->face->root.max_points,
exec->face->root.max_contours );
if ( error )
return error;
exec->pts.n_points = 0;
exec->pts.n_contours = 0;
......@@ -1427,7 +1364,7 @@
/* zone :: The affected glyph zone. */
/* */
static
void Direct_Move( EXEC_OP_ TT_GlyphZone* zone,
void Direct_Move( EXEC_OP_ FT_GlyphZone* zone,
TT_UShort point,
TT_F26Dot6 distance )
{
......@@ -1446,7 +1383,7 @@
v * 0x10000L,
CUR.F_dot_P );
#endif
zone->touch[point] |= FT_Curve_Tag_Touch_X;
zone->flags[point] |= FT_Curve_Tag_Touch_X;
}
v = CUR.GS.freeVector.y;
......@@ -1461,7 +1398,7 @@
v * 0x10000L,
CUR.F_dot_P );
#endif
zone->touch[point] |= FT_Curve_Tag_Touch_Y;
zone->flags[point] |= FT_Curve_Tag_Touch_Y;
}
}
......@@ -1476,26 +1413,26 @@
/*************************************************************************/
static
void Direct_Move_X( EXEC_OP_ TT_GlyphZone* zone,
void Direct_Move_X( EXEC_OP_ FT_GlyphZone* zone,
TT_UShort point,
TT_F26Dot6 distance )
{
UNUSED_EXEC;
zone->cur[point].x += distance;
zone->touch[point] |= FT_Curve_Tag_Touch_X;
zone->flags[point] |= FT_Curve_Tag_Touch_X;
}
static
void Direct_Move_Y( EXEC_OP_ TT_GlyphZone* zone,
void Direct_Move_Y( EXEC_OP_ FT_GlyphZone* zone,
TT_UShort point,
TT_F26Dot6 distance )
{
UNUSED_EXEC;
zone->cur[point].y += distance;
zone->touch[point] |= FT_Curve_Tag_Touch_Y;
zone->flags[point] |= FT_Curve_Tag_Touch_Y;
}
......@@ -4854,7 +4791,7 @@
}
}
else
CUR.pts.touch[point] ^= FT_Curve_Tag_On;
CUR.pts.flags[point] ^= FT_Curve_Tag_On;
CUR.GS.loop--;
}
......@@ -4888,7 +4825,7 @@
}
for ( I = L; I <= K; I++ )
CUR.pts.touch[I] |= FT_Curve_Tag_On;
CUR.pts.flags[I] |= FT_Curve_Tag_On;
}
......@@ -4916,17 +4853,17 @@
}
for ( I = L; I <= K; I++ )
CUR.pts.touch[I] &= ~FT_Curve_Tag_On;
CUR.pts.flags[I] &= ~FT_Curve_Tag_On;
}
static
TT_Bool Compute_Point_Displacement( EXEC_OP_ TT_F26Dot6* x,
TT_F26Dot6* y,
TT_GlyphZone* zone,
FT_GlyphZone* zone,
TT_UShort* refp )
{
TT_GlyphZone zp;
FT_GlyphZone zp;
TT_UShort p;
TT_F26Dot6 d;
......@@ -4979,14 +4916,14 @@
{
CUR.zp2.cur[point].x += dx;
if ( touch )
CUR.zp2.touch[point] |= FT_Curve_Tag_Touch_X;
CUR.zp2.flags[point] |= FT_Curve_Tag_Touch_X;
}
if ( CUR.GS.freeVector.y != 0 )
{
CUR.zp2.cur[point].y += dy;
if ( touch )
CUR.zp2.touch[point] |= FT_Curve_Tag_Touch_Y;
CUR.zp2.flags[point] |= FT_Curve_Tag_Touch_Y;
}
}
......@@ -5000,7 +4937,7 @@
static
void Ins_SHP( INS_ARG )
{
TT_GlyphZone zp;
FT_GlyphZone zp;
TT_UShort refp;
TT_F26Dot6 dx,
......@@ -5053,7 +4990,7 @@
static
void Ins_SHC( INS_ARG )
{
TT_GlyphZone zp;
FT_GlyphZone zp;
TT_UShort refp;
TT_F26Dot6 dx,
dy;
......@@ -5109,7 +5046,7 @@
static
void Ins_SHZ( INS_ARG )
{
TT_GlyphZone zp;
FT_GlyphZone zp;
TT_UShort refp;
TT_F26Dot6 dx,
dy;
......@@ -5660,7 +5597,7 @@
dx = CUR.zp0.cur[b0].x - CUR.zp1.cur[a0].x;
dy = CUR.zp0.cur[b0].y - CUR.zp1.cur[a0].y;
CUR.zp2.touch[point] |= FT_Curve_Tag_Touch_Both;
CUR.zp2.flags[point] |= FT_Curve_Tag_Touch_Both;
discriminant = TT_MULDIV( dax, -dby, 0x40 ) +
TT_MULDIV( day, dbx, 0x40 );
......@@ -5843,7 +5780,7 @@
if ( CUR.GS.freeVector.y != 0 )
mask &= ~FT_Curve_Tag_Touch_Y;
CUR.zp0.touch[point] &= mask;
CUR.zp0.flags[point] &= mask;
}
......@@ -5996,7 +5933,7 @@
end_point = CUR.pts.contours[contour];
first_point = point;
while ( point <= end_point && (CUR.pts.touch[point] & mask) == 0 )
while ( point <= end_point && (CUR.pts.flags[point] & mask) == 0 )
point++;
if ( point <= end_point )
......@@ -6008,7 +5945,7 @@
while ( point <= end_point )
{
if ( (CUR.pts.touch[point] & mask) != 0 )
if ( (CUR.pts.flags[point] & mask) != 0 )
{
if ( point > 0 )
Interp( cur_touched + 1,
......@@ -7657,8 +7594,8 @@
TT_Error error = 0;
TT_GlyphZone save;
TT_GlyphZone pts;
FT_GlyphZone save;
FT_GlyphZone pts;
#define TT_Round_Off 5
#define TT_Round_To_Half_Grid 0
......@@ -7695,7 +7632,7 @@
MEM_Alloc( save.org, sizeof ( TT_Vector ) * save.n_points );
MEM_Alloc( save.cur, sizeof ( TT_Vector ) * save.n_points );
MEM_Alloc( save.touch, sizeof ( TT_Byte ) * save.n_points );
MEM_Alloc( save.flags, sizeof ( TT_Byte ) * save.n_points );
exc->instruction_trap = 1;
......@@ -7858,7 +7795,7 @@
MEM_Copy( save.org, pts.org, pts.n_points * sizeof ( TT_Vector ) );
MEM_Copy( save.cur, pts.cur, pts.n_points * sizeof ( TT_Vector ) );
MEM_Copy( save.touch, pts.touch, pts.n_points );
MEM_Copy( save.flags, pts.flags, pts.n_points );
/* a return indicate the last command */
if (ch == '\r')
......@@ -7912,14 +7849,14 @@
if ( save.org[A].y != pts.org[A].y ) diff |= 2;
if ( save.cur[A].x != pts.cur[A].x ) diff |= 4;
if ( save.cur[A].y != pts.cur[A].y ) diff |= 8;
if ( save.touch[A] != pts.touch[A] ) diff |= 16;
if ( save.flags[A] != pts.flags[A] ) diff |= 16;
if ( diff )
{
FT_TRACE0(( "%02hx ", A ));
if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx ";
FT_TRACE0(( temp, save.touch[A] & 7 ));
FT_TRACE0(( temp, save.flags[A] & 7 ));
if ( diff & 1 ) temp = "(%08lx)"; else temp = " %08lx ";
FT_TRACE0(( temp, save.org[A].x ));
......@@ -7938,7 +7875,7 @@
FT_TRACE0(( "%02hx ", A ));
if ( diff & 16 ) temp = "[%01hx]"; else temp = " %01hx ";
FT_TRACE0(( temp, pts.touch[A] & 7 ));
FT_TRACE0(( temp, pts.flags[A] & 7 ));
if ( diff & 1 ) temp = "[%08lx]"; else temp = " %08lx ";
FT_TRACE0(( temp, pts.org[A].x ));
......
......@@ -71,7 +71,7 @@
TT_F26Dot6 compensation );
/* Point displacement along the freedom vector routine */
typedef void (*TT_Move_Func)( EXEC_OP_ TT_GlyphZone* zone,
typedef void (*TT_Move_Func)( EXEC_OP_ FT_GlyphZone* zone,
TT_UInt point,
TT_F26Dot6 distance );
......@@ -125,7 +125,7 @@
TT_Long args;
TT_UInt new_top; /* new top after exec. */
TT_GlyphZone zp0, /* zone records */
FT_GlyphZone zp0, /* zone records */
zp1,
zp2,
pts,
......
......@@ -46,75 +46,6 @@
/*************************************************************************/
/*************************************************************************/
/* */
/* <Function> */
/* TT_New_GlyphZone */
/* */
/* <Description> */
/* Allocates a new glyph zone. */
/* */
/* <Input> */
/* memory :: A handle to the current memory object. */
/* */
/* maxPoints :: The capacity of glyph zone in points. */
/* */
/* maxContours :: The capacity of glyph zone in contours. */
/* */
/* <InOut> */
/* pts :: A pointer to the target glyph zone record. */
/* */
/* <Return> */
/* TrueType error code. 0 means success. */
/* */
LOCAL_FUNC
TT_Error TT_New_GlyphZone( FT_Memory memory,
TT_GlyphZone* pts,
TT_UShort maxPoints,
TT_Short maxContours )
{
TT_Error error;
if ( ALLOC( pts->org, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) ||
ALLOC( pts->cur, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) ||
ALLOC( pts->touch, maxPoints * sizeof ( TT_Byte ) ) ||
ALLOC( pts->contours, maxContours * sizeof ( TT_UShort ) ) )
return error;
return TT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
/* TT_Done_GlyphZone */
/* */
/* <Description> */
/* Deallocates a glyph zone. */
/* */
/* <Input> */
/* memory :: A handle to the current memory object. */
/* */
/* pts :: A pointer to the target glyph zone record. */
/* */
/* <Return> */
/* TrueType error code. 0 means success. */
/* */
LOCAL_FUNC
TT_Error TT_Done_GlyphZone( FT_Memory memory,
TT_GlyphZone* pts )
{
FREE( pts->contours );
FREE( pts->touch );
FREE( pts->cur );
FREE( pts->org );
return TT_Err_Ok;
}
/*************************************************************************/
/* */
/* <Function> */
......@@ -525,7 +456,7 @@
/* reserve twilight zone */
n_twilight = maxp->maxTwilightPoints;
error = TT_New_GlyphZone( memory, &size->twilight, n_twilight, 0 );
error = FT_New_GlyphZone( memory, n_twilight, 0, &size->twilight );
if ( error )
goto Fail_Memory;
......@@ -662,7 +593,7 @@
size->storage_size = 0;
/* twilight zone */
TT_Done_GlyphZone( memory, &size->twilight );
FT_Done_GlyphZone( &size->twilight );
FREE( size->function_defs );
FREE( size->instruction_defs );
......@@ -894,12 +825,16 @@
LOCAL_FUNC