/***************************************************************************/
/*                                                                         */
/*  winfnt.c                                                               */
/*                                                                         */
/*    FreeType font driver for Windows FNT/FON files                       */
/*                                                                         */
/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007, 2008 by             */
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*  Copyright 2003 Huw D M Davies for Codeweavers                          */
/*  Copyright 2007 Dmitry Timoshkov for Codeweavers                        */
/*                                                                         */
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/***************************************************************************/


#include <ft2build.h>
#include FT_WINFONTS_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H

#include "winfnt.h"
#include "fnterrs.h"
#include FT_SERVICE_WINFNT_H
#include FT_SERVICE_XFREE86_NAME_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_winfnt


  static const FT_Frame_Field  winmz_header_fields[] =
  {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  WinMZ_HeaderRec

    FT_FRAME_START( 64 ),
      FT_FRAME_USHORT_LE ( magic ),
      FT_FRAME_SKIP_BYTES( 29 * 2 ),
      FT_FRAME_ULONG_LE  ( lfanew ),
    FT_FRAME_END
  };

  static const FT_Frame_Field  winne_header_fields[] =
  {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  WinNE_HeaderRec

    FT_FRAME_START( 40 ),
      FT_FRAME_USHORT_LE ( magic ),
      FT_FRAME_SKIP_BYTES( 34 ),
      FT_FRAME_USHORT_LE ( resource_tab_offset ),
      FT_FRAME_USHORT_LE ( rname_tab_offset ),
    FT_FRAME_END
  };

  static const FT_Frame_Field  winpe32_header_fields[] =
  {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  WinPE32_HeaderRec

    FT_FRAME_START( 248 ),
      FT_FRAME_ULONG_LE  ( magic ),   /* PE00 */
      FT_FRAME_USHORT_LE ( machine ), /* 0x014c - i386 */
      FT_FRAME_USHORT_LE ( number_of_sections ),
      FT_FRAME_SKIP_BYTES( 12 ),
      FT_FRAME_USHORT_LE ( size_of_optional_header ),
      FT_FRAME_SKIP_BYTES( 2 ),
      FT_FRAME_USHORT_LE ( magic32 ), /* 0x10b */
      FT_FRAME_SKIP_BYTES( 110 ),
      FT_FRAME_ULONG_LE  ( rsrc_virtual_address ),
      FT_FRAME_ULONG_LE  ( rsrc_size ),
      FT_FRAME_SKIP_BYTES( 104 ),
    FT_FRAME_END
  };

  static const FT_Frame_Field  winpe32_section_fields[] =
  {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  WinPE32_SectionRec

    FT_FRAME_START( 40 ),
      FT_FRAME_BYTES     ( name, 8 ),
      FT_FRAME_SKIP_BYTES( 4 ),
      FT_FRAME_ULONG_LE  ( virtual_address ),
      FT_FRAME_ULONG_LE  ( size_of_raw_data ),
      FT_FRAME_ULONG_LE  ( pointer_to_raw_data ),
      FT_FRAME_SKIP_BYTES( 16 ),
    FT_FRAME_END
  };

  static const FT_Frame_Field  winpe_rsrc_dir_fields[] =
  {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  WinPE_RsrcDirRec

    FT_FRAME_START( 16 ),
      FT_FRAME_ULONG_LE ( characteristics ),
      FT_FRAME_ULONG_LE ( time_date_stamp ),
      FT_FRAME_USHORT_LE( major_version ),
      FT_FRAME_USHORT_LE( minor_version ),
      FT_FRAME_USHORT_LE( number_of_named_entries ),
      FT_FRAME_USHORT_LE( number_of_id_entries ),
    FT_FRAME_END
  };

  static const FT_Frame_Field  winpe_rsrc_dir_entry_fields[] =
  {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  WinPE_RsrcDirEntryRec

    FT_FRAME_START( 8 ),
      FT_FRAME_ULONG_LE( name ),
      FT_FRAME_ULONG_LE( offset ),
    FT_FRAME_END
  };

  static const FT_Frame_Field  winpe_rsrc_data_entry_fields[] =
  {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  WinPE_RsrcDataEntryRec

    FT_FRAME_START( 16 ),
      FT_FRAME_ULONG_LE( offset_to_data ),
      FT_FRAME_ULONG_LE( size ),
      FT_FRAME_ULONG_LE( code_page ),
      FT_FRAME_ULONG_LE( reserved ),
    FT_FRAME_END
  };

  static const FT_Frame_Field  winfnt_header_fields[] =
  {
#undef  FT_STRUCTURE
#define FT_STRUCTURE  FT_WinFNT_HeaderRec

    FT_FRAME_START( 148 ),
      FT_FRAME_USHORT_LE( version ),
      FT_FRAME_ULONG_LE ( file_size ),
      FT_FRAME_BYTES    ( copyright, 60 ),
      FT_FRAME_USHORT_LE( file_type ),
      FT_FRAME_USHORT_LE( nominal_point_size ),
      FT_FRAME_USHORT_LE( vertical_resolution ),
      FT_FRAME_USHORT_LE( horizontal_resolution ),
      FT_FRAME_USHORT_LE( ascent ),
      FT_FRAME_USHORT_LE( internal_leading ),
      FT_FRAME_USHORT_LE( external_leading ),
      FT_FRAME_BYTE     ( italic ),
      FT_FRAME_BYTE     ( underline ),
      FT_FRAME_BYTE     ( strike_out ),
      FT_FRAME_USHORT_LE( weight ),
      FT_FRAME_BYTE     ( charset ),
      FT_FRAME_USHORT_LE( pixel_width ),
      FT_FRAME_USHORT_LE( pixel_height ),
      FT_FRAME_BYTE     ( pitch_and_family ),
      FT_FRAME_USHORT_LE( avg_width ),
      FT_FRAME_USHORT_LE( max_width ),
      FT_FRAME_BYTE     ( first_char ),
      FT_FRAME_BYTE     ( last_char ),
      FT_FRAME_BYTE     ( default_char ),
      FT_FRAME_BYTE     ( break_char ),
      FT_FRAME_USHORT_LE( bytes_per_row ),
      FT_FRAME_ULONG_LE ( device_offset ),
      FT_FRAME_ULONG_LE ( face_name_offset ),
      FT_FRAME_ULONG_LE ( bits_pointer ),
      FT_FRAME_ULONG_LE ( bits_offset ),
      FT_FRAME_BYTE     ( reserved ),
      FT_FRAME_ULONG_LE ( flags ),
      FT_FRAME_USHORT_LE( A_space ),
      FT_FRAME_USHORT_LE( B_space ),
      FT_FRAME_USHORT_LE( C_space ),
      FT_FRAME_ULONG_LE ( color_table_offset ),
      FT_FRAME_BYTES    ( reserved1, 16 ),
    FT_FRAME_END
  };


  static void
  fnt_font_done( FNT_Face face )
  {
    FT_Memory  memory = FT_FACE( face )->memory;
    FT_Stream  stream = FT_FACE( face )->stream;
    FNT_Font   font   = face->font;


    if ( !font )
      return;

    if ( font->fnt_frame )
      FT_FRAME_RELEASE( font->fnt_frame );
    FT_FREE( font->family_name );

    FT_FREE( font );
    face->font = 0;
  }


  static FT_Error
  fnt_font_load( FNT_Font   font,
                 FT_Stream  stream )
  {
    FT_Error          error;
    FT_WinFNT_Header  header = &font->header;
    FT_Bool           new_format;
    FT_UInt           size;


    /* first of all, read the FNT header */
    if ( FT_STREAM_SEEK( font->offset )                        ||
         FT_STREAM_READ_FIELDS( winfnt_header_fields, header ) )
      goto Exit;

    /* check header */
    if ( header->version != 0x200 &&
         header->version != 0x300 )
    {
      FT_TRACE2(( "[not a valid FNT file]\n" ));
      error = FNT_Err_Unknown_File_Format;
      goto Exit;
    }

    new_format = FT_BOOL( font->header.version == 0x300 );
    size       = new_format ? 148 : 118;

    if ( header->file_size < size )
    {
      FT_TRACE2(( "[not a valid FNT file]\n" ));
      error = FNT_Err_Unknown_File_Format;
      goto Exit;
    }

    /* Version 2 doesn't have these fields */
    if ( header->version == 0x200 )
    {
      header->flags   = 0;
      header->A_space = 0;
      header->B_space = 0;
      header->C_space = 0;

      header->color_table_offset = 0;
    }

    if ( header->file_type & 1 )
    {
      FT_TRACE2(( "[can't handle vector FNT fonts]\n" ));
      error = FNT_Err_Unknown_File_Format;
      goto Exit;
    }

    /* this is a FNT file/table; extract its frame */
    if ( FT_STREAM_SEEK( font->offset )                         ||
         FT_FRAME_EXTRACT( header->file_size, font->fnt_frame ) )
      goto Exit;

  Exit:
    return error;
  }


  static FT_Error
  fnt_face_get_dll_font( FNT_Face  face,
                         FT_Int    face_index )
  {
    FT_Error         error;
    FT_Stream        stream = FT_FACE( face )->stream;
    FT_Memory        memory = FT_FACE( face )->memory;
    WinMZ_HeaderRec  mz_header;


    face->font = 0;

    /* does it begin with an MZ header? */
    if ( FT_STREAM_SEEK( 0 )                                      ||
         FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) )
      goto Exit;

    error = FNT_Err_Unknown_File_Format;
    if ( mz_header.magic == WINFNT_MZ_MAGIC )
    {
      /* yes, now look for an NE header in the file */
      WinNE_HeaderRec  ne_header;


      FT_TRACE2(( "MZ signature found\n" ));

      if ( FT_STREAM_SEEK( mz_header.lfanew )                       ||
           FT_STREAM_READ_FIELDS( winne_header_fields, &ne_header ) )
        goto Exit;

      error = FNT_Err_Unknown_File_Format;
      if ( ne_header.magic == WINFNT_NE_MAGIC )
      {
        /* good, now look into the resource table for each FNT resource */
        FT_ULong   res_offset  = mz_header.lfanew +
                                   ne_header.resource_tab_offset;
        FT_UShort  size_shift;
        FT_UShort  font_count  = 0;
        FT_ULong   font_offset = 0;


        FT_TRACE2(( "NE signature found\n" ));

        if ( FT_STREAM_SEEK( res_offset )                    ||
             FT_FRAME_ENTER( ne_header.rname_tab_offset -
                             ne_header.resource_tab_offset ) )
          goto Exit;

        size_shift = FT_GET_USHORT_LE();

        for (;;)
        {
          FT_UShort  type_id, count;


          type_id = FT_GET_USHORT_LE();
          if ( !type_id )
            break;

          count = FT_GET_USHORT_LE();

          if ( type_id == 0x8008U )
          {
            font_count  = count;
            font_offset = (FT_ULong)( FT_STREAM_POS() + 4 +
                                      ( stream->cursor - stream->limit ) );
            break;
          }

          stream->cursor += 4 + count * 12;
        }

        FT_FRAME_EXIT();

        if ( !font_count || !font_offset )
        {
          FT_TRACE2(( "this file doesn't contain any FNT resources!\n" ));
          error = FNT_Err_Invalid_File_Format;
          goto Exit;
        }

        /* loading `winfnt_header_fields' needs at least 118 bytes;    */
        /* use this as a rough measure to check the expected font size */
        if ( font_count * 118UL > stream->size )
        {
          FT_TRACE2(( "invalid number of faces\n" ));
          error = FNT_Err_Invalid_File_Format;
          goto Exit;
        }

        face->root.num_faces = font_count;

        if ( face_index >= font_count )
        {
          error = FNT_Err_Bad_Argument;
          goto Exit;
        }
        else if ( face_index < 0 )
          goto Exit;

        if ( FT_NEW( face->font ) )
          goto Exit;

        if ( FT_STREAM_SEEK( font_offset + face_index * 12 ) ||
             FT_FRAME_ENTER( 12 )                            )
          goto Fail;

        face->font->offset   = (FT_ULong)FT_GET_USHORT_LE() << size_shift;
        face->font->fnt_size = (FT_ULong)FT_GET_USHORT_LE() << size_shift;

        stream->cursor += 8;

        FT_FRAME_EXIT();

        error = fnt_font_load( face->font, stream );
      }
      else if ( ne_header.magic == WINFNT_PE_MAGIC )
      {
        WinPE32_HeaderRec       pe32_header;
        WinPE32_SectionRec      pe32_section;
        WinPE_RsrcDirRec        root_dir, name_dir, lang_dir;
        WinPE_RsrcDirEntryRec   dir_entry1, dir_entry2, dir_entry3;
        WinPE_RsrcDataEntryRec  data_entry;

        FT_Long    root_dir_offset, name_dir_offset, lang_dir_offset;
        FT_UShort  i, j, k;


        FT_TRACE2(( "PE signature found\n" ));

        if ( FT_STREAM_SEEK( mz_header.lfanew )                           ||
             FT_STREAM_READ_FIELDS( winpe32_header_fields, &pe32_header ) )
          goto Exit;

        FT_TRACE2(( "magic %04lx, machine %02x, number_of_sections %u, "
                    "size_of_optional_header %02x\n"
                    "magic32 %02x, rsrc_virtual_address %04lx, "
                    "rsrc_size %04lx\n",
                    pe32_header.magic, pe32_header.machine,
                    pe32_header.number_of_sections,
                    pe32_header.size_of_optional_header,
                    pe32_header.magic32, pe32_header.rsrc_virtual_address,
                    pe32_header.rsrc_size ));

        if ( pe32_header.magic != WINFNT_PE_MAGIC /* check full signature */ ||
             pe32_header.machine != 0x014c /* i386 */                        ||
             pe32_header.size_of_optional_header != 0xe0 /* FIXME */         ||
             pe32_header.magic32 != 0x10b                                    )
        {
          FT_TRACE2(( "this file has an invalid PE header\n" ));
          error = FNT_Err_Invalid_File_Format;
          goto Exit;
        }

        face->root.num_faces = 0;

        for ( i = 0; i < pe32_header.number_of_sections; i++ )
        {
          if ( FT_STREAM_READ_FIELDS( winpe32_section_fields,
                                      &pe32_section ) )
            goto Exit;

          FT_TRACE2(( "name %.8s, va %04lx, size %04lx, offset %04lx\n",
                      pe32_section.name, pe32_section.virtual_address,
                      pe32_section.size_of_raw_data,
                      pe32_section.pointer_to_raw_data ));

          if ( pe32_header.rsrc_virtual_address ==
                 pe32_section.virtual_address )
            goto Found_rsrc_section;
        }

        FT_TRACE2(( "this file doesn't contain any resources\n" ));
        error = FNT_Err_Invalid_File_Format;
        goto Exit;

      Found_rsrc_section:
        FT_TRACE2(( "found resources section %.8s\n", pe32_section.name ));

        if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data )        ||
             FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &root_dir ) )
          goto Exit;

        root_dir_offset = pe32_section.pointer_to_raw_data;

        for ( i = 0; i < root_dir.number_of_named_entries +
                           root_dir.number_of_id_entries; i++ )
        {
          if ( FT_STREAM_SEEK( root_dir_offset + 16 + i * 8 )      ||
               FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,
                                      &dir_entry1 )                )
            goto Exit;

          if ( !(dir_entry1.offset & 0x80000000UL ) /* DataIsDirectory */ )
          {
            error = FNT_Err_Invalid_File_Format;
            goto Exit;
          }

          dir_entry1.offset &= ~0x80000000UL;

          name_dir_offset = pe32_section.pointer_to_raw_data +
                            dir_entry1.offset;

          if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data +
                               dir_entry1.offset )                       ||
               FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &name_dir ) )
            goto Exit;

          for ( j = 0; j < name_dir.number_of_named_entries +
                             name_dir.number_of_id_entries; j++ )
          {
            if ( FT_STREAM_SEEK( name_dir_offset + 16 + j * 8 )      ||
                 FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,
                                        &dir_entry2 )                )
              goto Exit;

            if ( !(dir_entry2.offset & 0x80000000UL ) /* DataIsDirectory */ )
            {
              error = FNT_Err_Invalid_File_Format;
              goto Exit;
            }

            dir_entry2.offset &= ~0x80000000UL;

            lang_dir_offset = pe32_section.pointer_to_raw_data +
                                dir_entry2.offset;

            if ( FT_STREAM_SEEK( pe32_section.pointer_to_raw_data +
                                   dir_entry2.offset )                     ||
                 FT_STREAM_READ_FIELDS( winpe_rsrc_dir_fields, &lang_dir ) )
              goto Exit;

            for ( k = 0; k < lang_dir.number_of_named_entries +
                               lang_dir.number_of_id_entries; k++ )
            {
              if ( FT_STREAM_SEEK( lang_dir_offset + 16 + k * 8 )      ||
                   FT_STREAM_READ_FIELDS( winpe_rsrc_dir_entry_fields,
                                          &dir_entry3 )                )
                goto Exit;

              if ( dir_entry2.offset & 0x80000000UL /* DataIsDirectory */ )
              {
                error = FNT_Err_Invalid_File_Format;
                goto Exit;
              }

              if ( dir_entry1.name == 8 /* RT_FONT */ )
              {
                if ( FT_STREAM_SEEK( root_dir_offset + dir_entry3.offset ) ||
                     FT_STREAM_READ_FIELDS( winpe_rsrc_data_entry_fields,
                                            &data_entry )                  )
                  goto Exit;

                FT_TRACE2(( "found font #%lu, offset %04lx, "
                            "size %04lx, cp %lu\n",
                            dir_entry2.name,
                            pe32_section.pointer_to_raw_data +
                              data_entry.offset_to_data -
                              pe32_section.virtual_address,
                            data_entry.size, data_entry.code_page ));

                if ( face_index == face->root.num_faces )
                {
                  if ( FT_NEW( face->font ) )
                    goto Exit;

                  face->font->offset   = pe32_section.pointer_to_raw_data +
                                           data_entry.offset_to_data -
                                           pe32_section.virtual_address;
                  face->font->fnt_size = data_entry.size;

                  error = fnt_font_load( face->font, stream );
                  if ( error )
                  {
                    FT_TRACE2(( "font #%lu load error %d\n",
                                dir_entry2.name, error ));
                    goto Fail;
                  }
                  else
                    FT_TRACE2(( "font #%lu successfully loaded\n",
                                dir_entry2.name ));
                }

                face->root.num_faces++;
              }
            }
          }
        }
      }

      if ( !face->root.num_faces )
      {
        FT_TRACE2(( "this file doesn't contain any RT_FONT resources\n" ));
        error = FNT_Err_Invalid_File_Format;
        goto Exit;
      }

      if ( face_index >= face->root.num_faces )
      {
        error = FNT_Err_Bad_Argument;
        goto Exit;
      }
    }

  Fail:
    if ( error )
      fnt_font_done( face );

  Exit:
    return error;
  }


  typedef struct  FNT_CMapRec_
  {
    FT_CMapRec  cmap;
    FT_UInt32   first;
    FT_UInt32   count;

  } FNT_CMapRec, *FNT_CMap;


  static FT_Error
  fnt_cmap_init( FNT_CMap  cmap )
  {
    FNT_Face  face = (FNT_Face)FT_CMAP_FACE( cmap );
    FNT_Font  font = face->font;


    cmap->first = (FT_UInt32)  font->header.first_char;
    cmap->count = (FT_UInt32)( font->header.last_char - cmap->first + 1 );

    return 0;
  }


  static FT_UInt
  fnt_cmap_char_index( FNT_CMap   cmap,
                       FT_UInt32  char_code )
  {
    FT_UInt  gindex = 0;


    char_code -= cmap->first;
    if ( char_code < cmap->count )
      gindex = char_code + 1; /* we artificially increase the glyph index; */
                              /* FNT_Load_Glyph reverts to the right one   */
    return gindex;
  }


  static FT_UInt
  fnt_cmap_char_next( FNT_CMap    cmap,
                      FT_UInt32  *pchar_code )
  {
    FT_UInt    gindex = 0;
    FT_UInt32  result = 0;
    FT_UInt32  char_code = *pchar_code + 1;


    if ( char_code <= cmap->first )
    {
      result = cmap->first;
      gindex = 1;
    }
    else
    {
      char_code -= cmap->first;
      if ( char_code < cmap->count )
      {
        result = cmap->first + char_code;
        gindex = char_code + 1;
      }
    }

    *pchar_code = result;
    return gindex;
  }


  static const FT_CMap_ClassRec  fnt_cmap_class_rec =
  {
    sizeof ( FNT_CMapRec ),

    (FT_CMap_InitFunc)     fnt_cmap_init,
    (FT_CMap_DoneFunc)     NULL,
    (FT_CMap_CharIndexFunc)fnt_cmap_char_index,
    (FT_CMap_CharNextFunc) fnt_cmap_char_next,

    NULL, NULL, NULL, NULL, NULL
  };

  static FT_CMap_Class const  fnt_cmap_class = &fnt_cmap_class_rec;


  static void
  FNT_Face_Done( FNT_Face  face )
  {
    FT_Memory  memory;


    if ( !face )
      return;

    memory = FT_FACE_MEMORY( face );

    fnt_font_done( face );

    FT_FREE( face->root.available_sizes );
    face->root.num_fixed_sizes = 0;
  }


  static FT_Error
  FNT_Face_Init( FT_Stream      stream,
                 FNT_Face       face,
                 FT_Int         face_index,
                 FT_Int         num_params,
                 FT_Parameter*  params )
  {
    FT_Error   error;
    FT_Memory  memory = FT_FACE_MEMORY( face );

    FT_UNUSED( num_params );
    FT_UNUSED( params );


    /* try to load font from a DLL */
    error = fnt_face_get_dll_font( face, face_index );
    if ( !error && face_index < 0 )
      goto Exit;

    if ( error == FNT_Err_Unknown_File_Format )
    {
      /* this didn't work; try to load a single FNT font */
      FNT_Font  font;

      if ( FT_NEW( face->font ) )
        goto Exit;

      face->root.num_faces = 1;

      font           = face->font;
      font->offset   = 0;
      font->fnt_size = stream->size;

      error = fnt_font_load( font, stream );

      if ( !error )
      {
        if ( face_index > 0 )
          error = FNT_Err_Bad_Argument;
        else if ( face_index < 0 )
          goto Exit;
      }
    }

    if ( error )
      goto Fail;

    /* we now need to fill the root FT_Face fields */
    /* with relevant information                   */
    {
      FT_Face     root = FT_FACE( face );
      FNT_Font    font = face->font;
      FT_PtrDist  family_size;


      root->face_flags = FT_FACE_FLAG_FIXED_SIZES |
                         FT_FACE_FLAG_HORIZONTAL;

      if ( font->header.avg_width == font->header.max_width )
        root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;

      if ( font->header.italic )
        root->style_flags |= FT_STYLE_FLAG_ITALIC;

      if ( font->header.weight >= 800 )
        root->style_flags |= FT_STYLE_FLAG_BOLD;

      /* set up the `fixed_sizes' array */
      if ( FT_NEW_ARRAY( root->available_sizes, 1 ) )
        goto Fail;

      root->num_fixed_sizes = 1;

      {
        FT_Bitmap_Size*  bsize = root->available_sizes;
        FT_UShort        x_res, y_res;


        bsize->width  = font->header.avg_width;
        bsize->height = (FT_Short)(
          font->header.pixel_height + font->header.external_leading );
        bsize->size   = font->header.nominal_point_size << 6;

        x_res = font->header.horizontal_resolution;
        if ( !x_res )
          x_res = 72;

        y_res = font->header.vertical_resolution;
        if ( !y_res )
          y_res = 72;

        bsize->y_ppem = FT_MulDiv( bsize->size, y_res, 72 );
        bsize->y_ppem = FT_PIX_ROUND( bsize->y_ppem );

        /*
         * this reads:
         *
         * the nominal height is larger than the bbox's height
         *
         * => nominal_point_size contains incorrect value;
         *    use pixel_height as the nominal height
         */
        if ( bsize->y_ppem > font->header.pixel_height << 6 )
        {
          FT_TRACE2(( "use pixel_height as the nominal height\n" ));

          bsize->y_ppem = font->header.pixel_height << 6;
          bsize->size   = FT_MulDiv( bsize->y_ppem, 72, y_res );
        }

        bsize->x_ppem = FT_MulDiv( bsize->size, x_res, 72 );
        bsize->x_ppem = FT_PIX_ROUND( bsize->x_ppem );
      }

      {
        FT_CharMapRec  charmap;


        charmap.encoding    = FT_ENCODING_NONE;
        charmap.platform_id = 0;
        charmap.encoding_id = 0;
        charmap.face        = root;

        if ( font->header.charset == FT_WinFNT_ID_MAC )
        {
          charmap.encoding    = FT_ENCODING_APPLE_ROMAN;
          charmap.platform_id = 1;
/*        charmap.encoding_id = 0; */
        }

        error = FT_CMap_New( fnt_cmap_class,
                             NULL,
                             &charmap,
                             NULL );
        if ( error )
          goto Fail;

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

      /* setup remaining flags */

      /* reserve one slot for the .notdef glyph at index 0 */
      root->num_glyphs = font->header.last_char -
                         font->header.first_char + 1 + 1;

      if ( font->header.face_name_offset >= font->header.file_size )
      {
        FT_TRACE2(( "invalid family name offset!\n" ));
        error = FNT_Err_Invalid_File_Format;
        goto Fail;
      }
      family_size = font->header.file_size - font->header.face_name_offset;
      /* Some broken fonts don't delimit the face name with a final */
      /* NULL byte -- the frame is erroneously one byte too small.  */
      /* We thus allocate one more byte, setting it explicitly to   */
      /* zero.                                                      */
      if ( FT_ALLOC( font->family_name, family_size + 1 ) )
        goto Fail;

      FT_MEM_COPY( font->family_name,
                   font->fnt_frame + font->header.face_name_offset,
                   family_size );

      font->family_name[family_size] = '\0';

      if ( FT_REALLOC( font->family_name,
                       family_size,
                       ft_strlen( font->family_name ) + 1 ) )
        goto Fail;

      root->family_name = font->family_name;
      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";
    }
    goto Exit;

  Fail:
    FNT_Face_Done( face );

  Exit:
    return error;
  }


  static FT_Error
  FNT_Size_Select( FT_Size  size )
  {
    FNT_Face          face   = (FNT_Face)size->face;
    FT_WinFNT_Header  header = &face->font->header;


    FT_Select_Metrics( size->face, 0 );

    size->metrics.ascender    = header->ascent * 64;
    size->metrics.descender   = -( header->pixel_height -
                                   header->ascent ) * 64;
    size->metrics.max_advance = header->max_width * 64;

    return FNT_Err_Ok;
  }


  static FT_Error
  FNT_Size_Request( FT_Size          size,
                    FT_Size_Request  req )
  {
    FNT_Face          face    = (FNT_Face)size->face;
    FT_WinFNT_Header  header  = &face->font->header;
    FT_Bitmap_Size*   bsize   = size->face->available_sizes;
    FT_Error          error   = FNT_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 = FNT_Err_Ok;
      break;

    case FT_SIZE_REQUEST_TYPE_REAL_DIM:
      if ( height == header->pixel_height )
        error = FNT_Err_Ok;
      break;

    default:
      error = FNT_Err_Unimplemented_Feature;
      break;
    }

    if ( error )
      return error;
    else
      return FNT_Size_Select( size );
  }


  static FT_Error
  FNT_Load_Glyph( FT_GlyphSlot  slot,
                  FT_Size       size,
                  FT_UInt       glyph_index,
                  FT_Int32      load_flags )
  {
    FNT_Face    face   = (FNT_Face)FT_SIZE_FACE( size );
    FNT_Font    font   = face->font;
    FT_Error    error  = FNT_Err_Ok;
    FT_Byte*    p;
    FT_Int      len;
    FT_Bitmap*  bitmap = &slot->bitmap;
    FT_ULong    offset;
    FT_Bool     new_format;

    FT_UNUSED( load_flags );


    if ( !face || !font ||
         glyph_index >= (FT_UInt)( FT_FACE( face )->num_glyphs ) )
    {
      error = FNT_Err_Invalid_Argument;
      goto Exit;
    }

    if ( glyph_index > 0 )
      glyph_index--;                           /* revert to real index */
    else
      glyph_index = font->header.default_char; /* the .notdef glyph */

    new_format = FT_BOOL( font->header.version == 0x300 );
    len        = new_format ? 6 : 4;

    /* jump to glyph entry */
    p = font->fnt_frame + ( new_format ? 148 : 118 ) + len * glyph_index;

    bitmap->width = FT_NEXT_SHORT_LE( p );

    if ( new_format )
      offset = FT_NEXT_ULONG_LE( p );
    else
      offset = FT_NEXT_USHORT_LE( p );

    if ( offset >= font->header.file_size )
    {
      FT_TRACE2(( "invalid FNT offset!\n" ));
      error = FNT_Err_Invalid_File_Format;
      goto Exit;
    }

    /* jump to glyph data */
    p = font->fnt_frame + /* font->header.bits_offset */ + offset;

    /* allocate and build bitmap */
    {
      FT_Memory  memory = FT_FACE_MEMORY( slot->face );
      FT_Int     pitch  = ( bitmap->width + 7 ) >> 3;
      FT_Byte*   column;
      FT_Byte*   write;


      bitmap->pitch      = pitch;
      bitmap->rows       = font->header.pixel_height;
      bitmap->pixel_mode = FT_PIXEL_MODE_MONO;

      if ( offset + pitch * bitmap->rows >= font->header.file_size )
      {
        FT_TRACE2(( "invalid bitmap width\n" ));
        error = FNT_Err_Invalid_File_Format;
        goto Exit;
      }

      /* note: since glyphs are stored in columns and not in rows we */
      /*       can't use ft_glyphslot_set_bitmap                     */
      if ( FT_ALLOC_MULT( bitmap->buffer, pitch, bitmap->rows ) )
        goto Exit;

      column = (FT_Byte*)bitmap->buffer;

      for ( ; pitch > 0; pitch--, column++ )
      {
        FT_Byte*  limit = p + bitmap->rows;


        for ( write = column; p < limit; p++, write += bitmap->pitch )
          *write = *p;
      }
    }

    slot->internal->flags = FT_GLYPH_OWN_BITMAP;
    slot->bitmap_left     = 0;
    slot->bitmap_top      = font->header.ascent;
    slot->format          = FT_GLYPH_FORMAT_BITMAP;

    /* now set up metrics */
    slot->metrics.width        = bitmap->width << 6;
    slot->metrics.height       = bitmap->rows << 6;
    slot->metrics.horiAdvance  = bitmap->width << 6;
    slot->metrics.horiBearingX = 0;
    slot->metrics.horiBearingY = slot->bitmap_top << 6;

    ft_synthesize_vertical_metrics( &slot->metrics,
                                    bitmap->rows << 6 );

  Exit:
    return error;
  }


  static FT_Error
  winfnt_get_header( FT_Face               face,
                     FT_WinFNT_HeaderRec  *aheader )
  {
    FNT_Font  font = ((FNT_Face)face)->font;


    *aheader = font->header;

    return 0;
  }


  static const FT_Service_WinFntRec  winfnt_service_rec =
  {
    winfnt_get_header
  };

 /*
  *  SERVICE LIST
  *
  */

  static const FT_ServiceDescRec  winfnt_services[] =
  {
    { FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_WINFNT },
    { FT_SERVICE_ID_WINFNT,    &winfnt_service_rec },
    { NULL, NULL }
  };


  static FT_Module_Interface
  winfnt_get_service( FT_Driver         driver,
                      const FT_String*  service_id )
  {
    FT_UNUSED( driver );

    return ft_service_list_lookup( winfnt_services, service_id );
  }




  FT_CALLBACK_TABLE_DEF
  const FT_Driver_ClassRec  winfnt_driver_class =
  {
    {
      FT_MODULE_FONT_DRIVER        |
      FT_MODULE_DRIVER_NO_OUTLINES,
      sizeof ( FT_DriverRec ),

      "winfonts",
      0x10000L,
      0x20000L,

      0,

      (FT_Module_Constructor)0,
      (FT_Module_Destructor) 0,
      (FT_Module_Requester)  winfnt_get_service
    },

    sizeof( FNT_FaceRec ),
    sizeof( FT_SizeRec ),
    sizeof( FT_GlyphSlotRec ),

    (FT_Face_InitFunc)        FNT_Face_Init,
    (FT_Face_DoneFunc)        FNT_Face_Done,
    (FT_Size_InitFunc)        0,
    (FT_Size_DoneFunc)        0,
    (FT_Slot_InitFunc)        0,
    (FT_Slot_DoneFunc)        0,

#ifdef FT_CONFIG_OPTION_OLD_INTERNALS
    ft_stub_set_char_sizes,
    ft_stub_set_pixel_sizes,
#endif
    (FT_Slot_LoadFunc)        FNT_Load_Glyph,

    (FT_Face_GetKerningFunc)  0,
    (FT_Face_AttachFunc)      0,
    (FT_Face_GetAdvancesFunc) 0,

    (FT_Size_RequestFunc)     FNT_Size_Request,
    (FT_Size_SelectFunc)      FNT_Size_Select
  };


/* END */
