Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / fetch / FontResource.cpp
old mode 100755 (executable)
new mode 100644 (file)
index d45debb..98c9f2f
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "core/fetch/FontResource.h"
 
+#include "core/dom/TagCollection.h"
 #include "core/fetch/ResourceClientWalker.h"
 #include "core/html/parser/TextResourceDecoder.h"
 #include "platform/SharedBuffer.h"
 #include "public/platform/Platform.h"
 #include "wtf/CurrentTime.h"
 
-#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
-#include "core/dom/NodeList.h"
-#include "core/svg/SVGDocument.h"
-#include "core/svg/SVGFontElement.h"
-#endif
+namespace blink {
 
-namespace WebCore {
+static const double fontLoadWaitLimitSec = 3.0;
+
+enum FontPackageFormat {
+    PackageFormatUnknown,
+    PackageFormatSFNT,
+    PackageFormatWOFF,
+    PackageFormatWOFF2,
+    PackageFormatSVG,
+    PackageFormatEnumMax
+};
+
+static FontPackageFormat packageFormatOf(SharedBuffer* buffer)
+{
+    if (buffer->size() < 4)
+        return PackageFormatUnknown;
+
+    const char* data = buffer->data();
+    if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == 'F')
+        return PackageFormatWOFF;
+    if (data[0] == 'w' && data[1] == 'O' && data[2] == 'F' && data[3] == '2')
+        return PackageFormatWOFF2;
+    return PackageFormatSFNT;
+}
+
+static void recordPackageFormatHistogram(FontPackageFormat format)
+{
+    blink::Platform::current()->histogramEnumeration("WebFont.PackageFormat", format, PackageFormatEnumMax);
+}
 
 FontResource::FontResource(const ResourceRequest& resourceRequest)
     : Resource(resourceRequest, Font)
-    , m_loadInitiated(false)
+    , m_state(Unloaded)
+    , m_exceedsFontLoadWaitLimit(false)
+    , m_corsFailed(false)
+    , m_fontLoadWaitLimitTimer(this, &FontResource::fontLoadWaitLimitCallback)
 {
 }
 
@@ -54,6 +80,18 @@ FontResource::~FontResource()
 {
 }
 
+void FontResource::didScheduleLoad()
+{
+    if (m_state == Unloaded)
+        m_state = LoadScheduled;
+}
+
+void FontResource::didUnscheduleLoad()
+{
+    if (m_state == LoadScheduled)
+        m_state = Unloaded;
+}
+
 void FontResource::load(ResourceFetcher*, const ResourceLoaderOptions& options)
 {
     // Don't load the file yet. Wait for an access before triggering the load.
@@ -71,9 +109,10 @@ void FontResource::didAddClient(ResourceClient* c)
 
 void FontResource::beginLoadIfNeeded(ResourceFetcher* dl)
 {
-    if (!m_loadInitiated) {
-        m_loadInitiated = true;
+    if (m_state != LoadInitiated) {
+        m_state = LoadInitiated;
         Resource::load(dl, m_options);
+        m_fontLoadWaitLimitTimer.startOneShot(fontLoadWaitLimitSec, FROM_HERE);
 
         ResourceClientWalker<FontResourceClient> walker(m_clients);
         while (FontResourceClient* client = walker.next())
@@ -86,74 +125,37 @@ bool FontResource::ensureCustomFontData()
     if (!m_fontData && !errorOccurred() && !isLoading()) {
         if (m_data)
             m_fontData = FontCustomPlatformData::create(m_data.get());
-        if (!m_fontData)
+
+        if (m_fontData) {
+            recordPackageFormatHistogram(packageFormatOf(m_data.get()));
+        } else {
             setStatus(DecodeError);
+            recordPackageFormatHistogram(PackageFormatUnknown);
+        }
     }
     return m_fontData;
 }
 
 FontPlatformData FontResource::platformDataFromCustomData(float size, bool bold, bool italic, FontOrientation orientation, FontWidthVariant widthVariant)
 {
-#if ENABLE(SVG_FONTS)
-    if (m_externalSVGDocument)
-        return FontPlatformData(size, bold, italic);
-#endif
     ASSERT(m_fontData);
     return m_fontData->fontPlatformData(size, bold, italic, orientation, widthVariant);
 }
 
-#if ENABLE(SVG_FONTS)
-bool FontResource::ensureSVGFontData()
+bool FontResource::isSafeToUnlock() const
 {
-    if (!m_externalSVGDocument && !errorOccurred() && !isLoading()) {
-        if (m_data) {
-            m_externalSVGDocument = SVGDocument::create();
-
-            OwnPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("application/xml");
-            String svgSource = decoder->decode(m_data->data(), m_data->size());
-            svgSource = svgSource + decoder->flush();
-
-            m_externalSVGDocument->setContent(svgSource);
-
-            if (decoder->sawError())
-                m_externalSVGDocument = 0;
-        }
-        if (!m_externalSVGDocument)
-            setStatus(DecodeError);
-    }
-
-    return m_externalSVGDocument;
+    return m_data->hasOneRef();
 }
 
-SVGFontElement* FontResource::getSVGFontById(const String& fontName) const
+void FontResource::fontLoadWaitLimitCallback(Timer<FontResource>*)
 {
-    RefPtr<NodeList> list = m_externalSVGDocument->getElementsByTagNameNS(SVGNames::fontTag.namespaceURI(), SVGNames::fontTag.localName());
-    if (!list)
-        return 0;
-
-    unsigned listLength = list->length();
-    if (!listLength)
-        return 0;
-
-#ifndef NDEBUG
-    for (unsigned i = 0; i < listLength; ++i) {
-        ASSERT(list->item(i));
-        ASSERT(list->item(i)->hasTagName(SVGNames::fontTag));
-    }
-#endif
-
-    if (fontName.isEmpty())
-        return toSVGFontElement(list->item(0));
-
-    for (unsigned i = 0; i < listLength; ++i) {
-        SVGFontElement* element = toSVGFontElement(list->item(i));
-        if (element->getIdAttribute() == fontName)
-            return element;
-    }
-
-    return 0;
+    if (!isLoading())
+        return;
+    m_exceedsFontLoadWaitLimit = true;
+    ResourceClientWalker<FontResourceClient> walker(m_clients);
+    while (FontResourceClient* client = walker.next())
+        client->fontLoadWaitLimitExceeded(this);
 }
-#endif
 
 void FontResource::allClientsRemoved()
 {
@@ -163,6 +165,7 @@ void FontResource::allClientsRemoved()
 
 void FontResource::checkNotify()
 {
+    m_fontLoadWaitLimitTimer.stop();
     ResourceClientWalker<FontResourceClient> w(m_clients);
     while (FontResourceClient* c = w.next())
         c->fontLoaded(this);