@@ -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