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

Sort the Skia typefaces in a font style set into a consistent order (#11056)

When Minikin searches for a font based on a font style, it will score the fonts
in the family and choose the best match.  However, multiple fonts may have
equal scores (e.g. searching for a font with weight 600 when the set includes
fonts with weights 500 and 700).  In this case Minikin will select the first
font in the list with the best score.

However, the fonts in a font family's SkFontStyleSet may not always be provided
in a consistent order by the SkFontMgr.  So if the minikin::FontFamily list is
populated based on the SkFontStyleSet order, then a query for a given style might
not always return the same font.

This change sorts the typefaces in the SkFontStyleSet before converting them
into a Minikin font family.

Fixes https://github.com/flutter/flutter/issues/31212
上级 942e6318
......@@ -209,26 +209,33 @@ std::shared_ptr<minikin::FontFamily> FontCollection::CreateMinikinFontFamily(
return nullptr;
}
std::vector<minikin::Font> minikin_fonts;
// Add fonts to the Minikin font family.
std::vector<sk_sp<SkTypeface>> skia_typefaces;
for (int i = 0; i < font_style_set->count(); ++i) {
TRACE_EVENT0("flutter", "CreateMinikinFont");
// Create the skia typeface.
TRACE_EVENT0("flutter", "CreateSkiaTypeface");
sk_sp<SkTypeface> skia_typeface(
sk_sp<SkTypeface>(font_style_set->createTypeface(i)));
if (skia_typeface == nullptr) {
continue;
if (skia_typeface != nullptr) {
skia_typefaces.emplace_back(std::move(skia_typeface));
}
}
std::sort(skia_typefaces.begin(), skia_typefaces.end(),
[](const sk_sp<SkTypeface>& a, const sk_sp<SkTypeface>& b) {
SkFontStyle a_style = a->fontStyle();
SkFontStyle b_style = b->fontStyle();
return (a_style.weight() != b_style.weight())
? a_style.weight() < b_style.weight()
: a_style.slant() < b_style.slant();
});
std::vector<minikin::Font> minikin_fonts;
for (const sk_sp<SkTypeface>& skia_typeface : skia_typefaces) {
// Create the minikin font from the skia typeface.
// Divide by 100 because the weights are given as "100", "200", etc.
minikin::Font minikin_font(
minikin_fonts.emplace_back(
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));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册