shithub: freetype+ttf2subf

Download patch

ref: f96594faf0ae04062e18e8debf9771c914be7ba9
parent: d18440f14d9a71719b069b90c7193b3dc15d6662
author: David Turner <[email protected]>
date: Mon Nov 6 18:07:51 EST 2000

integrated Yamano-Uchi changes to the base source code. However,
I've made a few modifications:

  - there is no new field named "driver" in "FT_SizeRec"

  - the new fields in "TT_SizeRec" are:

       strike_index   :: value 0xFFFF means "no sbit strike selected"
       strike_metrics :: the FT_Size_Metrics structure corresponding to
                         the currently selected strike

  - the code in "ttload.c" has been somewhat cleaned up too

thanks a lot, Y-U !!

- David

git/fs: mount .git/fs: mount/attach disallowed
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -877,16 +877,6 @@
   /*                    to scale vertical distances expressed in font      */
   /*                    units to fractional (26.6) pixel coordinates.      */
   /*                                                                       */
-  /*    x_resolution :: The horizontal device resolution for this size     */
-  /*                    object, expressed in integer dots per inches       */
-  /*                    (dpi).  As a convention, fixed font formats set    */
-  /*                    this value to 72.                                  */
-  /*                                                                       */
-  /*    y_resolution :: The vertical device resolution for this size       */
-  /*                    object, expressed in integer dots per inches       */
-  /*                    (dpi).  As a convention, fixed font formats set    */
-  /*                    this value to 72.                                  */
-  /*                                                                       */
   /*    ascender     :: The ascender, expressed in 26.6 fixed point        */
   /*                    pixels.  Always positive.                          */
   /*                                                                       */
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -281,8 +281,7 @@
   /*                                                                       */
   typedef
   FT_Error  (*TT_Load_SBit_Image_Func)( TT_Face           face,
-                                        FT_Int            x_ppem,
-                                        FT_Int            y_ppem,
+					FT_ULong          strike_index,
                                         FT_UInt           glyph_index,
                                         FT_UInt           load_flags,
                                         FT_Stream         stream,
@@ -289,6 +288,11 @@
                                         FT_Bitmap*        map,
                                         TT_SBit_Metrics*  metrics );
 
+  typedef
+  FT_Error  (*TT_Set_SBit_Strike_Func)( TT_Face           face,
+					FT_Int            x_ppem,
+					FT_Int            y_ppem,
+					FT_ULong*         astrike_index );
 
   /*************************************************************************/
   /*                                                                       */
@@ -473,8 +477,10 @@
 
     TT_Load_Table_Func        load_kerning;
     TT_Load_Table_Func        load_gasp;
-	TT_Load_Table_Func        load_pclt;
+    TT_Load_Table_Func        load_pclt;
 
+    TT_Load_Table_Func        load_bitmap_header;
+    TT_Set_SBit_Strike_Func   set_sbit_strike;
     /* see `ttsbit.h' */
     TT_Load_Table_Func        load_sbits;
     TT_Load_SBit_Image_Func   load_sbit_image;
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -492,7 +492,7 @@
   /* <Description>                                                         */
   /*    A structure used to hold the big metrics of a given glyph bitmap   */
   /*    in a TrueType or OpenType font.  These are usually found in the    */
-  /*    `EBDT' (Microsoft) or `bdat' (Apple) table.                        */
+  /*    `EBDT' (Microsoft) or `bloc' (Apple) table.                        */
   /*                                                                       */
   /* <Fields>                                                              */
   /*    height       :: The glyph height in pixels.                        */
@@ -700,7 +700,11 @@
   /*                                                                       */
   /*   index_ranges     :: An array of glyph index ranges.                 */
   /*                                                                       */
-  /*   color_ref        :: Unused.  A color reference?                     */
+  /*   color_ref        :: Unused.  color_ref is put in for future         */
+  /*                       enhancements, but these fields are already      */
+  /*			   in use by other platforms (e.g. Newton).        */
+  /*                       For details, please see                         */
+  /*                http://fonts.apple.com/TTRefMan/RM06/Chap6bloc.html    */
   /*                                                                       */
   /*   hori             :: The line metrics for horizontal layouts.        */
   /*                                                                       */
@@ -718,6 +722,8 @@
   /*                       and 8.                                          */
   /*                                                                       */
   /*   flags            :: Is this a vertical or horizontal strike?        */
+  /*                       For details, please see                         */
+  /*                http://fonts.apple.com/TTRefMan/RM06/Chap6bloc.html    */
   /*                                                                       */
   typedef struct  TT_SBit_Strike_
   {
@@ -760,7 +766,6 @@
   typedef struct  TT_SBit_Component_
   {
     FT_UShort  glyph_code;
-
     FT_Char    x_offset;
     FT_Char    y_offset;
 
--- a/include/freetype/tttags.h
+++ b/include/freetype/tttags.h
@@ -32,6 +32,7 @@
 #define TTAG_cvt   FT_MAKE_TAG( 'c', 'v', 't', ' ' )
 #define TTAG_CFF   FT_MAKE_TAG( 'C', 'F', 'F', ' ' )
 #define TTAG_DSIG  FT_MAKE_TAG( 'D', 'S', 'I', 'G' )
+#define TTAG_bhed  FT_MAKE_TAG( 'b', 'h', 'e', 'd' )
 #define TTAG_bdat  FT_MAKE_TAG( 'b', 'd', 'a', 't' )
 #define TTAG_bloc  FT_MAKE_TAG( 'b', 'l', 'o', 'c' )
 #define TTAG_EBDT  FT_MAKE_TAG( 'E', 'B', 'D', 'T' )
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -172,7 +172,11 @@
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
+    /* see `ttload.h` */
+    TT_Load_Bitmap_Header,
+
     /* see `ttsbit.h' */
+    TT_Set_SBit_Strike,
     TT_Load_SBit_Strikes,
     TT_Load_SBit_Image,
     TT_Free_SBit_Strikes,
@@ -179,6 +183,8 @@
 
 #else /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
+    0,
+    0,
     0,
     0,
     0,
--- a/src/sfnt/sfobjs.c
+++ b/src/sfnt/sfobjs.c
@@ -255,7 +255,9 @@
                             FT_Parameter*  params )
   {
     FT_Error         error;
-    FT_Bool          missing_outline = 0;
+    FT_Bool          has_outline;
+    FT_Bool          is_apple_sbit;
+
     SFNT_Interface*  sfnt = (SFNT_Interface*)face->sfnt;
 
     FT_UNUSED( face_index );
@@ -265,20 +267,41 @@
 
     /* Load tables */
 
-    /* If you load SFNT wrapped sbit font files, it will fail if you */
-    /* want to read the `head', `hhea', and `vhea' tables.           */
-    /*                                                               */
-    if ( LOAD_( header ) )
-    {
+    /* we now support two SFNT-based bitmapped font formats.       */
+    /* they are recognized easily as they do not include a "glyf"  */
+    /* table..                                                     */
+    /*                                                             */
+    /* the first format comes from Apple, and uses a table named   */
+    /* "bhed" instead of "head" to store the font header (using    */
+    /* the same format). it also doesn't include horizontal and    */
+    /* vertical metrics tables (i.e. "hhea" and "vhea" tables)     */
+    /*                                                             */
+    /* the other format comes from Microsoft, and is used with     */
+    /* WinCE / PocketPC. It's standard, except that it doesn't     */
+    /* contain outlines..                                          */
+    /*                                                             */
 
+    /* do we have outlines in there ?? */
+    has_outline   = (TT_LookUp_Table( face, TTAG_glyf ) != 0);
+    is_apple_sbit = 0;
+    
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-      missing_outline = 1;
-#else
-      goto Exit;
+
+    /*
+     * if this font doesn't contain outlines, we'll try to load
+     * a "bhed" table in it..
+     */
+    if ( !has_outline )
+      is_apple_sbit = !LOAD_(bitmap_header);
+
 #endif
 
-    }
+    /* load the font header ("head" table) if this isn't an Apple */
+    /* sbit font file..                                           */
+    if ( !is_apple_sbit && LOAD_(header) )
+      goto Exit;
 
+    /* load other tables */
     if ( LOAD_( max_profile ) ||
          LOAD_( charmaps )    ||
          LOAD_( names )       ||
@@ -285,19 +308,22 @@
          LOAD_( psnames )     )
       goto Exit;
 
-    if ( /* load the `hhea' & `hmtx' tables at once */
-         ( ( error = sfnt->load_metrics( face, stream, 0 ) ) != TT_Err_Ok ) ||
-         /* try to load the `vhea' & `vmtx' at once if present */
-         ( ( error = sfnt->load_metrics( face, stream, 1 ) ) != TT_Err_Ok ) ||
-         LOAD_( os2 ) )
+    /* do not load the metrics headers and tables if this is an Apple */
+    /* sbit font file..                                               */
+    if ( !is_apple_sbit )
     {
-
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-      missing_outline = 1;
-#else
-      goto Exit;
-#endif
-
+      /* load the "hhea" and "hmtx" tables at once */
+      error = sfnt->load_metrics( face, stream, 0 );
+      if (error)
+        goto Exit;
+        
+      /* try to load the "vhea" and "vmtx" tables at once */
+      error = sfnt->load_metrics( face, stream, 1 );
+      if (error)
+        goto Exit;
+        
+      if ( LOAD_(os2) )
+        goto Exit;
     }
 
     /* the optional tables */
@@ -307,11 +333,12 @@
     /* embedded bitmap support. */
     if ( sfnt->load_sbits && LOAD_( sbits ) )
     {
-      if ( !( ( error == TT_Err_Table_Missing ) &&      /* missing SBit */
-              ( missing_outline == 0 )        ) )       /* find outline */
+      /* return an error if this font file has no outlines */
+      if ( error == TT_Err_Table_Missing && has_outline )
+        error = 0;
+      else
         goto Exit;
     }
-
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
     if ( LOAD_( hdmx )    ||
@@ -343,7 +370,7 @@
       /*                                                                   */
       /* Compute face flags.                                               */
       /*                                                                   */
-      if ( missing_outline == 0 )
+      if ( has_outline == TRUE )
         flags = FT_FACE_FLAG_SCALABLE;    /* scalable outlines */
 
       flags |= FT_FACE_FLAG_SFNT      |   /* SFNT file format  */
@@ -374,26 +401,23 @@
       /* Compute style flags.                                              */
       /*                                                                   */
       flags = 0;
-      if ( missing_outline == 0 )
+      if ( has_outline == TRUE && face->os2.version != 0xFFFF )
       {
-        if ( face->os2.version != 0xFFFF )
-        {
-          /* we have an OS/2 table; use the `fsSelection' field */
-          if ( face->os2.fsSelection & 1 )
-            flags |= FT_STYLE_FLAG_ITALIC;
+        /* we have an OS/2 table; use the `fsSelection' field */
+        if ( face->os2.fsSelection & 1 )
+          flags |= FT_STYLE_FLAG_ITALIC;
 
-          if ( face->os2.fsSelection & 32 )
-            flags |= FT_STYLE_FLAG_BOLD;
-        }
-        else
-        {
-          /* this is an old Mac font, use the header field */
-          if ( face->header.Mac_Style & 1 )
-            flags |= FT_STYLE_FLAG_BOLD;
+        if ( face->os2.fsSelection & 32 )
+          flags |= FT_STYLE_FLAG_BOLD;
+      }
+      else
+      {
+        /* this is an old Mac font, use the header field */
+        if ( face->header.Mac_Style & 1 )
+          flags |= FT_STYLE_FLAG_BOLD;
 
-          if ( face->header.Mac_Style & 2 )
-            flags |= FT_STYLE_FLAG_ITALIC;
-        }
+        if ( face->header.Mac_Style & 2 )
+          flags |= FT_STYLE_FLAG_ITALIC;
       }
 
       root->style_flags = flags;
@@ -437,9 +461,10 @@
       if ( face->num_sbit_strikes )
       {
         root->face_flags |= FT_FACE_FLAG_FIXED_SIZES;
+
 #if 0
         /* I don't know criteria whether layout is horizontal or vertical */
-        if ( missing_outline )
+        if ( has_outline.... )
         {
           ...
           root->face_flags |= FT_FACE_FLAG_VERTICAL;
@@ -446,15 +471,17 @@
         }
 #endif
         root->num_fixed_sizes = face->num_sbit_strikes;
+
         if ( ALLOC_ARRAY( root->available_sizes,
                           face->num_sbit_strikes,
                           FT_Bitmap_Size ) )
-          return error;
+          goto Exit;
 
         for ( n = 0 ; n < face->num_sbit_strikes ; n++ )
         {
           root->available_sizes[n].width =
             face->sbit_strikes[n].x_ppem;
+
           root->available_sizes[n].height =
             face->sbit_strikes[n].y_ppem;
         }
@@ -464,8 +491,8 @@
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
       {
-       root->num_fixed_sizes = 0;
-       root->available_sizes = 0;
+        root->num_fixed_sizes = 0;
+        root->available_sizes = 0;
       }
 
       /*********************************************************************/
@@ -472,7 +499,7 @@
       /*                                                                   */
       /*  Set up metrics.                                                  */
       /*                                                                   */
-      if ( missing_outline == 0 )
+      if ( has_outline == TRUE )
       {
         /* XXX What about if outline header is missing */
         /*     (e.g. sfnt wrapped outline)?            */
--- a/src/sfnt/ttload.c
+++ b/src/sfnt/ttload.c
@@ -458,9 +458,10 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  FT_LOCAL_DEF
-  FT_Error  TT_Load_Header( TT_Face    face,
-                            FT_Stream  stream )
+  static
+  FT_Error  TT_Load_Generic_Header( TT_Face    face,
+                                    FT_Stream  stream,
+                                    FT_ULong   tag )
   {
     FT_Error    error;
     TT_Header*  header;
@@ -496,7 +497,7 @@
 
     FT_TRACE2(( "Load_TT_Header: %08p\n", face ));
 
-    error = face->goto_table( face, TTAG_head, stream, 0 );
+    error = face->goto_table( face, tag, stream, 0 );
     if ( error )
     {
       FT_TRACE0(( "Font Header is missing!\n" ));
@@ -516,6 +517,21 @@
     return error;
   }
 
+  FT_LOCAL_DEF
+  FT_Error  TT_Load_Header( TT_Face    face,
+			    FT_Stream  stream )
+  {
+    return TT_Load_Generic_Header( face, stream, TTAG_head );
+  }
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+  FT_LOCAL_DEF
+  FT_Error  TT_Load_Bitmap_Header( TT_Face    face,
+				   FT_Stream  stream )
+  {
+    return TT_Load_Generic_Header( face, stream, TTAG_bhed );
+  }
+#endif
 
   /*************************************************************************/
   /*                                                                       */
--- a/src/sfnt/ttload.h
+++ b/src/sfnt/ttload.h
@@ -120,6 +120,11 @@
   FT_Error  TT_Load_Gasp( TT_Face    face,
                           FT_Stream  stream );
 
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+  FT_LOCAL
+  FT_Error  TT_Load_Bitmap_Header( TT_Face    face,
+				   FT_Stream  stream );
+#endif
 
 #ifdef __cplusplus
   }
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -627,7 +627,33 @@
     face->num_sbit_strikes = 0;
   }
 
+  
+  FT_LOCAL_DEF
+  FT_Error  TT_Set_SBit_Strike( TT_Face   face,
+			        FT_Int    x_ppem,
+				FT_Int    y_ppem,
+				FT_ULong* astrike_index )
+  {
+    FT_Int i;
 
+    if ( x_ppem < 0 || x_ppem > 255 ||
+	 y_ppem < 1 || y_ppem > 255 )
+      return TT_Err_Invalid_PPem;
+
+    for ( i = 0; i < face->num_sbit_strikes; i++ )
+    {
+      if ( ( face->sbit_strikes[i].y_ppem  == y_ppem ) &&
+	   ( ( x_ppem == 0 ) ||
+	     ( face->sbit_strikes[i].x_ppem == x_ppem )))
+      {
+	*astrike_index = i;
+	return TT_Err_Ok;
+      }
+    }
+    return TT_Err_Invalid_PPem;
+  }
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -736,13 +762,12 @@
   /*                                                                       */
   /* <Description>                                                         */
   /*    Checks whether an embedded bitmap (an `sbit') exists for a given   */
-  /*    glyph, at given x and y ppems.                                     */
+  /*    glyph, at a given strike.                                          */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face          :: The target face object.                           */
   /*    glyph_index   :: The glyph index.                                  */
-  /*    x_ppem        :: The horizontal resolution in points per EM.       */
-  /*    y_ppem        :: The vertical resolution in points per EM.         */
+  /*    strike_index  :: The current strike index.                          */
   /*                                                                       */
   /* <Output>                                                              */
   /*    arange        :: The SBit range containing the glyph index.        */
@@ -756,38 +781,28 @@
   static
   FT_Error  Find_SBit_Image( TT_Face           face,
                              FT_UInt           glyph_index,
-                             FT_Int            x_ppem,
-                             FT_Int            y_ppem,
-
+			     FT_ULong          strike_index,
                              TT_SBit_Range**   arange,
                              TT_SBit_Strike**  astrike,
                              FT_ULong*         aglyph_offset )
   {
-    TT_SBit_Strike*  strike       = face->sbit_strikes;
-    TT_SBit_Strike*  strike_limit = strike + face->num_sbit_strikes;
+    FT_Error  error;
+    TT_SBit_Strike*  strike;
 
-
-    if ( !strike )
+    if ( !face->sbit_strikes || ( face->num_sbit_strikes <= (FT_Int)strike_index ) )
       goto Fail;
 
-    for ( ; strike < strike_limit; strike++ )
-    {
-      if ( strike->x_ppem == x_ppem && strike->y_ppem == y_ppem )
-      {
-        FT_Error  error;
+    strike = &face->sbit_strikes[strike_index];
 
+    error = Find_SBit_Range( glyph_index, strike,
+			     arange, aglyph_offset );
+    if ( error )
+      goto Fail;
 
-        error = Find_SBit_Range( glyph_index, strike,
-                                 arange, aglyph_offset );
-        if ( error )
-          goto Fail;
+    *astrike = strike;
 
-        *astrike = strike;
+    return TT_Err_Ok;
 
-        return TT_Err_Ok;
-      }
-    }
-
   Fail:
     /* no embedded bitmap for this glyph in face */
     *arange        = 0;
@@ -1353,10 +1368,8 @@
   /* <Input>                                                               */
   /*    face        :: The target face object.                             */
   /*                                                                       */
-  /*    x_ppem      :: The horizontal resolution in points per EM.         */
+  /*    strike_index :: The current strike index.                          */
   /*                                                                       */
-  /*    y_ppem      :: The vertical resolution in points per EM.           */
-  /*                                                                       */
   /*    glyph_index :: The current glyph index.                            */
   /*                                                                       */
   /*    load_flags  :: The glyph load flags (the code checks for the flag  */
@@ -1378,8 +1391,7 @@
   /*                                                                       */
   FT_LOCAL_DEF
   FT_Error  TT_Load_SBit_Image( TT_Face           face,
-                                FT_Int            x_ppem,
-                                FT_Int            y_ppem,
+				FT_ULong          strike_index,
                                 FT_UInt           glyph_index,
                                 FT_UInt           load_flags,
                                 FT_Stream         stream,
@@ -1395,7 +1407,7 @@
 
 
     /* Check whether there is a glyph sbit for the current index */
-    error = Find_SBit_Image( face, glyph_index, x_ppem, y_ppem,
+    error = Find_SBit_Image( face, glyph_index, strike_index,
                              &range, &strike, &glyph_offset );
     if ( error )
       goto Exit;
--- a/src/sfnt/ttsbit.h
+++ b/src/sfnt/ttsbit.h
@@ -41,17 +41,24 @@
                                   FT_Stream  stream );
 
   FT_LOCAL
-  void  TT_Free_SBit_Strikes( TT_Face  face );
+  void      TT_Free_SBit_Strikes( TT_Face  face );
 
+
   FT_LOCAL
+  FT_Error  TT_Set_SBit_Strike( TT_Face   face,
+   			        FT_Int    x_ppem,
+ 				FT_Int    y_ppem,
+ 				FT_ULong *astrike_index );
+
+  FT_LOCAL
   FT_Error  TT_Load_SBit_Image( TT_Face           face,
-                                FT_Int            x_ppem,
-                                FT_Int            y_ppem,
+                                FT_ULong          strike_index,
                                 FT_UInt           glyph_index,
                                 FT_UInt           load_flags,
                                 FT_Stream         stream,
-                                FT_Bitmap*        map,
-                                TT_SBit_Metrics*  metrics );
+                                FT_Bitmap        *map,
+                                TT_SBit_Metrics  *metrics );
+
 
 
 #ifdef __cplusplus
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -225,6 +225,7 @@
     }
 
     size->ttmetrics.valid = FALSE;
+    size->strike_index    = 0xFFFF;
 
     return TT_Reset_Size( size );
   }
@@ -261,6 +262,7 @@
     /* many things have been pre-computed by the base layer */
 
     size->ttmetrics.valid = FALSE;
+    size->strike_index    = 0xFFFF;
 
     return TT_Reset_Size( size );
   }
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1345,18 +1345,24 @@
     glyph->num_subglyphs = 0;
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-
-    /* try to load embedded bitmap if any */
+    /*
+     * try to load embedded bitmap if any
+     * 
+     * XXX: The convention should be emphasized in
+     *      the documents.  Because some application
+     *      developpers confuse.
+     */
     if ( size                                    &&
-         ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
-         sfnt->load_sbits                        )
+	 size->strike_index != 0xFFFF            &&
+         sfnt->load_sbits                        &&
+         ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
+
     {
       TT_SBit_Metrics  metrics;
 
 
       error = sfnt->load_sbit_image( face,
-                                     size->root.metrics.x_ppem,
-                                     size->root.metrics.y_ppem,
+                                     size->strike_index,
                                      glyph_index,
                                      load_flags,
                                      stream,
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -453,7 +453,7 @@
     size->ttmetrics.valid = FALSE;
     return error;
 
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
+#if defined(TT_CONFIG_OPTION_BYTECODE_INTERPRETER) || defined(TT_CONFIG_OPTION_EMBEDDED_BITMAPS)
 
   Fail_Exec:
     if ( !size->debug )
@@ -535,8 +535,8 @@
   /* <Input>                                                               */
   /*    size :: A handle to the target size object.                        */
   /*                                                                       */
-  FT_LOCAL
-  FT_Error  TT_Reset_Size( TT_Size  size )
+  static
+  FT_Error  Reset_Outline_Size( TT_Size  size )
   {
     TT_Face   face;
     FT_Error  error = TT_Err_Ok;
@@ -575,47 +575,7 @@
     }
 
     /* Compute root ascender, descender, test height, and max_advance */
-
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-
-    if ( ( !( face->root.face_flags & FT_FACE_FLAG_SCALABLE ) &&
-           ( face->root.face_flags & FT_FACE_FLAG_FIXED_SIZES ) ) )
     {
-      FT_Int i;
-
-
-      for ( i = 0; i < face->root.num_fixed_sizes; i++ )
-      {
-        if ( ( face->sbit_strikes[i].x_ppem  == metrics->x_ppem ) &&
-             ( face->sbit_strikes[i].y_ppem == metrics->y_ppem ) )
-        {
-          /*
-           * XXX: We now set horizontal metrics,
-           *      but this is not valid if we use vertical layout style
-           */
-          metrics->ascender =
-            face->sbit_strikes[i].hori.ascender * 64;
-          metrics->descender =
-            face->sbit_strikes[i].hori.descender * 64;
-          metrics->height =
-            ( face->sbit_strikes[i].hori.ascender -
-              face->sbit_strikes[i].hori.descender ) * 64;
-          /* XXX: Is this correct? */
-          metrics->max_advance =
-            ( face->sbit_strikes[i].hori.min_origin_SB +
-              face->sbit_strikes[i].hori.max_width +
-              face->sbit_strikes[i].hori.min_advance_SB ) * 64;
-          break;
-        }
-      }
-      if ( i == face->root.num_fixed_sizes )
-        return TT_Err_Invalid_PPem;
-    }
-    else
-
-#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
-
-    {
       metrics->ascender    = ( FT_MulFix( face->root.ascender,
                                           metrics->y_scale ) + 32 ) & -64;
       metrics->descender   = ( FT_MulFix( face->root.descender,
@@ -628,6 +588,11 @@
 
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+   /* set to "invalid" by default */
+    size->strike_index = 0xFFFF;
+#endif
+
     {
       TT_ExecContext  exec;
       FT_UInt         i, j;
@@ -708,6 +673,126 @@
     return error;
   }
 
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+  static
+  FT_Error  Reset_SBit_Size( TT_Size size )
+  {
+    TT_Face           face;
+    FT_Error          error = TT_Err_Ok;
+
+    FT_ULong          strike_index;
+    FT_Size_Metrics*  metrics;
+    FT_Size_Metrics*  sbit_metrics;
+    SFNT_Interface*   sfnt;
+
+    metrics = &size->root.metrics;
+
+    if (size->strike_index != 0xFFFF)
+      return TT_Err_Ok;
+
+    face = (TT_Face)size->root.face;
+    sfnt = (SFNT_Interface*)face->sfnt;
+
+    sbit_metrics = &size->strike_metrics;
+
+    error = sfnt->set_sbit_strike(face,
+				  metrics->x_ppem, metrics->y_ppem,
+				  &strike_index);
+
+    if (!error)
+    {
+      TT_SBit_Strike*  strike = face->sbit_strikes + strike_index;
+      
+      
+      sbit_metrics->x_ppem = metrics->x_ppem;
+      sbit_metrics->y_ppem = metrics->y_ppem;
+#if 0
+      /*
+       * sbit_metrics->?_scale
+       * are not used now.
+       */
+      sbit_metrics->x_scale = 1 << 16;
+      sbit_metrics->y_scale = 1 << 16;
+#endif
+      
+      sbit_metrics->ascender  = strike->hori.ascender << 6;
+      sbit_metrics->descender = strike->hori.descender << 6;
+      
+      /* XXX: Is this correct? */
+      sbit_metrics->height    = sbit_metrics->ascender -
+                                sbit_metrics->descender;
+      
+      /* XXX: Is this correct? */
+      sbit_metrics->max_advance = ( strike->hori.min_origin_SB +
+                                    strike->hori.max_width     +
+                                    strike->hori.min_advance_SB ) << 6;
+
+      size->strike_index = strike_index;
+    }
+    else
+    {
+      size->strike_index = 0xFFFF;
+      
+      sbit_metrics->x_ppem      = 0;
+      sbit_metrics->y_ppem      = 0;
+      sbit_metrics->ascender    = 0;
+      sbit_metrics->descender   = 0;
+      sbit_metrics->height      = 0;
+      sbit_metrics->max_advance = 0;
+    }
+
+    return error;
+  }
+#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    TT_Reset_Size                                                      */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Resets a TrueType size when resolutions and character dimensions   */
+  /*    have been changed.                                                 */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    size :: A handle to the target size object.                        */
+  /*                                                                       */
+  FT_LOCAL_DEF
+  FT_Error  TT_Reset_Size( TT_Size  size )
+  {
+    FT_Face face;
+    FT_Error  error = TT_Err_Ok;
+
+    face = size->root.face;
+
+    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
+    {
+      if ( !size->ttmetrics.valid )
+	error = Reset_Outline_Size( size );
+
+      if ( error )
+	 return error;
+    }
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+    if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
+    {
+      FT_Size_Metrics* sbit_metrics;
+
+      if ( size->strike_index == 0xFFFF )
+        error = Reset_SBit_Size( size );
+
+      sbit_metrics = &size->strike_metrics;
+
+      if ((!error) && !( face->face_flags & FT_FACE_FLAG_SCALABLE ))
+	size->root.metrics = *sbit_metrics;
+    }
+#endif
+    if (face->face_flags & FT_FACE_FLAG_SCALABLE)
+      return TT_Err_Ok;
+    else
+      return error;
+  }
 
   /*************************************************************************/
   /*                                                                       */
--- a/src/truetype/ttobjs.h
+++ b/src/truetype/ttobjs.h
@@ -305,6 +305,7 @@
   } TT_Size_Metrics;
 
 
+
   /*************************************************************************/
   /*                                                                       */
   /* TrueType size class.                                                  */
@@ -314,6 +315,11 @@
     FT_SizeRec         root;
 
     TT_Size_Metrics    ttmetrics;
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+    FT_UInt               strike_index;    /* 0xFFFF to indicate invalid */
+    FT_Size_Metrics       strike_metrics;  /* current strike's metrics   */
+#endif
 
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER