From 91a3402d786c35b100a1122cc43ff50dbf383960 Mon Sep 17 00:00:00 2001 From: David Turner Date: Fri, 5 Jan 2007 14:47:08 +0000 Subject: [PATCH] - don't load metrics table in memory, reduces heap usage - forgot to commit the changes in cffload.c that are already documented --- ChangeLog | 6 +++ include/freetype/config/ftoption.h | 2 +- include/freetype/internal/tttypes.h | 4 ++ src/cff/cffload.c | 5 +- src/sfnt/ttmtx.c | 78 ++++++++++++++++------------- 5 files changed, 56 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index a88fb0678..3e58a92d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2007-01-04 David Turner + * 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/cff/cffload.c, src/cff/cffload.h, src/cff/cffgload.c, diff --git a/include/freetype/config/ftoption.h b/include/freetype/config/ftoption.h index afd8139db..010f4103a 100644 --- a/include/freetype/config/ftoption.h +++ b/include/freetype/config/ftoption.h @@ -605,7 +605,7 @@ FT_BEGIN_HEADER * is recommended to disable the macro since it reduces the library's code * size and activates a few memory-saving optimizations as well. */ -#define FT_CONFIG_OPTION_OLD_INTERNALS +/* #define FT_CONFIG_OPTION_OLD_INTERNALS */ /* diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h index a0ddbb62f..2acc2ee6c 100644 --- a/include/freetype/internal/tttypes.h +++ b/include/freetype/internal/tttypes.h @@ -1424,6 +1424,10 @@ FT_BEGIN_HEADER TT_BDFRec bdf; #endif /* TT_CONFIG_OPTION_BDF */ + /* since 2.2.2 */ + FT_ULong horz_metrics_offset; + FT_ULong vert_metrics_offset; + } TT_FaceRec; diff --git a/src/cff/cffload.c b/src/cff/cffload.c index cca175990..988eed09d 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -746,7 +746,8 @@ for ( i = 0; i < num_glyphs; 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: return error; @@ -1194,7 +1195,7 @@ if ( sid ) - gid = charset->cids[sid]; + gid = cff_charset_cid_to_gindex( charset, sid ); if ( gid != 0 ) { diff --git a/src/sfnt/ttmtx.c b/src/sfnt/ttmtx.c index 9d8e79aaa..5aa4b810a 100644 --- a/src/sfnt/ttmtx.c +++ b/src/sfnt/ttmtx.c @@ -68,34 +68,29 @@ FT_Bool vertical ) { FT_Error error; - FT_ULong table_size; - FT_Byte** ptable; + FT_ULong tag, table_size; + FT_ULong* ptable_offset; FT_ULong* ptable_size; - if ( vertical ) { - error = face->goto_table( face, TTAG_vmtx, stream, &table_size ); - if ( error ) - goto Fail; - - ptable = &face->vert_metrics; - ptable_size = &face->vert_metrics_size; + tag = TTAG_vmtx; + ptable_offset = &face->vert_metrics_offset; + ptable_size = &face->vert_metrics_size; } else { - error = face->goto_table( face, TTAG_hmtx, stream, &table_size ); - if ( error ) - goto Fail; - - ptable = &face->horz_metrics; - ptable_size = &face->horz_metrics_size; + tag = TTAG_hmtx; + ptable_offset = &face->horz_metrics_offset; + 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; - *ptable_size = table_size; + *ptable_size = table_size; + *ptable_offset = FT_STREAM_POS(); Fail: return error; @@ -343,50 +338,61 @@ FT_Short *abearing, FT_UShort *aadvance ) { + FT_Error error; + FT_Stream stream = face->root.stream; TT_HoriHeader* header; - FT_Byte* p; - FT_Byte* limit; + FT_ULong table_pos, table_size, table_end; FT_UShort k; if ( vertical ) { - header = (TT_HoriHeader*)&face->vertical; - p = face->vert_metrics; - limit = p + face->vert_metrics_size; + header = (TT_HoriHeader*)&face->vertical; + table_pos = face->vert_metrics_offset; + table_size = face->vert_metrics_size; } else { - header = &face->horizontal; - p = face->horz_metrics; - limit = p + face->horz_metrics_size; + header = &face->horizontal; + table_pos = face->horz_metrics_offset; + table_size = face->horz_metrics_size; } + table_end = table_pos + table_end; + k = header->number_Of_HMetrics; if ( k > 0 ) { if ( gindex < (FT_UInt)k ) { - p += 4 * gindex; - if ( p + 4 > limit ) + table_pos += 4*gindex; + if ( table_pos+6 > table_end ) goto NoData; - *aadvance = FT_NEXT_USHORT( p ); - *abearing = FT_NEXT_SHORT( p ); + if ( FT_STREAM_SEEK( table_pos ) || + FT_READ_USHORT( *aadvance) || + FT_READ_SHORT( *abearing ) ) + goto NoData; } else { - p += 4 * ( k - 1 ); - if ( p + 4 > limit ) + table_pos += 4*(k-1); + if ( table_pos+4 > table_end ) goto NoData; - *aadvance = FT_NEXT_USHORT( p ); - p += 2 + 2 * ( gindex - k ); - if ( p + 2 > limit ) + if ( FT_STREAM_SEEK( table_pos ) || + FT_READ_USHORT( *aadvance ) ) + goto NoData; + + table_pos += 4 + 2*(gindex - k); + if ( table_pos+2 > table_end ) *abearing = 0; else - *abearing = FT_PEEK_SHORT( p ); + { + if ( !FT_STREAM_SEEK( table_pos ) ) + (void)FT_READ_SHORT( *abearing ); + } } } else @@ -399,7 +405,7 @@ return SFNT_Err_Ok; } -#else /* !OPTIMIZE_MEMORY || OLD_INTERNALS */ +#else /* OLD_INTERNALS */ FT_LOCAL_DEF( FT_Error ) tt_face_get_metrics( TT_Face face,