* include/freetype/config/ftoption.h, include/freetype/internal/ttypes.h,
src/truetype/ttpload.c, src/truetype/ttpload.h, src/truetype/ttgload.c: added the temporary configuration FT_OPTIMIZE_MEMORY to control various optimizations used to reduce the heap footprint of memory-mapped TrueType files. * src/truetype/ttpload.c (tt_face_load_loca, tt_face_get_location, tt_face_done_loca): when FT_OPTIMIZE_MEMORY is set, the locations table is read directly from memory-mapped streams, instead of being decoded into the heap. * src/truetype/ttpload.c: only load the CVT and fpgm tables when the bytecode interpreter is compiled in.
This commit is contained in:
parent
3e26d07e60
commit
e70d553111
14
ChangeLog
14
ChangeLog
|
@ -18,6 +18,20 @@
|
||||||
* include/freetype/internal/ftmemory.h: adding FT_ARRAY_ZERO, as a
|
* include/freetype/internal/ftmemory.h: adding FT_ARRAY_ZERO, as a
|
||||||
convenience macro.
|
convenience macro.
|
||||||
|
|
||||||
|
* include/freetype/config/ftoption.h, include/freetype/internal/ttypes.h,
|
||||||
|
src/truetype/ttpload.c, src/truetype/ttpload.h, src/truetype/ttgload.c:
|
||||||
|
added the temporary configuration FT_OPTIMIZE_MEMORY to control various
|
||||||
|
optimizations used to reduce the heap footprint of memory-mapped TrueType
|
||||||
|
files.
|
||||||
|
|
||||||
|
* src/truetype/ttpload.c (tt_face_load_loca, tt_face_get_location,
|
||||||
|
tt_face_done_loca): when FT_OPTIMIZE_MEMORY is set, the locations table
|
||||||
|
is read directly from memory-mapped streams, instead of being decoded
|
||||||
|
into the heap.
|
||||||
|
|
||||||
|
* src/truetype/ttpload.c: only load the CVT and fpgm tables when the
|
||||||
|
bytecode interpreter is compiled in.
|
||||||
|
|
||||||
|
|
||||||
2005-02-20 Werner Lemberg <wl@gnu.org>
|
2005-02-20 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
|
|
|
@ -568,6 +568,8 @@ FT_BEGIN_HEADER
|
||||||
|
|
||||||
#endif /* FT_CONFIG_OPTION_CHESTER_HINTS */
|
#endif /* FT_CONFIG_OPTION_CHESTER_HINTS */
|
||||||
|
|
||||||
|
#define FT_OPTIMIZE_MEMORY
|
||||||
|
|
||||||
FT_END_HEADER
|
FT_END_HEADER
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -361,6 +361,7 @@ FT_BEGIN_HEADER
|
||||||
} TT_HdmxRec, *TT_Hdmx;
|
} TT_HdmxRec, *TT_Hdmx;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* <Struct> */
|
/* <Struct> */
|
||||||
|
@ -1263,9 +1264,14 @@ FT_BEGIN_HEADER
|
||||||
/* */
|
/* */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
|
#ifdef FT_OPTIMIZE_MEMORY
|
||||||
|
FT_UInt num_locations;
|
||||||
|
FT_Byte* glyph_locations;
|
||||||
|
#else
|
||||||
/* the glyph locations */
|
/* the glyph locations */
|
||||||
FT_UShort num_locations;
|
FT_UShort num_locations;
|
||||||
FT_Long* glyph_locations;
|
FT_Long* glyph_locations;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* the font program, if any */
|
/* the font program, if any */
|
||||||
FT_ULong font_program_size;
|
FT_ULong font_program_size;
|
||||||
|
|
|
@ -304,12 +304,15 @@
|
||||||
|
|
||||||
|
|
||||||
if ( FT_RENEW_ARRAY( outline->points, max, news ) ||
|
if ( FT_RENEW_ARRAY( outline->points, max, news ) ||
|
||||||
FT_RENEW_ARRAY( outline->horz_edges, max * 2, news * 2 ) ||
|
FT_RENEW_ARRAY( outline->horz_edges, max * 2, news * 2 ) )
|
||||||
FT_RENEW_ARRAY( outline->horz_segments, max * 2, news * 2 ) )
|
goto Exit;
|
||||||
|
|
||||||
|
outline->vert_edges = outline->horz_edges + news;
|
||||||
|
|
||||||
|
if ( FT_RENEW_ARRAY( outline->horz_segments, max * 2, news * 2 ) )
|
||||||
goto Exit;
|
goto Exit;
|
||||||
|
|
||||||
/* readjust some pointers */
|
/* readjust some pointers */
|
||||||
outline->vert_edges = outline->horz_edges + news;
|
|
||||||
outline->vert_segments = outline->horz_segments + news;
|
outline->vert_segments = outline->horz_segments + news;
|
||||||
outline->max_points = news;
|
outline->max_points = news;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1019,13 +1019,7 @@
|
||||||
|
|
||||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||||
|
|
||||||
{
|
offset = tt_face_get_location( face, glyph_index, &count );
|
||||||
offset = face->glyph_locations[glyph_index];
|
|
||||||
count = 0;
|
|
||||||
|
|
||||||
if ( glyph_index < (FT_UInt)face->num_locations - 1 )
|
|
||||||
count = (FT_UInt)( face->glyph_locations[glyph_index + 1] - offset );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( count == 0 )
|
if ( count == 0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -218,8 +218,11 @@
|
||||||
if ( !face->root.internal->incremental_interface )
|
if ( !face->root.internal->incremental_interface )
|
||||||
error = tt_face_load_loca( face, stream );
|
error = tt_face_load_loca( face, stream );
|
||||||
if ( !error )
|
if ( !error )
|
||||||
error = tt_face_load_cvt( face, stream ) ||
|
{
|
||||||
tt_face_load_fpgm( face, stream );
|
error = tt_face_load_cvt( face, stream );
|
||||||
|
if ( !error )
|
||||||
|
error = tt_face_load_fpgm( face, stream );
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -290,8 +293,7 @@
|
||||||
sfnt->done_face( face );
|
sfnt->done_face( face );
|
||||||
|
|
||||||
/* freeing the locations table */
|
/* freeing the locations table */
|
||||||
FT_FREE( face->glyph_locations );
|
tt_face_done_loca( face );
|
||||||
face->num_locations = 0;
|
|
||||||
|
|
||||||
/* freeing the CVT */
|
/* freeing the CVT */
|
||||||
FT_FREE( face->cvt );
|
FT_FREE( face->cvt );
|
||||||
|
|
|
@ -58,6 +58,118 @@
|
||||||
/* <Return> */
|
/* <Return> */
|
||||||
/* FreeType error code. 0 means success. */
|
/* FreeType error code. 0 means success. */
|
||||||
/* */
|
/* */
|
||||||
|
#ifdef FT_OPTIMIZE_MEMORY
|
||||||
|
|
||||||
|
FT_LOCAL_DEF( FT_Error )
|
||||||
|
tt_face_load_loca( TT_Face face,
|
||||||
|
FT_Stream stream )
|
||||||
|
{
|
||||||
|
FT_Error error;
|
||||||
|
FT_Memory memory = stream->memory;
|
||||||
|
FT_ULong table_len;
|
||||||
|
|
||||||
|
|
||||||
|
FT_TRACE2(( "Locations " ));
|
||||||
|
error = face->goto_table( face, TTAG_loca, stream, &table_len );
|
||||||
|
if ( error )
|
||||||
|
{
|
||||||
|
error = TT_Err_Locations_Missing;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( face->header.Index_To_Loc_Format != 0 )
|
||||||
|
{
|
||||||
|
if ( table_len >= 040000 )
|
||||||
|
{
|
||||||
|
FT_TRACE2(( "table too large !!\n" ));
|
||||||
|
error = TT_Err_Invalid_Table;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
face->num_locations = (FT_UInt)(table_len >> 2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( table_len >= 0x20000 )
|
||||||
|
{
|
||||||
|
FT_TRACE2(( "table too large !!\n" ));
|
||||||
|
error = TT_Err_Invalid_Table;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
face->num_locations = (FT_UInt)(table_len >> 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* extract the frame. We don't need to decompress it since
|
||||||
|
* we'll be able to parse it directly
|
||||||
|
*/
|
||||||
|
if ( FT_FRAME_EXTRACT( table_len, face->glyph_locations ) )
|
||||||
|
goto Exit;
|
||||||
|
|
||||||
|
FT_TRACE2(( "loaded\n" ));
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL_DEF( FT_ULong )
|
||||||
|
tt_face_get_location( TT_Face face,
|
||||||
|
FT_UInt gindex,
|
||||||
|
FT_UInt *asize )
|
||||||
|
{
|
||||||
|
FT_ULong pos1, pos2;
|
||||||
|
FT_Byte* p;
|
||||||
|
FT_Byte* p_limit;
|
||||||
|
|
||||||
|
pos1 = pos2 = 0;
|
||||||
|
if ( gindex < face->num_locations )
|
||||||
|
{
|
||||||
|
if ( face->header.Index_To_Loc_Format != 0 )
|
||||||
|
{
|
||||||
|
p = face->glyph_locations + gindex*4;
|
||||||
|
p_limit = face->glyph_locations + face->num_locations*4;
|
||||||
|
|
||||||
|
pos1 = FT_NEXT_ULONG(p);
|
||||||
|
pos2 = pos1;
|
||||||
|
|
||||||
|
if ( p+4 <= p_limit )
|
||||||
|
pos2 = FT_NEXT_ULONG(p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p = face->glyph_locations + gindex*2;
|
||||||
|
p_limit = face->glyph_locations + face->num_locations*2;
|
||||||
|
|
||||||
|
pos1 = FT_NEXT_USHORT(p);
|
||||||
|
pos2 = pos1;
|
||||||
|
|
||||||
|
if ( p+2 <= p_limit )
|
||||||
|
pos2 = FT_NEXT_USHORT(p);
|
||||||
|
|
||||||
|
pos1 <<= 1;
|
||||||
|
pos2 <<= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*asize = (FT_UInt)(pos2 - pos1);
|
||||||
|
|
||||||
|
return pos1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL_DEF( void )
|
||||||
|
tt_face_done_loca( TT_Face face )
|
||||||
|
{
|
||||||
|
FT_Stream stream = face->root.stream;
|
||||||
|
|
||||||
|
FT_FRAME_RELEASE( face->glyph_locations );
|
||||||
|
face->num_locations = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#else /* !FT_OPTIMIZE_MEMORY */
|
||||||
|
|
||||||
FT_LOCAL_DEF( FT_Error )
|
FT_LOCAL_DEF( FT_Error )
|
||||||
tt_face_load_loca( TT_Face face,
|
tt_face_load_loca( TT_Face face,
|
||||||
FT_Stream stream )
|
FT_Stream stream )
|
||||||
|
@ -130,6 +242,39 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL_DEF( FT_ULong )
|
||||||
|
tt_face_get_location( TT_Face face,
|
||||||
|
FT_UInt gindex,
|
||||||
|
FT_UInt *asize )
|
||||||
|
{
|
||||||
|
FT_ULong offset;
|
||||||
|
FT_UInt count;
|
||||||
|
|
||||||
|
offset = face->glyph_locations[gindex];
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
if ( gindex < (FT_UInt)face->num_locations - 1 )
|
||||||
|
count = (FT_UInt)( face->glyph_locations[gindex + 1] - offset );
|
||||||
|
|
||||||
|
*asize = count;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FT_LOCAL_DEF( void )
|
||||||
|
tt_face_done_loca( TT_Face face )
|
||||||
|
{
|
||||||
|
FT_Memory memory = face->root.memory;
|
||||||
|
|
||||||
|
FT_FREE( face->glyph_locations );
|
||||||
|
face->num_locations = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !FT_OPTIMIZE_MEMORY */
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* <Function> */
|
/* <Function> */
|
||||||
|
@ -151,6 +296,8 @@
|
||||||
tt_face_load_cvt( TT_Face face,
|
tt_face_load_cvt( TT_Face face,
|
||||||
FT_Stream stream )
|
FT_Stream stream )
|
||||||
{
|
{
|
||||||
|
#ifdef FT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||||
|
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
FT_Memory memory = stream->memory;
|
FT_Memory memory = stream->memory;
|
||||||
FT_ULong table_len;
|
FT_ULong table_len;
|
||||||
|
@ -197,6 +344,12 @@
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
#else /* !BYTECODE_INTERPRETER */
|
||||||
|
FT_UNUSED(face);
|
||||||
|
FT_UNUSED(stream);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -221,6 +374,8 @@
|
||||||
tt_face_load_fpgm( TT_Face face,
|
tt_face_load_fpgm( TT_Face face,
|
||||||
FT_Stream stream )
|
FT_Stream stream )
|
||||||
{
|
{
|
||||||
|
#ifdef FT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||||
|
|
||||||
FT_Error error;
|
FT_Error error;
|
||||||
FT_ULong table_len;
|
FT_ULong table_len;
|
||||||
|
|
||||||
|
@ -267,6 +422,12 @@
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
#else /* !BYTECODE_INTERPRETER */
|
||||||
|
FT_UNUSED(face);
|
||||||
|
FT_UNUSED(stream);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,14 @@ FT_BEGIN_HEADER
|
||||||
tt_face_load_loca( TT_Face face,
|
tt_face_load_loca( TT_Face face,
|
||||||
FT_Stream stream );
|
FT_Stream stream );
|
||||||
|
|
||||||
|
FT_LOCAL( FT_ULong )
|
||||||
|
tt_face_get_location( TT_Face face,
|
||||||
|
FT_UInt gindex,
|
||||||
|
FT_UInt *asize );
|
||||||
|
|
||||||
|
FT_LOCAL( void )
|
||||||
|
tt_face_done_loca( TT_Face face );
|
||||||
|
|
||||||
FT_LOCAL( FT_Error )
|
FT_LOCAL( FT_Error )
|
||||||
tt_face_load_cvt( TT_Face face,
|
tt_face_load_cvt( TT_Face face,
|
||||||
FT_Stream stream );
|
FT_Stream stream );
|
||||||
|
|
Loading…
Reference in New Issue