1/* 2 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved. 3 * Copyright (C) 2007-2008 Torch Mobile, Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Apple Inc. ("Apple") nor the names of 15 * its contributors may be used to endorse or promote products derived 16 * from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#ifndef FontCache_h 31#define FontCache_h 32 33#include "FontDescription.h" 34#include <limits.h> 35#include <wtf/Forward.h> 36#include <wtf/PassRefPtr.h> 37#include <wtf/RefPtr.h> 38#include <wtf/Vector.h> 39#include <wtf/text/WTFString.h> 40 41#if PLATFORM(IOS) 42#include <CoreText/CTFont.h> 43#endif 44 45#if OS(WINDOWS) 46#include <windows.h> 47#include <objidl.h> 48#include <mlang.h> 49#endif 50 51namespace WebCore { 52 53class Font; 54class FontPlatformData; 55class FontData; 56class FontSelector; 57class OpenTypeVerticalData; 58class SimpleFontData; 59 60#if PLATFORM(WIN) 61#if USE(IMLANG_FONT_LINK2) 62typedef IMLangFontLink2 IMLangFontLinkType; 63#else 64typedef IMLangFontLink IMLangFontLinkType; 65#endif 66#endif 67 68// This key contains the FontDescription fields other than family that matter when fetching FontDatas (platform fonts). 69struct FontDescriptionFontDataCacheKey { 70 explicit FontDescriptionFontDataCacheKey(unsigned size = 0) 71 : size(size) 72 , weight(0) 73 , flags(0) 74 { } 75 FontDescriptionFontDataCacheKey(const FontDescription& description) 76 : size(description.computedPixelSize()) 77 , weight(description.weight()) 78 , flags(makeFlagKey(description)) 79 { } 80 static unsigned makeFlagKey(const FontDescription& description) 81 { 82 return static_cast<unsigned>(description.widthVariant()) << 4 83 | static_cast<unsigned>(description.orientation()) << 3 84 | static_cast<unsigned>(description.italic()) << 2 85 | static_cast<unsigned>(description.usePrinterFont()) << 1 86 | static_cast<unsigned>(description.renderingMode()); 87 } 88 bool operator==(const FontDescriptionFontDataCacheKey& other) const 89 { 90 return size == other.size && weight == other.weight && flags == other.flags; 91 } 92 bool operator!=(const FontDescriptionFontDataCacheKey& other) const 93 { 94 return !(*this == other); 95 } 96 inline unsigned computeHash() const 97 { 98 return StringHasher::hashMemory<sizeof(FontDescriptionFontDataCacheKey)>(this); 99 } 100 unsigned size; 101 unsigned weight; 102 unsigned flags; 103}; 104 105class FontCache { 106 friend class FontCachePurgePreventer; 107 friend class WTF::NeverDestroyed<FontCache>; 108 109 WTF_MAKE_NONCOPYABLE(FontCache); WTF_MAKE_FAST_ALLOCATED; 110public: 111 friend FontCache& fontCache(); 112 113 enum ShouldRetain { Retain, DoNotRetain }; 114 115 PassRefPtr<FontData> getFontData(const FontDescription&, int& familyIndex, FontSelector*); 116 void releaseFontData(const SimpleFontData*); 117 118 // This method is implemented by the platform. 119 PassRefPtr<SimpleFontData> systemFallbackForCharacters(const FontDescription&, const SimpleFontData* originalFontData, bool isPlatformFont, const UChar* characters, int length); 120 121 // Also implemented by the platform. 122 void platformInit(); 123 124#if PLATFORM(IOS) 125 static float weightOfCTFont(CTFontRef); 126#endif 127#if PLATFORM(WIN) 128 IMLangFontLinkType* getFontLinkInterface(); 129 static void comInitialize(); 130 static void comUninitialize(); 131 static IMultiLanguage* getMultiLanguageInterface(); 132#endif 133 134 void getTraitsInFamily(const AtomicString&, Vector<unsigned>&); 135 136 PassRefPtr<SimpleFontData> getCachedFontData(const FontDescription&, const AtomicString&, bool checkingAlternateName = false, ShouldRetain = Retain); 137 PassRefPtr<SimpleFontData> getLastResortFallbackFont(const FontDescription&, ShouldRetain = Retain); 138 SimpleFontData* getNonRetainedLastResortFallbackFont(const FontDescription&); 139 140 void addClient(FontSelector*); 141 void removeClient(FontSelector*); 142 143 unsigned short generation(); 144 void invalidate(); 145 146 size_t fontDataCount(); 147 size_t inactiveFontDataCount(); 148 void purgeInactiveFontData(int count = INT_MAX); 149 150#if PLATFORM(WIN) 151 PassRefPtr<SimpleFontData> fontDataFromDescriptionAndLogFont(const FontDescription&, ShouldRetain, const LOGFONT&, AtomicString& outFontFamilyName); 152#endif 153 154#if ENABLE(OPENTYPE_VERTICAL) 155 typedef AtomicString FontFileKey; 156 PassRefPtr<OpenTypeVerticalData> getVerticalData(const FontFileKey&, const FontPlatformData&); 157#endif 158 159 struct SimpleFontFamily { 160 String name; 161 bool isBold; 162 bool isItalic; 163 }; 164 static void getFontFamilyForCharacters(const UChar* characters, size_t numCharacters, const char* preferredLocale, SimpleFontFamily*); 165 166private: 167 FontCache(); 168 ~FontCache(); 169 170 void disablePurging() { m_purgePreventCount++; } 171 void enablePurging() 172 { 173 ASSERT(m_purgePreventCount); 174 if (!--m_purgePreventCount) 175 purgeInactiveFontDataIfNeeded(); 176 } 177 178 void purgeInactiveFontDataIfNeeded(); 179 180 // FIXME: This method should eventually be removed. 181 FontPlatformData* getCachedFontPlatformData(const FontDescription&, const AtomicString& family, bool checkingAlternateName = false); 182 183 // These methods are implemented by each platform. 184#if PLATFORM(IOS) 185 FontPlatformData* getCustomFallbackFont(const UInt32, const FontDescription&); 186 PassRefPtr<SimpleFontData> getSystemFontFallbackForCharacters(const FontDescription&, const SimpleFontData*, const UChar* characters, int length); 187#endif 188 PassOwnPtr<FontPlatformData> createFontPlatformData(const FontDescription&, const AtomicString& family); 189#if PLATFORM(COCOA) 190 PassRefPtr<SimpleFontData> similarFontPlatformData(const FontDescription&); 191#endif 192 193 PassRefPtr<SimpleFontData> getCachedFontData(const FontPlatformData*, ShouldRetain = Retain); 194 195 // Don't purge if this count is > 0; 196 int m_purgePreventCount; 197 198#if PLATFORM(COCOA) 199 friend class ComplexTextController; 200#endif 201 friend class SimpleFontData; // For getCachedFontData(const FontPlatformData*) 202 friend class FontGlyphs; 203}; 204 205// Get the global fontCache. 206FontCache& fontCache(); 207 208class FontCachePurgePreventer { 209public: 210 FontCachePurgePreventer() { fontCache().disablePurging(); } 211 ~FontCachePurgePreventer() { fontCache().enablePurging(); } 212}; 213 214} 215 216#endif 217