未验证 提交 686d2235 编写于 作者: J Jason Simmons 提交者: GitHub

libtxt: add all styles of a fallback font family to the cache (#5474)

libtxt will query Skia for a fallback typeface when it encounters a character
that is not found in the primary font.  The font collection should make all
the variants of the fallback typeface's font family available to Minikin for
use in future font lookups.

Fixes https://github.com/flutter/flutter/issues/17985
上级 a1193cfa
...@@ -105,45 +105,18 @@ FontCollection::GetMinikinFontCollectionForFamily( ...@@ -105,45 +105,18 @@ FontCollection::GetMinikinFontCollectionForFamily(
} }
for (sk_sp<SkFontMgr>& manager : GetFontManagerOrder()) { for (sk_sp<SkFontMgr>& manager : GetFontManagerOrder()) {
sk_sp<SkFontStyleSet> font_style_set( std::shared_ptr<minikin::FontFamily> minikin_family =
manager->matchFamily(font_family.c_str())); CreateMinikinFontFamily(manager, font_family);
if (font_style_set == nullptr || font_style_set->count() == 0) { if (!minikin_family)
continue; continue;
}
std::vector<minikin::Font> minikin_fonts;
// Add fonts to the Minikin font family.
for (int i = 0, style_count = font_style_set->count(); i < style_count;
++i) {
// Create the skia typeface.
sk_sp<SkTypeface> skia_typeface(
sk_sp<SkTypeface>(font_style_set->createTypeface(i)));
if (skia_typeface == nullptr) {
continue;
}
// Create the minikin font from the skia typeface.
// Divide by 100 because the weights are given as "100", "200", etc.
minikin::Font minikin_font(
std::make_shared<FontSkia>(skia_typeface),
minikin::FontStyle{skia_typeface->fontStyle().weight() / 100,
skia_typeface->isItalic()});
minikin_fonts.emplace_back(std::move(minikin_font));
}
// Create a Minikin font family.
auto minikin_family =
std::make_shared<minikin::FontFamily>(std::move(minikin_fonts));
// Create a vector of font families for the Minikin font collection. // Create a vector of font families for the Minikin font collection.
std::vector<std::shared_ptr<minikin::FontFamily>> minikin_families = { std::vector<std::shared_ptr<minikin::FontFamily>> minikin_families = {
minikin_family, minikin_family,
}; };
if (enable_font_fallback_) { if (enable_font_fallback_) {
for (SkFontID font_id : fallback_fonts_for_locale_[locale]) for (std::string fallback_family : fallback_fonts_for_locale_[locale])
minikin_families.push_back(fallback_fonts_[font_id]); minikin_families.push_back(fallback_fonts_[fallback_family]);
} }
// Create the minikin font collection. // Create the minikin font collection.
...@@ -172,6 +145,39 @@ FontCollection::GetMinikinFontCollectionForFamily( ...@@ -172,6 +145,39 @@ FontCollection::GetMinikinFontCollectionForFamily(
return nullptr; return nullptr;
} }
std::shared_ptr<minikin::FontFamily> FontCollection::CreateMinikinFontFamily(
const sk_sp<SkFontMgr>& manager,
const std::string& family_name) {
sk_sp<SkFontStyleSet> font_style_set(
manager->matchFamily(family_name.c_str()));
if (font_style_set == nullptr || font_style_set->count() == 0) {
return nullptr;
}
std::vector<minikin::Font> minikin_fonts;
// Add fonts to the Minikin font family.
for (int i = 0; i < font_style_set->count(); ++i) {
// Create the skia typeface.
sk_sp<SkTypeface> skia_typeface(
sk_sp<SkTypeface>(font_style_set->createTypeface(i)));
if (skia_typeface == nullptr) {
continue;
}
// Create the minikin font from the skia typeface.
// Divide by 100 because the weights are given as "100", "200", etc.
minikin::Font minikin_font(
std::make_shared<FontSkia>(skia_typeface),
minikin::FontStyle{skia_typeface->fontStyle().weight() / 100,
skia_typeface->isItalic()});
minikin_fonts.emplace_back(std::move(minikin_font));
}
return std::make_shared<minikin::FontFamily>(std::move(minikin_fonts));
}
const std::shared_ptr<minikin::FontFamily>& FontCollection::MatchFallbackFont( const std::shared_ptr<minikin::FontFamily>& FontCollection::MatchFallbackFont(
uint32_t ch, uint32_t ch,
std::string locale) { std::string locale) {
...@@ -184,28 +190,33 @@ const std::shared_ptr<minikin::FontFamily>& FontCollection::MatchFallbackFont( ...@@ -184,28 +190,33 @@ const std::shared_ptr<minikin::FontFamily>& FontCollection::MatchFallbackFont(
if (!typeface) if (!typeface)
continue; continue;
fallback_fonts_for_locale_[locale].insert(typeface->uniqueID()); SkString sk_family_name;
typeface->getFamilyName(&sk_family_name);
std::string family_name(sk_family_name.c_str());
fallback_fonts_for_locale_[locale].insert(family_name);
return GetFallbackFont(typeface); return GetFallbackFontFamily(manager, family_name);
} }
return null_family_; return null_family_;
} }
const std::shared_ptr<minikin::FontFamily>& const std::shared_ptr<minikin::FontFamily>&
FontCollection::GetFallbackFont(const sk_sp<SkTypeface>& typeface) { FontCollection::GetFallbackFontFamily(const sk_sp<SkFontMgr>& manager,
SkFontID typeface_id = typeface->uniqueID(); const std::string& family_name) {
auto fallback_it = fallback_fonts_.find(typeface_id); auto fallback_it = fallback_fonts_.find(family_name);
if (fallback_it != fallback_fonts_.end()) { if (fallback_it != fallback_fonts_.end()) {
return fallback_it->second; return fallback_it->second;
} }
std::vector<minikin::Font> minikin_fonts; std::shared_ptr<minikin::FontFamily> minikin_family =
minikin_fonts.emplace_back(std::make_shared<FontSkia>(typeface), CreateMinikinFontFamily(manager, family_name);
minikin::FontStyle()); if (!minikin_family)
auto insert_it = fallback_fonts_.insert(std::make_pair( return null_family_;
typeface_id,
std::make_shared<minikin::FontFamily>(std::move(minikin_fonts)))); auto insert_it =
fallback_fonts_.insert(std::make_pair(family_name, minikin_family));
// Clear the cache to force creation of new font collections that will include // Clear the cache to force creation of new font collections that will include
// this fallback font. // this fallback font.
......
...@@ -78,17 +78,22 @@ class FontCollection : public std::enable_shared_from_this<FontCollection> { ...@@ -78,17 +78,22 @@ class FontCollection : public std::enable_shared_from_this<FontCollection> {
std::shared_ptr<minikin::FontCollection>, std::shared_ptr<minikin::FontCollection>,
FamilyKey::Hasher> FamilyKey::Hasher>
font_collections_cache_; font_collections_cache_;
std::unordered_map<SkFontID, std::shared_ptr<minikin::FontFamily>> std::unordered_map<std::string, std::shared_ptr<minikin::FontFamily>>
fallback_fonts_; fallback_fonts_;
std::unordered_map<std::string, std::set<SkFontID>> std::unordered_map<std::string, std::set<std::string>>
fallback_fonts_for_locale_; fallback_fonts_for_locale_;
std::shared_ptr<minikin::FontFamily> null_family_; std::shared_ptr<minikin::FontFamily> null_family_;
bool enable_font_fallback_; bool enable_font_fallback_;
std::vector<sk_sp<SkFontMgr>> GetFontManagerOrder() const; std::vector<sk_sp<SkFontMgr>> GetFontManagerOrder() const;
const std::shared_ptr<minikin::FontFamily>& GetFallbackFont( std::shared_ptr<minikin::FontFamily> CreateMinikinFontFamily(
const sk_sp<SkTypeface>& typeface); const sk_sp<SkFontMgr>& manager,
const std::string& family_name);
const std::shared_ptr<minikin::FontFamily>& GetFallbackFontFamily(
const sk_sp<SkFontMgr>& manager,
const std::string& family_name);
FXL_DISALLOW_COPY_AND_ASSIGN(FontCollection); FXL_DISALLOW_COPY_AND_ASSIGN(FontCollection);
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册