Skip to content

Commit dd0eecc

Browse files
Sort the Skia typefaces in a font style set into a consistent order (flutter#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 flutter#31212
1 parent 942e631 commit dd0eecc

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

third_party/txt/src/txt/font_collection.cc

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -209,26 +209,33 @@ std::shared_ptr<minikin::FontFamily> FontCollection::CreateMinikinFontFamily(
209209
return nullptr;
210210
}
211211

212-
std::vector<minikin::Font> minikin_fonts;
213-
214-
// Add fonts to the Minikin font family.
212+
std::vector<sk_sp<SkTypeface>> skia_typefaces;
215213
for (int i = 0; i < font_style_set->count(); ++i) {
216-
TRACE_EVENT0("flutter", "CreateMinikinFont");
217-
// Create the skia typeface.
214+
TRACE_EVENT0("flutter", "CreateSkiaTypeface");
218215
sk_sp<SkTypeface> skia_typeface(
219216
sk_sp<SkTypeface>(font_style_set->createTypeface(i)));
220-
if (skia_typeface == nullptr) {
221-
continue;
217+
if (skia_typeface != nullptr) {
218+
skia_typefaces.emplace_back(std::move(skia_typeface));
222219
}
220+
}
223221

222+
std::sort(skia_typefaces.begin(), skia_typefaces.end(),
223+
[](const sk_sp<SkTypeface>& a, const sk_sp<SkTypeface>& b) {
224+
SkFontStyle a_style = a->fontStyle();
225+
SkFontStyle b_style = b->fontStyle();
226+
return (a_style.weight() != b_style.weight())
227+
? a_style.weight() < b_style.weight()
228+
: a_style.slant() < b_style.slant();
229+
});
230+
231+
std::vector<minikin::Font> minikin_fonts;
232+
for (const sk_sp<SkTypeface>& skia_typeface : skia_typefaces) {
224233
// Create the minikin font from the skia typeface.
225234
// Divide by 100 because the weights are given as "100", "200", etc.
226-
minikin::Font minikin_font(
235+
minikin_fonts.emplace_back(
227236
std::make_shared<FontSkia>(skia_typeface),
228237
minikin::FontStyle{skia_typeface->fontStyle().weight() / 100,
229238
skia_typeface->isItalic()});
230-
231-
minikin_fonts.emplace_back(std::move(minikin_font));
232239
}
233240

234241
return std::make_shared<minikin::FontFamily>(std::move(minikin_fonts));

0 commit comments

Comments
 (0)