Index: third_party/WebKit/Source/platform/fonts/FontCache.cpp |
diff --git a/third_party/WebKit/Source/platform/fonts/FontCache.cpp b/third_party/WebKit/Source/platform/fonts/FontCache.cpp |
index e12c590a3b00f85c550ed23c646695f140463805..bbba7b72eb74a5cbb4b7a345cd98201a04fbf610 100644 |
--- a/third_party/WebKit/Source/platform/fonts/FontCache.cpp |
+++ b/third_party/WebKit/Source/platform/fonts/FontCache.cpp |
@@ -67,7 +67,8 @@ FontCache::FontCache() |
} |
#endif // !OS(WIN) && !OS(LINUX) |
-typedef HashMap<FontCacheKey, OwnPtr<FontPlatformData>, FontCacheKeyHash, FontCacheKeyTraits> FontPlatformDataCache; |
+typedef HashMap<unsigned, OwnPtr<FontPlatformData>, WTF::IntHash<unsigned>, WTF::UnsignedWithZeroKeyHashTraits<unsigned>> SizedFontPlatformDataSet; |
+typedef HashMap<FontCacheKey, SizedFontPlatformDataSet, FontCacheKeyHash, FontCacheKeyTraits> FontPlatformDataCache; |
typedef HashMap<FallbackListCompositeKey, OwnPtr<ShapeCache>, FallbackListCompositeKeyHash, FallbackListCompositeKeyTraits> FallbackListShaperCache; |
static FontPlatformDataCache* gFontPlatformDataCache = nullptr; |
@@ -96,17 +97,36 @@ FontPlatformData* FontCache::getFontPlatformData(const FontDescription& fontDesc |
platformInit(); |
} |
+ float size = fontDescription.effectiveFontSize(); |
+ unsigned roundedSize = size * FontCacheKey::precisionMultiplier(); |
FontCacheKey key = fontDescription.cacheKey(creationParams); |
+ |
+ // Remove the font size from the cache key, and handle the font size separately in the inner |
+ // HashMap. So that different size of FontPlatformData can share underlying SkTypeface. |
+ if (RuntimeEnabledFeatures::fontCacheScalingEnabled()) |
+ key.clearFontSize(); |
+ |
FontPlatformData* result; |
bool foundResult; |
+ |
{ |
// addResult's scope must end before we recurse for alternate family names below, |
// to avoid trigering its dtor hash-changed asserts. |
- auto addResult = gFontPlatformDataCache->add(key, nullptr); |
- if (addResult.isNewEntry) |
- addResult.storedValue->value = createFontPlatformData(fontDescription, creationParams, fontDescription.effectiveFontSize()); |
+ SizedFontPlatformDataSet* sizedFonts = &gFontPlatformDataCache->add(key, SizedFontPlatformDataSet()).storedValue->value; |
+ bool wasEmpty = sizedFonts->isEmpty(); |
+ |
+ // Take a different size instance of the same font before adding an entry to |sizedFont|. |
+ FontPlatformData* anotherSize = wasEmpty ? nullptr : sizedFonts->begin()->value.get(); |
+ auto addResult = sizedFonts->add(roundedSize, nullptr); |
+ OwnPtr<FontPlatformData>* found = &addResult.storedValue->value; |
+ if (addResult.isNewEntry) { |
+ if (wasEmpty) |
+ *found = createFontPlatformData(fontDescription, creationParams, size); |
+ else if (anotherSize) |
+ *found = scaleFontPlatformData(*anotherSize, fontDescription, creationParams, size); |
+ } |
- result = addResult.storedValue->value.get(); |
+ result = found->get(); |
foundResult = result || !addResult.isNewEntry; |
} |
@@ -118,13 +138,25 @@ FontPlatformData* FontCache::getFontPlatformData(const FontDescription& fontDesc |
FontFaceCreationParams createByAlternateFamily(alternateName); |
result = getFontPlatformData(fontDescription, createByAlternateFamily, true); |
} |
- if (result) |
- gFontPlatformDataCache->set(key, adoptPtr(new FontPlatformData(*result))); // Cache the result under the old name. |
+ if (result) { |
+ // Cache the result under the old name. |
+ auto adding = &gFontPlatformDataCache->add(key, SizedFontPlatformDataSet()).storedValue->value; |
+ adding->set(roundedSize, adoptPtr(new FontPlatformData(*result))); |
+ } |
} |
return result; |
} |
+PassOwnPtr<FontPlatformData> FontCache::scaleFontPlatformData(const FontPlatformData& fontPlatformData, const FontDescription& fontDescription, const FontFaceCreationParams& creationParams, float fontSize) |
+{ |
+#if OS(MACOSX) |
+ return createFontPlatformData(fontDescription, creationParams, fontSize); |
+#else |
+ return adoptPtr(new FontPlatformData(fontPlatformData, fontSize)); |
+#endif |
+} |
+ |
ShapeCache* FontCache::getShapeCache(const FallbackListCompositeKey& key) |
{ |
if (!gFallbackListShaperCache) |
@@ -226,10 +258,16 @@ static inline void purgePlatformFontDataCache() |
Vector<FontCacheKey> keysToRemove; |
keysToRemove.reserveInitialCapacity(gFontPlatformDataCache->size()); |
- FontPlatformDataCache::iterator platformDataEnd = gFontPlatformDataCache->end(); |
- for (FontPlatformDataCache::iterator platformData = gFontPlatformDataCache->begin(); platformData != platformDataEnd; ++platformData) { |
- if (platformData->value && !gFontDataCache->contains(platformData->value.get())) |
- keysToRemove.append(platformData->key); |
+ for (auto& sizedFonts : *gFontPlatformDataCache) { |
+ Vector<unsigned> sizesToRemove; |
+ sizesToRemove.reserveInitialCapacity(sizedFonts.value.size()); |
+ for (const auto& platformData : sizedFonts.value) { |
+ if (platformData.value && !gFontDataCache->contains(platformData.value.get())) |
+ sizesToRemove.append(platformData.key); |
+ } |
+ sizedFonts.value.removeAll(sizesToRemove); |
+ if (sizedFonts.value.isEmpty()) |
+ keysToRemove.append(sizedFonts.key); |
} |
gFontPlatformDataCache->removeAll(keysToRemove); |
} |