* include/freetype/internal/internal.h, include/freetype/ftpfr.h,
        src/base/ftpfr.c, src/base/Jamfile, src/descrip.mms, src/rules.mk,
        src/pfr/pfrdrivr.c, src/pfr/pfrobjs.c, src/pfr/pfsobjs.h:

        added PFR-specific public API. Fixed the kerning retrievel routine
        (it returned invalid values when the outline and metrics resolution
        differ)

        * src/base/ftsynth.c: fixed the synthetic emboldener. at last.

        * src/base/ftobjs.c: small internal fix to better support
        bitmap-based font formats
diff --git a/include/freetype/config/ftmodule.h b/include/freetype/config/ftmodule.h
index 6e36a25..d0e6f16 100644
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -16,3 +16,4 @@
 FT_USE_MODULE(t42_driver_class)
 FT_USE_MODULE(pfr_driver_class)
 FT_USE_MODULE(winfnt_driver_class)
+
diff --git a/include/freetype/ftpfr.h b/include/freetype/ftpfr.h
new file mode 100644
index 0000000..2125391
--- /dev/null
+++ b/include/freetype/ftpfr.h
@@ -0,0 +1,156 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftpfr.h                                                                */
+/*                                                                         */
+/*    FreeType API for accessing PFR-specific data                         */
+/*                                                                         */
+/*  Copyright 2002 by                                                      */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+#ifndef __FTPFR_H__
+#define __FTPFR_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+
+FT_BEGIN_HEADER
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Section>                                                             */
+  /*    pfr_fonts                                                          */
+  /*                                                                       */
+  /* <Title>                                                               */
+  /*    PFR Fonts                                                          */
+  /*                                                                       */
+  /* <Abstract>                                                            */
+  /*    PFR/TrueDoc specific APIs                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This section contains the declaration of PFR-specific functions.   */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+ /**********************************************************************
+  *
+  * @function:
+  *    FT_Get_PFR_Metrics
+  *
+  * @description:
+  *    returns the outline and metrics resolutions of a given PFR
+  *    face.
+  *
+  * @input:
+  *    face :: handle to input face. It can be a non-PFR face.
+  *
+  * @output:
+  *    aoutline_resolution ::
+  *      outline resolution. This is equivalent to "face->units_per_EM".
+  *      optional (parameter can be NULL)
+  *
+  *    ametrics_resolution ::
+  *      metrics_resolution. This is equivalent to "outline_resolution"
+  *      for non-PFR fonts. can be NULL
+  *      optional (parameter can be NULL)
+  *
+  *    ametrics_x_scale ::
+  *      a 16.16 fixed-point number used to scale distance expressed
+  *      in metrics units to device sub-pixels. This is equivalent to
+  *      'face->size->x_scale', but for metrics only.
+  *      optional (parameter can be NULL)
+  *
+  *    ametrics_y_scale ::
+  *      same as 'ametrics_x_scale', but for the vertical direction.
+  *      optional (parameter can be NULL)
+  *
+  * @note:
+  *   if the input face is not a PFR, this function will return an error.
+  *   However, in all cases, it will return valid values.
+  */
+  FT_EXPORT( FT_Error )
+  FT_Get_PFR_Metrics( FT_Face     face,
+                      FT_UInt    *aoutline_resolution,
+                      FT_UInt    *ametrics_resolution,
+                      FT_Fixed   *ametrics_x_scale,
+                      FT_Fixed   *ametrics_y_scale );
+
+ /**********************************************************************
+  *
+  * @function:
+  *    FT_Get_PFR_Kerning
+  *
+  * @description:
+  *    returns the kerning pair corresponding to two glyphs in
+  *    a PFR face. The distance is expressed in metrics units, unlike
+  *    the result of @FT_Get_Kerning.
+  *
+  * @input:
+  *    face :: handle to input face.
+  *    left  :: left glyph index
+  *    right :: right glyph index
+  *
+  * @output:
+  *    avector :: kerning vector
+  *
+  * @note:
+  *    this function always return distances in original PFR metrics
+  *    units. This is unlike @FT_Get_Kerning with the @FT_KERNING_UNSCALED
+  *    mode, which always return distances converted to outline units.
+  *
+  *    you can use the value of the 'x_scale' and 'y_scale' parameters
+  *    returned by @FT_Get_PFR_Metrics to scale these to device sub-pixels
+  */
+  FT_EXPORT( FT_Error )
+  FT_Get_PFR_Kerning( FT_Face     face,
+                      FT_UInt     left,
+                      FT_UInt     right,
+                      FT_Vector  *avector );
+
+ /**********************************************************************
+  *
+  * @function:
+  *    FT_Get_PFR_Advance
+  *
+  * @description:
+  *    returns a given glyph advance, expressed in original metrics units,
+  *    from a PFR font.
+  *
+  * @input:
+  *    face   :: handle to input face.
+  *    gindex :: glyph index
+  *
+  * @output:
+  *    aadvance :: glyph advance in metrics units
+  *
+  * @return:
+  *    error code. 0 means success
+  *
+  * @note:
+  *    you can use the 'x_scale' or 'y_scale' results of @FT_Get_PFR_Metrics
+  *    to convert the advance to device sub-pixels (i.e. 1/64th of pixels)
+  */
+  FT_EXPORT( FT_Error )
+  FT_Get_PFR_Advance( FT_Face    face,
+                      FT_UInt    gindex,
+                      FT_Pos    *aadvance );
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __FTBDF_H__ */
+
+
+/* END */
diff --git a/include/freetype/internal/internal.h b/include/freetype/internal/internal.h
index 069593e..0458fec 100644
--- a/include/freetype/internal/internal.h
+++ b/include/freetype/internal/internal.h
@@ -45,6 +45,7 @@
 #define FT_INTERNAL_FNT_TYPES_H           <freetype/internal/fnttypes.h>
 #define FT_INTERNAL_BDF_TYPES_H           <freetype/internal/bdftypes.h>
 #define FT_INTERNAL_PCF_TYPES_H           <freetype/internal/pcftypes.h>
+#define FT_INTERNAL_PFR_H                 <freetype/internal/pfr.h>
 
 #define FT_INTERNAL_POSTSCRIPT_NAMES_H    <freetype/internal/psnames.h>
 #define FT_INTERNAL_POSTSCRIPT_AUX_H      <freetype/internal/psaux.h>
diff --git a/include/freetype/internal/pfr.h b/include/freetype/internal/pfr.h
new file mode 100644
index 0000000..cead078
--- /dev/null
+++ b/include/freetype/internal/pfr.h
@@ -0,0 +1,36 @@
+#ifndef __FT_INTERNAL_PFR_H__
+#define __FT_INTERNAL_PFR_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+FT_BEGIN_HEADER
+
+  typedef FT_Error  (*FT_PFR_GetMetricsFunc)( FT_Face    face,
+                                              FT_UInt   *aoutline,
+                                              FT_UInt   *ametrics,
+                                              FT_Fixed  *ax_scale,
+                                              FT_Fixed  *ay_scale );
+
+  typedef FT_Error  (*FT_PFR_GetKerningFunc)( FT_Face     face,
+                                              FT_UInt     left,
+                                              FT_UInt     right,
+                                              FT_Vector  *avector );
+
+  typedef FT_Error  (*FT_PFR_GetAdvanceFunc)( FT_Face   face,
+                                              FT_UInt   gindex,
+                                              FT_Pos   *aadvance );
+
+  typedef struct FT_PFR_ServiceRec_
+  {
+    FT_PFR_GetMetricsFunc    get_metrics;
+    FT_PFR_GetKerningFunc    get_kerning;
+    FT_PFR_GetAdvanceFunc    get_advance;
+
+  } FT_PFR_ServiceRec, *FT_PFR_Service;
+
+#define  FT_PFR_SERVICE_NAME  "pfr"
+
+FT_END_HEADER
+
+#endif /* __FT_INTERNAL_PFR_H__ */
diff --git a/src/base/Jamfile b/src/base/Jamfile
index b061897..956fb09 100644
--- a/src/base/Jamfile
+++ b/src/base/Jamfile
@@ -24,8 +24,7 @@
 # Add the optional/replaceable files.
 #
 Library  $(FT2_LIB) : ftsystem.c ftinit.c   ftglyph.c  ftmm.c     ftbdf.c
-                      ftbbox.c   ftdebug.c  ftxf86.c   fttype1.c  ftstroker.c
-                      ftsynth.c  ftobject.c fthash.c ;
+                      ftbbox.c   ftdebug.c  ftxf86.c   fttype1.c  ftpfr.c ;
 
 # Add Macintosh-specific file to the library when necessary.
 #
diff --git a/src/base/descrip.mms b/src/base/descrip.mms
index 8639e04..ac304d0 100644
--- a/src/base/descrip.mms
+++ b/src/base/descrip.mms
@@ -15,7 +15,7 @@
 
 CFLAGS=$(COMP_FLAGS)$(DEBUG)/include=([--.builds.vms],[--.include],[--.src.base])
 
-OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj
+OBJS=ftbase.obj,ftinit.obj,ftglyph.obj,ftdebug.obj,ftbdf.obj,ftmm.obj,fttype1.obj,ftxf86.obj,ftpfr.obj
 
 all : $(OBJS)
         library [--.lib]freetype.olb $(OBJS)
diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c
index 05e74f5..4f53ca1 100644
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -211,9 +211,14 @@
     }
 
     /* clear all public fields in the glyph slot */
-    FT_MEM_ZERO( &slot->metrics, sizeof ( slot->metrics ) );
-    FT_MEM_ZERO( &slot->outline, sizeof ( slot->outline ) );
-    FT_MEM_ZERO( &slot->bitmap,  sizeof ( slot->bitmap )  );
+    FT_ZERO( &slot->metrics );
+    FT_ZERO( &slot->outline );
+
+    slot->bitmap.width = 0;
+    slot->bitmap.rows  = 0;
+    slot->bitmap.pitch = 0;
+    slot->bitmap.pixel_mode = 0;
+    /* don't touch 'slot->bitmap.buffer' !! */
 
     slot->bitmap_left   = 0;
     slot->bitmap_top    = 0;
diff --git a/src/base/ftpfr.c b/src/base/ftpfr.c
new file mode 100644
index 0000000..bf2c2a2
--- /dev/null
+++ b/src/base/ftpfr.c
@@ -0,0 +1,105 @@
+/***************************************************************************/
+/*                                                                         */
+/*  ftpfr.c                                                                */
+/*                                                                         */
+/*    FreeType API for accessing PFR-specific data                         */
+/*                                                                         */
+/*  Copyright 2002 by                                                      */
+/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*                                                                         */
+/*  This file is part of the FreeType project, and may only be used,       */
+/*  modified, and distributed under the terms of the FreeType project      */
+/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
+/*  this file you indicate that you have read the license and              */
+/*  understand and accept it fully.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+#include <ft2build.h>
+#include FT_INTERNAL_PFR_H
+#include FT_INTERNAL_OBJECTS_H
+
+
+ /* check the format */
+  static FT_Error
+  ft_pfr_check( FT_Face           face,
+                FT_PFR_Service   *aservice )
+  {
+    FT_Error  error = FT_Err_Bad_Argument;
+
+    if ( face && face->driver )
+    {
+      FT_Module    module = (FT_Module) face->driver;
+      const char*  name   = module->clazz->module_name;
+
+      if ( name[0] == 'p' &&
+           name[1] == 'f' &&
+           name[2] == 'r' &&
+           name[4] == 0   )
+      {
+        *aservice = (FT_PFR_Service) module->clazz->module_interface;
+        error = 0;
+      }
+    }
+    return error;
+  }
+
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_PFR_Metrics( FT_Face     face,
+                      FT_UInt    *aoutline_resolution,
+                      FT_UInt    *ametrics_resolution,
+                      FT_Fixed   *ametrics_x_scale,
+                      FT_Fixed   *ametrics_y_scale )
+  {
+    FT_Error        error;
+    FT_PFR_Service  service;
+
+    error = ft_pfr_check( face, &service );
+    if ( !error )
+    {
+      error = service->get_metrics( face,
+                                    aoutline_resolution,
+                                    ametrics_resolution,
+                                    ametrics_x_scale,
+                                    ametrics_y_scale );
+    }
+    return error;
+  }
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_PFR_Kerning( FT_Face     face,
+                      FT_UInt     left,
+                      FT_UInt     right,
+                      FT_Vector  *avector )
+  {
+    FT_Error        error;
+    FT_PFR_Service  service;
+
+    error = ft_pfr_check( face, &service );
+    if ( !error )
+    {
+      error = service->get_kerning( face, left, right, avector );
+    }
+    return error;
+  }
+
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_PFR_Advance( FT_Face    face,
+                      FT_UInt    gindex,
+                      FT_Pos    *aadvance )
+  {
+    FT_Error        error;
+    FT_PFR_Service  service;
+
+    error = ft_pfr_check( face, &service );
+    if ( !error )
+    {
+      error = service->get_advance( face, gindex, aadvance );
+    }
+    return error;
+  }
+
+/* END */
diff --git a/src/base/ftsynth.c b/src/base/ftsynth.c
index 35b52e3..45459f3 100644
--- a/src/base/ftsynth.c
+++ b/src/base/ftsynth.c
@@ -257,12 +257,17 @@
         angle_diff = FT_Angle_Diff( angle_in, angle_out );
         scale      = FT_Cos( angle_diff/2 );
 
-        if ( scale < 0x4000L )
-          scale = 0x4000L;
+        if ( scale < 0x400L && scale > -0x400L )
+        {
+          if ( scale >= 0 )
+            scale = 0x400L;
+          else
+            scale = -0x400L;
+        }
 
         d = FT_DivFix( distance, scale );
 
-        FT_Vector_From_Polar( &in, d, (angle_in+angle_out)/2 + rotate );
+        FT_Vector_From_Polar( &in, d, angle_in + angle_diff/2 - rotate );
 
         outline->points[n].x = v_cur.x + distance + in.x;
         outline->points[n].y = v_cur.y + distance + in.y;
diff --git a/src/base/rules.mk b/src/base/rules.mk
index 5f7816d..0a38fae 100644
--- a/src/base/rules.mk
+++ b/src/base/rules.mk
@@ -54,6 +54,7 @@
                 $(BASE_)ftbdf.c   \
                 $(BASE_)fttype1.c \
                 $(BASE_)ftxf86.c  \
+                $(BASE_)ftpfr.c   \
                 $(BASE_)ftbbox.c
 
 # Default extensions objects
diff --git a/src/pfr/pfrdrivr.c b/src/pfr/pfrdrivr.c
index a4fcc42..c0697f5 100644
--- a/src/pfr/pfrdrivr.c
+++ b/src/pfr/pfrdrivr.c
@@ -19,10 +19,110 @@
 #include <ft2build.h>
 #include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_PFR_H
 #include "pfrdrivr.h"
 #include "pfrobjs.h"
 
 
+  static FT_Error
+  pfr_get_kerning( PFR_Face    face,
+                   FT_UInt     left,
+                   FT_UInt     right,
+                   FT_Vector  *avector )
+  {
+    FT_Error  error;
+
+    error = pfr_face_get_kerning( face, left, right, avector );
+    if ( !error )
+    {
+      PFR_PhyFont  phys = &face->phy_font;
+
+      /* convert from metrics to outline units when necessary */
+      if ( phys->outline_resolution != phys->metrics_resolution )
+      {
+        if ( avector->x != 0 )
+          avector->x = FT_MulDiv( avector->x, phys->outline_resolution,
+                                              phys->metrics_resolution );
+
+        if ( avector->y != 0 )
+          avector->y = FT_MulDiv( avector->x, phys->outline_resolution,
+                                              phys->metrics_resolution );
+      }
+    }
+    return error;
+  }
+
+
+  static FT_Error
+  pfr_get_advance( PFR_Face   face,
+                   FT_UInt    gindex,
+                   FT_Pos    *aadvance )
+  {
+    FT_Error     error = FT_Err_Bad_Argument;
+
+    *aadvance = 0;
+    if ( face )
+    {
+      PFR_PhyFont  phys  = &face->phy_font;
+
+      if ( gindex < phys->num_chars )
+      {
+        *aadvance = phys->chars[ gindex ].advance;
+        error = 0;
+      }
+    }
+
+    return error;
+  }
+
+
+  static FT_Error
+  pfr_get_metrics( PFR_Face   face,
+                   FT_UInt   *aoutline_resolution,
+                   FT_UInt   *ametrics_resolution,
+                   FT_Fixed  *ametrics_x_scale,
+                   FT_Fixed  *ametrics_y_scale )
+  {
+    FT_Error     error = 0;
+    PFR_PhyFont  phys  = &face->phy_font;
+    FT_Fixed     x_scale, y_scale;
+    FT_Size      size = face->root.size;
+
+    if ( aoutline_resolution )
+      *aoutline_resolution = phys->outline_resolution;
+
+    if ( ametrics_resolution )
+      *ametrics_resolution = phys->metrics_resolution;
+
+    x_scale = 0x10000L;
+    y_scale = 0x10000L;
+
+    if ( size )
+    {
+      x_scale = FT_DivFix( size->metrics.x_ppem << 6,
+                           phys->metrics_resolution );
+
+      y_scale = FT_DivFix( size->metrics.y_ppem << 6,
+                           phys->metrics_resolution );
+    }
+
+    if ( ametrics_x_scale )
+      *ametrics_x_scale = x_scale;
+
+    if ( ametrics_y_scale )
+      *ametrics_y_scale = y_scale;
+  }
+
+
+  FT_CALLBACK_TABLE_DEF
+  const FT_PFR_ServiceRec  pfr_service_rec =
+  {
+    (FT_PFR_GetMetricsFunc)  pfr_get_metrics,
+    (FT_PFR_GetKerningFunc)  pfr_get_kerning,
+    (FT_PFR_GetAdvanceFunc)  pfr_get_advance
+  };
+
+
   FT_CALLBACK_TABLE_DEF
   const FT_Driver_ClassRec  pfr_driver_class =
   {
@@ -36,7 +136,7 @@
       0x10000L,
       0x20000L,
 
-      0,   /* format interface */
+      (FT_PFR_Service)  &pfr_service_rec,   /* format interface */
 
       (FT_Module_Constructor)NULL,
       (FT_Module_Destructor) NULL,
@@ -58,7 +158,7 @@
     (FT_Size_ResetPixelsFunc) NULL,
     (FT_Slot_LoadFunc)        pfr_slot_load,
 
-    (FT_Face_GetKerningFunc)  pfr_face_get_kerning,
+    (FT_Face_GetKerningFunc)  pfr_get_kerning,
     (FT_Face_AttachFunc)      0,
     (FT_Face_GetAdvancesFunc) 0
   };
diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c
index c0438fc..8ede63a 100644
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -351,58 +351,6 @@
   /*************************************************************************/
   /*************************************************************************/
 
-  /* XXX: This relies on the font being spec-conformant, i.e., that the
-          kerning pairs are sorted.  We might want to sort it just to make
-          sure */
-
-#if 0
-
-  /* find the kerning for a given glyph pair */
-  FT_LOCAL_DEF( FT_Error )
-  pfr_face_get_kerning( PFR_Face    face,
-                        FT_UInt     glyph1,
-                        FT_UInt     glyph2,
-                        FT_Vector*  kerning )
-  {
-    PFR_PhyFont   phy_font = &face->phy_font;
-    PFR_KernPair  min, mid, max;
-    FT_ULong      idx = PFR_KERN_INDEX( glyph1, glyph2 );
-
-
-    /* simple binary search */
-    min = phy_font->kern_pairs;
-    max = min + phy_font->num_kern_pairs;
-
-    while ( min < max )
-    {
-      FT_ULong  midi;
-
-
-      mid  = min + ( max - min ) / 2;
-      midi = PFR_KERN_INDEX( mid->glyph1, mid->glyph2 );
-
-      if ( midi == idx )
-      {
-        *kerning = mid->kerning;
-        goto Exit;
-      }
-
-      if ( midi < idx )
-        min = mid + 1;
-      else
-        max = mid;
-    }
-
-    kerning->x = 0;
-    kerning->y = 0;
-
-  Exit:
-    return 0;
-  }
-
-#else /* 0 */
-
-  /* find the kerning for a given glyph pair */
   FT_LOCAL_DEF( FT_Error )
   pfr_face_get_kerning( PFR_Face    face,
                         FT_UInt     glyph1,
@@ -485,6 +433,5 @@
   Exit:
     return 0;
   }
-#endif
 
 /* END */
diff --git a/src/pfr/pfrobjs.h b/src/pfr/pfrobjs.h
index 7664b36..b29b64c 100644
--- a/src/pfr/pfrobjs.h
+++ b/src/pfr/pfrobjs.h
@@ -25,9 +25,9 @@
 FT_BEGIN_HEADER
 
   typedef struct PFR_FaceRec_*  PFR_Face;
-  
+
   typedef struct PFR_SizeRec_*  PFR_Size;
-  
+
   typedef struct PFR_SlotRec_*  PFR_Slot;
 
 
@@ -44,7 +44,7 @@
   typedef struct  PFR_SizeRec_
   {
     FT_SizeRec  root;
-  
+
   } PFR_SizeRec;
 
 
@@ -52,7 +52,7 @@
   {
     FT_GlyphSlotRec  root;
     PFR_GlyphRec     glyph;
-    
+
   } PFR_SlotRec;