/* ftglue.c: Glue code for compiling the OpenType code from
 *           FreeType 1 using only the public API of FreeType 2
 *
 * By David Turner, The FreeType Project (www.freetype.org)
 *
 * This code is explicitely put in the public domain
 *
 * See ftglue.h for more information.
 */

#include "ftglue.h"

#if 0
#include <stdio.h>
#define  LOG(x)  ftglue_log x

static void
ftglue_log( const char*   format, ... )
{
  va_list  ap;

  va_start( ap, format );
  vfprintf( stderr, format, ap );
  va_end( ap );
}

#else
#define  LOG(x)  do {} while (0)
#endif

/* only used internally */
static FT_Pointer
ftglue_qalloc( FT_Memory  memory,
               FT_ULong   size,
               FT_Error  *perror )
{
  FT_Error    error = 0;
  FT_Pointer  block = NULL;

  if ( size > 0 )
  {
    block = memory->alloc( memory, size );
    if ( !block )
      error = FT_Err_Out_Of_Memory;
  }

  *perror = error;
  return block;
}

#undef   QALLOC  /* just in case */
#define  QALLOC(ptr,size)    ( (ptr) = ftglue_qalloc( memory, (size), &error ), error != 0 )
#define  FREE(_ptr)                    \
  do {                                 \
    if ( (_ptr) )                      \
    {                                  \
      ftglue_free( memory, _ptr );     \
      _ptr = NULL;                     \
    }                                  \
  } while (0)


static void
ftglue_free( FT_Memory   memory,
             FT_Pointer  block )
{
  if ( block )
    memory->free( memory, block );
}

FTGLUE_APIDEF( FT_Long )
ftglue_stream_pos( FT_Stream   stream )
{
  LOG(( "ftglue:stream:pos() -> %ld\n", stream->pos ));
  return stream->pos;
}


FTGLUE_APIDEF( FT_Error )
ftglue_stream_seek( FT_Stream   stream,
                    FT_Long     pos )
{
  FT_Error  error = 0;

  if ( stream->read )
  {
    if ( stream->read( stream, pos, 0, 0 ) )
      error = FT_Err_Invalid_Stream_Operation;
  }
  else if ( pos > stream->size )
    error = FT_Err_Invalid_Stream_Operation;

  if ( !error )
    stream->pos = pos;
  LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos, error ));
  return error;
}


FTGLUE_APIDEF( FT_Error )
ftglue_stream_frame_enter( FT_Stream   stream,
                           FT_ULong    count )
{
  FT_Error  error = FT_Err_Ok;
  FT_ULong  read_bytes;

  if ( stream->read )
  {
    /* allocate the frame in memory */
    FT_Memory  memory = stream->memory;


    if ( QALLOC( stream->base, count ) )
      goto Exit;

    /* read it */
    read_bytes = stream->read( stream, stream->pos,
                               stream->base, count );
    if ( read_bytes < count )
    {
      FREE( stream->base );
      error = FT_Err_Invalid_Stream_Operation;
    }
    stream->cursor = stream->base;
    stream->limit  = stream->cursor + count;
    stream->pos   += read_bytes;
  }
  else
  {
    /* check current and new position */
    if ( stream->pos >= stream->size        ||
         stream->pos + count > stream->size )
    {
      error = FT_Err_Invalid_Stream_Operation;
      goto Exit;
    }

    /* set cursor */
    stream->cursor = stream->base + stream->pos;
    stream->limit  = stream->cursor + count;
    stream->pos   += count;
  }

Exit:
  LOG(( "ftglue:stream:frame_enter(%ld) -> %d\n", count, error ));
  return error;
}


FTGLUE_APIDEF( void )
ftglue_stream_frame_exit( FT_Stream  stream )
{
  if ( stream->read )
  {
    FT_Memory  memory = stream->memory;

    FREE( stream->base );
  }
  stream->cursor = 0;
  stream->limit  = 0;

  LOG(( "ftglue:stream:frame_exit()\n" ));
}


FTGLUE_APIDEF( FT_Error )
ftglue_face_goto_table( FT_Face    face,
                        FT_ULong   the_tag,
                        FT_Stream  stream )
{
  FT_Error  error;

  LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n",
                face,
                (int)((the_tag >> 24) & 0xFF),
                (int)((the_tag >> 16) & 0xFF),
                (int)((the_tag >> 8) & 0xFF),
                (int)(the_tag & 0xFF),
                stream ));

  if ( !FT_IS_SFNT(face) )
  {
    LOG(( "not a SFNT face !!\n" ));
    error = FT_Err_Invalid_Face_Handle;
  }
  else
  {
   /* parse the directory table directly, without using
    * FreeType's built-in data structures
    */
    FT_ULong  offset = 0, sig;
    FT_UInt   count, nn;

    if ( FILE_Seek( 0 ) || ACCESS_Frame( 4 ) )
      goto Exit;

    sig = GET_Tag4();

    FORGET_Frame();

    if ( sig == FT_MAKE_TAG( 't', 't', 'c', 'f' ) )
    {
      /* deal with TrueType collections */

      LOG(( ">> This is a TrueType Collection\n" ));

      if ( FILE_Seek( 12 + face->face_index*4 ) ||
           ACCESS_Frame( 4 )                    )
        goto Exit;

      offset = GET_ULong();

      FORGET_Frame();
    }

    LOG(( "TrueType offset = %ld\n", offset ));

    if ( FILE_Seek( offset+4 ) ||
         ACCESS_Frame( 2 )     )
      goto Exit;

    count = GET_UShort();

    FORGET_Frame();

    if ( FILE_Seek( offset+12 )   ||
         ACCESS_Frame( count*16 ) )
      goto Exit;

    for ( nn = 0; nn < count; nn++ )
    {
      FT_ULong  tag      = GET_ULong();
      FT_ULong  checksum = GET_ULong();
      FT_ULong  start    = GET_ULong();
      FT_ULong  size     = GET_ULong();

      FT_UNUSED(checksum);
      FT_UNUSED(size);

      if ( tag == the_tag )
      {
        LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size ));
        error = ftglue_stream_seek( stream, start );
        goto FoundIt;
      }
    }
    error = FT_Err_Table_Missing;

  FoundIt:
    FORGET_Frame();
  }

Exit:
  LOG(( "TrueType error=%d\n", error ));

  return error;
}

#undef QALLOC
#define __ftglue__
#include "fcaliastail.h"
#undef __ftglue__
