Commit 384be23418f8204baf785191a49f447d4ab40b9e

David Turner 2007-01-05T15:32:01

* src/truetype/ttobjs.h, src/truetype/ttobjs.c, src/truetype/ttgload.c: do not allocate interpreter-specific tables in memory if we're not going to load glyphs with it anyway.

diff --git a/ChangeLog b/ChangeLog
index d0cd84a..2358cbd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2007-01-04  David Turner  <david@freetype.org>
 
+	* src/truetype/ttobjs.h, src/truetype/ttobjs.c, 
+	src/truetype/ttgload.c: do not allocate interpreter-specific
+	tables in memory if we're not going to load glyphs with it
+	anyway.
+	
 	* src/sfnt/ttmtx.c, include/freetype/internal/tttypes.h:
 	don't extract the metrics table from the SFNT font file.
 	Instead, reparse it on each glyph load, since the runtime
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index 8ddc692..a04f914 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1718,11 +1718,19 @@
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
     /* load execution context */
+    if ( IS_HINTED( load_flags ) )
     {
       TT_ExecContext  exec;
       FT_Bool         grayscale;
 
 
+      if ( !size->cvt_ready )
+      {
+        FT_Error  error = tt_size_ready_bytecode( size );
+        if ( error )
+          return error;
+      }
+
       /* query new execution context */
       exec = size->debug ? size->context
                          : ( (TT_Driver)FT_FACE_DRIVER( face ) )->context;
diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c
index b464fcd..908194e 100644
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -519,29 +519,58 @@
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    tt_size_init                                                       */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initialize a new TrueType size object.                             */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size :: A handle to the size object.                               */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  FT_LOCAL_DEF( FT_Error )
-  tt_size_init( FT_Size  ttsize )           /* TT_Size */
+#ifdef TT_USE_BYTECODE_INTERPRETER
+
+  static void
+  tt_size_done_bytecode( FT_Size  ftsize )
   {
-    TT_Size   size  = (TT_Size)ttsize;
-    FT_Error  error = TT_Err_Ok;
+    TT_Size    size = (TT_Size)ftsize;
+    TT_Face    face = (TT_Face)ftsize->face;
+    FT_Memory  memory = face->root.memory;
 
-#ifdef TT_USE_BYTECODE_INTERPRETER
+    if ( size->debug )
+    {
+      /* the debug context must be deleted by the debugger itself */
+      size->context = NULL;
+      size->debug   = FALSE;
+    }
+
+    FT_FREE( size->cvt );
+    size->cvt_size = 0;
+
+    /* free storage area */
+    FT_FREE( size->storage );
+    size->storage_size = 0;
+
+    /* twilight zone */
+    tt_glyphzone_done( &size->twilight );
+
+    FT_FREE( size->function_defs );
+    FT_FREE( size->instruction_defs );
+
+    size->num_function_defs    = 0;
+    size->max_function_defs    = 0;
+    size->num_instruction_defs = 0;
+    size->max_instruction_defs = 0;
+
+    size->max_func = 0;
+    size->max_ins  = 0;
 
-    TT_Face    face   = (TT_Face)size->root.face;
+    size->bytecode_ready = 0;
+    size->cvt_ready      = 0;
+  }
+
+
+ /* initialize bytecode-related fields in the size object,
+  * should only be needed when bytecode interpretation is
+  * really needed
+  */
+  static FT_Error
+  tt_size_init_bytecode( FT_Size  ftsize )
+  {
+    FT_Error   error;
+    TT_Size    size = (TT_Size)ftsize;
+    TT_Face    face = (TT_Face)ftsize->face;
     FT_Memory  memory = face->root.memory;
     FT_Int     i;
 
@@ -549,6 +578,9 @@
     TT_MaxProfile*  maxp = &face->max_profile;
 
 
+    size->bytecode_ready = 1;
+    size->cvt_ready      = 0;
+
     size->max_function_defs    = maxp->maxFunctionDefs;
     size->max_instruction_defs = maxp->maxInstructionDefs;
 
@@ -583,11 +615,7 @@
          FT_NEW_ARRAY( size->instruction_defs, size->max_instruction_defs ) ||
          FT_NEW_ARRAY( size->cvt,              size->cvt_size             ) ||
          FT_NEW_ARRAY( size->storage,          size->storage_size         ) )
-    {
-      tt_size_done( ttsize );
-
-      return error;
-    }
+      goto Exit;
 
     /* reserve twilight zone */
     n_twilight = maxp->maxTwilightPoints;
@@ -597,11 +625,7 @@
 
     error = tt_glyphzone_new( memory, n_twilight, 0, &size->twilight );
     if ( error )
-    {
-      tt_size_done( ttsize );
-
-      return error;
-    }
+      goto Exit;
 
     size->twilight.n_points = n_twilight;
 
@@ -621,10 +645,95 @@
     /* Fine, now run the font program! */
     error = tt_size_run_fpgm( size );
 
-    if ( error )
-      tt_size_done( ttsize );
+  Exit:
+    if (error)
+      tt_size_done_bytecode( ftsize );
+
+    return error;
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
+  tt_size_ready_bytecode( TT_Size  size )
+  {
+    FT_Error  error = 0;
+
+    if ( !size->bytecode_ready )
+    {
+      error = tt_size_init_bytecode( (FT_Size)size );
+      if ( error )
+        goto Exit;
+    }
+
+    /* rescale CVT when needed */
+    if ( !size->cvt_ready )
+    {
+      FT_UInt  i;
+      TT_Face  face = (TT_Face) size->root.face;
+
+
+      /* Scale the cvt values to the new ppem.          */
+      /* We use by default the y ppem to scale the CVT. */
+      for ( i = 0; i < size->cvt_size; i++ )
+        size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
+
+      /* All twilight points are originally zero */
+      for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
+      {
+        size->twilight.org[i].x = 0;
+        size->twilight.org[i].y = 0;
+        size->twilight.cur[i].x = 0;
+        size->twilight.cur[i].y = 0;
+      }
+
+      /* clear storage area */
+      for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
+        size->storage[i] = 0;
+
+      size->GS = tt_default_graphics_state;
+
+      error = tt_size_run_prep( size );
+    }
+  Exit:
+    return error;
+  }
+
+#else /* !TT_USE_BYTECODE_INTERPRETER */
+
+  FT_LOCAL_DEF( FT_Error )
+  tt_size_ready_bytecode( TT_Size  size )
+  {
+    FT_UNUSED(ftsize);
+    return 0;
+  }
 
-#endif /* TT_USE_BYTECODE_INTERPRETER */
+
+#endif /* !TT_USE_BYTECODE_INTERPRETER */
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    tt_size_init                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Initialize a new TrueType size object.                             */
+  /*                                                                       */
+  /* <InOut>                                                               */
+  /*    size :: A handle to the size object.                               */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  FT_LOCAL_DEF( FT_Error )
+  tt_size_init( FT_Size  ttsize )           /* TT_Size */
+  {
+    TT_Size   size  = (TT_Size)ttsize;
+    FT_Error  error = TT_Err_Ok;
+
+#ifdef TT_USE_BYTECODE_INTERPRETER
+    size->bytecode_ready = 0;
+    size->cvt_ready      = 0;
+#endif
 
     size->ttmetrics.valid = FALSE;
     size->strike_index    = 0xFFFFFFFFUL;
@@ -650,38 +759,8 @@
     TT_Size    size = (TT_Size)ttsize;
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-
-    FT_Memory  memory = size->root.face->memory;
-
-
-    if ( size->debug )
-    {
-      /* the debug context must be deleted by the debugger itself */
-      size->context = NULL;
-      size->debug   = FALSE;
-    }
-
-    FT_FREE( size->cvt );
-    size->cvt_size = 0;
-
-    /* free storage area */
-    FT_FREE( size->storage );
-    size->storage_size = 0;
-
-    /* twilight zone */
-    tt_glyphzone_done( &size->twilight );
-
-    FT_FREE( size->function_defs );
-    FT_FREE( size->instruction_defs );
-
-    size->num_function_defs    = 0;
-    size->max_function_defs    = 0;
-    size->num_instruction_defs = 0;
-    size->max_instruction_defs = 0;
-
-    size->max_func = 0;
-    size->max_ins  = 0;
-
+    if ( size->bytecode_ready )
+      tt_size_done_bytecode( ttsize );
 #endif
 
     size->ttmetrics.valid = FALSE;
@@ -762,36 +841,8 @@
       size->ttmetrics.y_ratio = 0x10000L;
     }
 
-
 #ifdef TT_USE_BYTECODE_INTERPRETER
-
-    {
-      FT_UInt  i;
-
-
-      /* Scale the cvt values to the new ppem.          */
-      /* We use by default the y ppem to scale the CVT. */
-      for ( i = 0; i < size->cvt_size; i++ )
-        size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
-
-      /* All twilight points are originally zero */
-      for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ )
-      {
-        size->twilight.org[i].x = 0;
-        size->twilight.org[i].y = 0;
-        size->twilight.cur[i].x = 0;
-        size->twilight.cur[i].y = 0;
-      }
-
-      /* clear storage area */
-      for ( i = 0; i < (FT_UInt)size->storage_size; i++ )
-        size->storage[i] = 0;
-
-      size->GS = tt_default_graphics_state;
-
-      error = tt_size_run_prep( size );
-    }
-
+    size->cvt_ready = 0;
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
     if ( !error )
diff --git a/src/truetype/ttobjs.h b/src/truetype/ttobjs.h
index 5801af2..f81328f 100644
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -358,6 +358,9 @@ FT_BEGIN_HEADER
     FT_Bool            debug;
     TT_ExecContext     context;
 
+    FT_Bool            bytecode_ready;
+    FT_Bool            cvt_ready;
+
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
   } TT_SizeRec;
@@ -425,6 +428,9 @@ FT_BEGIN_HEADER
   FT_LOCAL( FT_Error )
   tt_size_reset( TT_Size  size );
 
+  FT_LOCAL( FT_Error )
+  tt_size_ready_bytecode( TT_Size  size );
+
 
   /*************************************************************************/
   /*                                                                       */