From e6c4842a6068e0e08b79530821eb694ec0b44e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Mon, 2 May 2022 01:24:32 -0300 Subject: [PATCH] Minor bug fixes in font loading and rendering. --- include/eepp/graphics/font.hpp | 2 + include/eepp/graphics/fontbmfont.hpp | 2 + include/eepp/graphics/fontsprite.hpp | 2 + include/eepp/graphics/fonttruetype.hpp | 4 ++ src/eepp/graphics/font.cpp | 8 ++-- src/eepp/graphics/fontbmfont.cpp | 4 ++ src/eepp/graphics/fonttruetype.cpp | 18 +++++++-- src/eepp/graphics/text.cpp | 23 ++++++++++-- src/tools/ecode/ecode.cpp | 51 ++++++++++++++++++++++---- 9 files changed, 96 insertions(+), 18 deletions(-) diff --git a/include/eepp/graphics/font.hpp b/include/eepp/graphics/font.hpp index 3a8b499aa..b53e54296 100644 --- a/include/eepp/graphics/font.hpp +++ b/include/eepp/graphics/font.hpp @@ -77,6 +77,8 @@ class EE_API Font { virtual bool isMonospace() const = 0; + virtual bool isScalable() const = 0; + virtual const Info& getInfo() const = 0; virtual const Glyph& getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, diff --git a/include/eepp/graphics/fontbmfont.hpp b/include/eepp/graphics/fontbmfont.hpp index c59e4eeac..1beb70762 100644 --- a/include/eepp/graphics/fontbmfont.hpp +++ b/include/eepp/graphics/fontbmfont.hpp @@ -32,6 +32,8 @@ class EE_API FontBMFont : public Font { bool isMonospace() const; + bool isScalable() const; + const Font::Info& getInfo() const; const Glyph& getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, diff --git a/include/eepp/graphics/fontsprite.hpp b/include/eepp/graphics/fontsprite.hpp index 3148249a7..b60bda01e 100644 --- a/include/eepp/graphics/fontsprite.hpp +++ b/include/eepp/graphics/fontsprite.hpp @@ -36,6 +36,8 @@ class EE_API FontSprite : public Font { bool isMonospace() const { return true; } + bool isScalable() const { return false; } + const Font::Info& getInfo() const; const Glyph& getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, diff --git a/include/eepp/graphics/fonttruetype.hpp b/include/eepp/graphics/fonttruetype.hpp index 928400e09..7b247caba 100644 --- a/include/eepp/graphics/fonttruetype.hpp +++ b/include/eepp/graphics/fonttruetype.hpp @@ -66,6 +66,8 @@ class EE_API FontTrueType : public Font { bool isMonospace() const; + bool isScalable() const; + bool isEmojiFont() const; bool hasGlyph( Uint32 codePoint ) const; @@ -74,6 +76,7 @@ class EE_API FontTrueType : public Font { void setIsEmojiFont( bool isEmojiFont ); + void setForceIsMonospace( bool isMonospace ); protected: explicit FontTrueType( const std::string& FontName ); @@ -143,6 +146,7 @@ class EE_API FontTrueType : public Font { bool mBoldAdvanceSameAsRegular; bool mIsColorEmojiFont{ false }; bool mIsEmojiFont{ false }; + bool mIsMonospace{ false }; mutable std::map mClosestCharacterSize; mutable std::map mCodePointIndexCache; diff --git a/src/eepp/graphics/font.cpp b/src/eepp/graphics/font.cpp index 97d6d5b68..a55d45e14 100644 --- a/src/eepp/graphics/font.cpp +++ b/src/eepp/graphics/font.cpp @@ -10,11 +10,11 @@ bool Font::isEmojiCodePoint( const Uint32& codePoint ) { const Uint32 rangeMax = 131069; const Uint32 rangeMin2 = 126980; const Uint32 rangeMax2 = 127569; - const Uint32 rangeMin3 = 8987; + const Uint32 rangeMin3 = 8986; const Uint32 rangeMax3 = 12953; - return codePoint > 8987 && ( ( rangeMin <= codePoint && codePoint <= rangeMax ) || - ( rangeMin2 <= codePoint && codePoint <= rangeMax2 ) || - ( rangeMin3 <= codePoint && codePoint <= rangeMax3 ) ); + return codePoint >= 8986 && ( ( rangeMin <= codePoint && codePoint <= rangeMax ) || + ( rangeMin2 <= codePoint && codePoint <= rangeMax2 ) || + ( rangeMin3 <= codePoint && codePoint <= rangeMax3 ) ); } bool Font::containsEmojiCodePoint( const String& string ) { diff --git a/src/eepp/graphics/fontbmfont.cpp b/src/eepp/graphics/fontbmfont.cpp index 2e9f890f9..851529ac4 100644 --- a/src/eepp/graphics/fontbmfont.cpp +++ b/src/eepp/graphics/fontbmfont.cpp @@ -177,6 +177,10 @@ bool FontBMFont::isMonospace() const { return mIsMonospace; } +bool FontBMFont::isScalable() const { + return false; +} + const FontBMFont::Info& FontBMFont::getInfo() const { return mInfo; } diff --git a/src/eepp/graphics/fonttruetype.cpp b/src/eepp/graphics/fonttruetype.cpp index 6e52cca59..65b78ce46 100644 --- a/src/eepp/graphics/fonttruetype.cpp +++ b/src/eepp/graphics/fonttruetype.cpp @@ -126,6 +126,7 @@ bool FontTrueType::loadFromFile( const std::string& filename ) { } mFace = face; + mIsMonospace = FT_IS_FIXED_WIDTH( static_cast( mFace ) ); mIsColorEmojiFont = checkIsColorEmojiFont( static_cast( mFace ) ); mIsEmojiFont = FT_Get_Char_Index( static_cast( mFace ), 0x1F600 ) != 0; @@ -202,6 +203,7 @@ bool FontTrueType::loadFromMemory( const void* data, std::size_t sizeInBytes, bo } mFace = face; + mIsMonospace = FT_IS_FIXED_WIDTH( static_cast( mFace ) ); mIsColorEmojiFont = checkIsColorEmojiFont( static_cast( mFace ) ); mIsEmojiFont = FT_Get_Char_Index( static_cast( mFace ), 0x1F600 ) != 0; @@ -286,6 +288,7 @@ bool FontTrueType::loadFromStream( IOStream& stream ) { } mFace = face; + mIsMonospace = FT_IS_FIXED_WIDTH( static_cast( mFace ) ); mIsColorEmojiFont = checkIsColorEmojiFont( static_cast( mFace ) ); mIsEmojiFont = FT_Get_Char_Index( static_cast( mFace ), 0x1F600 ) != 0; FT_Stroker stroker = nullptr; @@ -1015,8 +1018,9 @@ bool FontTrueType::setCurrentSize( unsigned int characterSize ) const { } else { return false; } - } else if ( characterSize != currentSize && face->size->metrics.x_ppem > 0 ) { - return setCurrentSize( it->second ); + } else if ( characterSize != currentSize && + ( result = FT_Set_Pixel_Sizes( face, 0, it->second ) ) == FT_Err_Ok ) { + return true; } } } @@ -1041,6 +1045,10 @@ void FontTrueType::setIsEmojiFont( bool isEmojiFont ) { mIsEmojiFont = isEmojiFont; } +void FontTrueType::setForceIsMonospace( bool isMonospace ) { + mIsMonospace = isMonospace; +} + void FontTrueType::setIsColorEmojiFont( bool isColorEmojiFont ) { mIsColorEmojiFont = isColorEmojiFont; } @@ -1050,7 +1058,11 @@ bool FontTrueType::isColorEmojiFont() const { } bool FontTrueType::isMonospace() const { - return FT_IS_FIXED_WIDTH( static_cast( mFace ) ); + return mIsMonospace; +} + +bool FontTrueType::isScalable() const { + return FT_IS_SCALABLE( static_cast( mFace ) ); } bool FontTrueType::isEmojiFont() const { diff --git a/src/eepp/graphics/text.cpp b/src/eepp/graphics/text.cpp index fab6c2049..de888d5c5 100644 --- a/src/eepp/graphics/text.cpp +++ b/src/eepp/graphics/text.cpp @@ -120,7 +120,12 @@ Text::Text( const String& string, Font* font, unsigned int characterSize ) : mFontShadowColor( Color( 0, 0, 0, 255 ) ), mAlign( 0 ), mFontHeight( mFont->getFontHeight( mRealFontSize ) ), - mTabWidth( 4 ) {} + mTabWidth( 4 ) { + if ( !mFont->isScalable() ) { + mFontSize = mFontHeight; + mRealFontSize = mFontHeight; + } +} Text::Text( Font* font, unsigned int characterSize ) : mFont( font ), @@ -139,7 +144,12 @@ Text::Text( Font* font, unsigned int characterSize ) : mFontShadowColor( Color( 0, 0, 0, 255 ) ), mAlign( 0 ), mFontHeight( mFont->getFontHeight( mRealFontSize ) ), - mTabWidth( 4 ) {} + mTabWidth( 4 ) { + if ( !mFont->isScalable() ) { + mFontSize = mFontHeight; + mRealFontSize = mFontHeight; + } +} void Text::create( Font* font, const String& text, Color FontColor, Color FontShadowColor, Uint32 characterSize ) { @@ -179,7 +189,10 @@ void Text::setFont( Font* font ) { mRealFontSize = PixelDensity::dpToPxI( mFontSize ); mFontHeight = mFont->getFontHeight( mRealFontSize ); - + if ( !mFont->isScalable() ) { + mFontSize = mFontHeight; + mRealFontSize = mFontHeight; + } mGeometryNeedUpdate = true; mCachedWidthNeedUpdate = true; } @@ -191,6 +204,10 @@ void Text::setFontSize( unsigned int size ) { mRealFontSize = PixelDensity::dpToPxI( mFontSize ); mFontHeight = mFont->getFontHeight( mRealFontSize ); + if ( !mFont->isScalable() ) { + mFontSize = mFontHeight; + mRealFontSize = mFontHeight; + } mGeometryNeedUpdate = true; mCachedWidthNeedUpdate = true; diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 536a1a8b7..2e5bc0f6a 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -184,7 +184,7 @@ void App::openFontDialog( std::string& fontPath, bool loadingMonoFont ) { if ( FileSystem::isRelativePath( absoluteFontPath ) ) absoluteFontPath = mResPath + fontPath; UIFileDialog* dialog = - UIFileDialog::New( UIFileDialog::DefaultFlags, "*.ttf; *.otf; *.wolff; *.otb", + UIFileDialog::New( UIFileDialog::DefaultFlags, "*.ttf; *.otf; *.wolff; *.otb; *.bdf", FileSystem::fileRemoveFileName( absoluteFontPath ) ); ModelIndex index = dialog->getMultiView()->getListView()->findRowWithText( FileSystem::fileNameFromPath( fontPath ), true, true ); @@ -211,11 +211,36 @@ void App::openFontDialog( std::string& fontPath, bool loadingMonoFont ) { FileSystem::fileRemoveExtension( FileSystem::fileNameFromPath( fontPath ) ); FontTrueType* fontMono = loadFont( fontName, fontPath ); if ( fontMono ) { - mFontMono = fontMono; - mFontMono->setBoldAdvanceSameAsRegular( true ); - if ( mEditorSplitter ) { - mEditorSplitter->forEachEditor( - [&]( UICodeEditor* editor ) { editor->setFont( mFontMono ); } ); + auto loadMonoFont = [&]( FontTrueType* fontMono ) { + mFontMono = fontMono; + mFontMono->setBoldAdvanceSameAsRegular( true ); + mFontMono->setForceIsMonospace( true ); + if ( mEditorSplitter ) { + mEditorSplitter->forEachEditor( + [&]( UICodeEditor* editor ) { editor->setFont( mFontMono ); } ); + } + }; + if ( !fontMono->isMonospace() ) { + auto* msgBox = UIMessageBox::New( + UIMessageBox::YES_NO, + i18n( + "confirm_loading_none_monospace_font", + "The editor only supports monospaced fonts and the selected font isn't " + "flagged as monospace.\nDo you want to load it anyways?" ) + .unescape() ); + msgBox->addEventListener( + Event::MsgBoxConfirmClick, + [&, loadMonoFont, fontMono]( const Event* ) { loadMonoFont( fontMono ); } ); + msgBox->addEventListener( Event::MsgBoxCancelClick, [fontMono]( const Event* ) { + FontManager::instance()->remove( fontMono ); + } ); + msgBox->addEventListener( Event::OnClose, + [&]( const Event* ) { msgBox = nullptr; } ); + msgBox->setTitle( i18n( "confirm_loading_font", "Font loading confirmation" ) ); + msgBox->center(); + msgBox->showWhenReady(); + } else { + loadMonoFont( fontMono ); } } } @@ -2643,6 +2668,8 @@ void App::init( std::string file, const Float& pidelDensity, const std::string& mWindow = engine->createWindow( winSettings, contextSettings ); if ( mWindow->isOpen() ) { + Log::info( "Window creation took: %.2fms", globalClock.getElapsedTime().asMilliseconds() ); + if ( mConfig.window.position != Vector2i( -1, -1 ) && mConfig.window.displayIndex < displayManager->getDisplayCount() ) mWindow->setPosition( mConfig.window.position.x, mConfig.window.position.y ); @@ -2678,9 +2705,10 @@ void App::init( std::string file, const Float& pidelDensity, const std::string& mFont = loadFont( "sans-serif", mConfig.ui.serifFont, "assets/fonts/NotoSans-Regular.ttf" ); mFontMono = loadFont( "monospace", mConfig.ui.monospaceFont, "assets/fonts/DejaVuSansMono.ttf" ); - if ( mFontMono ) + if ( mFontMono ) { mFontMono->setBoldAdvanceSameAsRegular( true ); - + mFontMono->setForceIsMonospace( true ); + } loadFont( "NotoEmoji-Regular", "assets/fonts/NotoEmoji-Regular.ttf" ); #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN @@ -2992,6 +3020,8 @@ void App::init( std::string file, const Float& pidelDensity, const std::string& mInitColorScheme ); mEditorSplitter->setHideTabBarOnSingleTab( mConfig.editor.hideTabBarOnSingleTab ); + Log::info( "Base UI took: %.2fms", globalClock.getElapsedTime().asMilliseconds() ); + #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN mFileWatcher = new efsw::FileWatcher(); mFileSystemListener = new FileSystemListener( mEditorSplitter, mFileSystemModel ); @@ -3021,6 +3051,8 @@ void App::init( std::string file, const Float& pidelDensity, const std::string& mConsole = eeNew( Console, ( mFontMono, true, true, 1024 * 1000, 0, mWindow ) ); + Log::info( "Complete UI took: %.2fms", globalClock.getElapsedTime().asMilliseconds() ); + #if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN if ( file == "./this.program" ) file = ""; @@ -3028,6 +3060,9 @@ void App::init( std::string file, const Float& pidelDensity, const std::string& initProjectTreeView( file ); + Log::info( "Init ProjectTreeView took: %.2fms", + globalClock.getElapsedTime().asMilliseconds() ); + #if EE_PLATFORM == EE_PLATFORM_EMSCRIPTEN if ( file.empty() ) downloadFileWeb( "https://raw.githubusercontent.com/SpartanJ/eepp/develop/README.md" );