Exemple #1
0
void FontCache::purgeInactiveFontData(unsigned purgeCount)
{
    pruneUnreferencedEntriesFromFontCascadeCache();
    pruneSystemFallbackFonts();

#if PLATFORM(IOS)
    FontLocker fontLocker;
#endif

    while (purgeCount) {
        Vector<RefPtr<Font>, 20> fontsToDelete;
        for (auto& font : cachedFonts().values()) {
            if (!font->hasOneRef())
                continue;
            fontsToDelete.append(WTF::move(font));
            if (!--purgeCount)
                break;
        }
        // Fonts may ref other fonts so we loop until there are no changes.
        if (fontsToDelete.isEmpty())
            break;
        for (auto& font : fontsToDelete)
            cachedFonts().remove(font->platformData());
    };

    Vector<FontPlatformDataCacheKey> keysToRemove;
    keysToRemove.reserveInitialCapacity(fontPlatformDataCache().size());
    for (auto& entry : fontPlatformDataCache()) {
        if (entry.value && !cachedFonts().contains(*entry.value))
            keysToRemove.append(entry.key);
    }
    for (auto key : keysToRemove)
        fontPlatformDataCache().remove(key);

#if ENABLE(OPENTYPE_VERTICAL)
    FontVerticalDataCache& fontVerticalDataCache = fontVerticalDataCacheInstance();
    if (!fontVerticalDataCache.isEmpty()) {
        // Mark & sweep unused verticalData
        for (auto& verticalData : fontVerticalDataCache.values()) {
            if (verticalData)
                verticalData->m_inFontCache = false;
        }
        for (auto& font : cachedFonts().values()) {
            auto* verticalData = const_cast<OpenTypeVerticalData*>(font->verticalData());
            if (verticalData)
                verticalData->m_inFontCache = true;
        }
        Vector<FontFileKey> keysToRemove;
        keysToRemove.reserveInitialCapacity(fontVerticalDataCache.size());
        for (auto& it : fontVerticalDataCache) {
            if (!it.value || !it.value->m_inFontCache)
                keysToRemove.append(it.key);
        }
        for (auto& key : keysToRemove)
            fontVerticalDataCache.remove(key);
    }
#endif

    platformPurgeInactiveFontData();
}
Exemple #2
0
void FontCache::purgeInactiveFontData(unsigned purgeCount)
{
    pruneUnreferencedEntriesFromFontCascadeCache();
    pruneSystemFallbackFonts();

#if PLATFORM(IOS)
    FontLocker fontLocker;
#endif

    while (purgeCount) {
        Vector<RefPtr<Font>, 20> fontsToDelete;
        for (auto& font : cachedFonts().values()) {
            if (!font->hasOneRef())
                continue;
            fontsToDelete.append(WTFMove(font));
            if (!--purgeCount)
                break;
        }
        // Fonts may ref other fonts so we loop until there are no changes.
        if (fontsToDelete.isEmpty())
            break;
        for (auto& font : fontsToDelete) {
            bool success = cachedFonts().remove(font->platformData());
            ASSERT_UNUSED(success, success);
#if ENABLE(OPENTYPE_VERTICAL)
            fontVerticalDataCache().remove(font->platformData());
#endif
        }
    };

    Vector<FontPlatformDataCacheKey> keysToRemove;
    keysToRemove.reserveInitialCapacity(fontPlatformDataCache().size());
    for (auto& entry : fontPlatformDataCache()) {
        if (entry.value && !cachedFonts().contains(*entry.value))
            keysToRemove.append(entry.key);
    }
    for (auto& key : keysToRemove)
        fontPlatformDataCache().remove(key);

    platformPurgeInactiveFontData();
}
Exemple #3
0
size_t FontCache::inactiveFontCount()
{
#if PLATFORM(IOS)
    FontLocker fontLocker;
#endif
    unsigned count = 0;
    for (auto& font : cachedFonts().values()) {
        if (font->hasOneRef())
            ++count;
    }
    return count;
}
Exemple #4
0
Ref<Font> FontCache::fontForPlatformData(const FontPlatformData& platformData)
{
#if PLATFORM(IOS)
    FontLocker fontLocker;
#endif
    
    auto addResult = cachedFonts().add(platformData, nullptr);
    if (addResult.isNewEntry)
        addResult.iterator->value = Font::create(platformData);

    return *addResult.iterator->value;
}
Exemple #5
0
void FontCache::purgeInactiveFontDataIfNeeded()
{
    bool underMemoryPressure = MemoryPressureHandler::singleton().isUnderMemoryPressure();
    unsigned inactiveFontDataLimit = underMemoryPressure ? cMaxUnderMemoryPressureInactiveFontData : cMaxInactiveFontData;

    if (cachedFonts().size() < inactiveFontDataLimit)
        return;
    unsigned inactiveCount = inactiveFontCount();
    if (inactiveCount <= inactiveFontDataLimit)
        return;

    unsigned targetFontDataLimit = underMemoryPressure ? cTargetUnderMemoryPressureInactiveFontData : cTargetInactiveFontData;
    purgeInactiveFontData(inactiveCount - targetFontDataLimit);
}
Exemple #6
0
size_t FontCache::fontCount()
{
    return cachedFonts().size();
}