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