Bug 1375944 - Increment font set generation when font-face is synchronously loaded in post-traversal. r?heycam draft
authorXidorn Quan <me@upsuper.org>
Wed, 28 Jun 2017 11:14:18 -0700
changeset 601546 19cc92a625f656478d07f11181576e205ea6f905
parent 600931 467684eafd512d89c5b8ee04e39cd94925e7982e
child 635296 b90d5803539c8dc679676f9833736f6fd94edb21
push id66100
push userxquan@mozilla.com
push dateWed, 28 Jun 2017 21:42:13 +0000
reviewersheycam
bugs1375944
milestone56.0a1
Bug 1375944 - Increment font set generation when font-face is synchronously loaded in post-traversal. r?heycam MozReview-Commit-ID: IJO6Uggpca4
gfx/thebes/gfxUserFontSet.cpp
layout/reftests/text-overflow/reftest.list
layout/style/test/Ahem.ttf
layout/style/test/file_bug1375944.html
layout/style/test/mochitest.ini
layout/style/test/test_bug1375944.html
--- a/gfx/thebes/gfxUserFontSet.cpp
+++ b/gfx/thebes/gfxUserFontSet.cpp
@@ -455,17 +455,34 @@ gfxUserFontEntry::LoadNextSrc()
 }
 
 void
 gfxUserFontEntry::ContinueLoad()
 {
     MOZ_ASSERT(mUserFontLoadState == STATUS_LOAD_PENDING);
     MOZ_ASSERT(mSrcList[mSrcIndex].mSourceType == gfxFontFaceSrc::eSourceType_URL);
 
+    SetLoadState(STATUS_LOADING);
     DoLoadNextSrc(true);
+    if (LoadState() != STATUS_LOADING) {
+      MOZ_ASSERT(mUserFontLoadState != STATUS_LOAD_PENDING,
+                 "Not in parallel traversal, shouldn't get LOAD_PENDING again");
+      // Loading is synchronously finished (loaded from cache or failed). We
+      // need to increment the generation so that we flush the style data to
+      // use the new loaded font face.
+      // Without parallel traversal, we would simply get the right font data
+      // after the first call to DoLoadNextSrc() in this case, so we don't need
+      // to touch the generation to trigger another restyle.
+      // XXX We may want to return synchronously in parallel traversal in those
+      // cases as well if possible, so that we don't have an additional restyle.
+      // That doesn't work currently because nsIDocument::GetDocShell (called
+      // from FontFaceSet::CheckFontLoad) dereferences a weak pointer, which is
+      // not allowed in parallel traversal.
+      IncrementGeneration();
+    }
 }
 
 void
 gfxUserFontEntry::DoLoadNextSrc(bool aForceAsync)
 {
     uint32_t numSrc = mSrcList.Length();
 
     // load each src entry in turn, until a local face is found
--- a/layout/reftests/text-overflow/reftest.list
+++ b/layout/reftests/text-overflow/reftest.list
@@ -1,12 +1,12 @@
 == ellipsis-font-fallback.html ellipsis-font-fallback-ref.html
 == line-clipping.html line-clipping-ref.html
 fuzzy-if(Android,16,244) HTTP(..) == marker-basic.html marker-basic-ref.html  # Bug 1128229
-fails-if(stylo) HTTP(..) == marker-string.html marker-string-ref.html
+HTTP(..) == marker-string.html marker-string-ref.html
 skip-if(Android) HTTP(..) == bidi-simple.html bidi-simple-ref.html # Fails on Android due to anti-aliasing
 skip-if(!gtkWidget) fuzzy-if(gtkWidget,2,289) HTTP(..) == bidi-simple-scrolled.html bidi-simple-scrolled-ref.html # Fails on Windows and OSX due to anti-aliasing
 fuzzy-if(Android,24,4000) fuzzy-if(cocoaWidget,1,40) fuzzy-if(asyncPan&&!layersGPUAccelerated,140,1836) HTTP(..) == scroll-rounding.html scroll-rounding-ref.html # bug 760264
 fuzzy(2,453) fuzzy-if(skiaContent,9,2100) fails-if(gtkWidget) HTTP(..) == anonymous-block.html anonymous-block-ref.html # gtkWidget:bug 1309103
 HTTP(..) == false-marker-overlap.html false-marker-overlap-ref.html
 HTTP(..) == visibility-hidden.html visibility-hidden-ref.html
 fuzzy-if(asyncPan&&!layersGPUAccelerated,102,1724) fuzzy-if(gtkWidget,10,8) skip-if(stylo) HTTP(..) == block-padding.html block-padding-ref.html
 HTTP(..) == quirks-decorations.html quirks-decorations-ref.html
copy from layout/reftests/fonts/Ahem.ttf
copy to layout/style/test/Ahem.ttf
new file mode 100644
--- /dev/null
+++ b/layout/style/test/file_bug1375944.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<style>
+@font-face {
+  font-family: Ahem;
+  src: url(Ahem.ttf);
+}
+#test {
+  display: inline-block;
+  font: 64px/1 Ahem;
+  margin-right: 1ex;
+}
+</style>
+<div id="test">X</div>
--- a/layout/style/test/mochitest.ini
+++ b/layout/style/test/mochitest.ini
@@ -150,16 +150,18 @@ support-files = file_bug829816.css
 support-files = file_bug1055933_circle-xxl.png
 [test_bug1089417.html]
 support-files = file_bug1089417_iframe.html
 [test_bug1112014.html]
 [test_bug1203766.html]
 [test_bug1232829.html]
 [test_bug1292447.html]
 [test_bug1371488.html]
+[test_bug1375944.html]
+support-files = file_bug1375944.html Ahem.ttf
 [test_cascade.html]
 [test_ch_ex_no_infloops.html]
 [test_change_hint_optimizations.html]
 [test_clip-path_polygon.html]
 [test_color_rounding.html]
 [test_compute_data_with_start_struct.html]
 skip-if = toolkit == 'android'
 [test_computed_style.html]
new file mode 100644
--- /dev/null
+++ b/layout/style/test/test_bug1375944.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <title>Test for bug 1375944</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<iframe id="subframe"></iframe>
+<pre id="log">
+<script>
+
+SimpleTest.waitForExplicitFinish();
+
+async function runTest() {
+  let f = new FontFace("Ahem", "url(Ahem.ttf)", {});
+  await f.load();
+  is(f.status, "loaded", "Loaded Ahem font");
+
+  let subframe = document.getElementById("subframe");
+  subframe.src = "file_bug1375944.html";
+  await new Promise(resolve => subframe.onload = resolve);
+  let elem = subframe.contentDocument.getElementById("test");
+  is(elem.getBoundingClientRect().width, 64,
+     "The font should be loaded properly");
+
+  SimpleTest.finish();
+}
+runTest();
+
+</script>
+</pre>
+</body>
+</html>