11512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/*
21512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Copyright (C) 1998-2004  David Turner and Werner Lemberg
31512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Copyright (C) 2006  Behdad Esfahbod
41512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *
51512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * This is part of HarfBuzz, an OpenType Layout engine library.
61512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *
71512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * Permission is hereby granted, without written agreement and without
81512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
91512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * software and its documentation for any purpose, provided that the
101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * all copies of this software.
121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *
131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * DAMAGE.
181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *
191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod */
251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-impl.h"
271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-gdef-private.h"
281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#include "harfbuzz-open-private.h"
291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error  Load_AttachList( HB_AttachList*  al,
311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				  HB_Stream        stream );
321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error  Load_LigCaretList( HB_LigCaretList*  lcl,
331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				    HB_Stream          stream );
341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void  Free_AttachList( HB_AttachList*  al);
361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void  Free_LigCaretList( HB_LigCaretList*  lcl);
371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void  Free_NewGlyphClasses( HB_GDEFHeader*  gdef);
391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* GDEF glyph classes */
431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#define UNCLASSIFIED_GLYPH  0
451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#define SIMPLE_GLYPH        1
461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#define LIGATURE_GLYPH      2
471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#define MARK_GLYPH          3
481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#define COMPONENT_GLYPH     4
491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
551512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_Error  HB_New_GDEF_Table( HB_GDEFHeader** retptr )
561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error         error;
581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_GDEFHeader*  gdef;
601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( !retptr )
621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return ERR(HB_Err_Invalid_Argument);
631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ALLOC( gdef, sizeof( *gdef ) ) )
651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->GlyphClassDef.loaded = FALSE;
681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->AttachList.loaded = FALSE;
691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->LigCaretList.loaded = FALSE;
701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->MarkAttachClassDef_offset = 0;
711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->MarkAttachClassDef.loaded = FALSE;
721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->LastGlyph = 0;
741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->NewGlyphClasses = NULL;
751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  *retptr = gdef;
771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
821512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_Error  HB_Load_GDEF_Table( HB_Stream stream,
831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			      HB_GDEFHeader** retptr )
841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error         error;
861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UInt         cur_offset, new_offset, base_offset;
871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_GDEFHeader*  gdef;
891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( !retptr )
921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return ERR(HB_Err_Invalid_Argument);
931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( GOTO_Table( TTAG_GDEF ) )
951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if (( error = HB_New_GDEF_Table ( &gdef ) ))
981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  base_offset = FILE_Pos();
1011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* skip version */
1031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( FILE_Seek( base_offset + 4L ) ||
1051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod       ACCESS_Frame( 2L ) )
1061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail0;
1071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  new_offset = GET_UShort();
1091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
1111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* all GDEF subtables are optional */
1131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( new_offset )
1151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
1161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_offset += base_offset;
1171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    /* only classes 1-4 are allowed here */
1191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cur_offset = FILE_Pos();
1211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( FILE_Seek( new_offset ) ||
1221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	 ( error = _HB_OPEN_Load_ClassDefinition( &gdef->GlyphClassDef, 5,
1231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					 stream ) ) != HB_Err_Ok )
1241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      goto Fail0;
1251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    (void)FILE_Seek( cur_offset );
1261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
1271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
1291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail1;
1301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  new_offset = GET_UShort();
1321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
1341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( new_offset )
1361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
1371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_offset += base_offset;
1381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cur_offset = FILE_Pos();
1401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( FILE_Seek( new_offset ) ||
1411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	 ( error = Load_AttachList( &gdef->AttachList,
1421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				    stream ) ) != HB_Err_Ok )
1431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      goto Fail1;
1441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    (void)FILE_Seek( cur_offset );
1451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
1461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
1481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail2;
1491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  new_offset = GET_UShort();
1511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
1531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( new_offset )
1551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
1561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_offset += base_offset;
1571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cur_offset = FILE_Pos();
1591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( FILE_Seek( new_offset ) ||
1601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	 ( error = Load_LigCaretList( &gdef->LigCaretList,
1611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				      stream ) ) != HB_Err_Ok )
1621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      goto Fail2;
1631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    (void)FILE_Seek( cur_offset );
1641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
1651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* OpenType 1.2 has introduced the `MarkAttachClassDef' field.  We
1671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     first have to scan the LookupFlag values to find out whether we
1681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     must load it or not.  Here we only store the offset of the table. */
1691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
1711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail3;
1721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  new_offset = GET_UShort();
1741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
1761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( new_offset )
1781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    gdef->MarkAttachClassDef_offset = new_offset + base_offset;
1791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  else
1801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    gdef->MarkAttachClassDef_offset = 0;
1811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  *retptr = gdef;
1831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
1851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1861512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail3:
1871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  Free_LigCaretList( &gdef->LigCaretList );
1881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1891512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail2:
1901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  Free_AttachList( &gdef->AttachList );
1911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1921512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail1:
1931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );
1941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1951512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail0:
1961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FREE( gdef );
1971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
1981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return error;
1991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
2001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2021512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_Error  HB_Done_GDEF_Table ( HB_GDEFHeader* gdef )
2031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
2041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  Free_LigCaretList( &gdef->LigCaretList );
2051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  Free_AttachList( &gdef->AttachList );
2061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );
2071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  _HB_OPEN_Free_ClassDefinition( &gdef->MarkAttachClassDef );
2081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  Free_NewGlyphClasses( gdef );
2101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FREE( gdef );
2121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
2141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
2151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/*******************************
2201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * AttachList related functions
2211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *******************************/
2221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* AttachPoint */
2251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error  Load_AttachPoint( HB_AttachPoint*  ap,
2271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				   HB_Stream         stream )
2281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
2291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error  error;
2301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort   n, count;
2321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort*  pi;
2331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
2361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
2371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  count = ap->PointCount = GET_UShort();
2391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
2411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  ap->PointIndex = NULL;
2431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( count )
2451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
2461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( ALLOC_ARRAY( ap->PointIndex, count, HB_UShort ) )
2471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return error;
2481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    pi = ap->PointIndex;
2501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( ACCESS_Frame( count * 2L ) )
2521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {
2531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      FREE( pi );
2541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return error;
2551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
2561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    for ( n = 0; n < count; n++ )
2581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      pi[n] = GET_UShort();
2591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FORGET_Frame();
2611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
2621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
2641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
2651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void  Free_AttachPoint( HB_AttachPoint*  ap )
2681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
2691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FREE( ap->PointIndex );
2701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
2711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* AttachList */
2741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error  Load_AttachList( HB_AttachList*  al,
2761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				  HB_Stream        stream )
2771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
2781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error  error;
2791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort         n, m, count;
2811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UInt          cur_offset, new_offset, base_offset;
2821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_AttachPoint*  ap;
2841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  base_offset = FILE_Pos();
2871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
2891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
2901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  new_offset = GET_UShort() + base_offset;
2921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
2941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
2951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  cur_offset = FILE_Pos();
2961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( FILE_Seek( new_offset ) ||
2971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod       ( error = _HB_OPEN_Load_Coverage( &al->Coverage, stream ) ) != HB_Err_Ok )
2981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
2991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  (void)FILE_Seek( cur_offset );
3001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
3021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail2;
3031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  count = al->GlyphCount = GET_UShort();
3051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
3071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  al->AttachPoint = NULL;
3091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ALLOC_ARRAY( al->AttachPoint, count, HB_AttachPoint ) )
3111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail2;
3121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  ap = al->AttachPoint;
3141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  for ( n = 0; n < count; n++ )
3161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
3171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( ACCESS_Frame( 2L ) )
3181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      goto Fail1;
3191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_offset = GET_UShort() + base_offset;
3211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FORGET_Frame();
3231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cur_offset = FILE_Pos();
3251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( FILE_Seek( new_offset ) ||
3261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	 ( error = Load_AttachPoint( &ap[n], stream ) ) != HB_Err_Ok )
3271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      goto Fail1;
3281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    (void)FILE_Seek( cur_offset );
3291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
3301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  al->loaded = TRUE;
3321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
3341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3351512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail1:
3361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  for ( m = 0; m < n; m++ )
3371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    Free_AttachPoint( &ap[m] );
3381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FREE( ap );
3401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3411512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail2:
3421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  _HB_OPEN_Free_Coverage( &al->Coverage );
3431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return error;
3441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
3451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void  Free_AttachList( HB_AttachList*  al)
3481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
3491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort         n, count;
3501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_AttachPoint*  ap;
3521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( !al->loaded )
3551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return;
3561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( al->AttachPoint )
3581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
3591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    count = al->GlyphCount;
3601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    ap    = al->AttachPoint;
3611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    for ( n = 0; n < count; n++ )
3631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      Free_AttachPoint( &ap[n] );
3641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FREE( ap );
3661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
3671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  _HB_OPEN_Free_Coverage( &al->Coverage );
3691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
3701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/*********************************
3741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * LigCaretList related functions
3751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod *********************************/
3761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* CaretValueFormat1 */
3791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* CaretValueFormat2 */
3801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* CaretValueFormat3 */
3811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* CaretValueFormat4 */
3821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error  Load_CaretValue( HB_CaretValue*  cv,
3841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				  HB_Stream        stream )
3851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
3861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error  error;
3871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UInt cur_offset, new_offset, base_offset;
3891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  base_offset = FILE_Pos();
3921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
3941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
3951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  cv->CaretValueFormat = GET_UShort();
3971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
3981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
3991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  switch ( cv->CaretValueFormat )
4011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
4021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case 1:
4031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( ACCESS_Frame( 2L ) )
4041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return error;
4051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cv->cvf.cvf1.Coordinate = GET_Short();
4071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FORGET_Frame();
4091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
4111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case 2:
4131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( ACCESS_Frame( 2L ) )
4141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return error;
4151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cv->cvf.cvf2.CaretValuePoint = GET_UShort();
4171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FORGET_Frame();
4191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
4211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case 3:
4231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( ACCESS_Frame( 4L ) )
4241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return error;
4251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cv->cvf.cvf3.Coordinate = GET_Short();
4271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_offset = GET_UShort() + base_offset;
4291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FORGET_Frame();
4311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cur_offset = FILE_Pos();
4331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( FILE_Seek( new_offset ) ||
4341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	 ( error = _HB_OPEN_Load_Device( &cv->cvf.cvf3.Device,
4351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				stream ) ) != HB_Err_Ok )
4361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return error;
4371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    (void)FILE_Seek( cur_offset );
4381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
4401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case 4:
4421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( ACCESS_Frame( 2L ) )
4431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return error;
4441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#ifdef HB_SUPPORT_MULTIPLE_MASTER
4461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cv->cvf.cvf4.IdCaretValue = GET_UShort();
4471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#else
4481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    (void) GET_UShort();
4491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod#endif
4501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FORGET_Frame();
4521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
4531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  default:
4551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return ERR(HB_Err_Invalid_SubTable_Format);
4561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
4571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
4591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
4601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void  Free_CaretValue( HB_CaretValue*  cv)
4631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
4641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( cv->CaretValueFormat == 3 )
4651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    _HB_OPEN_Free_Device( cv->cvf.cvf3.Device );
4661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
4671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* LigGlyph */
4701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error  Load_LigGlyph( HB_LigGlyph*  lg,
4721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				HB_Stream      stream )
4731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
4741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error  error;
4751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort        n, m, count;
4771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UInt         cur_offset, new_offset, base_offset;
4781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_CaretValue*  cv;
4801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  base_offset = FILE_Pos();
4831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
4851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
4861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  count = lg->CaretCount = GET_UShort();
4881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
4901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  lg->CaretValue = NULL;
4921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ALLOC_ARRAY( lg->CaretValue, count, HB_CaretValue ) )
4941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
4951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  cv = lg->CaretValue;
4971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
4981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  for ( n = 0; n < count; n++ )
4991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
5001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( ACCESS_Frame( 2L ) )
5011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      goto Fail;
5021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_offset = GET_UShort() + base_offset;
5041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FORGET_Frame();
5061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cur_offset = FILE_Pos();
5081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( FILE_Seek( new_offset ) ||
5091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	 ( error = Load_CaretValue( &cv[n], stream ) ) != HB_Err_Ok )
5101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      goto Fail;
5111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    (void)FILE_Seek( cur_offset );
5121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
5131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
5151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5161512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail:
5171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  for ( m = 0; m < n; m++ )
5181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    Free_CaretValue( &cv[m] );
5191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FREE( cv );
5211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return error;
5221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
5231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void  Free_LigGlyph( HB_LigGlyph*  lg)
5261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
5271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort        n, count;
5281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_CaretValue*  cv;
5301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( lg->CaretValue )
5331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
5341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    count = lg->CaretCount;
5351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cv    = lg->CaretValue;
5361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    for ( n = 0; n < count; n++ )
5381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      Free_CaretValue( &cv[n] );
5391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FREE( cv );
5411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
5421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
5431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* LigCaretList */
5461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error  Load_LigCaretList( HB_LigCaretList*  lcl,
5481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				    HB_Stream          stream )
5491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
5501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error  error;
5511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort      m, n, count;
5531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UInt       cur_offset, new_offset, base_offset;
5541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_LigGlyph*  lg;
5561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  base_offset = FILE_Pos();
5591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
5611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
5621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  new_offset = GET_UShort() + base_offset;
5641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
5661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  cur_offset = FILE_Pos();
5681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( FILE_Seek( new_offset ) ||
5691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod       ( error = _HB_OPEN_Load_Coverage( &lcl->Coverage, stream ) ) != HB_Err_Ok )
5701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
5711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  (void)FILE_Seek( cur_offset );
5721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ACCESS_Frame( 2L ) )
5741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail2;
5751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  count = lcl->LigGlyphCount = GET_UShort();
5771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FORGET_Frame();
5791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  lcl->LigGlyph = NULL;
5811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ALLOC_ARRAY( lcl->LigGlyph, count, HB_LigGlyph ) )
5831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail2;
5841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  lg = lcl->LigGlyph;
5861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  for ( n = 0; n < count; n++ )
5881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
5891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( ACCESS_Frame( 2L ) )
5901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      goto Fail1;
5911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_offset = GET_UShort() + base_offset;
5931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FORGET_Frame();
5951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
5961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    cur_offset = FILE_Pos();
5971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( FILE_Seek( new_offset ) ||
5981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	 ( error = Load_LigGlyph( &lg[n], stream ) ) != HB_Err_Ok )
5991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      goto Fail1;
6001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    (void)FILE_Seek( cur_offset );
6011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
6021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  lcl->loaded = TRUE;
6041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
6061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6071512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail1:
6081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  for ( m = 0; m < n; m++ )
6091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    Free_LigGlyph( &lg[m] );
6101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FREE( lg );
6121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6131512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail2:
6141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  _HB_OPEN_Free_Coverage( &lcl->Coverage );
6151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return error;
6161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
6171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void  Free_LigCaretList( HB_LigCaretList*  lcl )
6201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
6211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort      n, count;
6221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_LigGlyph*  lg;
6241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( !lcl->loaded )
6271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return;
6281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( lcl->LigGlyph )
6301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
6311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    count = lcl->LigGlyphCount;
6321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    lg    = lcl->LigGlyph;
6331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    for ( n = 0; n < count; n++ )
6351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      Free_LigGlyph( &lg[n] );
6361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FREE( lg );
6381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
6391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  _HB_OPEN_Free_Coverage( &lcl->Coverage );
6411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
6421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/***********
6461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod * GDEF API
6471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod ***********/
6481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_UShort  Get_New_Class( HB_GDEFHeader*  gdef,
6511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				 HB_UShort        glyphID,
6521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				 HB_UShort        index )
6531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
6541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort              glyph_index, array_index, count;
6551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort              byte, bits;
6561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_ClassRangeRecord*  gcrr;
6581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort**            ngc;
6591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( glyphID >= gdef->LastGlyph )
6621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return 0;
6631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
6651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
6661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  ngc  = gdef->NewGlyphClasses;
6671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( index < count && glyphID < gcrr[index].Start )
6691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
6701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    array_index = index;
6711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( index == 0 )
6721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      glyph_index = glyphID;
6731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    else
6741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      glyph_index = glyphID - gcrr[index - 1].End - 1;
6751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
6761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  else
6771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
6781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    array_index = index + 1;
6791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    glyph_index = glyphID - gcrr[index].End - 1;
6801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
6811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  byte = ngc[array_index][glyph_index / 4];
6831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
6841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return bits & 0x000F;
6861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
6871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6901512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_Error  HB_GDEF_Get_Glyph_Property( HB_GDEFHeader*  gdef,
6911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				      HB_UShort        glyphID,
6921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				      HB_UShort*       property )
6931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
6941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort class = 0, index = 0; /* shut compiler up */
6951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error  error;
6971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
6991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( !gdef || !property )
7001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return ERR(HB_Err_Invalid_Argument);
7011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* first, we check for mark attach classes */
7031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( gdef->MarkAttachClassDef.loaded )
7051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
7061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    error = _HB_OPEN_Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index );
7071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( error && error != HB_Err_Not_Covered )
7081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return error;
7091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( !error )
7101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {
7111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      *property = class << 8;
7121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return HB_Err_Ok;
7131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
7141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
7151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
7171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( error && error != HB_Err_Not_Covered )
7181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
7191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* if we have a constructed class table, check whether additional
7211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     values have been assigned                                      */
7221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( error == HB_Err_Not_Covered && gdef->NewGlyphClasses )
7241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    class = Get_New_Class( gdef, glyphID, index );
7251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  switch ( class )
7271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
7281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  default:
7291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case UNCLASSIFIED_GLYPH:
7301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    *property = 0;
7311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
7321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case SIMPLE_GLYPH:
7341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    *property = HB_GDEF_BASE_GLYPH;
7351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
7361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case LIGATURE_GLYPH:
7381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    *property = HB_GDEF_LIGATURE;
7391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
7401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case MARK_GLYPH:
7421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    *property = HB_GDEF_MARK;
7431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
7441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case COMPONENT_GLYPH:
7461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    *property = HB_GDEF_COMPONENT;
7471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
7481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
7491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
7511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
7521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic HB_Error  Make_ClassRange( HB_ClassDefinition*  cd,
7551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				  HB_UShort             start,
7561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				  HB_UShort             end,
7571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				  HB_UShort             class )
7581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
7591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error               error;
7601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort              index;
7611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_ClassDefFormat2*   cdf2;
7631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_ClassRangeRecord*  crr;
7641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  cdf2 = &cd->cd.cd2;
7671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,
7691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod		      cdf2->ClassRangeCount + 1 ,
7701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod		      HB_ClassRangeRecord ) )
7711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
7721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  cdf2->ClassRangeCount++;
7741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  crr   = cdf2->ClassRangeRecord;
7761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  index = cdf2->ClassRangeCount - 1;
7771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  crr[index].Start = start;
7791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  crr[index].End   = end;
7801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  crr[index].Class = class;
7811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
7831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
7841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7871512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_Error  HB_GDEF_Build_ClassDefinition( HB_GDEFHeader*  gdef,
7881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					 HB_UShort        num_glyphs,
7891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					 HB_UShort        glyph_count,
7901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					 HB_UShort*       glyph_array,
7911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					 HB_UShort*       class_array )
7921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
7931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort              start, curr_glyph, curr_class;
7941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort              n, m, count;
7951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error               error;
7961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
7971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_ClassDefinition*   gcd;
7981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_ClassRangeRecord*  gcrr;
7991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort**            ngc;
8001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( !gdef || !glyph_array || !class_array )
8031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return ERR(HB_Err_Invalid_Argument);
8041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gcd = &gdef->GlyphClassDef;
8061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* We build a format 2 table */
8081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gcd->ClassFormat = 2;
8101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gcd->cd.cd2.ClassRangeCount  = 0;
8121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gcd->cd.cd2.ClassRangeRecord = NULL;
8131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  start      = glyph_array[0];
8151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  curr_class = class_array[0];
8161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  curr_glyph = start;
8171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( curr_class >= 5 )
8191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
8201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    error = ERR(HB_Err_Invalid_Argument);
8211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail4;
8221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
8231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  glyph_count--;
8251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  for ( n = 0; n < glyph_count + 1; n++ )
8271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
8281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] )
8291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {
8301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( n == glyph_count )
8311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
8321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	if ( ( error = Make_ClassRange( gcd, start,
8331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					curr_glyph,
8341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					curr_class) ) != HB_Err_Ok )
8351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  goto Fail3;
8361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
8371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      else
8381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
8391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	if ( curr_glyph == 0xFFFF )
8401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	{
8411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  error = ERR(HB_Err_Invalid_Argument);
8421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  goto Fail3;
8431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	}
8441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	else
8451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  curr_glyph++;
8461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
8471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
8481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    else
8491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {
8501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( ( error = Make_ClassRange( gcd, start,
8511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				      curr_glyph - 1,
8521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod				      curr_class) ) != HB_Err_Ok )
8531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	goto Fail3;
8541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( curr_glyph > glyph_array[n] )
8561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
8571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	error = ERR(HB_Err_Invalid_Argument);
8581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	goto Fail3;
8591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
8601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      start      = glyph_array[n];
8621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      curr_class = class_array[n];
8631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      curr_glyph = start;
8641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( curr_class >= 5 )
8661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
8671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	error = ERR(HB_Err_Invalid_Argument);
8681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	goto Fail3;
8691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
8701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( n == glyph_count )
8721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
8731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	if ( ( error = Make_ClassRange( gcd, start,
8741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					curr_glyph,
8751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					curr_class) ) != HB_Err_Ok )
8761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  goto Fail3;
8771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
8781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      else
8791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
8801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	if ( curr_glyph == 0xFFFF )
8811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	{
8821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  error = ERR(HB_Err_Invalid_Argument);
8831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  goto Fail3;
8841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	}
8851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	else
8861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  curr_glyph++;
8871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
8881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
8891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
8901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* now prepare the arrays for class values assigned during the lookup
8921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     process                                                            */
8931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( ALLOC_ARRAY( gdef->NewGlyphClasses,
8951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod		    gcd->cd.cd2.ClassRangeCount + 1, HB_UShort* ) )
8961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    goto Fail3;
8971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
8981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  count = gcd->cd.cd2.ClassRangeCount;
8991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gcrr  = gcd->cd.cd2.ClassRangeRecord;
9001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  ngc   = gdef->NewGlyphClasses;
9011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* We allocate arrays for all glyphs not covered by the class range
9031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     records.  Each element holds four class values.                  */
9041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( count > 0 )
9061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
9071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( gcrr[0].Start )
9081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
9091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	if ( ALLOC_ARRAY( ngc[0], ( gcrr[0].Start + 3 ) / 4, HB_UShort ) )
9101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  goto Fail2;
9111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
9121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      for ( n = 1; n < count; n++ )
9141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
9151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	if ( gcrr[n].Start - gcrr[n - 1].End > 1 )
9161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  if ( ALLOC_ARRAY( ngc[n],
9171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			    ( gcrr[n].Start - gcrr[n - 1].End + 2 ) / 4,
9181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			    HB_UShort ) )
9191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	    goto Fail1;
9201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
9211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( gcrr[count - 1].End != num_glyphs - 1 )
9231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
9241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	if ( ALLOC_ARRAY( ngc[count],
9251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			  ( num_glyphs - gcrr[count - 1].End + 2 ) / 4,
9261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			  HB_UShort ) )
9271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	    goto Fail1;
9281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
9291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
9301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  else if ( num_glyphs > 0 )
9311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
9321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( ALLOC_ARRAY( ngc[count],
9331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			( num_glyphs + 3 ) / 4,
9341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			HB_UShort ) )
9351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  goto Fail2;
9361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
9371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->LastGlyph = num_glyphs - 1;
9391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->MarkAttachClassDef_offset = 0L;
9411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gdef->MarkAttachClassDef.loaded = FALSE;
9421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gcd->loaded = TRUE;
9441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
9461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9471512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail1:
9481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  for ( m = 0; m < n; m++ )
9491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FREE( ngc[m] );
9501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9511512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail2:
9521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FREE( gdef->NewGlyphClasses );
9531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9541512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail3:
9551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  FREE( gcd->cd.cd2.ClassRangeRecord );
9561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9571512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodFail4:
9581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return error;
9591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
9601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbodstatic void  Free_NewGlyphClasses( HB_GDEFHeader*  gdef )
9631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
9641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort**  ngc;
9651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort    n, count;
9661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9671512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( gdef->NewGlyphClasses )
9691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
9701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1;
9711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    ngc   = gdef->NewGlyphClasses;
9721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    for ( n = 0; n < count; n++ )
9741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      FREE( ngc[n] );
9751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    FREE( ngc );
9771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
9781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
9791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9811512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error
9821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,
9831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			      HB_UShort        glyphID,
9841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			      HB_UShort        property )
9851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
9861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error               error;
9871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort              class, new_class, index = 0; /* shut compiler up */
9881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort              byte, bits, mask;
9891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort              array_index, glyph_index, count;
9901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_ClassRangeRecord*  gcrr;
9921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort**            ngc;
9931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
9961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( error && error != HB_Err_Not_Covered )
9971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return error;
9981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
9991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* we don't accept glyphs covered in `GlyphClassDef' */
10001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( !error )
10021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return HB_Err_Not_Covered;
10031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  switch ( property )
10051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
10061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case 0:
10071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_class = UNCLASSIFIED_GLYPH;
10081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
10091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case HB_GDEF_BASE_GLYPH:
10111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_class = SIMPLE_GLYPH;
10121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
10131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case HB_GDEF_LIGATURE:
10151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_class = LIGATURE_GLYPH;
10161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
10171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case HB_GDEF_MARK:
10191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_class = MARK_GLYPH;
10201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
10211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  case HB_GDEF_COMPONENT:
10231512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    new_class = COMPONENT_GLYPH;
10241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    break;
10251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  default:
10271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    return ERR(HB_Err_Invalid_Argument);
10281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
10291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
10311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
10321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  ngc  = gdef->NewGlyphClasses;
10331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( index < count && glyphID < gcrr[index].Start )
10351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
10361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    array_index = index;
10371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( index == 0 )
10381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      glyph_index = glyphID;
10391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    else
10401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      glyph_index = glyphID - gcrr[index - 1].End - 1;
10411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
10421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  else
10431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
10441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    array_index = index + 1;
10451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    glyph_index = glyphID - gcrr[index].End - 1;
10461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
10471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  byte  = ngc[array_index][glyph_index / 4];
10491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  bits  = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
10501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  class = bits & 0x000F;
10511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* we don't overwrite existing entries */
10531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( !class )
10551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
10561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 );
10571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    mask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) );
10581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10591512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    ngc[array_index][glyph_index / 4] &= mask;
10601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    ngc[array_index][glyph_index / 4] |= bits;
10611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
10621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
10641512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
10651512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10661512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10671512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error
10681512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
10691512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			  HB_GlyphItem    gitem,
10701512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			  HB_UShort        flags,
10711512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod			  HB_UShort*       property )
10721512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
10731512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error  error;
10741512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10751512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( gdef )
10761512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
10771512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    HB_UShort basic_glyph_class;
10781512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    HB_UShort desired_attachment_class;
10791512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10801512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN )
10811512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {
10821512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );
10831512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( error )
10841512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	return error;
10851512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
10861512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10871512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    *property = gitem->gproperties;
10881512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10891512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    /* If the glyph was found in the MarkAttachmentClass table,
10901512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     * then that class value is the high byte of the result,
10911512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     * otherwise the low byte contains the basic type of the glyph
10921512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     * as defined by the GlyphClassDef table.
10931512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     */
10941512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( *property & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS  )
10951512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      basic_glyph_class = HB_GDEF_MARK;
10961512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    else
10971512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      basic_glyph_class = *property;
10981512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
10991512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    /* Return Not_Covered, if, for example, basic_glyph_class
11001512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     * is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES
11011512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     */
11021512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( flags & basic_glyph_class )
11031512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      return HB_Err_Not_Covered;
11041512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11051512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    /* The high byte of LookupFlags has the meaning
11061512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     * "ignore marks of attachment type different than
11071512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     * the attachment type specified."
11081512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     */
11091512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    desired_attachment_class = flags & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS;
11101512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    if ( desired_attachment_class )
11111512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {
11121512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( basic_glyph_class == HB_GDEF_MARK &&
11131512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	   *property != desired_attachment_class )
11141512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	return HB_Err_Not_Covered;
11151512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
11161512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  } else {
11171512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      *property = 0;
11181512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
11191512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11201512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return HB_Err_Ok;
11211512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
11221512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11231512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodHB_INTERNAL HB_Error
11241512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,
11251512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod						  HB_Stream      stream,
11261512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod						  HB_Lookup*     lo,
11271512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod						  HB_UShort      num_lookups)
11281512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod{
11291512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_Error   error = HB_Err_Ok;
11301512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  HB_UShort  i;
11311512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11321512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  /* We now check the LookupFlags for values larger than 0xFF to find
11331512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     out whether we need to load the `MarkAttachClassDef' field of the
11341512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     GDEF table -- this hack is necessary for OpenType 1.2 tables since
11351512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     the version field of the GDEF table hasn't been incremented.
11361512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11371512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     For constructed GDEF tables, we only load it if
11381512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     `MarkAttachClassDef_offset' is not zero (nevertheless, a build of
11391512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod     a constructed mark attach table is not supported currently).       */
11401512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11411512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  if ( gdef &&
11421512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod       gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )
11431512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  {
11441512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    for ( i = 0; i < num_lookups; i++ )
11451512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    {
11461512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11471512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      if ( lo[i].LookupFlag & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
11481512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      {
11491512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||
11501512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	     ( error = _HB_OPEN_Load_ClassDefinition( &gdef->MarkAttachClassDef,
11511512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod					     256, stream ) ) != HB_Err_Ok )
11521512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	  goto Done;
11531512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11541512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod	break;
11551512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod      }
11561512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod    }
11571512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  }
11581512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11591512a7357513b72e2a07dda706a176bb23d694e9Behdad EsfahbodDone:
11601512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod  return error;
11611512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod}
11621512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod
11631512a7357513b72e2a07dda706a176bb23d694e9Behdad Esfahbod/* END */
1164