📄 fontcache.cpp
字号:
/* * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "FontCache.h"#include "Font.h"#include "FontFallbackList.h"#include "FontPlatformData.h"#include "FontSelector.h"#include "StringHash.h"#include <wtf/HashMap.h>#include <wtf/ListHashSet.h>#include <wtf/StdLibExtras.h>using namespace WTF;namespace WebCore {FontCache* fontCache(){ DEFINE_STATIC_LOCAL(FontCache, globalFontCache, ()); return &globalFontCache;}FontCache::FontCache(){}struct FontPlatformDataCacheKey { FontPlatformDataCacheKey(const AtomicString& family = AtomicString(), unsigned size = 0, unsigned weight = 0, bool italic = false, bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode) : m_family(family) , m_size(size) , m_weight(weight) , m_italic(italic) , m_printerFont(isPrinterFont) , m_renderingMode(renderingMode) { } FontPlatformDataCacheKey(HashTableDeletedValueType) : m_size(hashTableDeletedSize()) { } bool isHashTableDeletedValue() const { return m_size == hashTableDeletedSize(); } bool operator==(const FontPlatformDataCacheKey& other) const { return equalIgnoringCase(m_family, other.m_family) && m_size == other.m_size && m_weight == other.m_weight && m_italic == other.m_italic && m_printerFont == other.m_printerFont && m_renderingMode == other.m_renderingMode; } AtomicString m_family; unsigned m_size; unsigned m_weight; bool m_italic; bool m_printerFont; FontRenderingMode m_renderingMode;private: static unsigned hashTableDeletedSize() { return 0xFFFFFFFFU; }};inline unsigned computeHash(const FontPlatformDataCacheKey& fontKey){ unsigned hashCodes[4] = { CaseFoldingHash::hash(fontKey.m_family), fontKey.m_size, fontKey.m_weight, static_cast<unsigned>(fontKey.m_italic) << 2 | static_cast<unsigned>(fontKey.m_printerFont) << 1 | static_cast<unsigned>(fontKey.m_renderingMode) }; return StringImpl::computeHash(reinterpret_cast<UChar*>(hashCodes), sizeof(hashCodes) / sizeof(UChar));}struct FontPlatformDataCacheKeyHash { static unsigned hash(const FontPlatformDataCacheKey& font) { return computeHash(font); } static bool equal(const FontPlatformDataCacheKey& a, const FontPlatformDataCacheKey& b) { return a == b; } static const bool safeToCompareToEmptyOrDeleted = true;};struct FontPlatformDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformDataCacheKey> { static const bool emptyValueIsZero = true; static const FontPlatformDataCacheKey& emptyValue() { DEFINE_STATIC_LOCAL(FontPlatformDataCacheKey, key, (nullAtom)); return key; } static void constructDeletedValue(FontPlatformDataCacheKey& slot) { new (&slot) FontPlatformDataCacheKey(HashTableDeletedValue); } static bool isDeletedValue(const FontPlatformDataCacheKey& value) { return value.isHashTableDeletedValue(); }};typedef HashMap<FontPlatformDataCacheKey, FontPlatformData*, FontPlatformDataCacheKeyHash, FontPlatformDataCacheKeyTraits> FontPlatformDataCache;static FontPlatformDataCache* gFontPlatformDataCache = 0;static const AtomicString& alternateFamilyName(const AtomicString& familyName){ // Alias Courier <-> Courier New DEFINE_STATIC_LOCAL(AtomicString, courier, ("Courier")); DEFINE_STATIC_LOCAL(AtomicString, courierNew, ("Courier New")); if (equalIgnoringCase(familyName, courier)) return courierNew;#if !PLATFORM(WIN_OS) // On Windows, Courier New (truetype font) is always present and // Courier is a bitmap font. So, we don't want to map Courier New to // Courier. if (equalIgnoringCase(familyName, courierNew)) return courier;#endif // Alias Times and Times New Roman. DEFINE_STATIC_LOCAL(AtomicString, times, ("Times")); DEFINE_STATIC_LOCAL(AtomicString, timesNewRoman, ("Times New Roman")); if (equalIgnoringCase(familyName, times)) return timesNewRoman; if (equalIgnoringCase(familyName, timesNewRoman)) return times; // Alias Arial and Helvetica DEFINE_STATIC_LOCAL(AtomicString, arial, ("Arial")); DEFINE_STATIC_LOCAL(AtomicString, helvetica, ("Helvetica")); if (equalIgnoringCase(familyName, arial)) return helvetica; if (equalIgnoringCase(familyName, helvetica)) return arial;#if PLATFORM(WIN_OS) // On Windows, bitmap fonts are blocked altogether so that we have to // alias MS Sans Serif (bitmap font) -> Microsoft Sans Serif (truetype font) DEFINE_STATIC_LOCAL(AtomicString, msSans, ("MS Sans Serif")); DEFINE_STATIC_LOCAL(AtomicString, microsoftSans, ("Microsoft Sans Serif")); if (equalIgnoringCase(familyName, msSans)) return microsoftSans; // Alias MS Serif (bitmap) -> Times New Roman (truetype font). There's no // 'Microsoft Sans Serif-equivalent' for Serif. static AtomicString msSerif("MS Serif"); if (equalIgnoringCase(familyName, msSerif)) return timesNewRoman;#endif return emptyAtom;}FontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& fontDescription, const AtomicString& familyName, bool checkingAlternateName){ if (!gFontPlatformDataCache) { gFontPlatformDataCache = new FontPlatformDataCache; platformInit(); } FontPlatformDataCacheKey key(familyName, fontDescription.computedPixelSize(), fontDescription.weight(), fontDescription.italic(), fontDescription.usePrinterFont(), fontDescription.renderingMode()); FontPlatformData* result = 0; bool foundResult; FontPlatformDataCache::iterator it = gFontPlatformDataCache->find(key); if (it == gFontPlatformDataCache->end()) { result = createFontPlatformData(fontDescription, familyName); gFontPlatformDataCache->set(key, result); foundResult = result; } else { result = it->second; foundResult = true; } if (!foundResult && !checkingAlternateName) { // We were unable to find a font. We have a small set of fonts that we alias to other names, // e.g., Arial/Helvetica, Courier/Courier New, etc. Try looking up the font under the aliased name. const AtomicString& alternateName = alternateFamilyName(familyName); if (!alternateName.isEmpty()) result = getCachedFontPlatformData(fontDescription, alternateName, true); if (result) gFontPlatformDataCache->set(key, new FontPlatformData(*result)); // Cache the result under the old name. } return result;}struct FontDataCacheKeyHash { static unsigned hash(const FontPlatformData& platformData) { return platformData.hash(); } static bool equal(const FontPlatformData& a, const FontPlatformData& b) { return a == b; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -