* 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:
David Turner 2005-02-22 16:53:06 +00:00
parent 3e26d07e60
commit e70d553111
8 changed files with 205 additions and 15 deletions

View File

@ -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>

View File

@ -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

View File

@ -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;

View File

@ -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;
} }

View File

@ -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 )
{ {

View File

@ -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 );

View File

@ -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
} }

View File

@ -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 );