From d8a683ee99df689b6803fa7acdbfd06f5b014202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Wed, 1 Jul 2026 23:27:52 -0300 Subject: [PATCH] Fix em, ex, ch resolution in UIWebView elements. --- src/eepp/ui/uinode.cpp | 22 ++++++++ src/tests/unit_tests/uiwebview_tests.cpp | 67 ++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/src/eepp/ui/uinode.cpp b/src/eepp/ui/uinode.cpp index 173a7da02..3bd9b6d13 100644 --- a/src/eepp/ui/uinode.cpp +++ b/src/eepp/ui/uinode.cpp @@ -1751,6 +1751,28 @@ Float UINode::lengthFromValue( const StyleSheetProperty& property, res.setValue( 12, StyleSheetLength::Unit::Dp ); return convertLength( res, 0 ); } + + if ( length.getUnit() != StyleSheetLength::Unit::Em && + length.getUnit() != StyleSheetLength::Unit::Ex && + length.getUnit() != StyleSheetLength::Unit::Ch ) + return convertLength( length, 0 ); + + Float parentFontSize = 12.f * PixelDensity::getPixelDensity(); + Node* parentNode = getParent(); + while ( parentNode ) { + if ( parentNode->isWidget() ) { + parentFontSize = getAbsoluteFontSize( parentNode->asType() ); + break; + } + parentNode = parentNode->getParent(); + } + + Font* font = nullptr; + if ( getUISceneNode() && getUISceneNode()->getUIThemeManager() ) + font = getUISceneNode()->getUIThemeManager()->getDefaultFont(); + + return length.asPixels( 0, Sizef::Zero, getSceneNode()->getDPI(), parentFontSize, + parentFontSize, font ); } return lengthFromValue( property.getValue(), property.getPropertyDefinition()->getRelativeTarget(), defaultValue, diff --git a/src/tests/unit_tests/uiwebview_tests.cpp b/src/tests/unit_tests/uiwebview_tests.cpp index 9c181522b..6a17b3e8b 100644 --- a/src/tests/unit_tests/uiwebview_tests.cpp +++ b/src/tests/unit_tests/uiwebview_tests.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -170,6 +171,72 @@ UTEST( UIWebView, DocumentRootHitTestingTraversesScrollableExtent ) { Engine::destroySingleton(); } +UTEST( UIWebView, FontSizeEmDoesNotCompoundOnViewportRelayout ) { + auto win = Engine::instance()->createWindow( + WindowSettings( 640, 480, "UIWebView Font Size Em Relayout", 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 ); + + UISceneNode* sceneNode = UISceneNode::New(); + SceneManager::instance()->add( sceneNode ); + sceneNode->getUIThemeManager()->setDefaultFont( font ); + + UIWebView* webView = UIWebView::New(); + webView->setParent( sceneNode->getRoot() ); + webView->setPixelsSize( 420, 260 ); + webView->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed ); + + const std::string path = Sys::getTempPath() + "eepp_uiwebview_font_size_em.html"; + FileSystem::fileWrite( path, R"html( + + + + + + +

Title

+
+ + +)html" ); + webView->loadURI( URI( "file://" + path ) ); + + UISceneNode* documentScene = webView->getDocumentSceneNode(); + ASSERT_TRUE( documentScene != nullptr ); + + auto pump = [&]() { + for ( int i = 0; i < 30; i++ ) { + win->getInput()->update(); + SceneManager::instance()->update( Seconds( 1.f / 60.f ) ); + } + }; + pump(); + + Node* title = documentScene->getRoot()->find( "title-text" ); + ASSERT_TRUE( title != nullptr && title->isType( UI_TYPE_TEXTSPAN ) ); + EXPECT_NEAR( title->asType()->getFontSize(), 40.f, 1.f ); + + for ( int i = 0; i < 4; i++ ) { + webView->setPixelsSize( 520 + i * 20, 320 + i * 10 ); + pump(); + webView->setPixelsSize( 420, 260 ); + pump(); + EXPECT_NEAR( title->asType()->getFontSize(), 40.f, 1.f ); + } + + Engine::destroySingleton(); +} + UTEST( UIWebView, VerticalScrollbarViewportDoesNotCreateHorizontalScroll ) { auto win = Engine::instance()->createWindow( WindowSettings( 640, 480, "UIWebView Scrollbar Viewport Test", WindowStyle::Default,