diff --git a/include/eepp/graphics/fonttruetype.hpp b/include/eepp/graphics/fonttruetype.hpp index 34df16b32..ed98bca72 100644 --- a/include/eepp/graphics/fonttruetype.hpp +++ b/include/eepp/graphics/fonttruetype.hpp @@ -123,7 +123,7 @@ class EE_API FontTrueType : public Font { bool mIsEmojiFont{ false }; mutable std::map mClosestCharacterSize; - Uint64 getCharIndexKey( Uint32 codePoint, bool bold, Float outlineThickness ) const; + Uint64 getCodePointIndexKey( Uint32 codePoint, bool bold, Float outlineThickness ) const; }; }} // namespace EE::Graphics diff --git a/src/eepp/core/string.cpp b/src/eepp/core/string.cpp index fdfc263c5..ec6a3b25b 100644 --- a/src/eepp/core/string.cpp +++ b/src/eepp/core/string.cpp @@ -175,7 +175,8 @@ std::vector String::split( const String& str, const StringBaseType& deli cont.emplace_back( std::move( substr ) ); if ( keepDelim ) { for ( size_t i = 0; i < cont.size(); i++ ) { - if ( i != cont.size() - 1 ) + if ( i != cont.size() - 1 || + ( str.lastChar() == delim && cont[cont.size() - 1].lastChar() != delim ) ) cont[i].push_back( delim ); if ( cont[cont.size() - 1].empty() ) cont.pop_back(); @@ -201,7 +202,10 @@ std::vector String::split( const std::string& str, const Int8& deli cont.emplace_back( std::move( substr ) ); if ( keepDelim ) { for ( size_t i = 0; i < cont.size(); i++ ) { - if ( i != cont.size() - 1 ) + if ( i != cont.size() - 1 || + ( !str.empty() && str[str.size() - 1] == delim && !cont.empty() && + !cont[cont.size() - 1].empty() && + cont[cont.size() - 1][cont[cont.size() - 1].size() - 1] != delim ) ) cont[i].push_back( delim ); if ( cont[cont.size() - 1].empty() ) cont.pop_back(); diff --git a/src/eepp/graphics/font.cpp b/src/eepp/graphics/font.cpp index 4dc9249ff..344f8e82c 100644 --- a/src/eepp/graphics/font.cpp +++ b/src/eepp/graphics/font.cpp @@ -10,14 +10,11 @@ bool Font::isEmojiCodePoint( const Uint32& codePoint ) { const Uint32 rangeMax = 131069; const Uint32 rangeMin2 = 126980; const Uint32 rangeMax2 = 127569; - const Uint32 rangeMin3 = 169; - const Uint32 rangeMax3 = 174; - const Uint32 rangeMin4 = 8205; - const Uint32 rangeMax4 = 12953; + const Uint32 rangeMin3 = 8987; + const Uint32 rangeMax3 = 12953; return ( ( rangeMin <= codePoint && codePoint <= rangeMax ) || ( rangeMin2 <= codePoint && codePoint <= rangeMax2 ) || - ( rangeMin3 <= codePoint && codePoint <= rangeMax3 ) || - ( rangeMin4 <= codePoint && codePoint <= rangeMax4 ) ); + ( rangeMin3 <= codePoint && codePoint <= rangeMax3 ) ); } bool Font::containsEmojiCodePoint( const String& string ) { diff --git a/src/eepp/graphics/fonttruetype.cpp b/src/eepp/graphics/fonttruetype.cpp index 0c1bc0be7..27dca2f29 100644 --- a/src/eepp/graphics/fonttruetype.cpp +++ b/src/eepp/graphics/fonttruetype.cpp @@ -18,6 +18,7 @@ #include namespace { + // FreeType callbacks that operate on a IOStream unsigned long read( FT_Stream rec, unsigned long offset, unsigned char* buffer, unsigned long count ) { @@ -43,8 +44,8 @@ template inline T reinterpret( const U& input ) { // Combine outline thickness, boldness and font glyph index into a single 64-bit key EE::Uint64 combine( float outlineThickness, bool bold, EE::Uint32 index ) { - return ( static_cast( reinterpret( outlineThickness ) ) << 32 ) | - ( static_cast( bold ) << 31 ) | index; + return ( static_cast( reinterpret( outlineThickness * 100 ) ) << 33 ) | + ( static_cast( bold ) << 32 ) | index; } } // namespace @@ -332,30 +333,8 @@ const FontTrueType::Info& FontTrueType::getInfo() const { return mInfo; } -Uint64 FontTrueType::getCharIndexKey( Uint32 codePoint, bool bold, Float outlineThickness ) const { - Uint32 charIndex = FT_Get_Char_Index( static_cast( mFace ), codePoint ); - Uint64 key = combine( outlineThickness, bold, charIndex ); - - if ( charIndex == 0 && Font::isEmojiCodePoint( codePoint ) && !mIsColorEmojiFont && - !mIsEmojiFont ) { - if ( FontManager::instance()->getColorEmojiFont() != nullptr && - FontManager::instance()->getColorEmojiFont()->getType() == FontType::TTF ) { - FontTrueType* fontEmoji = - static_cast( FontManager::instance()->getColorEmojiFont() ); - key = - combine( outlineThickness, bold, - FT_Get_Char_Index( static_cast( fontEmoji->mFace ), codePoint ) ); - } else if ( FontManager::instance()->getEmojiFont() != nullptr && - FontManager::instance()->getEmojiFont()->getType() == FontType::TTF ) { - FontTrueType* fontEmoji = - static_cast( FontManager::instance()->getEmojiFont() ); - key = - combine( outlineThickness, bold, - FT_Get_Char_Index( static_cast( fontEmoji->mFace ), codePoint ) ); - } - } - - return key; +Uint64 FontTrueType::getCodePointIndexKey( Uint32 codePoint, bool bold, Float outlineThickness ) const { + return combine( outlineThickness, bold, codePoint ); } const Glyph& FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSize, bool bold, @@ -364,7 +343,7 @@ const Glyph& FontTrueType::getGlyph( Uint32 codePoint, unsigned int characterSiz GlyphTable& glyphs = mPages[characterSize].glyphs; // Build the key by combining the code point, bold flag, and outline thickness - Uint64 key = getCharIndexKey( codePoint, bold, outlineThickness ); + Uint64 key = getCodePointIndexKey( codePoint, bold, outlineThickness ); // Search the glyph into the cache GlyphTable::const_iterator it = glyphs.find( key ); @@ -383,7 +362,7 @@ GlyphDrawable* FontTrueType::getGlyphDrawable( Uint32 codePoint, unsigned int ch bool bold, Float outlineThickness ) const { GlyphDrawableTable& drawables = mPages[characterSize].drawables; - Uint64 key = getCharIndexKey( codePoint, bold, outlineThickness ); + Uint64 key = getCodePointIndexKey( codePoint, bold, outlineThickness ); auto it = drawables.find( key ); if ( it != drawables.end() ) { diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index c2bec7308..8d99b9c57 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -1437,13 +1437,13 @@ TextRange TextDocument::find( String text, TextPosition from, const bool& caseSe if ( TextPosition( initPos.line(), (Int64)currentLine.size() - 1 ) > to ) return find( text, range.end(), caseSensitive, wholeWord, type, restrictRange ); - if ( caseSensitive ) { + if ( !caseSensitive ) { currentLine.toLower(); textLines[i].toLower(); } if ( currentLine == textLines[i] ) { - initPos = TextPosition( initPos.line(), 0 ); + initPos = TextPosition( i + 1, 0 ); } else { return find( text, range.end(), caseSensitive, wholeWord, type, restrictRange ); } @@ -1461,8 +1461,13 @@ TextRange TextDocument::find( String text, TextPosition from, const bool& caseSe if ( lastLine.size() < curSearch.size() ) return find( text, range.end(), caseSensitive, wholeWord, type, restrictRange ); - if ( String::startsWith( lastLine, curSearch ) ) - return TextRange( range.start(), TextPosition( initPos.line(), curSearch.size() ) ); + if ( String::startsWith( lastLine, curSearch ) ) { + TextRange foundRange( range.start(), + TextPosition( initPos.line(), curSearch.size() ) ); + if ( foundRange.end().column() == (Int64)mLines[foundRange.end().line()].size() ) + foundRange.setEnd( positionOffset( foundRange.end(), 1 ) ); + return foundRange; + } } } @@ -1505,13 +1510,13 @@ TextRange TextDocument::findLast( String text, TextPosition from, const bool& ca return findLast( text, range.end(), caseSensitive, wholeWord, type, restrictRange ); - if ( caseSensitive ) { + if ( !caseSensitive ) { currentLine.toLower(); textLines[i].toLower(); } if ( currentLine == textLines[i] ) { - initPos = TextPosition( initPos.line(), 0 ); + initPos = TextPosition( i + 1, 0 ); } else { return findLast( text, range.end(), caseSensitive, wholeWord, type, restrictRange ); @@ -1530,8 +1535,13 @@ TextRange TextDocument::findLast( String text, TextPosition from, const bool& ca if ( lastLine.size() < curSearch.size() ) return findLast( text, range.end(), caseSensitive, wholeWord, type, restrictRange ); - if ( String::startsWith( lastLine, curSearch ) ) - return TextRange( range.start(), TextPosition( initPos.line(), curSearch.size() ) ); + if ( String::startsWith( lastLine, curSearch ) ) { + TextRange foundRange( range.start(), + TextPosition( initPos.line(), curSearch.size() ) ); + if ( foundRange.end().column() == (Int64)mLines[foundRange.end().line()].size() ) + foundRange.setEnd( positionOffset( foundRange.end(), 1 ) ); + return foundRange; + } } } diff --git a/src/eepp/ui/uiwindow.cpp b/src/eepp/ui/uiwindow.cpp index 4872076b6..35506a480 100644 --- a/src/eepp/ui/uiwindow.cpp +++ b/src/eepp/ui/uiwindow.cpp @@ -1403,7 +1403,9 @@ Sizef UIWindow::getSizeWithoutDecoration() { } Sizef UIWindow::getMinWindowTitleSizeRequired() { - Sizef size( PixelDensity::pxToDp( mTitle->getTextWidth() + mTitle->getFontSize() * 4 ) + + Sizef size( PixelDensity::pxToDp( mTitle != nullptr + ? ( mTitle->getTextWidth() + mTitle->getFontSize() * 4 ) + : 0 ) + mPadding.Left + mPadding.Right, 0 ); diff --git a/src/tools/codeeditor/docsearchcontroller.cpp b/src/tools/codeeditor/docsearchcontroller.cpp index 4c3f42e3e..8ec524389 100644 --- a/src/tools/codeeditor/docsearchcontroller.cpp +++ b/src/tools/codeeditor/docsearchcontroller.cpp @@ -14,7 +14,7 @@ static void replaceAllEscapedSequences( String& target, const String& that, cons } } -static void escapeSequences( String& txt ) { +static void unescapeSequences( String& txt ) { replaceAllEscapedSequences( txt, "\\n", String( '\n' ) ); replaceAllEscapedSequences( txt, "\\t", String( '\t' ) ); replaceAllEscapedSequences( txt, "\\r", String( '\r' ) ); @@ -203,7 +203,7 @@ bool DocSearchController::findPrevText( SearchState& search ) { String txt( search.text ); if ( search.escapeSequences ) - escapeSequences( txt ); + unescapeSequences( txt ); TextRange found = doc.findLast( txt, from, search.caseSensitive, search.wholeWord, search.type, search.range ); @@ -243,7 +243,7 @@ bool DocSearchController::findNextText( SearchState& search ) { String txt( search.text ); if ( search.escapeSequences ) - escapeSequences( txt ); + unescapeSequences( txt ); TextRange found = doc.find( txt, from, search.caseSensitive, search.wholeWord, search.type, range ); @@ -288,8 +288,8 @@ int DocSearchController::replaceAll( SearchState& search, const String& replace String txt( search.text ); String repl( replace ); if ( search.escapeSequences ) { - escapeSequences( txt ); - escapeSequences( repl ); + unescapeSequences( txt ); + unescapeSequences( repl ); } int count = doc.replaceAll( txt, repl, search.caseSensitive, search.wholeWord, search.type, @@ -312,8 +312,8 @@ bool DocSearchController::findAndReplace( SearchState& search, const String& rep String txt( search.text ); String repl( replace ); if ( search.escapeSequences ) { - escapeSequences( txt ); - escapeSequences( repl ); + unescapeSequences( txt ); + unescapeSequences( repl ); } if ( doc.hasSelection() && doc.getSelectedText() == txt ) {