blob: 15e7c978229edaaf4a220fe638d36cf39081daf3 [file] [log] [blame]
[email protected]354de9e2014-08-07 03:27:191// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_FONT_FAMILY_CACHE_H_
6#define CHROME_BROWSER_FONT_FAMILY_CACHE_H_
7
Jan Wilken Dörriead587c32021-03-11 14:09:278#include <string>
brettw84cff3f2017-06-29 18:26:509#include <unordered_map>
10
[email protected]354de9e2014-08-07 03:27:1911#include "base/gtest_prod_util.h"
avi6846aef2015-12-26 01:09:3812#include "base/macros.h"
[email protected]354de9e2014-08-07 03:27:1913#include "base/strings/string16.h"
14#include "base/supports_user_data.h"
Brett Wilson21cf626a2017-09-07 00:30:2015#include "chrome/browser/font_pref_change_notifier.h"
Gyuyoung Kim1ac4ca782020-09-11 03:32:5116#include "third_party/blink/public/common/web_preferences/web_preferences.h"
[email protected]354de9e2014-08-07 03:27:1917
18class PrefService;
19class Profile;
20
21FORWARD_DECLARE_TEST(FontFamilyCacheTest, Caching);
22
23// Caches font family preferences associated with a PrefService. This class
24// relies on the assumption that each concatenation of map_name + '.' + script
25// is a unique string. It also relies on the assumption that the (const char*)
brettw84cff3f2017-06-29 18:26:5026// keys used in both inner and outer maps are compile time constants.
Erik Chen8be820612017-08-29 23:38:1827// This class caches the strings necessary to update
Gyuyoung Kim1ac4ca782020-09-11 03:32:5128// "blink::web_pref::ScriptFontFamilyMap". This is necessary since Chrome
29// attempts to update blink::web_pref::ScriptFontFamilyMap 20000 times at
30// startup. See https://crbug.com/308095.
Evan Stadecf0da232019-10-03 15:25:2131class FontFamilyCache : public base::SupportsUserData::Data {
[email protected]354de9e2014-08-07 03:27:1932 public:
33 explicit FontFamilyCache(Profile* profile);
Daniel Chenga542fca2014-10-21 09:51:2934 ~FontFamilyCache() override;
[email protected]354de9e2014-08-07 03:27:1935
36 // Gets or creates the relevant FontFamilyCache, and then fills |map|.
37 static void FillFontFamilyMap(Profile* profile,
38 const char* map_name,
Gyuyoung Kim1ac4ca782020-09-11 03:32:5139 blink::web_pref::ScriptFontFamilyMap* map);
[email protected]354de9e2014-08-07 03:27:1940
41 // Fills |map| with font family preferences.
42 void FillFontFamilyMap(const char* map_name,
Gyuyoung Kim1ac4ca782020-09-11 03:32:5143 blink::web_pref::ScriptFontFamilyMap* map);
[email protected]354de9e2014-08-07 03:27:1944
45 protected:
46 // Exposed and virtual for testing.
47 // Fetches the font without checking the cache.
48 virtual base::string16 FetchFont(const char* script, const char* map_name);
49
50 private:
51 FRIEND_TEST_ALL_PREFIXES(::FontFamilyCacheTest, Caching);
52
53 // Map from script to font.
54 // Key comparison uses pointer equality.
brettw84cff3f2017-06-29 18:26:5055 using ScriptFontMap = std::unordered_map<const char*, base::string16>;
[email protected]354de9e2014-08-07 03:27:1956
57 // Map from font family to ScriptFontMap.
58 // Key comparison uses pointer equality.
brettw84cff3f2017-06-29 18:26:5059 using FontFamilyMap = std::unordered_map<const char*, ScriptFontMap>;
[email protected]354de9e2014-08-07 03:27:1960
61 // Checks the cache for the font. If not present, fetches the font and stores
62 // the result in the cache.
63 // This method needs to be very fast, because it's called ~20,000 times on a
64 // fresh launch with an empty profile. It's important to avoid unnecessary
65 // object construction, hence the heavy use of const char* and the minimal use
66 // of std::string.
67 // |script| and |map_name| must be compile time constants. Two behaviors rely
68 // on this: key comparison uses pointer equality, and keys must outlive the
brettw84cff3f2017-06-29 18:26:5069 // maps.
[email protected]354de9e2014-08-07 03:27:1970 base::string16 FetchAndCacheFont(const char* script, const char* map_name);
71
72 // Called when font family preferences changed.
73 // Invalidates the cached entry, and removes the relevant observer.
74 // Note: It is safe to remove the observer from the pref change callback.
75 void OnPrefsChanged(const std::string& pref_name);
76
[email protected]354de9e2014-08-07 03:27:1977 // Cache of font family preferences.
78 FontFamilyMap font_family_map_;
79
80 // Weak reference.
81 // Note: The lifetime of this object is tied to the lifetime of the
82 // PrefService, so there is no worry about an invalid pointer.
83 const PrefService* prefs_;
84
Evan Stadecf0da232019-10-03 15:25:2185 // Reacts to profile font changes. |font_change_registrar_| will be
86 // automatically unregistered when the FontPrefChangeNotifier is destroyed as
87 // part of Profile destruction, thus ensuring safe unregistration even though
88 // |this| is destroyed after the Profile destructor completes as part of
89 // Profile's super class destructor ~base::SupportsUserData.
Brett Wilson21cf626a2017-09-07 00:30:2090 FontPrefChangeNotifier::Registrar font_change_registrar_;
[email protected]354de9e2014-08-07 03:27:1991
[email protected]354de9e2014-08-07 03:27:1992 DISALLOW_COPY_AND_ASSIGN(FontFamilyCache);
93};
94
95#endif // CHROME_BROWSER_FONT_FAMILY_CACHE_H_