1 /* 2 * Unit tests for mapping functions 3 * 4 * Copyright (c) 2005 Huw Davies 5 * Copyright (c) 2008 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "precomp.h" 23 24 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout); 25 static DWORD (WINAPI *pGetLayout)(HDC hdc); 26 static INT (WINAPI *pGetRandomRgn)(HDC hDC, HRGN hRgn, INT iCode); 27 static BOOL (WINAPI *pGetTransform)(HDC, DWORD, XFORM *); 28 static BOOL (WINAPI *pSetVirtualResolution)(HDC, DWORD, DWORD, DWORD, DWORD); 29 30 #define rough_match(got, expected) (abs( MulDiv( (got) - (expected), 1000, (expected) )) <= 5) 31 32 #define expect_LPtoDP(_hdc, _x, _y) \ 33 { \ 34 POINT _pt = { 1000, 1000 }; \ 35 LPtoDP(_hdc, &_pt, 1); \ 36 ok(rough_match(_pt.x, _x), "expected x %d, got %d\n", (_x), _pt.x); \ 37 ok(rough_match(_pt.y, _y), "expected y %d, got %d\n", (_y), _pt.y); \ 38 } 39 40 #define expect_world_transform(_hdc, _em11, _em22) \ 41 { \ 42 BOOL _ret; \ 43 XFORM _xform; \ 44 SetLastError(0xdeadbeef); \ 45 _ret = GetWorldTransform(_hdc, &_xform); \ 46 if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) \ 47 { \ 48 ok(_ret, "GetWorldTransform error %u\n", GetLastError()); \ 49 ok(_xform.eM11 == (_em11), "expected %f, got %f\n", (_em11), _xform.eM11); \ 50 ok(_xform.eM12 == 0.0, "expected 0.0, got %f\n", _xform.eM12); \ 51 ok(_xform.eM21 == 0.0, "expected 0.0, got %f\n", _xform.eM21); \ 52 ok(_xform.eM22 == (_em22), "expected %f, got %f\n", (_em22), _xform.eM22); \ 53 ok(_xform.eDx == 0.0, "expected 0.0, got %f\n", _xform.eDx); \ 54 ok(_xform.eDy == 0.0, "expected 0.0, got %f\n", _xform.eDy); \ 55 } \ 56 } 57 58 #define expect_dc_ext(_func, _hdc, _cx, _cy) \ 59 { \ 60 BOOL _ret; \ 61 SIZE _size; \ 62 SetLastError(0xdeadbeef); \ 63 _ret = _func(_hdc, &_size); \ 64 ok(_ret, #_func " error %u\n", GetLastError()); \ 65 ok(_size.cx == (_cx), "expected cx %d, got %d\n", (_cx), _size.cx); \ 66 ok(_size.cy == (_cy), "expected cy %d, got %d\n", (_cy), _size.cy); \ 67 } 68 69 #define expect_viewport_ext(_hdc, _cx, _cy) expect_dc_ext(GetViewportExtEx, _hdc, _cx, _cy) 70 #define expect_window_ext(_hdc, _cx, _cy) expect_dc_ext(GetWindowExtEx, _hdc, _cx, _cy) 71 72 static void test_world_transform(void) 73 { 74 HDC hdc; 75 INT ret, size_cx, size_cy, res_x, res_y, dpi_x, dpi_y; 76 XFORM xform; 77 SIZE size; 78 79 hdc = CreateCompatibleDC(0); 80 81 xform.eM11 = 1.0f; 82 xform.eM12 = 0.0f; 83 xform.eM21 = 0.0f; 84 xform.eM22 = 1.0f; 85 xform.eDx = 0.0f; 86 xform.eDy = 0.0f; 87 ret = SetWorldTransform(hdc, &xform); 88 ok(!ret, "SetWorldTransform should fail in GM_COMPATIBLE mode\n"); 89 90 size_cx = GetDeviceCaps(hdc, HORZSIZE); 91 size_cy = GetDeviceCaps(hdc, VERTSIZE); 92 res_x = GetDeviceCaps(hdc, HORZRES); 93 res_y = GetDeviceCaps(hdc, VERTRES); 94 dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); 95 dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); 96 trace("dc size %d x %d, resolution %d x %d dpi %d x %d\n", 97 size_cx, size_cy, res_x, res_y, dpi_x, dpi_y ); 98 99 expect_viewport_ext(hdc, 1, 1); 100 expect_window_ext(hdc, 1, 1); 101 expect_world_transform(hdc, 1.0, 1.0); 102 expect_LPtoDP(hdc, 1000, 1000); 103 104 SetLastError(0xdeadbeef); 105 ret = SetMapMode(hdc, MM_LOMETRIC); 106 ok(ret == MM_TEXT, "expected MM_TEXT, got %d\n", ret); 107 108 expect_viewport_ext(hdc, res_x, -res_y); 109 ok( GetWindowExtEx( hdc, &size ), "GetWindowExtEx failed\n" ); 110 ok( rough_match( size.cx, size_cx * 10 ) || 111 rough_match( size.cx, MulDiv( res_x, 254, dpi_x )), /* Vista uses a more precise method */ 112 "expected cx %d or %d, got %d\n", size_cx * 10, MulDiv( res_x, 254, dpi_x ), size.cx ); 113 ok( rough_match( size.cy, size_cy * 10 ) || 114 rough_match( size.cy, MulDiv( res_y, 254, dpi_y )), /* Vista uses a more precise method */ 115 "expected cy %d or %d, got %d\n", size_cy * 10, MulDiv( res_y, 254, dpi_y ), size.cy ); 116 expect_world_transform(hdc, 1.0, 1.0); 117 expect_LPtoDP(hdc, MulDiv(1000 / 10, res_x, size_cx), -MulDiv(1000 / 10, res_y, size_cy)); 118 119 SetLastError(0xdeadbeef); 120 ret = SetMapMode(hdc, MM_TEXT); 121 ok(ret == MM_LOMETRIC, "expected MM_LOMETRIC, got %d\n", ret); 122 123 expect_viewport_ext(hdc, 1, 1); 124 expect_window_ext(hdc, 1, 1); 125 expect_world_transform(hdc, 1.0, 1.0); 126 expect_LPtoDP(hdc, 1000, 1000); 127 128 ret = SetGraphicsMode(hdc, GM_ADVANCED); 129 if (!ret) 130 { 131 DeleteDC(hdc); 132 skip("GM_ADVANCED is not supported on this platform\n"); 133 return; 134 } 135 136 expect_viewport_ext(hdc, 1, 1); 137 expect_window_ext(hdc, 1, 1); 138 expect_world_transform(hdc, 1.0, 1.0); 139 expect_LPtoDP(hdc, 1000, 1000); 140 141 /* The transform must conform to (eM11 * eM22 != eM12 * eM21) requirement */ 142 xform.eM11 = 1.0f; 143 xform.eM12 = 2.0f; 144 xform.eM21 = 1.0f; 145 xform.eM22 = 2.0f; 146 xform.eDx = 0.0f; 147 xform.eDy = 0.0f; 148 ret = SetWorldTransform(hdc, &xform); 149 ok(!ret || 150 broken(ret), /* NT4 */ 151 "SetWorldTransform should fail with an invalid xform\n"); 152 153 xform.eM11 = 20.0f; 154 xform.eM12 = 0.0f; 155 xform.eM21 = 0.0f; 156 xform.eM22 = 20.0f; 157 xform.eDx = 0.0f; 158 xform.eDy = 0.0f; 159 SetLastError(0xdeadbeef); 160 ret = SetWorldTransform(hdc, &xform); 161 ok(ret, "SetWorldTransform error %u\n", GetLastError()); 162 163 expect_viewport_ext(hdc, 1, 1); 164 expect_window_ext(hdc, 1, 1); 165 expect_world_transform(hdc, 20.0, 20.0); 166 expect_LPtoDP(hdc, 20000, 20000); 167 168 SetLastError(0xdeadbeef); 169 ret = SetMapMode(hdc, MM_LOMETRIC); 170 ok(ret == MM_TEXT, "expected MM_TEXT, got %d\n", ret); 171 172 expect_viewport_ext(hdc, res_x, -res_y); 173 ok( GetWindowExtEx( hdc, &size ), "GetWindowExtEx failed\n" ); 174 ok( rough_match( size.cx, size_cx * 10 ) || 175 rough_match( size.cx, MulDiv( res_x, 254, dpi_x )), /* Vista uses a more precise method */ 176 "expected cx %d or %d, got %d\n", size_cx * 10, MulDiv( res_x, 254, dpi_x ), size.cx ); 177 ok( rough_match( size.cy, size_cy * 10 ) || 178 rough_match( size.cy, MulDiv( res_y, 254, dpi_y )), /* Vista uses a more precise method */ 179 "expected cy %d or %d, got %d\n", size_cy * 10, MulDiv( res_y, 254, dpi_y ), size.cy ); 180 expect_world_transform(hdc, 20.0, 20.0); 181 expect_LPtoDP(hdc, MulDiv(20000, res_x, size.cx), -MulDiv(20000, res_y, size.cy)); 182 183 SetLastError(0xdeadbeef); 184 ret = SetMapMode(hdc, MM_TEXT); 185 ok(ret == MM_LOMETRIC, "expected MM_LOMETRIC, got %d\n", ret); 186 187 expect_viewport_ext(hdc, 1, 1); 188 expect_window_ext(hdc, 1, 1); 189 expect_world_transform(hdc, 20.0, 20.0); 190 expect_LPtoDP(hdc, 20000, 20000); 191 192 size.cx = 0xdeadbeef; 193 size.cy = 0xdeadbeef; 194 ret = SetViewportExtEx(hdc, -1, -1, &size); 195 ok(ret, "SetViewportExtEx(-1, -1) failed\n"); 196 ok(size.cx == 1 && size.cy == 1, "expected 1,1 got %d,%d\n", size.cx, size.cy); 197 expect_viewport_ext(hdc, 1, 1); 198 expect_window_ext(hdc, 1, 1); 199 expect_world_transform(hdc, 20.0, 20.0); 200 expect_LPtoDP(hdc, 20000, 20000); 201 202 ret = SetMapMode(hdc, MM_ANISOTROPIC); 203 ok(ret == MM_TEXT, "expected MM_TEXT, got %d\n", ret); 204 205 expect_viewport_ext(hdc, 1, 1); 206 expect_window_ext(hdc, 1, 1); 207 expect_world_transform(hdc, 20.0, 20.0); 208 expect_LPtoDP(hdc, 20000, 20000); 209 210 size.cx = 0xdeadbeef; 211 size.cy = 0xdeadbeef; 212 ret = SetViewportExtEx(hdc, -1, -1, &size); 213 ok(ret, "SetViewportExtEx(-1, -1) failed\n"); 214 ok(size.cx == 1 && size.cy == 1, "expected 1,1 got %d,%d\n", size.cx, size.cy); 215 expect_viewport_ext(hdc, -1, -1); 216 expect_window_ext(hdc, 1, 1); 217 expect_world_transform(hdc, 20.0, 20.0); 218 expect_LPtoDP(hdc, -20000, -20000); 219 220 ret = SetGraphicsMode(hdc, GM_COMPATIBLE); 221 ok(ret, "SetGraphicsMode(GM_COMPATIBLE) should not fail if DC has't an identity transform\n"); 222 ret = GetGraphicsMode(hdc); 223 ok(ret == GM_COMPATIBLE, "expected GM_COMPATIBLE, got %d\n", ret); 224 225 expect_viewport_ext(hdc, -1, -1); 226 expect_window_ext(hdc, 1, 1); 227 expect_world_transform(hdc, 20.0, 20.0); 228 expect_LPtoDP(hdc, -20000, -20000); 229 230 DeleteDC(hdc); 231 } 232 233 static void test_dc_layout(void) 234 { 235 INT ret, size_cx, size_cy, res_x, res_y, dpi_x, dpi_y; 236 SIZE size; 237 POINT pt; 238 HBITMAP bitmap; 239 RECT rc, ret_rc; 240 HDC hdc; 241 HRGN hrgn; 242 243 if (!pGetLayout || !pSetLayout) 244 { 245 win_skip( "Don't have SetLayout\n" ); 246 return; 247 } 248 249 hdc = CreateCompatibleDC(0); 250 bitmap = CreateCompatibleBitmap( hdc, 100, 100 ); 251 SelectObject( hdc, bitmap ); 252 253 size_cx = GetDeviceCaps(hdc, HORZSIZE); 254 size_cy = GetDeviceCaps(hdc, VERTSIZE); 255 res_x = GetDeviceCaps(hdc, HORZRES); 256 res_y = GetDeviceCaps(hdc, VERTRES); 257 dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); 258 dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); 259 260 ret = GetMapMode( hdc ); 261 ok(ret == MM_TEXT, "expected MM_TEXT, got %d\n", ret); 262 expect_viewport_ext(hdc, 1, 1); 263 expect_window_ext(hdc, 1, 1); 264 expect_world_transform(hdc, 1.0, 1.0); 265 expect_LPtoDP(hdc, 1000, 1000); 266 267 pSetLayout( hdc, LAYOUT_RTL ); 268 if (!pGetLayout( hdc )) 269 { 270 win_skip( "SetLayout not supported\n" ); 271 DeleteDC(hdc); 272 return; 273 } 274 275 ret = GetMapMode( hdc ); 276 ok(ret == MM_ANISOTROPIC, "expected MM_ANISOTROPIC, got %d\n", ret); 277 expect_viewport_ext(hdc, 1, 1); 278 expect_window_ext(hdc, 1, 1); 279 expect_world_transform(hdc, 1.0, 1.0); 280 expect_LPtoDP(hdc, -1000 + 99, 1000); 281 GetViewportOrgEx( hdc, &pt ); 282 ok( pt.x == 0 && pt.y == 0, "wrong origin %d,%d\n", pt.x, pt.y ); 283 GetWindowOrgEx( hdc, &pt ); 284 ok( pt.x == 0 && pt.y == 0, "wrong origin %d,%d\n", pt.x, pt.y ); 285 GetDCOrgEx( hdc, &pt ); 286 ok( pt.x == 0 && pt.y == 0, "wrong origin %d,%d\n", pt.x, pt.y ); 287 if (pGetTransform) 288 { 289 XFORM xform; 290 BOOL ret = pGetTransform( hdc, 0x204, &xform ); /* World -> Device */ 291 ok( ret, "got %d\n", ret ); 292 ok( xform.eM11 == -1.0, "got %f\n", xform.eM11 ); 293 ok( xform.eM12 == 0.0, "got %f\n", xform.eM12 ); 294 ok( xform.eM21 == 0.0, "got %f\n", xform.eM21 ); 295 ok( xform.eM22 == 1.0, "got %f\n", xform.eM22 ); 296 ok( xform.eDx == 99.0, "got %f\n", xform.eDx ); 297 ok( xform.eDy == 0.0, "got %f\n", xform.eDy ); 298 } 299 300 SetRect( &rc, 10, 10, 20, 20 ); 301 IntersectClipRect( hdc, 10, 10, 20, 20 ); 302 hrgn = CreateRectRgn( 0, 0, 0, 0 ); 303 GetClipRgn( hdc, hrgn ); 304 GetRgnBox( hrgn, &ret_rc ); 305 ok( EqualRect( &rc, &ret_rc ), "wrong clip box %s\n", wine_dbgstr_rect( &ret_rc )); 306 pSetLayout( hdc, LAYOUT_LTR ); 307 SetRect( &rc, 80, 10, 90, 20 ); 308 GetClipRgn( hdc, hrgn ); 309 GetRgnBox( hrgn, &ret_rc ); 310 ok( EqualRect( &rc, &ret_rc ), "wrong clip box %s\n", wine_dbgstr_rect( &ret_rc )); 311 GetClipBox( hdc, &ret_rc ); 312 ok( EqualRect( &rc, &ret_rc ), "wrong clip box %s\n", wine_dbgstr_rect( &ret_rc )); 313 IntersectClipRect( hdc, 80, 10, 85, 20 ); 314 pSetLayout( hdc, LAYOUT_RTL ); 315 SetRect( &rc, 15, 10, 20, 20 ); 316 GetClipRgn( hdc, hrgn ); 317 GetRgnBox( hrgn, &ret_rc ); 318 ok( EqualRect( &rc, &ret_rc ), "wrong clip box %s\n", wine_dbgstr_rect( &ret_rc )); 319 GetClipBox( hdc, &ret_rc ); 320 ok( EqualRect( &rc, &ret_rc ), "wrong clip box %s\n", wine_dbgstr_rect( &ret_rc )); 321 SetRectRgn( hrgn, 60, 10, 80, 20 ); 322 pSetLayout( hdc, LAYOUT_LTR ); 323 ExtSelectClipRgn( hdc, hrgn, RGN_OR ); 324 pSetLayout( hdc, LAYOUT_RTL ); 325 SetRect( &rc, 15, 10, 40, 20 ); 326 GetClipRgn( hdc, hrgn ); 327 GetRgnBox( hrgn, &ret_rc ); 328 ok( EqualRect( &rc, &ret_rc ), "wrong clip box %s\n", wine_dbgstr_rect( &ret_rc )); 329 GetClipBox( hdc, &ret_rc ); 330 ok( EqualRect( &rc, &ret_rc ), "wrong clip box %s\n", wine_dbgstr_rect( &ret_rc )); 331 332 /* OffsetClipRgn mirrors too */ 333 OffsetClipRgn( hdc, 5, 5 ); 334 OffsetRect( &rc, 5, 5 ); 335 GetClipRgn( hdc, hrgn ); 336 GetRgnBox( hrgn, &ret_rc ); 337 ok( EqualRect( &rc, &ret_rc ), "wrong clip box %s\n", wine_dbgstr_rect( &ret_rc )); 338 339 /* GetRandomRgn returns the raw region */ 340 if (pGetRandomRgn) 341 { 342 SetRect( &rc, 55, 15, 80, 25 ); 343 pGetRandomRgn( hdc, hrgn, 1 ); 344 GetRgnBox( hrgn, &ret_rc ); 345 ok( EqualRect( &rc, &ret_rc ), "wrong clip box %s\n", wine_dbgstr_rect( &ret_rc )); 346 } 347 348 SetMapMode(hdc, MM_LOMETRIC); 349 ret = GetMapMode( hdc ); 350 ok(ret == MM_ANISOTROPIC, "expected MM_ANISOTROPIC, got %d\n", ret); 351 352 expect_viewport_ext(hdc, res_x, -res_y); 353 ok( GetWindowExtEx( hdc, &size ), "GetWindowExtEx failed\n" ); 354 ok( rough_match( size.cx, size_cx * 10 ) || 355 rough_match( size.cx, MulDiv( res_x, 254, dpi_x )), /* Vista uses a more precise method */ 356 "expected cx %d or %d, got %d\n", size_cx * 10, MulDiv( res_x, 254, dpi_x ), size.cx ); 357 ok( rough_match( size.cy, size_cy * 10 ) || 358 rough_match( size.cy, MulDiv( res_y, 254, dpi_y )), /* Vista uses a more precise method */ 359 "expected cy %d or %d, got %d\n", size_cy * 10, MulDiv( res_y, 254, dpi_y ), size.cy ); 360 expect_world_transform(hdc, 1.0, 1.0); 361 expect_LPtoDP(hdc, -MulDiv(1000 / 10, res_x, size_cx) + 99, -MulDiv(1000 / 10, res_y, size_cy)); 362 363 SetMapMode(hdc, MM_TEXT); 364 ret = GetMapMode( hdc ); 365 ok(ret == MM_ANISOTROPIC, "expected MM_ANISOTROPIC, got %d\n", ret); 366 pSetLayout( hdc, LAYOUT_LTR ); 367 ret = GetMapMode( hdc ); 368 ok(ret == MM_ANISOTROPIC, "expected MM_ANISOTROPIC, got %d\n", ret); 369 SetMapMode(hdc, MM_TEXT); 370 ret = GetMapMode( hdc ); 371 ok(ret == MM_TEXT, "expected MM_TEXT, got %d\n", ret); 372 373 DeleteDC(hdc); 374 DeleteObject( bitmap ); 375 } 376 377 static void test_modify_world_transform(void) 378 { 379 HDC hdc = GetDC(0); 380 int ret; 381 382 ret = SetGraphicsMode(hdc, GM_ADVANCED); 383 ok(ret, "ret = %d\n", ret); 384 385 ret = ModifyWorldTransform(hdc, NULL, MWT_IDENTITY); 386 ok(ret, "ret = %d\n", ret); 387 388 ret = ModifyWorldTransform(hdc, NULL, MWT_LEFTMULTIPLY); 389 ok(!ret, "ret = %d\n", ret); 390 391 ret = ModifyWorldTransform(hdc, NULL, MWT_RIGHTMULTIPLY); 392 ok(!ret, "ret = %d\n", ret); 393 394 ReleaseDC(0, hdc); 395 } 396 397 static void test_SetWindowExt(HDC hdc, LONG cx, LONG cy, LONG expected_vp_cx, LONG expected_vp_cy) 398 { 399 SIZE windowExt, viewportExt; 400 POINT windowOrg, windowOrgAfter, viewportOrg, viewportOrgAfter; 401 402 GetWindowOrgEx(hdc, &windowOrg); 403 GetViewportOrgEx(hdc, &viewportOrg); 404 405 SetWindowExtEx(hdc, cx, cy, NULL); 406 GetWindowExtEx(hdc, &windowExt); 407 ok(windowExt.cx == cx && windowExt.cy == cy, 408 "Window extension: Expected %dx%d, got %dx%d\n", 409 cx, cy, windowExt.cx, windowExt.cy); 410 411 GetViewportExtEx(hdc, &viewportExt); 412 ok(rough_match(viewportExt.cx, expected_vp_cx) && rough_match(viewportExt.cy, expected_vp_cy), 413 "Viewport extents have not been properly adjusted: Expected %dx%d, got %dx%d\n", 414 expected_vp_cx, expected_vp_cy, viewportExt.cx, viewportExt.cy); 415 416 GetWindowOrgEx(hdc, &windowOrgAfter); 417 ok(windowOrg.x == windowOrgAfter.x && windowOrg.y == windowOrgAfter.y, 418 "Window origin changed from (%d,%d) to (%d,%d)\n", 419 windowOrg.x, windowOrg.y, windowOrgAfter.x, windowOrgAfter.y); 420 421 GetViewportOrgEx(hdc, &viewportOrgAfter); 422 ok(viewportOrg.x == viewportOrgAfter.x && viewportOrg.y == viewportOrgAfter.y, 423 "Viewport origin changed from (%d,%d) to (%d,%d)\n", 424 viewportOrg.x, viewportOrg.y, viewportOrgAfter.x, viewportOrgAfter.y); 425 } 426 427 static void test_SetViewportExt(HDC hdc, LONG cx, LONG cy, LONG expected_vp_cx, LONG expected_vp_cy) 428 { 429 SIZE windowExt, windowExtAfter, viewportExt; 430 POINT windowOrg, windowOrgAfter, viewportOrg, viewportOrgAfter; 431 432 GetWindowOrgEx(hdc, &windowOrg); 433 GetViewportOrgEx(hdc, &viewportOrg); 434 GetWindowExtEx(hdc, &windowExt); 435 436 SetViewportExtEx(hdc, cx, cy, NULL); 437 GetViewportExtEx(hdc, &viewportExt); 438 ok(rough_match(viewportExt.cx, expected_vp_cx) && rough_match(viewportExt.cy, expected_vp_cy), 439 "Viewport extents have not been properly adjusted: Expected %dx%d, got %dx%d\n", 440 expected_vp_cx, expected_vp_cy, viewportExt.cx, viewportExt.cy); 441 442 GetWindowExtEx(hdc, &windowExtAfter); 443 ok(windowExt.cx == windowExtAfter.cx && windowExt.cy == windowExtAfter.cy, 444 "Window extension changed from %dx%d to %dx%d\n", 445 windowExt.cx, windowExt.cy, windowExtAfter.cx, windowExtAfter.cy); 446 447 GetWindowOrgEx(hdc, &windowOrgAfter); 448 ok(windowOrg.x == windowOrgAfter.x && windowOrg.y == windowOrgAfter.y, 449 "Window origin changed from (%d,%d) to (%d,%d)\n", 450 windowOrg.x, windowOrg.y, windowOrgAfter.x, windowOrgAfter.y); 451 452 GetViewportOrgEx(hdc, &viewportOrgAfter); 453 ok(viewportOrg.x == viewportOrgAfter.x && viewportOrg.y == viewportOrgAfter.y, 454 "Viewport origin changed from (%d,%d) to (%d,%d)\n", 455 viewportOrg.x, viewportOrg.y, viewportOrgAfter.x, viewportOrgAfter.y); 456 } 457 458 static void test_isotropic_mapping(void) 459 { 460 SIZE win, vp; 461 HDC hdc = GetDC(0); 462 463 SetMapMode(hdc, MM_ISOTROPIC); 464 465 /* MM_ISOTROPIC is set up like MM_LOMETRIC. 466 Initial values after SetMapMode(): 467 (1 inch = 25.4 mm) 468 469 Windows 9x: Windows NT: 470 Window Ext: 254 x -254 HORZSIZE*10 x VERTSIZE*10 471 Viewport Ext: LOGPIXELSX x LOGPIXELSY HORZRES x -VERTRES 472 473 To test without rounding errors, we have to use multiples of 474 these values! 475 */ 476 477 GetWindowExtEx(hdc, &win); 478 GetViewportExtEx(hdc, &vp); 479 480 test_SetViewportExt(hdc, 10 * vp.cx, 10 * vp.cy, 10 * vp.cx, 10 * vp.cy); 481 test_SetWindowExt(hdc, win.cx, win.cy, 10 * vp.cx, 10 * vp.cy); 482 test_SetWindowExt(hdc, 2 * win.cx, win.cy, 10 * vp.cx, 5 * vp.cy); 483 test_SetWindowExt(hdc, win.cx, win.cy, 5 * vp.cx, 5 * vp.cy); 484 test_SetViewportExt(hdc, 4 * vp.cx, 2 * vp.cy, 2 * vp.cx, 2 * vp.cy); 485 test_SetViewportExt(hdc, vp.cx, 2 * vp.cy, vp.cx, vp.cy); 486 test_SetViewportExt(hdc, 2 * vp.cx, 2 * vp.cy, 2 * vp.cx, 2 * vp.cy); 487 test_SetViewportExt(hdc, 4 * vp.cx, 2 * vp.cy, 2 * vp.cx, 2 * vp.cy); 488 test_SetWindowExt(hdc, 4 * win.cx, 2 * win.cy, 2 * vp.cx, vp.cy); 489 test_SetViewportExt(hdc, -2 * vp.cx, -4 * vp.cy, -2 * vp.cx, -vp.cy); 490 test_SetViewportExt(hdc, -2 * vp.cx, -1 * vp.cy, -2 * vp.cx, -vp.cy); 491 test_SetWindowExt(hdc, -4 * win.cx, -2 * win.cy, -2 * vp.cx, -vp.cy); 492 test_SetWindowExt(hdc, 4 * win.cx, -4 * win.cy, -vp.cx, -vp.cy); 493 494 ReleaseDC(0, hdc); 495 } 496 497 static void test_setvirtualresolution(void) 498 { 499 HDC hdc = CreateICA("DISPLAY", NULL, NULL, NULL); 500 BOOL r; 501 INT horz_res = GetDeviceCaps(hdc, HORZRES); 502 INT horz_size = GetDeviceCaps(hdc, HORZSIZE); 503 INT log_pixels_x = GetDeviceCaps(hdc, LOGPIXELSX); 504 SIZE orig_lometric_vp, orig_lometric_wnd; 505 506 if(!pSetVirtualResolution) 507 { 508 win_skip("Don't have SetVirtualResolution\n"); 509 return; 510 } 511 512 /* Get the true resolution limits */ 513 SetMapMode(hdc, MM_LOMETRIC); 514 GetViewportExtEx(hdc, &orig_lometric_vp); 515 GetWindowExtEx(hdc, &orig_lometric_wnd); 516 SetMapMode(hdc, MM_TEXT); 517 518 r = pSetVirtualResolution(hdc, 4000, 1000, 400, 200); /* 10 pix/mm x 5 pix/mm */ 519 ok(r == TRUE, "got %d\n", r); 520 expect_LPtoDP(hdc, 1000, 1000); 521 expect_viewport_ext(hdc, 1, 1); 522 expect_window_ext(hdc, 1, 1); 523 524 SetMapMode(hdc, MM_LOMETRIC); 525 expect_LPtoDP(hdc, 1000, -500); 526 expect_viewport_ext(hdc, 4000, -1000); 527 expect_window_ext(hdc, 4000, 2000); 528 529 /* Doesn't change the device caps */ 530 ok(horz_res == GetDeviceCaps(hdc, HORZRES), "horz_res changed\n"); 531 ok(horz_size == GetDeviceCaps(hdc, HORZSIZE), "horz_size changed\n"); 532 ok(log_pixels_x == GetDeviceCaps(hdc, LOGPIXELSX), "log_pixels_x changed\n"); 533 534 r = pSetVirtualResolution(hdc, 8000, 1000, 400, 200); /* 20 pix/mm x 5 pix/mm */ 535 ok(r == TRUE, "got %d\n", r); 536 expect_LPtoDP(hdc, 1000, -500); /* No change, need to re-set the mapping mode */ 537 SetMapMode(hdc, MM_TEXT); 538 SetMapMode(hdc, MM_LOMETRIC); 539 expect_LPtoDP(hdc, 2000, -500); 540 expect_viewport_ext(hdc, 8000, -1000); 541 expect_window_ext(hdc, 4000, 2000); 542 543 r = pSetVirtualResolution(hdc, 8000, 1000, 200, 200); /* 40 pix/mm x 5 pix/mm */ 544 ok(r == TRUE, "got %d\n", r); 545 SetMapMode(hdc, MM_TEXT); 546 SetMapMode(hdc, MM_LOMETRIC); 547 expect_LPtoDP(hdc, 4000, -500); 548 expect_viewport_ext(hdc, 8000, -1000); 549 expect_window_ext(hdc, 2000, 2000); 550 551 r = pSetVirtualResolution(hdc, 8000, 1000, 200, 200); /* 40 pix/mm x 5 pix/mm */ 552 ok(r == TRUE, "got %d\n", r); 553 SetMapMode(hdc, MM_TEXT); 554 SetMapMode(hdc, MM_LOMETRIC); 555 expect_LPtoDP(hdc, 4000, -500); 556 expect_viewport_ext(hdc, 8000, -1000); 557 expect_window_ext(hdc, 2000, 2000); 558 559 r = pSetVirtualResolution(hdc, 8000, 2000, 200, 200); /* 40 pix/mm x 10 pix/mm */ 560 ok(r == TRUE, "got %d\n", r); 561 SetMapMode(hdc, MM_TEXT); 562 SetMapMode(hdc, MM_LOMETRIC); 563 expect_LPtoDP(hdc, 4000, -1000); 564 expect_viewport_ext(hdc, 8000, -2000); 565 expect_window_ext(hdc, 2000, 2000); 566 567 r = pSetVirtualResolution(hdc, 0, 0, 10, 0); /* Error */ 568 ok(r == FALSE, "got %d\n", r); 569 SetMapMode(hdc, MM_TEXT); 570 SetMapMode(hdc, MM_LOMETRIC); 571 expect_LPtoDP(hdc, 4000, -1000); 572 expect_viewport_ext(hdc, 8000, -2000); 573 expect_window_ext(hdc, 2000, 2000); 574 575 r = pSetVirtualResolution(hdc, 0, 0, 0, 0); /* Reset to true resolution */ 576 ok(r == TRUE, "got %d\n", r); 577 SetMapMode(hdc, MM_TEXT); 578 SetMapMode(hdc, MM_LOMETRIC); 579 expect_viewport_ext(hdc, orig_lometric_vp.cx, orig_lometric_vp.cy); 580 expect_window_ext(hdc, orig_lometric_wnd.cx, orig_lometric_wnd.cy); 581 582 DeleteDC(hdc); 583 } 584 585 586 static inline void expect_identity(int line, XFORM *xf) 587 { 588 ok(xf->eM11 == 1.0, "%d: got %f\n", line, xf->eM11); 589 ok(xf->eM12 == 0.0, "%d: got %f\n", line, xf->eM12); 590 ok(xf->eM21 == 0.0, "%d: got %f\n", line, xf->eM21); 591 ok(xf->eM22 == 1.0, "%d: got %f\n", line, xf->eM22); 592 ok(xf->eDx == 0.0, "%d: got %f\n", line, xf->eDx); 593 ok(xf->eDy == 0.0, "%d: got %f\n", line, xf->eDy); 594 } 595 596 static inline void xform_near_match(int line, XFORM *got, XFORM *expect) 597 { 598 ok(fabs(got->eM11 - expect->eM11) < 0.001, "%d: got %f expect %f\n", line, got->eM11, expect->eM11); 599 ok(fabs(got->eM12 - expect->eM12) < 0.001, "%d: got %f expect %f\n", line, got->eM12, expect->eM12); 600 ok(fabs(got->eM21 - expect->eM21) < 0.001, "%d: got %f expect %f\n", line, got->eM21, expect->eM21); 601 ok(fabs(got->eM22 - expect->eM22) < 0.001, "%d: got %f expect %f\n", line, got->eM22, expect->eM22); 602 ok(fabs(got->eDx - expect->eDx) < 0.001, "%d: got %f expect %f\n", line, got->eDx, expect->eDx); 603 ok(fabs(got->eDy - expect->eDy) < 0.001, "%d: got %f expect %f\n", line, got->eDy, expect->eDy); 604 } 605 606 607 static void test_gettransform(void) 608 { 609 HDC hdc = CreateICA("DISPLAY", NULL, NULL, NULL); 610 XFORM xform, expect; 611 BOOL r; 612 SIZE lometric_vp, lometric_wnd; 613 614 if(!pGetTransform) 615 { 616 win_skip("Don't have GetTransform\n"); 617 return; 618 } 619 620 r = pGetTransform(hdc, 0x203, &xform); /* World -> Page */ 621 ok(r == TRUE, "got %d\n", r); 622 expect_identity(__LINE__, &xform); 623 r = pGetTransform(hdc, 0x304, &xform); /* Page -> Device */ 624 ok(r == TRUE, "got %d\n", r); 625 expect_identity(__LINE__, &xform); 626 r = pGetTransform(hdc, 0x204, &xform); /* World -> Device */ 627 ok(r == TRUE, "got %d\n", r); 628 expect_identity(__LINE__, &xform); 629 r = pGetTransform(hdc, 0x402, &xform); /* Device -> World */ 630 ok(r == TRUE, "got %d\n", r); 631 expect_identity(__LINE__, &xform); 632 633 SetMapMode(hdc, MM_LOMETRIC); 634 GetViewportExtEx(hdc, &lometric_vp); 635 GetWindowExtEx(hdc, &lometric_wnd); 636 637 r = pGetTransform(hdc, 0x203, &xform); /* World -> Page */ 638 ok(r == TRUE, "got %d\n", r); 639 expect_identity(__LINE__, &xform); 640 641 r = pGetTransform(hdc, 0x304, &xform); /* Page -> Device */ 642 ok(r == TRUE, "got %d\n", r); 643 expect.eM11 = (FLOAT) lometric_vp.cx / lometric_wnd.cx; 644 expect.eM12 = expect.eM21 = 0.0; 645 expect.eM22 = (FLOAT) lometric_vp.cy / lometric_wnd.cy; 646 expect.eDx = expect.eDy = 0.0; 647 xform_near_match(__LINE__, &xform, &expect); 648 649 r = pGetTransform(hdc, 0x204, &xform); /* World -> Device */ 650 ok(r == TRUE, "got %d\n", r); 651 xform_near_match(__LINE__, &xform, &expect); 652 653 r = pGetTransform(hdc, 0x402, &xform); /* Device -> World */ 654 ok(r == TRUE, "got %d\n", r); 655 expect.eM11 = (FLOAT) lometric_wnd.cx / lometric_vp.cx; 656 expect.eM22 = (FLOAT) lometric_wnd.cy / lometric_vp.cy; 657 xform_near_match(__LINE__, &xform, &expect); 658 659 660 SetGraphicsMode(hdc, GM_ADVANCED); 661 662 expect.eM11 = 10.0; 663 expect.eM22 = 20.0; 664 SetWorldTransform(hdc, &expect); 665 r = pGetTransform(hdc, 0x203, &xform); /* World -> Page */ 666 ok(r == TRUE, "got %d\n", r); 667 xform_near_match(__LINE__, &xform, &expect); 668 669 r = pGetTransform(hdc, 0x304, &xform); /* Page -> Device */ 670 ok(r == TRUE, "got %d\n", r); 671 expect.eM11 = (FLOAT) lometric_vp.cx / lometric_wnd.cx; 672 expect.eM22 = (FLOAT) lometric_vp.cy / lometric_wnd.cy; 673 xform_near_match(__LINE__, &xform, &expect); 674 675 r = pGetTransform(hdc, 0x204, &xform); /* World -> Device */ 676 ok(r == TRUE, "got %d\n", r); 677 expect.eM11 *= 10.0; 678 expect.eM22 *= 20.0; 679 xform_near_match(__LINE__, &xform, &expect); 680 681 r = pGetTransform(hdc, 0x402, &xform); /* Device -> World */ 682 ok(r == TRUE, "got %d\n", r); 683 expect.eM11 = 1 / expect.eM11; 684 expect.eM22 = 1 / expect.eM22; 685 xform_near_match(__LINE__, &xform, &expect); 686 687 r = pGetTransform(hdc, 0x102, &xform); 688 ok(r == FALSE, "got %d\n", r); 689 r = pGetTransform(hdc, 0x103, &xform); 690 ok(r == FALSE, "got %d\n", r); 691 r = pGetTransform(hdc, 0x104, &xform); 692 ok(r == FALSE, "got %d\n", r); 693 r = pGetTransform(hdc, 0x202, &xform); 694 ok(r == FALSE, "got %d\n", r); 695 r = pGetTransform(hdc, 0x302, &xform); 696 ok(r == FALSE, "got %d\n", r); 697 r = pGetTransform(hdc, 0x303, &xform); 698 ok(r == FALSE, "got %d\n", r); 699 r = pGetTransform(hdc, 0x403, &xform); 700 ok(r == FALSE, "got %d\n", r); 701 r = pGetTransform(hdc, 0x404, &xform); 702 ok(r == FALSE, "got %d\n", r); 703 r = pGetTransform(hdc, 0xffff, &xform); 704 ok(r == FALSE, "got %d\n", r); 705 } 706 707 START_TEST(mapping) 708 { 709 HMODULE mod = GetModuleHandleA("gdi32.dll"); 710 pGetLayout = (void *)GetProcAddress( mod, "GetLayout" ); 711 pSetLayout = (void *)GetProcAddress( mod, "SetLayout" ); 712 pGetRandomRgn = (void *)GetProcAddress( mod, "GetRandomRgn" ); 713 pGetTransform = (void *)GetProcAddress( mod, "GetTransform" ); 714 pSetVirtualResolution = (void *)GetProcAddress( mod, "SetVirtualResolution" ); 715 716 test_modify_world_transform(); 717 test_world_transform(); 718 test_dc_layout(); 719 test_isotropic_mapping(); 720 test_setvirtualresolution(); 721 test_gettransform(); 722 } 723