diff --git a/include/cairo/context.hpp b/include/cairo/context.hpp index d7899100..b1a7f748 100644 --- a/include/cairo/context.hpp +++ b/include/cairo/context.hpp @@ -172,8 +172,15 @@ namespace cairo { while (!chars.empty()) { auto remaining = chars.size(); for (auto&& f : fns) { - auto matches = f->match(chars); - if (!matches) { + unsigned int matches; + + // Match as many glyphs as possible if the default/preferred font + // is being tested. Otherwise test one glyph at a time against + // the remaining fonts. Roll back to the top of the font list + // when a glyph has been found. + if (f == fns.front() && (matches = f->match(chars)) == 0) { + continue; + } else if (f != fns.front() && (matches = f->match(chars.front())) == 0) { continue; } diff --git a/include/cairo/font.hpp b/include/cairo/font.hpp index 3029ea23..71f7e4f1 100644 --- a/include/cairo/font.hpp +++ b/include/cairo/font.hpp @@ -38,6 +38,7 @@ namespace cairo { cairo_set_font_face(m_cairo, cairo_font_face_reference(m_font_face)); } + virtual size_t match(utils::unicode_character& character) = 0; virtual size_t match(utils::unicode_charlist& charlist) = 0; virtual size_t render(const string& text, double x = 0.0, double y = 0.0) = 0; virtual void textwidth(const string& text, cairo_text_extents_t* extents) = 0; @@ -130,6 +131,12 @@ namespace cairo { cairo_set_scaled_font(m_cairo, m_scaled); } + size_t match(utils::unicode_character& character) override { + auto lock = make_unique(m_scaled); + auto face = static_cast(*lock); + return FT_Get_Char_Index(face, character.codepoint) ? 1 : 0; + } + size_t match(utils::unicode_charlist& charlist) override { auto lock = make_unique(m_scaled); auto face = static_cast(*lock);