2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS System Libraries
4 * FILE: dll/gdi32/objects/coord.c
5 * PURPOSE: Functions for coordinate transformation
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. */
15 MatrixToXForm(XFORM
*pxform
, const MATRIX
*pmx
)
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
);
36 for (i
= 0; i
< nCount
; i
++)
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
);
55 MatrixToXForm(&xform
, pmx
);
56 GdiTransformPoints2(&xform
, pptOut
, pptIn
, nCount
);
59 #define MAX_OFFSET 4294967041.0
60 #define _fmul(x,y) (((x) == 0) ? 0 : (x) * (y))
72 if (!pxfResult
|| !pxf1
|| !pxf2
) return FALSE
;
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
);
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.))
82 xformTmp
.eM12
= (pxf1
->eM11
* pxf2
->eM12
) + (pxf1
->eM12
* pxf2
->eM22
);
83 xformTmp
.eM21
= (pxf1
->eM21
* pxf2
->eM11
) + (pxf1
->eM22
* pxf2
->eM21
);
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
;
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
))
102 /* All is ok, return the calculated values */
103 *pxfResult
= xformTmp
;
110 DPtoLP(HDC hdc
, LPPOINT lpPoints
, INT nCount
)
116 pdcattr
= GdiGetDcAttr(hdc
);
119 SetLastError(ERROR_INVALID_HANDLE
);
123 if (pdcattr
->flXform
& ANY_XFORM_CHANGES
)
125 GdiFixupTransforms(pdcattr
);
128 // FIXME: can this fail on Windows?
129 GdiTransformPoints(&pdcattr
->mxDeviceToWorld
, lpPoints
, lpPoints
, nCount
);
133 return NtGdiTransformPoints(hdc
, lpPoints
, lpPoints
, nCount
, GdiDpToLp
);
138 LPtoDP(HDC hdc
, LPPOINT lpPoints
, INT nCount
)
144 pdcattr
= GdiGetDcAttr(hdc
);
147 SetLastError(ERROR_INVALID_HANDLE
);
151 if (pdcattr
->flXform
& ANY_XFORM_CHANGES
)
153 GdiFixupTransforms(pdcattr
);
156 // FIXME: can this fail on Windows?
157 GdiTransformPoints(&pdcattr
->mxWorldToDevice
, lpPoints
, lpPoints
, nCount
);
161 return NtGdiTransformPoints(hdc
, lpPoints
, lpPoints
, nCount
, GdiLpToDp
);
170 GetCurrentPositionEx(HDC hdc
,
175 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
179 if ( Dc_Attr
->ulDirty_
& DIRTY_PTLCURRENT
) // have a hit!
181 lpPoint
->x
= Dc_Attr
->ptfxCurrent
.x
;
182 lpPoint
->y
= Dc_Attr
->ptfxCurrent
.y
;
183 DPtoLP ( hdc
, lpPoint
, 1); // reconvert back.
184 Dc_Attr
->ptlCurrent
.x
= lpPoint
->x
; // save it
185 Dc_Attr
->ptlCurrent
.y
= lpPoint
->y
;
186 Dc_Attr
->ulDirty_
&= ~DIRTY_PTLCURRENT
; // clear bit
190 lpPoint
->x
= Dc_Attr
->ptlCurrent
.x
;
191 lpPoint
->y
= Dc_Attr
->ptlCurrent
.y
;
196 SetLastError(ERROR_INVALID_PARAMETER
);
207 GetWorldTransform(HDC hDC
, LPXFORM lpXform
)
212 pdcattr
= GdiGetDcAttr(hdc
);
215 SetLastError(ERROR_INVALID_HANDLE
);
219 if (pdcattr
->flXform
& ANY_XFORM_INVALID
)
221 GdiFixupTransforms(pdcattr
);
224 MatrixToXForm(lpXform
, &pdcattr
->mxWorldToDevice
);
226 return NtGdiGetTransform(hDC
, GdiWorldSpaceToPageSpace
, lpXform
);
232 SetWorldTransform( HDC hDC
, CONST XFORM
*Xform
)
234 /* FIXME shall we add undoc #define MWT_SETXFORM 4 ?? */
235 return ModifyWorldTransform( hDC
, Xform
, MWT_MAX
+1);
241 ModifyWorldTransform(
248 // Handle something other than a normal dc object.
249 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
251 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
255 PLDC pLDC
= GdiGetLDC(hDC
);
258 SetLastError(ERROR_INVALID_HANDLE
);
261 if (pLDC
->iType
== LDC_EMFLDC
)
263 if (iMode
== MWT_MAX
+1)
264 if (!EMFDRV_SetWorldTransform( hDC
, Xform
) ) return FALSE
;
265 return EMFDRV_ModifyWorldTransform( hDC
, Xform
, iMode
); // Ported from wine.
273 if (!GdiGetHandleUserData((HGDIOBJ
) hDC
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
275 /* Check that graphics mode is GM_ADVANCED */
276 if ( Dc_Attr
->iGraphicsMode
!= GM_ADVANCED
) return FALSE
;
278 return NtGdiModifyWorldTransform(hDC
, (CONST LPXFORM
) Xform
, iMode
);
290 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
292 if ((Dc_Attr
->flXform
& PAGE_EXTENTS_CHANGED
) && (Dc_Attr
->iMapMode
== MM_ISOTROPIC
))
293 // Something was updated, go to kernel.
294 return NtGdiGetDCPoint( hdc
, GdiGetViewPortExt
, (PPOINTL
) lpSize
);
297 lpSize
->cx
= Dc_Attr
->szlViewportExt
.cx
;
298 lpSize
->cy
= Dc_Attr
->szlViewportExt
.cy
;
313 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
314 lpPoint
->x
= Dc_Attr
->ptlViewportOrg
.x
;
315 lpPoint
->y
= Dc_Attr
->ptlViewportOrg
.y
;
316 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) lpPoint
->x
= -lpPoint
->x
;
318 // return NtGdiGetDCPoint( hdc, GdiGetViewPortOrg, lpPoint );
331 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
332 lpSize
->cx
= Dc_Attr
->szlWindowExt
.cx
;
333 lpSize
->cy
= Dc_Attr
->szlWindowExt
.cy
;
334 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) lpSize
->cx
= -lpSize
->cx
;
336 // return NtGdiGetDCPoint( hdc, GdiGetWindowExt, (LPPOINT) lpSize );
349 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
350 lpPoint
->x
= Dc_Attr
->ptlWindowOrg
.x
;
351 lpPoint
->y
= Dc_Attr
->ptlWindowOrg
.y
;
353 //return NtGdiGetDCPoint( hdc, GdiGetWindowOrg, lpPoint );
361 SetViewportExtEx(HDC hdc
,
368 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
370 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
371 return MFDRV_SetViewportExtEx();
374 PLDC pLDC
= GdiGetLDC(hdc
);
377 SetLastError(ERROR_INVALID_HANDLE
);
380 if (pLDC
->iType
== LDC_EMFLDC
)
382 return EMFDRV_SetViewportExtEx();
387 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
))
394 lpSize
->cx
= Dc_Attr
->szlViewportExt
.cx
;
395 lpSize
->cy
= Dc_Attr
->szlViewportExt
.cy
;
398 if ((Dc_Attr
->szlViewportExt
.cx
== nXExtent
) && (Dc_Attr
->szlViewportExt
.cy
== nYExtent
))
401 if ((Dc_Attr
->iMapMode
== MM_ISOTROPIC
) || (Dc_Attr
->iMapMode
== MM_ANISOTROPIC
))
403 if (NtCurrentTeb()->GdiTebBatch
.HDC
== hdc
)
405 if (Dc_Attr
->ulDirty_
& DC_FONTTEXT_DIRTY
)
407 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
408 Dc_Attr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
411 Dc_Attr
->szlViewportExt
.cx
= nXExtent
;
412 Dc_Attr
->szlViewportExt
.cy
= nYExtent
;
413 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) NtGdiMirrorWindowOrg(hdc
);
414 Dc_Attr
->flXform
|= (PAGE_EXTENTS_CHANGED
|INVALIDATE_ATTRIBUTES
|DEVICE_TO_WORLD_INVALID
);
424 SetWindowOrgEx(HDC hdc
,
432 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
434 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
435 return MFDRV_SetWindowOrgEx();
438 PLDC pLDC
= GdiGetLDC(hdc
);
441 SetLastError(ERROR_INVALID_HANDLE
);
444 if (pLDC
->iType
== LDC_EMFLDC
)
446 return EMFDRV_SetWindowOrgEx();
451 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
455 lpPoint
->x
= Dc_Attr
->ptlWindowOrg
.x
;
456 lpPoint
->y
= Dc_Attr
->ptlWindowOrg
.y
;
459 if ((Dc_Attr
->ptlWindowOrg
.x
== X
) && (Dc_Attr
->ptlWindowOrg
.y
== Y
))
462 if (NtCurrentTeb()->GdiTebBatch
.HDC
== (ULONG
)hdc
)
464 if (Dc_Attr
->ulDirty_
& DC_FONTTEXT_DIRTY
)
466 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
467 Dc_Attr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
471 Dc_Attr
->ptlWindowOrg
.x
= X
;
472 Dc_Attr
->lWindowOrgx
= X
;
473 Dc_Attr
->ptlWindowOrg
.y
= Y
;
474 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) NtGdiMirrorWindowOrg(hdc
);
475 Dc_Attr
->flXform
|= (PAGE_XLATE_CHANGED
|DEVICE_TO_WORLD_INVALID
);
478 return NtGdiSetWindowOrgEx(hdc
,X
,Y
,lpPoint
);
490 _Out_opt_ LPSIZE lpSize
)
495 /* Check what type of DC that is */
496 ulType
= GDI_HANDLE_GET_TYPE(hdc
);
499 case GDILoObjType_LO_DC_TYPE
:
500 /* Handle this in the path below */
502 #if 0// FIXME: we don't support this
503 case GDILoObjType_LO_METADC16_TYPE
:
504 return MFDRV_SetWindowExtEx(hdc
, nXExtent
, nYExtent
, lpSize
);
506 case GDILoObjType_LO_METAFILE_TYPE
:
507 return EMFDRV_SetWindowExtEx(hdc
, nXExtent
, nYExtent
, lpSize
);
510 /* Other types are not allowed */
511 SetLastError(ERROR_INVALID_HANDLE
);
515 /* Get the DC attr */
516 pdcattr
= GdiGetDcAttr(hdc
);
519 /* Set the error value and return failure */
520 SetLastError(ERROR_INVALID_PARAMETER
);
526 lpSize
->cx
= pdcattr
->szlWindowExt
.cx
;
527 lpSize
->cy
= pdcattr
->szlWindowExt
.cy
;
528 if (pdcattr
->dwLayout
& LAYOUT_RTL
) lpSize
->cx
= -lpSize
->cx
;
531 if (pdcattr
->dwLayout
& LAYOUT_RTL
)
533 NtGdiMirrorWindowOrg(hdc
);
534 pdcattr
->flXform
|= (PAGE_EXTENTS_CHANGED
|INVALIDATE_ATTRIBUTES
|DEVICE_TO_WORLD_INVALID
);
536 else if ((pdcattr
->iMapMode
== MM_ISOTROPIC
) || (pdcattr
->iMapMode
== MM_ANISOTROPIC
))
538 if ((pdcattr
->szlWindowExt
.cx
== nXExtent
) && (pdcattr
->szlWindowExt
.cy
== nYExtent
))
541 if ((!nXExtent
) || (!nYExtent
)) return FALSE
;
543 if (NtCurrentTeb()->GdiTebBatch
.HDC
== hdc
)
545 if (pdcattr
->ulDirty_
& DC_FONTTEXT_DIRTY
)
547 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
548 pdcattr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
551 pdcattr
->szlWindowExt
.cx
= nXExtent
;
552 pdcattr
->szlWindowExt
.cy
= nYExtent
;
553 if (pdcattr
->dwLayout
& LAYOUT_RTL
) NtGdiMirrorWindowOrg(hdc
);
554 pdcattr
->flXform
|= (PAGE_EXTENTS_CHANGED
|INVALIDATE_ATTRIBUTES
|DEVICE_TO_WORLD_INVALID
);
565 SetViewportOrgEx(HDC hdc
,
573 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
575 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
576 return MFDRV_SetViewportOrgEx();
579 PLDC pLDC
= GdiGetLDC(hdc
);
582 SetLastError(ERROR_INVALID_HANDLE
);
585 if (pLDC
->iType
== LDC_EMFLDC
)
587 return EMFDRV_SetViewportOrgEx();
592 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
596 lpPoint
->x
= Dc_Attr
->ptlViewportOrg
.x
;
597 lpPoint
->y
= Dc_Attr
->ptlViewportOrg
.y
;
598 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) lpPoint
->x
= -lpPoint
->x
;
600 Dc_Attr
->flXform
|= (PAGE_XLATE_CHANGED
|DEVICE_TO_WORLD_INVALID
);
601 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) X
= -X
;
602 Dc_Attr
->ptlViewportOrg
.x
= X
;
603 Dc_Attr
->ptlViewportOrg
.y
= Y
;
606 return NtGdiSetViewportOrgEx(hdc
,X
,Y
,lpPoint
);
624 if (GDI_HANDLE_GET_TYPE(a0
) != GDI_OBJECT_TYPE_DC
)
626 if (GDI_HANDLE_GET_TYPE(a0
) == GDI_OBJECT_TYPE_METADC
)
630 PLDC pLDC
= GdiGetLDC(a0
);
633 SetLastError(ERROR_INVALID_HANDLE
);
636 if (pLDC
->iType
== LDC_EMFLDC
)
643 if (!GdiIsHandleValid((HGDIOBJ
) a0
) ||
644 (GDI_HANDLE_GET_TYPE(a0
) != GDI_OBJECT_TYPE_DC
)) return FALSE
;
646 return NtGdiScaleViewportExtEx(a0
, a1
, a2
, a3
, a4
, a5
);
664 if (GDI_HANDLE_GET_TYPE(a0
) != GDI_OBJECT_TYPE_DC
)
666 if (GDI_HANDLE_GET_TYPE(a0
) == GDI_OBJECT_TYPE_METADC
)
670 PLDC pLDC
= GdiGetLDC(a0
);
673 SetLastError(ERROR_INVALID_HANDLE
);
676 if (pLDC
->iType
== LDC_EMFLDC
)
683 if (!GdiIsHandleValid((HGDIOBJ
) a0
) ||
684 (GDI_HANDLE_GET_TYPE(a0
) != GDI_OBJECT_TYPE_DC
)) return FALSE
;
686 return NtGdiScaleWindowExtEx(a0
, a1
, a2
, a3
, a4
, a5
);
698 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return GDI_ERROR
;
699 return Dc_Attr
->dwLayout
;
712 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
714 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
715 return MFDRV_SetLayout( hdc
, dwLayout
);
718 PLDC pLDC
= GdiGetLDC(hdc
);
721 SetLastError(ERROR_INVALID_HANDLE
);
724 if (pLDC
->iType
== LDC_EMFLDC
)
726 return EMFDRV_SetLayout( hdc
, dwLayout
);
731 if (!GdiIsHandleValid((HGDIOBJ
) hdc
) ||
732 (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)) return GDI_ERROR
;
733 return NtGdiSetLayout( hdc
, -1, dwLayout
);
741 SetLayoutWidth(HDC hdc
,LONG wox
,DWORD dwLayout
)
743 if (!GdiIsHandleValid((HGDIOBJ
) hdc
) ||
744 (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)) return GDI_ERROR
;
745 return NtGdiSetLayout( hdc
, wox
, dwLayout
);
754 OffsetViewportOrgEx(HDC hdc
,
762 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
764 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
765 return MFDRV_OffsetViewportOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
768 PLDC pLDC
= GdiGetLDC(hdc
);
771 SetLastError(ERROR_INVALID_HANDLE
);
774 if (pLDC
->iType
== LDC_EMFLDC
)
776 return EMFDRV_OffsetWindowOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
781 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
785 *lpPoint
= (POINT
)Dc_Attr
->ptlViewportOrg
;
786 if ( Dc_Attr
->dwLayout
& LAYOUT_RTL
) lpPoint
->x
= -lpPoint
->x
;
789 if ( nXOffset
|| nYOffset
!= nXOffset
)
791 if (NtCurrentTeb()->GdiTebBatch
.HDC
== (ULONG
)hdc
)
793 if (Dc_Attr
->ulDirty_
& DC_MODE_DIRTY
)
796 Dc_Attr
->ulDirty_
&= ~DC_MODE_DIRTY
;
799 Dc_Attr
->flXform
|= (PAGE_XLATE_CHANGED
|DEVICE_TO_WORLD_INVALID
);
800 if ( Dc_Attr
->dwLayout
& LAYOUT_RTL
) nXOffset
= -nXOffset
;
801 Dc_Attr
->ptlViewportOrg
.x
+= nXOffset
;
802 Dc_Attr
->ptlViewportOrg
.y
+= nYOffset
;
806 return NtGdiOffsetViewportOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
815 OffsetWindowOrgEx(HDC hdc
,
823 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
825 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
826 return MFDRV_OffsetWindowOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
829 PLDC pLDC
= GdiGetLDC(hdc
);
832 SetLastError(ERROR_INVALID_HANDLE
);
835 if (pLDC
->iType
== LDC_EMFLDC
)
837 return EMFDRV_OffsetWindowOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
842 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
846 *lpPoint
= (POINT
)Dc_Attr
->ptlWindowOrg
;
847 lpPoint
->x
= Dc_Attr
->lWindowOrgx
;
850 if ( nXOffset
|| nYOffset
!= nXOffset
)
852 if (NtCurrentTeb()->GdiTebBatch
.HDC
== (ULONG
)hdc
)
854 if (Dc_Attr
->ulDirty_
& DC_MODE_DIRTY
)
857 Dc_Attr
->ulDirty_
&= ~DC_MODE_DIRTY
;
860 Dc_Attr
->flXform
|= (PAGE_XLATE_CHANGED
|DEVICE_TO_WORLD_INVALID
);
861 Dc_Attr
->ptlWindowOrg
.x
+= nXOffset
;
862 Dc_Attr
->ptlWindowOrg
.y
+= nYOffset
;
863 Dc_Attr
->lWindowOrgx
+= nXOffset
;
867 return NtGdiOffsetWindowOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);