Add FT_Get_PS_Font_Value() API.

This allows a Type 1 font face to be interrogated to retrieve most
of the dictionary keys (keys not relevant to FreeType's Type 1
interpreter are not available).

* include/freetype/internal/services/svpsinfo.h
(PS_GetFontValueFunc): New typedef.
(PSInfo): Add `ps_get_font_value'.
(FT_DEFINE_SERVICE_PSINFOREC): Updated.

* include/freetype/internal/t1types.h (T1_EncodingType): Moved to...
* include/freetype/t1tables.h: Here.
(PS_Dict_Keys): New enumeration.
(FT_Get_PS_Font_Value): New declaration.

* src/base/fttype1.c (FT_Get_PS_Font_Value): New function.

* src/type1/t1driver.c (t1_ps_get_font_value): This new function
does the real job.
(t1_service_ps_info): Add it.

* src/cff/cffdrivr.c (cff_service_ps_info), src/cid/cidriver.c
(cid_service_ps_info), src/type42/t42drivr.c (t42_service_ps_info):
Updated.
diff --git a/ChangeLog b/ChangeLog
index f40b548..a059aa5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2011-11-13  Chris Liddell  <chris.liddell@artifex.com>
+
+	Add FT_Get_PS_Font_Value() API.
+
+	This allows a Type 1 font face to be interrogated to retrieve most
+	of the dictionary keys (keys not relevant to FreeType's Type 1
+	interpreter are not available).
+
+	* include/freetype/internal/services/svpsinfo.h
+	(PS_GetFontValueFunc): New typedef.
+	(PSInfo): Add `ps_get_font_value'.
+	(FT_DEFINE_SERVICE_PSINFOREC): Updated.
+
+	* include/freetype/internal/t1types.h (T1_EncodingType): Moved to...
+	* include/freetype/t1tables.h: Here.
+	(PS_Dict_Keys): New enumeration.
+	(FT_Get_PS_Font_Value): New declaration.
+
+	* src/base/fttype1.c (FT_Get_PS_Font_Value): New function.
+
+	* src/type1/t1driver.c (t1_ps_get_font_value): This new function
+	does the real job.
+	(t1_service_ps_info): Add it.
+
+	* src/cff/cffdrivr.c (cff_service_ps_info), src/cid/cidriver.c
+	(cid_service_ps_info), src/type42/t42drivr.c (t42_service_ps_info):
+	Updated.
+
 2011-11-08  Braden Thomas  <bthomas@apple.com>
 
 	[cid] Various loading fixes.
diff --git a/include/freetype/internal/services/svpsinfo.h b/include/freetype/internal/services/svpsinfo.h
index 91ba91e..84d6a78 100644
--- a/include/freetype/internal/services/svpsinfo.h
+++ b/include/freetype/internal/services/svpsinfo.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType PostScript info service (specification).                */
 /*                                                                         */
-/*  Copyright 2003, 2004, 2009 by                                          */
+/*  Copyright 2003, 2004, 2009, 2011 by                                    */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -44,6 +44,13 @@
   (*PS_GetFontPrivateFunc)( FT_Face         face,
                             PS_PrivateRec*  afont_private );
 
+  typedef FT_Long
+  (*PS_GetFontValueFunc)( FT_Face       face,
+                          PS_Dict_Keys  key,
+                          FT_UInt       idx,
+                          void         *value,
+                          FT_Long       value_len );
+
 
   FT_DEFINE_SERVICE( PsInfo )
   {
@@ -51,22 +58,25 @@
     PS_GetFontExtraFunc    ps_get_font_extra;
     PS_HasGlyphNamesFunc   ps_has_glyph_names;
     PS_GetFontPrivateFunc  ps_get_font_private;
+    PS_GetFontValueFunc    ps_get_font_value;
   };
 
 #ifndef FT_CONFIG_OPTION_PIC
 
 #define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_,      \
-        ps_get_font_extra_, has_glyph_names_, get_font_private_) \
+        ps_get_font_extra_, has_glyph_names_, get_font_private_, \
+        get_font_value_)                                         \
   static const FT_Service_PsInfoRec class_ =                     \
   {                                                              \
     get_font_info_, ps_get_font_extra_, has_glyph_names_,        \
-    get_font_private_                                            \
+    get_font_private_, get_font_value_                           \
   };
 
 #else /* FT_CONFIG_OPTION_PIC */ 
 
 #define FT_DEFINE_SERVICE_PSINFOREC(class_, get_font_info_,      \
-        ps_get_font_extra_, has_glyph_names_, get_font_private_) \
+        ps_get_font_extra_, has_glyph_names_, get_font_private_, \
+        get_font_value_)                                         \
   void                                                           \
   FT_Init_Class_##class_( FT_Library library,                    \
                           FT_Service_PsInfoRec*  clazz)          \
@@ -76,6 +86,7 @@
     clazz->ps_get_font_extra = ps_get_font_extra_;               \
     clazz->ps_has_glyph_names = has_glyph_names_;                \
     clazz->ps_get_font_private = get_font_private_;              \
+    clazz->ps_get_font_value = get_font_value_;                  \
   } 
 
 #endif /* FT_CONFIG_OPTION_PIC */ 
diff --git a/include/freetype/internal/t1types.h b/include/freetype/internal/t1types.h
index 5f73063..f859de2 100644
--- a/include/freetype/internal/t1types.h
+++ b/include/freetype/internal/t1types.h
@@ -5,7 +5,7 @@
 /*    Basic Type1/Type2 type definitions and interface (specification      */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */
+/*  Copyright 1996-2004, 2006, 2008, 2009, 2011 by                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -78,17 +78,6 @@
   } T1_EncodingRec, *T1_Encoding;
 
 
-  typedef enum  T1_EncodingType_
-  {
-    T1_ENCODING_TYPE_NONE = 0,
-    T1_ENCODING_TYPE_ARRAY,
-    T1_ENCODING_TYPE_STANDARD,
-    T1_ENCODING_TYPE_ISOLATIN1,
-    T1_ENCODING_TYPE_EXPERT
-
-  } T1_EncodingType;
-
-
   /* used to hold extra data of PS_FontInfoRec that
    * cannot be stored in the publicly defined structure.
    *
diff --git a/include/freetype/t1tables.h b/include/freetype/t1tables.h
index 5e2a393..db1a91e 100644
--- a/include/freetype/t1tables.h
+++ b/include/freetype/t1tables.h
@@ -5,7 +5,7 @@
 /*    Basic Type 1/Type 2 tables definitions and interface (specification  */
 /*    only).                                                               */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */
+/*  Copyright 1996-2004, 2006, 2008, 2009, 2011 by                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -493,8 +493,166 @@
   FT_Get_PS_Font_Private( FT_Face     face,
                           PS_Private  afont_private );
 
-  /* */
 
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Enum>                                                                */
+  /*    T1_EncodingType                                                    */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An enumeration describing the `Encoding' entry in a Type 1         */
+  /*    dictionary.                                                        */
+  /*                                                                       */
+  typedef enum  T1_EncodingType_
+  {
+    T1_ENCODING_TYPE_NONE = 0,
+    T1_ENCODING_TYPE_ARRAY,
+    T1_ENCODING_TYPE_STANDARD,
+    T1_ENCODING_TYPE_ISOLATIN1,
+    T1_ENCODING_TYPE_EXPERT
+
+  } T1_EncodingType;
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Enum>                                                                */
+  /*    PS_Dict_Keys                                                       */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    An enumeration used in calls to @FT_Get_PS_Font_Value to identify  */
+  /*    the Type~1 dictionary entry to retrieve.                           */
+  /*                                                                       */
+  typedef enum  PS_Dict_Keys_
+  {
+    /* conventionally in the font dictionary */
+    PS_DICT_FONT_TYPE,              /* FT_Byte         */
+    PS_DICT_FONT_MATRIX,            /* FT_Fixed        */
+    PS_DICT_FONT_BBOX,              /* FT_Fixed        */
+    PS_DICT_PAINT_TYPE,             /* FT_Byte         */
+    PS_DICT_FONT_NAME,              /* FT_String*      */
+    PS_DICT_UNIQUE_ID,              /* FT_Int          */
+    PS_DICT_NUM_CHAR_STRINGS,       /* FT_Int          */
+    PS_DICT_CHAR_STRING_KEY,        /* FT_String*      */
+    PS_DICT_CHAR_STRING,            /* FT_String*      */
+    PS_DICT_ENCODING_TYPE,          /* T1_EncodingType */
+    PS_DICT_ENCODING_ENTRY,         /* FT_String*      */
+
+    /* conventionally in the font Private dictionary */
+    PS_DICT_NUM_SUBRS,              /* FT_Int     */
+    PS_DICT_SUBR,                   /* FT_String* */
+    PS_DICT_STD_HW,                 /* FT_UShort  */
+    PS_DICT_STD_VW,                 /* FT_UShort  */
+    PS_DICT_NUM_BLUE_VALUES,        /* FT_Byte    */
+    PS_DICT_BLUE_VALUE,             /* FT_Short   */
+    PS_DICT_BLUE_FUZZ,              /* FT_Int     */
+    PS_DICT_NUM_OTHER_BLUES,        /* FT_Byte    */
+    PS_DICT_OTHER_BLUE,             /* FT_Short   */
+    PS_DICT_NUM_FAMILY_BLUES,       /* FT_Byte    */
+    PS_DICT_FAMILY_BLUE,            /* FT_Short   */
+    PS_DICT_NUM_FAMILY_OTHER_BLUES, /* FT_Byte    */
+    PS_DICT_FAMILY_OTHER_BLUE,      /* FT_Short   */
+    PS_DICT_BLUE_SCALE,             /* FT_Fixed   */
+    PS_DICT_BLUE_SHIFT,             /* FT_Int     */
+    PS_DICT_NUM_STEM_SNAP_H,        /* FT_Byte    */
+    PS_DICT_STEM_SNAP_H,            /* FT_Short   */
+    PS_DICT_NUM_STEM_SNAP_V,        /* FT_Byte    */
+    PS_DICT_STEM_SNAP_V,            /* FT_Short   */
+    PS_DICT_FORCE_BOLD,             /* FT_Bool    */
+    PS_DICT_RND_STEM_UP,            /* FT_Bool    */
+    PS_DICT_MIN_FEATURE,            /* FT_Short   */
+    PS_DICT_LEN_IV,                 /* FT_Int     */
+    PS_DICT_PASSWORD,               /* FT_Long    */
+    PS_DICT_LANGUAGE_GROUP,         /* FT_Long    */
+
+    /* conventionally in the font FontInfo dictionary */
+    PS_DICT_VERSION,                /* FT_String* */
+    PS_DICT_NOTICE,                 /* FT_String* */
+    PS_DICT_FULL_NAME,              /* FT_String* */
+    PS_DICT_FAMILY_NAME,            /* FT_String* */
+    PS_DICT_WEIGHT,                 /* FT_String  */
+    PS_DICT_IS_FIXED_PITCH,         /* FT_Bool    */
+    PS_DICT_UNDERLINE_POSITION,     /* FT_Short   */
+    PS_DICT_UNDERLINE_THICKNESS,    /* FT_UShort  */
+    PS_DICT_FS_TYPE,                /* FT_UShort  */
+    PS_DICT_ITALIC_ANGLE,           /* FT_Long    */
+
+    PS_DICT_MAX = PS_DICT_ITALIC_ANGLE
+
+  } PS_Dict_Keys;
+
+
+  /************************************************************************
+   *
+   * @function:
+   *    FT_Get_PS_Font_Value
+   *
+   * @description:
+   *    Retrieve the value for the supplied key from a PostScript font.
+   *
+   * @input:
+   *    face ::
+   *       PostScript face handle.
+   *
+   *    key ::
+   *       An enumeration value representing the dictionary key to retrieve.
+   *
+   *    idx ::
+   *       For array values, this specifies the index to be returned.
+   *
+   *    value ::
+   *       A pointer to memory into which to write the value.
+   *
+   *    valen_len ::
+   *       The size, in bytes, of the memory supplied for the value.
+   *
+   * @output:
+   *    value ::
+   *       The value matching the above key, if it exists.
+   *
+   * @return:
+   *    The amount of memory (in bytes) required to hold the requested
+   *    value (if it exists, -1 otherwise).
+   *
+   * @note:
+   *    The values returned are not pointers into the internal structures of
+   *    the face, but are `fresh' copies, so that the memory containing them
+   *    belongs to the calling application.  This also enforces the
+   *    `read-only' nature of these values, i.e., this function cannot be
+   *    used to manipulate the face.
+   *
+   *    `value' is a void pointer because the values returned can be of
+   *    various types.
+   *
+   *    If either `value' is NULL or `value_len' is too small, just the
+   *    required memory size for the requested entry is returned.
+   *
+   *    The `idx' parameter is used, not only to retrieve elements of, for
+   *    example, the FontMatrix or FontBBox, but also to retrieve name keys
+   *    from the CharStrings dictionary, and the charstrings themselves.  It
+   *    is ignored for atomic values.
+   *
+   *    PS_DICT_BLUE_SCALE returns a value that is scaled up by 1000.  To
+   *    get the value as in the font stream, you need to divide by
+   *    65536000.0 (to remove the FT_Fixed scale, and the x1000 scale).
+   *
+   *    IMPORTANT: Only key/value pairs read by the FreeType interpreter can
+   *    be retrieved.  So, for example, PostScript procedures such as NP,
+   *    ND, and RD are not available.  Arbitrary keys are, obviously, not be
+   *    available either.
+   *
+   *    If the font's format is not PostScript-based, this function returns
+   *    the `FT_Err_Invalid_Argument' error code.
+   *
+   */
+  FT_EXPORT( FT_Long )
+  FT_Get_PS_Font_Value( FT_Face       face,
+                        PS_Dict_Keys  key,
+                        FT_UInt       idx,
+                        void         *value,
+                        FT_Long       value_len );
+
+  /* */
 
 FT_END_HEADER
 
diff --git a/src/base/fttype1.c b/src/base/fttype1.c
index 3975584..885dba5 100644
--- a/src/base/fttype1.c
+++ b/src/base/fttype1.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType utility file for PS names support (body).                   */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2004 by                                          */
+/*  Copyright 2002-2004, 2011 by                                           */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -91,4 +91,30 @@
   }
 
 
+  /* documentation is in t1tables.h */
+
+  FT_EXPORT_DEF( FT_Long )
+  FT_Get_PS_Font_Value( FT_Face       face,
+                        PS_Dict_Keys  key,
+                        FT_UInt       idx,
+                        void         *value,
+                        FT_Long       value_len )
+  {
+    FT_Int             result  = 0;
+    FT_Service_PsInfo  service = NULL;
+
+
+    if ( face )
+    {
+      FT_FACE_FIND_SERVICE( face, service, POSTSCRIPT_INFO );
+
+      if ( service && service->ps_get_font_value )
+        result = service->ps_get_font_value( face, key, idx,
+                                             value, value_len );
+    }
+
+    return result;
+  }
+
+
 /* END */
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 4fd3436..bf2d016 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -4,8 +4,7 @@
 /*                                                                         */
 /*    OpenType font driver implementation (body).                          */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
-/*            2010 by                                                      */
+/*  Copyright 1996-2011 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -365,7 +364,8 @@
     (PS_GetFontInfoFunc)   cff_ps_get_font_info,
     (PS_GetFontExtraFunc)  NULL,
     (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
-    (PS_GetFontPrivateFunc)NULL         /* unsupported with CFF fonts */
+    (PS_GetFontPrivateFunc)NULL,        /* unsupported with CFF fonts */
+    (PS_GetFontValueFunc)  NULL         /* not implemented            */
   )
 
 
diff --git a/src/cid/cidriver.c b/src/cid/cidriver.c
index 3a2d225..86ee3bb 100644
--- a/src/cid/cidriver.c
+++ b/src/cid/cidriver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID driver interface (body).                                         */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2008, 2009 by             */
+/*  Copyright 1996-2004, 2006, 2008, 2009, 2011 by                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -91,7 +91,8 @@
     (PS_GetFontInfoFunc)   cid_ps_get_font_info,
     (PS_GetFontExtraFunc)  cid_ps_get_font_extra,
     (PS_HasGlyphNamesFunc) NULL,        /* unsupported with CID fonts */
-    (PS_GetFontPrivateFunc)NULL         /* unsupported                */
+    (PS_GetFontPrivateFunc)NULL,        /* unsupported                */
+    (PS_GetFontValueFunc)  NULL         /* not implemented            */
   };
 
 
diff --git a/src/type1/t1driver.c b/src/type1/t1driver.c
index 8c398ee..79516aa 100644
--- a/src/type1/t1driver.c
+++ b/src/type1/t1driver.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 driver interface (body).                                      */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2009 by             */
+/*  Copyright 1996-2004, 2006, 2007, 2009, 2011 by                         */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -171,12 +171,408 @@
   }
 
 
+  static FT_Long
+  t1_ps_get_font_value( FT_Face       face,
+                        PS_Dict_Keys  key,
+                        FT_UInt       idx,
+                        void         *value,
+                        FT_Long       value_len )
+  {
+    FT_Long  retval = -1;
+    T1_Face  t1face = (T1_Face)face;
+    T1_Font  type1  = &t1face->type1;
+
+
+    switch ( key )
+    {
+    case PS_DICT_FONT_TYPE:
+      retval = sizeof ( type1->font_type );
+      if ( value && value_len >= retval )
+        *((FT_Byte *)value) = type1->font_type;
+      break;
+
+    case PS_DICT_FONT_MATRIX:
+      if ( idx < sizeof ( type1->font_matrix ) /
+                   sizeof ( type1->font_matrix.xx ) )
+      {
+        FT_Fixed  val;
+
+
+        retval = sizeof ( val );
+        if ( value && value_len >= retval )
+        {
+          switch ( idx )
+          {
+          case 0:
+            val = type1->font_matrix.xx;
+            break;
+          case 1:
+            val = type1->font_matrix.xy;
+            break;
+          case 2:
+            val = type1->font_matrix.yx;
+            break;
+          case 3:
+            val = type1->font_matrix.yy;
+            break;
+          }
+          *((FT_Fixed *)value) = val;
+        }
+      }
+      break;
+
+    case PS_DICT_FONT_BBOX:
+      if ( idx < sizeof ( type1->font_bbox ) /
+                   sizeof ( type1->font_bbox.xMin ) )
+      {
+        FT_Fixed val;
+
+
+        retval = sizeof ( val );
+        if ( value && value_len >= retval )
+        {
+          switch ( idx )
+          {
+          case 0:
+            val = type1->font_bbox.xMin;
+            break;
+          case 1:
+            val = type1->font_bbox.yMin;
+            break;
+          case 2:
+            val = type1->font_bbox.xMax;
+            break;
+          case 3:
+            val = type1->font_bbox.yMax;
+            break;
+          }
+          *((FT_Fixed *)value) = val;
+        }
+      }
+      break;
+
+    case PS_DICT_PAINT_TYPE:
+      retval = sizeof ( type1->paint_type );
+      if ( value && value_len >= retval )
+        *((FT_Byte *)value) = type1->paint_type;
+      break;
+
+    case PS_DICT_FONT_NAME:
+      retval = ft_strlen( type1->font_name ) + 1;
+      if ( value && value_len >= retval )
+        ft_memcpy( value, (void *)( type1->font_name ), retval );
+      break;
+
+    case PS_DICT_UNIQUE_ID:
+      retval = sizeof ( type1->private_dict.unique_id );
+      if ( value && value_len >= retval )
+        *((FT_Int *)value) = type1->private_dict.unique_id;
+      break;
+
+    case PS_DICT_NUM_CHAR_STRINGS:
+      retval = sizeof ( type1->num_glyphs );
+      if ( value && value_len >= retval )
+        *((FT_Int *)value) = type1->num_glyphs;
+      break;
+
+    case PS_DICT_CHAR_STRING_KEY:
+      if ( idx < (FT_UInt)type1->num_glyphs )
+      {
+        retval = ft_strlen( type1->glyph_names[idx] ) + 1;
+        if ( value && value_len >= retval )
+        {
+          ft_memcpy( value, (void *)( type1->glyph_names[idx] ), retval );
+          ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
+        }
+      }
+      break;
+
+    case PS_DICT_CHAR_STRING:
+      if ( idx < (FT_UInt)type1->num_glyphs )
+      {
+        retval = type1->charstrings_len[idx] + 1;
+        if ( value && value_len >= retval )
+        {
+          ft_memcpy( value, (void *)( type1->charstrings[idx] ),
+                     retval - 1 );
+          ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
+        }
+      }
+      break;
+
+    case PS_DICT_ENCODING_TYPE:
+      retval = sizeof ( type1->encoding_type );
+      if ( value && value_len >= retval )
+        *((T1_EncodingType *)value) = type1->encoding_type;
+      break;
+
+    case PS_DICT_ENCODING_ENTRY:
+      if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY &&
+           idx < (FT_UInt)type1->encoding.num_chars       )
+      {
+        retval = ft_strlen( type1->encoding.char_name[idx] ) + 1;
+        if ( value && value_len >= retval )
+        {
+          ft_memcpy( value, (void *)( type1->encoding.char_name[idx] ),
+                     retval - 1 );
+          ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
+        }
+      }
+      break;
+
+    case PS_DICT_NUM_SUBRS:
+      retval = sizeof ( type1->num_subrs );
+      if ( value && value_len >= retval )
+        *((FT_Int *)value) = type1->num_subrs;
+      break;
+
+    case PS_DICT_SUBR:
+      if ( idx < (FT_UInt)type1->num_subrs )
+      {
+        retval = type1->subrs_len[idx] + 1;
+        if ( value && value_len >= retval )
+        {
+          ft_memcpy( value, (void *)( type1->subrs[idx] ), retval - 1 );
+          ((FT_Char *)value)[retval - 1] = (FT_Char)'\0';
+        }
+      }
+      break;
+
+    case PS_DICT_STD_HW:
+      retval = sizeof ( type1->private_dict.standard_width[0] );
+      if ( value && value_len >= retval )
+        *((FT_UShort *)value) = type1->private_dict.standard_width[0];
+      break;
+
+    case PS_DICT_STD_VW:
+      retval = sizeof ( type1->private_dict.standard_height[0] );
+      if ( value && value_len >= retval )
+        *((FT_UShort *)value) = type1->private_dict.standard_height[0];
+      break;
+
+    case PS_DICT_NUM_BLUE_VALUES:
+      retval = sizeof ( type1->private_dict.num_blue_values );
+      if ( value && value_len >= retval )
+        *((FT_Byte *)value) = type1->private_dict.num_blue_values;
+      break;
+
+    case PS_DICT_BLUE_VALUE:
+      if ( idx < type1->private_dict.num_blue_values )
+      {
+        retval = sizeof ( type1->private_dict.blue_values[idx] );
+        if ( value && value_len >= retval )
+          *((FT_Short *)value) = type1->private_dict.blue_values[idx];
+      }
+      break;
+
+    case PS_DICT_BLUE_SCALE:
+      retval = sizeof ( type1->private_dict.blue_scale );
+      if ( value && value_len >= retval )
+        *((FT_Fixed *)value) = type1->private_dict.blue_scale;
+      break;
+
+    case PS_DICT_BLUE_FUZZ:
+      retval = sizeof ( type1->private_dict.blue_fuzz );
+      if ( value && value_len >= retval )
+        *((FT_Int *)value) = type1->private_dict.blue_fuzz;
+      break;
+
+    case PS_DICT_BLUE_SHIFT:
+      retval = sizeof ( type1->private_dict.blue_shift );
+      if ( value && value_len >= retval )
+        *((FT_Int *)value) = type1->private_dict.blue_shift;
+      break;
+
+    case PS_DICT_NUM_OTHER_BLUES:
+      retval = sizeof ( type1->private_dict.num_other_blues );
+      if ( value && value_len >= retval )
+        *((FT_Byte *)value) = type1->private_dict.num_other_blues;
+      break;
+
+    case PS_DICT_OTHER_BLUE:
+      if ( idx < type1->private_dict.num_other_blues )
+      {
+        retval = sizeof ( type1->private_dict.other_blues[idx] );
+        if ( value && value_len >= retval )
+          *((FT_Short *)value) = type1->private_dict.other_blues[idx];
+      }
+      break;
+
+    case PS_DICT_NUM_FAMILY_BLUES:
+      retval = sizeof ( type1->private_dict.num_family_blues );
+      if ( value && value_len >= retval )
+        *((FT_Byte *)value) = type1->private_dict.num_family_blues;
+      break;
+
+    case PS_DICT_FAMILY_BLUE:
+      if ( idx < type1->private_dict.num_family_blues )
+      {
+        retval = sizeof ( type1->private_dict.family_blues[idx] );
+        if ( value && value_len >= retval )
+          *((FT_Short *)value) = type1->private_dict.family_blues[idx];
+      }
+      break;
+
+    case PS_DICT_NUM_FAMILY_OTHER_BLUES:
+      retval = sizeof ( type1->private_dict.num_family_other_blues );
+      if ( value && value_len >= retval )
+        *((FT_Byte *)value) = type1->private_dict.num_family_other_blues;
+      break;
+
+    case PS_DICT_FAMILY_OTHER_BLUE:
+      if ( idx < type1->private_dict.num_family_other_blues )
+      {
+        retval = sizeof ( type1->private_dict.family_other_blues[idx] );
+        if ( value && value_len >= retval )
+          *((FT_Short *)value) = type1->private_dict.family_other_blues[idx];
+      }
+      break;
+
+    case PS_DICT_NUM_STEM_SNAP_H:
+      retval = sizeof ( type1->private_dict.num_snap_widths );
+      if ( value && value_len >= retval )
+        *((FT_Byte *)value) = type1->private_dict.num_snap_widths;
+      break;
+
+    case PS_DICT_STEM_SNAP_H:
+      if ( idx < type1->private_dict.num_snap_widths )
+      {
+        retval = sizeof ( type1->private_dict.snap_widths[idx] );
+        if ( value && value_len >= retval )
+          *((FT_Short *)value) = type1->private_dict.snap_widths[idx];
+      }
+      break;
+
+    case PS_DICT_NUM_STEM_SNAP_V:
+      retval = sizeof ( type1->private_dict.num_snap_heights );
+      if ( value && value_len >= retval )
+        *((FT_Byte *)value) = type1->private_dict.num_snap_heights;
+      break;
+
+    case PS_DICT_STEM_SNAP_V:
+      if ( idx < type1->private_dict.num_snap_heights )
+      {
+        retval = sizeof ( type1->private_dict.snap_heights[idx] );
+        if ( value && value_len >= retval )
+          *((FT_Short *)value) = type1->private_dict.snap_heights[idx];
+      }
+      break;
+
+    case PS_DICT_RND_STEM_UP:
+      retval = sizeof ( type1->private_dict.round_stem_up );
+      if ( value && value_len >= retval )
+        *((FT_Bool *)value) = type1->private_dict.round_stem_up;
+      break;
+
+    case PS_DICT_FORCE_BOLD:
+      retval = sizeof ( type1->private_dict.force_bold );
+      if ( value && value_len >= retval )
+        *((FT_Bool *)value) = type1->private_dict.force_bold;
+      break;
+
+    case PS_DICT_MIN_FEATURE:
+      if ( idx < sizeof ( type1->private_dict.min_feature ) /
+                   sizeof ( type1->private_dict.min_feature[0] ) )
+      {
+        retval = sizeof ( type1->private_dict.min_feature[idx] );
+        if ( value && value_len >= retval )
+          *((FT_Short *)value) = type1->private_dict.min_feature[idx];
+      }
+      break;
+
+    case PS_DICT_LEN_IV:
+      retval = sizeof ( type1->private_dict.lenIV );
+      if ( value && value_len >= retval )
+        *((FT_Int *)value) = type1->private_dict.lenIV;
+      break;
+
+    case PS_DICT_PASSWORD:
+      retval = sizeof ( type1->private_dict.password );
+      if ( value && value_len >= retval )
+        *((FT_Long *)value) = type1->private_dict.password;
+      break;
+
+    case PS_DICT_LANGUAGE_GROUP:
+      retval = sizeof ( type1->private_dict.language_group );
+      if ( value && value_len >= retval )
+        *((FT_Long *)value) = type1->private_dict.language_group;
+      break;
+
+    case PS_DICT_IS_FIXED_PITCH:
+      retval = sizeof ( type1->font_info.is_fixed_pitch );
+      if ( value && value_len >= retval )
+        *((FT_Bool *)value) = type1->font_info.is_fixed_pitch;
+      break;
+
+    case PS_DICT_UNDERLINE_POSITION:
+      retval = sizeof ( type1->font_info.underline_position );
+      if ( value && value_len >= retval )
+        *((FT_Short *)value) = type1->font_info.underline_position;
+      break;
+
+    case PS_DICT_UNDERLINE_THICKNESS:
+      retval = sizeof ( type1->font_info.underline_thickness );
+      if ( value && value_len >= retval )
+        *((FT_UShort *)value) = type1->font_info.underline_thickness;
+      break;
+
+    case PS_DICT_FS_TYPE:
+      retval = sizeof ( type1->font_extra.fs_type );
+      if ( value && value_len >= retval )
+        *((FT_UShort *)value) = type1->font_extra.fs_type;
+      break;
+
+    case PS_DICT_VERSION:
+      retval = ft_strlen( type1->font_info.version ) + 1;
+      if ( value && value_len >= retval )
+        ft_memcpy( value, (void *)( type1->font_info.version ), retval );
+      break;
+
+    case PS_DICT_NOTICE:
+      retval = ft_strlen( type1->font_info.notice ) + 1;
+      if ( value && value_len >= retval )
+        ft_memcpy( value, (void *)( type1->font_info.notice ), retval );
+      break;
+
+    case PS_DICT_FULL_NAME:
+      retval = ft_strlen( type1->font_info.full_name ) + 1;
+      if ( value && value_len >= retval )
+        ft_memcpy( value, (void *)( type1->font_info.full_name ), retval );
+      break;
+
+    case PS_DICT_FAMILY_NAME:
+      retval = ft_strlen( type1->font_info.family_name ) + 1;
+      if ( value && value_len >= retval )
+        ft_memcpy( value, (void *)( type1->font_info.family_name ), retval );
+      break;
+
+    case PS_DICT_WEIGHT:
+      retval = ft_strlen( type1->font_info.weight ) + 1;
+      if ( value && value_len >= retval )
+        ft_memcpy( value, (void *)( type1->font_info.weight ), retval );
+      break;
+
+    case PS_DICT_ITALIC_ANGLE:
+      retval = sizeof ( type1->font_info.italic_angle );
+      if ( value && value_len >= retval )
+        *((FT_Long *)value) = type1->font_info.italic_angle;
+      break;
+
+    default:
+      break;
+    }
+
+    return retval;
+  }
+
+
   static const FT_Service_PsInfoRec  t1_service_ps_info =
   {
     (PS_GetFontInfoFunc)   t1_ps_get_font_info,
     (PS_GetFontExtraFunc)  t1_ps_get_font_extra,
     (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names,
     (PS_GetFontPrivateFunc)t1_ps_get_font_private,
+    (PS_GetFontValueFunc)  t1_ps_get_font_value,
   };
 
 
diff --git a/src/type42/t42drivr.c b/src/type42/t42drivr.c
index 820c679..f56d6e7 100644
--- a/src/type42/t42drivr.c
+++ b/src/type42/t42drivr.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    High-level Type 42 driver interface (body).                          */
 /*                                                                         */
-/*  Copyright 2002, 2003, 2004, 2006, 2007, 2009 by Roberto Alameda.       */
+/*  Copyright 2002-2004, 2006, 2007, 2009, 2011 by Roberto Alameda.        */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
 /*  modified, and distributed under the terms of the FreeType project      */
@@ -161,9 +161,10 @@
   static const FT_Service_PsInfoRec  t42_service_ps_info =
   {
     (PS_GetFontInfoFunc)   t42_ps_get_font_info,
-    (PS_GetFontExtraFunc)   t42_ps_get_font_extra,
+    (PS_GetFontExtraFunc)  t42_ps_get_font_extra,
     (PS_HasGlyphNamesFunc) t42_ps_has_glyph_names,
-    (PS_GetFontPrivateFunc)t42_ps_get_font_private
+    (PS_GetFontPrivateFunc)t42_ps_get_font_private,
+    (PS_GetFontValueFunc)  NULL             /* not implemented */
   };