@@ -360,13 +360,61 @@ void FT2Font::set_text(
360
360
throw std::runtime_error (" failed to set text flags for layout" );
361
361
}
362
362
363
- std::set<FT_String*> glyph_seen_fonts;
364
- glyph_seen_fonts.insert (face->family_name );
365
-
366
363
if (!raqm_layout (rq)) {
367
364
throw std::runtime_error (" failed to layout text" );
368
365
}
369
366
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
+ }
370
418
371
419
size_t num_glyphs = 0 ;
372
420
auto const & rq_glyphs = raqm_get_glyphs (rq, &num_glyphs);
0 commit comments