1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS System Libraries 4 * FILE: win32ss/gdi/gdi32/objects/coord.c 5 * PURPOSE: Functions for coordinate transformation 6 * PROGRAMMER: 7 */ 8 #include <precomp.h> 9 10 /* Currently we use a MATRIX inside the DC_ATTR containing the 11 coordinate transformations, while we deal with XFORM structures 12 internally. If we move all coordinate transformation to gdi32, 13 we might as well have an XFORM structure in the DC_ATTR. */ 14 void 15 MatrixToXForm(XFORM *pxform, const MATRIX *pmx) 16 { 17 XFORML *pxforml = (XFORML*)pxform; 18 pxforml->eM11 = FOtoF(&pmx->efM11); 19 pxforml->eM12 = FOtoF(&pmx->efM12); 20 pxforml->eM21 = FOtoF(&pmx->efM21); 21 pxforml->eM22 = FOtoF(&pmx->efM22); 22 pxforml->eDx = FOtoF(&pmx->efDx); 23 pxforml->eDy = FOtoF(&pmx->efDy); 24 } 25 26 void 27 GdiTransformPoints2( 28 _In_ XFORM *pxform, 29 _Out_writes_(nCount) PPOINT pptOut, 30 _In_reads_(nCount) PPOINT pptIn, 31 _In_ ULONG nCount) 32 { 33 ULONG i; 34 FLOAT x, y; 35 36 for (i = 0; i < nCount; i++) 37 { 38 x = pptIn[i].x * pxform->eM11 + pptIn[i].y * pxform->eM12 + pxform->eDx; 39 pptOut[i].x = _lrintf(x); 40 y = pptIn[i].x * pxform->eM21 + pptIn[i].y * pxform->eM22 + pxform->eDy; 41 pptOut[i].y = _lrintf(y); 42 } 43 } 44 45 FORCEINLINE 46 void 47 GdiTransformPoints( 48 _In_ MATRIX *pmx, 49 _Out_writes_(nCount) PPOINT pptOut, 50 _In_reads_(nCount) PPOINT pptIn, 51 _In_ ULONG nCount) 52 { 53 XFORM xform; 54 55 MatrixToXForm(&xform, pmx); 56 GdiTransformPoints2(&xform, pptOut, pptIn, nCount); 57 } 58 59 #define MAX_OFFSET 4294967041.0 60 #define _fmul(x,y) (((x) == 0) ? 0 : (x) * (y)) 61 62 BOOL 63 WINAPI 64 CombineTransform( 65 _Out_ LPXFORM pxfResult, 66 _In_ const XFORM *pxf1, 67 _In_ const XFORM *pxf2) 68 { 69 XFORM xformTmp; 70 71 /* Check paramters */ 72 if (!pxfResult || !pxf1 || !pxf2) return FALSE; 73 74 /* Do matrix multiplication, start with scaling elements */ 75 xformTmp.eM11 = (pxf1->eM11 * pxf2->eM11) + (pxf1->eM12 * pxf2->eM21); 76 xformTmp.eM22 = (pxf1->eM21 * pxf2->eM12) + (pxf1->eM22 * pxf2->eM22); 77 78 /* Calculate shear/rotate elements only of they are present */ 79 if ((pxf1->eM12 != 0.) || (pxf1->eM21 != 0.) || 80 (pxf2->eM12 != 0.) || (pxf2->eM21 != 0.)) 81 { 82 xformTmp.eM12 = (pxf1->eM11 * pxf2->eM12) + (pxf1->eM12 * pxf2->eM22); 83 xformTmp.eM21 = (pxf1->eM21 * pxf2->eM11) + (pxf1->eM22 * pxf2->eM21); 84 } 85 else 86 { 87 xformTmp.eM12 = 0.; 88 xformTmp.eM21 = 0.; 89 } 90 91 /* Calculate the offset */ 92 xformTmp.eDx = _fmul(pxf1->eDx, pxf2->eM11) + _fmul(pxf1->eDy, pxf2->eM21) + pxf2->eDx; 93 xformTmp.eDy = _fmul(pxf1->eDx, pxf2->eM12) + _fmul(pxf1->eDy, pxf2->eM22) + pxf2->eDy; 94 95 /* Check for invalid offset ranges */ 96 if ((xformTmp.eDx > MAX_OFFSET) || (xformTmp.eDx < -MAX_OFFSET) || 97 (xformTmp.eDy > MAX_OFFSET) || (xformTmp.eDy < -MAX_OFFSET)) 98 { 99 return FALSE; 100 } 101 102 /* All is ok, return the calculated values */ 103 *pxfResult = xformTmp; 104 return TRUE; 105 } 106 107 108 /* 109 * @implemented 110 * 111 */ 112 int 113 WINAPI 114 GetMapMode( 115 _In_ HDC hdc) 116 { 117 PDC_ATTR pdcattr; 118 119 /* Get the DC attribute */ 120 pdcattr = GdiGetDcAttr(hdc); 121 if (pdcattr == NULL) 122 { 123 SetLastError(ERROR_INVALID_PARAMETER); 124 return 0; 125 } 126 127 /* Return the map mode */ 128 return pdcattr->iMapMode; 129 } 130 131 /* 132 * @implemented 133 */ 134 INT 135 WINAPI 136 SetMapMode( 137 _In_ HDC hdc, 138 _In_ INT iMode) 139 { 140 PDC_ATTR pdcattr; 141 142 /* Handle METADC16 here, since we don't have a DCATTR. */ 143 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) \ 144 { 145 return GetAndSetDCDWord(hdc, GdiGetSetMapMode, iMode, 0, 0, 0 ); 146 } 147 148 /* Get the DC attribute */ 149 pdcattr = GdiGetDcAttr(hdc); 150 if (pdcattr == NULL) 151 { 152 SetLastError(ERROR_INVALID_PARAMETER); 153 return 0; 154 } 155 156 /* Force change if Isotropic is set for recompute. */ 157 if ((iMode != pdcattr->iMapMode) || (iMode == MM_ISOTROPIC)) 158 { 159 pdcattr->ulDirty_ &= ~SLOW_WIDTHS; 160 return GetAndSetDCDWord(hdc, GdiGetSetMapMode, iMode, 0, 0, 0 ); 161 } 162 163 return pdcattr->iMapMode; 164 } 165 166 167 BOOL 168 WINAPI 169 DPtoLP( 170 _In_ HDC hdc, 171 _Inout_updates_(nCount) LPPOINT lpPoints, 172 _In_ INT nCount) 173 { 174 PDC_ATTR pdcattr; 175 SIZEL sizlView; 176 177 if (nCount <= 0) 178 return TRUE; 179 180 if (hdc == NULL) 181 { 182 SetLastError(ERROR_INVALID_PARAMETER); 183 return FALSE; 184 } 185 if (lpPoints == NULL) 186 { 187 return TRUE; 188 } 189 190 pdcattr = GdiGetDcAttr(hdc); 191 if (pdcattr == NULL) 192 return FALSE; 193 194 if (pdcattr->iMapMode == MM_ISOTROPIC) 195 { 196 if (NtGdiGetDCPoint(hdc, GdiGetViewPortExt, (PPOINTL)&sizlView)) 197 { 198 if (sizlView.cx == 0 || sizlView.cy == 0) 199 return FALSE; 200 } 201 } 202 203 return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiDpToLp); 204 } 205 206 BOOL 207 WINAPI 208 LPtoDP( 209 _In_ HDC hdc, 210 _Inout_updates_(nCount) LPPOINT lpPoints, 211 _In_ INT nCount) 212 { 213 PDC_ATTR pdcattr; 214 215 if (nCount <= 0) 216 return TRUE; 217 218 if (hdc == NULL) 219 { 220 SetLastError(ERROR_INVALID_PARAMETER); 221 return FALSE; 222 } 223 if (lpPoints == NULL) 224 { 225 return TRUE; 226 } 227 228 pdcattr = GdiGetDcAttr(hdc); 229 if (pdcattr == NULL) 230 return FALSE; 231 232 return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiLpToDp); 233 } 234 235 /* 236 * @implemented 237 * 238 */ 239 BOOL 240 WINAPI 241 GetCurrentPositionEx( 242 _In_ HDC hdc, 243 _Out_ LPPOINT lpPoint) 244 { 245 PDC_ATTR pdcattr; 246 247 /* Get the DC attribute */ 248 pdcattr = GdiGetDcAttr(hdc); 249 if ((pdcattr == NULL) || (lpPoint == NULL)) 250 { 251 SetLastError(ERROR_INVALID_PARAMETER); 252 return FALSE; 253 } 254 255 if (pdcattr->ulDirty_ & DIRTY_PTLCURRENT) // have a hit! 256 { 257 lpPoint->x = pdcattr->ptfxCurrent.x; 258 lpPoint->y = pdcattr->ptfxCurrent.y; 259 DPtoLP(hdc, lpPoint, 1); // reconvert back. 260 pdcattr->ptlCurrent.x = lpPoint->x; // save it 261 pdcattr->ptlCurrent.y = lpPoint->y; 262 pdcattr->ulDirty_ &= ~DIRTY_PTLCURRENT; // clear bit 263 } 264 else 265 { 266 lpPoint->x = pdcattr->ptlCurrent.x; 267 lpPoint->y = pdcattr->ptlCurrent.y; 268 } 269 270 return TRUE; 271 } 272 273 /* 274 * @implemented 275 */ 276 BOOL 277 WINAPI 278 GetWorldTransform( 279 _In_ HDC hdc, 280 _Out_ LPXFORM pxform) 281 { 282 PDC_ATTR pdcattr; 283 284 pdcattr = GdiGetDcAttr(hdc); 285 if (!pdcattr) 286 { 287 SetLastError(ERROR_INVALID_HANDLE); 288 return FALSE; 289 } 290 #if 0 291 if (pdcattr->flXform & ANY_XFORM_INVALID) 292 { 293 GdiFixupTransforms(pdcattr); 294 } 295 296 MatrixToXForm(pxform, &pdcattr->mxWorldToDevice); 297 #endif 298 return NtGdiGetTransform(hdc, GdiWorldSpaceToPageSpace, pxform); 299 } 300 301 302 BOOL 303 WINAPI 304 SetWorldTransform( 305 _In_ HDC hdc, 306 _Out_ CONST XFORM *pxform) 307 { 308 return ModifyWorldTransform(hdc, pxform, MWT_SET); 309 } 310 311 312 BOOL 313 WINAPI 314 ModifyWorldTransform( 315 _In_ HDC hdc, 316 _In_opt_ CONST XFORM *pxform, 317 _In_ DWORD dwMode) 318 { 319 PDC_ATTR pdcattr; 320 321 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) 322 return FALSE; 323 324 if (dwMode == MWT_SET) 325 { 326 HANDLE_METADC(BOOL, SetWorldTransform, FALSE, hdc, pxform); 327 } 328 else 329 { 330 HANDLE_METADC(BOOL, ModifyWorldTransform, FALSE, hdc, pxform, dwMode); 331 } 332 333 /* Get the DC attribute */ 334 pdcattr = GdiGetDcAttr(hdc); 335 if (pdcattr == NULL) 336 { 337 SetLastError(ERROR_INVALID_PARAMETER); 338 return FALSE; 339 } 340 341 /* Check that graphics mode is GM_ADVANCED */ 342 if (pdcattr->iGraphicsMode != GM_ADVANCED) 343 return FALSE; 344 345 /* Call win32k to do the work */ 346 return NtGdiModifyWorldTransform(hdc, (LPXFORM)pxform, dwMode); 347 } 348 349 BOOL 350 WINAPI 351 GetViewportExtEx( 352 _In_ HDC hdc, 353 _Out_ LPSIZE lpSize) 354 { 355 PDC_ATTR pdcattr; 356 357 /* Get the DC attribute */ 358 pdcattr = GdiGetDcAttr(hdc); 359 if (pdcattr == NULL) 360 { 361 /* Do not set LastError here! */ 362 return FALSE; 363 } 364 365 /* Check if we need to update values */ 366 if ((pdcattr->flXform & PAGE_EXTENTS_CHANGED) && 367 (pdcattr->iMapMode == MM_ISOTROPIC)) 368 { 369 /* Call win32k to do the work */ 370 return NtGdiGetDCPoint(hdc, GdiGetViewPortExt, (PPOINTL)lpSize); 371 } 372 373 /* Nothing to calculate, return the current extension */ 374 lpSize->cx = pdcattr->szlViewportExt.cx; 375 lpSize->cy = pdcattr->szlViewportExt.cy; 376 377 return TRUE; 378 } 379 380 381 BOOL 382 WINAPI 383 GetViewportOrgEx( 384 _In_ HDC hdc, 385 _Out_ LPPOINT lpPoint) 386 { 387 PDC_ATTR pdcattr; 388 389 /* Get the DC attribute */ 390 pdcattr = GdiGetDcAttr(hdc); 391 if (pdcattr == NULL) 392 { 393 /* Do not set LastError here! */ 394 return FALSE; 395 } 396 397 /* Get the current viewport org */ 398 lpPoint->x = pdcattr->ptlViewportOrg.x; 399 lpPoint->y = pdcattr->ptlViewportOrg.y; 400 401 /* Handle right-to-left layout */ 402 if (pdcattr->dwLayout & LAYOUT_RTL) 403 lpPoint->x = -lpPoint->x; 404 405 return TRUE; 406 } 407 408 409 BOOL 410 WINAPI 411 GetWindowExtEx( 412 _In_ HDC hdc, 413 _Out_ LPSIZE lpSize) 414 { 415 PDC_ATTR pdcattr; 416 417 /* Get the DC attribute */ 418 pdcattr = GdiGetDcAttr(hdc); 419 if (pdcattr == NULL) 420 { 421 /* Do not set LastError here! */ 422 return FALSE; 423 } 424 425 /* Get the current window extension */ 426 lpSize->cx = pdcattr->szlWindowExt.cx; 427 lpSize->cy = pdcattr->szlWindowExt.cy; 428 429 /* Handle right-to-left layout */ 430 if (pdcattr->dwLayout & LAYOUT_RTL) 431 lpSize->cx = -lpSize->cx; 432 433 return TRUE; 434 } 435 436 437 BOOL 438 WINAPI 439 GetWindowOrgEx( 440 _In_ HDC hdc, 441 _Out_ LPPOINT lpPoint) 442 { 443 PDC_ATTR pdcattr; 444 445 /* Get the DC attribute */ 446 pdcattr = GdiGetDcAttr(hdc); 447 if (pdcattr == NULL) 448 { 449 /* Do not set LastError here! */ 450 return FALSE; 451 } 452 453 /* Get the current window origin */ 454 lpPoint->x = pdcattr->ptlWindowOrg.x; 455 lpPoint->y = pdcattr->ptlWindowOrg.y; 456 457 return TRUE; 458 } 459 460 /* 461 * @unimplemented 462 */ 463 BOOL 464 WINAPI 465 SetViewportExtEx( 466 _In_ HDC hdc, 467 _In_ int nXExtent, 468 _In_ int nYExtent, 469 _Out_opt_ LPSIZE lpSize) 470 { 471 PDC_ATTR pdcattr; 472 473 HANDLE_METADC(BOOL, SetViewportExtEx, FALSE, hdc, nXExtent, nYExtent, lpSize); 474 475 /* Get the DC attribute */ 476 pdcattr = GdiGetDcAttr(hdc); 477 if (pdcattr == NULL) 478 { 479 SetLastError(ERROR_INVALID_PARAMETER); 480 return FALSE; 481 } 482 483 /* Check if the caller wants the old extension */ 484 if (lpSize) 485 { 486 /* Return the current viewport extension */ 487 lpSize->cx = pdcattr->szlViewportExt.cx; 488 lpSize->cy = pdcattr->szlViewportExt.cy; 489 } 490 491 /* Check for trivial case */ 492 if ((pdcattr->szlViewportExt.cx == nXExtent) && 493 (pdcattr->szlViewportExt.cy == nYExtent)) 494 return TRUE; 495 496 if (nXExtent == 0 || nYExtent == 0) 497 return TRUE; 498 499 /* Only change viewport extension if we are in iso or aniso mode */ 500 if ((pdcattr->iMapMode == MM_ISOTROPIC) || 501 (pdcattr->iMapMode == MM_ANISOTROPIC)) 502 { 503 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 504 { 505 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 506 { 507 NtGdiFlush(); // Sync up pdcattr from Kernel space. 508 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 509 } 510 } 511 512 /* Set the new viewport extension */ 513 pdcattr->szlViewportExt.cx = nXExtent; 514 pdcattr->szlViewportExt.cy = nYExtent; 515 516 /* Handle right-to-left layout */ 517 if (pdcattr->dwLayout & LAYOUT_RTL) 518 NtGdiMirrorWindowOrg(hdc); 519 520 /* Update xform flags */ 521 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID); 522 } 523 524 return TRUE; 525 } 526 527 /* 528 * @unimplemented 529 */ 530 BOOL 531 WINAPI 532 SetWindowOrgEx( 533 _In_ HDC hdc, 534 _In_ int X, 535 _In_ int Y, 536 _Out_opt_ LPPOINT lpPoint) 537 { 538 PDC_ATTR pdcattr; 539 540 HANDLE_METADC(BOOL, SetWindowOrgEx, FALSE, hdc, X, Y, lpPoint); 541 542 /* Get the DC attribute */ 543 pdcattr = GdiGetDcAttr(hdc); 544 if (pdcattr == NULL) 545 { 546 /* Do not set LastError here! */ 547 return FALSE; 548 } 549 550 if (lpPoint) 551 { 552 lpPoint->x = pdcattr->ptlWindowOrg.x; 553 lpPoint->y = pdcattr->ptlWindowOrg.y; 554 } 555 556 if ((pdcattr->ptlWindowOrg.x == X) && (pdcattr->ptlWindowOrg.y == Y)) 557 return TRUE; 558 559 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 560 { 561 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 562 { 563 NtGdiFlush(); // Sync up pdcattr from Kernel space. 564 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 565 } 566 } 567 568 pdcattr->ptlWindowOrg.x = X; 569 pdcattr->ptlWindowOrg.y = Y; 570 571 pdcattr->lWindowOrgx = X; 572 if (pdcattr->dwLayout & LAYOUT_RTL) NtGdiMirrorWindowOrg(hdc); 573 pdcattr->flXform |= (PAGE_XLATE_CHANGED|WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID); 574 return TRUE; 575 576 // return NtGdiSetWindowOrgEx(hdc, X, Y, lpPoint); 577 } 578 579 /* 580 * @unimplemented 581 */ 582 BOOL 583 WINAPI 584 SetWindowExtEx( 585 _In_ HDC hdc, 586 _In_ INT nXExtent, 587 _In_ INT nYExtent, 588 _Out_opt_ LPSIZE lpSize) 589 { 590 PDC_ATTR pdcattr; 591 592 HANDLE_METADC(BOOL, SetWindowExtEx, FALSE, hdc, nXExtent, nYExtent, lpSize); 593 594 /* Get the DC attr */ 595 pdcattr = GdiGetDcAttr(hdc); 596 if (!pdcattr) 597 { 598 /* Set the error value and return failure */ 599 SetLastError(ERROR_INVALID_PARAMETER); 600 return FALSE; 601 } 602 603 /* Check if the caller wants the old extension */ 604 if (lpSize) 605 { 606 /* Return the current window extension */ 607 lpSize->cx = pdcattr->szlWindowExt.cx; 608 lpSize->cy = pdcattr->szlWindowExt.cy; 609 610 /* Handle right-to-left layout */ 611 if (pdcattr->dwLayout & LAYOUT_RTL) 612 lpSize->cx = -lpSize->cx; 613 } 614 615 if (pdcattr->dwLayout & LAYOUT_RTL) 616 { 617 NtGdiMirrorWindowOrg(hdc); 618 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID); 619 } 620 else if ((pdcattr->iMapMode == MM_ISOTROPIC) || 621 (pdcattr->iMapMode == MM_ANISOTROPIC)) 622 { 623 if ((pdcattr->szlWindowExt.cx == nXExtent) && 624 (pdcattr->szlWindowExt.cy == nYExtent)) 625 return TRUE; 626 627 if ((!nXExtent) || (!nYExtent)) 628 return FALSE; 629 630 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 631 { 632 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 633 { 634 NtGdiFlush(); // Sync up Dc_Attr from Kernel space. 635 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 636 } 637 } 638 639 pdcattr->szlWindowExt.cx = nXExtent; 640 pdcattr->szlWindowExt.cy = nYExtent; 641 if (pdcattr->dwLayout & LAYOUT_RTL) 642 NtGdiMirrorWindowOrg(hdc); 643 644 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID); 645 } 646 647 return TRUE; 648 } 649 650 /* 651 * @unimplemented 652 */ 653 BOOL 654 WINAPI 655 SetViewportOrgEx( 656 _In_ HDC hdc, 657 _In_ int X, 658 _In_ int Y, 659 _Out_opt_ LPPOINT lpPoint) 660 { 661 PDC_ATTR pdcattr; 662 663 HANDLE_METADC(BOOL, SetViewportOrgEx, FALSE, hdc, X, Y, lpPoint); 664 665 /* Get the DC attribute */ 666 pdcattr = GdiGetDcAttr(hdc); 667 if (!pdcattr) 668 { 669 /* Do not set LastError here! */ 670 return FALSE; 671 } 672 673 if (lpPoint) 674 { 675 lpPoint->x = pdcattr->ptlViewportOrg.x; 676 lpPoint->y = pdcattr->ptlViewportOrg.y; 677 if (pdcattr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x; 678 } 679 pdcattr->flXform |= (PAGE_XLATE_CHANGED|WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID); 680 if (pdcattr->dwLayout & LAYOUT_RTL) X = -X; 681 pdcattr->ptlViewportOrg.x = X; 682 pdcattr->ptlViewportOrg.y = Y; 683 return TRUE; 684 685 // return NtGdiSetViewportOrgEx(hdc,X,Y,lpPoint); 686 } 687 688 /* 689 * @implemented 690 */ 691 BOOL 692 WINAPI 693 ScaleViewportExtEx( 694 _In_ HDC hdc, 695 _In_ INT xNum, 696 _In_ INT xDenom, 697 _In_ INT yNum, 698 _In_ INT yDenom, 699 _Out_ LPSIZE lpSize) 700 { 701 HANDLE_METADC(BOOL, ScaleViewportExtEx, FALSE, hdc, xNum, xDenom, yNum, yDenom, lpSize); 702 703 if (!GdiGetDcAttr(hdc)) 704 { 705 SetLastError(ERROR_INVALID_PARAMETER); 706 return FALSE; 707 } 708 709 return NtGdiScaleViewportExtEx(hdc, xNum, xDenom, yNum, yDenom, lpSize); 710 } 711 712 /* 713 * @implemented 714 */ 715 BOOL 716 WINAPI 717 ScaleWindowExtEx( 718 _In_ HDC hdc, 719 _In_ INT xNum, 720 _In_ INT xDenom, 721 _In_ INT yNum, 722 _In_ INT yDenom, 723 _Out_ LPSIZE lpSize) 724 { 725 HANDLE_METADC(BOOL, ScaleWindowExtEx, FALSE, hdc, xNum, xDenom, yNum, yDenom, lpSize); 726 727 if (!GdiGetDcAttr(hdc)) 728 { 729 SetLastError(ERROR_INVALID_PARAMETER); 730 return FALSE; 731 } 732 733 return NtGdiScaleWindowExtEx(hdc, xNum, xDenom, yNum, yDenom, lpSize); 734 } 735 736 /* 737 * @implemented 738 */ 739 DWORD 740 WINAPI 741 GetLayout( 742 _In_ HDC hdc) 743 { 744 PDC_ATTR pdcattr; 745 746 /* METADC16 is not supported in this API */ 747 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) 748 { 749 return GDI_ERROR; 750 } 751 752 /* Get the DC attribute */ 753 pdcattr = GdiGetDcAttr(hdc); 754 if (!pdcattr) 755 { 756 /* Set the error value and return failure */ 757 SetLastError(ERROR_INVALID_PARAMETER); 758 return GDI_ERROR; 759 } 760 761 /* Return the layout */ 762 return pdcattr->dwLayout; 763 } 764 765 766 /* 767 * @implemented 768 */ 769 DWORD 770 WINAPI 771 SetLayout( 772 _In_ HDC hdc, 773 _In_ DWORD dwLayout) 774 { 775 HANDLE_METADC(DWORD, SetLayout, GDI_ERROR, hdc, dwLayout); 776 777 if (!GdiGetDcAttr(hdc)) 778 { 779 SetLastError(ERROR_INVALID_PARAMETER); 780 return GDI_ERROR; 781 } 782 783 return NtGdiSetLayout(hdc, -1, dwLayout); 784 } 785 786 /* 787 * @implemented 788 */ 789 DWORD 790 WINAPI 791 SetLayoutWidth( 792 _In_ HDC hdc, 793 _In_ LONG wox, 794 _In_ DWORD dwLayout) 795 { 796 /* Only normal DCs are handled here */ 797 if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE) 798 { 799 return GDI_ERROR; 800 } 801 802 if (!GdiGetDcAttr(hdc)) 803 { 804 SetLastError(ERROR_INVALID_PARAMETER); 805 return GDI_ERROR; 806 } 807 808 return NtGdiSetLayout(hdc, wox, dwLayout); 809 } 810 811 /* 812 * @implemented 813 */ 814 BOOL 815 WINAPI 816 GetDCOrgEx( 817 _In_ HDC hdc, 818 _Out_ LPPOINT lpPoint) 819 { 820 return NtGdiGetDCPoint(hdc, GdiGetDCOrg, (PPOINTL)lpPoint); 821 } 822 823 824 /* 825 * @implemented 826 */ 827 LONG 828 WINAPI 829 GetDCOrg( 830 _In_ HDC hdc) 831 { 832 POINT pt; 833 834 /* Call the new API */ 835 if (!GetDCOrgEx(hdc, &pt)) 836 return 0; 837 838 /* Return the point in the old way */ 839 return(MAKELONG(pt.x, pt.y)); 840 } 841 842 843 /* 844 * @implemented 845 * 846 */ 847 BOOL 848 WINAPI 849 OffsetViewportOrgEx( 850 _In_ HDC hdc, 851 _In_ int nXOffset, 852 _In_ int nYOffset, 853 _Out_opt_ LPPOINT lpPoint) 854 { 855 PDC_ATTR pdcattr; 856 857 HANDLE_METADC(BOOL, OffsetViewportOrgEx, FALSE, hdc, nXOffset, nYOffset, lpPoint); 858 859 /* Get the DC attribute */ 860 pdcattr = GdiGetDcAttr(hdc); 861 if (!pdcattr) 862 { 863 /* Do not set LastError here! */ 864 return FALSE; 865 } 866 867 if (lpPoint) 868 { 869 *lpPoint = pdcattr->ptlViewportOrg; 870 if ( pdcattr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x; 871 } 872 873 if ( nXOffset || nYOffset != nXOffset ) 874 { 875 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 876 { 877 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 878 { 879 NtGdiFlush(); 880 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 881 } 882 } 883 884 pdcattr->flXform |= (PAGE_XLATE_CHANGED|WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID); 885 if (pdcattr->dwLayout & LAYOUT_RTL) nXOffset = -nXOffset; 886 pdcattr->ptlViewportOrg.x += nXOffset; 887 pdcattr->ptlViewportOrg.y += nYOffset; 888 } 889 return TRUE; 890 891 // return NtGdiOffsetViewportOrgEx(hdc, nXOffset, nYOffset, lpPoint); 892 } 893 894 /* 895 * @implemented 896 * 897 */ 898 BOOL 899 WINAPI 900 OffsetWindowOrgEx( 901 _In_ HDC hdc, 902 _In_ int nXOffset, 903 _In_ int nYOffset, 904 _Out_opt_ LPPOINT lpPoint) 905 { 906 PDC_ATTR pdcattr; 907 908 HANDLE_METADC(BOOL, OffsetWindowOrgEx, FALSE, hdc, nXOffset, nYOffset, lpPoint); 909 910 /* Get the DC attribute */ 911 pdcattr = GdiGetDcAttr(hdc); 912 if (!pdcattr) 913 { 914 /* Do not set LastError here! */ 915 return FALSE; 916 } 917 918 if ( lpPoint ) 919 { 920 *lpPoint = pdcattr->ptlWindowOrg; 921 //lpPoint->x = pdcattr->lWindowOrgx; 922 } 923 924 if ( nXOffset || nYOffset != nXOffset ) 925 { 926 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 927 { 928 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 929 { 930 NtGdiFlush(); 931 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 932 } 933 } 934 935 pdcattr->flXform |= (PAGE_XLATE_CHANGED|WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID); 936 pdcattr->ptlWindowOrg.x += nXOffset; 937 pdcattr->ptlWindowOrg.y += nYOffset; 938 pdcattr->lWindowOrgx += nXOffset; 939 } 940 return TRUE; 941 942 // return NtGdiOffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint); 943 } 944 945