Changeset 252044 in webkit
- Timestamp:
- Nov 5, 2019 12:17:58 AM (4 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r252036 r252044 1 2019-11-05 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [FreeType] Too slow running encoding/legacy-mb-korean/euc-kr WPT tests 4 https://bugs.webkit.org/show_bug.cgi?id=203544 5 6 Reviewed by Carlos Alberto Lopez Perez. 7 8 Use a cache for system fallbacks to keep the fonts sorted by font description. When a system fallback is needed 9 again for the same font description, but different characters, we just iterate the cached font set comparing the 10 charsets to get the best one. This avoids using FcFontMatch and FcFontSort is only called once per font description. 11 12 * platform/graphics/FontCache.h: 13 * platform/graphics/freetype/FontCacheFreeType.cpp: 14 (WebCore::CachedFontSet::CachedFontSet): 15 (WebCore::CachedFontSet::bestForCharacters): 16 (WebCore::FallbackFontDescriptionKey::FallbackFontDescriptionKey): 17 (WebCore::FallbackFontDescriptionKey::operator== const): 18 (WebCore::FallbackFontDescriptionKey::operator!= const): 19 (WebCore::FallbackFontDescriptionKey::isHashTableDeletedValue const): 20 (WebCore::FallbackFontDescriptionKey::computeHash const): 21 (WebCore::FallbackFontDescriptionKeyHash::hash): 22 (WebCore::FallbackFontDescriptionKeyHash::equal): 23 (WebCore::systemFallbackCache): 24 (WebCore::FontCache::systemFallbackForCharacters): 25 (WebCore::FontCache::platformPurgeInactiveFontData): 26 1 27 2019-11-04 Chris Dumez <cdumez@apple.com> 2 28 -
trunk/Source/WebCore/platform/graphics/FontCache.h
r251413 r252044 293 293 } 294 294 295 #if !PLATFORM(COCOA) 295 #if !PLATFORM(COCOA) && !USE(FREETYPE) 296 296 297 297 inline void FontCache::platformPurgeInactiveFontData() -
trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp
r248846 r252044 25 25 #include "CairoUniquePtr.h" 26 26 #include "CairoUtilities.h" 27 #include "CharacterProperties.h" 27 28 #include "FcUniquePtr.h" 28 29 #include "FloatConversion.h" … … 37 38 #include <fontconfig/fcfreetype.h> 38 39 #include <wtf/Assertions.h> 40 #include <wtf/HashFunctions.h> 41 #include <wtf/HashMap.h> 39 42 #include <wtf/text/CString.h> 40 43 … … 119 122 } 120 123 124 struct CachedPattern { 125 // The pattern is owned by the CachedFontSet. 126 FcPattern* pattern { nullptr }; 127 FcCharSet* charSet { nullptr }; 128 }; 129 130 class CachedFontSet { 131 WTF_MAKE_NONCOPYABLE(CachedFontSet); WTF_MAKE_FAST_ALLOCATED; 132 public: 133 explicit CachedFontSet(RefPtr<FcPattern>&& pattern) 134 : m_pattern(WTFMove(pattern)) 135 { 136 FcResult result; 137 m_fontSet.reset(FcFontSort(nullptr, m_pattern.get(), FcTrue, nullptr, &result)); 138 for (int i = 0; i < m_fontSet->nfont; ++i) { 139 FcPattern* pattern = m_fontSet->fonts[i]; 140 FcCharSet* charSet; 141 142 if (FcPatternGetCharSet(pattern, FC_CHARSET, 0, &charSet) == FcResultMatch) 143 m_patterns.append({ pattern, charSet }); 144 } 145 } 146 147 RefPtr<FcPattern> bestForCharacters(const UChar* characters, unsigned length) 148 { 149 if (m_patterns.isEmpty()) { 150 FcResult result; 151 return adoptRef(FcFontMatch(nullptr, m_pattern.get(), &result)); 152 } 153 154 FcUniquePtr<FcCharSet> fontConfigCharSet(FcCharSetCreate()); 155 UTF16UChar32Iterator iterator(characters, length); 156 UChar32 character = iterator.next(); 157 bool hasNonIgnorableCharacters = false; 158 while (character != iterator.end()) { 159 if (!isDefaultIgnorableCodePoint(character)) { 160 FcCharSetAddChar(fontConfigCharSet.get(), character); 161 hasNonIgnorableCharacters = true; 162 } 163 character = iterator.next(); 164 } 165 166 FcPattern* bestPattern = nullptr; 167 int minScore = std::numeric_limits<int>::max(); 168 if (hasNonIgnorableCharacters) { 169 for (const auto& cachedPattern : m_patterns) { 170 if (!cachedPattern.charSet) 171 continue; 172 173 int score = FcCharSetSubtractCount(fontConfigCharSet.get(), cachedPattern.charSet); 174 if (!score) 175 return adoptRef(FcFontRenderPrepare(nullptr, m_pattern.get(), cachedPattern.pattern)); 176 177 if (score < minScore) { 178 bestPattern = cachedPattern.pattern; 179 minScore = score; 180 } 181 } 182 } 183 184 if (bestPattern) 185 return adoptRef(FcFontRenderPrepare(nullptr, m_pattern.get(), bestPattern)); 186 187 // If there aren't fonts with the given characters or all characters are ignorable, the first one is the best match. 188 return adoptRef(FcFontRenderPrepare(nullptr, m_pattern.get(), m_patterns[0].pattern)); 189 } 190 191 private: 192 RefPtr<FcPattern> m_pattern; 193 FcUniquePtr<FcFontSet> m_fontSet; 194 Vector<CachedPattern> m_patterns; 195 }; 196 197 struct FallbackFontDescriptionKey { 198 FallbackFontDescriptionKey() = default; 199 200 FallbackFontDescriptionKey(const FontDescription& description, FontCache::PreferColoredFont preferColoredFont) 201 : descriptionKey(description) 202 , coloredFont(preferColoredFont == FontCache::PreferColoredFont::Yes) 203 { 204 } 205 206 explicit FallbackFontDescriptionKey(WTF::HashTableDeletedValueType deletedValue) 207 : descriptionKey(deletedValue) 208 { 209 } 210 211 bool operator==(const FallbackFontDescriptionKey& other) const 212 { 213 return descriptionKey == other.descriptionKey && coloredFont == other.coloredFont; 214 } 215 216 bool operator!=(const FallbackFontDescriptionKey& other) const 217 { 218 return !(*this == other); 219 } 220 221 bool isHashTableDeletedValue() const { return descriptionKey.isHashTableDeletedValue(); } 222 223 unsigned computeHash() const 224 { 225 return WTF::pairIntHash(descriptionKey.computeHash(), WTF::DefaultHash<bool>::Hash::hash(coloredFont)); 226 } 227 228 FontDescriptionKey descriptionKey; 229 bool coloredFont { false }; 230 }; 231 232 struct FallbackFontDescriptionKeyHash { 233 static unsigned hash(const FallbackFontDescriptionKey& key) { return key.computeHash(); } 234 static bool equal(const FallbackFontDescriptionKey& a, const FallbackFontDescriptionKey& b) { return a == b; } 235 static const bool safeToCompareToEmptyOrDeleted = true; 236 }; 237 238 using SystemFallbackCache = HashMap<FallbackFontDescriptionKey, std::unique_ptr<CachedFontSet>, FallbackFontDescriptionKeyHash, SimpleClassHashTraits<FallbackFontDescriptionKey>>; 239 static SystemFallbackCache& systemFallbackCache() 240 { 241 static NeverDestroyed<SystemFallbackCache> cache; 242 return cache.get(); 243 } 244 121 245 RefPtr<Font> FontCache::systemFallbackForCharacters(const FontDescription& description, const Font*, IsForPlatformFont, PreferColoredFont preferColoredFont, const UChar* characters, unsigned length) 122 246 { 123 FcUniquePtr<FcCharSet> fontConfigCharSet(FcCharSetCreate()); 124 UTF16UChar32Iterator iterator(characters, length); 125 UChar32 character = iterator.next(); 126 while (character != iterator.end()) { 127 FcCharSetAddChar(fontConfigCharSet.get(), character); 128 character = iterator.next(); 129 } 130 131 RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate()); 132 FcPatternAddCharSet(pattern.get(), FC_CHARSET, fontConfigCharSet.get()); 133 134 FcPatternAddBool(pattern.get(), FC_SCALABLE, FcTrue); 247 auto addResult = systemFallbackCache().ensure(FallbackFontDescriptionKey(description, preferColoredFont), [&description, preferColoredFont]() -> std::unique_ptr<CachedFontSet> { 248 RefPtr<FcPattern> pattern = adoptRef(FcPatternCreate()); 249 FcPatternAddBool(pattern.get(), FC_SCALABLE, FcTrue); 135 250 #ifdef FC_COLOR 136 if (preferColoredFont == PreferColoredFont::Yes)137 FcPatternAddBool(pattern.get(), FC_COLOR, FcTrue);251 if (preferColoredFont == PreferColoredFont::Yes) 252 FcPatternAddBool(pattern.get(), FC_COLOR, FcTrue); 138 253 #endif 139 140 if (!configurePatternForFontDescription(pattern.get(), description)) 254 if (!configurePatternForFontDescription(pattern.get(), description)) 255 return nullptr; 256 257 FcConfigSubstitute(nullptr, pattern.get(), FcMatchPattern); 258 cairo_ft_font_options_substitute(getDefaultCairoFontOptions(), pattern.get()); 259 FcDefaultSubstitute(pattern.get()); 260 261 return makeUnique<CachedFontSet>(WTFMove(pattern)); 262 }); 263 264 if (!addResult.iterator->value) 141 265 return nullptr; 142 266 143 FcConfigSubstitute(nullptr, pattern.get(), FcMatchPattern); 144 cairo_ft_font_options_substitute(getDefaultCairoFontOptions(), pattern.get()); 145 FcDefaultSubstitute(pattern.get()); 146 147 FcResult fontConfigResult; 148 RefPtr<FcPattern> resultPattern = adoptRef(FcFontMatch(nullptr, pattern.get(), &fontConfigResult)); 267 RefPtr<FcPattern> resultPattern = addResult.iterator->value->bestForCharacters(characters, length); 149 268 if (!resultPattern) 150 269 return nullptr; … … 156 275 FontPlatformData alternateFontData(fontFace.get(), resultPattern.get(), description.computedPixelSize(), fixedWidth, syntheticBold, syntheticOblique, description.orientation()); 157 276 return fontForPlatformData(alternateFontData); 277 } 278 279 void FontCache::platformPurgeInactiveFontData() 280 { 281 systemFallbackCache().clear(); 158 282 } 159 283
Note: See TracChangeset
for help on using the changeset viewer.