diff --git a/bin/unit_tests/assets/fontrendering/eepp-text-wrap.webp b/bin/unit_tests/assets/fontrendering/eepp-text-wrap.webp new file mode 100644 index 000000000..2265bea2a Binary files /dev/null and b/bin/unit_tests/assets/fontrendering/eepp-text-wrap.webp differ diff --git a/include/eepp/graphics/text.hpp b/include/eepp/graphics/text.hpp index 2b64cb699..7085a7bb0 100644 --- a/include/eepp/graphics/text.hpp +++ b/include/eepp/graphics/text.hpp @@ -342,6 +342,7 @@ class EE_API Text { mutable bool mColorsNeedUpdate : 1 { false }; mutable bool mContainsColorEmoji : 1 { false }; bool mTabStops : 1 { false }; + TextDirection mDirection{ TextDirection::Unspecified }; Float mCachedWidth{ 0 }; Uint32 mAlign{ TEXT_ALIGN_LEFT }; @@ -354,7 +355,6 @@ class EE_API Text { std::vector mOutlineVertices; std::vector mOutlineColors; std::vector mLinesWidth; - TextDirection mDirection{ TextDirection::Unspecified }; void ensureGeometryUpdate(); diff --git a/src/eepp/graphics/text.cpp b/src/eepp/graphics/text.cpp index 033b5ccee..9ed8a2fcc 100644 --- a/src/eepp/graphics/text.cpp +++ b/src/eepp/graphics/text.cpp @@ -657,7 +657,7 @@ void Text::onNewString() { mCachedWidthNeedUpdate = true; mContainsColorEmoji = false; mTextHints = mString.getTextHints(); - if ( FontManager::instance()->getColorEmojiFont() != nullptr ) { + if ( mFontStyleConfig.Font && FontManager::instance()->getColorEmojiFont() != nullptr ) { if ( mFontStyleConfig.Font->getType() == FontType::TTF ) { FontTrueType* fontTrueType = static_cast( mFontStyleConfig.Font ); if ( fontTrueType->isColorEmojiFont() || !fontTrueType->isEmojiFont() ) @@ -922,7 +922,7 @@ Float Text::getTextWidth( Font* font, const Uint32& fontSize, const StringType& if ( TextShaperEnabled && font->getType() == FontType::TTF && !canSkipShaping( textDrawHints ) ) { return TextLayout::layout( string, static_cast( font ), fontSize, style, - tabWidth, outlineThickness, tabOffset, textDrawHints ) + tabWidth, outlineThickness, tabOffset, textDrawHints, direction ) ->size.getWidth(); } #endif diff --git a/src/tests/unit_tests/fontrendering.cpp b/src/tests/unit_tests/fontrendering.cpp index e11ef2feb..762a3fbfa 100644 --- a/src/tests/unit_tests/fontrendering.cpp +++ b/src/tests/unit_tests/fontrendering.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -825,3 +826,60 @@ UTEST( FontRendering, UITextTest ) { runTest(); } } + +UTEST( FontRendering, TextWrap ) { + FileSystem::changeWorkingDirectory( Sys::getProcessPath() ); + std::string loremIpsum; + FileSystem::fileGet( "assets/textfiles/lorem-ipsum.uext", loremIpsum ); + + const auto runTest = [&]() { + UIApplication app( + WindowSettings( 512, 512, "eepp - Text Wrap", WindowStyle::Default, + WindowBackend::Default, 32, {}, 1, false, true ), + UIApplication::Settings( Sys::getProcessPath() + ".." + FileSystem::getOSSlash(), 1 ) ); + FileSystem::changeWorkingDirectory( Sys::getProcessPath() ); + app.getWindow()->setClearColor( RGB( 255, 255, 255 ) ); + app.getWindow()->clear(); + Vector2f pos{ 5, 5 }; + Primitives p; + p.setColor( Color::Red ); + p.drawRectangle( Rectf( pos - 1.f, { 1, 501 } ) ); + p.drawRectangle( Rectf( pos - 1.f, { 501, 1 } ) ); + p.drawRectangle( Rectf( { pos.x - 1.f, 500 + pos.y }, { 502, 1 } ) ); + p.drawRectangle( Rectf( { 500 + pos.x, pos.y - 1.f }, { 1, 501 } ) ); + + Text text; + text.setFont( app.getUI()->getUIThemeManager()->getDefaultFont() ); + text.setFontSize( 16 ); + text.setColor( Color::Black ); + text.setString( loremIpsum ); + text.wrapText( 500 ); + text.draw( pos.x, pos.y ); + + text.setAlign( TEXT_ALIGN_CENTER ); + pos.y += text.getTextHeight() + 8; + text.draw( pos.x, pos.y ); + + pos.y += text.getTextHeight() + 8; + text.setAlign( TEXT_ALIGN_RIGHT ); + text.draw( pos.x, pos.y ); + + compareImages( utest_state, utest_result, app.getWindow(), "eepp-text-wrap" ); + }; + + UTEST_PRINT_STEP( "Text Shaper disabled" ); + { + BoolScopedOp op( Text::TextShaperEnabled, false ); + runTest(); + } + + UTEST_PRINT_STEP( "Text Shaper enabled" ); + { + BoolScopedOp op( Text::TextShaperEnabled, true ); + runTest(); + + UTEST_PRINT_STEP( "Text Shaper enabled w/o optimizations" ); + BoolScopedOp op2( Text::TextShaperOptimizations, false ); + runTest(); + } +}