Title: [212513] trunk
Revision
212513
Author
mmaxfi...@apple.com
Date
2017-02-16 17:28:00 -0800 (Thu, 16 Feb 2017)

Log Message

font-weight in @font-face can cause a font to be downloaded even when it's not used
https://bugs.webkit.org/show_bug.cgi?id=168114
<rdar://problem/30301317>

Reviewed by Darin Adler.

Source/WebCore:

There were two problems with our font loading code.

When we are in the middle of a download, we will use a special interstitial font,
and this special font has a flag set which will cause it to be invisible when it is
drawn. However, when we start using this font during the load, we give it a
unicode-range of U+0-0 which means that it will never be used, and fallback will
happen to other weights immediately.

The second problem with the font loading code is that this interstital font is just
Times. Times doesn't support every character, which means that if we are trying
to render some exotic character, we fall back to other weights. The solution here
is to use LastResort as the interstitial font, because it supports all characters.
Because its metrics are reasonable and we don't ever actually paint this
interstitial font, this choice is no worse than Times.

Tests: fast/text/font-style-download.html
       fast/text/font-weight-download-2.html
       fast/text/font-weight-download.html
       fast/text/font-weight-fallback.html

* css/CSSFontFace.cpp:
(WebCore::CSSFontFace::font):
* css/CSSSegmentedFontFace.cpp:
(WebCore::appendFont):
(WebCore::CSSSegmentedFontFace::fontRanges):
(WebCore::appendFontWithInvalidUnicodeRangeIfLoading): Deleted.
* platform/graphics/Font.h:
(WebCore::Font::widthForGlyph):
* platform/graphics/FontCache.h:
* platform/graphics/freetype/FontCacheFreeType.cpp:
(WebCore::FontCache::lastResortFallbackFontForEveryCharacter):
* platform/graphics/mac/FontCacheMac.mm:
(WebCore::FontCache::lastResortFallbackFontForEveryCharacter):
* platform/graphics/win/FontCacheWin.cpp:
(WebCore::FontCache::lastResortFallbackFontForEveryCharacter):

Tools:

LastResort needs to be usable in tests.

* DumpRenderTree/mac/DumpRenderTree.mm:
(allowedFontFamilySet):
* WebKitTestRunner/InjectedBundle/cocoa/ActivateFontsCocoa.mm:
(WTR::allowedFontFamilySet):
* WebKitTestRunner/mac/TestControllerMac.mm:
(WTR::allowedFontFamilySet):

LayoutTests:

* fast/text/font-style-download-expected.txt: Added.
* fast/text/font-style-download.html: Added.
* fast/text/font-weight-download-2-expected.txt: Added.
* fast/text/font-weight-download-2.html: Added.
* fast/text/font-weight-download-expected.txt: Added.
* fast/text/font-weight-download.html: Added.
* fast/text/font-weight-fallback-expected.html: Added.
* fast/text/font-weight-fallback.html: Added.
* http/tests/webfont/fallback-font-while-loading-expected.txt: We don't want to use the
fallback font while an earlier font is loading because the fallback font might require
an extra download. This represents a policy change.
* http/tests/webfont/fallback-font-while-loading.html: Ditto.
* resources/Ahem_CJK.ttf: Added.
* svg/W3C-SVG-1.1-SE/struct-dom-11-f.svg: The metrics of LastResort are different from
the metrics of the previous interstitial font, which means the new font causes elements
to intersect when they previously didn't. However, the web font isn't actually necessary
here, so we can just stop using it, thereby sidestepping the entire problem.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (212512 => 212513)


--- trunk/LayoutTests/ChangeLog	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/LayoutTests/ChangeLog	2017-02-17 01:28:00 UTC (rev 212513)
@@ -1,3 +1,29 @@
+2017-02-16  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        font-weight in @font-face can cause a font to be downloaded even when it's not used
+        https://bugs.webkit.org/show_bug.cgi?id=168114
+        <rdar://problem/30301317>
+
+        Reviewed by Darin Adler.
+
+        * fast/text/font-style-download-expected.txt: Added.
+        * fast/text/font-style-download.html: Added.
+        * fast/text/font-weight-download-2-expected.txt: Added.
+        * fast/text/font-weight-download-2.html: Added.
+        * fast/text/font-weight-download-expected.txt: Added.
+        * fast/text/font-weight-download.html: Added.
+        * fast/text/font-weight-fallback-expected.html: Added.
+        * fast/text/font-weight-fallback.html: Added.
+        * http/tests/webfont/fallback-font-while-loading-expected.txt: We don't want to use the
+        fallback font while an earlier font is loading because the fallback font might require
+        an extra download. This represents a policy change.
+        * http/tests/webfont/fallback-font-while-loading.html: Ditto.
+        * resources/Ahem_CJK.ttf: Added.
+        * svg/W3C-SVG-1.1-SE/struct-dom-11-f.svg: The metrics of LastResort are different from
+        the metrics of the previous interstitial font, which means the new font causes elements
+        to intersect when they previously didn't. However, the web font isn't actually necessary
+        here, so we can just stop using it, thereby sidestepping the entire problem.
+
 2017-02-16  Ryan Haddad  <ryanhad...@apple.com>
 
         Skip imported/w3c/web-platform-tests/resource-timing tests on Debug.

Added: trunk/LayoutTests/fast/text/font-style-download-expected.txt (0 => 212513)


--- trunk/LayoutTests/fast/text/font-style-download-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/text/font-style-download-expected.txt	2017-02-17 01:28:00 UTC (rev 212513)
@@ -0,0 +1,6 @@
+font-style-download.html - didFinishLoading
+Ahem.ttf - willSendRequest <NSURLRequest URL Ahem.ttf, main document URL font-style-download.html, http method GET> redirectResponse (null)
+Ahem.ttf - didReceiveResponse <NSURLResponse Ahem.ttf, http status code 0>
+Ahem.ttf - didFinishLoading
+This test makes sure that unnecessary fonts aren't downloaded. The test fails if Ahem.otf is downloaded.
+Hello
Property changes on: trunk/LayoutTests/fast/text/font-style-download-expected.txt
___________________________________________________________________

Added: svn:eol-style

+native \ No newline at end of property

Added: svn:keywords

+Author Date Id Rev URL \ No newline at end of property

Added: trunk/LayoutTests/fast/text/font-style-download.html (0 => 212513)


--- trunk/LayoutTests/fast/text/font-style-download.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/font-style-download.html	2017-02-17 01:28:00 UTC (rev 212513)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+    testRunner.dumpResourceLoadCallbacks();
+    testRunner.dumpAsText();
+}
+if (window.internals) {
+    internals.invalidateFontCache();
+    internals.clearMemoryCache();
+}
+</script>
+<style>
+@font-face {
+    font-family: "WebFont";
+    font-style: italic;
+    src: url("../../resources/Ahem.ttf") format("truetype");
+}
+@font-face {
+    font-family: "WebFont";
+    font-style: normal;
+    src: url("../../resources/Ahem.otf") format("opentype");
+}
+</style>
+</head>
+<body>
+This test makes sure that unnecessary fonts aren't downloaded. The test fails if Ahem.otf is downloaded.
+<div style="font: italic 100px 'WebFont';">Hello</div>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/text/font-weight-download-2-expected.txt (0 => 212513)


--- trunk/LayoutTests/fast/text/font-weight-download-2-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/text/font-weight-download-2-expected.txt	2017-02-17 01:28:00 UTC (rev 212513)
@@ -0,0 +1,6 @@
+font-weight-download-2.html - didFinishLoading
+Ahem_CJK.ttf - willSendRequest <NSURLRequest URL Ahem_CJK.ttf, main document URL font-weight-download-2.html, http method GET> redirectResponse (null)
+Ahem_CJK.ttf - didReceiveResponse <NSURLResponse Ahem_CJK.ttf, http status code 0>
+Ahem_CJK.ttf - didFinishLoading
+This test makes sure that unnecessary fonts aren't downloaded. The test fails if Ahem.otf is downloaded.
+横
Property changes on: trunk/LayoutTests/fast/text/font-weight-download-2-expected.txt
___________________________________________________________________

Added: svn:eol-style

+native \ No newline at end of property

Added: svn:keywords

+Author Date Id Rev URL \ No newline at end of property

Added: trunk/LayoutTests/fast/text/font-weight-download-2.html (0 => 212513)


--- trunk/LayoutTests/fast/text/font-weight-download-2.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/font-weight-download-2.html	2017-02-17 01:28:00 UTC (rev 212513)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+    testRunner.dumpResourceLoadCallbacks();
+    testRunner.dumpAsText();
+}
+if (window.internals) {
+    internals.invalidateFontCache();
+    internals.clearMemoryCache();
+}
+</script>
+<style>
+@font-face {
+    font-family: "WebFont";
+    font-weight: 100;
+    src: url("../../resources/Ahem_CJK.ttf") format("truetype");
+}
+@font-face {
+    font-family: "WebFont";
+    font-weight: 900;
+    src: url("../../resources/Ahem.otf") format("opentype");
+}
+</style>
+</head>
+<body>
+This test makes sure that unnecessary fonts aren't downloaded. The test fails if Ahem.otf is downloaded.
+<div style="font: 100 100px 'WebFont';">&#x6A2A;</div>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/text/font-weight-download-expected.txt (0 => 212513)


--- trunk/LayoutTests/fast/text/font-weight-download-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/text/font-weight-download-expected.txt	2017-02-17 01:28:00 UTC (rev 212513)
@@ -0,0 +1,6 @@
+font-weight-download.html - didFinishLoading
+Ahem.ttf - willSendRequest <NSURLRequest URL Ahem.ttf, main document URL font-weight-download.html, http method GET> redirectResponse (null)
+Ahem.ttf - didReceiveResponse <NSURLResponse Ahem.ttf, http status code 0>
+Ahem.ttf - didFinishLoading
+This test makes sure that unnecessary fonts aren't downloaded. The test fails if Ahem.otf is downloaded.
+Hello
Property changes on: trunk/LayoutTests/fast/text/font-weight-download-expected.txt
___________________________________________________________________

Added: svn:eol-style

+native \ No newline at end of property

Added: svn:keywords

+Author Date Id Rev URL \ No newline at end of property

Added: trunk/LayoutTests/fast/text/font-weight-download.html (0 => 212513)


--- trunk/LayoutTests/fast/text/font-weight-download.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/font-weight-download.html	2017-02-17 01:28:00 UTC (rev 212513)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+    testRunner.dumpResourceLoadCallbacks();
+    testRunner.dumpAsText();
+}
+if (window.internals) {
+    internals.invalidateFontCache();
+    internals.clearMemoryCache();
+}
+</script>
+<style>
+@font-face {
+    font-family: "WebFont";
+    font-weight: 100;
+    src: url("../../resources/Ahem.ttf") format("truetype");
+}
+@font-face {
+    font-family: "WebFont";
+    font-weight: 900;
+    src: url("../../resources/Ahem.otf") format("opentype");
+}
+</style>
+</head>
+<body>
+This test makes sure that unnecessary fonts aren't downloaded. The test fails if Ahem.otf is downloaded.
+<div style="font: 100 100px 'WebFont';">Hello</div>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/text/font-weight-fallback-expected.html (0 => 212513)


--- trunk/LayoutTests/fast/text/font-weight-fallback-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/font-weight-fallback-expected.html	2017-02-17 01:28:00 UTC (rev 212513)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+    font-family: "WebFont";
+    font-weight: 100;
+    src: url("../../resources/Ahem_CJK.ttf") format("truetype");
+}
+</style>
+</head>
+<body>
+This test makes sure that chaining font downloads works as expected. Specifically, Ahem.otf should be downloaded, but then we should realize that it doesn't support the character below, so we should download Ahem_CJK.ttf and use it because it supports the character.
+<div style="font: 100 100px 'WebFont';">&#x6A2A;</div>
+</body>
+</html>
\ No newline at end of file

Added: trunk/LayoutTests/fast/text/font-weight-fallback.html (0 => 212513)


--- trunk/LayoutTests/fast/text/font-weight-fallback.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/font-weight-fallback.html	2017-02-17 01:28:00 UTC (rev 212513)
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+@font-face {
+    font-family: "WebFont";
+    font-weight: 100;
+    src: url("../../resources/Ahem_CJK.ttf") format("truetype");
+}
+@font-face {
+    font-family: "WebFont";
+    font-weight: 300;
+    src: url("../../resources/Ahem.otf") format("opentype");
+}
+</style>
+</head>
+<body>
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+var promises = [];
+
+document.fonts.forEach(function(f) {
+    promises.push(f.loaded);
+});
+
+Promise.all(promises).then(function() {
+    if (window.testRunner)
+        testRunner.notifyDone();
+});
+</script>
+This test makes sure that chaining font downloads works as expected. Specifically, Ahem.otf should be downloaded, but then we should realize that it doesn't support the character below, so we should download Ahem_CJK.ttf and use it because it supports the character.
+<div style="font: 300 100px 'WebFont';">&#x6A2A;</div>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/LayoutTests/http/tests/webfont/fallback-font-while-loading-expected.txt (212512 => 212513)


--- trunk/LayoutTests/http/tests/webfont/fallback-font-while-loading-expected.txt	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/LayoutTests/http/tests/webfont/fallback-font-while-loading-expected.txt	2017-02-17 01:28:00 UTC (rev 212513)
@@ -1,7 +1,7 @@
-This test checks that the fallback font is used for layout while a webfont is loading.
+This test checks that the fallback font is not used for layout while a webfont is loading.
 
 Target:
 A text to be measured.
 Reference:
 A text to be measured.
-PASS: The width of target text and reference text is the same.
+PASS: The width of target text and reference text are different.

Modified: trunk/LayoutTests/http/tests/webfont/fallback-font-while-loading.html (212512 => 212513)


--- trunk/LayoutTests/http/tests/webfont/fallback-font-while-loading.html	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/LayoutTests/http/tests/webfont/fallback-font-while-loading.html	2017-02-17 01:28:00 UTC (rev 212513)
@@ -5,7 +5,7 @@
 }
 </style>
 <p>
-This test checks that the fallback font is used for layout while a webfont is loading.
+This test checks that the fallback font is not used for layout while a webfont is loading.
 </p>
 Target:
 <div>
@@ -26,10 +26,10 @@
     var targetWidth = document.getElementById('target').offsetWidth;
     var referenceWidth = document.getElementById('reference').offsetWidth;
     var result = document.getElementById('result');
-    if (targetWidth == referenceWidth)
-        result.innerText = 'PASS: The width of target text and reference text is the same.';
+    if (targetWidth != referenceWidth)
+        result.innerText = 'PASS: The width of target text and reference text are different.';
     else
-        result.innerText = 'FAIL: The width of target text and reference text is different: ' + targetWidth + ' != ' + referenceWidth;
+        result.innerText = 'FAIL: The width of target text and reference text are the same.';
 }
 
 checkSize();

Added: trunk/LayoutTests/resources/Ahem_CJK.ttf (0 => 212513)


--- trunk/LayoutTests/resources/Ahem_CJK.ttf	                        (rev 0)
+++ trunk/LayoutTests/resources/Ahem_CJK.ttf	2017-02-17 01:28:00 UTC (rev 212513)
@@ -0,0 +1,47 @@
+\x800OS/2sf\xF8\xBC`cmapED\xB4l$gasp	@glyf P\xF6head\xDBP͵!H6hhea
+:!\x80$hmtx$\xBE\x9D!\xA4dloca\xCCB\xD3&4maxp	(< nameѰ+(\,.post@\xF5\x91\xF1T\x8C\x9D\xD6\x90\xBC\x8A\x8F\xBC\x8A\xC52\x80\xAF HW3C @ \xFE\xFF \xFF8 \xC8\xFF\xFC\xFF\xFF   @@&~\xA0\xA1\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCF\xD0\xD1\xD2\xD4\xD5\xD6\xD7\xD8\xD9\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEB\xEC\xED\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFC\xFD\xFE\xFF1Sx\x92\xC6\xC7\xC9\xDA\xDB\xDC\xDD\x94\xA5\xA7\xA9\xBC\xC0   +      " & 0 : D!"!&"""""""""+"H"`"e"\xF2%\xCA00NNN	N]
 N\x8CN\x94QkQmSAV\xD7V\xDBWg(j*jkl4pk~&~1~\xB5\x91\xD1\xF0\xFE\xFF\xFF\xFF (\xA0\xA1\xA2\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xD0\xD1\xD2\xD3\xD5\xD6\xD7\xD8\xD9\xDA\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEC\xED\xEE\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFD\xFE\xFF1Rx\x92\xC6\xC7\xC9\xD8\xDB\xDC\xDD\x94\xA5\xA7\xA9\xBC\xC0  	         & 0 9 D!"!&"""""""""+"H"`"d"\xF2%\xCA00NNN	N]N\x8CN\x94QkQmSAV\xD7V\xDBWg(j*jkl4pk~&~1~\xB5\x91\xD1\xF0\xFE\xFF\xFF\xFF\xFF\xE3\xFF\xE2\xFF\xF9\xFF\xF4\xFF\xE0\xFF\xFD\xFF\xE9\xFF\xDD\xFF\xE2\xFF\xDF\xFF\xE6\xFF\xEC\xFF\xEA\xFF\xD9\xFF\xD1\xFF\xDC\xFF\xD5\xFF\xDA\xFF\xCF\xF
 F\xEB+\xFF\xD7\xFF\xDD+\xFF\xD5\xFF\xDA\xFF\xE4\xFF\xE1\xFF\xD8\xFF\x9D\xFF\xC5\xFF\x9C\xFF\xDF\xFF\x9B\xFF\xDA\xFF\xDB\xFF\xDF\xFF\xDB\xFF\xEE\xFF\x94\xFF\xDC\xFF\xD9\xFF\xC7\xFF\x90\xFF\xEE\xFF\xB4\xFF\xD8\xFF\xD5\xFF\x8B\xFF\xE3\xFF\xE4\xFF\xA7\xFF\x89\xFF\x87\xFF\x88\xFF\x89\xFF\x87\xFF\x88\xFF\xAC\xFF\x87\xFF\x88\xFF\x86\xFF\x87\xFF\x88\xFF\x86\xFF\x87\xFF\xCF\xFF\x86\xFF\x87\xFF\x85\xFF\x86\xFF\x87\xFF\x85\xFF\xA8\xFF\x9B\xFF\x85\xFF\x83\xFF\x84\xFF\xC4\xFF\xC5\xFF\xA1\xFF\x81\xFF|\xFFX\xFF?\xFD\xED\xFD\xF5\xFD\xEC\xFD\xDE\xFD\xE0\xFD\xD8\xFD\xDD\xFD>\xFDp\xFDk\xFD*\xFC\xD3\xFD\xE0\xF4\xE0\xF2\xE0\xF3\xDF\xFF\xE0\xC2\xE0\x85\xE0\xBD\xE0\xBC\xE0\xBB\xE0\xB8\xE0\xAF\xE0\xA7\xE0\x9E\xDF\xC1߭\xDE\xE2\xDE\xCC\xDE\xD6\xDE\xD5޲މ\xDE\xCD\xDE\xCA޾ޥފއ\xDD\xFB\xDB$\xD0\xFE\xD1\xB3\xB3\xB2\xFA\xB2\xAC\xB2v\xB2q\xAF\x9D\xAF\x99\xADɪ5\xAA)\xA9\xF2\x99\xE7\x96閩\x94ڐ\xA2\x82\xF1\x82\xE7\x82ao?\xEF\xF6
 \xFF\xFF}k 3!%!!}\xEE\xFD\x8F\xF4\xFE \xFC\xE0}&\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 
 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!
 \xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\
 xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE81!!\xE8\xFC\xC8\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \
 xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xE8 !!\xE8\xFC \xFC\xE0\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC
 \xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\x
 FF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\
 xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 
 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 
 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\
 xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\xFC \xFC\xFF8\xE8 !!\xE8\x
 FC \xFC\x90\xE8X!!\xE8\xFCX\xC8\x90\xE8X!!\xE8\xFCX\xC8\x90\xE8X!!\xE8\xFCX\xC8\xC8\xFF8\x90 3#\xC8\xC8\xC8 \xFC\xC8\xFF8\x90 3#\xC8\xC8\xC8 \xFC\xC8\xFF8\x90 3#\xC8\xC8\xC8 \xFC\xC8\xFF8\x90 3#\xC8\xC8\xC8 \xFC\x80\xFE4\x8A\xCA_<\xF5	\xE8\xB3o_Y\xC4ݫ$\xFF8\xE8  \xFF8\xE8\xE8\xE8}\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\x
 E8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8
 \xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xF4\xE8M\xFA\xA7\xC8d\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xE8\xC8\xE8\xC8\xE8\xC8\xE8\xC8!.;HUbo|\x89\x96\xA3\xB0\xBD\xCA\xD7\xE4\xF1\xFE%2?LYfs\x80\x8D\x9A\xA7\xB4\xC1\xCE\xDB\xE8\xF5)6CP]jw\x84\x91\x9E\xAB\xB8\xC5\xD2\xDF\xEC\xF9 -:GTan{\x88\x95\xA2\xAF\xBC\xC9\xD6\xE3\xF0\xFD
+#0=JWdq~\x8B\x98\xA5\xB2\xBF\xCC\xD9\xE6\xF3+'4AN[hu\x82\x8F\x9C\xA9\xB6\xC3\xD0\xDD\xEA\xF7+8ER_ly\x86\x93\xA0\xAD\xBA\xC7\xD4\xE1\xEE\xFB"/<IVcp}\x8A\x97\xA4\xA4\xB1\xBE\xCB\xD8\xE5\xF2\xFF&3@MZgt\x81\x8E\x9B\xA8\xB5\xC2\xCF\xDC\xE9\xF6				*	7	D	Q	^	k	x	\x85	\x92	\x9F	\xAC	\xB9	\xC6	\xD3	\xE0	\xED	\xFA
+
+
+!
+.
+;
+H
+U
+b
+o
+|
+\x89
+\x96
+\xA3
+\xB0
+\xBD
+\xCA
+\xD7
+\xE4
+\xF1
+\xFE%2?LYfs\x80\x8D\x9A\xA7\xB4\xC1\xCE\xDB\xE8\xF5)6CCCCCCCCCCCCCP]jw\x84\x91\x9E\xAB\xB8\xC5\xD2\xDF\xEC\xF9+++ +-+:+G+T+a+n+{$\xB6\xF0\xF0\xF8"(0H
+\xAEP$\xFER"\xF8tlpw\x88\x8C\x98
+\x9C\x9C)\xAE\xD7\xDB\xE2	\xF0\xE6	\xD6	\xDE	"\xEC			.	
+\xAE6	$)\xE4	R*	*Z	*b	*pThe Ahem font belongs to the public domain. In jurisdictions that do not recognize public domain ownership of these files, the following Creative Commons Zero declaration applies: http://labs.creativecommons.org/licenses/zero-waive/1.0/us/legalcodeAhemRegularVersion 1.50 AhemAhemVersion 1.50AhemThe Ahem font was developed by Todd Fahrner and Myles C. Maxfield to help test writers develop predictable tests. The units per em is 1000, the advance is 800, and
  the descent is 200, thereby making the em square exactly square. The glyphs for most characters is simply a box which fills this square. The codepoints mapped to this full square with a full advance are the following ranges: U+20-U+26, U+28-U+6F, U+71-U+7E, U+A0-U+C8, U+CA-U+FF, U+131, U+152-U+153, U+178, U+192, U+2C6-U+2C7, U+2C9, U+2D8-U+2DD, U+394, U+3A5, U+3A7, U+3A9, U+3BC, U+3C0, U+2013-U+2014, U+2018-U+201A, U+201C-U+201E, U+2020-U+2022, U+2026, U+2030, U+2039-U+203A, U+2044, U+2122
 , U+2126, U+2202, U+2206, U+220F, U+2211-U+2212, U+2219-U+221A, U+221E, U+222B, U+2248, U+2260, U+2264-U+2265, U+22F2, U+25CA, U+3007, U+4E00, U+4E03, U+4E09, U+4E5D, U+4E8C, U+4E94, U+516B, U+516D, U+5341, U+56D7, U+56DB, U+571F, U+6728, U+6C34, U+706B, U+91D1, U+F000-U+F002. The codepoints which are mapped to something else are the following: " " (U+20): No path but full advance; "p" (U+70): Path has 0 ascent but full descent; "\xC9" (U+C9): Path has 0 descent but full ascen
 t; Non-breaking space (U+A0): No path but full advance; Zero-width non-breaking space (U+FEFF): No path and 0 advance; En space (U+2002): No path and half advance; Em space (U+2003): No path but full advance; Three-per-em space (U+2004): No path and one third advance; Four-per-em space (U+2005): No path and one quarter advance; Six-per-em space (U+2006): No path and one sixth advance; Thin space (U+2009): No path and one fifth advance; Hair space (U+200A): No path and one tenth advance; Ze
 ro width space (U+200B): No path and no advance; Ideographic space (U+3000): No path but full advance; Zero width non-joiner (U+200C): No path and no advance; Zero width joiner (U+200D): No path and no advance; Greek capital letter Chi (U+3A7): Thin horizontal stripe and full advance; "j*" (U+6A2A): Thin horizontal stripe and full advance; "jk" (U+6A6B): Thin horizontal stripe and full advance; Greek capital letter Upsilon (U+3A5): Thin vertical stripe and full advance; "~\xB5" (
 U+7EB5): Thin vertical stripe and full advance;  "~&" (U+7E26): Thin vertical stripe and full advance;  "~1" (U+7E31): Thin vertical stripe and full advance.http://www.w3c.orghttp://dev.w3.org/CSS/fonts/ahem/COPYING
+The Ahem font belongs to the public domain. In jurisdictions that do not recognize public domain ownership of these files, the following Creative Commons Zero declaration applies: http://labs.creativecommons.org/licenses/zero-waive/1.0/us/legalcodeAhemRegularVersion 1.50 AhemAhemVersion 1.50Ahemhttp://www.w3c.orghttp://dev.w3.org/CSS/fonts/ahem/COPYING
+AhemRegularAhemThe Ahem font belongs to the public domain. In jurisdictions that do not recognize public domain ownership of these files, the following Creative Commons Zero declaration applies: http://labs.creativecommons.org/licenses/zero-waive/1.0/us/legalcodeAhemRegularVersion 1.50 AhemAhemVersion 1.50AhemThe Ahem font was developed by Todd Fahrner and Myles C. Maxfield to help test writers develop predictable tests. The units per em is 1000, the advance is 800, and the descent is 200, thereby
  making the em square exactly square. The glyphs for most characters is simply a box which fills this square. The codepoints mapped to this full square with a full advance are the following ranges: U+20-U+26, U+28-U+6F, U+71-U+7E, U+A0-U+C8, U+CA-U+FF, U+131, U+152-U+153, U+178, U+192, U+2C6-U+2C7, U+2C9, U+2D8-U+2DD, U+394, U+3A5, U+3A7, U+3A9, U+3BC, U+3C0, U+2013-U+2014, U+2018-U+201A, U+201C-U+201E, U+2020-U+2022, U+2026, U+2030, U+2039-U+203A, U+2044, U+2122, U+2126, U+2202, U+2206, U
 +220F, U+2211-U+2212, U+2219-U+221A, U+221E, U+222B, U+2248, U+2260, U+2264-U+2265, U+22F2, U+25CA, U+3007, U+4E00, U+4E03, U+4E09, U+4E5D, U+4E8C, U+4E94, U+516B, U+516D, U+5341, U+56D7, U+56DB, U+571F, U+6728, U+6C34, U+706B, U+91D1, U+F000-U+F002. The codepoints which are mapped to something else are the following: " " (U+20): No path but full advance; "p" (U+70): Path has 0 ascent but full descent; "\xC9" (U+C9): Path has 0 descent but full ascent; Non-breaking space (U+A0
 ): No path but full advance; Zero-width non-breaking space (U+FEFF): No path and 0 advance; En space (U+2002): No path and half advance; Em space (U+2003): No path but full advance; Three-per-em space (U+2004): No path and one third advance; Four-per-em space (U+2005): No path and one quarter advance; Six-per-em space (U+2006): No path and one sixth advance; Thin space (U+2009): No path and one fifth advance; Hair space (U+200A): No path and one tenth advance; Zero width space (U+200B): No 
 path and no advance; Ideographic space (U+3000): No path but full advance; Zero width non-joiner (U+200C): No path and no advance; Zero width joiner (U+200D): No path and no advance; Greek capital letter Chi (U+3A7): Thin horizontal stripe and full advance; "j*" (U+6A2A): Thin horizontal stripe and full advance; "jk" (U+6A6B): Thin horizontal stripe and full advance; Greek capital letter Upsilon (U+3A5): Thin vertical stripe and full advance; "~\xB5" (U+7EB5): Thin vertical strip
 e and full advance;  "~&" (U+7E26): Thin vertical stripe and full advance;  "~1" (U+7E31): Thin vertical stripe and full advance.http://www.w3c.orghttp://dev.w3.org/CSS/fonts/ahem/COPYING
+AhemRegularAhem\xFF{	+ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x80\x81\x83\x84\x85\x86\x88\x89\x8A\x8B\x8D\x8E\x90\x91\x93\x96\x97\x9D\x9E\xA0\xA1\xA2\xA3\xA4\xA9\xAA\xAC\xAD\xAE\xAF\xB6\xB7\xB8\xBA\xBD\xC3\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xB0\xB1\xBB\xA6\xA8\x9F\x9B\xB2\xB3\xC4\xB4\xB5\xC5\x82\xC2\x87\xAB\xC6\xBE\xBF\xBC\x8C\x98\x9A\x99\xA5\x92\x9C\x8F\x94\x95\xA7\xB9\xD2\xC0\xC1	
++ !"#$%&'()*+NULLglyph243glyph204glyph205HTDELuniFEFFuni2002uni2003uni2004uni2005uni2006uni2009uni200Auni200Buni3000	afii61664afii301uni4E00uni4E8Cuni4E09uni56DBuni4E94uni516Duni4E03uni516Buni4E5Duni5341uni3007uni56D7uni706Buni6C34uni6728uni91D1uni571Funi03A7uni6A2Auni6A6Buni03A5uni7EB5uni7E26uni7E31
\ No newline at end of file

Modified: trunk/LayoutTests/svg/W3C-SVG-1.1-SE/struct-dom-11-f.svg (212512 => 212513)


--- trunk/LayoutTests/svg/W3C-SVG-1.1-SE/struct-dom-11-f.svg	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/LayoutTests/svg/W3C-SVG-1.1-SE/struct-dom-11-f.svg	2017-02-17 01:28:00 UTC (rev 212513)
@@ -44,7 +44,7 @@
       </font-face-src>
     </font-face>
   </defs>
-  <g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
+  <g id="test-body-content" font-family="sans-serif" font-size="18">
 
     <text x='10' y='40' font-size='13'>Test getIntersectionList and getEnclosureList return value liveness</text>
 

Modified: trunk/Source/WebCore/ChangeLog (212512 => 212513)


--- trunk/Source/WebCore/ChangeLog	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Source/WebCore/ChangeLog	2017-02-17 01:28:00 UTC (rev 212513)
@@ -1,3 +1,47 @@
+2017-02-16  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        font-weight in @font-face can cause a font to be downloaded even when it's not used
+        https://bugs.webkit.org/show_bug.cgi?id=168114
+        <rdar://problem/30301317>
+
+        Reviewed by Darin Adler.
+
+        There were two problems with our font loading code.
+
+        When we are in the middle of a download, we will use a special interstitial font,
+        and this special font has a flag set which will cause it to be invisible when it is
+        drawn. However, when we start using this font during the load, we give it a
+        unicode-range of U+0-0 which means that it will never be used, and fallback will
+        happen to other weights immediately. 
+
+        The second problem with the font loading code is that this interstital font is just
+        Times. Times doesn't support every character, which means that if we are trying
+        to render some exotic character, we fall back to other weights. The solution here
+        is to use LastResort as the interstitial font, because it supports all characters.
+        Because its metrics are reasonable and we don't ever actually paint this
+        interstitial font, this choice is no worse than Times.
+
+        Tests: fast/text/font-style-download.html
+               fast/text/font-weight-download-2.html
+               fast/text/font-weight-download.html
+               fast/text/font-weight-fallback.html
+
+        * css/CSSFontFace.cpp:
+        (WebCore::CSSFontFace::font):
+        * css/CSSSegmentedFontFace.cpp:
+        (WebCore::appendFont):
+        (WebCore::CSSSegmentedFontFace::fontRanges):
+        (WebCore::appendFontWithInvalidUnicodeRangeIfLoading): Deleted.
+        * platform/graphics/Font.h:
+        (WebCore::Font::widthForGlyph):
+        * platform/graphics/FontCache.h:
+        * platform/graphics/freetype/FontCacheFreeType.cpp:
+        (WebCore::FontCache::lastResortFallbackFontForEveryCharacter):
+        * platform/graphics/mac/FontCacheMac.mm:
+        (WebCore::FontCache::lastResortFallbackFontForEveryCharacter):
+        * platform/graphics/win/FontCacheWin.cpp:
+        (WebCore::FontCache::lastResortFallbackFontForEveryCharacter):
+
 2017-02-16  Alex Christensen  <achristen...@webkit.org>
 
         Remove EFL-specific files in Source.

Modified: trunk/Source/WebCore/css/CSSFontFace.cpp (212512 => 212513)


--- trunk/Source/WebCore/css/CSSFontFace.cpp	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Source/WebCore/css/CSSFontFace.cpp	2017-02-17 01:28:00 UTC (rev 212513)
@@ -597,7 +597,7 @@
             fontIsLoading = true;
             if (status() == Status::TimedOut)
                 continue;
-            return Font::create(FontCache::singleton().lastResortFallbackFont(fontDescription)->platformData(), true, true);
+            return Font::create(FontCache::singleton().lastResortFallbackFontForEveryCharacter(fontDescription)->platformData(), true, true);
         case CSSFontFaceSource::Status::Success:
             if (RefPtr<Font> result = source->font(fontDescription, syntheticBold, syntheticItalic, m_featureSettings, m_variantSettings))
                 return result;

Modified: trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp (212512 => 212513)


--- trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp	2017-02-17 01:28:00 UTC (rev 212513)
@@ -94,13 +94,8 @@
     bool m_syntheticItalic;
 };
 
-static void appendFontWithInvalidUnicodeRangeIfLoading(FontRanges& ranges, Ref<FontAccessor>&& fontAccessor, const Vector<CSSFontFace::UnicodeRange>& unicodeRanges)
+static void appendFont(FontRanges& ranges, Ref<FontAccessor>&& fontAccessor, const Vector<CSSFontFace::UnicodeRange>& unicodeRanges)
 {
-    if (fontAccessor->isLoading()) {
-        ranges.appendRange({ 0, 0, WTFMove(fontAccessor) });
-        return;
-    }
-
     if (unicodeRanges.isEmpty()) {
         ranges.appendRange({ 0, 0x7FFFFFFF, WTFMove(fontAccessor) });
         return;
@@ -132,7 +127,7 @@
             auto fontAccessor = CSSFontAccessor::create(face, fontDescription, syntheticBold, syntheticItalic);
             if (result.isNull() && !fontAccessor->font())
                 continue;
-            appendFontWithInvalidUnicodeRangeIfLoading(result, WTFMove(fontAccessor), face->ranges());
+            appendFont(result, WTFMove(fontAccessor), face->ranges());
         }
     }
     return result;

Modified: trunk/Source/WebCore/platform/graphics/Font.h (212512 => 212513)


--- trunk/Source/WebCore/platform/graphics/Font.h	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Source/WebCore/platform/graphics/Font.h	2017-02-17 01:28:00 UTC (rev 212513)
@@ -339,7 +339,11 @@
 
 ALWAYS_INLINE float Font::widthForGlyph(Glyph glyph) const
 {
-    if (isZeroWidthSpaceGlyph(glyph))
+    // The optimization of returning 0 for the zero-width-space glyph is incorrect for the LastResort font,
+    // used in place of the actual font when isLoading() is true on both macOS and iOS.
+    // The zero-width-space glyph in that font does not have a width of zero and, further, that glyph is used
+    // for many other characters and must not be zero width when used for them.
+    if (isZeroWidthSpaceGlyph(glyph) && !isLoading())
         return 0;
 
     float width = m_glyphToWidthMap.metricsForGlyph(glyph);

Modified: trunk/Source/WebCore/platform/graphics/FontCache.h (212512 => 212513)


--- trunk/Source/WebCore/platform/graphics/FontCache.h	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Source/WebCore/platform/graphics/FontCache.h	2017-02-17 01:28:00 UTC (rev 212513)
@@ -202,6 +202,7 @@
 
     WEBCORE_EXPORT RefPtr<Font> fontForFamily(const FontDescription&, const AtomicString&, const FontFeatureSettings* fontFaceFeatures = nullptr, const FontVariantSettings* fontFaceVariantSettings = nullptr, bool checkingAlternateName = false);
     WEBCORE_EXPORT Ref<Font> lastResortFallbackFont(const FontDescription&);
+    Ref<Font> lastResortFallbackFontForEveryCharacter(const FontDescription&);
     WEBCORE_EXPORT Ref<Font> fontForPlatformData(const FontPlatformData&);
     RefPtr<Font> similarFont(const FontDescription&, const AtomicString& family);
 

Modified: trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp (212512 => 212513)


--- trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp	2017-02-17 01:28:00 UTC (rev 212513)
@@ -121,6 +121,11 @@
     return fontFamilies;
 }
 
+Ref<Font> FontCache::lastResortFallbackFontForEveryCharacter(const FontDescription& fontDescription)
+{
+    return lastResortFallbackFont(fontDescription);
+}
+
 Ref<Font> FontCache::lastResortFallbackFont(const FontDescription& fontDescription)
 {
     // We want to return a fallback font here, otherwise the logic preventing FontConfig

Modified: trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm (212512 => 212513)


--- trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm	2017-02-17 01:28:00 UTC (rev 212513)
@@ -30,13 +30,13 @@
 #import "config.h"
 #import "FontCache.h"
 
-#if !PLATFORM(IOS)
-
 #import "CoreGraphicsSPI.h"
 #import "CoreTextSPI.h"
 #import "Font.h"
 #import "FontCascade.h"
 #import "FontPlatformData.h"
+
+#if PLATFORM(MAC)
 #import "NSFontSPI.h"
 #import "WebCoreNSStringExtras.h"
 #import "WebCoreSystemInterface.h"
@@ -46,9 +46,12 @@
 #import <wtf/StdLibExtras.h>
 #import <wtf/Threading.h>
 #import <wtf/text/AtomicStringHash.h>
+#endif
 
 namespace WebCore {
 
+#if PLATFORM(MAC)
+
 #if !ENABLE(PLATFORM_FONT_LOOKUP)
 
 #define SYNTHESIZED_FONT_TRAITS (NSBoldFontMask | NSItalicFontMask)
@@ -390,6 +393,13 @@
     return *fontForFamily(fontDescription, AtomicString("Lucida Grande", AtomicString::ConstructFromLiteral), nullptr, nullptr, false);
 }
 
+#endif // PLATFORM(MAC)
+
+Ref<Font> FontCache::lastResortFallbackFontForEveryCharacter(const FontDescription& fontDescription)
+{
+    auto result = fontForFamily(fontDescription, AtomicString("LastResort", AtomicString::ConstructFromLiteral));
+    ASSERT(result);
+    return *result;
+}
+
 } // namespace WebCore
-
-#endif // !PLATFORM(IOS)

Modified: trunk/Source/WebCore/platform/graphics/win/FontCacheWin.cpp (212512 => 212513)


--- trunk/Source/WebCore/platform/graphics/win/FontCacheWin.cpp	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Source/WebCore/platform/graphics/win/FontCacheWin.cpp	2017-02-17 01:28:00 UTC (rev 212513)
@@ -338,6 +338,11 @@
     return fontData;
 }
 
+Ref<Font> FontCache::lastResortFallbackFontForEveryCharacter(const FontDescription& fontDescription)
+{
+    return lastResortFallbackFont(fontDescription);
+}
+
 Ref<Font> FontCache::lastResortFallbackFont(const FontDescription& fontDescription)
 {
     DEPRECATED_DEFINE_STATIC_LOCAL(AtomicString, fallbackFontName, ());

Modified: trunk/Tools/ChangeLog (212512 => 212513)


--- trunk/Tools/ChangeLog	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Tools/ChangeLog	2017-02-17 01:28:00 UTC (rev 212513)
@@ -1,3 +1,20 @@
+2017-02-16  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        font-weight in @font-face can cause a font to be downloaded even when it's not used
+        https://bugs.webkit.org/show_bug.cgi?id=168114
+        <rdar://problem/30301317>
+
+        Reviewed by Darin Adler.
+
+        LastResort needs to be usable in tests.
+
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (allowedFontFamilySet):
+        * WebKitTestRunner/InjectedBundle/cocoa/ActivateFontsCocoa.mm:
+        (WTR::allowedFontFamilySet):
+        * WebKitTestRunner/mac/TestControllerMac.mm:
+        (WTR::allowedFontFamilySet):
+
 2017-02-16  Alex Christensen  <achristen...@webkit.org>
 
         Remove old URL parser

Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (212512 => 212513)


--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm	2017-02-17 01:28:00 UTC (rev 212513)
@@ -378,6 +378,7 @@
         @"Kokonor",
         @"Krungthep",
         @"KufiStandardGK",
+        @"LastResort",
         @"LiHei Pro",
         @"LiSong Pro",
         @"Lucida Grande",

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/cocoa/ActivateFontsCocoa.mm (212512 => 212513)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/cocoa/ActivateFontsCocoa.mm	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/cocoa/ActivateFontsCocoa.mm	2017-02-17 01:28:00 UTC (rev 212513)
@@ -123,6 +123,7 @@
         @"Kokonor",
         @"Krungthep",
         @"KufiStandardGK",
+        @"LastResort",
         @"LiHei Pro",
         @"LiSong Pro",
         @"Lucida Grande",

Modified: trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm (212512 => 212513)


--- trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm	2017-02-17 01:25:26 UTC (rev 212512)
+++ trunk/Tools/WebKitTestRunner/mac/TestControllerMac.mm	2017-02-17 01:28:00 UTC (rev 212513)
@@ -221,6 +221,7 @@
         @"Kokonor",
         @"Krungthep",
         @"KufiStandardGK",
+        @"LastResort",
         @"LiHei Pro",
         @"LiSong Pro",
         @"Lucida Grande",
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to