/*******************************************************************
 *
 *  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 "ftxopen.h"
#include "ftxopenf.h"

#include "fterrcompat.h"

#include FT_TRUETYPE_TAGS_H

#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_MEMORY_H
#include FT_INTERNAL_TRUETYPE_TYPES_H

#define TTAG_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 */
