Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: ui/gfx/font_fallback_android.cc

Issue 2863693002: Fallback Font Cache and Character Hinting for VRShell (Closed)
Patch Set: using ICU script to increase cache hits Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gfx/font_fallback.h" 5 #include "ui/gfx/font_fallback_android.h"
6 6
7 #include <array>
8 #include <map>
9 #include <set>
7 #include <string> 10 #include <string>
8 #include <vector> 11 #include <vector>
9 12
13 #include "base/lazy_instance.h"
14 #include "base/memory/ptr_util.h"
15 #include "third_party/icu/source/common/unicode/uscript.h"
16 #include "third_party/skia/include/core/SkPaint.h"
17 #include "third_party/skia/include/core/SkTypeface.h"
18 #include "third_party/skia/include/ports/SkFontMgr.h"
19 #include "ui/gfx/platform_font_linux.h"
20
10 namespace gfx { 21 namespace gfx {
11 22
23 namespace {
24
25 constexpr int kMaxLocales = 1;
26
27 enum KnownGlyph {
28 UNDEFINED,
29 UNKNOWN,
30 KNOWN,
31 };
32
33 using ScriptCharMap = std::array<UChar32, UScriptCode::USCRIPT_CODE_LIMIT>;
34 base::LazyInstance<ScriptCharMap>::Leaky g_script_char_map =
mthiesse 2017/05/08 14:46:35 Doesn't look like you need this map. Just change
acondor_ 2017/05/08 16:55:29 Good catch. Done.
35 LAZY_INSTANCE_INITIALIZER;
36
37 class CachedFont {
38 public:
39 static std::unique_ptr<CachedFont> CreateForTypeface(
40 sk_sp<SkTypeface> typeface) {
41 return base::WrapUnique<CachedFont>(new CachedFont(typeface));
42 }
43 bool HasGlyphForCharacter(UChar32 character) {
44 // In order to increase cache hits, look for a character of the same
45 // script that was requested before. If this is the first one, store
46 // it for future lookups.
47 UErrorCode err;
48 UScriptCode script = uscript_getScript(character, &err);
49 UChar32 c;
50 if (U_SUCCESS(err)) {
51 UChar32& representative = g_script_char_map.Get()[script];
52 if (!representative)
53 representative = character;
54 c = representative;
55 } else {
56 c = character;
57 }
58 auto& supported = supported_characters_[c];
59 if (supported != UNDEFINED)
60 return supported == KNOWN;
61 uint16_t glyph_id;
62 paint_.textToGlyphs(&c, sizeof(UChar32), &glyph_id);
63 supported = glyph_id ? KNOWN : UNKNOWN;
64 return glyph_id;
65 }
66 std::string GetFontName() { return name_; }
67
68 private:
69 CachedFont(sk_sp<SkTypeface> skia_face) {
70 SkString sk_name;
71 skia_face->getFamilyName(&sk_name);
72 name_ = sk_name.c_str();
73 paint_.setTypeface(std::move(skia_face));
74 paint_.setTextEncoding(SkPaint::kUTF32_TextEncoding);
75 }
76
77 SkPaint paint_;
78 std::map<UChar32, KnownGlyph> supported_characters_;
79 std::string name_;
80 };
81
82 using FontCache = std::map<SkFontID, std::unique_ptr<CachedFont>>;
83 base::LazyInstance<FontCache>::Leaky g_fonts = LAZY_INSTANCE_INITIALIZER;
84
85 class CachedFontSet {
86 public:
87 CachedFontSet() : locale_() {}
88 ~CachedFontSet() = default;
89 void SetLocale(const std::string& locale) {
90 // Store font list for one locale at a time.
91 if (locale != locale_) {
92 font_ids_.clear();
93 unknown_chars_.clear();
94 locale_ = locale;
95 }
96 }
97
98 std::string GetFallbackFontNameForChar(UChar32 c) {
99 if (unknown_chars_.find(c) != unknown_chars_.end())
100 return "";
101 for (SkFontID font_id : font_ids_) {
102 std::unique_ptr<CachedFont>& font = g_fonts.Get()[font_id];
103 if (font->HasGlyphForCharacter(c))
104 return font->GetFontName();
105 }
106 sk_sp<SkFontMgr> font_mgr(SkFontMgr::RefDefault());
107 const char* bcp47_locales[kMaxLocales];
mthiesse 2017/05/08 14:46:35 I think this code would be more readable if you go
acondor_ 2017/05/08 16:55:29 The array is needed, but I got rid of the rest.
108 int locale_count = 0;
109 if (!locale_.empty())
110 bcp47_locales[locale_count++] = locale_.c_str();
111 sk_sp<SkTypeface> tf(font_mgr->matchFamilyStyleCharacter(
112 nullptr, SkFontStyle(), bcp47_locales, locale_count, c));
113 if (tf) {
114 SkFontID font_id = tf->uniqueID();
115 font_ids_.push_back(font_id);
116 std::unique_ptr<CachedFont>& cached_font = g_fonts.Get()[font_id];
117 if (!cached_font)
118 cached_font = CachedFont::CreateForTypeface(tf);
119 return cached_font->GetFontName();
120 }
121 unknown_chars_.insert(c);
122 return std::string();
123 }
124
125 private:
126 std::string locale_;
127 std::vector<SkFontID> font_ids_;
128 std::set<UChar32> unknown_chars_;
129 };
130
131 base::LazyInstance<CachedFontSet>::Leaky g_cached_font_set =
132 LAZY_INSTANCE_INITIALIZER;
133
134 bool FontSupportsChar(const gfx::Font& font, UChar32 c) {
135 sk_sp<SkTypeface> typeface =
136 static_cast<PlatformFontLinux*>(font.platform_font())->typeface();
137 std::unique_ptr<CachedFont>& cached_font =
138 g_fonts.Get()[typeface->uniqueID()];
139 if (!cached_font)
140 cached_font = CachedFont::CreateForTypeface(typeface);
141 return cached_font->HasGlyphForCharacter(c);
142 }
143
144 } // namespace
145
12 std::vector<Font> GetFallbackFonts(const Font& font) { 146 std::vector<Font> GetFallbackFonts(const Font& font) {
13 return std::vector<Font>(); 147 return std::vector<Font>();
14 } 148 }
15 149
150 std::string GetFallbackFontNameForChar(const Font& font,
151 UChar32 c,
152 const std::string& locale) {
153 if (FontSupportsChar(font, c))
154 return std::string();
155 CachedFontSet& cached_font_set = g_cached_font_set.Get();
156 cached_font_set.SetLocale(locale);
157 return cached_font_set.GetFallbackFontNameForChar(c);
158 }
159
16 } // namespace gfx 160 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698