Skip to content

Commit 3f304e9

Browse files
committed
Float minor fix.
1 parent c9add70 commit 3f304e9

4 files changed

Lines changed: 155 additions & 5 deletions

File tree

src/eepp/graphics/richtext.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1365,12 +1365,18 @@ class RichTextInlineLayouter {
13651365
}
13661366

13671367
Float floatBoundsBottom = 0;
1368-
for ( size_t i = externalLeftFloatCount; i < leftFloats.size(); ++i )
1368+
Float floatBoundsRight = 0;
1369+
for ( size_t i = externalLeftFloatCount; i < leftFloats.size(); ++i ) {
13691370
floatBoundsBottom = std::max( floatBoundsBottom, leftFloats[i].Bottom );
1370-
for ( size_t i = externalRightFloatCount; i < rightFloats.size(); ++i )
1371+
floatBoundsRight = std::max( floatBoundsRight, leftFloats[i].Right );
1372+
}
1373+
for ( size_t i = externalRightFloatCount; i < rightFloats.size(); ++i ) {
13711374
floatBoundsBottom = std::max( floatBoundsBottom, rightFloats[i].Bottom );
1375+
floatBoundsRight = std::max( floatBoundsRight, rightFloats[i].Right );
1376+
}
13721377

1373-
result.size = Sizef( maxWidth, std::max( accumY, floatBoundsBottom ) );
1378+
result.size =
1379+
Sizef( std::max( maxWidth, floatBoundsRight ), std::max( accumY, floatBoundsBottom ) );
13741380
result.totalCharacterCount = curCharIdx;
13751381
return result;
13761382
}

src/eepp/ui/blocklayouter.cpp

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,38 @@ void BlockLayouter::updateLayout() {
128128

129129
positionRichTextChildren( rt );
130130

131+
Sizef contentSize = rt->getSize();
132+
if ( mContainer->getLayoutWidthPolicy() == SizePolicy::WrapContent ||
133+
mContainer->getLayoutHeightPolicy() == SizePolicy::WrapContent ) {
134+
// RichText computes float placement from custom-block sizes captured before the
135+
// corresponding widgets are positioned and may be resized by nested layout. For the
136+
// intentional HTML-layer hit-test compatibility behavior, wrap-content parents must grow to
137+
// the final floated child bounds, including the parent's padding/content offset.
138+
const Rectf contentOffset = mContainer->getPixelsContentOffset();
139+
Node* child = mContainer->getFirstChild();
140+
while ( child != nullptr ) {
141+
if ( child->isWidget() && child->isType( UI_TYPE_HTML_WIDGET ) ) {
142+
auto* childWidget = child->asType<UIHTMLWidget>();
143+
if ( childWidget->isVisible() && !childWidget->isOutOfFlow() &&
144+
childWidget->getCSSFloat() != CSSFloat::None ) {
145+
const Rectf margin = childWidget->getNormalFlowLayoutPixelsMargin();
146+
const Vector2f pos = childWidget->getPixelsPosition();
147+
const Sizef size = childWidget->getPixelsSize();
148+
contentSize.setWidth(
149+
std::max( contentSize.getWidth(), pos.x - margin.Left + size.getWidth() +
150+
margin.Right - contentOffset.Left ) );
151+
contentSize.setHeight( std::max( contentSize.getHeight(),
152+
pos.y - margin.Top + size.getHeight() +
153+
margin.Bottom - contentOffset.Top ) );
154+
}
155+
}
156+
child = child->getNextNode();
157+
}
158+
}
159+
131160
Float totW = mContainer->getPixelsSize().getWidth();
132161
if ( mContainer->getLayoutWidthPolicy() == SizePolicy::WrapContent ) {
133-
totW = rt->getSize().getWidth() + mContainer->getPixelsContentOffset().Left +
162+
totW = contentSize.getWidth() + mContainer->getPixelsContentOffset().Left +
134163
mContainer->getPixelsContentOffset().Right;
135164
if ( !mContainer->getMaxWidthEq().empty() && totW > mContainer->getMaxSizePx().getWidth() )
136165
mContainer->setClipType( ClipType::ContentBox );
@@ -157,7 +186,7 @@ void BlockLayouter::updateLayout() {
157186

158187
Float totH = mContainer->getPixelsSize().getHeight();
159188
if ( mContainer->getLayoutHeightPolicy() == SizePolicy::WrapContent ) {
160-
totH = rt->getSize().getHeight() + mContainer->getPixelsContentOffset().Top +
189+
totH = contentSize.getHeight() + mContainer->getPixelsContentOffset().Top +
161190
mContainer->getPixelsContentOffset().Bottom;
162191
if ( !mContainer->getMaxHeightEq().empty() &&
163192
totH > mContainer->getMaxSizePx().getHeight() )

src/tests/unit_tests/uihtml_float_tests.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,32 @@ UTEST( UIHTMLFloat, floatLeftNonHTMLwidget_NoCrash ) {
11281128
Engine::destroySingleton();
11291129
}
11301130

1131+
UTEST( UIHTMLFloat, floatOnlyWrapContentParentIncludesPadding ) {
1132+
init_float_test();
1133+
UISceneNode* sceneNode = SceneManager::instance()->getUISceneNode();
1134+
1135+
UIRichText* container = UIRichText::New();
1136+
container->setParent( sceneNode->getRoot() );
1137+
container->setPixelsPosition( 10, 10 );
1138+
container->setPaddingPixels( { 10, 10, 10, 10 } );
1139+
container->setLayoutSizePolicy( SizePolicy::WrapContent, SizePolicy::WrapContent );
1140+
1141+
UIHTMLWidget* floatChild = UIHTMLWidget::New();
1142+
floatChild->setParent( container );
1143+
floatChild->setPixelsSize( 10, 10 );
1144+
floatChild->setCSSFloat( CSSFloat::Left );
1145+
floatChild->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed );
1146+
1147+
sceneNode->updateDirtyLayouts();
1148+
1149+
EXPECT_NEAR( container->getPixelsSize().getWidth(), 30.f, 1.f );
1150+
EXPECT_NEAR( container->getPixelsSize().getHeight(), 30.f, 1.f );
1151+
EXPECT_NEAR( floatChild->getPixelsPosition().x, 10.f, 1.f );
1152+
EXPECT_NEAR( floatChild->getPixelsPosition().y, 10.f, 1.f );
1153+
1154+
Engine::destroySingleton();
1155+
}
1156+
11311157
UTEST( UIHTMLFloat, floatNotAffectedByTextAlignCenter ) {
11321158
Engine::instance()->createWindow( WindowSettings( 800, 600, "Float + TextAlign Test",
11331159
WindowStyle::Default, WindowBackend::Default,

src/tests/unit_tests/uihtml_tests.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3656,6 +3656,95 @@ UTEST( UIHTML, RedditHeaderPagenameBottomAlign ) {
36563656
Engine::destroySingleton();
36573657
}
36583658

3659+
UTEST( UIHTML, PaddedHeaderWithNestedFloatsDoesNotOverlapClearedMain ) {
3660+
auto win = Engine::instance()->createWindow(
3661+
WindowSettings( 1024, 653, "padded header nested floats", WindowStyle::Default,
3662+
WindowBackend::Default, 32, {}, 1, false, true ),
3663+
ContextSettings( false, 0, 0, GLv_default, true, false ) );
3664+
FileSystem::changeWorkingDirectory( Sys::getProcessPath() );
3665+
3666+
UI::UISceneNode* sceneNode = init_test_inline_block();
3667+
sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( R"html(
3668+
<html>
3669+
<head>
3670+
<style>
3671+
#header {
3672+
padding: 30px 0 0 0;
3673+
width: 940px;
3674+
}
3675+
#masthead {
3676+
width: 940px;
3677+
}
3678+
#branding {
3679+
float: left;
3680+
width: 940px;
3681+
height: 267px;
3682+
}
3683+
#access {
3684+
display: block;
3685+
float: left;
3686+
width: 940px;
3687+
}
3688+
#access ul {
3689+
list-style: none;
3690+
margin: 0;
3691+
padding: 0;
3692+
}
3693+
#access li {
3694+
float: left;
3695+
}
3696+
#access a {
3697+
display: block;
3698+
line-height: 38px;
3699+
padding: 0 10px;
3700+
}
3701+
#main {
3702+
clear: both;
3703+
padding: 40px 0 0 0;
3704+
width: 940px;
3705+
}
3706+
</style>
3707+
</head>
3708+
<body>
3709+
<div id="header">
3710+
<div id="masthead">
3711+
<div id="branding"></div>
3712+
<div id="access">
3713+
<ul>
3714+
<li><a>Home</a></li>
3715+
</ul>
3716+
</div>
3717+
</div>
3718+
</div>
3719+
<div id="main"></div>
3720+
</body>
3721+
</html>
3722+
)html" ) );
3723+
win->getInput()->update();
3724+
SceneManager::instance()->update();
3725+
sceneNode->updateDirtyLayouts();
3726+
3727+
auto* header = sceneNode->getRoot()->find( "header" )->asType<UIHTMLWidget>();
3728+
auto* main = sceneNode->getRoot()->find( "main" )->asType<UIHTMLWidget>();
3729+
auto* branding = sceneNode->getRoot()->find( "branding" )->asType<UIHTMLWidget>();
3730+
auto* access = sceneNode->getRoot()->find( "access" )->asType<UIHTMLWidget>();
3731+
ASSERT_TRUE( header != nullptr );
3732+
ASSERT_TRUE( main != nullptr );
3733+
ASSERT_TRUE( branding != nullptr );
3734+
ASSERT_TRUE( access != nullptr );
3735+
3736+
const Float headerBottom =
3737+
header->convertToWorldSpace( { 0, 0 } ).y + header->getPixelsSize().getHeight();
3738+
const Float mainTop = main->convertToWorldSpace( { 0, 0 } ).y;
3739+
3740+
EXPECT_GE( header->getPixelsSize().getHeight(), header->getPixelsContentOffset().Top +
3741+
branding->getPixelsSize().getHeight() +
3742+
access->getPixelsSize().getHeight() );
3743+
EXPECT_GE( mainTop + 0.5f, headerBottom );
3744+
3745+
Engine::destroySingleton();
3746+
}
3747+
36593748
UTEST( UIHTML, AnchorsSizing ) {
36603749
auto win = Engine::instance()->createWindow(
36613750
WindowSettings( 1024, 653, "anchors sizing", WindowStyle::Default, WindowBackend::Default,

0 commit comments

Comments
 (0)