diff --git a/include/eepp/graphics/font.hpp b/include/eepp/graphics/font.hpp index b53e54296..e25e5e7df 100644 --- a/include/eepp/graphics/font.hpp +++ b/include/eepp/graphics/font.hpp @@ -82,13 +82,13 @@ class EE_API Font { virtual const Info& getInfo() const = 0; virtual const Glyph& getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, - Float outlineThickness = 0 ) const = 0; + Float outlineThickness = 0, Float maxWidth = 0 ) const = 0; /** @return The glyph drawable that represents the glyph in a texture. The glyph drawable * allocation is managed by the font. */ virtual GlyphDrawable* getGlyphDrawable( Uint32 codePoint, unsigned int characterSize, - bool bold = false, - Float outlineThickness = 0 ) const = 0; + bool bold = false, Float outlineThickness = 0, + const Float& forzeSize = 0 ) const = 0; virtual Float getKerning( Uint32 first, Uint32 second, unsigned int characterSize, bool bold ) const = 0; diff --git a/include/eepp/graphics/fontbmfont.hpp b/include/eepp/graphics/fontbmfont.hpp index 1beb70762..983783904 100644 --- a/include/eepp/graphics/fontbmfont.hpp +++ b/include/eepp/graphics/fontbmfont.hpp @@ -37,10 +37,11 @@ class EE_API FontBMFont : public Font { const Font::Info& getInfo() const; const Glyph& getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, - Float outlineThickness = 0 ) const; + Float outlineThickness = 0, Float maxWidth = 0 ) const; GlyphDrawable* getGlyphDrawable( Uint32 codePoint, unsigned int characterSize, - bool bold = false, Float outlineThickness = 0 ) const; + bool bold = false, Float outlineThickness = 0, + const Float& maxWidth = 0 ) const; Float getKerning( Uint32 first, Uint32 second, unsigned int characterSize, bool bold ) const; diff --git a/include/eepp/graphics/fontsprite.hpp b/include/eepp/graphics/fontsprite.hpp index b60bda01e..b11a202fb 100644 --- a/include/eepp/graphics/fontsprite.hpp +++ b/include/eepp/graphics/fontsprite.hpp @@ -41,10 +41,11 @@ class EE_API FontSprite : public Font { const Font::Info& getInfo() const; const Glyph& getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, - Float outlineThickness = 0 ) const; + Float outlineThickness = 0, Float maxWidth = 0 ) const; GlyphDrawable* getGlyphDrawable( Uint32 codePoint, unsigned int characterSize, - bool bold = false, Float outlineThickness = 0 ) const; + bool bold = false, Float outlineThickness = 0, + const Float& maxWidth = 0 ) const; Float getKerning( Uint32 first, Uint32 second, unsigned int characterSize, bool bold ) const; diff --git a/include/eepp/graphics/fonttruetype.hpp b/include/eepp/graphics/fonttruetype.hpp index 4f15266e3..798e329c0 100644 --- a/include/eepp/graphics/fonttruetype.hpp +++ b/include/eepp/graphics/fonttruetype.hpp @@ -32,13 +32,14 @@ class EE_API FontTrueType : public Font { const Font::Info& getInfo() const; const Glyph& getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, - Float outlineThickness = 0 ) const; + Float outlineThickness = 0, Float maxWidth = 0 ) const; const Glyph& getGlyphByIndex( Uint32 index, unsigned int characterSize, bool bold, Float outlineThickness = 0 ) const; GlyphDrawable* getGlyphDrawable( Uint32 codePoint, unsigned int characterSize, - bool bold = false, Float outlineThickness = 0 ) const; + bool bold = false, Float outlineThickness = 0, + const Float& maxWidth = 0 ) const; Float getKerning( Uint32 first, Uint32 second, unsigned int characterSize, bool bold ) const; @@ -82,6 +83,7 @@ class EE_API FontTrueType : public Font { void setEnableEmojiFallback( bool enableEmojiFallback ); + const Uint32& getFontInternalId() const; protected: explicit FontTrueType( const std::string& FontName ); @@ -114,16 +116,15 @@ class EE_API FontTrueType : public Font { void cleanup(); const Glyph& getGlyphByIndex( Uint32 index, unsigned int characterSize, bool bold, - Float outlineThickness, Page& page, - const Float& forzeSize ) const; + Float outlineThickness, Page& page, const Float& maxWidth ) const; const Glyph& getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, - Float outlineThickness, Page& page, const Float& forzeSize ) const; + Float outlineThickness, Page& page, const Float& maxWidth ) const; Uint32 getGlyphIndex( const Uint32& codePoint ) const; Glyph loadGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, - Float outlineThickness, Page& page, const Float& forceSize = 0.f ) const; + Float outlineThickness, Page& page, const Float& maxWidth = 0.f ) const; Rect findGlyphRect( Page& page, unsigned int width, unsigned int height ) const; @@ -145,7 +146,8 @@ class EE_API FontTrueType : public Font { int* mRefCount; ///< Reference counter used by implicit sharing mutable ScopedBuffer mMemCopy; ///< If loaded from memory, this is the file copy in memory Font::Info mInfo; ///< Information about the font - mutable PageTable mPages; ///< Table containing the glyphs pages by character size + Uint32 mFontInternalId{ 0 }; + mutable PageTable mPages; ///< Table containing the glyphs pages by character size mutable std::vector mPixelBuffer; ///< Pixel buffer holding a glyph's pixels before being written to the texture bool mBoldAdvanceSameAsRegular; @@ -158,6 +160,8 @@ class EE_API FontTrueType : public Font { Uint64 getIndexKey( Uint32 fontInternalId, Uint32 index, bool bold, Float outlineThickness ) const; + + void updateFontInternalId(); }; }} // namespace EE::Graphics diff --git a/src/eepp/graphics/fontbmfont.cpp b/src/eepp/graphics/fontbmfont.cpp index 851529ac4..696f93e0b 100644 --- a/src/eepp/graphics/fontbmfont.cpp +++ b/src/eepp/graphics/fontbmfont.cpp @@ -186,7 +186,7 @@ const FontBMFont::Info& FontBMFont::getInfo() const { } const Glyph& FontBMFont::getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, - Float outlineThickness ) const { + Float outlineThickness, Float ) const { GlyphTable& glyphs = mPages[characterSize].glyphs; GlyphTable::const_iterator it = glyphs.find( codePoint ); @@ -200,7 +200,8 @@ const Glyph& FontBMFont::getGlyph( Uint32 codePoint, unsigned int characterSize, } GlyphDrawable* FontBMFont::getGlyphDrawable( Uint32 codePoint, unsigned int characterSize, - bool bold, Float outlineThickness ) const { + bool bold, Float outlineThickness, + const Float& ) const { GlyphDrawableTable& drawables = mPages[characterSize].drawables; auto it = drawables.find( codePoint ); if ( it != drawables.end() ) { diff --git a/src/eepp/graphics/fontsprite.cpp b/src/eepp/graphics/fontsprite.cpp index f2e3d2e77..70dd1f30f 100644 --- a/src/eepp/graphics/fontsprite.cpp +++ b/src/eepp/graphics/fontsprite.cpp @@ -164,7 +164,7 @@ const FontSprite::Info& FontSprite::getInfo() const { return mInfo; } -const Glyph& FontSprite::getGlyph( Uint32 codePoint, unsigned int characterSize, bool, +const Glyph& FontSprite::getGlyph( Uint32 codePoint, unsigned int characterSize, bool, Float, Float ) const { GlyphTable& glyphs = mPages[characterSize].glyphs; @@ -179,7 +179,8 @@ const Glyph& FontSprite::getGlyph( Uint32 codePoint, unsigned int characterSize, } GlyphDrawable* FontSprite::getGlyphDrawable( Uint32 codePoint, unsigned int characterSize, - bool bold, Float outlineThickness ) const { + bool bold, Float outlineThickness, + const Float& ) const { GlyphDrawableTable& drawables = mPages[characterSize].drawables; auto it = drawables.find( codePoint ); if ( it != drawables.end() ) { diff --git a/src/eepp/graphics/fonttruetype.cpp b/src/eepp/graphics/fonttruetype.cpp index c445641be..e43ccb444 100644 --- a/src/eepp/graphics/fonttruetype.cpp +++ b/src/eepp/graphics/fonttruetype.cpp @@ -163,9 +163,7 @@ bool FontTrueType::loadFromFile( const std::string& filename ) { // Store the font information mInfo.family = face->family_name ? face->family_name : std::string(); - auto fontInternalId = fontsInternalIds.find( mInfo.family ); - if ( fontsInternalIds.end() == fontInternalId ) - fontsInternalIds[mInfo.family] = ++fontInternalIdCounter; + updateFontInternalId(); sendEvent( Event::Load ); @@ -238,9 +236,7 @@ bool FontTrueType::loadFromMemory( const void* data, std::size_t sizeInBytes, bo // Store the font information mInfo.family = face->family_name ? face->family_name : std::string(); - auto fontInternalId = fontsInternalIds.find( mInfo.family ); - if ( fontsInternalIds.end() == fontInternalId ) - fontsInternalIds[mInfo.family] = ++fontInternalIdCounter; + updateFontInternalId(); sendEvent( Event::Load ); @@ -326,9 +322,7 @@ bool FontTrueType::loadFromStream( IOStream& stream ) { // Store the font information mInfo.family = face->family_name ? face->family_name : std::string(); - auto fontInternalId = fontsInternalIds.find( mInfo.family ); - if ( fontsInternalIds.end() == fontInternalId ) - fontsInternalIds[mInfo.family] = ++fontInternalIdCounter; + updateFontInternalId(); sendEvent( Event::Load ); @@ -359,6 +353,16 @@ Uint64 FontTrueType::getIndexKey( Uint32 fontInternalId, Uint32 index, bool bold return combine( outlineThickness, bold, index, fontInternalId ); } +void FontTrueType::updateFontInternalId() { + auto fontInternalId = fontsInternalIds.find( mInfo.family ); + if ( fontsInternalIds.end() == fontInternalId ) { + mFontInternalId = ++fontInternalIdCounter; + fontsInternalIds[mInfo.family] = mFontInternalId; + } else { + mFontInternalId = fontInternalId->second; + } +} + bool FontTrueType::hasGlyph( Uint32 codePoint ) const { return getGlyphIndex( codePoint ) != 0; } @@ -376,17 +380,13 @@ Uint32 FontTrueType::getGlyphIndex( const Uint32& codePoint ) const { } const Glyph& FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, - Float outlineThickness ) const { - Uint32 index = getGlyphIndex( codePoint ); - + Float outlineThickness, Float maxWidth ) const { if ( mEnableEmojiFallback && Font::isEmojiCodePoint( codePoint ) && !mIsColorEmojiFont && !mIsEmojiFont ) { if ( !mIsColorEmojiFont && FontManager::instance()->getColorEmojiFont() != nullptr && FontManager::instance()->getColorEmojiFont()->getType() == FontType::TTF ) { - Float maxWidth = 0.f; - - if ( isMonospace() ) { + if ( isMonospace() && maxWidth == 0.f ) { Glyph monospaceGlyph = getGlyph( ' ', characterSize, bold, outlineThickness ); maxWidth = monospaceGlyph.advance; } @@ -398,12 +398,11 @@ const Glyph& FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSiz } else if ( !mIsEmojiFont && FontManager::instance()->getEmojiFont() != nullptr && FontManager::instance()->getEmojiFont()->getType() == FontType::TTF ) { - Float maxWidth = 0.f; - - if ( isMonospace() ) { + if ( isMonospace() && maxWidth == 0.f ) { Glyph monospaceGlyph = getGlyph( ' ', characterSize, bold, outlineThickness ); maxWidth = monospaceGlyph.advance; } + FontTrueType* fontEmoji = static_cast( FontManager::instance()->getEmojiFont() ); return fontEmoji->getGlyph( codePoint, characterSize, bold, outlineThickness, @@ -411,24 +410,24 @@ const Glyph& FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSiz } } - return getGlyphByIndex( index, characterSize, bold, outlineThickness ); + return getGlyphByIndex( getGlyphIndex( codePoint ), characterSize, bold, outlineThickness ); } const Glyph& FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, Float outlineThickness, Page& page, - const Float& forzeSize ) const { + const Float& maxWidth ) const { Uint32 index = getGlyphIndex( codePoint ); - return getGlyphByIndex( index, characterSize, bold, outlineThickness, page, forzeSize ); + return getGlyphByIndex( index, characterSize, bold, outlineThickness, page, maxWidth ); } const Glyph& FontTrueType::getGlyphByIndex( Uint32 index, unsigned int characterSize, bool bold, Float outlineThickness, Page& page, - const Float& forzeSize ) const { + const Float& maxWidth ) const { // Get the page corresponding to the character size GlyphTable& glyphs = page.glyphs; // Build the key by combining the code point, bold flag, and outline thickness - Uint64 key = getIndexKey( fontsInternalIds[mInfo.family], index, bold, outlineThickness ); + Uint64 key = getIndexKey( mFontInternalId, index, bold, outlineThickness ); // Search the glyph into the cache GlyphTable::const_iterator it = glyphs.find( key ); @@ -437,7 +436,7 @@ const Glyph& FontTrueType::getGlyphByIndex( Uint32 index, unsigned int character return it->second; } else { // Not found: we have to load it - Glyph glyph = loadGlyph( index, characterSize, bold, outlineThickness, page, forzeSize ); + Glyph glyph = loadGlyph( index, characterSize, bold, outlineThickness, page, maxWidth ); return glyphs.insert( std::make_pair( key, glyph ) ).first->second; } @@ -450,18 +449,42 @@ const Glyph& FontTrueType::getGlyphByIndex( Uint32 index, unsigned int character } GlyphDrawable* FontTrueType::getGlyphDrawable( Uint32 codePoint, unsigned int characterSize, - bool bold, Float outlineThickness ) const { - GlyphDrawableTable& drawables = getPage( characterSize ).drawables; + bool bold, Float outlineThickness, + const Float& maxWidth ) const { + Page& page = getPage( characterSize ); + GlyphDrawableTable& drawables = page.drawables; - Uint64 key = getIndexKey( getPage( characterSize ).fontInternalId, getGlyphIndex( codePoint ), - bold, outlineThickness ); + Uint32 glyphIndex = 0; + Uint32 fontInternalId = mFontInternalId; + + if ( mEnableEmojiFallback && Font::isEmojiCodePoint( codePoint ) && !mIsColorEmojiFont && + !mIsEmojiFont ) { + if ( !mIsColorEmojiFont && FontManager::instance()->getColorEmojiFont() != nullptr && + FontManager::instance()->getColorEmojiFont()->getType() == FontType::TTF ) { + FontTrueType* fontEmoji = + static_cast( FontManager::instance()->getColorEmojiFont() ); + glyphIndex = fontEmoji->getGlyphIndex( codePoint ); + fontInternalId = fontEmoji->getFontInternalId(); + } else if ( !mIsEmojiFont && FontManager::instance()->getEmojiFont() != nullptr && + FontManager::instance()->getEmojiFont()->getType() == FontType::TTF ) { + FontTrueType* fontEmoji = + static_cast( FontManager::instance()->getEmojiFont() ); + glyphIndex = fontEmoji->getGlyphIndex( codePoint ); + fontInternalId = fontEmoji->getFontInternalId(); + } else { + glyphIndex = getGlyphIndex( codePoint ); + } + } else { + glyphIndex = getGlyphIndex( codePoint ); + } + + Uint64 key = getIndexKey( fontInternalId, glyphIndex, bold, outlineThickness ); auto it = drawables.find( key ); if ( it != drawables.end() ) { return it->second; } else { - const Glyph& glyph = getGlyph( codePoint, characterSize, bold, outlineThickness ); - auto& page = getPage( characterSize ); + const Glyph& glyph = getGlyph( codePoint, characterSize, bold, outlineThickness, maxWidth ); GlyphDrawable* region = GlyphDrawable::New( page.texture, glyph.textureRect, String::format( "%s_%d_%u", mFontName.c_str(), characterSize, codePoint ) ); @@ -1035,8 +1058,7 @@ bool FontTrueType::setCurrentSize( unsigned int characterSize ) const { FontTrueType::Page& FontTrueType::getPage( unsigned int characterSize ) const { auto pageIt = mPages.find( characterSize ); if ( pageIt == mPages.end() ) { - mPages.insert( std::make_pair( characterSize, - std::make_unique( fontsInternalIds[mInfo.family] ) ) ); + mPages.insert( std::make_pair( characterSize, std::make_unique( mFontInternalId ) ) ); pageIt = mPages.find( characterSize ); } return *pageIt->second; @@ -1050,6 +1072,10 @@ void FontTrueType::setEnableEmojiFallback( bool enableEmojiFallback ) { mEnableEmojiFallback = enableEmojiFallback; } +const Uint32& FontTrueType::getFontInternalId() const { + return mFontInternalId; +} + void FontTrueType::setIsEmojiFont( bool isEmojiFont ) { mIsEmojiFont = isEmojiFont; } diff --git a/src/eepp/graphics/image.cpp b/src/eepp/graphics/image.cpp index f6f62132f..cc7cdd3b8 100644 --- a/src/eepp/graphics/image.cpp +++ b/src/eepp/graphics/image.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #define NANOSVG_IMPLEMENTATION #include @@ -95,18 +96,18 @@ static unsigned char* resample_image( unsigned char* pSrc_image, int src_width, linear_to_srgb[i] = (unsigned char)k; } - Resampler* resamplers[max_components]; + std::unique_ptr resamplers[max_components]; std::vector samples[max_components]; - resamplers[0] = + resamplers[0] = std::unique_ptr( new Resampler( src_width, src_height, dst_width, dst_height, Resampler::BOUNDARY_CLAMP, - 0.0f, 1.0f, pFilter, NULL, NULL, filter_scale, filter_scale ); + 0.0f, 1.0f, pFilter, NULL, NULL, filter_scale, filter_scale ) ); samples[0].resize( src_width ); for ( int i = 1; i < n; i++ ) { - resamplers[i] = + resamplers[i] = std::unique_ptr( new Resampler( src_width, src_height, dst_width, dst_height, Resampler::BOUNDARY_CLAMP, 0.0f, 1.0f, pFilter, resamplers[0]->get_clist_x(), - resamplers[0]->get_clist_y(), filter_scale, filter_scale ); + resamplers[0]->get_clist_y(), filter_scale, filter_scale ) ); samples[i].resize( src_width ); } diff --git a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp index 99dfd51f5..a3e980321 100644 --- a/src/eepp/ui/doc/syntaxdefinitionmanager.cpp +++ b/src/eepp/ui/doc/syntaxdefinitionmanager.cpp @@ -3556,6 +3556,9 @@ void SyntaxDefinitionManager::addxit() { { { "^[%wñàáâãäåèéêëìíîïòóôõöùúûüýÿÑÀÁÂÃÄÅÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝ][%w" "ñàáâãäåèéêëìíîïòóôõöùúûüýÿÑÀÁÂÃÄÅÈÉÊËÌÍÎÏÒÓÔÕÖÙÚÛÜÝ%s%p]*%f[\n]" }, "underline" }, + { { "https?://[%w_.~!*:@&+$/?%%#-]-%w[-.%w]*%.%w%w%w?%w?:?%d*/?[%w_.~!*:@&+$/" + "?%%#=-]*" }, + "link" }, }, {}, "", diff --git a/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp b/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp index 9ccc71ff0..7d6a384a8 100644 --- a/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp +++ b/src/modules/eterm/src/eterm/terminal/terminaldisplay.cpp @@ -1081,8 +1081,12 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) { auto advanceX = spaceCharAdvanceX * ( isWide ? 2.0f : 1.0f ); - if ( glyph.mode & ATTR_WDUMMY ) + if ( glyph.mode & ATTR_WDUMMY ) { + if ( mVBBackground ) + mVBBackground->setQuad( mCurGridPos, { x, y }, { advanceX, lineHeight }, + Color::Transparent ); continue; + } if ( mVBBackground ) { mVBBackground->setQuad( mCurGridPos, { x, y }, { advanceX, lineHeight }, bg ); @@ -1164,8 +1168,11 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) { auto advanceX = spaceCharAdvanceX * ( isWide ? 2.0f : 1.0f ); - if ( glyph.mode & ATTR_WDUMMY ) + if ( glyph.mode & ATTR_WDUMMY ) { + if ( mVBForeground ) + mVBForeground->setQuadColor( mCurGridPos, Color::Transparent ); continue; + } if ( glyph.u == 32 ) { x += advanceX; @@ -1180,25 +1187,18 @@ void TerminalDisplay::drawGrid( const Vector2f& pos ) { if ( mVBForeground ) mVBForeground->setQuadColor( mCurGridPos, Color::Transparent ); } else { - auto* gd = mFont->getGlyphDrawable( glyph.u, mFontSize, glyph.mode & ATTR_BOLD ); + auto* gd = mFont->getGlyphDrawable( glyph.u, mFontSize, glyph.mode & ATTR_BOLD, 0, + advanceX ); - if ( glyph.mode & ATTR_EMOJI ) { - if ( FontManager::instance()->getColorEmojiFont() ) { - Font* font = FontManager::instance()->getColorEmojiFont(); - gd = font->getGlyphDrawable( glyph.u, mFontSize ); - gd->setColor( Color::White ); - } else if ( FontManager::instance()->getEmojiFont() ) { - Font* font = FontManager::instance()->getEmojiFont(); - gd = font->getGlyphDrawable( glyph.u, mFontSize ); - gd->setColor( fg ); - } - gd->setDrawMode( GlyphDrawable::DrawMode::Text ); + if ( ( glyph.mode & ATTR_EMOJI ) && FontManager::instance()->getColorEmojiFont() ) { + gd->setColor( Color::White ); } else { - gd->setDrawMode( glyph.mode & ATTR_ITALIC ? GlyphDrawable::DrawMode::TextItalic - : GlyphDrawable::DrawMode::Text ); gd->setColor( fg ); } + gd->setDrawMode( glyph.mode & ATTR_ITALIC ? GlyphDrawable::DrawMode::TextItalic + : GlyphDrawable::DrawMode::Text ); + if ( mVBForeground ) { gd->drawIntoVertexBuffer( mVBForeground, mCurGridPos, { x, y } ); } else { diff --git a/src/tools/eterm/eterm.cpp b/src/tools/eterm/eterm.cpp index 5c3d66b83..9a5f882a8 100644 --- a/src/tools/eterm/eterm.cpp +++ b/src/tools/eterm/eterm.cpp @@ -202,7 +202,6 @@ EE_MAIN_FUNC int main( int argc, char* argv[] ) { if ( fontMono == nullptr ) { fontMono = FontTrueType::New( "monospace" ); fontMono->loadFromFile( resPath + "fonts/DejaVuSansMonoNerdFontComplete.ttf" ); - fontMono->setEnableEmojiFallback( false ); } if ( FileSystem::fileExists( resPath + "fonts/NotoColorEmoji.ttf" ) ) {