/*******************************************************************
 *
 *  ftxgpos.c
 *
 *    TrueType Open GPOS table support.
 *
 *  Copyright 1996-2000 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.
 *
 ******************************************************************/

/* XXX There is *a lot* of duplicated code (cf. formats 7 and 8), but
       I don't care currently.  I believe that it would be possible to
       save about 50% of TTO code by carefully designing the structures,
       sharing as much as possible with extensive use of macros.  This
       is something for a volunteer :-)                                  */

#include "ftxopen.h"
#include "ftxopenf.h"

#include "fterrcompat.h"

#include FT_TRUETYPE_TAGS_H

#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_TRUETYPE_TYPES_H

#define TTAG_GPOS  FT_MAKE_TAG( 'G', 'P', 'O', 'S' )

  struct  GPOS_Instance_
  {
    TTO_GPOSHeader*  gpos;
    FT_Face          face;
    FT_Bool          dvi;
    FT_UShort        load_flags;  /* how the glyph should be loaded */
    FT_Bool          r2l;

    FT_UShort        first;       /* the first glyph in a chain of
                                     cursive connections           */
    FT_UShort        last;        /* the last valid glyph -- used
                                     with cursive positioning     */
    FT_Pos           anchor_x;    /* the coordinates of the anchor point */
    FT_Pos           anchor_y;    /* of the last valid glyph             */
  };

  typedef struct GPOS_Instance_  GPOS_Instance;


  static FT_Error  Do_Glyph_Lookup( GPOS_Instance*    gpi,
                                    FT_UShort         lookup_index,
                                    TTO_GSUB_String*  in,
                                    TTO_GPOS_Data*    out,
                                    FT_UShort         context_length,
                                    int               nesting_level );


  /* the client application must replace this with something more
     meaningful if multiple master fonts are to be supported.     */

  static FT_Error  default_mmfunc( FT_Face      face,
                                   FT_UShort    metric_id,
                                   FT_Pos*      metric_value,
                                   void*        data )
  {
    return TTO_Err_No_MM_Interpreter;
  }


#if 0
#define GPOS_ID  Build_Extension_ID( 'G', 'P', 'O', 'S' )

  /**********************
   * Extension Functions
   **********************/

  static FT_Error  GPOS_Create( void*      ext,
                                FT_Stream stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    TTO_GPOSHeader*  gpos = (TTO_GPOSHeader*)ext;
    FT_Long          table;


    /* by convention */

    if ( !gpos )
      return TT_Err_Ok;

    /* a null offset indicates that there is no GPOS table */

    gpos->offset = 0;

    /* we store the start offset and the size of the subtable */

    table = face->lookup_table ( face, TTAG_GPOS );
    if ( table < 0 )
      return TT_Err_Ok;             /* The table is optional */

    if ( FILE_Seek( face->dirTables[table].Offset ) ||
         ACCESS_Frame( 4L ) )
      return error;

    gpos->offset  = FILE_Pos() - 4L;    /* undo ACCESS_Frame() */
    gpos->Version = GET_ULong();

    FORGET_Frame();

    /* a default mmfunc() handler which just returns an error */

    gpos->mmfunc = default_mmfunc;

    /* the default glyph function is TT_Load_Glyph() */

    gpos->gfunc = FT_Load_Glyph;

    gpos->loaded = FALSE;

    return TT_Err_Ok;
  }


  static FT_Error  GPOS_Destroy( void*  ext,
                                 PFace  face )
  {
    TTO_GPOSHeader*  gpos = (TTO_GPOSHeader*)ext;


    /* by convention */

    if ( !gpos )
      return TT_Err_Ok;

    if ( gpos->loaded )
    {
      Free_LookupList( &gpos->LookupList, GPOS );
      Free_FeatureList( &gpos->FeatureList );
      Free_ScriptList( &gpos->ScriptList );
    }

    return TT_Err_Ok;
  }


  EXPORT_FUNC
  FT_Error  TT_Init_GPOS_Extension( TT_Engine  engine )
  {
    PEngine_Instance  _engine = HANDLE_Engine( engine );


    if ( !_engine )
      return TT_Err_Invalid_Engine;

    return  TT_Register_Extension( _engine,
                                   GPOS_ID,
                                   sizeof ( TTO_GPOSHeader ),
                                   GPOS_Create,
                                   GPOS_Destroy );
  }
#endif

  EXPORT_FUNC
  FT_Error  TT_Load_GPOS_Table( FT_Face          face,
                                TTO_GPOSHeader** retptr,
                                TTO_GDEFHeader*  gdef )
  {
    FT_ULong         cur_offset, new_offset, base_offset;

    FT_UShort        i, num_lookups;
    TTO_GPOSHeader*  gpos;
    TTO_Lookup*      lo;
    TT_Face          tt_face = (TT_Face)face;

    FT_Stream  stream = face->stream;
    FT_Error   error;
    FT_Memory  memory = face->memory;


    if ( !retptr )
      return TT_Err_Invalid_Argument;

    if ( !stream )
      return TT_Err_Invalid_Face_Handle;

    if (( error = tt_face->goto_table( tt_face, TTAG_GPOS, stream, 0 ) ))
      return error;

    base_offset = FILE_Pos();

    if ( ALLOC ( gpos, sizeof( *gpos ) ) )
      return error;

    gpos->memory = memory;
    gpos->gfunc = FT_Load_Glyph;
    gpos->mmfunc = default_mmfunc;

    /* skip version */

    if ( FILE_Seek( base_offset + 4L ) ||
         ACCESS_Frame( 2L ) )
      goto Fail4;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_ScriptList( &gpos->ScriptList,
                                    stream ) ) != TT_Err_Ok )
      goto Fail4;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail3;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_FeatureList( &gpos->FeatureList,
                                     stream ) ) != TT_Err_Ok )
      goto Fail3;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_LookupList( &gpos->LookupList,
                                    stream, GPOS ) ) != TT_Err_Ok )
      goto Fail2;

    gpos->gdef = gdef;      /* can be NULL */

    /* We now check the LookupFlags for values larger than 0xFF to find
       out whether we need to load the `MarkAttachClassDef' field of the
       GDEF table -- this hack is necessary for OpenType 1.2 tables since
       the version field of the GDEF table hasn't been incremented.

       For constructed GDEF tables, we only load it if
       `MarkAttachClassDef_offset' is not zero (nevertheless, a build of
       a constructed mark attach table is not supported currently).       */

    if ( gdef &&
         gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )
    {
      lo          = gpos->LookupList.Lookup;
      num_lookups = gpos->LookupList.LookupCount;

      for ( i = 0; i < num_lookups; i++ )
      {
        if ( lo[i].LookupFlag & IGNORE_SPECIAL_MARKS )
        {
          if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||
               ( error = Load_ClassDefinition( &gdef->MarkAttachClassDef,
                                               256, stream ) ) != TT_Err_Ok )
            goto Fail1;

          break;
        }
      }
    }

    *retptr = gpos;

    return TT_Err_Ok;

  Fail1:
    Free_LookupList( &gpos->LookupList, GPOS, memory );

  Fail2:
    Free_FeatureList( &gpos->FeatureList, memory );

  Fail3:
    Free_ScriptList( &gpos->ScriptList, memory );

  Fail4:
    FREE( gpos );

    return error;
  }

  EXPORT_FUNC
  FT_Error  TT_Done_GPOS_Table( TTO_GPOSHeader* gpos )
  {
    FT_Memory memory = gpos->memory;
    
    Free_LookupList( &gpos->LookupList, GPOS, memory );
    Free_FeatureList( &gpos->FeatureList, memory );
    Free_ScriptList( &gpos->ScriptList, memory );

    return FT_Err_Ok;
  }


  /*****************************
   * SubTable related functions
   *****************************/

  /* shared tables */

  /* ValueRecord */

  /* There is a subtle difference in the specs between a `table' and a
     `record' -- offsets for device tables in ValueRecords are taken from
     the parent table and not the parent record.                          */

  static FT_Error  Load_ValueRecord( TTO_ValueRecord*  vr,
                                     FT_UShort         format,
                                     FT_ULong          base_offset,
                                     FT_Stream         stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;
    
    FT_ULong cur_offset, new_offset;


    if ( format & HAVE_X_PLACEMENT )
    {
      if ( ACCESS_Frame( 2L ) )
        return error;

      vr->XPlacement = GET_Short();

      FORGET_Frame();
    }
    else
      vr->XPlacement = 0;

    if ( format & HAVE_Y_PLACEMENT )
    {
      if ( ACCESS_Frame( 2L ) )
        return error;

      vr->YPlacement = GET_Short();

      FORGET_Frame();
    }
    else
      vr->YPlacement = 0;

    if ( format & HAVE_X_ADVANCE )
    {
      if ( ACCESS_Frame( 2L ) )
        return error;

      vr->XAdvance = GET_Short();

      FORGET_Frame();
    }
    else
      vr->XAdvance = 0;

    if ( format & HAVE_Y_ADVANCE )
    {
      if ( ACCESS_Frame( 2L ) )
        return error;

      vr->YAdvance = GET_Short();

      FORGET_Frame();
    }
    else
      vr->YAdvance = 0;

    if ( format & HAVE_X_PLACEMENT_DEVICE )
    {
      if ( ACCESS_Frame( 2L ) )
        return error;

      new_offset = GET_UShort();

      FORGET_Frame();

      if ( new_offset )
      {
        new_offset += base_offset;

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Device( &vr->XPlacementDevice,
                                    stream ) ) != TT_Err_Ok )
          return error;
        (void)FILE_Seek( cur_offset );
      }
      else
        goto empty1;
    }
    else
    {
    empty1:
      vr->XPlacementDevice.StartSize  = 0;
      vr->XPlacementDevice.EndSize    = 0;
      vr->XPlacementDevice.DeltaValue = NULL;
    }

    if ( format & HAVE_Y_PLACEMENT_DEVICE )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail3;

      new_offset = GET_UShort();

      FORGET_Frame();

      if ( new_offset )
      {
        new_offset += base_offset;

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Device( &vr->YPlacementDevice,
                                    stream ) ) != TT_Err_Ok )
          goto Fail3;
        (void)FILE_Seek( cur_offset );
      }
      else
        goto empty2;
    }
    else
    {
    empty2:
      vr->YPlacementDevice.StartSize  = 0;
      vr->YPlacementDevice.EndSize    = 0;
      vr->YPlacementDevice.DeltaValue = NULL;
    }

    if ( format & HAVE_X_ADVANCE_DEVICE )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail2;

      new_offset = GET_UShort();

      FORGET_Frame();

      if ( new_offset )
      {
        new_offset += base_offset;

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Device( &vr->XAdvanceDevice,
                                    stream ) ) != TT_Err_Ok )
          goto Fail2;
        (void)FILE_Seek( cur_offset );
      }
      else
        goto empty3;
    }
    else
    {
    empty3:
      vr->XAdvanceDevice.StartSize  = 0;
      vr->XAdvanceDevice.EndSize    = 0;
      vr->XAdvanceDevice.DeltaValue = NULL;
    }

    if ( format & HAVE_Y_ADVANCE_DEVICE )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail1;

      new_offset = GET_UShort();

      FORGET_Frame();

      if ( new_offset )
      {
        new_offset += base_offset;

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Device( &vr->YAdvanceDevice,
                                    stream ) ) != TT_Err_Ok )
          goto Fail1;
        (void)FILE_Seek( cur_offset );
      }
      else
        goto empty4;
    }
    else
    {
    empty4:
      vr->YAdvanceDevice.StartSize  = 0;
      vr->YAdvanceDevice.EndSize    = 0;
      vr->YAdvanceDevice.DeltaValue = NULL;
    }

    if ( format & HAVE_X_ID_PLACEMENT )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail1;

      vr->XIdPlacement = GET_UShort();

      FORGET_Frame();
    }
    else
      vr->XIdPlacement = 0;

    if ( format & HAVE_Y_ID_PLACEMENT )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail1;

      vr->YIdPlacement = GET_UShort();

      FORGET_Frame();
    }
    else
      vr->YIdPlacement = 0;

    if ( format & HAVE_X_ID_ADVANCE )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail1;

      vr->XIdAdvance = GET_UShort();

      FORGET_Frame();
    }
    else
      vr->XIdAdvance = 0;

    if ( format & HAVE_Y_ID_ADVANCE )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail1;

      vr->YIdAdvance = GET_UShort();

      FORGET_Frame();
    }
    else
      vr->YIdAdvance = 0;

    return TT_Err_Ok;

  Fail1:
    Free_Device( &vr->YAdvanceDevice, memory );

  Fail2:
    Free_Device( &vr->XAdvanceDevice, memory );

  Fail3:
    Free_Device( &vr->YPlacementDevice, memory );
    return error;
  }


  static void  Free_ValueRecord( TTO_ValueRecord*  vr,
                                 FT_UShort         format,
				 FT_Memory         memory )
  {
    if ( format & HAVE_Y_ADVANCE_DEVICE )
      Free_Device( &vr->YAdvanceDevice, memory );
    if ( format & HAVE_X_ADVANCE_DEVICE )
      Free_Device( &vr->XAdvanceDevice, memory );
    if ( format & HAVE_Y_PLACEMENT_DEVICE )
      Free_Device( &vr->YPlacementDevice, memory );
    if ( format & HAVE_X_PLACEMENT_DEVICE )
      Free_Device( &vr->XPlacementDevice, memory );
  }


  static FT_Error  Get_ValueRecord( GPOS_Instance*    gpi,
                                    TTO_ValueRecord*  vr,
                                    FT_UShort         format,
                                    TTO_GPOS_Data*    gd )
  {
    FT_Pos           value;
    FT_Short         pixel_value;
    FT_Error         error = TT_Err_Ok;
    TTO_GPOSHeader*  gpos = gpi->gpos;

    FT_UShort  x_ppem, y_ppem;
    FT_Fixed   x_scale, y_scale;


    if ( !format )
      return TT_Err_Ok;

    x_ppem  = gpi->face->size->metrics.x_ppem;
    y_ppem  = gpi->face->size->metrics.y_ppem;
    x_scale = gpi->face->size->metrics.x_scale;
    y_scale = gpi->face->size->metrics.y_scale;

    /* design units -> fractional pixel */

    if ( format & HAVE_X_PLACEMENT )
      gd->x_pos += x_scale * vr->XPlacement / 0x10000;
    if ( format & HAVE_Y_PLACEMENT )
      gd->y_pos += y_scale * vr->YPlacement / 0x10000;
    if ( format & HAVE_X_ADVANCE )
      gd->x_advance += x_scale * vr->XAdvance / 0x10000;
    if ( format & HAVE_Y_ADVANCE )
      gd->y_advance += y_scale * vr->YAdvance / 0x10000;

    if ( !gpi->dvi )
    {
      /* pixel -> fractional pixel */

      if ( format & HAVE_X_PLACEMENT_DEVICE )
      {
        Get_Device( &vr->XPlacementDevice, x_ppem, &pixel_value );
        gd->x_pos += pixel_value << 6;
      }
      if ( format & HAVE_Y_PLACEMENT_DEVICE )
      {
        Get_Device( &vr->YPlacementDevice, y_ppem, &pixel_value );
        gd->y_pos += pixel_value << 6;
      }
      if ( format & HAVE_X_ADVANCE_DEVICE )
      {
        Get_Device( &vr->XAdvanceDevice, x_ppem, &pixel_value );
        gd->x_advance += pixel_value << 6;
      }
      if ( format & HAVE_Y_ADVANCE_DEVICE )
      {
        Get_Device( &vr->YAdvanceDevice, y_ppem, &pixel_value );
        gd->y_advance += pixel_value << 6;
      }
    }

    /* values returned from mmfunc() are already in fractional pixels */

    if ( format & HAVE_X_ID_PLACEMENT )
    {
      error = (gpos->mmfunc)( gpi->face, vr->XIdPlacement,
                              &value, gpos->data );
      if ( error )
        return error;
      gd->x_pos += value;
    }
    if ( format & HAVE_Y_ID_PLACEMENT )
    {
      error = (gpos->mmfunc)( gpi->face, vr->YIdPlacement,
                              &value, gpos->data );
      if ( error )
        return error;
      gd->y_pos += value;
    }
    if ( format & HAVE_X_ID_ADVANCE )
    {
      error = (gpos->mmfunc)( gpi->face, vr->XIdAdvance,
                              &value, gpos->data );
      if ( error )
        return error;
      gd->x_advance += value;
    }
    if ( format & HAVE_Y_ID_ADVANCE )
    {
      error = (gpos->mmfunc)( gpi->face, vr->YIdAdvance,
                              &value, gpos->data );
      if ( error )
        return error;
      gd->y_advance += value;
    }

    return error;
  }


  /* AnchorFormat1 */
  /* AnchorFormat2 */
  /* AnchorFormat3 */
  /* AnchorFormat4 */

  static FT_Error  Load_Anchor( TTO_Anchor*  an,
                                FT_Stream    stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_ULong cur_offset, new_offset, base_offset;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    an->PosFormat = GET_UShort();

    FORGET_Frame();

    switch ( an->PosFormat )
    {
    case 1:
      if ( ACCESS_Frame( 4L ) )
        return error;

      an->af.af1.XCoordinate = GET_Short();
      an->af.af1.YCoordinate = GET_Short();

      FORGET_Frame();
      break;

    case 2:
      if ( ACCESS_Frame( 6L ) )
        return error;

      an->af.af2.XCoordinate = GET_Short();
      an->af.af2.YCoordinate = GET_Short();
      an->af.af2.AnchorPoint = GET_UShort();

      FORGET_Frame();
      break;

    case 3:
      if ( ACCESS_Frame( 6L ) )
        return error;

      an->af.af3.XCoordinate = GET_Short();
      an->af.af3.YCoordinate = GET_Short();

      new_offset = GET_UShort();

      FORGET_Frame();

      if ( new_offset )
      {
        new_offset += base_offset;

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Device( &an->af.af3.XDeviceTable,
                                    stream ) ) != TT_Err_Ok )
          return error;
        (void)FILE_Seek( cur_offset );
      }
      else
      {
        an->af.af3.XDeviceTable.StartSize  = 0;
        an->af.af3.XDeviceTable.EndSize    = 0;
        an->af.af3.XDeviceTable.DeltaValue = 0;
      }

      if ( ACCESS_Frame( 2L ) )
        goto Fail;

      new_offset = GET_UShort();

      FORGET_Frame();

      if ( new_offset )
      {
        new_offset += base_offset;

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Device( &an->af.af3.YDeviceTable,
                                    stream ) ) != TT_Err_Ok )
          goto Fail;
        (void)FILE_Seek( cur_offset );
      }
      else
      {
        an->af.af3.YDeviceTable.StartSize  = 0;
        an->af.af3.YDeviceTable.EndSize    = 0;
        an->af.af3.YDeviceTable.DeltaValue = 0;
      }
      break;

    case 4:
      if ( ACCESS_Frame( 4L ) )
        return error;

      an->af.af4.XIdAnchor = GET_UShort();
      an->af.af4.YIdAnchor = GET_UShort();

      FORGET_Frame();
      break;

    default:
      return TTO_Err_Invalid_GPOS_SubTable_Format;
    }

    return TT_Err_Ok;

  Fail:
    Free_Device( &an->af.af3.XDeviceTable, memory );
    return error;
  }


  static void  Free_Anchor( TTO_Anchor*  an,
			    FT_Memory    memory)
  {
    if ( an->PosFormat == 3 )
    {
      Free_Device( &an->af.af3.YDeviceTable, memory );
      Free_Device( &an->af.af3.XDeviceTable, memory );
    }
  }


  static FT_Error  Get_Anchor( GPOS_Instance*   gpi,
                               TTO_Anchor*      an,
                               FT_UShort        glyph_index,
                               FT_Pos*          x_value,
                               FT_Pos*          y_value )
  {
    FT_Error  error = TT_Err_Ok;

    FT_Outline       outline;
    TTO_GPOSHeader*  gpos = gpi->gpos;
    FT_UShort        ap;

    FT_Short         pixel_value;
    FT_UShort        load_flags;

    FT_UShort        x_ppem, y_ppem;
    FT_Fixed         x_scale, y_scale;


    x_ppem  = gpi->face->size->metrics.x_ppem;
    y_ppem  = gpi->face->size->metrics.y_ppem;
    x_scale = gpi->face->size->metrics.x_scale;
    y_scale = gpi->face->size->metrics.y_scale;

    switch ( an->PosFormat )
    {
    case 0:
      /* The special case of an empty AnchorTable */

      return TTO_Err_Not_Covered;

    case 1:
      *x_value = x_scale * an->af.af1.XCoordinate / 0x10000;
      *y_value = y_scale * an->af.af1.YCoordinate / 0x10000;
      break;

    case 2:
      /* glyphs must be scaled */

      load_flags = gpi->load_flags & ~FT_LOAD_NO_SCALE;

      if ( !gpi->dvi )
      {
        error = (gpos->gfunc)( gpi->face, glyph_index, load_flags );
        if ( error )
          return error;

	if ( gpi->face->glyph->format != ft_glyph_format_outline )
          return TTO_Err_Invalid_GPOS_SubTable;	  

	ap = an->af.af2.AnchorPoint;
	
	outline = gpi->face->glyph->outline;

        /* if outline.n_points is set to zero by gfunc(), we use the
           design coordinate value pair.  This can happen e.g. for
           sbit glyphs                                               */

        if ( !outline.n_points )
          goto no_contour_point;

        if ( ap >= outline.n_points )
          return TTO_Err_Invalid_GPOS_SubTable;

        *x_value = outline.points[ap].x;
        *y_value = outline.points[ap].y;
      }
      else
      {
      no_contour_point:
        *x_value = x_scale * an->af.af3.XCoordinate / 0x10000;
        *y_value = y_scale * an->af.af3.YCoordinate / 0x10000;
      }
      break;

    case 3:
      if ( !gpi->dvi )
      {
        Get_Device( &an->af.af3.XDeviceTable, x_ppem, &pixel_value );
        *x_value = pixel_value << 6;
        Get_Device( &an->af.af3.YDeviceTable, y_ppem, &pixel_value );
        *y_value = pixel_value << 6;
      }
      else
        *x_value = *y_value = 0;

      *x_value += x_scale * an->af.af3.XCoordinate / 0x10000;
      *y_value += y_scale * an->af.af3.YCoordinate / 0x10000;
      break;

    case 4:
      error = (gpos->mmfunc)( gpi->face, an->af.af4.XIdAnchor,
                              x_value, gpos->data );
      if ( error )
        return error;

      error = (gpos->mmfunc)( gpi->face, an->af.af4.YIdAnchor,
                              y_value, gpos->data );
      if ( error )
        return error;
      break;
    }

    return error;
  }


  /* MarkArray */

  static FT_Error  Load_MarkArray ( TTO_MarkArray*  ma,
                                    FT_Stream       stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort        n, m, count;
    FT_ULong         cur_offset, new_offset, base_offset;

    TTO_MarkRecord*  mr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = ma->MarkCount = GET_UShort();
    
    FORGET_Frame();

    ma->MarkRecord = NULL;

    if ( ALLOC_ARRAY( ma->MarkRecord, count, TTO_MarkRecord ) )
      return error;

    mr = ma->MarkRecord;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 4L ) )
        goto Fail;

      mr[n].Class = GET_UShort();
      new_offset  = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_Anchor( &mr[n].MarkAnchor, stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

  Fail:
    for ( m = 0; m < n; m++ )
      Free_Anchor( &mr[m].MarkAnchor, memory );

    FREE( mr );
    return error;
  }


  static void  Free_MarkArray( TTO_MarkArray*  ma,
			       FT_Memory       memory )
  {
    FT_UShort        n, count;

    TTO_MarkRecord*  mr;


    if ( ma->MarkRecord )
    {
      count = ma->MarkCount;
      mr    = ma->MarkRecord;

      for ( n = 0; n < count; n++ )
        Free_Anchor( &mr[n].MarkAnchor, memory );

      FREE( mr );
    }
  }


  /* LookupType 1 */

  /* SinglePosFormat1 */
  /* SinglePosFormat2 */

  FT_Error  Load_SinglePos( TTO_SinglePos*  sp,
                            FT_Stream       stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort         n, m, count, format;
    FT_ULong          cur_offset, new_offset, base_offset;

    TTO_ValueRecord*  vr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 6L ) )
      return error;

    sp->PosFormat = GET_UShort();
    new_offset    = GET_UShort() + base_offset;

    format = sp->ValueFormat = GET_UShort();

    FORGET_Frame();

    if ( !format )
      return TTO_Err_Invalid_GPOS_SubTable;

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &sp->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    switch ( sp->PosFormat )
    {
    case 1:
      error = Load_ValueRecord( &sp->spf.spf1.Value, format,
                                base_offset, stream );
      if ( error )
        goto Fail2;
      break;

    case 2:
      if ( ACCESS_Frame( 2L ) )
        goto Fail2;

      count = sp->spf.spf2.ValueCount = GET_UShort();

      FORGET_Frame();

      sp->spf.spf2.Value = NULL;

      if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, TTO_ValueRecord ) )
        goto Fail2;

      vr = sp->spf.spf2.Value;

      for ( n = 0; n < count; n++ )
      {
        error = Load_ValueRecord( &vr[n], format, base_offset, stream );
        if ( error )
          goto Fail1;
      }
      break;

    default:
      return TTO_Err_Invalid_GPOS_SubTable_Format;
    }

    return TT_Err_Ok;

  Fail1:
    for ( m = 0; m < n; m++ )
      Free_ValueRecord( &vr[m], format, memory );

    FREE( vr );

  Fail2:
    Free_Coverage( &sp->Coverage, memory );
    return error;
  }


  void  Free_SinglePos( TTO_SinglePos*  sp,
			FT_Memory       memory )
  {
    FT_UShort         n, count, format;

    TTO_ValueRecord*  v;


    format = sp->ValueFormat;

    switch ( sp->PosFormat )
    {
    case 1:
      Free_ValueRecord( &sp->spf.spf1.Value, format, memory );
      break;

    case 2:
      if ( sp->spf.spf2.Value )
      {
        count = sp->spf.spf2.ValueCount;
        v     = sp->spf.spf2.Value;

        for ( n = 0; n < count; n++ )
          Free_ValueRecord( &v[n], format, memory );

        FREE( v );
      }
      break;
    }

    Free_Coverage( &sp->Coverage, memory );
  }


  static FT_Error  Lookup_SinglePos( GPOS_Instance*    gpi,
                                     TTO_SinglePos*    sp,
                                     TTO_GSUB_String*  in,
                                     TTO_GPOS_Data*    out,
                                     FT_UShort         flags,
                                     FT_UShort         context_length )
  {
    FT_UShort        index, property;
    FT_Error         error;
    TTO_GPOSHeader*  gpos = gpi->gpos;


    if ( context_length != 0xFFFF && context_length < 1 )
      return TTO_Err_Not_Covered;

    if ( CHECK_Property( gpos->gdef, in->string[in->pos], flags, &property ) )
      return error;

    error = Coverage_Index( &sp->Coverage, in->string[in->pos], &index );
    if ( error )
      return error;

    switch ( sp->PosFormat )
    {
    case 1:
      error = Get_ValueRecord( gpi, &sp->spf.spf1.Value,
                               sp->ValueFormat, &out[in->pos] );
      if ( error )
        return error;
      break;

    case 2:
      if ( index >= sp->spf.spf2.ValueCount )
        return TTO_Err_Invalid_GPOS_SubTable;
      error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index],
                               sp->ValueFormat, &out[in->pos] );
      if ( error )
        return error;
      break;

    default:
      return TTO_Err_Invalid_GPOS_SubTable;
    }

    (in->pos)++;

    return TT_Err_Ok;
  }


  /* LookupType 2 */

  /* PairSet */

  static FT_Error  Load_PairSet ( TTO_PairSet*  ps,
                                  FT_UShort     format1,
                                  FT_UShort     format2,
                                  FT_Stream     stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             n, m, count;
    FT_ULong              base_offset;

    TTO_PairValueRecord*  pvr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = ps->PairValueCount = GET_UShort();
    
    FORGET_Frame();

    ps->PairValueRecord = NULL;

    if ( ALLOC_ARRAY( ps->PairValueRecord, count, TTO_PairValueRecord ) )
      return error;

    pvr = ps->PairValueRecord;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail;

      pvr[n].SecondGlyph = GET_UShort();

      FORGET_Frame();

      if ( format1 )
      {
        error = Load_ValueRecord( &pvr[n].Value1, format1,
                                  base_offset, stream );
        if ( error )
          goto Fail;
      }
      if ( format2 )
      {
        error = Load_ValueRecord( &pvr[n].Value2, format2,
                                  base_offset, stream );
        if ( error )
	{
	  if ( format1 )
	    Free_ValueRecord( &pvr[n].Value1, format1, memory );
          goto Fail;
	}
      }
    }

    return TT_Err_Ok;

  Fail:
    for ( m = 0; m < n; m++ )
    {
      if ( format1 )
        Free_ValueRecord( &pvr[m].Value1, format1, memory );
      if ( format2 )
        Free_ValueRecord( &pvr[m].Value2, format2, memory );
    }

    FREE( pvr );
    return error;
  }


  static void  Free_PairSet( TTO_PairSet*  ps,
                             FT_UShort     format1,
                             FT_UShort     format2,
			     FT_Memory     memory )
  {
    FT_UShort             n, count;

    TTO_PairValueRecord*  pvr;


    if ( ps->PairValueRecord )
    {
      count = ps->PairValueCount;
      pvr   = ps->PairValueRecord;

      for ( n = 0; n < count; n++ )
      {
        if ( format1 )
          Free_ValueRecord( &pvr[n].Value1, format1, memory );
        if ( format2 )
          Free_ValueRecord( &pvr[n].Value2, format2, memory );
      }

      FREE( pvr );
    }
  }


  /* PairPosFormat1 */

  static FT_Error  Load_PairPos1( TTO_PairPosFormat1*  ppf1,
                                  FT_UShort            format1,
                                  FT_UShort            format2,
                                  FT_Stream            stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort     n, m, count;
    FT_ULong      cur_offset, new_offset, base_offset;

    TTO_PairSet*  ps;


    base_offset = FILE_Pos() - 8L;

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = ppf1->PairSetCount = GET_UShort();

    FORGET_Frame();

    ppf1->PairSet = NULL;

    if ( ALLOC_ARRAY( ppf1->PairSet, count, TTO_PairSet ) )
      return error;

    ps = ppf1->PairSet;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_PairSet( &ps[n], format1,
                                   format2, stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

  Fail:
    for ( m = 0; m < n; m++ )
      Free_PairSet( &ps[m], format1, format2, memory );

    FREE( ps );
    return error;
  }


  static void  Free_PairPos1( TTO_PairPosFormat1*  ppf1,
                              FT_UShort            format1,
                              FT_UShort            format2,
			      FT_Memory            memory )
  {
    FT_UShort     n, count;

    TTO_PairSet*  ps;


    if ( ppf1->PairSet )
    {
      count = ppf1->PairSetCount;
      ps    = ppf1->PairSet;

      for ( n = 0; n < count; n++ )
        Free_PairSet( &ps[n], format1, format2, memory );

      FREE( ps );
    }
  }


  /* PairPosFormat2 */

  static FT_Error  Load_PairPos2( TTO_PairPosFormat2*  ppf2,
                                  FT_UShort            format1,
                                  FT_UShort            format2,
                                  FT_Stream            stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort          m, n, k, count1, count2;
    FT_ULong           cur_offset, new_offset1, new_offset2, base_offset;

    TTO_Class1Record*  c1r;
    TTO_Class2Record*  c2r;


    base_offset = FILE_Pos() - 8L;

    if ( ACCESS_Frame( 8L ) )
      return error;

    new_offset1 = GET_UShort() + base_offset;
    new_offset2 = GET_UShort() + base_offset;

    /* `Class1Count' and `Class2Count' are the upper limits for class
       values, thus we read it now to make additional safety checks.  */

    count1 = ppf2->Class1Count = GET_UShort();
    count2 = ppf2->Class2Count = GET_UShort();

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset1 ) ||
         ( error = Load_ClassDefinition( &ppf2->ClassDef1, count1,
                                         stream ) ) != TT_Err_Ok )
      return error;
    if ( FILE_Seek( new_offset2 ) ||
         ( error = Load_ClassDefinition( &ppf2->ClassDef2, count2,
                                         stream ) ) != TT_Err_Ok )
      goto Fail3;
    (void)FILE_Seek( cur_offset );

    ppf2->Class1Record = NULL;

    if ( ALLOC_ARRAY( ppf2->Class1Record, count1, TTO_Class1Record ) )
      goto Fail2;

    c1r = ppf2->Class1Record;

    for ( m = 0; m < count1; m++ )
    {
      c1r[m].Class2Record = NULL;

      if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, TTO_Class2Record ) )
        goto Fail1;

      c2r = c1r[m].Class2Record;

      for ( n = 0; n < count2; n++ )
      {
        if ( format1 )
        {
          error = Load_ValueRecord( &c2r[n].Value1, format1,
                                    base_offset, stream );
          if ( error )
            goto Fail0;
        }
        if ( format2 )
        {
          error = Load_ValueRecord( &c2r[n].Value2, format2,
                                    base_offset, stream );
          if ( error )
	  {
	    if ( format1 )
	      Free_ValueRecord( &c2r[n].Value1, format1, memory );	      
            goto Fail0;
	  }
        }
      }

      continue;

    Fail0:
      for ( k = 0; k < n; k++ )
      {
        if ( format1 )
          Free_ValueRecord( &c2r[k].Value1, format1, memory );
        if ( format2 )
          Free_ValueRecord( &c2r[k].Value2, format2, memory );
      }
      goto Fail1;
    }

    return TT_Err_Ok;

  Fail1:
    for ( k = 0; k < m; k++ )
    {
      c2r = c1r[k].Class2Record;

      for ( n = 0; n < count2; n++ )
      {
        if ( format1 )
          Free_ValueRecord( &c2r[n].Value1, format1, memory );
        if ( format2 )
          Free_ValueRecord( &c2r[n].Value2, format2, memory );
      }

      FREE( c2r );
    }

    FREE( c1r );
  Fail2:

    Free_ClassDefinition( &ppf2->ClassDef2, memory );

  Fail3:
    Free_ClassDefinition( &ppf2->ClassDef1, memory );
    return error;
  }


  static void  Free_PairPos2( TTO_PairPosFormat2*  ppf2,
                              FT_UShort            format1,
                              FT_UShort            format2,
			      FT_Memory            memory )
  {
    FT_UShort          m, n, count1, count2;

    TTO_Class1Record*  c1r;
    TTO_Class2Record*  c2r;


    if ( ppf2->Class1Record )
    {
      c1r    = ppf2->Class1Record;
      count1 = ppf2->Class1Count;
      count2 = ppf2->Class2Count;

      for ( m = 0; m < count1; m++ )
      {
        c2r = c1r[m].Class2Record;

        for ( n = 0; n < count2; n++ )
        {
          if ( format1 )
            Free_ValueRecord( &c2r[n].Value1, format1, memory );
          if ( format2 )
            Free_ValueRecord( &c2r[n].Value2, format2, memory );
        }

        FREE( c2r );
      }

      FREE( c1r );

      Free_ClassDefinition( &ppf2->ClassDef2, memory );
      Free_ClassDefinition( &ppf2->ClassDef1, memory );
    }
  }


  FT_Error  Load_PairPos( TTO_PairPos*  pp,
                          FT_Stream     stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort         format1, format2;
    FT_ULong          cur_offset, new_offset, base_offset;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 8L ) )
      return error;

    pp->PosFormat = GET_UShort();
    new_offset    = GET_UShort() + base_offset;

    format1 = pp->ValueFormat1 = GET_UShort();
    format2 = pp->ValueFormat2 = GET_UShort();

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &pp->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    switch ( pp->PosFormat )
    {
    case 1:
      error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, stream );
      if ( error )
        goto Fail;
      break;

    case 2:
      error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, stream );
      if ( error )
        goto Fail;
      break;

    default:
      return TTO_Err_Invalid_GPOS_SubTable_Format;
    }

    return TT_Err_Ok;

  Fail:
    Free_Coverage( &pp->Coverage, memory );
    return error;
  }


  void  Free_PairPos( TTO_PairPos*  pp,
		      FT_Memory     memory )
  {
    FT_UShort  format1, format2;


    format1 = pp->ValueFormat1;
    format2 = pp->ValueFormat2;

    switch ( pp->PosFormat )
    {
    case 1:
      Free_PairPos1( &pp->ppf.ppf1, format1, format2, memory );
      break;

    case 2:
      Free_PairPos2( &pp->ppf.ppf2, format1, format2, memory );
      break;
    }

    Free_Coverage( &pp->Coverage, memory );
  }


  static FT_Error  Lookup_PairPos1( GPOS_Instance*       gpi,
                                    TTO_PairPosFormat1*  ppf1,
                                    TTO_GSUB_String*     in,
                                    TTO_GPOS_Data*       out,
                                    FT_UShort            first_pos,
                                    FT_UShort            index,
                                    FT_UShort            format1,
                                    FT_UShort            format2 )
  {
    FT_Error              error;
    FT_UShort             numpvr, glyph2;

    TTO_PairValueRecord*  pvr;


    if ( index >= ppf1->PairSetCount )
       return TTO_Err_Invalid_GPOS_SubTable;

    pvr = ppf1->PairSet[index].PairValueRecord;
    if ( !pvr )
      return TTO_Err_Invalid_GPOS_SubTable;

    glyph2 = in->string[in->pos];

    for ( numpvr = ppf1->PairSet[index].PairValueCount;
          numpvr;
          numpvr--, pvr++ )
    {
      if ( glyph2 == pvr->SecondGlyph )
      {
        error = Get_ValueRecord( gpi, &pvr->Value1, format1,
                                 &out[first_pos] );
        if ( error )
          return error;
        return Get_ValueRecord( gpi, &pvr->Value2, format2,
                                &out[in->pos] );
      }
    }

    return TTO_Err_Not_Covered;
  }


  static FT_Error  Lookup_PairPos2( GPOS_Instance*       gpi,
                                    TTO_PairPosFormat2*  ppf2,
                                    TTO_GSUB_String*     in,
                                    TTO_GPOS_Data*       out,
                                    FT_UShort            first_pos,
                                    FT_UShort            format1,
                                    FT_UShort            format2 )
  {
    FT_Error           error;
    FT_UShort          cl1, cl2;

    TTO_Class1Record*  c1r;
    TTO_Class2Record*  c2r;


    error = Get_Class( &ppf2->ClassDef1, in->string[first_pos],
                       &cl1, NULL );
    if ( error && error != TTO_Err_Not_Covered )
      return error;
    error = Get_Class( &ppf2->ClassDef2, in->string[in->pos],
                       &cl2, NULL );
    if ( error && error != TTO_Err_Not_Covered )
      return error;

    c1r = &ppf2->Class1Record[cl1];
    if ( !c1r )
      return TTO_Err_Invalid_GPOS_SubTable;
    c2r = &c1r->Class2Record[cl2];

    error = Get_ValueRecord( gpi, &c2r->Value1, format1, &out[first_pos] );
    if ( error )
      return error;
    return Get_ValueRecord( gpi, &c2r->Value2, format2, &out[in->pos] );
  }


  static FT_Error  Lookup_PairPos( GPOS_Instance*    gpi,
                                   TTO_PairPos*      pp,
                                   TTO_GSUB_String*  in,
                                   TTO_GPOS_Data*    out,
                                   FT_UShort         flags,
                                   FT_UShort         context_length )
  {
    FT_Error         error;
    FT_UShort        index, property, first_pos;
    TTO_GPOSHeader*  gpos = gpi->gpos;


    if ( in->pos >= in->length - 1 )
      return TTO_Err_Not_Covered;           /* Not enough glyphs in stream */

    if ( context_length != 0xFFFF && context_length < 2 )
      return TTO_Err_Not_Covered;

    if ( CHECK_Property( gpos->gdef, in->string[in->pos], flags, &property ) )
      return error;

    error = Coverage_Index( &pp->Coverage, in->string[in->pos], &index );
    if ( error )
      return error;

    /* second glyph */

    first_pos = in->pos;
    (in->pos)++;

    while ( CHECK_Property( gpos->gdef, in->string[in->pos],
                            flags, &property ) )
    {
      if ( error && error != TTO_Err_Not_Covered )
        return error;

      if ( in->pos < in->length )
        (in->pos)++;
      else
        break;
    }

    switch ( pp->PosFormat )
    {
    case 1:
      error = Lookup_PairPos1( gpi, &pp->ppf.ppf1, in, out,
                               first_pos, index,
                               pp->ValueFormat1, pp->ValueFormat2 );
      break;

    case 2:
      error = Lookup_PairPos2( gpi, &pp->ppf.ppf2, in, out, first_pos,
                               pp->ValueFormat1, pp->ValueFormat2 );
      break;

    default:
      return TTO_Err_Invalid_GPOS_SubTable_Format;
    }

    /* adjusting the `next' glyph */

    if ( pp->ValueFormat2 )
      (in->pos)++;

    return error;
  }


  /* LookupType 3 */

  /* CursivePosFormat1 */

  FT_Error  Load_CursivePos( TTO_CursivePos*  cp,
                             FT_Stream        stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             n, m, count;
    FT_ULong              cur_offset, new_offset, base_offset;

    TTO_EntryExitRecord*  eer;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 4L ) )
      return error;

    cp->PosFormat = GET_UShort();
    new_offset    = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &cp->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = cp->EntryExitCount = GET_UShort();

    FORGET_Frame();

    cp->EntryExitRecord = NULL;

    if ( ALLOC_ARRAY( cp->EntryExitRecord, count, TTO_EntryExitRecord ) )
      goto Fail2;

    eer = cp->EntryExitRecord;

    for ( n = 0; n < count; n++ )
    {
      FT_ULong entry_offset;
      
      if ( ACCESS_Frame( 2L ) )
        return error;

      entry_offset = new_offset = GET_UShort();

      FORGET_Frame();

      if ( new_offset )
      {
        new_offset += base_offset;

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Anchor( &eer[n].EntryAnchor,
                                    stream ) ) != TT_Err_Ok )
          goto Fail1;
        (void)FILE_Seek( cur_offset );
      }
      else
        eer[n].EntryAnchor.PosFormat   = 0;

      if ( ACCESS_Frame( 2L ) )
        return error;

      new_offset = GET_UShort();

      FORGET_Frame();

      if ( new_offset )
      {
        new_offset += base_offset;

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Anchor( &eer[n].ExitAnchor,
                                    stream ) ) != TT_Err_Ok )
	{
	  if ( entry_offset )
	    Free_Anchor( &eer[n].EntryAnchor, memory );
          goto Fail1;
	}
        (void)FILE_Seek( cur_offset );
      }
      else
        eer[n].ExitAnchor.PosFormat   = 0;
    }

    return TT_Err_Ok;

  Fail1:
    for ( m = 0; m < n; m++ )
    {
      Free_Anchor( &eer[m].EntryAnchor, memory );
      Free_Anchor( &eer[m].ExitAnchor, memory );
    }

    FREE( eer );

  Fail2:
    Free_Coverage( &cp->Coverage, memory );
    return error;
  }


  void  Free_CursivePos( TTO_CursivePos*  cp,
			 FT_Memory        memory )
  {
    FT_UShort             n, count;

    TTO_EntryExitRecord*  eer;


    if ( cp->EntryExitRecord )
    {
      count = cp->EntryExitCount;
      eer   = cp->EntryExitRecord;

      for ( n = 0; n < count; n++ )
      {
        Free_Anchor( &eer[n].EntryAnchor, memory );
        Free_Anchor( &eer[n].ExitAnchor, memory );
      }

      FREE( eer );
    }

    Free_Coverage( &cp->Coverage, memory );
  }


  static FT_Error  Lookup_CursivePos( GPOS_Instance*    gpi,
                                      TTO_CursivePos*   cp,
                                      TTO_GSUB_String*  in,
                                      TTO_GPOS_Data*    out,
                                      FT_UShort         flags,
                                      FT_UShort         context_length )
  {
    FT_UShort        index, property;
    FT_Error         error;
    TTO_GPOSHeader*  gpos = gpi->gpos;

    TTO_EntryExitRecord*  eer;
    FT_Pos                entry_x, entry_y;
    FT_Pos                exit_x, exit_y;


    if ( context_length != 0xFFFF && context_length < 1 )
    {
      gpi->last = 0xFFFF;
      return TTO_Err_Not_Covered;
    }

    /* Glyphs not having the right GDEF properties will be ignored, i.e.,
       gpi->last won't be reset (contrary to user defined properties). */

    if ( CHECK_Property( gpos->gdef, in->string[in->pos], flags, &property ) )
      return error;

    /* We don't handle mark glyphs here.  According to Andrei, this isn't
       possible, but who knows...                                         */

    if ( property == MARK_GLYPH )
    {
      gpi->last = 0xFFFF;
      return TTO_Err_Not_Covered;
    }

    error = Coverage_Index( &cp->Coverage, in->string[in->pos], &index );
    if ( error )
    {
      gpi->last = 0xFFFF;
      return error;
    }

    if ( index >= cp->EntryExitCount )
      return TTO_Err_Invalid_GPOS_SubTable;

    eer = &cp->EntryExitRecord[index];

    /* Now comes the messiest part of the whole OpenType
       specification.  At first glance, cursive connections seem easy
       to understand, but there are pitfalls!  The reason is that
       the specs don't mention how to compute the advance values
       resp. glyph offsets.  I was told it would be an omission, to
       be fixed in the next OpenType version...  Again many thanks to
       Andrei Burago <andreib@microsoft.com> for clarifications.

       Consider the following example:

                        |  xadv1    |
                         +---------+
                         |         |
                   +-----+--+ 1    |
                   |     | .|      |
                   |    0+--+------+
                   |   2    |
                   |        |
                  0+--------+
                  |  xadv2   |

         glyph1: advance width = 12
                 anchor point = (3,1)

         glyph2: advance width = 11
                 anchor point = (9,4)

         LSB is 1 for both glyphs (so the boxes drawn above are glyph
         bboxes).  Writing direction is R2L; `0' denotes the glyph's
         coordinate origin.

       Now the surprising part: The advance width of the *left* glyph
       (resp. of the *bottom* glyph) will be modified, no matter
       whether the writing direction is L2R or R2L (resp. T2B or
       B2T)!  This assymetry is caused by the fact that the glyph's
       coordinate origin is always the lower left corner for all
       writing directions.

       Continuing the above example, we can compute the new
       (horizontal) advance width of glyph2 as

         9 - 3 = 6  ,

       and the new vertical offset of glyph2 as

         1 - 4 = -3  .


       Vertical writing direction is far more complicated:

       a) Assuming that we recompute the advance height of the lower glyph:

                                    --
                         +---------+
                --       |         |
                   +-----+--+ 1    | yadv1
                   |     | .|      |
             yadv2 |    0+--+------+        -- BSB1  --
                   |   2    |       --      --        y_offset
                   |        |
     BSB2 --      0+--------+                        --
          --    --

         glyph1: advance height = 6
                 anchor point = (3,1)

         glyph2: advance height = 7
                 anchor point = (9,4)

         TSB is 1 for both glyphs; writing direction is T2B.


           BSB1     = yadv1 - (TSB1 + ymax1)
           BSB2     = yadv2 - (TSB2 + ymax2)
           y_offset = y2 - y1

         vertical advance width of glyph2
           = y_offset + BSB2 - BSB1
           = (y2 - y1) + (yadv2 - (TSB2 + ymax2)) - (yadv1 - (TSB1 + ymax1))
           = y2 - y1 + yadv2 - TSB2 - ymax2 - (yadv1 - TSB1 - ymax1)
           = y2 - y1 + yadv2 - TSB2 - ymax2 - yadv1 + TSB1 + ymax1


       b) Assuming that we recompute the advance height of the upper glyph:

                                    --      --
                         +---------+        -- TSB1
          --    --       |         |
     TSB2 --       +-----+--+ 1    | yadv1   ymax1
                   |     | .|      |
             yadv2 |    0+--+------+        --       --
      ymax2        |   2    |       --                y_offset
                   |        |
          --      0+--------+                        --
                --

         glyph1: advance height = 6
                 anchor point = (3,1)

         glyph2: advance height = 7
                 anchor point = (9,4)

         TSB is 1 for both glyphs; writing direction is T2B.

         y_offset = y2 - y1

         vertical advance width of glyph2
           = TSB1 + ymax1 + y_offset - (TSB2 + ymax2)
           = TSB1 + ymax1 + y2 - y1 - TSB2 - ymax2


       Comparing a) with b) shows that b) is easier to compute.  I'll wait
       for a reply from Andrei to see what should really be implemented...

       Since horizontal advance widths or vertical advance heights
       can be used alone but not together, no ambiguity occurs.        */

    if ( gpi->last == 0xFFFF )
      goto end;

    /* Get_Anchor() returns TTO_Err_Not_Covered if there is no anchor
       table.                                                         */

    error = Get_Anchor( gpi, &eer->EntryAnchor, in->string[in->pos],
                        &entry_x, &entry_y );
    if ( error == TTO_Err_Not_Covered )
      goto end;
    if ( error )
      return error;

    if ( gpi->r2l )
    {
      out[in->pos].x_advance   = entry_x - gpi->anchor_x;
      out[in->pos].new_advance = TRUE;
    }
    else
    {
      out[gpi->last].x_advance   = gpi->anchor_x - entry_x;
      out[gpi->last].new_advance = TRUE;
    }

    out[in->pos].y_pos = gpi->anchor_y - entry_y + out[gpi->last].y_pos;

  end:
    error = Get_Anchor( gpi, &eer->ExitAnchor, in->string[in->pos],
                        &exit_x, &exit_y );
    if ( error == TTO_Err_Not_Covered )
      gpi->last = 0xFFFF;
    else
    {
      if ( gpi->first == 0xFFFF )
        gpi->first  = in->pos;
      gpi->last     = in->pos;
      gpi->anchor_x = exit_x;
      gpi->anchor_y = exit_y;
    }
    if ( error )
      return error;

    (in->pos)++;

    return TT_Err_Ok;
  }


  /* LookupType 4 */

  /* BaseArray */

  static FT_Error  Load_BaseArray( TTO_BaseArray*  ba,
                                   FT_UShort       num_classes,
                                   FT_Stream       stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort        m, n, k, count;
    FT_ULong         cur_offset, new_offset, base_offset;

    TTO_BaseRecord*  br;
    TTO_Anchor*      ban;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = ba->BaseCount = GET_UShort();
    
    FORGET_Frame();

    ba->BaseRecord = NULL;

    if ( ALLOC_ARRAY( ba->BaseRecord, count, TTO_BaseRecord ) )
      return error;

    br = ba->BaseRecord;

    for ( m = 0; m < count; m++ )
    {
      br[m].BaseAnchor = NULL;

      if ( ALLOC_ARRAY( br[m].BaseAnchor, num_classes, TTO_Anchor ) )
        goto Fail;

      ban = br[m].BaseAnchor;

      for ( n = 0; n < num_classes; n++ )
      {
        if ( ACCESS_Frame( 2L ) )
          goto Fail0;

        new_offset = GET_UShort() + base_offset;

        FORGET_Frame();

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Anchor( &ban[n], stream ) ) != TT_Err_Ok )
          goto Fail0;
        (void)FILE_Seek( cur_offset );
      }

      continue;
    Fail0:
      for ( k = 0; k < n; k++ )
        Free_Anchor( &ban[k], memory );
      goto Fail;
    }

    return TT_Err_Ok;

  Fail:
    for ( k = 0; k < m; k++ )
    {
      ban = br[k].BaseAnchor;
      
      for ( n = 0; n < num_classes; n++ )
        Free_Anchor( &ban[n], memory );

      FREE( ban );
    }

    FREE( br );
    return error;
  }


  static void  Free_BaseArray( TTO_BaseArray*  ba,
                               FT_UShort       num_classes,
			       FT_Memory       memory )
  {
    FT_UShort        m, n, count;

    TTO_BaseRecord*  br;
    TTO_Anchor*      ban;


    if ( ba->BaseRecord )
    {
      count = ba->BaseCount;
      br    = ba->BaseRecord;

      for ( m = 0; m < count; m++ )
      {
        ban = br[m].BaseAnchor;

        for ( n = 0; n < num_classes; n++ )
          Free_Anchor( &ban[n], memory );

        FREE( ban );
      }

      FREE( br );
    }
  }


  /* MarkBasePosFormat1 */

  FT_Error  Load_MarkBasePos( TTO_MarkBasePos*  mbp,
                              FT_Stream         stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_ULong  cur_offset, new_offset, base_offset;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 4L ) )
      return error;

    mbp->PosFormat = GET_UShort();
    new_offset     = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &mbp->MarkCoverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail3;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &mbp->BaseCoverage, stream ) ) != TT_Err_Ok )
      goto Fail3;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 4L ) )
      goto Fail2;

    mbp->ClassCount = GET_UShort();
    new_offset      = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_MarkArray( &mbp->MarkArray, stream ) ) != TT_Err_Ok )
      goto Fail2;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail1;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_BaseArray( &mbp->BaseArray, mbp->ClassCount,
                                   stream ) ) != TT_Err_Ok )
      goto Fail1;

    return TT_Err_Ok;

  Fail1:
    Free_MarkArray( &mbp->MarkArray, memory );

  Fail2:
    Free_Coverage( &mbp->BaseCoverage, memory );

  Fail3:
    Free_Coverage( &mbp->MarkCoverage, memory );
    return error;
  }


  void  Free_MarkBasePos( TTO_MarkBasePos*  mbp,
			  FT_Memory         memory )
  {
    Free_BaseArray( &mbp->BaseArray, mbp->ClassCount, memory );
    Free_MarkArray( &mbp->MarkArray, memory );
    Free_Coverage( &mbp->BaseCoverage, memory );
    Free_Coverage( &mbp->MarkCoverage, memory );
  }


  static FT_Error  Lookup_MarkBasePos( GPOS_Instance*    gpi,
                                       TTO_MarkBasePos*  mbp,
                                       TTO_GSUB_String*  in,
                                       TTO_GPOS_Data*    out,
                                       FT_UShort         flags,
                                       FT_UShort         context_length )
  {
    FT_UShort        i, j, mark_index, base_index, property, class;
    FT_Pos           x_mark_value, y_mark_value, x_base_value, y_base_value;
    FT_Error         error;
    TTO_GPOSHeader*  gpos = gpi->gpos;

    TTO_MarkArray*   ma;
    TTO_BaseArray*   ba;
    TTO_BaseRecord*  br;
    TTO_Anchor*      mark_anchor;
    TTO_Anchor*      base_anchor;

    TTO_GPOS_Data*   o;


    if ( context_length != 0xFFFF && context_length < 1 )
      return TTO_Err_Not_Covered;

    if ( flags & IGNORE_BASE_GLYPHS )
      return TTO_Err_Not_Covered;

    if ( CHECK_Property( gpos->gdef, in->string[in->pos],
                         flags, &property ) )
      return error;

    error = Coverage_Index( &mbp->MarkCoverage, in->string[in->pos],
                            &mark_index );
    if ( error )
      return error;

    /* now we search backwards for a non-mark glyph */

    i = 1;
    j = in->pos - 1;

    while ( i <= in->pos )
    {
      error = TT_GDEF_Get_Glyph_Property( gpos->gdef, in->string[j],
                                          &property );
      if ( error )
        return error;

      if ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) )
        break;

      i++;
      j--;
    }

    /* The following assertion is too strong -- at least for mangal.ttf. */
#if 0
    if ( property != TTO_BASE_GLYPH )
      return TTO_Err_Not_Covered;
#endif

    if ( i > in->pos )
      return TTO_Err_Not_Covered;

    error = Coverage_Index( &mbp->BaseCoverage, in->string[j],
                            &base_index );
    if ( error )
      return error;

    ma = &mbp->MarkArray;

    if ( mark_index >= ma->MarkCount )
      return TTO_Err_Invalid_GPOS_SubTable;

    class       = ma->MarkRecord[mark_index].Class;
    mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;

    if ( class >= mbp->ClassCount )
      return TTO_Err_Invalid_GPOS_SubTable;

    ba = &mbp->BaseArray;

    if ( base_index >= ba->BaseCount )
      return TTO_Err_Invalid_GPOS_SubTable;

    br          = &ba->BaseRecord[base_index];
    base_anchor = &br->BaseAnchor[class];

    error = Get_Anchor( gpi, mark_anchor, in->string[in->pos],
                        &x_mark_value, &y_mark_value );
    if ( error )
      return error;

    error = Get_Anchor( gpi, base_anchor, in->string[j],
                        &x_base_value, &y_base_value );
    if ( error )
      return error;

    /* anchor points are not cumulative */

    o = &out[in->pos];

    o->x_pos     = x_base_value - x_mark_value;
    o->y_pos     = y_base_value - y_mark_value;
    o->x_advance = 0;
    o->y_advance = 0;
    o->back      = i;

    (in->pos)++;

    return TT_Err_Ok;
  }


  /* LookupType 5 */

  /* LigatureAttach */

  static FT_Error  Load_LigatureAttach( TTO_LigatureAttach*  lat,
                                        FT_UShort            num_classes,
                                        FT_Stream            stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             m, n, k, count;
    FT_ULong              cur_offset, new_offset, base_offset;

    TTO_ComponentRecord*  cr;
    TTO_Anchor*           lan;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = lat->ComponentCount = GET_UShort();
    
    FORGET_Frame();

    lat->ComponentRecord = NULL;

    if ( ALLOC_ARRAY( lat->ComponentRecord, count, TTO_ComponentRecord ) )
      return error;

    cr = lat->ComponentRecord;

    for ( m = 0; m < count; m++ )
    {
      cr[m].LigatureAnchor = NULL;

      if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, TTO_Anchor ) )
        goto Fail;

      lan = cr[m].LigatureAnchor;

      for ( n = 0; n < num_classes; n++ )
      {
        if ( ACCESS_Frame( 2L ) )
          goto Fail0;

        new_offset = GET_UShort();

        FORGET_Frame();

        if ( new_offset )
        {
          new_offset += base_offset;

          cur_offset = FILE_Pos();
          if ( FILE_Seek( new_offset ) ||
               ( error = Load_Anchor( &lan[n], stream ) ) != TT_Err_Ok )
            goto Fail0;
          (void)FILE_Seek( cur_offset );
        }
        else
          lan[n].PosFormat = 0;
      }

      continue;
    Fail0:
      for ( k = 0; k < n; k++ )
        Free_Anchor( &lan[k], memory );
      goto Fail;
    }

    return TT_Err_Ok;

  Fail:
    for ( k = 0; k < m; k++ )
    {
      lan = cr[k].LigatureAnchor;
      
      for ( n = 0; n < num_classes; n++ )
        Free_Anchor( &lan[n], memory );

      FREE( lan );
    }

    FREE( cr );
    return error;
  }


  static void  Free_LigatureAttach( TTO_LigatureAttach*  lat,
                                    FT_UShort            num_classes,
				    FT_Memory            memory )
  {
    FT_UShort        m, n, count;

    TTO_ComponentRecord*  cr;
    TTO_Anchor*           lan;


    if ( lat->ComponentRecord )
    {
      count = lat->ComponentCount;
      cr    = lat->ComponentRecord;

      for ( m = 0; m < count; m++ )
      {
        lan = cr[m].LigatureAnchor;

        for ( n = 0; n < num_classes; n++ )
          Free_Anchor( &lan[n], memory );

        FREE( lan );
      }

      FREE( cr );
    }
  }


  /* LigatureArray */

  static FT_Error  Load_LigatureArray( TTO_LigatureArray*  la,
                                       FT_UShort           num_classes,
                                       FT_Stream           stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort            n, m, count;
    FT_ULong             cur_offset, new_offset, base_offset;

    TTO_LigatureAttach*  lat;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = la->LigatureCount = GET_UShort();

    FORGET_Frame();

    la->LigatureAttach = NULL;

    if ( ALLOC_ARRAY( la->LigatureAttach, count, TTO_LigatureAttach ) )
      return error;

    lat = la->LigatureAttach;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_LigatureAttach( &lat[n], num_classes,
                                          stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

  Fail:
    for ( m = 0; m < n; m++ )
      Free_LigatureAttach( &lat[m], num_classes, memory );

    FREE( lat );
    return error;
  }


  static void  Free_LigatureArray( TTO_LigatureArray*  la,
                                   FT_UShort           num_classes,
				   FT_Memory           memory )
  {
    FT_UShort            n, count;

    TTO_LigatureAttach*  lat;


    if ( la->LigatureAttach )
    {
      count = la->LigatureCount;
      lat   = la->LigatureAttach;

      for ( n = 0; n < count; n++ )
        Free_LigatureAttach( &lat[n], num_classes, memory );

      FREE( lat );
    }
  }


  /* MarkLigPosFormat1 */

  FT_Error  Load_MarkLigPos( TTO_MarkLigPos*  mlp,
                             FT_Stream        stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_ULong  cur_offset, new_offset, base_offset;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 4L ) )
      return error;

    mlp->PosFormat = GET_UShort();
    new_offset     = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &mlp->MarkCoverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail3;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &mlp->LigatureCoverage,
                                  stream ) ) != TT_Err_Ok )
      goto Fail3;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 4L ) )
      goto Fail2;

    mlp->ClassCount = GET_UShort();
    new_offset      = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_MarkArray( &mlp->MarkArray, stream ) ) != TT_Err_Ok )
      goto Fail2;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail1;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_LigatureArray( &mlp->LigatureArray, mlp->ClassCount,
                                       stream ) ) != TT_Err_Ok )
      goto Fail1;

    return TT_Err_Ok;

  Fail1:
    Free_MarkArray( &mlp->MarkArray, memory );

  Fail2:
    Free_Coverage( &mlp->LigatureCoverage, memory );

  Fail3:
    Free_Coverage( &mlp->MarkCoverage, memory );
    return error;
  }


  void  Free_MarkLigPos( TTO_MarkLigPos*  mlp,
			 FT_Memory        memory)
  {
    Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount, memory );
    Free_MarkArray( &mlp->MarkArray, memory );
    Free_Coverage( &mlp->LigatureCoverage, memory );
    Free_Coverage( &mlp->MarkCoverage, memory );
  }


  static FT_Error  Lookup_MarkLigPos( GPOS_Instance*    gpi,
                                      TTO_MarkLigPos*   mlp,
                                      TTO_GSUB_String*  in,
                                      TTO_GPOS_Data*    out,
                                      FT_UShort         flags,
                                      FT_UShort         context_length )
  {
    FT_UShort        i, j, mark_index, lig_index, property, class;
    FT_UShort        mark_glyph;
    FT_Pos           x_mark_value, y_mark_value, x_lig_value, y_lig_value;
    FT_Error         error;
    TTO_GPOSHeader*  gpos = gpi->gpos;

    TTO_MarkArray*        ma;
    TTO_LigatureArray*    la;
    TTO_LigatureAttach*   lat;
    TTO_ComponentRecord*  cr;
    FT_UShort             comp_index;
    TTO_Anchor*           mark_anchor;
    TTO_Anchor*           lig_anchor;

    TTO_GPOS_Data*  o;


    if ( context_length != 0xFFFF && context_length < 1 )
      return TTO_Err_Not_Covered;

    if ( flags & IGNORE_LIGATURES )
      return TTO_Err_Not_Covered;

    mark_glyph = in->string[in->pos];

    if ( CHECK_Property( gpos->gdef, mark_glyph, flags, &property ) )
      return error;

    error = Coverage_Index( &mlp->MarkCoverage, mark_glyph, &mark_index );
    if ( error )
      return error;

    /* now we search backwards for a non-mark glyph */

    i = 1;
    j = in->pos - 1;

    while ( i <= in->pos )
    {
      error = TT_GDEF_Get_Glyph_Property( gpos->gdef, in->string[j],
                                          &property );
      if ( error )
        return error;

      if ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) )
        break;

      i++;
      j--;
    }

    /* Similar to Lookup_MarkBasePos(), I suspect that this assertion is
       too strong, thus it is commented out.                             */
#if 0
    if ( property != TTO_LIGATURE )
      return TTO_Err_Not_Covered;
#endif

    if ( i > in->pos )
      return TTO_Err_Not_Covered;

    error = Coverage_Index( &mlp->LigatureCoverage, in->string[j],
                            &lig_index );
    if ( error )
      return error;

    ma = &mlp->MarkArray;

    if ( mark_index >= ma->MarkCount )
      return TTO_Err_Invalid_GPOS_SubTable;

    class       = ma->MarkRecord[mark_index].Class;
    mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;

    if ( class >= mlp->ClassCount )
      return TTO_Err_Invalid_GPOS_SubTable;

    la = &mlp->LigatureArray;

    if ( lig_index >= la->LigatureCount )
      return TTO_Err_Invalid_GPOS_SubTable;

    lat = &la->LigatureAttach[lig_index];

    /* We must now check whether the ligature ID of the current mark glyph
       is identical to the ligature ID of the found ligature.  If yes, we
       can directly use the component index.  If not, we attach the mark
       glyph to the last component of the ligature.                        */

    if ( in->ligIDs && in->components &&
         in->ligIDs[j] == in->ligIDs[in->pos] )
    {
      comp_index = in->components[in->pos];
      if ( comp_index >= lat->ComponentCount )
        return TTO_Err_Not_Covered;
    }
    else
      comp_index = lat->ComponentCount - 1;

    cr         = &lat->ComponentRecord[comp_index];
    lig_anchor = &cr->LigatureAnchor[class];

    error = Get_Anchor( gpi, mark_anchor, in->string[in->pos],
                        &x_mark_value, &y_mark_value );
    if ( error )
      return error;
    error = Get_Anchor( gpi, lig_anchor, in->string[j],
                        &x_lig_value, &y_lig_value );
    if ( error )
      return error;

    /* anchor points are not cumulative */

    o = &out[in->pos];

    o->x_pos     = x_lig_value - x_mark_value;
    o->y_pos     = y_lig_value - y_mark_value;
    o->x_advance = 0;
    o->y_advance = 0;
    o->back      = i;

    (in->pos)++;

    return TT_Err_Ok;
  }


  /* LookupType 6 */

  /* Mark2Array */

  static FT_Error  Load_Mark2Array( TTO_Mark2Array*  m2a,
                                    FT_UShort        num_classes,
                                    FT_Stream        stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort         k, m, n, count;
    FT_ULong          cur_offset, new_offset, base_offset;

    TTO_Mark2Record*  m2r;
    TTO_Anchor*       m2an;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = m2a->Mark2Count = GET_UShort();
    
    FORGET_Frame();

    m2a->Mark2Record = NULL;

    if ( ALLOC_ARRAY( m2a->Mark2Record, count, TTO_Mark2Record ) )
      return error;

    m2r = m2a->Mark2Record;

    for ( m = 0; m < count; m++ )
    {
      m2r[m].Mark2Anchor = NULL;

      if ( ALLOC_ARRAY( m2r[m].Mark2Anchor, num_classes, TTO_Anchor ) )
        goto Fail;

      m2an = m2r[m].Mark2Anchor;

      for ( n = 0; n < num_classes; n++ )
      {
        if ( ACCESS_Frame( 2L ) )
          goto Fail0;

        new_offset = GET_UShort() + base_offset;

        FORGET_Frame();

        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_Anchor( &m2an[n], stream ) ) != TT_Err_Ok )
          goto Fail0;
        (void)FILE_Seek( cur_offset );
      }

      continue;
    Fail0:
      for ( k = 0; k < n; k++ )
        Free_Anchor( &m2an[k], memory );
      goto Fail;
    }

    return TT_Err_Ok;

  Fail:
    for ( k = 0; k < m; k++ )
    {
      m2an = m2r[k].Mark2Anchor;
      
      for ( n = 0; n < num_classes; n++ )
        Free_Anchor( &m2an[n], memory );

      FREE( m2an );
    }

    FREE( m2r );
    return error;
  }


  static void  Free_Mark2Array( TTO_Mark2Array*  m2a,
                                FT_UShort        num_classes,
				FT_Memory        memory )
  {
    FT_UShort         m, n, count;

    TTO_Mark2Record*  m2r;
    TTO_Anchor*       m2an;


    if ( m2a->Mark2Record )
    {
      count = m2a->Mark2Count;
      m2r   = m2a->Mark2Record;

      for ( m = 0; m < count; m++ )
      {
        m2an = m2r[m].Mark2Anchor;

        for ( n = 0; n < num_classes; n++ )
          Free_Anchor( &m2an[n], memory );

        FREE( m2an );
      }

      FREE( m2r );
    }
  }


  /* MarkMarkPosFormat1 */

  FT_Error  Load_MarkMarkPos( TTO_MarkMarkPos*  mmp,
                              FT_Stream         stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_ULong  cur_offset, new_offset, base_offset;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 4L ) )
      return error;

    mmp->PosFormat = GET_UShort();
    new_offset     = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &mmp->Mark1Coverage,
                                  stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail3;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &mmp->Mark2Coverage,
                                  stream ) ) != TT_Err_Ok )
      goto Fail3;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 4L ) )
      goto Fail2;

    mmp->ClassCount = GET_UShort();
    new_offset      = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_MarkArray( &mmp->Mark1Array, stream ) ) != TT_Err_Ok )
      goto Fail2;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail1;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Mark2Array( &mmp->Mark2Array, mmp->ClassCount,
                                    stream ) ) != TT_Err_Ok )
      goto Fail1;

    return TT_Err_Ok;

  Fail1:
    Free_MarkArray( &mmp->Mark1Array, memory );

  Fail2:
    Free_Coverage( &mmp->Mark2Coverage, memory );

  Fail3:
    Free_Coverage( &mmp->Mark1Coverage, memory );
    return error;
  }


  void  Free_MarkMarkPos( TTO_MarkMarkPos*  mmp,
			  FT_Memory         memory)
  {
    Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount, memory );
    Free_MarkArray( &mmp->Mark1Array, memory );
    Free_Coverage( &mmp->Mark2Coverage, memory );
    Free_Coverage( &mmp->Mark1Coverage, memory );
  }


  static FT_Error  Lookup_MarkMarkPos( GPOS_Instance*    gpi,
                                       TTO_MarkMarkPos*  mmp,
                                       TTO_GSUB_String*  in,
                                       TTO_GPOS_Data*    out,
                                       FT_UShort         flags,
                                       FT_UShort         context_length )
  {
    FT_UShort        j, mark1_index, mark2_index, property, class;
    FT_Pos           x_mark1_value, y_mark1_value,
                     x_mark2_value, y_mark2_value;
    FT_Error         error;
    TTO_GPOSHeader*  gpos = gpi->gpos;

    TTO_MarkArray*    ma1;
    TTO_Mark2Array*   ma2;
    TTO_Mark2Record*  m2r;
    TTO_Anchor*       mark1_anchor;
    TTO_Anchor*       mark2_anchor;

    TTO_GPOS_Data*  o;


    if ( context_length != 0xFFFF && context_length < 1 )
      return TTO_Err_Not_Covered;

    if ( flags & IGNORE_MARKS )
      return TTO_Err_Not_Covered;

    if ( CHECK_Property( gpos->gdef, in->string[in->pos],
                         flags, &property ) )
      return error;

    error = Coverage_Index( &mmp->Mark1Coverage, in->string[in->pos],
                            &mark1_index );
    if ( error )
      return error;

    /* now we check the preceding glyph whether it is a suitable
       mark glyph                                                */

    if ( in->pos == 0 )
      return TTO_Err_Not_Covered;

    j = in->pos - 1;
    error = TT_GDEF_Get_Glyph_Property( gpos->gdef, in->string[j],
                                        &property );
    if ( error )
      return error;

    if ( flags & IGNORE_SPECIAL_MARKS )
    {
      if ( property != (flags & 0xFF00) )
        return TTO_Err_Not_Covered;
    }
    else
    {
      if ( property != TTO_MARK )
        return TTO_Err_Not_Covered;
    }

    error = Coverage_Index( &mmp->Mark2Coverage, in->string[j],
                            &mark2_index );
    if ( error )
      return error;

    ma1 = &mmp->Mark1Array;

    if ( mark1_index >= ma1->MarkCount )
      return TTO_Err_Invalid_GPOS_SubTable;

    class        = ma1->MarkRecord[mark1_index].Class;
    mark1_anchor = &ma1->MarkRecord[mark1_index].MarkAnchor;

    if ( class >= mmp->ClassCount )
      return TTO_Err_Invalid_GPOS_SubTable;

    ma2 = &mmp->Mark2Array;

    if ( mark2_index >= ma2->Mark2Count )
      return TTO_Err_Invalid_GPOS_SubTable;

    m2r          = &ma2->Mark2Record[mark2_index];
    mark2_anchor = &m2r->Mark2Anchor[class];

    error = Get_Anchor( gpi, mark1_anchor, in->string[in->pos],
                        &x_mark1_value, &y_mark1_value );
    if ( error )
      return error;
    error = Get_Anchor( gpi, mark2_anchor, in->string[j],
                        &x_mark2_value, &y_mark2_value );
    if ( error )
      return error;

    /* anchor points are not cumulative */

    o = &out[in->pos];

    o->x_pos     = x_mark2_value - x_mark1_value;
    o->y_pos     = y_mark2_value - y_mark1_value;
    o->x_advance = 0;
    o->y_advance = 0;
    o->back      = 1;

    (in->pos)++;

    return TT_Err_Ok;
  }


  /* Do the actual positioning for a context positioning (either format
     7 or 8).  This is only called after we've determined that the stream
     matches the subrule.                                                 */

  static FT_Error  Do_ContextPos( GPOS_Instance*        gpi,
                                  FT_UShort             GlyphCount,
                                  FT_UShort             PosCount,
                                  TTO_PosLookupRecord*  pos,
                                  TTO_GSUB_String*      in,
                                  TTO_GPOS_Data*        out,
                                  int                   nesting_level )
  {
    FT_Error  error;
    FT_UShort i, old_pos;


    i = 0;

    while ( i < GlyphCount )
    {
      if ( PosCount && i == pos->SequenceIndex )
      {
        old_pos = in->pos;

        /* Do a positioning */

        error = Do_Glyph_Lookup( gpi, pos->LookupListIndex, in, out,
                                 GlyphCount, nesting_level );

        if ( error )
          return error;

        pos++;
        PosCount--;
        i += in->pos - old_pos;
      }
      else
      {
        i++;
        (in->pos)++;
      }
    }

    return TT_Err_Ok;
  }


  /* LookupType 7 */

  /* PosRule */

  static FT_Error  Load_PosRule( TTO_PosRule*  pr,
                                 FT_Stream     stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             n, count;
    FT_UShort*            i;

    TTO_PosLookupRecord*  plr;


    if ( ACCESS_Frame( 4L ) )
      return error;

    pr->GlyphCount = GET_UShort();
    pr->PosCount   = GET_UShort();

    FORGET_Frame();

    pr->Input = NULL;

    count = pr->GlyphCount - 1;         /* only GlyphCount - 1 elements */

    if ( ALLOC_ARRAY( pr->Input, count, FT_UShort ) )
      return error;

    i = pr->Input;

    if ( ACCESS_Frame( count * 2L ) )
      goto Fail2;

    for ( n = 0; n < count; n++ )
      i[n] = GET_UShort();

    FORGET_Frame();

    pr->PosLookupRecord = NULL;

    count = pr->PosCount;

    if ( ALLOC_ARRAY( pr->PosLookupRecord, count, TTO_PosLookupRecord ) )
      goto Fail2;

    plr = pr->PosLookupRecord;

    if ( ACCESS_Frame( count * 4L ) )
      goto Fail1;

    for ( n = 0; n < count; n++ )
    {
      plr[n].SequenceIndex   = GET_UShort();
      plr[n].LookupListIndex = GET_UShort();
    }

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( plr );

  Fail2:
    FREE( i );
    return error;
  }


  static void  Free_PosRule( TTO_PosRule*  pr,
			     FT_Memory     memory )
  {
    FREE( pr->PosLookupRecord );
    FREE( pr->Input );
  }


  /* PosRuleSet */

  static FT_Error  Load_PosRuleSet( TTO_PosRuleSet*  prs,
                                    FT_Stream        stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort     n, m, count;
    FT_ULong      cur_offset, new_offset, base_offset;

    TTO_PosRule*  pr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = prs->PosRuleCount = GET_UShort();

    FORGET_Frame();

    prs->PosRule = NULL;

    if ( ALLOC_ARRAY( prs->PosRule, count, TTO_PosRule ) )
      return error;

    pr = prs->PosRule;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_PosRule( &pr[n], stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

  Fail:
    for ( m = 0; m < n; m++ )
      Free_PosRule( &pr[m], memory );

    FREE( pr );
    return error;
  }


  static void  Free_PosRuleSet( TTO_PosRuleSet*  prs,
				FT_Memory        memory )
  {
    FT_UShort     n, count;

    TTO_PosRule*  pr;


    if ( prs->PosRule )
    {
      count = prs->PosRuleCount;
      pr    = prs->PosRule;

      for ( n = 0; n < count; n++ )
        Free_PosRule( &pr[n], memory );

      FREE( pr );
    }
  }


  /* ContextPosFormat1 */

  static FT_Error  Load_ContextPos1( TTO_ContextPosFormat1*  cpf1,
                                     FT_Stream               stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort        n, m, count;
    FT_ULong         cur_offset, new_offset, base_offset;

    TTO_PosRuleSet*  prs;


    base_offset = FILE_Pos() - 2L;

    if ( ACCESS_Frame( 2L ) )
      return error;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &cpf1->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = cpf1->PosRuleSetCount = GET_UShort();

    FORGET_Frame();

    cpf1->PosRuleSet = NULL;

    if ( ALLOC_ARRAY( cpf1->PosRuleSet, count, TTO_PosRuleSet ) )
      goto Fail2;

    prs = cpf1->PosRuleSet;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail1;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_PosRuleSet( &prs[n], stream ) ) != TT_Err_Ok )
        goto Fail1;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

  Fail1:
    for ( m = 0; m < n; m++ )
      Free_PosRuleSet( &prs[m], memory );

    FREE( prs );

  Fail2:
    Free_Coverage( &cpf1->Coverage, memory );
    return error;
  }


  static void  Free_Context1( TTO_ContextPosFormat1*  cpf1,
			      FT_Memory               memory )
  {
    FT_UShort        n, count;

    TTO_PosRuleSet*  prs;


    if ( cpf1->PosRuleSet )
    {
      count = cpf1->PosRuleSetCount;
      prs   = cpf1->PosRuleSet;

      for ( n = 0; n < count; n++ )
        Free_PosRuleSet( &prs[n], memory );

      FREE( prs );
    }

    Free_Coverage( &cpf1->Coverage, memory );
  }


  /* PosClassRule */

  static FT_Error  Load_PosClassRule( TTO_ContextPosFormat2*  cpf2,
                                      TTO_PosClassRule*       pcr,
                                      FT_Stream               stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             n, count;

    FT_UShort*            c;
    TTO_PosLookupRecord*  plr;
    FT_Bool*              d;


    if ( ACCESS_Frame( 4L ) )
      return error;

    pcr->GlyphCount = GET_UShort();
    pcr->PosCount   = GET_UShort();

    FORGET_Frame();

    if ( pcr->GlyphCount > cpf2->MaxContextLength )
      cpf2->MaxContextLength = pcr->GlyphCount;

    pcr->Class = NULL;

    count = pcr->GlyphCount - 1;        /* only GlyphCount - 1 elements */

    if ( ALLOC_ARRAY( pcr->Class, count, FT_UShort ) )
      return error;

    c = pcr->Class;
    d = cpf2->ClassDef.Defined;

    if ( ACCESS_Frame( count * 2L ) )
      goto Fail2;

    for ( n = 0; n < count; n++ )
    {
      c[n] = GET_UShort();

      /* We check whether the specific class is used at all.  If not,
         class 0 is used instead.                                     */

      if ( !d[c[n]] )
        c[n] = 0;
    }

    FORGET_Frame();

    pcr->PosLookupRecord = NULL;

    count = pcr->PosCount;

    if ( ALLOC_ARRAY( pcr->PosLookupRecord, count, TTO_PosLookupRecord ) )
      goto Fail2;

    plr = pcr->PosLookupRecord;

    if ( ACCESS_Frame( count * 4L ) )
      goto Fail1;

    for ( n = 0; n < count; n++ )
    {
      plr[n].SequenceIndex   = GET_UShort();
      plr[n].LookupListIndex = GET_UShort();
    }

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( plr );

  Fail2:
    FREE( c );
    return error;
  }


  static void  Free_PosClassRule( TTO_PosClassRule*  pcr,
				  FT_Memory          memory )
  {
    FREE( pcr->PosLookupRecord );
    FREE( pcr->Class );
  }


  /* PosClassSet */

  static FT_Error  Load_PosClassSet( TTO_ContextPosFormat2*  cpf2,
                                     TTO_PosClassSet*        pcs,
                                     FT_Stream               stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort          n, m, count;
    FT_ULong           cur_offset, new_offset, base_offset;

    TTO_PosClassRule*  pcr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = pcs->PosClassRuleCount = GET_UShort();

    FORGET_Frame();

    pcs->PosClassRule = NULL;

    if ( ALLOC_ARRAY( pcs->PosClassRule, count, TTO_PosClassRule ) )
      return error;

    pcr = pcs->PosClassRule;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_PosClassRule( cpf2, &pcr[n],
                                        stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

  Fail:
    for ( m = 0; m < n; m++ )
      Free_PosClassRule( &pcr[m], memory );

    FREE( pcr );
    return error;
  }


  static void  Free_PosClassSet( TTO_PosClassSet*  pcs,
				 FT_Memory         memory )
  {
    FT_UShort          n, count;

    TTO_PosClassRule*  pcr;


    if ( pcs->PosClassRule )
    {
      count = pcs->PosClassRuleCount;
      pcr   = pcs->PosClassRule;

      for ( n = 0; n < count; n++ )
        Free_PosClassRule( &pcr[n], memory );

      FREE( pcr );
    }
  }


  /* ContextPosFormat2 */

  static FT_Error  Load_ContextPos2( TTO_ContextPosFormat2*  cpf2,
                                     FT_Stream               stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort         n, m, count;
    FT_ULong          cur_offset, new_offset, base_offset;

    TTO_PosClassSet*  pcs;


    base_offset = FILE_Pos() - 2;

    if ( ACCESS_Frame( 2L ) )
      return error;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &cpf2->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 4L ) )
      goto Fail3;

    new_offset = GET_UShort() + base_offset;

    /* `PosClassSetCount' is the upper limit for class values, thus we
       read it now to make an additional safety check.                 */

    count = cpf2->PosClassSetCount = GET_UShort();

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_ClassDefinition( &cpf2->ClassDef, count,
                                         stream ) ) != TT_Err_Ok )
      goto Fail3;
    (void)FILE_Seek( cur_offset );

    cpf2->PosClassSet      = NULL;
    cpf2->MaxContextLength = 0;

    if ( ALLOC_ARRAY( cpf2->PosClassSet, count, TTO_PosClassSet ) )
      goto Fail2;

    pcs = cpf2->PosClassSet;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail1;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      if ( new_offset != base_offset )      /* not a NULL offset */
      {
        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_PosClassSet( cpf2, &pcs[n],
                                         stream ) ) != TT_Err_Ok )
          goto Fail1;
        (void)FILE_Seek( cur_offset );
      }
      else
      {
        /* we create a PosClassSet table with no entries */

        cpf2->PosClassSet[n].PosClassRuleCount = 0;
        cpf2->PosClassSet[n].PosClassRule      = NULL;
      }
    }

    return TT_Err_Ok;

  Fail1:
    for ( m = 0; m < n; n++ )
      Free_PosClassSet( &pcs[m], memory );

    FREE( pcs );

  Fail2:
    Free_ClassDefinition( &cpf2->ClassDef, memory );

  Fail3:
    Free_Coverage( &cpf2->Coverage, memory );
    return error;
  }


  static void  Free_Context2( TTO_ContextPosFormat2*  cpf2,
			      FT_Memory               memory )
  {
    FT_UShort         n, count;

    TTO_PosClassSet*  pcs;


    if ( cpf2->PosClassSet )
    {
      count = cpf2->PosClassSetCount;
      pcs   = cpf2->PosClassSet;

      for ( n = 0; n < count; n++ )
        Free_PosClassSet( &pcs[n], memory );

      FREE( pcs );
    }

    Free_ClassDefinition( &cpf2->ClassDef, memory );
    Free_Coverage( &cpf2->Coverage, memory );
  }


  /* ContextPosFormat3 */

  static FT_Error  Load_ContextPos3( TTO_ContextPosFormat3*  cpf3,
                                     FT_Stream               stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             n, count;
    FT_ULong              cur_offset, new_offset, base_offset;

    TTO_Coverage*         c;
    TTO_PosLookupRecord*  plr;


    base_offset = FILE_Pos() - 2L;

    if ( ACCESS_Frame( 4L ) )
      return error;

    cpf3->GlyphCount = GET_UShort();
    cpf3->PosCount   = GET_UShort();

    FORGET_Frame();

    cpf3->Coverage = NULL;

    count = cpf3->GlyphCount;

    if ( ALLOC_ARRAY( cpf3->Coverage, count, TTO_Coverage ) )
      return error;

    c = cpf3->Coverage;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail2;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_Coverage( &c[n], stream ) ) != TT_Err_Ok )
        goto Fail2;
      (void)FILE_Seek( cur_offset );
    }

    cpf3->PosLookupRecord = NULL;

    count = cpf3->PosCount;

    if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, TTO_PosLookupRecord ) )
      goto Fail2;

    plr = cpf3->PosLookupRecord;

    if ( ACCESS_Frame( count * 4L ) )
      goto Fail1;

    for ( n = 0; n < count; n++ )
    {
      plr[n].SequenceIndex   = GET_UShort();
      plr[n].LookupListIndex = GET_UShort();
    }

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( plr );

  Fail2:
    for ( n = 0; n < count; n++ )
      Free_Coverage( &c[n], memory );

    FREE( c );
    return error;
  }


  static void  Free_Context3( TTO_ContextPosFormat3*  cpf3,
			      FT_Memory               memory )
  {
    FT_UShort      n, count;

    TTO_Coverage*  c;


    FREE( cpf3->PosLookupRecord );

    if ( cpf3->Coverage )
    {
      count = cpf3->GlyphCount;
      c     = cpf3->Coverage;

      for ( n = 0; n < count; n++ )
        Free_Coverage( &c[n], memory );

      FREE( c );
    }
  }


  /* ContextPos */

  FT_Error  Load_ContextPos( TTO_ContextPos*  cp,
                             FT_Stream        stream )
  {
    FT_Error  error;


    if ( ACCESS_Frame( 2L ) )
      return error;

    cp->PosFormat = GET_UShort();

    FORGET_Frame();

    switch ( cp->PosFormat )
    {
    case 1:
      return Load_ContextPos1( &cp->cpf.cpf1, stream );

    case 2:
      return Load_ContextPos2( &cp->cpf.cpf2, stream );

    case 3:
      return Load_ContextPos3( &cp->cpf.cpf3, stream );

    default:
      return TTO_Err_Invalid_GPOS_SubTable_Format;
    }

    return TT_Err_Ok;               /* never reached */
  }


  void  Free_ContextPos( TTO_ContextPos*  cp,
			 FT_Memory        memory )
  {
    switch ( cp->PosFormat )
    {
    case 1:
      Free_Context1( &cp->cpf.cpf1, memory );
      break;

    case 2:
      Free_Context2( &cp->cpf.cpf2, memory );
      break;

    case 3:
      Free_Context3( &cp->cpf.cpf3, memory );
      break;
    }
  }


  static FT_Error  Lookup_ContextPos1( GPOS_Instance*          gpi,
                                       TTO_ContextPosFormat1*  cpf1,
                                       TTO_GSUB_String*        in,
                                       TTO_GPOS_Data*          out,
                                       FT_UShort               flags,
                                       FT_UShort               context_length,
                                       int                     nesting_level )
  {
    FT_UShort        index, property;
    FT_UShort        i, j, k, numpr;
    FT_Error         error;
    FT_UShort*       s_in;
    TTO_GPOSHeader*  gpos = gpi->gpos;

    TTO_PosRule*     pr;
    TTO_GDEFHeader*  gdef;


    gdef = gpos->gdef;

    if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
      return error;

    error = Coverage_Index( &cpf1->Coverage, in->string[in->pos], &index );
    if ( error )
      return error;

    pr    = cpf1->PosRuleSet[index].PosRule;
    numpr = cpf1->PosRuleSet[index].PosRuleCount;

    for ( k = 0; k < numpr; k++ )
    {
      if ( context_length != 0xFFFF && context_length < pr[k].GlyphCount )
        continue;

      if ( in->pos + pr[k].GlyphCount > in->length )
        continue;                           /* context is too long */

      s_in = &in->string[in->pos];

      for ( i = 1, j = 1; i < pr[k].GlyphCount; i++, j++ )
      {
        while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
        {
          if ( error && error != TTO_Err_Not_Covered )
            return error;

          if ( in->pos + j < in->length )
            j++;
          else
            break;
        }

        if ( s_in[j] != pr[k].Input[i - 1] )
          break;
      }

      if ( i == pr[k].GlyphCount )
        return Do_ContextPos( gpi, pr[k].GlyphCount,
                              pr[k].PosCount, pr[k].PosLookupRecord,
                              in, out,
                              nesting_level );
    }

    return TTO_Err_Not_Covered;
  }


  static FT_Error  Lookup_ContextPos2( GPOS_Instance*          gpi,
                                       TTO_ContextPosFormat2*  cpf2,
                                       TTO_GSUB_String*        in,
                                       TTO_GPOS_Data*          out,
                                       FT_UShort               flags,
                                       FT_UShort               context_length,
                                       int                     nesting_level )
  {
    FT_UShort          index, property;
    FT_Error           error;
    FT_Memory          memory = gpi->face->memory;
    FT_UShort          i, j, k, known_classes;

    FT_UShort*         classes;
    FT_UShort*         s_in;
    FT_UShort*         cl;
    TTO_GPOSHeader*    gpos = gpi->gpos;

    TTO_PosClassSet*   pcs;
    TTO_PosClassRule*  pr;
    TTO_GDEFHeader*    gdef;


    gdef = gpos->gdef;

    if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
      return error;

    /* Note: The coverage table in format 2 doesn't give an index into
             anything.  It just lets us know whether or not we need to
             do any lookup at all.                                     */

    error = Coverage_Index( &cpf2->Coverage, in->string[in->pos], &index );
    if ( error )
      return error;

    if ( ALLOC_ARRAY( classes, cpf2->MaxContextLength, FT_UShort ) )
      return error;

    error = Get_Class( &cpf2->ClassDef, in->string[in->pos],
                       &classes[0], NULL );
    if ( error && error != TTO_Err_Not_Covered )
      goto End;
    known_classes = 0;

    pcs = &cpf2->PosClassSet[classes[0]];
    if ( !pcs )
    {
      error = TTO_Err_Invalid_GPOS_SubTable;
      goto End;
    }

    for ( k = 0; k < pcs->PosClassRuleCount; k++ )
    {
      pr = &pcs->PosClassRule[k];

      if ( context_length != 0xFFFF && context_length < pr->GlyphCount )
        continue;

      if ( in->pos + pr->GlyphCount > in->length )
        continue;                           /* context is too long */

      s_in = &in->string[in->pos];
      cl   = pr->Class;

      /* Start at 1 because [0] is implied */

      for ( i = 1, j = 1; i < pr->GlyphCount; i++, j++ )
      {
        while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
        {
          if ( error && error != TTO_Err_Not_Covered )
            goto End;

          if ( in->pos + j < in->length )
            j++;
          else
            break;
        }

        if ( i > known_classes )
        {
          /* Keeps us from having to do this for each rule */

          error = Get_Class( &cpf2->ClassDef, s_in[j], &classes[i], NULL );
          if ( error && error != TTO_Err_Not_Covered )
            goto End;
          known_classes = i;
        }

        if ( cl[i - 1] != classes[i] )
          break;
      }

      if ( i == pr->GlyphCount )
      {
        error = Do_ContextPos( gpi, pr->GlyphCount,
                               pr->PosCount, pr->PosLookupRecord,
                               in, out,
                               nesting_level );
        goto End;
      }
    }

    error = TTO_Err_Not_Covered;

  End:
    FREE( classes );
    return error;
  }


  static FT_Error  Lookup_ContextPos3( GPOS_Instance*          gpi,
                                       TTO_ContextPosFormat3*  cpf3,
                                       TTO_GSUB_String*        in,
                                       TTO_GPOS_Data*          out,
                                       FT_UShort               flags,
                                       FT_UShort               context_length,
                                       int                     nesting_level )
  {
    FT_Error         error;
    FT_UShort        index, i, j, property;
    FT_UShort*       s_in;
    TTO_GPOSHeader*  gpos = gpi->gpos;

    TTO_Coverage*    c;
    TTO_GDEFHeader*  gdef;


    gdef = gpos->gdef;

    if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
      return error;

    if ( context_length != 0xFFFF && context_length < cpf3->GlyphCount )
      return TTO_Err_Not_Covered;

    if ( in->pos + cpf3->GlyphCount > in->length )
      return TTO_Err_Not_Covered;         /* context is too long */

    s_in = &in->string[in->pos];
    c    = cpf3->Coverage;

    for ( i = 1, j = 1; i < cpf3->GlyphCount; i++, j++ )
    {
      while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
      {
        if ( error && error != TTO_Err_Not_Covered )
          return error;

        if ( in->pos + j < in->length )
          j++;
        else
          return TTO_Err_Not_Covered;
      }

      error = Coverage_Index( &c[i], s_in[j], &index );
      if ( error )
        return error;
    }

    return Do_ContextPos( gpi, cpf3->GlyphCount,
                          cpf3->PosCount, cpf3->PosLookupRecord,
                          in, out,
                          nesting_level );
  }


  static FT_Error  Lookup_ContextPos( GPOS_Instance*    gpi,
                                      TTO_ContextPos*   cp,
                                      TTO_GSUB_String*  in,
                                      TTO_GPOS_Data*    out,
                                      FT_UShort         flags,
                                      FT_UShort         context_length,
                                      int               nesting_level )
  {
    switch ( cp->PosFormat )
    {
    case 1:
      return Lookup_ContextPos1( gpi, &cp->cpf.cpf1, in, out,
                                 flags, context_length, nesting_level );

    case 2:
      return Lookup_ContextPos2( gpi, &cp->cpf.cpf2, in, out,
                                 flags, context_length, nesting_level );

    case 3:
      return Lookup_ContextPos3( gpi, &cp->cpf.cpf3, in, out,
                                 flags, context_length, nesting_level );

    default:
      return TTO_Err_Invalid_GPOS_SubTable_Format;
    }

    return TT_Err_Ok;               /* never reached */
  }


  /* LookupType 8 */

  /* ChainPosRule */

  static FT_Error  Load_ChainPosRule( TTO_ChainPosRule*  cpr,
                                      FT_Stream          stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             n, count;
    FT_UShort*            b;
    FT_UShort*            i;
    FT_UShort*            l;

    TTO_PosLookupRecord*  plr;


    if ( ACCESS_Frame( 2L ) )
      return error;

    cpr->BacktrackGlyphCount = GET_UShort();

    FORGET_Frame();

    cpr->Backtrack = NULL;

    count = cpr->BacktrackGlyphCount;

    if ( ALLOC_ARRAY( cpr->Backtrack, count, FT_UShort ) )
      return error;

    b = cpr->Backtrack;

    if ( ACCESS_Frame( count * 2L ) )
      goto Fail4;

    for ( n = 0; n < count; n++ )
      b[n] = GET_UShort();

    FORGET_Frame();

    if ( ACCESS_Frame( 2L ) )
      goto Fail4;

    cpr->InputGlyphCount = GET_UShort();

    FORGET_Frame();

    cpr->Input = NULL;

    count = cpr->InputGlyphCount - 1;  /* only InputGlyphCount - 1 elements */

    if ( ALLOC_ARRAY( cpr->Input, count, FT_UShort ) )
      goto Fail4;

    i = cpr->Input;

    if ( ACCESS_Frame( count * 2L ) )
      goto Fail3;

    for ( n = 0; n < count; n++ )
      i[n] = GET_UShort();

    FORGET_Frame();

    if ( ACCESS_Frame( 2L ) )
      goto Fail3;

    cpr->LookaheadGlyphCount = GET_UShort();

    FORGET_Frame();

    cpr->Lookahead = NULL;

    count = cpr->LookaheadGlyphCount;

    if ( ALLOC_ARRAY( cpr->Lookahead, count, FT_UShort ) )
      goto Fail3;

    l = cpr->Lookahead;

    if ( ACCESS_Frame( count * 2L ) )
      goto Fail2;

    for ( n = 0; n < count; n++ )
      l[n] = GET_UShort();

    FORGET_Frame();

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    cpr->PosCount = GET_UShort();

    FORGET_Frame();

    cpr->PosLookupRecord = NULL;

    count = cpr->PosCount;

    if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, TTO_PosLookupRecord ) )
      goto Fail2;

    plr = cpr->PosLookupRecord;

    if ( ACCESS_Frame( count * 4L ) )
      goto Fail1;

    for ( n = 0; n < count; n++ )
    {
      plr[n].SequenceIndex   = GET_UShort();
      plr[n].LookupListIndex = GET_UShort();
    }

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( plr );

  Fail2:
    FREE( l );

  Fail3:
    FREE( i );

  Fail4:
    FREE( b );
    return error;
  }


  static void  Free_ChainPosRule( TTO_ChainPosRule*  cpr,
				  FT_Memory          memory )
  {
    FREE( cpr->PosLookupRecord );
    FREE( cpr->Lookahead );
    FREE( cpr->Input );
    FREE( cpr->Backtrack );
  }


  /* ChainPosRuleSet */

  static FT_Error  Load_ChainPosRuleSet( TTO_ChainPosRuleSet*  cprs,
                                         FT_Stream             stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort          n, m, count;
    FT_ULong           cur_offset, new_offset, base_offset;

    TTO_ChainPosRule*  cpr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = cprs->ChainPosRuleCount = GET_UShort();

    FORGET_Frame();

    cprs->ChainPosRule = NULL;

    if ( ALLOC_ARRAY( cprs->ChainPosRule, count, TTO_ChainPosRule ) )
      return error;

    cpr = cprs->ChainPosRule;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_ChainPosRule( &cpr[n], stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

  Fail:
    for ( m = 0; m < n; m++ )
      Free_ChainPosRule( &cpr[m], memory );

    FREE( cpr );
    return error;
  }


  static void  Free_ChainPosRuleSet( TTO_ChainPosRuleSet*  cprs,
				     FT_Memory             memory )
  {
    FT_UShort          n, count;

    TTO_ChainPosRule*  cpr;


    if ( cprs->ChainPosRule )
    {
      count = cprs->ChainPosRuleCount;
      cpr   = cprs->ChainPosRule;

      for ( n = 0; n < count; n++ )
        Free_ChainPosRule( &cpr[n], memory );

      FREE( cpr );
    }
  }


  /* ChainContextPosFormat1 */

  static FT_Error  Load_ChainContextPos1( TTO_ChainContextPosFormat1*  ccpf1,
                                          FT_Stream                    stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             n, m, count;
    FT_ULong              cur_offset, new_offset, base_offset;

    TTO_ChainPosRuleSet*  cprs;


    base_offset = FILE_Pos() - 2L;

    if ( ACCESS_Frame( 2L ) )
      return error;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &ccpf1->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = ccpf1->ChainPosRuleSetCount = GET_UShort();

    FORGET_Frame();

    ccpf1->ChainPosRuleSet = NULL;

    if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, TTO_ChainPosRuleSet ) )
      goto Fail2;

    cprs = ccpf1->ChainPosRuleSet;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail1;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_ChainPosRuleSet( &cprs[n], stream ) ) != TT_Err_Ok )
        goto Fail1;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

  Fail1:
    for ( m = 0; m < n; m++ )
      Free_ChainPosRuleSet( &cprs[m], memory );

    FREE( cprs );

  Fail2:
    Free_Coverage( &ccpf1->Coverage, memory );
    return error;
  }


  static void  Free_ChainContext1( TTO_ChainContextPosFormat1*  ccpf1,
				   FT_Memory                    memory )
  {
    FT_UShort             n, count;

    TTO_ChainPosRuleSet*  cprs;


    if ( ccpf1->ChainPosRuleSet )
    {
      count = ccpf1->ChainPosRuleSetCount;
      cprs  = ccpf1->ChainPosRuleSet;

      for ( n = 0; n < count; n++ )
        Free_ChainPosRuleSet( &cprs[n], memory );

      FREE( cprs );
    }

    Free_Coverage( &ccpf1->Coverage, memory );
  }


  /* ChainPosClassRule */

  static FT_Error  Load_ChainPosClassRule(
                     TTO_ChainContextPosFormat2*  ccpf2,
                     TTO_ChainPosClassRule*       cpcr,
                     FT_Stream                    stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             n, count;

    FT_UShort*            b;
    FT_UShort*            i;
    FT_UShort*            l;
    TTO_PosLookupRecord*  plr;
    FT_Bool*              d;


    if ( ACCESS_Frame( 2L ) )
      return error;

    cpcr->BacktrackGlyphCount = GET_UShort();

    FORGET_Frame();

    if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength )
      ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount;

    cpcr->Backtrack = NULL;

    count = cpcr->BacktrackGlyphCount;

    if ( ALLOC_ARRAY( cpcr->Backtrack, count, FT_UShort ) )
      return error;

    b = cpcr->Backtrack;
    d = ccpf2->BacktrackClassDef.Defined;

    if ( ACCESS_Frame( count * 2L ) )
      goto Fail4;

    for ( n = 0; n < count; n++ )
    {
      b[n] = GET_UShort();

      /* We check whether the specific class is used at all.  If not,
         class 0 is used instead.                                     */

      if ( !d[b[n]] )
        b[n] = 0;
    }

    FORGET_Frame();

    if ( ACCESS_Frame( 2L ) )
      goto Fail4;

    cpcr->InputGlyphCount = GET_UShort();

    if ( cpcr->InputGlyphCount > ccpf2->MaxInputLength )
      ccpf2->MaxInputLength = cpcr->InputGlyphCount;

    FORGET_Frame();

    cpcr->Input = NULL;

    count = cpcr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */

    if ( ALLOC_ARRAY( cpcr->Input, count, FT_UShort ) )
      goto Fail4;

    i = cpcr->Input;
    d = ccpf2->InputClassDef.Defined;

    if ( ACCESS_Frame( count * 2L ) )
      goto Fail3;

    for ( n = 0; n < count; n++ )
    {
      i[n] = GET_UShort();

      if ( !d[i[n]] )
        i[n] = 0;
    }

    FORGET_Frame();

    if ( ACCESS_Frame( 2L ) )
      goto Fail3;

    cpcr->LookaheadGlyphCount = GET_UShort();

    FORGET_Frame();

    if ( cpcr->LookaheadGlyphCount > ccpf2->MaxLookaheadLength )
      ccpf2->MaxLookaheadLength = cpcr->LookaheadGlyphCount;

    cpcr->Lookahead = NULL;

    count = cpcr->LookaheadGlyphCount;

    if ( ALLOC_ARRAY( cpcr->Lookahead, count, FT_UShort ) )
      goto Fail3;

    l = cpcr->Lookahead;
    d = ccpf2->LookaheadClassDef.Defined;

    if ( ACCESS_Frame( count * 2L ) )
      goto Fail2;

    for ( n = 0; n < count; n++ )
    {
      l[n] = GET_UShort();

      if ( !d[l[n]] )
        l[n] = 0;
    }

    FORGET_Frame();

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    cpcr->PosCount = GET_UShort();

    FORGET_Frame();

    cpcr->PosLookupRecord = NULL;

    count = cpcr->PosCount;

    if ( ALLOC_ARRAY( cpcr->PosLookupRecord, count, TTO_PosLookupRecord ) )
      goto Fail2;

    plr = cpcr->PosLookupRecord;

    if ( ACCESS_Frame( count * 4L ) )
      goto Fail1;

    for ( n = 0; n < count; n++ )
    {
      plr[n].SequenceIndex   = GET_UShort();
      plr[n].LookupListIndex = GET_UShort();
    }

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( plr );

  Fail2:
    FREE( l );

  Fail3:
    FREE( i );

  Fail4:
    FREE( b );
    return error;
  }


  static void  Free_ChainPosClassRule( TTO_ChainPosClassRule*  cpcr,
				       FT_Memory               memory )
  {
    FREE( cpcr->PosLookupRecord );
    FREE( cpcr->Lookahead );
    FREE( cpcr->Input );
    FREE( cpcr->Backtrack );
  }


  /* PosClassSet */

  static FT_Error  Load_ChainPosClassSet(
                     TTO_ChainContextPosFormat2*  ccpf2,
                     TTO_ChainPosClassSet*        cpcs,
                     FT_Stream                    stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort               n, m, count;
    FT_ULong                cur_offset, new_offset, base_offset;

    TTO_ChainPosClassRule*  cpcr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = cpcs->ChainPosClassRuleCount = GET_UShort();

    FORGET_Frame();

    cpcs->ChainPosClassRule = NULL;

    if ( ALLOC_ARRAY( cpcs->ChainPosClassRule, count,
                      TTO_ChainPosClassRule ) )
      return error;

    cpcr = cpcs->ChainPosClassRule;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_ChainPosClassRule( ccpf2, &cpcr[n],
                                             stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

  Fail:
    for ( m = 0; m < n; m++ )
      Free_ChainPosClassRule( &cpcr[m], memory );

    FREE( cpcr );
    return error;
  }


  static void  Free_ChainPosClassSet( TTO_ChainPosClassSet*  cpcs,
				      FT_Memory              memory )
  {
    FT_UShort               n, count;

    TTO_ChainPosClassRule*  cpcr;


    if ( cpcs->ChainPosClassRule )
    {
      count = cpcs->ChainPosClassRuleCount;
      cpcr  = cpcs->ChainPosClassRule;

      for ( n = 0; n < count; n++ )
        Free_ChainPosClassRule( &cpcr[n], memory );

      FREE( cpcr );
    }
  }


  static FT_Error Load_EmptyOrClassDefinition( TTO_ClassDefinition*  cd,
                                               FT_UShort             limit,
					       FT_ULong              class_offset,
					       FT_ULong              base_offset,
				               FT_Stream             stream )
  {
    FT_Error error;
    FT_ULong               cur_offset;

    cur_offset = FILE_Pos();

    if ( class_offset )
      {
        if ( !FILE_Seek( class_offset + base_offset ) )
          error = Load_ClassDefinition( cd, limit, stream );
      }
    else
       error = Load_EmptyClassDefinition ( cd, stream );

    if (error == TT_Err_Ok)
      (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */

    return error;
  }

  /* ChainContextPosFormat2 */

  static FT_Error  Load_ChainContextPos2( TTO_ChainContextPosFormat2*  ccpf2,
                                          FT_Stream                    stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort              n, m, count;
    FT_ULong               cur_offset, new_offset, base_offset;
    FT_ULong               backtrack_offset, input_offset, lookahead_offset;

    TTO_ChainPosClassSet*  cpcs;


    base_offset = FILE_Pos() - 2;

    if ( ACCESS_Frame( 2L ) )
      return error;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
         ( error = Load_Coverage( &ccpf2->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 8L ) )
      goto Fail5;

    backtrack_offset = GET_UShort();
    input_offset     = GET_UShort();
    lookahead_offset = GET_UShort();

    /* `ChainPosClassSetCount' is the upper limit for input class values,
       thus we read it now to make an additional safety check. No limit
       is known or needed for the other two class definitions          */

    count = ccpf2->ChainPosClassSetCount = GET_UShort();

    FORGET_Frame();

    if ( ( error = Load_EmptyOrClassDefinition( &ccpf2->BacktrackClassDef, 65535,
						backtrack_offset, base_offset,
						stream ) ) != TT_Err_Ok )
      goto Fail5;
    if ( ( error = Load_EmptyOrClassDefinition( &ccpf2->InputClassDef, count,
						input_offset, base_offset,
						stream ) ) != TT_Err_Ok )
      goto Fail4;
    if ( ( error = Load_EmptyOrClassDefinition( &ccpf2->LookaheadClassDef, 65535,
						lookahead_offset, base_offset,
						stream ) ) != TT_Err_Ok )
      goto Fail3;

    ccpf2->ChainPosClassSet   = NULL;
    ccpf2->MaxBacktrackLength = 0;
    ccpf2->MaxInputLength     = 0;
    ccpf2->MaxLookaheadLength = 0;

    if ( ALLOC_ARRAY( ccpf2->ChainPosClassSet, count, TTO_ChainPosClassSet ) )
      goto Fail2;

    cpcs = ccpf2->ChainPosClassSet;

    for ( n = 0; n < count; n++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail1;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      if ( new_offset != base_offset )      /* not a NULL offset */
      {
        cur_offset = FILE_Pos();
        if ( FILE_Seek( new_offset ) ||
             ( error = Load_ChainPosClassSet( ccpf2, &cpcs[n],
                                              stream ) ) != TT_Err_Ok )
          goto Fail1;
        (void)FILE_Seek( cur_offset );
      }
      else
      {
        /* we create a ChainPosClassSet table with no entries */

        ccpf2->ChainPosClassSet[n].ChainPosClassRuleCount = 0;
        ccpf2->ChainPosClassSet[n].ChainPosClassRule      = NULL;
      }
    }

    return TT_Err_Ok;

  Fail1:
    for ( m = 0; m < n; m++ )
      Free_ChainPosClassSet( &cpcs[m], memory );

    FREE( cpcs );

  Fail2:
    Free_ClassDefinition( &ccpf2->LookaheadClassDef, memory );

  Fail3:
    Free_ClassDefinition( &ccpf2->InputClassDef, memory );

  Fail4:
    Free_ClassDefinition( &ccpf2->BacktrackClassDef, memory );

  Fail5:
    Free_Coverage( &ccpf2->Coverage, memory );
    return error;
  }


  static void  Free_ChainContext2( TTO_ChainContextPosFormat2*  ccpf2,
				   FT_Memory                    memory )
  {
    FT_UShort              n, count;

    TTO_ChainPosClassSet*  cpcs;


    if ( ccpf2->ChainPosClassSet )
    {
      count = ccpf2->ChainPosClassSetCount;
      cpcs  = ccpf2->ChainPosClassSet;

      for ( n = 0; n < count; n++ )
        Free_ChainPosClassSet( &cpcs[n], memory );

      FREE( cpcs );
    }

    Free_ClassDefinition( &ccpf2->LookaheadClassDef, memory );
    Free_ClassDefinition( &ccpf2->InputClassDef, memory );
    Free_ClassDefinition( &ccpf2->BacktrackClassDef, memory );

    Free_Coverage( &ccpf2->Coverage, memory );
  }


  /* ChainContextPosFormat3 */

  static FT_Error  Load_ChainContextPos3( TTO_ChainContextPosFormat3*  ccpf3,
                                          FT_Stream                    stream )
  {
    FT_Error  error;
    FT_Memory memory = stream->memory;

    FT_UShort             n, nb, ni, nl, m, count;
    FT_UShort             backtrack_count, input_count, lookahead_count;
    FT_ULong              cur_offset, new_offset, base_offset;

    TTO_Coverage*         b;
    TTO_Coverage*         i;
    TTO_Coverage*         l;
    TTO_PosLookupRecord*  plr;


    base_offset = FILE_Pos() - 2L;

    if ( ACCESS_Frame( 2L ) )
      return error;

    ccpf3->BacktrackGlyphCount = GET_UShort();

    FORGET_Frame();

    ccpf3->BacktrackCoverage = NULL;

    backtrack_count = ccpf3->BacktrackGlyphCount;

    if ( ALLOC_ARRAY( ccpf3->BacktrackCoverage, backtrack_count,
                      TTO_Coverage ) )
      return error;

    b = ccpf3->BacktrackCoverage;

    for ( nb = 0; nb < backtrack_count; nb++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail4;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_Coverage( &b[nb], stream ) ) != TT_Err_Ok )
        goto Fail4;
      (void)FILE_Seek( cur_offset );
    }

    if ( ACCESS_Frame( 2L ) )
      goto Fail4;

    ccpf3->InputGlyphCount = GET_UShort();

    FORGET_Frame();

    ccpf3->InputCoverage = NULL;

    input_count = ccpf3->InputGlyphCount;

    if ( ALLOC_ARRAY( ccpf3->InputCoverage, input_count, TTO_Coverage ) )
      goto Fail4;

    i = ccpf3->InputCoverage;

    for ( ni = 0; ni < input_count; ni++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail3;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_Coverage( &i[ni], stream ) ) != TT_Err_Ok )
        goto Fail3;
      (void)FILE_Seek( cur_offset );
    }

    if ( ACCESS_Frame( 2L ) )
      goto Fail3;

    ccpf3->LookaheadGlyphCount = GET_UShort();

    FORGET_Frame();

    ccpf3->LookaheadCoverage = NULL;

    lookahead_count = ccpf3->LookaheadGlyphCount;

    if ( ALLOC_ARRAY( ccpf3->LookaheadCoverage, lookahead_count,
                      TTO_Coverage ) )
      goto Fail3;

    l = ccpf3->LookaheadCoverage;

    for ( nl = 0; nl < lookahead_count; nl++ )
    {
      if ( ACCESS_Frame( 2L ) )
        goto Fail2;

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_Coverage( &l[nl], stream ) ) != TT_Err_Ok )
        goto Fail2;
      (void)FILE_Seek( cur_offset );
    }

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    ccpf3->PosCount = GET_UShort();

    FORGET_Frame();

    ccpf3->PosLookupRecord = NULL;

    count = ccpf3->PosCount;

    if ( ALLOC_ARRAY( ccpf3->PosLookupRecord, count, TTO_PosLookupRecord ) )
      goto Fail2;

    plr = ccpf3->PosLookupRecord;

    if ( ACCESS_Frame( count * 4L ) )
      goto Fail1;

    for ( n = 0; n < count; n++ )
    {
      plr[n].SequenceIndex   = GET_UShort();
      plr[n].LookupListIndex = GET_UShort();
    }

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( plr );

  Fail2:
    for ( m = 0; m < nl; nl++ )
      Free_Coverage( &l[m], memory );

    FREE( l );

  Fail3:
    for ( m = 0; m < ni; n++ )
      Free_Coverage( &i[m], memory );

    FREE( i );

  Fail4:
    for ( m = 0; m < nb; n++ )
      Free_Coverage( &b[m], memory );

    FREE( b );
    return error;
  }


  static void  Free_ChainContext3( TTO_ChainContextPosFormat3*  ccpf3,
				   FT_Memory                    memory )
  {
    FT_UShort      n, count;

    TTO_Coverage*  c;


    FREE( ccpf3->PosLookupRecord );

    if ( ccpf3->LookaheadCoverage )
    {
      count = ccpf3->LookaheadGlyphCount;
      c     = ccpf3->LookaheadCoverage;

      for ( n = 0; n < count; n++ )
        Free_Coverage( &c[n], memory );

      FREE( c );
    }

    if ( ccpf3->InputCoverage )
    {
      count = ccpf3->InputGlyphCount;
      c     = ccpf3->InputCoverage;

      for ( n = 0; n < count; n++ )
        Free_Coverage( &c[n], memory );

      FREE( c );
    }

    if ( ccpf3->BacktrackCoverage )
    {
      count = ccpf3->BacktrackGlyphCount;
      c     = ccpf3->BacktrackCoverage;

      for ( n = 0; n < count; n++ )
        Free_Coverage( &c[n], memory );

      FREE( c );
    }
  }


  /* ChainContextPos */

  FT_Error  Load_ChainContextPos( TTO_ChainContextPos*  ccp,
                                  FT_Stream             stream )
  {
    FT_Error  error;


    if ( ACCESS_Frame( 2L ) )
      return error;

    ccp->PosFormat = GET_UShort();

    FORGET_Frame();

    switch ( ccp->PosFormat )
    {
    case 1:
      return Load_ChainContextPos1( &ccp->ccpf.ccpf1, stream );

    case 2:
      return Load_ChainContextPos2( &ccp->ccpf.ccpf2, stream );

    case 3:
      return Load_ChainContextPos3( &ccp->ccpf.ccpf3, stream );

    default:
      return TTO_Err_Invalid_GPOS_SubTable_Format;
    }

    return TT_Err_Ok;               /* never reached */
  }


  void  Free_ChainContextPos( TTO_ChainContextPos*  ccp,
			      FT_Memory             memory )
  {
    switch ( ccp->PosFormat )
    {
    case 1:
      Free_ChainContext1( &ccp->ccpf.ccpf1, memory );
      break;

    case 2:
      Free_ChainContext2( &ccp->ccpf.ccpf2, memory );
      break;

    case 3:
      Free_ChainContext3( &ccp->ccpf.ccpf3, memory );
      break;
    }
  }


  static FT_Error  Lookup_ChainContextPos1(
                     GPOS_Instance*               gpi,
                     TTO_ChainContextPosFormat1*  ccpf1,
                     TTO_GSUB_String*             in,
                     TTO_GPOS_Data*               out,
                     FT_UShort                    flags,
                     FT_UShort                    context_length,
                     int                          nesting_level )
  {
    FT_UShort          index, property;
    FT_UShort          i, j, k, num_cpr, curr_pos;
    FT_UShort          bgc, igc, lgc;
    FT_Error           error;
    FT_UShort*         s_in;
    TTO_GPOSHeader*    gpos = gpi->gpos;

    TTO_ChainPosRule*  cpr;
    TTO_ChainPosRule   curr_cpr;
    TTO_GDEFHeader*    gdef;


    gdef = gpos->gdef;

    if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
      return error;

    error = Coverage_Index( &ccpf1->Coverage, in->string[in->pos], &index );
    if ( error )
      return error;

    cpr     = ccpf1->ChainPosRuleSet[index].ChainPosRule;
    num_cpr = ccpf1->ChainPosRuleSet[index].ChainPosRuleCount;

    for ( k = 0; k < num_cpr; k++ )
    {
      curr_cpr = cpr[k];
      bgc      = curr_cpr.BacktrackGlyphCount;
      igc      = curr_cpr.InputGlyphCount;
      lgc      = curr_cpr.LookaheadGlyphCount;

      if ( context_length != 0xFFFF && context_length < igc )
        continue;

      /* check whether context is too long; it is a first guess only */

      if ( bgc > in->pos || in->pos + igc + lgc > in->length )
        continue;

      if ( bgc )
      {
        /* Since we don't know in advance the number of glyphs to inspect,
           we search backwards for matches in the backtrack glyph array    */

        curr_pos = 0;
        s_in     = &in->string[curr_pos];

        for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- )
        {
          while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
          {
            if ( error && error != TTO_Err_Not_Covered )
              return error;

            if ( j > curr_pos )
              j--;
            else
              break;
          }

          /* In OpenType 1.3, it is undefined whether the offsets of
             backtrack glyphs is in logical order or not.  Version 1.4
             will clarify this:

               Logical order -      a  b  c  d  e  f  g  h  i  j
                                                i
               Input offsets -                  0  1
               Backtrack offsets -  3  2  1  0
               Lookahead offsets -                    0  1  2  3           */

          if ( s_in[j] != curr_cpr.Backtrack[i] )
            break;
        }

        if ( i != bgc )
          continue;
      }

      curr_pos = in->pos;
      s_in     = &in->string[curr_pos];

      /* Start at 1 because [0] is implied */

      for ( i = 1, j = 1; i < igc; i++, j++ )
      {
        while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
        {
          if ( error && error != TTO_Err_Not_Covered )
            return error;

          if ( curr_pos + j < in->length )
            j++;
          else
            break;
        }

        if ( s_in[j] != curr_cpr.Input[i - 1] )
          break;
      }

      if ( i != igc )
        continue;

      /* we are starting to check for lookahead glyphs right after the
         last context glyph                                            */

      curr_pos += j;
      s_in     = &in->string[curr_pos];

      for ( i = 0, j = 0; i < lgc; i++, j++ )
      {
        while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
        {
          if ( error && error != TTO_Err_Not_Covered )
            return error;

          if ( curr_pos + j < in->length )
            j++;
          else
            break;
        }

        if ( s_in[j] != curr_cpr.Lookahead[i] )
          break;
      }

      if ( i == lgc )
        return Do_ContextPos( gpi, igc,
                              curr_cpr.PosCount,
                              curr_cpr.PosLookupRecord,
                              in, out,
                              nesting_level );
    }

    return TTO_Err_Not_Covered;
  }


  static FT_Error  Lookup_ChainContextPos2(
                     GPOS_Instance*               gpi,
                     TTO_ChainContextPosFormat2*  ccpf2,
                     TTO_GSUB_String*             in,
                     TTO_GPOS_Data*               out,
                     FT_UShort                    flags,
                     FT_UShort                    context_length,
                     int                          nesting_level )
  {
    FT_UShort              index, property;
    FT_Memory              memory = gpi->face->memory;
    FT_Error               error;
    FT_UShort              i, j, k, curr_pos;
    FT_UShort              bgc, igc, lgc;
    FT_UShort              known_backtrack_classes,
                           known_input_classes,
                           known_lookahead_classes;

    FT_UShort*             backtrack_classes;
    FT_UShort*             input_classes;
    FT_UShort*             lookahead_classes;

    FT_UShort*             s_in;

    FT_UShort*             bc;
    FT_UShort*             ic;
    FT_UShort*             lc;
    TTO_GPOSHeader*        gpos = gpi->gpos;

    TTO_ChainPosClassSet*  cpcs;
    TTO_ChainPosClassRule  cpcr;
    TTO_GDEFHeader*        gdef;


    gdef = gpos->gdef;

    if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
      return error;

    /* Note: The coverage table in format 2 doesn't give an index into
             anything.  It just lets us know whether or not we need to
             do any lookup at all.                                     */

    error = Coverage_Index( &ccpf2->Coverage, in->string[in->pos], &index );
    if ( error )
      return error;

    if ( ALLOC_ARRAY( backtrack_classes, ccpf2->MaxBacktrackLength, FT_UShort ) )
      return error;
    known_backtrack_classes = 0;

    if ( ALLOC_ARRAY( input_classes, ccpf2->MaxInputLength, FT_UShort ) )
      goto End3;
    known_input_classes = 1;

    if ( ALLOC_ARRAY( lookahead_classes, ccpf2->MaxLookaheadLength, FT_UShort ) )
      goto End2;
    known_lookahead_classes = 0;

    error = Get_Class( &ccpf2->InputClassDef, in->string[in->pos],
                       &input_classes[0], NULL );
    if ( error && error != TTO_Err_Not_Covered )
      goto End1;

    cpcs = &ccpf2->ChainPosClassSet[input_classes[0]];
    if ( !cpcs )
    {
      error = TTO_Err_Invalid_GPOS_SubTable;
      goto End1;
    }

    for ( k = 0; k < cpcs->ChainPosClassRuleCount; k++ )
    {
      cpcr = cpcs->ChainPosClassRule[k];
      bgc  = cpcr.BacktrackGlyphCount;
      igc  = cpcr.InputGlyphCount;
      lgc  = cpcr.LookaheadGlyphCount;

      if ( context_length != 0xFFFF && context_length < igc )
        continue;

      /* check whether context is too long; it is a first guess only */

      if ( bgc > in->pos || in->pos + igc + lgc > in->length )
        continue;

      if ( bgc )
      {
        /* Since we don't know in advance the number of glyphs to inspect,
           we search backwards for matches in the backtrack glyph array.
           Note that `known_backtrack_classes' starts at index 0.         */

        curr_pos = 0;
        s_in     = &in->string[curr_pos];
        bc       = cpcr.Backtrack;

        for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- )
        {
          while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
          {
            if ( error && error != TTO_Err_Not_Covered )
              goto End1;

            if ( j > curr_pos )
              j--;
            else
              break;
          }

          if ( i >= known_backtrack_classes )
          {
            /* Keeps us from having to do this for each rule */

            error = Get_Class( &ccpf2->BacktrackClassDef, s_in[j],
                               &backtrack_classes[i], NULL );
            if ( error && error != TTO_Err_Not_Covered )
              goto End1;
            known_backtrack_classes = i;
          }

          if ( bc[i] != backtrack_classes[i] )
            break;
        }

        if ( i != bgc )
          continue;
      }

      curr_pos = in->pos;
      s_in     = &in->string[curr_pos];
      ic       = cpcr.Input;

      /* Start at 1 because [0] is implied */

      for ( i = 1, j = 1; i < igc; i++, j++ )
      {
        while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
        {
          if ( error && error != TTO_Err_Not_Covered )
            goto End1;

          if ( curr_pos + j < in->length )
            j++;
          else
            break;
        }

        if ( i >= known_input_classes )
        {
          error = Get_Class( &ccpf2->InputClassDef, s_in[j],
                             &input_classes[i], NULL );
          if ( error && error != TTO_Err_Not_Covered )
            goto End1;
          known_input_classes = i;
        }

        if ( ic[i - 1] != input_classes[i] )
          break;
      }

      if ( i != igc )
        continue;

      /* we are starting to check for lookahead glyphs right after the
         last context glyph                                            */

      curr_pos += j;
      s_in     = &in->string[curr_pos];
      lc       = cpcr.Lookahead;

      for ( i = 0, j = 0; i < lgc; i++, j++ )
      {
        while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
        {
          if ( error && error != TTO_Err_Not_Covered )
            goto End1;

          if ( curr_pos + j < in->length )
            j++;
          else
            break;
        }

        if ( i >= known_lookahead_classes )
        {
          error = Get_Class( &ccpf2->LookaheadClassDef, s_in[j],
                             &lookahead_classes[i], NULL );
          if ( error && error != TTO_Err_Not_Covered )
            goto End1;
          known_lookahead_classes = i;
        }

        if ( lc[i] != lookahead_classes[i] )
          break;
      }

      if ( i == lgc )
      {
        error = Do_ContextPos( gpi, igc,
                               cpcr.PosCount,
                               cpcr.PosLookupRecord,
                               in, out,
                               nesting_level );
        goto End1;
      }
    }

    error = TTO_Err_Not_Covered;

  End1:
    FREE( lookahead_classes );

  End2:
    FREE( input_classes );

  End3:
    FREE( backtrack_classes );
    return error;
  }


  static FT_Error  Lookup_ChainContextPos3(
                     GPOS_Instance*               gpi,
                     TTO_ChainContextPosFormat3*  ccpf3,
                     TTO_GSUB_String*             in,
                     TTO_GPOS_Data*               out,
                     FT_UShort                    flags,
                     FT_UShort                    context_length,
                     int                          nesting_level )
  {
    FT_UShort        index, i, j, curr_pos, property;
    FT_UShort        bgc, igc, lgc;
    FT_Error         error;
    FT_UShort*       s_in;
    TTO_GPOSHeader*  gpos = gpi->gpos;

    TTO_Coverage*    bc;
    TTO_Coverage*    ic;
    TTO_Coverage*    lc;
    TTO_GDEFHeader*  gdef;


    gdef = gpos->gdef;

    if ( CHECK_Property( gdef, in->string[in->pos], flags, &property ) )
      return error;

    bgc = ccpf3->BacktrackGlyphCount;
    igc = ccpf3->InputGlyphCount;
    lgc = ccpf3->LookaheadGlyphCount;

    if ( context_length != 0xFFFF && context_length < igc )
      return TTO_Err_Not_Covered;

    /* check whether context is too long; it is a first guess only */

    if ( bgc > in->pos || in->pos + igc + lgc > in->length )
      return TTO_Err_Not_Covered;

    if ( bgc )
    {
      /* Since we don't know in advance the number of glyphs to inspect,
         we search backwards for matches in the backtrack glyph array    */

      curr_pos = 0;
      s_in     = &in->string[curr_pos];
      bc       = ccpf3->BacktrackCoverage;

      for ( i = 0, j = in->pos - 1; i < bgc; i++, j-- )
      {
        while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
        {
          if ( error && error != TTO_Err_Not_Covered )
            return error;

          if ( j > curr_pos )
            j--;
          else
            return TTO_Err_Not_Covered;
        }

        error = Coverage_Index( &bc[i], s_in[j], &index );
        if ( error )
          return error;
      }
    }

    curr_pos = in->pos;
    s_in     = &in->string[curr_pos];
    ic       = ccpf3->InputCoverage;

    for ( i = 0, j = 0; i < igc; i++, j++ )
    {
      /* We already called CHECK_Property for s_in[0] */
      while ( j > 0 && CHECK_Property( gdef, s_in[j], flags, &property ) )
      {
        if ( error && error != TTO_Err_Not_Covered )
          return error;

        if ( curr_pos + j < in->length )
          j++;
        else
          return TTO_Err_Not_Covered;
      }

      error = Coverage_Index( &ic[i], s_in[j], &index );
      if ( error )
        return error;
    }

    /* we are starting to check for lookahead glyphs right after the
       last context glyph                                            */

    curr_pos += j;
    s_in     = &in->string[curr_pos];
    lc       = ccpf3->LookaheadCoverage;

    for ( i = 0, j = 0; i < lgc; i++, j++ )
    {
      while ( CHECK_Property( gdef, s_in[j], flags, &property ) )
      {
        if ( error && error != TTO_Err_Not_Covered )
          return error;

        if ( curr_pos + j < in->length )
          j++;
        else
          return TTO_Err_Not_Covered;
      }

      error = Coverage_Index( &lc[i], s_in[j], &index );
      if ( error )
        return error;
    }

    return Do_ContextPos( gpi, igc,
                          ccpf3->PosCount,
                          ccpf3->PosLookupRecord,
                          in, out,
                          nesting_level );
  }


  static FT_Error  Lookup_ChainContextPos(
                     GPOS_Instance*        gpi,
                     TTO_ChainContextPos*  ccp,
                     TTO_GSUB_String*      in,
                     TTO_GPOS_Data*        out,
                     FT_UShort             flags,
                     FT_UShort             context_length,
                     int                   nesting_level )
  {
    switch ( ccp->PosFormat )
    {
    case 1:
      return Lookup_ChainContextPos1( gpi, &ccp->ccpf.ccpf1, in, out,
                                      flags, context_length,
                                      nesting_level );

    case 2:
      return Lookup_ChainContextPos2( gpi, &ccp->ccpf.ccpf2, in, out,
                                      flags, context_length,
                                      nesting_level );

    case 3:
      return Lookup_ChainContextPos3( gpi, &ccp->ccpf.ccpf3, in, out,
                                      flags, context_length,
                                      nesting_level );

    default:
      return TTO_Err_Invalid_GPOS_SubTable_Format;
    }

    return TT_Err_Ok;               /* never reached */
  }



  /***********
   * GPOS API
   ***********/


  EXPORT_FUNC
  FT_Error  TT_GPOS_Select_Script( TTO_GPOSHeader*  gpos,
                                   FT_ULong         script_tag,
                                   FT_UShort*       script_index )
  {
    FT_UShort          n;

    TTO_ScriptList*    sl;
    TTO_ScriptRecord*  sr;


    if ( !gpos || !script_index )
      return TT_Err_Invalid_Argument;

    sl = &gpos->ScriptList;
    sr = sl->ScriptRecord;

    for ( n = 0; n < sl->ScriptCount; n++ )
      if ( script_tag == sr[n].ScriptTag )
      {
        *script_index = n;

        return TT_Err_Ok;
      }

    return TTO_Err_Not_Covered;
  }


  EXPORT_FUNC
  FT_Error  TT_GPOS_Select_Language( TTO_GPOSHeader*  gpos,
                                     FT_ULong         language_tag,
                                     FT_UShort        script_index,
                                     FT_UShort*       language_index,
                                     FT_UShort*       req_feature_index )
  {
    FT_UShort           n;

    TTO_ScriptList*     sl;
    TTO_ScriptRecord*   sr;
    TTO_Script*         s;
    TTO_LangSysRecord*  lsr;


    if ( !gpos || !language_index || !req_feature_index )
      return TT_Err_Invalid_Argument;

    sl = &gpos->ScriptList;
    sr = sl->ScriptRecord;

    if ( script_index >= sl->ScriptCount )
      return TT_Err_Invalid_Argument;

    s   = &sr[script_index].Script;
    lsr = s->LangSysRecord;

    for ( n = 0; n < s->LangSysCount; n++ )
      if ( language_tag == lsr[n].LangSysTag )
      {
        *language_index = n;
        *req_feature_index = lsr[n].LangSys.ReqFeatureIndex;

        return TT_Err_Ok;
      }

    return TTO_Err_Not_Covered;
  }


  /* selecting 0xFFFF for language_index asks for the values of the
     default language (DefaultLangSys)                              */

  EXPORT_FUNC
  FT_Error  TT_GPOS_Select_Feature( TTO_GPOSHeader*  gpos,
                                    FT_ULong         feature_tag,
                                    FT_UShort        script_index,
                                    FT_UShort        language_index,
                                    FT_UShort*       feature_index )
  {
    FT_UShort           n;

    TTO_ScriptList*     sl;
    TTO_ScriptRecord*   sr;
    TTO_Script*         s;
    TTO_LangSysRecord*  lsr;
    TTO_LangSys*        ls;
    FT_UShort*          fi;

    TTO_FeatureList*    fl;
    TTO_FeatureRecord*  fr;


    if ( !gpos || !feature_index )
      return TT_Err_Invalid_Argument;

    sl = &gpos->ScriptList;
    sr = sl->ScriptRecord;

    fl = &gpos->FeatureList;
    fr = fl->FeatureRecord;

    if ( script_index >= sl->ScriptCount )
      return TT_Err_Invalid_Argument;

    s   = &sr[script_index].Script;
    lsr = s->LangSysRecord;

    if ( language_index == 0xFFFF )
      ls = &s->DefaultLangSys;
    else
    {
      if ( language_index >= s->LangSysCount )
        return TT_Err_Invalid_Argument;

      ls = &lsr[language_index].LangSys;
    }

    fi = ls->FeatureIndex;

    for ( n = 0; n < ls->FeatureCount; n++ )
    {
      if ( fi[n] >= fl->FeatureCount )
        return TTO_Err_Invalid_GPOS_SubTable_Format;

      if ( feature_tag == fr[fi[n]].FeatureTag )
      {
        *feature_index = fi[n];

        return TT_Err_Ok;
      }
    }

    return TTO_Err_Not_Covered;
  }


  /* The next three functions return a null-terminated list */

  EXPORT_FUNC
  FT_Error  TT_GPOS_Query_Scripts( TTO_GPOSHeader*  gpos,
                                   FT_ULong**       script_tag_list )
  {
    FT_Error           error;
    FT_Memory          memory = gpos->memory;
    FT_UShort          n;
    FT_ULong*          stl;

    TTO_ScriptList*    sl;
    TTO_ScriptRecord*  sr;


    if ( !gpos || !script_tag_list )
      return TT_Err_Invalid_Argument;

    sl = &gpos->ScriptList;
    sr = sl->ScriptRecord;

    if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, FT_ULong ) )
      return error;

    for ( n = 0; n < sl->ScriptCount; n++ )
      stl[n] = sr[n].ScriptTag;
    stl[n] = 0;

    *script_tag_list = stl;

    return TT_Err_Ok;
  }


  EXPORT_FUNC
  FT_Error  TT_GPOS_Query_Languages( TTO_GPOSHeader*  gpos,
                                     FT_UShort        script_index,
                                     FT_ULong**       language_tag_list )
  {
    FT_Error            error;
    FT_Memory           memory = gpos->memory;
    FT_UShort           n;
    FT_ULong*           ltl;

    TTO_ScriptList*     sl;
    TTO_ScriptRecord*   sr;
    TTO_Script*         s;
    TTO_LangSysRecord*  lsr;


    if ( !gpos || !language_tag_list )
      return TT_Err_Invalid_Argument;

    sl = &gpos->ScriptList;
    sr = sl->ScriptRecord;

    if ( script_index >= sl->ScriptCount )
      return TT_Err_Invalid_Argument;

    s   = &sr[script_index].Script;
    lsr = s->LangSysRecord;

    if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, FT_ULong ) )
      return error;

    for ( n = 0; n < s->LangSysCount; n++ )
      ltl[n] = lsr[n].LangSysTag;
    ltl[n] = 0;

    *language_tag_list = ltl;

    return TT_Err_Ok;
  }


  /* selecting 0xFFFF for language_index asks for the values of the
     default language (DefaultLangSys)                              */

  EXPORT_FUNC
  FT_Error  TT_GPOS_Query_Features( TTO_GPOSHeader*  gpos,
                                    FT_UShort        script_index,
                                    FT_UShort        language_index,
                                    FT_ULong**       feature_tag_list )
  {
    FT_UShort           n;
    FT_Error            error;
    FT_Memory           memory = gpos->memory;
    FT_ULong*           ftl;

    TTO_ScriptList*     sl;
    TTO_ScriptRecord*   sr;
    TTO_Script*         s;
    TTO_LangSysRecord*  lsr;
    TTO_LangSys*        ls;
    FT_UShort*          fi;

    TTO_FeatureList*    fl;
    TTO_FeatureRecord*  fr;


    if ( !gpos || !feature_tag_list )
      return TT_Err_Invalid_Argument;

    sl = &gpos->ScriptList;
    sr = sl->ScriptRecord;

    fl = &gpos->FeatureList;
    fr = fl->FeatureRecord;

    if ( script_index >= sl->ScriptCount )
      return TT_Err_Invalid_Argument;

    s   = &sr[script_index].Script;
    lsr = s->LangSysRecord;

    if ( language_index == 0xFFFF )
      ls = &s->DefaultLangSys;
    else
    {
      if ( language_index >= s->LangSysCount )
        return TT_Err_Invalid_Argument;

      ls = &lsr[language_index].LangSys;
    }

    fi = ls->FeatureIndex;

    if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, FT_ULong ) )
      return error;

    for ( n = 0; n < ls->FeatureCount; n++ )
    {
      if ( fi[n] >= fl->FeatureCount )
      {
        FREE( ftl );
        return TTO_Err_Invalid_GPOS_SubTable_Format;
      }
      ftl[n] = fr[fi[n]].FeatureTag;
    }
    ftl[n] = 0;

    *feature_tag_list = ftl;

    return TT_Err_Ok;
  }


  /* Do an individual subtable lookup.  Returns TT_Err_Ok if positioning
     has been done, or TTO_Err_Not_Covered if not.                        */

  static FT_Error  Do_Glyph_Lookup( GPOS_Instance*    gpi,
                                    FT_UShort         lookup_index,
                                    TTO_GSUB_String*  in,
                                    TTO_GPOS_Data*    out,
                                    FT_UShort         context_length,
                                    int               nesting_level )
  {
    FT_Error         error = TT_Err_Ok;
    FT_UShort        i, flags;
    TTO_GPOSHeader*  gpos = gpi->gpos;
    TTO_Lookup*      lo;


    nesting_level++;

    if ( nesting_level > TTO_MAX_NESTING_LEVEL )
      return TTO_Err_Too_Many_Nested_Contexts;

    lo    = &gpos->LookupList.Lookup[lookup_index];
    flags = lo->LookupFlag;

    for ( i = 0; i < lo->SubTableCount; i++ )
    {
      switch ( lo->LookupType )
      {
      case GPOS_LOOKUP_SINGLE:
        error = Lookup_SinglePos( gpi,
                                  &lo->SubTable[i].st.gpos.single,
                                  in, out,
                                  flags, context_length );
        break;

      case GPOS_LOOKUP_PAIR:
        error = Lookup_PairPos( gpi,
                                &lo->SubTable[i].st.gpos.pair,
                                in, out,
                                flags, context_length );
        break;

      case GPOS_LOOKUP_CURSIVE:
        error = Lookup_CursivePos( gpi,
                                   &lo->SubTable[i].st.gpos.cursive,
                                   in, out,
                                   flags, context_length );
        break;

      case GPOS_LOOKUP_MARKBASE:
        error = Lookup_MarkBasePos( gpi,
                                    &lo->SubTable[i].st.gpos.markbase,
                                    in, out,
                                    flags, context_length );
        break;

      case GPOS_LOOKUP_MARKLIG:
        error = Lookup_MarkLigPos( gpi,
                                   &lo->SubTable[i].st.gpos.marklig,
                                   in, out,
                                   flags, context_length );
        break;

      case GPOS_LOOKUP_MARKMARK:
        error = Lookup_MarkMarkPos( gpi,
                                    &lo->SubTable[i].st.gpos.markmark,
                                    in, out,
                                    flags, context_length );
        break;

      case GPOS_LOOKUP_CONTEXT:
        error = Lookup_ContextPos( gpi,
                                   &lo->SubTable[i].st.gpos.context,
                                   in, out,
                                   flags, context_length,
                                   nesting_level );
        break;

      case GPOS_LOOKUP_CHAIN:
        error = Lookup_ChainContextPos( gpi,
                                        &lo->SubTable[i].st.gpos.chain,
                                        in, out,
                                        flags, context_length,
                                        nesting_level );
        break;
      }

      /* Check whether we have a successful positioning or an error other
         than TTO_Err_Not_Covered                                         */

      if ( error != TTO_Err_Not_Covered )
        return error;
    }

    return TTO_Err_Not_Covered;
  }


  /* apply one lookup to the input string object */

  static FT_Error  Do_String_Lookup( GPOS_Instance*    gpi,
                                     FT_UShort         lookup_index,
                                     TTO_GSUB_String*  in,
                                     TTO_GPOS_Data*    out )
  {
    FT_Error         error, retError = TTO_Err_Not_Covered;
    TTO_GPOSHeader*  gpos = gpi->gpos;

    FT_UShort*  properties = gpos->LookupList.Properties;
    FT_UShort*  p_in       = in->properties;

    int       nesting_level = 0;
    FT_UShort i;
    FT_Pos    offset;


    gpi->first = 0xFFFF;
    gpi->last  = 0xFFFF;     /* no last valid glyph for cursive pos. */

    in->pos = 0;

    while ( in->pos < in->length )
    {
      if ( ~p_in[in->pos] & properties[lookup_index] )
      {
        /* 0xFFFF indicates that we don't have a context length yet. */

        /* Note that the connection between mark and base glyphs hold
           exactly one (string) lookup.  For example, it would be possible
           that in the first lookup, mark glyph X is attached to base
           glyph A, and in the next lookup it is attached to base glyph B.
           It is up to the font designer to provide meaningful lookups and
           lookup order.                                                   */

        error = Do_Glyph_Lookup( gpi, lookup_index, in, out,
                                 0xFFFF, nesting_level );
        if ( error && error != TTO_Err_Not_Covered )
          return error;
      }
      else
      {
        /* Contrary to properties defined in GDEF, user-defined properties
           will always stop a possible cursive positioning.                */
        gpi->last = 0xFFFF;

        error = TTO_Err_Not_Covered;
      }

      /* test whether we have to adjust the offsets for cursive connections */

      if ( gpi->first != 0xFFFF && gpi->last == 0xFFFF &&
           gpos->LookupList.Lookup[lookup_index].LookupFlag & RIGHT_TO_LEFT )
      {
        offset = out[in->pos].y_pos;

        /* no horizontal offsets (for vertical writing direction)
           supported yet                                          */

        for ( i = gpi->first; i <= in->pos; i++ )
          out[i].y_pos -= offset;

        gpi->first = 0xFFFF;
      }

      if ( error == TTO_Err_Not_Covered )
        (in->pos)++;
      else
	retError = error;
    }

    return retError;
  }


  EXPORT_FUNC
  FT_Error  TT_GPOS_Add_Feature( TTO_GPOSHeader*  gpos,
                                 FT_UShort        feature_index,
                                 FT_UShort        property )
  {
    FT_UShort    i;

    TTO_Feature  feature;
    FT_UShort*   properties;
    FT_UShort*   index;


    if ( !gpos ||
         feature_index >= gpos->FeatureList.FeatureCount )
      return TT_Err_Invalid_Argument;

    properties = gpos->LookupList.Properties;

    feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
    index   = feature.LookupListIndex;

    for ( i = 0; i < feature.LookupListCount; i++ )
      properties[index[i]] |= property;

    return TT_Err_Ok;
  }


  EXPORT_FUNC
  FT_Error  TT_GPOS_Clear_Features( TTO_GPOSHeader*  gpos )
  {
    FT_UShort i;

    FT_UShort*  properties;


    if ( !gpos )
      return TT_Err_Invalid_Argument;

    properties = gpos->LookupList.Properties;

    for ( i = 0; i < gpos->LookupList.LookupCount; i++ )
      properties[i] = 0;

    return TT_Err_Ok;
  }


  EXPORT_FUNC
  FT_Error  TT_GPOS_Register_Glyph_Function( TTO_GPOSHeader*    gpos,
                                             TTO_GlyphFunction  gfunc )
  {
    if ( !gpos )
      return TT_Err_Invalid_Argument;

    gpos->gfunc = gfunc;

    return TT_Err_Ok;
  }


  EXPORT_FUNC
  FT_Error  TT_GPOS_Register_MM_Function( TTO_GPOSHeader*  gpos,
                                          TTO_MMFunction   mmfunc,
                                          void*            data )
  {
    if ( !gpos )
      return TT_Err_Invalid_Argument;

    gpos->mmfunc = mmfunc;
    gpos->data   = data;

    return TT_Err_Ok;
  }


  /* If `dvi' is TRUE, glyph contour points for anchor points and device
     tables are ignored -- you will get device independent values.         */

  EXPORT_FUNC
  FT_Error  TT_GPOS_Apply_String( FT_Face            face,
                                  TTO_GPOSHeader*    gpos,
                                  FT_UShort          load_flags,
                                  TTO_GSUB_String*   in,
                                  TTO_GPOS_Data**    out,
                                  FT_Bool            dvi,
                                  FT_Bool            r2l )
  {
    FT_Memory      memory = gpos->memory;
    FT_Error       error, retError = TTO_Err_Not_Covered;
    GPOS_Instance  gpi;

    FT_UShort j;

    FT_UShort* properties;


    if ( !face || !gpos ||
         !in || in->length == 0 || in->pos >= in->length )
      return TT_Err_Invalid_Argument;

    properties = gpos->LookupList.Properties;

    gpi.face       = face;
    gpi.gpos       = gpos;
    gpi.load_flags = load_flags;
    gpi.r2l        = r2l;
    gpi.dvi        = dvi;

    if ( *out )
      FREE( *out );
    if ( ALLOC_ARRAY( *out, in->length, TTO_GPOS_Data ) )
      return error;

    for ( j = 0; j < gpos->LookupList.LookupCount; j++ )
      if ( !properties || properties[j] )
      {
        error = Do_String_Lookup( &gpi, j, in, *out );
	if ( error )
	  {
	    if ( error != TTO_Err_Not_Covered )
	      return error;
	  }
	else
	  retError = error;
      }

    return retError;
  }

/* END */
