diff --git a/impeller/entity/contents/text_contents.cc b/impeller/entity/contents/text_contents.cc index bbb2524abb52d..fe6963d1684c8 100644 --- a/impeller/entity/contents/text_contents.cc +++ b/impeller/entity/contents/text_contents.cc @@ -176,8 +176,12 @@ bool TextContents::Render(const ContentContext& renderer, size_t vertex_offset = 0; for (const auto& run : frame_.GetRuns()) { const Font& font = run.GetFont(); + auto rounded_scale = TextFrame::RoundScaledFontSize( + scale_, font.GetMetrics().point_size); + for (const auto& glyph_position : run.GetGlyphPositions()) { - FontGlyphPair font_glyph_pair{font, glyph_position.glyph, scale_}; + FontGlyphPair font_glyph_pair{font, glyph_position.glyph, + rounded_scale}; auto maybe_atlas_glyph_bounds = atlas->FindFontGlyphBounds(font_glyph_pair); if (!maybe_atlas_glyph_bounds.has_value()) { diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index f64463694e71e..2b5dc770f367b 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -2426,6 +2426,13 @@ TEST_P(EntityTest, ColorFilterContentsWithLargeGeometry) { ASSERT_TRUE(OpenPlaygroundHere(entity)); } +TEST_P(EntityTest, TextContentsCeilsGlyphScaleToDecimal) { + ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f, 12), 0.43f); + ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f, 12), 0.53f); + ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f, 12), 2.1f); + ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f, 12), 0.0f); +} + } // namespace testing } // namespace impeller diff --git a/impeller/typographer/text_frame.cc b/impeller/typographer/text_frame.cc index 4191446f05462..c62023666e93a 100644 --- a/impeller/typographer/text_frame.cc +++ b/impeller/typographer/text_frame.cc @@ -79,13 +79,27 @@ bool TextFrame::MaybeHasOverlapping() const { return false; } +// static +Scalar TextFrame::RoundScaledFontSize(Scalar scale, Scalar point_size) { + return std::round(scale * 100) / 100; +} + void TextFrame::CollectUniqueFontGlyphPairs(FontGlyphPair::Set& set, Scalar scale) const { for (const TextRun& run : GetRuns()) { const Font& font = run.GetFont(); + auto rounded_scale = + RoundScaledFontSize(scale, font.GetMetrics().point_size); for (const TextRun::GlyphPosition& glyph_position : run.GetGlyphPositions()) { - set.insert({font, glyph_position.glyph, scale}); +#if false +// Glyph size error due to RoundScaledFontSize usage above. +if (rounded_scale != scale) { + auto delta = std::abs(rounded_scale - scale); + FML_LOG(ERROR) << glyph_position.glyph.bounds.size * delta; +} +#endif + set.insert({font, glyph_position.glyph, rounded_scale}); } } } diff --git a/impeller/typographer/text_frame.h b/impeller/typographer/text_frame.h index 512f7b705e3e3..834528c72b0c1 100644 --- a/impeller/typographer/text_frame.h +++ b/impeller/typographer/text_frame.h @@ -24,6 +24,8 @@ class TextFrame { void CollectUniqueFontGlyphPairs(FontGlyphPair::Set& set, Scalar scale) const; + static Scalar RoundScaledFontSize(Scalar scale, Scalar point_size); + //---------------------------------------------------------------------------- /// @brief The conservative bounding box for this text frame. ///