| 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);
|
| }
|
|
|