1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/graphics/affinetransform.cpp
3 // Purpose: Unit test for transformations implemented for wxAffineMatrix2D
4 // Author: Catalin Raceanu
6 // Copyright: (c) 2011 wxWidgets development team
7 ///////////////////////////////////////////////////////////////////////////////
9 // ----------------------------------------------------------------------------
11 // ----------------------------------------------------------------------------
19 #include "wx/graphics.h"
20 #include "wx/dcmemory.h"
21 #include "wx/affinematrix2d.h"
24 #include "testimage.h"
26 // ----------------------------------------------------------------------------
28 // ----------------------------------------------------------------------------
30 class AffineTransformTestCase
: public CppUnit::TestCase
33 AffineTransformTestCase()
35 wxImage::AddHandler(new wxJPEGHandler
);
41 CPPUNIT_TEST_SUITE( AffineTransformTestCase
);
42 CPPUNIT_TEST( InvertMatrix
);
43 #if wxUSE_DC_TRANSFORM_MATRIX
44 CPPUNIT_TEST( VMirrorAndTranslate
);
45 CPPUNIT_TEST( Rotate90Clockwise
);
46 #if wxUSE_GRAPHICS_CONTEXT
47 CPPUNIT_TEST( CompareToGraphicsContext
);
48 #endif // wxUSE_GRAPHICS_CONTEXT
49 #endif // wxUSE_DC_TRANSFORM_MATRIX
50 CPPUNIT_TEST_SUITE_END();
53 #if wxUSE_DC_TRANSFORM_MATRIX
54 void VMirrorAndTranslate();
55 void Rotate90Clockwise();
56 #if wxUSE_GRAPHICS_CONTEXT
57 void CompareToGraphicsContext();
58 #endif // wxUSE_GRAPHICS_CONTEXT
62 #endif // wxUSE_DC_TRANSFORM_MATRIX
64 DECLARE_NO_COPY_CLASS(AffineTransformTestCase
)
67 // register in the unnamed registry so that these tests are run by default
68 CPPUNIT_TEST_SUITE_REGISTRATION( AffineTransformTestCase
);
70 // also include in its own registry so that these tests can be run alone
71 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AffineTransformTestCase
, "AffineTransformTestCase" );
73 void AffineTransformTestCase::setUp()
75 #if wxUSE_DC_TRANSFORM_MATRIX
76 m_imgOrig
.LoadFile("horse.jpg");
78 CPPUNIT_ASSERT( m_imgOrig
.IsOk() );
80 m_bmpOrig
= wxBitmap(m_imgOrig
);
81 #endif // wxUSE_DC_TRANSFORM_MATRIX
84 void AffineTransformTestCase::InvertMatrix()
86 wxAffineMatrix2D matrix1
;
87 matrix1
.Set(wxMatrix2D(2, 1, 1, 1), wxPoint2DDouble(1, 1));
89 wxAffineMatrix2D
matrix2(matrix1
);
96 CPPUNIT_ASSERT_EQUAL( 1, (int)m
.m_11
);
97 CPPUNIT_ASSERT_EQUAL( -1, (int)m
.m_12
);
98 CPPUNIT_ASSERT_EQUAL( -1, (int)m
.m_21
);
99 CPPUNIT_ASSERT_EQUAL( 2, (int)m
.m_22
);
100 CPPUNIT_ASSERT_EQUAL( 0, (int)p
.m_x
);
101 CPPUNIT_ASSERT_EQUAL( -1, (int)p
.m_y
);
103 matrix2
.Concat(matrix1
);
104 CPPUNIT_ASSERT( matrix2
.IsIdentity() );
107 #if wxUSE_DC_TRANSFORM_MATRIX
109 void AffineTransformTestCase::VMirrorAndTranslate()
111 wxBitmap
bmpUsingMatrix(m_bmpOrig
.GetWidth(), m_bmpOrig
.GetHeight());
113 // build the mirrored image using the transformation matrix
115 wxMemoryDC
dc(bmpUsingMatrix
);
117 if ( !dc
.CanUseTransformMatrix() )
120 wxAffineMatrix2D matrix
;
121 matrix
.Mirror(wxVERTICAL
);
122 matrix
.Translate(0, -m_bmpOrig
.GetHeight() + 1);
123 dc
.SetTransformMatrix(matrix
);
124 dc
.DrawBitmap(m_bmpOrig
, 0, 0);
127 CPPUNIT_ASSERT_EQUAL( bmpUsingMatrix
.ConvertToImage(),
128 m_imgOrig
.Mirror(false) );
131 void AffineTransformTestCase::Rotate90Clockwise()
133 wxBitmap
bmpUsingMatrix(m_bmpOrig
.GetHeight(), m_bmpOrig
.GetWidth());
135 // build the rotated image using the transformation matrix
137 wxMemoryDC
dc(bmpUsingMatrix
);
139 if ( !dc
.CanUseTransformMatrix() )
142 wxAffineMatrix2D matrix
;
143 matrix
.Rotate(0.5 * M_PI
);
144 matrix
.Translate(0, -m_bmpOrig
.GetHeight());
145 dc
.SetTransformMatrix(matrix
);
146 dc
.DrawBitmap(m_bmpOrig
, 0, 0);
149 CPPUNIT_ASSERT_EQUAL( bmpUsingMatrix
.ConvertToImage(),
150 m_imgOrig
.Rotate90(true) );
153 #if wxUSE_GRAPHICS_CONTEXT
154 void AffineTransformTestCase::CompareToGraphicsContext()
156 wxPoint2DDouble
pointA1(1.0, 3.0), pointA2(60.0, 50.0),
157 pointG1(1.0, 3.0), pointG2(60.0, 50.0);
159 // Create affine matrix and transform it
160 wxAffineMatrix2D matrixA1
, matrixA2
;
161 matrixA2
.Rotate(M_PI
/ 3);
162 matrixA1
.Translate(-m_bmpOrig
.GetWidth()/2, -m_bmpOrig
.GetHeight()/2);
163 matrixA1
.Rotate(-M_PI
*2/ 6);
164 matrixA1
.Translate(m_bmpOrig
.GetWidth()/2, m_bmpOrig
.GetHeight()/2);
165 matrixA1
.Mirror(wxHORIZONTAL
);
166 matrixA1
.Concat(matrixA2
);
167 matrixA1
.Mirror(wxVERTICAL
);
168 matrixA1
.Translate(m_bmpOrig
.GetWidth()/2, -m_bmpOrig
.GetHeight()/2);
169 matrixA1
.Scale(0.9, 0.9);
172 // Create image using first matrix
173 wxBitmap
bmpUsingMatrixA1(m_bmpOrig
.GetHeight(), m_bmpOrig
.GetWidth());
175 // Build the transformed image using the transformation matrix
177 wxMemoryDC
dc(bmpUsingMatrixA1
);
179 if ( !dc
.CanUseTransformMatrix() )
183 dc
.SetTransformMatrix(matrixA1
);
184 dc
.DrawBitmap(m_bmpOrig
, 0, 0);
187 matrixA1
.TransformPoint(&pointA1
.m_x
, &pointA1
.m_y
);
188 matrixA1
.TransformDistance(&pointA2
.m_x
, &pointA2
.m_y
);
190 dc
.DrawLine(wxRound(pointA1
.m_x
), wxRound(pointA1
.m_y
),
191 wxRound(pointA1
.m_x
+ pointA2
.m_x
), wxRound(pointA1
.m_x
+ pointA2
.m_y
));
195 // Create graphics matrix and transform it
197 wxGraphicsContext
* gDc
= wxGraphicsContext::Create(mDc
);
198 wxGraphicsMatrix matrixG1
= gDc
->CreateMatrix();
199 wxGraphicsMatrix matrixG2
= gDc
->CreateMatrix();
200 matrixG2
.Rotate(M_PI
/ 3);
201 matrixG1
.Translate(-m_bmpOrig
.GetWidth()/2, -m_bmpOrig
.GetHeight()/2);
202 matrixG1
.Rotate(-M_PI
*2 / 6);
203 matrixG1
.Translate(m_bmpOrig
.GetWidth()/2, m_bmpOrig
.GetHeight()/2);
204 matrixG1
.Scale(-1, 1);
205 matrixG1
.Concat(matrixG2
);
206 matrixG1
.Scale(1, -1);
207 matrixG1
.Translate(m_bmpOrig
.GetWidth()/2, -m_bmpOrig
.GetHeight()/2);
208 matrixG1
.Scale(0.9, 0.9);
210 // Create affine matrix from the graphics matrix
213 matrixG1
.Get(&mat2D
.m_11
, &mat2D
.m_12
, &mat2D
.m_21
, &mat2D
.m_22
, &tr
.m_x
, &tr
.m_y
);
214 wxAffineMatrix2D matrixAG
;
215 matrixAG
.Set(mat2D
, tr
);
219 // Create image using last matrix
220 wxBitmap
bmpUsingMatrixAG(m_bmpOrig
.GetHeight(), m_bmpOrig
.GetWidth());
222 // Build the transformed image using the transformation matrix
224 wxMemoryDC
dc(bmpUsingMatrixAG
);
226 if ( !dc
.CanUseTransformMatrix() )
230 dc
.SetTransformMatrix(matrixAG
);
231 dc
.DrawBitmap(m_bmpOrig
, 0, 0);
234 matrixG1
.TransformPoint(&pointG1
.m_x
, &pointG1
.m_y
);
235 matrixG1
.TransformDistance(&pointG2
.m_x
, &pointG2
.m_y
);
237 dc
.DrawLine(wxRound(pointG1
.m_x
), wxRound(pointG1
.m_y
),
238 wxRound(pointG1
.m_x
+ pointG2
.m_x
), wxRound(pointG1
.m_x
+ pointG2
.m_y
));
242 CPPUNIT_ASSERT_EQUAL( bmpUsingMatrixA1
.ConvertToImage(),
243 bmpUsingMatrixAG
.ConvertToImage() );
245 // Save the images to check that something _is_ inside the visible area.
246 //bmpUsingMatrixA1.SaveFile("matrixA1.jpg", wxBITMAP_TYPE_JPEG);
247 //bmpUsingMatrixAG.SaveFile("matrixAG.jpg", wxBITMAP_TYPE_JPEG);
249 #endif // wxUSE_GRAPHICS_CONTEXT
251 #endif // wxUSE_DC_TRANSFORM_MATRIX