Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 9d1566d

Browse files
[Impeller] avoid reading font while parsing sktextblob. (#55442)
Use a faster approximation for finding out axis alignment that skips opening the font file, which is slow! ![image](https://github.com/user-attachments/assets/ae840597-b63b-4e46-b857-ac5f09e09ca8)
1 parent e57b440 commit 9d1566d

File tree

1 file changed

+18
-37
lines changed

1 file changed

+18
-37
lines changed

impeller/typographer/backends/skia/text_frame_skia.cc

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,6 @@
1919

2020
namespace impeller {
2121

22-
/// @brief Convert a Skia axis alignment into an Impeller alignment.
23-
///
24-
/// This does not include a case for AxisAlignment::kNone, that should
25-
/// be used if SkFont::isSubpixel is false.
26-
static AxisAlignment ToAxisAligment(SkAxisAlignment aligment) {
27-
switch (aligment) {
28-
case SkAxisAlignment::kNone:
29-
// Skia calls this case none, meaning alignment in both X and Y.
30-
// Impeller will call it "all" since that is less confusing. "none"
31-
// is reserved for no subpixel alignment.
32-
return AxisAlignment::kAll;
33-
case SkAxisAlignment::kX:
34-
return AxisAlignment::kX;
35-
case SkAxisAlignment::kY:
36-
return AxisAlignment::kY;
37-
}
38-
FML_UNREACHABLE();
39-
}
40-
4122
static Font ToFont(const SkTextBlobRunIterator& run, AxisAlignment alignment) {
4223
auto& font = run.font();
4324
auto typeface = std::make_shared<TypefaceSkia>(font.refTypeface());
@@ -63,35 +44,35 @@ std::shared_ptr<TextFrame> MakeTextFrameFromTextBlobSkia(
6344
bool has_color = false;
6445
std::vector<TextRun> runs;
6546
for (SkTextBlobRunIterator run(blob.get()); !run.done(); run.next()) {
66-
// TODO(112005): Ask Skia for a public API to look this up. This is using a
67-
// private API today.
6847
SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(run.font());
6948
SkBulkGlyphMetricsAndPaths paths{strikeSpec};
49+
SkSpan<const SkGlyph*> glyphs =
50+
paths.glyphs(SkSpan(run.glyphs(), run.glyphCount()));
51+
52+
for (const auto& glyph : glyphs) {
53+
has_color |= glyph->isColor();
54+
}
55+
7056
AxisAlignment alignment = AxisAlignment::kNone;
71-
if (run.font().isSubpixel()) {
72-
alignment = ToAxisAligment(
73-
strikeSpec.createScalerContext()->computeAxisAlignmentForHText());
57+
if (run.font().isSubpixel() && run.font().isBaselineSnap() && !has_color) {
58+
alignment = AxisAlignment::kX;
7459
}
7560

76-
const auto glyph_count = run.glyphCount();
77-
const auto* glyphs = run.glyphs();
7861
switch (run.positioning()) {
7962
case SkTextBlobRunIterator::kFull_Positioning: {
8063
std::vector<TextRun::GlyphPosition> positions;
81-
positions.reserve(glyph_count);
82-
for (auto i = 0u; i < glyph_count; i++) {
64+
positions.reserve(run.glyphCount());
65+
for (auto i = 0u; i < run.glyphCount(); i++) {
8366
// kFull_Positioning has two scalars per glyph.
8467
const SkPoint* glyph_points = run.points();
8568
const SkPoint* point = glyph_points + i;
86-
Glyph::Type type = paths.glyph(glyphs[i])->isColor()
87-
? Glyph::Type::kBitmap
88-
: Glyph::Type::kPath;
89-
has_color |= type == Glyph::Type::kBitmap;
90-
positions.emplace_back(
91-
TextRun::GlyphPosition{Glyph{glyphs[i], type}, Point{
92-
point->x(),
93-
point->y(),
94-
}});
69+
Glyph::Type type =
70+
glyphs[i]->isColor() ? Glyph::Type::kBitmap : Glyph::Type::kPath;
71+
positions.emplace_back(TextRun::GlyphPosition{
72+
Glyph{glyphs[i]->getGlyphID(), type}, Point{
73+
point->x(),
74+
point->y(),
75+
}});
9576
}
9677
TextRun text_run(ToFont(run, alignment), positions);
9778
runs.emplace_back(text_run);

0 commit comments

Comments
 (0)