/***************************************************************************/
/*                                                                         */
/*  ftmac.c                                                                */
/*                                                                         */
/*    Mac FOND support. Written by just@letterror.com.                     */
/*                                                                         */
/*  Copyright 1996-2000 by                                                 */
/*  Just van Rossum, 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.                                        */
/*                                                                         */
/***************************************************************************/


  /*
    Notes

    Mac suitcase files can (and often do!) contain multiple fonts. To
    support this I use the face_index argument of FT_(Open|New)_Face()
    functions, and pretend the suitcase file is a collection.
    Warning: although the FOND driver sets face->num_faces field to the
    number of available fonts, but the Type 1 driver sets it to 1 anyway.
    So this field is currently not reliable, and I don't see a clean way
    to  resolve that. The face_index argument translates to
      Get1IndResource( 'FOND', face_index + 1 );
    so clients should figure out the resource index of the FOND.
    (I'll try to provide some example code for this at some point.)


    The Mac FOND support works roughly like this:

    - Check whether the offered stream points to a Mac suitcase file.
      This is done by checking the file type: it has to be 'FFIL' or 'tfil'.
      The stream that gets passed to our init_face() routine is a stdio
      stream, which isn't usable for us, since the FOND resources live
      in the resource fork. So we just grab the stream->pathname field.

    - Read the FOND resource into memory, then check whether there is
      a TrueType font and/or (!) a Type 1 font available.

    - If there is a Type 1 font available (as a separate 'LWFN' file),
      read its data into memory, massage it slightly so it becomes
      PFB data, wrap it into a memory stream, load the Type 1 driver
      and delegate the rest of the work to it by calling FT_Open_Face().
      (XXX TODO: after this has been done, the kerning data from the FOND
      resource should be appended to the face: on the Mac there are usually
      no AFM files available. However, this is tricky since we need to map
      Mac char codes to ps glyph names to glyph ID's...)

    - If there is a TrueType font (an 'sfnt' resource), read it into
      memory, wrap it into a memory stream, load the TrueType driver
      and delegate the rest of the work to it, by calling FT_Open_Face().
  */

#include <freetype/freetype.h>
#include <freetype/internal/ftstream.h>
#include <truetype/ttobjs.h>
#include <type1z/z1objs.h>

#include <Resources.h>
#include <Fonts.h>
#include <Errors.h>

#include <ctype.h>  /* for isupper() and isalnum() */

#include <ftmac.h>



  /* Set PREFER_LWFN to 1 if LWFN (Type 1) is preferred over
     TrueType in case *both* are available (this is not common,
     but it *is* possible). */
#ifndef PREFER_LWFN
#define PREFER_LWFN 1
#endif



  /* Quick 'n' Dirty Pascal string to C string converter.
     Warning: this call is not thread safe! Use with caution. */
  static
  char * p2c_str( unsigned char *pstr )
  {
    static char cstr[256];


    strncpy( cstr, (char*)pstr+1, pstr[0] );
    cstr[pstr[0]] = '\0';
    return cstr;
  }


  /* Given a pathname, fill in a file spec. */
  static
  int file_spec_from_path( const char* pathname, FSSpec *spec )
  {
    Str255    p_path;
    FT_ULong  path_len;


    /* convert path to a pascal string */
    path_len = strlen( pathname );
    if ( path_len > 255 )
      return -1;
    p_path[0] = (unsigned char)path_len;
    strncpy( (char*)p_path+1, pathname, path_len );

    if ( FSMakeFSSpec( 0, 0, p_path, spec ) != noErr )
      return -1;
    else
      return 0;
  }


  /* Return the file type of the file specified by spec. */
  static
  OSType get_file_type( FSSpec  *spec )
  {
    FInfo   finfo;


    if ( FSpGetFInfo( spec, &finfo ) != noErr )
      return 0;  /* file might not exist */
    return finfo.fdType;
  }


  /* Given a PostScript font name, create the Macintosh LWFN file name. */
  static
  void create_lwfn_name( char* ps_name, Str255 lwfn_file_name )
  {
    int       max = 5, count = 0;
    FT_Byte*  p = lwfn_file_name;
    FT_Byte*  q = (FT_Byte*)ps_name;


    lwfn_file_name[0] = 0;

    while ( *q )
    {
      if ( isupper(*q) )
      {
        if ( count )
          max = 3;
        count = 0;
      }
      if ( count < max && (isalnum(*q) || *q == '_' ) )
      {
        *++p = *q;
        lwfn_file_name[0]++;
        count++;
      }
      q++;
    }
  }


  /* Given a file reference, answer its location as a vRefNum
     and a dirID. */
  static
  FT_Error get_file_location( short          ref_num,
                              short*         v_ref_num,
                              long*          dir_id,
                              unsigned char* file_name )
  {
    FCBPBRec  pb;
    OSErr     error;


    pb.ioNamePtr = file_name;
    pb.ioVRefNum = 0;
    pb.ioRefNum  = ref_num;
    pb.ioFCBIndx = 0;

    error = PBGetFCBInfoSync( &pb );
    if ( error == noErr )
    {
      *v_ref_num = pb.ioFCBVRefNum;
      *dir_id = pb.ioFCBParID;
    }
    return error;
  }


  /* Make a file spec for an LWFN file from a FOND resource and
     a file name. */
  static
  FT_Error make_lwfn_spec( Handle          fond,
                           unsigned char*  file_name,
                           FSSpec*         spec )
  {
    FT_Error  error;
    short     ref_num, v_ref_num;
    long      dir_id;
    Str255    fond_file_name;


    ref_num = HomeResFile( fond );
    error = ResError();
    if ( !error )
      error = get_file_location( ref_num, &v_ref_num, &dir_id, fond_file_name );
    if ( !error )
      error = FSMakeFSSpec( v_ref_num, dir_id, file_name, spec );

    return error;
  }


  /* Look inside the FOND data, answer whether there should be an SFNT
     resource, and answer the name of a possible LWFN Type 1 file. */
  static
  void parse_fond(  char*   fond_data,
                    short   *have_sfnt,
                    short   *sfnt_id,
                    Str255  lwfn_file_name )
  {
    AsscEntry*  assoc;
    FamRec*     fond;


    *sfnt_id          = 0;
    *have_sfnt        = 0;
    lwfn_file_name[0] = 0;

    fond = (FamRec*)fond_data;
    assoc = (AsscEntry*)(fond_data + sizeof(FamRec) + 2);

    if ( assoc->fontSize == 0 )
    {
      *have_sfnt = 1;
      *sfnt_id = assoc->fontID;
    }

    if ( fond->ffStylOff )
    {
      unsigned char*  p = (unsigned char*)fond_data;
      StyleTable*     style;
      unsigned short  string_count;
      unsigned char*  name_table = 0;
      char            ps_name[256];
      unsigned char*  names[64];
      int             i;

      p += fond->ffStylOff;
      style = (StyleTable*)p;
      p += sizeof(StyleTable);
      string_count = *(unsigned short*)(p);
      p += sizeof(short);

      for ( i = 0 ; i < string_count && i < 64; i++ )
      {
        names[i] = p;
        p += names[i][0];
        p++;
      }
      strcpy(ps_name, p2c_str(names[0]));  /* Family name */

      if ( style->indexes[0] > 1 )
      {
        unsigned char* suffixes = names[style->indexes[0]-1];
        for ( i=1; i<=suffixes[0]; i++ )
          strcat( ps_name, p2c_str(names[suffixes[i]-1]) );
      }
      create_lwfn_name( ps_name, lwfn_file_name );
    }
  }


  /* Read Type 1 data from the POST resources inside the LWFN file,
     return a PFB buffer. This is somewhat convoluted because the FT2
     PFB parser wants the ASCII header as one chunk, and the LWFN
     chunks are often not organized that way, so we'll glue chunks
     of the same type together. */
  static
  FT_Error read_lwfn( FT_Memory  memory,
                      FSSpec*    lwfn_spec,
                      FT_Byte**  pfb_data,
                      FT_ULong*  size )
  {
    FT_Error       error = FT_Err_Ok;
    short          res_ref, res_id;
    unsigned char  *buffer, *p, *size_p;
    FT_ULong       total_size = 0;
    FT_ULong       post_size, pfb_chunk_size;
    Handle         post_data;
    char           code, last_code;


    res_ref = FSpOpenResFile( lwfn_spec, fsRdPerm );
    if ( ResError() )
      return FT_Err_Out_Of_Memory;
    UseResFile( res_ref );

    /* First pass: load all POST resources, and determine the size of
       the output buffer. */
    res_id = 501;
    last_code = -1;
    for (;;)
    {
      post_data = Get1Resource( 'POST', res_id++ );
      if ( post_data == NULL )
        break;  /* we're done */

      code = (*post_data)[0];

      if ( code != last_code )
      {
        if ( code == 5 )
          total_size += 2; /* just the end code */
        else
          total_size += 6; /* code + 4 bytes chunk length */
      }

      total_size += GetHandleSize( post_data ) - 2;
      last_code = code;
    }

    if ( ALLOC( buffer, (FT_Long)total_size ) )
      goto Error;

    /* Second pass: append all POST data to the buffer, add PFB fields.
       Glue all consequtive chunks of the same type together. */
    p = buffer;
    res_id = 501;
    last_code = -1;
    pfb_chunk_size = 0;

    for (;;)
    {
      post_data = Get1Resource( 'POST', res_id++ );
      if ( post_data == NULL )
        break;  /* we're done */

      post_size = (FT_ULong)GetHandleSize( post_data ) - 2;
      code = (*post_data)[0];

      if ( code != last_code )
      {

        if ( last_code != -1 )
        {
          /* we're done adding a chunk, fill in the size field */
          *size_p++ = (FT_Byte)(pfb_chunk_size & 0xFF);
          *size_p++ = (FT_Byte)((pfb_chunk_size >> 8) & 0xFF);
          *size_p++ = (FT_Byte)((pfb_chunk_size >> 16) & 0xFF);
          *size_p++ = (FT_Byte)((pfb_chunk_size >> 24) & 0xFF);
          pfb_chunk_size = 0;
        }

        *p++ = 0x80;
        if ( code == 5 )
          *p++ = 0x03;  /* the end */
        else if ( code == 2 )
          *p++ = 0x02;  /* binary segment */
        else
          *p++ = 0x01;  /* ASCII segment */

        if ( code != 5 )
        {
          size_p = p;   /* save for later */
          p += 4;       /* make space for size field */
        }
      }

      memcpy( p, *post_data + 2, post_size );
      pfb_chunk_size += post_size;
      p += post_size;
      last_code = code;
    }

    *pfb_data = buffer;
    *size = total_size;

Error:
    CloseResFile( res_ref );
    return error;
  }


  /* Finalizer for a memory stream; gets called by FT_Done_Face().
     It frees the memory it uses. */
  static
  void memory_stream_close( FT_Stream  stream )
  {
    FT_Memory  memory = stream->memory;


    FREE( stream->base );
    stream->size               = 0;
    stream->base               = 0;
    stream->close              = 0;
  }


  /* Create a new memory stream from a buffer and a size. */
  static
  FT_Error new_memory_stream( FT_Library       library,
                              FT_Byte*         base,
                              FT_ULong         size,
                              FT_Stream_Close  close,
                              FT_Stream*       astream )
  {
      FT_Error   error;
      FT_Memory  memory;
      FT_Stream  stream;


      if ( !library )
        return FT_Err_Invalid_Library_Handle;

      if ( !base )
        return FT_Err_Invalid_Argument;

      *astream = 0;
      memory = library->memory;
      if ( ALLOC( stream, sizeof(*stream) ) )
        goto Exit;

      FT_New_Memory_Stream( library,
                            base,
                            size,
                            stream );

      stream->close = close;

      *astream = stream;

    Exit:
      return error;
  }


  /* Create a new FT_Face given a buffer and a driver name. */
  static
  FT_Error open_face_from_buffer( FT_Library  library,
                                  FT_Byte*    base,
                                  FT_ULong    size,
                                  FT_Long     face_index,
                                  char*       driver_name,
                                  FT_Face*    aface )
  {
    FT_Open_Args  args;
    FT_Error      error;
    FT_Stream     stream;
    FT_Memory     memory = library->memory;


    error = new_memory_stream( library,
                               base,
                               size,
                               memory_stream_close,
                               &stream );
    if ( error )
    {
      FREE( base );
      return error;
    }

    args.flags = ft_open_stream;
    args.stream = stream;
    if ( driver_name )
    {
      args.flags = args.flags | ft_open_driver;
      args.driver = FT_Get_Module( library, driver_name );
    }
    error = FT_Open_Face( library, &args, face_index, aface );
    if ( !error )
      (*aface)->face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
    FREE( stream );  /* FT_Open_Face() made a copy */
    return error;
  }


  /* Create a new FT_Face from a file spec to an LWFN file. */
  static
  FT_Error FT_New_Face_From_LWFN( FT_Library  library,
                                  FSSpec*     spec,
                                  FT_Long     face_index,
                                  FT_Face*    aface )
  {
    FT_Byte*      pfb_data;
    FT_ULong      pfb_size;
    FT_Error      error;
    FT_Memory     memory = library->memory;


    error = read_lwfn( library->memory, spec, &pfb_data, &pfb_size );
    if ( error )
      return error;

#if 0
    {
      FILE* f;
      char * path;

      path = p2c_str( spec->name );
      strcat( path, ".PFB" );
      f = fopen(path, "wb");
      if ( f )
      {
        fwrite( pfb_data, 1, pfb_size, f );
        fclose( f );
      }
    }
#endif

    return open_face_from_buffer( library,
                                  pfb_data,
                                  pfb_size,
                                  face_index,
                                  "type1",
                                  aface );
  }


  /* Create a new FT_Face from an SFNT resource, specified by res ID. */
  static
  FT_Error FT_New_Face_From_SFNT( FT_Library  library,
                                  short       sfnt_id,
                                  FT_Long     face_index,
                                  FT_Face*    aface )
  {
    Handle        sfnt = NULL;
    FT_Byte*      sfnt_data;
    size_t        sfnt_size;
    FT_Stream     stream = NULL;
    FT_Error      error = 0;
    FT_Memory     memory = library->memory;


    sfnt = GetResource( 'sfnt', sfnt_id );
    if ( ResError() )
      return FT_Err_Invalid_Handle;

    sfnt_size = (FT_ULong)GetHandleSize( sfnt );
    if ( ALLOC( sfnt_data, (FT_Long)sfnt_size ) )
    {
      ReleaseResource( sfnt );
      return error;
    }

    HLock( sfnt );
    memcpy( sfnt_data, *sfnt, sfnt_size);
    HUnlock( sfnt );
    ReleaseResource( sfnt );

    return open_face_from_buffer( library,
                                  sfnt_data,
                                  sfnt_size,
                                  face_index,
                                  "truetype",
                                  aface );
  }


  /* Create a new FT_Face from a file spec to a suitcase file. */
  static
  FT_Error FT_New_Face_From_Suitcase( FT_Library  library,
                                      FSSpec*     spec,
                                      FT_Long     face_index,
                                      FT_Face*    aface )
  {
    FT_Error  error = FT_Err_Ok;
    short     res_ref, res_index;
    Handle    fond;


    res_ref = FSpOpenResFile( spec, fsRdPerm );
    if ( ResError() )
      return FT_Err_Cannot_Open_Resource;
    UseResFile( res_ref );

    /* face_index may be -1, in which case we
       just need to do a sanity check */
    if ( face_index < 0)
      res_index = 1;
    else
    {
      res_index = (short)(face_index + 1);
      face_index = 0;
    }
    fond = Get1IndResource( 'FOND', res_index );
    if ( ResError() )
    {
      error = FT_Err_Cannot_Open_Resource;
      goto Error;
    }

    error = FT_New_Face_From_FOND( library, fond, face_index, aface );

Error:
    CloseResFile( res_ref );
    return error;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_New_Face_From_FOND                                              */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Creates a new face object from an FOND resource.                   */
  /*                                                                       */
  /* <InOut>                                                               */
  /*    library    :: A handle to the library resource.                    */
  /*                                                                       */
  /* <Input>                                                               */
  /*    fond       :: An FOND resource.                                    */
  /*                                                                       */
  /*    face_index :: only supported for the -1 `sanity check'             */
  /*                  special case.                                        */
  /*                                                                       */
  /* <Output>                                                              */
  /*    aface      :: A handle to a new face object.                       */
  /*                                                                       */
  /* <Return>                                                              */
  /*    FreeType error code.  0 means success.                             */
  /*                                                                       */
  /* <Notes>                                                               */
  /*    This function can be used to create FT_Face abjects from fonts     */
  /*    that are installed in the system like so:                          */
  /*      fond = GetResource( 'FOND', fontName );                          */
  /*      error = FT_New_Face_From_FOND( library, fond, 0, &face );        */
  /*                                                                       */
  FT_EXPORT_FUNC( FT_Error )  FT_New_Face_From_FOND(
                                FT_Library  library,
                                Handle      fond,
                                FT_Long     face_index,
                                FT_Face*    aface )
  {
    short     sfnt_id, have_sfnt, have_lwfn = 0;
    Str255    lwfn_file_name;
    short     fond_id;
    OSType    fond_type;
    Str255    fond_name;
    FSSpec    lwfn_spec;
    FT_Error  error = FT_Err_Unknown_File_Format;


    GetResInfo(fond, &fond_id, &fond_type, fond_name);
    if ( ResError() != noErr || fond_type != 'FOND' )
      return FT_Err_Invalid_File_Format;

    HLock( fond );
    parse_fond( *fond, &have_sfnt, &sfnt_id, lwfn_file_name );
    HUnlock( fond );

    if ( lwfn_file_name[0] )
    {
      if ( make_lwfn_spec( fond, lwfn_file_name, &lwfn_spec ) == FT_Err_Ok )
        have_lwfn = 1;  /* yeah, we got one! */
      else
        have_lwfn = 0;  /* no LWFN file found */
    }

    if ( have_lwfn && ( !have_sfnt || PREFER_LWFN ) )
      return FT_New_Face_From_LWFN( library,
                                    &lwfn_spec,
                                    face_index,
                                    aface );
    else if ( have_sfnt )
      return FT_New_Face_From_SFNT( library,
                                    sfnt_id,
                                    face_index,
                                    aface );

    return FT_Err_Unknown_File_Format;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    FT_New_Face                                                        */
  /*                                                                       */
  /* <Description>                                                         */
  /*    This is the Mac-specific implementation of FT_New_Face.  In        */
  /*    addition to the standard FT_New_Face functionality, it also        */
  /*    accepts pathnames to Mac suitcase files.  For further              */
  /*    documentation see the original FT_New_Face in ftobjs.c.            */
  /*                                                                       */
  FT_EXPORT_FUNC( FT_Error )  FT_New_Face( FT_Library   library,
                                           const char*  pathname,
                                           FT_Long      face_index,
                                           FT_Face*     aface )
  {
    FT_Open_Args  args;
    FSSpec        spec;
    OSType        file_type;


    /* test for valid `library' and `aface' delayed to FT_Open_Face() */
    if ( !pathname )
      return FT_Err_Invalid_Argument;

    if ( file_spec_from_path( pathname, &spec ) )
      return FT_Err_Invalid_Argument;

    file_type = get_file_type( &spec );
    if ( file_type == 'FFIL' || file_type == 'tfil' )
      return FT_New_Face_From_Suitcase( library, &spec, face_index, aface );
    else if ( file_type == 'LWFN' )
      return FT_New_Face_From_LWFN( library, &spec, face_index, aface );
    else
    {
      args.flags    = ft_open_pathname;
      args.pathname = (char*)pathname;

      return FT_Open_Face( library, &args, face_index, aface );
    }
  }

