Add UnifontEx fallback for glyphs that are missing from the current font

This commit is contained in:
Kae 2024-04-22 08:17:10 +10:00
parent ca1426eabc
commit 52dae03aae
6 changed files with 21 additions and 5 deletions

Binary file not shown.

View File

@ -133,4 +133,8 @@ std::pair<Image, Vec2I> Font::render(String::Char c) {
return { std::move(image), {slot->bitmap_left - 1, (slot->bitmap_top - height) + (m_pixelSize / 4) - 1} }; return { std::move(image), {slot->bitmap_left - 1, (slot->bitmap_top - height) + (m_pixelSize / 4) - 1} };
} }
bool Font::exists(String::Char c) {
return FT_Get_Char_Index(m_fontImpl->face, c);
}
} }

View File

@ -35,6 +35,7 @@ public:
// render a box, but if there is an internal freetype error this may return // render a box, but if there is an internal freetype error this may return
// an empty image). // an empty image).
std::pair<Image, Vec2I> render(String::Char c); std::pair<Image, Vec2I> render(String::Char c);
bool exists(String::Char c);
private: private:
FontImplPtr m_fontImpl; FontImplPtr m_fontImpl;

View File

@ -39,13 +39,19 @@ void FontTextureGroup::clearFonts() {
m_font = m_defaultFont; m_font = m_defaultFont;
} }
void FontTextureGroup::setFallbackFont(String const& fontName) {
if (auto font = m_fonts.ptr(fontName))
m_fallbackFont = *font;
}
const FontTextureGroup::GlyphTexture& FontTextureGroup::glyphTexture(String::Char c, unsigned size, Directives const* processingDirectives) const FontTextureGroup::GlyphTexture& FontTextureGroup::glyphTexture(String::Char c, unsigned size, Directives const* processingDirectives)
{ {
auto res = m_glyphs.insert(GlyphDescriptor{c, size, processingDirectives ? processingDirectives->hash() : 0, m_font.get()}, GlyphTexture()); Font* font = (m_font->exists(c) || !m_fallbackFont) ? m_font.get() : m_fallbackFont.get();
auto res = m_glyphs.insert(GlyphDescriptor{c, size, processingDirectives ? processingDirectives->hash() : 0, font}, GlyphTexture());
if (res.second) { if (res.second) {
m_font->setPixelSize(size); font->setPixelSize(size);
auto pair = m_font->render(c); auto pair = font->render(c);
Image& image = pair.first; Image& image = pair.first;
if (processingDirectives) { if (processingDirectives) {
try { try {
@ -83,8 +89,9 @@ TexturePtr FontTextureGroup::glyphTexturePtr(String::Char c, unsigned size, Dire
} }
unsigned FontTextureGroup::glyphWidth(String::Char c, unsigned fontSize) { unsigned FontTextureGroup::glyphWidth(String::Char c, unsigned fontSize) {
m_font->setPixelSize(fontSize); Font* font = (m_font->exists(c) || !m_fallbackFont) ? m_font.get() : m_fallbackFont.get();
return m_font->width(c); font->setPixelSize(fontSize);
return font->width(c);
} }
} }

View File

@ -37,11 +37,14 @@ public:
String const& activeFont(); String const& activeFont();
void addFont(FontPtr const& font, String const& name, bool isDefault = false); void addFont(FontPtr const& font, String const& name, bool isDefault = false);
void clearFonts(); void clearFonts();
void setFallbackFont(String const& fontName);
private: private:
CaseInsensitiveStringMap<FontPtr> m_fonts; CaseInsensitiveStringMap<FontPtr> m_fonts;
String m_fontName; String m_fontName;
FontPtr m_font; FontPtr m_font;
FontPtr m_defaultFont; FontPtr m_defaultFont;
FontPtr m_fallbackFont;
TextureGroupPtr m_textureGroup; TextureGroupPtr m_textureGroup;
HashMap<GlyphDescriptor, GlyphTexture> m_glyphs; HashMap<GlyphDescriptor, GlyphTexture> m_glyphs;

View File

@ -331,6 +331,7 @@ void TextPainter::reloadFonts() {
loadFontsByExtension("ttf"); loadFontsByExtension("ttf");
loadFontsByExtension("woff2"); loadFontsByExtension("woff2");
m_fontTextureGroup.addFont(defaultFont, defaultName, true); m_fontTextureGroup.addFont(defaultFont, defaultName, true);
m_fontTextureGroup.setFallbackFont("unifont");
} }
void TextPainter::cleanup(int64_t timeout) { void TextPainter::cleanup(int64_t timeout) {