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

Side by Side Diff: chrome/browser/android/vr_shell/font_fallback.cc

Issue 2863693002: Fallback Font Cache and Character Hinting for VRShell (Closed)
Patch Set: SkTypeface complete type 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
(Empty)
1 // Copyright 2017 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 #include "chrome/browser/android/vr_shell/font_fallback.h"
6
7 #include <map>
8 #include <set>
9 #include <string>
10 #include <vector>
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
20 namespace vr_shell {
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(std::move(typeface)));
35 }
36
37 bool HasGlyphForCharacter(UChar32 character) {
38 // In order to increase cache hits, the cache is script based rather than
39 // character based. This also limits the cache size to the number of Unicode
40 // scripts (174 at the time of writing).
41 UErrorCode err = UErrorCode::U_ZERO_ERROR;
42 UScriptCode script = uscript_getScript(character, &err);
43 if (!U_SUCCESS(err) || script == UScriptCode::USCRIPT_INVALID_CODE)
44 return false;
45 auto& supported = supported_scripts_[script];
46 if (supported != UNDEFINED)
47 return supported == KNOWN;
48 uint16_t glyph_id;
49 paint_.textToGlyphs(&character, sizeof(UChar32), &glyph_id);
50 supported = glyph_id ? KNOWN : UNKNOWN;
51 return glyph_id;
52 }
53 std::string GetFontName() { return name_; }
54
55 private:
56 explicit CachedFont(sk_sp<SkTypeface> skia_face) {
57 SkString sk_name;
58 skia_face->getFamilyName(&sk_name);
59 name_ = std::string(sk_name.c_str(), sk_name.size());
60 paint_.setTypeface(std::move(skia_face));
61 paint_.setTextEncoding(SkPaint::kUTF32_TextEncoding);
62 }
63
64 SkPaint paint_;
65 std::map<UScriptCode, KnownGlyph> supported_scripts_;
66 std::string name_;
67
68 DISALLOW_COPY_AND_ASSIGN(CachedFont);
69 };
70
71 using FontCache = std::map<SkFontID, std::unique_ptr<CachedFont>>;
72 base::LazyInstance<FontCache>::Leaky g_fonts = LAZY_INSTANCE_INITIALIZER;
73
74 class CachedFontSet {
75 public:
76 CachedFontSet() : locale_() {}
77 ~CachedFontSet() = default;
78
79 void SetLocale(const std::string& locale) {
80 // Store font list for one locale at a time.
81 if (locale != locale_) {
82 font_ids_.clear();
83 unknown_chars_.clear();
84 locale_ = locale;
85 }
86 }
87
88 std::string GetFallbackFontNameForChar(UChar32 c) {
89 if (unknown_chars_.find(c) != unknown_chars_.end())
90 return "";
91 for (SkFontID font_id : font_ids_) {
92 std::unique_ptr<CachedFont>& font = g_fonts.Get()[font_id];
93 if (font->HasGlyphForCharacter(c))
94 return font->GetFontName();
95 }
96 sk_sp<SkFontMgr> font_mgr(SkFontMgr::RefDefault());
97 const char* bcp47_locales[] = {locale_.c_str()};
98 sk_sp<SkTypeface> tf(font_mgr->matchFamilyStyleCharacter(
99 nullptr, SkFontStyle(), locale_.empty() ? nullptr : bcp47_locales,
100 locale_.empty() ? 0 : 1, c));
101 if (tf) {
102 SkFontID font_id = tf->uniqueID();
103 font_ids_.push_back(font_id);
104 std::unique_ptr<CachedFont>& cached_font = g_fonts.Get()[font_id];
105 if (!cached_font)
106 cached_font = CachedFont::CreateForTypeface(tf);
107 return cached_font->GetFontName();
108 }
109 unknown_chars_.insert(c);
110 return std::string();
111 }
112
113 private:
114 std::string locale_;
115 std::vector<SkFontID> font_ids_;
116 std::set<UChar32> unknown_chars_;
117
118 DISALLOW_COPY_AND_ASSIGN(CachedFontSet);
119 };
120
121 base::LazyInstance<CachedFontSet>::Leaky g_cached_font_set =
122 LAZY_INSTANCE_INITIALIZER;
123
124 bool FontSupportsChar(const gfx::Font& font, UChar32 c) {
125 sk_sp<SkTypeface> typeface =
126 static_cast<gfx::PlatformFontLinux*>(font.platform_font())->typeface();
127 std::unique_ptr<CachedFont>& cached_font =
128 g_fonts.Get()[typeface->uniqueID()];
129 if (!cached_font)
130 cached_font = CachedFont::CreateForTypeface(std::move(typeface));
131 return cached_font->HasGlyphForCharacter(c);
132 }
133
134 } // namespace
135
136 std::string GetFallbackFontNameForChar(const gfx::Font& default_font,
137 UChar32 c,
138 const std::string& locale) {
139 if (FontSupportsChar(default_font, c))
140 return std::string();
141 CachedFontSet& cached_font_set = g_cached_font_set.Get();
142 cached_font_set.SetLocale(locale);
143 return cached_font_set.GetFallbackFontNameForChar(c);
144 }
145
146 } // namespace vr_shell
OLDNEW
« no previous file with comments | « chrome/browser/android/vr_shell/font_fallback.h ('k') | chrome/browser/android/vr_shell/textures/ui_texture.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698