shithub: freetype+ttf2subf

Download patch

ref: f28b7bfaea2264a9db7de97decca6568ecdf6b24
parent: 6b76663625fce26634e2d6c72e2a0da90f1616ac
author: Werner Lemberg <[email protected]>
date: Mon Jan 1 12:24:31 EST 2001

Initial revision

git/fs: mount .git/fs: mount/attach disallowed
--- /dev/null
+++ b/src/pcf/module.mk
@@ -1,0 +1,32 @@
+#
+# FreeType 2 PCF module definition
+#
+
+# Copyright 2000 by
+# Francesco Zappa Nardelli
+# 
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+make_module_list: add_pcf_driver
+
+add_pcf_driver:
+	$(OPEN_DRIVER)pcf_driver_class$(CLOSE_DRIVER)
+	$(ECHO_DRIVER)pcf       $(ECHO_DRIVER_DESC)pcf bitmap fonts$(ECHO_DRIVER_DONE)
+
+# EOF
--- /dev/null
+++ b/src/pcf/pcf.c
@@ -1,0 +1,36 @@
+/*  pcf.c                                                                 
+
+    FreeType font driver for pcf fonts
+
+  Copyright 2000 by            
+  Francesco Zappa Nardelli     
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#define FT_MAKE_OPTION_SINGLE_OBJECT
+
+
+#include <ft2build.h>
+#include FT_SOURCE_FILE(pcf,pcfutil.c)
+#include FT_SOURCE_FILE(pcf,pcfread.c)
+#include FT_SOURCE_FILE(pcf,pcfdriver.c)
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcf.h
@@ -1,0 +1,239 @@
+/*  pcf.h                                                                 
+
+  FreeType font driver for pcf fonts
+
+  Copyright (C) 2000 by            
+  Francesco Zappa Nardelli     
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#ifndef __PCF_H__
+#define __PCF_H__
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_DRIVER_H
+
+
+FT_BEGIN_HEADER
+
+  typedef struct  PCF_TableRec_
+  {
+    FT_ULong  type;
+    FT_ULong  format;
+    FT_ULong  size;
+    FT_ULong  offset;
+
+  } PCF_TableRec, *PCF_Table;
+
+
+  typedef struct  PCF_TocRec_ 
+  {
+    FT_ULong   version;
+    FT_ULong   count;
+    PCF_Table  tables;
+
+  } PCF_TocRec, *PCF_Toc;
+
+
+  typedef struct  PCF_ParseProperty_ 
+  {
+    FT_Long  name;
+    FT_Byte  isString;
+    FT_Long  value;
+
+  } PCF_ParsePropertyRec, *PCF_ParseProperty;
+
+
+  typedef struct  PCF_Property_
+  {
+    FT_String*  name;
+    FT_Byte     isString;
+
+    union
+    {
+      FT_String*  atom;
+      FT_Long     integer;
+      FT_ULong    cardinal;
+
+    } value;
+
+  } PCF_PropertyRec, *PCF_Property;      
+
+
+  typedef struct  PCF_Compressed_Metric_ 
+  {
+    FT_Byte  leftSideBearing;
+    FT_Byte  rightSideBearing;
+    FT_Byte  characterWidth;
+    FT_Byte  ascent;
+    FT_Byte  descent;
+
+  } PCF_Compressed_MetricRec, *PCF_Compressed_Metric;
+    
+
+  typedef struct  PCF_Metric_ 
+  {
+    FT_Short  leftSideBearing;
+    FT_Short  rightSideBearing;
+    FT_Short  characterWidth;
+    FT_Short  ascent;
+    FT_Short  descent;
+    FT_Short  attributes;
+    FT_ULong  bits;
+
+  } PCF_MetricRec, *PCF_Metric;
+
+
+  typedef struct  PCF_AccelRec_
+  {
+    FT_Byte        noOverlap;
+    FT_Byte        constantMetrics;
+    FT_Byte        terminalFont;
+    FT_Byte        constantWidth;
+    FT_Byte        inkInside;
+    FT_Byte        inkMetrics;
+    FT_Byte        drawDirection;
+    FT_Long        fontAscent;
+    FT_Long        fontDescent;
+    FT_Long        maxOverlap;
+    PCF_MetricRec  minbounds;
+    PCF_MetricRec  maxbounds;
+    PCF_MetricRec  ink_minbounds;
+    PCF_MetricRec  ink_maxbounds;
+
+  } PCF_AccelRec, *PCF_Accel;
+
+
+  typedef struct  PCD_Encoding_
+  {
+    FT_Long   enc;
+    FT_Short  glyph;
+
+  } PCF_EncodingRec, *PCF_Encoding;
+
+
+  typedef struct  PCF_FaceRec_
+  {
+    FT_FaceRec     root;
+      
+    char*          charset_encoding;
+    char*          charset_registry;
+
+    PCF_TocRec     toc;
+    PCF_AccelRec   accel;
+
+    int            nprops;
+    PCF_Property   properties;
+
+    FT_Long        nmetrics;
+    PCF_Metric     metrics;
+    FT_Long        nencodings;
+    PCF_Encoding   encodings;
+      
+    FT_Short       defaultChar;
+
+    FT_ULong       bitmapsFormat;
+
+    FT_CharMap     charmap_handle;
+    FT_CharMapRec  charmap;  /* a single charmap per face */
+
+  } PCF_FaceRec, *PCF_Face;
+
+
+  /* XXX hack */
+  static
+  FT_Error  PCF_Done_Face( PCF_Face  face );
+
+
+  /* macros for pcf font format */
+
+#define LSBFirst  0
+#define MSBFirst  1
+
+#define PCF_FILE_VERSION        ( ( 'p' << 24 ) | \
+                                  ( 'c' << 16 ) | \
+                                  ( 'f' <<  8 ) | 1 )
+#define PCF_FORMAT_MASK         0xFFFFFF00L
+    
+#define PCF_DEFAULT_FORMAT      0x00000000L
+#define PCF_INKBOUNDS           0x00000200L
+#define PCF_ACCEL_W_INKBOUNDS   0x00000100L
+#define PCF_COMPRESSED_METRICS  0x00000100L
+
+#define PCF_FORMAT_MATCH( a, b ) \
+          ( ( (a) & PCF_FORMAT_MASK ) == ( (b) & PCF_FORMAT_MASK ) )
+
+#define PCF_GLYPH_PAD_MASK  ( 3 << 0 )
+#define PCF_BYTE_MASK       ( 1 << 2 )
+#define PCF_BIT_MASK        ( 1 << 3 )
+#define PCF_SCAN_UNIT_MASK  ( 3 << 4 )
+
+#define PCF_BYTE_ORDER( f ) \
+          ( ( (f) & PCF_BYTE_MASK ) ? MSBFirst : LSBFirst )
+#define PCF_BIT_ORDER( f ) \
+          ( ( (f) & PCF_BIT_MASK ) ? MSBFirst : LSBFirst )
+#define PCF_GLYPH_PAD_INDEX( f ) \
+          ( (f) & PCF_GLYPH_PAD_MASK )
+#define PCF_GLYPH_PAD( f ) \
+          ( 1 << PCF_GLYPH_PAD_INDEX( f ) )
+#define PCF_SCAN_UNIT_INDEX( f ) \
+          ( ( (f) & PCF_SCAN_UNIT_MASK ) >> 4 )
+#define PCF_SCAN_UNIT( f ) \
+          ( 1 << PCF_SCAN_UNIT_INDEX( f ) )
+#define PCF_FORMAT_BITS( f )             \
+          ( (f) & ( PCF_GLYPH_PAD_MASK | \
+                    PCF_BYTE_MASK      | \
+                    PCF_BIT_MASK       | \
+                    PCF_SCAN_UNIT_MASK ) )
+
+#define PCF_SIZE_TO_INDEX( s )  ( (s) == 4 ? 2 : (s) == 2 ? 1 : 0 )
+#define PCF_INDEX_TO_SIZE( b )  ( 1 << b )
+
+#define PCF_FORMAT( bit, byte, glyph, scan )          \
+          ( ( PCF_SIZE_TO_INDEX( scan )      << 4 ) | \
+            ( ( (bit)  == MSBFirst ? 1 : 0 ) << 3 ) | \
+            ( ( (byte) == MSBFirst ? 1 : 0 ) << 2 ) | \
+            ( PCF_SIZE_TO_INDEX( glyph )     << 0 ) )
+
+#define PCF_PROPERTIES        ( 1 << 0 )
+#define PCF_ACCELERATORS      ( 1 << 1 )
+#define PCF_METRICS           ( 1 << 2 )
+#define PCF_BITMAPS           ( 1 << 3 )
+#define PCF_INK_METRICS       ( 1 << 4 )
+#define PCF_BDF_ENCODINGS     ( 1 << 5 )
+#define PCF_SWIDTHS           ( 1 << 6 )
+#define PCF_GLYPH_NAMES       ( 1 << 7 )
+#define PCF_BDF_ACCELERATORS  ( 1 << 8 )
+
+#define GLYPHPADOPTIONS  4 /* I'm not sure about this */
+
+  static 
+  FT_Error  pcf_load_font( FT_Stream,
+                           PCF_Face );
+    
+
+FT_END_HEADER
+
+#endif /* __PCF_H__ */
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfdriver.c
@@ -1,0 +1,343 @@
+/*  pcfdriver.c
+
+    FreeType font driver for pcf files
+
+    Copyright (C) 2000 by
+    Francesco Zappa Nardelli                                               
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#include <ft2build.h>
+
+#include FT_ERRORS_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_OBJECTS_H
+
+#include FT_SOURCE_FILE(pcf,pcf.h)
+#include FT_SOURCE_FILE(pcf,pcfdriver.h)
+#include FT_SOURCE_FILE(pcf,pcfutil.h)
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_pcfdriver
+
+
+  static
+  FT_Error  PCF_Done_Face( PCF_Face  face )
+  { 
+    FT_Memory    memory = FT_FACE_MEMORY( face );
+    PCF_Property tmp    = face->properties;
+    int i;
+
+
+    FREE( face->encodings ); 
+    FREE( face->metrics );
+
+    for ( i = 0; i < face->nprops; i++ )
+    {
+      FREE( tmp->name );
+      if ( tmp->isString )
+        FREE( tmp->value );
+    }
+    FREE( face->properties );
+
+    FT_TRACE4(( "DONE_FACE!!!\n" ));
+
+    return FT_Err_Ok;
+  }
+
+
+  static
+  FT_Error  PCF_Init_Face( FT_Stream      stream,
+                           PCF_Face       face,
+                           FT_Int         face_index,
+                           FT_Int         num_params,
+                           FT_Parameter*  params )
+  {
+    FT_Error  error = FT_Err_Ok;
+  
+    FT_UNUSED( num_params );
+    FT_UNUSED( params );
+    FT_UNUSED( face_index );
+  
+
+    error = pcf_load_font( stream, face );
+    if ( error )
+      goto Fail;
+
+    return FT_Err_Ok;
+
+  Fail: 
+    FT_TRACE2(( "[not a valid PCF file]\n" ));
+    PCF_Done_Face( face );
+
+    return FT_Err_Unknown_File_Format; /* error */
+  }
+
+
+  static
+  FT_Error  PCF_Set_Pixel_Size( FT_Size  size )
+  {  
+    PCF_Face face = (PCF_Face)FT_SIZE_FACE( size );
+
+
+    FT_TRACE4(( "rec %d - pres %d\n", size->metrics.y_ppem,
+                                      face->root.available_sizes->height ));
+
+    if ( size->metrics.y_ppem == face->root.available_sizes->height )
+    {
+      size->metrics.ascender  = face->accel.fontAscent << 6; 
+      size->metrics.descender = face->accel.fontDescent * (-64);
+#if 0
+      size->metrics.height    = face->accel.maxbounds.ascent << 6;
+#endif
+      size->metrics.height    = size->metrics.ascender -
+                                size->metrics.descender;
+      
+      return FT_Err_Ok;
+    }
+    else
+    {
+      FT_TRACE4(( "size WRONG\n" ));
+      return FT_Err_Invalid_Pixel_Size;
+    }
+  }
+
+
+  static
+  FT_Error  PCF_Load_Glyph( FT_GlyphSlot  slot,
+                            FT_Size       size,
+                            FT_UInt       glyph_index,
+                            FT_Int        load_flags )
+  { 
+    PCF_Face    face   = (PCF_Face)FT_SIZE_FACE( size );
+    FT_Error    error  = FT_Err_Ok;
+    FT_Memory   memory = FT_FACE(face)->memory;
+    FT_Bitmap*  bitmap = &slot->bitmap;
+    PCF_Metric  metric;
+    int         bytes;
+
+    FT_Stream   stream = face->root.stream;
+
+    FT_UNUSED( load_flags );
+
+
+    FT_TRACE4(( "load_glyph %d ---", glyph_index ));
+
+    if ( !face )
+    {
+      error = FT_Err_Invalid_Argument;
+      goto Exit;
+    }
+
+    metric = face->metrics + glyph_index;
+  
+    bitmap->rows       = metric->ascent + metric->descent;
+    bitmap->width      = metric->characterWidth;
+    bitmap->num_grays  = 1;
+    bitmap->pixel_mode = ft_pixel_mode_mono;
+  
+    FT_TRACE6(( "BIT_ORDER %d ; BYTE_ORDER %d ; GLYPH_PAD %d\n",
+                  PCF_BIT_ORDER( face->bitmapsFormat ),
+                  PCF_BYTE_ORDER( face->bitmapsFormat ),
+                  PCF_GLYPH_PAD( face->bitmapsFormat ) ));
+
+    switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
+    {
+    case 1:       
+      bitmap->pitch = ( bitmap->width + 7 ) >> 3;
+      break;
+
+    case 2:
+      bitmap->pitch = ( ( bitmap->width + 15 ) >> 4 ) << 1;
+      break;
+
+    case 4:       
+      bitmap->pitch = ( ( bitmap->width + 31 ) >> 5 ) << 2;
+      break;
+
+    case 8:       
+      bitmap->pitch = ( ( bitmap->width + 63 ) >> 6 ) << 3; 
+      break;
+
+    default:
+      return FT_Err_Invalid_File_Format;
+    }
+
+    /* XXX: to do: are there cases that need repadding the bitmap? */
+    bytes = bitmap->pitch * bitmap->rows;
+
+    if ( ALLOC( bitmap->buffer, bytes ) )
+      goto Exit;
+
+    if ( FILE_Seek( metric->bits )        ||
+         FILE_Read( bitmap->buffer, bytes ) )
+      goto Exit;
+
+    if ( PCF_BIT_ORDER( face->bitmapsFormat ) != MSBFirst )
+      BitOrderInvert( bitmap->buffer,bytes );
+
+    if ( ( PCF_BYTE_ORDER( face->bitmapsFormat ) != 
+           PCF_BIT_ORDER( face->bitmapsFormat )  ) )
+    {
+      switch ( PCF_SCAN_UNIT( face->bitmapsFormat ) )
+      {
+      case 1:
+        break;
+
+      case 2:
+        TwoByteSwap( bitmap->buffer, bytes );
+        break;
+
+      case 4:
+        FourByteSwap( bitmap->buffer, bytes );
+        break;
+      }
+    }
+
+    slot->bitmap_left = 0;
+    slot->bitmap_top  = metric->ascent;
+
+    slot->metrics.horiAdvance  = metric->characterWidth << 6 ;
+    slot->metrics.horiBearingX = metric->rightSideBearing << 6 ;
+    slot->metrics.horiBearingY = metric->ascent << 6 ;
+    slot->metrics.width        = metric->characterWidth << 6 ;
+    slot->metrics.height       = bitmap->rows << 6;
+   
+    slot->linearHoriAdvance = (FT_Fixed)bitmap->width << 16;
+    slot->format            = ft_glyph_format_bitmap;
+    slot->flags             = ft_glyph_own_bitmap;
+
+    FT_TRACE4(( " --- ok\n" ));
+
+  Exit:
+    return error; 
+  }
+
+
+  static
+  FT_UInt  PCF_Get_Char_Index( FT_CharMap  charmap,
+                               FT_Long     char_code )
+  { 
+    PCF_Face      face     = (PCF_Face)charmap->face;
+    PCF_Encoding  en_table = face->encodings;
+    int           low, high, mid;
+
+
+    FT_TRACE4(( "get_char_index %ld\n", char_code ));
+
+    low = 0;
+    high = face->nencodings - 1;
+    while ( low <= high )
+    {
+      mid = ( low + high ) / 2;
+      if ( char_code < en_table[mid].enc )
+        high = mid - 1;
+      else if ( char_code > en_table[mid].enc )
+        low = mid + 1;
+      else
+        return en_table[mid].glyph;
+    }
+  
+    return face->defaultChar;
+  }
+
+
+  FT_CALLBACK_TABLE_DEF
+  const FT_Driver_Class  pcf_driver_class =
+  {
+    {
+      ft_module_font_driver,
+      sizeof ( FT_DriverRec ),
+    
+      "pcf",
+      0x10000L,
+      0x20000L,
+    
+      0,
+    
+      (FT_Module_Constructor)0,
+      (FT_Module_Destructor) 0,
+      (FT_Module_Requester)  0
+    },
+  
+    sizeof( PCF_FaceRec ),
+    sizeof( FT_SizeRec ),
+    sizeof( FT_GlyphSlotRec ),
+  
+    (FTDriver_initFace)     PCF_Init_Face,
+    (FTDriver_doneFace)     PCF_Done_Face,
+    (FTDriver_initSize)     0,
+    (FTDriver_doneSize)     0,
+    (FTDriver_initGlyphSlot)0,
+    (FTDriver_doneGlyphSlot)0,
+  
+    (FTDriver_setCharSizes) PCF_Set_Pixel_Size,
+    (FTDriver_setPixelSizes)PCF_Set_Pixel_Size,
+
+    (FTDriver_loadGlyph)    PCF_Load_Glyph,
+    (FTDriver_getCharIndex) PCF_Get_Char_Index,
+  
+    (FTDriver_getKerning)   0,
+    (FTDriver_attachFile)   0,
+    (FTDriver_getAdvances)  0
+  };
+
+
+#ifdef FT_CONFIG_OPTION_DYNAMIC_DRIVERS
+
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* <Function>                                                            */
+  /*    getDriverClass                                                     */
+  /*                                                                       */
+  /* <Description>                                                         */
+  /*    This function is used when compiling the TrueType driver as a      */
+  /*    shared library (`.DLL' or `.so').  It will be used by the          */
+  /*    high-level library of FreeType to retrieve the address of the      */
+  /*    driver's generic interface.                                        */
+  /*                                                                       */
+  /*    It shouldn't be implemented in a static build, as each driver must */
+  /*    have the same function as an exported entry point.                 */
+  /*                                                                       */
+  /* <Return>                                                              */
+  /*    The address of the TrueType's driver generic interface.  The       */
+  /*    format-specific interface can then be retrieved through the method */
+  /*    interface->get_format_interface.                                   */
+  /*                                                                       */
+  FT_EXPORT_DEF( const FT_Driver_Class* )  getDriverClass( void )
+  {
+    return &pcf_driver_class;
+  }
+
+
+#endif /* FT_CONFIG_OPTION_DYNAMIC_DRIVERS */
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfdriver.h
@@ -1,0 +1,44 @@
+/*  pcfdriver.h                      
+
+    FreeType font driver for pcf fonts
+
+  Copyright 2000 by            
+  Francesco Zappa Nardelli     
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#ifndef __PCFDRIVER_H__
+#define __PCFDRIVER_H__
+
+#include <ft2build.h>
+#include FT_INTERNAL_DRIVER_H
+
+FT_BEGIN_HEADER
+
+  FT_EXPORT_VAR( const FT_Driver_Class )  pcf_driver_class;
+
+FT_END_HEADER
+
+
+#endif /* __PCFDRIVER_H__ */
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfread.c
@@ -1,0 +1,1051 @@
+/*  pcfread.c                                                                 
+
+    FreeType font driver for pcf fonts
+
+  Copyright 2000 by            
+  Francesco Zappa Nardelli     
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#include <ft2build.h>
+
+#include FT_ERRORS_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+#include FT_INTERNAL_OBJECTS_H
+
+#include FT_SOURCE_FILE(pcf,pcf.h)
+#include FT_SOURCE_FILE(pcf,pcfdriver.h)
+
+#include <string.h>     /* strlen(), strcpy() */
+
+  /*************************************************************************/
+  /*                                                                       */
+  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
+  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
+  /* messages during execution.                                            */
+  /*                                                                       */
+#undef  FT_COMPONENT
+#define FT_COMPONENT  trace_pcfread
+
+
+#if defined( FT_DEBUG_LEVEL_TRACE )
+  static char*  tableNames[] =
+  {
+    "prop", "accl", "mtrcs", "bmps", "imtrcs",
+    "enc", "swidth", "names", "accel"
+  };
+#endif
+
+
+  static 
+  const FT_Frame_Field  pcf_toc_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_TocRec
+
+    FT_FRAME_START( 8 ),
+      FT_FRAME_ULONG_LE( version ),
+      FT_FRAME_ULONG_LE( count ),
+    FT_FRAME_END
+  };
+
+
+  static 
+  const FT_Frame_Field  pcf_table_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_TableRec
+
+    FT_FRAME_START( 16  ),
+      FT_FRAME_ULONG_LE( type ),
+      FT_FRAME_ULONG_LE( format ),
+      FT_FRAME_ULONG_LE( size ),
+      FT_FRAME_ULONG_LE( offset ),
+    FT_FRAME_END
+  };
+
+
+  static  
+  FT_Error pcf_read_TOC( FT_Stream  stream, 
+                         PCF_Face   face )
+  {
+    FT_Error   error;
+    PCF_Toc    toc = &face->toc;
+    PCF_Table  tables;
+
+    FT_Memory     memory = FT_FACE(face)->memory;
+    unsigned int  i;
+
+
+    if ( FILE_Seek ( 0 )                   ||
+         READ_Fields ( pcf_toc_header, toc ) )
+      return FT_Err_Cannot_Open_Resource;
+  
+    if ( toc->version != PCF_FILE_VERSION )
+      return FT_Err_Invalid_File_Format;
+
+    if ( ALLOC( face->toc.tables, toc->count * sizeof ( PCF_TableRec ) ) )
+      return FT_Err_Out_Of_Memory;
+
+    tables = face->toc.tables;
+    for ( i = 0; i < toc->count; i++ )
+    {
+      if ( READ_Fields( pcf_table_header, tables ) )
+        goto Exit;
+      tables++;
+    }
+
+#if defined( FT_DEBUG_LEVEL_TRACE )
+
+    {
+      int    i,j;
+      char*  name;
+
+
+      FT_TRACE4(( "Tables count: %ld\n", face->toc.count ));
+      tables = face->toc.tables;
+      for ( i = 0; i < toc->count; i++ )
+      {
+        for( j = 0; j < sizeof ( tableNames ) / sizeof ( tableNames[0] ); j++ )
+          if ( tables[i].type == ( 1 << j ) )
+            name=tableNames[j];
+        FT_TRACE4(( "Table %d: type=%-6s format=0x%04lX "
+                    "size=0x%06lX (%8ld) offset=0x%04lX\n",
+                    i, name,
+                    tables[i].format,
+                    tables[i].size, tables[i].size, 
+                    tables[i].offset ));
+      }
+    }
+
+#endif
+
+    return FT_Err_Ok;
+
+  Exit:
+    FREE( face->toc.tables );
+    return error;
+  }
+
+
+  static 
+  const FT_Frame_Field  pcf_metric_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_MetricRec
+
+    FT_FRAME_START( 12 ),
+      FT_FRAME_SHORT_LE( leftSideBearing ),
+      FT_FRAME_SHORT_LE( rightSideBearing ),
+      FT_FRAME_SHORT_LE( characterWidth ),
+      FT_FRAME_SHORT_LE( ascent ),
+      FT_FRAME_SHORT_LE( descent ),
+      FT_FRAME_SHORT_LE( attributes ),
+    FT_FRAME_END
+  };
+
+
+  static 
+  const FT_Frame_Field  pcf_metric_msb_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_MetricRec
+
+    FT_FRAME_START( 12 ),
+      FT_FRAME_SHORT( leftSideBearing ),
+      FT_FRAME_SHORT( rightSideBearing ),
+      FT_FRAME_SHORT( characterWidth ),
+      FT_FRAME_SHORT( ascent ),
+      FT_FRAME_SHORT( descent ),
+      FT_FRAME_SHORT( attributes ),
+    FT_FRAME_END
+  };
+
+
+  static 
+  const FT_Frame_Field  pcf_compressed_metric_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_Compressed_MetricRec
+
+    FT_FRAME_START( 5 ),
+      FT_FRAME_BYTE( leftSideBearing ),
+      FT_FRAME_BYTE( rightSideBearing ),
+      FT_FRAME_BYTE( characterWidth ),
+      FT_FRAME_BYTE( ascent ),
+      FT_FRAME_BYTE( descent ),
+    FT_FRAME_END
+  };
+
+
+  static 
+  FT_Error  pcf_parse_metric( FT_Stream              stream, 
+                              const FT_Frame_Field*  header, 
+                              PCF_Metric             metric )
+  {
+    FT_Error  error = FT_Err_Ok;
+  
+
+    (void)READ_Fields( header, metric ); 
+  
+    return error;
+  }
+
+
+  static
+  FT_Error  pcf_parse_compressed_metric( FT_Stream   stream,
+                                         PCF_Metric  metric )
+  {
+    PCF_Compressed_MetricRec  compr_metric;
+    FT_Error                  error = FT_Err_Ok;
+  
+
+    (void)READ_Fields( pcf_compressed_metric_header, &compr_metric );
+
+    metric->leftSideBearing  = (FT_Short)compr_metric.leftSideBearing - 0x80;
+    metric->rightSideBearing = (FT_Short)compr_metric.rightSideBearing - 0x80;
+    metric->characterWidth   = (FT_Short)compr_metric.characterWidth - 0x80;
+    metric->ascent           = (FT_Short)compr_metric.ascent - 0x80;
+    metric->descent          = (FT_Short)compr_metric.descent - 0x80;
+    metric->attributes       = 0;
+  
+    return error;
+  }
+
+
+  static
+  FT_Error  pcf_get_metric( FT_Stream   stream,
+                            FT_ULong    format,
+                            PCF_Metric  metric )
+  {
+    FT_Error error = FT_Err_Ok;
+
+
+    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+    {
+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+        error = pcf_parse_metric( stream, pcf_metric_msb_header, metric );
+      else
+        error = pcf_parse_metric( stream, pcf_metric_header, metric );
+    }
+    else
+      error = pcf_parse_compressed_metric( stream, metric );
+
+    return error;
+  }
+                         
+
+  static
+  FT_Error  pcfSeekToType( FT_Stream  stream,
+                           PCF_Table  tables,
+                           int        ntables, 
+                           FT_ULong   type,
+                           FT_ULong*  formatp,
+                           FT_ULong*  sizep )
+  {
+    FT_Error error;
+    int      i;
+
+
+    for ( i = 0; i < ntables; i++ )
+      if ( tables[i].type == type )
+      {
+        if ( stream->pos > tables[i].offset )
+          return FT_Err_Invalid_Stream_Skip;
+        if ( FILE_Skip( tables[i].offset - stream->pos ) )
+          return FT_Err_Invalid_Stream_Skip;
+        *sizep   = tables[i].size;  /* unused - to be removed */
+        *formatp = tables[i].format;
+        return FT_Err_Ok;
+      }
+
+    return FT_Err_Invalid_File_Format;
+  }
+
+
+  static 
+  FT_Bool  pcfHasType( PCF_Table  tables,
+                       int        ntables,
+                       FT_ULong   type )
+  {
+    int i;
+    
+
+    for ( i = 0; i < ntables; i++ )
+      if ( tables[i].type == type )
+        return TRUE;
+
+    return FALSE;
+  }
+
+
+  static 
+  const FT_Frame_Field  pcf_property_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_ParsePropertyRec
+
+    FT_FRAME_START( 9 ),
+      FT_FRAME_LONG_LE( name ),
+      FT_FRAME_BYTE   ( isString ),
+      FT_FRAME_LONG_LE( value ),
+    FT_FRAME_END
+  };
+
+
+  static 
+  const FT_Frame_Field  pcf_property_msb_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_ParsePropertyRec
+
+    FT_FRAME_START( 9 ),
+      FT_FRAME_LONG( name ),
+      FT_FRAME_BYTE( isString ),
+      FT_FRAME_LONG( value ),
+    FT_FRAME_END
+  };
+
+
+  static
+  PCF_Property  find_property( PCF_Face          face,
+                               const FT_String*  prop )
+  {
+    PCF_Property  properties = face->properties;
+    FT_Bool       found      = 0;
+    int           i;
+
+
+    for ( i = 0 ; i < face->nprops && !found; i++ )
+    {
+      if ( !strcmp( properties[i].name, prop ) )
+        found = 1;
+    }
+  
+    if ( found )
+      return properties + i - 1;
+    else
+      return NULL;
+  }
+
+
+  static
+  FT_Error  pcf_get_properties( FT_Stream  stream,
+                                PCF_Face   face )
+  {
+    PCF_ParseProperty  props      = 0;
+    PCF_Property       properties = 0;
+    int                nprops, i;
+    FT_ULong           format, size;
+    FT_Error           error;
+    FT_Memory          memory     = FT_FACE(face)->memory;
+    FT_ULong           string_size;
+    FT_String*         strings    = 0;
+  
+
+    error = pcfSeekToType( stream,
+                           face->toc.tables, 
+                           face->toc.count,
+                           PCF_PROPERTIES,
+                           &format,
+                           &size );
+    if ( error )
+      goto Bail;
+
+    if ( READ_ULongLE( format ) )
+      goto Bail;
+
+    FT_TRACE4(( "get_prop: format = %ld\n", format ));
+
+    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+      goto Bail;
+
+    if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+      (void)READ_ULong( nprops );
+    else
+      (void)READ_ULongLE( nprops );
+    if ( error )
+      goto Bail;
+
+    FT_TRACE4(( "get_prop: nprop = %d\n", nprops ));
+  
+    if ( ALLOC( props, nprops * sizeof ( PCF_ParsePropertyRec ) ) )
+      goto Bail;
+
+    for ( i = 0; i < nprops; i++ )
+    {
+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+        (void)READ_Fields( pcf_property_msb_header, props + i );
+      else
+        (void)READ_Fields( pcf_property_header, props + i );
+      if ( error )
+        goto Bail;
+    }
+
+    /* pad the property array                                            */
+    /*                                                                   */
+    /* clever here - nprops is the same as the number of odd-units read, */
+    /* as only isStringProp are odd length   (Keith Packard)             */
+    /*                                                                   */
+    if ( nprops & 3 )
+    {
+      i = 4 - ( nprops & 3 );
+      FT_Skip_Stream( stream, i );
+    }
+
+    if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+      (void)READ_ULong( string_size );
+    else
+      (void)READ_ULongLE( string_size );
+    if ( error )
+      goto Bail;
+  
+    FT_TRACE4(( "get_prop: string_size = %ld\n", string_size ));
+
+    if ( ALLOC( strings, string_size * sizeof ( char ) ) )
+      goto Bail;
+ 
+    error = FT_Read_Stream( stream, (FT_Byte*)strings, string_size );
+    if ( error )
+      goto Bail;
+
+    if ( ALLOC( properties, nprops * sizeof ( PCF_PropertyRec ) ) )
+      goto Bail;
+  
+    for ( i = 0; i < nprops; i++ )
+    {
+      /* XXX: make atom */ 
+      error = ALLOC( properties[i].name, 
+                     ( strlen( strings + props[i].name ) + 1 ) *
+                       sizeof ( char ) );
+      if ( error )
+        goto Bail;
+      strcpy( properties[i].name,strings + props[i].name );
+    
+      properties[i].isString = props[i].isString;
+   
+      if ( props[i].isString )
+      {
+        error = ALLOC( properties[i].value.atom, 
+                       ( strlen( strings + props[i].value ) + 1 ) * 
+                         sizeof ( char ) );
+        if ( error )
+          goto Bail;
+        strcpy( properties[i].value.atom, strings + props[i].value );
+      } 
+      else
+        properties[i].value.integer = props[i].value;
+    }
+  
+    face->properties = properties;
+    face->nprops = nprops;
+  
+    FREE( props );
+    FREE( strings );
+  
+    return FT_Err_Ok;
+ 
+  Bail:
+    FREE( props );
+    FREE( strings );
+
+    return error;
+  }
+
+
+  static
+  FT_Error  pcf_get_metrics( FT_Stream  stream,
+                             PCF_Face   face )
+  { 
+    FT_Error    error    = FT_Err_Ok;
+    FT_Memory   memory   = FT_FACE(face)->memory;
+    FT_ULong    format   = 0;
+    FT_ULong    size     = 0;
+    PCF_Metric  metrics  = 0;
+    int         i;
+    int         nmetrics = -1;
+
+
+    error = pcfSeekToType( stream,
+                           face->toc.tables, 
+                           face->toc.count,
+                           PCF_METRICS,
+                           &format,
+                           &size );
+    if ( error ) 
+      return error;
+
+    error = READ_ULongLE( format );
+
+    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )   &&
+         !PCF_FORMAT_MATCH( format, PCF_COMPRESSED_METRICS ) )
+      return FT_Err_Invalid_File_Format;
+
+    if ( PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+    {
+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+        (void)READ_ULong( nmetrics );
+      else
+        (void)READ_ULongLE( nmetrics );
+    }
+    else
+    {
+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+        (void)READ_UShort( nmetrics );
+      else
+        (void)READ_UShortLE( nmetrics );
+    }
+    if ( error || nmetrics == -1 )
+      return FT_Err_Invalid_File_Format;
+  
+    face->nmetrics = nmetrics;
+
+    error = ALLOC( face->metrics, nmetrics * sizeof ( PCF_MetricRec ) );
+    if ( error )
+      return FT_Err_Out_Of_Memory;
+
+    metrics = face->metrics;
+    for ( i = 0; i < nmetrics; i++ )
+    {
+      pcf_get_metric( stream, format, metrics + i );
+ 
+      metrics[i].bits = 0;
+
+      FT_TRACE4(( "%d : width=%d, "
+                  "lsb=%d, rsb=%d, ascent=%d, descent=%d, swidth=%d\n",
+                  i,
+                  ( metrics + i )->characterWidth,
+                  ( metrics + i )->leftSideBearing,
+                  ( metrics + i )->rightSideBearing,
+                  ( metrics + i )->ascent,
+                  ( metrics + i )->descent,
+                  ( metrics + i )->attributes ));
+    
+      if ( error )
+        break;
+    }
+
+    if ( error )
+      FREE( face->metrics );
+    return error;
+  }
+
+
+  static
+  FT_Error  pcf_get_bitmaps( FT_Stream  stream,
+                             PCF_Face   face )
+  {
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = FT_FACE(face)->memory;
+    FT_Long*   offsets;
+    FT_Long    bitmapSizes[GLYPHPADOPTIONS];
+    FT_ULong   format, size;
+    int        nbitmaps, i, sizebitmaps;
+    char*      bitmaps;
+
+
+    error = pcfSeekToType( stream,
+                           face->toc.tables, 
+                           face->toc.count,
+                           PCF_BITMAPS,
+                           &format,
+                           &size );
+    if ( error )
+      return error;
+
+    error = FT_Access_Frame( stream, 8 );
+    if ( error )
+      return error;
+    format = GET_ULongLE();
+    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+      return FT_Err_Invalid_File_Format;
+  
+    if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+      nbitmaps  = GET_ULong();
+    else
+      nbitmaps  = GET_ULongLE();
+    FT_Forget_Frame( stream );
+    if ( nbitmaps != face->nmetrics )
+      return FT_Err_Invalid_File_Format;
+
+    error = ALLOC( offsets, nbitmaps * sizeof ( FT_ULong ) );
+    if ( error )
+      return error;
+
+    if ( error )
+      goto Bail;
+    for ( i = 0; i < nbitmaps; i++ )
+    { 
+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+        (void)READ_Long( offsets[i] );
+      else
+        (void)READ_LongLE( offsets[i] );
+
+      FT_TRACE4(( "bitmap %d is at offset %ld\n", i, offsets[i] ));
+    }
+    if ( error )
+      goto Bail;
+
+    if ( error )
+      goto Bail;
+    for ( i = 0; i < GLYPHPADOPTIONS; i++ )
+    { 
+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+        (void)READ_Long( bitmapSizes[i] ); 
+      else
+        (void)READ_LongLE( bitmapSizes[i] );
+      if ( error )
+        goto Bail;
+
+      sizebitmaps = bitmapSizes[PCF_GLYPH_PAD_INDEX( format )];
+
+      FT_TRACE4(( "padding %d implies a size of %ld\n", i, bitmapSizes[i] ));
+    }
+
+    FT_TRACE4(( "  %d bitmaps, padding index %ld\n",
+                nbitmaps,
+                PCF_GLYPH_PAD_INDEX( format ) ));
+    FT_TRACE4(( "bitmap size = %d\n", sizebitmaps ));
+
+    for ( i = 0; i < nbitmaps; i++ )
+      face->metrics[i].bits = stream->pos + offsets[i]; 
+    
+    face->bitmapsFormat = format;
+  
+    FREE ( offsets );
+    return error;
+
+  Bail:
+    FREE ( offsets );
+    FREE ( bitmaps );
+    return error;
+  }
+
+
+  static
+  FT_Error  pcf_get_encodings( FT_Stream  stream,
+                               PCF_Face   face )
+  {
+    FT_Error      error   = FT_Err_Ok;
+    FT_Memory     memory  = FT_FACE(face)->memory;
+    FT_ULong      format, size;
+    int           firstCol, lastCol;
+    int           firstRow, lastRow;
+    int           nencoding, encodingOffset;
+    int           i, j;
+    PCF_Encoding  tmpEncoding, encoding = 0;
+
+
+    error = pcfSeekToType( stream,
+                           face->toc.tables, 
+                           face->toc.count,
+                           PCF_BDF_ENCODINGS,
+                           &format,
+                           &size );
+    if ( error )
+      return error;
+
+    error = FT_Access_Frame( stream, 14 );
+    if ( error )
+      return error;
+    format = GET_ULongLE();
+    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT ) )
+      return FT_Err_Invalid_File_Format;
+  
+    if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+    {
+      firstCol          = GET_Short();
+      lastCol           = GET_Short();
+      firstRow          = GET_Short();
+      lastRow           = GET_Short();
+      face->defaultChar = GET_Short();
+    }
+    else
+    {
+      firstCol          = GET_ShortLE();
+      lastCol           = GET_ShortLE();
+      firstRow          = GET_ShortLE();
+      lastRow           = GET_ShortLE();
+      face->defaultChar = GET_ShortLE();
+    }
+
+    FT_Forget_Frame( stream );
+
+    FT_TRACE4(( "enc: firstCol %d, lastCol %d, firstRow %d, lastRow %d\n",
+                firstCol, lastCol, firstRow, lastRow ));
+
+    nencoding = ( lastCol - firstCol + 1 ) * ( lastRow - firstRow + 1 );
+
+    if ( ALLOC( tmpEncoding, nencoding * sizeof ( PCF_EncodingRec ) ) )
+      return FT_Err_Out_Of_Memory;
+  
+    error = FT_Access_Frame( stream, 2 * nencoding );
+    if ( error )
+      goto Bail;
+  
+    for ( i = 0, j = 0 ; i < nencoding; i++ )
+    {
+      if ( PCF_BYTE_ORDER( format ) == MSBFirst )
+        encodingOffset = GET_Short(); 
+      else
+        encodingOffset = GET_ShortLE();
+  
+      if ( encodingOffset != 0xFFFF )
+      {
+        tmpEncoding[j].enc = ( ( ( i / ( lastCol - firstCol + 1 ) ) +
+                                 firstRow ) * 256 ) +
+                               ( ( i % ( lastCol - firstCol + 1 ) ) +
+                                 firstCol );
+
+        tmpEncoding[j].glyph = encodingOffset;
+        j++;
+      }
+
+      FT_TRACE4(( "enc n. %d ; Uni %ld ; Glyph %d\n",
+                  i, tmpEncoding[j - 1].enc, encodingOffset ));
+    }
+    FT_Forget_Frame( stream );
+
+    if ( ALLOC( encoding, (--j) * sizeof ( PCF_EncodingRec ) ) )
+      goto Bail;
+
+    for ( i = 0; i < j; i++ )
+    {
+      encoding[i].enc   = tmpEncoding[i].enc;
+      encoding[i].glyph = tmpEncoding[i].glyph;
+    }
+
+    face->nencodings = j;
+    face->encodings  = encoding;
+    FREE( tmpEncoding );
+
+    return error;
+
+  Bail:
+    FREE( encoding );
+    FREE( tmpEncoding );
+    return error;
+  }
+
+
+  static 
+  const FT_Frame_Field  pcf_accel_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_AccelRec
+
+    FT_FRAME_START( 20 ),
+      FT_FRAME_BYTE      ( noOverlap ),
+      FT_FRAME_BYTE      ( constantMetrics ),
+      FT_FRAME_BYTE      ( terminalFont ),
+      FT_FRAME_BYTE      ( constantWidth ),
+      FT_FRAME_BYTE      ( inkInside ),
+      FT_FRAME_BYTE      ( inkMetrics ),
+      FT_FRAME_BYTE      ( drawDirection ),
+      FT_FRAME_SKIP_BYTES( 1 ),
+      FT_FRAME_LONG_LE   ( fontAscent ),
+      FT_FRAME_LONG_LE   ( fontDescent ),
+      FT_FRAME_LONG_LE   ( maxOverlap ),
+    FT_FRAME_END
+  };
+
+
+  static 
+  const FT_Frame_Field  pcf_accel_msb_header[] =
+  {
+#undef  FT_STRUCTURE
+#define FT_STRUCTURE  PCF_AccelRec
+
+    FT_FRAME_START( 20 ),
+      FT_FRAME_BYTE      ( noOverlap ),
+      FT_FRAME_BYTE      ( constantMetrics ),
+      FT_FRAME_BYTE      ( terminalFont ),
+      FT_FRAME_BYTE      ( constantWidth ),
+      FT_FRAME_BYTE      ( inkInside ),
+      FT_FRAME_BYTE      ( inkMetrics ),
+      FT_FRAME_BYTE      ( drawDirection ),
+      FT_FRAME_SKIP_BYTES( 1 ),
+      FT_FRAME_LONG      ( fontAscent ),
+      FT_FRAME_LONG      ( fontDescent ),
+      FT_FRAME_LONG      ( maxOverlap ),
+    FT_FRAME_END
+  };
+
+
+  static 
+  FT_Error  pcf_get_accel( FT_Stream  stream,
+                           PCF_Face   face,
+                           FT_ULong   type )
+  {
+    FT_ULong   format, size;
+    FT_Error   error = FT_Err_Ok;
+    PCF_Accel  accel = &face->accel;
+
+
+    error = pcfSeekToType( stream,
+                           face->toc.tables,
+                           face->toc.count, 
+                           type,
+                           &format,
+                           &size );
+    if ( error ) 
+      goto Bail;
+
+    error = READ_ULongLE( format );
+    if ( !PCF_FORMAT_MATCH( format, PCF_DEFAULT_FORMAT )  &&
+         !PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
+      goto Bail;
+  
+    if ( PCF_BYTE_ORDER( format ) == MSBFirst ) 
+      (void)READ_Fields( pcf_accel_msb_header , accel );
+    else
+      (void)READ_Fields( pcf_accel_header, accel );
+    if ( error )
+      goto Bail;
+
+    error = pcf_get_metric( stream, format, &(accel->minbounds) );
+    if ( error ) 
+      goto Bail;
+    error = pcf_get_metric( stream, format, &(accel->maxbounds) );
+    if ( error )
+      goto Bail;
+    
+    if ( PCF_FORMAT_MATCH( format, PCF_ACCEL_W_INKBOUNDS ) )
+    {
+      error = pcf_get_metric( stream, format, &(accel->ink_minbounds) );
+      if ( error )
+        goto Bail;
+      error = pcf_get_metric( stream, format, &(accel->ink_maxbounds) );
+      if ( error )
+        goto Bail;
+    } 
+    else
+    {
+      accel->ink_minbounds = accel->minbounds; /* I'm not sure about this */
+      accel->ink_maxbounds = accel->maxbounds;
+    }
+    return error;
+  
+  Bail:
+    return error;
+  }
+
+
+  FT_Error  pcf_load_font( FT_Stream  stream,
+                           PCF_Face   face )
+  {
+    FT_Error   error  = FT_Err_Ok;
+    FT_Memory  memory = FT_FACE(face)->memory;
+    FT_Bool    hasBDFAccelerators;
+
+
+    error = pcf_read_TOC( stream, face );
+    if ( error )
+      return error;
+
+    error = pcf_get_properties( stream, face );
+    if ( error )
+      return error;;
+  
+    /* Use the old accelerators if no BDF accelerators are in the file. */
+    hasBDFAccelerators = pcfHasType( face->toc.tables,
+                                     face->toc.count, 
+                                     PCF_BDF_ACCELERATORS );
+    if ( !hasBDFAccelerators )
+    {
+      error = pcf_get_accel( stream, face, PCF_ACCELERATORS );
+      if ( error ) 
+        goto Bail;
+    }
+  
+    /* metrics */
+    error = pcf_get_metrics( stream, face );
+    if ( error )
+      goto Bail;
+
+    /* bitmaps */
+    error = pcf_get_bitmaps( stream, face );
+    if ( error )
+      goto Bail;
+
+    /* encodings */
+    error = pcf_get_encodings( stream, face );
+    if ( error )
+      goto Bail;
+ 
+    /* BDF style accelerators (i.e. bounds based on encoded glyphs) */
+    if ( hasBDFAccelerators )
+    {
+      error = pcf_get_accel( stream, face, PCF_BDF_ACCELERATORS );
+      if ( error )
+        goto Bail;   
+    }
+
+    /* XXX: TO DO: inkmetrics and glyph_names are missing */
+
+    /* now construct the face object */
+    {
+      FT_Face       root = FT_FACE( face );
+      PCF_Property  prop;
+
+
+      root->num_faces = 1;
+      root->face_index = 0;
+      root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
+                         FT_FACE_FLAG_HORIZONTAL  |
+                         FT_FACE_FLAG_FAST_GLYPHS;
+    
+      if ( face->accel.constantWidth )
+        root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
+
+      root->style_flags = 0;
+      prop = find_property( face, "SLANT" );
+      if ( prop != NULL ) 
+        if ( prop->isString )
+          if ( ( *(prop->value.atom) == 'O' ) ||
+               ( *(prop->value.atom) == 'I' ) )
+            root->style_flags |= FT_STYLE_FLAG_ITALIC;
+
+      prop = find_property( face, "WEIGHT_NAME" );
+      if ( prop != NULL ) 
+        if ( prop->isString )
+          if ( *(prop->value.atom) == 'B' )
+            root->style_flags |= FT_STYLE_FLAG_BOLD;
+
+      root->style_name = (char *)"Regular";
+
+      if ( root->style_flags & FT_STYLE_FLAG_BOLD ) {
+        if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
+          root->style_name = (char *)"Bold Italic";
+        else
+          root->style_name = (char *)"Bold";
+      }
+      else if ( root->style_flags & FT_STYLE_FLAG_ITALIC )
+        root->style_name = (char *)"Italic";
+  
+      prop = find_property( face, "FAMILY_NAME" );
+      if ( prop != NULL )
+      {
+        if ( prop->isString )
+        {
+          int  l = strlen( prop->value.atom ) + 1;
+
+
+          if ( ALLOC( root->family_name, l * sizeof ( char ) ) )
+            goto Bail;
+          strcpy( root->family_name, prop->value.atom );
+        }
+      }
+      else
+        root->family_name = 0;
+
+      root->num_glyphs = face->nmetrics;
+    
+      root->num_fixed_sizes = 1;
+      if ( ALLOC_ARRAY( root->available_sizes, 1, FT_Bitmap_Size ) )
+        goto Bail;
+    
+      prop = find_property( face, "PIXEL_SIZE" );
+      if ( prop != NULL )
+      {
+        PCF_Property  xres = 0, yres = 0;
+
+
+        xres = find_property( face, "RESOLUTION_X" );
+        yres = find_property( face, "RESOLUTION_Y" );
+        if ( ( xres != NULL ) && ( yres != NULL ) )
+        {
+          root->available_sizes->width = 
+            prop->value.integer * 75 / xres->value.integer;
+          root->available_sizes->height = 
+            prop->value.integer * 75 / yres->value.integer;
+        }
+      }
+      else
+      { /* XXX */
+#if 0
+        printf( "PCF Warning: Pixel Size undefined, assuming 12\n");
+#endif
+        root->available_sizes->width = 12; 
+        root->available_sizes->height = 12;
+      }      
+
+      /* XXX: charmaps */
+      root->charmaps     = &face->charmap_handle;
+      root->num_charmaps = 1;
+
+      {
+        PCF_Property  charset_registry = 0, charset_encoding = 0;
+      
+
+        charset_registry = find_property( face, "CHARSET_REGISTRY" );
+        charset_encoding = find_property( face, "CHARSET_ENCODING" );
+
+        if ( ( charset_registry != NULL ) &&
+             ( charset_encoding != NULL ) )
+        {
+          if ( ( charset_registry->isString ) &&
+               ( charset_encoding->isString ) )
+          {
+            if ( ALLOC( face->charset_encoding, 
+                        ( strlen( charset_encoding->value.atom ) + 1 ) *
+                          sizeof ( char ) ) ) 
+              goto Bail;
+            if ( ALLOC( face->charset_registry, 
+                        ( strlen( charset_registry->value.atom ) + 1 ) *
+                          sizeof ( char ) ) ) 
+              goto Bail;
+            strcpy( face->charset_registry, charset_registry->value.atom );
+            strcpy( face->charset_encoding, charset_encoding->value.atom );
+
+#if 0          
+            if ( !strcmp( charset_registry, "ISO10646" ) )
+            {
+              face->charmap.encoding    = ft_encoding_unicode;
+              face->charmap.platform_id = 3;
+              face->charmap.encoding_id = 1;
+              face->charmap.face        = root;
+              face->charmap_handle
+
+              return FT_Err_Ok;
+            }
+#endif
+          }
+        }
+      }
+ 
+      face->charmap.encoding    = ft_encoding_none;
+      face->charmap.platform_id = 0;
+      face->charmap.encoding_id = 0;
+      face->charmap.face        = root; 
+      face->charmap_handle      = &face->charmap;
+      root->charmap             = face->charmap_handle;
+    }  
+    return FT_Err_Ok;
+
+  Bail:
+    PCF_Done_Face( face );
+    return FT_Err_Invalid_File_Format;
+  }
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfutil.c
@@ -1,0 +1,211 @@
+/*
+
+Copyright 1990, 1994, 1998  The Open Group
+
+All Rights Reserved.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+/* $XFree86: xc/lib/font/util/utilbitmap.c,v 1.3 1999/08/22 08:58:58 dawes Exp $ */
+
+/*
+ * Author:  Keith Packard, MIT X Consortium
+ */
+
+
+#include <ft2build.h>
+#include FT_SOURCE_FILE(pcf,pcfutil.h)
+
+
+  /* Utility functions for reformatting font bitmaps */
+
+  static unsigned char _reverse_byte[0x100] =
+  {
+    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+  };
+
+  /*
+   *  Invert bit order within each BYTE of an array.
+   */
+
+  void  BitOrderInvert( unsigned char*  buf,
+                        int             nbytes )
+  {
+    unsigned char*  rev = _reverse_byte;
+
+
+    for ( ; --nbytes >= 0; buf++ )
+      *buf = rev[*buf];
+  }
+
+
+  /*
+   *  Invert byte order within each 16-bits of an array.
+   */
+
+  void  TwoByteSwap( unsigned char*  buf,
+                     int             nbytes )
+  {
+    unsigned char  c;
+
+
+    for ( ; nbytes > 0; nbytes -= 2, buf += 2 )
+    {
+      c      = buf[0];
+      buf[0] = buf[1];
+      buf[1] = c;
+    }
+  }
+
+  /*
+   *  Invert byte order within each 32-bits of an array.
+   */
+
+  void  FourByteSwap( unsigned char*  buf,
+                      int             nbytes )
+  {
+    unsigned char  c;
+
+
+    for ( ; nbytes > 0; nbytes -= 4, buf += 4 )
+    {
+      c      = buf[0];
+      buf[0] = buf[3];
+      buf[3] = c;
+
+      c      = buf[1];
+      buf[1] = buf[2];
+      buf[2] = c;
+    }
+  }
+
+
+  /*
+   *  Repad a bitmap.
+   */
+
+  int  RepadBitmap( char*         pSrc,
+                    char*         pDst, 
+                    unsigned int  srcPad,
+                    unsigned int  dstPad, 
+                    int           width,
+                    int           height )
+  {
+    int   srcWidthBytes, dstWidthBytes;
+    int   row, col;
+    char  *pTmpSrc, *pTmpDst;
+
+
+    switch ( srcPad )
+    {
+    case 1:     
+      srcWidthBytes = ( width + 7 ) >> 3;
+      break;
+
+    case 2:
+      srcWidthBytes = ( ( width + 15 ) >> 4 ) << 1;
+      break;
+
+    case 4:     
+      srcWidthBytes = ( ( width + 31 ) >> 5 ) << 2;
+      break;
+
+    case 8:     
+      srcWidthBytes = ( ( width + 63 ) >> 6 ) << 3; 
+      break;
+
+    default:
+      return 0;
+    }
+
+    switch ( dstPad )
+    {
+    case 1:     
+      dstWidthBytes = ( width + 7 ) >> 3;
+      break;
+
+    case 2:
+      dstWidthBytes = ( ( width + 15 ) >> 4 ) << 1;
+      break;
+
+    case 4:     
+      dstWidthBytes = ( ( width + 31 ) >> 5 ) << 2;
+      break;
+
+    case 8:     
+      dstWidthBytes = ( ( width + 63 ) >> 6 ) << 3; 
+      break;
+
+    default:
+      return 0;
+    }
+
+    width = srcWidthBytes;
+    if ( width > dstWidthBytes )
+      width = dstWidthBytes;
+
+    pTmpSrc= pSrc;
+    pTmpDst= pDst;
+
+    for ( row = 0; row < height; row++ )
+    {
+      for ( col = 0; col < width; col++ )
+        *pTmpDst++ = *pTmpSrc++;
+
+      while ( col < dstWidthBytes )
+      {
+        *pTmpDst++ = '\0';
+        col++;
+      }
+      pTmpSrc += srcWidthBytes - width;
+    }
+
+    return dstWidthBytes * height;
+  }
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/pcfutil.h
@@ -1,0 +1,54 @@
+/*  pcfutil.h                                                                 
+
+    FreeType font driver for pcf fonts
+
+  Copyright 2000 by            
+  Francesco Zappa Nardelli     
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+
+#ifndef __PCFUTIL_H__
+#define __PCFUTIL_H__
+
+
+#include <ft2build.h>
+
+
+  void  BitOrderInvert( unsigned char*  buf,
+                        int             nbytes);
+
+  void  TwoByteSwap   ( unsigned char*  buf,
+                        int             nbytes);
+
+  void  FourByteSwap  ( unsigned char*  buf,
+                        int             nbytes);
+
+  int   RepadBitmap   ( char*           pSrc,
+                        char*           pDst, 
+                        unsigned int    srcPad,
+                        unsigned int    dstPad, 
+                        int             width,
+                        int             height);
+
+#endif /* __PCFUTIL_H__ */
+
+
+/* END */
--- /dev/null
+++ b/src/pcf/readme
@@ -1,0 +1,114 @@
+                  FreeType font driver for PCF fonts
+
+                       Francesco Zappa Nardelli
+                  <[email protected]>
+
+
+Introduction
+************
+
+PCF (Portable Compiled Format) is a binary bitmap font format, largely used
+in X world. This code implements a PCF driver for the FreeType library.
+Glyph images are loaded into memory only on demand, thus leading to a small
+memory footprint.
+
+Informations on the PCF font format can only be worked out from
+``pcfread.c'', and ``pcfwrite.c'', to be found, for instance, in the XFree86
+(www.xfree86.org) source tree (xc/lib/font/bitmap/).
+
+Many good bitmap fonts in bdf format come with XFree86: they can be
+compiled into the pcf format using the ``bdftopcf'' utility.
+
+
+Supported hardware
+******************
+
+The driver has been tested on linux/x86 and sunos5.5/sparc.  In both
+cases the compiler was gcc.  When back in Paris, I will test it also
+on linux/alpha.
+
+
+Encodings
+*********
+
+The variety of encodings that accompanies pcf fonts appears to encompass the
+small set defined in freetype.h.  On the other hand, each pcf font defines
+two properties that specify encoding and registry.
+
+I decided to make these two properties directly accessible, leaving to the
+client application the work of interpreting them.  For instance:
+
+  #include "pcftypes.h"  /* include/freetype/internal/pcftypes.h */
+
+  FT_Face     face;
+  PCF_Public_Face  pcfface;
+
+  FT_New_Face( library,..., &face );
+
+  pcfface = (PCF_Public_Face)face;
+  
+  if ((pcfface->charset_registry == "ISO10646") && 
+        (pcfface->charset_encoding) == "1")) [..]
+
+Thus the driver always export ``ft_encoding_none'' as
+face->charmap.encoding.  FT_Get_Char_Index() behavior is unmodified, that
+is, it converts the ULong value given as argument into the corresponding
+glyph number.
+
+
+Known problems
+**************
+
+- dealing explicitly with encodings breaks the uniformity of freetype2
+  api.
+
+- except for encodings properties, client applications have no
+  visibility of the PCF_Face object.  This means that applications
+  cannot directly access font tables and are obliged to trust
+  FreeType.
+
+- currently, glyph names and ink_metrics are ignored.
+
+I plan to give full visibility of the PCF_Face object in the next
+release of the driver, thus implementing also glyph names and
+ink_metrics.
+
+- height is defined as (ascent - descent).  Is this correct?
+
+- if unable to read size informations from the font, PCF_Init_Face
+  sets available_size->width and available_size->height to 12.
+
+- too many english grammar errors in the readme file :-(
+
+
+License
+*******
+
+Copyright (C) 2000 by Francesco Zappa Nardelli
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+Credits
+*******
+
+Keith Packard wrote the pcf driver found in XFree86.  His work is at
+the same time the specification and the sample implementation of the
+PCF format.  Undoubtedly, this driver is inspired from his work.
--- /dev/null
+++ b/src/pcf/rules.mk
@@ -1,0 +1,79 @@
+#
+# FreeType 2 pcf driver configuration rules
+#
+
+
+# Copyright (C) 2000 by
+# Francesco Zappa Nardelli
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+
+# pcf driver directory
+#
+PCF_DIR  := $(SRC_)pcf
+PCF_DIR_ := $(PCF_DIR)$(SEP)
+
+
+PCF_COMPILE := $(FT_COMPILE)
+
+
+# pcf driver sources (i.e., C files)
+#
+PCF_DRV_SRC := $(PCF_DIR_)pcfread.c   \
+               $(PCF_DIR_)pcfdriver.c \
+               $(PCF_DIR_)pcfutil.c
+
+# pcf driver headers
+#
+PCF_DRV_H := $(PCF_DIR_)pcf.h       \
+             $(PCF_DIR_)pcfdriver.h \
+             $(PCF_DIR_)pcfutil.h
+
+# pcf driver object(s)
+#
+#   PCF_DRV_OBJ_M is used during `multi' builds
+#   PCF_DRV_OBJ_S is used during `single' builds
+#
+PCF_DRV_OBJ_M := $(PCF_DRV_SRC:$(PCF_DIR_)%.c=$(OBJ_)%.$O)
+PCF_DRV_OBJ_S := $(OBJ_)pcf.$O
+
+# Windows driver source file for single build
+#
+PCF_DRV_SRC_S := $(PCF_DIR_)pcf.c
+
+
+# pcf driver - single object
+#
+$(PCF_DRV_OBJ_S): $(PCF_DRV_SRC_S) $(PCF_DRV_SRC) $(FREETYPE_H) $(PCF_DRV_H)
+	$(PCF_COMPILE) $T$@ $(PCF_DRV_SRC_S)
+
+
+# pcf driver - multiple objects
+#
+$(OBJ_)%.$O: $(PCF_DIR_)%.c $(FREETYPE_H) $(PCF_DRV_H)
+	$(PCF_COMPILE) $T$@ $<
+
+
+# update main driver object lists
+#
+DRV_OBJS_S += $(PCF_DRV_OBJ_S)
+DRV_OBJS_M += $(PCF_DRV_OBJ_M)
+
+# EOF