fixed a potential memory leak when loading embedded bitmaps
This commit is contained in:
parent
c06eb3b73a
commit
c60c61c684
3
CHANGES
3
CHANGES
|
@ -53,6 +53,9 @@ LATEST CHANGES -
|
||||||
- updated the tutorial (not finished though).
|
- updated the tutorial (not finished though).
|
||||||
- updated the top-level BUILD document
|
- updated the top-level BUILD document
|
||||||
|
|
||||||
|
- fixed a potential memory leak that could occur when loading embedded
|
||||||
|
bitmaps.
|
||||||
|
|
||||||
- added the declaration of FT_New_Memory_Face in <freetype/freetype.h>, as
|
- added the declaration of FT_New_Memory_Face in <freetype/freetype.h>, as
|
||||||
it was missing from the public header (the implementation was already
|
it was missing from the public header (the implementation was already
|
||||||
in "ftobjs.c").
|
in "ftobjs.c").
|
||||||
|
|
|
@ -1304,10 +1304,17 @@
|
||||||
/* returned by FT_Load_Glyph(). */
|
/* returned by FT_Load_Glyph(). */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ft_glyph_own_bitmap = 1
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct FT_GlyphSlotRec_
|
typedef struct FT_GlyphSlotRec_
|
||||||
{
|
{
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
FT_GlyphSlot next;
|
FT_GlyphSlot next;
|
||||||
|
FT_UInt flags;
|
||||||
|
|
||||||
FT_Glyph_Metrics metrics;
|
FT_Glyph_Metrics metrics;
|
||||||
FT_Glyph_Metrics metrics2;
|
FT_Glyph_Metrics metrics2;
|
||||||
|
|
|
@ -1403,7 +1403,9 @@
|
||||||
ebdt_pos = FILE_Pos();
|
ebdt_pos = FILE_Pos();
|
||||||
|
|
||||||
/* clear the bitmap & load the bitmap */
|
/* clear the bitmap & load the bitmap */
|
||||||
FREE( map->buffer );
|
if (face->root.glyph->flags & ft_glyph_own_bitmap)
|
||||||
|
FREE( map->buffer );
|
||||||
|
|
||||||
map->rows = map->pitch = map->width = 0;
|
map->rows = map->pitch = map->width = 0;
|
||||||
|
|
||||||
error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
|
error = Load_SBit_Image( strike, range, ebdt_pos, glyph_offset,
|
||||||
|
@ -1411,6 +1413,9 @@
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
|
/* the glyph slot owns this bitmap buffer */
|
||||||
|
face->root.glyph->flags |= ft_glyph_own_bitmap;
|
||||||
|
|
||||||
/* setup vertical metrics if needed */
|
/* setup vertical metrics if needed */
|
||||||
if ( strike->flags & 1 )
|
if ( strike->flags & 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,7 +88,7 @@
|
||||||
/* Test for Apple Unicode encoding */
|
/* Test for Apple Unicode encoding */
|
||||||
else if ( rec->platformID == TT_PLATFORM_APPLE_UNICODE )
|
else if ( rec->platformID == TT_PLATFORM_APPLE_UNICODE )
|
||||||
found = 1;
|
found = 1;
|
||||||
|
|
||||||
/* Test for Apple Roman */
|
/* Test for Apple Roman */
|
||||||
else if ( rec->platformID == TT_PLATFORM_MACINTOSH &&
|
else if ( rec->platformID == TT_PLATFORM_MACINTOSH &&
|
||||||
rec->languageID == TT_MAC_ID_ROMAN )
|
rec->languageID == TT_MAC_ID_ROMAN )
|
||||||
|
@ -106,11 +106,11 @@
|
||||||
if ( wide_chars )
|
if ( wide_chars )
|
||||||
{
|
{
|
||||||
TT_UInt m;
|
TT_UInt m;
|
||||||
|
|
||||||
len = (TT_UInt)rec->stringLength / 2;
|
len = (TT_UInt)rec->stringLength / 2;
|
||||||
if ( MEM_Alloc( string, len + 1 ) )
|
if ( MEM_Alloc( string, len + 1 ) )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for ( m = 0; m < len; m ++ )
|
for ( m = 0; m < len; m ++ )
|
||||||
string[m] = rec->string[2*m + 1];
|
string[m] = rec->string[2*m + 1];
|
||||||
}
|
}
|
||||||
|
@ -173,31 +173,31 @@
|
||||||
{
|
{
|
||||||
/* look-up the SFNT driver */
|
/* look-up the SFNT driver */
|
||||||
FT_Driver sfnt_driver;
|
FT_Driver sfnt_driver;
|
||||||
|
|
||||||
sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" );
|
sfnt_driver = FT_Get_Driver( face->root.driver->library, "sfnt" );
|
||||||
if (!sfnt_driver)
|
if (!sfnt_driver)
|
||||||
return FT_Err_Invalid_File_Format;
|
return FT_Err_Invalid_File_Format;
|
||||||
|
|
||||||
sfnt = (SFNT_Interface*)(sfnt_driver->interface.format_interface);
|
sfnt = (SFNT_Interface*)(sfnt_driver->interface.format_interface);
|
||||||
if (!sfnt)
|
if (!sfnt)
|
||||||
return FT_Err_Invalid_File_Format;
|
return FT_Err_Invalid_File_Format;
|
||||||
|
|
||||||
face->sfnt = sfnt;
|
face->sfnt = sfnt;
|
||||||
face->goto_table = sfnt->goto_table;
|
face->goto_table = sfnt->goto_table;
|
||||||
}
|
}
|
||||||
|
|
||||||
psnames = (PSNames_Interface*)face->psnames;
|
psnames = (PSNames_Interface*)face->psnames;
|
||||||
if (!psnames)
|
if (!psnames)
|
||||||
{
|
{
|
||||||
/* look-up the PSNames driver */
|
/* look-up the PSNames driver */
|
||||||
FT_Driver psnames_driver;
|
FT_Driver psnames_driver;
|
||||||
|
|
||||||
psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" );
|
psnames_driver = FT_Get_Driver( face->root.driver->library, "psnames" );
|
||||||
if (psnames_driver)
|
if (psnames_driver)
|
||||||
face->psnames = (PSNames_Interface*)
|
face->psnames = (PSNames_Interface*)
|
||||||
(psnames_driver->interface.format_interface);
|
(psnames_driver->interface.format_interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create input stream from resource */
|
/* create input stream from resource */
|
||||||
if ( FILE_Seek(0) )
|
if ( FILE_Seek(0) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
@ -205,7 +205,7 @@
|
||||||
/* check that we have a valid TrueType file */
|
/* check that we have a valid TrueType file */
|
||||||
error = sfnt->load_format_tag( face, stream, face_index, &format_tag );
|
error = sfnt->load_format_tag( face, stream, face_index, &format_tag );
|
||||||
if (error) goto Exit;
|
if (error) goto Exit;
|
||||||
|
|
||||||
/* We must also be able to accept Mac/GX fonts, as well as OT ones */
|
/* We must also be able to accept Mac/GX fonts, as well as OT ones */
|
||||||
if ( format_tag != 0x00010000 && /* MS fonts */
|
if ( format_tag != 0x00010000 && /* MS fonts */
|
||||||
format_tag != TTAG_true ) /* Mac fonts */
|
format_tag != TTAG_true ) /* Mac fonts */
|
||||||
|
@ -245,7 +245,7 @@
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
/* the optional tables */
|
/* the optional tables */
|
||||||
|
|
||||||
/* embedded bitmap support. */
|
/* embedded bitmap support. */
|
||||||
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
|
||||||
if (sfnt->load_sbits && LOAD_(sbits)) goto Exit;
|
if (sfnt->load_sbits && LOAD_(sbits)) goto Exit;
|
||||||
|
@ -295,13 +295,13 @@
|
||||||
FT_Memory memory = face->root.memory;
|
FT_Memory memory = face->root.memory;
|
||||||
|
|
||||||
SFNT_Interface* sfnt = face->sfnt;
|
SFNT_Interface* sfnt = face->sfnt;
|
||||||
|
|
||||||
if (sfnt)
|
if (sfnt)
|
||||||
{
|
{
|
||||||
/* destroy the postscript names table if it is supported */
|
/* destroy the postscript names table if it is supported */
|
||||||
if (sfnt->free_psnames)
|
if (sfnt->free_psnames)
|
||||||
sfnt->free_psnames( face );
|
sfnt->free_psnames( face );
|
||||||
|
|
||||||
/* destroy the embedded bitmaps table if it is supported */
|
/* destroy the embedded bitmaps table if it is supported */
|
||||||
if (sfnt->free_sbits)
|
if (sfnt->free_sbits)
|
||||||
sfnt->free_sbits( face );
|
sfnt->free_sbits( face );
|
||||||
|
@ -372,7 +372,7 @@
|
||||||
/* freeing family and style name */
|
/* freeing family and style name */
|
||||||
FREE( face->root.family_name );
|
FREE( face->root.family_name );
|
||||||
FREE( face->root.style_name );
|
FREE( face->root.style_name );
|
||||||
|
|
||||||
face->sfnt = 0;
|
face->sfnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -402,7 +402,7 @@
|
||||||
TT_Error TT_Init_Size( TT_Size size )
|
TT_Error TT_Init_Size( TT_Size size )
|
||||||
{
|
{
|
||||||
TT_Error error = 0;
|
TT_Error error = 0;
|
||||||
|
|
||||||
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||||
TT_Face face = (TT_Face)size->root.face;
|
TT_Face face = (TT_Face)size->root.face;
|
||||||
FT_Memory memory = face->root.memory;
|
FT_Memory memory = face->root.memory;
|
||||||
|
@ -470,7 +470,7 @@
|
||||||
/* set `face->interpreter' according to the debug hook present */
|
/* set `face->interpreter' according to the debug hook present */
|
||||||
{
|
{
|
||||||
FT_Library library = face->root.driver->library;
|
FT_Library library = face->root.driver->library;
|
||||||
|
|
||||||
face->interpreter = (TT_Interpreter)
|
face->interpreter = (TT_Interpreter)
|
||||||
library->debug_hooks[ FT_DEBUG_HOOK_TRUETYPE ];
|
library->debug_hooks[ FT_DEBUG_HOOK_TRUETYPE ];
|
||||||
if (!face->interpreter)
|
if (!face->interpreter)
|
||||||
|
@ -682,13 +682,13 @@
|
||||||
{
|
{
|
||||||
TT_ExecContext exec;
|
TT_ExecContext exec;
|
||||||
TT_UInt i, j;
|
TT_UInt i, j;
|
||||||
|
|
||||||
/* Scale the cvt values to the new ppem. */
|
/* Scale the cvt values to the new ppem. */
|
||||||
/* We use by default the y ppem to scale the CVT. */
|
/* We use by default the y ppem to scale the CVT. */
|
||||||
|
|
||||||
for ( i = 0; i < size->cvt_size; i++ )
|
for ( i = 0; i < size->cvt_size; i++ )
|
||||||
size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
|
size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
|
||||||
|
|
||||||
/* All twilight points are originally zero */
|
/* All twilight points are originally zero */
|
||||||
for ( j = 0; j < size->twilight.n_points; j++ )
|
for ( j = 0; j < size->twilight.n_points; j++ )
|
||||||
{
|
{
|
||||||
|
@ -697,55 +697,55 @@
|
||||||
size->twilight.cur[j].x = 0;
|
size->twilight.cur[j].x = 0;
|
||||||
size->twilight.cur[j].y = 0;
|
size->twilight.cur[j].y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear storage area */
|
/* clear storage area */
|
||||||
for ( i = 0; i < size->storage_size; i++ )
|
for ( i = 0; i < size->storage_size; i++ )
|
||||||
size->storage[i] = 0;
|
size->storage[i] = 0;
|
||||||
|
|
||||||
size->GS = tt_default_graphics_state;
|
size->GS = tt_default_graphics_state;
|
||||||
|
|
||||||
/* get execution context and run prep program */
|
/* get execution context and run prep program */
|
||||||
if ( size->debug )
|
if ( size->debug )
|
||||||
exec = size->context;
|
exec = size->context;
|
||||||
else
|
else
|
||||||
exec = TT_New_Context( face );
|
exec = TT_New_Context( face );
|
||||||
/* debugging instances have their own context */
|
/* debugging instances have their own context */
|
||||||
|
|
||||||
if ( !exec )
|
if ( !exec )
|
||||||
return TT_Err_Could_Not_Find_Context;
|
return TT_Err_Could_Not_Find_Context;
|
||||||
|
|
||||||
TT_Load_Context( exec, face, size );
|
TT_Load_Context( exec, face, size );
|
||||||
|
|
||||||
TT_Set_CodeRange( exec,
|
TT_Set_CodeRange( exec,
|
||||||
tt_coderange_cvt,
|
tt_coderange_cvt,
|
||||||
face->cvt_program,
|
face->cvt_program,
|
||||||
face->cvt_program_size );
|
face->cvt_program_size );
|
||||||
|
|
||||||
TT_Clear_CodeRange( exec, tt_coderange_glyph );
|
TT_Clear_CodeRange( exec, tt_coderange_glyph );
|
||||||
|
|
||||||
exec->instruction_trap = FALSE;
|
exec->instruction_trap = FALSE;
|
||||||
|
|
||||||
exec->top = 0;
|
exec->top = 0;
|
||||||
exec->callTop = 0;
|
exec->callTop = 0;
|
||||||
|
|
||||||
if ( face->cvt_program_size > 0 )
|
if ( face->cvt_program_size > 0 )
|
||||||
{
|
{
|
||||||
error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
|
error = TT_Goto_CodeRange( exec, tt_coderange_cvt, 0 );
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Fin;
|
goto Fin;
|
||||||
|
|
||||||
if ( !size->debug )
|
if ( !size->debug )
|
||||||
error = face->interpreter( exec );
|
error = face->interpreter( exec );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error = TT_Err_Ok;
|
error = TT_Err_Ok;
|
||||||
|
|
||||||
size->GS = exec->GS;
|
size->GS = exec->GS;
|
||||||
/* save default graphics state */
|
/* save default graphics state */
|
||||||
|
|
||||||
Fin:
|
Fin:
|
||||||
TT_Save_Context( exec, size );
|
TT_Save_Context( exec, size );
|
||||||
|
|
||||||
if ( !size->debug )
|
if ( !size->debug )
|
||||||
TT_Done_Context( exec );
|
TT_Done_Context( exec );
|
||||||
/* debugging instances keep their context */
|
/* debugging instances keep their context */
|
||||||
|
@ -806,7 +806,10 @@
|
||||||
void TT_Done_GlyphSlot( TT_GlyphSlot slot )
|
void TT_Done_GlyphSlot( TT_GlyphSlot slot )
|
||||||
{
|
{
|
||||||
FT_Library library = slot->face->driver->library;
|
FT_Library library = slot->face->driver->library;
|
||||||
|
FT_Memory memory = library->memory;
|
||||||
|
|
||||||
|
if (slot->flags & ft_glyph_own_bitmap)
|
||||||
|
FREE( slot->bitmap.buffer );
|
||||||
|
|
||||||
FT_Outline_Done( library, &slot->outline );
|
FT_Outline_Done( library, &slot->outline );
|
||||||
return;
|
return;
|
||||||
|
@ -832,10 +835,10 @@
|
||||||
{
|
{
|
||||||
FT_Memory memory = driver->root.memory;
|
FT_Memory memory = driver->root.memory;
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
|
|
||||||
error = FT_New_GlyphZone( memory, 0, 0, &driver->zone );
|
error = FT_New_GlyphZone( memory, 0, 0, &driver->zone );
|
||||||
if (error) return error;
|
if (error) return error;
|
||||||
|
|
||||||
/* init extension registry if needed */
|
/* init extension registry if needed */
|
||||||
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
|
#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE
|
||||||
return TT_Init_Extensions( driver );
|
return TT_Init_Extensions( driver );
|
||||||
|
|
Loading…
Reference in New Issue