Skip to content

Commit 83675ed

Browse files
authored
[CP-stable] [Impeller] Fix positioning of text shadow masks (flutter#188766)
This pull request is created manually per (https://github.com/flutter/flutter/blob/main/docs/releases/Flutter-Cherrypick-Process.md#automatically-creates-a-cherry-pick-request) Please fill in the form below, and a flutter domain expert will evaluate this cherry pick request. ### Issue Link: What is the link to the issue this cherry-pick is addressing? flutter#188035 ### Impact Description: Apps that use shadows on Text will have those shadows separate from the text and appear at the coordinate origin of the nearest widget that wraps things with some kind of SaveLayer or engine layer. ### Changelog Description: Explain this cherry pick: * Ensures that shadows track the position of text even when enclosed in a SaveLayer * Prior to this fix, those shadows would appear at the origin of such a SaveLayer - typically the upper or lower corner of one of the parent widgets. * This would happen on all platforms. [flutter/188035] When rendering text with shadows, the shadows would appear elsewhere on the screen, separate from the text ### Workaround: No known workarounds exist. ### Risk: What is the risk level of this cherry-pick? ### Test Coverage: Are you confident that your fix is well-tested by automated tests? ### Validation Steps: The golden images created by this PR will verify the code is correct if the shadows on the text appear directly underneath each rendered string.
1 parent 97f70d2 commit 83675ed

3 files changed

Lines changed: 29 additions & 8 deletions

File tree

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,5 +1055,31 @@ TEST_P(AiksTest, TextWithNonUniformScale) {
10551055
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
10561056
}
10571057

1058+
TEST_P(AiksTest, TextWithShadowAndPosition) {
1059+
DisplayListBuilder builder;
1060+
builder.Scale(GetContentScale().x, GetContentScale().y);
1061+
builder.Clear(DlColor::kWhite());
1062+
1063+
auto frame = MakeDefaultTextFrame("Hello", 25.0f);
1064+
auto text = DlTextImpeller::Make(frame);
1065+
DlPaint paint = DlPaint().setColor(DlColor::kMagenta());
1066+
DlPaint shadow_paint_ctm = DlPaint().setMaskFilter(
1067+
DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 5.0f, true));
1068+
DlPaint shadow_paint_no_ctm = DlPaint().setMaskFilter(
1069+
DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 5.0f, false));
1070+
1071+
builder.Translate(100, 100);
1072+
builder.Scale(4, 4);
1073+
for (int x = 10; x <= 100; x += 30) {
1074+
builder.DrawText(text, x, 20, shadow_paint_ctm);
1075+
builder.DrawText(text, x, 20, paint);
1076+
1077+
builder.DrawText(text, x, 50, shadow_paint_no_ctm);
1078+
builder.DrawText(text, x, 50, paint);
1079+
}
1080+
1081+
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
1082+
}
1083+
10581084
} // namespace testing
10591085
} // namespace impeller

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1947,7 +1947,7 @@ void Canvas::DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
19471947
? std::optional(paint.stroke)
19481948
: std::nullopt);
19491949

1950-
entity.SetTransform(GetCurrentTransform());
1950+
entity.SetTransform(GetCurrentTransform().Translate(position));
19511951

19521952
if (AttemptBlurredTextOptimization(text_frame, text_contents, entity,
19531953
paint)) {

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,7 @@ void TextContents::SetForceTextColor(bool value) {
5858
}
5959

6060
std::optional<Rect> TextContents::GetCoverage(const Entity& entity) const {
61-
const Matrix entity_offset_transform =
62-
entity.GetTransform() * Matrix::MakeTranslation(position_);
63-
return frame_->GetBounds().TransformBounds(entity_offset_transform);
61+
return frame_->GetBounds().TransformBounds(entity.GetTransform());
6462
}
6563

6664
void TextContents::SetTextProperties(
@@ -92,7 +90,7 @@ Scalar AttractToOne(Scalar x) {
9290

9391
void TextContents::ComputeVertexData(
9492
VS::PerVertexData* vtx_contents,
95-
const Matrix& entity_transform,
93+
const Matrix& entity_offset_transform,
9694
const std::shared_ptr<TextFrame>& frame,
9795
Point position,
9896
const Matrix& screen_transform,
@@ -108,9 +106,6 @@ void TextContents::ComputeVertexData(
108106
constexpr std::array<Point, 4> unit_points = {Point{0, 0}, Point{1, 0},
109107
Point{0, 1}, Point{1, 1}};
110108

111-
Matrix entity_offset_transform =
112-
entity_transform * Matrix::MakeTranslation(position);
113-
114109
ISize atlas_size = atlas->GetTexture()->GetSize();
115110
bool is_translation_scale = entity_offset_transform.IsTranslationScaleOnly();
116111
Matrix basis_transform = entity_offset_transform.Basis();

0 commit comments

Comments
 (0)