shithub: freetype+ttf2subf

Download patch

ref: c313c50208ae4805c713e42d94a163139d3471c7
parent: 7d90a4f05caa56fca8e920ed0e84c8d7f2b04e59
author: David Turner <[email protected]>
date: Thu Sep 11 15:51:54 EDT 2003

* include/freetype/ftmm.h, include/freetype/ftmodule.h,
          include/freetype/tttables.h, include/freetype/config/ftconfig.h,
          include/freetype/internal/ftobjs.h,
          include/freetype/internal/ftserv.h,
          include/freetype/internal/internal.h,
          include/freetype/internal/sfnt.h,
          include/freetype/internal/tttypes.h,
          include/freetype/internal/services/bdf.h,
          include/freetype/internal/services/glyfdict.h,
          include/freetype/internal/services/multmast.h,
          include/freetype/internal/services/postname.h,
          include/freetype/internal/services/sfnt.h,
          include/freetype/internal/services/xf86name.h,
          src/base/ftbdf.c, src/base/ftmm.c, src/base/ftobjs.c,
          src/base/ftxf86.c, src/bdf/bdfdrivr.c, src/cff/cffdrivr.c,
          src/cid/cidriver.c, src/pcf/pcfdrivr.c, src/sfnt/sfdriver.c,
          src/truetype/ttdriver.c, src/type1/t1driver.c, src/type42/t42drivr.c:

          heavy internal modifications to introduce the concept of
          "module services". This is the first step towards a massive
          simplification of the engine's internals, in order to
          get rid of various numbers of hacks.

          Note that this changes will break source & binary compatibility
          for authors of external font drivers.

          Maybe 2.1.6 will be called 2.2.0 after all :-)

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2003-09-11  David Turner  <[email protected]>
+
+        * include/freetype/ftmm.h, include/freetype/ftmodule.h,
+          include/freetype/tttables.h, include/freetype/config/ftconfig.h,
+          include/freetype/internal/ftobjs.h,
+          include/freetype/internal/ftserv.h,
+          include/freetype/internal/internal.h,
+          include/freetype/internal/sfnt.h,
+          include/freetype/internal/tttypes.h,
+          include/freetype/internal/services/bdf.h,
+          include/freetype/internal/services/glyfdict.h,
+          include/freetype/internal/services/multmast.h,
+          include/freetype/internal/services/postname.h,
+          include/freetype/internal/services/sfnt.h,
+          include/freetype/internal/services/xf86name.h,
+          src/base/ftbdf.c, src/base/ftmm.c, src/base/ftobjs.c,
+          src/base/ftxf86.c, src/bdf/bdfdrivr.c, src/cff/cffdrivr.c,
+          src/cid/cidriver.c, src/pcf/pcfdrivr.c, src/sfnt/sfdriver.c,
+          src/truetype/ttdriver.c, src/type1/t1driver.c, src/type42/t42drivr.c:
+
+          heavy internal modifications to introduce the concept of
+          "module services". This is the first step towards a massive
+          simplification of the engine's internals, in order to
+          get rid of various numbers of hacks.
+
+          Note that this changes will break source & binary compatibility
+          for authors of external font drivers.
+
+          Maybe 2.1.6 will be called 2.2.0 after all :-)
+
+
+
 2003-09-09  David Turner  <[email protected]>
 
         * src/base/ftpfr.c, src/pfr/pfrtypes.h, src/pfr/pfrload.c,
--- a/include/freetype/config/ftconfig.h
+++ b/include/freetype/config/ftconfig.h
@@ -192,6 +192,10 @@
 #endif /* FT_SIZEOF_LONG == 8 */
 
 
+#define FT_BEGIN_STMNT  do {
+#define FT_END_STMNT    } while (0)
+#define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
+
   /*************************************************************************/
   /*                                                                       */
   /* A 64-bit data type will create compilation problems if you compile    */
--- a/include/freetype/ftmm.h
+++ b/include/freetype/ftmm.h
@@ -100,21 +100,6 @@
 
   /* */
 
-  typedef FT_Error
-  (*FT_Get_MM_Func)( FT_Face           face,
-                     FT_Multi_Master*  master );
-
-  typedef FT_Error
-  (*FT_Set_MM_Design_Func)( FT_Face   face,
-                            FT_UInt   num_coords,
-                            FT_Long*  coords );
-
-  typedef FT_Error
-  (*FT_Set_MM_Blend_Func)( FT_Face   face,
-                           FT_UInt   num_coords,
-                           FT_Long*  coords );
-
-
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */
--- a/include/freetype/ftmodule.h
+++ b/include/freetype/ftmodule.h
@@ -69,10 +69,8 @@
 #define ft_module_driver_no_outlines  FT_MODULE_DRIVER_NO_OUTLINES
 #define ft_module_driver_has_hinter   FT_MODULE_DRIVER_HAS_HINTER
 
+  typedef  FT_Pointer   FT_Module_Interface;
 
-  typedef void
-  (*FT_Module_Interface)( void );
-
   typedef FT_Error
   (*FT_Module_Constructor)( FT_Module  module );
 
@@ -79,7 +77,7 @@
   typedef void
   (*FT_Module_Destructor)( FT_Module  module );
 
-  typedef FT_Module_Interface
+  typedef FT_Module_Interface 
   (*FT_Module_Requester)( FT_Module    module,
                           const char*  name );
 
--- a/include/freetype/internal/ftobjs.h
+++ b/include/freetype/internal/ftobjs.h
@@ -34,7 +34,7 @@
 #include FT_INTERNAL_GLYPH_LOADER_H
 #include FT_INTERNAL_DRIVER_H
 #include FT_INTERNAL_AUTOHINT_H
-#include FT_INTERNAL_OBJECT_H
+#include FT_INTERNAL_SERVICE_H
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 #include FT_INCREMENTAL_H
@@ -296,8 +296,6 @@
   /*    transform_flags  :: Some flags used to classify the transform.     */
   /*                        Only used by the convenience functions.        */
   /*                                                                       */
-  /*    postscript_name  :: Postscript font name for this face.            */
-  /*                                                                       */
   /*    incremental_interface ::                                           */
   /*                        If non-null, the interface through             */
   /*                        which glyph data and metrics are loaded        */
@@ -315,7 +313,7 @@
     FT_Vector    transform_delta;
     FT_Int       transform_flags;
 
-    const char*  postscript_name;
+    FT_ServiceCacheRec  services;
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     FT_Incremental_InterfaceRec*  incremental_interface;
@@ -753,8 +751,6 @@
     FT_ULong           raster_pool_size; /* size of render pool in bytes */
 
     FT_DebugHook_Func  debug_hooks[4];
-
-    FT_MetaClassRec    meta_class;
 
   } FT_LibraryRec;
 
--- /dev/null
+++ b/include/freetype/internal/ftserv.h
@@ -1,0 +1,139 @@
+#ifndef __FT_SERVICE_H__
+#define __FT_SERVICE_H__
+
+ /*
+  *  each module can export one or more 'services'. Each service is
+  *  identified by a constant string, and modeled by a pointer, which
+  *  generally corresponds to a structure containing function pointers.
+  *
+  *  note that a service's data cannot be a mere function
+  *  pointer. that's because in C, function pointers might be implemented
+  *  differently than data pointers (e.g. 48 bits instead of 32)
+  */
+
+ /* this macro is used to lookup a service from a face's driver module
+  *
+  *   ptr :: variable that receives the service pointer. will be NULL
+  *          if not found
+  *
+  *   id  :: a string describing the service. the list of valid service
+  *          identifiers is below
+  *
+  *   face :: the source face handle
+  */
+#define  FT_FACE_FIND_SERVICE(ptr,face,id)                         \
+   FT_BEGIN_STMNT                                                  \
+     FT_Module  module = FT_MODULE(FT_FACE(face)->driver);         \
+                                                                   \
+     (ptr) = NULL;                                                 \
+     if ( module->clazz->get_interface )                           \
+       (ptr) = module->clazz->get_interface( module, id );         \
+   FT_END_STMNT
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*****                                                               *****/
+ /*****         S E R V I C E   D E S C R I P T O R S                 *****/
+ /*****                                                               *****/
+ /*************************************************************************/
+ /*************************************************************************/
+ 
+ /* the following structure is used to _describe_ a given service
+  * to the library. this is useful to build simple static service lists..
+  */  
+  typedef struct FT_ServiceDescRec_
+  {
+    const char*  serv_id;     /* service name         */
+    const void*  serv_data;   /* service pointer/data */
+  
+  } FT_ServiceDescRec;
+
+  typedef const FT_ServiceDescRec*   FT_ServiceDesc;
+
+
+ /* parse a list of FT_ServiceDescRec descriptors and look for
+  * a specific service by id. Note that the last element in the
+  * array must be { NULL, NULL }, and that the function should
+  * return NULL if the service isn't available
+  *
+  * this function can be used by modules to implement their "get_service"
+  * method
+  */
+  FT_BASE( FT_Pointer )
+  ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
+                          const char*     service_id );
+
+
+ /*************************************************************************/
+ /*************************************************************************/
+ /*****                                                               *****/
+ /*****             S E R V I C E S   C A C H E                       *****/
+ /*****                                                               *****/
+ /*************************************************************************/
+ /*************************************************************************/
+ 
+ /*  this structure is used to store a cache for several often-used
+  *  services. It is the type of 'face->internal->services'. You
+  *  should only use FT_FACE_LOOKUP_SERVICE to access it
+  *
+  *  all fields should have the type FT_Pointer to relax compilation
+  *  dependencies. We assume the developer isn't completely stupid
+  *
+  *
+  */
+  typedef struct FT_ServiceCacheRec_
+  {
+    FT_Pointer     postscript_name;
+    FT_Pointer     multi_masters;
+    FT_Pointer     glyph_dict;
+    
+  } FT_ServiceCacheRec, *FT_ServiceCache;
+
+ /* a magic number used within the services cache
+  */
+#define  FT_SERVICE_UNAVAILABLE  ((FT_Pointer)-2)  /* magic number */
+
+ /*  this macro is used to lookup a service from a face's driver module
+  *  using its cache.
+  *
+  *  ptr   :: variable receiving the service data. NULL if not available
+  *  face  :: source face handle containing the cache
+  *  field :: field name in cache
+  *  id    :: service id
+  *
+  */
+#define  FT_FACE_LOOKUP_SERVICE(face,ptr,field,id)                       \
+   FT_BEGIN_STMNT                                                        \
+     (ptr) = FT_FACE(face)->internal->services. field ;                  \
+     if ( (ptr) == FT_SERVICE_UNAVAILABLE )                              \
+       (ptr) = NULL;                                                     \
+     else if ( (ptr) == NULL )                                           \
+     {                                                                   \
+       FT_FACE_FIND_SERVICE( ptr, face, id );                            \
+                                                                         \
+       FT_FACE(face)->internal->services. field =                        \
+            (FT_Pointer)( (ptr) != NULL                                  \
+                        ? (ptr)                                          \
+                        : FT_SERVICE_UNAVAILABLE );                      \
+     }                                                                   \
+   FT_END_STMNT
+
+
+ /*  A macro used to define new service structure types
+  */
+
+#define FT_DEFINE_SERVICE( name )                                                  \
+  typedef struct FT_Service_ ## name ## Rec_          FT_Service_ ## name ## Rec;  \
+  typedef struct FT_Service_ ## name ## Rec_ const *  FT_Service_ ## name ;        \
+  struct FT_Service_ ## name ## Rec_
+
+ /* */
+ 
+#define FT_SERVICE_MULTIPLE_MASTERS_H  <freetype/internal/services/multmast.h>
+#define FT_SERVICE_POSTSCRIPT_NAME_H   <freetype/internal/services/postname.h> 
+#define FT_SERVICE_GLYPH_DICT_H        <freetype/internal/services/glyfdict.h>
+#define FT_SERVICE_BDF_H               <freetype/internal/services/bdf.h>
+#define FT_SERVICE_XFREE86_NAME_H      <freetype/internal/services/xf86name.h>
+
+#endif /* __FT_SERVICE_H__ */
--- a/include/freetype/internal/internal.h
+++ b/include/freetype/internal/internal.h
@@ -27,16 +27,13 @@
 #define FT_INTERNAL_OBJECTS_H             <freetype/internal/ftobjs.h>
 #define FT_INTERNAL_STREAM_H              <freetype/internal/ftstream.h>
 #define FT_INTERNAL_MEMORY_H              <freetype/internal/ftmemory.h>
-#define FT_INTERNAL_EXTENSION_H           <freetype/internal/ftextend.h>
 #define FT_INTERNAL_DEBUG_H               <freetype/internal/ftdebug.h>
 #define FT_INTERNAL_CALC_H                <freetype/internal/ftcalc.h>
 #define FT_INTERNAL_DRIVER_H              <freetype/internal/ftdriver.h>
-#define FT_INTERNAL_EXTEND_H              <freetype/internal/ftextend.h>
 #define FT_INTERNAL_TRACE_H               <freetype/internal/fttrace.h>
 #define FT_INTERNAL_GLYPH_LOADER_H        <freetype/internal/ftgloadr.h>
 #define FT_INTERNAL_SFNT_H                <freetype/internal/sfnt.h>
-#define FT_INTERNAL_HASH_H                <freetype/internal/fthash.h>
-#define FT_INTERNAL_OBJECT_H              <freetype/internal/ftobject.h>
+#define FT_INTERNAL_SERVICE_H             <freetype/internal/ftserv.h>
 
 #define FT_INTERNAL_TRUETYPE_TYPES_H      <freetype/internal/tttypes.h>
 #define FT_INTERNAL_TYPE1_TYPES_H         <freetype/internal/t1types.h>
--- /dev/null
+++ b/include/freetype/internal/services/bdf.h
@@ -1,0 +1,30 @@
+#ifndef __FT_SERVICE_BDF_H__
+#define __FT_SERVICE_BDF_H__
+
+#include FT_INTERNAL_SERVICE_H
+
+FT_BEGIN_HEADER
+
+#define FT_SERVICE_ID_BDF  "bdf"
+
+  typedef FT_Error  (*FT_BDF_GetCharsetIdFunc)
+                            ( FT_Face       face,
+                              const char*  *acharset_encoding,
+                              const char*  *acharset_registry );
+
+  typedef FT_Error  (*FT_BDF_GetPropertyFunc)
+                            ( FT_Face           face,
+                              const char*       prop_name,
+                              BDF_PropertyRec  *aproperty );
+
+  FT_DEFINE_SERVICE( BDF )
+  {
+    FT_BDF_GetCharsetIdFunc  get_charset_id;
+    FT_BDF_GetPropertyFunc   get_property;
+  };
+
+ /* */
+ 
+FT_END_HEADER
+
+#endif /* __FT_SERVICE_BDF_H__ */
--- /dev/null
+++ b/include/freetype/internal/services/glyfdict.h
@@ -1,0 +1,36 @@
+#ifndef __FT_SERVICE_GLYPH_DICT_H__
+#define __FT_SERVICE_GLYPH_DICT_H__
+
+#include FT_INTERNAL_SERVICE_H
+
+FT_BEGIN_HEADER
+
+ /*
+  *  a service used to retrieve glyph names, as well as to find the
+  *  index of a given glyph name in a font.
+  *
+  */
+
+#define FT_SERVICE_ID_GLYPH_DICT  "glyph-dict"
+
+  typedef FT_Error  (*FT_GlyphDict_GetNameFunc)
+                             ( FT_Face     face,
+                               FT_UInt     glyph_index,
+                               FT_Pointer  buffer,
+                               FT_UInt     buffer_max );
+
+  typedef  FT_UInt  (*FT_GlyphDict_NameIndexFunc)
+                              ( FT_Face     face,
+                                FT_String*  glyph_name );
+
+  FT_DEFINE_SERVICE( GlyphDict )
+  {
+    FT_GlyphDict_GetNameFunc    get_name;
+    FT_GlyphDict_NameIndexFunc  name_index;  /* optional */
+  };
+
+ /* */
+
+FT_END_HEADER
+
+#endif /* __FT_SERVICE_GLYPH_DICT_H__ */
--- /dev/null
+++ b/include/freetype/internal/services/multmast.h
@@ -1,0 +1,37 @@
+#ifndef __FT_SERVICE_MULTIPLE_MASTERS_H__
+#define __FT_SERVICE_MULTIPLE_MASTERS_H__
+
+#include FT_INTERNAL_SERVICE_H
+
+ /*
+  *  a service used to manage multiple-masters data in a given face
+  *
+  *  see the related APIs in "ftmm.h" / FT_MULTIPLE_MASTERS_H
+  *
+  */
+
+
+  typedef FT_Error
+  (*FT_Get_MM_Func)( FT_Face           face,
+                     FT_Multi_Master*  master );
+
+  typedef FT_Error
+  (*FT_Set_MM_Design_Func)( FT_Face   face,
+                            FT_UInt   num_coords,
+                            FT_Long*  coords );
+
+  typedef FT_Error
+  (*FT_Set_MM_Blend_Func)( FT_Face   face,
+                           FT_UInt   num_coords,
+                           FT_Long*  coords );
+
+#define FT_SERVICE_ID_MULTI_MASTERS  "multi-masters"
+
+  FT_DEFINE_SERVICE( MultiMasters )
+  {
+    FT_Get_MM_Func         get_mm;
+    FT_Set_MM_Design_Func  set_mm_design;
+    FT_Set_MM_Blend_Func   set_mm_blend;
+  };
+
+#endif /* __FT_SERVICE_MULTIPLE_MASTERS_H__ */
--- /dev/null
+++ b/include/freetype/internal/services/postname.h
@@ -1,0 +1,30 @@
+#ifndef __FT_SERVICE_POSTSCRIPT_NAME_H__
+#define __FT_SERVICE_POSTSCRIPT_NAME_H__
+
+#include FT_INTERNAL_SERVICE_H
+
+FT_BEGIN_HEADER
+
+ /*
+  *  a trivial service used to retrieve the Postscript name of a given
+  *  font when available. The "get_name" field should never be NULL
+  *
+  *  the correponding function can return NULL to indicate that the
+  *  Postscript name is not available.
+  *
+  *  the name is owned by the face and will be destroyed with it
+  *
+  */
+
+#define FT_SERVICE_ID_POSTSCRIPT_NAME   "postscript-name"
+
+  typedef const char*  (*FT_PsName_GetFunc)( FT_Face  face );
+  
+  FT_DEFINE_SERVICE( PsName )
+  {
+    FT_PsName_GetFunc   get_ps_name;
+  };
+
+FT_END_HEADER
+
+#endif /* __FT_SERVICE_POSTSCRIPT_NAME_H__ */
--- /dev/null
+++ b/include/freetype/internal/services/sfnt.h
@@ -1,0 +1,42 @@
+#ifndef __FT_SERVICE_SFNT_H__
+#define __FT_SERVICE_SFNT_H__
+
+#include FT_INTERNAL_SERVICE_H
+#include FT_TRUETYPE_TABLES_H
+
+FT_BEGIN_HEADER
+
+ /*
+  *  SFNT table loading service
+  *
+  */
+
+#define FT_SERVICE_ID_SFNT_TABLE  "sfnt-table"
+
+ /* used to implement FT_Load_Sfnt_Table()
+  */
+  typedef FT_Error
+  (*FT_SFNT_TableLoadFunc)( FT_Face    face,
+                            FT_ULong   tag,
+                            FT_Long    offset,
+                            FT_Byte*   buffer,
+                            FT_ULong*  length );
+
+ /* used to implement FT_Get_Sfnt_Table()
+  */
+  typedef void*
+  (*FT_SFNT_TableGetFunc)( FT_Face      face,
+                           FT_Sfnt_Tag  tag );
+
+ 
+  FT_DEFINE_SERVICE( SFNT_Table )
+  {
+    FT_SFNT_TableLoadFunc    load_table;
+    FT_SFNT_TableGetFunc     get_table;
+  };
+
+ /* */
+ 
+FT_END_HEADER
+
+#endif /* __FT_SERVICE_SFNT_H__ */
--- /dev/null
+++ b/include/freetype/internal/services/xf86name.h
@@ -1,0 +1,31 @@
+#ifndef __FT_SERVICE_XF86_NAME_H__
+#define __FT_SERVICE_XF86_NAME_H__
+
+#include FT_INTERNAL_SERVICE_H
+
+FT_BEGIN_HEADER
+
+ /*
+  *  a trivial service used to return the name of a face's font driver,
+  *  according to the XFree86 nomenclature. Note that the service data
+  *  is a simple constant string pointer
+  *
+  */
+
+#define  FT_SERVICE_ID_XF86_NAME  "xf86-driver-name"
+
+#define  FT_XF86_FORMAT_TRUETYPE  "TrueType"
+#define  FT_XF86_FORMAT_TYPE_1    "Type 1"
+#define  FT_XF86_FORMAT_BDF       "BDF"
+#define  FT_XF86_FORMAT_PCF       "PCF"
+#define  FT_XF86_FORMAT_TYPE_42   "Type 42"
+#define  FT_XF86_FORMAT_CID       "CID Type 1"
+#define  FT_XF86_FORMAT_CFF       "CFF"
+#define  FT_XF86_FORMAT_PFR       "PFR"
+#define  FT_XF86_FORMAT_WINFNT    "Windows FNT"
+
+ /* */
+ 
+FT_END_HEADER
+
+#endif /* __FT_SERVICE_XF86_NAME_H__ */
--- a/include/freetype/internal/sfnt.h
+++ b/include/freetype/internal/sfnt.h
@@ -125,11 +125,7 @@
   (*TT_Done_Face_Func)( TT_Face  face );
 
 
-  typedef FT_Module_Interface
-  (*SFNT_Get_Interface_Func)( FT_Module    module,
-                              const char*  func_interface );
 
-
   /*************************************************************************/
   /*                                                                       */
   /* <FuncType>                                                            */
@@ -457,22 +453,7 @@
   (*TT_Free_Table_Func)( TT_Face  face );
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <FuncType>                                                            */
-  /*    SFNT_Load_Table_Func                                               */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Loads a given SFNT table into memory.                              */
-  /*                                                                       */
-  typedef FT_Error
-  (*SFNT_Load_Table_Func)( FT_Face    face,
-                           FT_ULong   tag,
-                           FT_Long    offset,
-                           FT_Byte*   buffer,
-                           FT_ULong*  length );
 
-
   /*************************************************************************/
   /*                                                                       */
   /* <Struct>                                                              */
@@ -492,7 +473,7 @@
     TT_Init_Face_Func            init_face;
     TT_Load_Face_Func            load_face;
     TT_Done_Face_Func            done_face;
-    SFNT_Get_Interface_Func      get_interface;
+    FT_Module_Requester          get_interface;
 
     TT_Load_Any_Func             load_any;
     TT_Load_SFNT_HeaderRec_Func  load_sfnt_header;
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -1576,6 +1576,8 @@
 
     FT_Generic            extra;
 
+    const char*           postscript_name;
+
   } TT_FaceRec;
 
 
--- a/include/freetype/tttables.h
+++ b/include/freetype/tttables.h
@@ -566,11 +566,6 @@
 
   /* */
 
-  /* internal use only */
-  typedef void*
-  (*FT_Get_Sfnt_Table_Func)( FT_Face      face,
-                             FT_Sfnt_Tag  tag );
-
 
   /*************************************************************************/
   /*                                                                       */
--- a/src/base/ftbdf.c
+++ b/src/base/ftbdf.c
@@ -19,27 +19,9 @@
 #include <ft2build.h>
 #include FT_INTERNAL_BDF_TYPES_H
 #include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_BDF_H
 
 
-  static FT_Bool
-  test_font_type( FT_Face      face,
-                  const char*  name )
-  {
-    if ( face && face->driver )
-    {
-      FT_Module  driver = (FT_Module)face->driver;
-
-
-      if ( driver->clazz && driver->clazz->module_name )
-      {
-        if ( ft_strcmp( driver->clazz->module_name, name ) == 0 )
-          return 1;
-      }
-    }
-    return 0;
-  }
-
-
   FT_EXPORT_DEF( FT_Error )
   FT_Get_BDF_Charset_ID( FT_Face       face,
                          const char*  *acharset_encoding,
@@ -52,19 +34,18 @@
 
     error = FT_Err_Invalid_Argument;
 
-    if ( test_font_type( face, "bdf" ) )
+    if ( face )
     {
-      BDF_Public_Face  bdf_face = (BDF_Public_Face)face;
-
-
-      encoding = (const char*) bdf_face->charset_encoding;
-      registry = (const char*) bdf_face->charset_registry;
-      error    = 0;
+      FT_Service_BDF  service;
+      
+      FT_FACE_FIND_SERVICE( service, face, FT_SERVICE_ID_BDF );
+      
+      if ( service && service->get_charset_id )
+        error = service->get_charset_id( face, &encoding, &registry );
     }
-
     if ( acharset_encoding )
       *acharset_encoding = encoding;
-
+    
     if ( acharset_registry )
       *acharset_registry = registry;
 
@@ -84,22 +65,16 @@
 
     aproperty->type = BDF_PROPERTY_TYPE_NONE;
 
-    if ( face != NULL && face->driver != NULL )
+    if ( face )
     {
-      FT_Driver            driver = face->driver;
-      BDF_GetPropertyFunc  func;
-
-
-      if ( driver->root.clazz->get_interface )
-      {
-        func = (BDF_GetPropertyFunc)driver->root.clazz->get_interface(
-                 FT_MODULE( driver ), "get_bdf_property" );
-        if ( func )
-          error = func( face, prop_name, aproperty );
-      }
+      FT_Service_BDF  service;
+      
+      FT_FACE_FIND_SERVICE( service, face, FT_SERVICE_ID_BDF );
+      
+      if ( service && service->get_property )
+        error = service->get_property( face, prop_name, aproperty );
     }
-
-    return error;
+    return  error;
   }
 
 
--- a/src/base/ftmm.c
+++ b/src/base/ftmm.c
@@ -19,6 +19,7 @@
 #include <ft2build.h>
 #include FT_MULTIPLE_MASTERS_H
 #include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_MULTIPLE_MASTERS_H
 
 
   /*************************************************************************/
@@ -30,33 +31,46 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_mm
 
-
-  /* documentation is in ftmm.h */
-
-  FT_EXPORT_DEF( FT_Error )
-  FT_Get_Multi_Master( FT_Face           face,
-                       FT_Multi_Master  *amaster )
+  static FT_Error
+  ft_face_get_mm_service( FT_Face                   face,
+                          FT_Service_MultiMasters  *aservice )
   {
     FT_Error  error;
-
-
+    
+    *aservice = NULL;
+    
     if ( !face )
       return FT_Err_Invalid_Face_Handle;
-
+    
     error = FT_Err_Invalid_Argument;
-
+    
     if ( FT_HAS_MULTIPLE_MASTERS( face ) )
     {
-      FT_Driver       driver = face->driver;
-      FT_Get_MM_Func  func;
+      FT_FACE_LOOKUP_SERVICE( face, *aservice,
+                              multi_masters,
+                              FT_SERVICE_ID_MULTI_MASTERS );
+    }
+    return error;
+  }
 
 
-      func = (FT_Get_MM_Func)driver->root.clazz->get_interface(
-                               FT_MODULE( driver ), "get_mm" );
-      if ( func )
-        error = func( face, amaster );
-    }
+  /* documentation is in ftmm.h */
 
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_Multi_Master( FT_Face           face,
+                       FT_Multi_Master  *amaster )
+  {
+    FT_Error                 error;
+    FT_Service_MultiMasters  service;
+
+    error = ft_face_get_mm_service( face, &service );
+    if ( !error )
+    {
+      error = FT_Err_Invalid_Argument;
+      if ( service->get_mm )
+        error = service->get_mm( face, amaster );
+    }
+      
     return error;
   }
 
@@ -68,26 +82,16 @@
                                 FT_UInt   num_coords,
                                 FT_Long*  coords )
   {
-    FT_Error  error;
+    FT_Error                 error;
+    FT_Service_MultiMasters  service;
 
-
-    if ( !face )
-      return FT_Err_Invalid_Face_Handle;
-
-    error = FT_Err_Invalid_Argument;
-
-    if ( FT_HAS_MULTIPLE_MASTERS( face ) )
+    error = ft_face_get_mm_service( face, &service );
+    if ( !error )
     {
-      FT_Driver              driver = face->driver;
-      FT_Set_MM_Design_Func  func;
-
-
-      func = (FT_Set_MM_Design_Func)driver->root.clazz->get_interface(
-                                      FT_MODULE( driver ), "set_mm_design" );
-      if ( func )
-        error = func( face, num_coords, coords );
+      error = FT_Err_Invalid_Argument;
+      if ( service->set_mm_design )
+        error = service->set_mm_design( face, num_coords, coords );
     }
-
     return error;
   }
 
@@ -99,28 +103,17 @@
                                FT_UInt    num_coords,
                                FT_Fixed*  coords )
   {
-    FT_Error  error;
+    FT_Error                 error;
+    FT_Service_MultiMasters  service;
 
-
-    if ( !face )
-      return FT_Err_Invalid_Face_Handle;
-
-    error = FT_Err_Invalid_Argument;
-
-    if ( FT_HAS_MULTIPLE_MASTERS( face ) )
+    error = ft_face_get_mm_service( face, &service );
+    if ( !error )
     {
-      FT_Driver             driver = face->driver;
-      FT_Set_MM_Blend_Func  func;
-
-
-      func = (FT_Set_MM_Blend_Func)driver->root.clazz->get_interface(
-                                     FT_MODULE( driver ), "set_mm_blend" );
-      if ( func )
-        error = func( face, num_coords, coords );
+      error = FT_Err_Invalid_Argument;
+      if ( service->set_mm_blend )
+         error = service->set_mm_blend( face, num_coords, coords );
     }
-
     return error;
   }
-
 
 /* END */
--- a/src/base/ftobjs.c
+++ b/src/base/ftobjs.c
@@ -27,7 +27,30 @@
 #include FT_TRUETYPE_IDS_H
 #include FT_OUTLINE_H
 
+#include FT_SERVICE_POSTSCRIPT_NAME_H
+#include FT_SERVICE_GLYPH_DICT_H
 
+  FT_BASE_DEF( FT_Pointer )
+  ft_service_list_lookup( FT_ServiceDesc  service_descriptors,
+                          const char*     service_id )
+  {
+    FT_Pointer      result = NULL;
+    FT_ServiceDesc  desc   = service_descriptors;
+    
+    if ( desc && service_id )
+    {
+      for ( ; desc->serv_id != NULL; desc++ )
+      {
+        if ( ft_strcmp( desc->serv_id, service_id ) == 0 )
+        {
+          result = (FT_Pointer) desc->serv_data;
+          break;
+        }
+      }
+    }
+    return result;
+  }                          
+
   FT_BASE_DEF( void )
   ft_validator_init( FT_Validator        valid,
                      const FT_Byte*      base,
@@ -704,7 +727,6 @@
     /* get rid of it */
     if ( face->internal )
     {
-      FT_FREE( face->internal->postscript_name );
       FT_FREE( face->internal );
     }
     FT_FREE( face );
@@ -1154,14 +1176,14 @@
     if ( FT_ALLOC( pfb_data, (FT_Long)pfb_len + 2 ) )
       goto Exit;
 
-    pfb_pos             = 0;
-    pfb_data[pfb_pos++] = 0x80;
-    pfb_data[pfb_pos++] = 1;            /* Ascii section */
-    pfb_lenpos          = pfb_pos;
-    pfb_data[pfb_pos++] = 0;            /* 4-byte length, fill in later */
-    pfb_data[pfb_pos++] = 0;
-    pfb_data[pfb_pos++] = 0;
-    pfb_data[pfb_pos++] = 0;
+    pfb_data[0] = 0x80;
+    pfb_data[1] = 1;            /* Ascii section */
+    pfb_data[2] = 0;            /* 4-byte length, fill in later */
+    pfb_data[3] = 0;
+    pfb_data[4] = 0;
+    pfb_data[5] = 0;
+    pfb_pos     = 7;
+    pfb_lenpos  = 2;      
 
     len = 0;
     type = 1;
@@ -1179,10 +1201,10 @@
         len += rlen;
       else
       {
-        pfb_data[pfb_lenpos    ] =   len         & 0xFF;
-        pfb_data[pfb_lenpos + 1] = ( len >>  8 ) & 0xFF;
-        pfb_data[pfb_lenpos + 2] = ( len >> 16 ) & 0xFF;
-        pfb_data[pfb_lenpos + 3] = ( len >> 24 ) & 0xFF;
+        pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
+        pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
+        pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
+        pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
 
         if ( ( flags >> 8 ) == 5 )      /* End of font mark */
           break;
@@ -1192,8 +1214,8 @@
         type = flags >> 8;
         len = rlen;
 
-        pfb_data[pfb_pos++] = type;
-        pfb_lenpos          = pfb_pos;
+        pfb_data[pfb_pos++] = (FT_Byte) type;
+        pfb_lenpos          = (FT_Byte) pfb_pos;
         pfb_data[pfb_pos++] = 0;        /* 4-byte length, fill in later */
         pfb_data[pfb_pos++] = 0;
         pfb_data[pfb_pos++] = 0;
@@ -1207,10 +1229,10 @@
     pfb_data[pfb_pos++] = 0x80;
     pfb_data[pfb_pos++] = 3;
 
-    pfb_data[pfb_lenpos    ] =   len         & 0xFF;
-    pfb_data[pfb_lenpos + 1] = ( len >>  8 ) & 0xFF;
-    pfb_data[pfb_lenpos + 2] = ( len >> 16 ) & 0xFF;
-    pfb_data[pfb_lenpos + 3] = ( len >> 24 ) & 0xFF;
+    pfb_data[pfb_lenpos    ] = (FT_Byte)( len );
+    pfb_data[pfb_lenpos + 1] = (FT_Byte)( len >> 8 );
+    pfb_data[pfb_lenpos + 2] = (FT_Byte)( len >> 16 );
+    pfb_data[pfb_lenpos + 3] = (FT_Byte)( len >> 24 );
 
     return open_face_from_buffer( library,
                                   pfb_data,
@@ -1320,7 +1342,8 @@
     unsigned char  head[16], head2[16];
     FT_Long        rdata_pos, map_pos, rdata_len, map_len;
     int            allzeros, allmatch, i, cnt, subcnt;
-    FT_Long        type_list, tag, rpos, junk;
+    FT_Long        type_list, rpos, junk;
+    FT_ULong       tag;
 
 
     error = FT_Stream_Seek( stream, resource_offset );
@@ -1354,7 +1377,7 @@
     if ( error )
       goto Exit;
 
-    head2[15] = head[15] + 1;       /* make it be different */
+    head2[15] = (FT_Byte)(head[15] + 1);       /* make it be different */
 
     error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
     if ( error )
@@ -2368,23 +2391,33 @@
 
     if ( face && FT_HAS_GLYPH_NAMES( face ) )
     {
-      /* now, lookup for glyph name */
-      FT_Driver         driver = face->driver;
-      FT_Module_Class*  clazz  = FT_MODULE_CLASS( driver );
+      FT_Service_GlyphDict  service;
 
+#if 0
+      FT_FACE_LOOKUP_SERVICE( face, service,
+                              glyph_dict,
+                              FT_SERVICE_ID_GLYPH_DICT );
+#else
+     service = face->internal->services . glyph_dict;
+     if ( service == FT_SERVICE_UNAVAILABLE )
+       service = NULL;
+     else if ( service == NULL )
+     {
+       FT_Module  module = FT_MODULE(face->driver);
+       
+       if ( module->clazz->get_interface )
+         service = module->clazz->get_interface( module,
+                                                 FT_SERVICE_ID_GLYPH_DICT );
+     
+       face->internal->services . glyph_dict = service != NULL
+                                             ? service
+                                             : FT_SERVICE_UNAVAILABLE;
+     }
 
-      if ( clazz->get_interface )
-      {
-        FT_Face_GetGlyphNameIndexFunc  requester;
-
-
-        requester = (FT_Face_GetGlyphNameIndexFunc)clazz->get_interface(
-                      FT_MODULE( driver ), "name_index" );
-        if ( requester )
-          result = requester( face, glyph_name );
+#endif
+      if ( service && service->name_index )
+        result = service->name_index( face, glyph_name );
       }
-    }
-
     return result;
   }
 
@@ -2408,20 +2441,15 @@
          glyph_index <= (FT_UInt)face->num_glyphs &&
          FT_HAS_GLYPH_NAMES( face )               )
     {
-      /* now, lookup for glyph name */
-      FT_Driver         driver = face->driver;
-      FT_Module_Class*  clazz  = FT_MODULE_CLASS( driver );
+      FT_Service_GlyphDict  service;
 
+      FT_FACE_LOOKUP_SERVICE( face, service,
+                              glyph_dict,
+                              FT_SERVICE_ID_GLYPH_DICT );
 
-      if ( clazz->get_interface )
+      if ( service && service->get_name )
       {
-        FT_Face_GetGlyphNameFunc  requester;
-
-
-        requester = (FT_Face_GetGlyphNameFunc)clazz->get_interface(
-                      FT_MODULE( driver ), "glyph_name" );
-        if ( requester )
-          error = requester( face, glyph_index, buffer, buffer_max );
+        error = service->get_name( face, glyph_index, buffer, buffer_max );
       }
     }
 
@@ -2440,24 +2468,16 @@
     if ( !face )
       goto Exit;
 
-    result = face->internal->postscript_name;
     if ( !result )
     {
-      /* now, look up glyph name */
-      FT_Driver         driver = face->driver;
-      FT_Module_Class*  clazz  = FT_MODULE_CLASS( driver );
+      FT_Service_PsName  service;
 
+      FT_FACE_LOOKUP_SERVICE( face, service,
+                              postscript_name,
+                              FT_SERVICE_ID_POSTSCRIPT_NAME );
 
-      if ( clazz->get_interface )
-      {
-        FT_Face_GetPostscriptNameFunc  requester;
-
-
-        requester = (FT_Face_GetPostscriptNameFunc)clazz->get_interface(
-                      FT_MODULE( driver ), "postscript_name" );
-        if ( requester )
-          result = requester( face );
-      }
+      if ( service && service->get_ps_name )
+        result = service->get_ps_name( face );
     }
   Exit:
     return result;
@@ -2471,20 +2491,15 @@
                      FT_Sfnt_Tag  tag )
   {
     void*                   table = 0;
-    FT_Get_Sfnt_Table_Func  func;
-    FT_Driver               driver;
+    FT_Service_SFNT_Table   service;
 
-
-    if ( !face || !FT_IS_SFNT( face ) )
-      goto Exit;
-
-    driver = face->driver;
-    func = (FT_Get_Sfnt_Table_Func)driver->root.clazz->get_interface(
-                                     FT_MODULE( driver ), "get_sfnt" );
-    if ( func )
-      table = func( face, tag );
-
-  Exit:
+    if ( face && FT_IS_SFNT( face ) )
+    {
+      FT_FACE_FIND_SERVICE( face, service, FT_SERVICE_ID_SFNT_TABLE );
+      if ( service != NULL )
+        table = service->get_table( face, tag );
+    }
+      
     return table;
   }
 
@@ -2498,20 +2513,17 @@
                       FT_Byte*   buffer,
                       FT_ULong*  length )
   {
-    SFNT_Load_Table_Func  func;
-    FT_Driver             driver;
+    FT_Service_SFNT_Table  service;
 
 
     if ( !face || !FT_IS_SFNT( face ) )
       return FT_Err_Invalid_Face_Handle;
 
-    driver = face->driver;
-    func   = (SFNT_Load_Table_Func) driver->root.clazz->get_interface(
-                                      FT_MODULE( driver ), "load_sfnt" );
-    if ( !func )
+    FT_FACE_FIND_SERVICE( face, service, FT_SERVICE_ID_SFNT_TABLE );
+    if ( service == NULL )
       return FT_Err_Unimplemented_Feature;
-
-    return func( face, tag, offset, buffer, length );
+      
+    return service->load_table( face, tag, offset, buffer, length );
   }
 
 
--- a/src/base/ftxf86.c
+++ b/src/base/ftxf86.c
@@ -19,59 +19,15 @@
 #include <ft2build.h>
 #include FT_XFREE86_H
 #include FT_INTERNAL_OBJECTS_H
+#include FT_SERVICE_XFREE86_NAME_H
 
-  /* XXX: This really is a sad hack, but I didn't want to change every     */
-  /*      driver just to support this at the moment, since other important */
-  /*      changes are coming anyway.                                       */
-
-  typedef struct  FT_FontFormatRec_
-  {
-    const char*  driver_name;
-    const char*  format_name;
-
-  } FT_FontFormatRec;
-
-
   FT_EXPORT_DEF( const char* )
   FT_Get_X11_Font_Format( FT_Face  face )
   {
-    static const FT_FontFormatRec  font_formats[] =
-    {
-      { "type1",    "Type 1" },
-      { "truetype", "TrueType" },
-      { "bdf",      "BDF" },
-      { "pcf",      "PCF" },
-      { "type42",   "Type 42" },
-      { "cidtype1", "CID Type 1" },
-      { "cff",      "CFF" },
-      { "pfr",      "PFR" },
-      { "winfonts", "Windows FNT" }
-    };
-
     const char*  result = NULL;
 
-
-    if ( face && face->driver )
-    {
-      FT_Module  driver = (FT_Module)face->driver;
-
-
-      if ( driver->clazz && driver->clazz->module_name )
-      {
-        FT_Int  n;
-        FT_Int  count = sizeof( font_formats ) / sizeof ( font_formats[0] );
-
-
-        result = driver->clazz->module_name;
-
-        for ( n = 0; n < count; n++ )
-          if ( ft_strcmp( result, font_formats[n].driver_name ) == 0 )
-          {
-            result = font_formats[n].format_name;
-            break;
-          }
-      }
-    }
+    if ( face )
+      FT_FACE_FIND_SERVICE( result, face, FT_SERVICE_ID_XF86_NAME );
 
     return result;
   }
--- a/src/bdf/bdfdrivr.c
+++ b/src/bdf/bdfdrivr.c
@@ -31,6 +31,9 @@
 #include FT_INTERNAL_OBJECTS_H
 #include FT_BDF_H
 
+#include FT_SERVICE_BDF_H
+#include FT_SERVICE_XFREE86_NAME_H
+
 #include "bdf.h"
 #include "bdfdrivr.h"
 
@@ -649,6 +652,12 @@
   }
 
 
+ /*
+  *
+  *  BDF SERVICE
+  *
+  */
+  
   static FT_Error
   bdf_get_bdf_property( BDF_Face          face,
                         const char*       prop_name,
@@ -689,7 +698,39 @@
     return BDF_Err_Invalid_Argument;
   }
 
+  static FT_Error
+  bdf_get_charset_id( BDF_Face      face,
+                      const char*  *acharset_encoding,
+                      const char*  *acharset_registry )
+  {
+    *acharset_encoding = face->charset_encoding;
+    *acharset_registry = face->charset_registry;
+    
+    return 0;
+  }                      
 
+
+  static const FT_Service_BDFRec  bdf_service_bdf =
+  {
+    (FT_BDF_GetCharsetIdFunc)  bdf_get_charset_id,
+    (FT_BDF_GetPropertyFunc)   bdf_get_bdf_property
+  };
+
+
+ /*
+  *
+  *  SERVICES LIST
+  *
+  */
+  
+  static const FT_ServiceDescRec  bdf_services[] =
+  {
+    { FT_SERVICE_ID_BDF,       &bdf_service_bdf },
+    { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_BDF },
+    { NULL, NULL }
+  };
+
+
   static FT_Module_Interface
   bdf_driver_requester( FT_Module    module,
                         const char*  name )
@@ -696,11 +737,9 @@
   {
     FT_UNUSED( module );
 
-    if ( name && ft_strcmp( name, "get_bdf_property" ) == 0 )
-      return (FT_Module_Interface)bdf_get_bdf_property;
-
-    return NULL;
+    return ft_service_list_lookup( bdf_services, name );
   }
+
 
 
   FT_CALLBACK_TABLE_DEF
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -30,6 +30,8 @@
 
 #include "cfferrs.h"
 
+#include FT_SERVICE_XFREE86_NAME_H
+#include FT_SERVICE_GLYPH_DICT_H
 
   /*************************************************************************/
   /*                                                                       */
@@ -210,18 +212,13 @@
   }
 
 
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /****             C H A R A C T E R   M A P P I N G S                 ****/
-  /****                                                                 ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
+ /*
+  *  GLYPH DICT SERVICE
+  *
+  */
 
+#include FT_SERVICE_GLYPH_DICT_H
+
   static FT_Error
   cff_get_glyph_name( CFF_Face    face,
                       FT_UInt     glyph_index,
@@ -275,23 +272,6 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    cff_get_name_index                                                 */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Uses the psnames module and the CFF font's charset to to return a  */
-  /*    a given glyph name's glyph index.                                  */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face       :: A handle to the source face object.                  */
-  /*                                                                       */
-  /*    glyph_name :: The glyph name.                                      */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Glyph index.  0 means `undefined character code'.                  */
-  /*                                                                       */
   static FT_UInt
   cff_get_name_index( CFF_Face    face,
                       FT_String*  glyph_name )
@@ -334,6 +314,13 @@
   }
 
 
+  static const FT_Service_GlyphDictRec   cff_service_glyph_dict =
+  {
+    (FT_GlyphDict_GetNameFunc)    cff_get_glyph_name,
+    (FT_GlyphDict_NameIndexFunc)  cff_get_name_index,
+  };
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
@@ -346,22 +333,25 @@
   /*************************************************************************/
   /*************************************************************************/
 
+  static const FT_ServiceDescRec  cff_services[] =
+  {
+    { FT_SERVICE_ID_XF86_NAME,  FT_XF86_FORMAT_CFF },
+#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
+    { FT_SERVICE_ID_GLYPH_DICT, & cff_service_glyph_dict },
+#endif
+    { NULL, NULL }
+  };
+
   static FT_Module_Interface
   cff_get_interface( CFF_Driver   driver,
                      const char*  module_interface )
   {
     FT_Module  sfnt;
+    FT_Module_Interface  result;
 
-
-#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
-
-    if ( ft_strcmp( (const char*)module_interface, "glyph_name" ) == 0 )
-      return (FT_Module_Interface)cff_get_glyph_name;
-
-    if ( ft_strcmp( (const char*)module_interface, "name_index" ) == 0 )
-      return (FT_Module_Interface)cff_get_name_index;
-
-#endif
+    result = ft_service_list_lookup( cff_services, module_interface );
+    if ( result != NULL )
+      return  result;
 
     /* we simply pass our request to the `sfnt' module */
     sfnt = FT_Get_Module( driver->root.root.library, "sfnt" );
--- a/src/cid/cidriver.c
+++ b/src/cid/cidriver.c
@@ -25,6 +25,8 @@
 
 #include "ciderrs.h"
 
+#include FT_SERVICE_POSTSCRIPT_NAME_H
+#include FT_SERVICE_XFREE86_NAME_H
 
   /*************************************************************************/
   /*                                                                       */
@@ -36,6 +38,11 @@
 #define FT_COMPONENT  trace_ciddriver
 
 
+ /*
+  *  POSTSCRIPT NAME SERVICE
+  *
+  */
+  
   static const char*
   cid_get_postscript_name( CID_Face  face )
   {
@@ -47,7 +54,23 @@
 
     return result;
   }
+ 
+  static const FT_Service_PsNameRec  cid_service_ps_name =
+  {
+    (FT_PsName_GetFunc) cid_get_postscript_name
+  };
 
+ /*
+  *  SERVICE LIST
+  *
+  */
+  
+  static const FT_ServiceDescRec  cid_services[] =
+  {
+    { FT_SERVICE_ID_POSTSCRIPT_NAME, & cid_service_ps_name },
+    { FT_SERVICE_ID_XF86_NAME,       FT_XF86_FORMAT_CID },
+    { NULL, NULL }
+  };
 
   static FT_Module_Interface
   cid_get_interface( FT_Driver         driver,
@@ -56,10 +79,7 @@
     FT_UNUSED( driver );
     FT_UNUSED( cid_interface );
 
-    if ( ft_strcmp( (const char*)cid_interface, "postscript_name" ) == 0 )
-      return (FT_Module_Interface)cid_get_postscript_name;
-
-    return 0;
+    return ft_service_list_lookup( cid_services, cid_interface );
   }
 
 
--- a/src/pcf/pcfdrivr.c
+++ b/src/pcf/pcfdrivr.c
@@ -44,6 +44,8 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_pcfread
 
+#include FT_SERVICE_BDF_H
+#include FT_SERVICE_XFREE86_NAME_H
 
   typedef struct  PCF_CMapRec_
   {
@@ -471,6 +473,12 @@
   }
 
 
+ /*
+  *
+  *  BDF SERVICE
+  *
+  */
+  
   static FT_Error
   pcf_get_bdf_property( PCF_Face          face,
                         const char*       prop_name,
@@ -502,7 +510,27 @@
     return PCF_Err_Invalid_Argument;
   }
 
+  static FT_Service_BDFRec  pcf_service_bdf =
+  {
+    (FT_BDF_GetCharsetIdFunc)  NULL,  /* unimplemented ? */
+    (FT_BDF_GetPropertyFunc)   pcf_get_bdf_property
+  };
 
+
+ /*
+  *
+  *  SERVICE LIST
+  *
+  */
+
+  static FT_ServiceDescRec  pcf_services[] =
+  {
+    { FT_SERVICE_ID_BDF,       & pcf_service_bdf },
+    { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_PCF },
+    { NULL, NULL }
+  };
+  
+  
   static FT_Module_Interface
   pcf_driver_requester( FT_Module    module,
                         const char*  name )
@@ -509,10 +537,7 @@
   {
     FT_UNUSED( module );
 
-    if ( name && ft_strcmp( name, "get_bdf_property" ) == 0 )
-      return (FT_Module_Interface) pcf_get_bdf_property;
-
-    return NULL;
+    return ft_service_list_lookup( pcf_services, name );
   }
 
 
--- a/src/sfnt/sfdriver.c
+++ b/src/sfnt/sfdriver.c
@@ -33,6 +33,8 @@
 #include "ttpost.h"
 #endif
 
+#include FT_SERVICE_GLYPH_DICT_H
+#include FT_SERVICE_POSTSCRIPT_NAME_H
 
   static void*
   get_sfnt_table( TT_Face      face,
@@ -81,9 +83,13 @@
 
 #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
-
+ /*
+  *  GLYPH DICT SERVICE
+  *
+  */
+  
   static FT_Error
-  get_sfnt_glyph_name( TT_Face     face,
+  sfnt_get_glyph_name( TT_Face     face,
                        FT_UInt     glyph_index,
                        FT_Pointer  buffer,
                        FT_UInt     buffer_max )
@@ -109,8 +115,21 @@
   }
 
 
+  static const FT_Service_GlyphDictRec  sfnt_service_glyph_dict =
+  {
+    (FT_GlyphDict_GetNameFunc)    sfnt_get_glyph_name,
+    (FT_GlyphDict_NameIndexFunc)  NULL
+  };
+
+#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
+
+ /*
+  *  POSTSCRIPT NAME SERVICE
+  *
+  */
+  
   static const char*
-  get_sfnt_postscript_name( TT_Face  face )
+  sfnt_get_ps_name( TT_Face  face )
   {
     FT_Int       n, found_win, found_apple;
     const char*  result = NULL;
@@ -117,8 +136,8 @@
 
 
     /* shouldn't happen, but just in case to avoid memory leaks */
-    if ( face->root.internal->postscript_name )
-      return face->root.internal->postscript_name;
+    if ( face->postscript_name )
+      return face->postscript_name;
 
     /* scan the name table to see whether we have a Postscript name here, */
     /* either in Macintosh or Windows platform encodings                  */
@@ -215,14 +234,33 @@
     }
 
   Exit:
-    face->root.internal->postscript_name = result;
+    face->postscript_name = result;
     return result;
   }
 
+  static const FT_Service_PsNameRec   sfnt_service_ps_name =
+  {
+    (FT_PsName_GetFunc) & sfnt_get_ps_name
+  };
 
-#endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
 
+ /*
+  *  SERVICE LIST
+  *
+  */
+
+  static const FT_ServiceDescRec  sfnt_services[] =
+  {
+    { FT_SERVICE_ID_POSTSCRIPT_NAME, & sfnt_service_ps_name },
+#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
+    { FT_SERVICE_ID_GLYPH_DICT,      & sfnt_service_glyph_dict },
+#endif    
+
+    { NULL, NULL }
+  };  
+
+
   FT_CALLBACK_DEF( FT_Module_Interface )
   sfnt_get_interface( FT_Module    module,
                       const char*  module_interface )
@@ -235,15 +273,7 @@
     if ( ft_strcmp( module_interface, "load_sfnt" ) == 0 )
       return (FT_Module_Interface)tt_face_load_any;
 
-#ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
-    if ( ft_strcmp( module_interface, "glyph_name" ) == 0 )
-      return (FT_Module_Interface)get_sfnt_glyph_name;
-#endif
-
-    if ( ft_strcmp( module_interface, "postscript_name" ) == 0 )
-      return (FT_Module_Interface)get_sfnt_postscript_name;
-
-    return 0;
+    return ft_service_list_lookup( sfnt_services, module_interface );
   }
 
 
--- a/src/truetype/ttdriver.c
+++ b/src/truetype/ttdriver.c
@@ -21,6 +21,7 @@
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_SFNT_H
 #include FT_TRUETYPE_IDS_H
+#include FT_SERVICE_XFREE86_NAME_H
 
 #include "ttdriver.h"
 #include "ttgload.h"
@@ -344,17 +345,26 @@
   /*************************************************************************/
   /*************************************************************************/
 
+  static const FT_ServiceDescRec  tt_services[] =
+  {
+    { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_TRUETYPE },
+    { NULL, NULL }
+  };
 
   static FT_Module_Interface
   tt_get_interface( TT_Driver    driver,
                     const char*  tt_interface )
   {
-    FT_Module     sfntd = FT_Get_Module( driver->root.root.library,
-                                         "sfnt" );
-    SFNT_Service  sfnt;
+    FT_Module_Interface  result;
+    FT_Module            sfntd;
+    SFNT_Service         sfnt;
 
+    result = ft_service_list_lookup( tt_services, tt_interface );
+    if ( result != NULL )
+      return result;
 
     /* only return the default interface from the SFNT module */
+    sfntd = FT_Get_Module( driver->root.root.library,  "sfnt" );
     if ( sfntd )
     {
       sfnt = (SFNT_Service)( sfntd->clazz->module_interface );
--- a/src/type1/t1driver.c
+++ b/src/type1/t1driver.c
@@ -31,6 +31,10 @@
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_POSTSCRIPT_NAMES_H
 
+#include FT_SERVICE_MULTIPLE_MASTERS_H
+#include FT_SERVICE_GLYPH_DICT_H
+#include FT_SERVICE_XFREE86_NAME_H
+#include FT_SERVICE_POSTSCRIPT_NAME_H
 
   /*************************************************************************/
   /*                                                                       */
@@ -41,6 +45,10 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_t1driver
 
+ /*
+  *  GLYPH DICT SERVICE
+  *
+  */
 
   static FT_Error
   t1_get_glyph_name( T1_Face     face,
@@ -69,23 +77,6 @@
   }
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    t1_get_name_index                                                  */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Uses the Type 1 font's `glyph_names' table to find a given glyph   */
-  /*    name's glyph index.                                                */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face       :: A handle to the source face object.                  */
-  /*                                                                       */
-  /*    glyph_name :: The glyph name.                                      */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    Glyph index.  0 means `undefined character code'.                  */
-  /*                                                                       */
   static FT_UInt
   t1_get_name_index( T1_Face     face,
                      FT_String*  glyph_name )
@@ -105,7 +96,18 @@
     return 0;
   }
 
+  static const FT_Service_GlyphDictRec  t1_service_glyph_dict =
+  {
+    (FT_GlyphDict_GetNameFunc)    t1_get_glyph_name,
+    (FT_GlyphDict_NameIndexFunc)  t1_get_name_index
+  };
 
+
+ /*
+  *  POSTSCRIPT NAME SERVICE
+  *
+  */
+
   static const char*
   t1_get_ps_name( T1_Face  face )
   {
@@ -112,34 +114,45 @@
     return (const char*) face->type1.font_name;
   }
 
+  static const FT_Service_PsNameRec  t1_service_ps_name =
+  {
+    (FT_PsName_GetFunc) & t1_get_ps_name
+  };
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    Get_Interface                                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Each driver can provide one or more extensions to the base         */
-  /*    FreeType API.  These can be used to access format specific         */
-  /*    features (e.g., all TrueType/OpenType resources share a common     */
-  /*    file structure and common tables which can be accessed through the */
-  /*    `sfnt' interface), or more simply generic ones (e.g., the          */
-  /*    `postscript names' interface which can be used to retrieve the     */
-  /*     PostScript name of a given glyph index).                          */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    driver       :: A handle to a driver object.                       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    t1_interface :: A string designing the interface.  Examples are    */
-  /*                    `sfnt', `post_names', `charmaps', etc.             */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    A typeless pointer to the extension's interface (normally a table  */
-  /*    of function pointers).  Returns NULL if the requested extension    */
-  /*    isn't available (i.e., wasn't compiled in the driver at build      */
-  /*    time).                                                             */
-  /*                                                                       */
+
+ /*
+  *  MULTIPLE MASTERS SERVICE
+  *
+  */
+
+#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
+  static const FT_Service_MultiMastersRec  t1_service_multi_masters =
+  {
+    (FT_Get_MM_Func)         T1_Get_Multi_Master,
+    (FT_Set_MM_Design_Func)  T1_Set_MM_Design,
+    (FT_Set_MM_Blend_Func)   T1_Set_MM_Blend
+  };
+#endif
+
+
+ /*
+  *  SERVICE LIST
+  *
+  */
+
+  static const FT_ServiceDescRec  t1_services[] =
+  {
+    { FT_SERVICE_ID_POSTSCRIPT_NAME, &t1_service_ps_name },
+    { FT_SERVICE_ID_GLYPH_DICT,      &t1_service_glyph_dict },
+    { FT_SERVICE_ID_XF86_NAME,       FT_XF86_FORMAT_TYPE_1 },
+    
+#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT    
+    { FT_SERVICE_ID_MULTI_MASTERS, &t1_service_multi_masters },
+#endif      
+    { NULL, NULL }
+  };
+
+
   static FT_Module_Interface
   Get_Interface( FT_Driver         driver,
                  const FT_String*  t1_interface )
@@ -147,26 +160,7 @@
     FT_UNUSED( driver );
     FT_UNUSED( t1_interface );
 
-    if ( ft_strcmp( (const char*)t1_interface, "glyph_name" ) == 0 )
-      return (FT_Module_Interface)t1_get_glyph_name;
-
-    if ( ft_strcmp( (const char*)t1_interface, "name_index" ) == 0 )
-      return (FT_Module_Interface)t1_get_name_index;
-
-    if ( ft_strcmp( (const char*)t1_interface, "postscript_name" ) == 0 )
-      return (FT_Module_Interface)t1_get_ps_name;
-
-#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
-    if ( ft_strcmp( (const char*)t1_interface, "get_mm" ) == 0 )
-      return (FT_Module_Interface)T1_Get_Multi_Master;
-
-    if ( ft_strcmp( (const char*)t1_interface, "set_mm_design") == 0 )
-      return (FT_Module_Interface)T1_Set_MM_Design;
-
-    if ( ft_strcmp( (const char*)t1_interface, "set_mm_blend") == 0 )
-      return (FT_Module_Interface)T1_Set_MM_Blend;
-#endif
-    return 0;
+    return ft_service_list_lookup( t1_services, t1_interface );
   }
 
 
--- a/src/type42/t42drivr.c
+++ b/src/type42/t42drivr.c
@@ -41,11 +41,20 @@
 #include "t42error.h"
 #include FT_INTERNAL_DEBUG_H
 
+#include FT_SERVICE_XFREE86_NAME_H
+#include FT_SERVICE_GLYPH_DICT_H
+#include FT_SERVICE_POSTSCRIPT_NAME_H
 
 #undef  FT_COMPONENT
 #define FT_COMPONENT  trace_t42
 
 
+ /*
+  *
+  *  GLYPH DICT SERVICE
+  *
+  */
+  
   static FT_Error
   t42_get_glyph_name( T42_Face    face,
                       FT_UInt     glyph_index,
@@ -73,13 +82,6 @@
   }
 
 
-  static const char*
-  t42_get_ps_name( T42_Face  face )
-  {
-    return (const char*)face->type1.font_name;
-  }
-
-
   static FT_UInt
   t42_get_name_index( T42_Face    face,
                       FT_String*  glyph_name )
@@ -100,6 +102,46 @@
   }
 
 
+  static FT_Service_GlyphDictRec  t42_service_glyph_dict =
+  {
+    (FT_GlyphDict_GetNameFunc)    t42_get_glyph_name,
+    (FT_GlyphDict_NameIndexFunc)  t42_get_name_index
+  };
+
+
+ /*
+  *
+  *  POSTSCRIPT NAME SERVICE
+  *
+  */
+
+  static const char*
+  t42_get_ps_name( T42_Face  face )
+  {
+    return (const char*)face->type1.font_name;
+  }
+
+
+  static FT_Service_PsNameRec  t42_service_ps_name =
+  {
+    (FT_PsName_GetFunc)  t42_get_ps_name
+  };
+
+
+ /*
+  *
+  *  SERVICE LIST
+  *
+  */
+
+  static const FT_ServiceDescRec  t42_services[] =
+  {
+    { FT_SERVICE_ID_GLYPH_DICT,      & t42_service_glyph_dict },
+    { FT_SERVICE_ID_POSTSCRIPT_NAME, & t42_service_ps_name    },
+    { FT_SERVICE_ID_XF86_NAME,       FT_XF86_FORMAT_TYPE_42   },
+    { NULL, NULL }
+  };
+
   static FT_Module_Interface
   T42_Get_Interface( FT_Driver         driver,
                      const FT_String*  t42_interface )
@@ -106,17 +148,7 @@
   {
     FT_UNUSED( driver );
 
-    /* Any additional interface are defined here */
-    if (ft_strcmp( (const char*)t42_interface, "glyph_name" ) == 0 )
-      return (FT_Module_Interface)t42_get_glyph_name;
-
-    if ( ft_strcmp( (const char*)t42_interface, "name_index" ) == 0 )
-      return (FT_Module_Interface)t42_get_name_index;
-
-    if ( ft_strcmp( (const char*)t42_interface, "postscript_name" ) == 0 )
-      return (FT_Module_Interface)t42_get_ps_name;
-
-    return 0;
+    return ft_service_list_lookup( t42_services, t42_interface );
   }