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