Title: [203092] trunk
Revision
203092
Author
mmaxfi...@apple.com
Date
2016-07-11 16:23:56 -0700 (Mon, 11 Jul 2016)

Log Message

Honor the second argument to FontFaceSet.load and FontFaceSet.check
https://bugs.webkit.org/show_bug.cgi?id=159607
<rdar://problem/27284902>

Reviewed by Zalan Bujtas.

Source/WebCore:

This second argument is used in conjunction with the unicode-range CSS property, so that
loading from a FontFaceSet only loads the fonts which actually match the characters given.
Previously, we hadn't implemented proper support for this unicode-range property, but now
that we have implemented it, we should honor this second argument.

Test: fast/text/unicode-range-_javascript_.html

* css/CSSFontFace.cpp:
(WebCore::CSSFontFace::rangesMatchCodePoint):
* css/CSSFontFace.h:
* css/CSSFontFaceSet.cpp:
(WebCore::codePointsFromString):
(WebCore::CSSFontFaceSet::matchingFaces):

LayoutTests:

* fast/text/font-face-set-document-expected.txt:
* fast/text/font-face-set-document.html:
* fast/text/font-face-set-_javascript_-expected.txt:
* fast/text/font-face-set-_javascript_.html:
* fast/text/unicode-range-_javascript_-expected.txt: Added.
* fast/text/unicode-range-_javascript_.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (203091 => 203092)


--- trunk/LayoutTests/ChangeLog	2016-07-11 23:18:41 UTC (rev 203091)
+++ trunk/LayoutTests/ChangeLog	2016-07-11 23:23:56 UTC (rev 203092)
@@ -1,3 +1,18 @@
+2016-07-11  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Honor the second argument to FontFaceSet.load and FontFaceSet.check
+        https://bugs.webkit.org/show_bug.cgi?id=159607
+        <rdar://problem/27284902>
+
+        Reviewed by Zalan Bujtas.
+
+        * fast/text/font-face-set-document-expected.txt:
+        * fast/text/font-face-set-document.html:
+        * fast/text/font-face-set-_javascript_-expected.txt:
+        * fast/text/font-face-set-_javascript_.html:
+        * fast/text/unicode-range-_javascript_-expected.txt: Added.
+        * fast/text/unicode-range-_javascript_.html: Added.
+
 2016-07-11  Nan Wang  <n_w...@apple.com>
 
         AX: Crash when backspacing in number field with spin button

Modified: trunk/LayoutTests/fast/text/font-face-set-document-expected.txt (203091 => 203092)


--- trunk/LayoutTests/fast/text/font-face-set-document-expected.txt	2016-07-11 23:18:41 UTC (rev 203091)
+++ trunk/LayoutTests/fast/text/font-face-set-document-expected.txt	2016-07-11 23:23:56 UTC (rev 203092)
@@ -12,9 +12,8 @@
 PASS object.done is true
 PASS document.getElementById("testElement").offsetWidth is not originalWidth
 PASS document.getElementById("testElement").offsetWidth is originalWidth
-PASS object.length is 2
+PASS object.length is 1
 PASS object[0].family is "MyFont3"
-PASS object[1].family is "MyFont3"
 PASS document.getElementById("testElement").offsetWidth is not originalWidth
 PASS document.getElementById("testElement").offsetWidth is originalWidth
 PASS successfullyParsed is true

Modified: trunk/LayoutTests/fast/text/font-face-set-document.html (203091 => 203092)


--- trunk/LayoutTests/fast/text/font-face-set-document.html	2016-07-11 23:18:41 UTC (rev 203091)
+++ trunk/LayoutTests/fast/text/font-face-set-document.html	2016-07-11 23:23:56 UTC (rev 203092)
@@ -76,9 +76,8 @@
         return document.fonts.load("50px MyFont3");
     }).then(function(x) {
         object = x;
-        shouldBe("object.length", "2");
+        shouldBe("object.length", "1");
         shouldBeEqualToString("object[0].family", "MyFont3");
-        shouldBeEqualToString("object[1].family", "MyFont3");
         object = undefined;
         appliedFont = new FontFace("AppliedFont", "url(\"../../resources/Ahem.otf\")", {});
         document.fonts.add(appliedFont);

Modified: trunk/LayoutTests/fast/text/font-face-set-_javascript_-expected.txt (203091 => 203092)


--- trunk/LayoutTests/fast/text/font-face-set-_javascript_-expected.txt	2016-07-11 23:18:41 UTC (rev 203091)
+++ trunk/LayoutTests/fast/text/font-face-set-_javascript_-expected.txt	2016-07-11 23:23:56 UTC (rev 203092)
@@ -45,7 +45,7 @@
 PASS fontFaceSet.status is "loaded"
 PASS fontFaceSet.status is "loaded"
 PASS item is [fontFace3]
-PASS item is [fontFace3, fontFace4]
+PASS item is [fontFace3]
 PASS item is fontFaceSet
 PASS fontFaceSet.status is "loaded"
 PASS fontFaceSet.status is "loading"

Modified: trunk/LayoutTests/fast/text/font-face-set-_javascript_.html (203091 => 203092)


--- trunk/LayoutTests/fast/text/font-face-set-_javascript_.html	2016-07-11 23:18:41 UTC (rev 203091)
+++ trunk/LayoutTests/fast/text/font-face-set-_javascript_.html	2016-07-11 23:23:56 UTC (rev 203092)
@@ -126,7 +126,7 @@
     finishJSTest();
 }).then(function(arg) {
     item = arg;
-    shouldBe("item", "[fontFace3, fontFace4]");
+    shouldBe("item", "[fontFace3]");
     fontFaceSet.add(fontFace4);
     fontFaceSet.load("16px family3");
     return fontFaceSet.ready;

Added: trunk/LayoutTests/fast/text/unicode-range-_javascript_-expected.txt (0 => 203092)


--- trunk/LayoutTests/fast/text/unicode-range-_javascript_-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/text/unicode-range-_javascript_-expected.txt	2016-07-11 23:23:56 UTC (rev 203092)
@@ -0,0 +1,17 @@
+This test makes sure that the second argument to FontFaceSet.load() and FontFaceSet.check() is honored.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS faces.length is 1
+PASS faces[0].unicodeRange is "U+41-41"
+PASS document.fonts.check('14px WebFont', 'A') is true
+PASS faces.length is 1
+PASS faces[0].family is "WebFont"
+PASS faces[0].unicodeRange is "U+41-41"
+PASS document.fonts.check('14px WebFont3', 'A') is false
+PASS document.fonts.check('14px WebFont3', 'A') is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/text/unicode-range-_javascript_.html (0 => 203092)


--- trunk/LayoutTests/fast/text/unicode-range-_javascript_.html	                        (rev 0)
+++ trunk/LayoutTests/fast/text/unicode-range-_javascript_.html	2016-07-11 23:23:56 UTC (rev 203092)
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+if (window.internals) {
+    internals.clearMemoryCache();
+    internals.invalidateFontCache();
+}
+</script>
+<style>
+@font-face {
+	font-family: WebFont;
+	src: url("../../resources/Ahem.ttf") format("truetype");
+	unicode-range: U+42;
+}
+@font-face {
+    font-family: WebFont;
+    src: url("../../resources/Ahem.otf") format("opentype");
+    unicode-range: U+41;
+}
+@font-face {
+    font-family: WebFont2;
+    src: url("../../resources/Ahem.otf") format("opentype");
+    unicode-range: U+41-42;
+}
+@font-face {
+    font-family: WebFont3;
+    src: url("notafont.ttf") format("truetype");
+    unicode-range: U+42;
+}
+@font-face {
+    font-family: WebFont3;
+    src: url("../../resources/Ahem.woff") format("woff");
+    unicode-range: U+41;
+}
+</style>
+</head>
+<body>
+<script>
+self.jsTestIsAsync = true;
+
+description("This test makes sure that the second argument to FontFaceSet.load() and FontFaceSet.check() is honored.");
+
+function failure() {
+    testFailed("Promise should not fail.");
+    finishJSTest();
+}
+
+var faces;
+document.fonts.load("14px WebFont", "A").then(function(facesArgument) {
+    faces = facesArgument;
+    shouldBe("faces.length", "1");
+    shouldBeEqualToString("faces[0].unicodeRange", "U+41-41");
+    shouldBeTrue("document.fonts.check('14px WebFont', 'A')");
+    return document.fonts.load("14px WebFont, WebFont2", "A");
+}, failure).then(function(facesArgument) {
+    faces = facesArgument;
+    shouldBe("faces.length", "1");
+    shouldBeEqualToString("faces[0].family", "WebFont");
+    shouldBeEqualToString("faces[0].unicodeRange", "U+41-41");
+    shouldBeFalse("document.fonts.check('14px WebFont3', 'A')");
+    for (let f of document.fonts) {
+        if (f.family == "WebFont3" && f.unicodeRange == "U+41-41")
+            return f.load();
+    }
+    testFailed("Should find font.");
+    finishJSTest();
+}, failure).then(function(face) {
+    shouldBeTrue("document.fonts.check('14px WebFont3', 'A')");
+    finishJSTest();
+}, failure);
+</script>
+<script src=""
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (203091 => 203092)


--- trunk/Source/WebCore/ChangeLog	2016-07-11 23:18:41 UTC (rev 203091)
+++ trunk/Source/WebCore/ChangeLog	2016-07-11 23:23:56 UTC (rev 203092)
@@ -1,3 +1,25 @@
+2016-07-11  Myles C. Maxfield  <mmaxfi...@apple.com>
+
+        Honor the second argument to FontFaceSet.load and FontFaceSet.check
+        https://bugs.webkit.org/show_bug.cgi?id=159607
+        <rdar://problem/27284902>
+
+        Reviewed by Zalan Bujtas.
+
+        This second argument is used in conjunction with the unicode-range CSS property, so that
+        loading from a FontFaceSet only loads the fonts which actually match the characters given.
+        Previously, we hadn't implemented proper support for this unicode-range property, but now
+        that we have implemented it, we should honor this second argument.
+
+        Test: fast/text/unicode-range-_javascript_.html
+
+        * css/CSSFontFace.cpp:
+        (WebCore::CSSFontFace::rangesMatchCodePoint):
+        * css/CSSFontFace.h:
+        * css/CSSFontFaceSet.cpp:
+        (WebCore::codePointsFromString):
+        (WebCore::CSSFontFaceSet::matchingFaces):
+
 2016-07-11  Zalan Bujtas  <za...@apple.com>
 
         Unable to edit fields or drag to select text in Dashboard widgets.

Modified: trunk/Source/WebCore/css/CSSFontFace.cpp (203091 => 203092)


--- trunk/Source/WebCore/css/CSSFontFace.cpp	2016-07-11 23:18:41 UTC (rev 203091)
+++ trunk/Source/WebCore/css/CSSFontFace.cpp	2016-07-11 23:23:56 UTC (rev 203092)
@@ -370,6 +370,18 @@
     });
 }
 
+bool CSSFontFace::rangesMatchCodePoint(UChar32 character) const
+{
+    if (m_ranges.isEmpty())
+        return true;
+
+    for (auto& range : m_ranges) {
+        if (range.from <= character && character <= range.to)
+            return true;
+    }
+    return false;
+}
+
 void CSSFontFace::fontLoadEventOccurred()
 {
     Ref<CSSFontFace> protectedThis(*this);

Modified: trunk/Source/WebCore/css/CSSFontFace.h (203091 => 203092)


--- trunk/Source/WebCore/css/CSSFontFace.h	2016-07-11 23:18:41 UTC (rev 203091)
+++ trunk/Source/WebCore/css/CSSFontFace.h	2016-07-11 23:23:56 UTC (rev 203092)
@@ -133,6 +133,8 @@
         UChar32 to;
     };
 
+    bool rangesMatchCodePoint(UChar32) const;
+
     // We don't guarantee that the FontFace wrapper will be the same every time you ask for it.
     Ref<FontFace> wrapper();
     void setWrapper(FontFace&);

Modified: trunk/Source/WebCore/css/CSSFontFaceSet.cpp (203091 => 203092)


--- trunk/Source/WebCore/css/CSSFontFaceSet.cpp	2016-07-11 23:18:41 UTC (rev 203091)
+++ trunk/Source/WebCore/css/CSSFontFaceSet.cpp	2016-07-11 23:23:56 UTC (rev 203092)
@@ -308,8 +308,24 @@
     return static_cast<FontTraitsMask>(static_cast<unsigned>(styleMask) | static_cast<unsigned>(weightMask));
 }
 
-Vector<std::reference_wrapper<CSSFontFace>> CSSFontFaceSet::matchingFaces(const String& font, const String&, ExceptionCode& ec)
+static HashSet<UChar32> codePointsFromString(StringView stringView)
 {
+    HashSet<UChar32> result;
+    auto graphemeClusters = stringView.graphemeClusters();
+    for (auto cluster : graphemeClusters) {
+        ASSERT(cluster.length() > 0);
+        UChar32 character = 0;
+        if (cluster.is8Bit())
+            character = cluster[0];
+        else
+            U16_GET(cluster.characters16(), 0, 0, cluster.length(), character);
+        result.add(character);
+    }
+    return result;
+}
+
+Vector<std::reference_wrapper<CSSFontFace>> CSSFontFaceSet::matchingFaces(const String& font, const String& string, ExceptionCode& ec)
+{
     Vector<std::reference_wrapper<CSSFontFace>> result;
     auto style = MutableStyleProperties::create();
     auto parseResult = CSSParser::parseValue(style, CSSPropertyFont, font, true, CSSStrictMode, nullptr);
@@ -334,21 +350,37 @@
     CSSValueList& familyList = downcast<CSSValueList>(*family);
 
     HashSet<AtomicString> uniqueFamilies;
+    Vector<AtomicString> familyOrder;
     for (auto& family : familyList) {
         const CSSPrimitiveValue& primitive = downcast<CSSPrimitiveValue>(family.get());
         if (!primitive.isFontFamily())
             continue;
-        uniqueFamilies.add(primitive.fontFamily().familyName);
+        if (uniqueFamilies.add(primitive.fontFamily().familyName).isNewEntry)
+            familyOrder.append(primitive.fontFamily().familyName);
     }
 
-    for (auto& family : uniqueFamilies) {
-        CSSSegmentedFontFace* faces = getFontFace(fontTraitsMask, family);
-        if (!faces)
-            continue;
-        for (auto& constituentFace : faces->constituentFaces())
-            result.append(constituentFace.get());
+    HashSet<CSSFontFace*> resultConstituents;
+    for (auto codePoint : codePointsFromString(string)) {
+        bool found = false;
+        for (auto& family : familyOrder) {
+            CSSSegmentedFontFace* faces = getFontFace(fontTraitsMask, family);
+            if (!faces)
+                continue;
+            for (auto& constituentFace : faces->constituentFaces()) {
+                if (constituentFace->rangesMatchCodePoint(codePoint)) {
+                    resultConstituents.add(constituentFace.ptr());
+                    found = true;
+                    break;
+                }
+            }
+            if (found)
+                break;
+        }
     }
 
+    for (auto* constituent : resultConstituents)
+        result.append(*constituent);
+
     return result;
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to