Document should be a FontSelectorClient.
[WebKit-https.git] / Source / WebCore / css / CSSFontSelector.cpp
index 1150889..638c1c9 100644 (file)
 #include "CSSValueList.h"
 #include "CachedResourceLoader.h"
 #include "Document.h"
 #include "CSSValueList.h"
 #include "CachedResourceLoader.h"
 #include "Document.h"
+#include "Font.h"
 #include "FontCache.h"
 #include "Frame.h"
 #include "FrameLoader.h"
 #include "SVGFontFaceElement.h"
 #include "SVGNames.h"
 #include "Settings.h"
 #include "FontCache.h"
 #include "Frame.h"
 #include "FrameLoader.h"
 #include "SVGFontFaceElement.h"
 #include "SVGNames.h"
 #include "Settings.h"
-#include "SimpleFontData.h"
 #include "StyleProperties.h"
 #include "StyleResolver.h"
 #include "StyleRule.h"
 #include "StyleProperties.h"
 #include "StyleResolver.h"
 #include "StyleRule.h"
@@ -58,12 +58,11 @@ namespace WebCore {
 
 static unsigned fontSelectorId;
 
 
 static unsigned fontSelectorId;
 
-CSSFontSelector::CSSFontSelector(Document* document)
-    : m_document(document)
-    , m_beginLoadingTimer(this, &CSSFontSelector::beginLoadTimerFired)
+CSSFontSelector::CSSFontSelector(Document& document)
+    : m_document(&document)
+    , m_beginLoadingTimer(*this, &CSSFontSelector::beginLoadTimerFired)
     , m_uniqueId(++fontSelectorId)
     , m_version(0)
     , m_uniqueId(++fontSelectorId)
     , m_version(0)
-    
 {
     // FIXME: An old comment used to say there was no need to hold a reference to m_document
     // because "we are guaranteed to be destroyed before the document". But there does not
 {
     // FIXME: An old comment used to say there was no need to hold a reference to m_document
     // because "we are guaranteed to be destroyed before the document". But there does not
@@ -212,12 +211,12 @@ void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule)
             Settings* settings = m_document ? m_document->frame() ? &m_document->frame()->settings() : 0 : 0;
             bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
             if (allowDownloading && item.isSupportedFormat() && m_document) {
             Settings* settings = m_document ? m_document->frame() ? &m_document->frame()->settings() : 0 : 0;
             bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
             if (allowDownloading && item.isSupportedFormat() && m_document) {
-                CachedFont* cachedFont = item.cachedFont(m_document);
+                CachedFont* cachedFont = item.cachedFont(m_document, foundSVGFont);
                 if (cachedFont) {
                     source = std::make_unique<CSSFontFaceSource>(item.resource(), cachedFont);
 #if ENABLE(SVG_FONTS)
                     if (foundSVGFont)
                 if (cachedFont) {
                     source = std::make_unique<CSSFontFaceSource>(item.resource(), cachedFont);
 #if ENABLE(SVG_FONTS)
                     if (foundSVGFont)
-                        source->setHasExternalSVGFont(true);
+                        source->setHasExternalSVGFont();
 #endif
                 }
             }
 #endif
                 }
             }
@@ -339,15 +338,6 @@ void CSSFontSelector::dispatchInvalidationCallbacks()
     copyToVector(m_clients, clients);
     for (size_t i = 0; i < clients.size(); ++i)
         clients[i]->fontsNeedUpdate(this);
     copyToVector(m_clients, clients);
     for (size_t i = 0; i < clients.size(); ++i)
         clients[i]->fontsNeedUpdate(this);
-
-    // FIXME: Make Document a FontSelectorClient so that it can simply register for invalidation callbacks.
-    if (!m_document)
-        return;
-    if (StyleResolver* styleResolver = m_document->styleResolverIfExists())
-        styleResolver->invalidateMatchedPropertiesCache();
-    if (m_document->inPageCache() || !m_document->renderView())
-        return;
-    m_document->scheduleForcedStyleRecalc();
 }
 
 void CSSFontSelector::fontLoaded()
 }
 
 void CSSFontSelector::fontLoaded()
@@ -360,35 +350,30 @@ void CSSFontSelector::fontCacheInvalidated()
     dispatchInvalidationCallbacks();
 }
 
     dispatchInvalidationCallbacks();
 }
 
-static PassRefPtr<SimpleFontData> fontDataForGenericFamily(Document* document, const FontDescription& fontDescription, const AtomicString& familyName)
+static const AtomicString& resolveGenericFamily(Document* document, const FontDescription& fontDescription, const AtomicString& familyName)
 {
     if (!document || !document->frame())
 {
     if (!document || !document->frame())
-        return 0;
+        return familyName;
 
     const Settings& settings = document->frame()->settings();
 
 
     const Settings& settings = document->frame()->settings();
 
-    AtomicString genericFamily;
     UScriptCode script = fontDescription.script();
     UScriptCode script = fontDescription.script();
-
     if (familyName == serifFamily)
     if (familyName == serifFamily)
-        genericFamily = settings.serifFontFamily(script);
-    else if (familyName == sansSerifFamily)
-        genericFamily = settings.sansSerifFontFamily(script);
-    else if (familyName == cursiveFamily)
-        genericFamily = settings.cursiveFontFamily(script);
-    else if (familyName == fantasyFamily)
-        genericFamily = settings.fantasyFontFamily(script);
-    else if (familyName == monospaceFamily)
-        genericFamily = settings.fixedFontFamily(script);
-    else if (familyName == pictographFamily)
-        genericFamily = settings.pictographFontFamily(script);
-    else if (familyName == standardFamily)
-        genericFamily = settings.standardFontFamily(script);
-
-    if (!genericFamily.isEmpty())
-        return fontCache().getCachedFontData(fontDescription, genericFamily);
-
-    return nullptr;
+        return settings.serifFontFamily(script);
+    if (familyName == sansSerifFamily)
+        return settings.sansSerifFontFamily(script);
+    if (familyName == cursiveFamily)
+        return settings.cursiveFontFamily(script);
+    if (familyName == fantasyFamily)
+        return settings.fantasyFontFamily(script);
+    if (familyName == monospaceFamily)
+        return settings.fixedFontFamily(script);
+    if (familyName == pictographFamily)
+        return settings.pictographFontFamily(script);
+    if (familyName == standardFamily)
+        return settings.standardFontFamily(script);
+
+    return familyName;
 }
 
 static FontTraitsMask desiredTraitsMaskForComparison;
 }
 
 static FontTraitsMask desiredTraitsMaskForComparison;
@@ -473,28 +458,20 @@ static inline bool compareFontFaces(CSSFontFace* first, CSSFontFace* second)
     return false;
 }
 
     return false;
 }
 
-PassRefPtr<FontData> CSSFontSelector::getFontData(const FontDescription& fontDescription, const AtomicString& familyName)
+FontRanges CSSFontSelector::fontRangesForFamily(const FontDescription& fontDescription, const AtomicString& familyName)
 {
 {
-    if (m_fontFaces.isEmpty()) {
-        if (familyName.startsWith("-webkit-"))
-            return fontDataForGenericFamily(m_document, fontDescription, familyName);
-        if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
-            return fontDataForGenericFamily(m_document, fontDescription, standardFamily);
-        return 0;
-    }
+    // FIXME: The spec (and Firefox) says user specified generic families (sans-serif etc.) should be resolved before the @font-face lookup too.
+    bool resolveGenericFamilyFirst = familyName == standardFamily;
 
 
-    CSSSegmentedFontFace* face = getFontFace(fontDescription, familyName);
-    // If no face was found, then return 0 and let the OS come up with its best match for the name.
+    AtomicString familyForLookup = resolveGenericFamilyFirst ? resolveGenericFamily(m_document, fontDescription, familyName) : familyName;
+    CSSSegmentedFontFace* face = getFontFace(fontDescription, familyForLookup);
     if (!face) {
     if (!face) {
-        // If we were handed a generic family, but there was no match, go ahead and return the correct font based off our
-        // settings.
-        if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
-            return fontDataForGenericFamily(m_document, fontDescription, standardFamily);
-        return fontDataForGenericFamily(m_document, fontDescription, familyName);
+        if (!resolveGenericFamilyFirst)
+            familyForLookup = resolveGenericFamily(m_document, fontDescription, familyName);
+        return FontRanges(fontCache().fontForFamily(fontDescription, familyForLookup));
     }
 
     }
 
-    // We have a face. Ask it for a font data. If it cannot produce one, it will fail, and the OS will take over.
-    return face->getFontData(fontDescription);
+    return face->fontRanges(fontDescription);
 }
 
 CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDescription, const AtomicString& family)
 }
 
 CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDescription, const AtomicString& family)
@@ -587,7 +564,7 @@ void CSSFontSelector::beginLoadingFontSoon(CachedFont* font)
     m_beginLoadingTimer.startOneShot(0);
 }
 
     m_beginLoadingTimer.startOneShot(0);
 }
 
-void CSSFontSelector::beginLoadTimerFired(Timer&)
+void CSSFontSelector::beginLoadTimerFired()
 {
     Vector<CachedResourceHandle<CachedFont>> fontsToBeginLoading;
     fontsToBeginLoading.swap(m_fontsToBeginLoading);
 {
     Vector<CachedResourceHandle<CachedFont>> fontsToBeginLoading;
     fontsToBeginLoading.swap(m_fontsToBeginLoading);
@@ -613,8 +590,6 @@ bool CSSFontSelector::resolvesFamilyFor(const FontDescription& description) cons
 {
     for (unsigned i = 0; i < description.familyCount(); ++i) {
         const AtomicString& familyName = description.familyAt(i);
 {
     for (unsigned i = 0; i < description.familyCount(); ++i) {
         const AtomicString& familyName = description.familyAt(i);
-        if (description.genericFamily() == FontDescription::StandardFamily && !description.isSpecifiedFont())
-            return true;
         if (familyName.isEmpty())
             continue;
         if (m_fontFaces.contains(familyName))
         if (familyName.isEmpty())
             continue;
         if (m_fontFaces.contains(familyName))
@@ -627,7 +602,7 @@ bool CSSFontSelector::resolvesFamilyFor(const FontDescription& description) cons
     return false;
 }
 
     return false;
 }
 
-size_t CSSFontSelector::fallbackFontDataCount()
+size_t CSSFontSelector::fallbackFontCount()
 {
     if (!m_document)
         return 0;
 {
     if (!m_document)
         return 0;
@@ -638,7 +613,7 @@ size_t CSSFontSelector::fallbackFontDataCount()
     return 0;
 }
 
     return 0;
 }
 
-PassRefPtr<FontData> CSSFontSelector::getFallbackFontData(const FontDescription& fontDescription, size_t index)
+PassRefPtr<Font> CSSFontSelector::fallbackFontAt(const FontDescription& fontDescription, size_t index)
 {
     ASSERT_UNUSED(index, !index);
 
 {
     ASSERT_UNUSED(index, !index);
 
@@ -649,7 +624,7 @@ PassRefPtr<FontData> CSSFontSelector::getFallbackFontData(const FontDescription&
     if (!settings || !settings->fontFallbackPrefersPictographs())
         return 0;
 
     if (!settings || !settings->fontFallbackPrefersPictographs())
         return 0;
 
-    return fontCache().getCachedFontData(fontDescription, settings->pictographFontFamily());
+    return fontCache().fontForFamily(fontDescription, settings->pictographFontFamily());
 }
 
 }
 }
 
 }