shithub: freetype+ttf2subf

Download patch

ref: 561f0f568f969514ada751be1db7201aa6d32ac0
parent: e8ebfe988b5f57bfb9a3ecb13c70d9791bce9ecf
author: grobe0ba <grobe0ba@tcp80.org>
date: Wed Nov 23 13:46:31 EST 2022

ttf2subf

git/fs: mount .git/fs: mount/attach disallowed
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
+*.[05678qv]
+[05678qv].*
+*.o
+o.*
 /build/
 /config.mk
 include/dlg/
binary files /dev/null b/font differ
--- a/include/freetype/config/ftmodule.h
+++ b/include/freetype/config/ftmodule.h
@@ -1,21 +1,8 @@
-/*
- * This file registers the FreeType modules compiled into the library.
- *
- * If you use GNU make, this file IS NOT USED!  Instead, it is created in
- * the objects directory (normally `<topdir>/objs/`) based on information
- * from `<topdir>/modules.cfg`.
- *
- * Please read `docs/INSTALL.ANY` and `docs/CUSTOMIZE` how to compile
- * FreeType without GNU make.
- *
- */
-
 FT_USE_MODULE( FT_Module_Class, autofit_module_class )
 FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
 FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )
 FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
 FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )
 FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
 FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
 FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
@@ -26,8 +13,5 @@
 FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
 FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
 FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_sdf_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_bitmap_sdf_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_svg_renderer_class )
 
 /* EOF */
--- a/include/freetype/config/ftoption.h
+++ b/include/freetype/config/ftoption.h
@@ -180,7 +180,7 @@
    *
    *   Define this macro if you want to enable this 'feature'.
    */
-#define FT_CONFIG_OPTION_USE_LZW
+/* #define FT_CONFIG_OPTION_USE_LZW */
 
 
   /**************************************************************************
@@ -195,7 +195,7 @@
    *   Define this macro if you want to enable this 'feature'.  See also the
    *   macro `FT_CONFIG_OPTION_SYSTEM_ZLIB` below.
    */
-#define FT_CONFIG_OPTION_USE_ZLIB
+/* #define FT_CONFIG_OPTION_USE_ZLIB */
 
 
   /**************************************************************************
@@ -414,24 +414,22 @@
 #define FT_MAX_MODULES  32
 
 
-  /**************************************************************************
-   *
-   * Debug level
-   *
-   *   FreeType can be compiled in debug or trace mode.  In debug mode,
-   *   errors are reported through the 'ftdebug' component.  In trace mode,
-   *   additional messages are sent to the standard output during execution.
-   *
-   *   Define `FT_DEBUG_LEVEL_ERROR` to build the library in debug mode.
-   *   Define `FT_DEBUG_LEVEL_TRACE` to build it in trace mode.
-   *
-   *   Don't define any of these macros to compile in 'release' mode!
-   *
-   *   Do not `#undef` these macros here since the build system might define
-   *   them for certain configurations only.
-   */
-/* #define FT_DEBUG_LEVEL_ERROR */
-/* #define FT_DEBUG_LEVEL_TRACE */
+  /*************************************************************************/
+  /*                                                                       */
+  /* Debug level                                                           */
+  /*                                                                       */
+  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
+  /*   errors are reported through the `ftdebug' component.  In trace      */
+  /*   mode, additional messages are sent to the standard output during    */
+  /*   execution.                                                          */
+  /*                                                                       */
+  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
+  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
+  /*                                                                       */
+  /*   Don't define any of these macros to compile in `release' mode!      */
+  /*                                                                       */
+/* #define  FT_DEBUG_LEVEL_ERROR */
+/* #define  FT_DEBUG_LEVEL_TRACE */
 
 
   /**************************************************************************
@@ -551,7 +549,7 @@
    *
    *   More details can be found in the file `fterrors.h`.
    */
-/* #define FT_CONFIG_OPTION_ERROR_STRINGS */
+#define FT_CONFIG_OPTION_ERROR_STRINGS
 
 
   /*************************************************************************/
--- a/include/freetype/config/ftstdlib.h
+++ b/include/freetype/config/ftstdlib.h
@@ -32,8 +32,6 @@
 #define FTSTDLIB_H_
 
 
-#include <stddef.h>
-
 #define ft_ptrdiff_t  ptrdiff_t
 
 
@@ -56,17 +54,20 @@
    *
    */
 
+#include <u.h>
+#include <libc.h>
 
-#include <limits.h>
+#include <ape/limits.h>
+ 
+#define FT_UINT_MAX   0xFFFFFFFFUL
+#define FT_ULONG_MAX  0xFFFFFFFFUL
 
 #define FT_CHAR_BIT    CHAR_BIT
 #define FT_USHORT_MAX  USHRT_MAX
 #define FT_INT_MAX     INT_MAX
 #define FT_INT_MIN     INT_MIN
-#define FT_UINT_MAX    UINT_MAX
 #define FT_LONG_MIN    LONG_MIN
 #define FT_LONG_MAX    LONG_MAX
-#define FT_ULONG_MAX   ULONG_MAX
 #ifdef LLONG_MAX
 #define FT_LLONG_MAX   LLONG_MAX
 #endif
@@ -77,7 +78,6 @@
 #define FT_ULLONG_MAX  ULLONG_MAX
 #endif
 
-
   /**************************************************************************
    *
    *                character and string processing
@@ -85,9 +85,15 @@
    */
 
 
-#include <string.h>
-
 #define ft_memchr   memchr
+#define ft_strlen   strlen
+#define ft_strcmp   strcmp
+#define ft_strncmp  strncmp
+#define ft_memcpy   memcpy
+#define ft_strcpy   strcpy
+#define ft_strncpy  strncpy
+#define ft_memset   memset
+#define ft_memmove  memmove
 #define ft_memcmp   memcmp
 #define ft_memcpy   memcpy
 #define ft_memmove  memmove
@@ -126,9 +132,6 @@
    *
    */
 
-
-#include <stdlib.h>
-
 #define ft_qsort  qsort
 
 
@@ -163,7 +166,6 @@
    */
 
 
-#include <setjmp.h>
 
 #define ft_jmp_buf     jmp_buf  /* note: this cannot be a typedef since  */
                                 /*       `jmp_buf` is defined as a macro */
@@ -176,7 +178,6 @@
   /* The following is only used for debugging purposes, i.e., if   */
   /* `FT_DEBUG_LEVEL_ERROR` or `FT_DEBUG_LEVEL_TRACE` are defined. */
 
-#include <stdarg.h>
 
 
 #endif /* FTSTDLIB_H_ */
--- a/include/freetype/config/integer-types.h
+++ b/include/freetype/config/integer-types.h
@@ -29,15 +29,17 @@
 #define FT_CHAR_BIT  CHAR_BIT
 #endif
 
+#define size_t  unsigned long
+
 #ifndef FT_SIZEOF_INT
 
   /* The size of an `int` type. */
 #if                                 FT_UINT_MAX == 0xFFFFUL
-#define FT_SIZEOF_INT  ( 16 / FT_CHAR_BIT )
+#define FT_SIZEOF_INT  ( 16 / 8 )
 #elif                               FT_UINT_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_INT  ( 32 / FT_CHAR_BIT )
+#define FT_SIZEOF_INT  ( 32 / 8 )
 #elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_INT  ( 64 / FT_CHAR_BIT )
+#define FT_SIZEOF_INT  ( 64 / 8 )
 #else
 #error "Unsupported size of `int' type!"
 #endif
@@ -49,11 +51,11 @@
   /* The size of a `long` type.  A five-byte `long` (as used e.g. on the */
   /* DM642) is recognized but avoided.                                   */
 #if                                  FT_ULONG_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_LONG  ( 32 / FT_CHAR_BIT )
+#define FT_SIZEOF_LONG  ( 32 / 8 )
 #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  ( 32 / FT_CHAR_BIT )
+#define FT_SIZEOF_LONG  ( 32 / 8 )
 #elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  ( 64 / FT_CHAR_BIT )
+#define FT_SIZEOF_LONG  ( 64 / 8 )
 #else
 #error "Unsupported size of `long' type!"
 #endif
@@ -64,7 +66,7 @@
 
   /* The size of a `long long` type if available */
 #if defined( FT_ULLONG_MAX ) && FT_ULLONG_MAX >= 0xFFFFFFFFFFFFFFFFULL
-#define FT_SIZEOF_LONG_LONG  ( 64 / FT_CHAR_BIT )
+#define FT_SIZEOF_LONG_LONG  ( 64 / 8 )
 #else
 #define FT_SIZEOF_LONG_LONG  0
 #endif
@@ -157,12 +159,12 @@
 
 #endif
 
-#if FT_SIZEOF_INT == ( 32 / FT_CHAR_BIT )
+#if FT_SIZEOF_INT == ( 32 / 8 )
 
   typedef signed int      FT_Int32;
   typedef unsigned int    FT_UInt32;
 
-#elif FT_SIZEOF_LONG == ( 32 / FT_CHAR_BIT )
+#elif FT_SIZEOF_LONG == ( 32 / 8 )
 
   typedef signed long     FT_Int32;
   typedef unsigned long   FT_UInt32;
@@ -173,12 +175,12 @@
 
 
   /* look up an integer type that is at least 32~bits */
-#if FT_SIZEOF_INT >= ( 32 / FT_CHAR_BIT )
+#if FT_SIZEOF_INT >= ( 32 / 8 )
 
   typedef int            FT_Fast;
   typedef unsigned int   FT_UFast;
 
-#elif FT_SIZEOF_LONG >= ( 32 / FT_CHAR_BIT )
+#elif FT_SIZEOF_LONG >= ( 32 / 8 )
 
   typedef long           FT_Fast;
   typedef unsigned long  FT_UFast;
@@ -187,12 +189,12 @@
 
 
   /* determine whether we have a 64-bit integer type */
-#if FT_SIZEOF_LONG == ( 64 / FT_CHAR_BIT )
+#if FT_SIZEOF_LONG == ( 64 / 8 )
 
 #define FT_INT64   long
 #define FT_UINT64  unsigned long
 
-#elif FT_SIZEOF_LONG_LONG >= ( 64 / FT_CHAR_BIT )
+#elif FT_SIZEOF_LONG_LONG >= ( 64 / 8 )
 
 #define FT_INT64   long long int
 #define FT_UINT64  unsigned long long int
@@ -239,7 +241,7 @@
 
 #endif /* !__STDC__ */
 
-#endif /* FT_SIZEOF_LONG == (64 / FT_CHAR_BIT) */
+#endif /* FT_SIZEOF_LONG == (64 / 8) */
 
 #ifdef FT_INT64
   typedef FT_INT64   FT_Int64;
--- a/include/freetype/fttypes.h
+++ b/include/freetype/fttypes.h
@@ -25,9 +25,9 @@
 #include <freetype/ftsystem.h>
 #include <freetype/ftimage.h>
 
-#include <stddef.h>
 
 
+
 FT_BEGIN_HEADER
 
 
@@ -310,30 +310,30 @@
   typedef void*  FT_Pointer;
 
 
-  /**************************************************************************
-   *
-   * @type:
-   *   FT_Offset
-   *
-   * @description:
-   *   This is equivalent to the ANSI~C `size_t` type, i.e., the largest
-   *   _unsigned_ integer type used to express a file size or position, or a
-   *   memory block size.
-   */
-  typedef size_t  FT_Offset;
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_Offset                                                          */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This is equivalent to the ANSI C `size_t' type, i.e. the largest   */
+  /*    _unsigned_ integer type used to express a file size or position,   */
+  /*    or a memory block size.                                            */
+  /*                                                                       */
+  typedef int  FT_Offset;
 
 
-  /**************************************************************************
-   *
-   * @type:
-   *   FT_PtrDist
-   *
-   * @description:
-   *   This is equivalent to the ANSI~C `ptrdiff_t` type, i.e., the largest
-   *   _signed_ integer type used to express the distance between two
-   *   pointers.
-   */
-  typedef ft_ptrdiff_t  FT_PtrDist;
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Type>                                                                */
+  /*    FT_PtrDist                                                         */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This is equivalent to the ANSI C `ptrdiff_t' type, i.e. the        */
+  /*    largest _signed_ integer type used to express the distance         */
+  /*    between two pointers.                                              */
+  /*                                                                       */
+  typedef int  FT_PtrDist;
 
 
   /**************************************************************************
@@ -593,9 +593,9 @@
 #define FT_ERR_XCAT( x, y )  x ## y
 #define FT_ERR_CAT( x, y )   FT_ERR_XCAT( x, y )
 
-  /* see `ftmoderr.h` for descriptions of the following macros */
+#define FT_ERR FT_THROW
 
-#define FT_ERR( e )  FT_ERR_CAT( FT_ERR_PREFIX, e )
+  /* see `ftmoderr.h` for descriptions of the following macros */
 
 #define FT_ERROR_BASE( x )    ( (x) & 0xFF )
 #define FT_ERROR_MODULE( x )  ( (x) & 0xFF00U )
--- a/include/freetype/internal/ftdebug.h
+++ b/include/freetype/internal/ftdebug.h
@@ -331,6 +331,7 @@
 #endif /* !FT_DEBUG_LEVEL_ERROR */
 
 
+
   /**************************************************************************
    *
    * Define `FT_Message` and `FT_Panic` when needed.
@@ -339,7 +340,8 @@
 
 #ifdef FT_DEBUG_LEVEL_ERROR
 
-#include "stdio.h"  /* for vfprintf() */
+#include "stdio.h"
+  /* for vfprintf() */
 
   /* print a message */
   FT_BASE( void )
--- /dev/null
+++ b/install
@@ -1,0 +1,2 @@
+#! /bin/sh
+make install
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,144 @@
+</$objtype/mkfile
+
+CFLAGS=-p -Iinclude -w -DFT2_BUILD_LIBRARY
+LIB=libfreetype.a
+
+TARG=ttf2subf
+BIN=/$objtype/bin
+MANPAGE=freetype
+
+OFILES=\
+	src/autofit/afblue.$O \
+	src/autofit/afcjk.$O \
+	src/autofit/afdummy.$O \
+	src/autofit/afglobal.$O \
+	src/autofit/afhints.$O \
+	src/autofit/afindic.$O \
+	src/autofit/aflatin.$O \
+	src/autofit/afloader.$O \
+	src/autofit/afmodule.$O \
+	src/autofit/afranges.$O \
+	src/autofit/autofit.$O \
+	src/base/ftadvanc.$O \
+	src/base/ftbbox.$O \
+	src/base/ftbdf.$O \
+	src/base/ftbitmap.$O \
+	src/base/ftcalc.$O \
+	src/base/ftdbgmem.$O \
+	src/base/ftdebug.$O \
+	src/base/fterrors.$O \
+	src/base/ftfntfmt.$O \
+	src/base/ftgloadr.$O \
+	src/base/ftglyph.$O \
+	src/base/fthash.$O \
+	src/base/ftinit.$O \
+	src/base/ftlcdfil.$O \
+	src/base/ftmm.$O \
+	src/base/ftobjs.$O \
+	src/base/ftoutln.$O \
+	src/base/ftpfr.$O \
+	src/base/ftpsprop.$O \
+	src/base/ftrfork.$O \
+	src/base/ftstream.$O \
+	src/base/ftsystem.$O \
+	src/base/fttrigon.$O \
+	src/base/fttype1.$O \
+	src/base/ftutil.$O \
+	src/base/ftwinfnt.$O \
+	src/bdf/bdfdrivr.$O \
+	src/bdf/bdflib.$O \
+	src/cache/ftccache.$O \
+	src/cache/ftccmap.$O \
+	src/cache/ftcglyph.$O \
+	src/cache/ftcimage.$O \
+	src/cache/ftcmanag.$O \
+	src/cache/ftcsbits.$O \
+	src/cff/cffcmap.$O \
+	src/cff/cffdrivr.$O \
+	src/cff/cffgload.$O \
+	src/cff/cffload.$O \
+	src/cff/cffobjs.$O \
+	src/cff/cffparse.$O \
+	src/cid/cidgload.$O \
+	src/cid/cidload.$O \
+	src/cid/cidobjs.$O \
+	src/cid/cidparse.$O \
+	src/cid/cidriver.$O \
+	src/pcf/pcf.$O \
+	src/pcf/pcfdrivr.$O \
+	src/pcf/pcfread.$O \
+	src/pcf/pcfutil.$O \
+	src/psaux/afmparse.$O \
+	src/psaux/cffdecode.$O \
+	src/psaux/psarrst.$O \
+	src/psaux/psaux.$O \
+	src/psaux/psblues.$O \
+	src/psaux/psconv.$O \
+	src/psaux/pserror.$O \
+	src/psaux/psfont.$O \
+	src/psaux/psft.$O \
+	src/psaux/pshints.$O \
+	src/psaux/psintrp.$O \
+	src/psaux/psobjs.$O \
+	src/psaux/psread.$O \
+	src/psaux/psstack.$O \
+	src/psaux/t1cmap.$O \
+	src/psaux/t1decode.$O \
+	src/pshinter/pshalgo.$O \
+	src/pshinter/pshglob.$O \
+	src/pshinter/pshmod.$O \
+	src/pshinter/pshrec.$O \
+	src/psnames/psmodule.$O \
+	src/raster/ftraster.$O \
+	src/raster/ftrend1.$O \
+	src/sfnt/sfdriver.$O \
+	src/sfnt/sfobjs.$O \
+	src/sfnt/sfwoff.$O \
+	src/sfnt/ttbdf.$O \
+	src/sfnt/ttcmap.$O \
+	src/sfnt/ttcolr.$O \
+	src/sfnt/ttcpal.$O \
+	src/sfnt/ttkern.$O \
+	src/sfnt/ttload.$O \
+	src/sfnt/ttmtx.$O \
+	src/sfnt/ttpost.$O \
+	src/sfnt/ttsbit.$O \
+	src/sfnt/ttsvg.$O \
+	src/smooth/ftgrays.$O \
+	src/smooth/ftsmooth.$O \
+	src/truetype/ttdriver.$O \
+	src/truetype/ttgload.$O \
+	src/truetype/ttgxvar.$O \
+	src/truetype/ttinterp.$O \
+	src/truetype/ttobjs.$O \
+	src/truetype/ttpload.$O \
+	src/type1/t1afm.$O \
+	src/type1/t1driver.$O \
+	src/type1/t1gload.$O \
+	src/type1/t1load.$O \
+	src/type1/t1objs.$O \
+	src/type1/t1parse.$O \
+	src/type42/t42drivr.$O \
+	src/type42/t42objs.$O \
+	src/type42/t42parse.$O \
+	src/winfonts/winfnt.$O \
+
+
+%.$O: %.c
+	$CC -o $stem.$O -c $CFLAGS $stem.c
+
+all:V: $LIB $TARG
+
+$LIB:	$OFILES
+	ar vu $LIB $newprereq
+#	cp $LIB /$objtype/lib
+
+$TARG:	$LIB ttf2subf.$O
+	$LD -o $TARG ttf2subf.$O libfreetype.a
+
+install:	$TARG
+	cp $TARG $BIN/$TARG
+	cp ttf2subf.1 /sys/man/1/ttf2subf
+
+clean:
+	rm -f $LIB $OFILES $TARG main.$O
--- /dev/null
+++ b/mkfile.orig
@@ -1,0 +1,113 @@
+</$objtype/mkfile
+
+CFLAGS=-p -Iinclude
+LIB=libfreetype.a
+
+OFILES=\
+	src/winfonts/winfnt.$O \
+	src/type42/t42objs.$O \
+	src/type42/t42parse.$O \
+	src/type42/t42drivr.$O \
+	src/type1/t1parse.$O \
+	src/type1/t1load.$O \
+	src/type1/t1driver.$O \
+	src/type1/t1afm.$O \
+	src/type1/t1gload.$O \
+	src/type1/t1objs.$O \
+	src/truetype/ttobjs.$O \
+	src/truetype/ttpload.$O \
+	src/truetype/ttgload.$O \
+	src/truetype/ttinterp.$O \
+	src/truetype/ttdriver.$O \
+	src/smooth/ftgrays.$O \
+	src/smooth/ftsmooth.$O \
+	src/sfnt/ttload.$O \
+	src/sfnt/ttcmap.$O \
+	src/sfnt/ttcmap0.$O \
+	src/sfnt/ttsbit.$O \
+	src/sfnt/ttpost.$O \
+	src/sfnt/sfobjs.$O \
+	src/sfnt/sfdriver.$O \
+	src/raster/ftraster.$O \
+	src/raster/ftrend1.$O \
+	src/psnames/psmodule.$O \
+	src/pshinter/pshrec.$O \
+	src/pshinter/pshglob.$O \
+	src/pshinter/pshmod.$O \
+	src/pshinter/pshalgo1.$O \
+	src/pshinter/pshalgo2.$O \
+	src/pshinter/pshalgo3.$O \
+	src/psaux/psobjs.$O \
+	src/psaux/t1decode.$O \
+	src/psaux/t1cmap.$O \
+	src/psaux/psauxmod.$O \
+	src/pfr/pfrload.$O \
+	src/pfr/pfrgload.$O \
+	src/pfr/pfrcmap.$O \
+	src/pfr/pfrdrivr.$O \
+	src/pfr/pfrobjs.$O \
+	src/pcf/pcfread.$O \
+	src/pcf/pcfdriver.$O \
+	src/pcf/pcfutil.$O \
+	src/cid/cidparse.$O \
+	src/cid/cidload.$O  \
+	src/cid/cidriver.$O \
+	src/cid/cidgload.$O \
+	src/cid/cidobjs.$O \
+	src/cff/cffobjs.$O \
+	src/cff/cffload.$O \
+	src/cff/cffgload.$O \
+	src/cff/cffparse.$O \
+	src/cff/cffcmap.$O \
+	src/cff/cffdrivr.$O \
+	src/cache/ftlru.$O \
+	src/cache/ftcmanag.$O \
+	src/cache/ftccache.$O \
+	src/cache/ftcglyph.$O \
+	src/cache/ftcsbits.$O \
+	src/cache/ftcimage.$O \
+	src/cache/ftccmap.$O \
+	src/bdf/bdfdrivr.$O \
+	src/base/ftcalc.$O \
+	src/base/fttrigon.$O \
+	src/base/ftutil.$O \
+	src/base/ftstream.$O \
+	src/base/ftgloadr.$O \
+	src/base/ftoutln.$O \
+	src/base/ftobjs.$O \
+	src/base/ftapi.$O \
+	src/base/ftnames.$O \
+	src/base/ftdbgmem.$O \
+	src/base/ftglyph.$O \
+	src/base/ftmm.$O \
+	src/base/ftbdf.$O \
+	src/base/fttype1.$O \
+	src/base/ftxf86.$O \
+	src/base/ftpfr.$O \
+	src/base/ftstroker.$O \
+	src/base/ftwinfnt.$O \
+	src/base/ftbbox.$O \
+	src/base/ftsystem.$O \
+	src/base/ftinit.$O \
+	src/base/ftdebug.$O \
+	src/autohint/ahangles.$O \
+	src/autohint/ahglobal.$O \
+	src/autohint/ahglyph.$O \
+	src/autohint/ahhint.$O \
+	src/autohint/ahmodule.$O \
+
+
+
+%.$O: %.c
+	$CC -o $stem.$O -c $CFLAGS $stem.c
+
+all:V: $LIB
+
+$LIB:V:	$OFILES
+	ar vu $LIB $newprereq
+
+test:	$LIB main.$O
+	$LD -o test main.$O -lfreetype
+
+clean:
+	rm -f $LIB $OFILES test
--- a/src/base/ftdebug.c
+++ b/src/base/ftdebug.c
@@ -121,7 +121,7 @@
     vfprintf( stderr, fmt, ap );
     va_end( ap );
 
-    exit( EXIT_FAILURE );
+    exits("failure");
   }
 
 
--- a/src/base/ftsystem.c
+++ b/src/base/ftsystem.c
@@ -34,6 +34,7 @@
 #include <freetype/fttypes.h>
 
 
+
   /**************************************************************************
    *
    *                      MEMORY MANAGEMENT INTERFACE
--- a/src/bdf/bdflib.c
+++ b/src/bdf/bdflib.c
@@ -523,7 +523,7 @@
     _bdf_line_func_t  cb;
     unsigned long     lineno, buf_size;
     int               refill, hold, to_skip;
-    ptrdiff_t         bytes, start, end, cursor, avail;
+    unsigned long         bytes, start, end, cursor, avail;
     char*             buf    = NULL;
     FT_Memory         memory = stream->memory;
     FT_Error          error  = FT_Err_Ok;
@@ -555,7 +555,7 @@
     {
       if ( refill )
       {
-        bytes  = (ptrdiff_t)FT_Stream_TryRead(
+        bytes  = (unsigned long)FT_Stream_TryRead(
                    stream, (FT_Byte*)buf + cursor,
                    buf_size - (unsigned long)cursor );
         avail  = cursor + bytes;
--- a/src/gzip/adler32.c
+++ b/src/gzip/adler32.c
@@ -3,7 +3,7 @@
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
-/* @(#) $Id$ */
+/* @(#) $Id: adler32.c,v 1.4 2003/01/30 23:24:18 davidT Exp $ */
 
 #include "zutil.h"
 
--- a/src/gzip/ftgzip.c
+++ b/src/gzip/ftgzip.c
@@ -37,7 +37,6 @@
 
 #include <freetype/fterrors.h>
 
-
 #ifdef FT_CONFIG_OPTION_USE_ZLIB
 
 #ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB
--- /dev/null
+++ b/src/gzip/zconf.h
@@ -1,0 +1,278 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id: zconf.h,v 1.3 2002/12/26 20:50:40 davidT Exp $ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_	z_deflateInit_
+#  define deflate	z_deflate
+#  define deflateEnd	z_deflateEnd
+#  define inflateInit_ 	z_inflateInit_
+#  define inflate	z_inflate
+#  define inflateEnd	z_inflateEnd
+#  define deflateInit2_	z_deflateInit2_
+#  define deflateSetDictionary z_deflateSetDictionary
+#  define deflateCopy	z_deflateCopy
+#  define deflateReset	z_deflateReset
+#  define deflateParams	z_deflateParams
+#  define inflateInit2_	z_inflateInit2_
+#  define inflateSetDictionary z_inflateSetDictionary
+#  define inflateSync	z_inflateSync
+#  define inflateSyncPoint z_inflateSyncPoint
+#  define inflateReset	z_inflateReset
+#  define compress	z_compress
+#  define compress2	z_compress2
+#  define uncompress	z_uncompress
+#  define adler32	z_adler32
+#  define crc32		z_crc32
+#  define get_crc_table z_get_crc_table
+
+#  define Byte		z_Byte
+#  define uInt		z_uInt
+#  define uLong		z_uLong
+#  define Bytef	        z_Bytef
+#  define charf		z_charf
+#  define intf		z_intf
+#  define uIntf		z_uIntf
+#  define uLongf	z_uLongf
+#  define voidpf	z_voidpf
+#  define voidp		z_voidp
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+#  ifndef __32BIT__
+#    define __32BIT__
+#  endif
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(MSDOS) && !defined(__32BIT__)
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
+#  define STDC
+#endif
+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
+#  ifndef STDC
+#    define STDC
+#  endif
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Old Borland C and LCC incorrectly complains about missing returns: */
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
+#  define NEED_DUMMY_RETURN
+#endif
+
+#if defined(__LCC__)
+#  define  NEED_DUMMY_RETURN
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
+   /* MSC small or medium model */
+#  define SMALL_MEDIUM
+#  ifdef _MSC_VER
+#    define FAR _far
+#  else
+#    define FAR far
+#  endif
+#endif
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
+#  ifndef __32BIT__
+#    define SMALL_MEDIUM
+#    define FAR _far
+#  endif
+#endif
+
+/* Compile with -DZLIB_DLL for Windows DLL support */
+#if defined(ZLIB_DLL)
+#  if defined(_WINDOWS) || defined(WINDOWS)
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+#    define ZEXPORT(x)  x WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA(x)  x WINAPIV
+#    else
+#      define ZEXPORTVA(x)  x FAR _cdecl _export
+#    endif
+#  endif
+#  if defined (__BORLANDC__)
+#    if (__BORLANDC__ >= 0x0500) && defined (WIN32)
+#      include <windows.h>
+#      define ZEXPORT(x) x __declspec(dllexport) WINAPI
+#      define ZEXPORTRVA(x)  x __declspec(dllexport) WINAPIV
+#    else
+#      if defined (_Windows) && defined (__DLL__)
+#        define ZEXPORT(x) x _export
+#        define ZEXPORTVA(x) x _export
+#      endif
+#    endif
+#  endif
+#endif
+
+
+#ifndef ZEXPORT
+#  define ZEXPORT(x)   static x
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA(x)   static x
+#endif
+#ifndef ZEXTERN
+#  define ZEXTERN(x) static x
+#endif
+#ifndef ZEXTERNDEF
+#  define ZEXTERNDEF(x)  static x
+#endif
+
+#ifndef FAR
+#   define FAR
+#endif
+
+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void FAR *voidpf;
+   typedef void     *voidp;
+#else
+   typedef Byte FAR *voidpf;
+   typedef Byte     *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  define z_off_t  off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define  z_off_t long
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(inflate_blocks,"INBL")
+#   pragma map(inflate_blocks_new,"INBLNE")
+#   pragma map(inflate_blocks_free,"INBLFR")
+#   pragma map(inflate_blocks_reset,"INBLRE")
+#   pragma map(inflate_codes_free,"INCOFR")
+#   pragma map(inflate_codes,"INCO")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_flush,"INFLU")
+#   pragma map(inflate_mask,"INMA")
+#   pragma map(inflate_set_dictionary,"INSEDI2")
+#   pragma map(inflate_copyright,"INCOPY")
+#   pragma map(inflate_trees_bits,"INTRBI")
+#   pragma map(inflate_trees_dynamic,"INTRDY")
+#   pragma map(inflate_trees_fixed,"INTRFI")
+#   pragma map(inflate_trees_free,"INTRFR")
+#endif
+
+#endif /* _ZCONF_H */
--- a/src/gzip/zutil.c
+++ b/src/gzip/zutil.c
@@ -3,7 +3,7 @@
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
-/* @(#) $Id$ */
+/* @(#) $Id: zutil.c,v 1.2 2002/11/06 22:32:54 davidT Exp $ */
 
 #include "zutil.h"
 #ifndef Z_SOLO
--- a/src/gzip/zutil.h
+++ b/src/gzip/zutil.h
@@ -8,7 +8,7 @@
    subject to change. Applications should only use zlib.h.
  */
 
-/* @(#) $Id$ */
+/* @(#) $Id: zutil.h,v 1.3 2002/12/26 20:50:40 davidT Exp $ */
 
 #ifndef ZUTIL_H
 #define ZUTIL_H
--- /dev/null
+++ b/ttf2subf.1
@@ -1,0 +1,64 @@
+.TH TTF2SUBF 1
+.SH NAME
+ttf2subf \- convert glyphs in a TTF file to Subfont format
+.SH SYNOPSIS
+.B ttf2subf
+.B -f
+.I file
+.B -s
+.I size
+[
+.B -n
+name
+]
+[
+.B -m
+.I mode
+]
+[
+.B -r
+.I type
+]
+.SH DESCRIPTION
+.I Tt2subf
+parses a TTF (true type font) file to generate an internal structure describing each
+glyph for the given point size. Options
+.B -f
+and
+.B -s
+determine the file and point size to use. The font name is the file name or
+.I name
+when
+.B -n
+is given. The rendering mode can be specified with
+.B -m
+and is one of
+.B mono,
+.B antialias,
+and
+.B subpixel.
+THe LCD display type can be specified with
+.B -r
+and is one of
+.B rbg,
+.B bgr,
+.B vrgb,
+and
+.B vbgr.
+.SH EXAMPLE
+To generate the
+.B arialuni
+subfont with point size 14, using RGB and subpixel mode:
+
+.EX
+; ttf2subf -f arialuni.ttf -s 14 -n arialuni -m subpixel -r rgb
+; font=arialuni/arialuni.14.font
+.EE
+.SH SOURCE
+.B /sys/src/cmd/freetype-2.1.4
+.SH "SEE ALSO"
+.IR bdf2subf (1) subfont (2) cachechars (2)
+.IR font (6) utf (6)
+.SH BUGS
+Send bugs and fixes to
+.L devel@freetype.org
--- /dev/null
+++ b/ttf2subf.c
@@ -1,0 +1,637 @@
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_ERRORS_H
+#include <freetype/ftglyph.h>
+
+#include <draw.h>
+#include <memdraw.h>
+
+FT_Library lib;
+
+#define FLOOR(x) ((x) & -64)
+#define CEIL(x)	 (((x) + 63) & -64)
+#define TRUNC(x) ((x) >> 6)
+#define ROUND(x) (((x) + 32) & -64)
+
+enum {
+	Rmono = 1,
+	Rantialias,
+	Rsubpixel,
+};
+
+enum { Srgb = 1, Sbgr, Svrgb, Svbgr };
+
+typedef struct {
+	int left;
+	int right;
+	int top;
+	int bottom;
+	int advance;
+	int width;
+}FTmetrics;
+
+typedef struct _FTsubfont {
+	int nchars;
+	int startc;
+	int ascent;
+	int descent;
+	int image_height;
+	int image_width;
+	FTmetrics* metrics;
+	Fontchar* fchars;
+	Subfont sf;
+	Memimage* image;
+	struct _FTsubfont* next;
+	struct _FTsubfont* prev;
+}FTsubfont;
+
+typedef struct {
+	char* name;
+	int size;
+	FT_Face face;
+	FT_GlyphSlot slot;
+	int rmode;
+	int rgb;
+	int image_channels;
+	int ascent;
+	int descent;
+	int height;
+	FTsubfont* sfont;
+}FTfont;
+
+int f[3] = {1, 2, 3};
+int fsum = 9;
+
+FT_Vector
+getScale(FTfont* font)
+{
+	FT_Vector ret;
+
+	ret.x = ret.y = 1;
+	if(font->rmode == Rsubpixel){
+		switch(font->rgb){
+		case Srgb:
+		case Sbgr: ret.x = 3; break;
+
+		case Svrgb:
+		case Svbgr: ret.y = 3; break;
+		}
+	}
+
+	return ret;
+}
+
+FT_Glyph
+getGlyph(FTfont* font, int c)
+{
+	int status;
+	FT_Glyph glyph;
+	FT_UInt gidx;
+	FT_Int32 lflags;
+	FT_Vector scale;
+	FT_Vector pos;
+	FT_Matrix tm;
+
+	gidx = FT_Get_Char_Index(font->face, c);
+
+	switch(font->rmode){
+	case Rmono:
+	case Rsubpixel:
+	default: lflags = FT_LOAD_TARGET_MONO; break;
+
+	case Rantialias: lflags = FT_LOAD_DEFAULT; break;
+	}
+
+	if((status = FT_Load_Glyph(font->face, gidx, lflags)))
+		sysfatal("FT_Load_Glyph: %s\n", FT_Error_String(status));
+
+	if((status = FT_Get_Glyph(font->face->glyph, &glyph)))
+		sysfatal("FT_Get_Glyph: %s\n", FT_Error_String(status));
+
+	glyph->advance.x = font->slot->advance.x;
+	glyph->advance.y = font->slot->advance.y;
+
+	scale = getScale(font);
+	tm.xx = 0x10000 * scale.x;
+	tm.yy = 0x10000 * scale.y;
+	tm.xy = tm.yx = 0;
+	pos.x = pos.y = 0;
+
+	if((status = FT_Glyph_Transform(glyph, &tm, &pos)))
+		sysfatal("FT_Glyph_Transform: %s\n", FT_Error_String(status));
+
+	return glyph;
+}
+
+FT_BitmapGlyph
+getBitmapGlyph(FTfont* font, FT_Glyph glyph)
+{
+	int rmode = 0;
+	int status;
+
+	switch(font->rmode){
+	case Rmono: rmode = ft_render_mode_mono; break;
+
+	case Rantialias:
+	case Rsubpixel: rmode = ft_render_mode_normal; break;
+
+	default: sysfatal("error: rmode != antialias|mono|subpixel");
+	}
+
+	if((status = FT_Glyph_To_Bitmap(&glyph, rmode, 0, 1)))
+		sysfatal("FT_Glyph_To_Bitmap: %s\n", FT_Error_String(status));
+
+	return (FT_BitmapGlyph)glyph;
+}
+
+FTmetrics
+getMetrics(FTfont* font, int c)
+{
+	FT_Glyph glyph;
+	FT_BitmapGlyph bglyph;
+	FT_Bitmap bitmap;
+	FT_Vector scale;
+	FTmetrics ret;
+
+	glyph  = getGlyph(font, c);
+	bglyph = getBitmapGlyph(font, glyph);
+	scale  = getScale(font);
+	bitmap = bglyph->bitmap;
+
+	ret.left   = bglyph->left / scale.x;
+	ret.right  = (bglyph->left + bitmap.width) / scale.x;
+	ret.top	   = bglyph->top / scale.y;
+	ret.bottom = (bglyph->top - bitmap.rows) / scale.y;
+
+	ret.width   = bitmap.width / scale.x;
+	ret.advance = TRUNC(font->slot->advance.x); /* usage of slot ??? */
+
+	if(font->rmode == Rsubpixel){
+		switch(font->rgb){
+		case Srgb:
+		case Sbgr:
+			ret.left -= 1;
+			ret.right += 1;
+			ret.width += 2;
+
+			break;
+
+		case Svrgb:
+		case Svbgr:
+			ret.top -= 1;
+			ret.bottom -= 1;
+			break;
+		}
+	}
+
+	/*	FT_Done_Glyph(glyph); */
+
+	return ret;
+}
+
+unsigned long
+getPixelMono(FTfont*, FT_Bitmap* bitmap, int x, int y)
+{
+	int g = ((bitmap->buffer[bitmap->pitch * y + x / 8]) >> (7 - x % 8) & 1) * 255;
+	return (g << 24) | (g << 16) | (g << 8) | 0xFF;
+}
+
+unsigned long
+getPixelAntialias(FTfont*, FT_Bitmap* bitmap, int x, int y)
+{
+	int g = bitmap->buffer[bitmap->pitch * y + x];
+	return (g << 24) | (g << 16) | (g << 8) | 0xFF;
+}
+
+unsigned long
+getPixelSubpixel(FTfont* font, FT_Bitmap* bitmap, int x, int y)
+{
+	int xs = 0, ys = 0;
+	int af = 0, bf = 0, cf = 0;
+	int xx, yy;
+	int h[7];
+	int a, b, c;
+	FT_Vector scale;
+	int i;
+
+	scale = getScale(font);
+
+	switch(font->rgb){
+	case Srgb:
+	case Sbgr:
+		xs = 1;
+		ys = 0;
+		break;
+
+	case Svrgb:
+	case Svbgr:
+		xs = 0;
+		ys = 1;
+		break;
+	}
+
+	switch(font->rgb){
+	case Srgb:
+	case Svrgb:
+		af = 24;
+		bf = 16;
+		cf = 8;
+		break;
+
+	case Sbgr:
+	case Svbgr:
+		af = 8;
+		bf = 16;
+		cf = 24;
+		break;
+	}
+
+	xx = x * scale.x;
+	yy = y * scale.y;
+
+	for(i = -2; i < 5; i++){
+		int xc, yc;
+
+		xc = xx + (i - scale.x) * xs;
+		yc = yy + (i - scale.y) * ys;
+
+		if(xc < 0 || xc >= bitmap->width || yc < 0 || yc >= bitmap->rows){
+			h[i + 2] = 0;
+		}else{
+			h[i + 2] = bitmap->buffer[yc * bitmap->pitch + xc] * 65536;
+		}
+	}
+
+	a = (h[0] * f[0] + h[1] * f[1] + h[2] * f[2] + h[3] * f[1] + h[4] * f[0]) / fsum;
+	b = (h[1] * f[0] + h[2] * f[1] + h[3] * f[2] + h[4] * f[1] + h[5] * f[0]) / fsum;
+	c = (h[2] * f[0] + h[3] * f[1] + h[4] * f[2] + h[5] * f[1] + h[6] * f[0]) / fsum;
+
+	return ((a / 65536) << af) | ((b / 65536) << bf) | ((c / 65536) << cf) | 0xFF;
+}
+
+typedef unsigned long (*getpixelfunc)(FTfont*, FT_Bitmap*, int, int);
+
+getpixelfunc
+getPixelFunc(FTfont* font)
+{
+	getpixelfunc ret = 0;
+
+	switch(font->rmode){
+	case Rmono: ret = getPixelMono; break;
+
+	case Rantialias: ret = getPixelAntialias; break;
+
+	case Rsubpixel: ret = getPixelSubpixel; break;
+	}
+
+	return ret;
+}
+
+void
+drawChar(FTfont* font, Memimage* img, int x0, int y0, int c)
+{
+	Rectangle r;
+	Memimage* color;
+	FT_Glyph glyph;
+	FT_BitmapGlyph bglyph;
+	FT_Bitmap bitmap;
+	int x, y;
+	getpixelfunc getPixel;
+	FT_Vector scale;
+	int height, width;
+
+	glyph  = getGlyph(font, c);
+	scale  = getScale(font);
+	bglyph = getBitmapGlyph(font, glyph);
+	bitmap = bglyph->bitmap;
+
+	getPixel = getPixelFunc(font);
+
+	r.min.x = 0;
+	r.min.y = 0;
+	r.max.x = 1;
+	r.max.y = 1;
+	color	= allocmemimage(r, font->image_channels);
+
+	r.min.x = r.min.y = 0;
+	r.max.x		  = bitmap.width;
+	r.max.y		  = bitmap.rows;
+
+	width  = bitmap.width / scale.x;
+	height = bitmap.rows / scale.y;
+
+	if(font->rmode == Rsubpixel){
+		switch(font->rgb){
+		case Srgb:
+		case Sbgr: width += 2; break;
+
+		case Svrgb:
+		case Svbgr: height += 2; break;
+		}
+	}
+
+	for(y = 0; y < height; y++){
+		for(x = 0; x < width; x++){
+			Point pt;
+			unsigned long cl = getPixel(font, &bitmap, x, y);
+
+			pt.x = x + x0;
+			pt.y = y + y0;
+			memfillcolor(color, cl);
+			memimagedraw(img, rectaddpt(Rect(0, 0, 1, 1), pt), color, ZP, nil, ZP,
+				     SatopD);
+		}
+	}
+
+	freememimage(color);
+}
+
+void
+initSubfont(FTfont* font, FTsubfont* sf, int startc)
+{
+	int i;
+	int width;
+	int ascent, descent;
+	FTmetrics rc[257];
+
+	// get first defined character
+	while(startc < 65536){
+		if(startc == 0 || FT_Get_Char_Index(font->face, startc) != 0){
+			break;
+		}
+
+		startc++;
+	}
+
+	ascent	= 0;
+	descent = 100000;
+	width	= 0;
+	for(i = 0; i < sizeof(rc) / sizeof(rc[0]); i++){
+		if(startc + i >= 65536){
+			break;
+		}
+
+		if(width > 2000){
+			break;
+		}
+
+		if(i > 0 && FT_Get_Char_Index(font->face, startc + i) == 0){
+			rc[i]	      = getMetrics(font, 0);
+			rc[i].width   = 0;
+			rc[i].advance = 0;
+		}else
+			rc[i] = getMetrics(font, startc + i);
+
+		if(ascent < rc[i].top){
+			ascent = rc[i].top;
+		}
+
+		if(descent > rc[i].bottom){
+			descent = rc[i].bottom;
+		}
+
+		width += rc[i].width;  // +1?
+	}
+
+	sf->startc	= startc;
+	sf->nchars	= i;
+	sf->ascent	= ascent;
+	sf->descent	= descent;
+	sf->image_width = width;
+	sf->metrics	= malloc(i * sizeof(FTmetrics));
+	sf->fchars	= malloc((i + 1) * sizeof(Fontchar));
+
+	for(i = 0; i < sf->nchars; i++){ sf->metrics[i] = rc[i]; }
+}
+
+int
+createSubfont(FTfont* font, FTsubfont* sf, char* fname)
+{
+	int i;
+	Rectangle r;
+	int x;
+	int fd;
+
+	sf->image_height = sf->ascent - sf->descent;
+	/*	print("creating %d: (%d, %d)\n", sf->startc, sf->image_height, sf->image_width); */
+
+	r = Rect(0, 0, sf->image_width, font->height /*sf->image_height*/);
+	if(sf->image_width <= 0 || sf->image_height <= 0){
+		return 1;
+	}
+
+	sf->image = allocmemimage(r, font->image_channels);
+	memfillcolor(sf->image, 0x000000FF);
+
+	x = 0;
+	for(i = 0; i < sf->nchars; i++){
+		sf->fchars[i].x	     = x;
+		sf->fchars[i].width  = sf->metrics[i].advance;
+		sf->fchars[i].left   = sf->metrics[i].left;
+		sf->fchars[i].bottom = /*sf->ascent*/ font->ascent - sf->metrics[i].bottom;
+		sf->fchars[i].top =
+		    (font->ascent - sf->metrics[i].top) > 0 ? font->ascent - sf->metrics[i].top : 0;
+		x += sf->metrics[i].width;  // +1?
+
+		drawChar(font, sf->image, sf->fchars[i].x, sf->fchars[i].top, i + sf->startc);
+	}
+
+	sf->fchars[i].x = x;
+
+	sf->sf.name   = font->name;
+	sf->sf.n      = sf->nchars;
+	sf->sf.height = font->height; /*sf->image_height; */
+	sf->sf.ascent = font->ascent /*sf->ascent */;
+	sf->sf.info   = sf->fchars;
+	sf->sf.ref    = 1;
+
+	fd = create(fname, OWRITE, 0666);
+	if(fd < 0)
+		sysfatal("can not create font file: %r");
+
+	writememimage(fd, sf->image);
+	writesubfont(fd, &sf->sf);
+	close(fd);
+	freememimage(sf->image);
+	sf->image = nil;
+
+	return 0;
+}
+
+void
+usage(char* s)
+{
+	sysfatal(
+	    "usage: %s [-h] [-s size] [-f fname] [-n name] [-m 'rendering mode'] [-r 'display "
+	    "type']\n"
+	    "\t-s size                     - point size\n"
+	    "\t-h                          - this message\n"
+	    "\t-f fname                    - ttf file name\n"
+	    "\t-n name                     - font name\n"
+	    "\t-m mono|antialias|subpixel  - rendering mode\n"
+	    "\t-r rgb|bgr|vrgb|vbgr        - LCD display type\n",
+	    s);
+}
+
+void
+main(int argc, char* argv[])
+{
+	FTfont font;
+
+	int status;
+	int i;
+	FTsubfont* sf;
+	int fd;
+	char buf[256];
+
+	char* fname = nil;
+	char* mode  = nil;
+	char* srgb  = "rgb";
+
+	char* progname = argv[0];
+
+	font.name = nil;
+	font.size = 0;
+
+	if(argc == 1)
+		usage(progname);
+
+	ARGBEGIN
+	{
+	case 's': font.size = atoi(ARGF()); break;
+	case 'h': usage(progname); break; /* never reached */
+	case 'f': fname = ARGF(); break;
+	case 'n': font.name = ARGF(); break;
+
+	case 'm': mode = ARGF(); break;
+
+	case 'r': srgb = ARGF(); break;
+
+	default: sysfatal("bad flag: %c", ARGC());
+	}
+	ARGEND
+
+	if(fname == nil){
+		print("no font name specified\n");
+		exits("fname");
+	}
+
+	if(font.size == 0){
+		print("no font size specified\n");
+		exits("size");
+	}
+
+	if(mode != nil){
+		if(strcmp(mode, "mono") == 0){
+			font.rmode = Rmono;
+		}else if(strcmp(mode, "antialias") == 0){
+			font.rmode = Rantialias;
+		}else if(strcmp(mode, "subpixel") == 0){
+			font.rmode = Rsubpixel;
+		}
+	}else{
+		font.rmode = Rsubpixel;
+	}
+
+	switch(font.rmode){
+	case Rmono: font.image_channels = GREY1; break;
+
+	case Rantialias: font.image_channels = GREY8; break;
+
+	case Rsubpixel:
+		font.image_channels = RGB24;
+		if(strcmp(srgb, "rgb") == 0){
+			font.rgb = Srgb;
+		}else if(strcmp(srgb, "bgr") == 0){
+			font.rgb = Sbgr;
+		}else if(strcmp(srgb, "vrgb") == 0){
+			font.rgb = Svrgb;
+		}else if(strcmp(srgb, "vbgr") == 0){
+			font.rgb = Svbgr;
+		}else{
+			sysfatal("unknown subpixel mode: %s\n", srgb);
+		}
+		break;
+	}
+
+	if(font.name == nil){
+		font.name = fname;
+	}
+
+	print("font file: %s, font name: %s, size: %d\n", fname, font.name, font.size);
+	memimageinit();
+	if((status = FT_Init_FreeType(&lib)))
+		sysfatal("FT_Init_FreeType: %s\n", FT_Error_String(status));
+
+	if((status = FT_New_Face(lib, fname, 0, &font.face)))
+		sysfatal("FT_New_Face: %s\n", FT_Error_String(status));
+
+	if((status = FT_Set_Char_Size(font.face, 0, font.size * 64, 72, 72)))
+		sysfatal("FT_Set_Char_Size: %s\n", FT_Error_String(status));
+
+	FT_Select_Charmap(font.face, ft_encoding_unicode);
+
+	font.slot    = font.face->glyph;
+	font.sfont   = nil;
+	font.ascent  = 0;
+	font.descent = 10000;
+
+	i = 0;
+	while(i < 65536){
+		struct _FTsubfont* sf = malloc(sizeof(FTsubfont));
+
+		initSubfont(&font, sf, i);
+
+		if(sf->nchars == 0){
+			break;
+		}
+
+		print("last: %d, start: %d, nchars: %d, width: %d\n", i, sf->startc, sf->nchars,
+		      sf->image_width);
+
+		i	   = sf->startc + sf->nchars;
+		sf->next   = font.sfont;
+		font.sfont = sf;
+
+		if(font.ascent < sf->ascent){
+			font.ascent = sf->ascent;
+		}
+
+		if(font.descent > sf->descent){
+			font.descent = sf->descent;
+		}
+	}
+
+	/*	font.height = font.ascent - font.descent; */
+	font.height = font.size;
+	font.ascent = font.height - 3;
+
+	/* do we have a directory created for this font? */
+	snprint(buf, sizeof(buf), "%s", font.name);
+	if(access(buf, AEXIST) == -1){
+		fd = create(buf, OREAD, DMDIR | 0777);
+		if(fd < 0)
+			sysfatal("cannot create font directory: %r");
+	}
+
+	snprint(buf, sizeof(buf), "%s/%s.%d.font", font.name, font.name, font.size);
+	fd = create(buf, OWRITE, 0666);
+	if(fd < 0)
+		sysfatal("cannot create .font file: %r");
+
+	fprint(fd, "%d\t%d\n", font.height, font.ascent);
+
+	for(sf = font.sfont; sf != nil; sf = sf->next){
+		snprint(buf, sizeof(buf), "%s/%s.%d.%04x", font.name, font.name, font.size,
+			sf->startc);
+		//		printf("generating 0x%04x - 0x%04x\n", sf->startc, sf->startc +
+		// sf->nchars);
+
+		if(0 == createSubfont(&font, sf, buf)){
+			snprint(buf, sizeof(buf), "%s.%d.%04x", font.name, font.size, sf->startc);
+			fprint(fd, "0x%04x\t0x%04x\t%s\n", sf->startc, sf->startc + sf->nchars - 1,
+			       buf);
+		}
+	}
+	close(fd);
+}