@font-face related cleanup
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Aug 2015 08:06:00 +0000 (08:06 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Aug 2015 08:06:00 +0000 (08:06 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148355

Reviewed by Darin Adler.

This patch cleans up much of our code related to web fonts. In general, it
migrates to using C++ for-each style loops, uses Ref instead of RefPtr when
things can't be nullptr, migrates to C++ Rvalue-references instead of
PassRefPtr, and refactors CSSFontSelector::addFontFaceRule() to use helper
functions.

No new tests because there is no behavior change.

* css/CSSFontFace.cpp:
(WebCore::CSSFontFace::fontLoaded): Use a C++ for-each loop.
* css/CSSFontFace.h:
(WebCore::CSSFontFace::create): Use C++ Rvalue-references instead of
PassRefPtr.
(WebCore::CSSFontFace::CSSFontFace): Ditto.
* css/CSSFontSelector.cpp:
(WebCore::computeTraitsMask): Migrated a chunk of
CSSFontSelector::addFontFaceRule() into this helper function.
(WebCore::createFontFace): Ditto.
(WebCore::familyNameFromPrimitive): Ditto.
(WebCore::CSSFontSelector::addFontFaceRule): Call the newly-created helper
functions. In addition, migrate to Refs instead of RefPtrs.
(WebCore::compareFontFaces): Migrate to references instead of pointers.
(WebCore::CSSFontSelector::getFontFace): Migrate to Refs instead of
RefPtrs. Also use C++ for-each loops.
* css/CSSFontSelector.h:
* css/CSSSegmentedFontFace.cpp:
(WebCore::CSSSegmentedFontFace::~CSSSegmentedFontFace): Use C++ for-each
loops.
(WebCore::CSSSegmentedFontFace::isValid): Ditto.
(WebCore::CSSSegmentedFontFace::appendFontFace): Migrate to Rvalue-
references instead of PassRefPtr.
* css/CSSSegmentedFontFace.h:
* platform/graphics/FontCache.h:
* platform/graphics/cocoa/FontCacheCoreText.cpp:
(WebCore::FontCache::getTraitsInFamily): Return the result instead of being
passed an out parameter.
* platform/graphics/freetype/FontCacheFreeType.cpp:
(WebCore::FontCache::getTraitsInFamily): Ditto.
* platform/graphics/win/FontCacheWin.cpp:
(WebCore::traitsInFamilyEnumProc): Ditto.
(WebCore::FontCache::getTraitsInFamily): Ditto.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@188853 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WebCore/ChangeLog
Source/WebCore/css/CSSFontFace.cpp
Source/WebCore/css/CSSFontFace.h
Source/WebCore/css/CSSFontSelector.cpp
Source/WebCore/css/CSSFontSelector.h
Source/WebCore/css/CSSSegmentedFontFace.cpp
Source/WebCore/css/CSSSegmentedFontFace.h
Source/WebCore/css/StyleProperties.cpp
Source/WebCore/platform/graphics/FontCache.h
Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp
Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp
Source/WebCore/platform/graphics/win/FontCacheWin.cpp

index d3f4d82..3d4c268 100644 (file)
@@ -1,3 +1,52 @@
+2015-08-24  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        @font-face related cleanup
+        https://bugs.webkit.org/show_bug.cgi?id=148355
+
+        Reviewed by Darin Adler.
+
+        This patch cleans up much of our code related to web fonts. In general, it
+        migrates to using C++ for-each style loops, uses Ref instead of RefPtr when
+        things can't be nullptr, migrates to C++ Rvalue-references instead of
+        PassRefPtr, and refactors CSSFontSelector::addFontFaceRule() to use helper
+        functions.
+
+        No new tests because there is no behavior change.
+
+        * css/CSSFontFace.cpp:
+        (WebCore::CSSFontFace::fontLoaded): Use a C++ for-each loop.
+        * css/CSSFontFace.h:
+        (WebCore::CSSFontFace::create): Use C++ Rvalue-references instead of
+        PassRefPtr.
+        (WebCore::CSSFontFace::CSSFontFace): Ditto.
+        * css/CSSFontSelector.cpp:
+        (WebCore::computeTraitsMask): Migrated a chunk of
+        CSSFontSelector::addFontFaceRule() into this helper function.
+        (WebCore::createFontFace): Ditto.
+        (WebCore::familyNameFromPrimitive): Ditto.
+        (WebCore::CSSFontSelector::addFontFaceRule): Call the newly-created helper
+        functions. In addition, migrate to Refs instead of RefPtrs.
+        (WebCore::compareFontFaces): Migrate to references instead of pointers.
+        (WebCore::CSSFontSelector::getFontFace): Migrate to Refs instead of
+        RefPtrs. Also use C++ for-each loops.
+        * css/CSSFontSelector.h:
+        * css/CSSSegmentedFontFace.cpp:
+        (WebCore::CSSSegmentedFontFace::~CSSSegmentedFontFace): Use C++ for-each
+        loops.
+        (WebCore::CSSSegmentedFontFace::isValid): Ditto.
+        (WebCore::CSSSegmentedFontFace::appendFontFace): Migrate to Rvalue-
+        references instead of PassRefPtr.
+        * css/CSSSegmentedFontFace.h:
+        * platform/graphics/FontCache.h:
+        * platform/graphics/cocoa/FontCacheCoreText.cpp:
+        (WebCore::FontCache::getTraitsInFamily): Return the result instead of being
+        passed an out parameter.
+        * platform/graphics/freetype/FontCacheFreeType.cpp:
+        (WebCore::FontCache::getTraitsInFamily): Ditto.
+        * platform/graphics/win/FontCacheWin.cpp:
+        (WebCore::traitsInFamilyEnumProc): Ditto.
+        (WebCore::FontCache::getTraitsInFamily): Ditto.
+
 2015-08-23  Andy Estes  <aestes@apple.com>
 
         [Content Filtering] REGRESSION (r182356): Provisional URL is incorrect in didReceiveServerRedirectForProvisionalLoadForFrame when Content Filtering is enabled
index f62a5fb..4214acd 100644 (file)
@@ -98,9 +98,8 @@ void CSSFontFace::fontLoaded(CSSFontFaceSource* source)
     }
 #endif
 
-    HashSet<CSSSegmentedFontFace*>::iterator end = m_segmentedFontFaces.end();
-    for (HashSet<CSSSegmentedFontFace*>::iterator it = m_segmentedFontFaces.begin(); it != end; ++it)
-        (*it)->fontLoaded(this);
+    for (auto* face : m_segmentedFontFaces)
+        face->fontLoaded(this);
 
 #if ENABLE(FONT_LOAD_EVENTS)
     if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
index db67bc6..9eb021a 100644 (file)
@@ -44,7 +44,7 @@ class Font;
 
 class CSSFontFace : public RefCounted<CSSFontFace> {
 public:
-    static Ref<CSSFontFace> create(FontTraitsMask traitsMask, PassRefPtr<CSSFontFaceRule> rule, bool isLocalFallback = false) { return adoptRef(*new CSSFontFace(traitsMask, rule, isLocalFallback)); }
+    static Ref<CSSFontFace> create(FontTraitsMask traitsMask, RefPtr<CSSFontFaceRule>&& rule, bool isLocalFallback = false) { return adoptRef(*new CSSFontFace(traitsMask, WTF::move(rule), isLocalFallback)); }
 
     FontTraitsMask traitsMask() const { return m_traitsMask; }
 
@@ -92,7 +92,7 @@ public:
 #endif
 
 private:
-    CSSFontFace(FontTraitsMask traitsMask, PassRefPtr<CSSFontFaceRule> rule, bool isLocalFallback)
+    CSSFontFace(FontTraitsMask traitsMask, RefPtr<CSSFontFaceRule>&& rule, bool isLocalFallback)
         : m_traitsMask(traitsMask)
         , m_activeSource(0)
         , m_isLocalFallback(isLocalFallback)
index 269ddfc..202cfc0 100644 (file)
@@ -84,31 +84,13 @@ bool CSSFontSelector::isEmpty() const
     return m_fonts.isEmpty();
 }
 
-void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, bool isInitiatingElementInUserAgentShadowTree)
+static Optional<FontTraitsMask> computeTraitsMask(const StyleProperties& style)
 {
-    // Obtain the font-family property and the src property.  Both must be defined.
-    const StyleProperties& style = fontFaceRule->properties();
-    RefPtr<CSSValue> fontFamily = style.getPropertyCSSValue(CSSPropertyFontFamily);
-    RefPtr<CSSValue> src = style.getPropertyCSSValue(CSSPropertySrc);
-    RefPtr<CSSValue> unicodeRange = style.getPropertyCSSValue(CSSPropertyUnicodeRange);
-    if (!is<CSSValueList>(fontFamily.get()) || !is<CSSValueList>(src.get()) || (unicodeRange && !is<CSSValueList>(*unicodeRange)))
-        return;
-
-    CSSValueList& familyList = downcast<CSSValueList>(*fontFamily);
-    if (!familyList.length())
-        return;
-
-    CSSValueList& srcList = downcast<CSSValueList>(*src);
-    if (!srcList.length())
-        return;
-
-    CSSValueList* rangeList = downcast<CSSValueList>(unicodeRange.get());
-
     unsigned traitsMask = 0;
 
     if (RefPtr<CSSValue> fontStyle = style.getPropertyCSSValue(CSSPropertyFontStyle)) {
         if (!is<CSSPrimitiveValue>(*fontStyle))
-            return;
+            return Nullopt;
 
         switch (downcast<CSSPrimitiveValue>(*fontStyle).getValueID()) {
         case CSSValueNormal:
@@ -126,7 +108,7 @@ void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, boo
 
     if (RefPtr<CSSValue> fontWeight = style.getPropertyCSSValue(CSSPropertyFontWeight)) {
         if (!is<CSSPrimitiveValue>(*fontWeight))
-            return;
+            return Nullopt;
 
         switch (downcast<CSSPrimitiveValue>(*fontWeight).getValueID()) {
         case CSSValueBold:
@@ -171,12 +153,12 @@ void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, boo
             list->append(fontVariant.releaseNonNull());
             fontVariant = list.releaseNonNull();
         } else if (!is<CSSValueList>(*fontVariant))
-            return;
+            return Nullopt;
 
         CSSValueList& variantList = downcast<CSSValueList>(*fontVariant);
         unsigned numVariants = variantList.length();
         if (!numVariants)
-            return;
+            return Nullopt;
 
         for (unsigned i = 0; i < numVariants; ++i) {
             switch (downcast<CSSPrimitiveValue>(variantList.itemWithoutBoundsCheck(i))->getValueID()) {
@@ -193,8 +175,20 @@ void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, boo
     } else
         traitsMask |= FontVariantMask;
 
-    // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace.
-    RefPtr<CSSFontFace> fontFace;
+    return static_cast<FontTraitsMask>(traitsMask);
+}
+
+static Ref<CSSFontFace> createFontFace(CSSValueList& srcList, FontTraitsMask traitsMask, Document* document, const StyleRuleFontFace* fontFaceRule, bool isInitiatingElementInUserAgentShadowTree)
+{
+    RefPtr<CSSFontFaceRule> rule;
+#if ENABLE(FONT_LOAD_EVENTS)
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=112116 - This CSSFontFaceRule has no parent.
+    if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
+        rule = static_pointer_cast<CSSFontFaceRule>(fontFaceRule->createCSSOMWrapper());
+#else
+    UNUSED_PARAM(fontFaceRule);
+#endif
+    Ref<CSSFontFace> fontFace = CSSFontFace::create(traitsMask, WTF::move(rule));
 
     int srcLength = srcList.length();
 
@@ -209,10 +203,10 @@ void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, boo
         foundSVGFont = item.isSVGFontFaceSrc() || item.svgFontFaceElement();
 #endif
         if (!item.isLocal()) {
-            Settings* settings = m_document ? m_document->frame() ? &m_document->frame()->settings() : 0 : 0;
+            Settings* settings = document ? document->frame() ? &document->frame()->settings() : 0 : 0;
             bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
-            if (allowDownloading && item.isSupportedFormat() && m_document) {
-                CachedFont* cachedFont = item.cachedFont(m_document, foundSVGFont, isInitiatingElementInUserAgentShadowTree);
+            if (allowDownloading && item.isSupportedFormat() && document) {
+                CachedFont* cachedFont = item.cachedFont(document, foundSVGFont, isInitiatingElementInUserAgentShadowTree);
                 if (cachedFont) {
                     source = std::make_unique<CSSFontFaceSource>(item.resource(), cachedFont);
 #if ENABLE(SVG_FONTS)
@@ -225,16 +219,6 @@ void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, boo
             source = std::make_unique<CSSFontFaceSource>(item.resource());
         }
 
-        if (!fontFace) {
-            RefPtr<CSSFontFaceRule> rule;
-#if ENABLE(FONT_LOAD_EVENTS)
-            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=112116 - This CSSFontFaceRule has no parent.
-            if (RuntimeEnabledFeatures::sharedFeatures().fontLoadEventsEnabled())
-                rule = static_pointer_cast<CSSFontFaceRule>(fontFaceRule->createCSSOMWrapper());
-#endif
-            fontFace = CSSFontFace::create(static_cast<FontTraitsMask>(traitsMask), rule);
-        }
-
         if (source) {
 #if ENABLE(SVG_FONTS)
             source->setSVGFontFaceElement(item.svgFontFaceElement());
@@ -243,9 +227,82 @@ void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, boo
         }
     }
 
-    ASSERT(fontFace);
+    return fontFace;
+}
+
+static String familyNameFromPrimitive(const CSSPrimitiveValue& value)
+{
+    if (value.isFontFamily())
+        return value.fontFamily().familyName;
+    if (!value.isValueID())
+        return { };
+
+    // We need to use the raw text for all the generic family types, since @font-face is a way of actually
+    // defining what font to use for those types.
+    switch (value.getValueID()) {
+    case CSSValueSerif:
+        return serifFamily;
+    case CSSValueSansSerif:
+        return sansSerifFamily;
+    case CSSValueCursive:
+        return cursiveFamily;
+    case CSSValueFantasy:
+        return fantasyFamily;
+    case CSSValueMonospace:
+        return monospaceFamily;
+    case CSSValueWebkitPictograph:
+        return pictographFamily;
+    default:
+        return { };
+    }
+}
+
+static Vector<Ref<CSSFontFace>> constructFamilyFontFaces(const String& familyName, HashMap<String, Vector<Ref<CSSFontFace>>, CaseFoldingHash>& locallyInstalledFontFaces)
+{
+    auto result = Vector<Ref<CSSFontFace>>();
+
+    ASSERT(!locallyInstalledFontFaces.contains(familyName));
+
+    Vector<FontTraitsMask> traitsMasks = FontCache::singleton().getTraitsInFamily(familyName);
+    if (!traitsMasks.isEmpty()) {
+        Vector<Ref<CSSFontFace>> faces = { };
+        for (auto mask : traitsMasks) {
+            Ref<CSSFontFace> face = CSSFontFace::create(mask, nullptr, true);
+            face->addSource(std::make_unique<CSSFontFaceSource>(familyName));
+            ASSERT(face->isValid());
+            faces.append(WTF::move(face));
+        }
+        locallyInstalledFontFaces.add(familyName, WTF::move(faces));
+    }
+    return result;
+}
+
+void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, bool isInitiatingElementInUserAgentShadowTree)
+{
+    const StyleProperties& style = fontFaceRule->properties();
+    RefPtr<CSSValue> fontFamily = style.getPropertyCSSValue(CSSPropertyFontFamily);
+    RefPtr<CSSValue> src = style.getPropertyCSSValue(CSSPropertySrc);
+    RefPtr<CSSValue> unicodeRange = style.getPropertyCSSValue(CSSPropertyUnicodeRange);
+    if (!is<CSSValueList>(fontFamily.get()) || !is<CSSValueList>(src.get()) || (unicodeRange && !is<CSSValueList>(*unicodeRange)))
+        return;
+
+    CSSValueList& familyList = downcast<CSSValueList>(*fontFamily);
+    if (!familyList.length())
+        return;
+
+    CSSValueList& srcList = downcast<CSSValueList>(*src);
+    if (!srcList.length())
+        return;
+
+    CSSValueList* rangeList = downcast<CSSValueList>(unicodeRange.get());
 
-    if (fontFace && !fontFace->isValid())
+    auto computedTraitsMask = computeTraitsMask(style);
+    if (!computedTraitsMask)
+        return;
+    auto traitsMask = computedTraitsMask.value();
+
+    Ref<CSSFontFace> fontFace = createFontFace(srcList, traitsMask, m_document, fontFaceRule, isInitiatingElementInUserAgentShadowTree);
+    if (!fontFace->isValid())
         return;
 
     if (rangeList) {
@@ -256,65 +313,17 @@ void CSSFontSelector::addFontFaceRule(const StyleRuleFontFace* fontFaceRule, boo
         }
     }
 
-    // Hash under every single family name.
     for (auto& item : familyList) {
-        auto& value = downcast<CSSPrimitiveValue>(item.get());
-        String familyName;
-        if (value.isFontFamily()) {
-            familyName = value.fontFamily().familyName;
-        } else if (value.isValueID()) {
-            // We need to use the raw text for all the generic family types, since @font-face is a way of actually
-            // defining what font to use for those types.
-            switch (value.getValueID()) {
-                case CSSValueSerif:
-                    familyName = serifFamily;
-                    break;
-                case CSSValueSansSerif:
-                    familyName = sansSerifFamily;
-                    break;
-                case CSSValueCursive:
-                    familyName = cursiveFamily;
-                    break;
-                case CSSValueFantasy:
-                    familyName = fantasyFamily;
-                    break;
-                case CSSValueMonospace:
-                    familyName = monospaceFamily;
-                    break;
-                case CSSValueWebkitPictograph:
-                    familyName = pictographFamily;
-                    break;
-                default:
-                    break;
-            }
-        }
-
+        String familyName = familyNameFromPrimitive(downcast<CSSPrimitiveValue>(item.get()));
         if (familyName.isEmpty())
             continue;
 
-        std::unique_ptr<Vector<RefPtr<CSSFontFace>>>& familyFontFaces = m_fontFaces.add(familyName, nullptr).iterator->value;
-        if (!familyFontFaces) {
-            familyFontFaces = std::make_unique<Vector<RefPtr<CSSFontFace>>>();
+        auto addResult = m_fontFaces.add(familyName, Vector<Ref<CSSFontFace>>());
+        auto& familyFontFaces = addResult.iterator->value;
+        if (addResult.isNewEntry)
+            familyFontFaces = constructFamilyFontFaces(familyName, m_locallyInstalledFontFaces);
 
-            ASSERT(!m_locallyInstalledFontFaces.contains(familyName));
-
-            Vector<unsigned> locallyInstalledFontsTraitsMasks;
-            FontCache::singleton().getTraitsInFamily(familyName, locallyInstalledFontsTraitsMasks);
-            if (unsigned numLocallyInstalledFaces = locallyInstalledFontsTraitsMasks.size()) {
-                auto familyLocallyInstalledFaces = std::make_unique<Vector<RefPtr<CSSFontFace>>>();
-
-                for (unsigned i = 0; i < numLocallyInstalledFaces; ++i) {
-                    RefPtr<CSSFontFace> locallyInstalledFontFace = CSSFontFace::create(static_cast<FontTraitsMask>(locallyInstalledFontsTraitsMasks[i]), 0, true);
-                    locallyInstalledFontFace->addSource(std::make_unique<CSSFontFaceSource>(familyName));
-                    ASSERT(locallyInstalledFontFace->isValid());
-                    familyLocallyInstalledFaces->append(locallyInstalledFontFace);
-                }
-
-                m_locallyInstalledFontFaces.set(familyName, WTF::move(familyLocallyInstalledFaces));
-            }
-        }
-
-        familyFontFaces->append(fontFace);
+        familyFontFaces.append(fontFace.copyRef());
         
         ++m_version;
     }
@@ -378,10 +387,10 @@ static const AtomicString& resolveGenericFamily(Document* document, const FontDe
 
 static FontTraitsMask desiredTraitsMaskForComparison;
 
-static inline bool compareFontFaces(CSSFontFace* first, CSSFontFace* second)
+static inline bool compareFontFaces(const CSSFontFace& first, const CSSFontFace& second)
 {
-    FontTraitsMask firstTraitsMask = first->traitsMask();
-    FontTraitsMask secondTraitsMask = second->traitsMask();
+    FontTraitsMask firstTraitsMask = first.traitsMask();
+    FontTraitsMask secondTraitsMask = second.traitsMask();
 
     bool firstHasDesiredVariant = firstTraitsMask & desiredTraitsMaskForComparison & FontVariantMask;
     bool secondHasDesiredVariant = secondTraitsMask & desiredTraitsMaskForComparison & FontVariantMask;
@@ -390,7 +399,7 @@ static inline bool compareFontFaces(CSSFontFace* first, CSSFontFace* second)
         return firstHasDesiredVariant;
 
     // We need to check font-variant css property for CSS2.1 compatibility.
-    if ((desiredTraitsMaskForComparison & FontVariantSmallCapsMask) && !first->isLocalFallback() && !second->isLocalFallback()) {
+    if ((desiredTraitsMaskForComparison & FontVariantSmallCapsMask) && !first.isLocalFallback() && !second.isLocalFallback()) {
         // Prefer a font that has indicated that it can only support small-caps to a font that claims to support
         // all variants.  The specialized font is more likely to be true small-caps and not require synthesis.
         bool firstRequiresSmallCaps = (firstTraitsMask & FontVariantSmallCapsMask) && !(firstTraitsMask & FontVariantNormalMask);
@@ -405,7 +414,7 @@ static inline bool compareFontFaces(CSSFontFace* first, CSSFontFace* second)
     if (firstHasDesiredStyle != secondHasDesiredStyle)
         return firstHasDesiredStyle;
 
-    if ((desiredTraitsMaskForComparison & FontStyleItalicMask) && !first->isLocalFallback() && !second->isLocalFallback()) {
+    if ((desiredTraitsMaskForComparison & FontStyleItalicMask) && !first.isLocalFallback() && !second.isLocalFallback()) {
         // Prefer a font that has indicated that it can only support italics to a font that claims to support
         // all styles.  The specialized font is more likely to be the one the author wants used.
         bool firstRequiresItalics = (firstTraitsMask & FontStyleItalicMask) && !(firstTraitsMask & FontStyleNormalMask);
@@ -476,25 +485,23 @@ FontRanges CSSFontSelector::fontRangesForFamily(const FontDescription& fontDescr
 
 CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDescription, const AtomicString& family)
 {
-    Vector<RefPtr<CSSFontFace>>* familyFontFaces = m_fontFaces.get(family);
-    if (!familyFontFaces || familyFontFaces->isEmpty())
-        return 0;
+    auto iterator = m_fontFaces.find(family);
+    if (iterator == m_fontFaces.end())
+        return nullptr;
+    auto& familyFontFaces = iterator->value;
 
-    std::unique_ptr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace>>>& segmentedFontFaceCache = m_fonts.add(family, nullptr).iterator->value;
-    if (!segmentedFontFaceCache)
-        segmentedFontFaceCache = std::make_unique<HashMap<unsigned, RefPtr<CSSSegmentedFontFace>>>();
+    auto& segmentedFontFaceCache = m_fonts.add(family, HashMap<unsigned, RefPtr<CSSSegmentedFontFace>>()).iterator->value;
 
     FontTraitsMask traitsMask = fontDescription.traitsMask();
 
-    RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, nullptr).iterator->value;
+    RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache.add(traitsMask, nullptr).iterator->value;
     if (!face) {
         face = CSSSegmentedFontFace::create(this);
 
-        // Collect all matching faces and sort them in order of preference.
-        Vector<CSSFontFace*, 32> candidateFontFaces;
-        for (int i = familyFontFaces->size() - 1; i >= 0; --i) {
-            CSSFontFace* candidate = familyFontFaces->at(i).get();
-            unsigned candidateTraitsMask = candidate->traitsMask();
+        Vector<std::reference_wrapper<CSSFontFace>, 32> candidateFontFaces;
+        for (int i = familyFontFaces.size() - 1; i >= 0; --i) {
+            CSSFontFace& candidate = familyFontFaces[i];
+            unsigned candidateTraitsMask = candidate.traitsMask();
             if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask))
                 continue;
             if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask))
@@ -502,16 +509,15 @@ CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDe
 #if ENABLE(SVG_FONTS)
             // For SVG Fonts that specify that they only support the "normal" variant, we will assume they are incapable
             // of small-caps synthesis and just ignore the font face as a candidate.
-            if (candidate->hasSVGFontFaceSource() && (traitsMask & FontVariantSmallCapsMask) && !(candidateTraitsMask & FontVariantSmallCapsMask))
+            if (candidate.hasSVGFontFaceSource() && (traitsMask & FontVariantSmallCapsMask) && !(candidateTraitsMask & FontVariantSmallCapsMask))
                 continue;
 #endif
             candidateFontFaces.append(candidate);
         }
 
-        if (Vector<RefPtr<CSSFontFace>>* familyLocallyInstalledFontFaces = m_locallyInstalledFontFaces.get(family)) {
-            unsigned numLocallyInstalledFontFaces = familyLocallyInstalledFontFaces->size();
-            for (unsigned i = 0; i < numLocallyInstalledFontFaces; ++i) {
-                CSSFontFace* candidate = familyLocallyInstalledFontFaces->at(i).get();
+        auto iterator = m_locallyInstalledFontFaces.find(family);
+        if (iterator != m_locallyInstalledFontFaces.end()) {
+            for (auto& candidate : iterator->value) {
                 unsigned candidateTraitsMask = candidate->traitsMask();
                 if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask))
                     continue;
@@ -523,9 +529,8 @@ CSSSegmentedFontFace* CSSFontSelector::getFontFace(const FontDescription& fontDe
 
         desiredTraitsMaskForComparison = traitsMask;
         std::stable_sort(candidateFontFaces.begin(), candidateFontFaces.end(), compareFontFaces);
-        unsigned numCandidates = candidateFontFaces.size();
-        for (unsigned i = 0; i < numCandidates; ++i)
-            face->appendFontFace(candidateFontFaces[i]);
+        for (auto& candidate : candidateFontFaces)
+            face->appendFontFace(candidate.get());
     }
     return face.get();
 }
index 4be7408..47ea640 100644 (file)
@@ -89,9 +89,9 @@ private:
     void beginLoadTimerFired();
 
     Document* m_document;
-    HashMap<String, std::unique_ptr<Vector<RefPtr<CSSFontFace>>>, CaseFoldingHash> m_fontFaces;
-    HashMap<String, std::unique_ptr<Vector<RefPtr<CSSFontFace>>>, CaseFoldingHash> m_locallyInstalledFontFaces;
-    HashMap<String, std::unique_ptr<HashMap<unsigned, RefPtr<CSSSegmentedFontFace>>>, CaseFoldingHash> m_fonts;
+    HashMap<String, Vector<Ref<CSSFontFace>>, CaseFoldingHash> m_fontFaces;
+    HashMap<String, Vector<Ref<CSSFontFace>>, CaseFoldingHash> m_locallyInstalledFontFaces;
+    HashMap<String, HashMap<unsigned, RefPtr<CSSSegmentedFontFace>>, CaseFoldingHash> m_fonts;
     HashSet<FontSelectorClient*> m_clients;
 
     Vector<CachedResourceHandle<CachedFont>> m_fontsToBeginLoading;
index 2f37d6a..5cbfca4 100644 (file)
@@ -45,9 +45,8 @@ CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector)
 CSSSegmentedFontFace::~CSSSegmentedFontFace()
 {
     pruneTable();
-    unsigned size = m_fontFaces.size();
-    for (unsigned i = 0; i < size; i++)
-        m_fontFaces[i]->removedFromSegmentedFontFace(this);
+    for (auto& face : m_fontFaces)
+        face->removedFromSegmentedFontFace(this);
 }
 
 void CSSSegmentedFontFace::pruneTable()
@@ -58,9 +57,8 @@ void CSSSegmentedFontFace::pruneTable()
 bool CSSSegmentedFontFace::isValid() const
 {
     // Valid if at least one font face is valid.
-    unsigned size = m_fontFaces.size();
-    for (unsigned i = 0; i < size; i++) {
-        if (m_fontFaces[i]->isValid())
+    for (auto& face : m_fontFaces) {
+        if (face->isValid())
             return true;
     }
     return false;
@@ -84,11 +82,11 @@ void CSSSegmentedFontFace::fontLoaded(CSSFontFace*)
 #endif
 }
 
-void CSSSegmentedFontFace::appendFontFace(PassRefPtr<CSSFontFace> fontFace)
+void CSSSegmentedFontFace::appendFontFace(Ref<CSSFontFace>&& fontFace)
 {
     pruneTable();
     fontFace->addedToSegmentedFontFace(this);
-    m_fontFaces.append(fontFace);
+    m_fontFaces.append(WTF::move(fontFace));
 }
 
 static void appendFontWithInvalidUnicodeRangeIfLoading(FontRanges& ranges, Ref<Font>&& font, const Vector<CSSFontFace::UnicodeRange>& unicodeRanges)
index f869ff6..5ffebb1 100644 (file)
@@ -48,7 +48,7 @@ public:
 
     void fontLoaded(CSSFontFace*);
 
-    void appendFontFace(PassRefPtr<CSSFontFace>);
+    void appendFontFace(Ref<CSSFontFace>&&);
 
     FontRanges fontRanges(const FontDescription&);
 
@@ -75,7 +75,7 @@ private:
 
     CSSFontSelector* m_fontSelector;
     HashMap<FontDescriptionKey, FontRanges, FontDescriptionKeyHash, WTF::SimpleClassHashTraits<FontDescriptionKey>> m_descriptionToRangesMap;
-    Vector<RefPtr<CSSFontFace>, 1> m_fontFaces;
+    Vector<Ref<CSSFontFace>, 1> m_fontFaces;
 #if ENABLE(FONT_LOAD_EVENTS)
     Vector<RefPtr<LoadFontCallback>> m_callbacks;
 #endif
index 2c81d80..58723e1 100644 (file)
@@ -583,7 +583,7 @@ PassRefPtr<CSSValue> StyleProperties::getPropertyCSSValue(CSSPropertyID property
 {
     int foundPropertyIndex = findPropertyIndex(propertyID);
     if (foundPropertyIndex == -1)
-        return 0;
+        return nullptr;
     return propertyAt(foundPropertyIndex).value();
 }
 
index 3a0686c..27b500e 100644 (file)
@@ -166,7 +166,7 @@ public:
 
     // This function exists so CSSFontSelector can have a unified notion of preinstalled fonts and @font-face.
     // It comes into play when you create an @font-face which shares a family name as a preinstalled font.
-    void getTraitsInFamily(const AtomicString&, Vector<unsigned>&);
+    Vector<FontTraitsMask> getTraitsInFamily(const AtomicString&);
 
     WEBCORE_EXPORT RefPtr<Font> fontForFamily(const FontDescription&, const AtomicString&, bool checkingAlternateName = false);
     WEBCORE_EXPORT Ref<Font> lastResortFallbackFont(const FontDescription&);
index d87d798..386843c 100644 (file)
@@ -237,7 +237,7 @@ RefPtr<Font> FontCache::similarFont(const FontDescription& description)
     return font.release();
 }
 
-void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
+Vector<FontTraitsMask> FontCache::getTraitsInFamily(const AtomicString& familyName)
 {
     RetainPtr<CFStringRef> familyNameStr = familyName.string().createCFString();
     CFStringRef familyNameStrPtr = familyNameStr.get();
@@ -245,12 +245,14 @@ void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigne
     RetainPtr<CTFontDescriptorRef> fontDescriptor = adoptCF(CTFontDescriptorCreateWithAttributes(attributes.get()));
     RetainPtr<CFArrayRef> matchedDescriptors = adoptCF(CTFontDescriptorCreateMatchingFontDescriptors(fontDescriptor.get(), nullptr));
     if (!matchedDescriptors)
-        return;
+        return { };
 
     CFIndex numMatches = CFArrayGetCount(matchedDescriptors.get());
     if (!numMatches)
-        return;
+        return { };
 
+    Vector<FontTraitsMask> traitsMasks;
+    traitsMasks.reserveInitialCapacity(numMatches);
     for (CFIndex i = 0; i < numMatches; ++i) {
         RetainPtr<CFDictionaryRef> traits = adoptCF((CFDictionaryRef)CTFontDescriptorCopyAttribute((CTFontDescriptorRef)CFArrayGetValueAtIndex(matchedDescriptors.get(), i), kCTFontTraitsAttribute));
         CFNumberRef resultRef = (CFNumberRef)CFDictionaryGetValue(traits.get(), kCTFontSymbolicTrait);
@@ -260,9 +262,10 @@ void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigne
             CFNumberGetValue(resultRef, kCFNumberIntType, &symbolicTraits);
             CGFloat weight = 0;
             CFNumberGetValue(weightRef, kCFNumberCGFloatType, &weight);
-            traitsMasks.append(toTraitsMask(symbolicTraits, weight));
+            traitsMasks.uncheckedAppend(toTraitsMask(symbolicTraits, weight));
         }
     }
+    return traitsMasks;
 }
 
 }
index 7b60398..80903e4 100644 (file)
@@ -137,8 +137,9 @@ Ref<Font> FontCache::lastResortFallbackFont(const FontDescription& fontDescripti
     return *fontForFamily(fontDescription, timesStr, false);
 }
 
-void FontCache::getTraitsInFamily(const AtomicString&, Vector<unsigned>&)
+Vector<FontTraitsMask> FontCache::getTraitsInFamily(const AtomicString&)
 {
+    return { };
 }
 
 static String getFamilyNameStringFromFamily(const AtomicString& family)
index afa4841..fe02d25 100644 (file)
@@ -542,7 +542,7 @@ static int CALLBACK traitsInFamilyEnumProc(CONST LOGFONT* logFont, CONST TEXTMET
     procData->m_traitsMasks.add(traitsMask);
     return 1;
 }
-void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigned>& traitsMasks)
+Vector<FontTraitsMask> FontCache::getTraitsInFamily(const AtomicString& familyName)
 {
     HWndDC hdc(0);
 
@@ -555,7 +555,11 @@ void FontCache::getTraitsInFamily(const AtomicString& familyName, Vector<unsigne
 
     TraitsInFamilyProcData procData(familyName);
     EnumFontFamiliesEx(hdc, &logFont, traitsInFamilyEnumProc, reinterpret_cast<LPARAM>(&procData), 0);
-    copyToVector(procData.m_traitsMasks, traitsMasks);
+    Vector<FontTraitsMask> result;
+    result.reserveInitialCapacity(procData.m_traitsMasks.size());
+    for (unsigned mask : procData.m_traitsMasks)
+        result.uncheckedAppend(static_cast<FontTraitsMask>(mask));
+    return result;
 }
 
 std::unique_ptr<FontPlatformData> FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family)