Skip to content

Commit f0992e0

Browse files
authored
Fixes rendering text rotated 180 degrees (#165008)
fixes flutter/flutter#164958 ## 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
1 parent 6316b48 commit f0992e0

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

engine/src/flutter/impeller/display_list/aiks_dl_text_unittests.cc

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,44 @@ TEST_P(AiksTest, CanRenderTextFrameWithFractionScaling) {
207207
ASSERT_TRUE(OpenPlaygroundHere(callback));
208208
}
209209

210+
// https://github.com/flutter/flutter/issues/164958
211+
TEST_P(AiksTest, TextRotated180Degrees) {
212+
float fpivot[2] = {200 + 30, 200 - 20};
213+
float rotation = 180;
214+
float foffset[2] = {200, 200};
215+
216+
auto callback = [&]() -> sk_sp<DisplayList> {
217+
if (AiksTest::ImGuiBegin("Controls", nullptr,
218+
ImGuiWindowFlags_AlwaysAutoResize)) {
219+
ImGui::SliderFloat("pivotx", &fpivot[0], 0, 300);
220+
ImGui::SliderFloat("pivoty", &fpivot[1], 0, 300);
221+
ImGui::SliderFloat("rotation", &rotation, 0, 360);
222+
ImGui::SliderFloat("foffsetx", &foffset[0], 0, 300);
223+
ImGui::SliderFloat("foffsety", &foffset[1], 0, 300);
224+
ImGui::End();
225+
}
226+
DisplayListBuilder builder;
227+
builder.Scale(GetContentScale().x, GetContentScale().y);
228+
builder.DrawPaint(DlPaint().setColor(DlColor(0xffffeeff)));
229+
230+
builder.Save();
231+
DlPoint pivot = Point(fpivot[0], fpivot[1]);
232+
builder.Translate(pivot.x, pivot.y);
233+
builder.Rotate(rotation);
234+
builder.Translate(-pivot.x, -pivot.y);
235+
236+
RenderTextInCanvasSkia(GetContext(), builder, "test", "Roboto-Regular.ttf",
237+
TextRenderOptions{
238+
.color = DlColor::kBlack(),
239+
.position = DlPoint(foffset[0], foffset[1]),
240+
});
241+
242+
builder.Restore();
243+
return builder.Build();
244+
};
245+
ASSERT_TRUE(OpenPlaygroundHere(callback));
246+
}
247+
210248
TEST_P(AiksTest, TextFrameSubpixelAlignment) {
211249
// "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens.
212250
std::array<Scalar, 20> phase_offsets = {

engine/src/flutter/impeller/entity/contents/text_contents.cc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,11 +175,12 @@ void TextContents::ComputeVertexData(
175175
Point uv_origin = (atlas_glyph_bounds.GetLeftTop()) / atlas_size;
176176
Point uv_size = SizeToPoint(atlas_glyph_bounds.GetSize()) / atlas_size;
177177

178+
Matrix unscaled_basis =
179+
Matrix::MakeScale({basis_transform.m[0] > 0 ? 1.f : -1.f,
180+
basis_transform.m[5] > 0 ? 1.f : -1.f, 1.f});
178181
Point unrounded_glyph_position =
179182
// This is for RTL text.
180-
(basis_transform.m[0] < 0 ? Matrix::MakeScale({-1, 1, 1})
181-
: Matrix()) *
182-
glyph_bounds.GetLeftTop() +
183+
unscaled_basis * glyph_bounds.GetLeftTop() +
183184
(basis_transform * glyph_position.position);
184185

185186
Point screen_glyph_position =
@@ -189,9 +190,7 @@ void TextContents::ComputeVertexData(
189190
Point position;
190191
if (is_translation_scale) {
191192
position = (screen_glyph_position +
192-
((basis_transform.m[0] < 0 ? Matrix::MakeScale({-1, 1, 1})
193-
: Matrix()) *
194-
point * glyph_bounds.GetSize()))
193+
(unscaled_basis * point * glyph_bounds.GetSize()))
195194
.Round();
196195
} else {
197196
position = entity_transform *

engine/src/flutter/testing/impeller_golden_tests_output.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,9 @@ impeller_Play_AiksTest_TextForegroundShaderWithTransform_Vulkan.png
919919
impeller_Play_AiksTest_TextFrameSubpixelAlignment_Metal.png
920920
impeller_Play_AiksTest_TextFrameSubpixelAlignment_OpenGLES.png
921921
impeller_Play_AiksTest_TextFrameSubpixelAlignment_Vulkan.png
922+
impeller_Play_AiksTest_TextRotated180Degrees_Metal.png
923+
impeller_Play_AiksTest_TextRotated180Degrees_OpenGLES.png
924+
impeller_Play_AiksTest_TextRotated180Degrees_Vulkan.png
922925
impeller_Play_AiksTest_ToImageFromImage_Metal.png
923926
impeller_Play_AiksTest_ToImageFromImage_OpenGLES.png
924927
impeller_Play_AiksTest_ToImageFromImage_Vulkan.png

0 commit comments

Comments
 (0)