diff --git a/bin/unit_tests/assets/html/anchor_margins.html b/bin/unit_tests/assets/html/anchor_margins.html new file mode 100644 index 000000000..28183ac5a --- /dev/null +++ b/bin/unit_tests/assets/html/anchor_margins.html @@ -0,0 +1,65 @@ + + + + + + + + + diff --git a/bin/unit_tests/assets/html/eepp-ui-anchor-margins.webp b/bin/unit_tests/assets/html/eepp-ui-anchor-margins.webp new file mode 100644 index 000000000..70f198101 Binary files /dev/null and b/bin/unit_tests/assets/html/eepp-ui-anchor-margins.webp differ diff --git a/bin/unit_tests/assets/html/eepp-ui-span-padding.webp b/bin/unit_tests/assets/html/eepp-ui-span-padding.webp new file mode 100644 index 000000000..6ddf9b8fb Binary files /dev/null and b/bin/unit_tests/assets/html/eepp-ui-span-padding.webp differ diff --git a/bin/unit_tests/assets/html/span_padding.html b/bin/unit_tests/assets/html/span_padding.html new file mode 100644 index 000000000..5835d113f --- /dev/null +++ b/bin/unit_tests/assets/html/span_padding.html @@ -0,0 +1,56 @@ + + + + + + +
+ This is normal text with a padded span inside it. +
+
+ Here is a large padded span which should increase the line height and spacing. +
+
+ Finally, a mixed padding span to test asymmetrical padding values. +
+ + \ No newline at end of file diff --git a/include/eepp/graphics/richtext.hpp b/include/eepp/graphics/richtext.hpp index d803b5f63..1c7a90ced 100644 --- a/include/eepp/graphics/richtext.hpp +++ b/include/eepp/graphics/richtext.hpp @@ -33,6 +33,9 @@ class EE_API RichText : public Drawable { */ void addSpan( const String& text, const FontStyleConfig& style ); + void addSpan( const String& text, const FontStyleConfig& style, const Rectf& margin, + const Rectf& padding ); + /** * @brief Adds a text span with individual style parameters. * @param text The text content. @@ -82,7 +85,13 @@ class EE_API RichText : public Drawable { bool isBlock{ false }; }; - using Block = std::variant, std::shared_ptr, CustomBlock>; + struct SpanBlock { + std::shared_ptr text; + Rectf margin; + Rectf padding; + }; + + using Block = std::variant, CustomBlock>; /** * @brief Adds a drawable (e.g., an image) into the text flow. diff --git a/src/eepp/graphics/richtext.cpp b/src/eepp/graphics/richtext.cpp index 8bfc3705c..5e35eaace 100644 --- a/src/eepp/graphics/richtext.cpp +++ b/src/eepp/graphics/richtext.cpp @@ -57,7 +57,27 @@ void RichText::draw( const Float& X, const Float& Y, const Vector2f& scale, cons std::visit( Overloaded{ - [&]( const std::shared_ptr& text ) { + [&]( const SpanBlock& spanBlock ) { + const std::shared_ptr& text = spanBlock.text; + Color oldBgColor = text->getFontStyleConfig().BackgroundColor; + + if ( oldBgColor != Color::Transparent ) { + Primitives p; + p.setColor( oldBgColor ); + Rectf bgRect( + Vector2f( + std::trunc( X + pos.x - spanBlock.padding.Left ), + std::trunc( Y + line.y + pos.y - spanBlock.padding.Top ) ), + Sizef( span.size.getWidth() + spanBlock.padding.Left + + spanBlock.padding.Right, + span.size.getHeight() + spanBlock.padding.Top + + spanBlock.padding.Bottom ) ); + p.drawRectangle( bgRect, rotation, scale ); + } + + if ( oldBgColor != Color::Transparent ) + text->setBackgroundColor( Color::Transparent ); + bool selectionApplied = false; if ( mSelectionColor != Color::Transparent ) { TextSelectionRange spanSel = { @@ -85,6 +105,9 @@ void RichText::draw( const Float& X, const Float& Y, const Vector2f& scale, cons rotation, effect, rotationCenter, scaleCenter ); } + if ( oldBgColor != Color::Transparent ) + text->setBackgroundColor( oldBgColor ); + if ( selectionApplied ) text->invalidateColors(); }, @@ -127,9 +150,9 @@ Int64 RichText::findCharacterFromPos( const Vector2i& pos ) const { if ( pos.y >= line.y && pos.y < line.y + line.height ) { for ( const auto& span : line.spans ) { if ( pos.x >= span.position.x && pos.x < span.position.x + span.size.getWidth() ) { - if ( auto pText = std::get_if>( &span.block ) ) { + if ( auto pText = std::get_if( &span.block ) ) { return span.startCharIndex + - ( *pText )->findCharacterFromPos( Vector2i( + pText->text->findCharacterFromPos( Vector2i( pos.x - span.position.x, pos.y - line.y - span.position.y ) ); } else { return ( pos.x < span.position.x + span.size.getWidth() * 0.5f ) @@ -166,8 +189,8 @@ Vector2f RichText::findCharacterPos( Int64 index ) const { for ( const auto& line : mLines ) { for ( const auto& span : line.spans ) { if ( index >= span.startCharIndex && index < span.endCharIndex ) { - if ( auto pText = std::get_if>( &span.block ) ) { - Vector2f p = ( *pText )->findCharacterPos( index - span.startCharIndex ); + if ( auto pText = std::get_if( &span.block ) ) { + Vector2f p = pText->text->findCharacterPos( index - span.startCharIndex ); return { span.position.x + p.x, line.y + span.position.y + p.y }; } else { return { span.position.x, line.y + span.position.y }; @@ -197,8 +220,8 @@ SmallVector RichText::getSelectionRects() const { Int64 spanEnd = std::min( end, span.endCharIndex ); if ( spanStart < spanEnd ) { - if ( auto pText = std::get_if>( &span.block ) ) { - auto spanRects = ( *pText )->getSelectionRects( + if ( auto pText = std::get_if( &span.block ) ) { + auto spanRects = pText->text->getSelectionRects( { spanStart - span.startCharIndex, spanEnd - span.startCharIndex } ); for ( auto& rect : spanRects ) { rect.move( { span.position.x, line.y + span.position.y } ); @@ -237,9 +260,9 @@ String RichText::getSelectionString() const { Int64 spanEnd = std::min( end, span.endCharIndex ); if ( spanStart < spanEnd ) { - if ( auto pText = std::get_if>( &span.block ) ) { - res += ( *pText )->getString().substr( spanStart - span.startCharIndex, - spanEnd - spanStart ); + if ( auto pText = std::get_if( &span.block ) ) { + res += pText->text->getString().substr( spanStart - span.startCharIndex, + spanEnd - spanStart ); } else { // It's a drawable or custom size, it takes 1 "character" index. res += ' '; @@ -264,14 +287,15 @@ Sizef RichText::getPixelsSize() { return getSize(); } -void RichText::addSpan( const String& text, const FontStyleConfig& style ) { +void RichText::addSpan( const String& text, const FontStyleConfig& style, const Rectf& margin, + const Rectf& padding ) { if ( text.empty() ) return; auto span = std::make_shared(); span->setString( text ); span->setStyleConfig( style ); - mBlocks.push_back( span ); // Implicitly constructs the variant's Text alternative + mBlocks.push_back( SpanBlock{ span, margin, padding } ); invalidateLayout(); } @@ -287,6 +311,10 @@ void RichText::addCustomSize( const Sizef& size, bool isBlock ) { invalidateLayout(); } +void RichText::addSpan( const String& text, const FontStyleConfig& style ) { + addSpan( text, style, Rectf(), Rectf() ); +} + void RichText::addSpan( const String& text, Font* font, Uint32 characterSize, Color color, Uint32 style, Color backgroundColor ) { FontStyleConfig config; @@ -332,9 +360,9 @@ void RichText::setMaxWidth( Float width ) { void RichText::invalidate() { invalidateLayout(); for ( auto& block : mBlocks ) { - if ( auto pText = std::get_if>( &block ) ) { - if ( *pText ) - ( *pText )->invalidate(); + if ( auto pText = std::get_if( &block ) ) { + if ( pText->text ) + pText->text->invalidate(); } } } @@ -342,8 +370,8 @@ void RichText::invalidate() { Float RichText::getMinIntrinsicWidth() { Float minW = 0; for ( auto& block : mBlocks ) { - if ( auto pText = std::get_if>( &block ) ) { - auto& span = *pText; + if ( auto pText = std::get_if( &block ) ) { + auto& span = pText->text; if ( !span || span->getString().empty() ) continue; const String& s = span->getString(); @@ -359,7 +387,9 @@ Float RichText::getMinIntrinsicWidth() { end++; if ( start < end ) { minW = std::max( minW, Text::getTextWidth( s.substr( start, end - start ), - span->getFontStyleConfig() ) ); + span->getFontStyleConfig() ) + + pText->margin.Left + pText->margin.Right + + pText->padding.Left + pText->padding.Right ); } start = end; } @@ -376,23 +406,25 @@ Float RichText::getMaxIntrinsicWidth() { Float maxW = 0; Float curX = 0; for ( auto& block : mBlocks ) { - if ( auto pText = std::get_if>( &block ) ) { - auto& span = *pText; + if ( auto pText = std::get_if( &block ) ) { + auto& span = pText->text; if ( !span || span->getString().empty() ) continue; const String& s = span->getString(); size_t start = 0; size_t end = 0; + curX += pText->margin.Left + pText->padding.Left; while ( ( end = s.find( '\n', start ) ) != String::InvalidPos ) { curX += Text::getTextWidth( s.substr( start, end - start ), span->getFontStyleConfig(), 4, span->getTextHints() ); - maxW = std::max( maxW, curX ); + maxW = std::max( maxW, curX + pText->margin.Right + pText->padding.Right ); curX = 0; start = end + 1; } curX += Text::getTextWidth( s.substr( start ), span->getFontStyleConfig(), 4, - span->getTextHints() ); + span->getTextHints() ) + + pText->margin.Right + pText->padding.Right; } else if ( auto pDrawable = std::get_if>( &block ) ) { curX += ( *pDrawable )->getPixelsSize().getWidth(); } else if ( auto pSize = std::get_if( &block ) ) { @@ -423,8 +455,8 @@ void RichText::updateLayout() { Int64 curCharIdx = 0; for ( auto& block : mBlocks ) { - if ( auto pText = std::get_if>( &block ) ) { - auto& span = *pText; + if ( auto pText = std::get_if( &block ) ) { + auto& span = pText->text; if ( !span || span->getString().empty() ) continue; @@ -432,6 +464,11 @@ void RichText::updateLayout() { if ( !fontStyle.Font ) continue; + Float extraLeft = pText->margin.Left + pText->padding.Left; + curX += extraLeft; + if ( !mLines.empty() ) + mLines.back().width += extraLeft; + Uint32 textHints = span->getTextHints(); LineWrapInfoEx wrapInfo = LineWrap::computeLineBreaksEx( @@ -460,7 +497,7 @@ void RichText::updateLayout() { Float spanWidth = renderSpanText->getTextWidth(); RenderSpan renderSpan; - renderSpan.block = renderSpanText; + renderSpan.block = SpanBlock{ renderSpanText, pText->margin, pText->padding }; renderSpan.position = { curX, 0 }; // Y adjusted later renderSpan.size = Sizef( spanWidth, height ); // Configured BEFORE pushing to vector @@ -478,12 +515,30 @@ void RichText::updateLayout() { currentLine.width += spanWidth; } + if ( i == wrapInfo.wraps.size() - 2 && !isNewline ) { + Float extraRight = pText->margin.Right + pText->padding.Right; + curX += extraRight; + mLines.back().width += extraRight; + if ( !isNewline && mMaxWidth > 0 && curX > mMaxWidth ) { + // the margin forced a wrap + maxWidth = std::max( maxWidth, curX ); + mLines.push_back( RenderParagraph() ); + curX = 0; + continue; // skip the next newline check + } + } + // If it's a newline, or if it's not the very last segment (which means it wrapped), // start a new line. Exception: If the last segment was just a newline, we already // handled it. if ( i < wrapInfo.wraps.size() - 2 || isNewline ) { if ( isNewline ) { curCharIdx++; + if ( i == wrapInfo.wraps.size() - 2 ) { + Float extraRight = pText->margin.Right + pText->padding.Right; + curX += extraRight; + mLines.back().width += extraRight; + } } maxWidth = std::max( maxWidth, curX ); mLines.push_back( RenderParagraph() ); @@ -562,8 +617,8 @@ void RichText::updateLayout() { Float maxLineHeight = 0; for ( auto& span : line.spans ) { - if ( auto pText = std::get_if>( &span.block ) ) { - auto& textBlock = *pText; + if ( auto pText = std::get_if( &span.block ) ) { + auto& textBlock = pText->text; Float offsetY = line.maxAscent - textBlock->getCharacterSize(); span.position.x += xOffset; span.position.y = offsetY; diff --git a/src/eepp/ui/uirichtext.cpp b/src/eepp/ui/uirichtext.cpp index adb71dba3..e8cbe10f1 100644 --- a/src/eepp/ui/uirichtext.cpp +++ b/src/eepp/ui/uirichtext.cpp @@ -592,7 +592,9 @@ void UIRichText::rebuildRichText( UILayout* container, RichText& richText, Intri if ( widget->isType( UI_TYPE_TEXTSPAN ) ) { UITextSpan* span = widget->asType(); if ( !span->getText().empty() ) { - richText.addSpan( span->getText(), span->getFontStyleConfig() ); + Rectf margin = span->getLayoutPixelsMargin(); + Rectf padding = span->getPixelsPadding(); + richText.addSpan( span->getText(), span->getFontStyleConfig(), margin, padding ); } Node* spanChild = span->getFirstChild(); while ( spanChild != NULL ) { diff --git a/src/tests/unit_tests/richtext.cpp b/src/tests/unit_tests/richtext.cpp index 2aec19b61..56cba3e2d 100644 --- a/src/tests/unit_tests/richtext.cpp +++ b/src/tests/unit_tests/richtext.cpp @@ -362,8 +362,8 @@ UTEST( UIRichText, IntegrationAndLayoutVerification ) { ASSERT_EQ( blocks.size(), (size_t)4 ); // Check Text block - EXPECT_TRUE( std::holds_alternative>( blocks[1] ) ); - auto text1 = std::get>( blocks[1] ); + EXPECT_TRUE( std::holds_alternative( blocks[1] ) ); + auto text1 = std::get( blocks[1] ).text; EXPECT_TRUE( text1->getFillColor() == Color::fromString( "#FF0000" ) ); // Check CustomSize block @@ -374,7 +374,7 @@ UTEST( UIRichText, IntegrationAndLayoutVerification ) { UI::UIWidget* placeholder = rt->find( "placeholder" ); ASSERT_TRUE( placeholder != nullptr ); - auto text0 = std::get>( blocks[0] ); + auto text0 = std::get( blocks[0] ).text; Vector2f pos = placeholder->getPixelsPosition(); Float expectedX = text0->getTextWidth() + text1->getTextWidth(); EXPECT_NEAR( pos.x, expectedX, 2.0f ); @@ -464,10 +464,10 @@ UTEST( UIRichText, NestedWidgetsIntegration ) { ASSERT_EQ( blocks.size(), (size_t)4 ); // Check block types - EXPECT_TRUE( std::holds_alternative>( blocks[0] ) ); - EXPECT_TRUE( std::holds_alternative>( blocks[1] ) ); + EXPECT_TRUE( std::holds_alternative( blocks[0] ) ); + EXPECT_TRUE( std::holds_alternative( blocks[1] ) ); EXPECT_TRUE( std::holds_alternative( blocks[2] ) ); - EXPECT_TRUE( std::holds_alternative>( blocks[3] ) ); + EXPECT_TRUE( std::holds_alternative( blocks[3] ) ); EXPECT_EQ( std::get( blocks[2] ).size.getWidth(), PixelDensity::dpToPx( 50 ) ); @@ -478,8 +478,8 @@ UTEST( UIRichText, NestedWidgetsIntegration ) { UI::UIWidget* placeholder = rt->find( "placeholder" ); ASSERT_TRUE( placeholder != nullptr ); - auto text0 = std::get>( blocks[0] ); - auto text1 = std::get>( blocks[1] ); + auto text0 = std::get( blocks[0] ).text; + auto text1 = std::get( blocks[1] ).text; Vector2f pos = placeholder->getScreenPos(); Float expectedX = text0->getTextWidth() + text1->getTextWidth(); @@ -528,14 +528,14 @@ UTEST( UIRichText, DefaultStyleInheritance ) { // blocks[1] should be "Small" with overridden size and color ASSERT_TRUE( blocks.size() >= 2 ); - EXPECT_TRUE( std::holds_alternative>( blocks[0] ) ); - auto text0 = std::get>( blocks[0] ); + EXPECT_TRUE( std::holds_alternative( blocks[0] ) ); + auto text0 = std::get( blocks[0] ).text; EXPECT_EQ( text0->getCharacterSize(), rt->getFontSize() ); EXPECT_EQ( text0->getFillColor().getValue(), rt->getFontColor().getValue() ); EXPECT_EQ( text0->getFillColor().getValue(), Color::fromString( "#FF0000" ).getValue() ); - EXPECT_TRUE( std::holds_alternative>( blocks[1] ) ); - auto text1 = std::get>( blocks[1] ); + EXPECT_TRUE( std::holds_alternative( blocks[1] ) ); + auto text1 = std::get( blocks[1] ).text; EXPECT_EQ( text1->getCharacterSize(), (unsigned int)PixelDensity::dpToPxI( 16 ) ); EXPECT_EQ( text1->getFillColor().getValue(), Color::fromString( "#00FF00" ).getValue() ); diff --git a/src/tests/unit_tests/uihtml_tests.cpp b/src/tests/unit_tests/uihtml_tests.cpp index 997d0629b..568efd85e 100644 --- a/src/tests/unit_tests/uihtml_tests.cpp +++ b/src/tests/unit_tests/uihtml_tests.cpp @@ -140,6 +140,74 @@ UTEST( UIHTMLTable, complexLayout2 ) { Engine::destroySingleton(); } +UTEST( UIRichText, anchorMargins ) { + auto win = Engine::instance()->createWindow( + WindowSettings( 800, 600, "Anchor Margins Test", WindowStyle::Default, + WindowBackend::Default, 32, {}, 1, false, true ), + ContextSettings( false, 0, 0, GLv_default, true, false ) ); + FileSystem::changeWorkingDirectory( Sys::getProcessPath() ); + + FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ); + font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" ); + ASSERT_TRUE( font != nullptr && font->loaded() ); + FontFamily::loadFromRegular( font ); + + UI::UISceneNode* sceneNode = UI::UISceneNode::New(); + SceneManager::instance()->add( sceneNode ); + UI::UIThemeManager* themeManager = sceneNode->getUIThemeManager(); + themeManager->setDefaultFont( font ); + sceneNode->setURI( "file://" + Sys::getProcessPath() + "assets/html/" ); + std::string html; + FileSystem::fileGet( "assets/html/anchor_margins.html", html ); + sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( html ) ); + win->setClearColor( Color::White ); + + win->getInput()->update(); + SceneManager::instance()->update(); + + win->clear(); + SceneManager::instance()->draw(); + win->display(); + + compareImages( utest_state, utest_result, win, "eepp-ui-anchor-margins", "html" ); + + Engine::destroySingleton(); +} + +UTEST( UIRichText, spanPadding ) { + auto win = Engine::instance()->createWindow( + WindowSettings( 800, 600, "Span Padding Test", WindowStyle::Default, WindowBackend::Default, + 32, {}, 1, false, true ), + ContextSettings( false, 0, 0, GLv_default, true, false ) ); + FileSystem::changeWorkingDirectory( Sys::getProcessPath() ); + + FontTrueType* font = FontTrueType::New( "NotoSans-Regular" ); + font->loadFromFile( "../assets/fonts/NotoSans-Regular.ttf" ); + ASSERT_TRUE( font != nullptr && font->loaded() ); + FontFamily::loadFromRegular( font ); + + UI::UISceneNode* sceneNode = UI::UISceneNode::New(); + SceneManager::instance()->add( sceneNode ); + UI::UIThemeManager* themeManager = sceneNode->getUIThemeManager(); + themeManager->setDefaultFont( font ); + sceneNode->setURI( "file://" + Sys::getProcessPath() + "assets/html/" ); + std::string html; + FileSystem::fileGet( "assets/html/span_padding.html", html ); + sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( html ) ); + win->setClearColor( Color::White ); + + win->getInput()->update(); + SceneManager::instance()->update(); + + win->clear(); + SceneManager::instance()->draw(); + win->display(); + + compareImages( utest_state, utest_result, win, "eepp-ui-span-padding", "html" ); + + Engine::destroySingleton(); +} + UTEST( UIHTMLTable, complexLayout3 ) { auto win = Engine::instance()->createWindow( WindowSettings( 1024, 650, "HTML Tables Test 3", WindowStyle::Default, @@ -587,8 +655,7 @@ UTEST( UILayout, listStyleTypeDecimal ) { sceneNode->updateDirtyLayouts(); - const auto* propDef = - StyleSheetSpecification::instance()->getProperty( "list-style-type" ); + const auto* propDef = StyleSheetSpecification::instance()->getProperty( "list-style-type" ); ASSERT_TRUE( propDef != nullptr ); auto* li1 = sceneNode->getRoot()->find( "li1" )->asType(); @@ -619,8 +686,7 @@ UTEST( UILayout, listStyleTypeDisc ) { sceneNode->updateDirtyLayouts(); - const auto* propDef = - StyleSheetSpecification::instance()->getProperty( "list-style-type" ); + const auto* propDef = StyleSheetSpecification::instance()->getProperty( "list-style-type" ); ASSERT_TRUE( propDef != nullptr ); auto* li1 = sceneNode->getRoot()->find( "li1" )->asType(); @@ -651,10 +717,8 @@ UTEST( UILayout, listStyleShorthand ) { sceneNode->updateDirtyLayouts(); - const auto* typeDef = - StyleSheetSpecification::instance()->getProperty( "list-style-type" ); - const auto* posDef = - StyleSheetSpecification::instance()->getProperty( "list-style-position" ); + const auto* typeDef = StyleSheetSpecification::instance()->getProperty( "list-style-type" ); + const auto* posDef = StyleSheetSpecification::instance()->getProperty( "list-style-position" ); for ( const char* id : { "li1", "li2", "li3", "li4", "li5", "li6" } ) { auto* li = sceneNode->getRoot()->find( id )->asType(); @@ -662,18 +726,27 @@ UTEST( UILayout, listStyleShorthand ) { EXPECT_TRUE( li->isType( UI_TYPE_HTML_LIST_ITEM ) ); } - EXPECT_TRUE( sceneNode->getRoot()->find( "li1" )->asType()->getPropertyString( typeDef ) == "decimal" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "li1" )->asType()->getPropertyString( posDef ) == "outside" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "li1" )->asType()->getPropertyString( + typeDef ) == "decimal" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "li1" )->asType()->getPropertyString( + posDef ) == "outside" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "li2" )->asType()->getPropertyString( typeDef ) == "lower-alpha" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "li2" )->asType()->getPropertyString( posDef ) == "inside" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "li2" )->asType()->getPropertyString( + typeDef ) == "lower-alpha" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "li2" )->asType()->getPropertyString( + posDef ) == "inside" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "li3" )->asType()->getPropertyString( typeDef ) == "none" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "li3" )->asType()->getPropertyString( + typeDef ) == "none" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "li4" )->asType()->getPropertyString( typeDef ) == "disc" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "li5" )->asType()->getPropertyString( typeDef ) == "square" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "li5" )->asType()->getPropertyString( posDef ) == "outside" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "li6" )->asType()->getPropertyString( typeDef ) == "circle" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "li4" )->asType()->getPropertyString( + typeDef ) == "disc" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "li5" )->asType()->getPropertyString( + typeDef ) == "square" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "li5" )->asType()->getPropertyString( + posDef ) == "outside" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "li6" )->asType()->getPropertyString( + typeDef ) == "circle" ); Engine::destroySingleton(); } @@ -714,14 +787,18 @@ UTEST( UILayout, listStyleInheritanceFromUl ) { sceneNode->updateDirtyLayouts(); - const auto* typeDef = - StyleSheetSpecification::instance()->getProperty( "list-style-type" ); + const auto* typeDef = StyleSheetSpecification::instance()->getProperty( "list-style-type" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "h1" )->asType()->getPropertyString( typeDef ) == "upper-roman" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "a1" )->asType()->getPropertyString( typeDef ) == "circle" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "b1" )->asType()->getPropertyString( typeDef ) == "disc" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "c1" )->asType()->getPropertyString( typeDef ) == "square" ); - EXPECT_TRUE( sceneNode->getRoot()->find( "d1" )->asType()->getPropertyString( typeDef ) == "decimal" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "h1" )->asType()->getPropertyString( + typeDef ) == "upper-roman" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "a1" )->asType()->getPropertyString( + typeDef ) == "circle" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "b1" )->asType()->getPropertyString( + typeDef ) == "disc" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "c1" )->asType()->getPropertyString( + typeDef ) == "square" ); + EXPECT_TRUE( sceneNode->getRoot()->find( "d1" )->asType()->getPropertyString( + typeDef ) == "decimal" ); Engine::destroySingleton(); }