1 /* 2 * Copyright (C) 2006, 2008 Apple Computer, 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 Computer, 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_CACHE_H_ 31 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_CACHE_H_ 32 33 #include <limits.h> 34 35 #include <memory> 36 #include <string> 37 38 #include "base/memory/scoped_refptr.h" 39 #include "build/build_config.h" 40 #include "mojo/public/cpp/bindings/remote.h" 41 #include "third_party/blink/renderer/platform/fonts/fallback_list_composite_key.h" 42 #include "third_party/blink/renderer/platform/fonts/font_cache_client.h" 43 #include "third_party/blink/renderer/platform/fonts/font_cache_key.h" 44 #include "third_party/blink/renderer/platform/fonts/font_data_cache.h" 45 #include "third_party/blink/renderer/platform/fonts/font_face_creation_params.h" 46 #include "third_party/blink/renderer/platform/fonts/font_fallback_priority.h" 47 #include "third_party/blink/renderer/platform/fonts/font_platform_data.h" 48 #include "third_party/blink/renderer/platform/fonts/shaping/shape_cache.h" 49 #include "third_party/blink/renderer/platform/heap/heap_allocator.h" 50 #include "third_party/blink/renderer/platform/heap/persistent.h" 51 #include "third_party/blink/renderer/platform/platform_export.h" 52 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" 53 #include "third_party/blink/renderer/platform/wtf/forward.h" 54 #include "third_party/blink/renderer/platform/wtf/hash_map.h" 55 #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" 56 #include "third_party/blink/renderer/platform/wtf/text/unicode.h" 57 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" 58 #include "third_party/skia/include/core/SkFontMgr.h" 59 #include "third_party/skia/include/core/SkRefCnt.h" 60 61 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) 62 #include "ui/gfx/font_fallback_linux.h" 63 #endif 64 65 #if defined(OS_WIN) 66 #include "third_party/blink/public/mojom/dwrite_font_proxy/dwrite_font_proxy.mojom-blink.h" 67 #include "third_party/blink/renderer/platform/fonts/win/fallback_family_style_cache_win.h" 68 #endif 69 70 class SkString; 71 class SkTypeface; 72 73 namespace base { 74 namespace trace_event { 75 class ProcessMemoryDump; 76 } 77 } 78 79 namespace blink { 80 81 class FontDescription; 82 class FontFaceCreationParams; 83 class FontFallbackMap; 84 class FontGlobalContext; 85 class SimpleFontData; 86 87 enum class AlternateFontName { 88 kAllowAlternate, 89 kNoAlternate, 90 kLocalUniqueFace, 91 kLastResort 92 }; 93 94 enum CreateIfNeeded { kDoNotCreate, kCreate }; 95 96 typedef HashMap<unsigned, 97 std::unique_ptr<FontPlatformData>, 98 WTF::IntHash<unsigned>, 99 WTF::UnsignedWithZeroKeyHashTraits<unsigned>> 100 SizedFontPlatformDataSet; 101 typedef HashMap<FontCacheKey, SizedFontPlatformDataSet> FontPlatformDataCache; 102 typedef HashMap<FallbackListCompositeKey, 103 std::unique_ptr<ShapeCache>, 104 FallbackListCompositeKeyHash, 105 FallbackListCompositeKeyTraits> 106 FallbackListShaperCache; 107 108 // "und-Zsye", the special locale for retrieving the color emoji font defined 109 // in UTS #51: https://unicode.org/reports/tr51/#Emoji_Script 110 extern const char kColorEmojiLocale[]; 111 112 class PLATFORM_EXPORT FontCache { 113 friend class FontCachePurgePreventer; 114 115 USING_FAST_MALLOC(FontCache); 116 117 public: 118 // FontCache initialisation on Windows depends on a global FontMgr being 119 // configured through a call from the browser process. CreateIfNeeded helps 120 // avoid early creation of a font cache when these globals have not yet 121 // been set. 122 static FontCache* GetFontCache(CreateIfNeeded = kCreate); 123 124 void ReleaseFontData(const SimpleFontData*); 125 126 scoped_refptr<SimpleFontData> FallbackFontForCharacter( 127 const FontDescription&, 128 UChar32, 129 const SimpleFontData* font_data_to_substitute, 130 FontFallbackPriority = FontFallbackPriority::kText); 131 132 // Also implemented by the platform. 133 void PlatformInit(); 134 135 scoped_refptr<SimpleFontData> GetFontData( 136 const FontDescription&, 137 const AtomicString&, 138 AlternateFontName = AlternateFontName::kAllowAlternate, 139 ShouldRetain = kRetain); 140 scoped_refptr<SimpleFontData> GetLastResortFallbackFont(const FontDescription&, 141 ShouldRetain = kRetain); 142 SimpleFontData* GetNonRetainedLastResortFallbackFont(const FontDescription&); 143 144 // Should be used in determining whether family names listed in font-family: 145 // ... are available locally. Only returns true if family name matches. 146 bool IsPlatformFamilyMatchAvailable(const FontDescription&, 147 const AtomicString& family); 148 149 // Should be used in determining whether the <abc> argument to local in 150 // @font-face { ... src: local(<abc>) } are available locally, which should 151 // match Postscript name or full font name. Compare 152 // https://drafts.csswg.org/css-fonts-3/#src-desc 153 // TODO crbug.com/627143 complete this and actually look at the right 154 // namerecords. 155 bool IsPlatformFontUniqueNameMatchAvailable( 156 const FontDescription&, 157 const AtomicString& unique_font_name); 158 159 static String FirstAvailableOrFirst(const String&); 160 161 // Returns the ShapeCache instance associated with the given cache key. 162 // Creates a new instance as needed and as such is guaranteed not to return 163 // a nullptr. Instances are managed by FontCache and are only guaranteed to 164 // be valid for the duration of the current session, as controlled by 165 // disable/enablePurging. 166 ShapeCache* GetShapeCache(const FallbackListCompositeKey&); 167 168 void AddClient(FontCacheClient*); 169 170 uint16_t Generation(); 171 void Invalidate(); 172 FontManager()173 sk_sp<SkFontMgr> FontManager() { return font_manager_; } 174 static void SetFontManager(sk_sp<SkFontMgr>); 175 176 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) 177 // These are needed for calling QueryRenderStyleForStrike, since 178 // gfx::GetFontRenderParams makes distinctions based on DSF. DeviceScaleFactor()179 static float DeviceScaleFactor() { return device_scale_factor_; } SetDeviceScaleFactor(float device_scale_factor)180 static void SetDeviceScaleFactor(float device_scale_factor) { 181 device_scale_factor_ = device_scale_factor; 182 } 183 #endif 184 185 #if !defined(OS_MAC) 186 static const AtomicString& SystemFontFamily(); 187 #else 188 static const AtomicString& LegacySystemFontFamily(); 189 #endif 190 191 #if !defined(OS_MAC) 192 static void SetSystemFontFamily(const AtomicString&); 193 #endif 194 195 #if defined(OS_WIN) 196 // TODO(https://crbug.com/808221) System font style configuration is not 197 // related to FontCache. Move it somewhere else, e.g. to WebThemeEngine. AntialiasedTextEnabled()198 static bool AntialiasedTextEnabled() { return antialiased_text_enabled_; } LcdTextEnabled()199 static bool LcdTextEnabled() { return lcd_text_enabled_; } SetAntialiasedTextEnabled(bool enabled)200 static void SetAntialiasedTextEnabled(bool enabled) { 201 antialiased_text_enabled_ = enabled; 202 } SetLCDTextEnabled(bool enabled)203 static void SetLCDTextEnabled(bool enabled) { lcd_text_enabled_ = enabled; } 204 static void AddSideloadedFontForTesting(sk_sp<SkTypeface>); 205 // Functions to cache and retrieve the system font metrics. 206 static void SetMenuFontMetrics(const wchar_t* family_name, 207 int32_t font_height); 208 static void SetSmallCaptionFontMetrics(const wchar_t* family_name, 209 int32_t font_height); 210 static void SetStatusFontMetrics(const wchar_t* family_name, 211 int32_t font_height); MenuFontHeight()212 static int32_t MenuFontHeight() { return menu_font_height_; } MenuFontFamily()213 static const AtomicString& MenuFontFamily() { 214 return *menu_font_family_name_; 215 } SmallCaptionFontHeight()216 static int32_t SmallCaptionFontHeight() { return small_caption_font_height_; } SmallCaptionFontFamily()217 static const AtomicString& SmallCaptionFontFamily() { 218 return *small_caption_font_family_name_; 219 } StatusFontHeight()220 static int32_t StatusFontHeight() { return status_font_height_; } StatusFontFamily()221 static const AtomicString& StatusFontFamily() { 222 return *status_font_family_name_; 223 } SetUseSkiaFontFallback(bool use_skia_font_fallback)224 static void SetUseSkiaFontFallback(bool use_skia_font_fallback) { 225 use_skia_font_fallback_ = use_skia_font_fallback; 226 } 227 228 // On Windows pre 8.1 establish a connection to the DWriteFontProxy service in 229 // order to retrieve family names for fallback lookup. 230 void EnsureServiceConnected(); 231 232 scoped_refptr<SimpleFontData> GetFallbackFamilyNameFromHardcodedChoices( 233 const FontDescription&, 234 UChar32 codepoint, 235 FontFallbackPriority fallback_priority); 236 237 scoped_refptr<SimpleFontData> GetDWriteFallbackFamily( 238 const FontDescription&, 239 UChar32 codepoint, 240 FontFallbackPriority fallback_priority); 241 #endif // defined(OS_WIN) 242 243 static void AcceptLanguagesChanged(const String&); 244 245 #if defined(OS_ANDROID) 246 static AtomicString GetGenericFamilyNameForScript( 247 const AtomicString& family_name, 248 const FontDescription&); 249 #endif // defined(OS_ANDROID) 250 251 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) 252 static bool GetFontForCharacter(UChar32, 253 const char* preferred_locale, 254 gfx::FallbackFontData*); 255 #endif // defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) 256 257 scoped_refptr<SimpleFontData> FontDataFromFontPlatformData( 258 const FontPlatformData*, 259 ShouldRetain = kRetain, 260 bool subpixel_ascent_descent = false); 261 262 void InvalidateShapeCache(); 263 264 static void CrashWithFontInfo(const FontDescription*); 265 266 // Memory reporting 267 void DumpFontPlatformDataCache(base::trace_event::ProcessMemoryDump*); 268 void DumpShapeResultCache(base::trace_event::ProcessMemoryDump*); 269 270 FontFallbackMap& GetFontFallbackMap(); 271 272 ~FontCache() = default; 273 274 private: 275 // BCP47 list used when requesting fallback font for a character. 276 // inlineCapacity is set to 4: the array vector not need to hold more than 4 277 // elements. 278 using Bcp47Vector = WTF::Vector<const char*, 4>; 279 280 scoped_refptr<SimpleFontData> PlatformFallbackFontForCharacter( 281 const FontDescription&, 282 UChar32, 283 const SimpleFontData* font_data_to_substitute, 284 FontFallbackPriority = FontFallbackPriority::kText); 285 sk_sp<SkTypeface> CreateTypefaceFromUniqueName( 286 const FontFaceCreationParams& creation_params); 287 288 static Bcp47Vector GetBcp47LocaleForRequest( 289 const FontDescription& font_description, 290 FontFallbackPriority fallback_priority); 291 292 friend class FontGlobalContext; 293 FontCache(); 294 295 void Purge(PurgeSeverity = kPurgeIfNeeded); 296 DisablePurging()297 void DisablePurging() { purge_prevent_count_++; } EnablePurging()298 void EnablePurging() { 299 DCHECK(purge_prevent_count_); 300 if (!--purge_prevent_count_) 301 Purge(kPurgeIfNeeded); 302 } 303 304 // FIXME: This method should eventually be removed. 305 FontPlatformData* GetFontPlatformData( 306 const FontDescription&, 307 const FontFaceCreationParams&, 308 AlternateFontName = AlternateFontName::kAllowAlternate); 309 #if !defined(OS_MAC) 310 FontPlatformData* SystemFontPlatformData(const FontDescription&); 311 #endif // !defined(OS_MAC) 312 313 // These methods are implemented by each platform. 314 std::unique_ptr<FontPlatformData> CreateFontPlatformData( 315 const FontDescription&, 316 const FontFaceCreationParams&, 317 float font_size, 318 AlternateFontName = AlternateFontName::kAllowAlternate); 319 std::unique_ptr<FontPlatformData> ScaleFontPlatformData( 320 const FontPlatformData&, 321 const FontDescription&, 322 const FontFaceCreationParams&, 323 float font_size); 324 325 sk_sp<SkTypeface> CreateTypeface(const FontDescription&, 326 const FontFaceCreationParams&, 327 std::string& name); 328 329 #if defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) 330 static AtomicString GetFamilyNameForCharacter(SkFontMgr*, 331 UChar32, 332 const FontDescription&, 333 FontFallbackPriority); 334 #endif // defined(OS_ANDROID) || defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) 335 336 scoped_refptr<SimpleFontData> FallbackOnStandardFontStyle( 337 const FontDescription&, 338 UChar32); 339 340 // When true, the font size is removed from primary keys in 341 // |font_platform_data_cache_|. The font size is not necessary in the primary 342 // key, because per-size FontPlatformData are held in a nested map. This is 343 // controlled by a base::Feature to assess impact with an experiment. 344 const bool no_size_in_key_; 345 346 // Don't purge if this count is > 0; 347 int purge_prevent_count_; 348 349 sk_sp<SkFontMgr> font_manager_; 350 351 // A leaky owning bare pointer. 352 static SkFontMgr* static_font_manager_; 353 354 #if defined(OS_WIN) 355 static bool antialiased_text_enabled_; 356 static bool lcd_text_enabled_; 357 static HashMap<String, sk_sp<SkTypeface>, CaseFoldingHash>* sideloaded_fonts_; 358 // The system font metrics cache. 359 static AtomicString* menu_font_family_name_; 360 static int32_t menu_font_height_; 361 static AtomicString* small_caption_font_family_name_; 362 static int32_t small_caption_font_height_; 363 static AtomicString* status_font_family_name_; 364 static int32_t status_font_height_; 365 static bool use_skia_font_fallback_; 366 367 // Windows creates an SkFontMgr for unit testing automatically. This flag is 368 // to ensure it's not happening in the production from the crash log. 369 bool is_test_font_mgr_ = false; 370 mojo::Remote<mojom::blink::DWriteFontProxy> service_; 371 std::unique_ptr<FallbackFamilyStyleCache> fallback_params_cache_; 372 #endif // defined(OS_WIN) 373 374 #if defined(OS_LINUX) || defined(OS_CHROMEOS) || defined(OS_BSD) 375 static float device_scale_factor_; 376 #endif 377 378 uint16_t generation_ = 0; 379 bool platform_init_ = false; 380 Persistent<HeapHashSet<WeakMember<FontCacheClient>>> font_cache_clients_; 381 FontPlatformDataCache font_platform_data_cache_; 382 FallbackListShaperCache fallback_list_shaper_cache_; 383 FontDataCache font_data_cache_; 384 385 Persistent<FontFallbackMap> font_fallback_map_; 386 387 void PurgePlatformFontDataCache(); 388 void PurgeFallbackListShaperCache(); 389 390 // A maximum float value to which we limit incoming font sizes. This is the 391 // smallest float so that multiplying it by 392 // FontCacheKey::PrecisionMultiplier() is still smaller than 393 // std::numeric_limits<unsigned>::max() - 1 in order to avoid hitting HashMap 394 // sentinel values (placed at std::numeric_limits<unsigned>::max() and 395 // std::numeric_limits<unsigned>::max() - 1) for SizedFontPlatformDataSet and 396 // FontPlatformDataCache. 397 const float font_size_limit_; 398 399 friend class SimpleFontData; // For fontDataFromFontPlatformData 400 friend class FontFallbackList; 401 402 DISALLOW_COPY_AND_ASSIGN(FontCache); 403 }; 404 405 class PLATFORM_EXPORT FontCachePurgePreventer { 406 USING_FAST_MALLOC(FontCachePurgePreventer); 407 408 public: FontCachePurgePreventer()409 FontCachePurgePreventer() { FontCache::GetFontCache()->DisablePurging(); } ~FontCachePurgePreventer()410 ~FontCachePurgePreventer() { FontCache::GetFontCache()->EnablePurging(); } 411 412 private: 413 DISALLOW_COPY_AND_ASSIGN(FontCachePurgePreventer); 414 }; 415 416 AtomicString ToAtomicString(const SkString&); 417 418 } // namespace blink 419 420 #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_CACHE_H_ 421