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

Commit 24f8fec

Browse files
author
Jonah Williams
authored
[Impeller] fix colr/bitmap font color drawing. (#52871)
Fixes flutter/flutter#126546 Track the paint color used by Bitmap/Emoji/COLR fonts and use it as a cache key. This allows non-COLR glyphs in a COLR font to get the correct text color. For other kinds of fonts, we always record the color as black so there are no cache efficiency hits in general.
1 parent 8fbcb51 commit 24f8fec

File tree

15 files changed

+150
-22
lines changed

15 files changed

+150
-22
lines changed

impeller/entity/contents/text_contents.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ bool TextContents::Render(const ContentContext& renderer,
166166
Scalar rounded_scale = TextFrame::RoundScaledFontSize(
167167
scale_, font.GetMetrics().point_size);
168168
const FontGlyphAtlas* font_atlas =
169-
atlas->GetFontGlyphAtlas(font, rounded_scale);
169+
atlas->GetFontGlyphAtlas(font, rounded_scale, frame_->GetColor());
170170
if (!font_atlas) {
171171
VALIDATION_LOG << "Could not find font in the atlas.";
172172
continue;

impeller/geometry/color.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,16 @@ struct Color {
253253
return {r, g, b, a};
254254
}
255255

256+
/**
257+
* @brief Convert to ARGB 32 bit color.
258+
*
259+
* @return constexpr uint32_t
260+
*/
261+
constexpr uint32_t ToARGB() const {
262+
std::array<uint8_t, 4> result = ToR8G8B8A8();
263+
return result[3] << 24 | result[0] << 16 | result[1] << 8 | result[2];
264+
}
265+
256266
static constexpr Color White() { return {1.0f, 1.0f, 1.0f, 1.0f}; }
257267

258268
static constexpr Color Black() { return {0.0f, 0.0f, 0.0f, 1.0f}; }

impeller/typographer/backends/skia/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ impeller_component("typographer_skia_backend") {
1515
]
1616

1717
public_deps = [
18+
"//flutter/display_list",
1819
"//flutter/impeller/typographer",
1920
"//flutter/skia",
2021
]

impeller/typographer/backends/skia/text_frame_skia.cc

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <vector>
88

9+
#include "display_list/dl_color.h"
910
#include "flutter/fml/logging.h"
1011
#include "impeller/typographer/backends/skia/typeface_skia.h"
1112
#include "include/core/SkRect.h"
@@ -16,6 +17,15 @@
1617

1718
namespace impeller {
1819

20+
static Color ToColor(const flutter::DlColor& color) {
21+
return {
22+
static_cast<Scalar>(color.getRedF()), //
23+
static_cast<Scalar>(color.getGreenF()), //
24+
static_cast<Scalar>(color.getBlueF()), //
25+
static_cast<Scalar>(color.getAlphaF()) //
26+
};
27+
}
28+
1929
static Font ToFont(const SkTextBlobRunIterator& run) {
2030
auto& font = run.font();
2131
auto typeface = std::make_shared<TypefaceSkia>(font.refTypeface());
@@ -39,8 +49,10 @@ static Rect ToRect(const SkRect& rect) {
3949
static constexpr Scalar kScaleSize = 64.0f;
4050

4151
std::shared_ptr<TextFrame> MakeTextFrameFromTextBlobSkia(
42-
const sk_sp<SkTextBlob>& blob) {
52+
const sk_sp<SkTextBlob>& blob,
53+
flutter::DlColor dl_color) {
4354
bool has_color = false;
55+
Color color = ToColor(dl_color);
4456
std::vector<TextRun> runs;
4557
for (SkTextBlobRunIterator run(blob.get()); !run.done(); run.next()) {
4658
// TODO(jonahwilliams): ask Skia for a public API to look this up.
@@ -89,7 +101,8 @@ std::shared_ptr<TextFrame> MakeTextFrameFromTextBlobSkia(
89101
continue;
90102
}
91103
}
92-
return std::make_shared<TextFrame>(runs, ToRect(blob->bounds()), has_color);
104+
return std::make_shared<TextFrame>(runs, ToRect(blob->bounds()), has_color,
105+
has_color ? color : Color::Black());
93106
}
94107

95108
} // namespace impeller

impeller/typographer/backends/skia/text_frame_skia.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
#ifndef FLUTTER_IMPELLER_TYPOGRAPHER_BACKENDS_SKIA_TEXT_FRAME_SKIA_H_
66
#define FLUTTER_IMPELLER_TYPOGRAPHER_BACKENDS_SKIA_TEXT_FRAME_SKIA_H_
77

8+
#include "display_list/dl_color.h"
89
#include "impeller/typographer/text_frame.h"
910
#include "third_party/skia/include/core/SkTextBlob.h"
1011

1112
namespace impeller {
1213

1314
std::shared_ptr<impeller::TextFrame> MakeTextFrameFromTextBlobSkia(
14-
const sk_sp<SkTextBlob>& blob);
15+
const sk_sp<SkTextBlob>& blob,
16+
flutter::DlColor color = flutter::DlColor::kBlack());
1517

1618
} // namespace impeller
1719

impeller/typographer/backends/skia/typographer_context_skia.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ static void DrawGlyph(SkCanvas* canvas,
242242
sk_font.setHinting(SkFontHinting::kSlight);
243243
sk_font.setEmbolden(metrics.embolden);
244244

245-
auto glyph_color = has_color ? SK_ColorWHITE : SK_ColorBLACK;
245+
auto glyph_color = has_color ? scaled_font.color.ToARGB() : SK_ColorBLACK;
246246

247247
SkPaint glyph_paint;
248248
glyph_paint.setColor(glyph_color);
@@ -331,8 +331,8 @@ std::shared_ptr<GlyphAtlas> TypographerContextSkia::CreateGlyphAtlas(
331331
std::vector<FontGlyphPair> new_glyphs;
332332
for (const auto& font_value : font_glyph_map) {
333333
const ScaledFont& scaled_font = font_value.first;
334-
const FontGlyphAtlas* font_glyph_atlas =
335-
last_atlas->GetFontGlyphAtlas(scaled_font.font, scaled_font.scale);
334+
const FontGlyphAtlas* font_glyph_atlas = last_atlas->GetFontGlyphAtlas(
335+
scaled_font.font, scaled_font.scale, scaled_font.color);
336336
if (font_glyph_atlas) {
337337
for (const Glyph& glyph : font_value.second) {
338338
if (!font_glyph_atlas->FindGlyphBounds(glyph)) {

impeller/typographer/backends/stb/text_frame_stb.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ std::shared_ptr<TextFrame> MakeTextFrameSTB(
6363

6464
std::vector<TextRun> runs = {run};
6565
return std::make_shared<TextFrame>(
66-
runs, result.value_or(Rect::MakeLTRB(0, 0, 0, 0)), false);
66+
runs, result.value_or(Rect::MakeLTRB(0, 0, 0, 0)), false, Color::Black());
6767
}
6868

6969
} // namespace impeller

impeller/typographer/backends/stb/typographer_context_stb.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,8 @@ std::shared_ptr<GlyphAtlas> TypographerContextSTB::CreateGlyphAtlas(
412412
std::vector<FontGlyphPair> new_glyphs;
413413
for (const auto& font_value : font_glyph_map) {
414414
const ScaledFont& scaled_font = font_value.first;
415-
const FontGlyphAtlas* font_glyph_atlas =
416-
last_atlas->GetFontGlyphAtlas(scaled_font.font, scaled_font.scale);
415+
const FontGlyphAtlas* font_glyph_atlas = last_atlas->GetFontGlyphAtlas(
416+
scaled_font.font, scaled_font.scale, scaled_font.color);
417417
if (font_glyph_atlas) {
418418
for (const Glyph& glyph : font_value.second) {
419419
if (!font_glyph_atlas->FindGlyphBounds(glyph)) {

impeller/typographer/font_glyph_pair.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ namespace impeller {
2020
struct ScaledFont {
2121
Font font;
2222
Scalar scale;
23+
Color color;
2324
};
2425

2526
using FontGlyphMap = std::unordered_map<ScaledFont, std::unordered_set<Glyph>>;
@@ -40,15 +41,16 @@ struct FontGlyphPair {
4041
template <>
4142
struct std::hash<impeller::ScaledFont> {
4243
constexpr std::size_t operator()(const impeller::ScaledFont& sf) const {
43-
return fml::HashCombine(sf.font.GetHash(), sf.scale);
44+
return fml::HashCombine(sf.font.GetHash(), sf.scale, sf.color.ToARGB());
4445
}
4546
};
4647

4748
template <>
4849
struct std::equal_to<impeller::ScaledFont> {
4950
constexpr bool operator()(const impeller::ScaledFont& lhs,
5051
const impeller::ScaledFont& rhs) const {
51-
return lhs.font.IsEqual(rhs.font) && lhs.scale == rhs.scale;
52+
return lhs.font.IsEqual(rhs.font) && lhs.scale == rhs.scale &&
53+
lhs.color == rhs.color;
5254
}
5355
};
5456

impeller/typographer/glyph_atlas.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,9 @@ std::optional<Rect> GlyphAtlas::FindFontGlyphBounds(
7878
}
7979

8080
const FontGlyphAtlas* GlyphAtlas::GetFontGlyphAtlas(const Font& font,
81-
Scalar scale) const {
82-
const auto& found = font_atlas_map_.find({font, scale});
81+
Scalar scale,
82+
Color color) const {
83+
const auto& found = font_atlas_map_.find({font, scale, color});
8384
if (found == font_atlas_map_.end()) {
8485
return nullptr;
8586
}

0 commit comments

Comments
 (0)