18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * its contributors may be used to endorse or promote products derived 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * from this software without specific prior written permission. 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontCache.h" 328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Font.h" 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontFallbackList.h" 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontPlatformData.h" 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "FontSelector.h" 378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/HashMap.h> 388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <wtf/ListHashSet.h> 39635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <wtf/StdLibExtras.h> 40f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick#include <wtf/text/StringHash.h> 418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace WTF; 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WebCore { 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectFontCache* fontCache() 47635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 48635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(FontCache, globalFontCache, ()); 49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return &globalFontCache; 50635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 51635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 52635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectFontCache::FontCache() 53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 56ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochstruct FontPlatformDataCacheKey { 57ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WTF_MAKE_FAST_ALLOCATED; 58ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochpublic: 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FontPlatformDataCacheKey(const AtomicString& family = AtomicString(), unsigned size = 0, unsigned weight = 0, bool italic = false, 602bde8e466a4451c7319e3a072d118917957d6554Steve Block bool isPrinterFont = false, FontRenderingMode renderingMode = NormalRenderingMode, FontOrientation orientation = Horizontal, 612bde8e466a4451c7319e3a072d118917957d6554Steve Block TextOrientation textOrientation = TextOrientationVerticalRight, FontWidthVariant widthVariant = RegularWidth) 626c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen : m_size(size) 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_weight(weight) 646c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen , m_family(family) 658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_italic(italic) 668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_printerFont(isPrinterFont) 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project , m_renderingMode(renderingMode) 68e14391e94c850b8bd03680c23b38978db68687a8John Reck , m_orientation(orientation) 692bde8e466a4451c7319e3a072d118917957d6554Steve Block , m_textOrientation(textOrientation) 702fc2651226baac27029e38c9d6ef883fa32084dbSteve Block , m_widthVariant(widthVariant) 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FontPlatformDataCacheKey(HashTableDeletedValueType) : m_size(hashTableDeletedSize()) { } 758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool isHashTableDeletedValue() const { return m_size == hashTableDeletedSize(); } 768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool operator==(const FontPlatformDataCacheKey& other) const 788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return equalIgnoringCase(m_family, other.m_family) && m_size == other.m_size && 808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_weight == other.m_weight && m_italic == other.m_italic && m_printerFont == other.m_printerFont && 812bde8e466a4451c7319e3a072d118917957d6554Steve Block m_renderingMode == other.m_renderingMode && m_orientation == other.m_orientation && m_textOrientation == other.m_textOrientation && m_widthVariant == other.m_widthVariant; 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned m_size; 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned m_weight; 866c2af9490927c3c5959b5cb07461b646f8b32f6cKristian Monsen AtomicString m_family; 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool m_italic; 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool m_printerFont; 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FontRenderingMode m_renderingMode; 90e14391e94c850b8bd03680c23b38978db68687a8John Reck FontOrientation m_orientation; 912bde8e466a4451c7319e3a072d118917957d6554Steve Block TextOrientation m_textOrientation; 922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block FontWidthVariant m_widthVariant; 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectprivate: 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static unsigned hashTableDeletedSize() { return 0xFFFFFFFFU; } 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectinline unsigned computeHash(const FontPlatformDataCacheKey& fontKey) 998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1002fc2651226baac27029e38c9d6ef883fa32084dbSteve Block unsigned hashCodes[5] = { 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project CaseFoldingHash::hash(fontKey.m_family), 1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fontKey.m_size, 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project fontKey.m_weight, 1042fc2651226baac27029e38c9d6ef883fa32084dbSteve Block fontKey.m_widthVariant, 1052bde8e466a4451c7319e3a072d118917957d6554Steve Block static_cast<unsigned>(fontKey.m_textOrientation) << 4 | static_cast<unsigned>(fontKey.m_orientation) << 3 | static_cast<unsigned>(fontKey.m_italic) << 2 | static_cast<unsigned>(fontKey.m_printerFont) << 1 | static_cast<unsigned>(fontKey.m_renderingMode) 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project }; 1072bde8e466a4451c7319e3a072d118917957d6554Steve Block return StringHasher::hashMemory<sizeof(hashCodes)>(hashCodes); 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct FontPlatformDataCacheKeyHash { 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static unsigned hash(const FontPlatformDataCacheKey& font) 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return computeHash(font); 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static bool equal(const FontPlatformDataCacheKey& a, const FontPlatformDataCacheKey& b) 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return a == b; 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static const bool safeToCompareToEmptyOrDeleted = true; 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochstruct FontPlatformDataCacheKeyTraits : WTF::SimpleClassHashTraits<FontPlatformDataCacheKey> { }; 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef HashMap<FontPlatformDataCacheKey, FontPlatformData*, FontPlatformDataCacheKeyHash, FontPlatformDataCacheKeyTraits> FontPlatformDataCache; 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic FontPlatformDataCache* gFontPlatformDataCache = 0; 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const AtomicString& alternateFamilyName(const AtomicString& familyName) 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Alias Courier <-> Courier New 133635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(AtomicString, courier, ("Courier")); 134635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(AtomicString, courierNew, ("Courier New")); 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (equalIgnoringCase(familyName, courier)) 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return courierNew; 137d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !OS(WINDOWS) 1388f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // On Windows, Courier New (truetype font) is always present and 1398f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Courier is a bitmap font. So, we don't want to map Courier New to 1408f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Courier. 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (equalIgnoringCase(familyName, courierNew)) 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return courier; 1438f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Alias Times and Times New Roman. 146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(AtomicString, times, ("Times")); 147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(AtomicString, timesNewRoman, ("Times New Roman")); 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (equalIgnoringCase(familyName, times)) 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return timesNewRoman; 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (equalIgnoringCase(familyName, timesNewRoman)) 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return times; 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Alias Arial and Helvetica 154635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(AtomicString, arial, ("Arial")); 155635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DEFINE_STATIC_LOCAL(AtomicString, helvetica, ("Helvetica")); 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (equalIgnoringCase(familyName, arial)) 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return helvetica; 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (equalIgnoringCase(familyName, helvetica)) 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return arial; 1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 161d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINDOWS) 1628f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // On Windows, bitmap fonts are blocked altogether so that we have to 1638f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // alias MS Sans Serif (bitmap font) -> Microsoft Sans Serif (truetype font) 1648f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian DEFINE_STATIC_LOCAL(AtomicString, msSans, ("MS Sans Serif")); 1658f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian DEFINE_STATIC_LOCAL(AtomicString, microsoftSans, ("Microsoft Sans Serif")); 1668f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (equalIgnoringCase(familyName, msSans)) 1678f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return microsoftSans; 1688f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // Alias MS Serif (bitmap) -> Times New Roman (truetype font). There's no 1708f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian // 'Microsoft Sans Serif-equivalent' for Serif. 1718f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian static AtomicString msSerif("MS Serif"); 1728f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian if (equalIgnoringCase(familyName, msSerif)) 1738f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian return timesNewRoman; 1748f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian#endif 1758f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return emptyAtom; 1778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectFontPlatformData* FontCache::getCachedFontPlatformData(const FontDescription& fontDescription, 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const AtomicString& familyName, 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool checkingAlternateName) 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!gFontPlatformDataCache) { 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gFontPlatformDataCache = new FontPlatformDataCache; 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project platformInit(); 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FontPlatformDataCacheKey key(familyName, fontDescription.computedPixelSize(), fontDescription.weight(), fontDescription.italic(), 1892bde8e466a4451c7319e3a072d118917957d6554Steve Block fontDescription.usePrinterFont(), fontDescription.renderingMode(), fontDescription.orientation(), 1902bde8e466a4451c7319e3a072d118917957d6554Steve Block fontDescription.textOrientation(), fontDescription.widthVariant()); 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FontPlatformData* result = 0; 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project bool foundResult; 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FontPlatformDataCache::iterator it = gFontPlatformDataCache->find(key); 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (it == gFontPlatformDataCache->end()) { 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = createFontPlatformData(fontDescription, familyName); 1968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gFontPlatformDataCache->set(key, result); 1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project foundResult = result; 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 1998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = it->second; 2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project foundResult = true; 2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!foundResult && !checkingAlternateName) { 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We were unable to find a font. We have a small set of fonts that we alias to other names, 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // e.g., Arial/Helvetica, Courier/Courier New, etc. Try looking up the font under the aliased name. 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const AtomicString& alternateName = alternateFamilyName(familyName); 2078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!alternateName.isEmpty()) 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = getCachedFontPlatformData(fontDescription, alternateName, true); 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result) 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gFontPlatformDataCache->set(key, new FontPlatformData(*result)); // Cache the result under the old name. 2118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result; 2148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct FontDataCacheKeyHash { 2178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static unsigned hash(const FontPlatformData& platformData) 2188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return platformData.hash(); 2208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static bool equal(const FontPlatformData& a, const FontPlatformData& b) 2238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 2248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return a == b; 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static const bool safeToCompareToEmptyOrDeleted = true; 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstruct FontDataCacheKeyTraits : WTF::GenericHashTraits<FontPlatformData> { 2318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static const bool emptyValueIsZero = true; 2328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static const bool needsDestruction = true; 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static const FontPlatformData& emptyValue() 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 2358f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian DEFINE_STATIC_LOCAL(FontPlatformData, key, (0.f, false, false)); 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return key; 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static void constructDeletedValue(FontPlatformData& slot) 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project new (&slot) FontPlatformData(HashTableDeletedValue); 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static bool isDeletedValue(const FontPlatformData& value) 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project { 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return value.isHashTableDeletedValue(); 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}; 2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef HashMap<FontPlatformData, pair<SimpleFontData*, unsigned>, FontDataCacheKeyHash, FontDataCacheKeyTraits> FontDataCache; 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic FontDataCache* gFontDataCache = 0; 2518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst int cMaxInactiveFontData = 120; // Pretty Low Threshold 25381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochconst int cTargetInactiveFontData = 100; 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic ListHashSet<const SimpleFontData*>* gInactiveFontData = 0; 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve BlockSimpleFontData* FontCache::getCachedFontData(const FontDescription& fontDescription, const AtomicString& family, bool checkingAlternateName) 2578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 2588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block FontPlatformData* platformData = getCachedFontPlatformData(fontDescription, family, checkingAlternateName); 2598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (!platformData) 2608a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return 0; 2618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return getCachedFontData(platformData); 2638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 2648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectSimpleFontData* FontCache::getCachedFontData(const FontPlatformData* platformData) 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!platformData) 2688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 2698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!gFontDataCache) { 2718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gFontDataCache = new FontDataCache; 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gInactiveFontData = new ListHashSet<const SimpleFontData*>; 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FontDataCache::iterator result = gFontDataCache->find(*platformData); 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result == gFontDataCache->end()) { 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project pair<SimpleFontData*, unsigned> newValue(new SimpleFontData(*platformData), 1); 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gFontDataCache->set(*platformData, newValue); 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return newValue.first; 2808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result.get()->second.second++) { 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(gInactiveFontData->contains(result.get()->second.first)); 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gInactiveFontData->remove(result.get()->second.first); 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return result.get()->second.first; 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::releaseFontData(const SimpleFontData* fontData) 2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(gFontDataCache); 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!fontData->isCustomFont()); 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FontDataCache::iterator it = gFontDataCache->find(fontData->platformData()); 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(it != gFontDataCache->end()); 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!--it->second.second) { 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gInactiveFontData->add(fontData); 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (gInactiveFontData->size() > cMaxInactiveFontData) 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project purgeInactiveFontData(gInactiveFontData->size() - cTargetInactiveFontData); 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::purgeInactiveFontData(int count) 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!gInactiveFontData) 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static bool isPurging; // Guard against reentry when e.g. a deleted FontData releases its small caps FontData. 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (isPurging) 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isPurging = true; 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3155f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian Vector<const SimpleFontData*, 20> fontDataToDelete; 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ListHashSet<const SimpleFontData*>::iterator end = gInactiveFontData->end(); 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ListHashSet<const SimpleFontData*>::iterator it = gInactiveFontData->begin(); 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = 0; i < count && it != end; ++it, ++i) { 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const SimpleFontData* fontData = *it.get(); 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gFontDataCache->remove(fontData->platformData()); 3215f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian fontDataToDelete.append(fontData); 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (it == end) { 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Removed everything 3268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gInactiveFontData->clear(); 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = 0; i < count; ++i) 3298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gInactiveFontData->remove(gInactiveFontData->begin()); 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3325f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian size_t fontDataToDeleteCount = fontDataToDelete.size(); 3335f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian for (size_t i = 0; i < fontDataToDeleteCount; ++i) 3345f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian delete fontDataToDelete[i]; 3355f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 3360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (gFontPlatformDataCache) { 3370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch Vector<FontPlatformDataCacheKey> keysToRemove; 3380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch keysToRemove.reserveInitialCapacity(gFontPlatformDataCache->size()); 3390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch FontPlatformDataCache::iterator platformDataEnd = gFontPlatformDataCache->end(); 3400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (FontPlatformDataCache::iterator platformData = gFontPlatformDataCache->begin(); platformData != platformDataEnd; ++platformData) { 3410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch if (platformData->second && !gFontDataCache->contains(*platformData->second)) 3420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch keysToRemove.append(platformData->first); 3430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch } 3440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch 3450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch size_t keysToRemoveCount = keysToRemove.size(); 3460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch for (size_t i = 0; i < keysToRemoveCount; ++i) 3470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch delete gFontPlatformDataCache->take(keysToRemove[i]); 3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project isPurging = false; 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsize_t FontCache::fontDataCount() 3548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (gFontDataCache) 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return gFontDataCache->size(); 3578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectsize_t FontCache::inactiveFontDataCount() 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (gInactiveFontData) 3638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return gInactiveFontData->size(); 3648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectconst FontData* FontCache::getFontData(const Font& font, int& familyIndex, FontSelector* fontSelector) 3688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3698a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block SimpleFontData* result = 0; 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project int startIndex = familyIndex; 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const FontFamily* startFamily = &font.fontDescription().family(); 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (int i = 0; startFamily && i < startIndex; i++) 3748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project startFamily = startFamily->next(); 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project const FontFamily* currFamily = startFamily; 3768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project while (currFamily && !result) { 3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project familyIndex++; 3788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (currFamily->family().length()) { 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fontSelector) { 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project FontData* data = fontSelector->getFontData(font.fontDescription(), currFamily->family()); 3818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (data) 3828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return data; 3838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block result = getCachedFontData(font.fontDescription(), currFamily->family()); 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project currFamily = currFamily->next(); 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!currFamily) 3908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project familyIndex = cAllFamiliesScanned; 3918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result) 3938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // We didn't find a font. Try to find a similar font using our own specific knowledge about our platform. 3948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // For example on OS X, we know to map any families containing the words Arabic, Pashto, or Urdu to the 3958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Geeza Pro font. 3968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = getSimilarFontPlatformData(font); 3978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!result && startIndex == 0) { 3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If it's the primary font that we couldn't find, we try the following. In all other cases, we will 4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // just use per-character system fallback. 4018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (fontSelector) { 4038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Try the user's preferred standard font. 4048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (FontData* data = fontSelector->getFontData(font.fontDescription(), "-webkit-standard")) 4058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return data; 4068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Still no result. Hand back our last resort fallback font. 4098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project result = getLastResortFallbackFont(font.fontDescription()); 4108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return result; 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic HashSet<FontSelector*>* gClients; 4158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::addClient(FontSelector* client) 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!gClients) 4198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gClients = new HashSet<FontSelector*>; 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!gClients->contains(client)); 4228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gClients->add(client); 4238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::removeClient(FontSelector* client) 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(gClients); 4288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(gClients->contains(client)); 4298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gClients->remove(client); 4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic unsigned gGeneration = 0; 4348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectunsigned FontCache::generation() 4368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return gGeneration; 4388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid FontCache::invalidate() 4418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 4428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!gClients) { 4438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(!gFontPlatformDataCache); 4448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 4458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (gFontPlatformDataCache) { 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project deleteAllValues(*gFontPlatformDataCache); 4498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project delete gFontPlatformDataCache; 4508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gFontPlatformDataCache = new FontPlatformDataCache; 4518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project gGeneration++; 4548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project Vector<RefPtr<FontSelector> > clients; 4568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project size_t numClients = gClients->size(); 4578f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian clients.reserveInitialCapacity(numClients); 4588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HashSet<FontSelector*>::iterator end = gClients->end(); 4598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (HashSet<FontSelector*>::iterator it = gClients->begin(); it != end; ++it) 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clients.append(*it); 4618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(numClients == clients.size()); 4638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project for (size_t i = 0; i < numClients; ++i) 4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clients[i]->fontCacheInvalidated(); 4658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project purgeInactiveFontData(); 4678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WebCore 470