ref: e70d553111963cb0031869f708038f52c9f57fe9
parent: 3e26d07e60945b2cda301705ede608b924b4b915
author: David Turner <[email protected]>
date: Tue Feb 22 11:53:06 EST 2005
* 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.
--- a/ChangeLog
+++ b/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 <[email protected]>
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -568,6 +568,8 @@
#endif /* FT_CONFIG_OPTION_CHESTER_HINTS */
+#define FT_OPTIMIZE_MEMORY
+
FT_END_HEADER
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -361,6 +361,7 @@
} TT_HdmxRec, *TT_Hdmx;
+
/*************************************************************************/
/* */
/* <Struct> */
@@ -1263,9 +1264,14 @@
/* */
/***********************************************************************/
+#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_Bool doblend;
GX_Blend blend;
#endif
-
+
/***********************************************************************/
/* */
/* Other tables or fields. This is used by derivative formats like */
--- a/src/autohint/ahglyph.c
+++ b/src/autohint/ahglyph.c
@@ -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;
- /* readjust some pointers */
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_segments = outline->horz_segments + news;
outline->max_points = news;
}
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -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 )
{
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -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 );
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -58,6 +58,8 @@
/* <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 )
@@ -64,6 +66,116 @@
{
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 )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
FT_Short LongOffsets;
FT_ULong table_len;
@@ -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
}
--- a/src/truetype/ttpload.h
+++ b/src/truetype/ttpload.h
@@ -31,6 +31,14 @@
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 );