/*******************************************************************
 *
 *  ftxgsub.c
 *
 *    TrueType Open GSUB 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 5 and 6), 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 :-)                                  */

#define EXPORT_FUNC

#include <freetype/tttags.h>

#include <freetype/internal/ftstream.h>
#include <freetype/internal/ftmemory.h>
#include <freetype/internal/tttypes.h>

#include "fterrcompat.h"

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



#define GSUB_ID  Build_Extension_ID( 'G', 'S', 'U', 'B' )


#define ADD_String( in, num_in, out, num_out, glyph_data, component, ligID ) \
          ( ( error = TT_GSUB_Add_String( (in), (num_in),                    \
                                          (out), (num_out),                  \
                                          (glyph_data), (component), (ligID) \
                                        ) ) != TT_Err_Ok )


  static FT_Error  Do_Glyph_Lookup( TTO_GSUBHeader*   gsub,
                                    FT_UShort         lookup_index,
                                    TTO_GSUB_String*  in,
                                    TTO_GSUB_String*  out,
                                    FT_UShort         context_length,
                                    int               nesting_level );



  /**********************
   * Auxiliary functions
   **********************/


  /* The following function copies `num_out' elements from `glyph_data'
     to `out', advancing the array pointer in the `in' structure by
     `num_in' elements, and in `out' by `num_out' elements.  If the
     string (resp. the properties) array in `out' is empty or too
     small, it allocates resp. reallocates the string (and properties)
     array.  Finally, it sets the `length' field of `out' equal to
     `pos' of the `out' structure.

     If `component' is 0xFFFF, the value `in->component[in->pos]'
     will be copied `num_out' times, otherwise `component' itself will
     be used to fill `out->component'.

     If `ligID' is 0xFFFF, the value `in->lig_IDs[in->pos]' will be
     copied `num_out' times, otherwise `ligID' itself will be used to
     fill `out->ligIDs'.

     The properties (if defined) for all replaced glyphs are taken
     from the glyph at position `in->pos'.

     The logClusters[] value for the glyph at position in->pos is used
     for all replacement glyphs */

  EXPORT_FUNC
  FT_Error  TT_GSUB_Add_String( TTO_GSUB_String*  in,
                                FT_UShort         num_in,
                                TTO_GSUB_String*  out,
                                FT_UShort         num_out,
                                FT_UShort*        glyph_data,
                                FT_UShort         component,
                                FT_UShort         ligID )
  {
    FT_Memory memory = in->memory;
    FT_Error  error;
    FT_UShort i;
    FT_UShort p_in;
    FT_UShort*p_out;


    /* sanity check */

    if ( !in || !out ||
         in->length == 0 || in->pos >= in->length ||
         in->length < in->pos + num_in )
      return TT_Err_Invalid_Argument;

    if ( out->pos + num_out >= out->allocated )
    {
      FT_ULong  size = out->pos + num_out + 256L;


      /* The following works because all fields in `out' must be
         initialized to zero (including the `string' field) for the
         first use.                                                 */

      if ( REALLOC_ARRAY( out->string, out->allocated, size, FT_UShort ) )
        return error;
      if ( REALLOC_ARRAY( out->components, out->allocated, size, FT_UShort ) )
        return error;
      if ( REALLOC_ARRAY( out->ligIDs, out->allocated, size, FT_UShort ) )
        return error;
      if ( in->properties )
        if ( REALLOC_ARRAY( out->properties, out->allocated, size, FT_UShort ) )
          return error;
      if ( REALLOC_ARRAY( out->logClusters, out->allocated, size, FT_Int ) )
	return error;

      out->allocated = size;
    }

    if ( num_out )
    {
      MEM_Copy( &out->string[out->pos], glyph_data,
                num_out * sizeof ( FT_UShort ) );

      if ( component == 0xFFFF )
        component = in->components[in->pos];

      p_out = out->components;

      for ( i = out->pos; i < out->pos + num_out; i++ )
	p_out[i] = component;

      p_out = out->ligIDs;

      if ( ligID == 0xFFFF )
        ligID = in->ligIDs[in->pos];

      for ( i = out->pos; i < out->pos + num_out; i++ )
        p_out[i] = ligID;

      if ( in->properties )
      {
        p_in  = in->properties[in->pos];
        p_out = out->properties;

        for ( i = out->pos; i < out->pos + num_out; i++ )
          p_out[i] = p_in;
      }

      for ( i = out->pos; i < out->pos + num_out; i++ )
	out->logClusters[i] = in->logClusters[in->pos];
    }

    in->pos  += num_in;
    out->pos += num_out;

    out->length = out->pos;

    return TT_Err_Ok;
  }


#if 0

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


  static FT_Error  GSUB_Create( void*  ext,
                                PFace  face )
  {
    DEFINE_LOAD_LOCALS( face->stream );

    TTO_GSUBHeader*  gsub = (TTO_GSUBHeader*)ext;
    Long             table;


    /* by convention */

    if ( !gsub )
      return TT_Err_Ok;

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

    gsub->offset = 0;

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

    table = TT_LookUp_Table( face, TTAG_GSUB );
    if ( table < 0 )
      return TT_Err_Ok;             /* The table is optional */

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

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

    FORGET_Frame();

    gsub->loaded = FALSE;

    return TT_Err_Ok;
  }


  static FT_Error  GSUB_Destroy( void*  ext,
                                 PFace  face )
  {
    TTO_GSUBHeader*  gsub = (TTO_GSUBHeader*)ext;


    /* by convention */

    if ( !gsub )
      return TT_Err_Ok;

    if ( gsub->loaded )
    {
      Free_LookupList( &gsub->LookupList, GSUB, memory );
      Free_FeatureList( &gsub->FeatureList, memory );
      Free_ScriptList( &gsub->ScriptList, memory );
    }

    return TT_Err_Ok;
  }


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


    if ( !_engine )
      return TT_Err_Invalid_Engine;

    return  TT_Register_Extension( _engine,
                                   GSUB_ID,
                                   sizeof ( TTO_GSUBHeader ),
                                   GSUB_Create,
                                   GSUB_Destroy );
  }
#endif

  EXPORT_FUNC
  FT_Error  TT_Load_GSUB_Table( FT_Face          face,
                                TTO_GSUBHeader** retptr,
                                TTO_GDEFHeader*  gdef )
  {
    FT_Stream        stream = face->stream;
    FT_Memory        memory = face->memory;
    FT_Error         error;
    FT_ULong         cur_offset, new_offset, base_offset;
    TT_Face          tt_face = (TT_Face)face;

    FT_UShort        i, num_lookups;
    TTO_GSUBHeader*  gsub;
    TTO_Lookup*      lo;

    if ( !retptr )
      return TT_Err_Invalid_Argument;

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

    base_offset = FILE_Pos();

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

    gsub->memory = memory;

    /* 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( &gsub->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( &gsub->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( &gsub->LookupList,
                                    stream, GSUB ) ) != TT_Err_Ok )
      goto Fail2;

    gsub->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          = gsub->LookupList.Lookup;
      num_lookups = gsub->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 = gsub;

    return TT_Err_Ok;

  Fail1:
    Free_LookupList( &gsub->LookupList, GSUB, memory );

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

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

  Fail4:
    FREE ( gsub );


    return error;
  }

  EXPORT_FUNC
  FT_Error   TT_Done_GSUB_Table( TTO_GSUBHeader* gsub )
  {
    FT_Memory memory = gsub->memory;
    
    Free_LookupList( &gsub->LookupList, GSUB, memory );
    Free_FeatureList( &gsub->FeatureList, memory );
    Free_ScriptList( &gsub->ScriptList, memory );

    FREE( gsub );

    return TT_Err_Ok;
  }

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


  /* LookupType 1 */

  /* SingleSubstFormat1 */
  /* SingleSubstFormat2 */

  FT_Error  Load_SingleSubst( TTO_SingleSubst*  ss,
                              FT_Stream         stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    FT_UShort*  s;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 4L ) )
      return error;

    ss->SubstFormat = GET_UShort();
    new_offset      = GET_UShort() + base_offset;

    FORGET_Frame();

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

    switch ( ss->SubstFormat )
    {
    case 1:
      if ( ACCESS_Frame( 2L ) )
        goto Fail2;

      ss->ssf.ssf1.DeltaGlyphID = GET_UShort();

      FORGET_Frame();

      break;

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

      count = ss->ssf.ssf2.GlyphCount = GET_UShort();

      FORGET_Frame();

      ss->ssf.ssf2.Substitute = NULL;

      if ( ALLOC_ARRAY( ss->ssf.ssf2.Substitute, count, FT_UShort ) )
        goto Fail2;

      s = ss->ssf.ssf2.Substitute;

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

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

      FORGET_Frame();

      break;

    default:
      return TTO_Err_Invalid_GSUB_SubTable_Format;
    }

    return TT_Err_Ok;

  Fail1:
    FREE( s );

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


  void  Free_SingleSubst( TTO_SingleSubst*  ss,
			  FT_Memory         memory )
  {
    switch ( ss->SubstFormat )
    {
    case 1:
      break;

    case 2:
      FREE( ss->ssf.ssf2.Substitute );
      break;
    }

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


  static FT_Error  Lookup_SingleSubst( TTO_SingleSubst*  ss,
                                       TTO_GSUB_String*  in,
                                       TTO_GSUB_String*  out,
                                       FT_UShort         flags,
                                       FT_UShort         context_length,
                                       TTO_GDEFHeader*   gdef )
  {
    FT_UShort index, value[1], property;
    FT_Error  error;


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

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

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

    switch ( ss->SubstFormat )
    {
    case 1:
      value[0] = ( in->string[in->pos] + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF;
      if ( ADD_String( in, 1, out, 1, value, 0xFFFF, 0xFFFF ) )
        return error;
      break;

    case 2:
      if ( index >= ss->ssf.ssf2.GlyphCount )
        return TTO_Err_Invalid_GSUB_SubTable;
      value[0] = ss->ssf.ssf2.Substitute[index];
      if ( ADD_String( in, 1, out, 1, value, 0xFFFF, 0xFFFF ) )
        return error;
      break;

    default:
      return TTO_Err_Invalid_GSUB_SubTable;
    }

    if ( gdef && gdef->NewGlyphClasses )
    {
      /* we inherit the old glyph class to the substituted glyph */

      error = Add_Glyph_Property( gdef, value[0], property );
      if ( error && error != TTO_Err_Not_Covered )
        return error;
    }

    return TT_Err_Ok;
  }


  /* LookupType 2 */

  /* Sequence */

  static FT_Error  Load_Sequence( TTO_Sequence*  s,
                                  FT_Stream      stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

    FT_UShort n, count;
    FT_UShort*  sub;


    if ( ACCESS_Frame( 2L ) )
      return error;

    count = s->GlyphCount = GET_UShort();

    FORGET_Frame();

    s->Substitute = NULL;

    if ( count )
    {
      if ( ALLOC_ARRAY( s->Substitute, count, FT_UShort ) )
        return error;

      sub = s->Substitute;

      if ( ACCESS_Frame( count * 2L ) )
      {
        FREE( sub );
        return error;
      }

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

      FORGET_Frame();
    }

    return TT_Err_Ok;
  }


  static void  Free_Sequence( TTO_Sequence*  s,
			      FT_Memory      memory )
  {
    FREE( s->Substitute );
  }


  /* MultipleSubstFormat1 */

  FT_Error  Load_MultipleSubst( TTO_MultipleSubst*  ms,
                                FT_Stream           stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_Sequence*  s;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 4L ) )
      return error;

    ms->SubstFormat = GET_UShort();             /* should be 1 */
    new_offset      = GET_UShort() + base_offset;

    FORGET_Frame();

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

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = ms->SequenceCount = GET_UShort();

    FORGET_Frame();

    ms->Sequence = NULL;

    if ( ALLOC_ARRAY( ms->Sequence, count, TTO_Sequence ) )
      goto Fail2;

    s = ms->Sequence;

    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_Sequence( &s[n], stream ) ) != TT_Err_Ok )
        goto Fail1;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( s );

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


  void  Free_MultipleSubst( TTO_MultipleSubst*  ms,
			    FT_Memory           memory )
  {
    FT_UShort      n, count;

    TTO_Sequence*  s;


    if ( ms->Sequence )
    {
      count = ms->SequenceCount;
      s     = ms->Sequence;

      for ( n = 0; n < count; n++ )
        Free_Sequence( &s[n], memory );

      FREE( s );
    }

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


  static FT_Error  Lookup_MultipleSubst( TTO_MultipleSubst*  ms,
                                         TTO_GSUB_String*    in,
                                         TTO_GSUB_String*    out,
                                         FT_UShort           flags,
                                         FT_UShort           context_length,
                                         TTO_GDEFHeader*     gdef )
  {
    FT_Error  error;
    FT_UShort index, property, n, count;
    FT_UShort*s;


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

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

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

    if ( index >= ms->SequenceCount )
      return TTO_Err_Invalid_GSUB_SubTable;

    count = ms->Sequence[index].GlyphCount;
    s     = ms->Sequence[index].Substitute;

    if ( ADD_String( in, 1, out, count, s, 0xFFFF, 0xFFFF ) )
      return error;

    if ( gdef && gdef->NewGlyphClasses )
    {
      /* this is a guess only ... */

      if ( property == TTO_LIGATURE )
        property = TTO_BASE_GLYPH;

      for ( n = 0; n < count; n++ )
      {
        error = Add_Glyph_Property( gdef, s[n], property );
        if ( error && error != TTO_Err_Not_Covered )
          return error;
      }
    }

    return TT_Err_Ok;
  }


  /* LookupType 3 */

  /* AlternateSet */

  static FT_Error  Load_AlternateSet( TTO_AlternateSet*  as,
                                      FT_Stream          stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

    FT_UShort n, count;
    FT_UShort*  a;


    if ( ACCESS_Frame( 2L ) )
      return error;

    count = as->GlyphCount = GET_UShort();

    FORGET_Frame();

    as->Alternate = NULL;

    if ( ALLOC_ARRAY( as->Alternate, count, FT_UShort ) )
      return error;

    a = as->Alternate;

    if ( ACCESS_Frame( count * 2L ) )
    {
      FREE( a );
      return error;
    }

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

    FORGET_Frame();

    return TT_Err_Ok;
  }


  static void  Free_AlternateSet( TTO_AlternateSet*  as,
				  FT_Memory          memory )
  {
    FREE( as->Alternate );
  }


  /* AlternateSubstFormat1 */

  FT_Error  Load_AlternateSubst( TTO_AlternateSubst*  as,
                                 FT_Stream            stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_AlternateSet*  aset;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 4L ) )
      return error;

    as->SubstFormat = GET_UShort();             /* should be 1 */
    new_offset      = GET_UShort() + base_offset;

    FORGET_Frame();

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

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = as->AlternateSetCount = GET_UShort();

    FORGET_Frame();

    as->AlternateSet = NULL;

    if ( ALLOC_ARRAY( as->AlternateSet, count, TTO_AlternateSet ) )
      goto Fail2;

    aset = as->AlternateSet;

    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_AlternateSet( &aset[n], stream ) ) != TT_Err_Ok )
        goto Fail1;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( aset );

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


  void  Free_AlternateSubst( TTO_AlternateSubst*  as,
			     FT_Memory            memory )
  {
    FT_UShort          n, count;

    TTO_AlternateSet*  aset;


    if ( as->AlternateSet )
    {
      count = as->AlternateSetCount;
      aset  = as->AlternateSet;

      for ( n = 0; n < count; n++ )
        Free_AlternateSet( &aset[n], memory );

      FREE( aset );
    }

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


  static FT_Error  Lookup_AlternateSubst( TTO_GSUBHeader*      gsub,
                                          TTO_AlternateSubst*  as,
                                          TTO_GSUB_String*     in,
                                          TTO_GSUB_String*     out,
                                          FT_UShort            flags,
                                          FT_UShort            context_length,
                                          TTO_GDEFHeader*      gdef )
  {
    FT_Error          error;
    FT_UShort         index, alt_index, property;

    TTO_AlternateSet  aset;


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

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

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

    aset = as->AlternateSet[index];

    /* we use a user-defined callback function to get the alternate index */

    if ( gsub->altfunc )
      alt_index = (gsub->altfunc)( out->pos, in->string[in->pos],
                                   aset.GlyphCount, aset.Alternate,
                                   gsub->data );
    else
      alt_index = 0;

    if ( ADD_String( in, 1, out, 1, &aset.Alternate[alt_index],
                     0xFFFF, 0xFFFF ) )
      return error;

    if ( gdef && gdef->NewGlyphClasses )
    {
      /* we inherit the old glyph class to the substituted glyph */

      error = Add_Glyph_Property( gdef, aset.Alternate[alt_index],
                                  property );
      if ( error && error != TTO_Err_Not_Covered )
        return error;
    }

    return TT_Err_Ok;
  }


  /* LookupType 4 */

  /* Ligature */

  static FT_Error  Load_Ligature( TTO_Ligature*  l,
                                  FT_Stream      stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

    FT_UShort n, count;
    FT_UShort*  c;


    if ( ACCESS_Frame( 4L ) )
      return error;

    l->LigGlyph       = GET_UShort();
    l->ComponentCount = GET_UShort();

    FORGET_Frame();

    l->Component = NULL;

    count = l->ComponentCount - 1;      /* only ComponentCount - 1 elements */

    if ( ALLOC_ARRAY( l->Component, count, FT_UShort ) )
      return error;

    c = l->Component;

    if ( ACCESS_Frame( count * 2L ) )
    {
      FREE( c );
      return error;
    }

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

    FORGET_Frame();

    return TT_Err_Ok;
  }


  static void  Free_Ligature( TTO_Ligature*  l,
			      FT_Memory      memory )
  {
    FREE( l->Component );
  }


  /* LigatureSet */

  static FT_Error  Load_LigatureSet( TTO_LigatureSet*  ls,
                                     FT_Stream         stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_Ligature*  l;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = ls->LigatureCount = GET_UShort();

    FORGET_Frame();

    ls->Ligature = NULL;

    if ( ALLOC_ARRAY( ls->Ligature, count, TTO_Ligature ) )
      return error;

    l = ls->Ligature;

    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_Ligature( &l[n], stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( l );
    return error;
  }


  static void  Free_LigatureSet( TTO_LigatureSet*  ls,
				 FT_Memory         memory )
  {
    FT_UShort      n, count;

    TTO_Ligature*  l;


    if ( ls->Ligature )
    {
      count = ls->LigatureCount;
      l     = ls->Ligature;

      for ( n = 0; n < count; n++ )
        Free_Ligature( &l[n], memory );

      FREE( l );
    }
  }


  /* LigatureSubstFormat1 */

  FT_Error  Load_LigatureSubst( TTO_LigatureSubst*  ls,
                                FT_Stream           stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_LigatureSet*  lset;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 4L ) )
      return error;

    ls->SubstFormat = GET_UShort();             /* should be 1 */
    new_offset      = GET_UShort() + base_offset;

    FORGET_Frame();

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

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = ls->LigatureSetCount = GET_UShort();

    FORGET_Frame();

    ls->LigatureSet = NULL;

    if ( ALLOC_ARRAY( ls->LigatureSet, count, TTO_LigatureSet ) )
      goto Fail2;

    lset = ls->LigatureSet;

    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_LigatureSet( &lset[n], stream ) ) != TT_Err_Ok )
        goto Fail1;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( lset );

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


  void  Free_LigatureSubst( TTO_LigatureSubst*  ls,
			    FT_Memory           memory )
  {
    FT_UShort         n, count;

    TTO_LigatureSet*  lset;


    if ( ls->LigatureSet )
    {
      count = ls->LigatureSetCount;
      lset  = ls->LigatureSet;

      for ( n = 0; n < count; n++ )
        Free_LigatureSet( &lset[n], memory );

      FREE( lset );
    }

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


  static FT_Error  Lookup_LigatureSubst( TTO_LigatureSubst*  ls,
                                         TTO_GSUB_String*    in,
                                         TTO_GSUB_String*    out,
                                         FT_UShort           flags,
                                         FT_UShort           context_length,
                                         TTO_GDEFHeader*     gdef )
  {
    FT_UShort      index, property;
    FT_Error       error;
    FT_UShort      numlig, i, j, is_mark, first_is_mark = FALSE;
    FT_UShort*     s_in;
    FT_UShort*     c;

    TTO_Ligature*  lig;


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

    if ( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS )
      first_is_mark = TRUE;

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

    if ( index >= ls->LigatureSetCount )
       return TTO_Err_Invalid_GSUB_SubTable;

    lig = ls->LigatureSet[index].Ligature;

    for ( numlig = ls->LigatureSet[index].LigatureCount;
          numlig;
          numlig--, lig++ )
    {
      if ( in->pos + lig->ComponentCount > in->length )
        continue;                         /* Not enough glyphs in input */

      s_in = &in->string[in->pos];
      c    = lig->Component;

      is_mark = first_is_mark;

      if ( context_length != 0xFFFF && context_length < lig->ComponentCount )
        break;

      for ( i = 1, j = 1; i < lig->ComponentCount; 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 ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) )
          is_mark = FALSE;

        if ( s_in[j] != c[i - 1] )
          break;
      }

      if ( i == lig->ComponentCount )
      {
        if ( gdef && gdef->NewGlyphClasses )
        {
          /* this is just a guess ... */

          error = Add_Glyph_Property( gdef, lig->LigGlyph,
                                      is_mark ? TTO_MARK : TTO_LIGATURE );
          if ( error && error != TTO_Err_Not_Covered )
            return error;
        }

        if ( i == j )
        {
          /* We don't use a new ligature ID if there are no skipped
             glyphs and the ligature already has an ID.             */

          if ( in->ligIDs[in->pos] )
          {
            if ( ADD_String( in, i, out, 1, &lig->LigGlyph,
                             0xFFFF, 0xFFFF ) )
              return error;
          }
          else
          {
            if ( ADD_String( in, i, out, 1, &lig->LigGlyph,
                             0xFFFF, in->max_ligID ) )
              return error;

            (in->max_ligID)++;
          }
        }
        else
        {
          if ( ADD_String( in, 1, out, 1, &lig->LigGlyph,
                           0xFFFF, in->max_ligID ) )
            return error;

          /* Now we must do a second loop to copy the skipped glyphs to
             `out' and assign component values to it.  We start with the
             glyph after the first component.  Glyphs between component
             i and i+1 belong to component i.  Together with the ligID
             value it is later possible to check whether a specific
             component value really belongs to a given ligature.         */

          for ( i = 0; i < lig->ComponentCount - 1; i++ )
          {
            while ( CHECK_Property( gdef, in->string[in->pos],
                                    flags, &property ) )
              if ( ADD_String( in, 1, out, 1, &in->string[in->pos],
                               i, in->max_ligID ) )
                return error;

            (in->pos)++;
          }

          (in->max_ligID)++;
        }

        return TT_Err_Ok;
      }
    }

    return TTO_Err_Not_Covered;
  }


  /* Do the actual substitution for a context substitution (either format
     5 or 6).  This is only called after we've determined that the input
     matches the subrule.                                                 */

  static FT_Error  Do_ContextSubst( TTO_GSUBHeader*         gsub,
                                    FT_UShort               GlyphCount,
                                    FT_UShort               SubstCount,
                                    TTO_SubstLookupRecord*  subst,
                                    TTO_GSUB_String*        in,
                                    TTO_GSUB_String*        out,
                                    int                     nesting_level )
  {
    FT_Error  error;
    FT_UShort i, old_pos;


    i = 0;

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

        /* Do a substitution */

        error = Do_Glyph_Lookup( gsub, subst->LookupListIndex, in, out,
                                 GlyphCount, nesting_level );

        subst++;
        SubstCount--;
        i += in->pos - old_pos;

        if ( error == TTO_Err_Not_Covered )
        {
          /* XXX "can't happen" -- but don't count on it */

          if ( ADD_String( in, 1, out, 1, &in->string[in->pos],
                           0xFFFF, 0xFFFF ) )
            return error;
          i++;
        }
        else if ( error )
          return error;
      }
      else
      {
        /* No substitution for this index */

        if ( ADD_String( in, 1, out, 1, &in->string[in->pos],
                         0xFFFF, 0xFFFF ) )
          return error;
        i++;
      }
    }

    return TT_Err_Ok;
  }


  /* LookupType 5 */

  /* SubRule */

  static FT_Error  Load_SubRule( TTO_SubRule*  sr,
                                 FT_Stream     stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

    FT_UShort               n, count;
    FT_UShort*              i;

    TTO_SubstLookupRecord*  slr;


    if ( ACCESS_Frame( 4L ) )
      return error;

    sr->GlyphCount = GET_UShort();
    sr->SubstCount = GET_UShort();

    FORGET_Frame();

    sr->Input = NULL;

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

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

    i = sr->Input;

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

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

    FORGET_Frame();

    sr->SubstLookupRecord = NULL;

    count = sr->SubstCount;

    if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, TTO_SubstLookupRecord ) )
      goto Fail2;

    slr = sr->SubstLookupRecord;

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

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

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( slr );

  Fail2:
    FREE( i );
    return error;
  }


  static void  Free_SubRule( TTO_SubRule*  sr,
			     FT_Memory     memory )
  {
    FREE( sr->SubstLookupRecord );
    FREE( sr->Input );
  }


  /* SubRuleSet */

  static FT_Error  Load_SubRuleSet( TTO_SubRuleSet*  srs,
                                    FT_Stream        stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_SubRule*  sr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = srs->SubRuleCount = GET_UShort();

    FORGET_Frame();

    srs->SubRule = NULL;

    if ( ALLOC_ARRAY( srs->SubRule, count, TTO_SubRule ) )
      return error;

    sr = srs->SubRule;

    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_SubRule( &sr[n], stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( sr );
    return error;
  }


  static void  Free_SubRuleSet( TTO_SubRuleSet*  srs,
				FT_Memory        memory )
  {
    FT_UShort     n, count;

    TTO_SubRule*  sr;


    if ( srs->SubRule )
    {
      count = srs->SubRuleCount;
      sr    = srs->SubRule;

      for ( n = 0; n < count; n++ )
        Free_SubRule( &sr[n], memory );

      FREE( sr );
    }
  }


  /* ContextSubstFormat1 */

  static FT_Error  Load_ContextSubst1( TTO_ContextSubstFormat1*  csf1,
                                       FT_Stream                 stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_SubRuleSet*  srs;


    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( &csf1->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = csf1->SubRuleSetCount = GET_UShort();

    FORGET_Frame();

    csf1->SubRuleSet = NULL;

    if ( ALLOC_ARRAY( csf1->SubRuleSet, count, TTO_SubRuleSet ) )
      goto Fail2;

    srs = csf1->SubRuleSet;

    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_SubRuleSet( &srs[n], stream ) ) != TT_Err_Ok )
        goto Fail1;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( srs );

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


  static void  Free_Context1( TTO_ContextSubstFormat1* csf1,
			      FT_Memory                memory )
  {
    FT_UShort        n, count;

    TTO_SubRuleSet*  srs;


    if ( csf1->SubRuleSet )
    {
      count = csf1->SubRuleSetCount;
      srs   = csf1->SubRuleSet;

      for ( n = 0; n < count; n++ )
        Free_SubRuleSet( &srs[n], memory );

      FREE( srs );
    }

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


  /* SubClassRule */

  static FT_Error  Load_SubClassRule( TTO_ContextSubstFormat2*  csf2,
                                      TTO_SubClassRule*         scr,
                                      FT_Stream                 stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

    FT_UShort               n, count;

    FT_UShort*              c;
    TTO_SubstLookupRecord*  slr;
    FT_Bool*                d;


    if ( ACCESS_Frame( 4L ) )
      return error;

    scr->GlyphCount = GET_UShort();
    scr->SubstCount = GET_UShort();

    if ( scr->GlyphCount > csf2->MaxContextLength )
      csf2->MaxContextLength = scr->GlyphCount;

    FORGET_Frame();

    scr->Class = NULL;

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

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

    c = scr->Class;
    d = csf2->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();

    scr->SubstLookupRecord = NULL;

    count = scr->SubstCount;

    if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, TTO_SubstLookupRecord ) )
      goto Fail2;

    slr = scr->SubstLookupRecord;

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

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

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( slr );

  Fail2:
    FREE( c );
    return error;
  }


  static void  Free_SubClassRule( TTO_SubClassRule*  scr,
				  FT_Memory          memory )
  {
    FREE( scr->SubstLookupRecord );
    FREE( scr->Class );
  }


  /* SubClassSet */

  static FT_Error  Load_SubClassSet( TTO_ContextSubstFormat2*  csf2,
                                     TTO_SubClassSet*          scs,
                                     FT_Stream                 stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_SubClassRule*  scr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = scs->SubClassRuleCount = GET_UShort();

    FORGET_Frame();

    scs->SubClassRule = NULL;

    if ( ALLOC_ARRAY( scs->SubClassRule, count, TTO_SubClassRule ) )
      return error;

    scr = scs->SubClassRule;

    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_SubClassRule( csf2, &scr[n],
                                        stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( scr );
    return error;
  }


  static void  Free_SubClassSet( TTO_SubClassSet*  scs,
				 FT_Memory         memory )
  {
    FT_UShort          n, count;

    TTO_SubClassRule*  scr;


    if ( scs->SubClassRule )
    {
      count = scs->SubClassRuleCount;
      scr   = scs->SubClassRule;

      for ( n = 0; n < count; n++ )
        Free_SubClassRule( &scr[n], memory );

      FREE( scr );
    }
  }


  /* ContextSubstFormat2 */

  static FT_Error  Load_ContextSubst2( TTO_ContextSubstFormat2*  csf2,
                                       FT_Stream                 stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_SubClassSet*  scs;


    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( &csf2->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 4L ) )
      goto Fail3;

    new_offset = GET_UShort() + base_offset;

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

    count = csf2->SubClassSetCount = GET_UShort();

    FORGET_Frame();

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

    csf2->SubClassSet      = NULL;
    csf2->MaxContextLength = 0;

    if ( ALLOC_ARRAY( csf2->SubClassSet, count, TTO_SubClassSet ) )
      goto Fail2;

    scs = csf2->SubClassSet;

    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_SubClassSet( csf2, &scs[n],
                                         stream ) ) != TT_Err_Ok )
          goto Fail1;
        (void)FILE_Seek( cur_offset );
      }
      else
      {
        /* we create a SubClassSet table with no entries */

        csf2->SubClassSet[n].SubClassRuleCount = 0;
        csf2->SubClassSet[n].SubClassRule      = NULL;
      }
    }

    return TT_Err_Ok;

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

    FREE( scs );

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

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


  static void  Free_Context2( TTO_ContextSubstFormat2*  csf2,
			      FT_Memory                 memory )
  {
    FT_UShort         n, count;

    TTO_SubClassSet*  scs;


    if ( csf2->SubClassSet )
    {
      count = csf2->SubClassSetCount;
      scs   = csf2->SubClassSet;

      for ( n = 0; n < count; n++ )
        Free_SubClassSet( &scs[n], memory );

      FREE( scs );
    }

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


  /* ContextSubstFormat3 */

  static FT_Error  Load_ContextSubst3( TTO_ContextSubstFormat3*  csf3,
                                       FT_Stream                 stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_Coverage*           c;
    TTO_SubstLookupRecord*  slr;


    base_offset = FILE_Pos() - 2L;

    if ( ACCESS_Frame( 4L ) )
      return error;

    csf3->GlyphCount = GET_UShort();
    csf3->SubstCount = GET_UShort();

    FORGET_Frame();

    csf3->Coverage = NULL;

    count = csf3->GlyphCount;

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

    c = csf3->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 );
    }

    csf3->SubstLookupRecord = NULL;

    count = csf3->SubstCount;

    if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count,
                      TTO_SubstLookupRecord ) )
      goto Fail2;

    slr = csf3->SubstLookupRecord;

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

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

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( slr );

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

    FREE( c );
    return error;
  }


  static void  Free_Context3( TTO_ContextSubstFormat3*  csf3,
			      FT_Memory                 memory )
  {
    FT_UShort      n, count;

    TTO_Coverage*  c;


    FREE( csf3->SubstLookupRecord );

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

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

      FREE( c );
    }
  }


  /* ContextSubst */

  FT_Error  Load_ContextSubst( TTO_ContextSubst*  cs,
                               FT_Stream          stream )
  {
    FT_Error error;


    if ( ACCESS_Frame( 2L ) )
      return error;

    cs->SubstFormat = GET_UShort();

    FORGET_Frame();

    switch ( cs->SubstFormat )
    {
    case 1:
      return Load_ContextSubst1( &cs->csf.csf1, stream );

    case 2:
      return Load_ContextSubst2( &cs->csf.csf2, stream );

    case 3:
      return Load_ContextSubst3( &cs->csf.csf3, stream );

    default:
      return TTO_Err_Invalid_GSUB_SubTable_Format;
    }

    return TT_Err_Ok;               /* never reached */
  }


  void  Free_ContextSubst( TTO_ContextSubst*  cs,
			   FT_Memory          memory )
  {
    switch ( cs->SubstFormat )
    {
    case 1:
      Free_Context1( &cs->csf.csf1, memory );
      break;

    case 2:
      Free_Context2( &cs->csf.csf2, memory );
      break;

    case 3:
      Free_Context3( &cs->csf.csf3, memory );
      break;
    }
  }


  static FT_Error  Lookup_ContextSubst1(
                     TTO_GSUBHeader*           gsub,
                     TTO_ContextSubstFormat1*  csf1,
                     TTO_GSUB_String*          in,
                     TTO_GSUB_String*          out,
                     FT_UShort                 flags,
                     FT_UShort                 context_length,
                     int                       nesting_level )
  {
    FT_UShort        index, property;
    FT_UShort        i, j, k, numsr;
    FT_Error         error;
    FT_UShort*       s_in;

    TTO_SubRule*     sr;
    TTO_GDEFHeader*  gdef;


    gdef = gsub->gdef;

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

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

    sr    = csf1->SubRuleSet[index].SubRule;
    numsr = csf1->SubRuleSet[index].SubRuleCount;

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

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

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

      for ( i = 1, j = 1; i < sr[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] != sr[k].Input[i - 1] )
          break;
      }

      if ( i == sr[k].GlyphCount )
        return Do_ContextSubst( gsub, sr[k].GlyphCount,
                                sr[k].SubstCount, sr[k].SubstLookupRecord,
                                in, out,
                                nesting_level );
    }

    return TTO_Err_Not_Covered;
  }


  static FT_Error  Lookup_ContextSubst2(
                     TTO_GSUBHeader*           gsub,
                     TTO_ContextSubstFormat2*  csf2,
                     TTO_GSUB_String*          in,
                     TTO_GSUB_String*          out,
                     FT_UShort                 flags,
                     FT_UShort                 context_length,
                     int                       nesting_level )
  {
    FT_UShort          index, property;
    FT_Error           error;
    FT_Memory          memory = gsub->memory;
    FT_UShort          i, j, k, known_classes;

    FT_UShort*         classes;
    FT_UShort*         s_in;
    FT_UShort*         cl;

    TTO_SubClassSet*   scs;
    TTO_SubClassRule*  sr;
    TTO_GDEFHeader*    gdef;


    gdef = gsub->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( &csf2->Coverage, in->string[in->pos], &index );
    if ( error )
      return error;

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

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

    scs = &csf2->SubClassSet[classes[0]];
    if ( !scs )
    {
      error = TTO_Err_Invalid_GSUB_SubTable;
      goto End;
    }

    for ( k = 0; k < scs->SubClassRuleCount; k++ )
    {
      sr  = &scs->SubClassRule[k];

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

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

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

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

      for ( i = 1, j = 1; i < sr->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( &csf2->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 == sr->GlyphCount )
      {
        error = Do_ContextSubst( gsub, sr->GlyphCount,
                                 sr->SubstCount, sr->SubstLookupRecord,
                                 in, out,
                                 nesting_level );
        goto End;
      }
    }

    error = TTO_Err_Not_Covered;

  End:
    FREE( classes );
    return error;
  }


  static FT_Error  Lookup_ContextSubst3(
                     TTO_GSUBHeader*           gsub,
                     TTO_ContextSubstFormat3*  csf3,
                     TTO_GSUB_String*          in,
                     TTO_GSUB_String*          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_Coverage*    c;
    TTO_GDEFHeader*  gdef;


    gdef = gsub->gdef;

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

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

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

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

    for ( i = 1, j = 1; i < csf3->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_ContextSubst( gsub, csf3->GlyphCount,
                            csf3->SubstCount, csf3->SubstLookupRecord,
                            in, out,
                            nesting_level );
  }


  static FT_Error  Lookup_ContextSubst( TTO_GSUBHeader*    gsub,
                                        TTO_ContextSubst*  cs,
                                        TTO_GSUB_String*   in,
                                        TTO_GSUB_String*   out,
                                        FT_UShort          flags,
                                        FT_UShort          context_length,
                                        int                nesting_level )
  {
    switch ( cs->SubstFormat )
    {
    case 1:
      return Lookup_ContextSubst1( gsub, &cs->csf.csf1, in, out,
                                   flags, context_length, nesting_level );

    case 2:
      return Lookup_ContextSubst2( gsub, &cs->csf.csf2, in, out,
                                   flags, context_length, nesting_level );

    case 3:
      return Lookup_ContextSubst3( gsub, &cs->csf.csf3, in, out,
                                   flags, context_length, nesting_level );

    default:
      return TTO_Err_Invalid_GSUB_SubTable_Format;
    }

    return TT_Err_Ok;               /* never reached */
  }


  /* LookupType 6 */

  /* ChainSubRule */

  static FT_Error  Load_ChainSubRule( TTO_ChainSubRule*  csr,
                                      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_SubstLookupRecord*  slr;


    if ( ACCESS_Frame( 2L ) )
      return error;

    csr->BacktrackGlyphCount = GET_UShort();

    FORGET_Frame();

    csr->Backtrack = NULL;

    count = csr->BacktrackGlyphCount;

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

    b = csr->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;

    csr->InputGlyphCount = GET_UShort();

    FORGET_Frame();

    csr->Input = NULL;

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

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

    i = csr->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;

    csr->LookaheadGlyphCount = GET_UShort();

    FORGET_Frame();

    csr->Lookahead = NULL;

    count = csr->LookaheadGlyphCount;

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

    l = csr->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;

    csr->SubstCount = GET_UShort();

    FORGET_Frame();

    csr->SubstLookupRecord = NULL;

    count = csr->SubstCount;

    if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, TTO_SubstLookupRecord ) )
      goto Fail2;

    slr = csr->SubstLookupRecord;

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

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

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( slr );

  Fail2:
    FREE( l );

  Fail3:
    FREE( i );

  Fail4:
    FREE( b );
    return error;
  }


  static void  Free_ChainSubRule( TTO_ChainSubRule*  csr,
				  FT_Memory          memory )
  {
    FREE( csr->SubstLookupRecord );
    FREE( csr->Lookahead );
    FREE( csr->Input );
    FREE( csr->Backtrack );
  }


  /* ChainSubRuleSet */

  static FT_Error  Load_ChainSubRuleSet( TTO_ChainSubRuleSet*  csrs,
                                         FT_Stream             stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_ChainSubRule*  csr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = csrs->ChainSubRuleCount = GET_UShort();

    FORGET_Frame();

    csrs->ChainSubRule = NULL;

    if ( ALLOC_ARRAY( csrs->ChainSubRule, count, TTO_ChainSubRule ) )
      return error;

    csr = csrs->ChainSubRule;

    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_ChainSubRule( &csr[n], stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( csr );
    return error;
  }


  static void  Free_ChainSubRuleSet( TTO_ChainSubRuleSet*  csrs,
				     FT_Memory             memory )
  {
    FT_UShort          n, count;

    TTO_ChainSubRule*  csr;


    if ( csrs->ChainSubRule )
    {
      count = csrs->ChainSubRuleCount;
      csr   = csrs->ChainSubRule;

      for ( n = 0; n < count; n++ )
        Free_ChainSubRule( &csr[n], memory );

      FREE( csr );
    }
  }


  /* ChainContextSubstFormat1 */

  static FT_Error  Load_ChainContextSubst1(
                     TTO_ChainContextSubstFormat1*  ccsf1,
                     FT_Stream                      stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_ChainSubRuleSet*  csrs;


    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( &ccsf1->Coverage, stream ) ) != TT_Err_Ok )
      return error;
    (void)FILE_Seek( cur_offset );

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = ccsf1->ChainSubRuleSetCount = GET_UShort();

    FORGET_Frame();

    ccsf1->ChainSubRuleSet = NULL;

    if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, TTO_ChainSubRuleSet ) )
      goto Fail2;

    csrs = ccsf1->ChainSubRuleSet;

    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_ChainSubRuleSet( &csrs[n], stream ) ) != TT_Err_Ok )
        goto Fail1;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( csrs );

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


  static void  Free_ChainContext1( TTO_ChainContextSubstFormat1*  ccsf1,
				   FT_Memory                      memory )
  {
    FT_UShort             n, count;

    TTO_ChainSubRuleSet*  csrs;


    if ( ccsf1->ChainSubRuleSet )
    {
      count = ccsf1->ChainSubRuleSetCount;
      csrs  = ccsf1->ChainSubRuleSet;

      for ( n = 0; n < count; n++ )
        Free_ChainSubRuleSet( &csrs[n], memory );

      FREE( csrs );
    }

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


  /* ChainSubClassRule */

  static FT_Error  Load_ChainSubClassRule(
                     TTO_ChainContextSubstFormat2*  ccsf2,
                     TTO_ChainSubClassRule*         cscr,
                     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_SubstLookupRecord*  slr;
    FT_Bool*                d;


    if ( ACCESS_Frame( 2L ) )
      return error;

    cscr->BacktrackGlyphCount = GET_UShort();

    FORGET_Frame();

    if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength )
      ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount;

    cscr->Backtrack = NULL;

    count = cscr->BacktrackGlyphCount;

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

    b = cscr->Backtrack;
    d = ccsf2->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;

    cscr->InputGlyphCount = GET_UShort();

    FORGET_Frame();

    if ( cscr->InputGlyphCount > ccsf2->MaxInputLength )
      ccsf2->MaxInputLength = cscr->InputGlyphCount;

    cscr->Input = NULL;

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

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

    i = cscr->Input;
    d = ccsf2->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;

    cscr->LookaheadGlyphCount = GET_UShort();

    FORGET_Frame();

    if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength )
      ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount;

    cscr->Lookahead = NULL;

    count = cscr->LookaheadGlyphCount;

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

    l = cscr->Lookahead;
    d = ccsf2->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;

    cscr->SubstCount = GET_UShort();

    FORGET_Frame();

    cscr->SubstLookupRecord = NULL;

    count = cscr->SubstCount;

    if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count,
                      TTO_SubstLookupRecord ) )
      goto Fail2;

    slr = cscr->SubstLookupRecord;

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

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

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( slr );

  Fail2:
    FREE( l );

  Fail3:
    FREE( i );

  Fail4:
    FREE( b );
    return error;
  }


  static void  Free_ChainSubClassRule( TTO_ChainSubClassRule*  cscr,
				       FT_Memory               memory )
  {
    FREE( cscr->SubstLookupRecord );
    FREE( cscr->Lookahead );
    FREE( cscr->Input );
    FREE( cscr->Backtrack );
  }


  /* SubClassSet */

  static FT_Error  Load_ChainSubClassSet(
                     TTO_ChainContextSubstFormat2*  ccsf2,
                     TTO_ChainSubClassSet*          cscs,
                     FT_Stream                      stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_ChainSubClassRule*  cscr;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = cscs->ChainSubClassRuleCount = GET_UShort();

    FORGET_Frame();

    cscs->ChainSubClassRule = NULL;

    if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count,
                      TTO_ChainSubClassRule ) )
      return error;

    cscr = cscs->ChainSubClassRule;

    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_ChainSubClassRule( ccsf2, &cscr[n],
                                             stream ) ) != TT_Err_Ok )
        goto Fail;
      (void)FILE_Seek( cur_offset );
    }

    return TT_Err_Ok;

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

    FREE( cscr );
    return error;
  }


  static void  Free_ChainSubClassSet( TTO_ChainSubClassSet*  cscs,
				      FT_Memory              memory )
  {
    FT_UShort               n, count;

    TTO_ChainSubClassRule*  cscr;


    if ( cscs->ChainSubClassRule )
    {
      count = cscs->ChainSubClassRuleCount;
      cscr  = cscs->ChainSubClassRule;

      for ( n = 0; n < count; n++ )
        Free_ChainSubClassRule( &cscr[n], memory );

      FREE( cscr );
    }
  }

  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;
  }


  /* ChainContextSubstFormat2 */

  static FT_Error  Load_ChainContextSubst2(
                     TTO_ChainContextSubstFormat2*  ccsf2,
                     FT_Stream                      stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

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

    TTO_ChainSubClassSet*  cscs;


    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( &ccsf2->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();

    /* `ChainSubClassSetCount' 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 = ccsf2->ChainSubClassSetCount = GET_UShort();

    FORGET_Frame();

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

    ccsf2->ChainSubClassSet   = NULL;
    ccsf2->MaxBacktrackLength = 0;
    ccsf2->MaxInputLength     = 0;
    ccsf2->MaxLookaheadLength = 0;

    if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, TTO_ChainSubClassSet ) )
      goto Fail2;

    cscs = ccsf2->ChainSubClassSet;

    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_ChainSubClassSet( ccsf2, &cscs[n],
                                              stream ) ) != TT_Err_Ok )
          goto Fail1;
        (void)FILE_Seek( cur_offset );
      }
      else
      {
        /* we create a ChainSubClassSet table with no entries */

        ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0;
        ccsf2->ChainSubClassSet[n].ChainSubClassRule      = NULL;
      }
    }

    return TT_Err_Ok;

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

    FREE( cscs );

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

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

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

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


  static void  Free_ChainContext2( TTO_ChainContextSubstFormat2*  ccsf2,
				   FT_Memory                      memory )
  {
    FT_UShort              n, count;

    TTO_ChainSubClassSet*  cscs;


    if ( ccsf2->ChainSubClassSet )
    {
      count = ccsf2->ChainSubClassSetCount;
      cscs  = ccsf2->ChainSubClassSet;

      for ( n = 0; n < count; n++ )
        Free_ChainSubClassSet( &cscs[n], memory );

      FREE( cscs );
    }

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

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


  /* ChainContextSubstFormat3 */

  static FT_Error  Load_ChainContextSubst3(
                     TTO_ChainContextSubstFormat3*  ccsf3,
                     FT_Stream                      stream )
  {
    FT_Error error;
    FT_Memory memory = stream->memory;

    FT_UShort               n, nb = 0, ni =0, nl = 0, 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_SubstLookupRecord*  slr;


    base_offset = FILE_Pos() - 2L;

    if ( ACCESS_Frame( 2L ) )
      return error;

    ccsf3->BacktrackGlyphCount = GET_UShort();

    FORGET_Frame();

    ccsf3->BacktrackCoverage = NULL;

    backtrack_count = ccsf3->BacktrackGlyphCount;

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

    b = ccsf3->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;

    ccsf3->InputGlyphCount = GET_UShort();

    FORGET_Frame();

    ccsf3->InputCoverage = NULL;

    input_count = ccsf3->InputGlyphCount;

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

    i = ccsf3->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;

    ccsf3->LookaheadGlyphCount = GET_UShort();

    FORGET_Frame();

    ccsf3->LookaheadCoverage = NULL;

    lookahead_count = ccsf3->LookaheadGlyphCount;

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

    l = ccsf3->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;

    ccsf3->SubstCount = GET_UShort();

    FORGET_Frame();

    ccsf3->SubstLookupRecord = NULL;

    count = ccsf3->SubstCount;

    if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count,
                      TTO_SubstLookupRecord ) )
      goto Fail2;

    slr = ccsf3->SubstLookupRecord;

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

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

    FORGET_Frame();

    return TT_Err_Ok;

  Fail1:
    FREE( slr );

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

    FREE( l );

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

    FREE( i );

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

    FREE( b );
    return error;
  }


  static void  Free_ChainContext3( TTO_ChainContextSubstFormat3*  ccsf3,
				   FT_Memory                      memory )
  {
    FT_UShort      n, count;

    TTO_Coverage*  c;


    FREE( ccsf3->SubstLookupRecord );

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

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

      FREE( c );
    }

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

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

      FREE( c );
    }

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

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

      FREE( c );
    }
  }


  /* ChainContextSubst */

  FT_Error  Load_ChainContextSubst( TTO_ChainContextSubst*  ccs,
                                    FT_Stream               stream )
  {
    FT_Error error;


    if ( ACCESS_Frame( 2L ) )
      return error;

    ccs->SubstFormat = GET_UShort();

    FORGET_Frame();

    switch ( ccs->SubstFormat )
    {
    case 1:
      return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, stream );

    case 2:
      return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, stream );

    case 3:
      return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, stream );

    default:
      return TTO_Err_Invalid_GSUB_SubTable_Format;
    }

    return TT_Err_Ok;               /* never reached */
  }


  void  Free_ChainContextSubst( TTO_ChainContextSubst*  ccs,
				FT_Memory               memory )
  {
    switch ( ccs->SubstFormat )
    {
    case 1:
      Free_ChainContext1( &ccs->ccsf.ccsf1, memory );
      break;

    case 2:
      Free_ChainContext2( &ccs->ccsf.ccsf2, memory );
      break;

    case 3:
      Free_ChainContext3( &ccs->ccsf.ccsf3, memory );
      break;
    }
  }


  static FT_Error  Lookup_ChainContextSubst1(
                     TTO_GSUBHeader*                gsub,
                     TTO_ChainContextSubstFormat1*  ccsf1,
                     TTO_GSUB_String*               in,
                     TTO_GSUB_String*               out,
                     FT_UShort                      flags,
                     FT_UShort                      context_length,
                     int                            nesting_level )
  {
    FT_UShort          index, property;
    FT_UShort          i, j, k, num_csr, curr_pos;
    FT_UShort          bgc, igc, lgc;
    FT_Error           error;
    FT_UShort*         s_in;

    TTO_ChainSubRule*  csr;
    TTO_ChainSubRule   curr_csr;
    TTO_GDEFHeader*    gdef;


    gdef = gsub->gdef;

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

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

    csr     = ccsf1->ChainSubRuleSet[index].ChainSubRule;
    num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount;

    for ( k = 0; k < num_csr; k++ )
    {
      curr_csr = csr[k];
      bgc      = curr_csr.BacktrackGlyphCount;
      igc      = curr_csr.InputGlyphCount;
      lgc      = curr_csr.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_csr.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_csr.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_csr.Lookahead[i] )
          break;
      }

      if ( i == lgc )
        return Do_ContextSubst( gsub, igc,
                                curr_csr.SubstCount,
                                curr_csr.SubstLookupRecord,
                                in, out,
                                nesting_level );
    }

    return TTO_Err_Not_Covered;
  }


  static FT_Error  Lookup_ChainContextSubst2(
                     TTO_GSUBHeader*                gsub,
                     TTO_ChainContextSubstFormat2*  ccsf2,
                     TTO_GSUB_String*               in,
                     TTO_GSUB_String*               out,
                     FT_UShort                      flags,
                     FT_UShort                      context_length,
                     int                            nesting_level )
  {
    FT_UShort              index, property;
    FT_Memory              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_ChainSubClassSet*  cscs;
    TTO_ChainSubClassRule  ccsr;
    TTO_GDEFHeader*        gdef;


    gdef = gsub->gdef;
    memory = gsub->memory;

    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( &ccsf2->Coverage, in->string[in->pos], &index );
    if ( error )
      return error;

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

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

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

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

    cscs = &ccsf2->ChainSubClassSet[input_classes[0]];
    if ( !cscs )
    {
      error = TTO_Err_Invalid_GSUB_SubTable;
      goto End1;
    }

    for ( k = 0; k < cscs->ChainSubClassRuleCount; k++ )
    {
      ccsr = cscs->ChainSubClassRule[k];
      bgc  = ccsr.BacktrackGlyphCount;
      igc  = ccsr.InputGlyphCount;
      lgc  = ccsr.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       = ccsr.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( &ccsf2->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       = ccsr.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( &ccsf2->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       = ccsr.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( &ccsf2->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_ContextSubst( gsub, igc,
                                 ccsr.SubstCount,
                                 ccsr.SubstLookupRecord,
                                 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_ChainContextSubst3(
                     TTO_GSUBHeader*                gsub,
                     TTO_ChainContextSubstFormat3*  ccsf3,
                     TTO_GSUB_String*               in,
                     TTO_GSUB_String*               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_Coverage*    bc;
    TTO_Coverage*    ic;
    TTO_Coverage*    lc;
    TTO_GDEFHeader*  gdef;


    gdef = gsub->gdef;

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

    bgc = ccsf3->BacktrackGlyphCount;
    igc = ccsf3->InputGlyphCount;
    lgc = ccsf3->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       = ccsf3->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       = ccsf3->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 for lookahead glyphs right after the last context
       glyph                                                             */

    curr_pos += j;
    s_in     = &in->string[curr_pos];
    lc       = ccsf3->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_ContextSubst( gsub, igc,
                            ccsf3->SubstCount,
                            ccsf3->SubstLookupRecord,
                            in, out,
                            nesting_level );
  }


  static FT_Error  Lookup_ChainContextSubst(
                     TTO_GSUBHeader*         gsub,
                     TTO_ChainContextSubst*  ccs,
                     TTO_GSUB_String*        in,
                     TTO_GSUB_String*        out,
                     FT_UShort               flags,
                     FT_UShort               context_length,
                     int                     nesting_level )
  {
    switch ( ccs->SubstFormat )
    {
    case 1:
      return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, in, out,
                                        flags, context_length,
                                        nesting_level );

    case 2:
      return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, in, out,
                                        flags, context_length,
                                        nesting_level );

    case 3:
      return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, in, out,
                                        flags, context_length,
                                        nesting_level );

    default:
      return TTO_Err_Invalid_GSUB_SubTable_Format;
    }

    return TT_Err_Ok;               /* never reached */
  }



  /***********
   * GSUB API
   ***********/


  EXPORT_FUNC
  FT_Error  TT_GSUB_Select_Script( TTO_GSUBHeader*  gsub,
                                   FT_ULong         script_tag,
                                   FT_UShort*       script_index )
  {
    FT_UShort          n;

    TTO_ScriptList*    sl;
    TTO_ScriptRecord*  sr;


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

    sl = &gsub->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_GSUB_Select_Language( TTO_GSUBHeader*  gsub,
                                     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 ( !gsub || !language_index || !req_feature_index )
      return TT_Err_Invalid_Argument;

    sl = &gsub->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_GSUB_Select_Feature( TTO_GSUBHeader*  gsub,
                                    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 ( !gsub || !feature_index )
      return TT_Err_Invalid_Argument;

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

    fl = &gsub->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_GSUB_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_GSUB_Query_Scripts( TTO_GSUBHeader*  gsub,
                                   FT_ULong**       script_tag_list )
  {
    FT_UShort          n;
    FT_Error           error;
    FT_Memory          memory;
    FT_ULong*          stl;

    TTO_ScriptList*    sl;
    TTO_ScriptRecord*  sr;


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

    memory = gsub->memory;

    sl = &gsub->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_GSUB_Query_Languages( TTO_GSUBHeader*  gsub,
                                     FT_UShort        script_index,
                                     FT_ULong**       language_tag_list )
  {
    FT_UShort           n;
    FT_Error            error;
    FT_Memory           memory;
    FT_ULong*           ltl;

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


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

    memory = gsub->memory;
    
    sl = &gsub->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_GSUB_Query_Features( TTO_GSUBHeader*  gsub,
                                    FT_UShort        script_index,
                                    FT_UShort        language_index,
                                    FT_ULong**       feature_tag_list )
  {
    FT_UShort           n;
    FT_Error            error;
    FT_Memory           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 ( !gsub || !feature_tag_list )
      return TT_Err_Invalid_Argument;

    memory = gsub->memory;
    
    sl = &gsub->ScriptList;
    sr = sl->ScriptRecord;

    fl = &gsub->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_GSUB_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 substitution
     has been done, or TTO_Err_Not_Covered if not.                        */

  static FT_Error  Do_Glyph_Lookup( TTO_GSUBHeader*   gsub,
                                    FT_UShort         lookup_index,
                                    TTO_GSUB_String*  in,
                                    TTO_GSUB_String*  out,
                                    FT_UShort         context_length,
                                    int               nesting_level )
  {
    FT_Error     error = TT_Err_Ok;
    FT_UShort    i, flags;
    TTO_Lookup*  lo;


    nesting_level++;

    if ( nesting_level > TTO_MAX_NESTING_LEVEL )
      return TTO_Err_Too_Many_Nested_Contexts;

    lo    = &gsub->LookupList.Lookup[lookup_index];
    flags = lo->LookupFlag;

    for ( i = 0; i < lo->SubTableCount; i++ )
    {
      switch ( lo->LookupType )
      {
      case GSUB_LOOKUP_SINGLE:
        error = Lookup_SingleSubst( &lo->SubTable[i].st.gsub.single,
                                    in, out,
                                    flags, context_length, gsub->gdef );
        break;

      case GSUB_LOOKUP_MULTIPLE:
        error = Lookup_MultipleSubst( &lo->SubTable[i].st.gsub.multiple,
                                      in, out,
                                      flags, context_length, gsub->gdef );
        break;

      case GSUB_LOOKUP_ALTERNATE:
        error = Lookup_AlternateSubst( gsub,
                                       &lo->SubTable[i].st.gsub.alternate,
                                       in, out,
                                       flags, context_length, gsub->gdef );
        break;

      case GSUB_LOOKUP_LIGATURE:
        error = Lookup_LigatureSubst( &lo->SubTable[i].st.gsub.ligature,
                                      in, out,
                                      flags, context_length, gsub->gdef );
        break;

      case GSUB_LOOKUP_CONTEXT:
        error = Lookup_ContextSubst( gsub, &lo->SubTable[i].st.gsub.context,
                                     in, out,
                                     flags, context_length, nesting_level );
        break;

      case GSUB_LOOKUP_CHAIN:
        error = Lookup_ChainContextSubst( gsub,
                                          &lo->SubTable[i].st.gsub.chain,
                                          in, out,
                                          flags, context_length,
                                          nesting_level );
        break;
      }

      /* Check whether we have a successful substitution 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( TTO_GSUBHeader*   gsub,
                                     FT_UShort         lookup_index,
                                     TTO_GSUB_String*  in,
                                     TTO_GSUB_String*  out )
  {
    FT_Error  error, retError = TTO_Err_Not_Covered;

    FT_UShort*  properties = gsub->LookupList.Properties;
    FT_UShort*  p_in       = in->properties;
    FT_UShort*  s_in       = in->string;

    int      nesting_level = 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 */
        error = Do_Glyph_Lookup( gsub, lookup_index, in, out,
                                 0xFFFF, nesting_level );
        if ( error )
	{
	  if ( error != TTO_Err_Not_Covered )
	    return error;
	}
	else
	  retError = error;
      }
      else
        error = TTO_Err_Not_Covered;

      if ( error == TTO_Err_Not_Covered ) 
        if ( ADD_String( in, 1, out, 1, &s_in[in->pos], 0xFFFF, 0xFFFF ) )
          return error;
    }

    return retError;
  }


  EXPORT_FUNC
  FT_Error  TT_GSUB_Add_Feature( TTO_GSUBHeader*  gsub,
                                 FT_UShort        feature_index,
                                 FT_UShort        property )
  {
    FT_UShort    i;

    TTO_Feature  feature;
    FT_UShort*   properties;
    FT_UShort*   index;


    if ( !gsub ||
         feature_index >= gsub->FeatureList.FeatureCount )
      return TT_Err_Invalid_Argument;

    properties = gsub->LookupList.Properties;

    feature = gsub->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_GSUB_Clear_Features( TTO_GSUBHeader*  gsub )
  {
    FT_UShort i;

    FT_UShort*  properties;


    if ( !gsub )
      return TT_Err_Invalid_Argument;

    properties = gsub->LookupList.Properties;

    for ( i = 0; i < gsub->LookupList.LookupCount; i++ )
      properties[i] = 0;

    return TT_Err_Ok;
  }


  EXPORT_FUNC
  FT_Error  TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader*  gsub,
                                                 TTO_AltFunction  altfunc,
                                                 void*            data )
  {
    if ( !gsub )
      return TT_Err_Invalid_Argument;

    gsub->altfunc = altfunc;
    gsub->data    = data;

    return TT_Err_Ok;
  }


  EXPORT_FUNC
  FT_Error  TT_GSUB_String_New( FT_Memory           memory,
				TTO_GSUB_String   **result )
  {
    FT_Error error;
    
    TTO_GSUB_String *str;

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

    str->memory = memory;

    str->length = 0;
    str->allocated = 0;
    str->pos = 0;
    str->string = NULL;
    str->properties = NULL;
    str->components = NULL;
    str->max_ligID = 0;
    str->ligIDs = 0;
    str->logClusters = 0;

    *result = str;

    return TT_Err_Ok;
  }

  EXPORT_DEF
  FT_Error  TT_GSUB_String_Set_Length( TTO_GSUB_String *str,
				       FT_ULong         new_length)
  {
    FT_Memory memory = str->memory;
    FT_Error error;
    
    if ( new_length > str->allocated )
    {
      if ( REALLOC_ARRAY( str->string, str->allocated, new_length, FT_UShort ) )
        return error;
      if ( REALLOC_ARRAY( str->properties, str->allocated, new_length, FT_UShort ) )
        return error;
      if ( REALLOC_ARRAY( str->components, str->allocated, new_length, FT_UShort ) )
        return error;
      if ( REALLOC_ARRAY( str->ligIDs, str->allocated, new_length, FT_UShort ) )
        return error;
      if ( REALLOC_ARRAY( str->logClusters, str->allocated, new_length, FT_Int ) )
        return error;

      str->allocated = new_length;
      str->length = new_length;
    }

    return TT_Err_Ok;
  }

  EXPORT_FUNC
  FT_Error  TT_GSUB_String_Done( TTO_GSUB_String   *str )
  {
    FT_Memory memory = str->memory;

    FREE( str->string );
    FREE( str->properties );
    FREE( str->components );
    FREE( str->ligIDs );
    FREE( str->logClusters );

    FREE( str );

    return TT_Err_Ok;
  }

  EXPORT_FUNC
  FT_Error  TT_GSUB_Apply_String( TTO_GSUBHeader*   gsub,
                                  TTO_GSUB_String*  in,
                                  TTO_GSUB_String*  out )
  {
    FT_Error          error, retError = TTO_Err_Not_Covered;
    FT_Memory         memory = in->memory;
    FT_UShort         j;

    TTO_GSUB_String   tmp1;
    TTO_GSUB_String*  ptmp1;
    TTO_GSUB_String   tmp2;
    TTO_GSUB_String*  ptmp2;
    TTO_GSUB_String*  t;

    FT_UShort*        properties;


    if ( !gsub ||
         !in || !out || in->length == 0 || in->pos >= in->length )
      return TT_Err_Invalid_Argument;

    properties = gsub->LookupList.Properties;
    
    tmp1.memory      = memory;
    tmp1.length      = in->length;
    tmp1.allocated   = in->length;
    tmp1.pos         = in->pos;
    tmp1.max_ligID   = 1;
    tmp1.string      = NULL;
    tmp1.properties  = NULL;
    tmp1.components  = NULL;
    tmp1.ligIDs      = NULL;
    tmp1.logClusters = NULL;

    tmp2.memory      = memory;
    tmp2.allocated   = 0;
    tmp2.pos         = 0;
    tmp2.string      = NULL;
    tmp2.properties  = NULL;
    tmp2.components  = NULL;
    tmp2.ligIDs      = NULL;
    tmp2.logClusters = NULL;

    ptmp1 = &tmp1;
    ptmp2 = &tmp2;

    if ( ALLOC_ARRAY( tmp1.string, tmp1.length, FT_UShort ) )
      return error;
    MEM_Copy( tmp1.string, in->string, in->length * sizeof ( FT_UShort ) );

    /* make sure that we always have a `properties', `components', and
       `ligIDs' array in the string object                             */

    if ( ALLOC_ARRAY( tmp1.components, tmp1.length, FT_UShort ) )
      goto End;
    if ( ALLOC_ARRAY( tmp1.ligIDs, tmp1.length, FT_UShort ) )
      goto End;
    if ( ALLOC_ARRAY( tmp1.properties, tmp1.length, FT_UShort ) )
      goto End;
    if ( in->properties )
      MEM_Copy( tmp1.properties, in->properties,
                in->length * sizeof( FT_UShort ) );
    if ( ALLOC_ARRAY( tmp1.logClusters, tmp1.length, FT_Int ) )
      goto End;
    MEM_Copy( tmp1.logClusters, in->logClusters,
	      in->length * sizeof( FT_Int ) );

    for ( j = 0; j < gsub->LookupList.LookupCount; j++ )
      if ( properties[j] )
      {
        error = Do_String_Lookup( gsub, j, ptmp1, ptmp2 );
        if ( error )
	{
	  if ( error != TTO_Err_Not_Covered )
	    goto End;
	}
	else
	  retError = error;
	  

        /* flipping `in' and `out', preparing the next loop */

        ptmp1->pos       = in->pos;
        ptmp2->length    = ptmp2->pos;
        ptmp2->pos       = in->pos;
        ptmp2->max_ligID = ptmp1->max_ligID;

        t     = ptmp2;
        ptmp2 = ptmp1;
        ptmp1 = t;
      }

  End:
    FREE( ptmp2->string );
    FREE( ptmp2->properties );
    FREE( ptmp2->components );
    FREE( ptmp2->ligIDs );
    FREE( ptmp2->logClusters );

    if ( error && error != TTO_Err_Not_Covered )
    {
      FREE( ptmp1->string );
      FREE( ptmp1->components );
      FREE( ptmp1->ligIDs );
      FREE( ptmp1->properties );
      FREE( ptmp1->logClusters );
      
      return error;
    }
    else
    {
      out->length      = ptmp1->length;
      out->pos         = 0;
      out->allocated   = ptmp1->allocated;
      out->string      = ptmp1->string;
      out->components  = ptmp1->components;
      out->ligIDs      = ptmp1->ligIDs;
      out->logClusters = ptmp1->logClusters;
      
      if ( in->properties )
	out->properties = ptmp1->properties;
      else
      {
	FREE( ptmp1->properties );
	out->properties = NULL;
      }

      return retError;
    }
  }


/* END */
