mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-02 03:00:23 +03:00
Fix percentage in font-size for UIWebView.
Unload fonts from scene in UIWebView.
This commit is contained in:
@@ -168,7 +168,11 @@ application UISceneNode
|
|||||||
`UISceneNode::overFind()` compatibility override. `UIRoot` keeps its layout/self-hit
|
`UISceneNode::overFind()` compatibility override. `UIRoot` keeps its layout/self-hit
|
||||||
bounds viewport-sized, but embedded document scenes can ask it to traverse child
|
bounds viewport-sized, but embedded document scenes can ask it to traverse child
|
||||||
hit testing through the measured document extent.
|
hit testing through the measured document extent.
|
||||||
- Basic author `@font-face` isolation is implemented and covered by UIWebView tests.
|
- Author `@font-face` isolation and cleanup are implemented. Scene-local aliases resolve before
|
||||||
|
global font fallback; WebView navigation clears the document scene's previous author aliases and
|
||||||
|
internally registered font resources; document scene destruction removes any remaining scene-owned
|
||||||
|
author fonts. Tests cover sibling-scene isolation, navigation cleanup, and WebView destruction
|
||||||
|
cleanup.
|
||||||
- Tests cover the new topology, viewport-vs-extent behavior, scrolling, two-scene
|
- Tests cover the new topology, viewport-vs-extent behavior, scrolling, two-scene
|
||||||
style isolation, navigation supersession, and a resize metric regression that guards
|
style isolation, navigation supersession, and a resize metric regression that guards
|
||||||
against no-op queued viewport churn rebuilding RichText. They also cover document
|
against no-op queued viewport churn rebuilding RichText. They also cover document
|
||||||
@@ -176,9 +180,6 @@ application UISceneNode
|
|||||||
|
|
||||||
### Pending / Follow-Up
|
### Pending / Follow-Up
|
||||||
|
|
||||||
- **Author `@font-face` cleanup audit** should verify navigation/destruction cleanup
|
|
||||||
for scene-local aliases and loaded font resources. The basic scene-local isolation
|
|
||||||
path is implemented and tested.
|
|
||||||
- **Subresource lifetime coverage** should be completed for every async path described
|
- **Subresource lifetime coverage** should be completed for every async path described
|
||||||
in Phase 6, including deferred CSS, fonts, images, redirects, cookies, and destruction.
|
in Phase 6, including deferred CSS, fonts, images, redirects, cookies, and destruction.
|
||||||
- **Example and documentation integration** should be completed after the code shape
|
- **Example and documentation integration** should be completed after the code shape
|
||||||
@@ -385,7 +386,7 @@ Steps:
|
|||||||
1. Add a scene-local font-face alias registry keyed by CSS family, style, and weight.
|
1. Add a scene-local font-face alias registry keyed by CSS family, style, and weight.
|
||||||
2. Register loaded author fonts under scene-unique internal names.
|
2. Register loaded author fonts under scene-unique internal names.
|
||||||
3. Resolve author font aliases before global `FontManager` fallback.
|
3. Resolve author font aliases before global `FontManager` fallback.
|
||||||
4. Add `clearAuthorFontFaces()` and call it during navigation.
|
4. Add `clearFontFaces()` and call it during navigation.
|
||||||
5. Remove only this scene's internally registered author fonts during scene destruction.
|
5. Remove only this scene's internally registered author fonts during scene destruction.
|
||||||
6. Mark document extent dirty after a font load can affect metrics.
|
6. Mark document extent dirty after a font load can affect metrics.
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
> Status: IMPLEMENTED WITH FOLLOW-UPS - the owned document scene, real scroll-target
|
> Status: IMPLEMENTED WITH FOLLOW-UPS - the owned document scene, real scroll-target
|
||||||
> layout widget, viewport/extent split, root-scoped hit-test traversal, and focused
|
> layout widget, viewport/extent split, root-scoped hit-test traversal, and focused
|
||||||
> UIWebView coverage are implemented. Remaining work is cleanup/audit coverage for
|
> UIWebView coverage are implemented. Remaining work is broader async subresource
|
||||||
> async subresources, examples/docs, and fixed/sticky acceptance tests.
|
> coverage, examples/docs, and fixed/sticky acceptance tests.
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
|
||||||
@@ -453,7 +453,7 @@ Steps:
|
|||||||
3. Register author fonts under an internal scene-unique resource name if `FontManager` registration
|
3. Register author fonts under an internal scene-unique resource name if `FontManager` registration
|
||||||
remains required, while preserving the author-visible family only in the scene-local alias.
|
remains required, while preserving the author-visible family only in the scene-local alias.
|
||||||
4. Keep generic/system fonts and explicitly shared application defaults as global fallbacks.
|
4. Keep generic/system fonts and explicitly shared application defaults as global fallbacks.
|
||||||
5. Add an explicit `clearDocumentFontFaces()` / `clearAuthorFontFaces()` operation used during
|
5. Add an explicit `clearFontFaces()` operation used during
|
||||||
navigation before new document CSS is loaded. It removes only this scene's internally registered
|
navigation before new document CSS is loaded. It removes only this scene's internally registered
|
||||||
author fonts and clears aliases; it must not remove application/system fonts or sibling-document
|
author fonts and clears aliases; it must not remove application/system fonts or sibling-document
|
||||||
author fonts.
|
author fonts.
|
||||||
|
|||||||
@@ -822,6 +822,8 @@ class EE_API UISceneNode : public SceneNode {
|
|||||||
Font* getFontFromNamesList( std::string_view names, Uint32 fontStyle = 0,
|
Font* getFontFromNamesList( std::string_view names, Uint32 fontStyle = 0,
|
||||||
FontWeight weight = FontWeight::Normal ) const;
|
FontWeight weight = FontWeight::Normal ) const;
|
||||||
|
|
||||||
|
void clearFontFaces();
|
||||||
|
|
||||||
Font* reevaluateFontStyle( Font* currentFont, Uint32 fontStyle,
|
Font* reevaluateFontStyle( Font* currentFont, Uint32 fontStyle,
|
||||||
FontWeight weight = FontWeight::Normal ) const;
|
FontWeight weight = FontWeight::Normal ) const;
|
||||||
|
|
||||||
|
|||||||
+25
-18
@@ -1702,9 +1702,29 @@ Float UINode::lengthFromValue( const StyleSheetProperty& property,
|
|||||||
if ( property.getPropertyDefinition() &&
|
if ( property.getPropertyDefinition() &&
|
||||||
property.getPropertyDefinition()->getPropertyId() == PropertyId::FontSize ) {
|
property.getPropertyDefinition()->getPropertyId() == PropertyId::FontSize ) {
|
||||||
StyleSheetLength length( property.value() );
|
StyleSheetLength length( property.value() );
|
||||||
|
auto parentFontSize = [this]() {
|
||||||
|
Float fontSize = 12.f * PixelDensity::getPixelDensity();
|
||||||
|
Node* parentNode = getParent();
|
||||||
|
while ( parentNode ) {
|
||||||
|
if ( parentNode->isWidget() ) {
|
||||||
|
fontSize = getAbsoluteFontSize( parentNode->asType<UIWidget>() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
parentNode = parentNode->getParent();
|
||||||
|
}
|
||||||
|
return fontSize;
|
||||||
|
};
|
||||||
|
auto resolveFontRelativeLength = [this, &parentFontSize]( const StyleSheetLength& len ) {
|
||||||
|
const Float parentSize = parentFontSize();
|
||||||
|
Font* font = nullptr;
|
||||||
|
if ( getUISceneNode() && getUISceneNode()->getUIThemeManager() )
|
||||||
|
font = getUISceneNode()->getUIThemeManager()->getDefaultFont();
|
||||||
|
return len.asPixels( parentSize, Sizef::Zero, getSceneNode()->getDPI(), parentSize,
|
||||||
|
parentSize, font );
|
||||||
|
};
|
||||||
|
|
||||||
if ( length.getUnit() == StyleSheetLength::Unit::Percentage ) {
|
if ( length.getUnit() == StyleSheetLength::Unit::Percentage ) {
|
||||||
length.setValue( length.getValue() / 100.f, StyleSheetLength::Unit::Em );
|
return resolveFontRelativeLength( length );
|
||||||
return convertLength( length, 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr std::string_view FontSizeNames[] = {
|
static constexpr std::string_view FontSizeNames[] = {
|
||||||
@@ -1738,6 +1758,8 @@ Float UINode::lengthFromValue( const StyleSheetProperty& property,
|
|||||||
} else if ( keyword == "larger" ) {
|
} else if ( keyword == "larger" ) {
|
||||||
res.setValue( 1.2f, StyleSheetLength::Unit::Em );
|
res.setValue( 1.2f, StyleSheetLength::Unit::Em );
|
||||||
}
|
}
|
||||||
|
if ( res.getUnit() == StyleSheetLength::Unit::Em )
|
||||||
|
return resolveFontRelativeLength( res );
|
||||||
return convertLength( res, 0 );
|
return convertLength( res, 0 );
|
||||||
} else if ( property.getValue() == "inherit" ) {
|
} else if ( property.getValue() == "inherit" ) {
|
||||||
Node* parentNode = getParent();
|
Node* parentNode = getParent();
|
||||||
@@ -1757,22 +1779,7 @@ Float UINode::lengthFromValue( const StyleSheetProperty& property,
|
|||||||
length.getUnit() != StyleSheetLength::Unit::Ch )
|
length.getUnit() != StyleSheetLength::Unit::Ch )
|
||||||
return convertLength( length, 0 );
|
return convertLength( length, 0 );
|
||||||
|
|
||||||
Float parentFontSize = 12.f * PixelDensity::getPixelDensity();
|
return resolveFontRelativeLength( length );
|
||||||
Node* parentNode = getParent();
|
|
||||||
while ( parentNode ) {
|
|
||||||
if ( parentNode->isWidget() ) {
|
|
||||||
parentFontSize = getAbsoluteFontSize( parentNode->asType<UIWidget>() );
|
|
||||||
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(),
|
return lengthFromValue( property.getValue(),
|
||||||
property.getPropertyDefinition()->getRelativeTarget(), defaultValue,
|
property.getPropertyDefinition()->getRelativeTarget(), defaultValue,
|
||||||
|
|||||||
@@ -111,13 +111,11 @@ UISceneNode::~UISceneNode() {
|
|||||||
mAsyncResourceLoadState->generation++;
|
mAsyncResourceLoadState->generation++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearFontFaces();
|
||||||
|
|
||||||
eeSAFE_DELETE( mUIThemeManager );
|
eeSAFE_DELETE( mUIThemeManager );
|
||||||
eeSAFE_DELETE( mUIIconThemeManager );
|
eeSAFE_DELETE( mUIIconThemeManager );
|
||||||
|
|
||||||
for ( auto& font : mFontFaces ) {
|
|
||||||
FontManager::instance()->remove( font );
|
|
||||||
}
|
|
||||||
|
|
||||||
// UISceneNode can now destroy the ThreadPool shared to him. If that's the case,
|
// UISceneNode can now destroy the ThreadPool shared to him. If that's the case,
|
||||||
// We need to ensure that the children are destroyed before the thread pool,
|
// We need to ensure that the children are destroyed before the thread pool,
|
||||||
// since its children could be consuming it and need to uninitialize gracefully.
|
// since its children could be consuming it and need to uninitialize gracefully.
|
||||||
@@ -1937,6 +1935,20 @@ Font* UISceneNode::getFontFromNamesList( std::string_view names, Uint32 fontStyl
|
|||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UISceneNode::clearFontFaces() {
|
||||||
|
if ( mFontFaces.empty() && mFontFaceAliases.empty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
mFontFaceAliases.clear();
|
||||||
|
if ( mRoot )
|
||||||
|
mRoot->reloadFontFamily();
|
||||||
|
|
||||||
|
for ( auto& font : mFontFaces )
|
||||||
|
FontManager::instance()->remove( font );
|
||||||
|
|
||||||
|
mFontFaces.clear();
|
||||||
|
}
|
||||||
|
|
||||||
Font* UISceneNode::reevaluateFontStyle( Font* currentFont, Uint32 fontStyle,
|
Font* UISceneNode::reevaluateFontStyle( Font* currentFont, Uint32 fontStyle,
|
||||||
FontWeight weight ) const {
|
FontWeight weight ) const {
|
||||||
if ( !currentFont || !SystemFontResolver::isEnabled() )
|
if ( !currentFont || !SystemFontResolver::isEnabled() )
|
||||||
|
|||||||
@@ -375,6 +375,7 @@ void UIWebView::loadDocumentData( URI url, std::string data, Uint64 generation )
|
|||||||
self->getHorizontalScrollBar()->setValue( 0 );
|
self->getHorizontalScrollBar()->setValue( 0 );
|
||||||
static_cast<UIWebViewDocumentContainer*>( self->mDocContainer )->clearDocumentChildren();
|
static_cast<UIWebViewDocumentContainer*>( self->mDocContainer )->clearDocumentChildren();
|
||||||
ui->invalidateAsyncResourceLoads();
|
ui->invalidateAsyncResourceLoads();
|
||||||
|
ui->clearFontFaces();
|
||||||
ui->getStyleSheet().removeAllWithoutMarker( self->mStyleSheetDefaultMarker );
|
ui->getStyleSheet().removeAllWithoutMarker( self->mStyleSheetDefaultMarker );
|
||||||
ui->setURIFromURL( url );
|
ui->setURIFromURL( url );
|
||||||
|
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ UTEST( CSSInheritance, ComputedFontSizePercentageAndRem ) {
|
|||||||
UIWidget* targetSpan = root->querySelector( "#targetspan" );
|
UIWidget* targetSpan = root->querySelector( "#targetspan" );
|
||||||
EXPECT_TRUE( targetSpan != nullptr );
|
EXPECT_TRUE( targetSpan != nullptr );
|
||||||
|
|
||||||
EXPECT_NEAR( 18u * scale, targetSpan->asType<UITextSpan>()->getFontSize(), 1.f );
|
EXPECT_NEAR( 30u * scale, targetSpan->asType<UITextSpan>()->getFontSize(), 1.f );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -203,10 +203,12 @@ UTEST( UIWebView, FontSizeEmDoesNotCompoundOnViewportRelayout ) {
|
|||||||
html, body { margin: 0; padding: 0; }
|
html, body { margin: 0; padding: 0; }
|
||||||
body { font-size: 16px; }
|
body { font-size: 16px; }
|
||||||
h1 { font-size: 2.5em; margin: 0.5em 0; }
|
h1 { font-size: 2.5em; margin: 0.5em 0; }
|
||||||
|
h2 { font-size: 250%; margin: 0.5em 0; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1><span id="title-text">Title</span></h1>
|
<h1><span id="title-em">Title em</span></h1>
|
||||||
|
<h2><span id="title-percent">Title percent</span></h2>
|
||||||
<div style="height: 900px"></div>
|
<div style="height: 900px"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -224,16 +226,20 @@ UTEST( UIWebView, FontSizeEmDoesNotCompoundOnViewportRelayout ) {
|
|||||||
};
|
};
|
||||||
pump();
|
pump();
|
||||||
|
|
||||||
Node* title = documentScene->getRoot()->find( "title-text" );
|
Node* titleEm = documentScene->getRoot()->find( "title-em" );
|
||||||
ASSERT_TRUE( title != nullptr && title->isType( UI_TYPE_TEXTSPAN ) );
|
Node* titlePercent = documentScene->getRoot()->find( "title-percent" );
|
||||||
EXPECT_NEAR( title->asType<UITextSpan>()->getFontSize(), 40.f, 1.f );
|
ASSERT_TRUE( titleEm != nullptr && titleEm->isType( UI_TYPE_TEXTSPAN ) );
|
||||||
|
ASSERT_TRUE( titlePercent != nullptr && titlePercent->isType( UI_TYPE_TEXTSPAN ) );
|
||||||
|
EXPECT_NEAR( titleEm->asType<UITextSpan>()->getFontSize(), 40.f, 1.f );
|
||||||
|
EXPECT_NEAR( titlePercent->asType<UITextSpan>()->getFontSize(), 40.f, 1.f );
|
||||||
|
|
||||||
for ( int i = 0; i < 4; i++ ) {
|
for ( int i = 0; i < 4; i++ ) {
|
||||||
webView->setPixelsSize( 520 + i * 20, 320 + i * 10 );
|
webView->setPixelsSize( 520 + i * 20, 320 + i * 10 );
|
||||||
pump();
|
pump();
|
||||||
webView->setPixelsSize( 420, 260 );
|
webView->setPixelsSize( 420, 260 );
|
||||||
pump();
|
pump();
|
||||||
EXPECT_NEAR( title->asType<UITextSpan>()->getFontSize(), 40.f, 1.f );
|
EXPECT_NEAR( titleEm->asType<UITextSpan>()->getFontSize(), 40.f, 1.f );
|
||||||
|
EXPECT_NEAR( titlePercent->asType<UITextSpan>()->getFontSize(), 40.f, 1.f );
|
||||||
}
|
}
|
||||||
|
|
||||||
Engine::destroySingleton();
|
Engine::destroySingleton();
|
||||||
@@ -1479,6 +1485,8 @@ UTEST( UIWebView, DocumentScenesIsolateAuthorFontFaces ) {
|
|||||||
const std::string processPath( Sys::getProcessPath() );
|
const std::string processPath( Sys::getProcessPath() );
|
||||||
const std::string pathA = Sys::getTempPath() + "eepp_uiwebview_font_doc_a.html";
|
const std::string pathA = Sys::getTempPath() + "eepp_uiwebview_font_doc_a.html";
|
||||||
const std::string pathB = Sys::getTempPath() + "eepp_uiwebview_font_doc_b.html";
|
const std::string pathB = Sys::getTempPath() + "eepp_uiwebview_font_doc_b.html";
|
||||||
|
const std::string pathAWithoutFont =
|
||||||
|
Sys::getTempPath() + "eepp_uiwebview_font_doc_a_without_font.html";
|
||||||
const std::string pathA2 = Sys::getTempPath() + "eepp_uiwebview_font_doc_a2.html";
|
const std::string pathA2 = Sys::getTempPath() + "eepp_uiwebview_font_doc_a2.html";
|
||||||
FileSystem::fileWrite( pathA,
|
FileSystem::fileWrite( pathA,
|
||||||
"<html><head><style>"
|
"<html><head><style>"
|
||||||
@@ -1494,6 +1502,11 @@ UTEST( UIWebView, DocumentScenesIsolateAuthorFontFaces ) {
|
|||||||
"../assets/fonts/DejaVuSansMono.ttf'); }"
|
"../assets/fonts/DejaVuSansMono.ttf'); }"
|
||||||
"#target-b { font-family: 'SharedDocFace'; }"
|
"#target-b { font-family: 'SharedDocFace'; }"
|
||||||
"</style></head><body><span id='target-b'>B</span></body></html>" );
|
"</style></head><body><span id='target-b'>B</span></body></html>" );
|
||||||
|
FileSystem::fileWrite( pathAWithoutFont,
|
||||||
|
"<html><head><style>"
|
||||||
|
"#target-a-empty { font-family: 'SharedDocFace'; }"
|
||||||
|
"</style></head><body><span id='target-a-empty'>A empty</span></body>"
|
||||||
|
"</html>" );
|
||||||
FileSystem::fileWrite(
|
FileSystem::fileWrite(
|
||||||
pathA2, "<html><head><style>"
|
pathA2, "<html><head><style>"
|
||||||
"@font-face { font-family: 'SharedDocFace'; src: url('file://" +
|
"@font-face { font-family: 'SharedDocFace'; src: url('file://" +
|
||||||
@@ -1525,6 +1538,16 @@ UTEST( UIWebView, DocumentScenesIsolateAuthorFontFaces ) {
|
|||||||
EXPECT_TRUE( fontB->loaded() );
|
EXPECT_TRUE( fontB->loaded() );
|
||||||
EXPECT_NE( fontA, fontB );
|
EXPECT_NE( fontA, fontB );
|
||||||
EXPECT_EQ( nullptr, FontManager::instance()->getByName( "SharedDocFace" ) );
|
EXPECT_EQ( nullptr, FontManager::instance()->getByName( "SharedDocFace" ) );
|
||||||
|
const std::string fontAResourceName = fontA->getName();
|
||||||
|
EXPECT_EQ( fontA, FontManager::instance()->getByName( fontAResourceName ) );
|
||||||
|
|
||||||
|
webViewA->loadURI( URI( "file://" + pathAWithoutFont ) );
|
||||||
|
pump();
|
||||||
|
|
||||||
|
auto targetAWithoutFont = docA->getRoot()->find( "target-a-empty" );
|
||||||
|
ASSERT_TRUE( targetAWithoutFont != nullptr );
|
||||||
|
EXPECT_EQ( nullptr, docA->getFontFromNamesList( "SharedDocFace" ) );
|
||||||
|
EXPECT_EQ( nullptr, FontManager::instance()->getByName( fontAResourceName ) );
|
||||||
|
|
||||||
webViewA->loadURI( URI( "file://" + pathA2 ) );
|
webViewA->loadURI( URI( "file://" + pathA2 ) );
|
||||||
pump();
|
pump();
|
||||||
@@ -1533,13 +1556,92 @@ UTEST( UIWebView, DocumentScenesIsolateAuthorFontFaces ) {
|
|||||||
Font* stableFontB = docB->getFontFromNamesList( "SharedDocFace" );
|
Font* stableFontB = docB->getFontFromNamesList( "SharedDocFace" );
|
||||||
ASSERT_TRUE( reloadedFontA != nullptr );
|
ASSERT_TRUE( reloadedFontA != nullptr );
|
||||||
ASSERT_TRUE( stableFontB != nullptr );
|
ASSERT_TRUE( stableFontB != nullptr );
|
||||||
EXPECT_NE( reloadedFontA, fontA );
|
|
||||||
EXPECT_EQ( stableFontB, fontB );
|
EXPECT_EQ( stableFontB, fontB );
|
||||||
EXPECT_NE( reloadedFontA, stableFontB );
|
EXPECT_NE( reloadedFontA, stableFontB );
|
||||||
|
|
||||||
Engine::destroySingleton();
|
Engine::destroySingleton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UTEST( UIWebView, DocumentSceneAuthorFontFacesCleanUpOnDestruction ) {
|
||||||
|
auto win = Engine::instance()->createWindow(
|
||||||
|
WindowSettings( 800, 600, "UIWebView Font Face Cleanup 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 );
|
||||||
|
|
||||||
|
UISceneNode* sceneNode = UISceneNode::New();
|
||||||
|
SceneManager::instance()->add( sceneNode );
|
||||||
|
sceneNode->getUIThemeManager()->setDefaultFont( font );
|
||||||
|
|
||||||
|
UIWebView* webViewA = UIWebView::New();
|
||||||
|
webViewA->setParent( sceneNode->getRoot() );
|
||||||
|
webViewA->setPixelsSize( 300, 200 );
|
||||||
|
webViewA->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed );
|
||||||
|
UIWebView* webViewB = UIWebView::New();
|
||||||
|
webViewB->setParent( sceneNode->getRoot() );
|
||||||
|
webViewB->setPixelsSize( 300, 200 );
|
||||||
|
webViewB->setLayoutSizePolicy( SizePolicy::Fixed, SizePolicy::Fixed );
|
||||||
|
|
||||||
|
const std::string processPath( Sys::getProcessPath() );
|
||||||
|
const std::string pathA = Sys::getTempPath() + "eepp_uiwebview_font_doc_destroy_a.html";
|
||||||
|
const std::string pathB = Sys::getTempPath() + "eepp_uiwebview_font_doc_destroy_b.html";
|
||||||
|
FileSystem::fileWrite( pathA,
|
||||||
|
"<html><head><style>"
|
||||||
|
"@font-face { font-family: 'DestroyDocFace'; src: url('file://" +
|
||||||
|
processPath +
|
||||||
|
"../assets/fonts/DejaVuSansMono.ttf'); }"
|
||||||
|
"#target-a { font-family: 'DestroyDocFace'; }"
|
||||||
|
"</style></head><body><span id='target-a'>A</span></body></html>" );
|
||||||
|
FileSystem::fileWrite( pathB,
|
||||||
|
"<html><head><style>"
|
||||||
|
"@font-face { font-family: 'DestroyDocFace'; src: url('file://" +
|
||||||
|
processPath +
|
||||||
|
"../assets/fonts/NotoSans-Regular.ttf'); }"
|
||||||
|
"#target-b { font-family: 'DestroyDocFace'; }"
|
||||||
|
"</style></head><body><span id='target-b'>B</span></body></html>" );
|
||||||
|
|
||||||
|
webViewA->loadURI( URI( "file://" + pathA ) );
|
||||||
|
webViewB->loadURI( URI( "file://" + pathB ) );
|
||||||
|
|
||||||
|
auto pump = [&]() {
|
||||||
|
for ( int i = 0; i < 10; i++ ) {
|
||||||
|
win->getInput()->update();
|
||||||
|
SceneManager::instance()->update( Seconds( 1.f / 60.f ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
pump();
|
||||||
|
|
||||||
|
UISceneNode* docA = webViewA->getDocumentSceneNode();
|
||||||
|
UISceneNode* docB = webViewB->getDocumentSceneNode();
|
||||||
|
ASSERT_TRUE( docA != nullptr );
|
||||||
|
ASSERT_TRUE( docB != nullptr );
|
||||||
|
Font* loadedFontA = docA->getFontFromNamesList( "DestroyDocFace" );
|
||||||
|
Font* loadedFontB = docB->getFontFromNamesList( "DestroyDocFace" );
|
||||||
|
ASSERT_TRUE( loadedFontA != nullptr );
|
||||||
|
ASSERT_TRUE( loadedFontB != nullptr );
|
||||||
|
EXPECT_TRUE( loadedFontA->loaded() );
|
||||||
|
EXPECT_TRUE( loadedFontB->loaded() );
|
||||||
|
EXPECT_NE( loadedFontA, loadedFontB );
|
||||||
|
const std::string loadedFontAName = loadedFontA->getName();
|
||||||
|
const std::string loadedFontBName = loadedFontB->getName();
|
||||||
|
EXPECT_EQ( loadedFontA, FontManager::instance()->getByName( loadedFontAName ) );
|
||||||
|
EXPECT_EQ( loadedFontB, FontManager::instance()->getByName( loadedFontBName ) );
|
||||||
|
|
||||||
|
webViewA->close();
|
||||||
|
pump();
|
||||||
|
|
||||||
|
EXPECT_EQ( nullptr, FontManager::instance()->getByName( loadedFontAName ) );
|
||||||
|
EXPECT_EQ( loadedFontB, FontManager::instance()->getByName( loadedFontBName ) );
|
||||||
|
EXPECT_EQ( loadedFontB, docB->getFontFromNamesList( "DestroyDocFace" ) );
|
||||||
|
|
||||||
|
Engine::destroySingleton();
|
||||||
|
}
|
||||||
|
|
||||||
UTEST( UIWebView, NewerNavigationSupersedesStartedLoad ) {
|
UTEST( UIWebView, NewerNavigationSupersedesStartedLoad ) {
|
||||||
auto win = Engine::instance()->createWindow(
|
auto win = Engine::instance()->createWindow(
|
||||||
WindowSettings( 800, 600, "UIWebView Stale Navigation Test", WindowStyle::Default,
|
WindowSettings( 800, 600, "UIWebView Stale Navigation Test", WindowStyle::Default,
|
||||||
|
|||||||
Reference in New Issue
Block a user