* 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
|
||||
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>
|
||||
|
||||
|
@ -568,6 +568,8 @@ FT_BEGIN_HEADER
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_CHESTER_HINTS */
|
||||
|
||||
#define FT_OPTIMIZE_MEMORY
|
||||
|
||||
FT_END_HEADER
|
||||
|
||||
|
||||
|
@ -361,6 +361,7 @@ FT_BEGIN_HEADER
|
||||
} TT_HdmxRec, *TT_Hdmx;
|
||||
|
||||
|
||||
|
||||
/*************************************************************************/
|
||||
/* */
|
||||
/* <Struct> */
|
||||
@ -1263,9 +1264,14 @@ FT_BEGIN_HEADER
|
||||
/* */
|
||||
/***********************************************************************/
|
||||
|
||||
#ifdef FT_OPTIMIZE_MEMORY
|
||||
FT_UInt num_locations;
|
||||
FT_Byte* glyph_locations;
|
||||
#else
|
||||
/* the glyph locations */
|
||||
FT_UShort num_locations;
|
||||
FT_Long* glyph_locations;
|
||||
#endif
|
||||
|
||||
/* the font program, if any */
|
||||
FT_ULong font_program_size;
|
||||
@ -1297,7 +1303,7 @@ FT_BEGIN_HEADER
|
||||
FT_Bool doblend;
|
||||
GX_Blend blend;
|
||||
#endif
|
||||
|
||||
|
||||
/***********************************************************************/
|
||||
/* */
|
||||
/* Other tables or fields. This is used by derivative formats like */
|
||||
|
@ -304,12 +304,15 @@
|
||||
|
||||
|
||||
if ( FT_RENEW_ARRAY( outline->points, max, news ) ||
|
||||
FT_RENEW_ARRAY( outline->horz_edges, max * 2, news * 2 ) ||
|
||||
FT_RENEW_ARRAY( outline->horz_segments, max * 2, news * 2 ) )
|
||||
FT_RENEW_ARRAY( outline->horz_edges, 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;
|
||||
|
||||
/* readjust some pointers */
|
||||
outline->vert_edges = outline->horz_edges + news;
|
||||
outline->vert_segments = outline->horz_segments + news;
|
||||
outline->max_points = news;
|
||||
}
|
||||
|
@ -1019,13 +1019,7 @@
|
||||
|
||||
#endif /* FT_CONFIG_OPTION_INCREMENTAL */
|
||||
|
||||
{
|
||||
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 );
|
||||
}
|
||||
offset = tt_face_get_location( face, glyph_index, &count );
|
||||
|
||||
if ( count == 0 )
|
||||
{
|
||||
|
@ -218,8 +218,11 @@
|
||||
if ( !face->root.internal->incremental_interface )
|
||||
error = tt_face_load_loca( face, stream );
|
||||
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
|
||||
|
||||
@ -290,8 +293,7 @@
|
||||
sfnt->done_face( face );
|
||||
|
||||
/* freeing the locations table */
|
||||
FT_FREE( face->glyph_locations );
|
||||
face->num_locations = 0;
|
||||
tt_face_done_loca( face );
|
||||
|
||||
/* freeing the CVT */
|
||||
FT_FREE( face->cvt );
|
||||
|
@ -58,6 +58,118 @@
|
||||
/* <Return> */
|
||||
/* 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 )
|
||||
tt_face_load_loca( TT_Face face,
|
||||
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> */
|
||||
@ -151,6 +296,8 @@
|
||||
tt_face_load_cvt( TT_Face face,
|
||||
FT_Stream stream )
|
||||
{
|
||||
#ifdef FT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
||||
FT_Error error;
|
||||
FT_Memory memory = stream->memory;
|
||||
FT_ULong table_len;
|
||||
@ -197,6 +344,12 @@
|
||||
|
||||
Exit:
|
||||
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,
|
||||
FT_Stream stream )
|
||||
{
|
||||
#ifdef FT_CONFIG_OPTION_BYTECODE_INTERPRETER
|
||||
|
||||
FT_Error error;
|
||||
FT_ULong table_len;
|
||||
|
||||
@ -267,6 +422,12 @@
|
||||
|
||||
Exit:
|
||||
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,
|
||||
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 )
|
||||
tt_face_load_cvt( TT_Face face,
|
||||
FT_Stream stream );
|
||||
|
Loading…
Reference in New Issue
Block a user