shithub: freetype+ttf2subf

Download patch

ref: fa7d6ab2171c9cfa8b9b45a2a6f6a0fdd2e4a190
parent: 64714a28fbfe0ef186dc8648dcaa6252011ddc93
author: Wu, Chia-I (吳佳一) <[email protected]>
date: Fri Jan 13 07:21:31 EST 2006

* include/freetype/internal/sfnt.h (SFNT_Interface): New method
`load_strike_metrics' used to load the strike's metrics.

* src/sfnt/sfdriver.c, src/sfnt/ttsbit.c, src/sfnt/ttsbit.h,
src/sfnt/ttsbit0.c: New function `tt_face_load_strike_metrics'.

* src/pfr/pfrobjs.c (pfr_face_init): Set FT_Bitmap_Size correctly.

* src/winfonts/winfnt.c (FNT_Face_Init): Use `nominal_point_size' for
nominal size unless it is obviously incorrect.

* include/freetype/freetype.h (FT_Bitmap_Size): Update the comments on
FNT driver.


Introduce new size selection interface.

* include/freetype/internal/ftdriver.h (struct FT_Driver_ClassRec_):
Replace `set_char_sizes' and `set_pixel_sizes' by `request_size' and
`select_size'.

* include/freetype/freetype.h (FT_Select_Size, FT_Size_Request_Type,
FT_Size_Request, FT_Request_Size, FT_Select_Size), src/base/ftobjs.c
(FT_Select_Size, FT_Request_Size): API additions to export the new
size selection interface.

* src/base/ftobjs.c (FT_Set_Char_Size, FT_Set_Pixel_Sizes): Use
`FT_Request_Size'.

* include/freetype/internal/ftobjs.h (FT_Match_Size),
src/base/ftobjs.c (FT_Match_Size): New function to match a size
request against `available_sizes'.  Drivers supporting bitmap strikes
can use this function to implement `request_size'.

* src/bdf/bdfdrivr.c, src/cid/cidobjs.c, src/cid/cidobjs.h,
src/cid/cidriver.c, src/pcf/pcfdrivr.c, src/type1/t1driver.c,
src/type1/t1objs.c, src/type1/t1objs.h, src/type42/t42drivr.c,
src/type42/t42objs.c, src/type42/t42objs.h, src/winfonts/winfnt.c:
Update to new size selection interface.

* src/cff/cffdrivr.c, src/cff/cffgload.c, src/cff/cffobjs.c,
src/cff/cffobjs.h, src/truetype/ttdriver.c, src/truetype/ttgload.c,
src/truetype/ttobjs.c, src/truetype/ttobjs.h: Update to new size
selection interface.
Make `strike_index' FT_ULong and always defined.
Use `load_strike_metrics' provided by SFNT interface.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,53 @@
+2006-01-13  Chia-I Wu  <[email protected]>
+
+	Introduce new size selection interface.
+
+	* include/freetype/internal/ftdriver.h (struct FT_Driver_ClassRec_):
+	Replace `set_char_sizes' and `set_pixel_sizes' by `request_size' and
+	`select_size'.
+
+	* include/freetype/freetype.h (FT_Select_Size, FT_Size_Request_Type,
+	FT_Size_Request, FT_Request_Size, FT_Select_Size), src/base/ftobjs.c
+	(FT_Select_Size, FT_Request_Size): API additions to export the new
+	size selection interface.
+
+	* src/base/ftobjs.c (FT_Set_Char_Size, FT_Set_Pixel_Sizes): Use
+	`FT_Request_Size'.
+
+	* include/freetype/internal/ftobjs.h (FT_Match_Size),
+	src/base/ftobjs.c (FT_Match_Size): New function to match a size
+	request against `available_sizes'.  Drivers supporting bitmap strikes
+	can use this function to implement `request_size'.
+
+	* src/bdf/bdfdrivr.c, src/cid/cidobjs.c, src/cid/cidobjs.h,
+	src/cid/cidriver.c, src/pcf/pcfdrivr.c, src/type1/t1driver.c,
+	src/type1/t1objs.c, src/type1/t1objs.h, src/type42/t42drivr.c,
+	src/type42/t42objs.c, src/type42/t42objs.h, src/winfonts/winfnt.c:
+	Update to new size selection interface.
+
+	* src/cff/cffdrivr.c, src/cff/cffgload.c, src/cff/cffobjs.c,
+	src/cff/cffobjs.h, src/truetype/ttdriver.c, src/truetype/ttgload.c,
+	src/truetype/ttobjs.c, src/truetype/ttobjs.h: Update to new size
+	selection interface.
+	Make `strike_index' FT_ULong and always defined.
+	Use `load_strike_metrics' provided by SFNT interface.
+
+2006-01-13  Chia-I Wu  <[email protected]>
+
+	* include/freetype/internal/sfnt.h (SFNT_Interface): New method
+	`load_strike_metrics' used to load the strike's metrics.
+
+	* src/sfnt/sfdriver.c, src/sfnt/ttsbit.c, src/sfnt/ttsbit.h,
+	src/sfnt/ttsbit0.c: New function `tt_face_load_strike_metrics'.
+
+	* src/pfr/pfrobjs.c (pfr_face_init): Set FT_Bitmap_Size correctly.
+
+	* src/winfonts/winfnt.c (FNT_Face_Init): Use `nominal_point_size' for
+	nominal size unless it is obviously incorrect.
+
+	* include/freetype/freetype.h (FT_Bitmap_Size): Update the comments on
+	FNT driver.
+
 2006-01-12  Werner Lemberg  <[email protected]>
 
 	Prepare use of pscmap service within CFF module.
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -147,6 +147,11 @@
   /*    FT_Attach_File                                                     */
   /*    FT_Attach_Stream                                                   */
   /*                                                                       */
+  /*    FT_Select_Size                                                     */
+  /*    FT_Size_Request_Type                                               */
+  /*    FT_Size_Request                                                    */
+  /*    FT_Request_Size                                                    */
+  /*    FT_Select_Size                                                     */
   /*    FT_Set_Char_Size                                                   */
   /*    FT_Set_Pixel_Sizes                                                 */
   /*    FT_Set_Transform                                                   */
@@ -293,10 +298,10 @@
   /*    where `size' is in points.                                         */
   /*                                                                       */
   /*    Windows FNT:                                                       */
-  /*      The `size' parameter is not reliable: There exist fonts (e.g.,   */
-  /*      app850.fon) which have a wrong size for some subfonts; x_ppem    */
-  /*      and y_ppem are thus set equal to pixel width and height given in */
-  /*      in the Windows FNT header.                                       */
+  /*      The nominal size given in a FNT font is not reliable.  Thus when */
+  /*      the driver finds it incorrect, it sets `size' to some calculated */
+  /*      values and set `x_ppem' and `y_ppem' to pixel width and height   */
+  /*      given in the font, respectively.                                 */
   /*                                                                       */
   /*    TrueType embedded bitmaps:                                         */
   /*      `size', `width', and `height' values are not contained in the    */
@@ -2071,25 +2076,145 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    FT_Set_Char_Size                                                   */
+  /*    FT_Select_Size                                                     */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Sets the character dimensions of a given face object.  The         */
-  /*    `char_width' and `char_height' values are used for the width and   */
-  /*    height, respectively, expressed in 26.6 fractional points.         */
+  /*    Selects a fixed size.                                              */
   /*                                                                       */
-  /*    If the horizontal or vertical resolution values are zero, a        */
-  /*    default value of 72dpi is used.  Similarly, if one of the          */
-  /*    character dimensions is zero, its value is set equal to the other. */
+  /* <InOut>                                                               */
+  /*    face  :: A handle to a target face object.                         */
   /*                                                                       */
+  /* <Input>                                                               */
+  /*    index :: The index of the fixed size in the `available_sizes'      */
+  /*             field of @FT_FaceRec structure.                           */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Select_Size( FT_Face  face,
+                  FT_Int   index );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Enum>                                                                */
+  /*    FT_Size_Request_Type                                               */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An enumeration type that lists the size request types supported.   */
+  /*                                                                       */
+  /* <Values>                                                              */
+  /*    FT_SIZE_REQUEST_TYPE_NOMINAL ::                                    */
+  /*      The nominal size.  That is, the units_per_EM field of            */
+  /*      @FT_FaceRec.                                                     */
+  /*                                                                       */
+  /*    FT_SIZE_REQUEST_TYPE_REAL_DIM ::                                   */
+  /*      The real dimension.  That is, the sum of the Ascender and        */
+  /*      (minus of) Descender fields of @FT_FaceRec.                      */
+  /*                                                                       */
+  /*    FT_SIZE_REQUEST_TYPE_BBOX ::                                       */
+  /*      The font bounding box.  That is, the bbox field of @FT_FaceRec.  */
+  /*                                                                       */
+  /*    FT_SIZE_REQUEST_TYPE_CELL ::                                       */
+  /*      The horizontal scale is determined by the max_advance_width      */
+  /*      field of @FT_FaceRec and the vertical scale is determined the    */
+  /*      same way as @FT_SIZE_REQUEST_TYPE_REAL_DIM does.  Finally, both  */
+  /*      scales are set to the smaller one.  This type is useful when     */
+  /*      you want to specify the font size for, for example, a window of  */
+  /*      80x24 cells.                                                     */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    See the note section of @FT_Size_Metrics if you wonder how does    */
+  /*    size requesting relate to scales.                                  */
+  /*                                                                       */
+  typedef enum  FT_Size_Request_Type_
+  {
+    FT_SIZE_REQUEST_TYPE_NOMINAL,
+    FT_SIZE_REQUEST_TYPE_REAL_DIM,
+    FT_SIZE_REQUEST_TYPE_BBOX,
+    FT_SIZE_REQUEST_TYPE_CELL
+
+  } FT_Size_Request_Type;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Struct>                                                              */
+  /*    FT_Size_RequestRec                                                 */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    A structure used to model a size request.                          */
+  /*                                                                       */
+  /* <Fields>                                                              */
+  /*    type           :: See @FT_Size_Request_Type.                       */
+  /*                                                                       */
+  /*    width          :: The desired width.                               */
+  /*                                                                       */
+  /*    height         :: The desired height.                              */
+  /*                                                                       */
+  /*    horiResolution :: The horizontal resolution.  If set to zero, then */
+  /*                      the width is treated as 26.6 fractional pixels.  */
+  /*                                                                       */
+  /*    vertResolution :: The vertical resolution.  If set to zero, then   */
+  /*                      the height is treated as 26.6 fractional pixels. */
+  /*                                                                       */
+  /* <Note>                                                                */
+  /*    width and height cannot both be zero.  If either of them is zero,  */
+  /*    its value is chosen so that the horizontal and vertical scales are */
+  /*    equal.                                                             */
+  /*                                                                       */
+  /*    You should use @FT_Select_Size if you are intended to select some  */
+  /*    fixed size from the `available_sizes' field of @FT_FaceRec.        */
+  /*                                                                       */
+  typedef struct  FT_Size_RequestRec_
+  {
+    FT_Size_Request_Type  type;
+    FT_F26Dot6            width;
+    FT_F26Dot6            height;
+    FT_UInt               horiResolution;
+    FT_UInt               vertResolution;
+  } FT_Size_RequestRec, *FT_Size_Request;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Request_Size                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Request the size of the active size object of a given face object. */ 
+  /*                                                                       */
   /* <InOut>                                                               */
+  /*    face  :: A handle to a target face object.                         */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    req   :: A pointer to a @FT_Size_RequestRec.                       */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.                             */
+  /*                                                                       */
+  FT_EXPORT( FT_Error )
+  FT_Request_Size( FT_Face          face,
+                   FT_Size_Request  req );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    FT_Set_Char_Size                                                   */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This funcion calls @FT_Request_Size to request the nominal size,   */
+  /*    in points.                                                         */
+  /*                                                                       */
+  /* <InOut>                                                               */
   /*    face            :: A handle to a target face object.               */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    char_width      :: The character width, in 26.6 fractional points. */
+  /*    char_width      :: The nominal width, in 26.6 fractional points.   */
   /*                                                                       */
-  /*    char_height     :: The character height, in 26.6 fractional        */
-  /*                       points.                                         */
+  /*    char_height     :: The nominal height, in 26.6 fractional points.  */
   /*                                                                       */
   /*    horz_resolution :: The horizontal resolution.                      */
   /*                                                                       */
@@ -2099,9 +2224,8 @@
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
   /* <Note>                                                                */
-  /*    For BDF and PCF formats, this function uses the `PIXEL_SIZE'       */
-  /*    property of the bitmap font; the `char_width' parameter is         */
-  /*    ignored.                                                           */
+  /*    If either the horizontal or vertical resolution is zero, it is set */
+  /*    to a default value of 72dpi.                                       */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Set_Char_Size( FT_Face     face,
@@ -2117,44 +2241,19 @@
   /*    FT_Set_Pixel_Sizes                                                 */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Sets the character dimensions of a given face object.  The width   */
-  /*    and height are expressed in integer pixels.                        */
+  /*    This funcion calls @FT_Request_Size to request the nominal size,   */
+  /*    in pixels.                                                         */
   /*                                                                       */
-  /*    If one of the character dimensions is zero, its value is set equal */
-  /*    to the other.                                                      */
-  /*                                                                       */
   /* <InOut>                                                               */
   /*    face         :: A handle to the target face object.                */
   /*                                                                       */
   /* <Input>                                                               */
-  /*    pixel_width  :: The character width, in integer pixels.            */
+  /*    pixel_width  :: The nominal width, in pixels.                      */
   /*                                                                       */
-  /*    pixel_height :: The character height, in integer pixels.           */
+  /*    pixel_height :: The nominal height, in pixels.                     */
   /*                                                                       */
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
-  /* <Note>                                                                */
-  /*    The values of `pixel_width' and `pixel_height' correspond to the   */
-  /*    pixel values of the _typographic_ character size, which are NOT    */
-  /*    necessarily the same as the dimensions of the glyph `bitmap        */
-  /*    cells'.                                                            */
-  /*                                                                       */
-  /*    The `character size' is really the size of an abstract square      */
-  /*    called the `EM', used to design the font.  However, depending      */
-  /*    on the font design, glyphs is smaller or greater than the EM.      */
-  /*                                                                       */
-  /*    This means that setting the pixel size to, say, 8x8 doesn't        */
-  /*    guarantee in any way that you get glyph bitmaps that all fit       */
-  /*    within an 8x8 cell (sometimes even far from it).                   */
-  /*                                                                       */
-  /*    For bitmap fonts, `pixel_height' usually is a reliable value for   */
-  /*    the height of the bitmap cell.  Drivers for bitmap font formats    */
-  /*    which contain a single bitmap strike only (BDF, PCF, FNT) ignore   */
-  /*    `pixel_width'.                                                     */
-  /*                                                                       */
-  /*    For BDF and PCF formats, this function uses the sum of the         */
-  /*    `FONT_ASCENT' and `FONT_DESCENT' properties of the bitmap font.    */
   /*                                                                       */
   FT_EXPORT( FT_Error )
   FT_Set_Pixel_Sizes( FT_Face  face,
--- a/include/freetype/internal/ftdriver.h
+++ b/include/freetype/internal/ftdriver.h
@@ -53,16 +53,12 @@
 
 
   typedef FT_Error
-  (*FT_Size_ResetPointsFunc)( FT_Size     size,
-                              FT_F26Dot6  char_width,
-                              FT_F26Dot6  char_height,
-                              FT_UInt     horz_resolution,
-                              FT_UInt     vert_resolution );
+  (*FT_Size_RequestFunc)( FT_Size          size,
+                          FT_Size_Request  req );
 
   typedef FT_Error
-  (*FT_Size_ResetPixelsFunc)( FT_Size  size,
-                              FT_UInt  pixel_width,
-                              FT_UInt  pixel_height );
+  (*FT_Size_SelectFunc)( FT_Size   size,
+                         FT_ULong  index );
 
   typedef FT_Error
   (*FT_Slot_LoadFunc)( FT_GlyphSlot  slot,
@@ -129,16 +125,18 @@
   /*                                                                       */
   /*    done_slot        :: The format-specific slot destructor.           */
   /*                                                                       */
-  /*    set_char_sizes   :: A handle to a function used to set the new     */
-  /*                        character size in points + resolution.  Can be */
-  /*                        set to 0 to indicate default behaviour.        */
+  /*    request_size     :: A handle to a function used to request the new */
+  /*                        character size.  Can be set to 0 if the        */
+  /*                        scaling done in the base layer suffices.       */
   /*                                                                       */
-  /*    set_pixel_sizes  :: A handle to a function used to set the new     */
-  /*                        character size in pixels.  Can be set to 0 to  */
-  /*                        indicate default behaviour.                    */
+  /*    select_size      :: A handle to a function used to select a new    */
+  /*                        fixed size.  It is used only when              */
+  /*                        @FT_FACE_FLAG_FIXED_SIZES is set.  Can be set  */
+  /*                        to 0 if the scaling done in the base layer     */
+  /*                        suffices.                                      */
   /*                                                                       */
-  /*    load_glyph       :: A function handle to load a given glyph image  */
-  /*                        in a slot.  This field is mandatory!           */
+  /*    load_glyph       :: A function handle to load a glyph to a slot.   */
+  /*                        This field is mandatory!                       */
   /*                                                                       */
   /*    get_char_index   :: A function handle to return the glyph index of */
   /*                        a given character for a given charmap.  This   */
@@ -186,8 +184,8 @@
     FT_Slot_InitFunc          init_slot;
     FT_Slot_DoneFunc          done_slot;
 
-    FT_Size_ResetPointsFunc   set_char_sizes;
-    FT_Size_ResetPixelsFunc   set_pixel_sizes;
+    FT_Size_RequestFunc       request_size;
+    FT_Size_SelectFunc        select_size;
 
     FT_Slot_LoadFunc          load_glyph;
 
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -451,6 +451,16 @@
 
  /* */
 
+  /*
+   * Match a size request against `available_sizes'.
+   */
+  FT_BASE( FT_Error )
+  FT_Match_Size( FT_Face          face,
+                 FT_Size_Request  req,
+                 FT_Bool          ignore_width,
+                 FT_ULong*        index );
+
+
  /*
   * Free the bitmap of a given glyphslot when needed
   * (i.e., only when it was allocated with ft_glyphslot_alloc_bitmap).
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -365,16 +365,13 @@
   /*    TT_Set_SBit_Strike_Func                                            */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Selects an sbit strike for given horizontal and vertical ppem      */
-  /*    values.                                                            */
+  /*    Selects an sbit strike for a given size request.                   */
   /*                                                                       */
   /* <Input>                                                               */
   /*    face          :: The target face object.                           */
   /*                                                                       */
-  /*    x_ppem        :: The horizontal resolution in points per EM.       */
+  /*    req           :: The size request.                                 */
   /*                                                                       */
-  /*    y_ppem        :: The vertical resolution in points per EM.         */
-  /*                                                                       */
   /* <Output>                                                              */
   /*    astrike_index :: The index of the sbit strike.                     */
   /*                                                                       */
@@ -383,15 +380,40 @@
   /*    sbit strike exists for the selected ppem values.                   */
   /*                                                                       */
   typedef FT_Error
-  (*TT_Set_SBit_Strike_Func)( TT_Face    face,
-                              FT_UInt    x_ppem,
-                              FT_UInt    y_ppem,
-                              FT_ULong  *astrike_index );
+  (*TT_Set_SBit_Strike_Func)( TT_Face          face,
+                              FT_Size_Request  req,
+                              FT_ULong*        astrike_index );
 
 
   /*************************************************************************/
   /*                                                                       */
   /* <FuncType>                                                            */
+  /*    TT_Load_Strike_Metrics_Func                                        */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    Loads the metrics of a given strike.                               */
+  /*                                                                       */
+  /* <Input>                                                               */
+  /*    face          :: The target face object.                           */
+  /*                                                                       */
+  /*    strike_index  :: The strike index.                                 */
+  /*                                                                       */
+  /* <Output>                                                              */
+  /*    metrics       :: the metrics of the strike.                        */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    FreeType error code.  0 means success.  Returns an error if no     */
+  /*    such sbit strike exists.                                           */
+  /*                                                                       */
+  typedef FT_Error
+  (*TT_Load_Strike_Metrics_Func)( TT_Face           face,
+                                  FT_ULong          strike_index,
+                                  FT_Size_Metrics*  metrics );
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <FuncType>                                                            */
   /*    TT_Get_PS_Name_Func                                                */
   /*                                                                       */
   /* <Description>                                                         */
@@ -549,6 +571,7 @@
 
     /* see `ttsbit.h' */
     TT_Set_SBit_Strike_Func      set_sbit_strike;
+    TT_Load_Strike_Metrics_Func  load_strike_metrics;
     TT_Load_Table_Func           load_sbits;
     TT_Find_SBit_Image_Func      find_sbit_image;
     TT_Load_SBit_Metrics_Func    load_sbit_metrics;
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -1960,6 +1960,59 @@
   }
 
 
+  /* documentation is in ftobjs.h */
+
+  FT_BASE_DEF( FT_Error )
+  FT_Match_Size( FT_Face          face,
+                 FT_Size_Request  req,
+                 FT_Bool          ignore_width,
+                 FT_ULong*        index )
+  {
+    FT_Int   i;
+    FT_Long  w, h;
+
+
+    if ( !FT_HAS_FIXED_SIZES( face ) )
+      return FT_Err_Invalid_Face_Handle;
+
+    /* FT_Bitmap_Size doesn't provide enough info... */
+    if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
+      return FT_Err_Unimplemented_Feature;
+
+    if ( req->horiResolution )
+      w = ( req->width  * req->horiResolution + 36 ) / 72;
+    else
+      w = req->width;
+
+    if ( req->vertResolution )
+      h = ( req->height * req->vertResolution + 36 ) / 72;
+    else
+      h = req->height;
+
+    if ( req->width && !req->height )
+      h = w;
+    else if ( !req->width && req->height )
+      w = h;
+
+    for ( i = 0; i < face->num_fixed_sizes; i++ )
+    {
+      if ( h != face->available_sizes[i].y_ppem )
+        continue;
+
+      if ( w == face->available_sizes[i].x_ppem ||
+           ignore_width )
+      {
+        if ( index )
+          *index = (FT_ULong)i;
+
+        return FT_Err_Ok;
+      }
+    }
+
+    return FT_Err_Invalid_Pixel_Size;
+  }
+
+
   static void
   ft_recompute_scaled_metrics( FT_Face           face,
                                FT_Size_Metrics*  metrics )
@@ -1983,84 +2036,51 @@
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FT_Set_Char_Size( FT_Face     face,
-                    FT_F26Dot6  char_width,
-                    FT_F26Dot6  char_height,
-                    FT_UInt     horz_resolution,
-                    FT_UInt     vert_resolution )
+  FT_Select_Size( FT_Face  face,
+                  FT_Int   index )
   {
-    FT_Error          error = FT_Err_Ok;
-    FT_Driver         driver;
     FT_Driver_Class   clazz;
     FT_Size_Metrics*  metrics;
-    FT_Long           dim_x, dim_y;
+    FT_Bitmap_Size*   bsize;
 
 
-    if ( !face || !face->size || !face->driver )
+    if ( !face || !FT_HAS_FIXED_SIZES( face ) )
       return FT_Err_Invalid_Face_Handle;
 
-    driver  = face->driver;
+    if ( index < 0 || index >= face->num_fixed_sizes )
+      return FT_Err_Invalid_Argument;
+
+    clazz   = face->driver->clazz;
     metrics = &face->size->metrics;
-    clazz   = driver->clazz;
 
-    if ( !char_width )
-      char_width = char_height;
+    bsize   = face->available_sizes + index;
 
-    else if ( !char_height )
-      char_height = char_width;
+    metrics->x_ppem = ( bsize->x_ppem + 32 ) >> 6;
+    metrics->y_ppem = ( bsize->y_ppem + 32 ) >> 6;
 
-    if ( !horz_resolution )
-      horz_resolution = 72;
-
-    if ( !vert_resolution )
-      vert_resolution = 72;
-
-    /* default processing -- this can be overridden by the driver */
-    if ( char_width  < 1 * 64 )
-      char_width  = 1 * 64;
-    if ( char_height < 1 * 64 )
-      char_height = 1 * 64;
-
-    /* Compute pixel sizes in 26.6 units */
-    dim_x = ( char_width  * horz_resolution + 36 ) / 72;
-    dim_y = ( char_height * vert_resolution + 36 ) / 72;
-
+    if ( FT_IS_SCALABLE( face ) )
     {
-      FT_UShort  x_ppem = (FT_UShort)( ( dim_x + 32 ) >> 6 );
-      FT_UShort  y_ppem = (FT_UShort)( ( dim_y + 32 ) >> 6 );
+      metrics->x_scale = FT_DivFix( bsize->x_ppem,
+                                    face->units_per_EM );
+      metrics->y_scale = FT_DivFix( bsize->y_ppem,
+                                    face->units_per_EM );
 
-
-      /* Don't take, say, 12.5x12.5 equal to 13x13.  If working with */
-      /* fractional font sizes this would hide slightly different    */
-      /* font metrics.  Consequently, the next two lines are         */
-      /* disabled.                                                   */
-#if 0
-      if ( x_ppem == metrics->x_ppem && y_ppem == metrics->y_ppem )
-        return FT_Err_Ok;
-#endif
-
-      metrics->x_ppem = x_ppem;
-      metrics->y_ppem = y_ppem;
+      ft_recompute_scaled_metrics( face, metrics );
     }
-
-    metrics->x_scale = 0x10000L;
-    metrics->y_scale = 0x10000L;
-
-    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
+    else
     {
-      metrics->x_scale = FT_DivFix( dim_x, face->units_per_EM );
-      metrics->y_scale = FT_DivFix( dim_y, face->units_per_EM );
-
-      ft_recompute_scaled_metrics( face, metrics );
+      metrics->x_scale     = 0x10000;
+      metrics->y_scale     = 0x10000;
+      metrics->ascender    = bsize->y_ppem;
+      metrics->descender   = 0;
+      metrics->height      = bsize->height << 6;
+      metrics->max_advance = bsize->x_ppem;
     }
 
-    if ( clazz->set_char_sizes )
-      error = clazz->set_char_sizes( face->size,
-                                     char_width,
-                                     char_height,
-                                     horz_resolution,
-                                     vert_resolution );
-    return error;
+    if ( clazz->select_size )
+      return clazz->select_size( face->size, (FT_ULong)index );
+    else
+      return FT_Err_Ok;
   }
 
 
@@ -2067,59 +2087,154 @@
   /* documentation is in freetype.h */
 
   FT_EXPORT_DEF( FT_Error )
-  FT_Set_Pixel_Sizes( FT_Face  face,
-                      FT_UInt  pixel_width,
-                      FT_UInt  pixel_height )
+  FT_Request_Size( FT_Face          face,
+                   FT_Size_Request  req )
   {
-    FT_Error          error = FT_Err_Ok;
-    FT_Driver         driver;
     FT_Driver_Class   clazz;
     FT_Size_Metrics*  metrics;
+    FT_Error          error;
 
 
-    if ( !face || !face->size || !face->driver )
+    if ( !face )
       return FT_Err_Invalid_Face_Handle;
 
-    driver  = face->driver;
+    if ( !req )
+      return FT_Err_Invalid_Argument;
+
+    clazz   = face->driver->clazz;
     metrics = &face->size->metrics;
-    clazz   = driver->clazz;
 
-    if ( pixel_width == 0 )
-      pixel_width = pixel_height;
+    if ( FT_IS_SCALABLE( face ) )
+    {
+      FT_Long  w, h, scaled_w, scaled_h;
 
-    else if ( pixel_height == 0 )
-      pixel_height = pixel_width;
 
-    if ( pixel_width  < 1 )
-      pixel_width  = 1;
-    if ( pixel_height < 1 )
-      pixel_height = 1;
+      switch ( req->type )
+      {
+      case FT_SIZE_REQUEST_TYPE_NOMINAL:
+        w = h = face->units_per_EM;
+        break;
+      case FT_SIZE_REQUEST_TYPE_REAL_DIM:
+        w = h = face->ascender - face->descender;
+        break;
+      case FT_SIZE_REQUEST_TYPE_CELL:
+        w = face->max_advance_width;
+        h = face->ascender - face->descender;
+        break;
+      case FT_SIZE_REQUEST_TYPE_BBOX:
+        w = face->bbox.xMax - face->bbox.xMin;
+        h = face->bbox.yMax - face->bbox.yMin;
+        break;
+      default:
+        return FT_Err_Unimplemented_Feature;
+        break;
+      }
 
-    /* use `>=' to avoid potential compiler warnings on 16bit platforms */
-    if ( pixel_width >= 0xFFFFU )
-      pixel_width  = 0xFFFFU;
-    if ( pixel_height >= 0xFFFFU )
-      pixel_height = 0xFFFFU;
+      if ( req->horiResolution )
+        scaled_w = ( req->width  * req->horiResolution + 36 ) / 72;
+      else
+        scaled_w = req->width;
 
-    metrics->x_ppem = (FT_UShort)pixel_width;
-    metrics->y_ppem = (FT_UShort)pixel_height;
+      if ( req->vertResolution )
+        scaled_h = ( req->height * req->vertResolution + 36 ) / 72;
+      else
+        scaled_h = req->height;
 
-    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
-    {
-      metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
-                                    face->units_per_EM );
+      /* determine scales */
+      if ( req->width )
+      {
+        metrics->x_scale = FT_DivFix( scaled_w, w );
 
-      metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
-                                    face->units_per_EM );
+        if ( req->height )
+        {
+          metrics->y_scale = FT_DivFix( scaled_h, h );
 
+          if ( req->type == FT_SIZE_REQUEST_TYPE_CELL )
+          {
+            if ( metrics->y_scale > metrics->x_scale )
+              metrics->y_scale = metrics->x_scale;
+            else
+              metrics->x_scale = metrics->y_scale;
+          }
+        }
+        else
+        {
+          metrics->y_scale = metrics->x_scale;
+          scaled_h = FT_MulDiv( scaled_w, h, w );
+        }
+      }
+      else
+      {
+        metrics->x_scale = metrics->y_scale = FT_DivFix( scaled_h, h );
+        scaled_w = FT_MulDiv( scaled_h, w, h );
+      }
+
+      /* calculate ppem */
+      if ( req->type != FT_SIZE_REQUEST_TYPE_NOMINAL )
+      {
+        scaled_w = FT_MulFix( face->units_per_EM, metrics->x_scale );
+        scaled_h = FT_MulFix( face->units_per_EM, metrics->y_scale );
+      }
+
+      metrics->x_ppem = ( scaled_w + 32 ) >> 6;
+      metrics->y_ppem = ( scaled_h + 32 ) >> 6;
+
       ft_recompute_scaled_metrics( face, metrics );
+
+      error = FT_Err_Ok;
     }
+    else
+    {
+      FT_ZERO( metrics );
+      error = FT_Err_Invalid_Pixel_Size;
+    }
 
-    if ( clazz->set_pixel_sizes )
-      error = clazz->set_pixel_sizes( face->size,
-                                      pixel_width,
-                                      pixel_height );
-    return error;
+    if ( clazz->request_size )
+      return clazz->request_size( face->size, req );
+    else
+      return error;
+  }
+
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Set_Char_Size( FT_Face     face,
+                    FT_F26Dot6  char_width,
+                    FT_F26Dot6  char_height,
+                    FT_UInt     horz_resolution,
+                    FT_UInt     vert_resolution )
+  {
+    FT_Size_RequestRec  req;
+
+
+    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
+    req.width          = char_width;
+    req.height         = char_height;
+    req.horiResolution = ( horz_resolution ) ? horz_resolution : 72;
+    req.vertResolution = ( vert_resolution ) ? vert_resolution : 72;
+
+    return FT_Request_Size( face, &req );
+  }
+
+
+  /* documentation is in freetype.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Set_Pixel_Sizes( FT_Face  face,
+                      FT_UInt  pixel_width,
+                      FT_UInt  pixel_height )
+  {
+    FT_Size_RequestRec  req;
+
+
+    req.type           = FT_SIZE_REQUEST_TYPE_NOMINAL;
+    req.width          = pixel_width << 6;
+    req.height         = pixel_height << 6;
+    req.horiResolution = 0;
+    req.vertResolution = 0;
+
+    return FT_Request_Size( face, &req );
   }
 
 
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -582,62 +582,40 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  BDF_Set_Pixel_Size( FT_Size  size,
-                      FT_UInt  char_width,
-                      FT_UInt  char_height )
+  BDF_Size_Select( FT_Size   size,
+                   FT_ULong  index )
   {
-    BDF_Face  face = (BDF_Face)FT_SIZE_FACE( size );
-    FT_Face   root = FT_FACE( face );
+    bdf_font_t*  bdffont = ( (BDF_Face)size->face )->bdffont;
 
-    FT_UNUSED( char_width );
 
+    FT_UNUSED( index );
 
-    if ( char_height == (FT_UInt)root->available_sizes->height )
-    {
-      size->metrics.ascender    = face->bdffont->font_ascent << 6;
-      size->metrics.descender   = -face->bdffont->font_descent << 6;
-      size->metrics.height      = ( face->bdffont->font_ascent +
-                                    face->bdffont->font_descent ) << 6;
-      size->metrics.max_advance = face->bdffont->bbx.width << 6;
+    size->metrics.ascender    = bdffont->font_ascent << 6;
+    size->metrics.descender   = -bdffont->font_descent << 6;
+    size->metrics.max_advance = bdffont->bbx.width << 6;
 
-      return BDF_Err_Ok;
-    }
-    else
-      return BDF_Err_Invalid_Pixel_Size;
+    return BDF_Err_Ok;
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
-  BDF_Set_Point_Size( FT_Size     size,
-                      FT_F26Dot6  char_width,
-                      FT_F26Dot6  char_height,
-                      FT_UInt     horz_resolution,
-                      FT_UInt     vert_resolution )
+  BDF_Size_Request( FT_Size          size,
+                    FT_Size_Request  req )
   {
-    BDF_Face  face = (BDF_Face)FT_SIZE_FACE( size );
-    FT_Face   root = FT_FACE( face );
+    FT_Face   face = size->face;
+    FT_Error  error;
 
-    FT_UNUSED( char_width );
-    FT_UNUSED( char_height );
-    FT_UNUSED( horz_resolution );
-    FT_UNUSED( vert_resolution );
 
+    error = FT_Match_Size( face, req, 1, NULL );
 
-    FT_TRACE4(( "rec %d - pres %d\n",
-                size->metrics.y_ppem, root->available_sizes->y_ppem ));
-
-    if ( size->metrics.y_ppem == root->available_sizes->y_ppem >> 6 )
+    if ( error )
+      return error;
+    else
     {
-      size->metrics.ascender    = face->bdffont->font_ascent << 6;
-      size->metrics.descender   = -face->bdffont->font_descent << 6;
-      size->metrics.height      = ( face->bdffont->font_ascent +
-                                    face->bdffont->font_descent ) << 6;
-      size->metrics.max_advance = face->bdffont->bbx.width << 6;
+      size->metrics.height = face->available_sizes->height << 6;
 
-      return BDF_Err_Ok;
+      return BDF_Size_Select( size, 0 );
     }
-    else
-      return BDF_Err_Invalid_Pixel_Size;
   }
 
 
@@ -835,8 +813,8 @@
     0,                          /* FT_Slot_InitFunc */
     0,                          /* FT_Slot_DoneFunc */
 
-    BDF_Set_Point_Size,
-    BDF_Set_Pixel_Size,
+    BDF_Size_Request,
+    BDF_Size_Select,
 
     BDF_Glyph_Load,
 
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -433,8 +433,13 @@
     cff_slot_init,
     cff_slot_done,
 
-    cff_point_size_reset,
-    cff_size_reset,
+    cff_size_request,
+
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+    cff_size_select,
+#else
+    0,                      /* FT_Size_SelectFunc      */
+#endif 
 
     Load_Glyph,
 
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -2420,7 +2420,7 @@
       FT_Stream     stream   = cff_face->root.stream;
 
 
-      if ( size->strike_index != 0xFFFFU           &&
+      if ( size->strike_index != 0xFFFFFFFFU       &&
            sfnt->load_sbits                        &&
            ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
       {
@@ -2428,7 +2428,7 @@
 
 
         error = sfnt->load_sbit_image( face,
-                                       (FT_ULong)size->strike_index,
+                                       size->strike_index,
                                        (FT_UInt)glyph_index,
                                        (FT_Int)load_flags,
                                        stream,
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -52,90 +52,6 @@
   /*************************************************************************/
 
 
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-
-  static FT_Error
-  sbit_size_reset( CFF_Size  size )
-  {
-    CFF_Face          face;
-    FT_Error          error = CFF_Err_Ok;
-
-    FT_ULong          strike_index;
-    FT_Size_Metrics*  metrics;
-    FT_Size_Metrics*  sbit_metrics;
-    SFNT_Service      sfnt;
-
-
-    metrics = &size->root.metrics;
-
-    face = (CFF_Face)size->root.face;
-    sfnt = (SFNT_Service)face->sfnt;
-
-    sbit_metrics = &size->strike_metrics;
-
-    error = sfnt->set_sbit_strike( face,
-                                   metrics->x_ppem,
-                                   metrics->y_ppem,
-                                   &strike_index );
-
-    if ( !error )
-    {
-      /* XXX: TODO: move this code to the SFNT module where it belongs */
-
-#ifdef FT_OPTIMIZE_MEMORY
-
-      FT_Byte*    strike = face->sbit_table + 8 + strike_index*48;
-
-      sbit_metrics->ascender  = (FT_Char)strike[16] << 6;  /* hori.ascender  */
-      sbit_metrics->descender = (FT_Char)strike[17] << 6;  /* hori.descender */
-
-      /* XXX: Is this correct? */
-      sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB  */
-                                             strike[18] + /* max_width      */
-                                    (FT_Char)strike[23]   /* min_advance_SB */
-                                                        ) << 6;
-
-#else /* !OPTIMIZE_MEMORY */
-
-      TT_SBit_Strike  strike = face->sbit_strikes + strike_index;
-
-
-      sbit_metrics->ascender  = strike->hori.ascender << 6;
-      sbit_metrics->descender = strike->hori.descender << 6;
-
-      /* XXX: Is this correct? */
-      sbit_metrics->max_advance = ( strike->hori.min_origin_SB  +
-                                    strike->hori.max_width      +
-                                    strike->hori.min_advance_SB ) << 6;
-
-#endif /* !OPTIMIZE_MEMORY */
-
-      /* XXX: Is this correct? */
-      sbit_metrics->height = sbit_metrics->ascender -
-                             sbit_metrics->descender;
-
-      sbit_metrics->x_ppem = metrics->x_ppem;
-      sbit_metrics->y_ppem = metrics->y_ppem;
-      size->strike_index   = (FT_UInt)strike_index;
-    }
-    else
-    {
-      size->strike_index = 0xFFFFU;
-
-      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 */
-
-
   static PSH_Globals_Funcs
   cff_size_get_globals_funcs( CFF_Size  size )
   {
@@ -243,63 +159,89 @@
         cffsize->internal = (FT_Size_Internal)(void*)globals;
     }
 
+    size->strike_index = 0xFFFFFFFFU;
+
     return error;
   }
 
 
   FT_LOCAL_DEF( FT_Error )
-  cff_size_reset( FT_Size  cffsize,         /* CFF_Size */
-                  FT_UInt  char_width,
-                  FT_UInt  char_height )
+  cff_size_request( FT_Size          size,
+                    FT_Size_Request  req )
   {
-    CFF_Size           size  = (CFF_Size)cffsize;
-    PSH_Globals_Funcs  funcs = cff_size_get_globals_funcs( size );
-    FT_Error           error = CFF_Err_Ok;
-    FT_Face            face  = cffsize->face;
-
-    FT_UNUSED( char_width );
-    FT_UNUSED( char_height );
-
-
-    if ( funcs )
-      error = funcs->set_scale( (PSH_Globals)cffsize->internal,
-                                 cffsize->metrics.x_scale,
-                                 cffsize->metrics.y_scale,
-                                 0, 0 );
-
+    CFF_Size           cffsize = (CFF_Size)size;
+    PSH_Globals_Funcs  funcs;
+    
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
-    if ( face->face_flags & FT_FACE_FLAG_FIXED_SIZES )
+    if ( FT_HAS_FIXED_SIZES( size->face ) )
     {
-      error = sbit_size_reset( size );
+      CFF_Face          cffface = (CFF_Face)size->face;
+      SFNT_Service      sfnt    = cffface->sfnt;
+      FT_Size_Metrics*  metrics = &size->metrics;
+      FT_ULong          index;
+      FT_Error          error;
 
-      if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
-        cffsize->metrics = size->strike_metrics;
+
+      if ( !( error = sfnt->set_sbit_strike( cffface,
+                                             req,
+                                             &index ) ) &&
+           !( error = sfnt->load_strike_metrics( cffface,
+                                                 index,
+                                                 metrics ) ) )
+        cffsize->strike_index = index;
+      else
+        cffsize->strike_index = 0xFFFFFFFFU;
     }
 
 #endif
 
-    if ( face->face_flags & FT_FACE_FLAG_SCALABLE )
-      return CFF_Err_Ok;
-    else
-      return error;
+    FT_UNUSED( req );
+
+    funcs = cff_size_get_globals_funcs( cffsize );
+
+    if ( funcs )
+      funcs->set_scale( (PSH_Globals)size->internal,
+                        size->metrics.x_scale,
+                        size->metrics.y_scale,
+                        0, 0 );
+
+    return CFF_Err_Ok;
   }
 
 
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
   FT_LOCAL_DEF( FT_Error )
-  cff_point_size_reset( FT_Size     cffsize,
-                        FT_F26Dot6  char_width,
-                        FT_F26Dot6  char_height,
-                        FT_UInt     horz_resolution,
-                        FT_UInt     vert_resolution )
+  cff_size_select( FT_Size   size,
+                   FT_ULong  index )
   {
-    FT_UNUSED( char_width );
-    FT_UNUSED( char_height );
-    FT_UNUSED( horz_resolution );
-    FT_UNUSED( vert_resolution );
+    CFF_Face           cffface = (CFF_Face)size->face;
+    CFF_Size           cffsize = (CFF_Size)size;
+    FT_Size_Metrics*   metrics = &size->metrics;
+    SFNT_Interface*    sfnt    = cffface->sfnt;
+    FT_Error           error;
+    PSH_Globals_Funcs  funcs;
 
-    return cff_size_reset( cffsize, 0, 0 );
+
+    funcs = cff_size_get_globals_funcs( cffsize );
+
+    if ( funcs )
+      funcs->set_scale( (PSH_Globals)size->internal,
+                        size->metrics.x_scale,
+                        size->metrics.y_scale,
+                        0, 0 );
+
+    error = sfnt->load_strike_metrics( cffface, index, metrics );
+    if ( error )
+      cffsize->strike_index = 0xFFFFFFFFU;
+    else
+      cffsize->strike_index = index;
+
+    return error;
   }
+
+#endif
 
 
   /*************************************************************************/
--- a/src/cff/cffobjs.h
+++ b/src/cff/cffobjs.h
@@ -54,14 +54,8 @@
   typedef struct  CFF_SizeRec_
   {
     FT_SizeRec       root;
+    FT_ULong         strike_index;    /* 0xFFFFFFFFU to indicate invalid */
 
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-
-    FT_UInt          strike_index;    /* 0xFFFF to indicate invalid */
-    FT_Size_Metrics  strike_metrics;  /* current strike's metrics   */
-
-#endif
-
   } CFF_SizeRec, *CFF_Size;
 
 
@@ -119,16 +113,12 @@
   cff_size_done( FT_Size  size );           /* CFF_Size */
 
   FT_LOCAL( FT_Error )
-  cff_size_reset( FT_Size  size,            /* CFF_Size */
-                  FT_UInt  char_width,
-                  FT_UInt  char_height );
+  cff_size_request( FT_Size          size,
+                    FT_Size_Request  req );
 
   FT_LOCAL( FT_Error )
-  cff_point_size_reset( FT_Size     cffsize,
-                        FT_F26Dot6  char_width,
-                        FT_F26Dot6  char_height,
-                        FT_UInt     horz_resolution,
-                        FT_UInt     vert_resolution );
+  cff_size_select( FT_Size   size,
+                   FT_ULong  index );
 
   FT_LOCAL( void )
   cff_slot_done( FT_GlyphSlot  slot );
--- a/src/cid/cidobjs.c
+++ b/src/cid/cidobjs.c
@@ -152,41 +152,24 @@
   }
 
 
-  FT_LOCAL_DEF( FT_Error )
-  cid_size_reset( FT_Size  cidsize,             /* CID_Size */
-                  FT_UInt  char_width,
-                  FT_UInt  char_height )
+  FT_LOCAL( FT_Error )
+  cid_size_request( FT_Size          size,
+                    FT_Size_Request  req )
   {
-    CID_Size           size  = (CID_Size)cidsize;
-    PSH_Globals_Funcs  funcs = cid_size_get_globals_funcs( size );
-    FT_Error           error = 0;
+    PSH_Globals_Funcs  funcs;
 
-    FT_UNUSED( char_width );
-    FT_UNUSED( char_height );
 
+    FT_UNUSED( req );
 
+    funcs = cid_size_get_globals_funcs( (CID_Size)size );
+
     if ( funcs )
-      error = funcs->set_scale( (PSH_Globals)cidsize->internal,
-                                 cidsize->metrics.x_scale,
-                                 cidsize->metrics.y_scale,
-                                 0, 0 );
-    return error;
-  }
+      funcs->set_scale( (PSH_Globals)size->internal,
+                        size->metrics.x_scale,
+                        size->metrics.y_scale,
+                        0, 0 );
 
-
-  FT_LOCAL_DEF( FT_Error )
-  cid_point_size_reset( FT_Size     size,
-                        FT_F26Dot6  char_width,
-                        FT_F26Dot6  char_height,
-                        FT_UInt     horz_resolution,
-                        FT_UInt     vert_resolution )
-  {
-    FT_UNUSED( char_width );
-    FT_UNUSED( char_height );
-    FT_UNUSED( horz_resolution );
-    FT_UNUSED( vert_resolution );
-
-    return cid_size_reset( size, 0, 0 );
+    return CID_Err_Ok;
   }
 
 
--- a/src/cid/cidobjs.h
+++ b/src/cid/cidobjs.h
@@ -125,17 +125,8 @@
   cid_size_init( FT_Size  size );       /* CID_Size */
 
   FT_LOCAL( FT_Error )
-  cid_size_reset( FT_Size  size,        /* CID_Size */
-                  FT_UInt  char_width,
-                  FT_UInt  char_height );
-
-  FT_LOCAL( FT_Error )
-  cid_point_size_reset( FT_Size     size,
-                        FT_F26Dot6  char_width,
-                        FT_F26Dot6  char_height,
-                        FT_UInt     horz_resolution,
-                        FT_UInt     vert_resolution );
-
+  cid_size_request( FT_Size          size,      /* CID_Size */
+                    FT_Size_Request  req );
 
   FT_LOCAL( FT_Error )
   cid_face_init( FT_Stream      stream,
--- a/src/cid/cidriver.c
+++ b/src/cid/cidriver.c
@@ -143,8 +143,8 @@
     cid_slot_init,
     cid_slot_done,
 
-    cid_point_size_reset,
-    cid_size_reset,
+    cid_size_request,
+    0,                      /* FT_Size_SelectFunc      */
 
     cid_slot_load_glyph,
 
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -363,75 +363,43 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  PCF_Set_Pixel_Size( FT_Size  size,
-                      FT_UInt  pixel_width,
-                      FT_UInt  pixel_height )
+  PCF_Size_Select( FT_Size   size,
+                   FT_ULong  index )
   {
-    PCF_Face  face = (PCF_Face)FT_SIZE_FACE( size );
+    PCF_Face   face  = (PCF_Face)size->face;
 
-    FT_UNUSED( pixel_width );
 
+    FT_UNUSED( index );
 
-    if ( pixel_height == (FT_UInt)face->root.available_sizes->height )
-    {
-      size->metrics.ascender    = face->accel.fontAscent << 6;
-      size->metrics.descender   = face->accel.fontDescent * (-64);
+    size->metrics.ascender    = face->accel.fontAscent << 6;
+    size->metrics.descender   = -face->accel.fontDescent << 6;
 #if 0
-      size->metrics.height      = face->accel.maxbounds.ascent << 6;
+    size->metrics.height      = face->accel.maxbounds.ascent << 6;
 #endif
-      size->metrics.height      = size->metrics.ascender -
-                                  size->metrics.descender;
+    size->metrics.max_advance = face->accel.maxbounds.characterWidth << 6;
 
-      size->metrics.max_advance = face->accel.maxbounds.characterWidth << 6;
-
-      return PCF_Err_Ok;
-    }
-    else
-    {
-      FT_TRACE4(( "pixel size WRONG\n" ));
-      return PCF_Err_Invalid_Pixel_Size;
-    }
+    return PCF_Err_Ok;
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
-  PCF_Set_Point_Size( FT_Size     size,
-                      FT_F26Dot6  char_width,
-                      FT_F26Dot6  char_height,
-                      FT_UInt     horz_resolution,
-                      FT_UInt     vert_resolution )
+  PCF_Size_Request( FT_Size          size,
+                    FT_Size_Request  req )
   {
-    PCF_Face  face = (PCF_Face)FT_SIZE_FACE( size );
+    FT_Face   face = size->face;
+    FT_Error  error;
 
-    FT_UNUSED( char_width );
-    FT_UNUSED( char_height );
-    FT_UNUSED( horz_resolution );
-    FT_UNUSED( vert_resolution );
 
+    error = FT_Match_Size( face, req, 1, NULL );
 
-    FT_TRACE4(( "rec %d - pres %d\n",
-                size->metrics.y_ppem,
-                face->root.available_sizes->y_ppem >> 6 ));
-
-    if ( size->metrics.y_ppem == face->root.available_sizes->y_ppem >> 6 )
+    if ( error )
+      return error;
+    else
     {
-      size->metrics.ascender    = face->accel.fontAscent << 6;
-      size->metrics.descender   = face->accel.fontDescent * (-64);
-#if 0
-      size->metrics.height      = face->accel.maxbounds.ascent << 6;
-#endif
-      size->metrics.height      = size->metrics.ascender -
-                                  size->metrics.descender;
+      size->metrics.height = face->available_sizes->height << 6;
 
-      size->metrics.max_advance = face->accel.maxbounds.characterWidth << 6;
-
-      return PCF_Err_Ok;
+      return PCF_Size_Select( size, 0 );
     }
-    else
-    {
-      FT_TRACE4(( "size WRONG\n" ));
-      return PCF_Err_Invalid_Pixel_Size;
-    }
   }
 
 
@@ -659,8 +627,8 @@
     0,                      /* FT_Slot_InitFunc */
     0,                      /* FT_Slot_DoneFunc */
 
-    PCF_Set_Point_Size,
-    PCF_Set_Pixel_Size,
+    PCF_Size_Request,
+    PCF_Size_Select,
 
     PCF_Glyph_Load,
 
--- a/src/pfr/pfrdrivr.c
+++ b/src/pfr/pfrdrivr.c
@@ -190,8 +190,8 @@
     pfr_slot_init,
     pfr_slot_done,
 
-    0,                  /* FT_Size_ResetPointsFunc */
-    0,                  /* FT_Size_ResetPixelsFunc */
+    0,                  /* FT_Size_RequestFunc */
+    0,                  /* FT_Size_SelectFunc  */
     pfr_slot_load,
 
     pfr_get_kerning,
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -185,6 +185,9 @@
         {
           size->height = (FT_UShort)strike->y_ppm;
           size->width  = (FT_UShort)strike->x_ppm;
+          size->size   = strike->y_ppm << 6;
+          size->x_ppem = strike->x_ppm << 6;
+          size->y_ppem = strike->y_ppm << 6;
         }
         pfrface->num_fixed_sizes = count;
       }
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -413,6 +413,7 @@
 
     /* see `ttsbit.h' and `sfnt.h' */
     tt_face_set_sbit_strike,
+    tt_face_load_strike_metrics,
     tt_face_load_sbit_strikes,
 #ifdef FT_OPTIMIZE_MEMORY
     0,
--- a/src/sfnt/ttsbit.c
+++ b/src/sfnt/ttsbit.c
@@ -671,30 +671,40 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_face_set_sbit_strike( TT_Face    face,
-                           FT_UInt    x_ppem,
-                           FT_UInt    y_ppem,
-                           FT_ULong  *astrike_index )
+  tt_face_set_sbit_strike( TT_Face          face,
+                           FT_Size_Request  req,
+                           FT_ULong*        astrike_index )
   {
-    FT_ULong  i;
+    return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
+  }
 
 
-    if ( x_ppem > 255 ||
-         y_ppem < 1 || y_ppem > 255 )
-      return SFNT_Err_Invalid_PPem;
+  FT_LOCAL_DEF( FT_Error )
+  tt_face_load_strike_metrics( TT_Face           face,
+                               FT_ULong          strike_index,
+                               FT_Size_Metrics*  metrics )
+  {
+    TT_SBit_Strike  strike;
 
-    for ( i = 0; i < face->num_sbit_strikes; i++ )
-    {
-      if ( ( (FT_UInt)face->sbit_strikes[i].y_ppem == y_ppem )     &&
-           ( ( x_ppem == 0 )                                     ||
-             ( (FT_UInt)face->sbit_strikes[i].x_ppem == x_ppem ) ) )
-      {
-        *astrike_index = i;
-        return SFNT_Err_Ok;
-      }
-    }
 
-    return SFNT_Err_Invalid_PPem;
+    if ( strike_index >= face->num_sbit_strikes )
+      return SFNT_Err_Invalid_Argument;
+
+    strike = face->sbit_strikes + strike_index;
+
+
+    metrics->ascender  = strike->hori.ascender << 6;
+    metrics->descender = strike->hori.descender << 6;
+
+    /* XXX: Is this correct? */
+    metrics->max_advance = ( strike->hori.min_origin_SB  +
+                             strike->hori.max_width      +
+                             strike->hori.min_advance_SB ) << 6;
+
+    /* XXX: Is this correct? */
+    metrics->height = metrics->ascender - metrics->descender;
+
+    return SFNT_Err_Ok;
   }
 
 
--- a/src/sfnt/ttsbit.h
+++ b/src/sfnt/ttsbit.h
@@ -36,10 +36,14 @@
 
 
   FT_LOCAL( FT_Error )
-  tt_face_set_sbit_strike( TT_Face    face,
-                           FT_UInt    x_ppem,
-                           FT_UInt    y_ppem,
-                           FT_ULong  *astrike_index );
+  tt_face_set_sbit_strike( TT_Face          face,
+                           FT_Size_Request  req,
+                           FT_ULong*        astrike_index );
+
+  FT_LOCAL( FT_Error )
+  tt_face_load_strike_metrics( TT_Face           face,
+                               FT_ULong          strike_index,
+                               FT_Size_Metrics*  metrics );
 
 #ifndef FT_OPTIMIZE_MEMORY
   FT_LOCAL( FT_Error )
--- a/src/sfnt/ttsbit0.c
+++ b/src/sfnt/ttsbit0.c
@@ -206,35 +206,40 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_face_set_sbit_strike( TT_Face    face,
-                           FT_UInt    x_ppem,
-                           FT_UInt    y_ppem,
-                           FT_ULong  *astrike_index )
+  tt_face_set_sbit_strike( TT_Face          face,
+                           FT_Size_Request  req,
+                           FT_ULong*        astrike_index )
   {
-    FT_UInt   nn, count;
-    FT_Byte*  p;
-    FT_Byte*  p_limit;
+    return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
+  }
 
 
-    if ( x_ppem > 255               ||
-         y_ppem < 1 || y_ppem > 255 )
-      return SFNT_Err_Invalid_PPem;
+  FT_LOCAL_DEF( FT_Error )
+  tt_face_load_strike_metrics( TT_Face           face,
+                               FT_ULong          strike_index,
+                               FT_Size_Metrics*  metrics )
+  {
+    FT_Byte*    strike;
+    
 
-    p       = face->sbit_table + 8;
-    p_limit = p + face->sbit_table_size;
-    count   = face->sbit_num_strikes;
+    if ( strike_index >= (FT_ULong)face->num_sbit_strikes )
+      return SFNT_Err_Invalid_Argument;
 
-    for ( nn = 0; nn < count; nn++ )
-    {
-      if ( x_ppem == (FT_UInt)p[44] && y_ppem == (FT_UInt)p[45] )
-      {
-        *astrike_index = (FT_ULong)nn;
-        return SFNT_Err_Ok;
-      }
-      p += 48;
-    }
+    strike = face->sbit_table + 8 + strike_index * 48;
 
-    return SFNT_Err_Invalid_PPem;
+    metrics->ascender  = (FT_Char)strike[16] << 6;  /* hori.ascender  */
+    metrics->descender = (FT_Char)strike[17] << 6;  /* hori.descender */
+
+    /* XXX: Is this correct? */
+    metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB  */
+                                      strike[18] + /* max_width      */
+                             (FT_Char)strike[23]   /* min_advance_SB */
+                                                 ) << 6;
+
+    /* XXX: Is this correct? */
+    metrics->height = metrics->ascender - metrics->descender;
+
+    return SFNT_Err_Ok;
   }
 
 
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -134,115 +134,70 @@
   /*************************************************************************/
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Set_Char_Sizes                                                     */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A driver method used to reset a size's character sizes (horizontal */
-  /*    and vertical) expressed in fractional points.                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    char_width      :: The character width expressed in 26.6           */
-  /*                       fractional points.                              */
-  /*                                                                       */
-  /*    char_height     :: The character height expressed in 26.6          */
-  /*                       fractional points.                              */
-  /*                                                                       */
-  /*    horz_resolution :: The horizontal resolution of the output device. */
-  /*                                                                       */
-  /*    vert_resolution :: The vertical resolution of the output device.   */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size            :: A handle to the target size object.             */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
   static FT_Error
-  Set_Char_Sizes( FT_Size     ttsize,       /* TT_Size */
-                  FT_F26Dot6  char_width,
-                  FT_F26Dot6  char_height,
-                  FT_UInt     horz_resolution,
-                  FT_UInt     vert_resolution )
+  tt_size_request( FT_Size          size,
+                   FT_Size_Request  req )
   {
-    TT_Size           size    = (TT_Size)ttsize;
-    FT_Size_Metrics*  metrics = &size->metrics;
-    TT_Face           face    = (TT_Face)size->root.face;
+    TT_Face   ttface = (TT_Face)size->face;
+    TT_Size   ttsize = (TT_Size)size;
+    FT_Error  error  = TT_Err_Ok;
 
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
-    /* copy the result from base layer */
-    *metrics = size->root.metrics;
-
-    /* This bit flag, when set, indicates that the pixel size must be */
-    /* rounded to integer.  Nearly all TrueType fonts have this bit   */
-    /* set, as hinting won't work really well otherwise.              */
-    /*                                                                */
-    if ( ( face->header.Flags & 8 ) != 0 )
+    if ( FT_HAS_FIXED_SIZES( size->face ) )
     {
-      FT_Long  dim_x, dim_y;
+      SFNT_Service      sfnt    = ttface->sfnt;
+      FT_Size_Metrics*  metrics = &size->metrics;
+      FT_ULong          index;
 
-
-      dim_x = ( char_width  * horz_resolution + 36 ) / 72;
-      dim_y = ( char_height * vert_resolution + 36 ) / 72;
-
-      dim_x = FT_PIX_ROUND( dim_x );
-      dim_y = FT_PIX_ROUND( dim_y );
-
-      metrics->x_ppem  = (FT_UShort)( dim_x >> 6 );
-      metrics->y_ppem  = (FT_UShort)( dim_y >> 6 );
-      metrics->x_scale = FT_DivFix( dim_x, face->root.units_per_EM );
-      metrics->y_scale = FT_DivFix( dim_y, face->root.units_per_EM );
+      if ( !( error = sfnt->set_sbit_strike( ttface,
+                                             req,
+                                             &index ) ) &&
+           !( error = sfnt->load_strike_metrics( ttface,
+                                                 index,
+                                                 metrics ) ) )
+        ttsize->strike_index = index;
+      else
+        ttsize->strike_index = 0xFFFFFFFFU;
     }
 
-    size->ttmetrics.valid = FALSE;
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-    size->strike_index    = 0xFFFFU;
 #endif
 
-    return tt_size_reset( size );
+    if ( FT_IS_SCALABLE( size->face ) )
+      error = tt_size_reset( ttsize );
+
+    return error;
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Set_Pixel_Sizes                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A driver method used to reset a size's character sizes (horizontal */
-  /*    and vertical) expressed in integer pixels.                         */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    size         :: A handle to the target size object.                */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+
   static FT_Error
-  Set_Pixel_Sizes( FT_Size  ttsize,         /* TT_Size */
-                   FT_UInt  pixel_width,
-                   FT_UInt  pixel_height )
+  tt_size_select( FT_Size   size,
+                  FT_ULong  index )
   {
-    TT_Size  size = (TT_Size)ttsize;
+    TT_Face           ttface  = (TT_Face)size->face;
+    TT_Size           ttsize  = (TT_Size)size;
+    FT_Size_Metrics*  metrics = &size->metrics;
+    SFNT_Service      sfnt    = ttface->sfnt;
+    FT_Error          error;
 
-    FT_UNUSED( pixel_width );
-    FT_UNUSED( pixel_height );
 
+    if ( FT_IS_SCALABLE( size->face ) )
+      tt_size_reset( ttsize );
 
-    /* many things have been pre-computed by the base layer */
+    error = sfnt->load_strike_metrics( ttface, index, metrics );
+    if ( error )
+      ttsize->strike_index = 0xFFFFFFFFU;
+    else
+      ttsize->strike_index = index;
 
-    size->metrics         = size->root.metrics;
-    size->ttmetrics.valid = FALSE;
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-    size->strike_index    = 0xFFFFU;
-#endif
-
-    return tt_size_reset( size );
+    return error;
   }
 
+#endif
 
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
@@ -401,8 +356,13 @@
     tt_slot_init,
     0,                      /* FT_Slot_DoneFunc */
 
-    Set_Char_Sizes,
-    Set_Pixel_Sizes,
+    tt_size_request,
+#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
+    tt_size_select,
+#else
+    0,                      /* FT_Size_SelectFunc      */
+#endif 
+
     Load_Glyph,
 
     tt_get_kerning,
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1825,7 +1825,7 @@
     stream = face->root.stream;
 
     error = sfnt->load_sbit_image( face,
-                                   (FT_ULong)size->strike_index,
+                                   size->strike_index,
                                    glyph_index,
                                    (FT_Int)load_flags,
                                    stream,
@@ -2007,7 +2007,7 @@
     /*                                                 */
     /* XXX: The convention should be emphasized in     */
     /*      the documents because it can be confusing. */
-    if ( size->strike_index != 0xFFFFU           &&
+    if ( size->strike_index != 0xFFFFFFFFU       &&
          ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
     {
       error = load_sbit_image( size, glyph, glyph_index, load_flags );
--- a/src/truetype/ttobjs.c
+++ b/src/truetype/ttobjs.c
@@ -585,7 +585,7 @@
 #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
 
     size->ttmetrics.valid = FALSE;
-    size->strike_index    = 0xFFFFU;
+    size->strike_index    = 0xFFFFFFFFU;
 
     return error;
   }
@@ -649,34 +649,57 @@
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
-  /*    Reset_Outline_Size                                                 */
+  /*    tt_size_reset                                                      */
   /*                                                                       */
   /* <Description>                                                         */
-  /*    Resets a TrueType outline size when resolutions and character      */
-  /*    dimensions have been changed.                                      */
+  /*    Resets a TrueType size when resolutions and character dimensions   */
+  /*    have been changed.                                                 */
   /*                                                                       */
   /* <Input>                                                               */
   /*    size :: A handle to the target size object.                        */
   /*                                                                       */
-  static FT_Error
-  Reset_Outline_Size( TT_Size  size )
+  FT_LOCAL_DEF( FT_Error )
+  tt_size_reset( TT_Size  size )
   {
     TT_Face           face;
     FT_Error          error = TT_Err_Ok;
-
     FT_Size_Metrics*  metrics;
 
 
-    if ( size->ttmetrics.valid )
-      return TT_Err_Ok;
+    size->ttmetrics.valid = FALSE;
 
     face = (TT_Face)size->root.face;
 
     metrics = &size->metrics;
 
+    /* copy the result from base layer */
+    *metrics = size->root.metrics;
+
     if ( metrics->x_ppem < 1 || metrics->y_ppem < 1 )
       return TT_Err_Invalid_PPem;
 
+    /* This bit flag, when set, indicates that the ppems must be      */
+    /* rounded to integer.  Nearly all TrueType fonts have this bit   */
+    /* set, as hinting won't work really well otherwise.              */
+    /*                                                                */
+    if ( face->header.Flags & 8 )
+    {
+      metrics->x_scale = FT_DivFix( metrics->x_ppem << 6,
+                                    face->root.units_per_EM );
+      metrics->y_scale = FT_DivFix( metrics->y_ppem << 6,
+                                    face->root.units_per_EM );
+
+      metrics->ascender =
+        FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
+      metrics->descender =
+        FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
+      metrics->height =
+        FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
+      metrics->max_advance =
+        FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
+                                 metrics->x_scale ) );
+    }
+
     /* compute new transformation */
     if ( metrics->x_ppem >= metrics->y_ppem )
     {
@@ -697,23 +720,7 @@
       size->ttmetrics.y_ratio = 0x10000L;
     }
 
-    /* Compute root ascender, descender, text height, and max_advance */
-    metrics->ascender =
-      FT_PIX_ROUND( FT_MulFix( face->root.ascender, metrics->y_scale ) );
-    metrics->descender =
-      FT_PIX_ROUND( FT_MulFix( face->root.descender, metrics->y_scale ) );
-    metrics->height =
-      FT_PIX_ROUND( FT_MulFix( face->root.height, metrics->y_scale ) );
-    metrics->max_advance =
-      FT_PIX_ROUND( FT_MulFix( face->root.max_advance_width,
-                               metrics->x_scale ) );
 
-
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-    /* set to `invalid' by default */
-    size->strike_index = 0xFFFFU;
-#endif
-
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 
     {
@@ -749,153 +756,6 @@
       size->ttmetrics.valid = TRUE;
 
     return error;
-  }
-
-
-#ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Reset_SBit_Size                                                    */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Resets a TrueType sbit size when resolutions and character         */
-  /*    dimensions have been changed.                                      */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    size :: A handle to the target size object.                        */
-  /*                                                                       */
-  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_Service      sfnt;
-
-
-    metrics = &size->metrics;
-
-    if ( size->strike_index != 0xFFFFU )
-      return TT_Err_Ok;
-
-    face = (TT_Face)size->root.face;
-    sfnt = (SFNT_Service)face->sfnt;
-
-    sbit_metrics = &size->strike_metrics;
-
-    error = sfnt->set_sbit_strike( face,
-                                   metrics->x_ppem, metrics->y_ppem,
-                                   &strike_index );
-
-    if ( !error )
-    {
-      /* XXX: TODO: move this code to the SFNT module where it belongs */
-
-#ifdef FT_OPTIMIZE_MEMORY
-      FT_Byte*    strike = face->sbit_table + 8 + strike_index*48;
-
-      sbit_metrics->ascender  = (FT_Char)strike[16] << 6;  /* hori.ascender  */
-      sbit_metrics->descender = (FT_Char)strike[17] << 6;  /* hori.descender */
-
-      /* XXX: Is this correct? */
-      sbit_metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB  */
-                                             strike[18] + /* max_width      */
-                                    (FT_Char)strike[23]   /* min_advance_SB */
-                                                        ) << 6;
-
-#else /* !FT_OPTIMIZE_MEMORY */
-
-      TT_SBit_Strike  strike = face->sbit_strikes + strike_index;
-
-
-      sbit_metrics->ascender  = strike->hori.ascender << 6;
-      sbit_metrics->descender = strike->hori.descender << 6;
-
-      /* XXX: Is this correct? */
-      sbit_metrics->max_advance = ( strike->hori.min_origin_SB  +
-                                    strike->hori.max_width      +
-                                    strike->hori.min_advance_SB ) << 6;
-
-#endif /* !FT_OPTIMIZE_MEMORY */
-
-      /* XXX: Is this correct? */
-      sbit_metrics->height = sbit_metrics->ascender -
-                             sbit_metrics->descender;
-
-      sbit_metrics->x_ppem = metrics->x_ppem;
-      sbit_metrics->y_ppem = metrics->y_ppem;
-      size->strike_index   = (FT_UInt)strike_index;
-    }
-    else
-    {
-      size->strike_index = 0xFFFFU;
-
-      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_size_reset                                                      */
-  /*                                                                       */
-  /* <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_size_reset( 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 )
-    {
-      if ( size->strike_index == 0xFFFFU )
-        error = Reset_SBit_Size( size );
-
-      if ( !error && !( face->face_flags & FT_FACE_FLAG_SCALABLE ) )
-        size->root.metrics = size->strike_metrics;
-    }
-
-#endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
-
-    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
@@ -322,12 +322,7 @@
 
     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
+    FT_ULong           strike_index;    /* 0xFFFFFFFFU to indicate invalid */
 
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 
--- a/src/type1/t1driver.c
+++ b/src/type1/t1driver.c
@@ -295,8 +295,8 @@
     (FT_Slot_InitFunc)        T1_GlyphSlot_Init,
     (FT_Slot_DoneFunc)        T1_GlyphSlot_Done,
 
-    (FT_Size_ResetPointsFunc) T1_Size_Reset,
-    (FT_Size_ResetPixelsFunc) T1_Size_Reset,
+    (FT_Size_RequestFunc)     T1_Size_Request,
+    (FT_Size_SelectFunc)      0,
     (FT_Slot_LoadFunc)        T1_Load_Glyph,
 
 #ifdef T1_CONFIG_OPTION_NO_AFM
--- a/src/type1/t1objs.c
+++ b/src/type1/t1objs.c
@@ -111,18 +111,18 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Size_Reset( T1_Size  size )
+  T1_Size_Request( T1_Size  size )
   {
     PSH_Globals_Funcs  funcs = T1_Size_Get_Globals_Funcs( size );
-    FT_Error           error = 0;
 
 
     if ( funcs )
-      error = funcs->set_scale( (PSH_Globals)size->root.internal,
-                                size->root.metrics.x_scale,
-                                size->root.metrics.y_scale,
-                                0, 0 );
-    return error;
+      funcs->set_scale( (PSH_Globals)size->root.internal,
+                        size->root.metrics.x_scale,
+                        size->root.metrics.y_scale,
+                        0, 0 );
+
+    return T1_Err_Ok;
   }
 
 
--- a/src/type1/t1objs.h
+++ b/src/type1/t1objs.h
@@ -109,7 +109,7 @@
   T1_Size_Done( T1_Size  size );
 
   FT_LOCAL( FT_Error )
-  T1_Size_Reset( T1_Size  size );
+  T1_Size_Request( T1_Size  size );
 
   FT_LOCAL( FT_Error )
   T1_Size_Init( T1_Size  size );
--- a/src/type42/t42drivr.c
+++ b/src/type42/t42drivr.c
@@ -229,8 +229,8 @@
     (FT_Slot_InitFunc)        T42_GlyphSlot_Init,
     (FT_Slot_DoneFunc)        T42_GlyphSlot_Done,
 
-    (FT_Size_ResetPointsFunc) T42_Size_SetChars,
-    (FT_Size_ResetPixelsFunc) T42_Size_SetPixels,
+    (FT_Size_RequestFunc)     T42_Size_Request,
+    (FT_Size_SelectFunc)      T42_Size_Select,
     (FT_Slot_LoadFunc)        T42_GlyphSlot_Load,
 
     (FT_Face_GetKerningFunc)  0,
--- a/src/type42/t42objs.c
+++ b/src/type42/t42objs.c
@@ -489,6 +489,32 @@
   }
 
 
+  FT_LOCAL_DEF( FT_Error )
+  T42_Size_Request( T42_Size         size,
+                    FT_Size_Request  req )
+  {
+    T42_Face         face = (T42_Face)size->root.face;
+
+
+    FT_Activate_Size( size->ttsize );
+
+    return FT_Request_Size( face->ttf_face, req );
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
+  T42_Size_Select( T42_Size  size,
+                   FT_ULong  index )
+  {
+    T42_Face         face = (T42_Face)size->root.face;
+
+
+    FT_Activate_Size( size->ttsize );
+
+    return FT_Select_Size( face->ttf_face, index );
+  }
+
+
   FT_LOCAL_DEF( void )
   T42_Size_Done( T42_Size  size )
   {
@@ -534,45 +560,6 @@
   T42_GlyphSlot_Done( T42_GlyphSlot slot )
   {
     FT_Done_GlyphSlot( slot->ttslot );
-  }
-
-
-
-  FT_LOCAL_DEF( FT_Error )
-  T42_Size_SetChars( T42_Size    size,
-                     FT_F26Dot6  char_width,
-                     FT_F26Dot6  char_height,
-                     FT_UInt     horz_resolution,
-                     FT_UInt     vert_resolution )
-  {
-    FT_Face   face    = size->root.face;
-    T42_Face  t42face = (T42_Face)face;
-
-
-    FT_Activate_Size( size->ttsize );
-
-    return FT_Set_Char_Size( t42face->ttf_face,
-                             char_width,
-                             char_height,
-                             horz_resolution,
-                             vert_resolution );
-  }
-
-
-  FT_LOCAL_DEF( FT_Error )
-  T42_Size_SetPixels( T42_Size  size,
-                      FT_UInt   pixel_width,
-                      FT_UInt   pixel_height )
-  {
-    FT_Face   face    = size->root.face;
-    T42_Face  t42face = (T42_Face)face;
-
-
-    FT_Activate_Size( size->ttsize );
-
-    return FT_Set_Pixel_Sizes( t42face->ttf_face,
-                               pixel_width,
-                               pixel_height );
   }
 
 
--- a/src/type42/t42objs.h
+++ b/src/type42/t42objs.h
@@ -80,16 +80,14 @@
 
 
   FT_LOCAL( FT_Error )
-  T42_Size_SetChars( T42_Size    size,
-                     FT_F26Dot6  char_width,
-                     FT_F26Dot6  char_height,
-                     FT_UInt     horz_resolution,
-                     FT_UInt     vert_resolution );
+  T42_Size_Request( T42_Size         size,
+                    FT_Size_Request  req );
 
+
   FT_LOCAL( FT_Error )
-  T42_Size_SetPixels( T42_Size  size,
-                      FT_UInt   pixel_width,
-                      FT_UInt   pixel_height );
+  T42_Size_Select( T42_Size  size,
+                   FT_ULong  index );
+
 
   FT_LOCAL( void )
   T42_Size_Done( T42_Size  size );
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -460,6 +460,7 @@
 
       {
         FT_Bitmap_Size*  bsize = root->available_sizes;
+        FT_UShort        x_res, y_res;
 
 
         bsize->width  = font->header.avg_width;
@@ -466,8 +467,34 @@
         bsize->height = (FT_Short)(
           font->header.pixel_height + font->header.external_leading );
         bsize->size   = font->header.nominal_point_size << 6;
-        bsize->x_ppem = font->header.pixel_width << 6;
-        bsize->y_ppem = font->header.pixel_height << 6;
+
+        x_res = font->header.horizontal_resolution;
+        if ( !x_res )
+          x_res = 72;
+
+        y_res = font->header.vertical_resolution;
+        if ( !y_res )
+          y_res = 72;
+
+        bsize->y_ppem = FT_MulDiv( bsize->size, y_res, 72 );
+        bsize->y_ppem = FT_PIX_ROUND( bsize->y_ppem );
+
+        /* 
+         * this reads:
+         *
+         * the nominal height is larger than the bbox's height
+         *
+         * => nominal_point_size contains incorrect value;
+         *    use pixel_height as the nominal height
+         */
+        if ( bsize->y_ppem > font->header.pixel_height << 6 )
+        {
+          bsize->y_ppem = font->header.pixel_height << 6;
+          bsize->size   = FT_MulDiv( bsize->y_ppem, 72, y_res );
+        }
+
+        bsize->x_ppem = FT_MulDiv( bsize->size, x_res, 72 );
+        bsize->x_ppem = FT_PIX_ROUND( bsize->x_ppem );
       }
 
       {
@@ -543,27 +570,38 @@
 
 
   static FT_Error
-  FNT_Size_Set_Pixels( FT_Size  size )
+  FNT_Size_Select( FT_Size  size )
   {
-    FNT_Face  face = (FNT_Face)FT_SIZE_FACE( size );
-    FT_Face   root = FT_FACE( face );
+    FNT_Face          face    = (FNT_Face)size->face;
+    FT_WinFNT_Header  header  = &face->font->header;
 
 
-    if ( size->metrics.y_ppem == root->available_sizes->y_ppem >> 6 )
-    {
-      FNT_Font  font = face->font;
+    size->metrics.ascender    = header->ascent * 64;
+    size->metrics.descender   = -( header->pixel_height -
+                                   header->ascent ) * 64;
+    size->metrics.max_advance = header->max_width * 64;
 
+    return FNT_Err_Ok;
+  }
 
-      size->metrics.ascender    = font->header.ascent * 64;
-      size->metrics.descender   = -( font->header.pixel_height -
-                                       font->header.ascent ) * 64;
-      size->metrics.height      = font->header.pixel_height * 64;
-      size->metrics.max_advance = font->header.max_width * 64;
 
-      return FNT_Err_Ok;
-    }
+  static FT_Error
+  FNT_Size_Request( FT_Size          size,
+                    FT_Size_Request  req )
+  {
+    FT_Face   face = size->face;
+    FT_Error  error;
+    
+    error = FT_Match_Size( face, req, 1, NULL );
+
+    if ( error )
+      return error;
     else
-      return FNT_Err_Invalid_Pixel_Size;
+    {
+      size->metrics.height = face->available_sizes->height << 6;
+
+      return FNT_Size_Select( size );
+    }
   }
 
 
@@ -741,8 +779,8 @@
     (FT_Slot_InitFunc)        0,
     (FT_Slot_DoneFunc)        0,
 
-    (FT_Size_ResetPointsFunc) FNT_Size_Set_Pixels,
-    (FT_Size_ResetPixelsFunc) FNT_Size_Set_Pixels,
+    (FT_Size_RequestFunc)     FNT_Size_Request,
+    (FT_Size_SelectFunc)      FNT_Size_Select,
     (FT_Slot_LoadFunc)        FNT_Load_Glyph,
 
     (FT_Face_GetKerningFunc)  0,