shithub: freetype+ttf2subf

Download patch

ref: 6b3d00e1a0bc5033aeeab51912eda0aff6ed6e8b
parent: cf7d908c48007c4340aeee787e58e4002727973b
author: Werner Lemberg <[email protected]>
date: Tue Feb 3 16:34:29 EST 2004

* src/type1/t1load.c (parse_dict): Handle `RD' and `-|' commands
outside of /Subrs or /CharStrings.  This can happen if there is
additional code manipulating those two arrays so that FreeType
doesn't recognize them properly.
(T1_Open_Face): Improve an error message.

Remove CR/LF on many files.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2003-02-02  Werner Lemberg  <[email protected]>
+
+	* src/type1/t1load.c (parse_dict): Handle `RD' and `-|' commands
+	outside of /Subrs or /CharStrings.  This can happen if there is
+	additional code manipulating those two arrays so that FreeType
+	doesn't recognize them properly.
+	(T1_Open_Face): Improve an error message.
+
 2004-02-01  Werner Lemberg  <[email protected]>
 
 	* src/type1/t1load.c (parse_charstrings): Exit immediately if
@@ -9,16 +17,28 @@
 
 	* src/sfnt/Jamfile: Removing `ttcmap' from the list of sources.
 
-	* src/cache/*, include/freetype/cache/*: Fixing a bug after heavy
-	testing.  The current sources are now `release candidates' for the
-	final version of the cache sub-system.
+	* include/freetype/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP)
+	<FTC_INLINE>: Provide macro version which doesn't use inline code.
+	* include/freetype/cache/ftcglyph.h (FTC_GCACHE_LOOKUP_CMP)
+	<FTC_INLINE>: Ditto.
+	Use FTC_MRULIST_LOOKUP_CMP.
+	* include/freetype/cache/ftcmru.h (FTC_MRULIST_LOOKUP_CMP): New
+	macro.
+	(FTC_MRULIST_LOOKUP): Use it.
 
+	* src/cache/Jamfile (_sources), src/cache/descrip.mms: Updated.
+	* src/cache/ftcbasic.c: Fix compiler warnings.
+	* src/cache/ftcmanag.c (FTC_Manager_LookupSize,
+	FTC_Manager_LookupFace) <FTC_INLINE>: Use FTC_MRULIST_LOOKUP_CMP.
+	* src/cache/ftcmru.c (FTC_MruList_Find): Fix a bug (found after
+	heavy testing).
+
 	* Jamfile: Updating `refdoc' target, and adding `autohint' to the
 	list of modules to build.  Both the autohinter and autofitter will
 	be built by default.  But which one will be used is determined by
 	the content of `ftmodule.h'.
 
-	* src/autofit/*: Much updates, but the code is still buggy...
+	* src/autofit/*: Many updates, but the code is still buggy...
 
 2004-01-31  Werner Lemberg  <[email protected]>
 
--- a/Jamfile
+++ b/Jamfile
@@ -1,4 +1,4 @@
-# FreeType 2 top Jamfile (c) 2001, 2002, 2003 David Turner
+# FreeType 2 top Jamfile (c) 2001, 2002, 2003, 2004 David Turner
 #
 
 # The HDRMACRO is already defined in FTJam and is used to add
--- a/include/freetype/cache/ftccache.h
+++ b/include/freetype/cache/ftccache.h
@@ -1,271 +1,271 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftccache.h                                                             */
-/*                                                                         */
-/*    FreeType internal cache interface (specification).                   */
-/*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003 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 __FTCCACHE_H__
-#define __FTCCACHE_H__
-
-
-#include FT_CACHE_INTERNAL_MRU_H
-
-FT_BEGIN_HEADER
-
-  /* handle to cache object */
-  typedef struct FTC_CacheRec_*  FTC_Cache;
-
-  /* handle to cache class */
-  typedef const struct FTC_CacheClassRec_*  FTC_CacheClass;
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                   CACHE NODE DEFINITIONS                      *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Each cache controls one or more cache nodes.  Each node is part of    */
-  /* the global_lru list of the manager.  Its `data' field however is used */
-  /* as a reference count for now.                                         */
-  /*                                                                       */
-  /* A node can be anything, depending on the type of information held by  */
-  /* the cache.  It can be an individual glyph image, a set of bitmaps     */
-  /* glyphs for a given size, some metrics, etc.                           */
-  /*                                                                       */
-  /*************************************************************************/
-
-  /* structure size should be 20 bytes on 32-bits machines */
-  typedef struct  FTC_NodeRec_
-  {
-    FTC_MruNodeRec  mru;          /* circular mru list pointer           */
-    FTC_Node        link;         /* used for hashing                    */
-    FT_UInt32       hash;         /* used for hashing too                */
-    FT_UShort       cache_index;  /* index of cache the node belongs to  */
-    FT_Short        ref_count;    /* reference count for this node       */
-
-  } FTC_NodeRec;
-
-
-#define FTC_NODE( x )    ( (FTC_Node)(x) )
-#define FTC_NODE_P( x )  ( (FTC_Node*)(x) )
-
-#define FTC_NODE__NEXT(x)  FTC_NODE( (x)->mru.next )
-#define FTC_NODE__PREV(x)  FTC_NODE( (x)->mru.prev )
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* These functions are exported so that they can be called from          */
-  /* user-provided cache classes; otherwise, they are really part of the   */
-  /* cache sub-system internals.                                           */
-  /*                                                                       */
-
-  /* reserved for manager's use */
-  FT_EXPORT( void )
-  ftc_node_destroy( FTC_Node     node,
-                    FTC_Manager  manager );
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*****                                                               *****/
-  /*****                       CACHE DEFINITIONS                       *****/
-  /*****                                                               *****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /* initialize a new cache node */
-  typedef FT_Error
-  (*FTC_Node_NewFunc)( FTC_Node    *pnode,
-                       FT_Pointer   query,
-                       FTC_Cache    cache );
-
-  typedef FT_ULong
-  (*FTC_Node_WeightFunc)( FTC_Node   node,
-                          FTC_Cache  cache );
-
-  /* compare a node to a given key pair */
-  typedef FT_Bool
-  (*FTC_Node_CompareFunc)( FTC_Node    node,
-                           FT_Pointer  key,
-                           FTC_Cache   cache );
-
-
-  typedef void
-  (*FTC_Node_FreeFunc)( FTC_Node   node,
-                        FTC_Cache  cache );
-
-  typedef FT_Error
-  (*FTC_Cache_InitFunc)( FTC_Cache  cache );
-
-  typedef void
-  (*FTC_Cache_DoneFunc)( FTC_Cache  cache );
-
-
-  typedef struct  FTC_CacheClassRec_
-  {
-    FTC_Node_NewFunc      node_new;
-    FTC_Node_WeightFunc   node_weight;
-    FTC_Node_CompareFunc  node_compare;
-    FTC_Node_CompareFunc  node_remove_faceid;
-    FTC_Node_FreeFunc     node_free;
-
-    FT_UInt               cache_size;
-    FTC_Cache_InitFunc    cache_init;
-    FTC_Cache_DoneFunc    cache_done;
-
-  } FTC_CacheClassRec;
-
-
-  /* each cache really implements a dynamic hash table to manage its nodes */
-  typedef struct  FTC_CacheRec_
-  {
-    FT_UFast           p;
-    FT_UFast           mask;
-    FT_Long            slack;
-    FTC_Node*          buckets;
-
-    FTC_CacheClassRec  clazz;       /* local copy, for speed  */
-
-    FTC_Manager        manager;
-    FT_Memory          memory;
-    FT_UInt            index;       /* in manager's table     */
-
-    FTC_CacheClass     org_class;   /* original class pointer */
-
-  } FTC_CacheRec;
-
-
-#define FTC_CACHE( x )    ( (FTC_Cache)(x) )
-#define FTC_CACHE_P( x )  ( (FTC_Cache*)(x) )
-
-
-  /* default cache initialize */
-  FT_EXPORT( FT_Error )
-  FTC_Cache_Init( FTC_Cache  cache );
-
-  /* default cache finalizer */
-  FT_EXPORT( void )
-  FTC_Cache_Done( FTC_Cache  cache );
-
-  /* Call this function to lookup the cache.  If no corresponding
-   * node is found, a new one is automatically created.  This function
-   * is capable of flushing the cache adequately to make room for the
-   * new cache object.
-   */
-  FT_EXPORT( FT_Error )
-  FTC_Cache_Lookup( FTC_Cache   cache,
-                    FT_UInt32   hash,
-                    FT_Pointer  query,
-                    FTC_Node   *anode );
-
-  FT_EXPORT( FT_Error )
-  FTC_Cache_NewNode( FTC_Cache   cache,
-                     FT_UInt32   hash,
-                     FT_Pointer  query,
-                     FTC_Node   *anode );
-
-  /* Remove all nodes that relate to a given face_id.  This is useful
-   * when un-installing fonts.  Note that if a cache node relates to
-   * the face_id, but is locked (i.e., has 'ref_count > 0'), the node
-   * will _not_ be destroyed, but its internal face_id reference will
-   * be modified.
-   *
-   * The final result will be that the node will never come back
-   * in further lookup requests, and will be flushed on demand from
-   * the cache normally when its reference count reaches 0.
-   */
-  FT_EXPORT( void )
-  FTC_Cache_RemoveFaceID( FTC_Cache   cache,
-                          FTC_FaceID  face_id );
-
-
-#ifdef FTC_INLINE
-
-#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error )   \
-  FT_BEGIN_STMNT                                                           \
-    FTC_Node             *_bucket, *_pnode, _node;                         \
-    FTC_Cache             _cache   = FTC_CACHE(cache);                     \
-    FT_UInt32             _hash    = (FT_UInt32)(hash);                    \
-    FTC_Node_CompareFunc  _nodcomp = (FTC_Node_CompareFunc)(nodecmp);      \
-    FT_UInt               _idx;                                            \
-                                                                           \
-                                                                           \
-    error = 0;                                                             \
-    _idx  = _hash & _cache->mask;                                          \
-    if ( _idx < _cache->p )                                                \
-      _idx = _hash & (_cache->mask*2 + 1);                                 \
-                                                                           \
-    _bucket = _pnode = _cache->buckets + _idx;                             \
-    for (;;)                                                               \
-    {                                                                      \
-      _node = *_pnode;                                                     \
-      if ( _node == NULL )                                                 \
-        goto _NewNode;                                                     \
-                                                                           \
-      if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) )      \
-        break;                                                             \
-                                                                           \
-      _pnode = &_node->link;                                               \
-    }                                                                      \
-                                                                           \
-    if ( _node != *_bucket )                                               \
-    {                                                                      \
-      *_pnode     = _node->link;                                           \
-      _node->link = *_bucket;                                              \
-      *_bucket    = _node;                                                 \
-    }                                                                      \
-                                                                           \
-    {                                                                      \
-      FTC_Manager  _manager = _cache->manager;                             \
-                                                                           \
-                                                                           \
-      if ( _node != _manager->nodes_list )                                 \
-        FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list,               \
-                        (FTC_MruNode)_node );                              \
-    }                                                                      \
-    goto _Ok;                                                              \
-                                                                           \
-  _NewNode:                                                                \
-    error = FTC_Cache_NewNode( _cache, _hash, query, &_node );             \
-                                                                           \
-  _Ok:                                                                     \
-    *(FTC_Node*)&(node) = _node;                                           \
-  FT_END_STMNT
-
-#else /* !FTC_INLINE */
-
-#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error )   \
-  FT_BEGIN_STMNT                                                           \
-    error = FTC_Cache_Lookup( FTC_CACHE(cache), hash, query,               \
-                              (FTC_Node*)&(node) );                        \
-  FT_END_STMNT
-
-#endif /* !FTC_INLINE */
-
- /* */
-
-FT_END_HEADER
-
-
-#endif /* __FTCCACHE_H__ */
-
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftccache.h                                                             */
+/*                                                                         */
+/*    FreeType internal cache interface (specification).                   */
+/*                                                                         */
+/*  Copyright 2000-2001, 2002, 2003, 2004 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 __FTCCACHE_H__
+#define __FTCCACHE_H__
+
+
+#include FT_CACHE_INTERNAL_MRU_H
+
+FT_BEGIN_HEADER
+
+  /* handle to cache object */
+  typedef struct FTC_CacheRec_*  FTC_Cache;
+
+  /* handle to cache class */
+  typedef const struct FTC_CacheClassRec_*  FTC_CacheClass;
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                   CACHE NODE DEFINITIONS                      *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Each cache controls one or more cache nodes.  Each node is part of    */
+  /* the global_lru list of the manager.  Its `data' field however is used */
+  /* as a reference count for now.                                         */
+  /*                                                                       */
+  /* A node can be anything, depending on the type of information held by  */
+  /* the cache.  It can be an individual glyph image, a set of bitmaps     */
+  /* glyphs for a given size, some metrics, etc.                           */
+  /*                                                                       */
+  /*************************************************************************/
+
+  /* structure size should be 20 bytes on 32-bits machines */
+  typedef struct  FTC_NodeRec_
+  {
+    FTC_MruNodeRec  mru;          /* circular mru list pointer           */
+    FTC_Node        link;         /* used for hashing                    */
+    FT_UInt32       hash;         /* used for hashing too                */
+    FT_UShort       cache_index;  /* index of cache the node belongs to  */
+    FT_Short        ref_count;    /* reference count for this node       */
+
+  } FTC_NodeRec;
+
+
+#define FTC_NODE( x )    ( (FTC_Node)(x) )
+#define FTC_NODE_P( x )  ( (FTC_Node*)(x) )
+
+#define FTC_NODE__NEXT(x)  FTC_NODE( (x)->mru.next )
+#define FTC_NODE__PREV(x)  FTC_NODE( (x)->mru.prev )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* These functions are exported so that they can be called from          */
+  /* user-provided cache classes; otherwise, they are really part of the   */
+  /* cache sub-system internals.                                           */
+  /*                                                                       */
+
+  /* reserved for manager's use */
+  FT_EXPORT( void )
+  ftc_node_destroy( FTC_Node     node,
+                    FTC_Manager  manager );
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*****                                                               *****/
+  /*****                       CACHE DEFINITIONS                       *****/
+  /*****                                                               *****/
+  /*************************************************************************/
+  /*************************************************************************/
+
+  /* initialize a new cache node */
+  typedef FT_Error
+  (*FTC_Node_NewFunc)( FTC_Node    *pnode,
+                       FT_Pointer   query,
+                       FTC_Cache    cache );
+
+  typedef FT_ULong
+  (*FTC_Node_WeightFunc)( FTC_Node   node,
+                          FTC_Cache  cache );
+
+  /* compare a node to a given key pair */
+  typedef FT_Bool
+  (*FTC_Node_CompareFunc)( FTC_Node    node,
+                           FT_Pointer  key,
+                           FTC_Cache   cache );
+
+
+  typedef void
+  (*FTC_Node_FreeFunc)( FTC_Node   node,
+                        FTC_Cache  cache );
+
+  typedef FT_Error
+  (*FTC_Cache_InitFunc)( FTC_Cache  cache );
+
+  typedef void
+  (*FTC_Cache_DoneFunc)( FTC_Cache  cache );
+
+
+  typedef struct  FTC_CacheClassRec_
+  {
+    FTC_Node_NewFunc      node_new;
+    FTC_Node_WeightFunc   node_weight;
+    FTC_Node_CompareFunc  node_compare;
+    FTC_Node_CompareFunc  node_remove_faceid;
+    FTC_Node_FreeFunc     node_free;
+
+    FT_UInt               cache_size;
+    FTC_Cache_InitFunc    cache_init;
+    FTC_Cache_DoneFunc    cache_done;
+
+  } FTC_CacheClassRec;
+
+
+  /* each cache really implements a dynamic hash table to manage its nodes */
+  typedef struct  FTC_CacheRec_
+  {
+    FT_UFast           p;
+    FT_UFast           mask;
+    FT_Long            slack;
+    FTC_Node*          buckets;
+
+    FTC_CacheClassRec  clazz;       /* local copy, for speed  */
+
+    FTC_Manager        manager;
+    FT_Memory          memory;
+    FT_UInt            index;       /* in manager's table     */
+
+    FTC_CacheClass     org_class;   /* original class pointer */
+
+  } FTC_CacheRec;
+
+
+#define FTC_CACHE( x )    ( (FTC_Cache)(x) )
+#define FTC_CACHE_P( x )  ( (FTC_Cache*)(x) )
+
+
+  /* default cache initialize */
+  FT_EXPORT( FT_Error )
+  FTC_Cache_Init( FTC_Cache  cache );
+
+  /* default cache finalizer */
+  FT_EXPORT( void )
+  FTC_Cache_Done( FTC_Cache  cache );
+
+  /* Call this function to lookup the cache.  If no corresponding
+   * node is found, a new one is automatically created.  This function
+   * is capable of flushing the cache adequately to make room for the
+   * new cache object.
+   */
+  FT_EXPORT( FT_Error )
+  FTC_Cache_Lookup( FTC_Cache   cache,
+                    FT_UInt32   hash,
+                    FT_Pointer  query,
+                    FTC_Node   *anode );
+
+  FT_EXPORT( FT_Error )
+  FTC_Cache_NewNode( FTC_Cache   cache,
+                     FT_UInt32   hash,
+                     FT_Pointer  query,
+                     FTC_Node   *anode );
+
+  /* Remove all nodes that relate to a given face_id.  This is useful
+   * when un-installing fonts.  Note that if a cache node relates to
+   * the face_id, but is locked (i.e., has 'ref_count > 0'), the node
+   * will _not_ be destroyed, but its internal face_id reference will
+   * be modified.
+   *
+   * The final result will be that the node will never come back
+   * in further lookup requests, and will be flushed on demand from
+   * the cache normally when its reference count reaches 0.
+   */
+  FT_EXPORT( void )
+  FTC_Cache_RemoveFaceID( FTC_Cache   cache,
+                          FTC_FaceID  face_id );
+
+
+#ifdef FTC_INLINE
+
+#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error )   \
+  FT_BEGIN_STMNT                                                           \
+    FTC_Node             *_bucket, *_pnode, _node;                         \
+    FTC_Cache             _cache   = FTC_CACHE(cache);                     \
+    FT_UInt32             _hash    = (FT_UInt32)(hash);                    \
+    FTC_Node_CompareFunc  _nodcomp = (FTC_Node_CompareFunc)(nodecmp);      \
+    FT_UInt               _idx;                                            \
+                                                                           \
+                                                                           \
+    error = 0;                                                             \
+    _idx  = _hash & _cache->mask;                                          \
+    if ( _idx < _cache->p )                                                \
+      _idx = _hash & (_cache->mask*2 + 1);                                 \
+                                                                           \
+    _bucket = _pnode = _cache->buckets + _idx;                             \
+    for (;;)                                                               \
+    {                                                                      \
+      _node = *_pnode;                                                     \
+      if ( _node == NULL )                                                 \
+        goto _NewNode;                                                     \
+                                                                           \
+      if ( _node->hash == _hash && _nodcomp( _node, query, _cache ) )      \
+        break;                                                             \
+                                                                           \
+      _pnode = &_node->link;                                               \
+    }                                                                      \
+                                                                           \
+    if ( _node != *_bucket )                                               \
+    {                                                                      \
+      *_pnode     = _node->link;                                           \
+      _node->link = *_bucket;                                              \
+      *_bucket    = _node;                                                 \
+    }                                                                      \
+                                                                           \
+    {                                                                      \
+      FTC_Manager  _manager = _cache->manager;                             \
+                                                                           \
+                                                                           \
+      if ( _node != _manager->nodes_list )                                 \
+        FTC_MruNode_Up( (FTC_MruNode*)&_manager->nodes_list,               \
+                        (FTC_MruNode)_node );                              \
+    }                                                                      \
+    goto _Ok;                                                              \
+                                                                           \
+  _NewNode:                                                                \
+    error = FTC_Cache_NewNode( _cache, _hash, query, &_node );             \
+                                                                           \
+  _Ok:                                                                     \
+    *(FTC_Node*)&(node) = _node;                                           \
+  FT_END_STMNT
+
+#else /* !FTC_INLINE */
+
+#define FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error )   \
+  FT_BEGIN_STMNT                                                           \
+    error = FTC_Cache_Lookup( FTC_CACHE(cache), hash, query,               \
+                              (FTC_Node*)&(node) );                        \
+  FT_END_STMNT
+
+#endif /* !FTC_INLINE */
+
+ /* */
+
+FT_END_HEADER
+
+
+#endif /* __FTCCACHE_H__ */
+
+
+/* END */
--- a/include/freetype/cache/ftcglyph.h
+++ b/include/freetype/cache/ftcglyph.h
@@ -1,297 +1,297 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftcglyph.h                                                             */
-/*                                                                         */
-/*    FreeType abstract glyph cache (specification).                       */
-/*                                                                         */
-/*  Copyright 2000-2001, 2003 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.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-  /*
-   *
-   *  FTC_GCache is an _abstract_ cache object optimized to store glyph
-   *  data.  It works as follows:
-   *
-   *   - It manages FTC_GNode objects. Each one of them can hold one or more
-   *     glyph `items'.  Item types are not specified in the FTC_GCache but
-   *     in classes that extend it.
-   *
-   *   - Glyph attributes, like face ID, character size, render mode, etc.,
-   *     can be grouped into abstract `glyph families'.  This avoids storing
-   *     the attributes within the FTC_GCache, since it is likely that many
-   *     FTC_GNodes will belong to the same family in typical uses.
-   *
-   *   - Each FTC_GNode is thus an FTC_Node with two additional fields:
-   *
-   *       * gindex: A glyph index, or the first index in a glyph range.
-   *       * family: A pointer to a glyph `family'.
-   *
-   *   - Family types are not fully specific in the FTC_Family type, but
-   *     by classes that extend it.
-   *
-   *  Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache.
-   *  They share an FTC_Family sub-class called FTC_BasicFamily which is
-   *  used to store the following data: face ID, pixel/point sizes, load
-   *  flags.  For more details see the file `src/cache/ftcbasic.c'.
-   *
-   *  Client applications can extend FTC_GNode with their own FTC_GNode
-   *  and FTC_Family sub-classes to implement more complex caches (e.g.,
-   *  handling automatic synthesis, like obliquing & emboldening, colored
-   *  glyphs, etc.).
-   *
-   *  See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and
-   *  `ftcsbits.h', which both extend FTC_GCache with additional
-   *  optimizations.
-   *
-   *  A typical FTC_GCache implementation must provide at least the
-   *  following:
-   *
-   *  - FTC_GNode sub-class, e.g. MyNode, with relevant methods:
-   *        my_node_new            (must call FTC_GNode_Init)
-   *        my_node_free           (must call FTC_GNode_Done)
-   *        my_node_compare        (must call FTC_GNode_Compare)
-   *        my_node_remove_faceid  (must call ftc_gnode_unselect in case
-   *                                of match)
-   *
-   *  - FTC_Family sub-class, e.g. MyFamily, with relevant methods:
-   *        my_family_compare
-   *        my_family_init
-   *        my_family_reset (optional)
-   *        my_family_done
-   *
-   *  - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query
-   *    data.
-   *
-   *  - Constant structures for a FTC_GNodeClass.
-   *
-   *  - MyCacheNew() can be implemented easily as a call to the convenience
-   *    function FTC_GCache_New.
-   *
-   *  - MyCacheLookup with a call to FTC_GCache_Lookup.  This function will
-   *    automatically:
-   *
-   *    - Search for the corresponding family in the cache, or create
-   *      a new one if necessary.  Put it in FTC_GQUERY(myquery).family
-   *
-   *    - Call FTC_Cache_Lookup.
-   *
-   *    If it returns NULL, you should create a new node, then call
-   *    ftc_cache_add as usual.
-   */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Important: The functions defined in this file are only used to        */
-  /*            implement an abstract glyph cache class.  You need to      */
-  /*            provide additional logic to implement a complete cache.    */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*********                                                       *********/
-  /*********             WARNING, THIS IS BETA CODE.               *********/
-  /*********                                                       *********/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-#ifndef __FTCGLYPH_H__
-#define __FTCGLYPH_H__
-
-
-#include <ft2build.h>
-#include FT_CACHE_INTERNAL_MANAGER_H
-
-
-FT_BEGIN_HEADER
-
-
- /*
-  *  We can group glyphs into `families'.  Each family correspond to a
-  *  given face ID, character size, transform, etc.
-  *
-  *  Families are implemented as MRU list nodes.  They are
-  *  reference-counted.
-  */
-
-  typedef struct  FTC_FamilyRec_
-  {
-    FTC_MruNodeRec    mrunode;
-    FT_UInt           num_nodes; /* current number of nodes in this family */
-    FTC_Cache         cache;
-    FTC_MruListClass  clazz;
-
-  } FTC_FamilyRec, *FTC_Family;
-
-#define  FTC_FAMILY(x)    ( (FTC_Family)(x) )
-#define  FTC_FAMILY_P(x)  ( (FTC_Family*)(x) )
-
-
-  typedef struct  FTC_GNodeRec_
-  {
-    FTC_NodeRec      node;
-    FTC_Family       family;
-    FT_UInt          gindex;
-
-  } FTC_GNodeRec, *FTC_GNode;
-
-#define FTC_GNODE( x )    ( (FTC_GNode)(x) )
-#define FTC_GNODE_P( x )  ( (FTC_GNode*)(x) )
-
-
-  typedef struct  FTC_GQueryRec_
-  {
-    FT_UInt      gindex;
-    FTC_Family   family;
-
-  } FTC_GQueryRec, *FTC_GQuery;
-
-#define FTC_GQUERY( x )  ( (FTC_GQuery)(x) )
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* These functions are exported so that they can be called from          */
-  /* user-provided cache classes; otherwise, they are really part of the   */
-  /* cache sub-system internals.                                           */
-  /*                                                                       */
-
-  /* must be called by derived FTC_Node_InitFunc routines */
-  FT_EXPORT( void )
-  FTC_GNode_Init( FTC_GNode   node,
-                  FT_UInt     gindex,  /* glyph index for node */
-                  FTC_Family  family );
-
-  /* returns TRUE iff the query's glyph index correspond to the node;  */
-  /* this assumes that the "family" and "hash" fields of the query are */
-  /* already correctly set                                             */
-  FT_EXPORT( FT_Bool )
-  FTC_GNode_Compare( FTC_GNode   gnode,
-                     FTC_GQuery  gquery );
-
-  /* call this function to clear a node's family -- this is necessary */
-  /* to implement the `node_remove_faceid' cache method correctly     */
-  FT_EXPORT( void )
-  FTC_GNode_UnselectFamily( FTC_GNode  gnode,
-                            FTC_Cache  cache );
-
-  /* must be called by derived FTC_Node_DoneFunc routines */
-  FT_EXPORT( void )
-  FTC_GNode_Done( FTC_GNode  node,
-                  FTC_Cache  cache );
-
-
-  FT_EXPORT( void )
-  FTC_Family_Init( FTC_Family  family,
-                   FTC_Cache   cache );
-
-  typedef struct FTC_GCacheRec_
-  {
-    FTC_CacheRec    cache;
-    FTC_MruListRec  families;
-
-  } FTC_GCacheRec, *FTC_GCache;
-
-#define FTC_GCACHE( x )  ((FTC_GCache)(x))
-
-
-  /* can be used as @FTC_Cache_InitFunc */
-  FT_EXPORT( FT_Error )
-  FTC_GCache_Init( FTC_GCache  cache );
-
-
-  /* can be used as @FTC_Cache_DoneFunc */
-  FT_EXPORT( void )
-  FTC_GCache_Done( FTC_GCache  cache );
-
-
-  /* the glyph cache class adds fields for the family implementation */
-  typedef struct  FTC_GCacheClassRec_
-  {
-    FTC_CacheClassRec  clazz;
-    FTC_MruListClass   family_class;
-
-  } FTC_GCacheClassRec;
-
-  typedef const FTC_GCacheClassRec*   FTC_GCacheClass;
-
-#define FTC_GCACHE_CLASS( x )  ((FTC_GCacheClass)(x))
-
-#define FTC_CACHE__GCACHE_CLASS( x ) \
-          FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class )
-#define FTC_CACHE__FAMILY_CLASS( x ) \
-          ((FTC_MruListClass) FTC_CACHE__GCACHE_CLASS(x)->family_class)
-
-
-  /* convenience function; use it instead of FTC_Manager_Register_Cache */
-  FT_EXPORT( FT_Error )
-  FTC_GCache_New( FTC_Manager       manager,
-                  FTC_GCacheClass   clazz,
-                  FTC_GCache       *acache );
-
-  FT_EXPORT( FT_Error )
-  FTC_GCache_Lookup( FTC_GCache   cache,
-                     FT_UInt32    hash,
-                     FT_UInt      gindex,
-                     FTC_GQuery   query,
-                     FTC_Node    *anode );
-
-
-#ifdef FTC_INLINE
-
-#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,                \
-                               gindex, query, node, error )                 \
-  FT_BEGIN_STMNT                                                            \
-    FTC_GCache               _gcache   = FTC_GCACHE( cache );               \
-    FTC_GQuery               _gquery   = (FTC_GQuery)( query );             \
-    FTC_MruNode_CompareFunc  _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \
-                                                                            \
-                                                                            \
-    _gquery->gindex = (gindex);                                             \
-                                                                            \
-    FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare,         \
-                            _gquery->family, error );                       \
-    if ( !error )                                                           \
-    {                                                                       \
-      FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error );     \
-    }                                                                       \
-  FT_END_STMNT
-  /* */
-
-#else /* !FTC_INLINE */
-
-#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,                \
-                               gindex, query, node, error )                 \
-   FT_BEGIN_STMNT                                                           \
-     error = FTC_GCache_Lookup( FTC_GCACHE(cache), hash, gindex, FTC_GQUERY(query),     \
-                                (FTC_Node*) &(node) );                      \
-   FT_END_STMNT
-
-#endif /* !FTC_INLINE */
-
-
-FT_END_HEADER
-
-
-#endif /* __FTCGLYPH_H__ */
-
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftcglyph.h                                                             */
+/*                                                                         */
+/*    FreeType abstract glyph cache (specification).                       */
+/*                                                                         */
+/*  Copyright 2000-2001, 2003, 2004 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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*
+   *
+   *  FTC_GCache is an _abstract_ cache object optimized to store glyph
+   *  data.  It works as follows:
+   *
+   *   - It manages FTC_GNode objects. Each one of them can hold one or more
+   *     glyph `items'.  Item types are not specified in the FTC_GCache but
+   *     in classes that extend it.
+   *
+   *   - Glyph attributes, like face ID, character size, render mode, etc.,
+   *     can be grouped into abstract `glyph families'.  This avoids storing
+   *     the attributes within the FTC_GCache, since it is likely that many
+   *     FTC_GNodes will belong to the same family in typical uses.
+   *
+   *   - Each FTC_GNode is thus an FTC_Node with two additional fields:
+   *
+   *       * gindex: A glyph index, or the first index in a glyph range.
+   *       * family: A pointer to a glyph `family'.
+   *
+   *   - Family types are not fully specific in the FTC_Family type, but
+   *     by classes that extend it.
+   *
+   *  Note that both FTC_ImageCache and FTC_SBitCache extend FTC_GCache.
+   *  They share an FTC_Family sub-class called FTC_BasicFamily which is
+   *  used to store the following data: face ID, pixel/point sizes, load
+   *  flags.  For more details see the file `src/cache/ftcbasic.c'.
+   *
+   *  Client applications can extend FTC_GNode with their own FTC_GNode
+   *  and FTC_Family sub-classes to implement more complex caches (e.g.,
+   *  handling automatic synthesis, like obliquing & emboldening, colored
+   *  glyphs, etc.).
+   *
+   *  See also the FTC_ICache & FTC_SCache classes in `ftcimage.h' and
+   *  `ftcsbits.h', which both extend FTC_GCache with additional
+   *  optimizations.
+   *
+   *  A typical FTC_GCache implementation must provide at least the
+   *  following:
+   *
+   *  - FTC_GNode sub-class, e.g. MyNode, with relevant methods:
+   *        my_node_new            (must call FTC_GNode_Init)
+   *        my_node_free           (must call FTC_GNode_Done)
+   *        my_node_compare        (must call FTC_GNode_Compare)
+   *        my_node_remove_faceid  (must call ftc_gnode_unselect in case
+   *                                of match)
+   *
+   *  - FTC_Family sub-class, e.g. MyFamily, with relevant methods:
+   *        my_family_compare
+   *        my_family_init
+   *        my_family_reset (optional)
+   *        my_family_done
+   *
+   *  - FTC_GQuery sub-class, e.g. MyQuery, to hold cache-specific query
+   *    data.
+   *
+   *  - Constant structures for a FTC_GNodeClass.
+   *
+   *  - MyCacheNew() can be implemented easily as a call to the convenience
+   *    function FTC_GCache_New.
+   *
+   *  - MyCacheLookup with a call to FTC_GCache_Lookup.  This function will
+   *    automatically:
+   *
+   *    - Search for the corresponding family in the cache, or create
+   *      a new one if necessary.  Put it in FTC_GQUERY(myquery).family
+   *
+   *    - Call FTC_Cache_Lookup.
+   *
+   *    If it returns NULL, you should create a new node, then call
+   *    ftc_cache_add as usual.
+   */
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* Important: The functions defined in this file are only used to        */
+  /*            implement an abstract glyph cache class.  You need to      */
+  /*            provide additional logic to implement a complete cache.    */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*********                                                       *********/
+  /*********             WARNING, THIS IS BETA CODE.               *********/
+  /*********                                                       *********/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+#ifndef __FTCGLYPH_H__
+#define __FTCGLYPH_H__
+
+
+#include <ft2build.h>
+#include FT_CACHE_INTERNAL_MANAGER_H
+
+
+FT_BEGIN_HEADER
+
+
+ /*
+  *  We can group glyphs into `families'.  Each family correspond to a
+  *  given face ID, character size, transform, etc.
+  *
+  *  Families are implemented as MRU list nodes.  They are
+  *  reference-counted.
+  */
+
+  typedef struct  FTC_FamilyRec_
+  {
+    FTC_MruNodeRec    mrunode;
+    FT_UInt           num_nodes; /* current number of nodes in this family */
+    FTC_Cache         cache;
+    FTC_MruListClass  clazz;
+
+  } FTC_FamilyRec, *FTC_Family;
+
+#define  FTC_FAMILY(x)    ( (FTC_Family)(x) )
+#define  FTC_FAMILY_P(x)  ( (FTC_Family*)(x) )
+
+
+  typedef struct  FTC_GNodeRec_
+  {
+    FTC_NodeRec      node;
+    FTC_Family       family;
+    FT_UInt          gindex;
+
+  } FTC_GNodeRec, *FTC_GNode;
+
+#define FTC_GNODE( x )    ( (FTC_GNode)(x) )
+#define FTC_GNODE_P( x )  ( (FTC_GNode*)(x) )
+
+
+  typedef struct  FTC_GQueryRec_
+  {
+    FT_UInt      gindex;
+    FTC_Family   family;
+
+  } FTC_GQueryRec, *FTC_GQuery;
+
+#define FTC_GQUERY( x )  ( (FTC_GQuery)(x) )
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* These functions are exported so that they can be called from          */
+  /* user-provided cache classes; otherwise, they are really part of the   */
+  /* cache sub-system internals.                                           */
+  /*                                                                       */
+
+  /* must be called by derived FTC_Node_InitFunc routines */
+  FT_EXPORT( void )
+  FTC_GNode_Init( FTC_GNode   node,
+                  FT_UInt     gindex,  /* glyph index for node */
+                  FTC_Family  family );
+
+  /* returns TRUE iff the query's glyph index correspond to the node;  */
+  /* this assumes that the "family" and "hash" fields of the query are */
+  /* already correctly set                                             */
+  FT_EXPORT( FT_Bool )
+  FTC_GNode_Compare( FTC_GNode   gnode,
+                     FTC_GQuery  gquery );
+
+  /* call this function to clear a node's family -- this is necessary */
+  /* to implement the `node_remove_faceid' cache method correctly     */
+  FT_EXPORT( void )
+  FTC_GNode_UnselectFamily( FTC_GNode  gnode,
+                            FTC_Cache  cache );
+
+  /* must be called by derived FTC_Node_DoneFunc routines */
+  FT_EXPORT( void )
+  FTC_GNode_Done( FTC_GNode  node,
+                  FTC_Cache  cache );
+
+
+  FT_EXPORT( void )
+  FTC_Family_Init( FTC_Family  family,
+                   FTC_Cache   cache );
+
+  typedef struct FTC_GCacheRec_
+  {
+    FTC_CacheRec    cache;
+    FTC_MruListRec  families;
+
+  } FTC_GCacheRec, *FTC_GCache;
+
+#define FTC_GCACHE( x )  ((FTC_GCache)(x))
+
+
+  /* can be used as @FTC_Cache_InitFunc */
+  FT_EXPORT( FT_Error )
+  FTC_GCache_Init( FTC_GCache  cache );
+
+
+  /* can be used as @FTC_Cache_DoneFunc */
+  FT_EXPORT( void )
+  FTC_GCache_Done( FTC_GCache  cache );
+
+
+  /* the glyph cache class adds fields for the family implementation */
+  typedef struct  FTC_GCacheClassRec_
+  {
+    FTC_CacheClassRec  clazz;
+    FTC_MruListClass   family_class;
+
+  } FTC_GCacheClassRec;
+
+  typedef const FTC_GCacheClassRec*   FTC_GCacheClass;
+
+#define FTC_GCACHE_CLASS( x )  ((FTC_GCacheClass)(x))
+
+#define FTC_CACHE__GCACHE_CLASS( x ) \
+          FTC_GCACHE_CLASS( FTC_CACHE(x)->org_class )
+#define FTC_CACHE__FAMILY_CLASS( x ) \
+          ((FTC_MruListClass) FTC_CACHE__GCACHE_CLASS(x)->family_class)
+
+
+  /* convenience function; use it instead of FTC_Manager_Register_Cache */
+  FT_EXPORT( FT_Error )
+  FTC_GCache_New( FTC_Manager       manager,
+                  FTC_GCacheClass   clazz,
+                  FTC_GCache       *acache );
+
+  FT_EXPORT( FT_Error )
+  FTC_GCache_Lookup( FTC_GCache   cache,
+                     FT_UInt32    hash,
+                     FT_UInt      gindex,
+                     FTC_GQuery   query,
+                     FTC_Node    *anode );
+
+
+#ifdef FTC_INLINE
+
+#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,                \
+                               gindex, query, node, error )                 \
+  FT_BEGIN_STMNT                                                            \
+    FTC_GCache               _gcache   = FTC_GCACHE( cache );               \
+    FTC_GQuery               _gquery   = (FTC_GQuery)( query );             \
+    FTC_MruNode_CompareFunc  _fcompare = (FTC_MruNode_CompareFunc)(famcmp); \
+                                                                            \
+                                                                            \
+    _gquery->gindex = (gindex);                                             \
+                                                                            \
+    FTC_MRULIST_LOOKUP_CMP( &_gcache->families, _gquery, _fcompare,         \
+                            _gquery->family, error );                       \
+    if ( !error )                                                           \
+    {                                                                       \
+      FTC_CACHE_LOOKUP_CMP( cache, nodecmp, hash, query, node, error );     \
+    }                                                                       \
+  FT_END_STMNT
+  /* */
+
+#else /* !FTC_INLINE */
+
+#define FTC_GCACHE_LOOKUP_CMP( cache, famcmp, nodecmp, hash,                \
+                               gindex, query, node, error )                 \
+   FT_BEGIN_STMNT                                                           \
+     error = FTC_GCache_Lookup( FTC_GCACHE(cache), hash, gindex, FTC_GQUERY(query),     \
+                                (FTC_Node*) &(node) );                      \
+   FT_END_STMNT
+
+#endif /* !FTC_INLINE */
+
+
+FT_END_HEADER
+
+
+#endif /* __FTCGLYPH_H__ */
+
+
+/* END */
--- a/include/freetype/cache/ftcmru.h
+++ b/include/freetype/cache/ftcmru.h
@@ -1,246 +1,246 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftcmru.h                                                               */
-/*                                                                         */
-/*    Simple MRU list-cache (specification).                               */
-/*                                                                         */
-/*  Copyright 2000-2001, 2003 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.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* An MRU is a list that cannot hold more than a certain number of       */
-  /* elements (`max_elements').  All elements in the list are sorted in    */
-  /* least-recently-used order, i.e., the `oldest' element is at the tail  */
-  /* of the list.                                                          */
-  /*                                                                       */
-  /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'),   */
-  /* the list is searched for an element with the corresponding key.  If   */
-  /* it is found, the element is moved to the head of the list and is      */
-  /* returned.                                                             */
-  /*                                                                       */
-  /* If no corresponding element is found, the lookup routine will try to  */
-  /* obtain a new element with the relevant key.  If the list is already   */
-  /* full, the oldest element from the list is discarded and replaced by a */
-  /* new one; a new element is added to the list otherwise.                */
-  /*                                                                       */
-  /* Note that it is possible to pre-allocate the element list nodes.      */
-  /* This is handy if `max_elements' is sufficiently small, as it saves    */
-  /* allocations/releases during the lookup process.                       */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#ifndef __FTCMRU_H__
-#define __FTCMRU_H__
-
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#ifdef FREETYPE_H
-#error "freetype.h of FreeType 1 has been loaded!"
-#error "Please fix the directory search order for header files"
-#error "so that freetype.h of FreeType 2 is found first."
-#endif
-
-#define  xxFT_DEBUG_ERROR
-#define  FTC_INLINE
-
-FT_BEGIN_HEADER
-
-  typedef struct FTC_MruNodeRec_*  FTC_MruNode;
-
-  typedef struct  FTC_MruNodeRec_
-  {
-    FTC_MruNode  next;
-    FTC_MruNode  prev;
-
-  } FTC_MruNodeRec;
-
-
-  FT_EXPORT( void )
-  FTC_MruNode_Prepend( FTC_MruNode  *plist,
-                       FTC_MruNode   node );
-
-  FT_EXPORT( void )
-  FTC_MruNode_Up( FTC_MruNode  *plist,
-                  FTC_MruNode   node );
-
-  FT_EXPORT( void )
-  FTC_MruNode_Remove( FTC_MruNode  *plist,
-                      FTC_MruNode   node );
-
-
-  typedef struct FTC_MruListRec_*              FTC_MruList;
-
-  typedef struct FTC_MruListClassRec_ const *  FTC_MruListClass;
-
-
-  typedef FT_Int
-  (*FTC_MruNode_CompareFunc)( FTC_MruNode  node,
-                              FT_Pointer   key );
-
-  typedef FT_Error
-  (*FTC_MruNode_InitFunc)( FTC_MruNode  node,
-                           FT_Pointer   key,
-                           FT_Pointer   data );
-
-  typedef FT_Error
-  (*FTC_MruNode_ResetFunc)( FTC_MruNode  node,
-                            FT_Pointer   key,
-                            FT_Pointer   data );
-
-  typedef void
-  (*FTC_MruNode_DoneFunc)( FTC_MruNode  node,
-                           FT_Pointer   data );
-
-
-  typedef struct  FTC_MruListClassRec_
-  {
-    FT_UInt                  node_size;
-    FTC_MruNode_CompareFunc  node_compare;
-    FTC_MruNode_InitFunc     node_init;
-    FTC_MruNode_ResetFunc    node_reset;
-    FTC_MruNode_DoneFunc     node_done;
-
-  } FTC_MruListClassRec;
-
-  typedef struct  FTC_MruListRec_
-  {
-    FT_UInt              num_nodes;
-    FT_UInt              max_nodes;
-    FTC_MruNode          nodes;
-    FT_Pointer           data;
-    FTC_MruListClassRec  clazz;
-    FT_Memory            memory;
-
-  } FTC_MruListRec;
-
-
-  FT_EXPORT( void )
-  FTC_MruList_Init( FTC_MruList       list,
-                    FTC_MruListClass  clazz,
-                    FT_UInt           max_nodes,
-                    FT_Pointer        data,
-                    FT_Memory         memory );
-
-  FT_EXPORT( void )
-  FTC_MruList_Reset( FTC_MruList  list );
-
-
-  FT_EXPORT( void )
-  FTC_MruList_Done( FTC_MruList  list );
-
-  FT_EXPORT( FTC_MruNode )
-  FTC_MruList_Find( FTC_MruList  list,
-                    FT_Pointer   key );
-
-  FT_EXPORT( FT_Error )
-  FTC_MruList_New( FTC_MruList   list,
-                   FT_Pointer    key,
-                   FTC_MruNode  *anode );
-
-  FT_EXPORT( FT_Error )
-  FTC_MruList_Lookup( FTC_MruList   list,
-                      FT_Pointer    key,
-                      FTC_MruNode  *pnode );
-                      
-
-  FT_EXPORT( void )
-  FTC_MruList_Remove( FTC_MruList  list,
-                      FTC_MruNode  node );
-
-  FT_EXPORT( void )
-  FTC_MruList_RemoveSelection( FTC_MruList              list,
-                               FTC_MruNode_CompareFunc  selection,
-                               FT_Pointer               key );
-
-
-#ifdef FTC_INLINE
-
-#define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error )           \
-  FT_BEGIN_STMNT                                                            \
-    FTC_MruNode*             _pfirst  = &(list)->nodes;                     \
-    FTC_MruNode_CompareFunc  _compare = (FTC_MruNode_CompareFunc)(compare); \
-    FTC_MruNode              _first, _node;                              \
-                                                                         \
-                                                                         \
-    error  = 0;                                                          \
-    _first = *(_pfirst);                                                 \
-    _node  = NULL;                                                       \
-                                                                         \
-    if ( _first )                                                        \
-    {                                                                    \
-      _node = _first;                                                    \
-      do                                                                 \
-      {                                                                  \
-        if ( _compare( _node, (key) ) )                                  \
-        {                                                                \
-          if ( _node != _first )                                         \
-            FTC_MruNode_Up( _pfirst, _node );                            \
-                                                                         \
-          *(FTC_MruNode*)&(node) = _node;                                \
-          goto _MruOk;                                                   \
-        }                                                                \
-        _node = _node->next;                                             \
-                                                                         \
-      } while ( _node != _first) ;                                       \
-    }                                                                    \
-                                                                         \
-    error = FTC_MruList_New( (list), (key), (FTC_MruNode*)&(node) );     \
-  _MruOk:                                                                \
-    ;                                                                    \
-  FT_END_STMNT
-
-#define FTC_MRULIST_LOOKUP( list, key, node, error ) \
-  FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error )
-
-#else  /* !FTC_INLINE */
-
-#define FTC_MRULIST_LOOKUP( list, key, node, error ) \
-  error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) 
-
-#endif /* !FTC_INLINE */
-
-
-#define FTC_MRULIST_LOOP( list, node )        \
-  FT_BEGIN_STMNT                              \
-    FTC_MruNode  _first = (list)->nodes;      \
-                                              \
-                                              \
-    if ( _first )                             \
-    {                                         \
-      FTC_MruNode  _node = _first;            \
-                                              \
-                                              \
-      do                                      \
-      {                                       \
-        *(FTC_MruNode*)&(node) = _node;
-
-
-#define FTC_MRULIST_LOOP_END()               \
-        _node = _node->next;                 \
-                                             \
-      } while ( _node != _first );           \
-    }                                        \
-  FT_END_STMNT
-
- /* */
-
-FT_END_HEADER
-
-
-#endif /* __FTCMRU_H__ */
-
-
-/* END */
+/***************************************************************************/
+/*                                                                         */
+/*  ftcmru.h                                                               */
+/*                                                                         */
+/*    Simple MRU list-cache (specification).                               */
+/*                                                                         */
+/*  Copyright 2000-2001, 2003, 2004 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.                                        */
+/*                                                                         */
+/***************************************************************************/
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* An MRU is a list that cannot hold more than a certain number of       */
+  /* elements (`max_elements').  All elements in the list are sorted in    */
+  /* least-recently-used order, i.e., the `oldest' element is at the tail  */
+  /* of the list.                                                          */
+  /*                                                                       */
+  /* When doing a lookup (either through `Lookup()' or `Lookup_Node()'),   */
+  /* the list is searched for an element with the corresponding key.  If   */
+  /* it is found, the element is moved to the head of the list and is      */
+  /* returned.                                                             */
+  /*                                                                       */
+  /* If no corresponding element is found, the lookup routine will try to  */
+  /* obtain a new element with the relevant key.  If the list is already   */
+  /* full, the oldest element from the list is discarded and replaced by a */
+  /* new one; a new element is added to the list otherwise.                */
+  /*                                                                       */
+  /* Note that it is possible to pre-allocate the element list nodes.      */
+  /* This is handy if `max_elements' is sufficiently small, as it saves    */
+  /* allocations/releases during the lookup process.                       */
+  /*                                                                       */
+  /*************************************************************************/
+
+
+#ifndef __FTCMRU_H__
+#define __FTCMRU_H__
+
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifdef FREETYPE_H
+#error "freetype.h of FreeType 1 has been loaded!"
+#error "Please fix the directory search order for header files"
+#error "so that freetype.h of FreeType 2 is found first."
+#endif
+
+#define  xxFT_DEBUG_ERROR
+#define  FTC_INLINE
+
+FT_BEGIN_HEADER
+
+  typedef struct FTC_MruNodeRec_*  FTC_MruNode;
+
+  typedef struct  FTC_MruNodeRec_
+  {
+    FTC_MruNode  next;
+    FTC_MruNode  prev;
+
+  } FTC_MruNodeRec;
+
+
+  FT_EXPORT( void )
+  FTC_MruNode_Prepend( FTC_MruNode  *plist,
+                       FTC_MruNode   node );
+
+  FT_EXPORT( void )
+  FTC_MruNode_Up( FTC_MruNode  *plist,
+                  FTC_MruNode   node );
+
+  FT_EXPORT( void )
+  FTC_MruNode_Remove( FTC_MruNode  *plist,
+                      FTC_MruNode   node );
+
+
+  typedef struct FTC_MruListRec_*              FTC_MruList;
+
+  typedef struct FTC_MruListClassRec_ const *  FTC_MruListClass;
+
+
+  typedef FT_Int
+  (*FTC_MruNode_CompareFunc)( FTC_MruNode  node,
+                              FT_Pointer   key );
+
+  typedef FT_Error
+  (*FTC_MruNode_InitFunc)( FTC_MruNode  node,
+                           FT_Pointer   key,
+                           FT_Pointer   data );
+
+  typedef FT_Error
+  (*FTC_MruNode_ResetFunc)( FTC_MruNode  node,
+                            FT_Pointer   key,
+                            FT_Pointer   data );
+
+  typedef void
+  (*FTC_MruNode_DoneFunc)( FTC_MruNode  node,
+                           FT_Pointer   data );
+
+
+  typedef struct  FTC_MruListClassRec_
+  {
+    FT_UInt                  node_size;
+    FTC_MruNode_CompareFunc  node_compare;
+    FTC_MruNode_InitFunc     node_init;
+    FTC_MruNode_ResetFunc    node_reset;
+    FTC_MruNode_DoneFunc     node_done;
+
+  } FTC_MruListClassRec;
+
+  typedef struct  FTC_MruListRec_
+  {
+    FT_UInt              num_nodes;
+    FT_UInt              max_nodes;
+    FTC_MruNode          nodes;
+    FT_Pointer           data;
+    FTC_MruListClassRec  clazz;
+    FT_Memory            memory;
+
+  } FTC_MruListRec;
+
+
+  FT_EXPORT( void )
+  FTC_MruList_Init( FTC_MruList       list,
+                    FTC_MruListClass  clazz,
+                    FT_UInt           max_nodes,
+                    FT_Pointer        data,
+                    FT_Memory         memory );
+
+  FT_EXPORT( void )
+  FTC_MruList_Reset( FTC_MruList  list );
+
+
+  FT_EXPORT( void )
+  FTC_MruList_Done( FTC_MruList  list );
+
+  FT_EXPORT( FTC_MruNode )
+  FTC_MruList_Find( FTC_MruList  list,
+                    FT_Pointer   key );
+
+  FT_EXPORT( FT_Error )
+  FTC_MruList_New( FTC_MruList   list,
+                   FT_Pointer    key,
+                   FTC_MruNode  *anode );
+
+  FT_EXPORT( FT_Error )
+  FTC_MruList_Lookup( FTC_MruList   list,
+                      FT_Pointer    key,
+                      FTC_MruNode  *pnode );
+                      
+
+  FT_EXPORT( void )
+  FTC_MruList_Remove( FTC_MruList  list,
+                      FTC_MruNode  node );
+
+  FT_EXPORT( void )
+  FTC_MruList_RemoveSelection( FTC_MruList              list,
+                               FTC_MruNode_CompareFunc  selection,
+                               FT_Pointer               key );
+
+
+#ifdef FTC_INLINE
+
+#define FTC_MRULIST_LOOKUP_CMP( list, key, compare, node, error )           \
+  FT_BEGIN_STMNT                                                            \
+    FTC_MruNode*             _pfirst  = &(list)->nodes;                     \
+    FTC_MruNode_CompareFunc  _compare = (FTC_MruNode_CompareFunc)(compare); \
+    FTC_MruNode              _first, _node;                              \
+                                                                         \
+                                                                         \
+    error  = 0;                                                          \
+    _first = *(_pfirst);                                                 \
+    _node  = NULL;                                                       \
+                                                                         \
+    if ( _first )                                                        \
+    {                                                                    \
+      _node = _first;                                                    \
+      do                                                                 \
+      {                                                                  \
+        if ( _compare( _node, (key) ) )                                  \
+        {                                                                \
+          if ( _node != _first )                                         \
+            FTC_MruNode_Up( _pfirst, _node );                            \
+                                                                         \
+          *(FTC_MruNode*)&(node) = _node;                                \
+          goto _MruOk;                                                   \
+        }                                                                \
+        _node = _node->next;                                             \
+                                                                         \
+      } while ( _node != _first) ;                                       \
+    }                                                                    \
+                                                                         \
+    error = FTC_MruList_New( (list), (key), (FTC_MruNode*)&(node) );     \
+  _MruOk:                                                                \
+    ;                                                                    \
+  FT_END_STMNT
+
+#define FTC_MRULIST_LOOKUP( list, key, node, error ) \
+  FTC_MRULIST_LOOKUP_CMP( list, key, (list)->clazz.node_compare, node, error )
+
+#else  /* !FTC_INLINE */
+
+#define FTC_MRULIST_LOOKUP( list, key, node, error ) \
+  error = FTC_MruList_Lookup( (list), (key), (FTC_MruNode*)&(node) ) 
+
+#endif /* !FTC_INLINE */
+
+
+#define FTC_MRULIST_LOOP( list, node )        \
+  FT_BEGIN_STMNT                              \
+    FTC_MruNode  _first = (list)->nodes;      \
+                                              \
+                                              \
+    if ( _first )                             \
+    {                                         \
+      FTC_MruNode  _node = _first;            \
+                                              \
+                                              \
+      do                                      \
+      {                                       \
+        *(FTC_MruNode*)&(node) = _node;
+
+
+#define FTC_MRULIST_LOOP_END()               \
+        _node = _node->next;                 \
+                                             \
+      } while ( _node != _first );           \
+    }                                        \
+  FT_END_STMNT
+
+ /* */
+
+FT_END_HEADER
+
+
+#endif /* __FTCMRU_H__ */
+
+
+/* END */
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -1,938 +1,934 @@
-#include "afhints.h"
-
-#ifdef AF_DEBUG
-
-#include <stdio.h>
-
-  void
-  af_glyph_hints_dump_edges( AF_GlyphHints  hints )
-  {
-    AF_Edge     edges;
-    AF_Edge     edge_limit;
-    AF_Segment  segments;
-    FT_Int      dimension;
-
-
-    edges      = hints->horz_edges;
-    edge_limit = edges + hints->num_hedges;
-    segments   = hints->horz_segments;
-
-    for ( dimension = 1; dimension >= 0; dimension-- )
-    {
-      AF_Edge   edge;
-
-
-      printf ( "Table of %s edges:\n",
-               !dimension ? "vertical" : "horizontal" );
-      printf ( "  [ index |  pos |  dir  | link |"
-               " serif | blue | opos  |  pos  ]\n" );
-
-      for ( edge = edges; edge < edge_limit; edge++ )
-      {
-        printf ( "  [ %5d | %4d | %5s | %4d | %5d |  %c  | %5.2f | %5.2f ]\n",
-                 edge - edges,
-                 (int)edge->fpos,
-                 edge->dir == AF_DIR_UP
-                   ? "up"
-                   : ( edge->dir == AF_DIR_DOWN
-                         ? "down"
-                         : ( edge->dir == AF_DIR_LEFT
-                               ? "left"
-                               : ( edge->dir == AF_DIR_RIGHT
-                                     ? "right"
-                                     : "none" ) ) ),
-                 edge->link ? ( edge->link - edges ) : -1,
-                 edge->serif ? ( edge->serif - edges ) : -1,
-                 edge->blue_edge ? 'y' : 'n',
-                 edge->opos / 64.0,
-                 edge->pos / 64.0 );
-      }
-
-      edges      = hints->vert_edges;
-      edge_limit = edges + hints->num_vedges;
-      segments   = hints->vert_segments;
-    }
-  }
-
-
-  /* A function used to dump the array of linked segments */
-  void
-  af_glyph_hints_dump_segments( AF_GlyphHints  hints )
-  {
-    AF_Segment  segments;
-    AF_Segment  segment_limit;
-    AF_Point    points;
-    FT_Int      dimension;
-
-
-    points        = hints->points;
-    segments      = hints->horz_segments;
-    segment_limit = segments + hints->num_hsegments;
-
-    for ( dimension = 1; dimension >= 0; dimension-- )
-    {
-      AF_Segment  seg;
-
-
-      printf ( "Table of %s segments:\n",
-               !dimension ? "vertical" : "horizontal" );
-      printf ( "  [ index |  pos |  dir  | link | serif |"
-               " numl | first | start ]\n" );
-
-      for ( seg = segments; seg < segment_limit; seg++ )
-      {
-        printf ( "  [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
-                 seg - segments,
-                 (int)seg->pos,
-                 seg->dir == AF_DIR_UP
-                   ? "up"
-                   : ( seg->dir == AF_DIR_DOWN
-                         ? "down"
-                         : ( seg->dir == AF_DIR_LEFT
-                               ? "left"
-                               : ( seg->dir == AF_DIR_RIGHT
-                                     ? "right"
-                                     : "none" ) ) ),
-                 seg->link ? ( seg->link - segments ) : -1,
-                 seg->serif ? ( seg->serif - segments ) : -1,
-                 (int)seg->num_linked,
-                 seg->first - points,
-                 seg->last - points );
-      }
-
-      segments      = hints->vert_segments;
-      segment_limit = segments + hints->num_vsegments;
-    }
-  }
-
-#endif /* AF_DEBUG */
-
-
-  /* compute the direction value of a given vector */
-  FT_LOCAL_DEF( AF_Direction )
-  af_direction_compute( FT_Pos  dx,
-                        FT_Pos  dy )
-  {
-    AF_Direction  dir;
-    FT_Pos        ax = ABS( dx );
-    FT_Pos        ay = ABS( dy );
-
-
-    dir = AF_DIR_NONE;
-
-    /* atan(1/12) == 4.7 degrees */
-
-    /* test for vertical direction */
-    if ( ax * 12 < ay )
-    {
-      dir = dy > 0 ? AF_DIR_UP : AF_DIR_DOWN;
-    }
-    /* test for horizontal direction */
-    else if ( ay * 12 < ax )
-    {
-      dir = dx > 0 ? AF_DIR_RIGHT : AF_DIR_LEFT;
-    }
-
-    return dir;
-  }
-
-
-  /* compute all inflex points in a given glyph */
-  static void
-  af_glyph_hints_compute_inflections( AF_GlyphHints  hints )
-  {
-    AF_Point*  contour       = hints->contours;
-    AF_Point*  contour_limit = contour + hints->num_contours;
-
-
-    /* do each contour separately */
-    for ( ; contour < contour_limit; contour++ )
-    {
-      AF_Point   point = contour[0];
-      AF_Point   first = point;
-      AF_Point   start = point;
-      AF_Point   end   = point;
-      AF_Point   before;
-      AF_Point   after;
-      AF_Angle   angle_in, angle_seg, angle_out;
-      AF_Angle   diff_in, diff_out;
-      FT_Int     finished = 0;
-
-
-      /* compute first segment in contour */
-      first = point;
-
-      start = end = first;
-      do
-      {
-        end = end->next;
-        if ( end == first )
-          goto Skip;
-
-      } while ( end->fx == first->fx && end->fy == first->fy );
-
-      angle_seg = af_angle_atan( end->fx - start->fx,
-                                 end->fy - start->fy );
-
-      /* extend the segment start whenever possible */
-      before = start;
-      do
-      {
-        do
-        {
-          start  = before;
-          before = before->prev;
-          if ( before == first )
-            goto Skip;
-
-        } while ( before->fx == start->fx && before->fy == start->fy );
-
-        angle_in = af_angle_atan( start->fx - before->fx,
-                                  start->fy - before->fy );
-
-      } while ( angle_in == angle_seg );
-
-      first   = start;
-      diff_in = af_angle_diff( angle_in, angle_seg );
-
-      /* now, process all segments in the contour */
-      do
-      {
-        /* first, extend current segment's end whenever possible */
-        after = end;
-        do
-        {
-          do
-          {
-            end   = after;
-            after = after->next;
-            if ( after == first )
-              finished = 1;
-
-          } while ( end->fx == after->fx && end->fy == after->fy );
-
-          angle_out = af_angle_atan( after->fx - end->fx,
-                                     after->fy - end->fy );
-
-        } while ( angle_out == angle_seg );
-
-        diff_out = af_angle_diff( angle_seg, angle_out );
-
-        if ( ( diff_in ^ diff_out ) < 0 )
-        {
-          /* diff_in and diff_out have different signs, we have */
-          /* inflection points here...                          */
-          do
-          {
-            start->flags |= AF_FLAG_INFLECTION;
-            start = start->next;
-
-          } while ( start != end );
-
-          start->flags |= AF_FLAG_INFLECTION;
-        }
-
-        start     = end;
-        end       = after;
-        angle_seg = angle_out;
-        diff_in   = diff_out;
-
-      } while ( !finished );
-
-    Skip:
-      ;
-    }
-  }
-
-
-
-  FT_LOCAL_DEF( void )
-  af_glyph_hints_init( AF_GlyphHints  hints,
-                       FT_Memory      memory )
-  {
-    FT_ZERO( hints );
-    hints->memory = memory;
-  }
-
-
-
-  FT_LOCAL_DEF( void )
-  af_glyph_hints_done( AF_GlyphHints  hints )
-  {
-    if ( hints && hints->memory )
-    {
-      FT_Memory     memory = hints->memory;
-      AF_Dimension  dim;
-
-     /* note that we don't need to free the segment and edge
-      * buffers, since they're really within the hints->points array
-      */
-      for ( dim = 0; dim < 2; dim++ )
-      {
-        AF_AxisHints  axis = &hints->axis[ dim ];
-
-        axis->num_segments = 0;
-        axis->num_edges    = 0;
-        axis->segments     = NULL;
-        axis->edges        = NULL;
-      }
-
-      FT_FREE( hints->contours );
-      hints->max_contours = 0;
-      hints->num_contours = 0;
-
-      FT_FREE( hints->points );
-      hints->num_points = 0;
-      hints->max_points = 0;
-
-      hints->memory = NULL;
-    }
-  }
-
-
-
-  FT_LOCAL_DEF( FT_Error )
-  af_glyph_hints_reset( AF_GlyphHints  hints,
-                        AF_Scaler      scaler,
-                        FT_Outline*    outline )
-  {
-    FT_Error     error        = FT_Err_Ok;
-    AF_Point     points;
-    FT_UInt      old_max, new_max;
-    FT_Fixed     x_scale = scaler->x_scale;
-    FT_Fixed     y_scale = scaler->y_scale;
-    FT_Pos       x_delta = scaler->x_delta;
-    FT_Pos       y_delta = scaler->y_delta;
-    FT_Memory    memory  = hints->memory;
-
-    hints->scaler_flags = scaler->flags;
-    hints->other_flags  = 0;
-
-    hints->num_points    = 0;
-    hints->num_contours  = 0;
-
-    hints->axis[0].num_segments = 0;
-    hints->axis[0].num_edges    = 0;
-    hints->axis[1].num_segments = 0;
-    hints->axis[1].num_edges    = 0;
-
-   /* first of all, reallocate the contours array when necessary
-    */
-    new_max = (FT_UInt) outline->n_contours;
-    old_max = hints->max_contours;
-    if ( new_max > old_max )
-    {
-      new_max = (new_max + 3) & ~3;
-
-      if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
-        goto Exit;
-
-      hints->max_contours = new_max;
-    }
-
-   /* then, reallocate the points, segments & edges arrays if needed --
-    * note that we reserved two additional point positions, used to
-    * hint metrics appropriately
-    */
-    new_max = (FT_UInt)( outline->n_points + 2 );
-    old_max = hints->max_points;
-    if ( new_max > old_max )
-    {
-      FT_Byte*    items;
-      FT_ULong    off1, off2, off3;
-
-     /* we store in a single buffer the following arrays:
-      *
-      *  - an array of   N  AF_PointRec   items
-      *  - an array of 2*N  AF_SegmentRec items
-      *  - an array of 2*N  AF_EdgeRec    items
-      *
-      */
-
-      new_max = ( new_max + 2 + 7 ) & ~7;
-
-#undef  OFF_INCREMENT
-#define OFF_INCREMENT( _off, _type, _count )   \
-     ( FT_PAD_CEIL( _off, sizeof(_type) ) + (_count)*sizeof(_type))
-
-      off1 = OFF_INCREMENT( 0, AF_PointRec, new_max );
-      off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max );
-      off3 = OFF_INCREMENT( off2, AF_EdgeRec, new_max*2 );
-
-      FT_FREE( hints->points );
-
-      if ( FT_ALLOC( items, off3 ) )
-      {
-        hints->max_points       = 0;
-        hints->axis[0].segments = NULL;
-        hints->axis[0].edges    = NULL;
-        hints->axis[1].segments = NULL;
-        hints->axis[1].edges    = NULL;
-        goto Exit;
-      }
-
-     /* readjust some pointers
-      */
-      hints->max_points       = new_max;
-      hints->points           = (AF_Point) items;
-
-      hints->axis[0].segments = (AF_Segment)( items + off1 );
-      hints->axis[1].segments = hints->axis[0].segments + new_max;
-
-      hints->axis[0].edges    = (AF_Edge)   ( items + off2 );
-      hints->axis[1].edges    = hints->axis[0].edges + new_max;
-    }
-
-    hints->num_points   = outline->n_points;
-    hints->num_contours = outline->n_contours;
-
-
-    /* We can't rely on the value of `FT_Outline.flags' to know the fill  */
-    /* direction used for a glyph, given that some fonts are broken (e.g. */
-    /* the Arphic ones).  We thus recompute it each time we need to.      */
-    /*                                                                    */
-    hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_UP;
-    hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_LEFT;
-
-    if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )
-    {
-      hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_DOWN;
-      hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_RIGHT;
-    }
-
-    hints->x_scale = x_scale;
-    hints->y_scale = y_scale;
-    hints->x_delta = x_delta;
-    hints->y_delta = y_delta;
-
-    points = hints->points;
-    if ( hints->num_points == 0 )
-      goto Exit;
-
-    {
-      AF_Point  point;
-      AF_Point  point_limit = points + hints->num_points;
-
-
-      /* compute coordinates & bezier flags */
-      {
-        FT_Vector*  vec = outline->points;
-        char*       tag = outline->tags;
-
-
-        for ( point = points; point < point_limit; point++, vec++, tag++ )
-        {
-          point->fx = vec->x;
-          point->fy = vec->y;
-          point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
-          point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
-
-          switch ( FT_CURVE_TAG( *tag ) )
-          {
-          case FT_CURVE_TAG_CONIC:
-            point->flags = AF_FLAG_CONIC;
-            break;
-          case FT_CURVE_TAG_CUBIC:
-            point->flags = AF_FLAG_CUBIC;
-            break;
-          default:
-            point->flags = 0;
-            ;
-          }
-        }
-      }
-
-      /* compute `next' and `prev' */
-      {
-        FT_Int    contour_index;
-        AF_Point  prev;
-        AF_Point  first;
-        AF_Point  end;
-
-
-        contour_index = 0;
-
-        first = points;
-        end   = points + outline->contours[0];
-        prev  = end;
-
-        for ( point = points; point < point_limit; point++ )
-        {
-          point->prev = prev;
-          if ( point < end )
-          {
-            point->next = point + 1;
-            prev        = point;
-          }
-          else
-          {
-            point->next = first;
-            contour_index++;
-            if ( point + 1 < point_limit )
-            {
-              end   = points + outline->contours[contour_index];
-              first = point + 1;
-              prev  = end;
-            }
-          }
-        }
-      }
-
-      /* set-up the contours array */
-      {
-        AF_Point*  contour       = hints->contours;
-        AF_Point*  contour_limit = contour + hints->num_contours;
-        short*     end           = outline->contours;
-        short      idx           = 0;
-
-
-        for ( ; contour < contour_limit; contour++, end++ )
-        {
-          contour[0] = points + idx;
-          idx        = (short)( end[0] + 1 );
-        }
-      }
-
-      /* compute directions of in & out vectors */
-      {
-        for ( point = points; point < point_limit; point++ )
-        {
-          AF_Point   prev;
-          AF_Point   next;
-          FT_Pos     in_x, in_y, out_x, out_y;
-
-
-          prev   = point->prev;
-          in_x   = point->fx - prev->fx;
-          in_y   = point->fy - prev->fy;
-
-          point->in_dir = af_direction_compute( in_x, in_y );
-
-          next   = point->next;
-          out_x  = next->fx - point->fx;
-          out_y  = next->fy - point->fy;
-
-          point->out_dir = af_direction_compute( out_x, out_y );
-
-          if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )
-          {
-          Is_Weak_Point:
-            point->flags |= AF_FLAG_WEAK_INTERPOLATION;
-          }
-          else if ( point->out_dir == point->in_dir )
-          {
-            AF_Angle  angle_in, angle_out, delta;
-
-
-            if ( point->out_dir != AF_DIR_NONE )
-              goto Is_Weak_Point;
-
-            angle_in  = af_angle_atan( in_x, in_y );
-            angle_out = af_angle_atan( out_x, out_y );
-            delta     = af_angle_diff( angle_in, angle_out );
-
-            if ( delta < 2 && delta > -2 )
-              goto Is_Weak_Point;
-          }
-          else if ( point->in_dir == -point->out_dir )
-            goto Is_Weak_Point;
-        }
-      }
-    }
-
-   /* compute inflection points
-    */
-    af_glyph_hints_compute_inflections( hints );
-
-  Exit:
-    return error;
-  }
-
-
-
-
- /*
-  *
-  *  E D G E   P O I N T   G R I D - F I T T I N G
-  *
-  */
-
-
-  FT_LOCAL_DEF( void )
-  af_glyph_hints_align_edge_points( AF_GlyphHints  hints,
-                                    AF_Dimension   dim )
-  {
-    AF_AxisHints  axis       = & hints->axis[ dim ];
-    AF_Edge       edges      = axis->edges;
-    AF_Edge       edge_limit = edges + axis->num_edges;
-    AF_Edge       edge;
-
-    for ( edge = edges; edge < edge_limit; edge++ )
-    {
-      /* move the points of each segment     */
-      /* in each edge to the edge's position */
-      AF_Segment  seg = edge->first;
-
-
-      do
-      {
-        AF_Point  point = seg->first;
-
-
-        for (;;)
-        {
-          if ( dim == AF_DIMENSION_HORZ )
-          {
-            point->x      = edge->pos;
-            point->flags |= AF_FLAG_TOUCH_X;
-          }
-          else
-          {
-            point->y      = edge->pos;
-            point->flags |= AF_FLAG_TOUCH_Y;
-          }
-
-          if ( point == seg->last )
-            break;
-
-          point = point->next;
-        }
-
-        seg = seg->edge_next;
-
-      } while ( seg != edge->first );
-    }
-  }
-
-
- /*
-  *
-  *  S T R O N G   P O I N T   I N T E R P O L A T I O N
-  *
-  */
-
-
-  /* hint the strong points -- this is equivalent to the TrueType `IP' */
-  /* hinting instruction                                               */
-  FT_LOCAL_DEF( void )
-  af_glyph_hints_align_strong_points( AF_GlyphHints  hints,
-                                      AF_Dimension   dim )
-  {
-    AF_Point      points      = hints->points;
-    AF_Point      point_limit = points + hints->num_points;
-    AF_AxisHints  axis        = &hints->axis[dim];
-    AF_Edge       edges       = axis->edges;
-    AF_Edge       edge_limit  = edges + axis->num_edges;
-    AF_Flags      touch_flag;
-
-
-    if ( dim == AF_DIMENSION_HORZ )
-      touch_flag = AF_FLAG_TOUCH_X;
-    else
-      touch_flag  = AF_FLAG_TOUCH_Y;
-
-    if ( edges < edge_limit )
-    {
-      AF_Point  point;
-      AF_Edge   edge;
-
-      for ( point = points; point < point_limit; point++ )
-      {
-        FT_Pos  u, ou, fu;  /* point position */
-        FT_Pos  delta;
-
-
-        if ( point->flags & touch_flag )
-          continue;
-
-        /* if this point is candidate to weak interpolation, we will  */
-        /* interpolate it after all strong points have been processed */
-        if (  ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) &&
-             !( point->flags & AF_FLAG_INFLECTION )         )
-          continue;
-
-        if ( dim == AF_DIMENSION_VERT )
-        {
-          u  = point->fy;
-          ou = point->oy;
-        }
-        else
-        {
-          u  = point->fx;
-          ou = point->ox;
-        }
-
-        fu = u;
-
-        /* is the point before the first edge? */
-        edge  = edges;
-        delta = edge->fpos - u;
-        if ( delta >= 0 )
-        {
-          u = edge->pos - ( edge->opos - ou );
-          goto Store_Point;
-        }
-
-        /* is the point after the last edge? */
-        edge  = edge_limit - 1;
-        delta = u - edge->fpos;
-        if ( delta >= 0 )
-        {
-          u = edge->pos + ( ou - edge->opos );
-          goto Store_Point;
-        }
-
-        {
-          FT_UInt  min, max, mid;
-          FT_Pos   fpos;
-
-
-          /* find enclosing edges */
-          min = 0;
-          max = edge_limit - edges;
-
-          while ( min < max )
-          {
-            mid  = ( max + min ) >> 1;
-            edge = edges + mid;
-            fpos = edge->fpos;
-
-            if ( u < fpos )
-              max = mid;
-            else if ( u > fpos )
-              min = mid + 1;
-            else
-            {
-              /* we are on the edge */
-              u = edge->pos;
-              goto Store_Point;
-            }
-          }
-
-          {
-            AF_Edge  before = edges + min - 1;
-            AF_Edge  after  = edges + min + 0;
-
-
-            /* assert( before && after && before != after ) */
-            if ( before->scale == 0 )
-              before->scale = FT_DivFix( after->pos - before->pos,
-                                         after->fpos - before->fpos );
-
-            u = before->pos + FT_MulFix( fu - before->fpos,
-                                         before->scale );
-          }
-        }
-
-
-      Store_Point:
-
-        /* save the point position */
-        if ( dim == AF_DIMENSION_HORZ )
-          point->x = u;
-        else
-          point->y = u;
-
-        point->flags |= touch_flag;
-      }
-    }
-  }
-
-
- /*
-  *
-  *  W E A K   P O I N T   I N T E R P O L A T I O N
-  *
-  */
-
-  static void
-  af_iup_shift( AF_Point  p1,
-                AF_Point  p2,
-                AF_Point  ref )
-  {
-    AF_Point  p;
-    FT_Pos    delta = ref->u - ref->v;
-
-
-    for ( p = p1; p < ref; p++ )
-      p->u = p->v + delta;
-
-    for ( p = ref + 1; p <= p2; p++ )
-      p->u = p->v + delta;
-  }
-
-
-  static void
-  af_iup_interp( AF_Point  p1,
-                 AF_Point  p2,
-                 AF_Point  ref1,
-                 AF_Point  ref2 )
-  {
-    AF_Point  p;
-    FT_Pos    u;
-    FT_Pos    v1 = ref1->v;
-    FT_Pos    v2 = ref2->v;
-    FT_Pos    d1 = ref1->u - v1;
-    FT_Pos    d2 = ref2->u - v2;
-
-
-    if ( p1 > p2 )
-      return;
-
-    if ( v1 == v2 )
-    {
-      for ( p = p1; p <= p2; p++ )
-      {
-        u = p->v;
-
-        if ( u <= v1 )
-          u += d1;
-        else
-          u += d2;
-
-        p->u = u;
-      }
-      return;
-    }
-
-    if ( v1 < v2 )
-    {
-      for ( p = p1; p <= p2; p++ )
-      {
-        u = p->v;
-
-        if ( u <= v1 )
-          u += d1;
-        else if ( u >= v2 )
-          u += d2;
-        else
-          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
-
-        p->u = u;
-      }
-    }
-    else
-    {
-      for ( p = p1; p <= p2; p++ )
-      {
-        u = p->v;
-
-        if ( u <= v2 )
-          u += d2;
-        else if ( u >= v1 )
-          u += d1;
-        else
-          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
-
-        p->u = u;
-      }
-    }
-  }
-
-
-  FT_LOCAL_DEF( void )
-  af_glyph_hints_align_weak_points( AF_GlyphHints  hints,
-                                    AF_Dimension   dim )
-  {
-    AF_Point    points        = hints->points;
-    AF_Point    point_limit   = points + hints->num_points;
-    AF_Point*   contour       = hints->contours;
-    AF_Point*   contour_limit = contour + hints->num_contours;
-    AF_Flags    touch_flag;
-    AF_Point    point;
-    AF_Point    end_point;
-    AF_Point    first_point;
-
-
-    /* PASS 1: Move segment points to edge positions */
-
-    if ( dim == AF_DIMENSION_HORZ )
-    {
-      touch_flag = AF_FLAG_TOUCH_X;
-
-      for ( point = points; point < point_limit; point++ )
-      {
-        point->u = point->x;
-        point->v = point->ox;
-      }
-    }
-    else
-    {
-      touch_flag = AF_FLAG_TOUCH_Y;
-
-      for ( point = points; point < point_limit; point++ )
-      {
-        point->u = point->y;
-        point->v = point->oy;
-      }
-    }
-
-    point   = points;
-
-    for ( ; contour < contour_limit; contour++ )
-    {
-      point       = *contour;
-      end_point   = point->prev;
-      first_point = point;
-
-      while ( point <= end_point && !( point->flags & touch_flag ) )
-        point++;
-
-      if ( point <= end_point )
-      {
-        AF_Point  first_touched = point;
-        AF_Point  cur_touched   = point;
-
-
-        point++;
-        while ( point <= end_point )
-        {
-          if ( point->flags & touch_flag )
-          {
-            /* we found two successive touched points; we interpolate */
-            /* all contour points between them                        */
-            af_iup_interp( cur_touched + 1, point - 1,
-                           cur_touched, point );
-            cur_touched = point;
-          }
-          point++;
-        }
-
-        if ( cur_touched == first_touched )
-        {
-          /* this is a special case: only one point was touched in the */
-          /* contour; we thus simply shift the whole contour           */
-          af_iup_shift( first_point, end_point, cur_touched );
-        }
-        else
-        {
-          /* now interpolate after the last touched point to the end */
-          /* of the contour                                          */
-          af_iup_interp( cur_touched + 1, end_point,
-                         cur_touched, first_touched );
-
-          /* if the first contour point isn't touched, interpolate */
-          /* from the contour start to the first touched point     */
-          if ( first_touched > points )
-            af_iup_interp( first_point, first_touched - 1,
-                           cur_touched, first_touched );
-        }
-      }
-    }
-
-    /* now save the interpolated values back to x/y */
-    if ( dim == AF_DIMENSION_HORZ )
-    {
-      for ( point = points; point < point_limit; point++ )
-        point->x = point->u;
-    }
-    else
-    {
-      for ( point = points; point < point_limit; point++ )
-        point->y = point->u;
-    }
-  }
-
-
-
-
+#include "afhints.h"
+
+#ifdef AF_DEBUG
+
+#include <stdio.h>
+
+  void
+  af_glyph_hints_dump_edges( AF_GlyphHints  hints )
+  {
+    AF_Edge     edges;
+    AF_Edge     edge_limit;
+    AF_Segment  segments;
+    FT_Int      dimension;
+
+
+    edges      = hints->horz_edges;
+    edge_limit = edges + hints->num_hedges;
+    segments   = hints->horz_segments;
+
+    for ( dimension = 1; dimension >= 0; dimension-- )
+    {
+      AF_Edge   edge;
+
+
+      printf ( "Table of %s edges:\n",
+               !dimension ? "vertical" : "horizontal" );
+      printf ( "  [ index |  pos |  dir  | link |"
+               " serif | blue | opos  |  pos  ]\n" );
+
+      for ( edge = edges; edge < edge_limit; edge++ )
+      {
+        printf ( "  [ %5d | %4d | %5s | %4d | %5d |  %c  | %5.2f | %5.2f ]\n",
+                 edge - edges,
+                 (int)edge->fpos,
+                 edge->dir == AF_DIR_UP
+                   ? "up"
+                   : ( edge->dir == AF_DIR_DOWN
+                         ? "down"
+                         : ( edge->dir == AF_DIR_LEFT
+                               ? "left"
+                               : ( edge->dir == AF_DIR_RIGHT
+                                     ? "right"
+                                     : "none" ) ) ),
+                 edge->link ? ( edge->link - edges ) : -1,
+                 edge->serif ? ( edge->serif - edges ) : -1,
+                 edge->blue_edge ? 'y' : 'n',
+                 edge->opos / 64.0,
+                 edge->pos / 64.0 );
+      }
+
+      edges      = hints->vert_edges;
+      edge_limit = edges + hints->num_vedges;
+      segments   = hints->vert_segments;
+    }
+  }
+
+
+  /* A function used to dump the array of linked segments */
+  void
+  af_glyph_hints_dump_segments( AF_GlyphHints  hints )
+  {
+    AF_Segment  segments;
+    AF_Segment  segment_limit;
+    AF_Point    points;
+    FT_Int      dimension;
+
+
+    points        = hints->points;
+    segments      = hints->horz_segments;
+    segment_limit = segments + hints->num_hsegments;
+
+    for ( dimension = 1; dimension >= 0; dimension-- )
+    {
+      AF_Segment  seg;
+
+
+      printf ( "Table of %s segments:\n",
+               !dimension ? "vertical" : "horizontal" );
+      printf ( "  [ index |  pos |  dir  | link | serif |"
+               " numl | first | start ]\n" );
+
+      for ( seg = segments; seg < segment_limit; seg++ )
+      {
+        printf ( "  [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",
+                 seg - segments,
+                 (int)seg->pos,
+                 seg->dir == AF_DIR_UP
+                   ? "up"
+                   : ( seg->dir == AF_DIR_DOWN
+                         ? "down"
+                         : ( seg->dir == AF_DIR_LEFT
+                               ? "left"
+                               : ( seg->dir == AF_DIR_RIGHT
+                                     ? "right"
+                                     : "none" ) ) ),
+                 seg->link ? ( seg->link - segments ) : -1,
+                 seg->serif ? ( seg->serif - segments ) : -1,
+                 (int)seg->num_linked,
+                 seg->first - points,
+                 seg->last - points );
+      }
+
+      segments      = hints->vert_segments;
+      segment_limit = segments + hints->num_vsegments;
+    }
+  }
+
+#endif /* AF_DEBUG */
+
+
+  /* compute the direction value of a given vector */
+  FT_LOCAL_DEF( AF_Direction )
+  af_direction_compute( FT_Pos  dx,
+                        FT_Pos  dy )
+  {
+    AF_Direction  dir;
+    FT_Pos        ax = ABS( dx );
+    FT_Pos        ay = ABS( dy );
+
+
+    dir = AF_DIR_NONE;
+
+    /* atan(1/12) == 4.7 degrees */
+
+    /* test for vertical direction */
+    if ( ax * 12 < ay )
+    {
+      dir = dy > 0 ? AF_DIR_UP : AF_DIR_DOWN;
+    }
+    /* test for horizontal direction */
+    else if ( ay * 12 < ax )
+    {
+      dir = dx > 0 ? AF_DIR_RIGHT : AF_DIR_LEFT;
+    }
+
+    return dir;
+  }
+
+
+  /* compute all inflex points in a given glyph */
+  static void
+  af_glyph_hints_compute_inflections( AF_GlyphHints  hints )
+  {
+    AF_Point*  contour       = hints->contours;
+    AF_Point*  contour_limit = contour + hints->num_contours;
+
+
+    /* do each contour separately */
+    for ( ; contour < contour_limit; contour++ )
+    {
+      AF_Point   point = contour[0];
+      AF_Point   first = point;
+      AF_Point   start = point;
+      AF_Point   end   = point;
+      AF_Point   before;
+      AF_Point   after;
+      AF_Angle   angle_in, angle_seg, angle_out;
+      AF_Angle   diff_in, diff_out;
+      FT_Int     finished = 0;
+
+
+      /* compute first segment in contour */
+      first = point;
+
+      start = end = first;
+      do
+      {
+        end = end->next;
+        if ( end == first )
+          goto Skip;
+
+      } while ( end->fx == first->fx && end->fy == first->fy );
+
+      angle_seg = af_angle_atan( end->fx - start->fx,
+                                 end->fy - start->fy );
+
+      /* extend the segment start whenever possible */
+      before = start;
+      do
+      {
+        do
+        {
+          start  = before;
+          before = before->prev;
+          if ( before == first )
+            goto Skip;
+
+        } while ( before->fx == start->fx && before->fy == start->fy );
+
+        angle_in = af_angle_atan( start->fx - before->fx,
+                                  start->fy - before->fy );
+
+      } while ( angle_in == angle_seg );
+
+      first   = start;
+      diff_in = af_angle_diff( angle_in, angle_seg );
+
+      /* now, process all segments in the contour */
+      do
+      {
+        /* first, extend current segment's end whenever possible */
+        after = end;
+        do
+        {
+          do
+          {
+            end   = after;
+            after = after->next;
+            if ( after == first )
+              finished = 1;
+
+          } while ( end->fx == after->fx && end->fy == after->fy );
+
+          angle_out = af_angle_atan( after->fx - end->fx,
+                                     after->fy - end->fy );
+
+        } while ( angle_out == angle_seg );
+
+        diff_out = af_angle_diff( angle_seg, angle_out );
+
+        if ( ( diff_in ^ diff_out ) < 0 )
+        {
+          /* diff_in and diff_out have different signs, we have */
+          /* inflection points here...                          */
+          do
+          {
+            start->flags |= AF_FLAG_INFLECTION;
+            start = start->next;
+
+          } while ( start != end );
+
+          start->flags |= AF_FLAG_INFLECTION;
+        }
+
+        start     = end;
+        end       = after;
+        angle_seg = angle_out;
+        diff_in   = diff_out;
+
+      } while ( !finished );
+
+    Skip:
+      ;
+    }
+  }
+
+
+
+  FT_LOCAL_DEF( void )
+  af_glyph_hints_init( AF_GlyphHints  hints,
+                       FT_Memory      memory )
+  {
+    FT_ZERO( hints );
+    hints->memory = memory;
+  }
+
+
+
+  FT_LOCAL_DEF( void )
+  af_glyph_hints_done( AF_GlyphHints  hints )
+  {
+    if ( hints && hints->memory )
+    {
+      FT_Memory     memory = hints->memory;
+      AF_Dimension  dim;
+
+     /* note that we don't need to free the segment and edge
+      * buffers, since they're really within the hints->points array
+      */
+      for ( dim = 0; dim < 2; dim++ )
+      {
+        AF_AxisHints  axis = &hints->axis[ dim ];
+
+        axis->num_segments = 0;
+        axis->num_edges    = 0;
+        axis->segments     = NULL;
+        axis->edges        = NULL;
+      }
+
+      FT_FREE( hints->contours );
+      hints->max_contours = 0;
+      hints->num_contours = 0;
+
+      FT_FREE( hints->points );
+      hints->num_points = 0;
+      hints->max_points = 0;
+
+      hints->memory = NULL;
+    }
+  }
+
+
+
+  FT_LOCAL_DEF( FT_Error )
+  af_glyph_hints_reset( AF_GlyphHints  hints,
+                        AF_Scaler      scaler,
+                        FT_Outline*    outline )
+  {
+    FT_Error     error        = FT_Err_Ok;
+    AF_Point     points;
+    FT_UInt      old_max, new_max;
+    FT_Fixed     x_scale = scaler->x_scale;
+    FT_Fixed     y_scale = scaler->y_scale;
+    FT_Pos       x_delta = scaler->x_delta;
+    FT_Pos       y_delta = scaler->y_delta;
+    FT_Memory    memory  = hints->memory;
+
+    hints->scaler_flags = scaler->flags;
+    hints->other_flags  = 0;
+
+    hints->num_points    = 0;
+    hints->num_contours  = 0;
+
+    hints->axis[0].num_segments = 0;
+    hints->axis[0].num_edges    = 0;
+    hints->axis[1].num_segments = 0;
+    hints->axis[1].num_edges    = 0;
+
+   /* first of all, reallocate the contours array when necessary
+    */
+    new_max = (FT_UInt) outline->n_contours;
+    old_max = hints->max_contours;
+    if ( new_max > old_max )
+    {
+      new_max = (new_max + 3) & ~3;
+
+      if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
+        goto Exit;
+
+      hints->max_contours = new_max;
+    }
+
+   /* then, reallocate the points, segments & edges arrays if needed --
+    * note that we reserved two additional point positions, used to
+    * hint metrics appropriately
+    */
+    new_max = (FT_UInt)( outline->n_points + 2 );
+    old_max = hints->max_points;
+    if ( new_max > old_max )
+    {
+      FT_Byte*    items;
+      FT_ULong    off1, off2, off3;
+
+     /* we store in a single buffer the following arrays:
+      *
+      *  - an array of   N  AF_PointRec   items
+      *  - an array of 2*N  AF_SegmentRec items
+      *  - an array of 2*N  AF_EdgeRec    items
+      *
+      */
+
+      new_max = ( new_max + 2 + 7 ) & ~7;
+
+#undef  OFF_INCREMENT
+#define OFF_INCREMENT( _off, _type, _count )   \
+     ( FT_PAD_CEIL( _off, sizeof(_type) ) + (_count)*sizeof(_type))
+
+      off1 = OFF_INCREMENT( 0, AF_PointRec, new_max );
+      off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max );
+      off3 = OFF_INCREMENT( off2, AF_EdgeRec, new_max*2 );
+
+      FT_FREE( hints->points );
+
+      if ( FT_ALLOC( items, off3 ) )
+      {
+        hints->max_points       = 0;
+        hints->axis[0].segments = NULL;
+        hints->axis[0].edges    = NULL;
+        hints->axis[1].segments = NULL;
+        hints->axis[1].edges    = NULL;
+        goto Exit;
+      }
+
+     /* readjust some pointers
+      */
+      hints->max_points       = new_max;
+      hints->points           = (AF_Point) items;
+
+      hints->axis[0].segments = (AF_Segment)( items + off1 );
+      hints->axis[1].segments = hints->axis[0].segments + new_max;
+
+      hints->axis[0].edges    = (AF_Edge)   ( items + off2 );
+      hints->axis[1].edges    = hints->axis[0].edges + new_max;
+    }
+
+    hints->num_points   = outline->n_points;
+    hints->num_contours = outline->n_contours;
+
+
+    /* We can't rely on the value of `FT_Outline.flags' to know the fill  */
+    /* direction used for a glyph, given that some fonts are broken (e.g. */
+    /* the Arphic ones).  We thus recompute it each time we need to.      */
+    /*                                                                    */
+    hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_UP;
+    hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_LEFT;
+
+    if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )
+    {
+      hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_DOWN;
+      hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_RIGHT;
+    }
+
+    hints->x_scale = x_scale;
+    hints->y_scale = y_scale;
+    hints->x_delta = x_delta;
+    hints->y_delta = y_delta;
+
+    points = hints->points;
+    if ( hints->num_points == 0 )
+      goto Exit;
+
+    {
+      AF_Point  point;
+      AF_Point  point_limit = points + hints->num_points;
+
+
+      /* compute coordinates & bezier flags */
+      {
+        FT_Vector*  vec = outline->points;
+        char*       tag = outline->tags;
+
+
+        for ( point = points; point < point_limit; point++, vec++, tag++ )
+        {
+          point->fx = vec->x;
+          point->fy = vec->y;
+          point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
+          point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;
+
+          switch ( FT_CURVE_TAG( *tag ) )
+          {
+          case FT_CURVE_TAG_CONIC:
+            point->flags = AF_FLAG_CONIC;
+            break;
+          case FT_CURVE_TAG_CUBIC:
+            point->flags = AF_FLAG_CUBIC;
+            break;
+          default:
+            point->flags = 0;
+            ;
+          }
+        }
+      }
+
+      /* compute `next' and `prev' */
+      {
+        FT_Int    contour_index;
+        AF_Point  prev;
+        AF_Point  first;
+        AF_Point  end;
+
+
+        contour_index = 0;
+
+        first = points;
+        end   = points + outline->contours[0];
+        prev  = end;
+
+        for ( point = points; point < point_limit; point++ )
+        {
+          point->prev = prev;
+          if ( point < end )
+          {
+            point->next = point + 1;
+            prev        = point;
+          }
+          else
+          {
+            point->next = first;
+            contour_index++;
+            if ( point + 1 < point_limit )
+            {
+              end   = points + outline->contours[contour_index];
+              first = point + 1;
+              prev  = end;
+            }
+          }
+        }
+      }
+
+      /* set-up the contours array */
+      {
+        AF_Point*  contour       = hints->contours;
+        AF_Point*  contour_limit = contour + hints->num_contours;
+        short*     end           = outline->contours;
+        short      idx           = 0;
+
+
+        for ( ; contour < contour_limit; contour++, end++ )
+        {
+          contour[0] = points + idx;
+          idx        = (short)( end[0] + 1 );
+        }
+      }
+
+      /* compute directions of in & out vectors */
+      {
+        for ( point = points; point < point_limit; point++ )
+        {
+          AF_Point   prev;
+          AF_Point   next;
+          FT_Pos     in_x, in_y, out_x, out_y;
+
+
+          prev   = point->prev;
+          in_x   = point->fx - prev->fx;
+          in_y   = point->fy - prev->fy;
+
+          point->in_dir = af_direction_compute( in_x, in_y );
+
+          next   = point->next;
+          out_x  = next->fx - point->fx;
+          out_y  = next->fy - point->fy;
+
+          point->out_dir = af_direction_compute( out_x, out_y );
+
+          if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )
+          {
+          Is_Weak_Point:
+            point->flags |= AF_FLAG_WEAK_INTERPOLATION;
+          }
+          else if ( point->out_dir == point->in_dir )
+          {
+            AF_Angle  angle_in, angle_out, delta;
+
+
+            if ( point->out_dir != AF_DIR_NONE )
+              goto Is_Weak_Point;
+
+            angle_in  = af_angle_atan( in_x, in_y );
+            angle_out = af_angle_atan( out_x, out_y );
+            delta     = af_angle_diff( angle_in, angle_out );
+
+            if ( delta < 2 && delta > -2 )
+              goto Is_Weak_Point;
+          }
+          else if ( point->in_dir == -point->out_dir )
+            goto Is_Weak_Point;
+        }
+      }
+    }
+
+   /* compute inflection points
+    */
+    af_glyph_hints_compute_inflections( hints );
+
+  Exit:
+    return error;
+  }
+
+
+
+
+ /*
+  *
+  *  E D G E   P O I N T   G R I D - F I T T I N G
+  *
+  */
+
+
+  FT_LOCAL_DEF( void )
+  af_glyph_hints_align_edge_points( AF_GlyphHints  hints,
+                                    AF_Dimension   dim )
+  {
+    AF_AxisHints  axis       = & hints->axis[ dim ];
+    AF_Edge       edges      = axis->edges;
+    AF_Edge       edge_limit = edges + axis->num_edges;
+    AF_Edge       edge;
+
+    for ( edge = edges; edge < edge_limit; edge++ )
+    {
+      /* move the points of each segment     */
+      /* in each edge to the edge's position */
+      AF_Segment  seg = edge->first;
+
+
+      do
+      {
+        AF_Point  point = seg->first;
+
+
+        for (;;)
+        {
+          if ( dim == AF_DIMENSION_HORZ )
+          {
+            point->x      = edge->pos;
+            point->flags |= AF_FLAG_TOUCH_X;
+          }
+          else
+          {
+            point->y      = edge->pos;
+            point->flags |= AF_FLAG_TOUCH_Y;
+          }
+
+          if ( point == seg->last )
+            break;
+
+          point = point->next;
+        }
+
+        seg = seg->edge_next;
+
+      } while ( seg != edge->first );
+    }
+  }
+
+
+ /*
+  *
+  *  S T R O N G   P O I N T   I N T E R P O L A T I O N
+  *
+  */
+
+
+  /* hint the strong points -- this is equivalent to the TrueType `IP' */
+  /* hinting instruction                                               */
+  FT_LOCAL_DEF( void )
+  af_glyph_hints_align_strong_points( AF_GlyphHints  hints,
+                                      AF_Dimension   dim )
+  {
+    AF_Point      points      = hints->points;
+    AF_Point      point_limit = points + hints->num_points;
+    AF_AxisHints  axis        = &hints->axis[dim];
+    AF_Edge       edges       = axis->edges;
+    AF_Edge       edge_limit  = edges + axis->num_edges;
+    AF_Flags      touch_flag;
+
+
+    if ( dim == AF_DIMENSION_HORZ )
+      touch_flag = AF_FLAG_TOUCH_X;
+    else
+      touch_flag  = AF_FLAG_TOUCH_Y;
+
+    if ( edges < edge_limit )
+    {
+      AF_Point  point;
+      AF_Edge   edge;
+
+      for ( point = points; point < point_limit; point++ )
+      {
+        FT_Pos  u, ou, fu;  /* point position */
+        FT_Pos  delta;
+
+
+        if ( point->flags & touch_flag )
+          continue;
+
+        /* if this point is candidate to weak interpolation, we will  */
+        /* interpolate it after all strong points have been processed */
+        if (  ( point->flags & AF_FLAG_WEAK_INTERPOLATION ) &&
+             !( point->flags & AF_FLAG_INFLECTION )         )
+          continue;
+
+        if ( dim == AF_DIMENSION_VERT )
+        {
+          u  = point->fy;
+          ou = point->oy;
+        }
+        else
+        {
+          u  = point->fx;
+          ou = point->ox;
+        }
+
+        fu = u;
+
+        /* is the point before the first edge? */
+        edge  = edges;
+        delta = edge->fpos - u;
+        if ( delta >= 0 )
+        {
+          u = edge->pos - ( edge->opos - ou );
+          goto Store_Point;
+        }
+
+        /* is the point after the last edge? */
+        edge  = edge_limit - 1;
+        delta = u - edge->fpos;
+        if ( delta >= 0 )
+        {
+          u = edge->pos + ( ou - edge->opos );
+          goto Store_Point;
+        }
+
+        {
+          FT_UInt  min, max, mid;
+          FT_Pos   fpos;
+
+
+          /* find enclosing edges */
+          min = 0;
+          max = edge_limit - edges;
+
+          while ( min < max )
+          {
+            mid  = ( max + min ) >> 1;
+            edge = edges + mid;
+            fpos = edge->fpos;
+
+            if ( u < fpos )
+              max = mid;
+            else if ( u > fpos )
+              min = mid + 1;
+            else
+            {
+              /* we are on the edge */
+              u = edge->pos;
+              goto Store_Point;
+            }
+          }
+
+          {
+            AF_Edge  before = edges + min - 1;
+            AF_Edge  after  = edges + min + 0;
+
+
+            /* assert( before && after && before != after ) */
+            if ( before->scale == 0 )
+              before->scale = FT_DivFix( after->pos - before->pos,
+                                         after->fpos - before->fpos );
+
+            u = before->pos + FT_MulFix( fu - before->fpos,
+                                         before->scale );
+          }
+        }
+
+
+      Store_Point:
+
+        /* save the point position */
+        if ( dim == AF_DIMENSION_HORZ )
+          point->x = u;
+        else
+          point->y = u;
+
+        point->flags |= touch_flag;
+      }
+    }
+  }
+
+
+ /*
+  *
+  *  W E A K   P O I N T   I N T E R P O L A T I O N
+  *
+  */
+
+  static void
+  af_iup_shift( AF_Point  p1,
+                AF_Point  p2,
+                AF_Point  ref )
+  {
+    AF_Point  p;
+    FT_Pos    delta = ref->u - ref->v;
+
+
+    for ( p = p1; p < ref; p++ )
+      p->u = p->v + delta;
+
+    for ( p = ref + 1; p <= p2; p++ )
+      p->u = p->v + delta;
+  }
+
+
+  static void
+  af_iup_interp( AF_Point  p1,
+                 AF_Point  p2,
+                 AF_Point  ref1,
+                 AF_Point  ref2 )
+  {
+    AF_Point  p;
+    FT_Pos    u;
+    FT_Pos    v1 = ref1->v;
+    FT_Pos    v2 = ref2->v;
+    FT_Pos    d1 = ref1->u - v1;
+    FT_Pos    d2 = ref2->u - v2;
+
+
+    if ( p1 > p2 )
+      return;
+
+    if ( v1 == v2 )
+    {
+      for ( p = p1; p <= p2; p++ )
+      {
+        u = p->v;
+
+        if ( u <= v1 )
+          u += d1;
+        else
+          u += d2;
+
+        p->u = u;
+      }
+      return;
+    }
+
+    if ( v1 < v2 )
+    {
+      for ( p = p1; p <= p2; p++ )
+      {
+        u = p->v;
+
+        if ( u <= v1 )
+          u += d1;
+        else if ( u >= v2 )
+          u += d2;
+        else
+          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
+
+        p->u = u;
+      }
+    }
+    else
+    {
+      for ( p = p1; p <= p2; p++ )
+      {
+        u = p->v;
+
+        if ( u <= v2 )
+          u += d2;
+        else if ( u >= v1 )
+          u += d1;
+        else
+          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );
+
+        p->u = u;
+      }
+    }
+  }
+
+
+  FT_LOCAL_DEF( void )
+  af_glyph_hints_align_weak_points( AF_GlyphHints  hints,
+                                    AF_Dimension   dim )
+  {
+    AF_Point    points        = hints->points;
+    AF_Point    point_limit   = points + hints->num_points;
+    AF_Point*   contour       = hints->contours;
+    AF_Point*   contour_limit = contour + hints->num_contours;
+    AF_Flags    touch_flag;
+    AF_Point    point;
+    AF_Point    end_point;
+    AF_Point    first_point;
+
+
+    /* PASS 1: Move segment points to edge positions */
+
+    if ( dim == AF_DIMENSION_HORZ )
+    {
+      touch_flag = AF_FLAG_TOUCH_X;
+
+      for ( point = points; point < point_limit; point++ )
+      {
+        point->u = point->x;
+        point->v = point->ox;
+      }
+    }
+    else
+    {
+      touch_flag = AF_FLAG_TOUCH_Y;
+
+      for ( point = points; point < point_limit; point++ )
+      {
+        point->u = point->y;
+        point->v = point->oy;
+      }
+    }
+
+    point   = points;
+
+    for ( ; contour < contour_limit; contour++ )
+    {
+      point       = *contour;
+      end_point   = point->prev;
+      first_point = point;
+
+      while ( point <= end_point && !( point->flags & touch_flag ) )
+        point++;
+
+      if ( point <= end_point )
+      {
+        AF_Point  first_touched = point;
+        AF_Point  cur_touched   = point;
+
+
+        point++;
+        while ( point <= end_point )
+        {
+          if ( point->flags & touch_flag )
+          {
+            /* we found two successive touched points; we interpolate */
+            /* all contour points between them                        */
+            af_iup_interp( cur_touched + 1, point - 1,
+                           cur_touched, point );
+            cur_touched = point;
+          }
+          point++;
+        }
+
+        if ( cur_touched == first_touched )
+        {
+          /* this is a special case: only one point was touched in the */
+          /* contour; we thus simply shift the whole contour           */
+          af_iup_shift( first_point, end_point, cur_touched );
+        }
+        else
+        {
+          /* now interpolate after the last touched point to the end */
+          /* of the contour                                          */
+          af_iup_interp( cur_touched + 1, end_point,
+                         cur_touched, first_touched );
+
+          /* if the first contour point isn't touched, interpolate */
+          /* from the contour start to the first touched point     */
+          if ( first_touched > points )
+            af_iup_interp( first_point, first_touched - 1,
+                           cur_touched, first_touched );
+        }
+      }
+    }
+
+    /* now save the interpolated values back to x/y */
+    if ( dim == AF_DIMENSION_HORZ )
+    {
+      for ( point = points; point < point_limit; point++ )
+        point->x = point->u;
+    }
+    else
+    {
+      for ( point = points; point < point_limit; point++ )
+        point->y = point->u;
+    }
+  }
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -1,431 +1,431 @@
-#include "afloader.h"
-#include "afhints.h"
-#include "afglobal.h"
-#include "aflatin.h"
-
-  FT_LOCAL_DEF( FT_Error )
-  af_loader_init( AF_Loader  loader,
-                  FT_Memory  memory )
-  {
-    FT_Error  error;
-
-    FT_ZERO( loader );
-
-    af_glyph_hints_init( &loader->hints, memory );
-
-    error = FT_GlyphLoader_New( memory, &loader->gloader );
-    if ( !error )
-    {
-      error = FT_GlyphLoader_CreateExtra( loader->gloader );
-      if ( error )
-      {
-        FT_GlyphLoader_Done( loader->gloader );
-        loader->gloader = NULL;
-      }
-    }
-    return error;
-  }
-
-
-  FT_LOCAL_DEF( FT_Error )
-  af_loader_reset( AF_Loader   loader,
-                   FT_Face     face )
-  {
-    FT_Error   error = 0;
-
-    loader->face    = face;
-    loader->gloader = face->glyph->internal->loader;
-    loader->globals = (AF_FaceGlobals) face->autohint.data;
-
-    if ( loader->globals == NULL )
-    {
-      error = af_face_globals_new( face, &loader->globals );
-      if ( !error )
-      {
-        face->autohint.data      = (FT_Pointer) loader->globals;
-        face->autohint.finalizer = (FT_Generic_Finalizer) af_face_globals_free;
-      }
-    }
-    return error;
-  }
-
-
-  FT_LOCAL_DEF( void )
-  af_loader_done( AF_Loader   loader )
-  {
-    loader->face    = NULL;
-    loader->globals = NULL;
-
-    FT_GlyphLoader_Done( loader->gloader );
-    loader->gloader = NULL;
-  }
-
-
-  static FT_Error
-  af_loader_load_g( AF_Loader  loader,
-                    AF_Scaler  scaler,
-                    FT_UInt    glyph_index,
-                    FT_Int32   load_flags,
-                    FT_UInt    depth )
-  {
-    FT_Error          error    = 0;
-    FT_Face           face     = loader->face;
-    AF_FaceGlobals    globals  = loader->globals;
-    FT_GlyphLoader    gloader  = loader->gloader;
-    AF_ScriptMetrics  metrics  = loader->metrics;
-    AF_GlyphHints     hints    = &loader->hints;
-    FT_GlyphSlot      slot     = face->glyph;
-    FT_Slot_Internal  internal = slot->internal;
-
-    error = FT_Load_Glyph( face, glyph_index, load_flags );
-    if ( error )
-      goto Exit;
-
-    loader->transformed = internal->glyph_transformed;
-    if ( loader->transformed )
-    {
-      FT_Matrix  inverse;
-
-      loader->trans_matrix = internal->glyph_matrix;
-      loader->trans_delta  = internal->glyph_delta;
-
-      inverse = loader->trans_matrix;
-      FT_Matrix_Invert( &inverse );
-      FT_Vector_Transform( &loader->trans_delta, &inverse );
-    }
-
-    /* set linear metrics */
-    slot->linearHoriAdvance = slot->metrics.horiAdvance;
-    slot->linearVertAdvance = slot->metrics.vertAdvance;
-
-    switch ( slot->format )
-    {
-      case FT_GLYPH_FORMAT_OUTLINE:
-       /* translate the loaded glyph when an internal transform
-        * is needed
-        */
-        if ( loader->transformed )
-        {
-          FT_Vector*  point = slot->outline.points;
-          FT_Vector*  limit = point + slot->outline.n_points;
-
-          for ( ; point < limit; point++ )
-          {
-            point->x += loader->trans_delta.x;
-            point->y += loader->trans_delta.y;
-          }
-        }
-
-        /* copy the outline points in the loader's current               */
-        /* extra points which is used to keep original glyph coordinates */
-        error = FT_GlyphLoader_CheckPoints( gloader,
-                                            slot->outline.n_points + 2,
-                                            slot->outline.n_contours );
-        if ( error )
-          goto Exit;
-
-        FT_ARRAY_COPY( gloader->current.extra_points,
-                       slot->outline.points,
-                       slot->outline.n_points );
-
-        FT_ARRAY_COPY( gloader->current.outline.contours,
-                       slot->outline.contours,
-                       slot->outline.n_contours );
-
-        FT_ARRAY_COPY( gloader->current.outline.tags,
-                       slot->outline.tags,
-                       slot->outline.n_points );
-
-        gloader->current.outline.n_points   = slot->outline.n_points;
-        gloader->current.outline.n_contours = slot->outline.n_contours;
-
-        /* compute original phantom points */
-        loader->pp1.x = hints->x_delta;
-        loader->pp1.y = hints->y_delta;
-        loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
-                                   hints->x_scale ) + hints->x_delta;
-        loader->pp2.y = hints->y_delta;
-
-        /* be sure to check for spacing glyphs */
-        if ( slot->outline.n_points == 0 )
-          goto Hint_Metrics;
-
-        /* now load the slot image into the auto-outline and run the */
-        /* automatic hinting process                                 */
-        error = metrics->clazz->script_hints_init( hints,
-                                                   &gloader->current.outline,
-                                                   metrics );
-        if ( error )
-          goto Exit;
-
-        /* apply the hints */
-        metrics->clazz->script_hints_apply( hints,
-                                            &gloader->current.outline,
-                                            metrics );
-        /* we now need to hint the metrics according to the change in */
-        /* width/positioning that occured during the hinting process  */
-        {
-          FT_Pos        old_advance, old_rsb, old_lsb, new_lsb;
-          AF_AxisHints  axis  = &hints->axis[ AF_DIMENSION_HORZ ];
-          AF_Edge       edge1 = axis->edges;    /* leftmost edge  */
-          AF_Edge       edge2 = edge1 + axis->num_edges - 1; /* rightmost edge */
-
-
-          old_advance = loader->pp2.x;
-          old_rsb     = old_advance - edge2->opos;
-          old_lsb     = edge1->opos;
-          new_lsb     = edge1->pos;
-
-          loader->pp1.x = FT_PIX_ROUND( new_lsb    - old_lsb );
-          loader->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb );
-
-#if 0
-          /* try to fix certain bad advance computations */
-          if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 )
-            loader->pp2.x += 64;
-#endif
-        }
-
-        /* good, we simply add the glyph to our loader's base */
-        FT_GlyphLoader_Add( gloader );
-        break;
-
-    case FT_GLYPH_FORMAT_COMPOSITE:
-      {
-        FT_UInt      nn, num_subglyphs = slot->num_subglyphs;
-        FT_UInt      num_base_subgs, start_point;
-        FT_SubGlyph  subglyph;
-
-
-        start_point = gloader->base.outline.n_points;
-
-        /* first of all, copy the subglyph descriptors in the glyph loader */
-        error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
-        if ( error )
-          goto Exit;
-
-        FT_ARRAY_COPY( gloader->current.subglyphs,
-                       slot->subglyphs,
-                       num_subglyphs );
-
-        gloader->current.num_subglyphs = num_subglyphs;
-        num_base_subgs = gloader->base.num_subglyphs;
-
-        /* now, read each subglyph independently */
-        for ( nn = 0; nn < num_subglyphs; nn++ )
-        {
-          FT_Vector  pp1, pp2;
-          FT_Pos     x, y;
-          FT_UInt    num_points, num_new_points, num_base_points;
-
-
-          /* gloader.current.subglyphs can change during glyph loading due */
-          /* to re-allocation -- we must recompute the current subglyph on */
-          /* each iteration                                                */
-          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
-
-          pp1 = loader->pp1;
-          pp2 = loader->pp2;
-
-          num_base_points = gloader->base.outline.n_points;
-
-          error = af_loader_load_g( loader, scaler, subglyph->index,
-                                    load_flags, depth + 1 );
-          if ( error )
-            goto Exit;
-
-          /* recompute subglyph pointer */
-          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
-
-          if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
-          {
-            pp1 = loader->pp1;
-            pp2 = loader->pp2;
-          }
-          else
-          {
-            loader->pp1 = pp1;
-            loader->pp2 = pp2;
-          }
-
-          num_points     = gloader->base.outline.n_points;
-          num_new_points = num_points - num_base_points;
-
-          /* now perform the transform required for this subglyph */
-
-          if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE    |
-                                   FT_SUBGLYPH_FLAG_XY_SCALE |
-                                   FT_SUBGLYPH_FLAG_2X2      ) )
-          {
-            FT_Vector*  cur   = gloader->base.outline.points +
-                                num_base_points;
-            FT_Vector*  org   = gloader->base.extra_points +
-                                num_base_points;
-            FT_Vector*  limit = cur + num_new_points;
-
-
-            for ( ; cur < limit; cur++, org++ )
-            {
-              FT_Vector_Transform( cur, &subglyph->transform );
-              FT_Vector_Transform( org, &subglyph->transform );
-            }
-          }
-
-          /* apply offset */
-
-          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
-          {
-            FT_Int      k = subglyph->arg1;
-            FT_UInt     l = subglyph->arg2;
-            FT_Vector*  p1;
-            FT_Vector*  p2;
-
-
-            if ( start_point + k >= num_base_points         ||
-                               l >= (FT_UInt)num_new_points )
-            {
-              error = FT_Err_Invalid_Composite;
-              goto Exit;
-            }
-
-            l += num_base_points;
-
-            /* for now, only use the current point coordinates;    */
-            /* we may consider another approach in the near future */
-            p1 = gloader->base.outline.points + start_point + k;
-            p2 = gloader->base.outline.points + start_point + l;
-
-            x = p1->x - p2->x;
-            y = p1->y - p2->y;
-          }
-          else
-          {
-            x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
-            y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
-
-            x = FT_PIX_ROUND(x);
-            y = FT_PIX_ROUND(y);
-          }
-
-          {
-            FT_Outline  dummy = gloader->base.outline;
-
-
-            dummy.points  += num_base_points;
-            dummy.n_points = (short)num_new_points;
-
-            FT_Outline_Translate( &dummy, x, y );
-          }
-        }
-      }
-      break;
-
-    default:
-      /* we don't support other formats (yet?) */
-      error = FT_Err_Unimplemented_Feature;
-    }
-
-  Hint_Metrics:
-    if ( depth == 0 )
-    {
-      FT_BBox  bbox;
-
-
-      /* transform the hinted outline if needed */
-      if ( loader->transformed )
-        FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
-
-      /* we must translate our final outline by -pp1.x and compute */
-      /* the new metrics                                           */
-      if ( loader->pp1.x )
-        FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
-
-      FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
-
-      bbox.xMin  = FT_PIX_FLOOR(  bbox.xMin );
-      bbox.yMin  = FT_PIX_FLOOR(  bbox.yMin );
-      bbox.xMax  = FT_PIX_CEIL( bbox.xMax );
-      bbox.yMax  = FT_PIX_CEIL( bbox.yMax );
-
-      slot->metrics.width        = bbox.xMax - bbox.xMin;
-      slot->metrics.height       = bbox.yMax - bbox.yMin;
-      slot->metrics.horiBearingX = bbox.xMin;
-      slot->metrics.horiBearingY = bbox.yMax;
-
-      /* for mono-width fonts (like Andale, Courier, etc.) we need */
-      /* to keep the original rounded advance width                */
-#if 0
-      if ( !FT_IS_FIXED_WIDTH( slot->face ) )
-        slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
-      else
-        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
-                                               x_scale );
-#else
-      slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
-#endif
-
-      slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
-
-      /* now copy outline into glyph slot */
-      FT_GlyphLoader_Rewind( loader->gloader );
-      error = FT_GlyphLoader_CopyPoints( loader->gloader, gloader );
-      if ( error )
-        goto Exit;
-
-      slot->outline = slot->internal->loader->base.outline;
-      slot->format  = FT_GLYPH_FORMAT_OUTLINE;
-    }
-
-#ifdef DEBUG_HINTER
-    af_debug_hinter = hinter;
-#endif
-
-  Exit:
-    return error;
-  }
-
-
-
-
-  FT_LOCAL_DEF( FT_Error )
-  af_loader_load_glyph( AF_Loader  loader,
-                        FT_Face    face,
-                        FT_UInt    gindex,
-                        FT_UInt32  load_flags )
-  {
-    FT_Error      error;
-    FT_Size       size = face->size;
-    AF_ScalerRec  scaler;
-
-    if ( !size )
-      return FT_Err_Invalid_Argument;
-
-    FT_ZERO( &scaler );
-
-    scaler.face    = face;
-    scaler.x_scale = size->metrics.x_scale;
-    scaler.x_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
-    scaler.y_scale = size->metrics.y_scale;
-    scaler.y_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
-
-    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
-    scaler.flags       = 0;  /* XXX: fix this */
-
-    error = af_loader_reset( loader, face );
-    if ( !error )
-    {
-      AF_ScriptMetrics  metrics;
-
-      error = af_face_globals_get_metrics( loader->globals, gindex, &metrics );
-      if ( !error )
-      {
-        metrics->clazz->script_metrics_scale( metrics, &scaler );
-
-        load_flags |=  FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
-        load_flags &= ~FT_LOAD_RENDER;
-
-        error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
-      }
-    }
-    return error;
-  }
+#include "afloader.h"
+#include "afhints.h"
+#include "afglobal.h"
+#include "aflatin.h"
+
+  FT_LOCAL_DEF( FT_Error )
+  af_loader_init( AF_Loader  loader,
+                  FT_Memory  memory )
+  {
+    FT_Error  error;
+
+    FT_ZERO( loader );
+
+    af_glyph_hints_init( &loader->hints, memory );
+
+    error = FT_GlyphLoader_New( memory, &loader->gloader );
+    if ( !error )
+    {
+      error = FT_GlyphLoader_CreateExtra( loader->gloader );
+      if ( error )
+      {
+        FT_GlyphLoader_Done( loader->gloader );
+        loader->gloader = NULL;
+      }
+    }
+    return error;
+  }
+
+
+  FT_LOCAL_DEF( FT_Error )
+  af_loader_reset( AF_Loader   loader,
+                   FT_Face     face )
+  {
+    FT_Error   error = 0;
+
+    loader->face    = face;
+    loader->gloader = face->glyph->internal->loader;
+    loader->globals = (AF_FaceGlobals) face->autohint.data;
+
+    if ( loader->globals == NULL )
+    {
+      error = af_face_globals_new( face, &loader->globals );
+      if ( !error )
+      {
+        face->autohint.data      = (FT_Pointer) loader->globals;
+        face->autohint.finalizer = (FT_Generic_Finalizer) af_face_globals_free;
+      }
+    }
+    return error;
+  }
+
+
+  FT_LOCAL_DEF( void )
+  af_loader_done( AF_Loader   loader )
+  {
+    loader->face    = NULL;
+    loader->globals = NULL;
+
+    FT_GlyphLoader_Done( loader->gloader );
+    loader->gloader = NULL;
+  }
+
+
+  static FT_Error
+  af_loader_load_g( AF_Loader  loader,
+                    AF_Scaler  scaler,
+                    FT_UInt    glyph_index,
+                    FT_Int32   load_flags,
+                    FT_UInt    depth )
+  {
+    FT_Error          error    = 0;
+    FT_Face           face     = loader->face;
+    AF_FaceGlobals    globals  = loader->globals;
+    FT_GlyphLoader    gloader  = loader->gloader;
+    AF_ScriptMetrics  metrics  = loader->metrics;
+    AF_GlyphHints     hints    = &loader->hints;
+    FT_GlyphSlot      slot     = face->glyph;
+    FT_Slot_Internal  internal = slot->internal;
+
+    error = FT_Load_Glyph( face, glyph_index, load_flags );
+    if ( error )
+      goto Exit;
+
+    loader->transformed = internal->glyph_transformed;
+    if ( loader->transformed )
+    {
+      FT_Matrix  inverse;
+
+      loader->trans_matrix = internal->glyph_matrix;
+      loader->trans_delta  = internal->glyph_delta;
+
+      inverse = loader->trans_matrix;
+      FT_Matrix_Invert( &inverse );
+      FT_Vector_Transform( &loader->trans_delta, &inverse );
+    }
+
+    /* set linear metrics */
+    slot->linearHoriAdvance = slot->metrics.horiAdvance;
+    slot->linearVertAdvance = slot->metrics.vertAdvance;
+
+    switch ( slot->format )
+    {
+      case FT_GLYPH_FORMAT_OUTLINE:
+       /* translate the loaded glyph when an internal transform
+        * is needed
+        */
+        if ( loader->transformed )
+        {
+          FT_Vector*  point = slot->outline.points;
+          FT_Vector*  limit = point + slot->outline.n_points;
+
+          for ( ; point < limit; point++ )
+          {
+            point->x += loader->trans_delta.x;
+            point->y += loader->trans_delta.y;
+          }
+        }
+
+        /* copy the outline points in the loader's current               */
+        /* extra points which is used to keep original glyph coordinates */
+        error = FT_GlyphLoader_CheckPoints( gloader,
+                                            slot->outline.n_points + 2,
+                                            slot->outline.n_contours );
+        if ( error )
+          goto Exit;
+
+        FT_ARRAY_COPY( gloader->current.extra_points,
+                       slot->outline.points,
+                       slot->outline.n_points );
+
+        FT_ARRAY_COPY( gloader->current.outline.contours,
+                       slot->outline.contours,
+                       slot->outline.n_contours );
+
+        FT_ARRAY_COPY( gloader->current.outline.tags,
+                       slot->outline.tags,
+                       slot->outline.n_points );
+
+        gloader->current.outline.n_points   = slot->outline.n_points;
+        gloader->current.outline.n_contours = slot->outline.n_contours;
+
+        /* compute original phantom points */
+        loader->pp1.x = hints->x_delta;
+        loader->pp1.y = hints->y_delta;
+        loader->pp2.x = FT_MulFix( slot->metrics.horiAdvance,
+                                   hints->x_scale ) + hints->x_delta;
+        loader->pp2.y = hints->y_delta;
+
+        /* be sure to check for spacing glyphs */
+        if ( slot->outline.n_points == 0 )
+          goto Hint_Metrics;
+
+        /* now load the slot image into the auto-outline and run the */
+        /* automatic hinting process                                 */
+        error = metrics->clazz->script_hints_init( hints,
+                                                   &gloader->current.outline,
+                                                   metrics );
+        if ( error )
+          goto Exit;
+
+        /* apply the hints */
+        metrics->clazz->script_hints_apply( hints,
+                                            &gloader->current.outline,
+                                            metrics );
+        /* we now need to hint the metrics according to the change in */
+        /* width/positioning that occured during the hinting process  */
+        {
+          FT_Pos        old_advance, old_rsb, old_lsb, new_lsb;
+          AF_AxisHints  axis  = &hints->axis[ AF_DIMENSION_HORZ ];
+          AF_Edge       edge1 = axis->edges;    /* leftmost edge  */
+          AF_Edge       edge2 = edge1 + axis->num_edges - 1; /* rightmost edge */
+
+
+          old_advance = loader->pp2.x;
+          old_rsb     = old_advance - edge2->opos;
+          old_lsb     = edge1->opos;
+          new_lsb     = edge1->pos;
+
+          loader->pp1.x = FT_PIX_ROUND( new_lsb    - old_lsb );
+          loader->pp2.x = FT_PIX_ROUND( edge2->pos + old_rsb );
+
+#if 0
+          /* try to fix certain bad advance computations */
+          if ( loader->pp2.x + loader->pp1.x == edge2->pos && old_rsb > 4 )
+            loader->pp2.x += 64;
+#endif
+        }
+
+        /* good, we simply add the glyph to our loader's base */
+        FT_GlyphLoader_Add( gloader );
+        break;
+
+    case FT_GLYPH_FORMAT_COMPOSITE:
+      {
+        FT_UInt      nn, num_subglyphs = slot->num_subglyphs;
+        FT_UInt      num_base_subgs, start_point;
+        FT_SubGlyph  subglyph;
+
+
+        start_point = gloader->base.outline.n_points;
+
+        /* first of all, copy the subglyph descriptors in the glyph loader */
+        error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs );
+        if ( error )
+          goto Exit;
+
+        FT_ARRAY_COPY( gloader->current.subglyphs,
+                       slot->subglyphs,
+                       num_subglyphs );
+
+        gloader->current.num_subglyphs = num_subglyphs;
+        num_base_subgs = gloader->base.num_subglyphs;
+
+        /* now, read each subglyph independently */
+        for ( nn = 0; nn < num_subglyphs; nn++ )
+        {
+          FT_Vector  pp1, pp2;
+          FT_Pos     x, y;
+          FT_UInt    num_points, num_new_points, num_base_points;
+
+
+          /* gloader.current.subglyphs can change during glyph loading due */
+          /* to re-allocation -- we must recompute the current subglyph on */
+          /* each iteration                                                */
+          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
+
+          pp1 = loader->pp1;
+          pp2 = loader->pp2;
+
+          num_base_points = gloader->base.outline.n_points;
+
+          error = af_loader_load_g( loader, scaler, subglyph->index,
+                                    load_flags, depth + 1 );
+          if ( error )
+            goto Exit;
+
+          /* recompute subglyph pointer */
+          subglyph = gloader->base.subglyphs + num_base_subgs + nn;
+
+          if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )
+          {
+            pp1 = loader->pp1;
+            pp2 = loader->pp2;
+          }
+          else
+          {
+            loader->pp1 = pp1;
+            loader->pp2 = pp2;
+          }
+
+          num_points     = gloader->base.outline.n_points;
+          num_new_points = num_points - num_base_points;
+
+          /* now perform the transform required for this subglyph */
+
+          if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE    |
+                                   FT_SUBGLYPH_FLAG_XY_SCALE |
+                                   FT_SUBGLYPH_FLAG_2X2      ) )
+          {
+            FT_Vector*  cur   = gloader->base.outline.points +
+                                num_base_points;
+            FT_Vector*  org   = gloader->base.extra_points +
+                                num_base_points;
+            FT_Vector*  limit = cur + num_new_points;
+
+
+            for ( ; cur < limit; cur++, org++ )
+            {
+              FT_Vector_Transform( cur, &subglyph->transform );
+              FT_Vector_Transform( org, &subglyph->transform );
+            }
+          }
+
+          /* apply offset */
+
+          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )
+          {
+            FT_Int      k = subglyph->arg1;
+            FT_UInt     l = subglyph->arg2;
+            FT_Vector*  p1;
+            FT_Vector*  p2;
+
+
+            if ( start_point + k >= num_base_points         ||
+                               l >= (FT_UInt)num_new_points )
+            {
+              error = FT_Err_Invalid_Composite;
+              goto Exit;
+            }
+
+            l += num_base_points;
+
+            /* for now, only use the current point coordinates;    */
+            /* we may consider another approach in the near future */
+            p1 = gloader->base.outline.points + start_point + k;
+            p2 = gloader->base.outline.points + start_point + l;
+
+            x = p1->x - p2->x;
+            y = p1->y - p2->y;
+          }
+          else
+          {
+            x = FT_MulFix( subglyph->arg1, hints->x_scale ) + hints->x_delta;
+            y = FT_MulFix( subglyph->arg2, hints->y_scale ) + hints->y_delta;
+
+            x = FT_PIX_ROUND(x);
+            y = FT_PIX_ROUND(y);
+          }
+
+          {
+            FT_Outline  dummy = gloader->base.outline;
+
+
+            dummy.points  += num_base_points;
+            dummy.n_points = (short)num_new_points;
+
+            FT_Outline_Translate( &dummy, x, y );
+          }
+        }
+      }
+      break;
+
+    default:
+      /* we don't support other formats (yet?) */
+      error = FT_Err_Unimplemented_Feature;
+    }
+
+  Hint_Metrics:
+    if ( depth == 0 )
+    {
+      FT_BBox  bbox;
+
+
+      /* transform the hinted outline if needed */
+      if ( loader->transformed )
+        FT_Outline_Transform( &gloader->base.outline, &loader->trans_matrix );
+
+      /* we must translate our final outline by -pp1.x and compute */
+      /* the new metrics                                           */
+      if ( loader->pp1.x )
+        FT_Outline_Translate( &gloader->base.outline, -loader->pp1.x, 0 );
+
+      FT_Outline_Get_CBox( &gloader->base.outline, &bbox );
+
+      bbox.xMin  = FT_PIX_FLOOR(  bbox.xMin );
+      bbox.yMin  = FT_PIX_FLOOR(  bbox.yMin );
+      bbox.xMax  = FT_PIX_CEIL( bbox.xMax );
+      bbox.yMax  = FT_PIX_CEIL( bbox.yMax );
+
+      slot->metrics.width        = bbox.xMax - bbox.xMin;
+      slot->metrics.height       = bbox.yMax - bbox.yMin;
+      slot->metrics.horiBearingX = bbox.xMin;
+      slot->metrics.horiBearingY = bbox.yMax;
+
+      /* for mono-width fonts (like Andale, Courier, etc.) we need */
+      /* to keep the original rounded advance width                */
+#if 0
+      if ( !FT_IS_FIXED_WIDTH( slot->face ) )
+        slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
+      else
+        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,
+                                               x_scale );
+#else
+      slot->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
+#endif
+
+      slot->metrics.horiAdvance = FT_PIX_ROUND( slot->metrics.horiAdvance );
+
+      /* now copy outline into glyph slot */
+      FT_GlyphLoader_Rewind( loader->gloader );
+      error = FT_GlyphLoader_CopyPoints( loader->gloader, gloader );
+      if ( error )
+        goto Exit;
+
+      slot->outline = slot->internal->loader->base.outline;
+      slot->format  = FT_GLYPH_FORMAT_OUTLINE;
+    }
+
+#ifdef DEBUG_HINTER
+    af_debug_hinter = hinter;
+#endif
+
+  Exit:
+    return error;
+  }
+
+
+
+
+  FT_LOCAL_DEF( FT_Error )
+  af_loader_load_glyph( AF_Loader  loader,
+                        FT_Face    face,
+                        FT_UInt    gindex,
+                        FT_UInt32  load_flags )
+  {
+    FT_Error      error;
+    FT_Size       size = face->size;
+    AF_ScalerRec  scaler;
+
+    if ( !size )
+      return FT_Err_Invalid_Argument;
+
+    FT_ZERO( &scaler );
+
+    scaler.face    = face;
+    scaler.x_scale = size->metrics.x_scale;
+    scaler.x_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
+    scaler.y_scale = size->metrics.y_scale;
+    scaler.y_delta = 0;  /* XXX: TODO: add support for sub-pixel hinting */
+
+    scaler.render_mode = FT_LOAD_TARGET_MODE( load_flags );
+    scaler.flags       = 0;  /* XXX: fix this */
+
+    error = af_loader_reset( loader, face );
+    if ( !error )
+    {
+      AF_ScriptMetrics  metrics;
+
+      error = af_face_globals_get_metrics( loader->globals, gindex, &metrics );
+      if ( !error )
+      {
+        metrics->clazz->script_metrics_scale( metrics, &scaler );
+
+        load_flags |=  FT_LOAD_NO_SCALE | FT_LOAD_IGNORE_TRANSFORM;
+        load_flags &= ~FT_LOAD_RENDER;
+
+        error = af_loader_load_g( loader, &scaler, gindex, load_flags, 0 );
+      }
+    }
+    return error;
+  }
--- a/src/autofit/afloader.h
+++ b/src/autofit/afloader.h
@@ -1,50 +1,49 @@
-#ifndef __AF_LOADER_H__
-#define __AF_LOADER_H__
-
-#include "afhints.h"
-#include "afglobal.h"
-
-FT_BEGIN_HEADER
-
-  typedef struct AF_LoaderRec_
-  {
-    FT_Face           face;           /* current face */
-    AF_FaceGlobals    globals;        /* current face globals */
-    FT_GlyphLoader    gloader;        /* glyph loader */
-    AF_GlyphHintsRec  hints;
-    AF_ScriptMetrics  metrics;
-    FT_Bool           transformed;
-    FT_Matrix         trans_matrix;
-    FT_Vector         trans_delta;
-    FT_Vector         pp1;
-    FT_Vector         pp2;
-
-  } AF_LoaderRec, *AF_Loader;
-
-
-  FT_LOCAL( FT_Error )
-  af_loader_init( AF_Loader  loader,
-                  FT_Memory  memory );
-
-
-  FT_LOCAL( FT_Error )
-  af_loader_reset( AF_Loader  loader,
-                   FT_Face    face );
-
-
-  FT_LOCAL( void )
-  af_loader_done( AF_Loader  loader );
-
-
-  FT_LOCAL( FT_Error )
-  af_loader_load_glyph( AF_Loader  loader,
-                        FT_Face    face,
-                        FT_UInt    gindex,
-                        FT_UInt32  load_flags );
-
-/* */
-
-FT_END_HEADER
-
-#endif /* __AF_LOADER_H__ */
-
+#ifndef __AF_LOADER_H__
+#define __AF_LOADER_H__
+
+#include "afhints.h"
+#include "afglobal.h"
+
+FT_BEGIN_HEADER
+
+  typedef struct AF_LoaderRec_
+  {
+    FT_Face           face;           /* current face */
+    AF_FaceGlobals    globals;        /* current face globals */
+    FT_GlyphLoader    gloader;        /* glyph loader */
+    AF_GlyphHintsRec  hints;
+    AF_ScriptMetrics  metrics;
+    FT_Bool           transformed;
+    FT_Matrix         trans_matrix;
+    FT_Vector         trans_delta;
+    FT_Vector         pp1;
+    FT_Vector         pp2;
+
+  } AF_LoaderRec, *AF_Loader;
+
+
+  FT_LOCAL( FT_Error )
+  af_loader_init( AF_Loader  loader,
+                  FT_Memory  memory );
+
+
+  FT_LOCAL( FT_Error )
+  af_loader_reset( AF_Loader  loader,
+                   FT_Face    face );
+
+
+  FT_LOCAL( void )
+  af_loader_done( AF_Loader  loader );
+
+
+  FT_LOCAL( FT_Error )
+  af_loader_load_glyph( AF_Loader  loader,
+                        FT_Face    face,
+                        FT_UInt    gindex,
+                        FT_UInt32  load_flags );
+
+/* */
+
+FT_END_HEADER
+
+#endif /* __AF_LOADER_H__ */
--- a/src/autofit/afmodule.h
+++ b/src/autofit/afmodule.h
@@ -1,17 +1,16 @@
-#ifndef __AFMODULE_H__
-#define __AFMODULE_H__
-
-#include <ft2build.h>
-#include FT_MODULE_H
-
-
-FT_BEGIN_HEADER
-
-  FT_CALLBACK_TABLE
-  const FT_Module_Class  autofit_module_class;
-
-
-FT_END_HEADER
-
-#endif /* __AFMODULE_H__ */
-
+#ifndef __AFMODULE_H__
+#define __AFMODULE_H__
+
+#include <ft2build.h>
+#include FT_MODULE_H
+
+
+FT_BEGIN_HEADER
+
+  FT_CALLBACK_TABLE
+  const FT_Module_Class  autofit_module_class;
+
+
+FT_END_HEADER
+
+#endif /* __AFMODULE_H__ */
--- a/src/autofit/autofit.c
+++ b/src/autofit/autofit.c
@@ -1,10 +1,8 @@
-#define FT_MAKE_OPTION_SINGLE_OBJECT
-#include <ft2build.h>
-#include "afangles.c"
-#include "afglobal.c"
-#include "afhints.c"
-#include "aflatin.c"
-#include "afloader.c"
-#include "afmodule.c"
-
-
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+#include <ft2build.h>
+#include "afangles.c"
+#include "afglobal.c"
+#include "afhints.c"
+#include "aflatin.c"
+#include "afloader.c"
+#include "afmodule.c"
--- a/src/autohint/ahmodule.c
+++ b/src/autohint/ahmodule.c
@@ -117,7 +117,7 @@
 
 
   FT_CALLBACK_TABLE_DEF
-  const FT_Module_Class  autofit_module_class =
+  const FT_Module_Class  autohint_module_class =
   {
     FT_MODULE_HINTER,
     sizeof ( FT_AutoHinterRec ),
--- a/src/cache/Jamfile
+++ b/src/cache/Jamfile
@@ -1,4 +1,4 @@
-# FreeType 2 src/cache Jamfile (c) 2001, 2003 David Turner
+# FreeType 2 src/cache Jamfile (c) 2001, 2003, 2004 David Turner
 #
 
 SubDir  FT2_TOP $(FT2_SRC_DIR) cache ;
--- a/src/cache/descrip.mms
+++ b/src/cache/descrip.mms
@@ -3,7 +3,7 @@
 #
 
 
-# Copyright 2001, 2002, 2003 by
+# Copyright 2001, 2002, 2003, 2004 by
 # David Turner, Robert Wilhelm, and Werner Lemberg.
 #
 # This file is part of the FreeType project, and may only be used, modified,
--- a/src/cache/ftcbasic.c
+++ b/src/cache/ftcbasic.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    The FreeType basic cache interface (body).                           */
 /*                                                                         */
-/*  Copyright 2003 by                                                      */
+/*  Copyright 2003, 2004 by                                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
--- a/src/cache/ftccmap.c
+++ b/src/cache/ftccmap.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType CharMap cache (body)                                        */
 /*                                                                         */
-/*  Copyright 2000-2001, 2002, 2003 by                                     */
+/*  Copyright 2000-2001, 2002, 2003, 2004 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
--- a/src/cache/ftcmru.c
+++ b/src/cache/ftcmru.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType MRU support (body).                                         */
 /*                                                                         */
-/*  Copyright 2003 by                                                      */
+/*  Copyright 2003, 2004 by                                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
--- a/src/sfnt/Jamfile
+++ b/src/sfnt/Jamfile
@@ -1,4 +1,4 @@
-# FreeType 2 src/sfnt Jamfile (c) 2001, 2002 David Turner
+# FreeType 2 src/sfnt Jamfile (c) 2001, 2002, 2004 David Turner
 #
 
 SubDir  FT2_TOP $(FT2_SRC_DIR) sfnt ;
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -787,10 +787,11 @@
     FT_Byte*  limit = parser->root.limit;
 
 
-    /* the binary data has the following format */
-    /*                                          */
-    /* `size' [white*] RD white ....... ND      */
-    /*                                          */
+    /* the binary data has one of the following formats */
+    /*                                                  */
+    /*   `size' [white*] RD white ....... ND            */
+    /*   `size' [white*] -| white ....... |-            */
+    /*                                                  */
 
     T1_Skip_Spaces( parser );
 
@@ -1116,7 +1117,7 @@
       /* (bound to `noaccess put') or by two separate tokens:  */
       /* `noaccess' & `put'.  We position the parser right     */
       /* before the next `dup', if any.                        */
-      T1_Skip_PS_Token( parser );   /* `NP' or `I' or `noaccess' */
+      T1_Skip_PS_Token( parser );   /* `NP' or `|' or `noaccess' */
       T1_Skip_Spaces  ( parser );
 
       if ( ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 )
@@ -1487,7 +1488,8 @@
               FT_Byte*   keyword_flags )
   {
     T1_Parser  parser = &loader->parser;
-    FT_Byte*   limit;
+    FT_Byte   *limit, *start_binary;
+    FT_Bool    have_integer;
 
 
     parser->root.cursor = base;
@@ -1543,6 +1545,7 @@
             cur2 = parser->root.cursor;
         }
         parser->root.cursor = cur2;
+        have_integer = 0;
       }
 
       /* look for `eexec' */
@@ -1555,6 +1558,43 @@
                 ft_strncmp( (char*)cur, "closefile", 9 ) == 0 )
         break;
 
+      /* check whether we have an integer */
+      else if ( ft_isdigit( *cur ) )
+      {
+        start_binary = cur;
+        T1_Skip_PS_Token( parser );
+        have_integer = 1;
+      }
+
+      /* in valid Type 1 fonts we don't see `RD' or `-|' directly */
+      /* since those tokens are handled by parse_subrs and        */
+      /* parse_charstrings                                        */
+      else if ( *cur == 'R' && cur + 6 < limit && *(cur + 1) == 'D' &&
+                have_integer )
+      {
+        FT_Long   s;
+        FT_Byte*  b;
+
+
+        parser->root.cursor = start_binary;
+        if ( !read_binary_data( parser, &s, &b ) )
+          return T1_Err_Invalid_File_Format;
+        have_integer = 0;
+      }
+
+      else if ( *cur == '-' && cur + 6 < limit && *(cur + 1) == '|' &&
+                have_integer )
+      {
+        FT_Long   s;
+        FT_Byte*  b;
+
+
+        parser->root.cursor = start_binary;
+        if ( !read_binary_data( parser, &s, &b ) )
+          return T1_Err_Invalid_File_Format;
+        have_integer = 0;
+      }
+
       /* look for immediates */
       else if ( *cur == '/' && cur + 2 < limit )
       {
@@ -1582,10 +1622,7 @@
 
             name = (FT_Byte*)keyword->ident;
             if ( !name )
-            {
-              T1_Skip_PS_Token( parser );
               break;
-            }
 
             if ( cur[0] == name[0]                      &&
                  len == ft_strlen( (const char *)name ) &&
@@ -1614,9 +1651,14 @@
             keyword_flag++;
           }
         }
+
+        have_integer = 0;
       }
       else
+      {
         T1_Skip_PS_Token( parser );
+        have_integer = 0;
+      }
 
       T1_Skip_Spaces( parser );
     }
@@ -1732,7 +1774,7 @@
 #endif
       if ( !loader.charstrings.init )
       {
-        FT_ERROR(( "T1_Open_Face: no charstrings array in face!\n" ));
+        FT_ERROR(( "T1_Open_Face: no `/CharStrings' array in face!\n" ));
         error = T1_Err_Invalid_File_Format;
       }