7085b5e2126718ab254fbdf6b296406d19b92a4f
[reactos.git] / rostests / apitests / gdi32 / CombineTransform.c
1 /*
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for CombineTransform
5 * PROGRAMMERS: Timo Kreuzer
6 */
7
8 #include <wine/test.h>
9 #include <wingdi.h>
10 #include <winddi.h>
11
12 typedef union
13 {
14 float e;
15 long l;
16 } FLT_LONG;
17
18 #define ok_flt(x, y) \
19 { \
20 FLT_LONG __x, __y; \
21 __x.e = (x); \
22 __y.e = (y); \
23 if (_isnan(y)) {\
24 ok((__x.l == __y.l) || (__x.l == 0), "Wrong value for " #x ", expected " #y " (%f), got %f\n", (double)(y), (double)(x)); \
25 } else {\
26 ok(__x.l == __y.l, "Wrong value for " #x ", expected " #y " (%f), got %f\n", (double)(y), (double)(x)); \
27 } \
28 }
29
30 #define ok_xform(xform, m11, m12, m21, m22, dx, dy) \
31 ok_flt(xform.eM11, m11); \
32 ok_flt(xform.eM12, m12); \
33 ok_flt(xform.eM21, m21); \
34 ok_flt(xform.eM22, m22); \
35 ok_flt(xform.eDx, dx); \
36 ok_flt(xform.eDy, dy);
37
38 #define set_xform(pxform, m11, m12, m21, m22, dx, dy) \
39 (pxform)->eM11 = m11; \
40 (pxform)->eM12 = m12; \
41 (pxform)->eM21 = m21; \
42 (pxform)->eM22 = m22; \
43 (pxform)->eDx = dx; \
44 (pxform)->eDy = dy;
45
46 float geINF;
47 float geIND;
48 float geQNAN;
49
50 void Test_CombineTransform()
51 {
52 XFORM xform1, xform2, xform3;
53
54 /* Test NULL paramters */
55 set_xform(&xform1, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
56 set_xform(&xform2, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
57 SetLastError(ERROR_SUCCESS);
58 ok_int(CombineTransform(&xform3, &xform1, NULL), 0);
59 ok_int(CombineTransform(&xform3, NULL, &xform2), 0);
60 ok_int(CombineTransform(NULL, &xform1, &xform2), 0);
61 ok_int(GetLastError(), ERROR_SUCCESS);
62
63 /* 2 zero matrices */
64 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
65 set_xform(&xform2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
66 SetLastError(ERROR_SUCCESS);
67 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
68 ok_xform(xform3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
69 ok_int(GetLastError(), ERROR_SUCCESS);
70
71 /* 2 Identity matrices */
72 set_xform(&xform1, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
73 set_xform(&xform2, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
74 SetLastError(ERROR_SUCCESS);
75 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
76 ok_xform(xform3, 1.0, 0., 0., 1.0, 0., 0.);
77 ok_int(GetLastError(), ERROR_SUCCESS);
78
79 /* 2 Identity matrices with offsets */
80 set_xform(&xform1, 1.0, 0.0, 0.0, 1.0, 20.0, -100.0);
81 set_xform(&xform2, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
82 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
83 ok_xform(xform3, 1.0, 0., 0., 1.0, 20.0, -100.0);
84
85 xform2.eDx = -60.0;
86 xform2.eDy = -20;
87 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
88 ok_flt(xform3.eDx, -40.0);
89 ok_flt(xform3.eDy, -120.0);
90
91 /* add some stretching */
92 xform2.eM11 = 2;
93 xform2.eM22 = 4;
94 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
95 ok_xform(xform3, 2.0, 0., 0., 4.0, -20.0, -420.0);
96
97 /* add some more stretching */
98 xform1.eM11 = -2.5;
99 xform1.eM22 = 0.5;
100 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
101 ok_xform(xform3, -5.0, 0., 0., 2.0, -20.0, -420.0);
102
103 xform1.eM12 = 2.0;
104 xform1.eM21 = -0.5;
105 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
106 ok_xform(xform3, -5.0, 8.0, -1.0, 2.0, -20.0, -420.0);
107
108 xform2.eM12 = 4.0;
109 xform2.eM21 = 6.5;
110 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
111 ok_xform(xform3, 8.0, -2.0, 2.25, 0.0, -670.0, -340.0);
112
113 set_xform(&xform1, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
114 set_xform(&xform2, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
115 set_xform(&xform3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
116 xform1.eDx = (FLOAT)4294967167.999999761;
117 ok(xform1.eDx == 4294967040.0, "float rounding error.\n");
118 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
119 ok_xform(xform3, 1.0, 0.0, 0.0, 1.0, 4294967040.0, 0.0);
120
121 set_xform(&xform3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
122 xform1.eDx = (FLOAT)4294967167.999999762;
123 ok(xform1.eDx == 4294967296.0, "float rounding error.\n");
124 ok_int(CombineTransform(&xform3, &xform1, &xform2), 0);
125 ok_int(GetLastError(), ERROR_SUCCESS);
126 ok_xform(xform3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
127
128 xform1.eDx = (FLOAT)-4294967167.999999761;
129 ok(xform1.eDx == -4294967040.0, "float rounding error.\n");
130 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
131
132 xform1.eDx = (FLOAT)-4294967167.999999762;
133 ok(xform1.eDx == -4294967296.0, "float rounding error.\n");
134 ok_int(CombineTransform(&xform3, &xform1, &xform2), 0);
135 ok_int(GetLastError(), ERROR_SUCCESS);
136
137 xform1.eDx = 0;
138 xform1.eDy = (FLOAT)4294967167.999999761;
139 ok(xform1.eDy == 4294967040.0, "float rounding error.\n");
140 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
141
142 xform2.eDy = 1;
143 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
144 ok_flt(xform3.eDy, 4294967040.0);
145
146 xform1.eDy = (FLOAT)4294967167.999999762;
147 ok(xform1.eDy == 4294967296.0, "float rounding error.\n");
148 ok_int(CombineTransform(&xform3, &xform1, &xform2), 0);
149 ok_int(GetLastError(), ERROR_SUCCESS);
150
151 xform1.eDy = (FLOAT)-4294967167.999999761;
152 ok(xform1.eDy == -4294967040.0, "float rounding error.\n");
153 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
154
155 xform1.eDy = (FLOAT)-4294967167.999999762;
156 ok(xform1.eDy == -4294967296.0, "float rounding error.\n");
157 ok_int(CombineTransform(&xform3, &xform1, &xform2), 0);
158 ok_int(GetLastError(), ERROR_SUCCESS);
159
160 xform2.eDy = 10000;
161 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
162
163 set_xform(&xform1, 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0);
164 xform1.eDx = (FLOAT)-4294967167.999999762;
165 xform2.eM11 = 1000.0;
166 ok_int(CombineTransform(&xform3, &xform1, &xform2), 0);
167 ok_int(GetLastError(), ERROR_SUCCESS);
168
169 xform1.eDx = 100000.0;
170 xform2.eM11 = 100000.0;
171 ok_int(CombineTransform(&xform3, &xform1, &xform2), 0);
172 ok_int(GetLastError(), ERROR_SUCCESS);
173
174 /* Some undefined values */
175 set_xform(&xform1, geIND, 0.0, 0.0, geINF, 0.0, 0.0);
176 xform2 = xform1;
177 SetLastError(ERROR_SUCCESS);
178 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
179 ok_xform(xform3, geIND, 0.0, 0.0, geINF, 0.0, 0.0);
180 ok_int(GetLastError(), ERROR_SUCCESS);
181
182 set_xform(&xform2, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0);
183 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
184 ok_xform(xform3, geIND, geIND, geINF, geINF, 0.0, 0.0);
185 ok_int(GetLastError(), ERROR_SUCCESS);
186
187 set_xform(&xform1, (FLOAT)18446743500000000000.0, 0.0, 1.0, 0.0, 0.0, 0.0);
188 xform2 = xform1;
189 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
190 ok_flt(xform3.eM11, 340282326356119260000000000000000000000.0);
191
192 xform1.eM11 = (FLOAT)18446745000000000000.0;
193 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
194 ok_flt(xform3.eM11, 340282346638528860000000000000000000000.0);
195
196 xform1.eM11 = (FLOAT)18446746000000000000.0;
197 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
198 ok_long(*(DWORD*)&xform3.eM11, 0x7f800000);
199
200 /* zero matrix + 1 invalid */
201 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
202 set_xform(&xform2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
203 *(DWORD*)&xform2.eM22 = 0x7f800000; // (0.0F/0.0F)
204 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
205 ok_xform(xform3, 0.0, 0.0, 0.0, geIND, 0.0, 0.0);
206
207 /* zero matrix + 1 invalid */
208 xform2 = xform1;
209 *(DWORD*)&xform2.eM12 = 0x7f800000; // (0.0F/0.0F)
210 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
211 ok_xform(xform3, 0.0, geIND, 0.0, geIND, 0.0, 0.0);
212
213 /* Some undefined values */
214 set_xform(&xform1, 0.0, geIND, 0.0, 0.0, 0.0, 0.0);
215 set_xform(&xform2, geIND, 0.0, 0.0, geINF, 0.0, 0.0);
216 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
217 ok_xform(xform3, geIND, geIND, geIND, geIND, 0.0, 0.0);
218
219 }
220
221 void Test_CombineTransform_Inval(float eInval, float eOut)
222 {
223 XFORM xform1, xform2, xform3;
224
225 /* zero matrix / M11 invalid */
226 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
227 set_xform(&xform2, eInval, 0.0, 0.0, 0.0, 0.0, 0.0);
228 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
229 ok_xform(xform3, eOut, 0.0, 0.0, 0.0, 0.0, 0.0); // -> M21
230 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1);
231 ok_xform(xform3, eOut, 0.0, 0.0, 0.0, 0.0, 0.0); // -> M12
232
233 /* zero matrix / M12 invalid */
234 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
235 set_xform(&xform2, 0.0, eInval, 0.0, 0.0, 0.0, 0.0);
236 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
237 ok_xform(xform3, 0.0, eOut, 0.0, eOut, 0.0, 0.0);
238 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1);
239 ok_xform(xform3, eOut, eOut, 0.0, 0.0, 0.0, 0.0);
240
241 /* zero matrix / M21 invalid */
242 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
243 set_xform(&xform2, 0.0, 0.0, eInval, 0.0, 0.0, 0.0);
244 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
245 ok_xform(xform3, eOut, 0.0, eOut, 0.0, 0.0, 0.0);
246 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1);
247 ok_xform(xform3, 0.0, 0.0, eOut, eOut, 0.0, 0.0);
248
249 /* zero matrix / M22 invalid */
250 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
251 set_xform(&xform2, 0.0, 0.0, 0.0, eInval, 0.0, 0.0);
252 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
253 ok_xform(xform3, 0.0, 0.0, 0.0, eOut, 0.0, 0.0); // -> M12
254 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1);
255 ok_xform(xform3, 0.0, 0.0, 0.0, eOut, 0.0, 0.0); // -> M21
256
257 /* zero matrix / M11,M12 invalid */
258 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
259 set_xform(&xform2, eInval, eInval, 0.0, 0.0, 0.0, 0.0);
260 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
261 ok_xform(xform3, eOut, eOut, eOut, eOut, 0.0, 0.0);
262 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1);
263 ok_xform(xform3, eOut, eOut, 0.0, 0.0, 0.0, 0.0);
264
265 /* zero matrix / M11,M21 invalid */
266 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
267 set_xform(&xform2, eInval, 0.0, eInval, 0.0, 0.0, 0.0);
268 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
269 ok_xform(xform3, eOut, 0.0, eOut, 0.0, 0.0, 0.0);
270 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1);
271 ok_xform(xform3, eOut, eOut, eOut, eOut, 0.0, 0.0);
272
273 /* zero matrix / M11,M22 invalid */
274 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
275 set_xform(&xform2, eInval, 0.0, 0.0, eInval, 0.0, 0.0);
276 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
277 ok_xform(xform3, eOut, 0.0, 0.0, eOut, 0.0, 0.0); // -> M12, M21
278 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1);
279 ok_xform(xform3, eOut, 0.0, 0.0, eOut, 0.0, 0.0);
280
281 /* zero matrix / M12,M21 invalid */
282 set_xform(&xform1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
283 set_xform(&xform2, 0.0, eInval, eInval, 0.0, 0.0, 0.0);
284 ok_int(CombineTransform(&xform3, &xform1, &xform2), 1);
285 ok_xform(xform3, eOut, eOut, eOut, eOut, 0.0, 0.0);
286 ok_int(CombineTransform(&xform3, &xform2, &xform1), 1);
287 ok_xform(xform3, eOut, eOut, eOut, eOut, 0.0, 0.0);
288 }
289
290 START_TEST(CombineTransform)
291 {
292 *(DWORD*)&geINF = 0x7f800000;
293 *(DWORD*)&geIND = 0xffc00000;
294 *(DWORD*)&geQNAN = 0x7fc00000;
295
296 Test_CombineTransform();
297
298 Test_CombineTransform_Inval(geINF, geIND);
299 Test_CombineTransform_Inval(geIND, geIND);
300 Test_CombineTransform_Inval(geQNAN, geQNAN);
301
302 }
303