- don't load metrics table in memory, reduces heap usage

- forgot to commit the changes in cffload.c that are already documented
This commit is contained in:
David Turner 2007-01-05 14:47:08 +00:00
parent 9d7d50f789
commit 91a3402d78
5 changed files with 56 additions and 39 deletions

View File

@ -1,5 +1,11 @@
2007-01-04 David Turner <david@freetype.org> 2007-01-04 David Turner <david@freetype.org>
* src/sfnt/ttmtx.c: don't extract the metrics table from the
SFNT font file. Instead, reparse it on each glyph load,
since the runtime difference will not be noticeable, and
it can save a lot of heap memory when memory-mapped files
are not used.
* src/sfnt/ttcmap.c: slight optimization in the CMAP 4 validator * src/sfnt/ttcmap.c: slight optimization in the CMAP 4 validator
* src/cff/cffload.c, src/cff/cffload.h, src/cff/cffgload.c, * src/cff/cffload.c, src/cff/cffload.h, src/cff/cffgload.c,

View File

@ -605,7 +605,7 @@ FT_BEGIN_HEADER
* is recommended to disable the macro since it reduces the library's code * is recommended to disable the macro since it reduces the library's code
* size and activates a few memory-saving optimizations as well. * size and activates a few memory-saving optimizations as well.
*/ */
#define FT_CONFIG_OPTION_OLD_INTERNALS /* #define FT_CONFIG_OPTION_OLD_INTERNALS */
/* /*

View File

@ -1424,6 +1424,10 @@ FT_BEGIN_HEADER
TT_BDFRec bdf; TT_BDFRec bdf;
#endif /* TT_CONFIG_OPTION_BDF */ #endif /* TT_CONFIG_OPTION_BDF */
/* since 2.2.2 */
FT_ULong horz_metrics_offset;
FT_ULong vert_metrics_offset;
} TT_FaceRec; } TT_FaceRec;

View File

@ -747,6 +747,7 @@
charset->cids[charset->sids[i]] = (FT_UShort)i; charset->cids[charset->sids[i]] = (FT_UShort)i;
charset->max_cid = max_cid; charset->max_cid = max_cid;
charset->num_glyphs = num_glyphs;
Exit: Exit:
return error; return error;
@ -1194,7 +1195,7 @@
if ( sid ) if ( sid )
gid = charset->cids[sid]; gid = cff_charset_cid_to_gindex( charset, sid );
if ( gid != 0 ) if ( gid != 0 )
{ {

View File

@ -68,34 +68,29 @@
FT_Bool vertical ) FT_Bool vertical )
{ {
FT_Error error; FT_Error error;
FT_ULong table_size; FT_ULong tag, table_size;
FT_Byte** ptable; FT_ULong* ptable_offset;
FT_ULong* ptable_size; FT_ULong* ptable_size;
if ( vertical ) if ( vertical )
{ {
error = face->goto_table( face, TTAG_vmtx, stream, &table_size ); tag = TTAG_vmtx;
if ( error ) ptable_offset = &face->vert_metrics_offset;
goto Fail;
ptable = &face->vert_metrics;
ptable_size = &face->vert_metrics_size; ptable_size = &face->vert_metrics_size;
} }
else else
{ {
error = face->goto_table( face, TTAG_hmtx, stream, &table_size ); tag = TTAG_hmtx;
if ( error ) ptable_offset = &face->horz_metrics_offset;
goto Fail;
ptable = &face->horz_metrics;
ptable_size = &face->horz_metrics_size; ptable_size = &face->horz_metrics_size;
} }
if ( FT_FRAME_EXTRACT( table_size, *ptable ) ) error = face->goto_table( face, tag, stream, &table_size );
if (error)
goto Fail; goto Fail;
*ptable_size = table_size; *ptable_size = table_size;
*ptable_offset = FT_STREAM_POS();
Fail: Fail:
return error; return error;
@ -343,50 +338,61 @@
FT_Short *abearing, FT_Short *abearing,
FT_UShort *aadvance ) FT_UShort *aadvance )
{ {
FT_Error error;
FT_Stream stream = face->root.stream;
TT_HoriHeader* header; TT_HoriHeader* header;
FT_Byte* p; FT_ULong table_pos, table_size, table_end;
FT_Byte* limit;
FT_UShort k; FT_UShort k;
if ( vertical ) if ( vertical )
{ {
header = (TT_HoriHeader*)&face->vertical; header = (TT_HoriHeader*)&face->vertical;
p = face->vert_metrics; table_pos = face->vert_metrics_offset;
limit = p + face->vert_metrics_size; table_size = face->vert_metrics_size;
} }
else else
{ {
header = &face->horizontal; header = &face->horizontal;
p = face->horz_metrics; table_pos = face->horz_metrics_offset;
limit = p + face->horz_metrics_size; table_size = face->horz_metrics_size;
} }
table_end = table_pos + table_end;
k = header->number_Of_HMetrics; k = header->number_Of_HMetrics;
if ( k > 0 ) if ( k > 0 )
{ {
if ( gindex < (FT_UInt)k ) if ( gindex < (FT_UInt)k )
{ {
p += 4 * gindex; table_pos += 4*gindex;
if ( p + 4 > limit ) if ( table_pos+6 > table_end )
goto NoData; goto NoData;
*aadvance = FT_NEXT_USHORT( p ); if ( FT_STREAM_SEEK( table_pos ) ||
*abearing = FT_NEXT_SHORT( p ); FT_READ_USHORT( *aadvance) ||
FT_READ_SHORT( *abearing ) )
goto NoData;
} }
else else
{ {
p += 4 * ( k - 1 ); table_pos += 4*(k-1);
if ( p + 4 > limit ) if ( table_pos+4 > table_end )
goto NoData; goto NoData;
*aadvance = FT_NEXT_USHORT( p ); if ( FT_STREAM_SEEK( table_pos ) ||
p += 2 + 2 * ( gindex - k ); FT_READ_USHORT( *aadvance ) )
if ( p + 2 > limit ) goto NoData;
table_pos += 4 + 2*(gindex - k);
if ( table_pos+2 > table_end )
*abearing = 0; *abearing = 0;
else else
*abearing = FT_PEEK_SHORT( p ); {
if ( !FT_STREAM_SEEK( table_pos ) )
(void)FT_READ_SHORT( *abearing );
}
} }
} }
else else
@ -399,7 +405,7 @@
return SFNT_Err_Ok; return SFNT_Err_Ok;
} }
#else /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ #else /* OLD_INTERNALS */
FT_LOCAL_DEF( FT_Error ) FT_LOCAL_DEF( FT_Error )
tt_face_get_metrics( TT_Face face, tt_face_get_metrics( TT_Face face,