Skip to content

Commit 9f9c557

Browse files
chinmaygardednfield
authored andcommitted
Account for glyph extents in the atlas. (flutter#42)
1 parent 62135be commit 9f9c557

File tree

5 files changed

+70
-41
lines changed

5 files changed

+70
-41
lines changed

impeller/entity/contents.cc

+4-8
Original file line numberDiff line numberDiff line change
@@ -635,11 +635,7 @@ bool TextContents::Render(const ContentContext& renderer,
635635
// Iterate through all the runs in the blob.
636636
for (const auto& run : frame_.GetRuns()) {
637637
auto font = run.GetFont();
638-
auto glyph_size = font.GetGlyphSize();
639-
if (!glyph_size.has_value()) {
640-
VALIDATION_LOG << "Glyph has no size.";
641-
return false;
642-
}
638+
auto glyph_size = ISize::Ceil(font.GetMetrics().GetBoundingBox().size);
643639
// Draw each glyph individually. This should probably be batched.
644640
for (const auto& glyph_position : run.GetGlyphPositions()) {
645641
FontGlyphPair font_glyph_pair{font, glyph_position.glyph};
@@ -651,9 +647,9 @@ bool TextContents::Render(const ContentContext& renderer,
651647

652648
VS::GlyphInfo glyph_info;
653649
glyph_info.position = glyph_position.position.Translate(
654-
{0.0, font.GetMetrics().ascent, 0.0});
655-
glyph_info.glyph_size = {static_cast<Scalar>(glyph_size->width),
656-
static_cast<Scalar>(glyph_size->height)};
650+
{font.GetMetrics().min_extent.x, font.GetMetrics().ascent, 0.0});
651+
glyph_info.glyph_size = {static_cast<Scalar>(glyph_size.width),
652+
static_cast<Scalar>(glyph_size.height)};
657653
glyph_info.atlas_position = atlas_glyph_pos->origin;
658654
glyph_info.atlas_glyph_size = {atlas_glyph_pos->size.width,
659655
atlas_glyph_pos->size.height};

impeller/typographer/backends/skia/text_frame_skia.cc

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ static Font ToFont(const SkFont& font) {
2222
metrics.point_size = font.getSize();
2323
metrics.ascent = sk_metrics.fAscent;
2424
metrics.descent = sk_metrics.fDescent;
25+
metrics.min_extent = {sk_metrics.fXMin, sk_metrics.fTop};
26+
metrics.max_extent = {sk_metrics.fXMax, sk_metrics.fBottom};
2527

2628
return Font{std::move(typeface), std::move(metrics)};
2729
}

impeller/typographer/backends/skia/text_render_context_skia.cc

+39-17
Original file line numberDiff line numberDiff line change
@@ -62,21 +62,19 @@ static bool PairsFitInAtlasOfSize(const FontGlyphPair::Vector& pairs,
6262
glyph_positions.reserve(pairs.size());
6363

6464
for (const auto& pair : pairs) {
65-
auto glyph_size = pair.font.GetGlyphSize();
66-
if (!glyph_size.has_value()) {
67-
continue;
68-
}
65+
const auto glyph_size =
66+
ISize::Ceil(pair.font.GetMetrics().GetBoundingBox().size);
6967
SkIPoint16 location_in_atlas;
70-
if (!rect_packer->addRect(glyph_size->width, //
71-
glyph_size->height, //
72-
&location_in_atlas //
68+
if (!rect_packer->addRect(glyph_size.width, //
69+
glyph_size.height, //
70+
&location_in_atlas //
7371
)) {
7472
return false;
7573
}
7674
glyph_positions.emplace_back(Rect::MakeXYWH(location_in_atlas.x(), //
7775
location_in_atlas.y(), //
78-
glyph_size->width, //
79-
glyph_size->height //
76+
glyph_size.width, //
77+
glyph_size.height //
8078
));
8179
}
8280

@@ -122,22 +120,46 @@ static std::optional<SkBitmap> CreateAtlasBitmap(const GlyphAtlas& atlas,
122120
const Rect& location) -> bool {
123121
const auto position = SkPoint::Make(location.origin.x, location.origin.y);
124122
SkGlyphID glyph_id = font_glyph.glyph.index;
125-
SkFont font(
123+
124+
SkFont sk_font(
126125
TypefaceSkia::Cast(*font_glyph.font.GetTypeface()).GetSkiaTypeface(),
127126
font_glyph.font.GetMetrics().point_size);
128127

129-
SkFontMetrics metrics;
130-
font.getMetrics(&metrics);
128+
const auto& metrics = font_glyph.font.GetMetrics();
129+
130+
auto glyph_color = SK_ColorWHITE;
131+
132+
#if 0
133+
{
134+
glyph_color = SkColorSetARGB(255, //
135+
std::rand() % 255, //
136+
std::rand() % 255, //
137+
std::rand() % 255 //
138+
);
139+
SkPaint debug_paint;
140+
debug_paint.setARGB(255 / 4, //
141+
std::rand() % 255, //
142+
std::rand() % 255, //
143+
std::rand() % 255 //
144+
);
145+
canvas->drawRect(SkRect::MakeXYWH(location.origin.x, //
146+
location.origin.y, //
147+
location.size.width, //
148+
location.size.height //
149+
),
150+
debug_paint);
151+
}
152+
#endif
131153

132154
SkPaint glyph_paint;
133-
glyph_paint.setColor(SK_ColorWHITE);
155+
glyph_paint.setColor(glyph_color);
134156
canvas->drawGlyphs(1u, // count
135157
&glyph_id, // glyphs
136158
&position, // positions
137-
SkPoint::Make(0.0,
138-
-metrics.fAscent), // origin
139-
font, // font
140-
glyph_paint // paint
159+
SkPoint::Make(-metrics.min_extent.x,
160+
-metrics.ascent), // origin
161+
sk_font, // font
162+
glyph_paint // paint
141163
);
142164
return true;
143165
});

impeller/typographer/font.cc

-7
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,6 @@ bool Font::IsEqual(const Font& other) const {
3434
is_valid_ == other.is_valid_ && metrics_ == other.metrics_;
3535
}
3636

37-
std::optional<ISize> Font::GetGlyphSize() const {
38-
if (!IsValid()) {
39-
return std::nullopt;
40-
}
41-
return ISize::Ceil(typeface_->GetBoundingBox().size * metrics_.point_size);
42-
}
43-
4437
const Font::Metrics& Font::GetMetrics() const {
4538
return metrics_;
4639
}

impeller/typographer/font.h

+25-9
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,34 @@ class Font : public Comparable<Font> {
4444
/// yields larger numbers.
4545
///
4646
Scalar descent = 0.0f;
47+
//--------------------------------------------------------------------------
48+
/// The minimum glyph extents relative to the origin. Typically negative in
49+
/// an upper-left-origin coordinate system.
50+
///
51+
Point min_extent;
52+
//--------------------------------------------------------------------------
53+
/// The maximum glyph extents relative to the origin. Typically positive in
54+
/// an upper-left-origin coordinate system.
55+
///
56+
Point max_extent;
57+
58+
//--------------------------------------------------------------------------
59+
/// @brief The union of the bounding boxes of all the glyphs.
60+
///
61+
/// @return The bounding box.
62+
///
63+
constexpr Rect GetBoundingBox() const {
64+
return Rect::MakeLTRB(min_extent.x, //
65+
min_extent.y, //
66+
max_extent.x, //
67+
max_extent.y //
68+
);
69+
}
4770

4871
constexpr bool operator==(const Metrics& o) const {
4972
return point_size == o.point_size && ascent == o.ascent &&
50-
descent == o.descent;
73+
descent == o.descent && min_extent == o.min_extent &&
74+
max_extent == o.max_extent;
5175
}
5276
};
5377

@@ -64,14 +88,6 @@ class Font : public Comparable<Font> {
6488
///
6589
const std::shared_ptr<Typeface>& GetTypeface() const;
6690

67-
//----------------------------------------------------------------------------
68-
/// @brief A conservatively large scaled bounding box of all glyphs in
69-
/// this font.
70-
///
71-
/// @return The scaled glyph size.
72-
///
73-
std::optional<ISize> GetGlyphSize() const;
74-
7591
const Metrics& GetMetrics() const;
7692

7793
// |Comparable<Font>|

0 commit comments

Comments
 (0)