Support ArrayBufferViews in the CSS Font Loading API
https://bugs.webkit.org/show_bug.cgi?id=157694
<rdar://problem/25554267>

Source/WebCore:

This patch adds a new mode to CSSFontFaceSource for immediate (ArrayBuffer) data.
Then, FontFace can simply be hooked up to this new mode.

Reviewed by Darin Adler.

Test: fast/text/css-font-loading-arraybuffer.html

* css/CSSFontFaceSource.cpp:
(WebCore::CSSFontFaceSource::CSSFontFaceSource):
(WebCore::CSSFontFaceSource::font):
* css/CSSFontFaceSource.h:
* css/FontFace.cpp:
(WebCore::FontFace::create):
* loader/cache/CachedFont.cpp:
(WebCore::CachedFont::ensureCustomFontData):
(WebCore::CachedFont::createCustomFontData):
(WebCore::CachedFont::createFont):
(WebCore::CachedFont::platformDataFromCustomData):
* loader/cache/CachedFont.h:

LayoutTests:

Reviewed by Darin Adler.

* fast/text/css-font-loading-arraybuffer-expected.txt: Added.
* fast/text/css-font-loading-arraybuffer.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@200921 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/css/FontFace.cpp b/Source/WebCore/css/FontFace.cpp
index aef5ad3..782e7d3 100644
--- a/Source/WebCore/css/FontFace.cpp
+++ b/Source/WebCore/css/FontFace.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "FontFace.h"
 
+#include "CSSFontFaceSource.h"
 #include "CSSFontFeatureValue.h"
 #include "CSSUnicodeRangeValue.h"
 #include "CSSValuePool.h"
@@ -36,10 +37,19 @@
 
 namespace WebCore {
 
+static bool populateFontFaceWithArrayBuffer(CSSFontFace& fontFace, Ref<JSC::ArrayBufferView>&& arrayBufferView)
+{
+    auto source = std::make_unique<CSSFontFaceSource>(fontFace, String(), nullptr, nullptr, WTFMove(arrayBufferView));
+    fontFace.adoptSource(WTFMove(source));
+    return false;
+}
+
 RefPtr<FontFace> FontFace::create(JSC::ExecState& state, Document& document, const String& family, JSC::JSValue source, const Descriptors& descriptors, ExceptionCode& ec)
 {
     auto result = adoptRef(*new FontFace(document.fontSelector()));
 
+    bool dataRequiresAsynchronousLoading = true;
+
     ec = 0;
     result->setFamily(family, ec);
     if (ec)
@@ -52,6 +62,11 @@
             return nullptr;
         }
         CSSFontFace::appendSources(result->backing(), downcast<CSSValueList>(*value), &document, false);
+    } else if (auto arrayBufferView = toArrayBufferView(source))
+        dataRequiresAsynchronousLoading = populateFontFaceWithArrayBuffer(result->backing(), arrayBufferView.releaseNonNull());
+    else if (auto arrayBuffer = toArrayBuffer(source)) {
+        auto arrayBufferView = JSC::Uint8Array::create(arrayBuffer, 0, arrayBuffer->byteLength());
+        dataRequiresAsynchronousLoading = populateFontFaceWithArrayBuffer(result->backing(), arrayBufferView.releaseNonNull());
     }
 
     result->setStyle(descriptors.style, ec);
@@ -73,6 +88,11 @@
     if (ec)
         return nullptr;
 
+    if (!dataRequiresAsynchronousLoading) {
+        result->backing().load();
+        ASSERT(result->backing().status() == CSSFontFace::Status::Success);
+    }
+
     return WTFMove(result);
 }