@@ -444,13 +444,61 @@ void FT2Font::set_text(
444444 throw std::runtime_error (" failed to set text flags for layout" );
445445 }
446446
447- std::set<FT_String*> glyph_seen_fonts;
448- glyph_seen_fonts.insert (face->family_name );
449-
450447 if (!raqm_layout (rq)) {
451448 throw std::runtime_error (" failed to layout text" );
452449 }
453450
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+ }
454502
455503 size_t num_glyphs = 0 ;
456504 auto const & rq_glyphs = raqm_get_glyphs (rq, &num_glyphs);
0 commit comments