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