Skip to content

Instantly share code, notes, and snippets.

@emonkak
Created February 4, 2022 06:29
Show Gist options
  • Save emonkak/daa6c8fff98d0bd93e428c85b146ce56 to your computer and use it in GitHub Desktop.
Save emonkak/daa6c8fff98d0bd93e428c85b146ce56 to your computer and use it in GitHub Desktop.
diff --git a/components/services/font/font_service_app.cc b/components/services/font/font_service_app.cc
index 4bbeebcb5..5c8a6ee89 100644
--- a/components/services/font/font_service_app.cc
+++ b/components/services/font/font_service_app.cc
@@ -149,11 +149,13 @@ void FontServiceApp::OpenStream(uint32_t id_number,
void FontServiceApp::FallbackFontForCharacter(
uint32_t character,
const std::string& locale,
+ mojom::TypefaceStylePtr requested_style,
FallbackFontForCharacterCallback callback) {
TRACE_EVENT0("fonts", "FontServiceApp::FallbackFontForCharacter");
gfx::FallbackFontData fallback_font;
- if (gfx::GetFallbackFontForChar(character, locale, &fallback_font)) {
+ if (gfx::GetFallbackFontForChar(character, locale, requested_style,
+ &fallback_font)) {
size_t index = FindOrAddPath(fallback_font.filepath);
mojom::FontIdentityPtr identity(mojom::FontIdentity::New());
diff --git a/components/services/font/font_service_app.h b/components/services/font/font_service_app.h
index 811a3ea66..6289038c1 100644
--- a/components/services/font/font_service_app.h
+++ b/components/services/font/font_service_app.h
@@ -35,6 +35,7 @@ class FontServiceApp : public mojom::FontService {
void FallbackFontForCharacter(
uint32_t character,
const std::string& locale,
+ mojom::TypefaceStylePtr requested_style,
FallbackFontForCharacterCallback callback) override;
void FontRenderStyleForStrike(
const std::string& family,
diff --git a/components/services/font/public/cpp/font_loader.cc b/components/services/font/public/cpp/font_loader.cc
index 4be7f118f..a58455edf 100644
--- a/components/services/font/public/cpp/font_loader.cc
+++ b/components/services/font/public/cpp/font_loader.cc
@@ -70,13 +70,16 @@ sk_sp<SkTypeface> FontLoader::makeTypeface(const FontIdentity& identity) {
bool FontLoader::FallbackFontForCharacter(
uint32_t character,
std::string locale,
+ mojom::TypefaceStylePtr requested_style,
mojom::FontIdentityPtr* out_font_identity,
std::string* out_family_name,
bool* out_is_bold,
bool* out_is_italic) {
return thread_->FallbackFontForCharacter(character, std::move(locale),
- out_font_identity, out_family_name,
- out_is_bold, out_is_italic);
+ std::move(requested_style),
+ out_font_identity,
+ out_family_name, out_is_bold,
+ out_is_italic);
}
bool FontLoader::FontRenderStyleForStrike(
diff --git a/components/services/font/public/cpp/font_loader.h b/components/services/font/public/cpp/font_loader.h
index 413ce7567..767c31a3d 100644
--- a/components/services/font/public/cpp/font_loader.h
+++ b/components/services/font/public/cpp/font_loader.h
@@ -54,6 +54,7 @@ class FontLoader : public SkFontConfigInterface,
// true.
bool FallbackFontForCharacter(uint32_t character,
std::string locale,
+ mojom::TypefaceStylePtr requested_style,
mojom::FontIdentityPtr* out_identity,
std::string* out_family_name,
bool* out_is_bold,
diff --git a/components/services/font/public/cpp/font_service_thread.cc b/components/services/font/public/cpp/font_service_thread.cc
index 84446cdf0..01e32ed41 100644
--- a/components/services/font/public/cpp/font_service_thread.cc
+++ b/components/services/font/public/cpp/font_service_thread.cc
@@ -58,6 +58,7 @@ bool FontServiceThread::MatchFamilyName(
bool FontServiceThread::FallbackFontForCharacter(
uint32_t character,
std::string locale,
+ mojom::TypefaceStylePtr requested_style,
font_service::mojom::FontIdentityPtr* out_font_identity,
std::string* out_family_name,
bool* out_is_bold,
@@ -68,9 +69,9 @@ bool FontServiceThread::FallbackFontForCharacter(
task_runner_->PostTask(
FROM_HERE,
base::BindOnce(&FontServiceThread::FallbackFontForCharacterImpl, this,
- &done_event, character, std::move(locale), &out_valid,
- out_font_identity, out_family_name, out_is_bold,
- out_is_italic));
+ &done_event, character, std::move(locale),
+ std::move(requested_style), &out_valid, out_font_identity,
+ out_family_name, out_is_bold, out_is_italic));
done_event.Wait();
return out_valid;
@@ -245,6 +246,7 @@ void FontServiceThread::FallbackFontForCharacterImpl(
base::WaitableEvent* done_event,
uint32_t character,
std::string locale,
+ mojom::TypefaceStylePtr requested_style,
bool* out_valid,
font_service::mojom::FontIdentityPtr* out_font_identity,
std::string* out_family_name,
@@ -260,7 +262,7 @@ void FontServiceThread::FallbackFontForCharacterImpl(
pending_waitable_events_.insert(done_event);
font_service_->FallbackFontForCharacter(
- character, std::move(locale),
+ character, std::move(locale), std::move(requested_style),
base::BindOnce(&FontServiceThread::OnFallbackFontForCharacterComplete,
this, done_event, out_valid, out_font_identity,
out_family_name, out_is_bold, out_is_italic));
diff --git a/components/services/font/public/cpp/font_service_thread.h b/components/services/font/public/cpp/font_service_thread.h
index 5c7f3b8c3..941c240b8 100644
--- a/components/services/font/public/cpp/font_service_thread.h
+++ b/components/services/font/public/cpp/font_service_thread.h
@@ -55,6 +55,7 @@ class FontServiceThread : public base::RefCountedThreadSafe<FontServiceThread> {
bool FallbackFontForCharacter(
uint32_t character,
std::string locale,
+ mojom::TypefaceStylePtr requested_style,
font_service::mojom::FontIdentityPtr* out_font_identity,
std::string* out_family_name,
bool* out_is_bold,
@@ -119,6 +120,7 @@ class FontServiceThread : public base::RefCountedThreadSafe<FontServiceThread> {
base::WaitableEvent* done_event,
uint32_t character,
std::string locale,
+ mojom::TypefaceStylePtr requested_style,
bool* out_is_valid,
font_service::mojom::FontIdentityPtr* out_font_identity,
std::string* out_family_name,
diff --git a/components/services/font/public/mojom/font_service.mojom b/components/services/font/public/mojom/font_service.mojom
index 42c9666b4..55e809ecb 100644
--- a/components/services/font/public/mojom/font_service.mojom
+++ b/components/services/font/public/mojom/font_service.mojom
@@ -67,7 +67,10 @@ interface FontService {
// Returns a fallback FontIdentity and Typeface style for the given character
// and locale. If no fallback font can be found, returns a null identity.
- FallbackFontForCharacter(uint32 character, string locale) =>
+ FallbackFontForCharacter(
+ uint32 character,
+ string locale,
+ TypefaceStyle fallback_style) =>
(FontIdentity? identity,
string family_name,
bool is_bold,
diff --git a/content/child/child_process_sandbox_support_impl_linux.cc b/content/child/child_process_sandbox_support_impl_linux.cc
index c97c8fa19..96c97203a 100644
--- a/content/child/child_process_sandbox_support_impl_linux.cc
+++ b/content/child/child_process_sandbox_support_impl_linux.cc
@@ -30,13 +30,16 @@ WebSandboxSupportLinux::~WebSandboxSupportLinux() = default;
bool WebSandboxSupportLinux::GetFallbackFontForCharacter(
blink::WebUChar32 character,
const char* preferred_locale,
+ font_service::mojom::TypefaceStylePtr requested_style,
gfx::FallbackFontData* fallback_font) {
TRACE_EVENT0("fonts", "WebSandboxSupportLinux::GetFallbackFontForCharacter");
+ FontFamilyCacheKey key(character, *requested_style);
+
{
base::AutoLock lock(lock_);
- const auto iter = unicode_font_families_.find(character);
- if (iter != unicode_font_families_.end()) {
+ const auto iter = cached_font_families_.find(key);
+ if (iter != cached_font_families_.end()) {
*fallback_font = iter->second;
return true;
}
@@ -47,8 +50,9 @@ bool WebSandboxSupportLinux::GetFallbackFontForCharacter(
bool is_italic = false;
std::string family_name;
if (!font_loader_->FallbackFontForCharacter(character, preferred_locale,
- &font_identity, &family_name,
- &is_bold, &is_italic))
+ std::move(requested_style), &font_identity,
+ &family_name, &is_bold,
+ &is_italic))
return false;
// mojom::FontIdentityPtr cannot be exposed on the blink/public interface.
@@ -61,7 +65,7 @@ bool WebSandboxSupportLinux::GetFallbackFontForCharacter(
fallback_font->is_italic = is_italic;
base::AutoLock lock(lock_);
- unicode_font_families_.emplace(character, *fallback_font);
+ cached_font_families_.emplace(key, *fallback_font);
return true;
}
diff --git a/content/child/child_process_sandbox_support_impl_linux.h b/content/child/child_process_sandbox_support_impl_linux.h
index 37e6e4e91..a05e3ff53 100644
--- a/content/child/child_process_sandbox_support_impl_linux.h
+++ b/content/child/child_process_sandbox_support_impl_linux.h
@@ -42,6 +42,7 @@ class WebSandboxSupportLinux : public blink::WebSandboxSupport {
bool GetFallbackFontForCharacter(
blink::WebUChar32 character,
const char* preferred_locale,
+ font_service::mojom::TypefaceStylePtr requested_style,
gfx::FallbackFontData* fallback_font) override;
// Matches a font uniquely by postscript name or full font name. Used in
@@ -65,11 +66,13 @@ class WebSandboxSupportLinux : public blink::WebSandboxSupport {
blink::WebFontRenderStyle* out) override;
private:
+ using FontFamilyCacheKey = std::tuple<int32_t, font_service::mojom::TypefaceStyle>;
+
// Blink calls GetFallbackFontForCharacter frequently, so the results are
// cached. The cache is protected by this lock.
base::Lock lock_;
- // Maps unicode chars to their fallback fonts.
- std::map<int32_t, gfx::FallbackFontData> unicode_font_families_
+ // Maps unicode char and style pairs to their fallback fonts.
+ std::map<FontFamilyCacheKey, gfx::FallbackFontData> cached_font_families_
GUARDED_BY(lock_);
sk_sp<font_service::FontLoader> font_loader_;
diff --git a/third_party/blink/public/platform/linux/web_sandbox_support.h b/third_party/blink/public/platform/linux/web_sandbox_support.h
index 8a73df652..5125e4889 100644
--- a/third_party/blink/public/platform/linux/web_sandbox_support.h
+++ b/third_party/blink/public/platform/linux/web_sandbox_support.h
@@ -31,6 +31,7 @@
#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_LINUX_WEB_SANDBOX_SUPPORT_H_
#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_LINUX_WEB_SANDBOX_SUPPORT_H_
+#include "components/services/font/public/mojom/font_service.mojom.h"
#include "third_party/blink/public/platform/web_common.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -60,6 +61,7 @@ class WebSandboxSupport {
virtual bool GetFallbackFontForCharacter(
WebUChar32 character,
const char* preferred_locale,
+ font_service::mojom::TypefaceStylePtr requested_style,
gfx::FallbackFontData* fallback_font) = 0;
// Get a FallbackFontData specification for a font uniquely identified by full
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
index 731de98df..395ea6ace 100644
--- a/third_party/blink/renderer/platform/BUILD.gn
+++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -1688,6 +1688,7 @@ component("platform") {
"//components/paint_preview/common",
"//components/power_scheduler",
"//components/search_engines:search_engine_utils",
+ "//components/services/font/public/mojom",
"//components/viz/client",
"//components/viz/common",
"//crypto",
diff --git a/third_party/blink/renderer/platform/fonts/font_cache.h b/third_party/blink/renderer/platform/fonts/font_cache.h
index c5a99eb1c..b9aec6141 100644
--- a/third_party/blink/renderer/platform/fonts/font_cache.h
+++ b/third_party/blink/renderer/platform/fonts/font_cache.h
@@ -60,6 +60,7 @@
#include "third_party/skia/include/core/SkRefCnt.h"
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
+#include "components/services/font/public/mojom/font_service.mojom.h"
#include "ui/gfx/font_fallback_linux.h"
#endif
@@ -275,9 +276,11 @@ class PLATFORM_EXPORT FontCache {
#endif // defined(OS_ANDROID)
#if defined(OS_LINUX) || defined(OS_CHROMEOS)
- static bool GetFontForCharacter(UChar32,
- const char* preferred_locale,
- gfx::FallbackFontData*);
+ static bool GetFontForCharacter(
+ UChar32,
+ const char* preferred_locale,
+ font_service::mojom::TypefaceStylePtr requested_style,
+ gfx::FallbackFontData*);
#endif // defined(OS_LINUX) || defined(OS_CHROMEOS)
scoped_refptr<SimpleFontData> FontDataFromFontPlatformData(
diff --git a/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc b/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
index 56d8b64b9..ccf76399d 100644
--- a/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
+++ b/third_party/blink/renderer/platform/fonts/linux/font_cache_linux.cc
@@ -49,16 +49,21 @@ void FontCache::SetSystemFontFamily(const AtomicString& family_name) {
MutableSystemFontFamily() = family_name;
}
-bool FontCache::GetFontForCharacter(UChar32 c,
- const char* preferred_locale,
- gfx::FallbackFontData* fallback_font) {
+bool FontCache::GetFontForCharacter(
+ UChar32 c,
+ const char* preferred_locale,
+ font_service::mojom::TypefaceStylePtr requested_style,
+ gfx::FallbackFontData* fallback_font) {
if (Platform::Current()->GetSandboxSupport()) {
return Platform::Current()
->GetSandboxSupport()
- ->GetFallbackFontForCharacter(c, preferred_locale, fallback_font);
+ ->GetFallbackFontForCharacter(c, preferred_locale,
+ std::move(requested_style),
+ fallback_font);
} else {
std::string locale = preferred_locale ? preferred_locale : std::string();
- return gfx::GetFallbackFontForChar(c, locale, fallback_font);
+ return gfx::GetFallbackFontForChar(c, locale, requested_style,
+ fallback_font);
}
}
@@ -102,12 +107,21 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter(
return font_data;
}
+ SkFontStyle base_style = font_description.SkiaFontStyle();
+ font_service::mojom::TypefaceStylePtr
+ style(font_service::mojom::TypefaceStyle::New());
+ style->weight = base_style.weight();
+ style->width = base_style.width();
+ style->slant =
+ static_cast<font_service::mojom::TypefaceSlant>(base_style.slant());
+
gfx::FallbackFontData fallback_font;
if (!FontCache::GetFontForCharacter(
c,
fallback_priority == FontFallbackPriority::kEmojiEmoji
? kColorEmojiLocale
: font_description.LocaleOrDefault().Ascii().c_str(),
+ std::move(style),
&fallback_font))
return nullptr;
diff --git a/ui/gfx/font_fallback_linux.cc b/ui/gfx/font_fallback_linux.cc
index da9cede9d..18975a017 100644
--- a/ui/gfx/font_fallback_linux.cc
+++ b/ui/gfx/font_fallback_linux.cc
@@ -19,6 +19,7 @@
#include "third_party/icu/source/common/unicode/uchar.h"
#include "third_party/icu/source/common/unicode/utf16.h"
#include "third_party/skia/include/core/SkFontMgr.h"
+#include "third_party/skia/include/core/SkFontStyle.h"
#include "ui/gfx/font.h"
#include "ui/gfx/font_fallback.h"
#include "ui/gfx/linux/fontconfig_util.h"
@@ -421,8 +422,9 @@ class CachedFontSet {
public:
// CachedFontSet takes ownership of the passed FcFontSet.
static std::unique_ptr<CachedFontSet> CreateForLocale(
- const std::string& locale) {
- FcFontSet* font_set = CreateFcFontSetForLocale(locale);
+ const std::string& locale,
+ font_service::mojom::TypefaceStylePtr& requested_style) {
+ FcFontSet* font_set = CreateFcFontSetForLocale(locale, requested_style);
return base::WrapUnique(new CachedFontSet(font_set));
}
@@ -447,7 +449,8 @@ class CachedFontSet {
}
private:
- static FcFontSet* CreateFcFontSetForLocale(const std::string& locale) {
+ static FcFontSet* CreateFcFontSetForLocale(const std::string& locale,
+ font_service::mojom::TypefaceStylePtr& requested_style) {
FcPattern* pattern = FcPatternCreate();
if (!locale.empty()) {
@@ -456,6 +459,53 @@ class CachedFontSet {
reinterpret_cast<const FcChar8*>(locale.c_str()));
}
+ if (requested_style->weight != 0) {
+ FcPatternAddInteger(pattern, FC_WEIGHT,
+ FcWeightFromOpenType(requested_style->weight));
+ }
+
+ switch (requested_style->width) {
+ case SkFontStyle::kUltraCondensed_Width:
+ FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_ULTRACONDENSED);
+ break;
+ case SkFontStyle::kExtraCondensed_Width:
+ FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_EXTRACONDENSED);
+ break;
+ case SkFontStyle::kCondensed_Width:
+ FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_CONDENSED);
+ break;
+ case SkFontStyle::kSemiCondensed_Width:
+ FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_SEMICONDENSED);
+ break;
+ case SkFontStyle::kNormal_Width:
+ FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_NORMAL);
+ break;
+ case SkFontStyle::kSemiExpanded_Width:
+ FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_SEMIEXPANDED);
+ break;
+ case SkFontStyle::kExpanded_Width:
+ FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_EXPANDED);
+ break;
+ case SkFontStyle::kExtraExpanded_Width:
+ FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_EXTRAEXPANDED);
+ break;
+ case SkFontStyle::kUltraExpanded_Width:
+ FcPatternAddInteger(pattern, FC_WIDTH, FC_WIDTH_ULTRAEXPANDED);
+ break;
+ }
+
+ switch (requested_style->slant) {
+ case font_service::mojom::TypefaceSlant::ROMAN:
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ROMAN);
+ break;
+ case font_service::mojom::TypefaceSlant::ITALIC:
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+ break;
+ case font_service::mojom::TypefaceSlant::OBLIQUE:
+ FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_OBLIQUE);
+ break;
+ }
+
FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
FcConfigSubstitute(0, pattern, FcMatchPattern);
@@ -508,10 +558,6 @@ class CachedFontSet {
std::vector<CachedFont> fallback_list_;
};
-typedef std::map<std::string, std::unique_ptr<CachedFontSet>> FontSetCache;
-base::LazyInstance<FontSetCache>::Leaky g_font_sets_by_locale =
- LAZY_INSTANCE_INITIALIZER;
-
} // namespace
FallbackFontData::FallbackFontData() = default;
@@ -521,11 +567,26 @@ FallbackFontData& FallbackFontData::operator=(const FallbackFontData& other) =
bool GetFallbackFontForChar(UChar32 c,
const std::string& locale,
+ font_service::mojom::TypefaceStylePtr& requested_style,
FallbackFontData* fallback_font) {
- auto& cached_font_set = g_font_sets_by_locale.Get()[locale];
- if (!cached_font_set)
- cached_font_set = CachedFontSet::CreateForLocale(locale);
- return cached_font_set->GetFallbackFontForChar(c, fallback_font);
+ using FontSetCacheKey =
+ std::tuple<std::string, font_service::mojom::TypefaceStyle>;
+ using FontSetCache =
+ base::LRUCache<FontSetCacheKey, std::unique_ptr<CachedFontSet>>;
+
+ constexpr int kFontSetCacheSize = 32;
+ static base::NoDestructor<FontSetCache> font_set_caches(kFontSetCacheSize);
+
+ FontSetCache* font_set_cache = font_set_caches.get();
+ FontSetCacheKey key(locale, *requested_style);
+ auto cached_font_set = font_set_cache->Get(key);
+
+ if (cached_font_set == font_set_cache->end()) {
+ auto new_font_set = CachedFontSet::CreateForLocale(locale, requested_style);
+ cached_font_set = font_set_cache->Put(key, std::move(new_font_set));
+ }
+
+ return cached_font_set->second->GetFallbackFontForChar(c, fallback_font);
}
} // namespace gfx
diff --git a/ui/gfx/font_fallback_linux.h b/ui/gfx/font_fallback_linux.h
index 7a768690a..5404ff0e5 100644
--- a/ui/gfx/font_fallback_linux.h
+++ b/ui/gfx/font_fallback_linux.h
@@ -8,6 +8,7 @@
#include <string>
#include "base/files/file_path.h"
+#include "components/services/font/public/mojom/font_service.mojom.h"
#include "third_party/icu/source/common/unicode/uchar.h"
#include "ui/gfx/gfx_export.h"
@@ -40,6 +41,7 @@ struct GFX_EXPORT FallbackFontData {
// Return whether the request was successful or not.
GFX_EXPORT bool GetFallbackFontForChar(UChar32 c,
const std::string& preferred_locale,
+ font_service::mojom::TypefaceStylePtr& fallback_style,
FallbackFontData* fallback_font);
} // namespace gfx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment