/****************************************************************************
 *
 * pkdrivr.c
 *
 *   FreeType font driver for TeX's PK FONT files.
 *
 * Copyright 1996-2018 by
 * David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 * 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_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H
#include FT_TRUETYPE_IDS_H
#include FT_INTERNAL_TFM_H

#include FT_SERVICE_PK_H
#include FT_SERVICE_FONT_FORMAT_H

#include "pk.h"
#include "pkdrivr.h"
#include "pkerror.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_pkdriver


  typedef struct  PK_CMapRec_
  {
    FT_CMapRec      cmap;
    FT_ULong        num_encodings;
    PK_Encoding     encodings;
  } PK_CMapRec, *PK_CMap;


  FT_CALLBACK_DEF( FT_Error )
  pk_cmap_init(  FT_CMap     pkcmap,
                 FT_Pointer  init_data )
  {
    PK_CMap  cmap = (PK_CMap)pkcmap;
    PK_Face  face = (PK_Face)FT_CMAP_FACE( cmap );
    FT_UNUSED( init_data );

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

    return FT_Err_Ok;
  }


  FT_CALLBACK_DEF( void )
  pk_cmap_done( FT_CMap  pkcmap )
  {
    PK_CMap  cmap = (PK_CMap)pkcmap;

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


  FT_CALLBACK_DEF( FT_UInt )
  pk_cmap_char_index(  FT_CMap    pkcmap,
                       FT_UInt32  charcode )
  {
    PK_CMap       cmap      = (PK_CMap)pkcmap;
    PK_Encoding   encodings = cmap->encodings;
    FT_UInt       max, code, result    = 0, i;

    max = cmap->num_encodings;

    for( i = 0; i < max; i++ )
    {
      code = (FT_ULong)encodings[i].enc;
      if ( charcode == code )
      {
        result = encodings[i].glyph;
        goto Exit;
      }
    }
    Exit:
      return result;
  }


  FT_CALLBACK_DEF( FT_UInt )
  pk_cmap_char_next(  FT_CMap    pkcmap,
                       FT_UInt32  *acharcode )
  {
    PK_CMap       cmap      = (PK_CMap)pkcmap;
    PK_Encoding   encodings = cmap->encodings;
    FT_UInt       result    = 0, i, code, max;
    FT_ULong      charcode  = *acharcode + 1;

    max = cmap->num_encodings;

    for( i = 0; i < max; i++ )
    {
      code = (FT_ULong)encodings[i].enc;
      if ( charcode == code )
      {
        result = encodings[i].glyph + 1;
        goto Exit;
      }
    }

  Exit:
    if ( charcode > 0xFFFFFFFFUL )
    {
      FT_TRACE1(( "gf_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  pk_cmap_class =
  {
    sizeof ( PK_CMapRec ),
    pk_cmap_init,
    pk_cmap_done,
    pk_cmap_char_index,
    pk_cmap_char_next,

    NULL, NULL, NULL, NULL, NULL
  };


  FT_CALLBACK_DEF( void )
  PK_Face_Done( FT_Face        pkface )         /* PK_Face */
  {
    PK_Face    face   = (PK_Face)pkface;
    FT_Memory  memory;


    if ( !face )
      return;

    memory = FT_FACE_MEMORY( face );

    pk_free_font( face );

    FT_FREE( pkface->available_sizes );
  }


  FT_CALLBACK_DEF( FT_Error )
  PK_Face_Init(   FT_Stream      stream,
                  FT_Face        pkface,         /* PK_Face */
                  FT_Int         face_index,
                  FT_Int         num_params,
                  FT_Parameter*  params )
  {
    PK_Face     face   = (PK_Face)pkface;
    FT_Error    error  = FT_Err_Ok;
    FT_Memory   memory = FT_FACE_MEMORY( face );
    PK_Glyph    go=NULL;
    FT_UInt16   i,count;

    TFM_Service tfm;

    FT_UNUSED( num_params );
    FT_UNUSED( params );

    face->tfm = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
                                           "tfm" );
    tfm = (TFM_Service)face->tfm;
    if ( !tfm )
    {
      FT_ERROR(( "GF_Face_Init: cannot access `tfm' module\n" ));
      error = FT_THROW( Missing_Module );
      goto Exit;
    }

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

    /* load font */
    error = pk_load_font( stream, memory, &go );
    if ( FT_ERR_EQ( error, Unknown_File_Format ) )
    {
      FT_TRACE2(( "  not a PK file\n" ));
      goto Fail;
    }
    else if ( error )
      goto Exit;

    /* we have a pk font: let's construct the face object */
    face->pk_glyph = go ;

    /* sanity check */
    if ( !face->pk_glyph->bm_table )
    {
      FT_TRACE2(( "glyph bitmaps not allocated\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    /* PK cannot have multiple faces in a single font file.
     * XXX: non-zero face_index is already invalid argument, but
     *      Type1, Type42 driver has a convention to return
     *      an invalid argument error when the font could be
     *      opened by the specified driver.
     */
    if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 )
    {
      FT_ERROR(( "PK_Face_Init: invalid face index\n" ));
      PK_Face_Done( pkface );
      return FT_THROW( Invalid_Argument );
    }

    /* we now need to fill the root FT_Face fields */
    /* with relevant information                   */

    pkface->num_faces       = 1;
    pkface->face_index      = 0;
    pkface->face_flags     |= FT_FACE_FLAG_FIXED_SIZES |
                             FT_FACE_FLAG_HORIZONTAL ;
    /*
     * XXX: TO-DO: pkface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
     * XXX: I have to check for this.
     */

    pkface->family_name     = NULL;
    count=0;
    for (i = 0; i < 256; i++)
    {
      if(go->bm_table[i].bitmap != NULL)
        count++;
    }
    pkface->num_glyphs      = (FT_Long)count;

    FT_TRACE4(( "  number of glyphs: allocated %d\n",pkface->num_glyphs ));

    if ( pkface->num_glyphs <= 0 )
    {
      FT_ERROR(( "PK_Face_Init: glyphs not allocated\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    pkface->num_fixed_sizes = 1;
    if ( FT_NEW_ARRAY( pkface->available_sizes, 1 ) )
      goto Exit;

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

      bsize->height = (FT_Short) face->pk_glyph->font_bbx_h ;
      bsize->width  = (FT_Short) face->pk_glyph->font_bbx_w ;
      bsize->size   = (FT_Pos)   FT_MulDiv( FT_ABS( face->pk_glyph->ds ),
                                     64 * 7200,
                                     72270L );

      x_res = toint( face->pk_glyph->hppp * 72.27 );
      y_res = toint( face->pk_glyph->vppp * 72.27 );

      bsize->y_ppem = (FT_Pos) toint((face->pk_glyph->ds * y_res)/ 72.27) << 6 ;
      bsize->x_ppem = (FT_Pos) FT_MulDiv( bsize->y_ppem,
                                         x_res,
                                         y_res );
    }

    /* set up charmap */
    {
      /* FT_Bool     unicode_charmap ; */

      /*
       * XXX: TO-DO
       * Currently the unicode_charmap is set to `0'
       * The functionality of extracting coding scheme
       * from `xxx' and `yyy' commands will be used to
       * set the unicode_charmap.
      */
    }

    /* Charmaps */
    {
      FT_CharMapRec  charmap;
      FT_Bool        unicode_charmap = 0;

      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 )
      {
        /* 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( &pk_cmap_class, NULL, &charmap, NULL );

      if ( error )
        goto Exit;
    }

    if ( go->code_max < go->code_min )
    {
      FT_TRACE2(( "invalid number of glyphs\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

  Exit:
    return error;

  Fail:
    PK_Face_Done( pkface );
    return FT_THROW( Unknown_File_Format );
  }


  FT_CALLBACK_DEF( FT_Error )
  PK_Size_Select(  FT_Size   size,
                   FT_ULong  strike_index )
  {
    PK_Face     face  = (PK_Face)size->face;
    PK_Glyph    go    = face->pk_glyph;
    FT_UNUSED( strike_index );

    FT_Select_Metrics( size->face, 0 );

    size->metrics.ascender    = (go->font_bbx_h - go->font_bbx_yoff) * 64;
    size->metrics.descender   = -go->font_bbx_yoff * 64;
    size->metrics.max_advance = go->font_bbx_w * 64;

    return FT_Err_Ok;
  }


  FT_CALLBACK_DEF( FT_Error )
  PK_Size_Request( FT_Size          size,
                   FT_Size_Request  req )
  {
    PK_Face           face    = (PK_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->pk_glyph->font_bbx_h )
        error = FT_Err_Ok;
      break;

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

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


  FT_CALLBACK_DEF( FT_Error )
  PK_Glyph_Load(   FT_GlyphSlot  slot,
                   FT_Size       size,
                   FT_UInt       glyph_index,
                   FT_Int32      load_flags )
  {
    PK_Face      pk     = (PK_Face)FT_SIZE_FACE( size );
    FT_Face      face   = FT_FACE( pk );
    FT_Error     error  = FT_Err_Ok;
    FT_Bitmap*   bitmap = &slot->bitmap;
    PK_Bitmap    bm;
    PK_Glyph     go;

    go = pk->pk_glyph;

    FT_UNUSED( load_flags );

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

    if ( !go                                         ||
         glyph_index >= (FT_UInt)( face->num_glyphs ) )
    {
      error = FT_THROW( Invalid_Argument );
      goto Exit;
    }

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

    if ( !go->bm_table )
    {
      FT_TRACE2(( "invalid bitmap table\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    /* slot, bitmap => freetype, bm => pklib */
    bm = &pk->pk_glyph->bm_table[glyph_index];

    bitmap->rows       = bm->bbx_height;
    bitmap->width      = bm->bbx_width;
    bitmap->pixel_mode = FT_PIXEL_MODE_MONO;

    if ( !bm->raster )
    {
      FT_TRACE2(( "invalid bitmap width\n" ));
      error = FT_THROW( Invalid_File_Format );
      goto Exit;
    }

    bitmap->pitch = (int)bm->raster ;

    /* note: we don't allocate a new array to hold the bitmap; */
    /*       we can simply point to it                         */
    ft_glyphslot_set_bitmap( slot, bm->bitmap );

    slot->format      = FT_GLYPH_FORMAT_BITMAP;
    slot->bitmap_left = bm->off_x ;
    slot->bitmap_top  = bm->off_y ;

    slot->metrics.horiAdvance  = (FT_Pos) (bm->mv_x ) * 64;
    slot->metrics.horiBearingX = (FT_Pos) (bm->off_x ) * 64;
    slot->metrics.horiBearingY = (FT_Pos) (bm->bbx_height) * 64;
    slot->metrics.width        = (FT_Pos) ( bitmap->width * 64 );
    slot->metrics.height       = (FT_Pos) ( bitmap->rows * 64 );

    ft_synthesize_vertical_metrics( &slot->metrics, bm->bbx_height * 64 );

  Exit:
    return error;
  }


  FT_LOCAL_DEF( void )
  TFM_Done_Metrics( FT_Memory     memory,
                    TFM_FontInfo  fi )
  {
    FT_FREE(fi->width);
    FT_FREE(fi->height);
    FT_FREE(fi->depth);
    FT_FREE( fi );
  }


  /* parse a TFM metrics file */
  FT_LOCAL_DEF( FT_Error )
  TFM_Read_Metrics( FT_Face    pk_face,
                    FT_Stream  stream )
  {
    TFM_Service    tfm;
    FT_Memory      memory  = stream->memory;
    TFM_ParserRec  parser;
    TFM_FontInfo   fi      = NULL;
    FT_Error       error   = FT_ERR( Unknown_File_Format );
    PK_Face        face    = (PK_Face)pk_face;
    PK_Glyph       pk_glyph= face->pk_glyph;


    if ( face->tfm_data )
    {
      FT_TRACE1(( "TFM_Read_Metrics:"
                  " Freeing previously attached metrics data.\n" ));
      TFM_Done_Metrics( memory, (TFM_FontInfo)face->tfm_data );

      face->tfm_data = NULL;
    }

    if ( FT_NEW( fi ) )
      goto Exit;

    FT_TRACE4(( "TFM_Read_Metrics: Invoking TFM_Service.\n" ));

    tfm = (TFM_Service)face->tfm;
    if ( tfm->tfm_parser_funcs )
    {
      /* Initialise TFM Service */
      error = tfm->tfm_parser_funcs->init( &parser,
                                           memory,
                                           stream );

      if ( !error )
      {
        FT_TRACE4(( "TFM_Read_Metrics: Initialised tfm metric data.\n" ));
        parser.FontInfo  = fi;
        parser.user_data = pk_glyph;

        error = tfm->tfm_parser_funcs->parse_metrics( &parser );
        if( !error )
          FT_TRACE4(( "TFM_Read_Metrics: parsing TFM metric information done.\n" ));

        FT_TRACE6(( "TFM_Read_Metrics: TFM Metric Information:\n"
                    "                  Check Sum  : %ld\n"
                    "                  Design Size: %ld\n"
                    "                  Begin Char : %d\n"
                    "                  End Char   : %d\n"
                    "                  font_bbx_w : %d\n"
                    "                  font_bbx_h : %d\n"
                    "                  slant      : %d\n", parser.FontInfo->cs, parser.FontInfo->design_size, parser.FontInfo->begin_char,
                                                           parser.FontInfo->end_char, parser.FontInfo->font_bbx_w,
                                                           parser.FontInfo->font_bbx_h, parser.FontInfo->slant ));
        tfm->tfm_parser_funcs->done( &parser );
      }
    }

    if ( !error )
    {
      /* Modify PK_Glyph data according to TFM metric values */

      /*
      face->pk_glyph->font_bbx_w = fi->font_bbx_w;
      face->pk_glyph->font_bbx_h = fi->font_bbx_h;
      */

      face->tfm_data       = fi;
    }

  Exit:
    if ( fi )
      TFM_Done_Metrics( memory, fi );

    return error;
  }

 /*
  *
  * SERVICES LIST
  *
  */

  static const FT_ServiceDescRec  pk_services[] =
  {
    { FT_SERVICE_ID_PK,          NULL },
    { FT_SERVICE_ID_FONT_FORMAT, FT_FONT_FORMAT_PK },
    { NULL, NULL }
  };


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

    return ft_service_list_lookup( pk_services, name );
  }


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

      "pk",
      0x10000L,
      0x20000L,

      NULL,    									/* module-specific interface */

      NULL,                     /* FT_Module_Constructor  module_init   */
      NULL,                     /* FT_Module_Destructor   module_done   */
      pk_driver_requester       /* FT_Module_Requester    get_interface */
    },

    sizeof ( PK_FaceRec ),
    sizeof ( FT_SizeRec ),
    sizeof ( FT_GlyphSlotRec ),

    PK_Face_Init,               /* FT_Face_InitFunc  init_face */
    PK_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 */

    PK_Glyph_Load,              /* FT_Slot_LoadFunc  load_glyph */

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

    PK_Size_Request,           /* FT_Size_RequestFunc  request_size */
    PK_Size_Select             /* FT_Size_SelectFunc   select_size  */
  };


/* END */
