... |
... |
@@ -55,7 +55,7 @@ adjustment_database[] = |
55
|
55
|
{0xEC, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0},
|
56
|
56
|
{0xED, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0},
|
57
|
57
|
{0xEE, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0},
|
58
|
|
- {0xF1, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 1}, /*n with tilde*/
|
|
58
|
+ {0xF1, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0}, /*n with tilde*/
|
59
|
59
|
{0xF2, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0},
|
60
|
60
|
{0xF3, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0},
|
61
|
61
|
{0xF4, AF_VERTICAL_ADJUSTMENT_TOP_CONTOUR_UP, 0},
|
... |
... |
@@ -446,16 +446,31 @@ af_all_glyph_variants( FT_Face face, |
446
|
446
|
hb_face_t *hb_face = hb_font_get_face( hb_font );
|
447
|
447
|
|
448
|
448
|
/*The set of all feature tags in the font*/
|
449
|
|
- hb_set_t *feature_tags = hb_set_create();
|
|
449
|
+ hb_set_t *feature_tags = hb_set_create();
|
|
450
|
+ hb_set_t *type_3_lookup_indicies = hb_set_create();
|
|
451
|
+ hb_buffer_t *codepoint_buffer = hb_buffer_create();
|
|
452
|
+ hb_codepoint_t *type_3_alternate_glyphs_buffer;
|
450
|
453
|
if ( !hb_set_allocation_successful( feature_tags ) )
|
451
|
454
|
{
|
452
|
|
- return FT_Err_Out_Of_Memory;
|
|
455
|
+ error = FT_Err_Out_Of_Memory;
|
|
456
|
+ goto Exit;
|
|
457
|
+ }
|
|
458
|
+ if ( !hb_buffer_allocation_successful( codepoint_buffer ) )
|
|
459
|
+ {
|
|
460
|
+ error = FT_Err_Out_Of_Memory;
|
|
461
|
+ goto Exit;
|
|
462
|
+ }
|
|
463
|
+ if ( !hb_set_allocation_successful ( type_3_lookup_indicies ) )
|
|
464
|
+ {
|
|
465
|
+ error = FT_Err_Out_Of_Memory;
|
|
466
|
+ goto Exit;
|
453
|
467
|
}
|
454
|
468
|
|
455
|
469
|
/*populate feature_tags using the output of hb_ot_layout_table_get_feature_tags*/
|
456
|
470
|
FT_Bool feature_list_done = 0;
|
457
|
471
|
unsigned int start_offset = 0;
|
458
|
|
- while ( !feature_list_done ) {
|
|
472
|
+ while ( !feature_list_done )
|
|
473
|
+ {
|
459
|
474
|
unsigned int feature_count = 20;
|
460
|
475
|
hb_tag_t tags[20];
|
461
|
476
|
hb_ot_layout_table_get_feature_tags ( hb_face,
|
... |
... |
@@ -474,31 +489,28 @@ af_all_glyph_variants( FT_Face face, |
474
|
489
|
}
|
475
|
490
|
if ( !hb_set_allocation_successful( feature_tags ) )
|
476
|
491
|
{
|
477
|
|
- return FT_Err_Out_Of_Memory;
|
|
492
|
+ error = FT_Err_Out_Of_Memory;
|
|
493
|
+ goto Exit;
|
478
|
494
|
}
|
479
|
495
|
}
|
480
|
496
|
|
481
|
497
|
/*make a buffer only consisting of the given codepoint*/
|
482
|
|
- hb_buffer_t *codepoint_buffer = hb_buffer_create();
|
483
|
|
- if ( !hb_buffer_allocation_successful( codepoint_buffer ) )
|
484
|
|
- {
|
485
|
|
- return FT_Err_Out_Of_Memory;
|
486
|
|
- }
|
487
|
498
|
if ( !hb_buffer_pre_allocate( codepoint_buffer, 1 ) )
|
488
|
499
|
{
|
489
|
|
- return FT_Err_Out_Of_Memory;
|
|
500
|
+ error = FT_Err_Out_Of_Memory;
|
|
501
|
+ goto Exit;
|
490
|
502
|
}
|
491
|
|
- hb_buffer_set_direction (codepoint_buffer,
|
492
|
|
- HB_DIRECTION_LTR);
|
|
503
|
+ hb_buffer_set_direction ( codepoint_buffer,
|
|
504
|
+ HB_DIRECTION_LTR );
|
493
|
505
|
hb_buffer_add( codepoint_buffer, codepoint, 0 );
|
494
|
506
|
|
495
|
507
|
/*The array of features that will be used by the recursive part
|
496
|
508
|
it will have at most as many entries as there are features, so
|
497
|
509
|
make the length = length of feature_tags*/
|
498
|
510
|
hb_feature_t *feature_buffer;
|
499
|
|
- if ( FT_NEW_ARRAY( feature_buffer, hb_set_get_population( feature_tags ) ) )
|
|
511
|
+ if (( error = FT_NEW_ARRAY( feature_buffer, hb_set_get_population( feature_tags ) ) ))
|
500
|
512
|
{
|
501
|
|
- return error;
|
|
513
|
+ goto Exit;
|
502
|
514
|
}
|
503
|
515
|
|
504
|
516
|
error = af_all_glyph_variants_helper( hb_font,
|
... |
... |
@@ -507,10 +519,72 @@ af_all_glyph_variants( FT_Face face, |
507
|
519
|
feature_buffer,
|
508
|
520
|
0,
|
509
|
521
|
result );
|
|
522
|
+ if ( error )
|
|
523
|
+ {
|
|
524
|
+ goto Exit;
|
|
525
|
+ }
|
|
526
|
+
|
|
527
|
+ /*
|
|
528
|
+ Add the alternative glyph forms that come from features using
|
|
529
|
+ type 3 lookups.
|
|
530
|
+ This file from gtk was very useful in figuring out my approach:
|
|
531
|
+ https://github.com/val-verde/gtk/blob/212e85e92628eda9f9650e5cc8d88c44062642ae/gtk/gtkfontchooserwidget.c#L2085
|
|
532
|
+ */
|
|
533
|
+ /*list of features containing type 3 lookups:*/
|
|
534
|
+ hb_tag_t feature_list[] = {
|
|
535
|
+ HB_TAG('s','a','l','t'),
|
|
536
|
+ HB_TAG('s','w','s','h'),
|
|
537
|
+ HB_TAG('n','a','l','t'),
|
|
538
|
+ HB_TAG_NONE
|
|
539
|
+ };
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+ hb_ot_layout_collect_lookups ( hb_face,
|
|
543
|
+ HB_OT_TAG_GSUB,
|
|
544
|
+ NULL,
|
|
545
|
+ NULL,
|
|
546
|
+ feature_list,
|
|
547
|
+ type_3_lookup_indicies);
|
|
548
|
+
|
|
549
|
+ if ( !hb_set_allocation_successful( type_3_lookup_indicies ) )
|
|
550
|
+ {
|
|
551
|
+ error = FT_Err_Out_Of_Memory;
|
|
552
|
+ goto Exit;
|
|
553
|
+ }
|
|
554
|
+
|
|
555
|
+ if (( error = FT_NEW_ARRAY( type_3_alternate_glyphs_buffer, 100 ) ))
|
|
556
|
+ {
|
|
557
|
+ goto Exit;
|
|
558
|
+ }
|
|
559
|
+ hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID;
|
|
560
|
+ FT_UInt base_glyph_index = FT_Get_Char_Index( face, codepoint );
|
|
561
|
+ if ( base_glyph_index != 0 ) {
|
|
562
|
+ while ( hb_set_next( type_3_lookup_indicies, &lookup_index ) )
|
|
563
|
+ {
|
|
564
|
+ unsigned alternate_count = 100;
|
|
565
|
+
|
|
566
|
+ hb_ot_layout_lookup_get_glyph_alternates
|
|
567
|
+ ( hb_face,
|
|
568
|
+ lookup_index,
|
|
569
|
+ base_glyph_index,
|
|
570
|
+ 0,
|
|
571
|
+ &alternate_count,
|
|
572
|
+ type_3_alternate_glyphs_buffer );
|
|
573
|
+
|
|
574
|
+ for ( unsigned i = 0; i < alternate_count; i++ )
|
|
575
|
+ {
|
|
576
|
+ hb_set_add( result, type_3_alternate_glyphs_buffer[i] );
|
|
577
|
+ }
|
|
578
|
+ }
|
|
579
|
+ }
|
|
580
|
+
|
510
|
581
|
|
|
582
|
+
|
|
583
|
+Exit:
|
511
|
584
|
hb_set_destroy( feature_tags );
|
512
|
585
|
hb_buffer_destroy( codepoint_buffer );
|
513
|
586
|
FT_FREE( feature_buffer );
|
|
587
|
+ FT_FREE( type_3_alternate_glyphs_buffer );
|
514
|
588
|
return error;
|
515
|
589
|
}
|
516
|
590
|
#endif /*FT_CONFIG_OPTION_USE_HARFBUZZ*/
|
... |
... |
@@ -528,7 +602,8 @@ af_reverse_character_map_new( AF_ReverseCharacterMap *map, AF_FaceGlobals global |
528
|
602
|
FT_Error error;
|
529
|
603
|
/* backup face->charmap because find_unicode_charmap sets it */
|
530
|
604
|
FT_CharMap old_charmap = face->charmap;
|
531
|
|
- if ( ( error = find_unicode_charmap( face ) ) ) {
|
|
605
|
+ if ( ( error = find_unicode_charmap( face ) ) )
|
|
606
|
+ {
|
532
|
607
|
*map = NULL;
|
533
|
608
|
goto Exit;
|
534
|
609
|
}
|