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

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

Issue 2863693002: Fallback Font Cache and Character Hinting for VRShell (Closed)
Patch Set: bugfix on UScriptCode 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 <map>
8 #include <set>
7 #include <string> 9 #include <string>
8 #include <vector> 10 #include <vector>
9 11
12 #include "base/lazy_instance.h"
13 #include "base/memory/ptr_util.h"
14 #include "third_party/icu/source/common/unicode/uscript.h"
15 #include "third_party/skia/include/core/SkPaint.h"
16 #include "third_party/skia/include/core/SkTypeface.h"
17 #include "third_party/skia/include/ports/SkFontMgr.h"
18 #include "ui/gfx/platform_font_linux.h"
19
10 namespace gfx { 20 namespace gfx {
11 21
22 namespace {
23
24 enum KnownGlyph {
25 UNDEFINED,
26 UNKNOWN,
27 KNOWN,
28 };
29
30 class CachedFont {
31 public:
32 static std::unique_ptr<CachedFont> CreateForTypeface(
33 sk_sp<SkTypeface> typeface) {
34 return base::WrapUnique<CachedFont>(new CachedFont(typeface));
35 }
Alexei Svitkine (slow) 2017/05/09 14:52:17 Nit: Add an empty line after this.
acondor_ 2017/05/09 16:21:51 Done.
36 bool HasGlyphForCharacter(UChar32 character) {
37 // In order to increase cache hits, the cache is script based rather than
38 // character based. This also limits the cache size to the number of Unicode
39 // scripts (174 at the time of writing).
40 UErrorCode err;
41 UScriptCode script = uscript_getScript(character, &err);
42 if (!U_SUCCESS(err) || script == UScriptCode::USCRIPT_INVALID_CODE)
43 return false;
44 auto& supported = supported_scripts_[script];
45 if (supported != UNDEFINED)
46 return supported == KNOWN;
47 uint16_t glyph_id;
48 paint_.textToGlyphs(&character, sizeof(UChar32), &glyph_id);
49 supported = glyph_id ? KNOWN : UNKNOWN;
50 return glyph_id;
51 }
52 std::string GetFontName() { return name_; }
53
54 private:
55 CachedFont(sk_sp<SkTypeface> skia_face) {
56 SkString sk_name;
57 skia_face->getFamilyName(&sk_name);
58 name_ = sk_name.c_str();
59 paint_.setTypeface(std::move(skia_face));
60 paint_.setTextEncoding(SkPaint::kUTF32_TextEncoding);
61 }
62
63 SkPaint paint_;
64 std::map<UScriptCode, KnownGlyph> supported_scripts_;
65 std::string name_;
66 };
Alexei Svitkine (slow) 2017/05/09 14:52:17 Nit: DISALLOW_COPY_AND_ASSIGN()
acondor_ 2017/05/09 16:21:51 Done.
67
68 using FontCache = std::map<SkFontID, std::unique_ptr<CachedFont>>;
69 base::LazyInstance<FontCache>::Leaky g_fonts = LAZY_INSTANCE_INITIALIZER;
70
71 class CachedFontSet {
72 public:
73 CachedFontSet() : locale_() {}
74 ~CachedFontSet() = default;
Alexei Svitkine (slow) 2017/05/09 14:52:16 Nit: Add an empty line after this.
acondor_ 2017/05/09 16:21:51 Done.
75 void SetLocale(const std::string& locale) {
76 // Store font list for one locale at a time.
77 if (locale != locale_) {
78 font_ids_.clear();
79 unknown_chars_.clear();
80 locale_ = locale;
81 }
82 }
83
84 std::string GetFallbackFontNameForChar(UChar32 c) {
85 if (unknown_chars_.find(c) != unknown_chars_.end())
86 return "";
87 for (SkFontID font_id : font_ids_) {
88 std::unique_ptr<CachedFont>& font = g_fonts.Get()[font_id];
89 if (font->HasGlyphForCharacter(c))
90 return font->GetFontName();
91 }
92 sk_sp<SkFontMgr> font_mgr(SkFontMgr::RefDefault());
93 const char* bcp47_locales[] = {locale_.c_str()};
94 sk_sp<SkTypeface> tf(font_mgr->matchFamilyStyleCharacter(
95 nullptr, SkFontStyle(), locale_.empty() ? nullptr : bcp47_locales,
96 locale_.empty() ? 0 : 1, c));
97 if (tf) {
98 SkFontID font_id = tf->uniqueID();
99 font_ids_.push_back(font_id);
100 std::unique_ptr<CachedFont>& cached_font = g_fonts.Get()[font_id];
101 if (!cached_font)
102 cached_font = CachedFont::CreateForTypeface(tf);
103 return cached_font->GetFontName();
104 }
105 unknown_chars_.insert(c);
106 return std::string();
107 }
108
109 private:
110 std::string locale_;
111 std::vector<SkFontID> font_ids_;
112 std::set<UChar32> unknown_chars_;
113 };
Alexei Svitkine (slow) 2017/05/09 14:52:17 DISALLOW_COPY_AND_ASSIGN()
acondor_ 2017/05/09 16:21:51 Done.
114
115 base::LazyInstance<CachedFontSet>::Leaky g_cached_font_set =
116 LAZY_INSTANCE_INITIALIZER;
117
118 bool FontSupportsChar(const gfx::Font& font, UChar32 c) {
119 sk_sp<SkTypeface> typeface =
120 static_cast<PlatformFontLinux*>(font.platform_font())->typeface();
121 std::unique_ptr<CachedFont>& cached_font =
122 g_fonts.Get()[typeface->uniqueID()];
123 if (!cached_font)
124 cached_font = CachedFont::CreateForTypeface(typeface);
125 return cached_font->HasGlyphForCharacter(c);
126 }
127
128 } // namespace
129
12 std::vector<Font> GetFallbackFonts(const Font& font) { 130 std::vector<Font> GetFallbackFonts(const Font& font) {
13 return std::vector<Font>(); 131 return std::vector<Font>();
14 } 132 }
15 133
134 std::string GetFallbackFontNameForChar(const Font& default_font,
135 UChar32 c,
136 const std::string& locale) {
137 if (FontSupportsChar(default_font, c))
138 return std::string();
139 CachedFontSet& cached_font_set = g_cached_font_set.Get();
140 cached_font_set.SetLocale(locale);
141 return cached_font_set.GetFallbackFontNameForChar(c);
142 }
143
16 } // namespace gfx 144 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698