shithub: freetype+ttf2subf

Download patch

ref: 9fbd2ab8849d2517f2e7f4ce1af3c5a77893cbe5
parent: 69d45172b6b03f4e4f6fd82cbe8f32ac7a2e7e91
author: David Turner <[email protected]>
date: Fri Oct 28 12:14:14 EDT 2005

- various performance enhancements
- fixing apinames.c, adding support for Watcom and Borland compilers
- adding generation of exported symbols list to the build system, including the Unix one !!

sorry Werner, I have no time to document this in ChangeLog at the moment

git/fs: mount .git/fs: mount/attach disallowed
--- a/Jamfile
+++ b/Jamfile
@@ -155,12 +155,14 @@
 
 rule GenExportSymbols
 {
-  local  headers = [ Glob $(2) : *.h ] ;
+  local  apinames = apinames$(SUFEXE) ;
+  local  headers  = [ Glob $(2) : *.h ] ;
 
   APINAMES on $(1) = apinames$(SUFEXE) ;
 
-  Depends            $(1) : $(headers) ;
+  Depends            $(1) : $(apinames) $(headers) ;
   GenExportSymbols1  $(1) : $(headers) ;
+  Clean              clean : $(1) ;
 }
 
 actions GenExportSymbols1 bind APINAMES
--- a/builds/compiler/visualc.mk
+++ b/builds/compiler/visualc.mk
@@ -55,6 +55,9 @@
 #
 T := /Fo
 
+# Target executable flag
+#
+TE := /Fe
 
 # C flags
 #
--- a/builds/dos/dos-def.mk
+++ b/builds/dos/dos-def.mk
@@ -19,6 +19,10 @@
 PLATFORM  := dos
 
 
+# The executable file extension (for tools). NOTE: WE INCLUDE THE DOT HERE !!
+#
+E := .exe
+
 # The directory where all object files are placed.
 #
 # This lets you build the library in your own directory with something like
--- a/builds/freetype.mk
+++ b/builds/freetype.mk
@@ -142,6 +142,9 @@
 #
 include $(TOP_DIR)/builds/modules.mk
 
+# Includes the 'exports' rules file.
+#
+include $(TOP_DIR)/builds/exports.mk
 
 # Initialize the list of objects.
 #
@@ -247,6 +250,8 @@
 
 library: $(PROJECT_LIBRARY)
 
+dll: $(PROJECT_LIBRARY) exported_symbols
+
 .c.$O:
 	$(FT_COMPILE) $T$(subst /,$(COMPILER_SEP),$@ $<)
 
@@ -283,7 +288,7 @@
 # working correctly on Win9x.
 #
 clean_project_dos:
-	-$(DELETE) $(subst /,\,$(OBJ)/*.$O $(CLEAN) $(NO_OUTPUT))
+	-$(DELETE) $(subst /,\,$(OBJ_DIR)/*.$O $(CLEAN) $(NO_OUTPUT))
 
 distclean_project_dos: clean_project_dos
 	-$(DELETE) $(subst /,\,$(PROJECT_LIBRARY) $(DISTCLEAN) $(NO_OUTPUT))
--- a/builds/os2/os2-def.mk
+++ b/builds/os2/os2-def.mk
@@ -18,6 +18,9 @@
 BUILD_DIR := $(TOP_DIR)/builds/os2
 PLATFORM  := os2
 
+# The executable file extension (for tools). NOTE: WE INCLUDE THE DOT HERE !!
+#
+E := .exe
 
 # The directory where all object files are placed.
 #
--- a/builds/unix/ftsystem.c
+++ b/builds/unix/ftsystem.c
@@ -280,13 +280,13 @@
     else
     {
       ssize_t  total_read_count;
-    
 
+
       FT_ERROR(( "FT_Stream_Open:" ));
       FT_ERROR(( " could not `mmap' file `%s'\n", filepathname ));
-      
+
       stream->base = (unsigned char*)ft_alloc( NULL, stream->size );
-      
+
       if ( !stream->base )
       {
         FT_ERROR(( "FT_Stream_Open:" ));
@@ -293,14 +293,14 @@
         FT_ERROR(( " could not `alloc' memory\n" ));
         goto Fail_Map;
       }
-      
+
       total_read_count = 0;
       do {
         ssize_t  read_count;
 
 
-        read_count = read( file, 
-                           stream->base + total_read_count, 
+        read_count = read( file,
+                           stream->base + total_read_count,
                            stream->size - total_read_count );
 
         if ( ( read_count == -1 ) )
--- a/builds/unix/unix-cc.in
+++ b/builds/unix/unix-cc.in
@@ -90,11 +90,16 @@
 LDFLAGS := @LDFLAGS@
 
 
+# export symbols (XXX: HOW TO DEAL WITH CROSS COMPILATION ?)
+#
+EXPORTS_LIST := $(OBJ_DIR)/ftexport.sym
+CCexe        := $(CCraw)   # used to compile "apinames" only
+
+
 # Library linking
 #
 LINK_LIBRARY = $(LIBTOOL) --mode=link $(CCraw) -o $@ $(OBJECTS_LIST) \
                           -rpath $(libdir) -version-info $(version_info) \
-                          $(LDFLAGS)
-
+                          $(LDFLAGS) -export-symbols $(EXPORTS_LIST)
 
 # EOF
--- a/builds/unix/unixddef.mk
+++ b/builds/unix/unixddef.mk
@@ -51,5 +51,4 @@
 
 NO_OUTPUT := 2> /dev/null
 
-
 # EOF
--- a/builds/win32/w32-bcc.mk
+++ b/builds/win32/w32-bcc.mk
@@ -12,6 +12,11 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
+# default definitions of the export list
+#
+EXPORTS_LIST      = $(OBJ_DIR)/freetype.def
+EXPORTS_OPTIONS   = /DEF:$(EXPORTS_LIST)
+APINAMES_OPTIONS := -dfreetype.dll -wB
 
 include $(TOP_DIR)/builds/win32/win32-def.mk
 include $(TOP_DIR)/builds/compiler/bcc.mk
--- a/builds/win32/w32-gcc.mk
+++ b/builds/win32/w32-gcc.mk
@@ -12,6 +12,11 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
+# default definitions of the export list
+#
+EXPORTS_LIST      = $(OBJ_DIR)/freetype.def
+EXPORTS_OPTIONS   = $(EXPORTS_LIST)
+APINAMES_OPTIONS := -dfreetype.dll -w
 
 # include Win32-specific definitions
 include $(TOP_DIR)/builds/win32/win32-def.mk
--- a/builds/win32/w32-icc.mk
+++ b/builds/win32/w32-icc.mk
@@ -12,6 +12,11 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
+# default definitions of the export list
+#
+EXPORTS_LIST      = $(OBJ_DIR)/freetype.def
+EXPORTS_OPTIONS   = /DEF:$(EXPORTS_LIST)
+APINAMES_OPTIONS := -dfreetype.dll -w
 
 include $(TOP_DIR)/builds/win32/win32-def.mk
 include $(TOP_DIR)/builds/compiler/visualage.mk
--- a/builds/win32/w32-intl.mk
+++ b/builds/win32/w32-intl.mk
@@ -12,6 +12,11 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
+# default definitions of the export list
+#
+EXPORTS_LIST      = $(OBJ_DIR)/freetype.def
+EXPORTS_OPTIONS   = /DEF:$(EXPORTS_LIST)
+APINAMES_OPTIONS := -dfreetype.dll -w
 
 include $(TOP_DIR)/builds/win32/win32-def.mk
 include $(TOP_DIR)/builds/compiler/intelc.mk
--- a/builds/win32/w32-mingw32.mk
+++ b/builds/win32/w32-mingw32.mk
@@ -12,6 +12,11 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
+# default definitions of the export list
+#
+EXPORTS_LIST      = $(OBJ_DIR)/freetype.def
+EXPORTS_OPTIONS   = $(EXPORTS_LIST)
+APINAMES_OPTIONS := -dfreetype.dll -w
 
 # include Win32-specific definitions
 include $(TOP_DIR)/builds/win32/win32-def.mk
--- a/builds/win32/w32-vcc.mk
+++ b/builds/win32/w32-vcc.mk
@@ -12,6 +12,11 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
+# definitions of the export list
+#
+EXPORTS_LIST      = $(OBJ_DIR)/freetype.def
+EXPORTS_OPTIONS   = /DEF:$(EXPORTS_LIST)
+APINAMES_OPTIONS := -dfreetype.dll -w
 
 include $(TOP_DIR)/builds/win32/win32-def.mk
 include $(TOP_DIR)/builds/compiler/visualc.mk
--- a/builds/win32/w32-wat.mk
+++ b/builds/win32/w32-wat.mk
@@ -12,6 +12,11 @@
 # indicate that you have read the license and understand and accept it
 # fully.
 
+# redefine export symbol definitions
+#
+EXPORTS_LIST      = $(OBJ_DIR)/watcom-ftexports.lbc
+EXPORTS_OPTIONS   = -\"export @$(EXPORTS_LIST)\"-
+APINAMES_OPTIONS := -wW
 
 include $(TOP_DIR)/builds/win32/win32-def.mk
 include $(TOP_DIR)/builds/compiler/watcom.mk
--- a/builds/win32/win32-def.mk
+++ b/builds/win32/win32-def.mk
@@ -18,6 +18,9 @@
 BUILD_DIR := $(TOP_DIR)/builds/win32
 PLATFORM  := win32
 
+# The executable file extension (for tools). NOTE: WE INCLUDE THE DOT HERE !!
+#
+E := .exe
 
 # The directory where all object files are placed.
 #
--- a/include/freetype/internal/ftgloadr.h
+++ b/include/freetype/internal/ftgloadr.h
@@ -59,7 +59,7 @@
     FT_Int     arg1;
     FT_Int     arg2;
     FT_Matrix  transform;
-    
+
   } FT_SubGlyphRec;
 
 
@@ -116,6 +116,22 @@
   FT_GlyphLoader_CheckPoints( FT_GlyphLoader  loader,
                               FT_UInt         n_points,
                               FT_UInt         n_contours );
+
+#define  FT_GLYPHLOADER_CHECK_P(_loader,_count)                         \
+   ( (_count) == 0 || (int)((_loader)->base.outline.n_points    +       \
+                            (_loader)->current.outline.n_points +       \
+                            (_count)) <= (int)(_loader)->max_points )
+
+#define  FT_GLYPHLOADER_CHECK_C(_loader,_count)                           \
+  ( (_count) == 0 || (int)((_loader)->base.outline.n_contours         +   \
+                           (_loader)->current.outline.n_contours      +   \
+                           (_count)) <= (int)(_loader)->max_contours )
+
+#define  FT_GLYPHLOADER_CHECK_POINTS(_loader,_points,_contours)       \
+  ( ( FT_GLYPHLOADER_CHECK_P(_loader,_points)   &&                    \
+      FT_GLYPHLOADER_CHECK_C(_loader,_contours) )                     \
+    ? 0                                                               \
+    : FT_GlyphLoader_CheckPoints( (_loader), (_points), (_contours) ) )
 
   /* check that there is enough space to add `n_subs' sub-glyphs to */
   /* a glyph loader                                                 */
--- a/src/autofit/afhints.c
+++ b/src/autofit/afhints.c
@@ -265,11 +265,55 @@
 #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 )
   {
+#if 1
+    AF_Direction  dir = AF_DIR_NONE;
+
+    if ( dx < 0 )
+    {
+      if ( dy < 0 )
+      {
+        if ( -dx*12 < -dy )
+          dir = AF_DIR_DOWN;
+
+        else if ( -dy*12 < -dx )
+          dir = AF_DIR_LEFT;
+      }
+      else /* dy >= 0 */
+      {
+        if ( -dx*12 < dy )
+          dir = AF_DIR_UP;
+
+        else if ( dy*12 < -dx )
+          dir = AF_DIR_LEFT;
+      }
+    }
+    else /* dx >= 0 */
+    {
+      if ( dy < 0 )
+      {
+        if ( dx*12 < -dy )
+          dir = AF_DIR_DOWN;
+
+        else if ( -dy*12 < dx )
+          dir = AF_DIR_RIGHT;
+      }
+      else  /* dy >= 0 */
+      {
+        if ( dx*12 < dy )
+          dir = AF_DIR_UP;
+
+        else if ( dy*12 < dx )
+          dir = AF_DIR_RIGHT;
+      }
+    }
+    return  dir;
+#else
     AF_Direction  dir;
     FT_Pos        ax = FT_ABS( dx );
     FT_Pos        ay = FT_ABS( dy );
@@ -291,6 +335,7 @@
     }
 
     return dir;
+#endif
   }
 
 
@@ -350,8 +395,9 @@
       } while ( angle_in == angle_seg );
 
       first   = start;
-      diff_in = af_angle_diff( angle_in, angle_seg );
 
+      AF_ANGLE_DIFF( diff_in, angle_in, angle_seg );
+
       /* now, process all segments in the contour */
       do
       {
@@ -373,7 +419,7 @@
 
         } while ( angle_out == angle_seg );
 
-        diff_out = af_angle_diff( angle_seg, angle_out );
+        AF_ANGLE_DIFF( diff_out, angle_seg, angle_out );
 
         if ( ( diff_in ^ diff_out ) < 0 )
         {
@@ -657,7 +703,8 @@
 
             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 );
+
+            AF_ANGLE_DIFF( delta, angle_in, angle_out );
 
             if ( delta < 2 && delta > -2 )
               goto Is_Weak_Point;
--- a/src/autofit/afloader.c
+++ b/src/autofit/afloader.c
@@ -138,9 +138,9 @@
 
       /* 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 + 4,
-                                          slot->outline.n_contours );
+      error = FT_GLYPHLOADER_CHECK_POINTS( gloader,
+                                           slot->outline.n_points + 4,
+                                           slot->outline.n_contours );
       if ( error )
         goto Exit;
 
--- a/src/autofit/aftypes.h
+++ b/src/autofit/aftypes.h
@@ -133,6 +133,20 @@
   af_angle_diff( AF_Angle  angle1,
                  AF_Angle  angle2 );
 
+#define  AF_ANGLE_DIFF(result,angle1,angle2)  \
+  FT_BEGIN_STMNT                              \
+    AF_Angle  _delta = (angle2) - (angle1);   \
+                                              \
+                                              \
+    _delta %= AF_ANGLE_2PI;                   \
+    if ( _delta < 0 )                         \
+      _delta += AF_ANGLE_2PI;                 \
+                                              \
+    if ( _delta > AF_ANGLE_PI )               \
+      _delta -= AF_ANGLE_2PI;                 \
+                                              \
+    result = _delta;                          \
+  FT_END_STMNT
 
   /*************************************************************************/
   /*************************************************************************/
--- a/src/base/ftcalc.c
+++ b/src/base/ftcalc.c
@@ -394,6 +394,38 @@
   FT_MulFix( FT_Long  a,
              FT_Long  b )
   {
+#if 1
+    FT_Long   sa, sb;
+    FT_ULong  ua, ub;
+
+
+    if ( a == 0 || b == 0x10000L )
+      return a;
+
+    sa = (a >> (sizeof(a)*8 - 1)); a = (a^sa) - sa;
+    sb = (b >> (sizeof(b)*8 - 1)); b = (b^sb) - sb;
+
+    ua = (FT_ULong)a;
+    ub = (FT_ULong)b;
+
+    if ( ua <= 2048 && ub <= 1048576L )
+    {
+      ua = ( ua * ub + 0x8000 ) >> 16;
+    }
+    else
+    {
+      FT_ULong  al = ua & 0xFFFF;
+
+
+      ua = ( ua >> 16 ) * ub +  al * ( ub >> 16 ) +
+           ( ( al * ( ub & 0xFFFF ) + 0x8000 ) >> 16 );
+    }
+
+    sa ^= sb,
+    ua  = (FT_ULong)((ua ^ sa) - sa);
+
+    return (FT_Long)ua;
+#else
     FT_Long   s;
     FT_ULong  ua, ub;
 
@@ -421,6 +453,7 @@
     }
 
     return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua );
+#endif
   }
 
 
--- a/src/base/ftgloadr.c
+++ b/src/base/ftgloadr.c
@@ -195,7 +195,7 @@
     FT_Error     error   = FT_Err_Ok;
     FT_Outline*  base    = &loader->base.outline;
     FT_Outline*  current = &loader->current.outline;
-    FT_Bool      adjust  = 1;
+    FT_Bool      adjust  = 0;
 
     FT_UInt      new_max, old_max;
 
--- a/src/base/fttrigon.c
+++ b/src/base/fttrigon.c
@@ -109,6 +109,46 @@
     z     = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
     shift = 0;
 
+#if 1
+    /* determine msb bit index in 'shift' */
+    if ( z >= (1L << 16 ) )
+    {
+      z     >>= 16;
+      shift  += 16;
+    }
+    if ( z >= (1L << 8) )
+    {
+      z     >>= 8;
+      shift  += 8;
+    }
+    if ( z >= (1L << 4) )
+    {
+      z     >>= 4;
+      shift  += 4;
+    }
+    if ( z >= (1L << 2) )
+    {
+      z     >>= 2;
+      shift  += 2;
+    }
+    if ( z >= 1 )
+      shift += 1;
+
+    if ( shift < 28 )
+    {
+      shift  = 28-shift;
+
+      vec->x = x << shift;
+      vec->y = y << shift;
+    }
+    else if ( shift > 28 )
+    {
+      shift -= 28;
+      vec->x = x >> shift;
+      vec->y = y >> shift;
+      shift  = -shift;
+    }
+#else
     if ( z < ( 1L << 27 ) )
     {
       do
@@ -116,7 +156,6 @@
         shift++;
         z <<= 1;
       } while ( z < ( 1L << 27 ) );
-
       vec->x = x << shift;
       vec->y = y << shift;
     }
@@ -132,6 +171,7 @@
       vec->y = y >> shift;
       shift  = -shift;
     }
+#endif
     return shift;
   }
 
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -403,7 +403,7 @@
   check_points( CFF_Builder*  builder,
                 FT_Int        count )
   {
-    return FT_GlyphLoader_CheckPoints( builder->loader, count, 0 );
+    return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
   }
 
 
@@ -465,7 +465,7 @@
       return CFF_Err_Ok;
     }
 
-    error = FT_GlyphLoader_CheckPoints( builder->loader, 0, 1 );
+    error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
     if ( !error )
     {
       if ( outline->n_contours > 0 )
--- a/src/pfr/pfrgload.c
+++ b/src/pfr/pfrgload.c
@@ -133,7 +133,7 @@
     /* check that we have begun a new path */
     FT_ASSERT( glyph->path_begun != 0 );
 
-    error = FT_GlyphLoader_CheckPoints( loader, 1, 0 );
+    error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 0 );
     if ( !error )
     {
       FT_UInt  n = outline->n_points;
@@ -163,7 +163,7 @@
     /* check that we have begun a new path */
     FT_ASSERT( glyph->path_begun != 0 );
 
-    error = FT_GlyphLoader_CheckPoints( loader, 3, 0 );
+    error = FT_GLYPHLOADER_CHECK_POINTS( loader, 3, 0 );
     if ( !error )
     {
       FT_Vector*  vec = outline->points         + outline->n_points;
@@ -199,7 +199,7 @@
     glyph->path_begun = 1;
 
     /* check that there is space for a new contour and a new point */
-    error = FT_GlyphLoader_CheckPoints( loader, 1, 1 );
+    error = FT_GLYPHLOADER_CHECK_POINTS( loader, 1, 1 );
     if ( !error )
       /* add new start point */
       error = pfr_glyph_line_to( glyph, to );
--- a/src/pfr/pfrload.c
+++ b/src/pfr/pfrload.c
@@ -609,149 +609,7 @@
   }
 
 
-#ifndef FT_OPTIMIZE_MEMORY
 
-  /*
-   *  The kerning data embedded in a PFR font are (charcode,charcode)
-   *  pairs; we need to translate them to (gindex,gindex) and sort
-   *  the resulting array.
-   */
-  static FT_UInt
-  pfr_get_gindex( PFR_Char  chars,
-                  FT_UInt   count,
-                  FT_UInt   charcode )
-  {
-    FT_UInt  min = 0;
-    FT_UInt  max = count;
-
-
-    while ( min < max )
-    {
-      FT_UInt   mid = ( min + max ) >> 1;
-      PFR_Char  c   = chars + mid;
-
-
-      if ( c->char_code == charcode )
-        return mid + 1;
-
-      if ( c->char_code < charcode )
-        min = mid + 1;
-      else
-        max = mid;
-    }
-    return 0;
-  }
-
-
-  FT_CALLBACK_DEF( int )
-  pfr_compare_kern_pairs( const void*  pair1,
-                          const void*  pair2 )
-  {
-    FT_UInt32  p1 = PFR_KERN_PAIR_INDEX( (PFR_KernPair)pair1 );
-    FT_UInt32  p2 = PFR_KERN_PAIR_INDEX( (PFR_KernPair)pair2 );
-
-
-    if ( p1 < p2 )
-      return -1;
-    if ( p1 > p2 )
-      return 1;
-    return 0;
-  }
-
-
-  static FT_Error
-  pfr_sort_kerning_pairs( FT_Stream    stream,
-                          PFR_PhyFont  phy_font )
-  {
-    FT_Error      error;
-    FT_Memory     memory = stream->memory;
-    PFR_KernPair  pairs;
-    PFR_KernItem  item;
-    PFR_Char      chars     = phy_font->chars;
-    FT_UInt       num_chars = phy_font->num_chars;
-    FT_UInt       count;
-
-
-    /* create kerning pairs array */
-    if ( FT_NEW_ARRAY( phy_font->kern_pairs, phy_font->num_kern_pairs ) )
-      goto Exit;
-
-    /*
-     *  load all kerning items into the array,
-     *  converting character codes into glyph indices
-     */
-    pairs = phy_font->kern_pairs;
-    item  = phy_font->kern_items;
-    count = 0;
-
-    for ( ; item; item = item->next )
-    {
-      FT_UInt   limit = count + item->pair_count;
-      FT_Byte*  p;
-
-
-      if ( limit > phy_font->num_kern_pairs )
-      {
-        error = PFR_Err_Invalid_Table;
-        goto Exit;
-      }
-
-      if ( FT_STREAM_SEEK( item->offset )                       ||
-           FT_FRAME_ENTER( item->pair_count * item->pair_size ) )
-        goto Exit;
-
-      p = stream->cursor;
-
-      for ( ; count < limit; count++ )
-      {
-        PFR_KernPair  pair = pairs + count;
-        FT_UInt       char1, char2;
-        FT_Int        kerning;
-
-
-        if ( item->flags & PFR_KERN_2BYTE_CHAR )
-        {
-          char1 = FT_NEXT_USHORT( p );
-          char2 = FT_NEXT_USHORT( p );
-        }
-        else
-        {
-          char1 = FT_NEXT_BYTE( p );
-          char2 = FT_NEXT_BYTE( p );
-        }
-
-        if ( item->flags & PFR_KERN_2BYTE_ADJ )
-          kerning = item->base_adj + FT_NEXT_SHORT( p );
-        else
-          kerning = item->base_adj + FT_NEXT_BYTE( p );
-
-        pair->glyph1  = pfr_get_gindex( chars, num_chars, char1 );
-        pair->glyph2  = pfr_get_gindex( chars, num_chars, char2 );
-        pair->kerning = kerning;
-      }
-
-      FT_FRAME_EXIT();
-    }
-
-    /* sort the resulting array */
-    ft_qsort( pairs, count,
-              sizeof ( PFR_KernPairRec ),
-              pfr_compare_kern_pairs );
-
-  Exit:
-    if ( error )
-    {
-     /* disable kerning data in case of error
-      */
-      phy_font->num_kern_pairs = 0;
-    }
-
-    return error;
-  }
-
-#endif /* !FT_OPTIMIZE_MEMORY */
-
-
   static const PFR_ExtraItemRec  pfr_phy_font_extra_items[] =
   {
     { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info },
@@ -829,10 +687,6 @@
     FT_FREE( phy_font->blue_values );
     phy_font->num_blue_values = 0;
 
-#ifndef FT_OPTIMIZE_MEMORY
-    FT_FREE( phy_font->kern_pairs );
-#endif
-
     {
       PFR_KernItem  item, next;
 
@@ -1070,11 +924,6 @@
     /* save position of bitmap info */
     phy_font->bct_offset = FT_STREAM_POS();
     phy_font->cursor     = NULL;
-
-#ifndef FT_OPTIMIZE_MEMORY
-    /* now sort kerning pairs */
-    error = pfr_sort_kerning_pairs( stream, phy_font );
-#endif
 
   Exit:
     return error;
--- a/src/pfr/pfrobjs.c
+++ b/src/pfr/pfrobjs.c
@@ -422,8 +422,6 @@
   /*************************************************************************/
   /*************************************************************************/
 
-#ifdef FT_OPTIMIZE_MEMORY
-
   FT_LOCAL_DEF( FT_Error )
   pfr_face_get_kerning( FT_Face     pfrface,        /* PFR_Face */
                         FT_UInt     glyph1,
@@ -545,52 +543,5 @@
   Exit:
     return error;
   }
-
-#else /* !FT_OPTIMIZE_MEMORY */
-
-  FT_LOCAL_DEF( FT_Error )
-  pfr_face_get_kerning( FT_Face     pfrface,        /* PFR_Face */
-                        FT_UInt     glyph1,
-                        FT_UInt     glyph2,
-                        FT_Vector*  kerning )
-  {
-    PFR_Face      face     = (PFR_Face)pfrface;
-    FT_Error      error    = PFR_Err_Ok;
-    PFR_PhyFont   phy_font = &face->phy_font;
-    PFR_KernPair  pairs    = phy_font->kern_pairs;
-    FT_UInt32     idx      = PFR_KERN_INDEX( glyph1, glyph2 );
-    FT_UInt       min, max;
-
-
-    kerning->x = 0;
-    kerning->y = 0;
-
-    min = 0;
-    max = phy_font->num_kern_pairs;
-
-    while ( min < max )
-    {
-      FT_UInt       mid  = ( min + max ) >> 1;
-      PFR_KernPair  pair = pairs + mid;
-      FT_UInt32     pidx = PFR_KERN_PAIR_INDEX( pair );
-
-
-      if ( pidx == idx )
-      {
-        kerning->x = pair->kerning;
-        break;
-      }
-
-      if ( pidx < idx )
-        min = mid + 1;
-      else
-        max = mid;
-    }
-
-    return error;
-  }
-
-#endif /* !FT_OPTIMIZE_MEMORY */
-
 
 /* END */
--- a/src/pfr/pfrtypes.h
+++ b/src/pfr/pfrtypes.h
@@ -217,14 +217,6 @@
                                ( (FT_UInt32)p[-2] << 16 ) | p[-1] )
 
 
-  typedef struct  PFR_KernPairRec_
-  {
-    FT_UInt    glyph1;
-    FT_UInt    glyph2;
-    FT_Int     kerning;
-
-  } PFR_KernPairRec, *PFR_KernPair;
-
   /************************************************************************/
 
   typedef struct  PFR_PhyFontRec_
@@ -266,9 +258,6 @@
     FT_UInt            num_kern_pairs;
     PFR_KernItem       kern_items;
     PFR_KernItem*      kern_items_tail;
-#ifndef FT_OPTIMIZE_MEMORY
-    PFR_KernPair       kern_pairs;
-#endif
 
     /* not part of the spec, but used during load */
     FT_UInt32          bct_offset;
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -1623,7 +1623,7 @@
   t1_builder_check_points( T1_Builder  builder,
                            FT_Int      count )
   {
-    return FT_GlyphLoader_CheckPoints( builder->loader, count, 0 );
+    return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
   }
 
 
@@ -1689,7 +1689,7 @@
       return PSaux_Err_Ok;
     }
 
-    error = FT_GlyphLoader_CheckPoints( builder->loader, 0, 1 );
+    error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
     if ( !error )
     {
       if ( outline->n_contours > 0 )
--- a/src/tools/apinames.c
+++ b/src/tools/apinames.c
@@ -1,323 +1,441 @@
-/*
- * This little program is used to parse the FreeType headers and
- * find the declaration of all public API.  This is easy, because
- * they all look like the following:
- *
- *   FT_EXPORT( return_type )
- *   function_name( function arguments );
- *
- * You must pass the list of header files as arguments.  Wildcards are
- * accepted if you are using GCC for compilation (and probably by
- * other compilers too).
- *
- * Author: David Turner, 2005
- *
- * This code is explicitly placed into the public domain.
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#define  PROGRAM_NAME     "apinames"
-#define  PROGRAM_VERSION  "0.1"
-
-#define  LINEBUFF_SIZE  1024
-
-static void
-panic( const char*  message )
-{
-  fprintf( stderr, "PANIC: %s\n", message );
-  exit(2);
-}
-
-
-typedef struct
-{
-  char*         name;
-  unsigned int  hash;
-
-} NameRec, *Name;
-
-static Name  the_names;
-static int   num_names;
-static int   max_names;
-
-static void
-names_add( const char*  name,
-           const char*  end )
-{
-  int   nn, len, h;
-  Name  nm;
-
-  if ( end <= name )
-    return;
-
-  /* compute hash value */
-  len = (int)(end - name);
-  h   = 0;
-  for ( nn = 0; nn < len; nn++ )
-    h = h*33 + name[nn];
-
-  /* check for an pre-existing name */
-  for ( nn = 0; nn < num_names; nn++ )
-  {
-    nm = the_names + nn;
-
-    if ( nm->hash                      == h &&
-         memcmp( name, nm->name, len ) == 0 &&
-         nm->name[len]                 == 0 )
-      return;
-  }
-
-  /* add new name */
-  if ( num_names >= max_names )
-  {
-    max_names += (max_names >> 1) + 4;
-    the_names  = realloc( the_names, sizeof(the_names[0])*max_names );
-    if ( the_names == NULL )
-      panic( "not enough memory" );
-  }
-  nm = &the_names[num_names++];
-
-  nm->hash = h;
-  nm->name = malloc( len+1 );
-  if ( nm->name == NULL )
-    panic( "not enough memory" );
-
-  memcpy( nm->name, name, len );
-  nm->name[len] = 0;
-}
-
-
-static int
-name_compare( const void*  name1,
-              const void*  name2 )
-{
-  Name  n1 = (Name)name1;
-  Name  n2 = (Name)name2;
-
-  return strcmp( n1->name, n2->name );
-}
-
-static void
-names_sort( void )
-{
-  qsort( the_names, (size_t)num_names, sizeof(the_names[0]), name_compare );
-}
-
-static void
-names_dump( FILE*  out )
-{
-  int  nn;
-
-  for ( nn = 0; nn < num_names; nn++ )
-    fprintf( out, "%s\n", the_names[nn].name );
-}
-
-
-static void
-names_dump_windef( FILE*  out )
-{
-  int  nn;
-
- /* note that we assume that __cdecl was used when compiling the
-  * DLL object files.
-  */
-  fprintf( out, "DESCRIPTION  FreeType 2 DLL\n" );
-  fprintf( out, "EXPORTS\n" );
-  for ( nn = 0; nn < num_names; nn++ )
-    fprintf( out, "  %s\n", the_names[nn].name );
-}
-
-
-/* states of the line parser */
-
-typedef enum
-{
-  STATE_START = 0,  /* waiting for FT_EXPORT keyword and return type */
-  STATE_TYPE,       /* type was read, waiting for function name      */
-
-} State;
-
-static int
-read_header_file( FILE*  file, int  verbose )
-{
-  static char  buff[ LINEBUFF_SIZE+1 ];
-  State        state = STATE_START;
-
-  while ( !feof( file ) )
-  {
-    char*  p;
-
-    if ( !fgets( buff, LINEBUFF_SIZE, file ) )
-      break;
-
-    p = buff;
-
-    while ( *p && (*p == ' ' || *p == '\\') )  /* skip leading whitespace */
-      p++;
-
-    if ( *p == '\n' || *p == '\r' )  /* skip empty lines */
-      continue;
-
-    switch ( state )
-    {
-      case STATE_START:
-        {
-          if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 )
-            break;
-
-          p += 10;
-          for (;;)
-          {
-            if ( *p == 0 || *p == '\n' || *p == '\r' )
-              goto NextLine;
-
-            if ( *p == ')' )
-            {
-              p++;
-              break;
-            }
-
-            p++;
-          }
-
-          state = STATE_TYPE;
-
-         /* sometimes, the name is just after the FT_EXPORT(...), so
-          * skip whitespace, and fall-through if we find an alphanumeric
-          * character
-          */
-          while ( *p == ' ' || *p == '\t' )
-            p++;
-
-          if ( !isalpha(*p) )
-            break;
-        }
-        /* fall-through */
-
-      case STATE_TYPE:
-        {
-          char*   name = p;
-          size_t  func_len;
-
-          while ( isalpha(*p) || *p == '_' )
-            p++;
-
-          if ( p > name )
-          {
-            if ( verbose )
-              fprintf( stderr, ">>> %.*s\n", p-name, name );
-
-            names_add( name, p );
-          }
-
-          state = STATE_START;
-        }
-        break;
-
-      default:
-        ;
-    }
-
-  NextLine:
-    ;
-  }
-
-  return 0;
-}
-
-
-static void
-usage( void )
-{
-  fprintf( stderr,
-           "%s %s: extract FreeType API names from header files\n\n"
-           "this program is used to extract the list of public FreeType API\n"
-           "functions. It receives the list of header files as argument and\n"
-           "generates a sorted list of unique identifiers\n\n"
-
-           "usage: %s header1 [options] [header2 ...]\n\n"
-
-           "options:   -  : parse the content of stdin, ignore arguments\n"
-           "           -v : verbose mode\n",
-           "           -w : output windows .DEF file\n"
-           ,
-           PROGRAM_NAME,
-           PROGRAM_VERSION,
-           PROGRAM_NAME
-           );
-  exit(1);
-}
-
-
-int  main( int argc, const char* const*  argv )
-{
-  int  from_stdin = 0;
-  int  verbose = 0;
-  int  do_win_def = 0;
-
-  if ( argc < 2 )
-    usage();
-
-  /* '-' used as a single argument means read source file from stdin */
-  while ( argc > 1 && argv[1][0] == '-' )
-  {
-    switch ( argv[1][1] )
-    {
-      case 'v':
-        verbose = 1;
-        break;
-
-      case 'w':
-        do_win_def = 1;
-        break;
-
-      case 0:
-        from_stdin = 1;
-        break;
-
-      default:
-        usage();
-    }
-
-    argc--;
-    argv++;
-  }
-
-  if ( from_stdin )
-  {
-    read_header_file( stdin, verbose );
-  }
-  else
-  {
-    for ( --argc, argv++; argc > 0; argc--, argv++ )
-    {
-      FILE*  file = fopen( argv[0], "rb" );
-
-      if ( file == NULL )
-        fprintf( stderr, "unable to open '%s'\n", argv[0] );
-      else
-      {
-        if ( verbose )
-          fprintf( stderr, "opening '%s'\n", argv[0] );
-
-        read_header_file( file, verbose );
-        fclose( file );
-      }
-    }
-  }
-
-  if ( num_names == 0 )
-    panic( "could not find exported functions !!\n" );
-
-  names_sort();
-
-  if ( do_win_def )
-    names_dump_windef( stdout );
-  else
-    names_dump( stdout );
-
-  return 0;
-}
+/*
+ * This little program is used to parse the FreeType headers and
+ * find the declaration of all public API.  This is easy, because
+ * they all look like the following:
+ *
+ *   FT_EXPORT( return_type )
+ *   function_name( function arguments );
+ *
+ * You must pass the list of header files as arguments.  Wildcards are
+ * accepted if you are using GCC for compilation (and probably by
+ * other compilers too).
+ *
+ * Author: David Turner, 2005
+ *
+ * This code is explicitly placed into the public domain.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define  PROGRAM_NAME     "apinames"
+#define  PROGRAM_VERSION  "0.1"
+
+#define  LINEBUFF_SIZE  1024
+
+typedef enum
+{
+  OUTPUT_LIST = 0,      /* output the list of names, one per line             */
+  OUTPUT_WINDOWS_DEF,   /* output a Windows .DEF file for Visual C++ or Mingw */
+  OUTPUT_BORLAND_DEF,   /* output a Windows .DEF file for Borland C++         */
+  OUTPUT_WATCOM_LBC     /* output a Watcom Linker Command File                */
+
+} OutputFormat;
+
+
+static void
+panic( const char*  message )
+{
+  fprintf( stderr, "PANIC: %s\n", message );
+  exit(2);
+}
+
+
+typedef struct
+{
+  char*         name;
+  unsigned int  hash;
+
+} NameRec, *Name;
+
+static Name  the_names;
+static int   num_names;
+static int   max_names;
+
+static void
+names_add( const char*  name,
+           const char*  end )
+{
+  int   nn, len, h;
+  Name  nm;
+
+  if ( end <= name )
+    return;
+
+  /* compute hash value */
+  len = (int)(end - name);
+  h   = 0;
+  for ( nn = 0; nn < len; nn++ )
+    h = h*33 + name[nn];
+
+  /* check for an pre-existing name */
+  for ( nn = 0; nn < num_names; nn++ )
+  {
+    nm = the_names + nn;
+
+    if ( nm->hash                      == h &&
+         memcmp( name, nm->name, len ) == 0 &&
+         nm->name[len]                 == 0 )
+      return;
+  }
+
+  /* add new name */
+  if ( num_names >= max_names )
+  {
+    max_names += (max_names >> 1) + 4;
+    the_names  = realloc( the_names, sizeof(the_names[0])*max_names );
+    if ( the_names == NULL )
+      panic( "not enough memory" );
+  }
+  nm = &the_names[num_names++];
+
+  nm->hash = h;
+  nm->name = malloc( len+1 );
+  if ( nm->name == NULL )
+    panic( "not enough memory" );
+
+  memcpy( nm->name, name, len );
+  nm->name[len] = 0;
+}
+
+
+static int
+name_compare( const void*  name1,
+              const void*  name2 )
+{
+  Name  n1 = (Name)name1;
+  Name  n2 = (Name)name2;
+
+  return strcmp( n1->name, n2->name );
+}
+
+static void
+names_sort( void )
+{
+  qsort( the_names, (size_t)num_names, sizeof(the_names[0]), name_compare );
+}
+
+
+static void
+names_dump( FILE*         out,
+            OutputFormat  format,
+            const char*   dll_name )
+{
+  int  nn;
+
+  switch ( format )
+  {
+    case OUTPUT_WINDOWS_DEF:
+      if ( dll_name )
+        fprintf( out, "LIBRARY %s\n", dll_name );
+
+      fprintf( out, "DESCRIPTION  FreeType 2 DLL\n" );
+      fprintf( out, "EXPORTS\n" );
+      for ( nn = 0; nn < num_names; nn++ )
+        fprintf( out, "  %s\n", the_names[nn].name );
+      break;
+
+    case OUTPUT_BORLAND_DEF:
+      if ( dll_name )
+        fprintf( out, "LIBRARY %s\n", dll_name );
+
+      fprintf( out, "DESCRIPTION  FreeType 2 DLL\n" );
+      fprintf( out, "EXPORTS\n" );
+      for ( nn = 0; nn < num_names; nn++ )
+        fprintf( out, "  _%s\n", the_names[nn].name );
+      break;
+
+    case OUTPUT_WATCOM_LBC:
+      {
+        /* we must omit the .dll suffix from the library name */
+        char   temp[512];
+        char*  dot;
+
+        if ( dll_name == NULL )
+        {
+          fprintf( stderr,
+                   "you must provide a DLL name with the -d option !!\n" );
+          exit(4);
+        }
+
+        dot = strchr( dll_name, '.' );
+        if ( dot != NULL )
+        {
+          int  len = (dot - dll_name);
+          if ( len > sizeof(temp)-1 )
+            len = sizeof(temp)-1;
+
+          memcpy( temp, dll_name, len );
+          temp[len] = 0;
+
+          dll_name = (const char*)temp;
+        }
+
+        for ( nn = 0; nn < num_names; nn++ )
+          fprintf( out, "++_%s.%s.%s\n", the_names[nn].name, dll_name,
+                        the_names[nn].name );
+      }
+      break;
+
+    default:  /* LIST */
+      for ( nn = 0; nn < num_names; nn++ )
+        fprintf( out, "%s\n", the_names[nn].name );
+  }
+}
+
+
+
+
+/* states of the line parser */
+
+typedef enum
+{
+  STATE_START = 0,  /* waiting for FT_EXPORT keyword and return type */
+  STATE_TYPE,       /* type was read, waiting for function name      */
+
+} State;
+
+static int
+read_header_file( FILE*  file, int  verbose )
+{
+  static char  buff[ LINEBUFF_SIZE+1 ];
+  State        state = STATE_START;
+
+  while ( !feof( file ) )
+  {
+    char*  p;
+
+    if ( !fgets( buff, LINEBUFF_SIZE, file ) )
+      break;
+
+    p = buff;
+
+    while ( *p && (*p == ' ' || *p == '\\') )  /* skip leading whitespace */
+      p++;
+
+    if ( *p == '\n' || *p == '\r' )  /* skip empty lines */
+      continue;
+
+    switch ( state )
+    {
+      case STATE_START:
+        {
+          if ( memcmp( p, "FT_EXPORT(", 10 ) != 0 )
+            break;
+
+          p += 10;
+          for (;;)
+          {
+            if ( *p == 0 || *p == '\n' || *p == '\r' )
+              goto NextLine;
+
+            if ( *p == ')' )
+            {
+              p++;
+              break;
+            }
+
+            p++;
+          }
+
+          state = STATE_TYPE;
+
+         /* sometimes, the name is just after the FT_EXPORT(...), so
+          * skip whitespace, and fall-through if we find an alphanumeric
+          * character
+          */
+          while ( *p == ' ' || *p == '\t' )
+            p++;
+
+          if ( !isalpha(*p) )
+            break;
+        }
+        /* fall-through */
+
+      case STATE_TYPE:
+        {
+          char*   name = p;
+          size_t  func_len;
+
+          while ( isalnum(*p) || *p == '_' )
+            p++;
+
+          if ( p > name )
+          {
+            if ( verbose )
+              fprintf( stderr, ">>> %.*s\n", p-name, name );
+
+            names_add( name, p );
+          }
+
+          state = STATE_START;
+        }
+        break;
+
+      default:
+        ;
+    }
+
+  NextLine:
+    ;
+  }
+
+  return 0;
+}
+
+
+static void
+usage( void )
+{
+  fprintf( stderr,
+           "%s %s: extract FreeType API names from header files\n\n"
+           "this program is used to extract the list of public FreeType API\n"
+           "functions. It receives the list of header files as argument and\n"
+           "generates a sorted list of unique identifiers\n\n"
+
+           "usage: %s header1 [options] [header2 ...]\n\n"
+
+           "options:   -      : parse the content of stdin, ignore arguments\n"
+           "           -v     : verbose mode, output sent to standard error\n",
+           "           -oFILE : write output to FILE instead of standard output\n"
+           "           -dNAME : indicate DLL file name, 'freetype.dll' by default\n"
+           "           -w     : output .DEF file for Visual C++ and Mingw\n"
+           "           -wB    : output .DEF file for Borland C++\n"
+           "           -wW    : output Watcom Linker Response File\n"
+           "\n"
+           ,
+           PROGRAM_NAME,
+           PROGRAM_VERSION,
+           PROGRAM_NAME
+           );
+  exit(1);
+}
+
+
+int  main( int argc, const char* const*  argv )
+{
+  int           from_stdin = 0;
+  int           verbose = 0;
+  OutputFormat  format = OUTPUT_LIST;  /* the default */
+  FILE*         out    = stdout;
+  const char*   library_name = NULL;
+
+  if ( argc < 2 )
+    usage();
+
+  /* '-' used as a single argument means read source file from stdin */
+  while ( argc > 1 && argv[1][0] == '-' )
+  {
+    const char*  arg = argv[1];
+
+    switch ( arg[1] )
+    {
+      case 'v':
+        verbose = 1;
+        break;
+
+      case 'o':
+        if ( arg[2] == 0 )
+        {
+          if ( argc < 2 )
+            usage();
+
+          arg = argv[2];
+          argv++;
+          argc--;
+        }
+        else
+          arg += 2;
+
+        out = fopen( arg, "wt" );
+        if ( out == NULL )
+        {
+          fprintf( stderr, "could not open '%s' for writing\n", argv[2] );
+          exit(3);
+        }
+        break;
+
+      case 'd':
+        if ( arg[2] == 0 )
+        {
+          if ( argc < 2 )
+            usage();
+
+          arg = argv[2];
+          argv++;
+          argc--;
+        }
+        else
+          arg += 2;
+
+        library_name = arg;
+        break;
+
+      case 'w':
+        format = OUTPUT_WINDOWS_DEF;
+        switch ( arg[2] )
+        {
+          case 'B':
+            format = OUTPUT_BORLAND_DEF;
+            break;
+
+          case 'W':
+            format = OUTPUT_WATCOM_LBC;
+            break;
+
+          case 0:
+            break;
+
+          default:
+            usage();
+        }
+        break;
+
+      case 0:
+        from_stdin = 1;
+        break;
+
+      default:
+        usage();
+    }
+
+    argc--;
+    argv++;
+  }
+
+  if ( from_stdin )
+  {
+    read_header_file( stdin, verbose );
+  }
+  else
+  {
+    for ( --argc, argv++; argc > 0; argc--, argv++ )
+    {
+      FILE*  file = fopen( argv[0], "rb" );
+
+      if ( file == NULL )
+        fprintf( stderr, "unable to open '%s'\n", argv[0] );
+      else
+      {
+        if ( verbose )
+          fprintf( stderr, "opening '%s'\n", argv[0] );
+
+        read_header_file( file, verbose );
+        fclose( file );
+      }
+    }
+  }
+
+  if ( num_names == 0 )
+    panic( "could not find exported functions !!\n" );
+
+  names_sort();
+  names_dump( out, format, library_name );
+
+  if ( out != stdout )
+    fclose( out );
+
+  return 0;
+}
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -420,7 +420,7 @@
 
 
     /* check that we can add the contours to the glyph */
-    error = FT_GlyphLoader_CheckPoints( gloader, 0, n_contours );
+    error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours );
     if ( error )
       goto Fail;
 
@@ -441,7 +441,7 @@
       n_points = cont[-1] + 1;
 
     /* note that we will add four phantom points later */
-    error = FT_GlyphLoader_CheckPoints( gloader, n_points + 4, 0 );
+    error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );
     if ( error )
       goto Fail;
 
@@ -1106,9 +1106,9 @@
     outline = &loader->gloader->base.outline;
 
     /* make room for phantom points */
-    error = FT_GlyphLoader_CheckPoints( loader->gloader,
-                                        outline->n_points + 4,
-                                        0 );
+    error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
+                                         outline->n_points + 4,
+                                         0 );
     if ( error )
       return error;