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