1d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// found in the LICENSE file.
4d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
5d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "config.h"
6d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/css/RemoteFontFaceSource.h"
7d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
8d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/css/CSSCustomFontData.h"
9d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/css/CSSFontFace.h"
105d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/css/FontLoader.h"
11d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/fonts/FontCache.h"
12d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/fonts/FontDescription.h"
13d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/fonts/SimpleFontData.h"
14d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "public/platform/Platform.h"
15d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/CurrentTime.h"
16d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
17c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
18d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
19d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)RemoteFontFaceSource::RemoteFontFaceSource(FontResource* font, PassRefPtrWillBeRawPtr<FontLoader> fontLoader)
20d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : m_font(font)
21d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    , m_fontLoader(fontLoader)
22d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
23d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_font->addClient(this);
24d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
25d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
26d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)RemoteFontFaceSource::~RemoteFontFaceSource()
27d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
28d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_font->removeClient(this);
29d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    pruneTable();
30d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
31d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
32d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RemoteFontFaceSource::pruneTable()
33d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
34d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_fontDataTable.isEmpty())
35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    for (FontDataTable::iterator it = m_fontDataTable.begin(); it != m_fontDataTable.end(); ++it) {
38d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        SimpleFontData* fontData = it->value.get();
39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (fontData && fontData->customFontData())
40d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            fontData->customFontData()->clearFontFaceSource();
41d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_fontDataTable.clear();
43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool RemoteFontFaceSource::isLoading() const
46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return !m_font->stillNeedsLoad() && !m_font->isLoaded();
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
49d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool RemoteFontFaceSource::isLoaded() const
51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return m_font->isLoaded();
53d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
54d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
55d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool RemoteFontFaceSource::isValid() const
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
57d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return !m_font->errorOccurred();
58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RemoteFontFaceSource::didStartFontLoad(FontResource*)
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
6210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    // We may send duplicated reports when multiple CSSFontFaceSource are
6310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    // registered at this FontResource. Associating the same URL to different
6410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    // font-family causes the case, but we treat them as indivisual resources.
6510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_histograms.loadStarted();
66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
67d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
68d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RemoteFontFaceSource::fontLoaded(FontResource*)
69d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
7010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_histograms.recordRemoteFont(m_font.get());
71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
72d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    pruneTable();
7376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (m_face) {
7476c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        m_fontLoader->fontFaceInvalidated();
75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_face->fontLoaded(this);
7676c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    }
77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RemoteFontFaceSource::fontLoadWaitLimitExceeded(FontResource*)
80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    pruneTable();
8276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    if (m_face) {
8376c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        m_fontLoader->fontFaceInvalidated();
84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_face->fontLoadWaitLimitExceeded(this);
8576c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)    }
86d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
87d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_histograms.recordFallbackTime(m_font.get());
88d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
89d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
90d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtr<SimpleFontData> RemoteFontFaceSource::createFontData(const FontDescription& fontDescription)
91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
92d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!isLoaded())
93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return createLoadingFallbackFontData(fontDescription);
94d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Create new FontPlatformData from our CGFontRef, point size and ATSFontRef.
96d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_font->ensureCustomFontData())
97d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
99d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_histograms.recordFallbackTime(m_font.get());
100d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return SimpleFontData::create(
102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_font->platformDataFromCustomData(fontDescription.effectiveFontSize(),
103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic(),
104d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            fontDescription.orientation(), fontDescription.widthVariant()), CustomFontData::create());
105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
106d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
107d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)PassRefPtr<SimpleFontData> RemoteFontFaceSource::createLoadingFallbackFontData(const FontDescription& fontDescription)
108d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // This temporary font is not retained and should not be returned.
110d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    FontCachePurgePreventer fontCachePurgePreventer;
111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    SimpleFontData* temporaryFont = FontCache::fontCache()->getNonRetainedLastResortFallbackFont(fontDescription);
112d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!temporaryFont) {
113d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        ASSERT_NOT_REACHED();
114d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return nullptr;
115d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
116d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create(this, m_font->exceedsFontLoadWaitLimit() ? CSSCustomFontData::VisibleFallback : CSSCustomFontData::InvisibleFallback);
117d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return SimpleFontData::create(temporaryFont->platformData(), cssFontData);
118d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
119d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RemoteFontFaceSource::beginLoadIfNeeded()
121d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
122d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    if (m_font->stillNeedsLoad())
123d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        m_fontLoader->addFontToBeginLoading(m_font.get());
124d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
125d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_face)
126d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        m_face->didBeginLoad();
127d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
128d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
129d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool RemoteFontFaceSource::ensureFontData()
130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return m_font->ensureCustomFontData();
132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
133d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
134d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void RemoteFontFaceSource::trace(Visitor* visitor)
135d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
136d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_fontLoader);
137d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    CSSFontFaceSource::trace(visitor);
138d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
139d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RemoteFontFaceSource::FontLoadHistograms::loadStarted()
141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
142d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_loadStartTime)
143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_loadStartTime = currentTimeMS();
144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RemoteFontFaceSource::FontLoadHistograms::fallbackFontPainted()
147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!m_fallbackPaintTime)
149d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_fallbackPaintTime = currentTimeMS();
150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime(const FontResource* font)
153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_fallbackPaintTime <= 0)
155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    int duration = static_cast<int>(currentTimeMS() - m_fallbackPaintTime);
157d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    blink::Platform::current()->histogramCustomCounts("WebFont.BlankTextShownTime", duration, 0, 10000, 50);
158d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_fallbackPaintTime = -1;
159d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
160d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
161d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void RemoteFontFaceSource::FontLoadHistograms::recordRemoteFont(const FontResource* font)
162d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_loadStartTime > 0 && font && !font->isLoading()) {
164d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        int duration = static_cast<int>(currentTimeMS() - m_loadStartTime);
165d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        blink::Platform::current()->histogramCustomCounts(histogramName(font), duration, 0, 10000, 50);
166d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_loadStartTime = -1;
167d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        enum { Miss, Hit, DataUrl, CacheHitEnumMax };
169d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        int histogramValue = font->url().protocolIsData() ? DataUrl
170d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            : font->response().wasCached() ? Hit
171d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            : Miss;
172d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        blink::Platform::current()->histogramEnumeration("WebFont.CacheHit", histogramValue, CacheHitEnumMax);
173197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
174197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        enum { CORSFail, CORSSuccess, CORSEnumMax };
175197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        int corsValue = font->isCORSFailed() ? CORSFail : CORSSuccess;
176197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        blink::Platform::current()->histogramEnumeration("WebFont.CORSSuccess", corsValue, CORSEnumMax);
177d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
179d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)const char* RemoteFontFaceSource::FontLoadHistograms::histogramName(const FontResource* font)
181d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (font->errorOccurred())
183d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return "WebFont.DownloadTime.LoadError";
184d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
185d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    unsigned size = font->encodedSize();
186d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (size < 10 * 1024)
187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return "WebFont.DownloadTime.0.Under10KB";
188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (size < 50 * 1024)
189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return "WebFont.DownloadTime.1.10KBTo50KB";
190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (size < 100 * 1024)
191d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return "WebFont.DownloadTime.2.50KBTo100KB";
192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (size < 1024 * 1024)
193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return "WebFont.DownloadTime.3.100KBTo1MB";
194d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return "WebFont.DownloadTime.4.Over1MB";
195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
196d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
198