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

Commit 303e26e

Browse files
authored
[Impeller] Use glyph bounds to compute the max glyph size instead of font metrics (#37998)
1 parent d75b7ce commit 303e26e

File tree

7 files changed

+66
-11
lines changed

7 files changed

+66
-11
lines changed

impeller/aiks/aiks_unittests.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,43 @@ TEST_P(AiksTest, CanRenderTextInSaveLayer) {
11181118
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
11191119
}
11201120

1121+
TEST_P(AiksTest, CanRenderTextOutsideBoundaries) {
1122+
Canvas canvas;
1123+
canvas.Translate({200, 150});
1124+
1125+
// Construct the text blob.
1126+
auto mapping = OpenFixtureAsSkData("wtf.otf");
1127+
ASSERT_NE(mapping, nullptr);
1128+
1129+
Scalar font_size = 80;
1130+
SkFont sk_font(SkTypeface::MakeFromData(mapping), font_size);
1131+
1132+
Paint text_paint;
1133+
text_paint.color = Color::White().WithAlpha(0.8);
1134+
1135+
struct {
1136+
Point position;
1137+
const char* text;
1138+
} text[] = {{Point(0, 0), "0F0F0F0"},
1139+
{Point(1, 2), "789"},
1140+
{Point(1, 3), "456"},
1141+
{Point(1, 4), "123"},
1142+
{Point(0, 6), "0F0F0F0"}};
1143+
for (auto& t : text) {
1144+
canvas.Save();
1145+
canvas.Translate(t.position * Point(font_size * 2, font_size * 1.1));
1146+
{
1147+
auto blob = SkTextBlob::MakeFromString(t.text, sk_font);
1148+
ASSERT_NE(blob, nullptr);
1149+
auto frame = TextFrameFromTextBlob(blob);
1150+
canvas.DrawTextFrame(frame, Point(), text_paint);
1151+
}
1152+
canvas.Restore();
1153+
}
1154+
1155+
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
1156+
}
1157+
11211158
TEST_P(AiksTest, CanDrawPaint) {
11221159
Paint paint;
11231160
paint.color = Color::MediumTurquoise();

impeller/entity/contents/text_contents.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,7 @@ static bool CommonRender(
131131
auto glyph_size_ = font.GetMetrics().GetBoundingBox().size;
132132
auto glyph_size = Point{static_cast<Scalar>(glyph_size_.width),
133133
static_cast<Scalar>(glyph_size_.height)};
134-
auto metrics_offset =
135-
Point{font.GetMetrics().min_extent.x, font.GetMetrics().ascent};
134+
auto metrics_offset = font.GetMetrics().min_extent;
136135

137136
for (const auto& glyph_position : run.GetGlyphPositions()) {
138137
FontGlyphPair font_glyph_pair{font, glyph_position.glyph};

impeller/fixtures/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ test_fixtures("file_fixtures") {
7373
"table_mountain_pz.png",
7474
"test_texture.frag",
7575
"types.h",
76+
"wtf.otf",
7677
]
7778
if (host_os == "mac") {
7879
fixtures += [ "/System/Library/Fonts/Apple Color Emoji.ttc" ]

impeller/fixtures/wtf.otf

2.49 KB
Binary file not shown.

impeller/typographer/backends/skia/text_frame_skia.cc

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,21 @@
44

55
#include "impeller/typographer/backends/skia/text_frame_skia.h"
66

7+
#include <vector>
8+
79
#include "flutter/fml/logging.h"
810
#include "impeller/typographer/backends/skia/typeface_skia.h"
11+
#include "include/core/SkFontTypes.h"
12+
#include "include/core/SkRect.h"
913
#include "third_party/skia/include/core/SkFont.h"
1014
#include "third_party/skia/include/core/SkFontMetrics.h"
1115
#include "third_party/skia/src/core/SkStrikeSpec.h" // nogncheck
1216
#include "third_party/skia/src/core/SkTextBlobPriv.h" // nogncheck
1317

1418
namespace impeller {
1519

16-
static Font ToFont(const SkFont& font, Scalar scale) {
20+
static Font ToFont(const SkTextBlobRunIterator& run, Scalar scale) {
21+
auto& font = run.font();
1722
auto typeface = std::make_shared<TypefaceSkia>(font.refTypefaceOrDefault());
1823

1924
SkFontMetrics sk_metrics;
@@ -24,8 +29,20 @@ static Font ToFont(const SkFont& font, Scalar scale) {
2429
metrics.point_size = font.getSize();
2530
metrics.ascent = sk_metrics.fAscent;
2631
metrics.descent = sk_metrics.fDescent;
27-
metrics.min_extent = {sk_metrics.fXMin, sk_metrics.fAscent};
28-
metrics.max_extent = {sk_metrics.fXMax, sk_metrics.fDescent};
32+
metrics.min_extent = {sk_metrics.fXMin, sk_metrics.fTop};
33+
metrics.max_extent = {sk_metrics.fXMax, sk_metrics.fBottom};
34+
35+
std::vector<SkRect> glyph_bounds;
36+
SkPaint paint;
37+
38+
glyph_bounds.resize(run.glyphCount());
39+
run.font().getBounds(run.glyphs(), run.glyphCount(), glyph_bounds.data(),
40+
nullptr);
41+
for (auto& bounds : glyph_bounds) {
42+
metrics.min_extent = metrics.min_extent.Min({bounds.fLeft, bounds.fTop});
43+
metrics.max_extent =
44+
metrics.max_extent.Max({bounds.fRight, bounds.fBottom});
45+
}
2946

3047
return Font{std::move(typeface), metrics};
3148
}
@@ -38,7 +55,7 @@ TextFrame TextFrameFromTextBlob(const sk_sp<SkTextBlob>& blob, Scalar scale) {
3855
TextFrame frame;
3956

4057
for (SkTextBlobRunIterator run(blob.get()); !run.done(); run.next()) {
41-
TextRun text_run(ToFont(run.font(), scale));
58+
TextRun text_run(ToFont(run, scale));
4259

4360
// TODO(jonahwilliams): ask Skia for a public API to look this up.
4461
// https://github.com/flutter/flutter/issues/112005

impeller/typographer/backends/skia/text_render_context_skia.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ static size_t PairsFitInAtlasOfSize(const FontGlyphPair::Vector& pairs,
7777

7878
for (size_t i = 0; i < pairs.size(); i++) {
7979
const auto& pair = pairs[i];
80+
8081
const auto glyph_size =
8182
ISize::Ceil(pair.font.GetMetrics().GetBoundingBox().size *
8283
pair.font.GetMetrics().scale);
@@ -291,9 +292,9 @@ static std::shared_ptr<SkBitmap> CreateAtlasBitmap(const GlyphAtlas& atlas,
291292
&glyph_id, // glyphs
292293
&position, // positions
293294
SkPoint::Make(-metrics.min_extent.x,
294-
-metrics.ascent), // origin
295-
sk_font, // font
296-
glyph_paint // paint
295+
-metrics.min_extent.y), // origin
296+
sk_font, // font
297+
glyph_paint // paint
297298
);
298299
return true;
299300
});

impeller/typographer/typographer_unittests.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ TEST_P(TypographerTest, GlyphAtlasWithOddUniqueGlyphSize) {
110110

111111
// The 3 unique glyphs should not evenly fit into a square texture, so we
112112
// should have a rectangular one.
113-
ASSERT_EQ(atlas->GetTexture()->GetSize().width * 2,
113+
ASSERT_EQ(atlas->GetTexture()->GetSize().width,
114114
atlas->GetTexture()->GetSize().height);
115115
}
116116

@@ -166,7 +166,7 @@ TEST_P(TypographerTest, GlyphAtlasWithLotsOfdUniqueGlyphSize) {
166166
ASSERT_NE(atlas, nullptr);
167167
ASSERT_NE(atlas->GetTexture(), nullptr);
168168

169-
ASSERT_EQ(atlas->GetTexture()->GetSize().width * 2,
169+
ASSERT_EQ(atlas->GetTexture()->GetSize().width,
170170
atlas->GetTexture()->GetSize().height);
171171
}
172172

0 commit comments

Comments
 (0)