From 4f62eabb8b6920333453df353700dc92526c040b Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 12 May 2023 15:28:19 -0700 Subject: [PATCH] [Impeller] Ignore the Z basis when scaling text (#41995) Fixes https://github.com/flutter/flutter/issues/126510. `GetMaxBasisLength()` includes the Z basis vector, which happens to not be getting scaled down along with the X and Y for this reproduction case. And so given the 2D nature of text and the intent of this scale parameter, it's returning a value that's too large here. (cherry picked from commit 6dc9b28677b7d3e65594864347a2c1e3c1b19481) --- impeller/display_list/display_list_dispatcher.cc | 2 +- impeller/geometry/geometry_unittests.cc | 15 +++++++++++++++ impeller/geometry/matrix.cc | 8 ++++++++ impeller/geometry/matrix.h | 2 ++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index c50d0d00ea00a..53f4e67357c6a 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -1283,7 +1283,7 @@ void DisplayListDispatcher::drawDisplayList( void DisplayListDispatcher::drawTextBlob(const sk_sp blob, SkScalar x, SkScalar y) { - Scalar scale = canvas_.GetCurrentTransformation().GetMaxBasisLength(); + Scalar scale = canvas_.GetCurrentTransformation().GetMaxBasisLengthXY(); canvas_.DrawTextFrame(TextFrameFromTextBlob(blob, scale), // impeller::Point{x, y}, // paint_ // diff --git a/impeller/geometry/geometry_unittests.cc b/impeller/geometry/geometry_unittests.cc index 54625b85b9617..a904c07e92124 100644 --- a/impeller/geometry/geometry_unittests.cc +++ b/impeller/geometry/geometry_unittests.cc @@ -336,6 +336,21 @@ TEST(GeometryTest, MatrixGetMaxBasisLength) { } } +TEST(GeometryTest, MatrixGetMaxBasisLengthXY) { + { + auto m = Matrix::MakeScale({3, 1, 1}); + ASSERT_EQ(m.GetMaxBasisLengthXY(), 3); + + m = m * Matrix::MakeSkew(0, 4); + ASSERT_EQ(m.GetMaxBasisLengthXY(), 5); + } + + { + auto m = Matrix::MakeScale({-3, 4, 7}); + ASSERT_EQ(m.GetMaxBasisLengthXY(), 4); + } +} + TEST(GeometryTest, MatrixMakeOrthographic) { { auto m = Matrix::MakeOrthographic(Size(100, 200)); diff --git a/impeller/geometry/matrix.cc b/impeller/geometry/matrix.cc index 70ede5866aee8..0819465591496 100644 --- a/impeller/geometry/matrix.cc +++ b/impeller/geometry/matrix.cc @@ -202,6 +202,14 @@ Scalar Matrix::GetMaxBasisLength() const { return std::sqrt(max); } +Scalar Matrix::GetMaxBasisLengthXY() const { + Scalar max = 0; + for (int i = 0; i < 3; i++) { + max = std::max(max, e[i][0] * e[i][0] + e[i][1] * e[i][1]); + } + return std::sqrt(max); +} + /* * Adapted for Impeller from Graphics Gems: * http://www.realtimerendering.com/resources/GraphicsGems/gemsii/unmatrix.c diff --git a/impeller/geometry/matrix.h b/impeller/geometry/matrix.h index d30d803491288..6938cf930fffa 100644 --- a/impeller/geometry/matrix.h +++ b/impeller/geometry/matrix.h @@ -290,6 +290,8 @@ struct Matrix { Scalar GetMaxBasisLength() const; + Scalar GetMaxBasisLengthXY() const; + constexpr Vector3 GetBasisX() const { return Vector3(m[0], m[1], m[2]); } constexpr Vector3 GetBasisY() const { return Vector3(m[4], m[5], m[6]); }