@@ -360,13 +360,61 @@ void FT2Font::set_text(
360360 throw std::runtime_error (" failed to set text flags for layout" );
361361 }
362362
363- std::set<FT_String*> glyph_seen_fonts;
364- glyph_seen_fonts.insert (face->family_name );
365-
366363 if (!raqm_layout (rq)) {
367364 throw std::runtime_error (" failed to layout text" );
368365 }
369366
367+ std::vector<std::pair<size_t , const FT_Face&>> face_substitutions;
368+ std::set<FT_String*> glyph_seen_fonts;
369+ glyph_seen_fonts.insert (face->family_name );
370+
371+ // Attempt to use fallback fonts if necessary.
372+ for (auto const & fallback : fallbacks) {
373+ size_t num_glyphs = 0 ;
374+ auto const & rq_glyphs = raqm_get_glyphs (rq, &num_glyphs);
375+ bool new_fallback_used = false ;
376+
377+ for (size_t i = 0 ; i < num_glyphs; i++) {
378+ auto const & rglyph = rq_glyphs[i];
379+
380+ if (rglyph.index == 0 ) {
381+ face_substitutions.emplace_back (rglyph.cluster , fallback->face );
382+ new_fallback_used = true ;
383+ }
384+ }
385+
386+ if (new_fallback_used) {
387+ // If a fallback was used, then re-attempt the layout with the new fonts.
388+ if (!fallback->warn_if_used ) {
389+ glyph_seen_fonts.insert (fallback->face ->family_name );
390+ }
391+
392+ raqm_clear_contents (rq);
393+ if (!raqm_set_text (rq,
394+ reinterpret_cast <const uint32_t *>(text.data ()),
395+ text.size ()))
396+ {
397+ throw std::runtime_error (" failed to set text for layout" );
398+ }
399+ if (!raqm_set_freetype_face (rq, face)) {
400+ throw std::runtime_error (" failed to set text face for layout" );
401+ }
402+ for (auto [cluster, face] : face_substitutions) {
403+ raqm_set_freetype_face_range (rq, face, cluster, 1 );
404+ }
405+ if (!raqm_set_freetype_load_flags (rq, flags)) {
406+ throw std::runtime_error (" failed to set text flags for layout" );
407+ }
408+
409+ if (!raqm_layout (rq)) {
410+ throw std::runtime_error (" failed to layout text" );
411+ }
412+ } else {
413+ // If we never used a fallback, then we're good to go with the existing
414+ // layout we have already made.
415+ break ;
416+ }
417+ }
370418
371419 size_t num_glyphs = 0 ;
372420 auto const & rq_glyphs = raqm_get_glyphs (rq, &num_glyphs);
0 commit comments