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 #if 0 175 INT i; 176 PDC_ATTR pdcattr; 177 178 /* Get the DC attribute */ 179 pdcattr = GdiGetDcAttr(hdc); 180 if (!pdcattr) 181 { 182 SetLastError(ERROR_INVALID_PARAMETER); 183 return FALSE; 184 } 185 186 if (pdcattr->flXform & ANY_XFORM_CHANGES) 187 { 188 GdiFixupTransforms(pdcattr); 189 } 190 191 // FIXME: can this fail on Windows? 192 GdiTransformPoints(&pdcattr->mxDeviceToWorld, lpPoints, lpPoints, nCount); 193 194 return TRUE; 195 #endif 196 return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiDpToLp); 197 } 198 199 BOOL 200 WINAPI 201 LPtoDP( 202 _In_ HDC hdc, 203 _Inout_updates_(nCount) LPPOINT lpPoints, 204 _In_ INT nCount) 205 { 206 #if 0 207 INT i; 208 PDC_ATTR pdcattr; 209 210 /* Get the DC attribute */ 211 pdcattr = GdiGetDcAttr(hdc); 212 if (!pdcattr) 213 { 214 SetLastError(ERROR_INVALID_PARAMETER); 215 return FALSE; 216 } 217 218 if (pdcattr->flXform & ANY_XFORM_CHANGES) 219 { 220 GdiFixupTransforms(pdcattr); 221 } 222 223 // FIXME: can this fail on Windows? 224 GdiTransformPoints(&pdcattr->mxWorldToDevice, lpPoints, lpPoints, nCount); 225 226 return TRUE; 227 #endif 228 return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiLpToDp); 229 } 230 231 /* 232 * @implemented 233 * 234 */ 235 BOOL 236 WINAPI 237 GetCurrentPositionEx( 238 _In_ HDC hdc, 239 _Out_ LPPOINT lpPoint) 240 { 241 PDC_ATTR pdcattr; 242 243 /* Get the DC attribute */ 244 pdcattr = GdiGetDcAttr(hdc); 245 if ((pdcattr == NULL) || (lpPoint == NULL)) 246 { 247 SetLastError(ERROR_INVALID_PARAMETER); 248 return FALSE; 249 } 250 251 if (pdcattr->ulDirty_ & DIRTY_PTLCURRENT) // have a hit! 252 { 253 lpPoint->x = pdcattr->ptfxCurrent.x; 254 lpPoint->y = pdcattr->ptfxCurrent.y; 255 DPtoLP(hdc, lpPoint, 1); // reconvert back. 256 pdcattr->ptlCurrent.x = lpPoint->x; // save it 257 pdcattr->ptlCurrent.y = lpPoint->y; 258 pdcattr->ulDirty_ &= ~DIRTY_PTLCURRENT; // clear bit 259 } 260 else 261 { 262 lpPoint->x = pdcattr->ptlCurrent.x; 263 lpPoint->y = pdcattr->ptlCurrent.y; 264 } 265 266 return TRUE; 267 } 268 269 /* 270 * @implemented 271 */ 272 BOOL 273 WINAPI 274 GetWorldTransform( 275 _In_ HDC hdc, 276 _Out_ LPXFORM pxform) 277 { 278 #if 0 279 PDC_ATTR pdcattr; 280 281 pdcattr = GdiGetDcAttr(hdc); 282 if (!pdcattr) 283 { 284 SetLastError(ERROR_INVALID_HANDLE); 285 return FALSE; 286 } 287 288 if (pdcattr->flXform & ANY_XFORM_INVALID) 289 { 290 GdiFixupTransforms(pdcattr); 291 } 292 293 MatrixToXForm(pxform, &pdcattr->mxWorldToDevice); 294 #endif 295 return NtGdiGetTransform(hdc, GdiWorldSpaceToPageSpace, pxform); 296 } 297 298 299 BOOL 300 WINAPI 301 SetWorldTransform( 302 _In_ HDC hdc, 303 _Out_ CONST XFORM *pxform) 304 { 305 return ModifyWorldTransform(hdc, pxform, MWT_SET); 306 } 307 308 309 BOOL 310 WINAPI 311 ModifyWorldTransform( 312 _In_ HDC hdc, 313 _In_opt_ CONST XFORM *pxform, 314 _In_ DWORD dwMode) 315 { 316 PDC_ATTR pdcattr; 317 318 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) 319 return FALSE; 320 321 if (dwMode == MWT_SET) 322 { 323 HANDLE_METADC(BOOL, SetWorldTransform, FALSE, hdc, pxform); 324 } 325 else 326 { 327 HANDLE_METADC(BOOL, ModifyWorldTransform, FALSE, hdc, pxform, dwMode); 328 } 329 330 /* Get the DC attribute */ 331 pdcattr = GdiGetDcAttr(hdc); 332 if (pdcattr == NULL) 333 { 334 SetLastError(ERROR_INVALID_PARAMETER); 335 return FALSE; 336 } 337 338 /* Check that graphics mode is GM_ADVANCED */ 339 if (pdcattr->iGraphicsMode != GM_ADVANCED) 340 return FALSE; 341 342 /* Call win32k to do the work */ 343 return NtGdiModifyWorldTransform(hdc, (LPXFORM)pxform, dwMode); 344 } 345 346 BOOL 347 WINAPI 348 GetViewportExtEx( 349 _In_ HDC hdc, 350 _Out_ LPSIZE lpSize) 351 { 352 PDC_ATTR pdcattr; 353 354 /* Get the DC attribute */ 355 pdcattr = GdiGetDcAttr(hdc); 356 if (pdcattr == NULL) 357 { 358 /* Do not set LastError here! */ 359 return FALSE; 360 } 361 362 /* Check if we need to update values */ 363 if ((pdcattr->flXform & PAGE_EXTENTS_CHANGED) && 364 (pdcattr->iMapMode == MM_ISOTROPIC)) 365 { 366 /* Call win32k to do the work */ 367 return NtGdiGetDCPoint(hdc, GdiGetViewPortExt, (PPOINTL)lpSize); 368 } 369 370 /* Nothing to calculate, return the current extension */ 371 lpSize->cx = pdcattr->szlViewportExt.cx; 372 lpSize->cy = pdcattr->szlViewportExt.cy; 373 374 return TRUE; 375 } 376 377 378 BOOL 379 WINAPI 380 GetViewportOrgEx( 381 _In_ HDC hdc, 382 _Out_ LPPOINT lpPoint) 383 { 384 PDC_ATTR pdcattr; 385 386 /* Get the DC attribute */ 387 pdcattr = GdiGetDcAttr(hdc); 388 if (pdcattr == NULL) 389 { 390 /* Do not set LastError here! */ 391 return FALSE; 392 } 393 394 /* Get the current viewport org */ 395 lpPoint->x = pdcattr->ptlViewportOrg.x; 396 lpPoint->y = pdcattr->ptlViewportOrg.y; 397 398 /* Handle right-to-left layout */ 399 if (pdcattr->dwLayout & LAYOUT_RTL) 400 lpPoint->x = -lpPoint->x; 401 402 return TRUE; 403 } 404 405 406 BOOL 407 WINAPI 408 GetWindowExtEx( 409 _In_ HDC hdc, 410 _Out_ LPSIZE lpSize) 411 { 412 PDC_ATTR pdcattr; 413 414 /* Get the DC attribute */ 415 pdcattr = GdiGetDcAttr(hdc); 416 if (pdcattr == NULL) 417 { 418 /* Do not set LastError here! */ 419 return FALSE; 420 } 421 422 /* Get the current window extension */ 423 lpSize->cx = pdcattr->szlWindowExt.cx; 424 lpSize->cy = pdcattr->szlWindowExt.cy; 425 426 /* Handle right-to-left layout */ 427 if (pdcattr->dwLayout & LAYOUT_RTL) 428 lpSize->cx = -lpSize->cx; 429 430 return TRUE; 431 } 432 433 434 BOOL 435 WINAPI 436 GetWindowOrgEx( 437 _In_ HDC hdc, 438 _Out_ LPPOINT lpPoint) 439 { 440 PDC_ATTR pdcattr; 441 442 /* Get the DC attribute */ 443 pdcattr = GdiGetDcAttr(hdc); 444 if (pdcattr == NULL) 445 { 446 /* Do not set LastError here! */ 447 return FALSE; 448 } 449 450 /* Get the current window origin */ 451 lpPoint->x = pdcattr->ptlWindowOrg.x; 452 lpPoint->y = pdcattr->ptlWindowOrg.y; 453 454 return TRUE; 455 } 456 457 /* 458 * @unimplemented 459 */ 460 BOOL 461 WINAPI 462 SetViewportExtEx( 463 _In_ HDC hdc, 464 _In_ int nXExtent, 465 _In_ int nYExtent, 466 _Out_opt_ LPSIZE lpSize) 467 { 468 PDC_ATTR pdcattr; 469 470 HANDLE_METADC(BOOL, SetViewportExtEx, FALSE, hdc, nXExtent, nYExtent, lpSize); 471 472 /* Get the DC attribute */ 473 pdcattr = GdiGetDcAttr(hdc); 474 if (pdcattr == NULL) 475 { 476 SetLastError(ERROR_INVALID_PARAMETER); 477 return FALSE; 478 } 479 480 /* Check if the caller wants the old extension */ 481 if (lpSize) 482 { 483 /* Return the current viewport extension */ 484 lpSize->cx = pdcattr->szlViewportExt.cx; 485 lpSize->cy = pdcattr->szlViewportExt.cy; 486 } 487 488 /* Check for trivial case */ 489 if ((pdcattr->szlViewportExt.cx == nXExtent) && 490 (pdcattr->szlViewportExt.cy == nYExtent)) 491 return TRUE; 492 493 /* Only change viewport extension if we are in iso or aniso mode */ 494 if ((pdcattr->iMapMode == MM_ISOTROPIC) || 495 (pdcattr->iMapMode == MM_ANISOTROPIC)) 496 { 497 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 498 { 499 if (pdcattr->ulDirty_ & DC_FONTTEXT_DIRTY) 500 { 501 NtGdiFlush(); // Sync up pdcattr from Kernel space. 502 pdcattr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY); 503 } 504 } 505 506 /* Set the new viewport extension */ 507 pdcattr->szlViewportExt.cx = nXExtent; 508 pdcattr->szlViewportExt.cy = nYExtent; 509 510 /* Handle right-to-left layout */ 511 if (pdcattr->dwLayout & LAYOUT_RTL) 512 NtGdiMirrorWindowOrg(hdc); 513 514 /* Update xform flags */ 515 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID); 516 } 517 518 return TRUE; 519 } 520 521 /* 522 * @unimplemented 523 */ 524 BOOL 525 WINAPI 526 SetWindowOrgEx( 527 _In_ HDC hdc, 528 _In_ int X, 529 _In_ int Y, 530 _Out_opt_ LPPOINT lpPoint) 531 { 532 PDC_ATTR pdcattr; 533 534 HANDLE_METADC(BOOL, SetWindowOrgEx, FALSE, hdc, X, Y, lpPoint); 535 536 /* Get the DC attribute */ 537 pdcattr = GdiGetDcAttr(hdc); 538 if (pdcattr == NULL) 539 { 540 /* Do not set LastError here! */ 541 return FALSE; 542 } 543 #if 0 544 if (lpPoint) 545 { 546 lpPoint->x = pdcattr->ptlWindowOrg.x; 547 lpPoint->y = pdcattr->ptlWindowOrg.y; 548 } 549 550 if ((pdcattr->ptlWindowOrg.x == X) && (pdcattr->ptlWindowOrg.y == Y)) 551 return TRUE; 552 553 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc) 554 { 555 if (pdcattr->ulDirty_ & DC_FONTTEXT_DIRTY) 556 { 557 NtGdiFlush(); // Sync up pdcattr from Kernel space. 558 pdcattr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY); 559 } 560 } 561 562 pdcattr->ptlWindowOrg.x = X; 563 pdcattr->lWindowOrgx = X; 564 pdcattr->ptlWindowOrg.y = Y; 565 if (pdcattr->dwLayout & LAYOUT_RTL) NtGdiMirrorWindowOrg(hdc); 566 pdcattr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID); 567 return TRUE; 568 #endif 569 return NtGdiSetWindowOrgEx(hdc, X, Y, lpPoint); 570 } 571 572 /* 573 * @unimplemented 574 */ 575 BOOL 576 WINAPI 577 SetWindowExtEx( 578 _In_ HDC hdc, 579 _In_ INT nXExtent, 580 _In_ INT nYExtent, 581 _Out_opt_ LPSIZE lpSize) 582 { 583 PDC_ATTR pdcattr; 584 585 HANDLE_METADC(BOOL, SetWindowExtEx, FALSE, hdc, nXExtent, nYExtent, lpSize); 586 587 /* Get the DC attr */ 588 pdcattr = GdiGetDcAttr(hdc); 589 if (!pdcattr) 590 { 591 /* Set the error value and return failure */ 592 SetLastError(ERROR_INVALID_PARAMETER); 593 return FALSE; 594 } 595 596 /* Check if the caller wants the old extension */ 597 if (lpSize) 598 { 599 /* Return the current window extension */ 600 lpSize->cx = pdcattr->szlWindowExt.cx; 601 lpSize->cy = pdcattr->szlWindowExt.cy; 602 603 /* Handle right-to-left layout */ 604 if (pdcattr->dwLayout & LAYOUT_RTL) 605 lpSize->cx = -lpSize->cx; 606 } 607 608 if (pdcattr->dwLayout & LAYOUT_RTL) 609 { 610 NtGdiMirrorWindowOrg(hdc); 611 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID); 612 } 613 else if ((pdcattr->iMapMode == MM_ISOTROPIC) || 614 (pdcattr->iMapMode == MM_ANISOTROPIC)) 615 { 616 if ((pdcattr->szlWindowExt.cx == nXExtent) && 617 (pdcattr->szlWindowExt.cy == nYExtent)) 618 return TRUE; 619 620 if ((!nXExtent) || (!nYExtent)) 621 return FALSE; 622 623 if (NtCurrentTeb()->GdiTebBatch.HDC == hdc) 624 { 625 if (pdcattr->ulDirty_ & DC_FONTTEXT_DIRTY) 626 { 627 NtGdiFlush(); // Sync up Dc_Attr from Kernel space. 628 pdcattr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY); 629 } 630 } 631 632 pdcattr->szlWindowExt.cx = nXExtent; 633 pdcattr->szlWindowExt.cy = nYExtent; 634 if (pdcattr->dwLayout & LAYOUT_RTL) 635 NtGdiMirrorWindowOrg(hdc); 636 637 pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID); 638 } 639 640 return TRUE; 641 } 642 643 /* 644 * @unimplemented 645 */ 646 BOOL 647 WINAPI 648 SetViewportOrgEx( 649 _In_ HDC hdc, 650 _In_ int X, 651 _In_ int Y, 652 _Out_opt_ LPPOINT lpPoint) 653 { 654 PDC_ATTR pdcattr; 655 656 HANDLE_METADC(BOOL, SetViewportOrgEx, FALSE, hdc, X, Y, lpPoint); 657 658 /* Get the DC attribute */ 659 pdcattr = GdiGetDcAttr(hdc); 660 if (!pdcattr) 661 { 662 /* Do not set LastError here! */ 663 return FALSE; 664 } 665 666 #if 0 667 if (lpPoint) 668 { 669 lpPoint->x = pdcattr->ptlViewportOrg.x; 670 lpPoint->y = pdcattr->ptlViewportOrg.y; 671 if (pdcattr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x; 672 } 673 pdcattr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID); 674 if (pdcattr->dwLayout & LAYOUT_RTL) X = -X; 675 pdcattr->ptlViewportOrg.x = X; 676 pdcattr->ptlViewportOrg.y = Y; 677 return TRUE; 678 #endif 679 return NtGdiSetViewportOrgEx(hdc,X,Y,lpPoint); 680 } 681 682 /* 683 * @implemented 684 */ 685 BOOL 686 WINAPI 687 ScaleViewportExtEx( 688 _In_ HDC hdc, 689 _In_ INT xNum, 690 _In_ INT xDenom, 691 _In_ INT yNum, 692 _In_ INT yDenom, 693 _Out_ LPSIZE lpSize) 694 { 695 HANDLE_METADC(BOOL, ScaleViewportExtEx, FALSE, hdc, xNum, xDenom, yNum, yDenom, lpSize); 696 697 if (!GdiGetDcAttr(hdc)) 698 { 699 SetLastError(ERROR_INVALID_PARAMETER); 700 return FALSE; 701 } 702 703 return NtGdiScaleViewportExtEx(hdc, xNum, xDenom, yNum, yDenom, lpSize); 704 } 705 706 /* 707 * @implemented 708 */ 709 BOOL 710 WINAPI 711 ScaleWindowExtEx( 712 _In_ HDC hdc, 713 _In_ INT xNum, 714 _In_ INT xDenom, 715 _In_ INT yNum, 716 _In_ INT yDenom, 717 _Out_ LPSIZE lpSize) 718 { 719 HANDLE_METADC(BOOL, ScaleWindowExtEx, FALSE, hdc, xNum, xDenom, yNum, yDenom, lpSize); 720 721 if (!GdiGetDcAttr(hdc)) 722 { 723 SetLastError(ERROR_INVALID_PARAMETER); 724 return FALSE; 725 } 726 727 return NtGdiScaleWindowExtEx(hdc, xNum, xDenom, yNum, yDenom, lpSize); 728 } 729 730 /* 731 * @implemented 732 */ 733 DWORD 734 WINAPI 735 GetLayout( 736 _In_ HDC hdc) 737 { 738 PDC_ATTR pdcattr; 739 740 /* METADC16 is not supported in this API */ 741 if (GDI_HANDLE_GET_TYPE(hdc) == GDILoObjType_LO_METADC16_TYPE) 742 { 743 return GDI_ERROR; 744 } 745 746 /* Get the DC attribute */ 747 pdcattr = GdiGetDcAttr(hdc); 748 if (!pdcattr) 749 { 750 /* Set the error value and return failure */ 751 SetLastError(ERROR_INVALID_PARAMETER); 752 return GDI_ERROR; 753 } 754 755 /* Return the layout */ 756 return pdcattr->dwLayout; 757 } 758 759 760 /* 761 * @implemented 762 */ 763 DWORD 764 WINAPI 765 SetLayout( 766 _In_ HDC hdc, 767 _In_ DWORD dwLayout) 768 { 769 HANDLE_METADC(DWORD, SetLayout, GDI_ERROR, hdc, dwLayout); 770 771 if (!GdiGetDcAttr(hdc)) 772 { 773 SetLastError(ERROR_INVALID_PARAMETER); 774 return GDI_ERROR; 775 } 776 777 return NtGdiSetLayout(hdc, -1, dwLayout); 778 } 779 780 /* 781 * @implemented 782 */ 783 DWORD 784 WINAPI 785 SetLayoutWidth( 786 _In_ HDC hdc, 787 _In_ LONG wox, 788 _In_ DWORD dwLayout) 789 { 790 /* Only normal DCs are handled here */ 791 if (GDI_HANDLE_GET_TYPE(hdc) != GDILoObjType_LO_DC_TYPE) 792 { 793 return GDI_ERROR; 794 } 795 796 if (!GdiGetDcAttr(hdc)) 797 { 798 SetLastError(ERROR_INVALID_PARAMETER); 799 return GDI_ERROR; 800 } 801 802 return NtGdiSetLayout(hdc, wox, dwLayout); 803 } 804 805 /* 806 * @implemented 807 */ 808 BOOL 809 WINAPI 810 GetDCOrgEx( 811 _In_ HDC hdc, 812 _Out_ LPPOINT lpPoint) 813 { 814 return NtGdiGetDCPoint(hdc, GdiGetDCOrg, (PPOINTL)lpPoint); 815 } 816 817 818 /* 819 * @implemented 820 */ 821 LONG 822 WINAPI 823 GetDCOrg( 824 _In_ HDC hdc) 825 { 826 POINT pt; 827 828 /* Call the new API */ 829 if (!GetDCOrgEx(hdc, &pt)) 830 return 0; 831 832 /* Return the point in the old way */ 833 return(MAKELONG(pt.x, pt.y)); 834 } 835 836 837 /* 838 * @implemented 839 * 840 */ 841 BOOL 842 WINAPI 843 OffsetViewportOrgEx( 844 _In_ HDC hdc, 845 _In_ int nXOffset, 846 _In_ int nYOffset, 847 _Out_opt_ LPPOINT lpPoint) 848 { 849 //PDC_ATTR pdcattr; 850 851 HANDLE_METADC(BOOL, OffsetViewportOrgEx, FALSE, hdc, nXOffset, nYOffset, lpPoint); 852 #if 0 853 854 /* Get the DC attribute */ 855 pdcattr = GdiGetDcAttr(hdc); 856 if (!pdcattr) 857 { 858 /* Do not set LastError here! */ 859 return FALSE; 860 } 861 862 if (lpPoint) 863 { 864 *lpPoint = (POINT)pdcattr->ptlViewportOrg; 865 if ( pdcattr->dwLayout & LAYOUT_RTL) lpPoint->x = -lpPoint->x; 866 } 867 868 if ( nXOffset || nYOffset != nXOffset ) 869 { 870 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc) 871 { 872 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 873 { 874 NtGdiFlush(); 875 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 876 } 877 } 878 879 pdcattr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID); 880 if (pdcattr->dwLayout & LAYOUT_RTL) nXOffset = -nXOffset; 881 pdcattr->ptlViewportOrg.x += nXOffset; 882 pdcattr->ptlViewportOrg.y += nYOffset; 883 } 884 return TRUE; 885 #endif 886 return NtGdiOffsetViewportOrgEx(hdc, nXOffset, nYOffset, lpPoint); 887 } 888 889 /* 890 * @implemented 891 * 892 */ 893 BOOL 894 WINAPI 895 OffsetWindowOrgEx( 896 _In_ HDC hdc, 897 _In_ int nXOffset, 898 _In_ int nYOffset, 899 _Out_opt_ LPPOINT lpPoint) 900 { 901 //PDC_ATTR pdcattr; 902 903 HANDLE_METADC(BOOL, OffsetWindowOrgEx, FALSE, hdc, nXOffset, nYOffset, lpPoint); 904 905 #if 0 906 /* Get the DC attribute */ 907 pdcattr = GdiGetDcAttr(hdc); 908 if (!pdcattr) 909 { 910 /* Do not set LastError here! */ 911 return FALSE; 912 } 913 914 if ( lpPoint ) 915 { 916 *lpPoint = (POINT)pdcattr->ptlWindowOrg; 917 lpPoint->x = pdcattr->lWindowOrgx; 918 } 919 920 if ( nXOffset || nYOffset != nXOffset ) 921 { 922 if (NtCurrentTeb()->GdiTebBatch.HDC == (ULONG)hdc) 923 { 924 if (pdcattr->ulDirty_ & DC_MODE_DIRTY) 925 { 926 NtGdiFlush(); 927 pdcattr->ulDirty_ &= ~DC_MODE_DIRTY; 928 } 929 } 930 931 pdcattr->flXform |= (PAGE_XLATE_CHANGED|DEVICE_TO_WORLD_INVALID); 932 pdcattr->ptlWindowOrg.x += nXOffset; 933 pdcattr->ptlWindowOrg.y += nYOffset; 934 pdcattr->lWindowOrgx += nXOffset; 935 } 936 return TRUE; 937 #endif 938 return NtGdiOffsetWindowOrgEx(hdc, nXOffset, nYOffset, lpPoint); 939 } 940 941