18#ifdef FT_CONFIG_OPTION_USE_HARFBUZZ
40 af_validate_coverage( FT_Byte* table,
50 if ( table_limit < p + 4 )
53 format = FT_NEXT_USHORT( p );
56 FT_UInt glyphCount = FT_NEXT_USHORT( p );
60 if ( table_limit < p + glyphCount * 2 )
65 else if ( format == 2 )
67 FT_UInt rangeCount = FT_NEXT_USHORT( p );
68 FT_Byte* limit = p + rangeCount * 6;
71 if ( table_limit < limit )
76 FT_UInt startGlyphID = FT_NEXT_USHORT( p );
77 FT_UInt endGlyphID = FT_NEXT_USHORT( p );
80 if ( startGlyphID > endGlyphID )
83 count += endGlyphID - startGlyphID + 1;
100 af_validate_single_subst1( FT_Byte* table,
101 FT_Byte* table_limit )
110 coverage = table + FT_PEEK_USHORT( table + 2 );
111 if ( !af_validate_coverage( coverage, table_limit, NULL ) )
121 af_validate_single_subst2( FT_Byte* table,
122 FT_Byte* table_limit )
129 FT_Byte* p = table + 2;
134 coverage = table + FT_NEXT_USHORT( p );
135 if ( !af_validate_coverage( coverage, table_limit, &num_glyphs ) )
138 glyphCount = FT_NEXT_USHORT( p );
140 if ( table_limit < p + glyphCount * 2 )
143 if ( glyphCount != num_glyphs )
151 af_validate_alternate( FT_Byte* table,
152 FT_Byte* table_limit )
155 FT_UInt alternateSetCount;
159 FT_Byte* p = table + 2;
165 coverage = table + FT_NEXT_USHORT( p );
166 if ( !af_validate_coverage( coverage, table_limit, &num_glyphs ) )
169 alternateSetCount = FT_NEXT_USHORT( p );
170 limit = p + alternateSetCount * 2;
171 if ( table_limit < limit )
174 if ( alternateSetCount != num_glyphs )
179 FT_Byte* alternate_set;
183 alternate_set = table + FT_NEXT_USHORT( p );
184 if ( table_limit < alternate_set + 2 )
187 glyphCount = FT_PEEK_USHORT( alternate_set );
189 if ( table_limit < alternate_set + 2 + glyphCount * 2 )
199 af_validate_lookup_table( FT_Byte* table,
200 FT_Byte* table_limit )
203 FT_UInt real_lookupType = 0;
204 FT_UInt subtableCount;
210 if ( table_limit < p + 6 )
213 lookupType = FT_NEXT_USHORT( p );
217 subtableCount = FT_NEXT_USHORT( p );
218 limit = p + subtableCount * 2;
219 if ( table_limit < limit )
224 FT_Byte* subtable = table + FT_NEXT_USHORT( p );
228 if ( lookupType == 7 )
231 FT_Byte* q = subtable;
234 if ( table_limit < q + 8 )
237 if ( FT_NEXT_USHORT( q ) != 1 )
240 if ( real_lookupType == 0 )
241 real_lookupType = FT_NEXT_USHORT( q );
242 else if ( real_lookupType != FT_NEXT_USHORT( q ) )
245 subtable += FT_PEEK_ULONG( q );
248 real_lookupType = lookupType;
251 if ( table_limit < subtable + 6 )
254 format = FT_PEEK_USHORT( subtable );
256 if ( real_lookupType == 1 )
260 if ( !af_validate_single_subst1( subtable, table_limit ) )
263 else if ( format == 2 )
265 if ( !af_validate_single_subst2( subtable, table_limit ) )
271 else if ( real_lookupType == 3 )
275 if ( !af_validate_alternate( subtable, table_limit ) )
290 af_parse_gsub( AF_FaceGlobals globals )
292 FT_Error error = FT_Err_Ok;
294 FT_Face face = globals->face;
295 FT_Memory memory = face->memory;
297 FT_ULong gsub_length;
301 FT_UInt32* gsub_lookups_single_alternate;
303 FT_UInt lookupListOffset;
304 FT_Byte* lookup_list;
313 globals->gsub = NULL;
314 globals->gsub_lookups_single_alternate = NULL;
319 gsub_lookups_single_alternate = NULL;
322 if ( FT_Load_Sfnt_Table( face, TTAG_GSUB, 0, NULL, &gsub_length ) )
325 if ( FT_QALLOC( gsub, gsub_length ) )
328 if ( FT_Load_Sfnt_Table( face, TTAG_GSUB, 0, gsub, &gsub_length ) )
331 if ( gsub_length < 10 )
334 lookupListOffset = FT_PEEK_USHORT( gsub + 8 );
335 if ( gsub_length < lookupListOffset + 2 )
338 lookupCount = FT_PEEK_USHORT( gsub + lookupListOffset );
339 if ( gsub_length < lookupListOffset + 2 + lookupCount * 2 )
342 if ( FT_NEW_ARRAY( gsub_lookups_single_alternate, lookupCount ) )
345 gsub_limit = gsub + gsub_length;
346 lookup_list = gsub + lookupListOffset;
348 limit = p + lookupCount * 2;
352 FT_UInt lookupOffset = FT_NEXT_USHORT( p );
355 if ( af_validate_lookup_table( lookup_list + lookupOffset,
359 gsub_lookups_single_alternate[idx] = lookupListOffset + lookupOffset;
365 globals->gsub = gsub;
366 globals->gsub_lookups_single_alternate = gsub_lookups_single_alternate;
372 FT_FREE( gsub_lookups_single_alternate );
384 af_coverage_format( FT_Byte* coverage )
386 return FT_PEEK_USHORT( coverage );
391 af_coverage_start( FT_Byte* coverage )
398 af_coverage_limit( FT_Byte* coverage )
400 if ( af_coverage_format( coverage ) == 1 )
402 FT_UInt glyphCount = FT_PEEK_USHORT( coverage + 2 );
405 return af_coverage_start( coverage ) + glyphCount * 2;
409 FT_UInt rangeCount = FT_PEEK_USHORT( coverage + 2 );
412 return af_coverage_start( coverage ) + rangeCount * 6;
417 typedef struct AF_CoverageIteratorRec_* AF_CoverageIterator;
419 typedef struct AF_CoverageIteratorRec_
427 FT_UInt16 glyph_limit;
429 } AF_CoverageIteratorRec;
433 af_coverage_iterator( AF_CoverageIterator iter,
436 if ( iter->p >= iter->limit )
439 if ( iter->format == 1 )
440 *glyph = FT_NEXT_USHORT( iter->p );
443 if ( iter->glyph > iter->glyph_limit )
445 iter->glyph = FT_NEXT_USHORT( iter->p );
446 iter->glyph_limit = FT_NEXT_USHORT( iter->p );
451 *glyph = iter->glyph++;
458 static AF_CoverageIteratorRec
459 af_coverage_iterator_init( FT_Byte* coverage )
461 AF_CoverageIteratorRec iterator;
464 iterator.format = af_coverage_format( coverage );
465 iterator.p = af_coverage_start( coverage );
466 iterator.limit = af_coverage_limit( coverage );
468 iterator.glyph_limit = 0;
493 af_hash_insert( FT_UInt16 glyph,
494 FT_UInt16 substitute,
500 size_t* value = ft_hash_num_lookup( glyph, map );
505 error = ft_hash_num_insert( glyph, substitute, map, memory );
512 FT_UInt mask = ( (FT_UInt)*value & 0xFFFF0000U ) + 0x10000U;
516 error = ft_hash_num_insert( (FT_Int)( glyph | mask ),
532 af_map_single_subst1( FT_Hash map,
538 FT_Byte* coverage = table + FT_PEEK_USHORT( table + 2 );
539 FT_UInt deltaGlyphID = FT_PEEK_USHORT( table + 4 );
541 AF_CoverageIteratorRec iterator = af_coverage_iterator_init( coverage );
546 while ( af_coverage_iterator( &iterator, &glyph ) )
549 FT_UInt16 subst = (FT_UInt16)( ( glyph + deltaGlyphID ) % 0x10000U );
552 error = af_hash_insert( glyph, subst, map, memory );
562 af_map_single_subst2( FT_Hash map,
568 FT_Byte* coverage = table + FT_PEEK_USHORT( table + 2 );
570 AF_CoverageIteratorRec iterator = af_coverage_iterator_init( coverage );
573 FT_Byte* p = table + 6;
576 while ( af_coverage_iterator( &iterator, &glyph ) )
578 FT_UInt16 subst = FT_NEXT_USHORT( p );
581 error = af_hash_insert( glyph, subst, map, memory );
591 af_map_alternate( FT_Hash map,
597 FT_Byte* coverage = table + FT_PEEK_USHORT( table + 2 );
599 AF_CoverageIteratorRec iterator = af_coverage_iterator_init( coverage );
602 FT_Byte* p = table + 6;
605 while ( af_coverage_iterator( &iterator, &glyph ) )
607 FT_Byte* alternate_set = table + FT_NEXT_USHORT( p );
609 FT_Byte* q = alternate_set;
610 FT_UInt glyphCount = FT_NEXT_USHORT( q );
615 for ( i = 0; i < glyphCount; i++ )
617 FT_UInt16 subst = FT_NEXT_USHORT( q );
620 error = af_hash_insert( glyph, subst, map, memory );
631 FT_LOCAL_DEF( FT_Error )
632 af_map_lookup( AF_FaceGlobals globals,
634 FT_UInt32 lookup_offset )
636 FT_Face face = globals->face;
637 FT_Memory memory = face->memory;
639 FT_Byte* table = globals->gsub + lookup_offset;
641 FT_UInt lookupType = FT_PEEK_USHORT( table );
642 FT_UInt subtableCount = FT_PEEK_USHORT( table + 4 );
644 FT_Byte* p = table + 6;
645 FT_Byte* limit = p + subtableCount * 2;
652 FT_UInt real_lookupType = lookupType;
654 FT_Byte* subtable = table + FT_NEXT_USHORT( p );
657 if ( lookupType == 7 )
659 FT_Byte* q = subtable + 2;
662 real_lookupType = FT_NEXT_USHORT( q );
663 subtable += FT_PEEK_ULONG( q );
666 if ( real_lookupType == 1 )
668 FT_UInt format = FT_PEEK_USHORT( subtable );
671 error = ( format == 1 )
672 ? af_map_single_subst1( map, subtable, memory )
673 : af_map_single_subst2( map, subtable, memory );
676 error = af_map_alternate( map, subtable, memory );
689typedef int afgsub_dummy_;