shithub: freetype+ttf2subf

Download patch

ref: 29873a0ccd69376125323ded561e271872564077
parent: e140f14232037570e241b42a3483f535a23da6e7
author: David Turner <[email protected]>
date: Mon Oct 23 06:23:17 EDT 2006

* src/sfnt/ttmtx.c, src/cff/cffload.c: speeding up the CFF font
        loader, with some large CFF fonts, FT_Open_Face is now 350% faster !

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,11 @@
 2006-10-23  David Turner  <[email protected]>
 
-    * src/pshinter/pshalgo.c: major speed improvements to the Postscript
-    hinter, more than 100% speed increase on my machine
+	* src/sfnt/ttmtx.c, src/cff/cffload.c: speeding up the CFF font
+	loader, with some large CFF fonts, FT_Open_Face is now 350% faster !
 
+	* src/pshinter/pshalgo.c: major speed improvements to the Postscript
+	hinter, more than 100% speed increase on my machine
+
 2006-10-15  suzuki toshiya  <[email protected]>
 
 	* src/base/ftmac.c (FT_New_Face_From_FOND): Initialize variable
@@ -115,6 +118,7 @@
 
 	* src/smooth/ftsmooth.c (ft_smooth_render_generic): Remove arguments
 	`hmul' and `vmul'.
+	5A
 	Handle subpixel rendering.
 	Simplify function.
 	(ft_smooth_render_lcd): Use `FT_RENDER_MODE_LCD'.
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -1063,24 +1063,6 @@
 #define FT_COMPONENT  trace_cffload
 
 
-  /* read a CFF offset from memory */
-  static FT_ULong
-  cff_get_offset( FT_Byte*  p,
-                  FT_Byte   off_size )
-  {
-    FT_ULong  result;
-
-
-    for ( result = 0; off_size > 0; off_size-- )
-    {
-      result <<= 8;
-      result  |= *p++;
-    }
-
-    return result;
-  }
-
-
   static FT_Error
   cff_new_index( CFF_Index  idx,
                  FT_Stream  stream,
@@ -1101,6 +1083,7 @@
       FT_Byte    offsize;
       FT_ULong   data_size;
       FT_ULong*  poff;
+      FT_Byte*   p_end;
 
 
       /* there is at least one element; read the offset size,           */
@@ -1108,6 +1091,12 @@
       if ( FT_READ_BYTE( offsize ) )
         goto Exit;
 
+      if ( offsize < 1 || offsize > 4 )
+      {
+        error = FT_Err_Invalid_Table;
+        goto Exit;
+      }
+
       idx->stream   = stream;
       idx->count    = count;
       idx->off_size = offsize;
@@ -1117,14 +1106,30 @@
            FT_FRAME_ENTER( data_size )             )
         goto Exit;
 
-      poff = idx->offsets;
-      p    = (FT_Byte*)stream->cursor;
+      poff   = idx->offsets;
+      p      = (FT_Byte*)stream->cursor;
+      p_end  = p + data_size;
 
-      for ( ; (FT_Short)count >= 0; count-- )
+      switch ( offsize )
       {
-        poff[0] = cff_get_offset( p, offsize );
-        poff++;
-        p += offsize;
+        case 1:
+          for ( ; p < p_end; p++, poff++ )
+            poff[0] = p[0];
+          break;
+
+        case 2:
+          for ( ; p < p_end; p += 2, poff++ )
+            poff[0] = FT_PEEK_USHORT(p);
+          break;
+
+        case 3:
+          for ( ; p < p_end; p += 3, poff++ )
+            poff[0] = FT_PEEK_OFF3(p);
+          break;
+
+        default:
+          for ( ; p < p_end; p += 4, poff++ )
+            poff[0] = FT_PEEK_ULONG(p);
       }
 
       FT_FRAME_EXIT();
@@ -1493,20 +1498,60 @@
   /*************************************************************************/
   /*************************************************************************/
 
+  static FT_Error
+  cff_charset_compute_cids( CFF_Charset  charset,
+                            FT_UInt      num_glyphs,
+                            FT_Memory    memory )
+  {
+    FT_Error   error = 0;
+    FT_UInt    i;
+    FT_UShort  max_cid = 0;
+
+    if ( charset->max_cid > 0 )
+      goto Exit;
+
+    for ( i = 0; i < num_glyphs; i++ )
+      if ( charset->sids[i] > max_cid )
+        max_cid = charset->sids[i];
+    max_cid++;
+
+    if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
+      goto Exit;
+
+    for ( i = 0; i < num_glyphs; i++ )
+      charset->cids[charset->sids[i]] = (FT_UShort)i;
+
+    charset->max_cid = max_cid;
+
+  Exit:
+      return error;
+  }
+
+
   static void
+  cff_charset_free_cids( CFF_Charset  charset,
+                         FT_Memory    memory )
+  {
+    FT_FREE( charset->cids );
+    charset->max_cid = 0;
+  }
+
+
+  static void
   cff_charset_done( CFF_Charset  charset,
                     FT_Stream    stream )
   {
     FT_Memory  memory = stream->memory;
 
+    cff_charset_free_cids( charset, memory );
 
     FT_FREE( charset->sids );
-    FT_FREE( charset->cids );
     charset->format = 0;
     charset->offset = 0;
   }
 
 
+
   static FT_Error
   cff_charset_load( CFF_Charset  charset,
                     FT_UInt      num_glyphs,
@@ -1672,26 +1717,8 @@
 
     /* we have to invert the `sids' array for subsetted CID-keyed fonts */
     if ( invert )
-    {
-      FT_UInt    i;
-      FT_UShort  max_cid = 0;
+      error = cff_charset_compute_cids( charset, num_glyphs, memory );
 
-
-      for ( i = 0; i < num_glyphs; i++ )
-        if ( charset->sids[i] > max_cid )
-          max_cid = charset->sids[i];
-      max_cid++;
-
-      if ( FT_NEW_ARRAY( charset->cids, max_cid ) )
-        goto Exit;
-      FT_MEM_ZERO( charset->cids, sizeof ( FT_UShort ) * max_cid );
-
-      for ( i = 0; i < num_glyphs; i++ )
-        charset->cids[charset->sids[i]] = (FT_UShort)i;
-
-      charset->max_cid = max_cid;
-    }
-
   Exit:
     /* Clean up if there was an error. */
     if ( error )
@@ -1921,33 +1948,30 @@
 
         encoding->count = 0;
 
+        error = cff_charset_compute_cids( charset, num_glyphs, stream->memory );
+        if (error)
+          goto Exit;
+
         for ( j = 0; j < 256; j++ )
         {
-          /* If j is encoded, find the GID for it. */
-          if ( encoding->sids[j] )
-          {
-            for ( i = 1; i < num_glyphs; i++ )
-              /* We matched, so break. */
-              if ( charset->sids[i] == encoding->sids[j] )
-                break;
+          FT_UInt  sid = encoding->sids[j];
+          FT_UInt  gid = 0;
 
-            /* i will be equal to num_glyphs if we exited the above */
-            /* loop without a match.  In this case, we also have to */
-            /* fix the code to SID mapping.                         */
-            if ( i == num_glyphs )
-            {
-              encoding->codes[j] = 0;
-              encoding->sids [j] = 0;
-            }
-            else
-            {
-              encoding->codes[j] = (FT_UShort)i;
+          if ( sid )
+            gid = charset->cids[sid];
 
-              /* update encoding count */
-              if ( encoding->count < j + 1 )
-                encoding->count = j + 1;
-            }
+          if ( gid != 0 )
+          {
+            encoding->codes[j] = (FT_UShort)gid;
+
+            if ( encoding->count < j+1 )
+              encoding->count = j+1;
           }
+          else
+          {
+            encoding->codes[j] = 0;
+            encoding->sids [j] = 0;
+          }
         }
         break;
 
@@ -2013,7 +2037,7 @@
 
     if ( error )
       goto Exit;
- 
+
     /* if it is a CID font, we stop there */
     if ( top->cid_registry != 0xFFFFU )
       goto Exit;
--- a/src/sfnt/ttmtx.c
+++ b/src/sfnt/ttmtx.c
@@ -71,8 +71,8 @@
     FT_ULong   table_size;
     FT_Byte**  ptable;
     FT_ULong*  ptable_size;
-    
-    
+
+
     if ( vertical )
     {
       error = face->goto_table( face, TTAG_vmtx, stream, &table_size );
@@ -91,10 +91,10 @@
       ptable      = &face->horz_metrics;
       ptable_size = &face->horz_metrics_size;
     }
-    
+
     if ( FT_FRAME_EXTRACT( table_size, *ptable ) )
       goto Fail;
-      
+
     *ptable_size = table_size;
 
   Fail:
@@ -116,6 +116,7 @@
 
     TT_LongMetrics *   longs;
     TT_ShortMetrics**  shorts;
+    FT_Byte*           p;
 
 
     if ( vertical )
@@ -175,6 +176,8 @@
     if ( FT_FRAME_ENTER( table_len ) )
       goto Fail;
 
+    p = stream->cursor;
+
     {
       TT_LongMetrics  cur   = *longs;
       TT_LongMetrics  limit = cur + num_longs;
@@ -182,8 +185,8 @@
 
       for ( ; cur < limit; cur++ )
       {
-        cur->advance = FT_GET_USHORT();
-        cur->bearing = FT_GET_SHORT();
+        cur->advance = FT_NEXT_USHORT(p);
+        cur->bearing = FT_NEXT_SHORT(p);
       }
     }
 
@@ -195,7 +198,7 @@
 
 
       for ( ; cur < limit; cur++ )
-        *cur = FT_GET_SHORT();
+        *cur = FT_NEXT_SHORT(p);
 
       /* We fill up the missing left side bearings with the     */
       /* last valid value.  Since this will occur for buggy CJK */
@@ -313,7 +316,7 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    tt_face_get_metrics                                                */ 
+  /*    tt_face_get_metrics                                                */
   /*                                                                       */
   /* <Description>                                                         */
   /*    Returns the horizontal or vertical metrics in font units for a     */