diff --git a/bin/unit_tests/assets/html/flex_form.html b/bin/unit_tests/assets/html/flex_form.html index 8bd2b9093..f4107cdb3 100644 --- a/bin/unit_tests/assets/html/flex_form.html +++ b/bin/unit_tests/assets/html/flex_form.html @@ -4,6 +4,7 @@ +
+ + )html"; + sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( html ) ); + win->getInput()->update(); + SceneManager::instance()->update(); + sceneNode->updateDirtyLayouts(); + + const Sizef base = applyImageSizingOrder( sceneNode, { "width", "height", "max-width" } ); + EXPECT_GT( base.getWidth(), 0.f ); + EXPECT_GT( base.getHeight(), 0.f ); + // max-width:100% constrains the image to the 800px containing block, and + // height:auto keeps the 1436/2560 aspect ratio. + EXPECT_LE( base.getWidth(), 800.f ); + EXPECT_NEAR( base.getHeight() / base.getWidth(), 1436.f / 2560.f, 0.01f ); + + const std::vector> orders = { + { "max-width", "height", "width" }, + { "height", "width", "max-width" }, + { "max-width", "width", "height" }, + }; + for ( const auto& order : orders ) { + const Sizef other = applyImageSizingOrder( sceneNode, order ); + EXPECT_NEAR( other.getWidth(), base.getWidth(), 1.f ); + EXPECT_NEAR( other.getHeight(), base.getHeight(), 1.f ); + } + + Engine::destroySingleton(); +} + +UTEST( UIHTML, ImageHeightAutoMaxWidthStyleStateTransition ) { + auto win = Engine::instance()->createWindow( + WindowSettings( 1024, 768, "img style state transition", WindowStyle::Default, + WindowBackend::Default, 32, {}, 1, false, true ), + ContextSettings( false, 0, 0, GLv_default, true, false ) ); + + UISceneNode* sceneNode = init_test_inline_block(); + sceneNode->setURI( "file://" + Sys::getProcessPath() + "assets/html/" ); + + const std::string html = R"html( + + + +
+ + )html"; + sceneNode->loadLayoutFromString( HTMLFormatter::HTMLtoXML( html ) ); + win->getInput()->update(); + SceneManager::instance()->update(); + sceneNode->updateDirtyLayouts(); + + auto images = sceneNode->getRoot()->findAllByTag( "img" ); + ASSERT_EQ( images.size(), (size_t)1 ); + auto* img = images[0]->asType(); + ASSERT_TRUE( img != nullptr ); + + // HTML attributes alone keep the fixed 2560x1436 box. + EXPECT_NEAR( img->getPixelsSize().getWidth(), 2560.f, 1.f ); + EXPECT_NEAR( img->getPixelsSize().getHeight(), 1436.f, 1.f ); + + const std::string rule = "img { height: auto; max-width: 100%; }"; + + // Apply height:auto + max-width:100% through a style state change. + sceneNode->setStyleSheet( rule ); + sceneNode->updateDirtyLayouts(); + const Float constrainedWidth = img->getPixelsSize().getWidth(); + const Float constrainedHeight = img->getPixelsSize().getHeight(); + EXPECT_LE( constrainedWidth, 800.f ); + EXPECT_NEAR( constrainedHeight / constrainedWidth, 1436.f / 2560.f, 0.01f ); + + // Remove the rule, then reapply it: the final geometry must be identical. + sceneNode->setStyleSheet( CSS::StyleSheet() ); + sceneNode->updateDirtyLayouts(); + sceneNode->setStyleSheet( rule ); + sceneNode->updateDirtyLayouts(); + EXPECT_NEAR( img->getPixelsSize().getWidth(), constrainedWidth, 1.f ); + EXPECT_NEAR( img->getPixelsSize().getHeight(), constrainedHeight, 1.f ); + + Engine::destroySingleton(); +}