Commit 91a3402d786c35b100a1122cc43ff50dbf383960

David Turner 2007-01-05T14:47:08

- don't load metrics table in memory, reduces heap usage - forgot to commit the changes in cffload.c that are already documented

diff --git a/ChangeLog b/ChangeLog
index a88fb06..3e58a92 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 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/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 afd8139..010f410 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 a0ddbb6..2acc2ee 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 cca1759..988eed0 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 9d8e79a..5aa4b81 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,