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