From 8949190bf94e3f192046a55b7e73b312423e40ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Tue, 4 Oct 2022 02:09:40 -0300 Subject: [PATCH] Initial support for fallback fonts. Minor fix in TerminalDisplay. --- include/eepp/core/string.hpp | 7 ++++++ include/eepp/graphics/fontmanager.hpp | 5 ++++ src/eepp/core/string.cpp | 4 ++++ src/eepp/graphics/fontmanager.cpp | 8 +++++++ src/eepp/graphics/fonttruetype.cpp | 18 ++++++++++++++- .../src/eterm/terminal/terminaldisplay.cpp | 23 ++++++++++++++++++- src/tools/eterm/eterm.cpp | 9 ++++++++ 7 files changed, 72 insertions(+), 2 deletions(-) diff --git a/include/eepp/core/string.hpp b/include/eepp/core/string.hpp index 2f4e53b7c..f828dc5f9 100644 --- a/include/eepp/core/string.hpp +++ b/include/eepp/core/string.hpp @@ -213,6 +213,13 @@ class EE_API String { */ static bool startsWith( const String& haystack, const String& needle ); + /** Compare two strings from its beginning. + * @param haystack The string to search in. + * @param needle The searched string. + * @return true if string starts with the substring + */ + static bool startsWith( const char* haystack, const char* needle ); + /** Compare two strings from its end. * @param haystack The string to search in. * @param needle The searched string. diff --git a/include/eepp/graphics/fontmanager.hpp b/include/eepp/graphics/fontmanager.hpp index d551f238d..a0f5f25f3 100644 --- a/include/eepp/graphics/fontmanager.hpp +++ b/include/eepp/graphics/fontmanager.hpp @@ -31,9 +31,14 @@ class EE_API FontManager : public ResourceManager { void setEmojiFont( Font* newEmojiFont ); + Font* getFallbackFont() const; + + void setFallbackFont( Font* fallbackFont ); + protected: Font* mColorEmojiFont{ nullptr }; Font* mEmojiFont{ nullptr }; + Font* mFallbackFont{ nullptr }; FontManager(); }; diff --git a/src/eepp/core/string.cpp b/src/eepp/core/string.cpp index 9c812ec41..2f63404bd 100644 --- a/src/eepp/core/string.cpp +++ b/src/eepp/core/string.cpp @@ -650,6 +650,10 @@ bool String::startsWith( const String& haystack, const String& needle ) { std::equal( needle.begin(), needle.end(), haystack.begin() ); } +bool String::startsWith( const char* haystack, const char* needle ) { + return strncmp( needle, haystack, strlen( needle ) ) == 0; +} + bool String::endsWith( const std::string& haystack, const std::string& needle ) { return needle.length() <= haystack.length() && haystack.compare( haystack.size() - needle.size(), needle.size(), needle ) == 0; diff --git a/src/eepp/graphics/fontmanager.cpp b/src/eepp/graphics/fontmanager.cpp index 8bc4233ce..c68469e43 100644 --- a/src/eepp/graphics/fontmanager.cpp +++ b/src/eepp/graphics/fontmanager.cpp @@ -29,4 +29,12 @@ void FontManager::setEmojiFont( Graphics::Font* newEmojiFont ) { mEmojiFont = newEmojiFont; } +Font* FontManager::getFallbackFont() const { + return mFallbackFont; +} + +void FontManager::setFallbackFont( Font* fallbackFont ) { + mFallbackFont = fallbackFont; +} + }} // namespace EE::Graphics diff --git a/src/eepp/graphics/fonttruetype.cpp b/src/eepp/graphics/fonttruetype.cpp index e43ccb444..8d30aa88d 100644 --- a/src/eepp/graphics/fonttruetype.cpp +++ b/src/eepp/graphics/fonttruetype.cpp @@ -410,7 +410,16 @@ const Glyph& FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSiz } } - return getGlyphByIndex( getGlyphIndex( codePoint ), characterSize, bold, outlineThickness ); + Uint32 glyphIndex = getGlyphIndex( codePoint ); + if ( 0 == glyphIndex && FontManager::instance()->getFallbackFont() && + FontManager::instance()->getFallbackFont()->getType() == FontType::TTF ) { + FontTrueType* fallbackFont = + static_cast( FontManager::instance()->getFallbackFont() ); + return fallbackFont->getGlyph( codePoint, characterSize, bold, outlineThickness, + getPage( characterSize ), maxWidth ); + } + + return getGlyphByIndex( glyphIndex, characterSize, bold, outlineThickness ); } const Glyph& FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, @@ -476,6 +485,13 @@ GlyphDrawable* FontTrueType::getGlyphDrawable( Uint32 codePoint, unsigned int ch } } else { glyphIndex = getGlyphIndex( codePoint ); + if ( 0 == glyphIndex && FontManager::instance()->getFallbackFont() != nullptr && + FontManager::instance()->getFallbackFont()->getType() == FontType::TTF ) { + FontTrueType* fontFallback = + static_cast( FontManager::instance()->getFallbackFont() ); + glyphIndex = fontFallback->getGlyphIndex( codePoint ); + fontInternalId = fontFallback->getFontInternalId(); + } } Uint64 key = getIndexKey( fontInternalId, glyphIndex, bold, outlineThickness ); diff --git a/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp b/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp index 491619aa5..87fbcc886 100644 --- a/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp +++ b/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp @@ -500,7 +500,28 @@ int TerminalDisplay::resetColor( const Uint32& index, const char* name ) { } if ( index < mColors.size() ) { - mColors[index] = Color::fromString( name ); + if ( name && String::startsWith( name, "rgb:" ) ) { + auto split = String::split( std::string( name ), ':' ); + if ( split.size() == 2 ) { + auto splitRgb = String::split( split[1], '/' ); + if ( splitRgb.size() == 3 ) { + char* pr = NULL; + char* pg = NULL; + char* pb = NULL; + long r = 0, g = 0, b = 0; + r = std::strtol( splitRgb[0].c_str(), &pr, 16 ); + g = std::strtol( splitRgb[1].c_str(), &pg, 16 ); + b = std::strtol( splitRgb[2].c_str(), &pb, 16 ); + if ( pr && pg && pb ) { + mColors[index] = Color( r, g, b ); + return 0; + } + } + } + } else { + mColors[index] = Color::fromString( name ); + return 0; + } } return 1; diff --git a/src/tools/eterm/eterm.cpp b/src/tools/eterm/eterm.cpp index 9a5f882a8..b37d6dc58 100644 --- a/src/tools/eterm/eterm.cpp +++ b/src/tools/eterm/eterm.cpp @@ -118,6 +118,8 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { args::Flag fb( parser, "framebuffer", "Use frame buffer (more memory usage, less CPU usage)", { "fb", "framebuffer" } ); args::ValueFlag fontPath( parser, "fontpath", "Font path", { 'f', "font" } ); + args::ValueFlag fallbackFontPathF( parser, "fallback-fontpath", + "Fallback Font path", { "fallback-font" } ); args::ValueFlag fontSize( parser, "fontsize", "Font size (in dp)", { 's', "fontsize" }, 11 ); args::ValueFlag width( parser, "winwidth", "Window width (in dp)", { "width" }, 1280 ); @@ -212,6 +214,13 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { ->loadFromFile( resPath + "fonts/NotoEmoji-Regular.ttf" ); } + std::string fallbackFontPath( fallbackFontPathF.Get() ); + if ( FileSystem::fileExists( fallbackFontPath ) ) { + FontTrueType* fallbackFont = FontTrueType::New( "fallback-font" ); + if ( fallbackFont->loadFromFile( fallbackFontPath ) ) + FontManager::instance()->setFallbackFont( fallbackFont ); + } + Float realMaxFPS = maxFPS.Get() ? maxFPS.Get() : currentDisplay->getRefreshRate(); frameTime = benchmarkMode ? Time::Zero : Milliseconds( 1000.f / realMaxFPS );