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