/*******************************************************************
 *
 *  ftxgdef.c
 *
 *    TrueType Open GDEF table support.
 *
 *  Copyright 1996-2000 by
 *  David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 *  This file is part of the FreeType project, and may only be used
 *  modified and distributed under the terms of the FreeType project
 *  license, LICENSE.TXT.  By continuing to use, modify, or distribute
 *  this file you indicate that you have read the license and
 *  understand and accept it fully.
 *
 ******************************************************************/

#include <freetype/tttags.h>

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

#include "fterrcompat.h"

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

#define TTAG_GDEF  FT_MAKE_TAG( 'G', 'D', 'E', 'F' )

  static FT_Error  Load_AttachList( TTO_AttachList*  al,
                                    FT_Stream        stream );
  static FT_Error  Load_LigCaretList( TTO_LigCaretList*  lcl,
                                      FT_Stream          stream );

  static void  Free_AttachList( TTO_AttachList*  al,
				FT_Memory        memory );
  static void  Free_LigCaretList( TTO_LigCaretList*  lcl,
				  FT_Memory          memory );

  static void  Free_NewGlyphClasses( TTO_GDEFHeader*  gdef,
				     FT_Memory        memory );



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

#if 0
#define GDEF_ID  Build_Extension_ID( 'G', 'D', 'E', 'F' )


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

    TTO_GDEFHeader*  gdef = (TTO_GDEFHeader*)ext;
    Long             table;


    /* by convention */

    if ( !gdef )
      return TT_Err_Ok;

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

    gdef->offset = 0;

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

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

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

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

    FORGET_Frame();

    gdef->loaded = FALSE;

    return TT_Err_Ok;
  }


  static FT_Error  GDEF_Destroy( void*  ext,
                                 PFace  face )
  {
    TTO_GDEFHeader*  gdef = (TTO_GDEFHeader*)ext;


    /* by convention */

    if ( !gdef )
      return TT_Err_Ok;

    if ( gdef->loaded )
    {
      Free_LigCaretList( &gdef->LigCaretList, memory );
      Free_AttachList( &gdef->AttachList, memory );
      Free_ClassDefinition( &gdef->GlyphClassDef, memory );
      Free_ClassDefinition( &gdef->MarkAttachClassDef, memory );

      Free_NewGlyphClasses( gdef, memory );
    }

    return TT_Err_Ok;
  }


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


    if ( !_engine )
      return TT_Err_Invalid_Engine;

    return  TT_Register_Extension( _engine,
                                   GDEF_ID,
                                   sizeof ( TTO_GDEFHeader ),
                                   GDEF_Create,
                                   GDEF_Destroy );
  }
#endif

  EXPORT_FUNC
  FT_Error  TT_New_GDEF_Table( FT_Face          face,
			       TTO_GDEFHeader** retptr )
  {
    FT_Error         error;
    FT_Memory        memory = face->memory;

    TTO_GDEFHeader*  gdef;

    if ( !retptr )
      return TT_Err_Invalid_Argument;

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

    gdef->memory = face->memory;

    gdef->GlyphClassDef.loaded = FALSE;
    gdef->AttachList.loaded = FALSE;
    gdef->LigCaretList.loaded = FALSE;
    gdef->MarkAttachClassDef_offset = 0;
    gdef->MarkAttachClassDef.loaded = FALSE;

    gdef->LastGlyph = 0;
    gdef->NewGlyphClasses = NULL;

    *retptr = gdef;

    return TT_Err_Ok;
  }

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

    TTO_GDEFHeader*  gdef;


    if ( !retptr )
      return TT_Err_Invalid_Argument;

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

    if (( error = TT_New_GDEF_Table ( face, &gdef ) ))
      return error;

    base_offset = FILE_Pos();

    /* skip version */

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

    new_offset = GET_UShort();

    FORGET_Frame();

    /* all GDEF subtables are optional */

    if ( new_offset )
    {
      new_offset += base_offset;

      /* only classes 1-4 are allowed here */

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_ClassDefinition( &gdef->GlyphClassDef, 5,
                                           stream ) ) != TT_Err_Ok )
        goto Fail0;
      (void)FILE_Seek( cur_offset );
    }

    if ( ACCESS_Frame( 2L ) )
      goto Fail1;

    new_offset = GET_UShort();

    FORGET_Frame();

    if ( new_offset )
    {
      new_offset += base_offset;

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_AttachList( &gdef->AttachList,
                                      stream ) ) != TT_Err_Ok )
        goto Fail1;
      (void)FILE_Seek( cur_offset );
    }

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    new_offset = GET_UShort();

    FORGET_Frame();

    if ( new_offset )
    {
      new_offset += base_offset;

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_LigCaretList( &gdef->LigCaretList,
                                        stream ) ) != TT_Err_Ok )
        goto Fail2;
      (void)FILE_Seek( cur_offset );
    }

    /* OpenType 1.2 has introduced the `MarkAttachClassDef' field.  We
       first have to scan the LookupFlag values to find out whether we
       must load it or not.  Here we only store the offset of the table. */

    if ( ACCESS_Frame( 2L ) )
      goto Fail3;

    new_offset = GET_UShort();

    FORGET_Frame();

    if ( new_offset )
      gdef->MarkAttachClassDef_offset = new_offset + base_offset;
    else
      gdef->MarkAttachClassDef_offset = 0;

    *retptr = gdef;

    return TT_Err_Ok;

  Fail3:
    Free_LigCaretList( &gdef->LigCaretList, memory );
    
  Fail2:
    Free_AttachList( &gdef->AttachList, memory );

  Fail1:
    Free_ClassDefinition( &gdef->GlyphClassDef, memory );

  Fail0:
    FREE( gdef );

    return error;
  }

  EXPORT_FUNC
  FT_Error  TT_Done_GDEF_Table ( TTO_GDEFHeader* gdef ) 
  {
    FT_Memory memory = gdef->memory;
    
    Free_LigCaretList( &gdef->LigCaretList, memory );
    Free_AttachList( &gdef->AttachList, memory );
    Free_ClassDefinition( &gdef->GlyphClassDef, memory );
    Free_ClassDefinition( &gdef->MarkAttachClassDef, memory );
    
    Free_NewGlyphClasses( gdef, memory );

    return TT_Err_Ok;
  }




  /*******************************
   * AttachList related functions
   *******************************/


  /* AttachPoint */

  static FT_Error  Load_AttachPoint( TTO_AttachPoint*  ap,
                                     FT_Stream         stream )
  {
    FT_Memory memory = stream->memory;
    FT_Error  error;

    FT_UShort   n, count;
    FT_UShort*  pi;


    if ( ACCESS_Frame( 2L ) )
      return error;

    count = ap->PointCount = GET_UShort();

    FORGET_Frame();

    ap->PointIndex = NULL;

    if ( count )
    {
      if ( ALLOC_ARRAY( ap->PointIndex, count, FT_UShort ) )
        return error;

      pi = ap->PointIndex;

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

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

      FORGET_Frame();
    }

    return TT_Err_Ok;
  }


  static void  Free_AttachPoint( TTO_AttachPoint*  ap,
				 FT_Memory        memory )
  {
    FREE( ap->PointIndex );
  }


  /* AttachList */

  static FT_Error  Load_AttachList( TTO_AttachList*  al,
                                    FT_Stream        stream )
  {
    FT_Memory memory = stream->memory;
    FT_Error  error;

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

    TTO_AttachPoint*  ap;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

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

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = al->GlyphCount = GET_UShort();

    FORGET_Frame();

    al->AttachPoint = NULL;

    if ( ALLOC_ARRAY( al->AttachPoint, count, TTO_AttachPoint ) )
      goto Fail2;

    ap = al->AttachPoint;

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

    al->loaded = TRUE;

    return TT_Err_Ok;

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

    FREE( ap );

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


  static void  Free_AttachList( TTO_AttachList*  al,
				FT_Memory        memory )
  {
    FT_UShort         n, count;

    TTO_AttachPoint*  ap;


    if ( !al->loaded )
      return;

    if ( al->AttachPoint )
    {
      count = al->GlyphCount;
      ap    = al->AttachPoint;

      for ( n = 0; n < count; n++ )
        Free_AttachPoint( &ap[n], memory );

      FREE( ap );
    }

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



  /*********************************
   * LigCaretList related functions
   *********************************/


  /* CaretValueFormat1 */
  /* CaretValueFormat2 */
  /* CaretValueFormat3 */
  /* CaretValueFormat4 */

  static FT_Error  Load_CaretValue( TTO_CaretValue*  cv,
                                    FT_Stream        stream )
  {
    FT_Error  error;

    FT_ULong cur_offset, new_offset, base_offset;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    cv->CaretValueFormat = GET_UShort();

    FORGET_Frame();

    switch ( cv->CaretValueFormat )
    {
    case 1:
      if ( ACCESS_Frame( 2L ) )
        return error;

      cv->cvf.cvf1.Coordinate = GET_Short();

      FORGET_Frame();

      break;

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

      cv->cvf.cvf2.CaretValuePoint = GET_UShort();

      FORGET_Frame();

      break;

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

      cv->cvf.cvf3.Coordinate = GET_Short();

      new_offset = GET_UShort() + base_offset;

      FORGET_Frame();

      cur_offset = FILE_Pos();
      if ( FILE_Seek( new_offset ) ||
           ( error = Load_Device( &cv->cvf.cvf3.Device,
                                  stream ) ) != TT_Err_Ok )
        return error;
      (void)FILE_Seek( cur_offset );

      break;

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

      cv->cvf.cvf4.IdCaretValue = GET_UShort();

      FORGET_Frame();
      break;

    default:
      return TTO_Err_Invalid_GDEF_SubTable_Format;
    }

    return TT_Err_Ok;
  }


  static void  Free_CaretValue( TTO_CaretValue*  cv,
				FT_Memory        memory )
  {
    if ( cv->CaretValueFormat == 3 )
      Free_Device( &cv->cvf.cvf3.Device, memory );
  }


  /* LigGlyph */

  static FT_Error  Load_LigGlyph( TTO_LigGlyph*  lg,
                                  FT_Stream      stream )
  {
    FT_Memory memory = stream->memory;
    FT_Error  error;

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

    TTO_CaretValue*  cv;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    count = lg->CaretCount = GET_UShort();

    FORGET_Frame();

    lg->CaretValue = NULL;

    if ( ALLOC_ARRAY( lg->CaretValue, count, TTO_CaretValue ) )
      return error;

    cv = lg->CaretValue;

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

    return TT_Err_Ok;

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

    FREE( cv );
    return error;
  }


  static void  Free_LigGlyph( TTO_LigGlyph*  lg,
			      FT_Memory      memory )
  {
    FT_UShort        n, count;

    TTO_CaretValue*  cv;


    if ( lg->CaretValue )
    {
      count = lg->CaretCount;
      cv    = lg->CaretValue;

      for ( n = 0; n < count; n++ )
        Free_CaretValue( &cv[n], memory );

      FREE( cv );
    }
  }


  /* LigCaretList */

  static FT_Error  Load_LigCaretList( TTO_LigCaretList*  lcl,
                                      FT_Stream          stream )
  {
    FT_Memory memory = stream->memory;
    FT_Error  error;

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

    TTO_LigGlyph*  lg;


    base_offset = FILE_Pos();

    if ( ACCESS_Frame( 2L ) )
      return error;

    new_offset = GET_UShort() + base_offset;

    FORGET_Frame();

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

    if ( ACCESS_Frame( 2L ) )
      goto Fail2;

    count = lcl->LigGlyphCount = GET_UShort();

    FORGET_Frame();

    lcl->LigGlyph = NULL;

    if ( ALLOC_ARRAY( lcl->LigGlyph, count, TTO_LigGlyph ) )
      goto Fail2;

    lg = lcl->LigGlyph;

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

    lcl->loaded = TRUE;

    return TT_Err_Ok;

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

    FREE( lg );

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


  static void  Free_LigCaretList( TTO_LigCaretList*  lcl,
				  FT_Memory           memory )
  {
    FT_UShort      n, count;

    TTO_LigGlyph*  lg;


    if ( !lcl->loaded )
      return;

    if ( lcl->LigGlyph )
    {
      count = lcl->LigGlyphCount;
      lg    = lcl->LigGlyph;

      for ( n = 0; n < count; n++ )
        Free_LigGlyph( &lg[n], memory );

      FREE( lg );
    }

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



  /***********
   * GDEF API
   ***********/


  static FT_UShort  Get_New_Class( TTO_GDEFHeader*  gdef,
				   FT_UShort        glyphID,
				   FT_UShort        index )
  {
    FT_UShort              glyph_index, array_index;
    FT_UShort              byte, bits;
    
    TTO_ClassRangeRecord*  gcrr;
    FT_UShort**            ngc;


    if ( glyphID >= gdef->LastGlyph )
      return 0;

    gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
    ngc  = gdef->NewGlyphClasses;

    if ( glyphID < gcrr[index].Start )
    {
      array_index = 0;
      if ( index == 0 )
        glyph_index = glyphID;
      else
        glyph_index = glyphID - gcrr[index - 1].End - 1;
    }
    else
    {
      array_index = index + 1;
      glyph_index = glyphID - gcrr[index].End - 1;
    }

    byte = ngc[array_index][glyph_index / 4 + 1];
    bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );

    return bits & 0x000F;
  }


  EXPORT_FUNC
  FT_Error  TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader*  gdef,
                                        FT_UShort        glyphID,
                                        FT_UShort*       property )
  {
    FT_UShort class, index;

    FT_Error  error;


    if ( !gdef || !property )
      return TT_Err_Invalid_Argument;

    /* first, we check for mark attach classes */

    if ( gdef->MarkAttachClassDef.loaded )
    {
      error = Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index );
      if ( error && error != TTO_Err_Not_Covered )
        return error;
      if ( !error )
      {
        *property = class << 8;
        return TT_Err_Ok;
      }
    }

    error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
    if ( error && error != TTO_Err_Not_Covered )
      return error;

    /* if we have a constructed class table, check whether additional
       values have been assigned                                      */

    if ( error == TTO_Err_Not_Covered && gdef->NewGlyphClasses )
      class = Get_New_Class( gdef, glyphID, index );

    switch ( class )
    {
    case UNCLASSIFIED_GLYPH:
      *property = 0;
      break;

    case SIMPLE_GLYPH:
      *property = TTO_BASE_GLYPH;
      break;

    case LIGATURE_GLYPH:
      *property = TTO_LIGATURE;
      break;

    case MARK_GLYPH:
      *property = TTO_MARK;
      break;

    case COMPONENT_GLYPH:
      *property = TTO_COMPONENT;
      break;
    }

    return TT_Err_Ok;
  }


  static FT_Error  Make_ClassRange( TTO_ClassDefinition*  cd,
                                    FT_UShort             start,
                                    FT_UShort             end,
                                    FT_UShort             class,
				    FT_Memory             memory )
  {
    FT_Error               error;
    FT_UShort              index;

    TTO_ClassDefFormat2*   cdf2;
    TTO_ClassRangeRecord*  crr;


    cdf2 = &cd->cd.cd2;

    if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,
			cdf2->ClassRangeCount,
			cdf2->ClassRangeCount + 1 ,
                        TTO_ClassRangeRecord ) )
      return error;

    cdf2->ClassRangeCount++;

    crr   = cdf2->ClassRangeRecord;
    index = cdf2->ClassRangeCount - 1;

    crr[index].Start = start;
    crr[index].End   = end;
    crr[index].Class = class;

    cd->Defined[class] = TRUE;

    return TT_Err_Ok;
  }


  EXPORT_FUNC
  FT_Error  TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader*  gdef,
                                           FT_UShort        num_glyphs,
                                           FT_UShort        glyph_count,
                                           FT_UShort*       glyph_array,
                                           FT_UShort*       class_array )
  {
    FT_UShort              start, curr_glyph, curr_class;
    FT_UShort              n, m, count;
    FT_Error               error;
    FT_Memory              memory = gdef->memory;

    TTO_ClassDefinition*   gcd;
    TTO_ClassRangeRecord*  gcrr;
    FT_UShort**            ngc;


    if ( !gdef || !glyph_array || !class_array )
      return TT_Err_Invalid_Argument;

    gcd = &gdef->GlyphClassDef;

    /* We build a format 2 table */

    gcd->ClassFormat = 2;

    /* A GlyphClassDef table contains at most 5 different class values */

    if ( ALLOC_ARRAY( gcd->Defined, 5, FT_Bool ) )
      return error;

    gcd->cd.cd2.ClassRangeCount  = 0;
    gcd->cd.cd2.ClassRangeRecord = NULL;

    start      = glyph_array[0];
    curr_class = class_array[0];
    curr_glyph = start;

    if ( curr_class >= 5 )
    {
      error = TT_Err_Invalid_Argument;
      goto Fail4;
    }

    glyph_count--;

    for ( n = 0; n <= glyph_count; n++ )
    {
      if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] )
      {
        if ( n == glyph_count )
        {
          if ( ( error = Make_ClassRange( gcd, start,
                                          curr_glyph,
                                          curr_class,
					  memory ) ) != TT_Err_Ok )
            goto Fail3;
        }
        else
        {
          if ( curr_glyph == 0xFFFF )
          {
            error = TT_Err_Invalid_Argument;
            goto Fail3;
          }
          else
            curr_glyph++;
        }
      }
      else
      {
        if ( ( error = Make_ClassRange( gcd, start,
                                        curr_glyph - 1,
                                        curr_class,
					memory ) ) != TT_Err_Ok )
          goto Fail3;

        if ( curr_glyph > glyph_array[n] )
        {
          error = TT_Err_Invalid_Argument;
          goto Fail3;
        }

        start      = glyph_array[n];
        curr_class = class_array[n];
        curr_glyph = start;

        if ( curr_class >= 5 )
        {
          error = TT_Err_Invalid_Argument;
          goto Fail3;
        }

        if ( n == glyph_count )
        {
          if ( ( error = Make_ClassRange( gcd, start,
                                          curr_glyph,
                                          curr_class,
					  memory ) ) != TT_Err_Ok )
            goto Fail3;
        }
        else
        {
          if ( curr_glyph == 0xFFFF )
          {
            error = TT_Err_Invalid_Argument;
            goto Fail3;
          }
          else
            curr_glyph++;
        }
      }
    }

    /* now prepare the arrays for class values assigned during the lookup
       process                                                            */

    if ( ALLOC_ARRAY( gdef->NewGlyphClasses,
                      gcd->cd.cd2.ClassRangeCount + 1, FT_UShort* ) )
      goto Fail2;

    count = gcd->cd.cd2.ClassRangeCount;
    gcrr  = gcd->cd.cd2.ClassRangeRecord;
    ngc   = gdef->NewGlyphClasses;

    /* We allocate arrays for all glyphs not covered by the class range
       records.  Each element holds four class values.                  */

    if ( gcrr[0].Start )
    {
      if ( ALLOC_ARRAY( ngc[0], gcrr[0].Start / 4 + 1, FT_UShort ) )
        goto Fail1;
    }

    for ( n = 1; n < count; n++ )
    {
      if ( gcrr[n].Start - gcrr[n - 1].End > 1 )
        if ( ALLOC_ARRAY( ngc[n],
                          ( gcrr[n].Start - gcrr[n - 1].End - 1 ) / 4 + 1,
                          FT_UShort ) )
          goto Fail1;
    }

    if ( gcrr[count - 1].End != num_glyphs - 1 )
    {
      if ( ALLOC_ARRAY( ngc[count],
                        ( num_glyphs - gcrr[count - 1].End - 1 ) / 4 + 1,
                        FT_UShort ) )
        goto Fail1;
    }

    gdef->LastGlyph = num_glyphs - 1;

    gdef->MarkAttachClassDef_offset = 0L;
    gdef->MarkAttachClassDef.loaded = FALSE;

    return TT_Err_Ok;

  Fail1:
    for ( m = 0; m < n; m++ )
      FREE( ngc[m] );

  Fail2:
    FREE( gdef->NewGlyphClasses );

  Fail3:
    FREE( gcd->cd.cd2.ClassRangeRecord );

  Fail4:
    FREE( gcd->Defined );
    return error;
  }


  static void  Free_NewGlyphClasses( TTO_GDEFHeader*  gdef,
				     FT_Memory        memory )
  {
    FT_UShort**  ngc;
    FT_UShort    n, count;


    if ( gdef->NewGlyphClasses )
    {
      count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1;
      ngc   = gdef->NewGlyphClasses;

      for ( n = 0; n < count; n++ )
        FREE( ngc[n] );

      FREE( ngc );
    }
  }


  FT_Error  Add_Glyph_Property( TTO_GDEFHeader*  gdef,
                                FT_UShort        glyphID,
                                FT_UShort        property )
  {
    FT_Error               error;
    FT_UShort              class, new_class, index;
    FT_UShort              byte, bits, mask;
    FT_UShort              array_index, glyph_index;

    TTO_ClassRangeRecord*  gcrr;
    FT_UShort**            ngc;


    error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
    if ( error && error != TTO_Err_Not_Covered )
      return error;

    /* we don't accept glyphs covered in `GlyphClassDef' */

    if ( !error )
      return TTO_Err_Not_Covered;

    switch ( property )
    {
    case 0:
      new_class = UNCLASSIFIED_GLYPH;
      break;

    case TTO_BASE_GLYPH:
      new_class = SIMPLE_GLYPH;
      break;

    case TTO_LIGATURE:
      new_class = LIGATURE_GLYPH;
      break;

    case TTO_MARK:
      new_class = MARK_GLYPH;
      break;

    case TTO_COMPONENT:
      new_class = COMPONENT_GLYPH;
      break;

    default:
      return TT_Err_Invalid_Argument;
    }

    gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
    ngc  = gdef->NewGlyphClasses;

    if ( glyphID < gcrr[index].Start )
    {
      array_index = 0;
      if ( index == 0 )
        glyph_index = glyphID;
      else
        glyph_index = glyphID - gcrr[index - 1].End - 1;
    }
    else
    {
      array_index = index + 1;
      glyph_index = glyphID - gcrr[index].End - 1;
    }

    byte  = ngc[array_index][glyph_index / 4 + 1];
    bits  = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
    class = bits & 0x000F;

    /* we don't overwrite existing entries */

    if ( !class )
    {
      bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 );
      mask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) );

      ngc[array_index][glyph_index / 4 + 1] &= mask;
      ngc[array_index][glyph_index / 4 + 1] |= bits;
    }

    return TT_Err_Ok;
  }


  FT_Error  Check_Property( TTO_GDEFHeader*  gdef,
                            FT_UShort        index,
                            FT_UShort        flags,
                            FT_UShort*       property )
  {
    FT_Error  error;


    if ( gdef )
    {
      FT_UShort basic_glyph_class;
      FT_UShort desired_attachment_class;
	    
      error = TT_GDEF_Get_Glyph_Property( gdef, index, property );
      if ( error )
        return error;

      /* If the glyph was found in the MarkAttachmentClass table,
       * then that class value is the high byte of the result,
       * otherwise the low byte contains the basic type of the glyph
       * as defined by the GlyphClassDef table.
       */
      if ( *property & IGNORE_SPECIAL_MARKS  )
	basic_glyph_class = TTO_MARK;
      else
	basic_glyph_class = *property;

      /* Return Not_Covered, if, for example, basic_glyph_class
       * is TTO_LIGATURE and LookFlags includes IGNORE_LIGATURES
       */
      if ( flags & basic_glyph_class )
	return TTO_Err_Not_Covered;
      
      /* The high byte of LookupFlags has the meaning
       * "ignore marks of attachment type different than
       * the attachment type specified."
       */
      desired_attachment_class = flags & IGNORE_SPECIAL_MARKS;
      if ( desired_attachment_class )
      {
	if ( basic_glyph_class == TTO_MARK &&
	     *property != desired_attachment_class )
	  return TTO_Err_Not_Covered;
      }
    }

    return TT_Err_Ok;
  }


/* END */
