Fixed the text aspect ratio (#162415)

fixes https://github.com/flutter/flutter/issues/162348

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
gaaclarke 2025-01-30 18:50:20 -08:00 committed by GitHub
parent 1902fb27a6
commit 3c5ae1eb87
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 49 additions and 8 deletions

View File

@ -18,6 +18,9 @@
#include "impeller/typographer/glyph_atlas.h"
namespace impeller {
Point SizeToPoint(Size size) {
return Point(size.width, size.height);
}
using VS = GlyphAtlasPipeline::VertexShader;
using FS = GlyphAtlasPipeline::FragmentShader;
@ -167,9 +170,8 @@ void TextContents::ComputeVertexData(
// glyph bounds are used to compute UVs in cases where the
// destination and source sizes may differ due to clamping the sizes
// of large glyphs.
Point uv_origin =
(atlas_glyph_bounds.GetLeftTop() - Point(0.5, 0.5)) / atlas_size;
Point uv_size = (atlas_glyph_bounds.GetSize() + Point(1, 1)) / atlas_size;
Point uv_origin = (atlas_glyph_bounds.GetLeftTop()) / atlas_size;
Point uv_size = SizeToPoint(atlas_glyph_bounds.GetSize()) / atlas_size;
Point unrounded_glyph_position =
// This is for RTL text.

View File

@ -88,6 +88,9 @@ Rect PerVertexDataUVToRect(
return Rect::MakeLTRB(left, top, right, bottom);
}
double GetAspectRatio(Rect rect) {
return static_cast<double>(rect.GetWidth()) / rect.GetHeight();
}
} // namespace
TEST_P(TextContentsTest, SimpleComputeVertexData) {
@ -123,10 +126,7 @@ TEST_P(TextContentsTest, SimpleComputeVertexData) {
// is 50, the math appears to be to get back a 50x50 rect and apply 1 pixel
// of padding.
EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -41, 52, 52));
// (0.5, 0.5) gets us sampling from the exact middle of the first pixel, the
// extra width takes us 0.5 past the end of the glyph too to sample fully the
// last pixel.
EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(0.5, 0.5, 53, 53));
EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 52, 52));
}
TEST_P(TextContentsTest, SimpleComputeVertexData2x) {
@ -160,7 +160,46 @@ TEST_P(TextContentsTest, SimpleComputeVertexData2x) {
Rect position_rect = PerVertexDataPositionToRect(data);
Rect uv_rect = PerVertexDataUVToRect(data, texture_size);
EXPECT_RECT_NEAR(position_rect, Rect::MakeXYWH(-1, -81, 102, 102));
EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(0.5, 0.5, 103, 103));
EXPECT_RECT_NEAR(uv_rect, Rect::MakeXYWH(1.0, 1.0, 102, 102));
}
TEST_P(TextContentsTest, MaintainsShape) {
std::shared_ptr<TextFrame> text_frame =
MakeTextFrame("th", "ahem.ttf", /*font_size=*/50);
std::shared_ptr<TypographerContext> context = TypographerContextSkia::Make();
std::shared_ptr<GlyphAtlasContext> atlas_context =
context->CreateGlyphAtlasContext(GlyphAtlas::Type::kAlphaBitmap);
std::shared_ptr<HostBuffer> host_buffer = HostBuffer::Create(
GetContext()->GetResourceAllocator(), GetContext()->GetIdleWaiter());
ASSERT_TRUE(context && context->IsValid());
for (int i = 0; i <= 1000; ++i) {
Scalar font_scale = 0.440 + (i / 1000.0);
Rect position_rect[2];
Rect uv_rect[2];
{
GlyphAtlasPipeline::VertexShader::PerVertexData data[12];
std::shared_ptr<GlyphAtlas> atlas =
CreateGlyphAtlas(*GetContext(), context.get(), *host_buffer,
GlyphAtlas::Type::kAlphaBitmap, font_scale,
atlas_context, text_frame);
ISize texture_size = atlas->GetTexture()->GetSize();
TextContents::ComputeVertexData(
data, text_frame, font_scale,
/*entity_transform=*/Matrix::MakeScale({font_scale, font_scale, 1}),
/*offset=*/Vector2(0, 0),
/*glyph_properties=*/std::nullopt, atlas);
position_rect[0] = PerVertexDataPositionToRect(data);
uv_rect[0] = PerVertexDataUVToRect(data, texture_size);
position_rect[1] = PerVertexDataPositionToRect(data + 6);
uv_rect[1] = PerVertexDataUVToRect(data + 6, texture_size);
}
EXPECT_NEAR(GetAspectRatio(position_rect[1]), GetAspectRatio(uv_rect[1]),
0.001)
<< i;
}
}
} // namespace testing