freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] parthw-wip 7236cde: Make branch even for testing.


From: Parth Wazurkar
Subject: [freetype2] parthw-wip 7236cde: Make branch even for testing.
Date: Tue, 31 Jul 2018 16:01:55 -0400 (EDT)

branch: parthw-wip
commit 7236cde177f9c5586e9fd3089b3bc5dc47465d9d
Author: Parth Wazurkar <address@hidden>
Commit: Parth Wazurkar <address@hidden>

    Make branch even for testing.
    
    * For testing modifications to gf, pk and tfm modules.
---
 include/freetype/config/ftconfig.h                 |   4 +-
 include/freetype/config/ftmodule.h                 |   1 +
 include/freetype/freetype.h                        |   3 +-
 include/freetype/ftmodapi.h                        |  20 +-
 include/freetype/ftsystem.h                        |   3 +-
 include/freetype/ftwinfnt.h                        |   2 +-
 include/freetype/internal/ftcalc.h                 |   9 +
 include/freetype/internal/ftserv.h                 |   1 +
 include/freetype/internal/ftstream.h               |  29 +-
 include/freetype/internal/fttrace.h                |   9 +-
 include/freetype/internal/internal.h               |   2 +
 include/freetype/internal/services/svfntfmt.h      |   1 +
 .../freetype/internal/services/svpk.h              |  27 +-
 include/freetype/internal/tfm.h                    | 137 +++++
 include/freetype/ttnameid.h                        |   2 +-
 modules.cfg                                        |  11 +-
 src/gf/gfdrivr.c                                   | 120 ++++-
 src/gf/gfdrivr.h                                   |  19 +-
 src/gf/gflib.c                                     |   6 +-
 src/gf/module.mk                                   |   1 +
 src/gf/rules.mk                                    |   2 +-
 src/{tfm => pk}/README                             |   0
 src/{gf => pk}/module.mk                           |  11 +-
 src/{tfm/tfm.c => pk/pk.c}                         |   8 +-
 src/{tfm/tfm.h => pk/pk.h}                         |  30 +-
 src/{gf/gfdrivr.c => pk/pkdrivr.c}                 | 321 ++++++++----
 src/{gf/gfdrivr.h => pk/pkdrivr.h}                 |  37 +-
 src/{tfm/tfmerror.h => pk/pkerror.h}               |  16 +-
 src/pk/pklib.c                                     | 575 +++++++++++++++++++++
 src/pk/rules.mk                                    |  70 +++
 src/{gf/module.mk => tfm/Jamfile}                  |  30 +-
 src/tfm/module.mk                                  |  11 +-
 src/tfm/rules.mk                                   |  42 +-
 src/tfm/tfm.c                                      |   7 +-
 src/tfm/tfmdrivr.c                                 | 417 ---------------
 src/tfm/tfmdrivr.h                                 |  73 ---
 src/tfm/{tfmerror.h => tfmerr.h}                   |  16 +-
 src/tfm/tfmmod.c                                   |  50 ++
 src/tfm/{tfm.c => tfmmod.h}                        |  24 +-
 src/tfm/{tfmlib.c => tfmobjs.c}                    | 245 +++++----
 src/tfm/tfmobjs.h                                  |  53 ++
 41 files changed, 1585 insertions(+), 860 deletions(-)

diff --git a/include/freetype/config/ftconfig.h 
b/include/freetype/config/ftconfig.h
index b093f6f..3d127f8 100644
--- a/include/freetype/config/ftconfig.h
+++ b/include/freetype/config/ftconfig.h
@@ -457,7 +457,7 @@ FT_BEGIN_HEADER
 
 #ifdef FT2_BUILD_LIBRARY
 
-#if defined( _WIN32 ) && ( defined( _DLL ) || defined( DLL_EXPORT ) )
+#if defined( _WIN32 ) && defined( DLL_EXPORT )
 #define FT_EXPORT( x )  __declspec( dllexport )  x
 #elif defined( __GNUC__ ) && __GNUC__ >= 4
 #define FT_EXPORT( x )  __attribute__(( visibility( "default" ) ))  x
@@ -471,7 +471,7 @@ FT_BEGIN_HEADER
 
 #else
 
-#if defined( FT2_DLLIMPORT )
+#if defined( _WIN32 ) && defined( DLL_IMPORT )
 #define FT_EXPORT( x )  __declspec( dllimport )  x
 #elif defined( __cplusplus )
 #define FT_EXPORT( x )  extern "C"  x
diff --git a/include/freetype/config/ftmodule.h 
b/include/freetype/config/ftmodule.h
index 820c11c..c9adfb6 100644
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -28,5 +28,6 @@ FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
 FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )
 FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )
 FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
+FT_USE_MODULE( FT_Driver_ClassRec, gf_driver_class )
 
 /* EOF */
diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h
index b47b0e4..92a4b44 100644
--- a/include/freetype/freetype.h
+++ b/include/freetype/freetype.h
@@ -642,7 +642,8 @@ FT_BEGIN_HEADER
    *
    * @values:
    *   FT_ENCODING_NONE ::
-   *     The encoding value~0 is reserved.
+   *     The encoding value~0 is reserved for all formats except BDF, PCF,
+   *     and Windows FNT; see below for more information.
    *
    *   FT_ENCODING_UNICODE ::
    *     The Unicode character set.  This value covers all versions of
diff --git a/include/freetype/ftmodapi.h b/include/freetype/ftmodapi.h
index 4900528..c50c9ce 100644
--- a/include/freetype/ftmodapi.h
+++ b/include/freetype/ftmodapi.h
@@ -195,27 +195,31 @@ FT_BEGIN_HEADER
    *   FT_Module_Class
    *
    * @description:
-   *   The module class descriptor.
+   *   The module class descriptor.  While being a public structure
+   *   necessary for FreeType's module bookkeeping, most of the fields are
+   *   essentially internal, not to be used directly by an application.
    *
    * @fields:
    *   module_flags ::
    *     Bit flags describing the module.
    *
    *   module_size ::
-   *     The size of one module object/instance in
-   *     bytes.
+   *     The size of one module object/instance in bytes.
    *
    *   module_name ::
    *     The name of the module.
    *
    *   module_version ::
-   *     The version, as a 16.16 fixed number
-   *     (major.minor).
+   *     The version, as a 16.16 fixed number (major.minor).
    *
    *   module_requires ::
-   *     The version of FreeType this module requires,
-   *     as a 16.16 fixed number (major.minor).  Starts
-   *     at version 2.0, i.e., 0x20000.
+   *     The version of FreeType this module requires, as a 16.16 fixed
+   *     number (major.minor).  Starts at version 2.0, i.e., 0x20000.
+   *
+   *   module_interface ::
+   *     A typeless pointer to a structure (which varies between different
+   *     modules) that holds the module's interface functions.  This is
+   *     essentially what `get_interface' returns.
    *
    *   module_init ::
    *     The initializing function.
diff --git a/include/freetype/ftsystem.h b/include/freetype/ftsystem.h
index 564b4ea..0b415b6 100644
--- a/include/freetype/ftsystem.h
+++ b/include/freetype/ftsystem.h
@@ -320,7 +320,8 @@ FT_BEGIN_HEADER
    *
    *   cursor ::
    *     This field is set and used internally by FreeType when parsing
-   *     frames.
+   *     frames.  In particular, the `FT_GET_XXX' macros use this instead
+   *     of the `pos' field.
    *
    *   limit ::
    *     This field is set and used internally by FreeType when parsing
diff --git a/include/freetype/ftwinfnt.h b/include/freetype/ftwinfnt.h
index 9358368..5d0eb0f 100644
--- a/include/freetype/ftwinfnt.h
+++ b/include/freetype/ftwinfnt.h
@@ -95,7 +95,7 @@ FT_BEGIN_HEADER
    *     second default codepage that most international versions of
    *     Windows have.  It is one of the OEM codepages from
    *
-   *     https://msdn.microsoft.com/en-us/goglobal/bb964655,
+   *     
https://docs.microsoft.com/en-us/windows/desktop/intl/code-page-identifiers ,
    *
    *     and is used for the `DOS boxes', to support legacy applications.
    *     A German Windows version for example usually uses ANSI codepage
diff --git a/include/freetype/internal/ftcalc.h 
b/include/freetype/internal/ftcalc.h
index 02467e9..733b674 100644
--- a/include/freetype/internal/ftcalc.h
+++ b/include/freetype/internal/ftcalc.h
@@ -462,6 +462,15 @@ FT_BEGIN_HEADER
    *
    * Use with care!
    */
+#define ADD_INT( a, b )                           \
+          (FT_Int)( (FT_UInt)(a) + (FT_UInt)(b) )
+#define SUB_INT( a, b )                           \
+          (FT_Int)( (FT_UInt)(a) - (FT_UInt)(b) )
+#define MUL_INT( a, b )                           \
+          (FT_Int)( (FT_UInt)(a) * (FT_UInt)(b) )
+#define NEG_INT( a )                              \
+          (FT_Int)( (FT_UInt)0 - (FT_UInt)(a) )
+
 #define ADD_LONG( a, b )                             \
           (FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) )
 #define SUB_LONG( a, b )                             \
diff --git a/include/freetype/internal/ftserv.h 
b/include/freetype/internal/ftserv.h
index 83e3f26..56fbb9b 100644
--- a/include/freetype/internal/ftserv.h
+++ b/include/freetype/internal/ftserv.h
@@ -511,6 +511,7 @@ FT_BEGIN_HEADER
 #define FT_SERVICE_TT_CMAP_H            <freetype/internal/services/svttcmap.h>
 #define FT_SERVICE_WINFNT_H             <freetype/internal/services/svwinfnt.h>
 #define FT_SERVICE_GF_H                 <freetype/internal/services/svgf.h>
+#define FT_SERVICE_PK_H                 <freetype/internal/services/svpk.h>
 
  /* */
 
diff --git a/include/freetype/internal/ftstream.h 
b/include/freetype/internal/ftstream.h
index c3ab755..aaf8e0b 100644
--- a/include/freetype/internal/ftstream.h
+++ b/include/freetype/internal/ftstream.h
@@ -165,6 +165,10 @@ FT_BEGIN_HEADER
 #define FT_BYTE_U32( p, i, s )  ( FT_UINT32( FT_BYTE_( p, i ) ) << (s) )
 
 
+  /*
+   * `FT_PEEK_XXX' are generic macros to get data from a buffer position.
+   * No safety checks are performed.
+   */
 #define FT_PEEK_SHORT( p )  FT_INT16( FT_BYTE_U16( p, 0, 8 ) | \
                                       FT_BYTE_U16( p, 1, 0 ) )
 
@@ -213,7 +217,10 @@ FT_BEGIN_HEADER
                                           FT_BYTE_U32( p, 1,  8 ) | \
                                           FT_BYTE_U32( p, 0,  0 ) )
 
-
+  /*
+   * `FT_NEXT_XXX' are generic macros to get data from a buffer position
+   * which is then increased appropriately.  No safety checks are performed.
+   */
 #define FT_NEXT_CHAR( buffer )       \
           ( (signed char)*buffer++ )
 
@@ -260,7 +267,11 @@ FT_BEGIN_HEADER
 
   /**************************************************************************
    *
-   * Each GET_xxxx() macro uses an implicit `stream' variable.
+   * The `FT_GET_XXX' macros use an implicit `stream' variable.
+   *
+   * Note that a call to `FT_STREAM_SEEK' or `FT_STREAM_POS' has *no* effect
+   * on `FT_GET_XXX'!  They operate on `stream->pos', while `FT_GET_XXX' use
+   * `stream->cursor'.
    */
 #if 0
 #define FT_GET_MACRO( type )    FT_NEXT_ ## type ( stream->cursor )
@@ -299,10 +310,18 @@ FT_BEGIN_HEADER
 #define FT_GET_ULONG_LE()   FT_GET_MACRO( FT_Stream_GetULongLE, FT_ULong )
 #endif
 
+
 #define FT_READ_MACRO( func, type, var )        \
           ( var = (type)func( stream, &error ), \
             error != FT_Err_Ok )
 
+  /*
+   * The `FT_READ_XXX' macros use implicit `stream' and `error' variables.
+   *
+   * `FT_READ_XXX' can be controlled with `FT_STREAM_SEEK' and
+   * `FT_STREAM_POS'.  They use the full machinery to check whether a read
+   * is valid.
+   */
 #define FT_READ_BYTE( var )       FT_READ_MACRO( FT_Stream_ReadChar, FT_Byte, 
var )
 #define FT_READ_CHAR( var )       FT_READ_MACRO( FT_Stream_ReadChar, FT_Char, 
var )
 #define FT_READ_SHORT( var )      FT_READ_MACRO( FT_Stream_ReadUShort, 
FT_Short, var )
@@ -387,10 +406,10 @@ FT_BEGIN_HEADER
 
   /* Enter a frame of `count' consecutive bytes in a stream.  Returns an */
   /* error if the frame could not be read/accessed.  The caller can use  */
-  /* the FT_Stream_Get_XXX functions to retrieve frame data without      */
+  /* the `FT_Stream_Get_XXX' functions to retrieve frame data without    */
   /* error checks.                                                       */
   /*                                                                     */
-  /* You must _always_ call FT_Stream_ExitFrame() once you have entered  */
+  /* You must _always_ call `FT_Stream_ExitFrame' once you have entered  */
   /* a stream frame!                                                     */
   /*                                                                     */
   FT_BASE( FT_Error )
@@ -415,7 +434,7 @@ FT_BEGIN_HEADER
                           FT_ULong   count,
                           FT_Byte**  pbytes );
 
-  /* release an extract frame (see FT_Stream_ExtractFrame) */
+  /* release an extract frame (see `FT_Stream_ExtractFrame') */
   FT_BASE( void )
   FT_Stream_ReleaseFrame( FT_Stream  stream,
                           FT_Byte**  pbytes );
diff --git a/include/freetype/internal/fttrace.h 
b/include/freetype/internal/fttrace.h
index fc9b7d8..6fee24b 100644
--- a/include/freetype/internal/fttrace.h
+++ b/include/freetype/internal/fttrace.h
@@ -120,9 +120,12 @@ FT_TRACE_DEF( bdflib )
 FT_TRACE_DEF( gfdriver )
 FT_TRACE_DEF( gflib )
 
-  /* GF font components */
-FT_TRACE_DEF( tfmdriver )
-FT_TRACE_DEF( tfmlib )
+  /* TFM helper module components */
+FT_TRACE_DEF( tfmobjs )
+
+  /* PK font components */
+FT_TRACE_DEF( pkdriver )
+FT_TRACE_DEF( pklib )
 
   /* PFR font component */
 FT_TRACE_DEF( pfr )
diff --git a/include/freetype/internal/internal.h 
b/include/freetype/internal/internal.h
index 8261043..c24be48 100644
--- a/include/freetype/internal/internal.h
+++ b/include/freetype/internal/internal.h
@@ -50,6 +50,8 @@
 #define FT_INTERNAL_CFF_TYPES_H           <freetype/internal/cfftypes.h>
 #define FT_INTERNAL_CFF_OBJECTS_TYPES_H   <freetype/internal/cffotypes.h>
 
+#define FT_INTERNAL_TFM_H                 <freetype/internal/tfm.h>
+
 
 #if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
 
diff --git a/include/freetype/internal/services/svfntfmt.h 
b/include/freetype/internal/services/svfntfmt.h
index 9f27c6b..5e03843 100644
--- a/include/freetype/internal/services/svfntfmt.h
+++ b/include/freetype/internal/services/svfntfmt.h
@@ -43,6 +43,7 @@ FT_BEGIN_HEADER
 #define FT_FONT_FORMAT_PFR       "PFR"
 #define FT_FONT_FORMAT_WINFNT    "Windows FNT"
 #define FT_FONT_FORMAT_GF        "GF"
+#define FT_FONT_FORMAT_PK        "PK"
 
   /* */
 
diff --git a/src/tfm/tfm.c b/include/freetype/internal/services/svpk.h
similarity index 65%
copy from src/tfm/tfm.c
copy to include/freetype/internal/services/svpk.h
index 26a58d9..993cc7c 100644
--- a/src/tfm/tfm.c
+++ b/include/freetype/internal/services/svpk.h
@@ -1,10 +1,10 @@
 /****************************************************************************
  *
- * tfm.c
+ * svpk.h
  *
- *   FreeType font driver for TeX's TFM FONT files
+ *   The FreeType PK services (specification).
  *
- * Copyright 1996-2018 by
+ * Copyright 2003-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,12 +16,25 @@
  */
 
 
-#define FT_MAKE_OPTION_SINGLE_OBJECT
+#ifndef SVPK_H_
+#define SVPK_H_
 
-#include <ft2build.h>
 
-#include "tfmlib.c"
-#include "tfmdrivr.c"
+#include FT_INTERNAL_SERVICE_H
+
+
+FT_BEGIN_HEADER
+
+
+#define FT_SERVICE_ID_PK  "pk"
+
+  /* */
+
+
+FT_END_HEADER
+
+
+#endif /* SVPK_H_ */
 
 
 /* END */
diff --git a/include/freetype/internal/tfm.h b/include/freetype/internal/tfm.h
new file mode 100644
index 0000000..895786e
--- /dev/null
+++ b/include/freetype/internal/tfm.h
@@ -0,0 +1,137 @@
+/****************************************************************************
+ *
+ * tfm.h
+ *
+ *   Auxiliary functions and data structures related to TFM metric files
+ *   (specification).
+ *
+ * Copyright 1996-2018 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#ifndef TFM_H_
+#define TFM_H_
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_OBJECTS_H
+#include FT_INTERNAL_HASH_H
+#include FT_INTERNAL_TRUETYPE_TYPES_H
+
+
+
+FT_BEGIN_HEADER
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /***                TFM FONT INFORMATION STRUCTURES                    ***/
+  /***                                                                   ***/
+  /***                                                                   ***/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  typedef struct  TFM_FontInfoRec_
+  {
+    /* Font Info */
+    FT_Long        cs; /* Check Sum */
+    /* Metrics */
+    FT_ULong       ds; /* Design Size */
+    FT_UInt        design_size;
+    FT_UInt        slant;
+    FT_UInt        begin_char, end_char;
+    FT_Long        *width, *height, *depth;
+    /* Font bounding box */
+    FT_UInt        font_bbx_w, font_bbx_h;
+    FT_UInt        font_bbx_xoff, font_bbx_yoff;
+
+  } TFM_FontInfoRec, *TFM_FontInfo;
+
+  #define RDS2PT(rds)    (tfm->design_size * ((FT_Long)(rds)/(FT_Long)(1<<20)))
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                            TFM PARSER                         *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  typedef struct TFM_ParserRec_*  TFM_Parser;
+
+  /**************************************************************************
+   *
+   * @struct:
+   *   TFM_ParserRec
+   *
+   * @description:
+   *   An TFM_Parser is a parser for the TFM files.
+   *
+   * @fields:
+   *   memory ::
+   *     The object used for memory operations (alloc and
+   *     realloc).
+   *
+   *   stream ::
+   *     This is an FT_Stream object.
+   *
+   *   FontInfo ::
+   *     The result will be stored here.
+   */
+  typedef struct  TFM_ParserRec_
+  {
+    FT_Memory     memory;
+    FT_Stream     stream;
+
+    TFM_FontInfo  FontInfo;
+
+    void*         user_data;  /* To be checked for compatibility */
+
+  } TFM_ParserRec;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                        TFM Module Interface                   *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  typedef struct  TFM_ServiceRec_
+  {
+    FT_Error
+    (*init)( TFM_Parser  parser,
+             FT_Memory   memory,
+             FT_Stream   stream );
+
+    FT_Error
+    (*parse_metrics)( TFM_Parser  parser );
+
+    void
+    (*done)( TFM_Parser  parser );
+
+  } TFM_ServiceRec, *TFM_Service;
+
+  /* backward compatible type definition */
+  typedef TFM_ServiceRec   TFM_Interface;
+
+
+FT_END_HEADER
+
+#endif /* PSAUX_H_ */
+
+
+/* END */
diff --git a/include/freetype/ttnameid.h b/include/freetype/ttnameid.h
index 16e6b92..f71516c 100644
--- a/include/freetype/ttnameid.h
+++ b/include/freetype/ttnameid.h
@@ -437,7 +437,7 @@ FT_BEGIN_HEADER
    *
    *   The canonical source for Microsoft's IDs is
    *
-   *     https://www.microsoft.com/globaldev/reference/lcid-all.mspx ,
+   *     
https://docs.microsoft.com/en-us/windows/desktop/Intl/language-identifier-constants-and-strings
 ,
    *
    *   however, we only provide macros for language identifiers present in
    *   the OpenType specification: Microsoft has abandoned the concept of
diff --git a/modules.cfg b/modules.cfg
index 62dbba7..1003073 100644
--- a/modules.cfg
+++ b/modules.cfg
@@ -68,10 +68,10 @@ FONT_MODULES += pcf
 FONT_MODULES += bdf
 
 # GF font driver.
-#FONT_MODULES += gf
+FONT_MODULES += gf
 
-# TFM font driver.
-FONT_MODULES += tfm
+# PK font driver.
+FONT_MODULES += pk
 
 # SFNT files support.  If used without `truetype' or `cff', it supports
 # bitmap-only fonts within an SFNT wrapper.
@@ -143,6 +143,11 @@ AUX_MODULES += bzip2
 # This module depends on `psnames'.
 AUX_MODULES += psaux
 
+# Auxiliary METAFONT driver component to share common code.
+#
+# TFM Module.
+AUX_MODULES += tfm
+
 # Support for PostScript glyph names.
 #
 # This module can be controlled in ftconfig.h
diff --git a/src/gf/gfdrivr.c b/src/gf/gfdrivr.c
index e3ee126..5cebaee 100644
--- a/src/gf/gfdrivr.c
+++ b/src/gf/gfdrivr.c
@@ -21,6 +21,7 @@
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_TRUETYPE_IDS_H
+#include FT_INTERNAL_TFM_H
 
 #include FT_SERVICE_GF_H
 #include FT_SERVICE_FONT_FORMAT_H
@@ -164,10 +165,22 @@
     GF_Glyph    go=NULL;
     FT_UInt16   i,count;
 
+    TFM_Service tfm;
+
     FT_UNUSED( num_params );
     FT_UNUSED( params );
 
 
+    face->tfm = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
+                                           "tfm" );
+    tfm = (TFM_Service)face->tfm;
+    if ( !tfm )
+    {
+      FT_ERROR(( "GF_Face_Init: cannot access `tfm' module\n" ));
+      error = FT_THROW( Missing_Module );
+      goto Exit;
+    }
+
     FT_TRACE2(( "GF driver\n" ));
 
     /* load font */
@@ -240,17 +253,21 @@
 
     {
       FT_Bitmap_Size*  bsize = gfface->available_sizes;
-      /* FT_UShort        x_res, y_res; */
+      FT_UShort        x_res, y_res;
 
       bsize->height = (FT_Short) face->gf_glyph->font_bbx_h ;
       bsize->width  = (FT_Short) face->gf_glyph->font_bbx_w ;
-      bsize->size   = (FT_Pos)   face->gf_glyph->ds << 6    ;
+      bsize->size   = (FT_Pos)   FT_MulDiv( FT_ABS( face->gf_glyph->ds ),
+                                     64 * 7200,
+                                     72270L );
 
-      /* x_res = toint( go->hppp * 72.27 ); */
-      /* y_res = toint( go->vppp * 72.27 ); */
+      x_res = toint( go->hppp * 72.27 );
+      y_res = toint( go->vppp * 72.27 );
 
-      bsize->y_ppem = (FT_Pos)(bsize->size/10) << 6 ;
-      bsize->x_ppem = (FT_Pos)bsize->y_ppem ;
+      bsize->y_ppem = (FT_Pos) toint((face->gf_glyph->ds * y_res)/ 72.27) << 6 
;
+      bsize->x_ppem = (FT_Pos)FT_MulDiv( bsize->y_ppem,
+                                         x_res,
+                                         y_res ); ;
     }
 
     /* Charmaps */
@@ -373,7 +390,7 @@
 
     FT_TRACE1(( "GF_Glyph_Load: glyph index %d\n", glyph_index ));
 
-    if ( glyph_index < 0 )
+    if ( (FT_Int)glyph_index < 0 )
       glyph_index = 0;
 
     if ((glyph_index < go->code_min) || (go->code_max < glyph_index))
@@ -427,6 +444,93 @@
     return error;
   }
 
+  FT_LOCAL_DEF( void )
+  TFM_Done_Metrics( FT_Memory     memory,
+                    TFM_FontInfo  fi )
+  {
+    FT_FREE(fi->width);
+    FT_FREE(fi->height);
+    FT_FREE(fi->depth);
+    FT_FREE( fi );
+  }
+
+  /* parse a TFM metrics file */
+  FT_LOCAL_DEF( FT_Error )
+  TFM_Read_Metrics( FT_Face    gf_face,
+                    FT_Stream  stream )
+  {
+    TFM_Service    tfm;
+    FT_Memory      memory  = stream->memory;
+    TFM_ParserRec  parser;
+    TFM_FontInfo   fi      = NULL;
+    FT_Error       error   = FT_ERR( Unknown_File_Format );
+    GF_Face        face    = (GF_Face)gf_face;
+    GF_Glyph       gf_glyph= face->gf_glyph;
+
+
+    if ( face->tfm_data )
+    {
+      FT_TRACE1(( "TFM_Read_Metrics:"
+                  " Freeing previously attached metrics data.\n" ));
+      TFM_Done_Metrics( memory, (TFM_FontInfo)face->tfm_data );
+
+      face->tfm_data = NULL;
+    }
+
+    if ( FT_NEW( fi ) )
+      goto Exit;
+
+    FT_TRACE4(( "TFM_Read_Metrics: Invoking TFM_Service.\n" ));
+
+    tfm = (TFM_Service)face->tfm;
+
+    /* Initialise TFM Service */
+    error = tfm->init( &parser,
+                       memory,
+                       stream );
+
+    if ( !error )
+    {
+      FT_TRACE4(( "TFM_Read_Metrics: Initialised tfm metric data.\n" ));
+      parser.FontInfo  = fi;
+      parser.user_data = gf_glyph;
+
+      error = tfm->parse_metrics( &parser );
+      if( !error )
+        FT_TRACE4(( "TFM_Read_Metrics: parsing TFM metric information done.\n" 
));
+
+      FT_TRACE6(( "TFM_Read_Metrics: TFM Metric Information:\n"
+                  "                  Check Sum  : %ld\n"
+                  "                  Design Size: %ld\n"
+                  "                  Begin Char : %d\n"
+                  "                  End Char   : %d\n"
+                  "                  font_bbx_w : %d\n"
+                  "                  font_bbx_h : %d\n"
+                  "                  slant      : %d\n", parser.FontInfo->cs, 
parser.FontInfo->design_size, parser.FontInfo->begin_char,
+                                                         
parser.FontInfo->end_char, parser.FontInfo->font_bbx_w,
+                                                         
parser.FontInfo->font_bbx_h, parser.FontInfo->slant ));
+      tfm->done( &parser );
+    }
+
+    if ( !error )
+    {
+      /* Modify GF_Glyph data according to TFM metric values */
+
+      /*face->gf_glyph->font_bbx_w = fi->font_bbx_w;
+      face->gf_glyph->font_bbx_h = fi->font_bbx_h;
+      */
+
+      face->tfm_data       = fi;
+      fi                   = NULL;
+    }
+
+  Exit:
+    if ( fi )
+      TFM_Done_Metrics( memory, fi );
+
+    return error;
+  }
+
  /*
   *
   * SERVICES LIST
@@ -483,7 +587,7 @@
     GF_Glyph_Load,              /* FT_Slot_LoadFunc  load_glyph */
 
     NULL,                       /* FT_Face_GetKerningFunc   get_kerning  */
-    NULL,                       /* FT_Face_AttachFunc       attach_file  */
+    TFM_Read_Metrics,           /* FT_Face_AttachFunc       attach_file  */
     NULL,                       /* FT_Face_GetAdvancesFunc  get_advances */
 
     GF_Size_Request,           /* FT_Size_RequestFunc  request_size */
diff --git a/src/gf/gfdrivr.h b/src/gf/gfdrivr.h
index 01fe0d3..0dc631a 100644
--- a/src/gf/gfdrivr.h
+++ b/src/gf/gfdrivr.h
@@ -30,11 +30,11 @@ FT_BEGIN_HEADER
   /* BitmapRec for GF format specific glyphs  */
   typedef struct GF_BitmapRec_
   {
-    FT_UInt              bbx_width, bbx_height;
-    FT_UInt              off_x, off_y;
-    FT_UInt              mv_x,  mv_y;
-    FT_Byte              *bitmap;
-    FT_UInt              raster;
+    FT_UInt         bbx_width, bbx_height;
+    FT_UInt         off_x, off_y;
+    FT_UInt         mv_x,  mv_y;
+    FT_Byte         *bitmap;
+    FT_UInt         raster;
 
   } GF_BitmapRec, *GF_Bitmap;
 
@@ -43,7 +43,7 @@ FT_BEGIN_HEADER
   {
     FT_UInt         code_min, code_max;
     GF_Bitmap       bm_table;
-    FT_UInt         ds, hppp, vppp;
+    FT_Int          ds, hppp, vppp;
     FT_UInt         font_bbx_w, font_bbx_h;
     FT_UInt         font_bbx_xoff, font_bbx_yoff;
 
@@ -52,8 +52,11 @@ FT_BEGIN_HEADER
 
   typedef struct  GF_FaceRec_
   {
-    FT_FaceRec        root;
-    GF_Glyph          gf_glyph;
+    FT_FaceRec      root;
+    GF_Glyph        gf_glyph;
+
+    const void*     tfm;
+    const void*     tfm_data;
 
   } GF_FaceRec, *GF_Face;
 
diff --git a/src/gf/gflib.c b/src/gf/gflib.c
index 323190d..25bb3b6 100644
--- a/src/gf/gflib.c
+++ b/src/gf/gflib.c
@@ -317,7 +317,7 @@ FT_Byte  bit_table[] = {
     GF_Glyph        go;
     GF_Bitmap       bm;
     FT_Byte         instr, d, pre, id, k, code;
-    FT_ULong        ds, check_sum, hppp, vppp;
+    FT_Long         ds, check_sum, hppp, vppp;
     FT_Long         min_m, max_m, min_n, max_n, w;
     FT_UInt         dx, dy;
     FT_Long         ptr_post, ptr_p, ptr, optr;
@@ -334,7 +334,6 @@ FT_Byte  bit_table[] = {
     pre = READ_UINT1( stream );
     if (pre != GF_PRE)
     {
-      FT_ERROR(( "gf_load_font: missing GF_PRE(247) field\n" ));
       error = FT_THROW( Unknown_File_Format );
       goto Exit;
     }
@@ -342,7 +341,6 @@ FT_Byte  bit_table[] = {
     id = READ_UINT1( stream );
     if (id != GF_ID)
     {
-      FT_ERROR(( "gf_load_font: missing GF_ID(131) field\n" ));
       error = FT_THROW( Unknown_File_Format );
       goto Exit;
     }
@@ -428,6 +426,8 @@ FT_Byte  bit_table[] = {
     min_n     = READ_INT4( stream );
     max_n     = READ_INT4( stream );
 
+    FT_TRACE5(( "gf_load_font: checksum is %ld\n",check_sum ));
+
     if( ptr_p < 0 )     /* Defined to use ptr_p */
     {
       FT_ERROR(( "gf_load_font: invalid pointer in postamble\n" ));
diff --git a/src/gf/module.mk b/src/gf/module.mk
index 1eb5346..bf9f2c2 100644
--- a/src/gf/module.mk
+++ b/src/gf/module.mk
@@ -12,6 +12,7 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
+
 FTMODULE_H_COMMANDS += GF_DRIVER
 
 define GF_DRIVER
diff --git a/src/gf/rules.mk b/src/gf/rules.mk
index 3882e2f..a261541 100644
--- a/src/gf/rules.mk
+++ b/src/gf/rules.mk
@@ -26,7 +26,7 @@ GF_COMPILE := $(CC) $(ANSIFLAGS)                            \
 
 # gf driver sources (i.e., C files)
 #
-GF_DRV_SRC :=  $(GF_DIR)/gflib.c \
+GF_DRV_SRC := $(GF_DIR)/gflib.c \
                $(GF_DIR)/gfdrivr.c
 
 
diff --git a/src/tfm/README b/src/pk/README
similarity index 100%
rename from src/tfm/README
rename to src/pk/README
diff --git a/src/gf/module.mk b/src/pk/module.mk
similarity index 65%
copy from src/gf/module.mk
copy to src/pk/module.mk
index 1eb5346..4a984b0 100644
--- a/src/gf/module.mk
+++ b/src/pk/module.mk
@@ -1,5 +1,5 @@
 #
-# FreeType 2 GF Font module definition
+# FreeType 2 PK Font module definition
 #
 
 
@@ -12,11 +12,12 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
-FTMODULE_H_COMMANDS += GF_DRIVER
 
-define GF_DRIVER
-$(OPEN_DRIVER) FT_Driver_ClassRec, gf_driver_class $(CLOSE_DRIVER)
-$(ECHO_DRIVER)gf        $(ECHO_DRIVER_DESC)METAFONT bitmap 
fonts$(ECHO_DRIVER_DONE)
+FTMODULE_H_COMMANDS += PK_DRIVER
+
+define PK_DRIVER
+$(OPEN_DRIVER) FT_Driver_ClassRec, pk_driver_class $(CLOSE_DRIVER)
+$(ECHO_DRIVER)pk        $(ECHO_DRIVER_DESC)METAFONT bitmap 
fonts$(ECHO_DRIVER_DONE)
 endef
 
 # EOF
diff --git a/src/tfm/tfm.c b/src/pk/pk.c
similarity index 84%
copy from src/tfm/tfm.c
copy to src/pk/pk.c
index 26a58d9..79c11cb 100644
--- a/src/tfm/tfm.c
+++ b/src/pk/pk.c
@@ -1,8 +1,8 @@
 /****************************************************************************
  *
- * tfm.c
+ * pk.c
  *
- *   FreeType font driver for TeX's TFM FONT files
+ *   FreeType font driver for TeX's PK FONT files.
  *
  * Copyright 1996-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
@@ -20,8 +20,8 @@
 
 #include <ft2build.h>
 
-#include "tfmlib.c"
-#include "tfmdrivr.c"
+#include "pklib.c"
+#include "pkdrivr.c"
 
 
 /* END */
diff --git a/src/tfm/tfm.h b/src/pk/pk.h
similarity index 70%
rename from src/tfm/tfm.h
rename to src/pk/pk.h
index ab7888a..d9c5a72 100644
--- a/src/tfm/tfm.h
+++ b/src/pk/pk.h
@@ -1,8 +1,8 @@
 /****************************************************************************
  *
- * tfm.h
+ * pk.h
  *
- *   FreeType font driver for TeX's TFM FONT files
+ *   FreeType font driver for TeX's PK FONT files.
  *
  * Copyright 1996-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
@@ -16,8 +16,8 @@
  */
 
 
-#ifndef TFM_H_
-#define TFM_H_
+#ifndef PK_H_
+#define PK_H_
 
 #include <ft2build.h>
 #include FT_INTERNAL_OBJECTS_H
@@ -27,13 +27,22 @@
 
 FT_BEGIN_HEADER
 
+#define  FONT_DRIVER_PK   1
+
+#define  PK_PRE   247
+#define  PK_ID    89
+#define  PK_XXX1  240
+#define  PK_XXX2  241
+#define  PK_XXX3  242
+#define  PK_XXX4  243
+#define  PK_YYY   244
+#define  PK_POST  245
+#define  PK_NO_OP 246
+
+#define toint(x)  (int)(((x)>0)?(x+0.5):(x-0.5))
+
 /* Temporary TO BE REMOVED */
 
-/* IMPORTANT ASSUMPTION:
- *   char:  at least 8 bits
- *   int:   at least 16 bits
- *   long:  at least 32 bits
- */
 typedef  char           INT1;
 typedef  unsigned char  UINT1;
 typedef  int            INT2;
@@ -43,10 +52,11 @@ typedef  unsigned long  UINT3;
 typedef  long           INT4;
 typedef  unsigned long  UINT4;
 
+
 FT_END_HEADER
 
 
-#endif /* TFM_H_ */
+#endif /* PK_H_ */
 
 
 /* END */
diff --git a/src/gf/gfdrivr.c b/src/pk/pkdrivr.c
similarity index 51%
copy from src/gf/gfdrivr.c
copy to src/pk/pkdrivr.c
index e3ee126..306d29d 100644
--- a/src/gf/gfdrivr.c
+++ b/src/pk/pkdrivr.c
@@ -1,8 +1,8 @@
 /****************************************************************************
  *
- * gfdrivr.c
+ * pkdrivr.c
  *
- *   FreeType font driver for METAFONT GF FONT files
+ *   FreeType font driver for TeX's PK FONT files.
  *
  * Copyright 1996-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
@@ -21,13 +21,14 @@
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_OBJECTS_H
 #include FT_TRUETYPE_IDS_H
+#include FT_INTERNAL_TFM_H
 
-#include FT_SERVICE_GF_H
+#include FT_SERVICE_PK_H
 #include FT_SERVICE_FONT_FORMAT_H
 
-#include "gf.h"
-#include "gfdrivr.h"
-#include "gferror.h"
+#include "pk.h"
+#include "pkdrivr.h"
+#include "pkerror.h"
 
 
   /**************************************************************************
@@ -37,49 +38,48 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_gfdriver
+#define FT_COMPONENT  trace_pkdriver
 
 
-  typedef struct  GF_CMapRec_
+  typedef struct  PK_CMapRec_
   {
     FT_CMapRec        cmap;
     FT_UInt32         bc;       /* Beginning Character */
     FT_UInt32         ec;       /* End Character */
-  } GF_CMapRec, *GF_CMap;
+  } PK_CMapRec, *PK_CMap;
 
 
   FT_CALLBACK_DEF( FT_Error )
-  gf_cmap_init(  FT_CMap     gfcmap,
+  pk_cmap_init(  FT_CMap     pkcmap,
                  FT_Pointer  init_data )
   {
-    GF_CMap  cmap = (GF_CMap)gfcmap;
-    GF_Face  face = (GF_Face)FT_CMAP_FACE( cmap );
+    PK_CMap  cmap = (PK_CMap)pkcmap;
+    PK_Face  face = (PK_Face)FT_CMAP_FACE( cmap );
     FT_UNUSED( init_data );
 
-    cmap->bc     = face->gf_glyph->code_min;
-    cmap->ec     = face->gf_glyph->code_max;
+    cmap->bc     = face->pk_glyph->code_min;
+    cmap->ec     = face->pk_glyph->code_max;
 
     return FT_Err_Ok;
   }
 
 
   FT_CALLBACK_DEF( void )
-  gf_cmap_done( FT_CMap  gfcmap )
+  pk_cmap_done( FT_CMap  pkcmap )
   {
-    GF_CMap  cmap = (GF_CMap)gfcmap;
+    PK_CMap  cmap = (PK_CMap)pkcmap;
 
     cmap->bc     =  0;
     cmap->ec     = -1;
-
   }
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  gf_cmap_char_index(  FT_CMap    gfcmap,
+  pk_cmap_char_index(  FT_CMap    pkcmap,
                        FT_UInt32  char_code )
   {
     FT_UInt  gindex = 0;
-    GF_CMap  cmap   = (GF_CMap)gfcmap;
+    PK_CMap  cmap   = (PK_CMap)pkcmap;
 
     char_code -= cmap->bc;
 
@@ -90,10 +90,10 @@
   }
 
   FT_CALLBACK_DEF( FT_UInt )
-  gf_cmap_char_next(  FT_CMap     gfcmap,
-                      FT_UInt32  *achar_code )
+  pk_cmap_char_next(  FT_CMap    pkcmap,
+                       FT_UInt32  *achar_code )
   {
-    GF_CMap    cmap   = (GF_CMap)gfcmap;
+    PK_CMap    cmap   = (PK_CMap)pkcmap;
     FT_UInt    gindex = 0;
     FT_UInt32  result = 0;
     FT_UInt32  char_code = *achar_code + 1;
@@ -120,22 +120,22 @@
 
 
   static
-  const FT_CMap_ClassRec  gf_cmap_class =
+  const FT_CMap_ClassRec  pk_cmap_class =
   {
-    sizeof ( GF_CMapRec ),
-    gf_cmap_init,
-    gf_cmap_done,
-    gf_cmap_char_index,
-    gf_cmap_char_next,
+    sizeof ( PK_CMapRec ),
+    pk_cmap_init,
+    pk_cmap_done,
+    pk_cmap_char_index,
+    pk_cmap_char_next,
 
     NULL, NULL, NULL, NULL, NULL
   };
 
 
   FT_CALLBACK_DEF( void )
-  GF_Face_Done( FT_Face        gfface )         /* GF_Face */
+  PK_Face_Done( FT_Face        pkface )         /* PK_Face */
   {
-    GF_Face    face   = (GF_Face)gfface;
+    PK_Face    face   = (PK_Face)pkface;
     FT_Memory  memory;
 
 
@@ -144,54 +144,64 @@
 
     memory = FT_FACE_MEMORY( face );
 
-    gf_free_font( face );
-
-    FT_FREE( gfface->available_sizes );
+    pk_free_font( face );
 
+    FT_FREE( pkface->available_sizes );
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
-  GF_Face_Init(  FT_Stream      stream,
-                 FT_Face        gfface,         /* GF_Face */
-                 FT_Int         face_index,
-                 FT_Int         num_params,
-                 FT_Parameter*  params )
+  PK_Face_Init(   FT_Stream      stream,
+                  FT_Face        pkface,         /* PK_Face */
+                  FT_Int         face_index,
+                  FT_Int         num_params,
+                  FT_Parameter*  params )
   {
-    GF_Face     face   = (GF_Face)gfface;
+    PK_Face     face   = (PK_Face)pkface;
     FT_Error    error  = FT_Err_Ok;
     FT_Memory   memory = FT_FACE_MEMORY( face );
-    GF_Glyph    go=NULL;
+    PK_Glyph    go=NULL;
     FT_UInt16   i,count;
 
+    TFM_Service tfm;
+
     FT_UNUSED( num_params );
     FT_UNUSED( params );
 
+    face->tfm = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
+                                           "tfm" );
+    tfm = (TFM_Service)face->tfm;
+    if ( !tfm )
+    {
+      FT_ERROR(( "GF_Face_Init: cannot access `tfm' module\n" ));
+      error = FT_THROW( Missing_Module );
+      goto Exit;
+    }
 
-    FT_TRACE2(( "GF driver\n" ));
+    FT_TRACE2(( "PK driver\n" ));
 
     /* load font */
-    error = gf_load_font( stream, memory, &go );
+    error = pk_load_font( stream, memory, &go );
     if ( FT_ERR_EQ( error, Unknown_File_Format ) )
     {
-      FT_TRACE2(( "  not a GF file\n" ));
+      FT_TRACE2(( "  not a PK file\n" ));
       goto Fail;
     }
     else if ( error )
       goto Exit;
 
-    /* we have a gf font: let's construct the face object */
-    face->gf_glyph = go ;
+    /* we have a pk font: let's construct the face object */
+    face->pk_glyph = go ;
 
     /* sanity check */
-    if ( !face->gf_glyph->bm_table )
+    if ( !face->pk_glyph->bm_table )
     {
       FT_TRACE2(( "glyph bitmaps not allocated\n" ));
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
-    /* GF cannot have multiple faces in a single font file.
+    /* PK cannot have multiple faces in a single font file.
      * XXX: non-zero face_index is already invalid argument, but
      *      Type1, Type42 driver has a convention to return
      *      an invalid argument error when the font could be
@@ -199,58 +209,62 @@
      */
     if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 )
     {
-      FT_ERROR(( "GF_Face_Init: invalid face index\n" ));
-      GF_Face_Done( gfface );
+      FT_ERROR(( "PK_Face_Init: invalid face index\n" ));
+      PK_Face_Done( pkface );
       return FT_THROW( Invalid_Argument );
     }
 
     /* we now need to fill the root FT_Face fields */
     /* with relevant information                   */
 
-    gfface->num_faces       = 1;
-    gfface->face_index      = 0;
-    gfface->face_flags     |= FT_FACE_FLAG_FIXED_SIZES |
+    pkface->num_faces       = 1;
+    pkface->face_index      = 0;
+    pkface->face_flags     |= FT_FACE_FLAG_FIXED_SIZES |
                              FT_FACE_FLAG_HORIZONTAL ;
     /*
-     * XXX: TO-DO: gfface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
+     * XXX: TO-DO: pkface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
      * XXX: I have to check for this.
      */
 
-    gfface->family_name     = NULL;
+    pkface->family_name     = NULL;
     count=0;
     for (i = 0; i < 256; i++)
     {
       if(go->bm_table[i].bitmap != NULL)
         count++;
     }
-    gfface->num_glyphs      = (FT_Long)count;
+    pkface->num_glyphs      = (FT_Long)count;
 
-    FT_TRACE4(( "  number of glyphs: allocated %d\n",gfface->num_glyphs ));
+    FT_TRACE4(( "  number of glyphs: allocated %d\n",pkface->num_glyphs ));
 
-    if ( gfface->num_glyphs <= 0 )
+    if ( pkface->num_glyphs <= 0 )
     {
-      FT_ERROR(( "GF_Face_Init: glyphs not allocated\n" ));
+      FT_ERROR(( "PK_Face_Init: glyphs not allocated\n" ));
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
-    gfface->num_fixed_sizes = 1;
-    if ( FT_NEW_ARRAY( gfface->available_sizes, 1 ) )
+    pkface->num_fixed_sizes = 1;
+    if ( FT_NEW_ARRAY( pkface->available_sizes, 1 ) )
       goto Exit;
 
     {
-      FT_Bitmap_Size*  bsize = gfface->available_sizes;
-      /* FT_UShort        x_res, y_res; */
-
-      bsize->height = (FT_Short) face->gf_glyph->font_bbx_h ;
-      bsize->width  = (FT_Short) face->gf_glyph->font_bbx_w ;
-      bsize->size   = (FT_Pos)   face->gf_glyph->ds << 6    ;
-
-      /* x_res = toint( go->hppp * 72.27 ); */
-      /* y_res = toint( go->vppp * 72.27 ); */
-
-      bsize->y_ppem = (FT_Pos)(bsize->size/10) << 6 ;
-      bsize->x_ppem = (FT_Pos)bsize->y_ppem ;
+      FT_Bitmap_Size*  bsize = pkface->available_sizes;
+      FT_UShort        x_res, y_res;
+
+      bsize->height = (FT_Short) face->pk_glyph->font_bbx_h ;
+      bsize->width  = (FT_Short) face->pk_glyph->font_bbx_w ;
+      bsize->size   = (FT_Pos)   FT_MulDiv( FT_ABS( face->pk_glyph->ds ),
+                                     64 * 7200,
+                                     72270L );
+
+      x_res = toint( face->pk_glyph->hppp * 72.27 );
+      y_res = toint( face->pk_glyph->vppp * 72.27 );
+
+      bsize->y_ppem = (FT_Pos) toint((face->pk_glyph->ds * y_res)/ 72.27) << 6 
;
+      bsize->x_ppem = (FT_Pos)FT_MulDiv( bsize->y_ppem,
+                                         x_res,
+                                         y_res ); ;
     }
 
     /* Charmaps */
@@ -263,7 +277,7 @@
       charmap.encoding_id = TT_MS_ID_UNICODE_CS;
       charmap.face        = FT_FACE( face );
 
-      error = FT_CMap_New( &gf_cmap_class, NULL, &charmap, NULL );
+      error = FT_CMap_New( &pk_cmap_class, NULL, &charmap, NULL );
 
       if ( error )
         goto Exit;
@@ -280,16 +294,16 @@
     return error;
 
   Fail:
-    GF_Face_Done( gfface );
+    PK_Face_Done( pkface );
     return FT_THROW( Unknown_File_Format );
   }
 
   FT_CALLBACK_DEF( FT_Error )
-  GF_Size_Select(  FT_Size   size,
+  PK_Size_Select(  FT_Size   size,
                    FT_ULong  strike_index )
   {
-    GF_Face     face  = (GF_Face)size->face;
-    GF_Glyph    go    = face->gf_glyph;
+    PK_Face     face  = (PK_Face)size->face;
+    PK_Glyph    go    = face->pk_glyph;
     FT_UNUSED( strike_index );
 
     FT_Select_Metrics( size->face, 0 );
@@ -299,14 +313,13 @@
     size->metrics.max_advance = go->font_bbx_w * 64;
 
     return FT_Err_Ok;
-
   }
 
   FT_CALLBACK_DEF( FT_Error )
-  GF_Size_Request(  FT_Size          size,
-                    FT_Size_Request  req )
+  PK_Size_Request( FT_Size          size,
+                   FT_Size_Request  req )
   {
-    GF_Face           face    = (GF_Face)size->face;
+    PK_Face           face    = (PK_Face)size->face;
     FT_Bitmap_Size*   bsize   = size->face->available_sizes;
     FT_Error          error   = FT_ERR( Invalid_Pixel_Size );
     FT_Long           height;
@@ -323,7 +336,7 @@
       break;
 
     case FT_SIZE_REQUEST_TYPE_REAL_DIM:
-      if ( height == face->gf_glyph->font_bbx_h )
+      if ( height == face->pk_glyph->font_bbx_h )
         error = FT_Err_Ok;
       break;
 
@@ -335,26 +348,26 @@
     if ( error )
       return error;
     else
-      return GF_Size_Select( size, 0 );
+      return PK_Size_Select( size, 0 );
   }
 
 
 
   FT_CALLBACK_DEF( FT_Error )
-  GF_Glyph_Load(  FT_GlyphSlot  slot,
-                  FT_Size       size,
-                  FT_UInt       glyph_index,
-                  FT_Int32      load_flags )
+  PK_Glyph_Load(   FT_GlyphSlot  slot,
+                   FT_Size       size,
+                   FT_UInt       glyph_index,
+                   FT_Int32      load_flags )
   {
-    GF_Face      gf     = (GF_Face)FT_SIZE_FACE( size );
-    FT_Face      face   = FT_FACE( gf );
+    PK_Face      pk     = (PK_Face)FT_SIZE_FACE( size );
+    FT_Face      face   = FT_FACE( pk );
     FT_Error     error  = FT_Err_Ok;
     FT_Bitmap*   bitmap = &slot->bitmap;
-    GF_BitmapRec bm;
-    GF_Glyph     go;
+    PK_BitmapRec bm;
+    PK_Glyph     go;
     FT_Int       ascent;
 
-    go = gf->gf_glyph;
+    go = pk->pk_glyph;
 
     FT_UNUSED( load_flags );
 
@@ -371,7 +384,7 @@
       goto Exit;
     }
 
-    FT_TRACE1(( "GF_Glyph_Load: glyph index %d\n", glyph_index ));
+    FT_TRACE1(( "PK_Glyph_Load: glyph index %d\n", glyph_index ));
 
     if ( glyph_index < 0 )
       glyph_index = 0;
@@ -390,8 +403,8 @@
       goto Exit;
     }
 
-    /* slot, bitmap => freetype, bm => gflib */
-    bm = gf->gf_glyph->bm_table[glyph_index];
+    /* slot, bitmap => freetype, bm => pklib */
+    bm = pk->pk_glyph->bm_table[glyph_index];
 
     bitmap->rows       = bm.bbx_height;
     bitmap->width      = bm.bbx_width;
@@ -427,38 +440,126 @@
     return error;
   }
 
+  FT_LOCAL_DEF( void )
+  TFM_Done_Metrics( FT_Memory     memory,
+                    TFM_FontInfo  fi )
+  {
+    FT_FREE(fi->width);
+    FT_FREE(fi->height);
+    FT_FREE(fi->depth);
+    FT_FREE( fi );
+  }
+
+  /* parse a TFM metrics file */
+  FT_LOCAL_DEF( FT_Error )
+  TFM_Read_Metrics( FT_Face    pk_face,
+                    FT_Stream  stream )
+  {
+    TFM_Service    tfm;
+    FT_Memory      memory  = stream->memory;
+    TFM_ParserRec  parser;
+    TFM_FontInfo   fi      = NULL;
+    FT_Error       error   = FT_ERR( Unknown_File_Format );
+    PK_Face        face    = (PK_Face)pk_face;
+    PK_Glyph       pk_glyph= face->pk_glyph;
+
+
+    if ( face->tfm_data )
+    {
+      FT_TRACE1(( "TFM_Read_Metrics:"
+                  " Freeing previously attached metrics data.\n" ));
+      TFM_Done_Metrics( memory, (TFM_FontInfo)face->tfm_data );
+
+      face->tfm_data = NULL;
+    }
+
+    if ( FT_NEW( fi ) )
+      goto Exit;
+
+    FT_TRACE4(( "TFM_Read_Metrics: Invoking TFM_Service.\n" ));
+
+    tfm = (TFM_Service)face->tfm;
+
+    /* Initialise TFM Service */
+    error = tfm->init( &parser,
+                       memory,
+                       stream );
+
+    if ( !error )
+    {
+      FT_TRACE4(( "TFM_Read_Metrics: Initialised tfm metric data.\n" ));
+      parser.FontInfo  = fi;
+      parser.user_data = pk_glyph;
+
+      error = tfm->parse_metrics( &parser );
+      if( !error )
+        FT_TRACE4(( "TFM_Read_Metrics: parsing TFM metric information done.\n" 
));
+
+      FT_TRACE6(( "TFM_Read_Metrics: TFM Metric Information:\n"
+                  "                  Check Sum  : %ld\n"
+                  "                  Design Size: %ld\n"
+                  "                  Begin Char : %d\n"
+                  "                  End Char   : %d\n"
+                  "                  font_bbx_w : %d\n"
+                  "                  font_bbx_h : %d\n"
+                  "                  slant      : %d\n", parser.FontInfo->cs, 
parser.FontInfo->design_size, parser.FontInfo->begin_char,
+                                                         
parser.FontInfo->end_char, parser.FontInfo->font_bbx_w,
+                                                         
parser.FontInfo->font_bbx_h, parser.FontInfo->slant ));
+      tfm->done( &parser );
+    }
+
+    if ( !error )
+    {
+      /* Modify PK_Glyph data according to TFM metric values */
+
+      /*face->pk_glyph->font_bbx_w = fi->font_bbx_w;
+      face->pk_glyph->font_bbx_h = fi->font_bbx_h;
+      */
+
+      face->tfm_data       = fi;
+      fi                   = NULL;
+    }
+
+  Exit:
+    if ( fi )
+      TFM_Done_Metrics( memory, fi );
+
+    return error;
+  }
+
  /*
   *
   * SERVICES LIST
   *
   */
 
-  static const FT_ServiceDescRec  gf_services[] =
+  static const FT_ServiceDescRec  pk_services[] =
   {
-    { FT_SERVICE_ID_GF,          NULL },
-    { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_GF },
+    { FT_SERVICE_ID_PK,          NULL },
+    { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PK },
     { NULL, NULL }
   };
 
+
   FT_CALLBACK_DEF( FT_Module_Interface )
-  gf_driver_requester( FT_Module    module,
+  pk_driver_requester( FT_Module    module,
                         const char*  name )
   {
     FT_UNUSED( module );
 
-    return ft_service_list_lookup( gf_services, name );
+    return ft_service_list_lookup( pk_services, name );
   }
 
 
    FT_CALLBACK_TABLE_DEF
-  const FT_Driver_ClassRec  gf_driver_class =
+  const FT_Driver_ClassRec  pk_driver_class =
   {
     {
       FT_MODULE_FONT_DRIVER         |
       FT_MODULE_DRIVER_NO_OUTLINES,
       sizeof ( FT_DriverRec ),
 
-      "gf",
+      "pk",
       0x10000L,
       0x20000L,
 
@@ -466,28 +567,28 @@
 
       NULL,                     /* FT_Module_Constructor  module_init   */
       NULL,                     /* FT_Module_Destructor   module_done   */
-      gf_driver_requester      /* FT_Module_Requester    get_interface */
+      pk_driver_requester       /* FT_Module_Requester    get_interface */
     },
 
-    sizeof ( GF_FaceRec ),
+    sizeof ( PK_FaceRec ),
     sizeof ( FT_SizeRec ),
     sizeof ( FT_GlyphSlotRec ),
 
-    GF_Face_Init,               /* FT_Face_InitFunc  init_face */
-    GF_Face_Done,               /* FT_Face_DoneFunc  done_face */
+    PK_Face_Init,               /* FT_Face_InitFunc  init_face */
+    PK_Face_Done,               /* FT_Face_DoneFunc  done_face */
     NULL,                       /* FT_Size_InitFunc  init_size */
     NULL,                       /* FT_Size_DoneFunc  done_size */
     NULL,                       /* FT_Slot_InitFunc  init_slot */
     NULL,                       /* FT_Slot_DoneFunc  done_slot */
 
-    GF_Glyph_Load,              /* FT_Slot_LoadFunc  load_glyph */
+    PK_Glyph_Load,              /* FT_Slot_LoadFunc  load_glyph */
 
     NULL,                       /* FT_Face_GetKerningFunc   get_kerning  */
-    NULL,                       /* FT_Face_AttachFunc       attach_file  */
+    TFM_Read_Metrics,           /* FT_Face_AttachFunc       attach_file  */
     NULL,                       /* FT_Face_GetAdvancesFunc  get_advances */
 
-    GF_Size_Request,           /* FT_Size_RequestFunc  request_size */
-    GF_Size_Select             /* FT_Size_SelectFunc   select_size  */
+    PK_Size_Request,           /* FT_Size_RequestFunc  request_size */
+    PK_Size_Select             /* FT_Size_SelectFunc   select_size  */
   };
 
 
diff --git a/src/gf/gfdrivr.h b/src/pk/pkdrivr.h
similarity index 64%
copy from src/gf/gfdrivr.h
copy to src/pk/pkdrivr.h
index 01fe0d3..8ee6a10 100644
--- a/src/gf/gfdrivr.h
+++ b/src/pk/pkdrivr.h
@@ -1,8 +1,8 @@
 /****************************************************************************
  *
- * gfdrivr.h
+ * pkdrivr.h
  *
- *   FreeType font driver for METAFONT GF FONT files
+ *   FreeType font driver for TeX's PK FONT files.
  *
  * Copyright 1996-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
@@ -16,19 +16,18 @@
  */
 
 
-#ifndef GFDRIVR_H_
-#define GFDRIVR_H_
+#ifndef PKDRIVR_H_
+#define PKDRIVR_H_
 
 #include <ft2build.h>
 #include FT_INTERNAL_DRIVER_H
 
-#include "gf.h"
+#include "pk.h"
 
 
 FT_BEGIN_HEADER
 
-  /* BitmapRec for GF format specific glyphs  */
-  typedef struct GF_BitmapRec_
+  typedef struct PK_BitmapRec_
   {
     FT_UInt              bbx_width, bbx_height;
     FT_UInt              off_x, off_y;
@@ -36,35 +35,35 @@ FT_BEGIN_HEADER
     FT_Byte              *bitmap;
     FT_UInt              raster;
 
-  } GF_BitmapRec, *GF_Bitmap;
+  } PK_BitmapRec, *PK_Bitmap;
 
-
-  typedef struct GF_GlyphRec_
+  typedef struct PK_GlyphRec_
   {
     FT_UInt         code_min, code_max;
-    GF_Bitmap       bm_table;
+    PK_Bitmap       bm_table;
     FT_UInt         ds, hppp, vppp;
     FT_UInt         font_bbx_w, font_bbx_h;
     FT_UInt         font_bbx_xoff, font_bbx_yoff;
 
-  } GF_GlyphRec, *GF_Glyph;
-
+  } PK_GlyphRec, *PK_Glyph;
 
-  typedef struct  GF_FaceRec_
+  typedef struct  PK_FaceRec_
   {
-    FT_FaceRec        root;
-    GF_Glyph          gf_glyph;
+    FT_FaceRec      root;
+    PK_Glyph        pk_glyph;
 
-  } GF_FaceRec, *GF_Face;
+    const void*     tfm;
+    const void*     tfm_data;
 
+  } PK_FaceRec, *PK_Face;
 
-  FT_EXPORT_VAR( const FT_Driver_ClassRec )  gf_driver_class;
+  FT_EXPORT_VAR( const FT_Driver_ClassRec )  pk_driver_class;
 
 
 FT_END_HEADER
 
 
-#endif /* GFDRIVR_H_ */
+#endif /* PKDRIVR_H_ */
 
 
 /* END */
diff --git a/src/tfm/tfmerror.h b/src/pk/pkerror.h
similarity index 71%
copy from src/tfm/tfmerror.h
copy to src/pk/pkerror.h
index f0f6e0c..00d200e 100644
--- a/src/tfm/tfmerror.h
+++ b/src/pk/pkerror.h
@@ -1,8 +1,8 @@
 /****************************************************************************
  *
- * tfmerror.h
+ * pkerror.h
  *
- *   FreeType font driver for TeX's TFM FONT files
+ *   FreeType font driver for TeX's PK FONT files.
  *
  * Copyright 1996-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
@@ -17,24 +17,24 @@
 
   /**************************************************************************
    *
-   * This file is used to define the TFM error enumeration constants.
+   * This file is used to define the PK error enumeration constants.
    *
    */
 
-#ifndef TFMERROR_H_
-#define TFMERROR_H_
+#ifndef PKERROR_H_
+#define PKERROR_H_
 
 #include FT_MODULE_ERRORS_H
 
 #undef FTERRORS_H_
 
 #undef  FT_ERR_PREFIX
-#define FT_ERR_PREFIX  TFM_Err_
-#define FT_ERR_BASE    FT_Mod_Err_TFM
+#define FT_ERR_PREFIX  PK_Err_
+#define FT_ERR_BASE    FT_Mod_Err_PK
 
 #include FT_ERRORS_H
 
-#endif /* TFMERROR_H_ */
+#endif /* PKERROR_H_ */
 
 
 /* END */
diff --git a/src/pk/pklib.c b/src/pk/pklib.c
new file mode 100644
index 0000000..09a62e5
--- /dev/null
+++ b/src/pk/pklib.c
@@ -0,0 +1,575 @@
+/****************************************************************************
+ *
+ * pklib.c
+ *
+ *   FreeType font driver for TeX's PK FONT files.
+ *
+ * Copyright 1996-2018 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+#include <ft2build.h>
+
+#include FT_FREETYPE_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_OBJECTS_H
+#include FT_SYSTEM_H
+#include FT_CONFIG_CONFIG_H
+#include FT_ERRORS_H
+#include FT_TYPES_H
+
+#include "pk.h"
+#include "pkdrivr.h"
+#include "pkerror.h"
+
+
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_pklib
+
+unsigned char   bits_table[] = {
+  0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+
+
+  /**************************************************************************
+   *
+   * PK font utility functions.
+   *
+   */
+
+  long           pk_read_intn(FT_Stream,int);
+  unsigned long  pk_read_uintn(FT_Stream,int);
+
+#define READ_UINT1( stream )    (UINT1)pk_read_uintn( stream, 1)
+#define READ_UINT2( stream )    (UINT1)pk_read_uintn( stream, 2)
+#define READ_UINT3( stream )    (UINT1)pk_read_uintn( stream, 3)
+#define READ_UINT4( stream )    (UINT1)pk_read_uintn( stream, 4)
+#define READ_UINTN( stream,n)   (UINT4)pk_read_uintn( stream, n)
+#define READ_INT1( stream )     (INT1)pk_read_intn( stream, 1)
+#define READ_INT2( stream )     (INT1)pk_read_intn( stream, 2)
+#define READ_INT4( stream )     (INT4)pk_read_intn( stream, 4)
+
+/*
+ * Reading a Number from file
+ */
+  unsigned long
+  pk_read_uintn(FT_Stream stream, int size)
+  {
+    unsigned long  v,k;
+    FT_Error error;
+    FT_Byte tp;
+    v = 0L;
+    while (size >= 1)
+    {
+      if ( FT_READ_BYTE(tp) )
+        return 0; /* To be changed */
+      k =(unsigned long)tp;
+      v = v*256L + k;
+      --size;
+    }
+    return v;
+  }
+
+  long
+  pk_read_intn(FT_Stream stream, int size)
+  {
+    long           v;
+    FT_Byte tp;
+    FT_Error error;
+    unsigned long z ;
+    if ( FT_READ_BYTE(tp) )
+        return 0;/* To be changed */
+    z= (unsigned long)tp;
+    v = (long)z & 0xffL;
+    if (v & 0x80L)
+      v = v - 256L;
+    --size;
+    while (size >= 1)
+    {
+      if ( FT_READ_BYTE(tp) )
+        return 0;/* To be changed */
+      z= (unsigned long)tp;
+      v = v*256L + z;
+      --size;
+               }
+    return v;
+  }
+
+  int  pk_read_nyble_rest_cnt;
+  int  pk_read_nyble_max_bytes;
+
+  void
+  pk_read_nyble_init(int max)
+  {
+    pk_read_nyble_rest_cnt  = 0;
+    pk_read_nyble_max_bytes = max;
+  }
+
+  int
+  pk_read_nyble(FT_Stream stream)
+  {
+    static UINT1  d;
+    int           v;
+
+    switch (pk_read_nyble_rest_cnt)
+    {
+    case 0:
+      d = READ_UINT1( stream );
+      if (--pk_read_nyble_max_bytes < 0)
+        return -1L;
+      v = d / 0x10;
+      d = d % 0x10;
+      pk_read_nyble_rest_cnt = 1;
+      break;
+    case 1:
+    default:
+      v = d;
+      pk_read_nyble_rest_cnt = 0;
+      break;
+    }
+  return v;
+  }
+
+  long
+  pk_read_packed_number(long* repeat, FT_Stream stream, int dyn_f)
+  {
+    int   d, n;
+    long  di;
+
+    entry:
+      d = pk_read_nyble( stream );
+      if (d == 0)
+      {
+        n = 0;
+        do
+        {
+          di = pk_read_nyble( stream );
+          n++;
+        }
+        while (di == 0);
+        for ( ; n > 0; n--)
+          di = di*16 + pk_read_nyble( stream );
+        return di - 15 + (13 - dyn_f)*16 + dyn_f;
+      }
+    if (d <= dyn_f)
+      return d;
+    if (d <= 13)
+      return (d - dyn_f - 1)*16 + pk_read_nyble( stream ) + dyn_f + 1;
+    *repeat = 1;
+    if (d == 14)
+      *repeat = pk_read_packed_number(repeat, stream, dyn_f);
+    goto entry;
+  }
+
+  int
+  pk_read_14(FT_Stream stream, int dyn_f, int bw, UINT4 rs, PK_Bitmap bm, long 
cc)
+  {
+    long           x, y, x8, xm;
+    unsigned char  *bm_ptr;
+    unsigned long  bit16_buff;
+    int            rest_bit16_buff;
+    static unsigned int mask_table[] =
+      { 0xdead,   0x80,   0xc0,   0xe0,   0xf0,   0xf8,   0xfc,   0xfe, 0xdead 
};
+
+    if (rs == 0)
+      return 0;
+
+    x8 = bm->bbx_width / 8;
+    xm = bm->bbx_width % 8;
+    bm_ptr = bm->bitmap;
+
+    bit16_buff = READ_UINT1( stream ) << 8;
+    rest_bit16_buff = 8;
+    --rs;
+
+    for(y = 0; y < bm->bbx_height; y++)
+    {
+      for(x = 0; x < x8; x++)
+      {
+        *(bm_ptr++) = bit16_buff >> 8;
+        rest_bit16_buff -= 8;
+        bit16_buff = (bit16_buff << 8) & 0xffff;
+        if (rs > 0)
+        {
+               bit16_buff |= (READ_UINT1( stream ) << (8 - rest_bit16_buff));
+               rest_bit16_buff += 8;
+               --rs;
+        }
+      }
+      if (xm != 0)
+      {
+        *(bm_ptr++) = (bit16_buff >> 8) & mask_table[xm];
+        rest_bit16_buff -= xm;
+        bit16_buff = (bit16_buff << xm) & 0xffff;
+        if (rest_bit16_buff < 8)
+        {
+               if (rs > 0)
+               {
+                 bit16_buff |= (READ_UINT1( stream ) << (8 - rest_bit16_buff));
+                 rest_bit16_buff += 8;
+                 --rs;
+               }
+        }
+      }
+    }
+    return 0;
+  }
+
+  int
+  pk_read_n14(FT_Stream stream, int dyn_f, int bw, UINT4 rs, PK_Bitmap bm, 
long cc)
+  {
+    long           x, y, xx, yy, repeat;
+    int            bits, b_p;
+    unsigned char  *p, *p0, *p1;
+
+    pk_read_nyble_init(rs);
+    p    = bm->bitmap;
+    bw   = 1-bw;
+    bits = 0;
+    for (y = 0; y < bm->bbx_height; )
+    {
+      b_p    = 0;
+      repeat = 0;
+      p0     = p;
+      for (x = 0; x < bm->bbx_width; x++)
+      {
+        if (bits == 0)
+        {
+               bw   = 1-bw;
+               if ((bits = pk_read_packed_number(&repeat, stream, dyn_f)) < 0)
+                 return -1;
+        }
+        if (bw == 1)
+               *p = *p | bits_table[b_p];
+        --bits;
+        if (++b_p >= 8)
+        {
+               b_p = 0;
+               p++;
+        }
+      }
+      if (b_p != 0)
+        p++;
+      y++;
+      for (yy = 0; yy < repeat; yy++)
+      {
+        p1 = p0;
+        for (xx = 0; xx < bm->raster; xx++)
+               *(p++) = *(p1++);
+        y++;
+      }
+    }
+    return 0;
+  }
+
+  /**************************************************************************
+   *
+   * API.
+   *
+   */
+
+  FT_LOCAL_DEF( FT_Error )
+  pk_load_font(FT_Stream       stream,
+               FT_Memory       extmemory,
+               PK_Glyph        *goptr )
+  {
+    PK_Glyph      go;
+    UINT1         instr, pre, id;;
+    unsigned long ds, check_sum, hppp, vppp, k;
+    unsigned int  flag, dny_f, bw, ess, size;
+    UINT4         cc, tfm, dx, dy, dm, w, h, rs;
+    INT4          hoff, voff, mv_x, mv_y;
+    long          gptr;
+    int           bc, ec, nchars, index, i;
+    FT_Error      error  = FT_Err_Ok;
+    FT_Memory     memory = extmemory; /* needed for FT_NEW */
+
+    go = NULL;
+    nchars = -1;
+
+    if( FT_STREAM_SEEK( 0 ) )
+      goto Exit;
+
+    pre = READ_UINT1( stream );
+    if (pre != PK_PRE)
+    {
+      error = FT_THROW( Unknown_File_Format );
+      goto Exit;
+    }
+
+    id = READ_UINT1( stream );
+    if (id != PK_ID)
+    {
+      error = FT_THROW( Unknown_File_Format );
+      goto Exit;
+    }
+
+    k = READ_UINT1( stream );
+    if ( FT_STREAM_SKIP( k ) )
+      goto Exit;
+    ds        = READ_UINT4( stream );
+    check_sum = READ_UINT4( stream );
+    hppp      = READ_UINT4( stream );
+    vppp      = READ_UINT4( stream );
+
+    /* gptr = ftell(fp); */
+    gptr = stream->pos;
+
+    #if 0
+      /* read min & max char code */
+      bc = 256;
+      ec = -1;
+      for (;;)
+      {
+        instr = READ_UINT1( stream );
+        if (instr == PK_POST)
+        break;
+        switch ((int) instr)
+        {
+          case PK_XXX1:  k = (UINT4)READ_UINT1( stream ); if ( FT_STREAM_SKIP( 
k ) ) goto Exit; break;
+          case PK_XXX2:  k = (UINT4)READ_UINT2( stream ); if ( FT_STREAM_SKIP( 
k ) ) goto Exit; break;
+          case PK_XXX3:  k = (UINT4)READ_UINT3( stream ); if ( FT_STREAM_SKIP( 
k ) ) goto Exit; break;
+          case PK_XXX4:  k = (UINT4)READ_UINT4( stream ); if ( FT_STREAM_SKIP( 
k ) ) goto Exit; break;
+          case PK_YYY:   if ( FT_STREAM_SKIP( 4 ) ) goto Exit; break;
+          case PK_NO_OP: break;
+          default:
+            size  = instr & 0x3; instr >>= 2;
+            ess   = instr & 0x1;
+          if (ess == 0)
+          {                          /* short */
+                 rs = (UINT4)(size*256) + (UINT4)READ_UINT1( stream );
+                 cc   = (UINT4)READ_UINT1( stream );
+          }
+          else if ((ess == 1) && (size != 3))
+          {                          /* extended short */
+                 rs = (UINT4)(size*65536) + (UINT4)READ_UINT2( stream );
+                 cc   = (UINT4)READ_UINT1( stream );
+          }
+          else
+          {                          /* standard */
+                 rs   = READ_UINT4( stream );
+                 cc   = (UINT4)READ_UINT4( stream );
+          }
+          if ( FT_STREAM_SKIP( rs ) )
+            goto Exit;
+          if (cc < bc)
+                 bc = cc;
+          if (cc > ec)
+                 ec = cc;
+          break;
+        }
+      }
+    #else
+      bc = 0;
+      ec = 255;
+    #endif
+
+    nchars = ec - bc + 1;
+    if( FT_ALLOC(go, sizeof(PK_GlyphRec)) )
+      goto Exit;
+
+    if( FT_ALLOC_MULT(go->bm_table, sizeof(PK_BitmapRec), nchars) )
+      goto Exit;
+
+    for (i = 0; i < nchars; i++)
+      go->bm_table[i].bitmap = NULL;
+
+    go->ds   = (FT_UInt)ds/(1<<20);
+    go->hppp = (FT_UInt)hppp/(1<<16);
+    go->vppp = (FT_UInt)vppp/(1<<16);
+    go->font_bbx_w = 0;
+    go->font_bbx_h = 0;
+    go->font_bbx_xoff = 0;
+    go->font_bbx_yoff = 0;
+    go->code_min = bc;
+    go->code_max = ec;
+
+    /* read glyphs */
+    /* fseek(fp, gptr, SEEK_SET); */
+    if( FT_STREAM_SEEK( gptr ) )
+        goto Exit;
+
+    for (;;)
+    {
+      if ((instr = READ_UINT1( stream )) == PK_POST)
+        break;
+      switch ((int)instr)
+      {
+        case PK_XXX1:
+          k = (UINT4)READ_UINT1( stream );
+          if ( FT_STREAM_SKIP( k ) )
+            goto Exit;
+          break;
+        case PK_XXX2:
+          k = (UINT4)READ_UINT2( stream );
+          if ( FT_STREAM_SKIP( k ) )
+            goto Exit;
+          break;
+        case PK_XXX3:
+          k = (UINT4)READ_UINT3( stream );
+          if ( FT_STREAM_SKIP( k ) )
+            goto Exit;
+          break;
+        case PK_XXX4:
+          k = (UINT4)READ_UINT4( stream );
+          if ( FT_STREAM_SKIP( k ) )
+            goto Exit;
+          break;
+        case PK_YYY:
+          if ( FT_STREAM_SKIP( 4 ) )
+            goto Exit;
+          break;
+        case PK_NO_OP:
+          break;
+        default:
+          flag = instr;
+          size  = flag % 0x04;  flag = flag >> 2;
+          ess   = flag % 0x02;  flag = flag >> 1;
+          bw    = flag % 0x02;  flag = flag >> 1;
+          dny_f = flag % 0x10;
+        if (ess == 0)
+        {                          /* short */
+          rs = (UINT4)(size*256) + (UINT4)READ_UINT1( stream ) - (UINT4)8;
+          cc   = (UINT4)READ_UINT1( stream );
+          tfm  = (UINT4)READ_UINT3( stream );
+          dm   = (UINT4)READ_UINT1( stream );
+          w    = (UINT4)READ_UINT1( stream );
+          h    = (UINT4)READ_UINT1( stream );
+          hoff = (INT4)READ_INT1( stream );
+          voff = (INT4)READ_INT1( stream );
+          mv_x = dm;
+          mv_y = 0;
+        }
+        else if ((ess == 1) && (size != 3))
+        {                          /* extended short */
+          rs = (UINT4)(size*65536) + (UINT4)READ_UINT2( stream ) - (UINT4)13;
+          cc   = (UINT4)READ_UINT1( stream );
+          tfm  = (UINT4)READ_UINT3( stream );
+          dm   = (UINT4)READ_UINT2( stream );
+          w    = (UINT4)READ_UINT2( stream );
+          h    = (UINT4)READ_UINT2( stream );
+          hoff = (INT4)READ_INT2( stream );
+          voff = (INT4)READ_INT2( stream );
+          mv_x = dm;
+          mv_y = 0;
+        }
+        else
+        {                           /* standard */
+          rs   = READ_UINT4( stream ) - (UINT4)28;
+          cc   = READ_UINT4( stream );
+          tfm  = READ_UINT4( stream );
+          dx   = READ_UINT4( stream );
+          dy   = READ_UINT4( stream );
+               w    = READ_UINT4( stream );
+          h    = READ_UINT4( stream );
+          hoff = READ_INT4( stream );
+          voff = READ_INT4( stream );
+          mv_x = (FT_UInt)dx/(FT_UInt)(1<<16);
+          mv_y = (FT_UInt)dy/(FT_UInt)(1<<16);
+        }
+
+        if ((cc < go->code_min) || (go->code_max < cc))
+        {
+          error = FT_THROW( Invalid_File_Format );
+          goto Exit;
+        }
+
+        index = cc - go->code_min;
+        go->bm_table[index].bbx_width  = w;
+        go->bm_table[index].bbx_height = h;
+        go->bm_table[index].raster = (w+7)/8;
+        go->bm_table[index].off_x  = -hoff;
+        go->bm_table[index].off_y  = voff;
+        go->bm_table[index].mv_x   = mv_x;
+        go->bm_table[index].mv_y   = mv_y;
+        go->bm_table[index].bitmap = (unsigned char*)malloc(h*((w+7)/8));
+
+        if (go->bm_table[index].bitmap == NULL)
+        {
+          error = FT_THROW( Invalid_File_Format );
+          goto Exit;
+        }
+
+        memset(go->bm_table[index].bitmap, 0, h*((w+7)/8));
+
+        if (dny_f == 14)
+        {
+          if (pk_read_14(stream, dny_f, bw, rs, &(go->bm_table[index]), cc) < 
0)
+          {
+            /* vf_error = VF_ERR_ILL_FONT_FILE; (FOR TRACING) */
+            error = FT_THROW( Unknown_File_Format );
+            goto Exit;
+          }
+        }
+        else
+        {
+          if (pk_read_n14(stream, dny_f, bw, rs, &(go->bm_table[index]), cc) < 
0)
+          {
+            /* vf_error = VF_ERR_ILL_FONT_FILE; (FOR TRACING) */
+            error = FT_THROW( Unknown_File_Format );
+            goto Exit;
+          }
+        }
+        if (go->font_bbx_w < w)
+          go->font_bbx_w = w;
+        if (go->font_bbx_h < h)
+          go->font_bbx_h = h;
+        if (go->font_bbx_xoff > -hoff)
+          go->font_bbx_xoff = -hoff;
+        if (go->font_bbx_yoff > (voff - h))
+          go->font_bbx_yoff = (voff - h);
+      }
+    }
+    *goptr          = go;
+    return error;
+
+    Exit:
+      if (go != NULL)
+      {
+        for (i = 0; i < nchars; i++)
+        {
+          if (go->bm_table[i].bitmap != NULL)
+           FT_FREE(go->bm_table[i].bitmap);
+        }
+        FT_FREE(go->bm_table);
+        FT_FREE(go);
+      }
+      return error;
+  }
+
+  FT_LOCAL_DEF( void )
+  pk_free_font( PK_Face face )
+  {
+    FT_Memory  memory = FT_FACE( face )->memory;
+    PK_Glyph   go     = face->pk_glyph;
+    FT_UInt    nchars = FT_FACE( face )->num_glyphs,i;
+
+    if ( !go )
+      return;
+
+    if( go->bm_table )
+    {
+      for (i = 0; i < nchars; i++)
+      {
+        if (go->bm_table[i].bitmap != NULL)
+          FT_FREE(go->bm_table[i].bitmap);
+       }
+    }
+    FT_FREE(go->bm_table);
+    FT_FREE(go);
+  }
+
+/* END */
diff --git a/src/pk/rules.mk b/src/pk/rules.mk
new file mode 100644
index 0000000..8d55011
--- /dev/null
+++ b/src/pk/rules.mk
@@ -0,0 +1,70 @@
+#
+# FreeType 2 PK driver configuration rules
+#
+
+
+# Copyright 1996-2018 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+
+
+# pk driver directory
+#
+PK_DIR := $(SRC_DIR)/pk
+
+
+PK_COMPILE := $(CC) $(ANSIFLAGS)                            \
+                     $I$(subst /,$(COMPILER_SEP),$(PK_DIR)) \
+                     $(INCLUDE_FLAGS)                        \
+                     $(FT_CFLAGS)
+
+
+# pk driver sources (i.e., C files)
+#
+PK_DRV_SRC :=  $(PK_DIR)/pklib.c \
+               $(PK_DIR)/pkdrivr.c
+
+
+# pk driver headers
+#
+PK_DRV_H :=  $(PK_DIR)/pk.h \
+             $(PK_DIR)/pkdrivr.h \
+             $(PK_DIR)/pkerror.h
+
+# pk driver object(s)
+#
+#   PK_DRV_OBJ_M is used during `multi' builds
+#   PK_DRV_OBJ_S is used during `single' builds
+#
+PK_DRV_OBJ_M := $(PK_DRV_SRC:$(PK_DIR)/%.c=$(OBJ_DIR)/%.$O)
+PK_DRV_OBJ_S := $(OBJ_DIR)/pk.$O
+
+# pk driver source file for single build
+#
+PK_DRV_SRC_S := $(PK_DIR)/pk.c
+
+
+# pk driver - single object
+#
+$(PK_DRV_OBJ_S): $(PK_DRV_SRC_S) $(PK_DRV_SRC) $(FREETYPE_H) $(PK_DRV_H)
+       $(PK_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(PK_DRV_SRC_S))
+
+
+# pk driver - multiple objects
+#
+$(OBJ_DIR)/%.$O: $(PK_DIR)/%.c $(FREETYPE_H) $(PK_DRV_H)
+       $(PK_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(PK_DRV_OBJ_S)
+DRV_OBJS_M += $(PK_DRV_OBJ_M)
+
+
+# EOF
diff --git a/src/gf/module.mk b/src/tfm/Jamfile
similarity index 56%
copy from src/gf/module.mk
copy to src/tfm/Jamfile
index 1eb5346..16df704 100644
--- a/src/gf/module.mk
+++ b/src/tfm/Jamfile
@@ -1,9 +1,6 @@
+# FreeType 2 src/tfm Jamfile
 #
-# FreeType 2 GF Font module definition
-#
-
-
-# Copyright 1996-2018 by
+# Copyright 2001-2018 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
@@ -12,11 +9,22 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
-FTMODULE_H_COMMANDS += GF_DRIVER
+SubDir  FT2_TOP $(FT2_SRC_DIR) tfm ;
+
+{
+  local  _sources ;
+
+  if $(FT2_MULTI)
+  {
+    _sources = tfmmod
+               ;
+  }
+  else
+  {
+    _sources = tfm ;
+  }
 
-define GF_DRIVER
-$(OPEN_DRIVER) FT_Driver_ClassRec, gf_driver_class $(CLOSE_DRIVER)
-$(ECHO_DRIVER)gf        $(ECHO_DRIVER_DESC)METAFONT bitmap 
fonts$(ECHO_DRIVER_DONE)
-endef
+  Library  $(FT2_LIB) : $(_sources).c ;
+}
 
-# EOF
+# end of src/tfm Jamfile
diff --git a/src/tfm/module.mk b/src/tfm/module.mk
index c0c510c..85467ca 100644
--- a/src/tfm/module.mk
+++ b/src/tfm/module.mk
@@ -1,5 +1,5 @@
 #
-# FreeType 2 TFM Font module definition
+# FreeType 2 TFM module definition
 #
 
 
@@ -12,11 +12,12 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
-FTMODULE_H_COMMANDS += TFM_DRIVER
 
-define TFM_DRIVER
-$(OPEN_DRIVER) FT_Driver_ClassRec, tfm_driver_class $(CLOSE_DRIVER)
-$(ECHO_DRIVER)tfm       $(ECHO_DRIVER_DESC)METAFONT bitmap 
fonts$(ECHO_DRIVER_DONE)
+FTMODULE_H_COMMANDS += TFM_MODULE
+
+define TFM_MODULE
+$(OPEN_DRIVER) FT_Module_Class, tfm_module_class $(CLOSE_DRIVER)
+$(ECHO_DRIVER)tfm       $(ECHO_DRIVER_DESC)TFM helper module$(ECHO_DRIVER_DONE)
 endef
 
 # EOF
diff --git a/src/tfm/rules.mk b/src/tfm/rules.mk
index 4bf58bf..4311745 100644
--- a/src/tfm/rules.mk
+++ b/src/tfm/rules.mk
@@ -13,49 +13,51 @@
 # fully.
 
 
-# tfm driver directory
+# TFM driver directory
 #
 TFM_DIR := $(SRC_DIR)/tfm
 
 
-TFM_COMPILE := $(CC) $(ANSIFLAGS)                            \
-                     $I$(subst /,$(COMPILER_SEP),$(TFM_DIR)) \
-                     $(INCLUDE_FLAGS)                        \
-                     $(FT_CFLAGS)
+# compilation flags for the driver
+#
+TFM_COMPILE := $(CC) $(ANSIFLAGS)                              \
+                       $I$(subst /,$(COMPILER_SEP),$(TFM_DIR)) \
+                       $(INCLUDE_FLAGS)                          \
+                       $(FT_CFLAGS)
 
 
-# tfm driver sources (i.e., C files)
+# TFM driver sources (i.e., C files)
 #
-TFM_DRV_SRC :=  $(TFM_DIR)/tfmlib.c \
-               $(TFM_DIR)/tfmdrivr.c
-
+TFM_DRV_SRC := $(TFM_DIR)/tfmmod.c   \
+               $(TFM_DIR)/tfmobjs.c   \
 
-# tfm driver headers
+# TFM driver headers
 #
-TFM_DRV_H :=  $(TFM_DIR)/tfm.h \
-             $(TFM_DIR)/tfmdrivr.h \
-             $(TFM_DIR)/tfmerror.h
+TFM_DRV_H := $(TFM_DRV_SRC:%c=%h)  \
+               $(TFM_DIR)/tfmerr.h \
+
 
-# tfm driver object(s)
+# TFM driver object(s)
 #
-#   TFM_DRV_OBJ_M is used during `multi' builds
-#   TFM_DRV_OBJ_S is used during `single' builds
+#   TFM_DRV_OBJ_M is used during `multi' builds.
+#   TFM_DRV_OBJ_S is used during `single' builds.
 #
 TFM_DRV_OBJ_M := $(TFM_DRV_SRC:$(TFM_DIR)/%.c=$(OBJ_DIR)/%.$O)
 TFM_DRV_OBJ_S := $(OBJ_DIR)/tfm.$O
 
-# tfm driver source file for single build
+# TFM driver source file for single build
 #
 TFM_DRV_SRC_S := $(TFM_DIR)/tfm.c
 
 
-# tfm driver - single object
+# TFM driver - single object
 #
-$(TFM_DRV_OBJ_S): $(TFM_DRV_SRC_S) $(TFM_DRV_SRC) $(FREETYPE_H) $(TFM_DRV_H)
+$(TFM_DRV_OBJ_S): $(TFM_DRV_SRC_S) $(TFM_DRV_SRC) \
+                   $(FREETYPE_H) $(TFM_DRV_H)
        $(TFM_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $(TFM_DRV_SRC_S))
 
 
-# tfm driver - multiple objects
+# TFM driver - multiple objects
 #
 $(OBJ_DIR)/%.$O: $(TFM_DIR)/%.c $(FREETYPE_H) $(TFM_DRV_H)
        $(TFM_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
diff --git a/src/tfm/tfm.c b/src/tfm/tfm.c
index 26a58d9..51738b2 100644
--- a/src/tfm/tfm.c
+++ b/src/tfm/tfm.c
@@ -2,7 +2,7 @@
  *
  * tfm.c
  *
- *   FreeType font driver for TeX's TFM FONT files
+ *   FreeType auxiliary TFM module.
  *
  * Copyright 1996-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
@@ -17,11 +17,10 @@
 
 
 #define FT_MAKE_OPTION_SINGLE_OBJECT
-
 #include <ft2build.h>
 
-#include "tfmlib.c"
-#include "tfmdrivr.c"
+#include "tfmmod.c"
+#include "tfmobjs.c"
 
 
 /* END */
diff --git a/src/tfm/tfmdrivr.c b/src/tfm/tfmdrivr.c
deleted file mode 100644
index f2a24d3..0000000
--- a/src/tfm/tfmdrivr.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/****************************************************************************
- *
- * tfmdrivr.c
- *
- *   FreeType font driver for TeX's TFM FONT files
- *
- * Copyright 1996-2018 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- * This file is part of the FreeType project, and may only be used,
- * modified, and distributed under the terms of the FreeType project
- * license, LICENSE.TXT.  By continuing to use, modify, or distribute
- * this file you indicate that you have read the license and
- * understand and accept it fully.
- *
- */
-
-#include <ft2build.h>
-
-#include FT_INTERNAL_DEBUG_H
-#include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_TRUETYPE_IDS_H
-#include FT_SERVICE_FONT_FORMAT_H
-
-
-#include "tfm.h"
-#include "tfmdrivr.h"
-#include "tfmerror.h"
-
-
-  /**************************************************************************
-   *
-   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
-   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
-   * messages during execution.
-   */
-#undef  FT_COMPONENT
-#define FT_COMPONENT  trace_tfmdriver
-
-
-  typedef struct  TFM_CMapRec_
-  {
-    FT_CMapRec        cmap;
-    FT_UInt32         begin_char;       /* Beginning Character */
-    FT_UInt32         end_char  ;       /* End Character */
-  } TFM_CMapRec, *TFM_CMap;
-
-
-  FT_CALLBACK_DEF( FT_Error )
-  tfm_cmap_init(  FT_CMap     tfmcmap,
-                  FT_Pointer  init_data )
-  {
-    TFM_CMap  cmap = (TFM_CMap)tfmcmap;
-    TFM_Face  face = (TFM_Face)FT_CMAP_FACE( cmap );
-    FT_UNUSED( init_data );
-
-    cmap->begin_char     = face->tfm_glyph->begin_char;;
-    cmap->end_char       = face->tfm_glyph->end_char;
-
-    return FT_Err_Ok;
-  }
-
-
-  FT_CALLBACK_DEF( void )
-  tfm_cmap_done( FT_CMap  tfmcmap )
-  {
-    TFM_CMap  cmap = (TFM_CMap)tfmcmap;
-
-    cmap->begin_char     = 0;
-    cmap->end_char       = -1;
-
-  }
-
-
-  FT_CALLBACK_DEF( FT_UInt )
-  tfm_cmap_char_index(  FT_CMap    tfmcmap,
-                        FT_UInt32  char_code )
-  {
-    FT_UInt  gindex = 0;
-    TFM_CMap  cmap   = (TFM_CMap)tfmcmap;
-
-    char_code -= cmap->begin_char;
-
-    if ( char_code < cmap->end_char - cmap->begin_char + 1 )
-      gindex = (FT_UInt)( char_code );
-
-    return gindex;
-  }
-
-  FT_CALLBACK_DEF( FT_UInt )
-  tfm_cmap_char_next(  FT_CMap     tfmcmap,
-                       FT_UInt32  *achar_code )
-  {
-    TFM_CMap    cmap      = (TFM_CMap)tfmcmap;
-    FT_UInt     gindex    = 0;
-    FT_UInt32   result    = 0;
-    FT_UInt32   char_code = *achar_code + 1;
-
-
-    if ( char_code <= cmap->begin_char )
-    {
-      result = cmap->begin_char;
-      gindex = 1;
-    }
-    else
-    {
-      char_code -= cmap->begin_char;
-      if ( char_code < cmap->end_char - cmap->begin_char + 1 )
-      {
-        result = char_code;
-        gindex = (FT_UInt)( char_code );
-      }
-    }
-
-    *achar_code = result;
-    return gindex;
-  }
-
-
-  static
-  const FT_CMap_ClassRec  tfm_cmap_class =
-  {
-    sizeof ( TFM_CMapRec ),
-    tfm_cmap_init,
-    tfm_cmap_done,
-    tfm_cmap_char_index,
-    tfm_cmap_char_next,
-
-    NULL, NULL, NULL, NULL, NULL
-  };
-
-
-  FT_CALLBACK_DEF( void )
-  TFM_Face_Done( FT_Face        tfmface )         /* TFM_Face */
-  {
-    TFM_Face    face   = (TFM_Face)tfmface;
-    FT_Memory   memory;
-
-
-    if ( !face )
-      return;
-
-    memory = FT_FACE_MEMORY( face );
-
-    tfm_free_font( face->tfm_glyph, memory );
-
-    FT_FREE( tfmface->available_sizes );
-  }
-
-
-  FT_CALLBACK_DEF( FT_Error )
-  TFM_Face_Init(  FT_Stream      stream,
-                  FT_Face        tfmface,         /* TFM_Face */
-                  FT_Int         face_index,
-                  FT_Int         num_params,
-                  FT_Parameter*  params )
-  {
-    TFM_Face    face   = (TFM_Face)tfmface;
-    FT_Error    error  = FT_Err_Ok;
-    FT_Memory   memory = FT_FACE_MEMORY( face );
-    TFM_Glyph   tfm=NULL;
-
-    FT_UNUSED( num_params );
-    FT_UNUSED( params );
-
-
-    FT_TRACE2(( "TFM driver\n" ));
-
-    /* load font */
-    error = tfm_load_font( stream, memory, &tfm );
-    if ( FT_ERR_EQ( error, Unknown_File_Format ) )
-    {
-      FT_TRACE2(( "  not a TFM file\n" ));
-      goto Fail;
-    }
-    else if ( error )
-      goto Exit;
-
-    /* we have a tfm font: let's construct the face object */
-    face->tfm_glyph = tfm ;
-
-    /* TFM cannot have multiple faces in a single font file.
-     * XXX: non-zero face_index is already invalid argument, but
-     *      Type1, Type42 driver has a convention to return
-     *      an invalid argument error when the font could be
-     *      opened by the specified driver.
-     */
-    if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 )
-    {
-      FT_ERROR(( "TFM_Face_Init: invalid face index\n" ));
-      TFM_Face_Done( tfmface );
-      return FT_THROW( Invalid_Argument );
-    }
-
-    /* we now need to fill the root FT_Face fields */
-    /* with relevant information                   */
-
-    tfmface->num_faces       = 1;
-    tfmface->face_index      = 0;
-    tfmface->face_flags     |= FT_FACE_FLAG_FIXED_SIZES |
-                             FT_FACE_FLAG_HORIZONTAL ;
-
-    tfmface->family_name     = NULL;
-
-    FT_TRACE4(( "  number of glyphs: allocated %d\n",tfmface->num_glyphs ));
-
-    if ( tfmface->num_glyphs <= 0 )
-    {
-      FT_ERROR(( "TFM_Face_Init: glyphs not allocated\n" ));
-      error = FT_THROW( Invalid_File_Format );
-      goto Exit;
-    }
-
-    tfmface->num_fixed_sizes = 1;
-    if ( FT_NEW_ARRAY( tfmface->available_sizes, 1 ) )
-      goto Exit;
-
-    {
-      FT_Bitmap_Size*  bsize = tfmface->available_sizes;
-      /* FT_UShort        x_res, y_res; */
-
-      bsize->height = (FT_Short)face->tfm_glyph->font_bbx_h ;
-      bsize->width  = (FT_Short)face->tfm_glyph->font_bbx_w ;
-      bsize->size   = (FT_Pos)  face->tfm_glyph->design_size ;
-
-      /*x_res = ;
-      y_res = ;
-      */
-
-      bsize->y_ppem = (FT_Pos) (bsize->size/10) << 6;
-      bsize->x_ppem = (FT_Pos) bsize->y_ppem;
-    }
-
-    /* Charmaps */
-    {
-      FT_CharMapRec  charmap;
-
-      /* Unicode Charmap */
-      charmap.encoding    = FT_ENCODING_UNICODE;
-      charmap.platform_id = TT_PLATFORM_MICROSOFT;
-      charmap.encoding_id = TT_MS_ID_UNICODE_CS;
-      charmap.face        = FT_FACE( face );
-
-      error = FT_CMap_New( &tfm_cmap_class, NULL, &charmap, NULL );
-
-      if ( error )
-        goto Exit;
-    }
-
-  Exit:
-    return error;
-
-  Fail:
-    TFM_Face_Done( tfmface );
-    return FT_THROW( Unknown_File_Format );
-  }
-
-  FT_CALLBACK_DEF( FT_Error )
-  TFM_Size_Select(  FT_Size   size,
-                    FT_ULong  strike_index )
-  {
-    TFM_Face     face  = (TFM_Face)size->face;
-    TFM_Glyph    go    = face->tfm_glyph;
-    FT_UNUSED( strike_index );
-
-    FT_Select_Metrics( size->face, 0 );
-
-    size->metrics.ascender    = (go->font_bbx_h - go->font_bbx_yoff) * 64;
-    size->metrics.descender   = -go->font_bbx_yoff * 64;
-    size->metrics.max_advance = go->font_bbx_w * 64;
-
-    return FT_Err_Ok;
-  }
-
-  FT_CALLBACK_DEF( FT_Error )
-  TFM_Size_Request(  FT_Size          size,
-                     FT_Size_Request  req )
-  {
-    TFM_Face           face    = (TFM_Face)size->face;
-    FT_Bitmap_Size*   bsize   = size->face->available_sizes;
-    FT_Error          error   = FT_ERR( Invalid_Pixel_Size );
-    FT_Long           height;
-
-
-    height = FT_REQUEST_HEIGHT( req );
-    height = ( height + 32 ) >> 6;
-
-    switch ( req->type )
-    {
-    case FT_SIZE_REQUEST_TYPE_NOMINAL:
-      if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
-        error = FT_Err_Ok;
-      break;
-
-    case FT_SIZE_REQUEST_TYPE_REAL_DIM:
-      if ( height == face->tfm_glyph->font_bbx_h )
-        error = FT_Err_Ok;
-      break;
-
-    default:
-      error = FT_THROW( Unimplemented_Feature );
-      break;
-    }
-
-    if ( error )
-      return error;
-    else
-      return TFM_Size_Select( size, 0 );
-  }
-
-
-
-  FT_CALLBACK_DEF( FT_Error )
-  TFM_Glyph_Load(  FT_GlyphSlot  slot,
-                   FT_Size       size,
-                   FT_UInt       glyph_index,
-                   FT_Int32      load_flags )
-  {
-    TFM_Face      tfm    = (TFM_Face)FT_SIZE_FACE( size );
-    FT_Face       face   = FT_FACE( tfm );
-    FT_Error      error  = FT_Err_Ok;
-    FT_Bitmap*    bitmap = &slot->bitmap;
-    TFM_Glyph     go     = tfm->tfm_glyph;
-    FT_Int       ascent;
-
-    FT_UNUSED( load_flags );
-
-    if ( !face )
-    {
-      error = FT_THROW( Invalid_Face_Handle );
-      goto Exit;
-    }
-
-    if ( glyph_index >= (FT_UInt)( face->num_glyphs ) )
-    {
-      error = FT_THROW( Invalid_Argument );
-      goto Exit;
-    }
-
-    FT_TRACE1(( "TFM_Glyph_Load: glyph index %d\n", glyph_index ));
-
-    if ( glyph_index < 0 )
-      glyph_index = 0;
-
-    /* slot, bitmap => freetype, bm => tfmlib */
-
-    bitmap->rows       = go->font_bbx_h;
-    bitmap->width      = go->font_bbx_w;
-    bitmap->pixel_mode = FT_PIXEL_MODE_MONO;
-
-    /*bitmap->pitch = (int);*/
-
-    /* note: we don't allocate a new array to hold the bitmap; */
-    /*       we can simply point to it                         */
-    /*ft_glyphslot_set_bitmap( slot, );*/
-
-    ascent = (go->font_bbx_h + go->font_bbx_yoff);
-    slot->format      = FT_GLYPH_FORMAT_BITMAP;
-    slot->bitmap_left = go->font_bbx_xoff ;
-    slot->bitmap_top  = ascent ;
-
-    slot->metrics.horiAdvance  = (FT_Pos) (go->font_bbx_xoff ) * 64;
-    slot->metrics.horiBearingX = (FT_Pos) (go->font_bbx_xoff ) * 64;
-    slot->metrics.horiBearingY = (FT_Pos) ascent * 64;
-    slot->metrics.width        = (FT_Pos) ( bitmap->width * 64 );
-    slot->metrics.height       = (FT_Pos) ( bitmap->rows * 64 );
-
-    ft_synthesize_vertical_metrics( &slot->metrics, go->font_bbx_h * 64 );
-
-  Exit:
-    return error;
-  }
-
-
-   FT_CALLBACK_TABLE_DEF
-  const FT_Driver_ClassRec  tfm_driver_class =
-  {
-    {
-      FT_MODULE_FONT_DRIVER         |
-      FT_MODULE_DRIVER_NO_OUTLINES,
-      sizeof ( FT_DriverRec ),
-
-      "tfm",
-      0x10000L,
-      0x20000L,
-
-      NULL,                                                                    
        /* module-specific interface */
-
-      NULL,                     /* FT_Module_Constructor  module_init   */
-      NULL,                     /* FT_Module_Destructor   module_done   */
-      NULL                                                                     
/* FT_Module_Requester    get_interface */
-    },
-
-    sizeof ( TFM_FaceRec ),
-    sizeof ( FT_SizeRec ),
-    sizeof ( FT_GlyphSlotRec ),
-
-    TFM_Face_Init,               /* FT_Face_InitFunc  init_face */
-    TFM_Face_Done,               /* FT_Face_DoneFunc  done_face */
-    NULL,                       /* FT_Size_InitFunc  init_size */
-    NULL,                       /* FT_Size_DoneFunc  done_size */
-    NULL,                       /* FT_Slot_InitFunc  init_slot */
-    NULL,                       /* FT_Slot_DoneFunc  done_slot */
-
-    TFM_Glyph_Load,              /* FT_Slot_LoadFunc  load_glyph */
-
-    NULL,                       /* FT_Face_GetKerningFunc   get_kerning  */
-    NULL,                       /* FT_Face_AttachFunc       attach_file  */
-    NULL,                       /* FT_Face_GetAdvancesFunc  get_advances */
-
-    TFM_Size_Request,           /* FT_Size_RequestFunc  request_size */
-    TFM_Size_Select             /* FT_Size_SelectFunc   select_size  */
-  };
-
-
-/* END */
diff --git a/src/tfm/tfmdrivr.h b/src/tfm/tfmdrivr.h
deleted file mode 100644
index b81d310..0000000
--- a/src/tfm/tfmdrivr.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/****************************************************************************
- *
- * tfmdrivr.h
- *
- *   FreeType font driver for TeX's TFM FONT files
- *
- * Copyright 1996-2018 by
- * David Turner, Robert Wilhelm, and Werner Lemberg.
- *
- * This file is part of the FreeType project, and may only be used,
- * modified, and distributed under the terms of the FreeType project
- * license, LICENSE.TXT.  By continuing to use, modify, or distribute
- * this file you indicate that you have read the license and
- * understand and accept it fully.
- *
- */
-
-
-#ifndef TFMDRIVR_H_
-#define TFMDRIVR_H_
-
-#include <ft2build.h>
-#include FT_INTERNAL_DRIVER_H
-
-#include "tfm.h"
-
-
-FT_BEGIN_HEADER
-
-  typedef struct TFM_BitmapRec_
-  {
-    FT_UInt              bbx_width, bbx_height;
-    FT_UInt              off_x, off_y;
-    FT_UInt              mv_x,  mv_y;
-    FT_Byte              *bitmap;
-    FT_UInt              raster;
-
-  } TFM_BitmapRec, *TFM_Bitmap;
-
-  typedef struct TFM_GlyphRec_
-  {
-    /* Font Info */
-    int             type_aux;     /* METRIC_TYPE_AUX_xxx */
-    UINT4           cs;
-    /* Metrics */
-    UINT4           ds;
-    double          design_size;
-    double          slant;
-    unsigned int    begin_char, end_char;
-    INT4            *width, *height, *depth;
-    /* Font bounding box */
-    double          font_bbx_w, font_bbx_h;
-    double          font_bbx_xoff, font_bbx_yoff;
-
-  } TFM_GlyphRec, *TFM_Glyph;
-
-  typedef struct  TFM_FaceRec_
-  {
-    FT_FaceRec        root;
-    TFM_Glyph         tfm_glyph;
-  } TFM_FaceRec, *TFM_Face;
-
-
-  FT_EXPORT_VAR( const FT_Driver_ClassRec )  tfm_driver_class;
-
-
-FT_END_HEADER
-
-
-#endif /* TFMDRIVR_H_ */
-
-
-/* END */
diff --git a/src/tfm/tfmerror.h b/src/tfm/tfmerr.h
similarity index 73%
rename from src/tfm/tfmerror.h
rename to src/tfm/tfmerr.h
index f0f6e0c..0a1e8f8 100644
--- a/src/tfm/tfmerror.h
+++ b/src/tfm/tfmerr.h
@@ -1,10 +1,10 @@
 /****************************************************************************
  *
- * tfmerror.h
+ * tfmerr.h
  *
- *   FreeType font driver for TeX's TFM FONT files
+ *   FreeType auxiliary TFM module error codes (specification only).
  *
- * Copyright 1996-2018 by
+ * Copyright 2001-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -15,14 +15,16 @@
  *
  */
 
+
   /**************************************************************************
    *
-   * This file is used to define the TFM error enumeration constants.
+   * This file is used to define the TFM auxiliary module error enumeration
+   * constants.
    *
    */
 
-#ifndef TFMERROR_H_
-#define TFMERROR_H_
+#ifndef TFMERR_H_
+#define TFMERR_H_
 
 #include FT_MODULE_ERRORS_H
 
@@ -34,7 +36,7 @@
 
 #include FT_ERRORS_H
 
-#endif /* TFMERROR_H_ */
+#endif /* TFMERR_H_ */
 
 
 /* END */
diff --git a/src/tfm/tfmmod.c b/src/tfm/tfmmod.c
new file mode 100644
index 0000000..f987fa4
--- /dev/null
+++ b/src/tfm/tfmmod.c
@@ -0,0 +1,50 @@
+/****************************************************************************
+ *
+ * tfmmod.c
+ *
+ *   FreeType auxiliary TFM module.
+ *
+ * Copyright 2000-2018 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#include <ft2build.h>
+#include "tfmmod.h"
+#include "tfmobjs.h"
+
+
+  static
+  const TFM_Interface  tfm_interface =
+  {
+    tfm_init,           /* init          */
+    tfm_parse_metrics,  /* parse metrics */
+    tfm_close,          /* done          */
+  };
+
+
+  FT_CALLBACK_TABLE_DEF
+  const FT_Module_Class  tfm_module_class =
+  {
+    0,
+    sizeof ( FT_ModuleRec ),
+    "tfm",
+    0x20000L,
+    0x20000L,
+
+    &tfm_interface,   /* module-specific interface */
+
+    (FT_Module_Constructor)NULL,  /* module_init   */
+    (FT_Module_Destructor) NULL,  /* module_done   */
+    (FT_Module_Requester)  NULL   /* get_interface */
+  };
+
+
+/* END */
diff --git a/src/tfm/tfm.c b/src/tfm/tfmmod.h
similarity index 63%
copy from src/tfm/tfm.c
copy to src/tfm/tfmmod.h
index 26a58d9..f1fec8f 100644
--- a/src/tfm/tfm.c
+++ b/src/tfm/tfmmod.h
@@ -1,10 +1,10 @@
 /****************************************************************************
  *
- * tfm.c
+ * tfmmod.h
  *
- *   FreeType font driver for TeX's TFM FONT files
+ *   FreeType auxiliary TFM module.
  *
- * Copyright 1996-2018 by
+ * Copyright 2000-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
  *
  * This file is part of the FreeType project, and may only be used,
@@ -16,12 +16,24 @@
  */
 
 
-#define FT_MAKE_OPTION_SINGLE_OBJECT
+#ifndef TFMMOD_H_
+#define TFMMOD_H_
+
 
 #include <ft2build.h>
+#include FT_MODULE_H
+
+#include FT_INTERNAL_TFM_H
+
+FT_BEGIN_HEADER
+
+
+  FT_EXPORT_VAR( const FT_Module_Class )  tfm_driver_class;
+
+
+FT_END_HEADER
 
-#include "tfmlib.c"
-#include "tfmdrivr.c"
+#endif /* TFMMOD_H_ */
 
 
 /* END */
diff --git a/src/tfm/tfmlib.c b/src/tfm/tfmobjs.c
similarity index 61%
rename from src/tfm/tfmlib.c
rename to src/tfm/tfmobjs.c
index 92c38bc..69ec22e 100644
--- a/src/tfm/tfmlib.c
+++ b/src/tfm/tfmobjs.c
@@ -1,8 +1,8 @@
 /****************************************************************************
  *
- * tfmlib.c
+ * tfmobjs.c
  *
- *   FreeType font driver for TeX's TFM FONT files
+ *   FreeType auxiliary TFM module.
  *
  * Copyright 1996-2018 by
  * David Turner, Robert Wilhelm, and Werner Lemberg.
@@ -15,20 +15,19 @@
  *
  */
 
-#include <ft2build.h>
 
+#include <ft2build.h>
 #include FT_FREETYPE_H
-#include FT_INTERNAL_DEBUG_H
 #include FT_INTERNAL_STREAM_H
-#include FT_INTERNAL_OBJECTS_H
-#include FT_SYSTEM_H
-#include FT_CONFIG_CONFIG_H
-#include FT_ERRORS_H
-#include FT_TYPES_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_TFM_H
+
+#include "tfmobjs.h"
+#include "tfmmod.h"
+#include "tfmerr.h"
+
+
 
-#include "tfm.h"
-#include "tfmdrivr.h"
-#include "tfmerror.h"
 
 
   /**************************************************************************
@@ -38,9 +37,10 @@
    * messages during execution.
    */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_tfmlib
+#define FT_COMPONENT  trace_tfmobjs
 
-  /**************************************************************************
+
+ /**************************************************************************
    *
    * TFM font utility functions.
    *
@@ -49,9 +49,9 @@
   long           tfm_read_intn(FT_Stream,int);
   unsigned long  tfm_read_uintn(FT_Stream,int);
 
-#define READ_UINT2( stream )    (UINT1)tfm_read_uintn( stream, 2)
-#define READ_UINT4( stream )    (UINT1)tfm_read_uintn( stream, 4)
-#define READ_INT4( stream )     (INT4)tfm_read_intn( stream, 4)
+#define READ_UINT2( stream )    (FT_Byte)tfm_read_uintn( stream, 2)
+#define READ_UINT4( stream )    (FT_Byte)tfm_read_uintn( stream, 4)
+#define READ_INT4( stream )     (FT_Long)tfm_read_intn( stream, 4)
 
 /*
  * Reading a Number from file
@@ -105,60 +105,78 @@
    *
    */
 
-  FT_LOCAL_DEF( void )
-  tfm_free_font( TFM_Glyph tfm, FT_Memory memory )
+  FT_LOCAL_DEF( FT_Error )
+  tfm_init( TFM_Parser  parser,
+            FT_Memory   memory,
+            FT_Stream   stream )
+  {
+    parser->memory    = memory;
+    parser->stream    = stream;
+    parser->FontInfo  = NULL;
+    parser->user_data = NULL;
+
+    return FT_Err_Ok;
+  }
+
+
+  FT_LOCAL( void )
+  tfm_close( TFM_Parser  parser )
   {
-    if (tfm == NULL)
-      return;
+    FT_Memory  memory = parser->memory;
 
-      FT_FREE(tfm->width);
-      FT_FREE(tfm->height);
-      FT_FREE(tfm->depth);
-      FT_FREE(tfm);
+    FT_FREE( parser->stream );
   }
 
+
   FT_LOCAL_DEF( FT_Error )
-  tfm_load_font(  FT_Stream       stream,
-                  FT_Memory       extmemory,
-                  TFM_Glyph       *tfmptr  )
+  tfm_parse_metrics( TFM_Parser  parser )
   {
-    TFM_Glyph  tfm;
-    UINT4  lf, lh, nc, nci, err;
-    UINT4  offset_header, offset_char_info, offset_param;
-    UINT4  nw,  nh,  nd,  ni, nl, nk, neng, np, dir;
-    INT4   *w,  *h,  *d;
-    UINT4  *ci, v;
-    UINT4  i;
-    INT4   bbxw, bbxh, xoff, yoff;
-    FT_Error        error  =FT_Err_Ok;
-    FT_Memory       memory = extmemory; /* needed for FT_NEW */
-
-    if( FT_ALLOC(tfm, sizeof(TFM_GlyphRec)) )
-      goto Exit;
+    FT_Memory     memory = parser->memory;
+    TFM_FontInfo  fi     = parser->FontInfo;
+    FT_Stream     stream = parser->stream;
+    FT_Error      error  = FT_ERR( Syntax_Error );
 
-    tfm->width  = NULL;
-    tfm->height = NULL;
-    tfm->depth  = NULL;
+    FT_ULong      lf, lh, nc, nci;
+    FT_ULong      offset_header, offset_char_info, offset_param;
+    FT_ULong      nw,  nh,  nd,  ni, nl, nk, neng, np;
 
-    tfm->font_bbx_w = 0.0;
-    tfm->font_bbx_h = 0.0;
-    tfm->font_bbx_xoff = 0.0;
-    tfm->font_bbx_yoff = 0.0;
+    FT_Long       *w,  *h,  *d;
+    FT_ULong      *ci, v;
+
+    FT_ULong      i;
+    FT_Long       bbxw, bbxh, xoff, yoff;
+
+    if ( !fi )
+      return FT_THROW( Invalid_Argument );
+
+    fi->width  = NULL;
+    fi->height = NULL;
+    fi->depth  = NULL;
+    ci         = NULL;
+    w          = NULL;
+    h          = NULL;
+    d          = NULL;
+
+    fi->font_bbx_w = 0.0;
+    fi->font_bbx_h = 0.0;
+    fi->font_bbx_xoff = 0.0;
+    fi->font_bbx_yoff = 0.0;
 
-    err = 0;
     /* rewind(fp); */
     if( FT_STREAM_SEEK( 0 ) )
       return error;
-    lf = (UINT4)READ_UINT2( stream );
+
+    lf = (FT_ULong)READ_UINT2( stream );
+
     #if 0
     if ((lf == 11) || (lf == 9))
     {
       /* JFM file of Japanese TeX by ASCII Coop. */
       tfm->type        = METRIC_TYPE_JFM;
       tfm->type_aux    = (lf == 
11)?METRIC_TYPE_JFM_AUX_H:METRIC_TYPE_JFM_AUX_V;
-      tfm->nt          = (UINT4)READ_UINT2(fp);
-      lf               = (UINT4)READ_UINT2(fp);
-      lh               = (UINT4)READ_UINT2(fp);
+      tfm->nt          = (FT_ULong)READ_UINT2(fp);
+      lf               = (FT_ULong)READ_UINT2(fp);
+      lh               = (FT_ULong)READ_UINT2(fp);
       offset_header    = 4*7;
       offset_char_info = 4*(7+tfm->nt+lh);
     }
@@ -185,8 +203,8 @@
     else
     { }
     #endif
+
     /* Traditional TeX Metric File */
-    tfm->type_aux    = 0;
     lh               = (int)READ_UINT2( stream );
     offset_header    = 4*6;
     offset_char_info = 4*(6+lh);
@@ -217,24 +235,26 @@
     else
     { }
     #endif
-    tfm->begin_char  = (int)READ_UINT2( stream );
-    tfm->end_char    = (int)READ_UINT2( stream );
-    nw   = (UINT4)READ_UINT2( stream );
-    nh   = (UINT4)READ_UINT2( stream );
-    nd   = (UINT4)READ_UINT2( stream );
-
-    ni   = (UINT4)READ_UINT2( stream );
-    nl   = (UINT4)READ_UINT2( stream );
-    nk   = (UINT4)READ_UINT2( stream );
-    neng = (UINT4)READ_UINT2( stream );
-    np   = (UINT4)READ_UINT2( stream );
+
+    fi->begin_char  = (int)READ_UINT2( stream );
+    fi->end_char    = (int)READ_UINT2( stream );
+
+    nw   = (FT_ULong)READ_UINT2( stream );
+    nh   = (FT_ULong)READ_UINT2( stream );
+    nd   = (FT_ULong)READ_UINT2( stream );
+
+    ni   = (FT_ULong)READ_UINT2( stream );
+    nl   = (FT_ULong)READ_UINT2( stream );
+    nk   = (FT_ULong)READ_UINT2( stream );
+    neng = (FT_ULong)READ_UINT2( stream );
+    np   = (FT_ULong)READ_UINT2( stream );
 
     #if 0
       if (tfm->type == METRIC_TYPE_TFM)
         {}
     #endif
-    if (((signed)(tfm->begin_char-1) > (signed)tfm->end_char) ||
-       (tfm->end_char > 255))
+    if (((signed)(fi->begin_char-1) > (signed)fi->end_char) ||
+       (fi->end_char > 255))
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
@@ -243,28 +263,34 @@
     /* fseek(fp, offset_header, SEEK_SET); */
     if (FT_STREAM_SEEK( offset_header ) )
       goto Exit;
-    tfm->cs          = READ_UINT4( stream );
-    tfm->ds          = READ_UINT4( stream );
-    tfm->design_size = (double)(tfm->ds)/(double)(1<<20);
+    fi->cs          = READ_UINT4( stream ); /* Check Sum  */
+    fi->ds          = READ_UINT4( stream ); /* Design Size */
+
+    fi->design_size = (FT_ULong)((double)(fi->ds)/(double)(1<<20));
 
-    nc  = tfm->end_char - tfm->begin_char + 1;
+    nc  = fi->end_char - fi->begin_char + 1;
     nci = nc;
+
     #if 0
     if (tfm->type == METRIC_TYPE_OFM)
       nci *= 2;
     #endif
-    ci = (UINT4*)calloc(nci, sizeof(UINT4));
-    w  = (INT4*)calloc(nw,  sizeof(UINT4));
-    h  = (INT4*)calloc(nh,  sizeof(UINT4));
-    d  = (INT4*)calloc(nd,  sizeof(UINT4));
+
+    ci = (FT_ULong*)calloc(nci, sizeof(FT_ULong));
+    w  = (FT_Long*)calloc(nw,  sizeof(FT_ULong));
+    h  = (FT_Long*)calloc(nh,  sizeof(FT_ULong));
+    d  = (FT_Long*)calloc(nd,  sizeof(FT_ULong));
+
     if ((ci == NULL) || (w == NULL) || (h == NULL) || (d == NULL))
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
     }
+
     /* fseek(fp, offset_char_info, SEEK_SET); */
-    if( FT_STREAM_SEEK( offset_char_info ) )
+    if( FT_STREAM_SEEK( offset_char_info ) ) /* Skip over coding scheme and 
font family name */
       goto Exit;
+
     for (i = 0; i < nci; i++)
       ci[i] = READ_UINT4( stream );
 
@@ -278,18 +304,21 @@
     for (i = 0; i < nd; i++)
       d[i] = READ_INT4( stream );
 
-    tfm->width  = (INT4*)calloc(nc, sizeof(INT4));
-    tfm->height = (INT4*)calloc(nc, sizeof(INT4));
-    tfm->depth  = (INT4*)calloc(nc, sizeof(INT4));
-    if ((tfm->width == NULL) || (tfm->height == NULL) || (tfm->depth == NULL))
+    fi->width  = (FT_Long*)calloc(nc, sizeof(FT_Long));
+    fi->height = (FT_Long*)calloc(nc, sizeof(FT_Long));
+    fi->depth  = (FT_Long*)calloc(nc, sizeof(FT_Long));
+
+    if ((fi->width == NULL) || (fi->height == NULL) || (fi->depth == NULL))
     {
       error = FT_THROW( Invalid_Argument );
       goto Exit;
     }
+
     bbxw = 0;
     bbxh = 0;
     xoff = 0;
     yoff = 0;
+
     #if 0
     if (tfm->type == METRIC_TYPE_OFM)
     {
@@ -316,28 +345,28 @@
     else
     { }
     #endif
+
     for (i = 0; i < nc; i++)
     {
       v = ci[i] / 0x10000L;
-      tfm->depth[i]  = d[v & 0xf];  v >>= 4;
-      tfm->height[i] = h[v & 0xf];  v >>= 4;
-      tfm->width[i]  = w[v & 0xff];
-      if (bbxw < tfm->width[i])
-             bbxw = tfm->width[i];
-      if (bbxh < (tfm->height[i] + tfm->depth[i]))
-             bbxh = tfm->height[i] + tfm->depth[i];
-      if (yoff > -tfm->depth[i])
-             yoff = -tfm->depth[i];
-      #if 0
-        printf("** %.3f %.3f\n",
-             (double)tfm->height[i]/(double)(1<<20),
-             (double)tfm->depth[i]/(double)(1<<20));
-      #endif
+      fi->depth[i]  = d[v & 0xf];  v >>= 4;
+      fi->height[i] = h[v & 0xf];  v >>= 4;
+      fi->width[i]  = w[v & 0xff];
+
+      if (bbxw < fi->width[i])
+             bbxw = fi->width[i];
+
+      if (bbxh < (fi->height[i] + fi->depth[i]))
+             bbxh = fi->height[i] + fi->depth[i];
+
+      if (yoff > -fi->depth[i])
+             yoff = -fi->depth[i];
     }
-    tfm->font_bbx_w = tfm->design_size * ((double)bbxw / (double)(1<<20));
-    tfm->font_bbx_h = tfm->design_size * ((double)bbxh / (double)(1<<20));
-    tfm->font_bbx_xoff = tfm->design_size * ((double)xoff / (double)(1<<20));
-    tfm->font_bbx_yoff = tfm->design_size * ((double)yoff / (double)(1<<20));
+
+    fi->font_bbx_w = (FT_ULong)(fi->design_size * ((double)bbxw / 
(double)(1<<20)));
+    fi->font_bbx_h = (FT_ULong)(fi->design_size * ((FT_ULong)bbxh / 
(double)(1<<20)));
+    fi->font_bbx_xoff = (FT_ULong)(fi->design_size * ((double)xoff / 
(double)(1<<20)));
+    fi->font_bbx_yoff = (FT_ULong)(fi->design_size * ((double)yoff / 
(double)(1<<20)));
 
     #if 0
     if (tfm->type == METRIC_TYPE_JFM)
@@ -364,22 +393,20 @@
     /* fseek(fp, offset_param, SEEK_SET); */
     if( FT_STREAM_SEEK( offset_param ) )
       return error; /* To be changed */
-    if (FT_READ_ULONG(tfm->slant) )
+    if (FT_READ_ULONG(fi->slant) )
       return error;
-    tfm->slant = (double)tfm->slant/(double)(1<<20);
-    *tfmptr          = tfm;
-  Exit:
-    FT_FREE(ci);
-    FT_FREE(w);
-    FT_FREE(h);
-    FT_FREE(d);
+    fi->slant = (FT_ULong)((double)fi->slant/(double)(1<<20));
 
-    if (err != 0)
+  Exit:
+    if( !ci || !w || !h || !d )
     {
-      tfm_free_font(tfm, memory);
-      error = err;
+      FT_FREE(ci);
+      FT_FREE(w);
+      FT_FREE(h);
+      FT_FREE(d);
     }
     return error;
   }
 
+
 /* END */
diff --git a/src/tfm/tfmobjs.h b/src/tfm/tfmobjs.h
new file mode 100644
index 0000000..53bff11
--- /dev/null
+++ b/src/tfm/tfmobjs.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+ *
+ * tfmobjs.h
+ *
+ *   FreeType auxiliary TFM module.
+ *
+ * Copyright 1996-2018 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#ifndef TFMOBJS_H_
+#define TFMOBJS_H_
+
+#include <ft2build.h>
+#include "tfmmod.h"
+
+FT_BEGIN_HEADER
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_TFM_H
+
+
+FT_BEGIN_HEADER
+
+  /* Initialise the TFM stream */
+  FT_LOCAL( FT_Error )
+  tfm_init( TFM_Parser  parser,
+            FT_Memory   memory,
+            FT_Stream   stream );
+
+  /* Parse TFM metric data */
+  FT_LOCAL( FT_Error )
+  tfm_parse_metrics( TFM_Parser  parser );
+
+  FT_LOCAL( void )
+  tfm_close( TFM_Parser  parser );
+
+
+FT_END_HEADER
+
+#endif /* TFMOBJS_H_ */
+
+
+/* END */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]