diff options
Diffstat (limited to 'core/fxcrt')
-rw-r--r-- | core/fxcrt/fx_coordinates.cpp | 6 | ||||
-rw-r--r-- | core/fxcrt/fx_coordinates.h | 2 | ||||
-rw-r--r-- | core/fxcrt/fx_coordinates_unittest.cpp | 64 |
3 files changed, 69 insertions, 3 deletions
diff --git a/core/fxcrt/fx_coordinates.cpp b/core/fxcrt/fx_coordinates.cpp index ac13a32329..69fedb5522 100644 --- a/core/fxcrt/fx_coordinates.cpp +++ b/core/fxcrt/fx_coordinates.cpp @@ -271,10 +271,10 @@ void CFX_Matrix::Rotate(float fRadian, bool bPrepended) { bPrepended); } -void CFX_Matrix::RotateAt(float fRadian, float dx, float dy, bool bPrepended) { - Translate(dx, dy, bPrepended); +void CFX_Matrix::RotateAt(float fRadian, float x, float y, bool bPrepended) { + Translate(-x, -y, bPrepended); Rotate(fRadian, bPrepended); - Translate(-dx, -dy, bPrepended); + Translate(x, y, bPrepended); } void CFX_Matrix::Shear(float fAlphaRadian, float fBetaRadian, bool bPrepended) { diff --git a/core/fxcrt/fx_coordinates.h b/core/fxcrt/fx_coordinates.h index 69d16d1c55..3d09652b13 100644 --- a/core/fxcrt/fx_coordinates.h +++ b/core/fxcrt/fx_coordinates.h @@ -637,6 +637,8 @@ class CFX_Matrix { void Scale(float sx, float sy, bool bPrepended = false); void Rotate(float fRadian, bool bPrepended = false); + + // Rotates counterclockwise around the (x, y) point. void RotateAt(float fRadian, float x, float y, bool bPrepended = false); void Shear(float fAlphaRadian, float fBetaRadian, bool bPrepended = false); diff --git a/core/fxcrt/fx_coordinates_unittest.cpp b/core/fxcrt/fx_coordinates_unittest.cpp index 3368a40e18..6fec10ecac 100644 --- a/core/fxcrt/fx_coordinates_unittest.cpp +++ b/core/fxcrt/fx_coordinates_unittest.cpp @@ -289,3 +289,67 @@ TEST(CFX_Matrix, ReverseCR714187) { EXPECT_FLOAT_EQ(expected.x, result.x); EXPECT_FLOAT_EQ(expected.y, result.y); } + +TEST(CFX_Matrix, RotateAt) { + CFX_Matrix m; + m.RotateAt(FX_PI, 10, 20); + + // 180 degree rotation + CFX_PointF p(27, 19); + CFX_PointF new_p = m.Transform(p); + EXPECT_FLOAT_EQ(-7, new_p.x); + EXPECT_FLOAT_EQ(21, new_p.y); + + p = CFX_PointF(10, 20); + new_p = m.Transform(p); + EXPECT_FLOAT_EQ(10, new_p.x); + EXPECT_FLOAT_EQ(20, new_p.y); + + p = CFX_PointF(0, 0); + new_p = m.Transform(p); + EXPECT_FLOAT_EQ(20, new_p.x); + EXPECT_FLOAT_EQ(40, new_p.y); + + // 90 degree rotation + m.SetIdentity(); + m.RotateAt(FX_PI / 2, 10, 20); + + p = CFX_PointF(6, 17); + new_p = m.Transform(p); + EXPECT_FLOAT_EQ(13, new_p.x); + EXPECT_FLOAT_EQ(16, new_p.y); + + p = CFX_PointF(10, 20); + new_p = m.Transform(p); + EXPECT_FLOAT_EQ(10, new_p.x); + EXPECT_FLOAT_EQ(20, new_p.y); + + p = CFX_PointF(0, 0); + new_p = m.Transform(p); + EXPECT_FLOAT_EQ(30, new_p.x); + EXPECT_FLOAT_EQ(10, new_p.y); + + // 60 degree rotation + m.SetIdentity(); + m.RotateAt(FX_PI / 3, 10, 20); + + p = CFX_PointF(20, 20); + new_p = m.Transform(p); + EXPECT_FLOAT_EQ(15, new_p.x); + EXPECT_FLOAT_EQ(28.660254f, new_p.y); + + p = CFX_PointF(10, 20); + new_p = m.Transform(p); + EXPECT_FLOAT_EQ(10, new_p.x); + EXPECT_FLOAT_EQ(20, new_p.y); + + p = CFX_PointF(0, 0); + new_p = m.Transform(p); + EXPECT_FLOAT_EQ(22.320509f, new_p.x); + EXPECT_FLOAT_EQ(1.3397465f, new_p.y); + + p = CFX_PointF(10, -80); + new_p = m.Transform(p); + EXPECT_FLOAT_EQ(96.602540f, new_p.x); + EXPECT_FLOAT_EQ(-30, new_p.y); +} |