]>
Commit | Line | Data |
---|---|---|
ab797d5d VZ |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: tests/graphics/affinetransform.cpp | |
3 | // Purpose: Unit test for transformations implemented for wxAffineMatrix2D | |
4 | // Author: Catalin Raceanu | |
5 | // Created: 2011-04-14 | |
6 | // Copyright: (c) 2011 wxWidgets development team | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | ||
9 | // ---------------------------------------------------------------------------- | |
10 | // headers | |
11 | // ---------------------------------------------------------------------------- | |
12 | ||
13 | #include "testprec.h" | |
14 | ||
15 | #ifdef __BORLANDC__ | |
16 | #pragma hdrstop | |
17 | #endif | |
18 | ||
fd5cfba7 | 19 | #include "wx/graphics.h" |
ab797d5d VZ |
20 | #include "wx/dcmemory.h" |
21 | #include "wx/affinematrix2d.h" | |
22 | #include "wx/math.h" | |
23 | ||
24 | #include "testimage.h" | |
25 | ||
26 | // ---------------------------------------------------------------------------- | |
27 | // test class | |
28 | // ---------------------------------------------------------------------------- | |
29 | ||
30 | class AffineTransformTestCase : public CppUnit::TestCase | |
31 | { | |
32 | public: | |
33 | AffineTransformTestCase() | |
34 | { | |
35 | wxImage::AddHandler(new wxJPEGHandler); | |
36 | } | |
37 | ||
38 | virtual void setUp(); | |
39 | ||
40 | private: | |
41 | CPPUNIT_TEST_SUITE( AffineTransformTestCase ); | |
42 | CPPUNIT_TEST( InvertMatrix ); | |
09fa09bf | 43 | #if wxUSE_DC_TRANSFORM_MATRIX |
ab797d5d VZ |
44 | CPPUNIT_TEST( VMirrorAndTranslate ); |
45 | CPPUNIT_TEST( Rotate90Clockwise ); | |
fd5cfba7 VZ |
46 | #if wxUSE_GRAPHICS_CONTEXT |
47 | CPPUNIT_TEST( CompareToGraphicsContext ); | |
48 | #endif // wxUSE_GRAPHICS_CONTEXT | |
09fa09bf | 49 | #endif // wxUSE_DC_TRANSFORM_MATRIX |
ab797d5d VZ |
50 | CPPUNIT_TEST_SUITE_END(); |
51 | ||
52 | void InvertMatrix(); | |
09fa09bf | 53 | #if wxUSE_DC_TRANSFORM_MATRIX |
ab797d5d VZ |
54 | void VMirrorAndTranslate(); |
55 | void Rotate90Clockwise(); | |
fd5cfba7 VZ |
56 | #if wxUSE_GRAPHICS_CONTEXT |
57 | void CompareToGraphicsContext(); | |
58 | #endif // wxUSE_GRAPHICS_CONTEXT | |
ab797d5d VZ |
59 | |
60 | wxImage m_imgOrig; | |
61 | wxBitmap m_bmpOrig; | |
09fa09bf | 62 | #endif // wxUSE_DC_TRANSFORM_MATRIX |
ab797d5d VZ |
63 | |
64 | DECLARE_NO_COPY_CLASS(AffineTransformTestCase) | |
65 | }; | |
66 | ||
67 | // register in the unnamed registry so that these tests are run by default | |
68 | CPPUNIT_TEST_SUITE_REGISTRATION( AffineTransformTestCase ); | |
69 | ||
e3778b4d | 70 | // also include in its own registry so that these tests can be run alone |
ab797d5d VZ |
71 | CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( AffineTransformTestCase, "AffineTransformTestCase" ); |
72 | ||
73 | void AffineTransformTestCase::setUp() | |
74 | { | |
09fa09bf | 75 | #if wxUSE_DC_TRANSFORM_MATRIX |
ab797d5d VZ |
76 | m_imgOrig.LoadFile("horse.jpg"); |
77 | ||
78 | CPPUNIT_ASSERT( m_imgOrig.IsOk() ); | |
79 | ||
80 | m_bmpOrig = wxBitmap(m_imgOrig); | |
09fa09bf | 81 | #endif // wxUSE_DC_TRANSFORM_MATRIX |
ab797d5d VZ |
82 | } |
83 | ||
84 | void AffineTransformTestCase::InvertMatrix() | |
85 | { | |
86 | wxAffineMatrix2D matrix1; | |
87 | matrix1.Set(wxMatrix2D(2, 1, 1, 1), wxPoint2DDouble(1, 1)); | |
88 | ||
89 | wxAffineMatrix2D matrix2(matrix1); | |
90 | ||
91 | matrix2.Invert(); | |
92 | ||
93 | wxMatrix2D m; | |
94 | wxPoint2DDouble p; | |
95 | matrix2.Get(&m, &p); | |
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 ); | |
102 | ||
103 | matrix2.Concat(matrix1); | |
104 | CPPUNIT_ASSERT( matrix2.IsIdentity() ); | |
105 | } | |
106 | ||
09fa09bf VZ |
107 | #if wxUSE_DC_TRANSFORM_MATRIX |
108 | ||
ab797d5d VZ |
109 | void AffineTransformTestCase::VMirrorAndTranslate() |
110 | { | |
111 | wxBitmap bmpUsingMatrix(m_bmpOrig.GetWidth(), m_bmpOrig.GetHeight()); | |
112 | ||
113 | // build the mirrored image using the transformation matrix | |
114 | { | |
115 | wxMemoryDC dc(bmpUsingMatrix); | |
116 | ||
117 | if ( !dc.CanUseTransformMatrix() ) | |
118 | return; | |
119 | ||
120 | wxAffineMatrix2D matrix; | |
121 | matrix.Mirror(wxVERTICAL); | |
5c7fe477 | 122 | matrix.Translate(0, -m_bmpOrig.GetHeight() + 1); |
ab797d5d VZ |
123 | dc.SetTransformMatrix(matrix); |
124 | dc.DrawBitmap(m_bmpOrig, 0, 0); | |
125 | } | |
126 | ||
48611b8f VZ |
127 | CPPUNIT_ASSERT_EQUAL( bmpUsingMatrix.ConvertToImage(), |
128 | m_imgOrig.Mirror(false) ); | |
ab797d5d VZ |
129 | } |
130 | ||
131 | void AffineTransformTestCase::Rotate90Clockwise() | |
132 | { | |
133 | wxBitmap bmpUsingMatrix(m_bmpOrig.GetHeight(), m_bmpOrig.GetWidth()); | |
134 | ||
135 | // build the rotated image using the transformation matrix | |
136 | { | |
137 | wxMemoryDC dc(bmpUsingMatrix); | |
138 | ||
139 | if ( !dc.CanUseTransformMatrix() ) | |
140 | return; | |
141 | ||
142 | wxAffineMatrix2D matrix; | |
fd5cfba7 | 143 | matrix.Rotate(0.5 * M_PI); |
5c7fe477 | 144 | matrix.Translate(0, -m_bmpOrig.GetHeight()); |
ab797d5d VZ |
145 | dc.SetTransformMatrix(matrix); |
146 | dc.DrawBitmap(m_bmpOrig, 0, 0); | |
147 | } | |
148 | ||
48611b8f VZ |
149 | CPPUNIT_ASSERT_EQUAL( bmpUsingMatrix.ConvertToImage(), |
150 | m_imgOrig.Rotate90(true) ); | |
ab797d5d | 151 | } |
09fa09bf | 152 | |
fd5cfba7 VZ |
153 | #if wxUSE_GRAPHICS_CONTEXT |
154 | void AffineTransformTestCase::CompareToGraphicsContext() | |
155 | { | |
156 | wxPoint2DDouble pointA1(1.0, 3.0), pointA2(60.0, 50.0), | |
157 | pointG1(1.0, 3.0), pointG2(60.0, 50.0); | |
158 | ||
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); | |
170 | matrixA1.Invert(); | |
171 | ||
172 | // Create image using first matrix | |
173 | wxBitmap bmpUsingMatrixA1(m_bmpOrig.GetHeight(), m_bmpOrig.GetWidth()); | |
174 | ||
175 | // Build the transformed image using the transformation matrix | |
176 | { | |
177 | wxMemoryDC dc(bmpUsingMatrixA1); | |
178 | ||
179 | if ( !dc.CanUseTransformMatrix() ) | |
180 | return; | |
181 | ||
182 | // Draw the bitmap | |
183 | dc.SetTransformMatrix(matrixA1); | |
184 | dc.DrawBitmap(m_bmpOrig, 0, 0); | |
185 | ||
186 | // Draw a line | |
187 | matrixA1.TransformPoint(&pointA1.m_x, &pointA1.m_y); | |
188 | matrixA1.TransformDistance(&pointA2.m_x, &pointA2.m_y); | |
189 | ||
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)); | |
192 | } | |
193 | ||
194 | ||
195 | // Create graphics matrix and transform it | |
196 | wxMemoryDC mDc; | |
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); | |
209 | matrixG1.Invert(); | |
210 | // Create affine matrix from the graphics matrix | |
211 | wxMatrix2D mat2D; | |
212 | wxPoint2DDouble tr; | |
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); | |
216 | ||
217 | delete gDc; | |
218 | ||
219 | // Create image using last matrix | |
220 | wxBitmap bmpUsingMatrixAG(m_bmpOrig.GetHeight(), m_bmpOrig.GetWidth()); | |
221 | ||
222 | // Build the transformed image using the transformation matrix | |
223 | { | |
224 | wxMemoryDC dc(bmpUsingMatrixAG); | |
225 | ||
226 | if ( !dc.CanUseTransformMatrix() ) | |
227 | return; | |
228 | ||
229 | // Draw the bitmap | |
230 | dc.SetTransformMatrix(matrixAG); | |
231 | dc.DrawBitmap(m_bmpOrig, 0, 0); | |
232 | ||
233 | // Draw a line | |
234 | matrixG1.TransformPoint(&pointG1.m_x, &pointG1.m_y); | |
235 | matrixG1.TransformDistance(&pointG2.m_x, &pointG2.m_y); | |
236 | ||
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)); | |
239 | } | |
240 | ||
241 | ||
242 | CPPUNIT_ASSERT_EQUAL( bmpUsingMatrixA1.ConvertToImage(), | |
243 | bmpUsingMatrixAG.ConvertToImage() ); | |
244 | ||
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); | |
248 | } | |
249 | #endif // wxUSE_GRAPHICS_CONTEXT | |
250 | ||
09fa09bf | 251 | #endif // wxUSE_DC_TRANSFORM_MATRIX |