/*  pcfdrivr.c

    FreeType font driver for pcf files

    Copyright (C) 2000-2004, 2006-2011, 2013, 2014 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_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H
#include FT_GZIP_H
#include FT_LZW_H
#include FT_BZIP2_H
#include FT_ERRORS_H
#include FT_BDF_H
#include FT_TRUETYPE_IDS_H

#include "pcf.h"
#include "pcfdrivr.h"
#include "pcfread.h"

#include "pcferror.h"
#include "pcfutil.h"

#undef  FT_COMPONENT
#define FT_COMPONENT  trace_pcfread

#include FT_SERVICE_BDF_H
#include FT_SERVICE_FONT_FORMAT_H
#include FT_SERVICE_PROPERTIES_H
#include FT_PCF_DRIVER_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


  typedef struct  PCF_CMapRec_
  {
    FT_CMapRec    root;
    FT_ULong      num_encodings;
    PCF_Encoding  encodings;

  } PCF_CMapRec, *PCF_CMap;


  FT_CALLBACK_DEF( FT_Error )
  pcf_cmap_init( FT_CMap     pcfcmap,   /* PCF_CMap */
                 FT_Pointer  init_data )
  {
    PCF_CMap  cmap = (PCF_CMap)pcfcmap;
    PCF_Face  face = (PCF_Face)FT_CMAP_FACE( pcfcmap );

    FT_UNUSED( init_data );


    cmap->num_encodings = face->nencodings;
    cmap->encodings     = face->encodings;

    return FT_Err_Ok;
  }


  FT_CALLBACK_DEF( void )
  pcf_cmap_done( FT_CMap  pcfcmap )         /* PCF_CMap */
  {
    PCF_CMap  cmap = (PCF_CMap)pcfcmap;


    cmap->encodings     = NULL;
    cmap->num_encodings = 0;
  }


  FT_CALLBACK_DEF( FT_UInt )
  pcf_cmap_char_index( FT_CMap    pcfcmap,  /* PCF_CMap */
                       FT_UInt32  charcode )
  {
    PCF_CMap      cmap      = (PCF_CMap)pcfcmap;
    PCF_Encoding  encodings = cmap->encodings;
    FT_ULong      min, max, mid;
    FT_UInt       result    = 0;


    min = 0;
    max = cmap->num_encodings;

    while ( min < max )
    {
      FT_ULong  code;


      mid  = ( min + max ) >> 1;
      code = (FT_ULong)encodings[mid].enc;

      if ( charcode == code )
      {
        result = encodings[mid].glyph + 1;
        break;
      }

      if ( charcode < code )
        max = mid;
      else
        min = mid + 1;
    }

    return result;
  }


  FT_CALLBACK_DEF( FT_UInt )
  pcf_cmap_char_next( FT_CMap    pcfcmap,   /* PCF_CMap */
                      FT_UInt32  *acharcode )
  {
    PCF_CMap      cmap      = (PCF_CMap)pcfcmap;
    PCF_Encoding  encodings = cmap->encodings;
    FT_ULong      min, max, mid;
    FT_ULong      charcode  = *acharcode + 1;
    FT_UInt       result    = 0;


    min = 0;
    max = cmap->num_encodings;

    while ( min < max )
    {
      FT_ULong  code;


      mid  = ( min + max ) >> 1;
      code = (FT_ULong)encodings[mid].enc;

      if ( charcode == code )
      {
        result = encodings[mid].glyph + 1;
        goto Exit;
      }

      if ( charcode < code )
        max = mid;
      else
        min = mid + 1;
    }

    charcode = 0;
    if ( min < cmap->num_encodings )
    {
      charcode = (FT_ULong)encodings[min].enc;
      result   = encodings[min].glyph + 1;
    }

  Exit:
    if ( charcode > 0xFFFFFFFFUL )
    {
      FT_TRACE1(( "pcf_cmap_char_next: charcode 0x%x > 32bit API" ));
      *acharcode = 0;
      /* XXX: result should be changed to indicate an overflow error */
    }
    else
      *acharcode = (FT_UInt32)charcode;
    return result;
  }


  static
  const FT_CMap_ClassRec  pcf_cmap_class =
  {
    sizeof ( PCF_CMapRec ),
    pcf_cmap_init,
    pcf_cmap_done,
    pcf_cmap_char_index,
    pcf_cmap_char_next,

    NULL, NULL, NULL, NULL, NULL
  };


  FT_CALLBACK_DEF( void )
  PCF_Face_Done( FT_Face  pcfface )         /* PCF_Face */
  {
    PCF_Face   face = (PCF_Face)pcfface;
    FT_Memory  memory;


    if ( !face )
      return;

    memory = FT_FACE_MEMORY( face );

    FT_FREE( face->encodings );
    FT_FREE( face->metrics );

    /* free properties */
    if ( face->properties )
    {
      FT_Int  i;


      for ( i = 0; i < face->nprops; i++ )
      {
        PCF_Property  prop = &face->properties[i];


        if ( prop )
        {
          FT_FREE( prop->name );
          if ( prop->isString )
            FT_FREE( prop->value.atom );
        }
      }

      FT_FREE( face->properties );
    }

    FT_FREE( face->toc.tables );
    FT_FREE( pcfface->family_name );
    FT_FREE( pcfface->style_name );
    FT_FREE( pcfface->available_sizes );
    FT_FREE( face->charset_encoding );
    FT_FREE( face->charset_registry );

    /* close compressed stream if any */
    if ( pcfface->stream == &face->comp_stream )
    {
      FT_Stream_Close( &face->comp_stream );
      pcfface->stream = face->comp_source;
    }
  }


  FT_CALLBACK_DEF( FT_Error )
  PCF_Face_Init( FT_Stream      stream,
                 FT_Face        pcfface,        /* PCF_Face */
                 FT_Int         face_index,
                 FT_Int         num_params,
                 FT_Parameter*  params )
  {
    PCF_Face  face  = (PCF_Face)pcfface;
    FT_Error  error;

    FT_UNUSED( num_params );
    FT_UNUSED( params );


    FT_TRACE2(( "PCF driver\n" ));

    error = pcf_load_font( stream, face, face_index );
    if ( error )
    {
      PCF_Face_Done( pcfface );

#if defined( FT_CONFIG_OPTION_USE_ZLIB )  || \
    defined( FT_CONFIG_OPTION_USE_LZW )   || \
    defined( FT_CONFIG_OPTION_USE_BZIP2 )

#ifdef FT_CONFIG_OPTION_USE_ZLIB
      {
        FT_Error  error2;


        /* this didn't work, try gzip support! */
        FT_TRACE2(( "  ... try gzip stream\n" ));
        error2 = FT_Stream_OpenGzip( &face->comp_stream, stream );
        if ( FT_ERR_EQ( error2, Unimplemented_Feature ) )
          goto Fail;

        error = error2;
      }
#endif /* FT_CONFIG_OPTION_USE_ZLIB */

#ifdef FT_CONFIG_OPTION_USE_LZW
      if ( error )
      {
        FT_Error  error3;


        /* this didn't work, try LZW support! */
        FT_TRACE2(( "  ... try LZW stream\n" ));
        error3 = FT_Stream_OpenLZW( &face->comp_stream, stream );
        if ( FT_ERR_EQ( error3, Unimplemented_Feature ) )
          goto Fail;

        error = error3;
      }
#endif /* FT_CONFIG_OPTION_USE_LZW */

#ifdef FT_CONFIG_OPTION_USE_BZIP2
      if ( error )
      {
        FT_Error  error4;


        /* this didn't work, try Bzip2 support! */
        FT_TRACE2(( "  ... try Bzip2 stream\n" ));
        error4 = FT_Stream_OpenBzip2( &face->comp_stream, stream );
        if ( FT_ERR_EQ( error4, Unimplemented_Feature ) )
          goto Fail;

        error = error4;
      }
#endif /* FT_CONFIG_OPTION_USE_BZIP2 */

      if ( error )
        goto Fail;

      face->comp_source = stream;
      pcfface->stream   = &face->comp_stream;

      stream = pcfface->stream;

      error = pcf_load_font( stream, face, face_index );
      if ( error )
        goto Fail;

#else /* !(FT_CONFIG_OPTION_USE_ZLIB ||
           FT_CONFIG_OPTION_USE_LZW ||
           FT_CONFIG_OPTION_USE_BZIP2) */

      goto Fail;

#endif
    }

    /* PCF cannot have multiple faces in a single font file.
     * XXX: A non-zero face_index is already an invalid argument, but
     *      Type1, Type42 drivers have a convention to return
     *      an invalid argument error when the font could be
     *      opened by the specified driver.
     */
    if ( face_index < 0 )
      goto Exit;
    else if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 )
    {
      FT_ERROR(( "PCF_Face_Init: invalid face index\n" ));
      PCF_Face_Done( pcfface );
      return FT_THROW( Invalid_Argument );
    }

    /* set up charmap */
    {
      FT_String  *charset_registry = face->charset_registry;
      FT_String  *charset_encoding = face->charset_encoding;
      FT_Bool     unicode_charmap  = 0;


      if ( charset_registry && charset_encoding )
      {
        char*  s = charset_registry;


        /* Uh, oh, compare first letters manually to avoid dependency
           on locales. */
        if ( ( s[0] == 'i' || s[0] == 'I' ) &&
             ( s[1] == 's' || s[1] == 'S' ) &&
             ( s[2] == 'o' || s[2] == 'O' ) )
        {
          s += 3;
          if ( !ft_strcmp( s, "10646" )                      ||
               ( !ft_strcmp( s, "8859" ) &&
                 !ft_strcmp( face->charset_encoding, "1" ) ) )
          unicode_charmap = 1;
        }
      }

      {
        FT_CharMapRec  charmap;


        charmap.face        = FT_FACE( face );
        charmap.encoding    = FT_ENCODING_NONE;
        /* initial platform/encoding should indicate unset status? */
        charmap.platform_id = TT_PLATFORM_APPLE_UNICODE;
        charmap.encoding_id = TT_APPLE_ID_DEFAULT;

        if ( unicode_charmap )
        {
          charmap.encoding    = FT_ENCODING_UNICODE;
          charmap.platform_id = TT_PLATFORM_MICROSOFT;
          charmap.encoding_id = TT_MS_ID_UNICODE_CS;
        }

        error = FT_CMap_New( &pcf_cmap_class, NULL, &charmap, NULL );

#if 0
        /* Select default charmap */
        if ( pcfface->num_charmaps )
          pcfface->charmap = pcfface->charmaps[0];
#endif
      }
    }

  Exit:
    return error;

  Fail:
    FT_TRACE2(( "  not a PCF file\n" ));
    PCF_Face_Done( pcfface );
    error = FT_THROW( Unknown_File_Format );  /* error */
    goto Exit;
  }


  FT_CALLBACK_DEF( FT_Error )
  PCF_Size_Select( FT_Size   size,
                   FT_ULong  strike_index )
  {
    PCF_Accel  accel = &( (PCF_Face)size->face )->accel;


    FT_Select_Metrics( size->face, strike_index );

    size->metrics.ascender    =  accel->fontAscent * 64;
    size->metrics.descender   = -accel->fontDescent * 64;
    size->metrics.max_advance =  accel->maxbounds.characterWidth * 64;

    return FT_Err_Ok;
  }


  FT_CALLBACK_DEF( FT_Error )
  PCF_Size_Request( FT_Size          size,
                    FT_Size_Request  req )
  {
    PCF_Face         face  = (PCF_Face)size->face;
    FT_Bitmap_Size*  bsize = size->face->available_sizes;
    FT_Error         error = FT_ERR( Invalid_Pixel_Size );
    FT_Long          height;


    height = FT_REQUEST_HEIGHT( req );
    height = ( height + 32 ) >> 6;

    switch ( req->type )
    {
    case FT_SIZE_REQUEST_TYPE_NOMINAL:
      if ( height == ( ( bsize->y_ppem + 32 ) >> 6 ) )
        error = FT_Err_Ok;
      break;

    case FT_SIZE_REQUEST_TYPE_REAL_DIM:
      if ( height == ( face->accel.fontAscent +
                       face->accel.fontDescent ) )
        error = FT_Err_Ok;
      break;

    default:
      error = FT_THROW( Unimplemented_Feature );
      break;
    }

    if ( error )
      return error;
    else
      return PCF_Size_Select( size, 0 );
  }


  FT_CALLBACK_DEF( FT_Error )
  PCF_Glyph_Load( FT_GlyphSlot  slot,
                  FT_Size       size,
                  FT_UInt       glyph_index,
                  FT_Int32      load_flags )
  {
    PCF_Face    face   = (PCF_Face)FT_SIZE_FACE( size );
    FT_Stream   stream;
    FT_Error    error  = FT_Err_Ok;
    FT_Bitmap*  bitmap = &slot->bitmap;
    PCF_Metric  metric;
    FT_ULong    bytes;


    FT_TRACE1(( "PCF_Glyph_Load: glyph index %d\n", glyph_index ));

    if ( !face )
    {
      error = FT_THROW( Invalid_Face_Handle );
      goto Exit;
    }

    if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

    stream = face->root.stream;

    if ( glyph_index > 0 )
      glyph_index--;

    metric = face->metrics + glyph_index;

    bitmap->rows       = (unsigned int)( metric->ascent +
                                         metric->descent );
    bitmap->width      = (unsigned int)( metric->rightSideBearing -
                                         metric->leftSideBearing );
    bitmap->num_grays  = 1;
    bitmap->pixel_mode = FT_PIXEL_MODE_MONO;

    switch ( PCF_GLYPH_PAD( face->bitmapsFormat ) )
    {
    case 1:
      bitmap->pitch = (int)( ( bitmap->width + 7 ) >> 3 );
      break;

    case 2:
      bitmap->pitch = (int)( ( ( bitmap->width + 15 ) >> 4 ) << 1 );
      break;

    case 4:
      bitmap->pitch = (int)( ( ( bitmap->width + 31 ) >> 5 ) << 2 );
      break;

    case 8:
      bitmap->pitch = (int)( ( ( bitmap->width + 63 ) >> 6 ) << 3 );
      break;

    default:
      return FT_THROW( Invalid_File_Format );
    }

    slot->format      = FT_GLYPH_FORMAT_BITMAP;
    slot->bitmap_left = metric->leftSideBearing;
    slot->bitmap_top  = metric->ascent;

    slot->metrics.horiAdvance  = (FT_Pos)( metric->characterWidth * 64 );
    slot->metrics.horiBearingX = (FT_Pos)( metric->leftSideBearing * 64 );
    slot->metrics.horiBearingY = (FT_Pos)( metric->ascent * 64 );
    slot->metrics.width        = (FT_Pos)( ( metric->rightSideBearing -
                                             metric->leftSideBearing ) * 64 );
    slot->metrics.height       = (FT_Pos)( bitmap->rows * 64 );

    ft_synthesize_vertical_metrics( &slot->metrics,
                                    ( face->accel.fontAscent +
                                      face->accel.fontDescent ) * 64 );

    if ( load_flags & FT_LOAD_BITMAP_METRICS_ONLY )
      goto Exit;

    /* XXX: to do: are there cases that need repadding the bitmap? */
    bytes = (FT_ULong)bitmap->pitch * bitmap->rows;

    error = ft_glyphslot_alloc_bitmap( slot, (FT_ULong)bytes );
    if ( error )
      goto Exit;

    if ( FT_STREAM_SEEK( metric->bits )          ||
         FT_STREAM_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;
      }
    }

  Exit:
    return error;
  }


 /*
  *
  *  BDF SERVICE
  *
  */

  static FT_Error
  pcf_get_bdf_property( PCF_Face          face,
                        const char*       prop_name,
                        BDF_PropertyRec  *aproperty )
  {
    PCF_Property  prop;


    prop = pcf_find_property( face, prop_name );
    if ( prop )
    {
      if ( prop->isString )
      {
        aproperty->type   = BDF_PROPERTY_TYPE_ATOM;
        aproperty->u.atom = prop->value.atom;
      }
      else
      {
        if ( prop->value.l > 0x7FFFFFFFL          ||
             prop->value.l < ( -1 - 0x7FFFFFFFL ) )
        {
          FT_TRACE1(( "pcf_get_bdf_property:" ));
          FT_TRACE1(( " too large integer 0x%x is truncated\n" ));
        }

        /*
         *  The PCF driver loads all properties as signed integers.
         *  This really doesn't seem to be a problem, because this is
         *  sufficient for any meaningful values.
         */
        aproperty->type      = BDF_PROPERTY_TYPE_INTEGER;
        aproperty->u.integer = (FT_Int32)prop->value.l;
      }

      return FT_Err_Ok;
    }

    return FT_THROW( Invalid_Argument );
  }


  static FT_Error
  pcf_get_charset_id( PCF_Face      face,
                      const char*  *acharset_encoding,
                      const char*  *acharset_registry )
  {
    *acharset_encoding = face->charset_encoding;
    *acharset_registry = face->charset_registry;

    return FT_Err_Ok;
  }


  static const FT_Service_BDFRec  pcf_service_bdf =
  {
    (FT_BDF_GetCharsetIdFunc)pcf_get_charset_id,     /* get_charset_id */
    (FT_BDF_GetPropertyFunc) pcf_get_bdf_property    /* get_property   */
  };


  /*
   *  PROPERTY SERVICE
   *
   */
  static FT_Error
  pcf_property_set( FT_Module    module,         /* PCF_Driver */
                    const char*  property_name,
                    const void*  value,
                    FT_Bool      value_is_string )
  {
#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES

    FT_Error    error  = FT_Err_Ok;
    PCF_Driver  driver = (PCF_Driver)module;

#ifndef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
    FT_UNUSED( value_is_string );
#endif


    if ( !ft_strcmp( property_name, "no-long-family-names" ) )
    {
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
      if ( value_is_string )
      {
        const char*  s   = (const char*)value;
        long         lfn = ft_strtol( s, NULL, 10 );


        if ( lfn == 0 )
          driver->no_long_family_names = 0;
        else if ( lfn == 1 )
          driver->no_long_family_names = 1;
        else
          return FT_THROW( Invalid_Argument );
      }
      else
#endif
      {
        FT_Bool*  no_long_family_names = (FT_Bool*)value;


        driver->no_long_family_names = *no_long_family_names;
      }

      return error;
    }

#else /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */

    FT_UNUSED( module );
    FT_UNUSED( value );
    FT_UNUSED( value_is_string );
#ifndef FT_DEBUG_LEVEL_TRACE
    FT_UNUSED( property_name );
#endif

#endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */

    FT_TRACE0(( "pcf_property_set: missing property `%s'\n",
                property_name ));
    return FT_THROW( Missing_Property );
  }


  static FT_Error
  pcf_property_get( FT_Module    module,         /* PCF_Driver */
                    const char*  property_name,
                    const void*  value )
  {
#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES

    FT_Error    error  = FT_Err_Ok;
    PCF_Driver  driver = (PCF_Driver)module;


    if ( !ft_strcmp( property_name, "no-long-family-names" ) )
    {
      FT_Bool   no_long_family_names = driver->no_long_family_names;
      FT_Bool*  val                  = (FT_Bool*)value;


      *val = no_long_family_names;

      return error;
    }

#else /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */

    FT_UNUSED( module );
    FT_UNUSED( value );
#ifndef FT_DEBUG_LEVEL_TRACE
    FT_UNUSED( property_name );
#endif

#endif /* !PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */

    FT_TRACE0(( "pcf_property_get: missing property `%s'\n",
                property_name ));
    return FT_THROW( Missing_Property );
  }


  FT_DEFINE_SERVICE_PROPERTIESREC(
    pcf_service_properties,

    (FT_Properties_SetFunc)pcf_property_set,      /* set_property */
    (FT_Properties_GetFunc)pcf_property_get )     /* get_property */


 /*
  *
  *  SERVICE LIST
  *
  */

  static const FT_ServiceDescRec  pcf_services[] =
  {
    { FT_SERVICE_ID_BDF,         &pcf_service_bdf },
    { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PCF },
    { FT_SERVICE_ID_PROPERTIES,  &pcf_service_properties },
    { NULL, NULL }
  };


  FT_CALLBACK_DEF( FT_Module_Interface )
  pcf_driver_requester( FT_Module    module,
                        const char*  name )
  {
    FT_UNUSED( module );

    return ft_service_list_lookup( pcf_services, name );
  }


  FT_CALLBACK_DEF( FT_Error )
  pcf_driver_init( FT_Module  module )      /* PCF_Driver */
  {
#ifdef PCF_CONFIG_OPTION_LONG_FAMILY_NAMES
    PCF_Driver  driver = (PCF_Driver)module;


    driver->no_long_family_names = 0;
#else
    FT_UNUSED( module );
#endif

    return FT_Err_Ok;
  }


  FT_CALLBACK_DEF( void )
  pcf_driver_done( FT_Module  module )      /* PCF_Driver */
  {
    FT_UNUSED( module );
  }


  FT_CALLBACK_TABLE_DEF
  const FT_Driver_ClassRec  pcf_driver_class =
  {
    {
      FT_MODULE_FONT_DRIVER        |
      FT_MODULE_DRIVER_NO_OUTLINES,

      sizeof ( PCF_DriverRec ),
      "pcf",
      0x10000L,
      0x20000L,

      NULL,   /* module-specific interface */

      pcf_driver_init,          /* FT_Module_Constructor  module_init   */
      pcf_driver_done,          /* FT_Module_Destructor   module_done   */
      pcf_driver_requester      /* FT_Module_Requester    get_interface */
    },

    sizeof ( PCF_FaceRec ),
    sizeof ( FT_SizeRec ),
    sizeof ( FT_GlyphSlotRec ),

    PCF_Face_Init,              /* FT_Face_InitFunc  init_face */
    PCF_Face_Done,              /* FT_Face_DoneFunc  done_face */
    NULL,                       /* FT_Size_InitFunc  init_size */
    NULL,                       /* FT_Size_DoneFunc  done_size */
    NULL,                       /* FT_Slot_InitFunc  init_slot */
    NULL,                       /* FT_Slot_DoneFunc  done_slot */

    PCF_Glyph_Load,             /* FT_Slot_LoadFunc  load_glyph */

    NULL,                       /* FT_Face_GetKerningFunc   get_kerning  */
    NULL,                       /* FT_Face_AttachFunc       attach_file  */
    NULL,                       /* FT_Face_GetAdvancesFunc  get_advances */

    PCF_Size_Request,           /* FT_Size_RequestFunc  request_size */
    PCF_Size_Select             /* FT_Size_SelectFunc   select_size  */
  };


/* END */
