Fri 09 Mar 2007 04:21:05 PM UTC, original submission:
Hello,
I have experiencing issue while rendering composite glyghs using incremental memory interface and using bytecode interpreter. The problem occurs while calling function TT_Process_Composite_Glyph from function load_truetype_glyph which acessing to a memory stream. In my opinion, the memory stream becomes invalid because is replaced by another stream which is stored on stack by function load_truetype_glyph called in loop. I have changed the code to save and restore previous memory stream and it seems to solve the problem. Below is the modified code fragment with comments.
Regards,
Martin
/*********************************************************************/
/*********************************************************************/
/*********************************************************************/
{
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;
//***save current stream
FT_StreamRec *oldinc_stream = loader->stream;
FT_GlyphLoader_Add( gloader );
/* read each subglyph independently */
for ( n = 0; n < num_subglyphs; n++ )
{
FT_Vector pp[4];
/* 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 */
/* pointer on each iteration. */
subglyph = gloader->base.subglyphs + num_base_subgs + n;
pp[0] = loader->pp1;
pp[1] = loader->pp2;
pp[2] = loader->pp3;
pp[3] = loader->pp4;
num_base_points = gloader->base.outline.n_points;
//***calling function below caused overwriting current stream interface by another which was stored on destroyed stack
error = load_truetype_glyph( loader, subglyph->index,
recurse_count + 1 );
if ( error )
goto Exit;
/* restore subglyph pointer */
subglyph = gloader->base.subglyphs + num_base_subgs + n;
if ( !( subglyph->flags & USE_MY_METRICS ) )
{
loader->pp1 = pp[0];
loader->pp2 = pp[1];
loader->pp3 = pp[2];
loader->pp4 = pp[3];
}
num_points = gloader->base.outline.n_points;
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 */
TT_Process_Composite_Component( loader, subglyph, start_point,
num_base_points );
}
//***restore stream
loader->stream = oldinc_stream;
/* process the glyph */
loader->ins_pos = ins_pos;
if ( IS_HINTED( loader->load_flags ) &&
#ifdef TT_USE_BYTECODE_INTERPRETER
subglyph->flags & WE_HAVE_INSTR &&
#endif
//***calling function below caused exception
num_points > start_point )
TT_Process_Composite_Glyph( loader, start_point, start_contour );
}
|