Changeset 196322 in webkit
- Timestamp:
- Feb 9, 2016 11:50:05 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r196313 r196322 1 2016-02-09 Myles C. Maxfield <mmaxfield@apple.com> 2 3 Decouple font creation from font loading 4 https://bugs.webkit.org/show_bug.cgi?id=153414 5 6 Reviewed by Darin Adler. 7 8 Previously, CSSFontFaceSource never triggered a font download until that font was actually used. This means 9 that the function which triggers the download also has the goal of returning a font to use. However, 10 the CSS Font Loading JavaScript API requires being able to trigger a font download without this extra font 11 creation overhead. 12 13 In addition, this patch adds an explicit (and enforced) state transition diagram. The diagram looks like 14 this: 15 => Success 16 // 17 Pending => Loading 18 \\ 19 => Failure 20 21 Therefore, the API for CSSFontFaceSource has changed to expose the concept of these new states. This means 22 that its user (CSSSegmentedFontFaceSource) has been updated to handle each possible state that its constituent 23 CSSFontFaceSources may be in. 24 25 No new tests because there is no behavior change. 26 27 * css/CSSFontFace.cpp: 28 (WebCore::CSSFontFace::allSourcesFailed): Renamed to make the name clearer. 29 (WebCore::CSSFontFace::addedToSegmentedFontFace): Use references instead of pointers. 30 (WebCore::CSSFontFace::removedFromSegmentedFontFace): Ditto. 31 (WebCore::CSSFontFace::adoptSource): Renamed to make the name clearer. 32 (WebCore::CSSFontFace::fontLoaded): Use references instead of pointers. Also, remove old dead code. 33 (WebCore::CSSFontFace::font): Adapt to the new API of CSSFontFaceSource. 34 (WebCore::CSSFontFace::isValid): Deleted. 35 (WebCore::CSSFontFace::addSource): Deleted. 36 (WebCore::CSSFontFace::notifyFontLoader): Deleted. Old dead code. 37 (WebCore::CSSFontFace::notifyLoadingDone): Deleted. Old dead code. 38 * css/CSSFontFace.h: 39 (WebCore::CSSFontFace::create): Remove old dead code. 40 (WebCore::CSSFontFace::CSSFontFace): Use references instead of pointers. 41 (WebCore::CSSFontFace::loadState): Deleted. Remove old dead code. 42 * css/CSSFontFaceSource.cpp: 43 (WebCore::CSSFontFaceSource::setStatus): Enforce state transitions. 44 (WebCore::CSSFontFaceSource::CSSFontFaceSource): Explicitly handle new state transitions. 45 (WebCore::CSSFontFaceSource::fontLoaded): Update for new states. 46 (WebCore::CSSFontFaceSource::load): Pulled out code from font(). 47 (WebCore::CSSFontFaceSource::font): Moved code into load(). 48 (WebCore::CSSFontFaceSource::isValid): Deleted. 49 (WebCore::CSSFontFaceSource::isDecodeError): Deleted. 50 (WebCore::CSSFontFaceSource::ensureFontData): Deleted. 51 * css/CSSFontFaceSource.h: Much cleaner API. 52 * css/CSSFontSelector.cpp: 53 (WebCore::createFontFace): Migrate to references instead of pointers. This requires a little 54 reorganization. 55 (WebCore::registerLocalFontFacesForFamily): Update to new CSSFontFaceSource API. 56 (WebCore::CSSFontSelector::addFontFaceRule): Ditto. 57 (WebCore::CSSFontSelector::getFontFace): Ditto. 58 * css/CSSSegmentedFontFace.cpp: 59 (WebCore::CSSSegmentedFontFace::CSSSegmentedFontFace): Migrate to references instead of pointers. 60 (WebCore::CSSSegmentedFontFace::~CSSSegmentedFontFace): Ditto. 61 (WebCore::CSSSegmentedFontFace::fontLoaded): Remove old dead code. 62 (WebCore::CSSSegmentedFontFace::appendFontFace): Cleanup. 63 (WebCore::CSSSegmentedFontFace::fontRanges): Adopt to new API. 64 (WebCore::CSSSegmentedFontFace::pruneTable): Deleted. 65 (WebCore::CSSSegmentedFontFace::isLoading): Deleted. Old dead code. 66 (WebCore::CSSSegmentedFontFace::checkFont): Deleted. Ditto. 67 (WebCore::CSSSegmentedFontFace::loadFont): Deleted. Ditto. 68 * css/CSSSegmentedFontFace.h: 69 (WebCore::CSSSegmentedFontFace::create): Migrate to references instead of pointers. 70 (WebCore::CSSSegmentedFontFace::fontSelector): Ditto. 71 (WebCore::CSSSegmentedFontFace::LoadFontCallback::~LoadFontCallback): Deleted. 72 * loader/cache/CachedFont.cpp: 73 (WebCore::CachedFont::didAddClient): Migrate to references instead of pointers. 74 (WebCore::CachedFont::checkNotify): Ditto. 75 * loader/cache/CachedFontClient.h: 76 (WebCore::CachedFontClient::fontLoaded): Ditto. 77 1 78 2016-02-09 Brady Eidson <beidson@apple.com> 2 79 -
trunk/Source/WebCore/css/CSSFontFace.cpp
r194923 r196322 38 38 namespace WebCore { 39 39 40 bool CSSFontFace:: isValid() const40 bool CSSFontFace::allSourcesFailed() const 41 41 { 42 size_t size = m_sources.size(); 43 for (size_t i = 0; i < size; i++) { 44 if (m_sources[i]->isValid()) 45 return true; 42 for (auto& source : m_sources) { 43 if (source->status() != CSSFontFaceSource::Status::Failure) 44 return false; 46 45 } 47 return false;46 return true; 48 47 } 49 48 50 void CSSFontFace::addedToSegmentedFontFace(CSSSegmentedFontFace *segmentedFontFace)49 void CSSFontFace::addedToSegmentedFontFace(CSSSegmentedFontFace& segmentedFontFace) 51 50 { 52 m_segmentedFontFaces.add( segmentedFontFace);51 m_segmentedFontFaces.add(&segmentedFontFace); 53 52 } 54 53 55 void CSSFontFace::removedFromSegmentedFontFace(CSSSegmentedFontFace *segmentedFontFace)54 void CSSFontFace::removedFromSegmentedFontFace(CSSSegmentedFontFace& segmentedFontFace) 56 55 { 57 m_segmentedFontFaces.remove( segmentedFontFace);56 m_segmentedFontFaces.remove(&segmentedFontFace); 58 57 } 59 58 60 void CSSFontFace::ad dSource(std::unique_ptr<CSSFontFaceSource>source)59 void CSSFontFace::adoptSource(std::unique_ptr<CSSFontFaceSource>&& source) 61 60 { 62 source->setFontFace(this);63 61 m_sources.append(WTFMove(source)); 64 62 } 65 63 66 void CSSFontFace::fontLoaded(CSSFontFaceSource * source)64 void CSSFontFace::fontLoaded(CSSFontFaceSource&) 67 65 { 68 if (source != m_activeSource)69 return;70 71 66 // FIXME: Can we assert that m_segmentedFontFaces is not empty? That may 72 67 // require stopping in-progress font loading when the last … … 75 70 return; 76 71 77 // Use one of the CSSSegmentedFontFaces' font selector. They all have 78 // the same font selector, so it's wasteful to store it in the CSSFontFace. 79 CSSFontSelector* fontSelector = (*m_segmentedFontFaces.begin())->fontSelector(); 80 fontSelector->fontLoaded(); 81 82 #if ENABLE(FONT_LOAD_EVENTS) 83 if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading) { 84 if (source->ensureFontData()) 85 notifyFontLoader(Loaded); 86 else if (!isValid()) 87 notifyFontLoader(Error); 88 } 89 #endif 72 (*m_segmentedFontFaces.begin())->fontSelector().fontLoaded(); 90 73 91 74 for (auto* face : m_segmentedFontFaces) 92 face->fontLoaded(this); 93 94 #if ENABLE(FONT_LOAD_EVENTS) 95 if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled()) 96 notifyLoadingDone(); 97 #endif 75 face->fontLoaded(*this); 98 76 } 99 77 100 78 RefPtr<Font> CSSFontFace::font(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic) 101 79 { 102 m_activeSource = 0; 103 if (!isValid()) 104 return 0; 80 if (allSourcesFailed()) 81 return nullptr; 105 82 106 83 ASSERT(!m_segmentedFontFaces.isEmpty()); 107 CSSFontSelector *fontSelector = (*m_segmentedFontFaces.begin())->fontSelector();84 CSSFontSelector& fontSelector = (*m_segmentedFontFaces.begin())->fontSelector(); 108 85 109 #if ENABLE(FONT_LOAD_EVENTS) 110 if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == NotLoaded) 111 notifyFontLoader(Loading); 112 #endif 86 for (auto& source : m_sources) { 87 if (source->status() == CSSFontFaceSource::Status::Pending) 88 source->load(fontSelector); 113 89 114 size_t size = m_sources.size(); 115 for (size_t i = 0; i < size; ++i) { 116 if (RefPtr<Font> result = m_sources[i]->font(fontDescription, syntheticBold, syntheticItalic, fontSelector, m_featureSettings, m_variantSettings)) { 117 m_activeSource = m_sources[i].get(); 118 #if ENABLE(FONT_LOAD_EVENTS) 119 if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading && m_sources[i]->isLoaded()) { 120 notifyFontLoader(Loaded); 121 notifyLoadingDone(); 122 } 123 #endif 124 return result.release(); 90 switch (source->status()) { 91 case CSSFontFaceSource::Status::Pending: 92 ASSERT_NOT_REACHED(); 93 break; 94 case CSSFontFaceSource::Status::Loading: 95 return Font::create(FontCache::singleton().lastResortFallbackFont(fontDescription)->platformData(), true, true); 96 case CSSFontFaceSource::Status::Success: 97 if (RefPtr<Font> result = source->font(fontDescription, syntheticBold, syntheticItalic, m_featureSettings, m_variantSettings)) 98 return WTFMove(result); 99 break; 100 case CSSFontFaceSource::Status::Failure: 101 break; 125 102 } 126 103 } 127 104 128 #if ENABLE(FONT_LOAD_EVENTS)129 if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && m_loadState == Loading) {130 notifyFontLoader(Error);131 notifyLoadingDone();132 }133 #endif134 105 return nullptr; 135 106 } 136 137 #if ENABLE(FONT_LOAD_EVENTS)138 void CSSFontFace::notifyFontLoader(LoadState newState)139 {140 m_loadState = newState;141 142 Document* document = (*m_segmentedFontFaces.begin())->fontSelector()->document();143 if (!document)144 return;145 146 switch (newState) {147 case Loading:148 document->fonts()->beginFontLoading(m_rule.get());149 break;150 case Loaded:151 document->fonts()->fontLoaded(m_rule.get());152 break;153 case Error:154 document->fonts()->loadError(m_rule.get(), m_activeSource);155 break;156 default:157 break;158 }159 }160 161 void CSSFontFace::notifyLoadingDone()162 {163 Document* document = (*m_segmentedFontFaces.begin())->fontSelector()->document();164 if (document)165 document->fonts()->loadingDone();166 }167 #endif168 107 169 108 #if ENABLE(SVG_FONTS) -
trunk/Source/WebCore/css/CSSFontFace.h
r194923 r196322 46 46 class CSSFontFace : public RefCounted<CSSFontFace> { 47 47 public: 48 static Ref<CSSFontFace> create(FontTraitsMask traitsMask, RefPtr<CSSFontFaceRule>&& rule, bool isLocalFallback = false) { return adoptRef(*new CSSFontFace(traitsMask, WTFMove(rule), isLocalFallback)); }48 static Ref<CSSFontFace> create(FontTraitsMask traitsMask, bool isLocalFallback = false) { return adoptRef(*new CSSFontFace(traitsMask, isLocalFallback)); } 49 49 50 50 FontTraitsMask traitsMask() const { return m_traitsMask; } … … 73 73 void setVariantEastAsianRuby(FontVariantEastAsianRuby ruby) { m_variantSettings.eastAsianRuby = ruby; } 74 74 75 void addedToSegmentedFontFace(CSSSegmentedFontFace *);76 void removedFromSegmentedFontFace(CSSSegmentedFontFace *);75 void addedToSegmentedFontFace(CSSSegmentedFontFace&); 76 void removedFromSegmentedFontFace(CSSSegmentedFontFace&); 77 77 78 bool isValid() const;78 bool allSourcesFailed() const; 79 79 80 80 bool isLocalFallback() const { return m_isLocalFallback; } 81 81 82 void ad dSource(std::unique_ptr<CSSFontFaceSource>);82 void adoptSource(std::unique_ptr<CSSFontFaceSource>&&); 83 83 84 void fontLoaded(CSSFontFaceSource *);84 void fontLoaded(CSSFontFaceSource&); 85 85 86 86 RefPtr<Font> font(const FontDescription&, bool syntheticBold, bool syntheticItalic); … … 105 105 #endif 106 106 107 #if ENABLE(FONT_LOAD_EVENTS)108 enum LoadState { NotLoaded, Loading, Loaded, Error };109 LoadState loadState() const { return m_loadState; }110 #endif111 112 107 private: 113 CSSFontFace(FontTraitsMask traitsMask, RefPtr<CSSFontFaceRule>&& rule,bool isLocalFallback)108 CSSFontFace(FontTraitsMask traitsMask, bool isLocalFallback) 114 109 : m_traitsMask(traitsMask) 115 , m_activeSource(0)116 110 , m_isLocalFallback(isLocalFallback) 117 #if ENABLE(FONT_LOAD_EVENTS)118 , m_loadState(isLocalFallback ? Loaded : NotLoaded)119 , m_rule(rule)120 #endif121 111 { 122 UNUSED_PARAM(rule);123 112 } 124 113 … … 129 118 FontVariantSettings m_variantSettings; 130 119 Vector<std::unique_ptr<CSSFontFaceSource>> m_sources; 131 CSSFontFaceSource* m_activeSource;132 120 bool m_isLocalFallback; 133 #if ENABLE(FONT_LOAD_EVENTS)134 LoadState m_loadState;135 RefPtr<CSSFontFaceRule> m_rule;136 void notifyFontLoader(LoadState);137 void notifyLoadingDone();138 #endif139 121 }; 140 122 -
trunk/Source/WebCore/css/CSSFontFaceSource.cpp
r195567 r196322 54 54 namespace WebCore { 55 55 56 CSSFontFaceSource::CSSFontFaceSource(const String& str, CachedFont* font) 57 : m_string(str) 56 inline void CSSFontFaceSource::setStatus(Status newStatus) 57 { 58 switch (newStatus) { 59 case Status::Pending: 60 ASSERT_NOT_REACHED(); 61 break; 62 case Status::Loading: 63 ASSERT(status() == Status::Pending); 64 break; 65 case Status::Success: 66 ASSERT(status() == Status::Loading); 67 break; 68 case Status::Failure: 69 ASSERT(status() == Status::Loading); 70 break; 71 } 72 m_status = newStatus; 73 } 74 75 CSSFontFaceSource::CSSFontFaceSource(CSSFontFace& owner, const String& familyNameOrURI, CachedFont* font, SVGFontFaceElement* fontFace) 76 : m_familyNameOrURI(familyNameOrURI) 58 77 , m_font(font) 59 , m_face(0) 78 , m_face(owner) 79 , m_svgFontFaceElement(fontFace) 60 80 { 81 // This may synchronously call fontLoaded(). 61 82 if (m_font) 62 83 m_font->addClient(this); 84 85 if (status() == Status::Pending && (!m_font || m_font->isLoaded())) { 86 setStatus(Status::Loading); 87 if (m_font && m_font->errorOccurred()) 88 setStatus(Status::Failure); 89 else 90 setStatus(Status::Success); 91 } 63 92 } 64 93 … … 69 98 } 70 99 71 bool CSSFontFaceSource::isValid() const 100 void CSSFontFaceSource::fontLoaded(CachedFont& loadedFont) 72 101 { 73 if (m_font) 74 return !m_font->errorOccurred(); 75 return true; 102 ASSERT_UNUSED(loadedFont, &loadedFont == m_font.get()); 103 104 // If the font is in the cache, this will be synchronously called from CachedFont::addClient(). 105 if (m_status == Status::Pending) 106 setStatus(Status::Loading); 107 108 if (m_font->errorOccurred()) 109 setStatus(Status::Failure); 110 else 111 setStatus(Status::Success); 112 m_face.fontLoaded(*this); 76 113 } 77 114 78 void CSSFontFaceSource:: fontLoaded(CachedFont*)115 void CSSFontFaceSource::load(CSSFontSelector& fontSelector) 79 116 { 80 if (m_face) 81 m_face->fontLoaded(this); 117 setStatus(Status::Loading); 118 119 fontSelector.beginLoadingFontSoon(m_font.get()); 82 120 } 83 121 84 RefPtr<Font> CSSFontFaceSource::font(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, CSSFontSelector* fontSelector,const FontFeatureSettings& fontFaceFeatures, const FontVariantSettings& fontFaceVariantSettings)122 RefPtr<Font> CSSFontFaceSource::font(const FontDescription& fontDescription, bool syntheticBold, bool syntheticItalic, const FontFeatureSettings& fontFaceFeatures, const FontVariantSettings& fontFaceVariantSettings) 85 123 { 86 // If the font hasn't loaded or an error occurred, then we've got nothing. 87 if (!isValid()) 124 ASSERT(status() == Status::Success); 125 126 SVGFontFaceElement* fontFaceElement = nullptr; 127 #if ENABLE(SVG_FONTS) 128 fontFaceElement = m_svgFontFaceElement.get(); 129 #endif 130 131 if (!m_font && !fontFaceElement) { 132 // We're local. Just return a Font from the normal cache. 133 // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter. 134 return FontCache::singleton().fontForFamily(fontDescription, m_familyNameOrURI, true); 135 } 136 137 if (m_font) { 138 if (!m_font->ensureCustomFontData(m_familyNameOrURI)) 139 return nullptr; 140 141 return m_font->createFont(fontDescription, m_familyNameOrURI, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings); 142 } 143 144 // In-Document SVG Fonts 145 if (!fontFaceElement) 88 146 return nullptr; 89 147 90 if (!m_font91 148 #if ENABLE(SVG_FONTS) 92 && !m_svgFontFaceElement 149 #if ENABLE(SVG_OTF_CONVERTER) 150 if (!m_svgFontFaceElement->parentNode() || !is<SVGFontElement>(m_svgFontFaceElement->parentNode())) 151 return nullptr; 152 SVGFontElement& fontElement = downcast<SVGFontElement>(*m_svgFontFaceElement->parentNode()); 153 // FIXME: Re-run this when script modifies the element or any of its descendents 154 // FIXME: We might have already converted this font. Make existing conversions discoverable. 155 if (auto otfFont = convertSVGToOTFFont(fontElement)) 156 m_generatedOTFBuffer = SharedBuffer::adoptVector(otfFont.value()); 157 if (!m_generatedOTFBuffer) 158 return nullptr; 159 m_inDocumentCustomPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer); 160 if (!m_inDocumentCustomPlatformData) 161 return nullptr; 162 return Font::create(m_inDocumentCustomPlatformData->fontPlatformData(fontDescription, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings), true, false); 163 #else 164 return Font::create(std::make_unique<SVGFontData>(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic); 93 165 #endif 94 ) { 95 // We're local. Just return a Font from the normal cache. 96 // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter. 97 return FontCache::singleton().fontForFamily(fontDescription, m_string, true); 98 } 166 #endif 99 167 100 if (!m_font || m_font->isLoaded()) { 101 if (m_font) { 102 if (!m_font->ensureCustomFontData(m_string)) 103 return nullptr; 104 105 return m_font->createFont(fontDescription, m_string, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings); 106 } else { 107 #if ENABLE(SVG_FONTS) 108 // In-Document SVG Fonts 109 if (m_svgFontFaceElement) { 110 #if ENABLE(SVG_OTF_CONVERTER) 111 if (!m_svgFontFaceElement->parentNode() || !is<SVGFontElement>(m_svgFontFaceElement->parentNode())) 112 return nullptr; 113 SVGFontElement& fontElement = downcast<SVGFontElement>(*m_svgFontFaceElement->parentNode()); 114 // FIXME: Re-run this when script modifies the element or any of its descendents 115 // FIXME: We might have already converted this font. Make existing conversions discoverable. 116 if (auto otfFont = convertSVGToOTFFont(fontElement)) 117 m_generatedOTFBuffer = SharedBuffer::adoptVector(otfFont.value()); 118 if (!m_generatedOTFBuffer) 119 return nullptr; 120 auto customPlatformData = createFontCustomPlatformData(*m_generatedOTFBuffer); 121 if (!customPlatformData) 122 return nullptr; 123 return Font::create(customPlatformData->fontPlatformData(fontDescription, syntheticBold, syntheticItalic, fontFaceFeatures, fontFaceVariantSettings), true, false); 124 #else 125 return Font::create(std::make_unique<SVGFontData>(m_svgFontFaceElement.get()), fontDescription.computedPixelSize(), syntheticBold, syntheticItalic); 126 #endif 127 } 128 #endif 129 return nullptr; 130 } 131 } else { 132 // Kick off the load. Do it soon rather than now, because we may be in the middle of layout, 133 // and the loader may invoke arbitrary delegate or event handler code. 134 fontSelector->beginLoadingFontSoon(m_font.get()); 135 136 return Font::create(FontCache::singleton().lastResortFallbackFont(fontDescription)->platformData(), true, true); 137 } 168 ASSERT_NOT_REACHED(); 169 return nullptr; 138 170 } 139 171 … … 145 177 #endif 146 178 147 #if ENABLE(FONT_LOAD_EVENTS)148 bool CSSFontFaceSource::isDecodeError() const149 {150 if (m_font)151 return m_font->status() == CachedResource::DecodeError;152 return false;153 179 } 154 155 bool CSSFontFaceSource::ensureFontData()156 {157 if (!m_font)158 return false;159 return m_font->ensureCustomFontData(m_hasExternalSVGFont, m_string);160 }161 #endif162 163 } -
trunk/Source/WebCore/css/CSSFontFaceSource.h
r195567 r196322 29 29 #include "CachedFontClient.h" 30 30 #include "CachedResourceHandle.h" 31 #include "SharedBuffer.h"32 #if ENABLE(SVG_FONTS)33 #include "SVGFontElement.h"34 #include "SVGFontFaceElement.h"35 #endif36 #include "Timer.h"37 31 #include <wtf/text/AtomicString.h> 38 32 … … 42 36 class CSSFontSelector; 43 37 class Font; 38 struct FontCustomPlatformData; 44 39 class FontDescription; 45 40 class FontFeatureSettings; 46 41 struct FontVariantSettings; 42 class SVGFontFaceElement; 43 class SharedBuffer; 47 44 48 45 class CSSFontFaceSource final : public CachedFontClient { 49 46 WTF_MAKE_FAST_ALLOCATED; 50 47 public: 51 CSSFontFaceSource(const String&, CachedFont* = nullptr); 48 49 // => Succeeded 50 // // 51 // Pending => Loading 52 // \\. 53 // => Failed 54 enum class Status { 55 Pending, 56 Loading, 57 Success, 58 Failure 59 }; 60 61 CSSFontFaceSource(CSSFontFace& owner, const String& familyNameOrURI, CachedFont* = nullptr, SVGFontFaceElement* = nullptr); 52 62 virtual ~CSSFontFaceSource(); 53 63 54 bool isValid() const;64 Status status() const { return m_status; } 55 65 56 const AtomicString& string() const { return m_string; }66 const AtomicString& familyNameOrURI() const { return m_familyNameOrURI; } 57 67 58 void setFontFace(CSSFontFace* face) { m_face = face; } 59 60 virtual void fontLoaded(CachedFont*) override; 61 62 RefPtr<Font> font(const FontDescription&, bool syntheticBold, bool syntheticItalic, CSSFontSelector*, const FontFeatureSettings&, const FontVariantSettings&); 63 64 void pruneTable(); 68 void load(CSSFontSelector&); 69 RefPtr<Font> font(const FontDescription&, bool syntheticBold, bool syntheticItalic, const FontFeatureSettings&, const FontVariantSettings&); 65 70 66 71 #if ENABLE(SVG_FONTS) 67 SVGFontFaceElement* svgFontFaceElement() const { return m_svgFontFaceElement.get(); }68 void setSVGFontFaceElement(PassRefPtr<SVGFontFaceElement> element) { m_svgFontFaceElement = element; }69 72 bool isSVGFontFaceSource() const; 70 73 #endif 71 74 72 #if ENABLE(FONT_LOAD_EVENTS) 73 bool isDecodeError() const; 74 bool ensureFontData(); 75 #endif 75 private: 76 virtual void fontLoaded(CachedFont&) override; 76 77 77 private: 78 void startLoadingTimerFired(); 78 void setStatus(Status); 79 79 80 AtomicString m_ string; // URI for remote, built-in font name for local.80 AtomicString m_familyNameOrURI; // URI for remote, built-in font name for local. 81 81 CachedResourceHandle<CachedFont> m_font; // For remote fonts, a pointer to our cached resource. 82 CSSFontFace *m_face; // Our owning font face.82 CSSFontFace& m_face; // Our owning font face. 83 83 84 84 #if ENABLE(SVG_OTF_CONVERTER) … … 88 88 #if ENABLE(SVG_FONTS) || ENABLE(SVG_OTF_CONVERTER) 89 89 RefPtr<SVGFontFaceElement> m_svgFontFaceElement; 90 std::unique_ptr<FontCustomPlatformData> m_inDocumentCustomPlatformData; 90 91 #endif 92 93 Status m_status { Status::Pending }; 91 94 }; 92 95 -
trunk/Source/WebCore/css/CSSFontSelector.cpp
r195928 r196322 153 153 } 154 154 155 static Ref<CSSFontFace> createFontFace(CSSValueList& srcList, FontTraitsMask traitsMask, Document* document, const StyleRuleFontFace& fontFaceRule, bool isInitiatingElementInUserAgentShadowTree) 156 { 157 RefPtr<CSSFontFaceRule> rule; 158 #if ENABLE(FONT_LOAD_EVENTS) 159 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=112116 - This CSSFontFaceRule has no parent. 160 if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled()) 161 rule = static_pointer_cast<CSSFontFaceRule>(fontFaceRule.createCSSOMWrapper()); 162 #else 163 UNUSED_PARAM(fontFaceRule); 164 #endif 165 Ref<CSSFontFace> fontFace = CSSFontFace::create(traitsMask, WTFMove(rule)); 166 167 int srcLength = srcList.length(); 168 169 bool foundSVGFont = false; 170 171 for (int i = 0; i < srcLength; i++) { 155 static Ref<CSSFontFace> createFontFace(CSSValueList& srcList, FontTraitsMask traitsMask, Document* document, bool isInitiatingElementInUserAgentShadowTree) 156 { 157 Ref<CSSFontFace> fontFace = CSSFontFace::create(traitsMask); 158 159 for (auto& src : srcList) { 172 160 // An item in the list either specifies a string (local font name) or a URL (remote font to download). 173 CSSFontFaceSrcValue& item = downcast<CSSFontFaceSrcValue>( *srcList.itemWithoutBoundsCheck(i));161 CSSFontFaceSrcValue& item = downcast<CSSFontFaceSrcValue>(src.get()); 174 162 std::unique_ptr<CSSFontFaceSource> source; 163 SVGFontFaceElement* fontFaceElement = nullptr; 164 bool foundSVGFont = false; 175 165 176 166 #if ENABLE(SVG_FONTS) 177 167 foundSVGFont = item.isSVGFontFaceSrc() || item.svgFontFaceElement(); 168 fontFaceElement = item.svgFontFaceElement(); 178 169 #endif 179 170 if (!item.isLocal()) { … … 182 173 if (allowDownloading && item.isSupportedFormat() && document) { 183 174 if (CachedFont* cachedFont = item.cachedFont(document, foundSVGFont, isInitiatingElementInUserAgentShadowTree)) 184 source = std::make_unique<CSSFontFaceSource>( item.resource(), cachedFont);175 source = std::make_unique<CSSFontFaceSource>(fontFace.get(), item.resource(), cachedFont); 185 176 } 186 177 } else 187 source = std::make_unique<CSSFontFaceSource>(item.resource()); 188 189 if (source) { 190 #if ENABLE(SVG_FONTS) 191 source->setSVGFontFaceElement(item.svgFontFaceElement()); 192 #endif 193 fontFace->addSource(WTFMove(source)); 194 } 178 source = std::make_unique<CSSFontFaceSource>(fontFace.get(), item.resource(), nullptr, fontFaceElement); 179 180 if (source) 181 fontFace->adoptSource(WTFMove(source)); 195 182 } 196 183 … … 235 222 Vector<Ref<CSSFontFace>> faces = { }; 236 223 for (auto mask : traitsMasks) { 237 Ref<CSSFontFace> face = CSSFontFace::create(mask, nullptr,true);238 face->ad dSource(std::make_unique<CSSFontFaceSource>(familyName));239 ASSERT( face->isValid());224 Ref<CSSFontFace> face = CSSFontFace::create(mask, true); 225 face->adoptSource(std::make_unique<CSSFontFaceSource>(face.get(), familyName)); 226 ASSERT(!face->allSourcesFailed()); 240 227 faces.append(WTFMove(face)); 241 228 } … … 274 261 auto traitsMask = computedTraitsMask.value(); 275 262 276 Ref<CSSFontFace> fontFace = createFontFace(srcList, traitsMask, m_document, fontFaceRule,isInitiatingElementInUserAgentShadowTree);277 if ( !fontFace->isValid())263 Ref<CSSFontFace> fontFace = createFontFace(srcList, traitsMask, m_document, isInitiatingElementInUserAgentShadowTree); 264 if (fontFace->allSourcesFailed()) 278 265 return; 279 266 … … 487 474 return face.get(); 488 475 489 face = CSSSegmentedFontFace::create( this);476 face = CSSSegmentedFontFace::create(*this); 490 477 491 478 Vector<std::reference_wrapper<CSSFontFace>, 32> candidateFontFaces; -
trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp
r194923 r196322 38 38 namespace WebCore { 39 39 40 CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector *fontSelector)40 CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector& fontSelector) 41 41 : m_fontSelector(fontSelector) 42 42 { … … 45 45 CSSSegmentedFontFace::~CSSSegmentedFontFace() 46 46 { 47 pruneTable();48 47 for (auto& face : m_fontFaces) 49 face->removedFromSegmentedFontFace( this);48 face->removedFromSegmentedFontFace(*this); 50 49 } 51 50 52 void CSSSegmentedFontFace:: pruneTable()51 void CSSSegmentedFontFace::fontLoaded(CSSFontFace&) 53 52 { 54 m_descriptionToRangesMap.clear(); 55 } 56 57 void CSSSegmentedFontFace::fontLoaded(CSSFontFace*) 58 { 59 pruneTable(); 60 61 #if ENABLE(FONT_LOAD_EVENTS) 62 if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled() && !isLoading()) { 63 Vector<RefPtr<LoadFontCallback>> callbacks; 64 m_callbacks.swap(callbacks); 65 for (size_t index = 0; index < callbacks.size(); ++index) { 66 if (checkFont()) 67 callbacks[index]->notifyLoaded(); 68 else 69 callbacks[index]->notifyError(); 70 } 71 } 72 #endif 53 m_cache.clear(); 73 54 } 74 55 75 56 void CSSSegmentedFontFace::appendFontFace(Ref<CSSFontFace>&& fontFace) 76 57 { 77 pruneTable();78 fontFace->addedToSegmentedFontFace( this);58 m_cache.clear(); 59 fontFace->addedToSegmentedFontFace(*this); 79 60 m_fontFaces.append(WTFMove(fontFace)); 80 61 } … … 101 82 FontTraitsMask desiredTraitsMask = fontDescription.traitsMask(); 102 83 103 auto addResult = m_ descriptionToRangesMap.add(FontDescriptionKey(fontDescription), FontRanges());84 auto addResult = m_cache.add(FontDescriptionKey(fontDescription), FontRanges()); 104 85 auto& fontRanges = addResult.iterator->value; 105 86 106 87 if (addResult.isNewEntry) { 107 88 for (auto& face : m_fontFaces) { 108 if ( !face->isValid())89 if (face->allSourcesFailed()) 109 90 continue; 110 91 … … 120 101 } 121 102 122 #if ENABLE(FONT_LOAD_EVENTS)123 bool CSSSegmentedFontFace::isLoading() const124 {125 for (auto& face : m_fontFaces) {126 if (face->loadState() == CSSFontFace::Loading)127 return true;128 }129 return false;130 103 } 131 132 bool CSSSegmentedFontFace::checkFont() const133 {134 for (auto& face : m_fontFaces) {135 if (face->loadState() != CSSFontFace::Loaded)136 return false;137 }138 return true;139 }140 141 void CSSSegmentedFontFace::loadFont(const FontDescription& fontDescription, PassRefPtr<LoadFontCallback> callback)142 {143 fontRanges(fontDescription); // Kick off the load.144 145 if (callback) {146 if (isLoading())147 m_callbacks.append(callback);148 else if (checkFont())149 callback->notifyLoaded();150 else151 callback->notifyError();152 }153 }154 #endif155 156 } -
trunk/Source/WebCore/css/CSSSegmentedFontFace.h
r194923 r196322 42 42 class CSSSegmentedFontFace : public RefCounted<CSSSegmentedFontFace> { 43 43 public: 44 static Ref<CSSSegmentedFontFace> create(CSSFontSelector *selector) { return adoptRef(*new CSSSegmentedFontFace(selector)); }44 static Ref<CSSSegmentedFontFace> create(CSSFontSelector& selector) { return adoptRef(*new CSSSegmentedFontFace(selector)); } 45 45 ~CSSSegmentedFontFace(); 46 46 47 CSSFontSelector *fontSelector() const { return m_fontSelector; }47 CSSFontSelector& fontSelector() const { return m_fontSelector; } 48 48 49 void fontLoaded(CSSFontFace *);49 void fontLoaded(CSSFontFace&); 50 50 51 51 void appendFontFace(Ref<CSSFontFace>&&); … … 53 53 FontRanges fontRanges(const FontDescription&); 54 54 55 #if ENABLE(FONT_LOAD_EVENTS) 56 class LoadFontCallback : public RefCounted<LoadFontCallback> { 57 public: 58 virtual ~LoadFontCallback() { } 59 virtual void notifyLoaded() = 0; 60 virtual void notifyError() = 0; 61 }; 55 private: 56 CSSSegmentedFontFace(CSSFontSelector&); 62 57 63 bool checkFont() const; 64 void loadFont(const FontDescription&, PassRefPtr<LoadFontCallback> loadCallback); 65 #endif 66 67 private: 68 CSSSegmentedFontFace(CSSFontSelector*); 69 70 void pruneTable(); 71 #if ENABLE(FONT_LOAD_EVENTS) 72 bool isLoading() const; 73 #endif 74 75 CSSFontSelector* m_fontSelector; 76 HashMap<FontDescriptionKey, FontRanges, FontDescriptionKeyHash, WTF::SimpleClassHashTraits<FontDescriptionKey>> m_descriptionToRangesMap; 58 CSSFontSelector& m_fontSelector; 59 HashMap<FontDescriptionKey, FontRanges, FontDescriptionKeyHash, WTF::SimpleClassHashTraits<FontDescriptionKey>> m_cache; 77 60 Vector<Ref<CSSFontFace>, 1> m_fontFaces; 78 #if ENABLE(FONT_LOAD_EVENTS)79 Vector<RefPtr<LoadFontCallback>> m_callbacks;80 #endif81 61 }; 82 62 -
trunk/Source/WebCore/loader/cache/CachedFont.cpp
r195523 r196322 70 70 } 71 71 72 void CachedFont::didAddClient(CachedResourceClient* c )72 void CachedFont::didAddClient(CachedResourceClient* client) 73 73 { 74 ASSERT(c ->resourceClientType() == CachedFontClient::expectedType());74 ASSERT(client->resourceClientType() == CachedFontClient::expectedType()); 75 75 if (!isLoading()) 76 static_cast<CachedFontClient*>(c )->fontLoaded(this);76 static_cast<CachedFontClient*>(client)->fontLoaded(*this); 77 77 } 78 78 … … 149 149 return; 150 150 151 CachedResourceClientWalker<CachedFontClient> w (m_clients);152 while (CachedFontClient* c = w.next())153 c->fontLoaded(this);151 CachedResourceClientWalker<CachedFontClient> walker(m_clients); 152 while (CachedFontClient* client = walker.next()) 153 client->fontLoaded(*this); 154 154 } 155 155 -
trunk/Source/WebCore/loader/cache/CachedFontClient.h
r162139 r196322 38 38 static CachedResourceClientType expectedType() { return FontType; } 39 39 virtual CachedResourceClientType resourceClientType() const override { return expectedType(); } 40 virtual void fontLoaded(CachedFont *) { }40 virtual void fontLoaded(CachedFont&) { } 41 41 }; 42 42
Note: See TracChangeset
for help on using the changeset viewer.