/*
 * Copyright (C) 1998-2004  David Turner and Werner Lemberg
 * Copyright (C) 2006  Behdad Esfahbod
 * Copyright (C) 2007  Red Hat, Inc.
 *
 * This is part of HarfBuzz, an OpenType Layout engine library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Red Hat Author(s): Behdad Esfahbod
 */

#include "harfbuzz-impl.h"
#include "harfbuzz-gsub-private.h"
#include "harfbuzz-open-private.h"
#include "harfbuzz-gdef-private.h"

static HB_Error  GSUB_Do_Glyph_Lookup( HB_GSUBHeader*   gsub,
				       HB_UShort         lookup_index,
				       HB_Buffer        buffer,
				       HB_UShort         context_length,
				       int               nesting_level );



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



HB_Error  HB_Load_GSUB_Table( HB_Stream stream,
			      HB_GSUBHeader** retptr,
			      HB_GDEFHeader*  gdef,
                              HB_Stream       gdefStream )
{
  HB_Error         error;
  HB_UInt         cur_offset, new_offset, base_offset;

  HB_GSUBHeader*  gsub;

  if ( !retptr )
    return ERR(HB_Err_Invalid_Argument);

  if ( GOTO_Table( TTAG_GSUB ) )
    return error;

  base_offset = FILE_Pos();

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

  /* 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 = _HB_OPEN_Load_ScriptList( &gsub->ScriptList,
				  stream ) ) != HB_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 = _HB_OPEN_Load_FeatureList( &gsub->FeatureList,
				   stream ) ) != HB_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 = _HB_OPEN_Load_LookupList( &gsub->LookupList,
				  stream, HB_Type_GSUB ) ) != HB_Err_Ok )
    goto Fail2;

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

  if ( ( error =  _HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( gdef, gdefStream,
								     gsub->LookupList.Lookup,
								     gsub->LookupList.LookupCount ) ) )
    goto Fail1;

  *retptr = gsub;

  return HB_Err_Ok;

Fail1:
  _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB );

Fail2:
  _HB_OPEN_Free_FeatureList( &gsub->FeatureList );

Fail3:
  _HB_OPEN_Free_ScriptList( &gsub->ScriptList );

Fail4:
  FREE ( gsub );


  return error;
}


HB_Error   HB_Done_GSUB_Table( HB_GSUBHeader* gsub )
{
  _HB_OPEN_Free_LookupList( &gsub->LookupList, HB_Type_GSUB );
  _HB_OPEN_Free_FeatureList( &gsub->FeatureList );
  _HB_OPEN_Free_ScriptList( &gsub->ScriptList );

  FREE( gsub );

  return HB_Err_Ok;
}

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


/* LookupType 1 */

/* SingleSubstFormat1 */
/* SingleSubstFormat2 */

static HB_Error  Load_SingleSubst( HB_GSUB_SubTable* st,
				   HB_Stream         stream )
{
  HB_Error error;
  HB_SingleSubst*  ss = &st->single;

  HB_UShort n, count;
  HB_UInt cur_offset, new_offset, base_offset;

  HB_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 = _HB_OPEN_Load_Coverage( &ss->Coverage, stream ) ) != HB_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, HB_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 ERR(HB_Err_Invalid_SubTable_Format);
  }

  return HB_Err_Ok;

Fail1:
  FREE( s );

Fail2:
  _HB_OPEN_Free_Coverage( &ss->Coverage );
  return error;
}


static void  Free_SingleSubst( HB_GSUB_SubTable* st )
{
  HB_SingleSubst*  ss = &st->single;

  switch ( ss->SubstFormat )
  {
  case 1:
    break;

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

  default:
    break;
  }

  _HB_OPEN_Free_Coverage( &ss->Coverage );
}


static HB_Error  Lookup_SingleSubst( HB_GSUBHeader*   gsub,
				     HB_GSUB_SubTable* st,
				     HB_Buffer        buffer,
				     HB_UShort         flags,
				     HB_UShort         context_length,
				     int               nesting_level )
{
  HB_UShort index, value, property;
  HB_Error  error;
  HB_SingleSubst*  ss = &st->single;
  HB_GDEFHeader*   gdef = gsub->gdef;

  HB_UNUSED(nesting_level);

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

  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
    return error;

  error = _HB_OPEN_Coverage_Index( &ss->Coverage, IN_CURGLYPH(), &index );
  if ( error )
    return error;

  switch ( ss->SubstFormat )
  {
  case 1:
    value = ( IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF;
    if ( REPLACE_Glyph( buffer, value, nesting_level ) )
      return error;
    break;

  case 2:
    if ( index >= ss->ssf.ssf2.GlyphCount )
      return ERR(HB_Err_Invalid_SubTable);
    value = ss->ssf.ssf2.Substitute[index];
    if ( REPLACE_Glyph( buffer, value, nesting_level ) )
      return error;
    break;

  default:
    return ERR(HB_Err_Invalid_SubTable);
  }

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

    error = _HB_GDEF_Add_Glyph_Property( gdef, value, property );
    if ( error && error != HB_Err_Not_Covered )
      return error;
  }

  return HB_Err_Ok;
}


/* LookupType 2 */

/* Sequence */

static HB_Error  Load_Sequence( HB_Sequence*  s,
				HB_Stream      stream )
{
  HB_Error error;

  HB_UShort n, count;
  HB_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, HB_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 HB_Err_Ok;
}


static void  Free_Sequence( HB_Sequence*  s )
{
  FREE( s->Substitute );
}


/* MultipleSubstFormat1 */

static HB_Error  Load_MultipleSubst( HB_GSUB_SubTable* st,
				     HB_Stream         stream )
{
  HB_Error error;
  HB_MultipleSubst*  ms = &st->multiple;

  HB_UShort      n = 0, m, count;
  HB_UInt       cur_offset, new_offset, base_offset;

  HB_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 = _HB_OPEN_Load_Coverage( &ms->Coverage, stream ) ) != HB_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, HB_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 ) ) != HB_Err_Ok )
      goto Fail1;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( s );

Fail2:
  _HB_OPEN_Free_Coverage( &ms->Coverage );
  return error;
}


static void  Free_MultipleSubst( HB_GSUB_SubTable* st )
{
  HB_UShort      n, count;
  HB_MultipleSubst*  ms = &st->multiple;

  HB_Sequence*  s;


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

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

    FREE( s );
  }

  _HB_OPEN_Free_Coverage( &ms->Coverage );
}


static HB_Error  Lookup_MultipleSubst( HB_GSUBHeader*    gsub,
				       HB_GSUB_SubTable* st,
				       HB_Buffer         buffer,
				       HB_UShort          flags,
				       HB_UShort          context_length,
				       int                nesting_level )
{
  HB_Error  error;
  HB_UShort index, property, n, count;
  HB_UShort*s;
  HB_MultipleSubst*  ms = &st->multiple;
  HB_GDEFHeader*     gdef = gsub->gdef;

  HB_UNUSED(nesting_level);

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

  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
    return error;

  error = _HB_OPEN_Coverage_Index( &ms->Coverage, IN_CURGLYPH(), &index );
  if ( error )
    return error;

  if ( index >= ms->SequenceCount )
    return ERR(HB_Err_Invalid_SubTable);

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

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

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

    if ( property == HB_GDEF_LIGATURE )
      property = HB_GDEF_BASE_GLYPH;

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

  return HB_Err_Ok;
}


/* LookupType 3 */

/* AlternateSet */

static HB_Error  Load_AlternateSet( HB_AlternateSet*  as,
				    HB_Stream          stream )
{
  HB_Error error;

  HB_UShort n, count;
  HB_UShort*  a;


  if ( ACCESS_Frame( 2L ) )
    return error;

  count = as->GlyphCount = GET_UShort();

  FORGET_Frame();

  as->Alternate = NULL;

  if ( ALLOC_ARRAY( as->Alternate, count, HB_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 HB_Err_Ok;
}


static void  Free_AlternateSet( HB_AlternateSet*  as )
{
  FREE( as->Alternate );
}


/* AlternateSubstFormat1 */

static HB_Error  Load_AlternateSubst( HB_GSUB_SubTable* st,
				      HB_Stream         stream )
{
  HB_Error error;
  HB_AlternateSubst* as = &st->alternate;

  HB_UShort          n = 0, m, count;
  HB_UInt           cur_offset, new_offset, base_offset;

  HB_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 = _HB_OPEN_Load_Coverage( &as->Coverage, stream ) ) != HB_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, HB_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 ) ) != HB_Err_Ok )
      goto Fail1;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( aset );

Fail2:
  _HB_OPEN_Free_Coverage( &as->Coverage );
  return error;
}


static void  Free_AlternateSubst( HB_GSUB_SubTable* st )
{
  HB_UShort          n, count;
  HB_AlternateSubst* as = &st->alternate;

  HB_AlternateSet*  aset;


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

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

    FREE( aset );
  }

  _HB_OPEN_Free_Coverage( &as->Coverage );
}


static HB_Error  Lookup_AlternateSubst( HB_GSUBHeader*    gsub,
					HB_GSUB_SubTable* st,
					HB_Buffer         buffer,
					HB_UShort          flags,
					HB_UShort          context_length,
					int                nesting_level )
{
  HB_Error          error;
  HB_UShort         index, value, alt_index, property;
  HB_AlternateSubst* as = &st->alternate;
  HB_GDEFHeader*     gdef = gsub->gdef;
  HB_AlternateSet  aset;

  HB_UNUSED(nesting_level);

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

  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
    return error;

  error = _HB_OPEN_Coverage_Index( &as->Coverage, IN_CURGLYPH(), &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)( buffer->out_pos, IN_CURGLYPH(),
				 aset.GlyphCount, aset.Alternate,
				 gsub->data );
  else
    alt_index = 0;

  value = aset.Alternate[alt_index];
  if ( REPLACE_Glyph( buffer, value, nesting_level ) )
    return error;

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

    error = _HB_GDEF_Add_Glyph_Property( gdef, value, property );
    if ( error && error != HB_Err_Not_Covered )
      return error;
  }

  return HB_Err_Ok;
}


/* LookupType 4 */

/* Ligature */

static HB_Error  Load_Ligature( HB_Ligature*  l,
				HB_Stream      stream )
{
  HB_Error error;

  HB_UShort n, count;
  HB_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, HB_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 HB_Err_Ok;
}


static void  Free_Ligature( HB_Ligature*  l )
{
  FREE( l->Component );
}


/* LigatureSet */

static HB_Error  Load_LigatureSet( HB_LigatureSet*  ls,
				   HB_Stream         stream )
{
  HB_Error error;

  HB_UShort      n = 0, m, count;
  HB_UInt       cur_offset, new_offset, base_offset;

  HB_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, HB_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 ) ) != HB_Err_Ok )
      goto Fail;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( l );
  return error;
}


static void  Free_LigatureSet( HB_LigatureSet*  ls )
{
  HB_UShort      n, count;

  HB_Ligature*  l;


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

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

    FREE( l );
  }
}


/* LigatureSubstFormat1 */

static HB_Error  Load_LigatureSubst( HB_GSUB_SubTable* st,
				     HB_Stream         stream )
{
  HB_Error error;
  HB_LigatureSubst*  ls = &st->ligature;

  HB_UShort         n = 0, m, count;
  HB_UInt          cur_offset, new_offset, base_offset;

  HB_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 = _HB_OPEN_Load_Coverage( &ls->Coverage, stream ) ) != HB_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, HB_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 ) ) != HB_Err_Ok )
      goto Fail1;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( lset );

Fail2:
  _HB_OPEN_Free_Coverage( &ls->Coverage );
  return error;
}


static void  Free_LigatureSubst( HB_GSUB_SubTable* st )
{
  HB_UShort         n, count;
  HB_LigatureSubst*  ls = &st->ligature;

  HB_LigatureSet*  lset;


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

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

    FREE( lset );
  }

  _HB_OPEN_Free_Coverage( &ls->Coverage );
}


static HB_Error  Lookup_LigatureSubst( HB_GSUBHeader*    gsub,
				       HB_GSUB_SubTable* st,
				       HB_Buffer         buffer,
				       HB_UShort          flags,
				       HB_UShort          context_length,
				       int                nesting_level )
{
  HB_UShort      index, property;
  HB_Error       error;
  HB_UShort      numlig, i, j, is_mark, first_is_mark = FALSE;
  HB_UShort*     c;
  HB_LigatureSubst*  ls = &st->ligature;
  HB_GDEFHeader*     gdef = gsub->gdef;

  HB_Ligature*  lig;

  HB_UNUSED(nesting_level);

  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
    return error;

  if ( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
    first_is_mark = TRUE;

  error = _HB_OPEN_Coverage_Index( &ls->Coverage, IN_CURGLYPH(), &index );
  if ( error )
    return error;

  if ( index >= ls->LigatureSetCount )
     return ERR(HB_Err_Invalid_SubTable);

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

  for ( numlig = ls->LigatureSet[index].LigatureCount;
	numlig;
	numlig--, lig++ )
  {
    if ( buffer->in_pos + lig->ComponentCount > buffer->in_length )
      goto next_ligature;               /* Not enough glyphs in input */

    c    = lig->Component;

    is_mark = first_is_mark;

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

    for ( i = 1, j = buffer->in_pos + 1; i < lig->ComponentCount; i++, j++ )
    {
      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
      {
	if ( error && error != HB_Err_Not_Covered )
	  return error;

	if ( j + lig->ComponentCount - i == (HB_Int)buffer->in_length )
	  goto next_ligature;
	j++;
      }

      if ( !( property == HB_GDEF_MARK || property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS ) )
	is_mark = FALSE;

      if ( IN_GLYPH( j ) != c[i - 1] )
	goto next_ligature;
    }

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

      error = _HB_GDEF_Add_Glyph_Property( gdef, lig->LigGlyph,
				  is_mark ? HB_GDEF_MARK : HB_GDEF_LIGATURE );
      if ( error && error != HB_Err_Not_Covered )
	return error;
    }

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

      if ( IN_LIGID( buffer->in_pos ) )
      {
	if ( ADD_String( buffer, i, 1, &lig->LigGlyph,
			0xFFFF, 0xFFFF ) )
	  return error;
      }
      else
      {
	HB_UShort ligID = _hb_buffer_allocate_ligid( buffer );
	if ( ADD_String( buffer, i, 1, &lig->LigGlyph,
			0xFFFF, ligID ) )
	  return error;
      }
    }
    else
    {
      HB_UShort ligID = _hb_buffer_allocate_ligid( buffer );
      if ( ADD_Glyph( buffer, lig->LigGlyph, 0xFFFF, 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_CURITEM(),
				flags, &property ) )
	  if ( ADD_Glyph( buffer, IN_CURGLYPH(), i, ligID ) )
	    return error;

	(buffer->in_pos)++;
      }
    }

    return HB_Err_Ok;

  next_ligature:
    ;
  }

  return HB_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 HB_Error  Do_ContextSubst( HB_GSUBHeader*        gsub,
				  HB_UShort              GlyphCount,
				  HB_UShort              SubstCount,
				  HB_SubstLookupRecord* subst,
				  HB_Buffer             buffer,
				  int                    nesting_level )
{
  HB_Error  error;
  HB_UInt   i, old_pos;


  i = 0;

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

      /* Do a substitution */

      error = GSUB_Do_Glyph_Lookup( gsub, subst->LookupListIndex, buffer,
				    GlyphCount, nesting_level );

      subst++;
      SubstCount--;
      i += buffer->in_pos - old_pos;

      if ( error == HB_Err_Not_Covered )
      {
	if ( COPY_Glyph( buffer ) )
	  return error;
	i++;
      }
      else if ( error )
	return error;
    }
    else
    {
      /* No substitution for this index */

      if ( COPY_Glyph( buffer ) )
	return error;
      i++;
    }
  }

  return HB_Err_Ok;
}


/* LookupType 5 */

/* SubRule */

static HB_Error  Load_SubRule( HB_SubRule*  sr,
			       HB_Stream     stream )
{
  HB_Error error;

  HB_UShort               n, count;
  HB_UShort*              i;

  HB_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, HB_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, HB_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 HB_Err_Ok;

Fail1:
  FREE( slr );

Fail2:
  FREE( i );
  return error;
}


static void  Free_SubRule( HB_SubRule*  sr )
{
  FREE( sr->SubstLookupRecord );
  FREE( sr->Input );
}


/* SubRuleSet */

static HB_Error  Load_SubRuleSet( HB_SubRuleSet*  srs,
				  HB_Stream        stream )
{
  HB_Error error;

  HB_UShort     n = 0, m, count;
  HB_UInt      cur_offset, new_offset, base_offset;

  HB_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, HB_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 ) ) != HB_Err_Ok )
      goto Fail;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( sr );
  return error;
}


static void  Free_SubRuleSet( HB_SubRuleSet*  srs )
{
  HB_UShort     n, count;

  HB_SubRule*  sr;


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

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

    FREE( sr );
  }
}


/* ContextSubstFormat1 */

static HB_Error  Load_ContextSubst1( HB_ContextSubstFormat1*  csf1,
				     HB_Stream                 stream )
{
  HB_Error error;

  HB_UShort        n = 0, m, count;
  HB_UInt         cur_offset, new_offset, base_offset;

  HB_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 = _HB_OPEN_Load_Coverage( &csf1->Coverage, stream ) ) != HB_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, HB_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 ) ) != HB_Err_Ok )
      goto Fail1;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( srs );

Fail2:
  _HB_OPEN_Free_Coverage( &csf1->Coverage );
  return error;
}


static void  Free_ContextSubst1( HB_ContextSubstFormat1* csf1 )
{
  HB_UShort        n, count;

  HB_SubRuleSet*  srs;


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

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

    FREE( srs );
  }

  _HB_OPEN_Free_Coverage( &csf1->Coverage );
}


/* SubClassRule */

static HB_Error  Load_SubClassRule( HB_ContextSubstFormat2*  csf2,
				    HB_SubClassRule*         scr,
				    HB_Stream                 stream )
{
  HB_Error error;

  HB_UShort               n, count;

  HB_UShort*              c;
  HB_SubstLookupRecord*  slr;


  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, HB_UShort ) )
    return error;

  c = scr->Class;

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

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

  FORGET_Frame();

  scr->SubstLookupRecord = NULL;

  count = scr->SubstCount;

  if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, HB_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 HB_Err_Ok;

Fail1:
  FREE( slr );

Fail2:
  FREE( c );
  return error;
}


static void  Free_SubClassRule( HB_SubClassRule*  scr )
{
  FREE( scr->SubstLookupRecord );
  FREE( scr->Class );
}


/* SubClassSet */

static HB_Error  Load_SubClassSet( HB_ContextSubstFormat2*  csf2,
				   HB_SubClassSet*          scs,
				   HB_Stream                 stream )
{
  HB_Error error;

  HB_UShort          n = 0, m, count;
  HB_UInt           cur_offset, new_offset, base_offset;

  HB_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, HB_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 ) ) != HB_Err_Ok )
      goto Fail;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( scr );
  return error;
}


static void  Free_SubClassSet( HB_SubClassSet*  scs )
{
  HB_UShort          n, count;

  HB_SubClassRule*  scr;


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

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

    FREE( scr );
  }
}


/* ContextSubstFormat2 */

static HB_Error  Load_ContextSubst2( HB_ContextSubstFormat2*  csf2,
				     HB_Stream                 stream )
{
  HB_Error error;

  HB_UShort         n = 0, m, count;
  HB_UInt          cur_offset, new_offset, base_offset;

  HB_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 = _HB_OPEN_Load_Coverage( &csf2->Coverage, stream ) ) != HB_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 = _HB_OPEN_Load_ClassDefinition( &csf2->ClassDef, count,
				       stream ) ) != HB_Err_Ok )
    goto Fail3;
  (void)FILE_Seek( cur_offset );

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

  if ( ALLOC_ARRAY( csf2->SubClassSet, count, HB_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 ) ) != HB_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 HB_Err_Ok;

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

  FREE( scs );

Fail2:
  _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef );

Fail3:
  _HB_OPEN_Free_Coverage( &csf2->Coverage );
  return error;
}


static void  Free_ContextSubst2( HB_ContextSubstFormat2*  csf2 )
{
  HB_UShort         n, count;

  HB_SubClassSet*  scs;


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

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

    FREE( scs );
  }

  _HB_OPEN_Free_ClassDefinition( &csf2->ClassDef );
  _HB_OPEN_Free_Coverage( &csf2->Coverage );
}


/* ContextSubstFormat3 */

static HB_Error  Load_ContextSubst3( HB_ContextSubstFormat3*  csf3,
				     HB_Stream                 stream )
{
  HB_Error error;

  HB_UShort               n = 0, m, count;
  HB_UInt                cur_offset, new_offset, base_offset;

  HB_Coverage*           c;
  HB_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, HB_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 = _HB_OPEN_Load_Coverage( &c[n], stream ) ) != HB_Err_Ok )
      goto Fail2;
    (void)FILE_Seek( cur_offset );
  }

  csf3->SubstLookupRecord = NULL;

  count = csf3->SubstCount;

  if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count,
		    HB_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 HB_Err_Ok;

Fail1:
  FREE( slr );

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

  FREE( c );
  return error;
}


static void  Free_ContextSubst3( HB_ContextSubstFormat3*  csf3 )
{
  HB_UShort      n, count;

  HB_Coverage*  c;


  FREE( csf3->SubstLookupRecord );

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

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

    FREE( c );
  }
}


/* ContextSubst */

static HB_Error  Load_ContextSubst( HB_GSUB_SubTable* st,
				    HB_Stream         stream )
{
  HB_Error error;
  HB_ContextSubst*  cs = &st->context;


  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 ERR(HB_Err_Invalid_SubTable_Format);
  }

  return HB_Err_Ok;               /* never reached */
}


static void  Free_ContextSubst( HB_GSUB_SubTable* st )
{
  HB_ContextSubst*  cs = &st->context;

  switch ( cs->SubstFormat )
  {
  case 1:  Free_ContextSubst1( &cs->csf.csf1 ); break;
  case 2:  Free_ContextSubst2( &cs->csf.csf2 ); break;
  case 3:  Free_ContextSubst3( &cs->csf.csf3 ); break;
  default:						break;
  }
}


static HB_Error  Lookup_ContextSubst1( HB_GSUBHeader*          gsub,
				       HB_ContextSubstFormat1* csf1,
				       HB_Buffer               buffer,
				       HB_UShort                flags,
				       HB_UShort                context_length,
				       int                      nesting_level )
{
  HB_UShort        index, property;
  HB_UShort        i, j, k, numsr;
  HB_Error         error;

  HB_SubRule*     sr;
  HB_GDEFHeader*  gdef;


  gdef = gsub->gdef;

  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
    return error;

  error = _HB_OPEN_Coverage_Index( &csf1->Coverage, IN_CURGLYPH(), &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 )
      goto next_subrule;

    if ( buffer->in_pos + sr[k].GlyphCount > buffer->in_length )
      goto next_subrule;                        /* context is too long */

    for ( i = 1, j = buffer->in_pos + 1; i < sr[k].GlyphCount; i++, j++ )
    {
      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
      {
	if ( error && error != HB_Err_Not_Covered )
	  return error;

	if ( j + sr[k].GlyphCount - i == (HB_Int)buffer->in_length )
	  goto next_subrule;
	j++;
      }

      if ( IN_GLYPH( j ) != sr[k].Input[i - 1] )
	goto next_subrule;
    }

    return Do_ContextSubst( gsub, sr[k].GlyphCount,
			    sr[k].SubstCount, sr[k].SubstLookupRecord,
			    buffer,
			    nesting_level );
  next_subrule:
    ;
  }

  return HB_Err_Not_Covered;
}


static HB_Error  Lookup_ContextSubst2( HB_GSUBHeader*          gsub,
				       HB_ContextSubstFormat2* csf2,
				       HB_Buffer               buffer,
				       HB_UShort                flags,
				       HB_UShort                context_length,
				       int                      nesting_level )
{
  HB_UShort          index, property;
  HB_Error           error;
  HB_UShort          i, j, k, known_classes;

  HB_UShort*         classes;
  HB_UShort*         cl;

  HB_SubClassSet*   scs;
  HB_SubClassRule*  sr;
  HB_GDEFHeader*    gdef;


  gdef = gsub->gdef;

  if ( CHECK_Property( gdef, IN_CURITEM(), 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 = _HB_OPEN_Coverage_Index( &csf2->Coverage, IN_CURGLYPH(), &index );
  if ( error )
    return error;

  if (csf2->MaxContextLength < 1)
    return HB_Err_Not_Covered;

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

  error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_CURGLYPH(),
		     &classes[0], NULL );
  if ( error && error != HB_Err_Not_Covered )
    goto End;
  known_classes = 0;

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

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

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

    if ( buffer->in_pos + sr->GlyphCount > buffer->in_length )
      goto next_subclassrule;                      /* context is too long */

    cl   = sr->Class;

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

    for ( i = 1, j = buffer->in_pos + 1; i < sr->GlyphCount; i++, j++ )
    {
      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
      {
	if ( error && error != HB_Err_Not_Covered )
	  goto End;

	if ( j + sr->GlyphCount - i < (HB_Int)buffer->in_length )
	  goto next_subclassrule;
	j++;
      }

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

	error = _HB_OPEN_Get_Class( &csf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL );
	if ( error && error != HB_Err_Not_Covered )
	  goto End;
	known_classes = i;
      }

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

    error = Do_ContextSubst( gsub, sr->GlyphCount,
			     sr->SubstCount, sr->SubstLookupRecord,
			     buffer,
			     nesting_level );
    goto End;

  next_subclassrule:
    ;
  }

  error = HB_Err_Not_Covered;

End:
  FREE( classes );
  return error;
}


static HB_Error  Lookup_ContextSubst3( HB_GSUBHeader*          gsub,
				       HB_ContextSubstFormat3* csf3,
				       HB_Buffer               buffer,
				       HB_UShort                flags,
				       HB_UShort                context_length,
				       int                      nesting_level )
{
  HB_Error         error;
  HB_UShort        index, i, j, property;

  HB_Coverage*    c;
  HB_GDEFHeader*  gdef;


  gdef = gsub->gdef;

  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
    return error;

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

  if ( buffer->in_pos + csf3->GlyphCount > buffer->in_length )
    return HB_Err_Not_Covered;         /* context is too long */

  c    = csf3->Coverage;

  for ( i = 1, j = buffer->in_pos + 1; i < csf3->GlyphCount; i++, j++ )
  {
    while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
    {
      if ( error && error != HB_Err_Not_Covered )
	return error;

      if ( j + csf3->GlyphCount - i == (HB_Int)buffer->in_length )
	return HB_Err_Not_Covered;
      j++;
    }

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

  return Do_ContextSubst( gsub, csf3->GlyphCount,
			  csf3->SubstCount, csf3->SubstLookupRecord,
			  buffer,
			  nesting_level );
}


static HB_Error  Lookup_ContextSubst( HB_GSUBHeader*    gsub,
				      HB_GSUB_SubTable* st,
				      HB_Buffer         buffer,
				      HB_UShort          flags,
				      HB_UShort          context_length,
				      int                nesting_level )
{
  HB_ContextSubst*  cs = &st->context;

  switch ( cs->SubstFormat )
  {
  case 1:  return Lookup_ContextSubst1( gsub, &cs->csf.csf1, buffer, flags, context_length, nesting_level );
  case 2:  return Lookup_ContextSubst2( gsub, &cs->csf.csf2, buffer, flags, context_length, nesting_level );
  case 3:  return Lookup_ContextSubst3( gsub, &cs->csf.csf3, buffer, flags, context_length, nesting_level );
  default: return ERR(HB_Err_Invalid_SubTable_Format);
  }

  return HB_Err_Ok;               /* never reached */
}


/* LookupType 6 */

/* ChainSubRule */

static HB_Error  Load_ChainSubRule( HB_ChainSubRule*  csr,
				    HB_Stream          stream )
{
  HB_Error error;

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

  HB_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, HB_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, HB_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, HB_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, HB_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 HB_Err_Ok;

Fail1:
  FREE( slr );

Fail2:
  FREE( l );

Fail3:
  FREE( i );

Fail4:
  FREE( b );
  return error;
}


static void  Free_ChainSubRule( HB_ChainSubRule*  csr )
{
  FREE( csr->SubstLookupRecord );
  FREE( csr->Lookahead );
  FREE( csr->Input );
  FREE( csr->Backtrack );
}


/* ChainSubRuleSet */

static HB_Error  Load_ChainSubRuleSet( HB_ChainSubRuleSet*  csrs,
				       HB_Stream             stream )
{
  HB_Error error;

  HB_UShort          n = 0, m, count;
  HB_UInt           cur_offset, new_offset, base_offset;

  HB_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, HB_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 ) ) != HB_Err_Ok )
      goto Fail;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( csr );
  return error;
}


static void  Free_ChainSubRuleSet( HB_ChainSubRuleSet*  csrs )
{
  HB_UShort          n, count;

  HB_ChainSubRule*  csr;


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

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

    FREE( csr );
  }
}


/* ChainContextSubstFormat1 */

static HB_Error  Load_ChainContextSubst1(
		   HB_ChainContextSubstFormat1*  ccsf1,
		   HB_Stream                      stream )
{
  HB_Error error;

  HB_UShort             n = 0, m, count;
  HB_UInt              cur_offset, new_offset, base_offset;

  HB_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 = _HB_OPEN_Load_Coverage( &ccsf1->Coverage, stream ) ) != HB_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, HB_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 ) ) != HB_Err_Ok )
      goto Fail1;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( csrs );

Fail2:
  _HB_OPEN_Free_Coverage( &ccsf1->Coverage );
  return error;
}


static void  Free_ChainContextSubst1( HB_ChainContextSubstFormat1*  ccsf1 )
{
  HB_UShort             n, count;

  HB_ChainSubRuleSet*  csrs;


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

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

    FREE( csrs );
  }

  _HB_OPEN_Free_Coverage( &ccsf1->Coverage );
}


/* ChainSubClassRule */

static HB_Error  Load_ChainSubClassRule(
		   HB_ChainContextSubstFormat2*  ccsf2,
		   HB_ChainSubClassRule*         cscr,
		   HB_Stream                      stream )
{
  HB_Error error;

  HB_UShort               n, count;

  HB_UShort*              b;
  HB_UShort*              i;
  HB_UShort*              l;
  HB_SubstLookupRecord*  slr;


  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, HB_UShort ) )
    return error;

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

  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, HB_UShort ) )
    goto Fail4;

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

  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, HB_UShort ) )
    goto Fail3;

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

  cscr->SubstCount = GET_UShort();

  FORGET_Frame();

  cscr->SubstLookupRecord = NULL;

  count = cscr->SubstCount;

  if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count,
		    HB_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 HB_Err_Ok;

Fail1:
  FREE( slr );

Fail2:
  FREE( l );

Fail3:
  FREE( i );

Fail4:
  FREE( b );
  return error;
}


static void  Free_ChainSubClassRule( HB_ChainSubClassRule*  cscr )
{
  FREE( cscr->SubstLookupRecord );
  FREE( cscr->Lookahead );
  FREE( cscr->Input );
  FREE( cscr->Backtrack );
}


/* SubClassSet */

static HB_Error  Load_ChainSubClassSet(
		   HB_ChainContextSubstFormat2*  ccsf2,
		   HB_ChainSubClassSet*          cscs,
		   HB_Stream                      stream )
{
  HB_Error error;

  HB_UShort               n = 0, m, count;
  HB_UInt                cur_offset, new_offset, base_offset;

  HB_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,
		    HB_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 ) ) != HB_Err_Ok )
      goto Fail;
    (void)FILE_Seek( cur_offset );
  }

  return HB_Err_Ok;

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

  FREE( cscr );
  return error;
}


static void  Free_ChainSubClassSet( HB_ChainSubClassSet*  cscs )
{
  HB_UShort               n, count;

  HB_ChainSubClassRule*  cscr;


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

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

    FREE( cscr );
  }
}


/* ChainContextSubstFormat2 */

static HB_Error  Load_ChainContextSubst2(
		   HB_ChainContextSubstFormat2*  ccsf2,
		   HB_Stream                      stream )
{
  HB_Error error;

  HB_UShort              n = 0, m, count;
  HB_UInt               cur_offset, new_offset, base_offset;
  HB_UInt               backtrack_offset, input_offset, lookahead_offset;

  HB_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 = _HB_OPEN_Load_Coverage( &ccsf2->Coverage, stream ) ) != HB_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 = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, 65535,
						       backtrack_offset, base_offset,
						       stream ) ) != HB_Err_Ok )
      goto Fail5;

  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count,
						       input_offset, base_offset,
						       stream ) ) != HB_Err_Ok )
      goto Fail4;
  if ( ( error = _HB_OPEN_Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, 65535,
						       lookahead_offset, base_offset,
						       stream ) ) != HB_Err_Ok )
    goto Fail3;

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

  if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, HB_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 ) ) != HB_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 HB_Err_Ok;

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

  FREE( cscs );

Fail2:
  _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef );

Fail3:
  _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef );

Fail4:
  _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef );

Fail5:
  _HB_OPEN_Free_Coverage( &ccsf2->Coverage );
  return error;
}


static void  Free_ChainContextSubst2( HB_ChainContextSubstFormat2*  ccsf2 )
{
  HB_UShort              n, count;

  HB_ChainSubClassSet*  cscs;


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

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

    FREE( cscs );
  }

  _HB_OPEN_Free_ClassDefinition( &ccsf2->LookaheadClassDef );
  _HB_OPEN_Free_ClassDefinition( &ccsf2->InputClassDef );
  _HB_OPEN_Free_ClassDefinition( &ccsf2->BacktrackClassDef );

  _HB_OPEN_Free_Coverage( &ccsf2->Coverage );
}


/* ChainContextSubstFormat3 */

static HB_Error  Load_ChainContextSubst3(
		   HB_ChainContextSubstFormat3*  ccsf3,
		   HB_Stream                      stream )
{
  HB_Error error;

  HB_UShort               n, nb = 0, ni =0, nl = 0, m, count;
  HB_UShort               backtrack_count, input_count, lookahead_count;
  HB_UInt                cur_offset, new_offset, base_offset;

  HB_Coverage*           b;
  HB_Coverage*           i;
  HB_Coverage*           l;
  HB_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,
		    HB_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 = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_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, HB_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 = _HB_OPEN_Load_Coverage( &i[ni], stream ) ) != HB_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,
		    HB_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 = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_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,
		    HB_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 HB_Err_Ok;

Fail1:
  FREE( slr );

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

  FREE( l );

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

  FREE( i );

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

  FREE( b );
  return error;
}


static void  Free_ChainContextSubst3( HB_ChainContextSubstFormat3*  ccsf3 )
{
  HB_UShort      n, count;

  HB_Coverage*  c;


  FREE( ccsf3->SubstLookupRecord );

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

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

    FREE( c );
  }

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

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

    FREE( c );
  }

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

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

    FREE( c );
  }
}


/* ChainContextSubst */

static HB_Error  Load_ChainContextSubst( HB_GSUB_SubTable* st,
					 HB_Stream         stream )
{
  HB_Error error;
  HB_ChainContextSubst*  ccs = &st->chain;

  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 ERR(HB_Err_Invalid_SubTable_Format);
  }

  return HB_Err_Ok;               /* never reached */
}


static void  Free_ChainContextSubst( HB_GSUB_SubTable* st )
{
  HB_ChainContextSubst*  ccs = &st->chain;

  switch ( ccs->SubstFormat ) {
    case 1:  Free_ChainContextSubst1( &ccs->ccsf.ccsf1 ); break;
    case 2:  Free_ChainContextSubst2( &ccs->ccsf.ccsf2 ); break;
    case 3:  Free_ChainContextSubst3( &ccs->ccsf.ccsf3 ); break;
    default:							  break;
  }
}


static HB_Error  Lookup_ChainContextSubst1( HB_GSUBHeader*               gsub,
					    HB_ChainContextSubstFormat1* ccsf1,
					    HB_Buffer                    buffer,
					    HB_UShort                     flags,
					    HB_UShort                     context_length,
					    int                           nesting_level )
{
  HB_UShort          index, property;
  HB_UShort          i, j, k, num_csr;
  HB_UShort          bgc, igc, lgc;
  HB_Error           error;

  HB_ChainSubRule*  csr;
  HB_ChainSubRule   curr_csr;
  HB_GDEFHeader*    gdef;


  gdef = gsub->gdef;

  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
    return error;

  error = _HB_OPEN_Coverage_Index( &ccsf1->Coverage, IN_CURGLYPH(), &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 )
      goto next_chainsubrule;

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

    if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
      goto next_chainsubrule;

    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    */

      for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
      {
	while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
	{
	  if ( error && error != HB_Err_Not_Covered )
	    return error;

	  if ( j + 1 == bgc - i )
	    goto next_chainsubrule;
	  j--;
	}

	/* 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 ( OUT_GLYPH( j ) != curr_csr.Backtrack[i] )
	  goto next_chainsubrule;
      }
    }

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

    for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
    {
      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
      {
	if ( error && error != HB_Err_Not_Covered )
	  return error;

	if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
	  goto next_chainsubrule;
	j++;
      }

      if ( IN_GLYPH( j ) != curr_csr.Input[i - 1] )
	  goto next_chainsubrule;
    }

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

    for ( i = 0; i < lgc; i++, j++ )
    {
      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
      {
	if ( error && error != HB_Err_Not_Covered )
	  return error;

	if ( j + lgc - i == (HB_Int)buffer->in_length )
	  goto next_chainsubrule;
	j++;
      }

      if ( IN_GLYPH( j ) != curr_csr.Lookahead[i] )
	goto next_chainsubrule;
    }

    return Do_ContextSubst( gsub, igc,
			    curr_csr.SubstCount,
			    curr_csr.SubstLookupRecord,
			    buffer,
			    nesting_level );

  next_chainsubrule:
    ;
  }

  return HB_Err_Not_Covered;
}


static HB_Error  Lookup_ChainContextSubst2( HB_GSUBHeader*               gsub,
					    HB_ChainContextSubstFormat2* ccsf2,
					    HB_Buffer                    buffer,
					    HB_UShort                     flags,
					    HB_UShort                     context_length,
					    int                           nesting_level )
{
  HB_UShort              index, property;
  HB_Error               error;
  HB_UShort              i, j, k;
  HB_UShort              bgc, igc, lgc;
  HB_UShort              known_backtrack_classes,
			 known_input_classes,
			 known_lookahead_classes;

  HB_UShort*             backtrack_classes;
  HB_UShort*             input_classes;
  HB_UShort*             lookahead_classes;

  HB_UShort*             bc;
  HB_UShort*             ic;
  HB_UShort*             lc;

  HB_ChainSubClassSet*  cscs;
  HB_ChainSubClassRule  ccsr;
  HB_GDEFHeader*        gdef;


  gdef = gsub->gdef;

  if ( CHECK_Property( gdef, IN_CURITEM(), 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 = _HB_OPEN_Coverage_Index( &ccsf2->Coverage, IN_CURGLYPH(), &index );
  if ( error )
    return error;

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

  if (ccsf2->MaxInputLength < 1)
    return HB_Err_Not_Covered;

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

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

  error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_CURGLYPH(),
		     &input_classes[0], NULL );
  if ( error && error != HB_Err_Not_Covered )
    goto End1;

  cscs = &ccsf2->ChainSubClassSet[input_classes[0]];
  if ( !cscs )
  {
    error = ERR(HB_Err_Invalid_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 )
      goto next_chainsubclassrule;

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

    if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
      goto next_chainsubclassrule;

    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.         */

      bc       = ccsr.Backtrack;

      for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
      {
	while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
	{
	  if ( error && error != HB_Err_Not_Covered )
	    goto End1;

	  if ( j + 1 == bgc - i )
	    goto next_chainsubclassrule;
	  j--;
	}

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

	  error = _HB_OPEN_Get_Class( &ccsf2->BacktrackClassDef, OUT_GLYPH( j ),
			     &backtrack_classes[i], NULL );
	  if ( error && error != HB_Err_Not_Covered )
	    goto End1;
	  known_backtrack_classes = i;
	}

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

    ic       = ccsr.Input;

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

    for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
    {
      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
      {
	if ( error && error != HB_Err_Not_Covered )
	  goto End1;

	if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
	  goto next_chainsubclassrule;
	j++;
      }

      if ( i >= known_input_classes )
      {
	error = _HB_OPEN_Get_Class( &ccsf2->InputClassDef, IN_GLYPH( j ),
			   &input_classes[i], NULL );
	if ( error && error != HB_Err_Not_Covered )
	  goto End1;
	known_input_classes = i;
      }

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

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

    lc       = ccsr.Lookahead;

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

	if ( j + lgc - i == (HB_Int)buffer->in_length )
	  goto next_chainsubclassrule;
	j++;
      }

      if ( i >= known_lookahead_classes )
      {
	error = _HB_OPEN_Get_Class( &ccsf2->LookaheadClassDef, IN_GLYPH( j ),
			   &lookahead_classes[i], NULL );
	if ( error && error != HB_Err_Not_Covered )
	  goto End1;
	known_lookahead_classes = i;
      }

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

    error = Do_ContextSubst( gsub, igc,
			     ccsr.SubstCount,
			     ccsr.SubstLookupRecord,
			     buffer,
			     nesting_level );
    goto End1;

  next_chainsubclassrule:
    ;
  }

  error = HB_Err_Not_Covered;

End1:
  FREE( lookahead_classes );

End2:
  FREE( input_classes );

End3:
  FREE( backtrack_classes );
  return error;
}


static HB_Error  Lookup_ChainContextSubst3( HB_GSUBHeader*               gsub,
					    HB_ChainContextSubstFormat3* ccsf3,
					    HB_Buffer                    buffer,
					    HB_UShort                     flags,
					    HB_UShort                     context_length,
					    int                           nesting_level )
{
  HB_UShort        index, i, j, property;
  HB_UShort        bgc, igc, lgc;
  HB_Error         error;

  HB_Coverage*    bc;
  HB_Coverage*    ic;
  HB_Coverage*    lc;
  HB_GDEFHeader*  gdef;


  gdef = gsub->gdef;

  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
    return error;

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

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

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

  if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
    return HB_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    */

    bc       = ccsf3->BacktrackCoverage;

    for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
    {
      while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
      {
	if ( error && error != HB_Err_Not_Covered )
	  return error;

	if ( j + 1 == bgc - i )
	  return HB_Err_Not_Covered;
	j--;
      }

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

  ic       = ccsf3->InputCoverage;

  for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ )
  {
    /* We already called CHECK_Property for IN_GLYPH( buffer->in_pos ) */
    while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
    {
      if ( error && error != HB_Err_Not_Covered )
	return error;

      if ( j + igc - i + lgc == (HB_Int)buffer->in_length )
	return HB_Err_Not_Covered;
      j++;
    }

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

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

  lc       = ccsf3->LookaheadCoverage;

  for ( i = 0; i < lgc; i++, j++ )
  {
    while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
    {
      if ( error && error != HB_Err_Not_Covered )
	return error;

      if ( j + lgc - i == (HB_Int)buffer->in_length )
	return HB_Err_Not_Covered;
      j++;
    }

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

  return Do_ContextSubst( gsub, igc,
			  ccsf3->SubstCount,
			  ccsf3->SubstLookupRecord,
			  buffer,
			  nesting_level );
}


static HB_Error  Lookup_ChainContextSubst( HB_GSUBHeader*    gsub,
					   HB_GSUB_SubTable* st,
					   HB_Buffer         buffer,
					   HB_UShort          flags,
					   HB_UShort          context_length,
					   int                nesting_level )
{
  HB_ChainContextSubst*  ccs = &st->chain;

  switch ( ccs->SubstFormat ) {
    case 1:  return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, buffer, flags, context_length, nesting_level );
    case 2:  return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, buffer, flags, context_length, nesting_level );
    case 3:  return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, buffer, flags, context_length, nesting_level );
    default: return ERR(HB_Err_Invalid_SubTable_Format);
  }
}


static HB_Error  Load_ReverseChainContextSubst( HB_GSUB_SubTable* st,
					        HB_Stream         stream )
{
  HB_Error error;
  HB_ReverseChainContextSubst*  rccs = &st->reverse;

  HB_UShort               m, count;

  HB_UShort               nb = 0, nl = 0, n;
  HB_UShort               backtrack_count, lookahead_count;
  HB_UInt                cur_offset, new_offset, base_offset;

  HB_Coverage*           b;
  HB_Coverage*           l;
  HB_UShort*              sub;

  base_offset = FILE_Pos();

  if ( ACCESS_Frame( 2L ) )
    return error;

  rccs->SubstFormat = GET_UShort();

  if ( rccs->SubstFormat != 1 )
    return ERR(HB_Err_Invalid_SubTable_Format);

  FORGET_Frame();

  if ( ACCESS_Frame( 2L ) )
    return error;

  new_offset = GET_UShort() + base_offset;

  FORGET_Frame();

  cur_offset = FILE_Pos();
  if ( FILE_Seek( new_offset ) ||
       ( error = _HB_OPEN_Load_Coverage( &rccs->Coverage, stream ) ) != HB_Err_Ok )
    return error;
  (void)FILE_Seek( cur_offset );


  if ( ACCESS_Frame( 2L ) )
    goto Fail4;

  rccs->BacktrackGlyphCount = GET_UShort();

  FORGET_Frame();

  rccs->BacktrackCoverage = NULL;

  backtrack_count = rccs->BacktrackGlyphCount;

  if ( ALLOC_ARRAY( rccs->BacktrackCoverage, backtrack_count,
		    HB_Coverage ) )
    goto Fail4;

  b = rccs->BacktrackCoverage;

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

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

    cur_offset = FILE_Pos();
    if ( FILE_Seek( new_offset ) ||
	 ( error = _HB_OPEN_Load_Coverage( &b[nb], stream ) ) != HB_Err_Ok )
      goto Fail3;
    (void)FILE_Seek( cur_offset );
  }


  if ( ACCESS_Frame( 2L ) )
    goto Fail3;

  rccs->LookaheadGlyphCount = GET_UShort();

  FORGET_Frame();

  rccs->LookaheadCoverage = NULL;

  lookahead_count = rccs->LookaheadGlyphCount;

  if ( ALLOC_ARRAY( rccs->LookaheadCoverage, lookahead_count,
		    HB_Coverage ) )
    goto Fail3;

  l = rccs->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 = _HB_OPEN_Load_Coverage( &l[nl], stream ) ) != HB_Err_Ok )
      goto Fail2;
    (void)FILE_Seek( cur_offset );
  }

  if ( ACCESS_Frame( 2L ) )
    goto Fail2;

  rccs->GlyphCount = GET_UShort();

  FORGET_Frame();

  rccs->Substitute = NULL;

  count = rccs->GlyphCount;

  if ( ALLOC_ARRAY( rccs->Substitute, count,
		    HB_UShort ) )
    goto Fail2;

  sub = rccs->Substitute;

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

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

  FORGET_Frame();

  return HB_Err_Ok;

Fail1:
  FREE( sub );

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

  FREE( l );

Fail3:
  for ( m = 0; m < nb; m++ )
    _HB_OPEN_Free_Coverage( &b[m] );

  FREE( b );

Fail4:
  _HB_OPEN_Free_Coverage( &rccs->Coverage );
  return error;
}


static void  Free_ReverseChainContextSubst( HB_GSUB_SubTable* st )
{
  HB_UShort      n, count;
  HB_ReverseChainContextSubst*  rccs = &st->reverse;

  HB_Coverage*  c;

  _HB_OPEN_Free_Coverage( &rccs->Coverage );

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

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

    FREE( c );
  }

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

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

    FREE( c );
  }

  FREE ( rccs->Substitute );
}


static HB_Error  Lookup_ReverseChainContextSubst( HB_GSUBHeader*    gsub,
						  HB_GSUB_SubTable* st,
						  HB_Buffer         buffer,
						  HB_UShort          flags,
						  HB_UShort         context_length,
						  int               nesting_level )
{
  HB_UShort        index, input_index, i, j, property;
  HB_UShort        bgc, lgc;
  HB_Error         error;

  HB_ReverseChainContextSubst*  rccs = &st->reverse;
  HB_Coverage*    bc;
  HB_Coverage*    lc;
  HB_GDEFHeader*  gdef;

  if ( nesting_level != 1 || context_length != 0xFFFF )
    return HB_Err_Not_Covered;

  gdef = gsub->gdef;

  if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
    return error;

  bgc = rccs->BacktrackGlyphCount;
  lgc = rccs->LookaheadGlyphCount;

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

  if ( bgc > buffer->in_pos || buffer->in_pos + 1 + lgc > buffer->in_length )
    return HB_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    */

    bc       = rccs->BacktrackCoverage;

    for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
    {
      while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
      {
	if ( error && error != HB_Err_Not_Covered )
	  return error;

	if ( j + 1 == bgc - i )
	  return HB_Err_Not_Covered;
	j--;
      }

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

  j = buffer->in_pos;

  error = _HB_OPEN_Coverage_Index( &rccs->Coverage, IN_GLYPH( j ), &input_index );
  if ( error )
      return error;

  lc       = rccs->LookaheadCoverage;

  for ( i = 0, j = buffer->in_pos + 1; i < lgc; i++, j++ )
  {
    while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
    {
      if ( error && error != HB_Err_Not_Covered )
	return error;

      if ( j + lgc - i == (HB_Int)buffer->in_length )
	return HB_Err_Not_Covered;
      j++;
    }

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

  IN_CURGLYPH() = rccs->Substitute[input_index];
  buffer->in_pos--; /* Reverse! */

  return error;
}



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



HB_Error  HB_GSUB_Select_Script( HB_GSUBHeader*  gsub,
				 HB_UInt         script_tag,
				 HB_UShort*       script_index )
{
  HB_UShort          n;

  HB_ScriptList*    sl;
  HB_ScriptRecord*  sr;


  if ( !gsub || !script_index )
    return ERR(HB_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 HB_Err_Ok;
    }

  return HB_Err_Not_Covered;
}



HB_Error  HB_GSUB_Select_Language( HB_GSUBHeader*  gsub,
				   HB_UInt         language_tag,
				   HB_UShort        script_index,
				   HB_UShort*       language_index,
				   HB_UShort*       req_feature_index )
{
  HB_UShort           n;

  HB_ScriptList*     sl;
  HB_ScriptRecord*   sr;
  HB_ScriptTable*    s;
  HB_LangSysRecord*  lsr;


  if ( !gsub || !language_index || !req_feature_index )
    return ERR(HB_Err_Invalid_Argument);

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

  if ( script_index >= sl->ScriptCount )
    return ERR(HB_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 HB_Err_Ok;
    }

  return HB_Err_Not_Covered;
}


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


HB_Error  HB_GSUB_Select_Feature( HB_GSUBHeader*  gsub,
				  HB_UInt         feature_tag,
				  HB_UShort        script_index,
				  HB_UShort        language_index,
				  HB_UShort*       feature_index )
{
  HB_UShort           n;

  HB_ScriptList*     sl;
  HB_ScriptRecord*   sr;
  HB_ScriptTable*    s;
  HB_LangSysRecord*  lsr;
  HB_LangSys*        ls;
  HB_UShort*          fi;

  HB_FeatureList*    fl;
  HB_FeatureRecord*  fr;


  if ( !gsub || !feature_index )
    return ERR(HB_Err_Invalid_Argument);

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

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

  if ( script_index >= sl->ScriptCount )
    return ERR(HB_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 ERR(HB_Err_Invalid_Argument);

    ls = &lsr[language_index].LangSys;
  }

  fi = ls->FeatureIndex;

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

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

      return HB_Err_Ok;
    }
  }

  return HB_Err_Not_Covered;
}


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


HB_Error  HB_GSUB_Query_Scripts( HB_GSUBHeader*  gsub,
				 HB_UInt**       script_tag_list )
{
  HB_UShort          n;
  HB_Error           error;
  HB_UInt*          stl;

  HB_ScriptList*    sl;
  HB_ScriptRecord*  sr;


  if ( !gsub || !script_tag_list )
    return ERR(HB_Err_Invalid_Argument);

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

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

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

  *script_tag_list = stl;

  return HB_Err_Ok;
}



HB_Error  HB_GSUB_Query_Languages( HB_GSUBHeader*  gsub,
				   HB_UShort        script_index,
				   HB_UInt**       language_tag_list )
{
  HB_UShort           n;
  HB_Error            error;
  HB_UInt*           ltl;

  HB_ScriptList*     sl;
  HB_ScriptRecord*   sr;
  HB_ScriptTable*    s;
  HB_LangSysRecord*  lsr;


  if ( !gsub || !language_tag_list )
    return ERR(HB_Err_Invalid_Argument);

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

  if ( script_index >= sl->ScriptCount )
    return ERR(HB_Err_Invalid_Argument);

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

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

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

  *language_tag_list = ltl;

  return HB_Err_Ok;
}


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


HB_Error  HB_GSUB_Query_Features( HB_GSUBHeader*  gsub,
				  HB_UShort        script_index,
				  HB_UShort        language_index,
				  HB_UInt**       feature_tag_list )
{
  HB_UShort           n;
  HB_Error            error;
  HB_UInt*           ftl;

  HB_ScriptList*     sl;
  HB_ScriptRecord*   sr;
  HB_ScriptTable*    s;
  HB_LangSysRecord*  lsr;
  HB_LangSys*        ls;
  HB_UShort*          fi;

  HB_FeatureList*    fl;
  HB_FeatureRecord*  fr;


  if ( !gsub || !feature_tag_list )
    return ERR(HB_Err_Invalid_Argument);

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

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

  if ( script_index >= sl->ScriptCount )
    return ERR(HB_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 ERR(HB_Err_Invalid_Argument);

    ls = &lsr[language_index].LangSys;
  }

  fi = ls->FeatureIndex;

  if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, HB_UInt ) )
    return error;

  for ( n = 0; n < ls->FeatureCount; n++ )
  {
    if ( fi[n] >= fl->FeatureCount )
    {
      FREE( ftl );
      return ERR(HB_Err_Invalid_SubTable_Format);
    }
    ftl[n] = fr[fi[n]].FeatureTag;
  }
  ftl[n] = 0;

  *feature_tag_list = ftl;

  return HB_Err_Ok;
}


/* Do an individual subtable lookup.  Returns HB_Err_Ok if substitution
   has been done, or HB_Err_Not_Covered if not.                        */
static HB_Error  GSUB_Do_Glyph_Lookup( HB_GSUBHeader* gsub,
				       HB_UShort       lookup_index,
				       HB_Buffer      buffer,
				       HB_UShort       context_length,
				       int             nesting_level )
{
  HB_Error               error = HB_Err_Not_Covered;
  HB_UShort              i, flags, lookup_count;
  HB_Lookup*             lo;
  int                    lookup_type;

  nesting_level++;

  if ( nesting_level > HB_MAX_NESTING_LEVEL )
    return ERR(HB_Err_Not_Covered); /* ERR() call intended */

  lookup_count = gsub->LookupList.LookupCount;
  if (lookup_index >= lookup_count)
    return error;

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

  for ( i = 0; i < lo->SubTableCount; i++ )
  {
    HB_GSUB_SubTable *st = &lo->SubTable[i].st.gsub;

    switch (lookup_type) {
      case HB_GSUB_LOOKUP_SINGLE:
	error = Lookup_SingleSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
      case HB_GSUB_LOOKUP_MULTIPLE:
	error = Lookup_MultipleSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
      case HB_GSUB_LOOKUP_ALTERNATE:
	error = Lookup_AlternateSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
      case HB_GSUB_LOOKUP_LIGATURE:
	error = Lookup_LigatureSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
      case HB_GSUB_LOOKUP_CONTEXT:
	error = Lookup_ContextSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;
      case HB_GSUB_LOOKUP_CHAIN:
	error = Lookup_ChainContextSubst	( gsub, st, buffer, flags, context_length, nesting_level ); break;
    /*case HB_GSUB_LOOKUP_EXTENSION:
	error = Lookup_ExtensionSubst		( gsub, st, buffer, flags, context_length, nesting_level ); break;*/
      case HB_GSUB_LOOKUP_REVERSE_CHAIN:
	error = Lookup_ReverseChainContextSubst	( gsub, st, buffer, flags, context_length, nesting_level ); break;
      default:
	error = HB_Err_Not_Covered;
    };

    /* Check whether we have a successful substitution or an error other
       than HB_Err_Not_Covered                                          */
    if ( error != HB_Err_Not_Covered )
      return error;
  }

  return HB_Err_Not_Covered;
}


HB_INTERNAL HB_Error
_HB_GSUB_Load_SubTable( HB_GSUB_SubTable* st,
			HB_Stream         stream,
			HB_UShort         lookup_type )
{
  switch (lookup_type) {
    case HB_GSUB_LOOKUP_SINGLE:		return Load_SingleSubst			( st, stream );
    case HB_GSUB_LOOKUP_MULTIPLE:	return Load_MultipleSubst		( st, stream );
    case HB_GSUB_LOOKUP_ALTERNATE:	return Load_AlternateSubst		( st, stream );
    case HB_GSUB_LOOKUP_LIGATURE:	return Load_LigatureSubst		( st, stream );
    case HB_GSUB_LOOKUP_CONTEXT:	return Load_ContextSubst		( st, stream );
    case HB_GSUB_LOOKUP_CHAIN:		return Load_ChainContextSubst		( st, stream );
  /*case HB_GSUB_LOOKUP_EXTENSION:	return Load_ExtensionSubst		( st, stream );*/
    case HB_GSUB_LOOKUP_REVERSE_CHAIN:	return Load_ReverseChainContextSubst	( st, stream );
    default:				return ERR(HB_Err_Invalid_SubTable_Format);
  };
}


HB_INTERNAL void
_HB_GSUB_Free_SubTable( HB_GSUB_SubTable* st,
			HB_UShort         lookup_type )
{
  switch ( lookup_type ) {
    case HB_GSUB_LOOKUP_SINGLE:		Free_SingleSubst		( st ); return;
    case HB_GSUB_LOOKUP_MULTIPLE:	Free_MultipleSubst		( st ); return;
    case HB_GSUB_LOOKUP_ALTERNATE:	Free_AlternateSubst		( st ); return;
    case HB_GSUB_LOOKUP_LIGATURE:	Free_LigatureSubst		( st ); return;
    case HB_GSUB_LOOKUP_CONTEXT:	Free_ContextSubst		( st ); return;
    case HB_GSUB_LOOKUP_CHAIN:		Free_ChainContextSubst		( st ); return;
  /*case HB_GSUB_LOOKUP_EXTENSION:	Free_ExtensionSubst		( st ); return;*/
    case HB_GSUB_LOOKUP_REVERSE_CHAIN:	Free_ReverseChainContextSubst	( st ); return;
    default:									return;
  };
}



/* apply one lookup to the input string object */

static HB_Error  GSUB_Do_String_Lookup( HB_GSUBHeader*   gsub,
				   HB_UShort         lookup_index,
				   HB_Buffer        buffer )
{
  HB_Error  error, retError = HB_Err_Not_Covered;

  HB_UInt*  properties = gsub->LookupList.Properties;
  int       lookup_type = gsub->LookupList.Lookup[lookup_index].LookupType;

  const int       nesting_level = 0;
  /* 0xFFFF indicates that we don't have a context length yet */
  const HB_UShort context_length = 0xFFFF;

  switch (lookup_type) {

    case HB_GSUB_LOOKUP_SINGLE:
    case HB_GSUB_LOOKUP_MULTIPLE:
    case HB_GSUB_LOOKUP_ALTERNATE:
    case HB_GSUB_LOOKUP_LIGATURE:
    case HB_GSUB_LOOKUP_CONTEXT:
    case HB_GSUB_LOOKUP_CHAIN:
      /* in/out forward substitution (implemented lazy) */

      _hb_buffer_clear_output ( buffer );
      buffer->in_pos = 0;
  while ( buffer->in_pos < buffer->in_length )
  {
    if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
    {
	  error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level );
      if ( error )
      {
	if ( error != HB_Err_Not_Covered )
	  return error;
      }
      else
	retError = error;
    }
    else
      error = HB_Err_Not_Covered;

    if ( error == HB_Err_Not_Covered )
	  if ( COPY_Glyph ( buffer ) )
	return error;
  }
      /* we shouldn't swap if error occurred.
       *
       * also don't swap if nothing changed (ie HB_Err_Not_Covered).
       * shouldn't matter in that case though.
       */
      if ( retError == HB_Err_Ok )
	_hb_buffer_swap( buffer );

  return retError;

    case HB_GSUB_LOOKUP_REVERSE_CHAIN:
      /* in-place backward substitution */

      buffer->in_pos = buffer->in_length - 1;
    do
    {
      if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
	{
	  error = GSUB_Do_Glyph_Lookup( gsub, lookup_index, buffer, context_length, nesting_level );
	  if ( error )
	    {
	      if ( error != HB_Err_Not_Covered )
		return error;
	    }
	  else
	    retError = error;
	}
	else
	  error = HB_Err_Not_Covered;

	if ( error == HB_Err_Not_Covered )
	  buffer->in_pos--;
      }
      while ((HB_Int) buffer->in_pos >= 0);

      return retError;

  /*case HB_GSUB_LOOKUP_EXTENSION:*/
    default:
  return retError;
  };
}


HB_Error  HB_GSUB_Add_Feature( HB_GSUBHeader*  gsub,
			       HB_UShort        feature_index,
			       HB_UInt          property )
{
  HB_UShort    i;

  HB_Feature  feature;
  HB_UInt*     properties;
  HB_UShort*   index;
  HB_UShort    lookup_count;

  /* Each feature can only be added once */

  if ( !gsub ||
       feature_index >= gsub->FeatureList.FeatureCount ||
       gsub->FeatureList.ApplyCount == gsub->FeatureList.FeatureCount )
    return ERR(HB_Err_Invalid_Argument);

  gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index;

  properties = gsub->LookupList.Properties;

  feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
  index   = feature.LookupListIndex;
  lookup_count = gsub->LookupList.LookupCount;

  for ( i = 0; i < feature.LookupListCount; i++ )
  {
    HB_UShort lookup_index = index[i];
    if (lookup_index < lookup_count)
      properties[lookup_index] |= property;
  }

  return HB_Err_Ok;
}



HB_Error  HB_GSUB_Clear_Features( HB_GSUBHeader*  gsub )
{
  HB_UShort i;

  HB_UInt*  properties;


  if ( !gsub )
    return ERR(HB_Err_Invalid_Argument);

  gsub->FeatureList.ApplyCount = 0;

  properties = gsub->LookupList.Properties;

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

  return HB_Err_Ok;
}



HB_Error  HB_GSUB_Register_Alternate_Function( HB_GSUBHeader*  gsub,
					       HB_AltFunction  altfunc,
					       void*            data )
{
  if ( !gsub )
    return ERR(HB_Err_Invalid_Argument);

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

  return HB_Err_Ok;
}

/* returns error if one happened, otherwise returns HB_Err_Not_Covered if no
 * feature were applied, or HB_Err_Ok otherwise.
 */
HB_Error  HB_GSUB_Apply_String( HB_GSUBHeader*   gsub,
				HB_Buffer        buffer )
{
  HB_Error          error, retError = HB_Err_Not_Covered;
  int               i, j, lookup_count, num_features;

  if ( !gsub ||
       !buffer)
    return ERR(HB_Err_Invalid_Argument);

  if ( buffer->in_length == 0 )
    return retError;

  lookup_count = gsub->LookupList.LookupCount;
  num_features = gsub->FeatureList.ApplyCount;

  for ( i = 0; i < num_features; i++)
  {
    HB_UShort  feature_index = gsub->FeatureList.ApplyOrder[i];
    HB_Feature feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;

    for ( j = 0; j < feature.LookupListCount; j++ )
    {
      HB_UShort         lookup_index = feature.LookupListIndex[j];

      /* Skip nonexistant lookups */
      if (lookup_index >= lookup_count)
       continue;

	error = GSUB_Do_String_Lookup( gsub, lookup_index, buffer );
      if ( error )
      {
	if ( error != HB_Err_Not_Covered )
	  return error;
      }
      else
	retError = error;
    }
  }

  error = retError;

  return error;
}


/* END */
