@@ -444,13 +444,61 @@ void FT2Font::set_text(
444
444
throw std::runtime_error (" failed to set text flags for layout" );
445
445
}
446
446
447
- std::set<FT_String*> glyph_seen_fonts;
448
- glyph_seen_fonts.insert (face->family_name );
449
-
450
447
if (!raqm_layout (rq)) {
451
448
throw std::runtime_error (" failed to layout text" );
452
449
}
453
450
451
+ std::vector<std::pair<size_t , const FT_Face&>> face_substitutions;
452
+ std::set<FT_String*> glyph_seen_fonts;
453
+ glyph_seen_fonts.insert (face->family_name );
454
+
455
+ // Attempt to use fallback fonts if necessary.
456
+ for (auto const & fallback : fallbacks) {
457
+ size_t num_glyphs = 0 ;
458
+ auto const & rq_glyphs = raqm_get_glyphs (rq, &num_glyphs);
459
+ bool new_fallback_used = false ;
460
+
461
+ for (size_t i = 0 ; i < num_glyphs; i++) {
462
+ auto const & rglyph = rq_glyphs[i];
463
+
464
+ if (rglyph.index == 0 ) {
465
+ face_substitutions.emplace_back (rglyph.cluster , fallback->face );
466
+ new_fallback_used = true ;
467
+ }
468
+ }
469
+
470
+ if (new_fallback_used) {
471
+ // If a fallback was used, then re-attempt the layout with the new fonts.
472
+ if (!fallback->warn_if_used ) {
473
+ glyph_seen_fonts.insert (fallback->face ->family_name );
474
+ }
475
+
476
+ raqm_clear_contents (rq);
477
+ if (!raqm_set_text (rq,
478
+ reinterpret_cast <const uint32_t *>(text.data ()),
479
+ text.size ()))
480
+ {
481
+ throw std::runtime_error (" failed to set text for layout" );
482
+ }
483
+ if (!raqm_set_freetype_face (rq, face)) {
484
+ throw std::runtime_error (" failed to set text face for layout" );
485
+ }
486
+ for (auto [cluster, face] : face_substitutions) {
487
+ raqm_set_freetype_face_range (rq, face, cluster, 1 );
488
+ }
489
+ if (!raqm_set_freetype_load_flags (rq, flags)) {
490
+ throw std::runtime_error (" failed to set text flags for layout" );
491
+ }
492
+
493
+ if (!raqm_layout (rq)) {
494
+ throw std::runtime_error (" failed to layout text" );
495
+ }
496
+ } else {
497
+ // If we never used a fallback, then we're good to go with the existing
498
+ // layout we have already made.
499
+ break ;
500
+ }
501
+ }
454
502
455
503
size_t num_glyphs = 0 ;
456
504
auto const & rq_glyphs = raqm_get_glyphs (rq, &num_glyphs);
0 commit comments