⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fontcache.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    static const bool safeToCompareToEmptyOrDeleted = true;};struct FontDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformData> {    static const bool emptyValueIsZero = true;    static const bool needsDestruction = true;    static const FontPlatformData& emptyValue()    {        DEFINE_STATIC_LOCAL(FontPlatformData, key, (0.f, false, false));        return key;    }    static void constructDeletedValue(FontPlatformData& slot)    {        new (&slot) FontPlatformData(HashTableDeletedValue);    }    static bool isDeletedValue(const FontPlatformData& value)    {        return value.isHashTableDeletedValue();    }};typedef HashMap<FontPlatformData, pair<SimpleFontData*, unsigned>, FontDataCacheKeyHash, FontDataCacheKeyTraits> FontDataCache;static FontDataCache* gFontDataCache = 0;const int cMaxInactiveFontData = 120;  // Pretty Low Thresholdconst float cTargetInactiveFontData = 100;static ListHashSet<const SimpleFontData*>* gInactiveFontData = 0;SimpleFontData* FontCache::getCachedFontData(const FontPlatformData* platformData){    if (!platformData)        return 0;    if (!gFontDataCache) {        gFontDataCache = new FontDataCache;        gInactiveFontData = new ListHashSet<const SimpleFontData*>;    }        FontDataCache::iterator result = gFontDataCache->find(*platformData);    if (result == gFontDataCache->end()) {        pair<SimpleFontData*, unsigned> newValue(new SimpleFontData(*platformData), 1);        gFontDataCache->set(*platformData, newValue);        return newValue.first;    }    if (!result.get()->second.second++) {        ASSERT(gInactiveFontData->contains(result.get()->second.first));        gInactiveFontData->remove(result.get()->second.first);    }    return result.get()->second.first;}void FontCache::releaseFontData(const SimpleFontData* fontData){    ASSERT(gFontDataCache);    ASSERT(!fontData->isCustomFont());    FontDataCache::iterator it = gFontDataCache->find(fontData->platformData());    ASSERT(it != gFontDataCache->end());    if (!--it->second.second) {        gInactiveFontData->add(fontData);        if (gInactiveFontData->size() > cMaxInactiveFontData)            purgeInactiveFontData(gInactiveFontData->size() - cTargetInactiveFontData);    }}void FontCache::purgeInactiveFontData(int count){    if (!gInactiveFontData)        return;    static bool isPurging;  // Guard against reentry when e.g. a deleted FontData releases its small caps FontData.    if (isPurging)        return;    isPurging = true;    ListHashSet<const SimpleFontData*>::iterator end = gInactiveFontData->end();    ListHashSet<const SimpleFontData*>::iterator it = gInactiveFontData->begin();    for (int i = 0; i < count && it != end; ++it, ++i) {        const SimpleFontData* fontData = *it.get();        gFontDataCache->remove(fontData->platformData());        delete fontData;    }    if (it == end) {        // Removed everything        gInactiveFontData->clear();    } else {        for (int i = 0; i < count; ++i)            gInactiveFontData->remove(gInactiveFontData->begin());    }    Vector<FontPlatformDataCacheKey> keysToRemove;    keysToRemove.reserveInitialCapacity(gFontPlatformDataCache->size());    FontPlatformDataCache::iterator platformDataEnd = gFontPlatformDataCache->end();    for (FontPlatformDataCache::iterator platformData = gFontPlatformDataCache->begin(); platformData != platformDataEnd; ++platformData) {        if (platformData->second && !gFontDataCache->contains(*platformData->second))            keysToRemove.append(platformData->first);    }    size_t keysToRemoveCount = keysToRemove.size();    for (size_t i = 0; i < keysToRemoveCount; ++i)        delete gFontPlatformDataCache->take(keysToRemove[i]);    isPurging = false;}size_t FontCache::fontDataCount(){    if (gFontDataCache)        return gFontDataCache->size();    return 0;}size_t FontCache::inactiveFontDataCount(){    if (gInactiveFontData)        return gInactiveFontData->size();    return 0;}const FontData* FontCache::getFontData(const Font& font, int& familyIndex, FontSelector* fontSelector){    FontPlatformData* result = 0;    int startIndex = familyIndex;    const FontFamily* startFamily = &font.fontDescription().family();    for (int i = 0; startFamily && i < startIndex; i++)        startFamily = startFamily->next();    const FontFamily* currFamily = startFamily;    while (currFamily && !result) {        familyIndex++;        if (currFamily->family().length()) {            if (fontSelector) {                FontData* data = fontSelector->getFontData(font.fontDescription(), currFamily->family());                if (data)                    return data;            }            result = getCachedFontPlatformData(font.fontDescription(), currFamily->family());        }        currFamily = currFamily->next();    }    if (!currFamily)        familyIndex = cAllFamiliesScanned;    if (!result)        // We didn't find a font. Try to find a similar font using our own specific knowledge about our platform.        // For example on OS X, we know to map any families containing the words Arabic, Pashto, or Urdu to the        // Geeza Pro font.        result = getSimilarFontPlatformData(font);    if (!result && startIndex == 0) {        // If it's the primary font that we couldn't find, we try the following. In all other cases, we will        // just use per-character system fallback.        if (fontSelector) {            // Try the user's preferred standard font.            if (FontData* data = fontSelector->getFontData(font.fontDescription(), "-webkit-standard"))                return data;        }        // Still no result.  Hand back our last resort fallback font.        result = getLastResortFallbackFont(font.fontDescription());    }    // Now that we have a result, we need to go from FontPlatformData -> FontData.    return getCachedFontData(result);}static HashSet<FontSelector*>* gClients;void FontCache::addClient(FontSelector* client){    if (!gClients)        gClients = new HashSet<FontSelector*>;    ASSERT(!gClients->contains(client));    gClients->add(client);}void FontCache::removeClient(FontSelector* client){    ASSERT(gClients);    ASSERT(gClients->contains(client));    gClients->remove(client);}static unsigned gGeneration = 0;unsigned FontCache::generation(){    return gGeneration;}void FontCache::invalidate(){    if (!gClients) {        ASSERT(!gFontPlatformDataCache);        return;    }    if (gFontPlatformDataCache) {        deleteAllValues(*gFontPlatformDataCache);        delete gFontPlatformDataCache;        gFontPlatformDataCache = new FontPlatformDataCache;    }    gGeneration++;    Vector<RefPtr<FontSelector> > clients;    size_t numClients = gClients->size();    clients.reserveInitialCapacity(numClients);    HashSet<FontSelector*>::iterator end = gClients->end();    for (HashSet<FontSelector*>::iterator it = gClients->begin(); it != end; ++it)        clients.append(*it);    ASSERT(numClients == clients.size());    for (size_t i = 0; i < numClients; ++i)        clients[i]->fontCacheInvalidated();    purgeInactiveFontData();}} // namespace WebCore

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -