| Index: third_party/harfbuzz/src/harfbuzz-gdef.c
|
| diff --git a/third_party/harfbuzz/src/harfbuzz-gdef.c b/third_party/harfbuzz/src/harfbuzz-gdef.c
|
| deleted file mode 100644
|
| index ff3a1f4738ee61220929125c69f27992a856dbf0..0000000000000000000000000000000000000000
|
| --- a/third_party/harfbuzz/src/harfbuzz-gdef.c
|
| +++ /dev/null
|
| @@ -1,1159 +0,0 @@
|
| -/*
|
| - * Copyright (C) 1998-2004 David Turner and Werner Lemberg
|
| - * Copyright (C) 2006 Behdad Esfahbod
|
| - *
|
| - * This is part of HarfBuzz, an OpenType Layout engine library.
|
| - *
|
| - * Permission is hereby granted, without written agreement and without
|
| - * license or royalty fees, to use, copy, modify, and distribute this
|
| - * software and its documentation for any purpose, provided that the
|
| - * above copyright notice and the following two paragraphs appear in
|
| - * all copies of this software.
|
| - *
|
| - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
| - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
| - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
| - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
| - * DAMAGE.
|
| - *
|
| - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
| - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
| - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
| - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
| - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
| - */
|
| -
|
| -#include "harfbuzz-impl.h"
|
| -#include "harfbuzz-gdef-private.h"
|
| -#include "harfbuzz-open-private.h"
|
| -
|
| -static HB_Error Load_AttachList( HB_AttachList* al,
|
| - HB_Stream stream );
|
| -static HB_Error Load_LigCaretList( HB_LigCaretList* lcl,
|
| - HB_Stream stream );
|
| -
|
| -static void Free_AttachList( HB_AttachList* al);
|
| -static void Free_LigCaretList( HB_LigCaretList* lcl);
|
| -
|
| -static void Free_NewGlyphClasses( HB_GDEFHeader* gdef);
|
| -
|
| -
|
| -
|
| -/* GDEF glyph classes */
|
| -
|
| -#define UNCLASSIFIED_GLYPH 0
|
| -#define SIMPLE_GLYPH 1
|
| -#define LIGATURE_GLYPH 2
|
| -#define MARK_GLYPH 3
|
| -#define COMPONENT_GLYPH 4
|
| -
|
| -
|
| -
|
| -
|
| -
|
| -
|
| -HB_Error HB_New_GDEF_Table( HB_GDEFHeader** retptr )
|
| -{
|
| - HB_Error error;
|
| -
|
| - HB_GDEFHeader* gdef;
|
| -
|
| - if ( !retptr )
|
| - return ERR(HB_Err_Invalid_Argument);
|
| -
|
| - if ( ALLOC( gdef, sizeof( *gdef ) ) )
|
| - return error;
|
| -
|
| - 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 HB_Err_Ok;
|
| -}
|
| -
|
| -
|
| -HB_Error HB_Load_GDEF_Table( HB_Stream stream,
|
| - HB_GDEFHeader** retptr )
|
| -{
|
| - HB_Error error;
|
| - HB_UInt cur_offset, new_offset, base_offset;
|
| -
|
| - HB_GDEFHeader* gdef;
|
| -
|
| -
|
| - if ( !retptr )
|
| - return ERR(HB_Err_Invalid_Argument);
|
| -
|
| - if ( GOTO_Table( TTAG_GDEF ) )
|
| - return error;
|
| -
|
| - if (( error = HB_New_GDEF_Table ( &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 = _HB_OPEN_Load_ClassDefinition( &gdef->GlyphClassDef, 5,
|
| - stream ) ) != HB_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 ) ) != HB_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 ) ) != HB_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 HB_Err_Ok;
|
| -
|
| -Fail3:
|
| - Free_LigCaretList( &gdef->LigCaretList );
|
| -
|
| -Fail2:
|
| - Free_AttachList( &gdef->AttachList );
|
| -
|
| -Fail1:
|
| - _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );
|
| -
|
| -Fail0:
|
| - FREE( gdef );
|
| -
|
| - return error;
|
| -}
|
| -
|
| -
|
| -HB_Error HB_Done_GDEF_Table ( HB_GDEFHeader* gdef )
|
| -{
|
| - Free_LigCaretList( &gdef->LigCaretList );
|
| - Free_AttachList( &gdef->AttachList );
|
| - _HB_OPEN_Free_ClassDefinition( &gdef->GlyphClassDef );
|
| - _HB_OPEN_Free_ClassDefinition( &gdef->MarkAttachClassDef );
|
| -
|
| - Free_NewGlyphClasses( gdef );
|
| -
|
| - FREE( gdef );
|
| -
|
| - return HB_Err_Ok;
|
| -}
|
| -
|
| -
|
| -
|
| -
|
| -/*******************************
|
| - * AttachList related functions
|
| - *******************************/
|
| -
|
| -
|
| -/* AttachPoint */
|
| -
|
| -static HB_Error Load_AttachPoint( HB_AttachPoint* ap,
|
| - HB_Stream stream )
|
| -{
|
| - HB_Error error;
|
| -
|
| - HB_UShort n, count;
|
| - HB_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, HB_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 HB_Err_Ok;
|
| -}
|
| -
|
| -
|
| -static void Free_AttachPoint( HB_AttachPoint* ap )
|
| -{
|
| - FREE( ap->PointIndex );
|
| -}
|
| -
|
| -
|
| -/* AttachList */
|
| -
|
| -static HB_Error Load_AttachList( HB_AttachList* al,
|
| - HB_Stream stream )
|
| -{
|
| - HB_Error error;
|
| -
|
| - HB_UShort n, m, count;
|
| - HB_UInt cur_offset, new_offset, base_offset;
|
| -
|
| - HB_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 = _HB_OPEN_Load_Coverage( &al->Coverage, stream ) ) != HB_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, HB_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 ) ) != HB_Err_Ok )
|
| - goto Fail1;
|
| - (void)FILE_Seek( cur_offset );
|
| - }
|
| -
|
| - al->loaded = TRUE;
|
| -
|
| - return HB_Err_Ok;
|
| -
|
| -Fail1:
|
| - for ( m = 0; m < n; m++ )
|
| - Free_AttachPoint( &ap[m] );
|
| -
|
| - FREE( ap );
|
| -
|
| -Fail2:
|
| - _HB_OPEN_Free_Coverage( &al->Coverage );
|
| - return error;
|
| -}
|
| -
|
| -
|
| -static void Free_AttachList( HB_AttachList* al)
|
| -{
|
| - HB_UShort n, count;
|
| -
|
| - HB_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] );
|
| -
|
| - FREE( ap );
|
| - }
|
| -
|
| - _HB_OPEN_Free_Coverage( &al->Coverage );
|
| -}
|
| -
|
| -
|
| -
|
| -/*********************************
|
| - * LigCaretList related functions
|
| - *********************************/
|
| -
|
| -
|
| -/* CaretValueFormat1 */
|
| -/* CaretValueFormat2 */
|
| -/* CaretValueFormat3 */
|
| -/* CaretValueFormat4 */
|
| -
|
| -static HB_Error Load_CaretValue( HB_CaretValue* cv,
|
| - HB_Stream stream )
|
| -{
|
| - HB_Error error;
|
| -
|
| - HB_UInt 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 = _HB_OPEN_Load_Device( &cv->cvf.cvf3.Device,
|
| - stream ) ) != HB_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 ERR(HB_Err_Invalid_SubTable_Format);
|
| - }
|
| -
|
| - return HB_Err_Ok;
|
| -}
|
| -
|
| -
|
| -static void Free_CaretValue( HB_CaretValue* cv)
|
| -{
|
| - if ( cv->CaretValueFormat == 3 )
|
| - _HB_OPEN_Free_Device( &cv->cvf.cvf3.Device );
|
| -}
|
| -
|
| -
|
| -/* LigGlyph */
|
| -
|
| -static HB_Error Load_LigGlyph( HB_LigGlyph* lg,
|
| - HB_Stream stream )
|
| -{
|
| - HB_Error error;
|
| -
|
| - HB_UShort n, m, count;
|
| - HB_UInt cur_offset, new_offset, base_offset;
|
| -
|
| - HB_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, HB_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 ) ) != HB_Err_Ok )
|
| - goto Fail;
|
| - (void)FILE_Seek( cur_offset );
|
| - }
|
| -
|
| - return HB_Err_Ok;
|
| -
|
| -Fail:
|
| - for ( m = 0; m < n; m++ )
|
| - Free_CaretValue( &cv[m] );
|
| -
|
| - FREE( cv );
|
| - return error;
|
| -}
|
| -
|
| -
|
| -static void Free_LigGlyph( HB_LigGlyph* lg)
|
| -{
|
| - HB_UShort n, count;
|
| -
|
| - HB_CaretValue* cv;
|
| -
|
| -
|
| - if ( lg->CaretValue )
|
| - {
|
| - count = lg->CaretCount;
|
| - cv = lg->CaretValue;
|
| -
|
| - for ( n = 0; n < count; n++ )
|
| - Free_CaretValue( &cv[n] );
|
| -
|
| - FREE( cv );
|
| - }
|
| -}
|
| -
|
| -
|
| -/* LigCaretList */
|
| -
|
| -static HB_Error Load_LigCaretList( HB_LigCaretList* lcl,
|
| - HB_Stream stream )
|
| -{
|
| - HB_Error error;
|
| -
|
| - HB_UShort m, n, count;
|
| - HB_UInt cur_offset, new_offset, base_offset;
|
| -
|
| - HB_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 = _HB_OPEN_Load_Coverage( &lcl->Coverage, stream ) ) != HB_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, HB_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 ) ) != HB_Err_Ok )
|
| - goto Fail1;
|
| - (void)FILE_Seek( cur_offset );
|
| - }
|
| -
|
| - lcl->loaded = TRUE;
|
| -
|
| - return HB_Err_Ok;
|
| -
|
| -Fail1:
|
| - for ( m = 0; m < n; m++ )
|
| - Free_LigGlyph( &lg[m] );
|
| -
|
| - FREE( lg );
|
| -
|
| -Fail2:
|
| - _HB_OPEN_Free_Coverage( &lcl->Coverage );
|
| - return error;
|
| -}
|
| -
|
| -
|
| -static void Free_LigCaretList( HB_LigCaretList* lcl )
|
| -{
|
| - HB_UShort n, count;
|
| -
|
| - HB_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] );
|
| -
|
| - FREE( lg );
|
| - }
|
| -
|
| - _HB_OPEN_Free_Coverage( &lcl->Coverage );
|
| -}
|
| -
|
| -
|
| -
|
| -/***********
|
| - * GDEF API
|
| - ***********/
|
| -
|
| -
|
| -static HB_UShort Get_New_Class( HB_GDEFHeader* gdef,
|
| - HB_UShort glyphID,
|
| - HB_UShort index )
|
| -{
|
| - HB_UShort glyph_index, array_index, count;
|
| - HB_UShort byte, bits;
|
| -
|
| - HB_ClassRangeRecord* gcrr;
|
| - HB_UShort** ngc;
|
| -
|
| -
|
| - if ( glyphID >= gdef->LastGlyph )
|
| - return 0;
|
| -
|
| - count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
|
| - gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
|
| - ngc = gdef->NewGlyphClasses;
|
| -
|
| - if ( index < count && glyphID < gcrr[index].Start )
|
| - {
|
| - array_index = index;
|
| - 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];
|
| - bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
|
| -
|
| - return bits & 0x000F;
|
| -}
|
| -
|
| -
|
| -
|
| -HB_Error HB_GDEF_Get_Glyph_Property( HB_GDEFHeader* gdef,
|
| - HB_UShort glyphID,
|
| - HB_UShort* property )
|
| -{
|
| - HB_UShort class = 0, index = 0; /* shut compiler up */
|
| -
|
| - HB_Error error;
|
| -
|
| -
|
| - if ( !gdef || !property )
|
| - return ERR(HB_Err_Invalid_Argument);
|
| -
|
| - /* first, we check for mark attach classes */
|
| -
|
| - if ( gdef->MarkAttachClassDef.loaded )
|
| - {
|
| - error = _HB_OPEN_Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index );
|
| - if ( error && error != HB_Err_Not_Covered )
|
| - return error;
|
| - if ( !error )
|
| - {
|
| - *property = class << 8;
|
| - return HB_Err_Ok;
|
| - }
|
| - }
|
| -
|
| - error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
|
| - if ( error && error != HB_Err_Not_Covered )
|
| - return error;
|
| -
|
| - /* if we have a constructed class table, check whether additional
|
| - values have been assigned */
|
| -
|
| - if ( error == HB_Err_Not_Covered && gdef->NewGlyphClasses )
|
| - class = Get_New_Class( gdef, glyphID, index );
|
| -
|
| - switch ( class )
|
| - {
|
| - default:
|
| - case UNCLASSIFIED_GLYPH:
|
| - *property = 0;
|
| - break;
|
| -
|
| - case SIMPLE_GLYPH:
|
| - *property = HB_GDEF_BASE_GLYPH;
|
| - break;
|
| -
|
| - case LIGATURE_GLYPH:
|
| - *property = HB_GDEF_LIGATURE;
|
| - break;
|
| -
|
| - case MARK_GLYPH:
|
| - *property = HB_GDEF_MARK;
|
| - break;
|
| -
|
| - case COMPONENT_GLYPH:
|
| - *property = HB_GDEF_COMPONENT;
|
| - break;
|
| - }
|
| -
|
| - return HB_Err_Ok;
|
| -}
|
| -
|
| -
|
| -static HB_Error Make_ClassRange( HB_ClassDefinition* cd,
|
| - HB_UShort start,
|
| - HB_UShort end,
|
| - HB_UShort class )
|
| -{
|
| - HB_Error error;
|
| - HB_UShort index;
|
| -
|
| - HB_ClassDefFormat2* cdf2;
|
| - HB_ClassRangeRecord* crr;
|
| -
|
| -
|
| - cdf2 = &cd->cd.cd2;
|
| -
|
| - if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,
|
| - cdf2->ClassRangeCount + 1 ,
|
| - HB_ClassRangeRecord ) )
|
| - return error;
|
| -
|
| - cdf2->ClassRangeCount++;
|
| -
|
| - crr = cdf2->ClassRangeRecord;
|
| - index = cdf2->ClassRangeCount - 1;
|
| -
|
| - crr[index].Start = start;
|
| - crr[index].End = end;
|
| - crr[index].Class = class;
|
| -
|
| - return HB_Err_Ok;
|
| -}
|
| -
|
| -
|
| -
|
| -HB_Error HB_GDEF_Build_ClassDefinition( HB_GDEFHeader* gdef,
|
| - HB_UShort num_glyphs,
|
| - HB_UShort glyph_count,
|
| - HB_UShort* glyph_array,
|
| - HB_UShort* class_array )
|
| -{
|
| - HB_UShort start, curr_glyph, curr_class;
|
| - HB_UShort n, m, count;
|
| - HB_Error error;
|
| -
|
| - HB_ClassDefinition* gcd;
|
| - HB_ClassRangeRecord* gcrr;
|
| - HB_UShort** ngc;
|
| -
|
| -
|
| - if ( !gdef || !glyph_array || !class_array )
|
| - return ERR(HB_Err_Invalid_Argument);
|
| -
|
| - gcd = &gdef->GlyphClassDef;
|
| -
|
| - /* We build a format 2 table */
|
| -
|
| - gcd->ClassFormat = 2;
|
| -
|
| - 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 = ERR(HB_Err_Invalid_Argument);
|
| - goto Fail4;
|
| - }
|
| -
|
| - glyph_count--;
|
| -
|
| - for ( n = 0; n < glyph_count + 1; 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) ) != HB_Err_Ok )
|
| - goto Fail3;
|
| - }
|
| - else
|
| - {
|
| - if ( curr_glyph == 0xFFFF )
|
| - {
|
| - error = ERR(HB_Err_Invalid_Argument);
|
| - goto Fail3;
|
| - }
|
| - else
|
| - curr_glyph++;
|
| - }
|
| - }
|
| - else
|
| - {
|
| - if ( ( error = Make_ClassRange( gcd, start,
|
| - curr_glyph - 1,
|
| - curr_class) ) != HB_Err_Ok )
|
| - goto Fail3;
|
| -
|
| - if ( curr_glyph > glyph_array[n] )
|
| - {
|
| - error = ERR(HB_Err_Invalid_Argument);
|
| - goto Fail3;
|
| - }
|
| -
|
| - start = glyph_array[n];
|
| - curr_class = class_array[n];
|
| - curr_glyph = start;
|
| -
|
| - if ( curr_class >= 5 )
|
| - {
|
| - error = ERR(HB_Err_Invalid_Argument);
|
| - goto Fail3;
|
| - }
|
| -
|
| - if ( n == glyph_count )
|
| - {
|
| - if ( ( error = Make_ClassRange( gcd, start,
|
| - curr_glyph,
|
| - curr_class) ) != HB_Err_Ok )
|
| - goto Fail3;
|
| - }
|
| - else
|
| - {
|
| - if ( curr_glyph == 0xFFFF )
|
| - {
|
| - error = ERR(HB_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, HB_UShort* ) )
|
| - goto Fail3;
|
| -
|
| - 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 ( count > 0 )
|
| - {
|
| - if ( gcrr[0].Start )
|
| - {
|
| - if ( ALLOC_ARRAY( ngc[0], ( gcrr[0].Start + 3 ) / 4, HB_UShort ) )
|
| - goto Fail2;
|
| - }
|
| -
|
| - 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 + 2 ) / 4,
|
| - HB_UShort ) )
|
| - goto Fail1;
|
| - }
|
| -
|
| - if ( gcrr[count - 1].End != num_glyphs - 1 )
|
| - {
|
| - if ( ALLOC_ARRAY( ngc[count],
|
| - ( num_glyphs - gcrr[count - 1].End + 2 ) / 4,
|
| - HB_UShort ) )
|
| - goto Fail1;
|
| - }
|
| - }
|
| - else if ( num_glyphs > 0 )
|
| - {
|
| - if ( ALLOC_ARRAY( ngc[count],
|
| - ( num_glyphs + 3 ) / 4,
|
| - HB_UShort ) )
|
| - goto Fail2;
|
| - }
|
| -
|
| - gdef->LastGlyph = num_glyphs - 1;
|
| -
|
| - gdef->MarkAttachClassDef_offset = 0L;
|
| - gdef->MarkAttachClassDef.loaded = FALSE;
|
| -
|
| - gcd->loaded = TRUE;
|
| -
|
| - return HB_Err_Ok;
|
| -
|
| -Fail1:
|
| - for ( m = 0; m < n; m++ )
|
| - FREE( ngc[m] );
|
| -
|
| -Fail2:
|
| - FREE( gdef->NewGlyphClasses );
|
| -
|
| -Fail3:
|
| - FREE( gcd->cd.cd2.ClassRangeRecord );
|
| -
|
| -Fail4:
|
| - return error;
|
| -}
|
| -
|
| -
|
| -static void Free_NewGlyphClasses( HB_GDEFHeader* gdef )
|
| -{
|
| - HB_UShort** ngc;
|
| - HB_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 );
|
| - }
|
| -}
|
| -
|
| -
|
| -HB_INTERNAL HB_Error
|
| -_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,
|
| - HB_UShort glyphID,
|
| - HB_UShort property )
|
| -{
|
| - HB_Error error;
|
| - HB_UShort class, new_class, index = 0; /* shut compiler up */
|
| - HB_UShort byte, bits, mask;
|
| - HB_UShort array_index, glyph_index, count;
|
| -
|
| - HB_ClassRangeRecord* gcrr;
|
| - HB_UShort** ngc;
|
| -
|
| -
|
| - error = _HB_OPEN_Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
|
| - if ( error && error != HB_Err_Not_Covered )
|
| - return error;
|
| -
|
| - /* we don't accept glyphs covered in `GlyphClassDef' */
|
| -
|
| - if ( !error )
|
| - return HB_Err_Not_Covered;
|
| -
|
| - switch ( property )
|
| - {
|
| - case 0:
|
| - new_class = UNCLASSIFIED_GLYPH;
|
| - break;
|
| -
|
| - case HB_GDEF_BASE_GLYPH:
|
| - new_class = SIMPLE_GLYPH;
|
| - break;
|
| -
|
| - case HB_GDEF_LIGATURE:
|
| - new_class = LIGATURE_GLYPH;
|
| - break;
|
| -
|
| - case HB_GDEF_MARK:
|
| - new_class = MARK_GLYPH;
|
| - break;
|
| -
|
| - case HB_GDEF_COMPONENT:
|
| - new_class = COMPONENT_GLYPH;
|
| - break;
|
| -
|
| - default:
|
| - return ERR(HB_Err_Invalid_Argument);
|
| - }
|
| -
|
| - count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
|
| - gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
|
| - ngc = gdef->NewGlyphClasses;
|
| -
|
| - if ( index < count && glyphID < gcrr[index].Start )
|
| - {
|
| - array_index = index;
|
| - 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];
|
| - 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] &= mask;
|
| - ngc[array_index][glyph_index / 4] |= bits;
|
| - }
|
| -
|
| - return HB_Err_Ok;
|
| -}
|
| -
|
| -
|
| -HB_INTERNAL HB_Error
|
| -_HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
|
| - HB_GlyphItem gitem,
|
| - HB_UShort flags,
|
| - HB_UShort* property )
|
| -{
|
| - HB_Error error;
|
| -
|
| - if ( gdef )
|
| - {
|
| - HB_UShort basic_glyph_class;
|
| - HB_UShort desired_attachment_class;
|
| -
|
| - if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN )
|
| - {
|
| - error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );
|
| - if ( error )
|
| - return error;
|
| - }
|
| -
|
| - *property = gitem->gproperties;
|
| -
|
| - /* 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 & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
|
| - basic_glyph_class = HB_GDEF_MARK;
|
| - else
|
| - basic_glyph_class = *property;
|
| -
|
| - /* Return Not_Covered, if, for example, basic_glyph_class
|
| - * is HB_GDEF_LIGATURE and LookFlags includes HB_LOOKUP_FLAG_IGNORE_LIGATURES
|
| - */
|
| - if ( flags & basic_glyph_class )
|
| - return HB_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 & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS;
|
| - if ( desired_attachment_class )
|
| - {
|
| - if ( basic_glyph_class == HB_GDEF_MARK &&
|
| - *property != desired_attachment_class )
|
| - return HB_Err_Not_Covered;
|
| - }
|
| - } else {
|
| - *property = 0;
|
| - }
|
| -
|
| - return HB_Err_Ok;
|
| -}
|
| -
|
| -HB_INTERNAL HB_Error
|
| -_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,
|
| - HB_Stream stream,
|
| - HB_Lookup* lo,
|
| - HB_UShort num_lookups)
|
| -{
|
| - HB_Error error = HB_Err_Ok;
|
| - HB_UShort i;
|
| -
|
| - /* We now check the LookupFlags for values larger than 0xFF to find
|
| - out whether we need to load the `MarkAttachClassDef' field of the
|
| - GDEF table -- this hack is necessary for OpenType 1.2 tables since
|
| - the version field of the GDEF table hasn't been incremented.
|
| -
|
| - For constructed GDEF tables, we only load it if
|
| - `MarkAttachClassDef_offset' is not zero (nevertheless, a build of
|
| - a constructed mark attach table is not supported currently). */
|
| -
|
| - if ( gdef &&
|
| - gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )
|
| - {
|
| - for ( i = 0; i < num_lookups; i++ )
|
| - {
|
| -
|
| - if ( lo[i].LookupFlag & HB_LOOKUP_FLAG_IGNORE_SPECIAL_MARKS )
|
| - {
|
| - if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||
|
| - ( error = _HB_OPEN_Load_ClassDefinition( &gdef->MarkAttachClassDef,
|
| - 256, stream ) ) != HB_Err_Ok )
|
| - goto Done;
|
| -
|
| - break;
|
| - }
|
| - }
|
| - }
|
| -
|
| -Done:
|
| - return error;
|
| -}
|
| -
|
| -/* END */
|
|
|