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
;
118 /* Get the DC attribute */
119 pdcattr
= GdiGetDcAttr(hdc
);
122 SetLastError(ERROR_INVALID_PARAMETER
);
126 return pdcattr
->iMapMode
;
140 /* Get the DC attribute */
141 pdcattr
= GdiGetDcAttr(hdc
);
144 SetLastError(ERROR_INVALID_PARAMETER
);
149 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
151 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
152 return MFDRV_SetMapMode(hdc
, iMode
);
155 SetLastError(ERROR_INVALID_HANDLE
);
160 /* Force change if Isotropic is set for recompute. */
161 if ((iMode
!= pdcattr
->iMapMode
) || (iMode
== MM_ISOTROPIC
))
163 pdcattr
->ulDirty_
&= ~SLOW_WIDTHS
;
164 return GetAndSetDCDWord( hdc
, GdiGetSetMapMode
, iMode
, 0, 0, 0 );
167 return pdcattr
->iMapMode
;
173 DPtoLP(HDC hdc
, LPPOINT lpPoints
, INT nCount
)
179 pdcattr
= GdiGetDcAttr(hdc
);
182 SetLastError(ERROR_INVALID_HANDLE
);
186 if (pdcattr
->flXform
& ANY_XFORM_CHANGES
)
188 GdiFixupTransforms(pdcattr
);
191 // FIXME: can this fail on Windows?
192 GdiTransformPoints(&pdcattr
->mxDeviceToWorld
, lpPoints
, lpPoints
, nCount
);
196 return NtGdiTransformPoints(hdc
, lpPoints
, lpPoints
, nCount
, GdiDpToLp
);
201 LPtoDP(HDC hdc
, LPPOINT lpPoints
, INT nCount
)
207 pdcattr
= GdiGetDcAttr(hdc
);
210 SetLastError(ERROR_INVALID_HANDLE
);
214 if (pdcattr
->flXform
& ANY_XFORM_CHANGES
)
216 GdiFixupTransforms(pdcattr
);
219 // FIXME: can this fail on Windows?
220 GdiTransformPoints(&pdcattr
->mxWorldToDevice
, lpPoints
, lpPoints
, nCount
);
224 return NtGdiTransformPoints(hdc
, lpPoints
, lpPoints
, nCount
, GdiLpToDp
);
233 GetCurrentPositionEx(HDC hdc
,
238 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
242 if ( Dc_Attr
->ulDirty_
& DIRTY_PTLCURRENT
) // have a hit!
244 lpPoint
->x
= Dc_Attr
->ptfxCurrent
.x
;
245 lpPoint
->y
= Dc_Attr
->ptfxCurrent
.y
;
246 DPtoLP ( hdc
, lpPoint
, 1); // reconvert back.
247 Dc_Attr
->ptlCurrent
.x
= lpPoint
->x
; // save it
248 Dc_Attr
->ptlCurrent
.y
= lpPoint
->y
;
249 Dc_Attr
->ulDirty_
&= ~DIRTY_PTLCURRENT
; // clear bit
253 lpPoint
->x
= Dc_Attr
->ptlCurrent
.x
;
254 lpPoint
->y
= Dc_Attr
->ptlCurrent
.y
;
259 SetLastError(ERROR_INVALID_PARAMETER
);
270 GetWorldTransform(HDC hDC
, LPXFORM lpXform
)
275 pdcattr
= GdiGetDcAttr(hdc
);
278 SetLastError(ERROR_INVALID_HANDLE
);
282 if (pdcattr
->flXform
& ANY_XFORM_INVALID
)
284 GdiFixupTransforms(pdcattr
);
287 MatrixToXForm(lpXform
, &pdcattr
->mxWorldToDevice
);
289 return NtGdiGetTransform(hDC
, GdiWorldSpaceToPageSpace
, lpXform
);
295 SetWorldTransform( HDC hDC
, CONST XFORM
*Xform
)
297 /* FIXME shall we add undoc #define MWT_SETXFORM 4 ?? */
298 return ModifyWorldTransform( hDC
, Xform
, MWT_MAX
+1);
304 ModifyWorldTransform(
311 // Handle something other than a normal dc object.
312 if (GDI_HANDLE_GET_TYPE(hDC
) != GDI_OBJECT_TYPE_DC
)
314 if (GDI_HANDLE_GET_TYPE(hDC
) == GDI_OBJECT_TYPE_METADC
)
318 PLDC pLDC
= GdiGetLDC(hDC
);
321 SetLastError(ERROR_INVALID_HANDLE
);
324 if (pLDC
->iType
== LDC_EMFLDC
)
326 if (iMode
== MWT_MAX
+1)
327 if (!EMFDRV_SetWorldTransform( hDC
, Xform
) ) return FALSE
;
328 return EMFDRV_ModifyWorldTransform( hDC
, Xform
, iMode
); // Ported from wine.
336 if (!GdiGetHandleUserData((HGDIOBJ
) hDC
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
338 /* Check that graphics mode is GM_ADVANCED */
339 if ( Dc_Attr
->iGraphicsMode
!= GM_ADVANCED
) return FALSE
;
341 return NtGdiModifyWorldTransform(hDC
, (CONST LPXFORM
) Xform
, iMode
);
353 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
355 if ((Dc_Attr
->flXform
& PAGE_EXTENTS_CHANGED
) && (Dc_Attr
->iMapMode
== MM_ISOTROPIC
))
356 // Something was updated, go to kernel.
357 return NtGdiGetDCPoint( hdc
, GdiGetViewPortExt
, (PPOINTL
) lpSize
);
360 lpSize
->cx
= Dc_Attr
->szlViewportExt
.cx
;
361 lpSize
->cy
= Dc_Attr
->szlViewportExt
.cy
;
376 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
377 lpPoint
->x
= Dc_Attr
->ptlViewportOrg
.x
;
378 lpPoint
->y
= Dc_Attr
->ptlViewportOrg
.y
;
379 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) lpPoint
->x
= -lpPoint
->x
;
381 // return NtGdiGetDCPoint( hdc, GdiGetViewPortOrg, lpPoint );
394 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
395 lpSize
->cx
= Dc_Attr
->szlWindowExt
.cx
;
396 lpSize
->cy
= Dc_Attr
->szlWindowExt
.cy
;
397 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) lpSize
->cx
= -lpSize
->cx
;
399 // return NtGdiGetDCPoint( hdc, GdiGetWindowExt, (LPPOINT) lpSize );
412 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
413 lpPoint
->x
= Dc_Attr
->ptlWindowOrg
.x
;
414 lpPoint
->y
= Dc_Attr
->ptlWindowOrg
.y
;
416 //return NtGdiGetDCPoint( hdc, GdiGetWindowOrg, lpPoint );
424 SetViewportExtEx(HDC hdc
,
431 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
433 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
434 return MFDRV_SetViewportExtEx();
437 PLDC pLDC
= GdiGetLDC(hdc
);
440 SetLastError(ERROR_INVALID_HANDLE
);
443 if (pLDC
->iType
== LDC_EMFLDC
)
445 return EMFDRV_SetViewportExtEx();
450 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
))
457 lpSize
->cx
= Dc_Attr
->szlViewportExt
.cx
;
458 lpSize
->cy
= Dc_Attr
->szlViewportExt
.cy
;
461 if ((Dc_Attr
->szlViewportExt
.cx
== nXExtent
) && (Dc_Attr
->szlViewportExt
.cy
== nYExtent
))
464 if ((Dc_Attr
->iMapMode
== MM_ISOTROPIC
) || (Dc_Attr
->iMapMode
== MM_ANISOTROPIC
))
466 if (NtCurrentTeb()->GdiTebBatch
.HDC
== hdc
)
468 if (Dc_Attr
->ulDirty_
& DC_FONTTEXT_DIRTY
)
470 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
471 Dc_Attr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
474 Dc_Attr
->szlViewportExt
.cx
= nXExtent
;
475 Dc_Attr
->szlViewportExt
.cy
= nYExtent
;
476 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) NtGdiMirrorWindowOrg(hdc
);
477 Dc_Attr
->flXform
|= (PAGE_EXTENTS_CHANGED
|INVALIDATE_ATTRIBUTES
|DEVICE_TO_WORLD_INVALID
);
487 SetWindowOrgEx(HDC hdc
,
495 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
497 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
498 return MFDRV_SetWindowOrgEx();
501 PLDC pLDC
= GdiGetLDC(hdc
);
504 SetLastError(ERROR_INVALID_HANDLE
);
507 if (pLDC
->iType
== LDC_EMFLDC
)
509 return EMFDRV_SetWindowOrgEx();
514 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
518 lpPoint
->x
= Dc_Attr
->ptlWindowOrg
.x
;
519 lpPoint
->y
= Dc_Attr
->ptlWindowOrg
.y
;
522 if ((Dc_Attr
->ptlWindowOrg
.x
== X
) && (Dc_Attr
->ptlWindowOrg
.y
== Y
))
525 if (NtCurrentTeb()->GdiTebBatch
.HDC
== (ULONG
)hdc
)
527 if (Dc_Attr
->ulDirty_
& DC_FONTTEXT_DIRTY
)
529 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
530 Dc_Attr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
534 Dc_Attr
->ptlWindowOrg
.x
= X
;
535 Dc_Attr
->lWindowOrgx
= X
;
536 Dc_Attr
->ptlWindowOrg
.y
= Y
;
537 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) NtGdiMirrorWindowOrg(hdc
);
538 Dc_Attr
->flXform
|= (PAGE_XLATE_CHANGED
|DEVICE_TO_WORLD_INVALID
);
541 return NtGdiSetWindowOrgEx(hdc
,X
,Y
,lpPoint
);
553 _Out_opt_ LPSIZE lpSize
)
558 /* Check what type of DC that is */
559 ulType
= GDI_HANDLE_GET_TYPE(hdc
);
562 case GDILoObjType_LO_DC_TYPE
:
563 /* Handle this in the path below */
565 #if 0// FIXME: we don't support this
566 case GDILoObjType_LO_METADC16_TYPE
:
567 return MFDRV_SetWindowExtEx(hdc
, nXExtent
, nYExtent
, lpSize
);
569 case GDILoObjType_LO_METAFILE_TYPE
:
570 return EMFDRV_SetWindowExtEx(hdc
, nXExtent
, nYExtent
, lpSize
);
573 /* Other types are not allowed */
574 SetLastError(ERROR_INVALID_HANDLE
);
578 /* Get the DC attr */
579 pdcattr
= GdiGetDcAttr(hdc
);
582 /* Set the error value and return failure */
583 SetLastError(ERROR_INVALID_PARAMETER
);
589 lpSize
->cx
= pdcattr
->szlWindowExt
.cx
;
590 lpSize
->cy
= pdcattr
->szlWindowExt
.cy
;
591 if (pdcattr
->dwLayout
& LAYOUT_RTL
) lpSize
->cx
= -lpSize
->cx
;
594 if (pdcattr
->dwLayout
& LAYOUT_RTL
)
596 NtGdiMirrorWindowOrg(hdc
);
597 pdcattr
->flXform
|= (PAGE_EXTENTS_CHANGED
|INVALIDATE_ATTRIBUTES
|DEVICE_TO_WORLD_INVALID
);
599 else if ((pdcattr
->iMapMode
== MM_ISOTROPIC
) || (pdcattr
->iMapMode
== MM_ANISOTROPIC
))
601 if ((pdcattr
->szlWindowExt
.cx
== nXExtent
) && (pdcattr
->szlWindowExt
.cy
== nYExtent
))
604 if ((!nXExtent
) || (!nYExtent
)) return FALSE
;
606 if (NtCurrentTeb()->GdiTebBatch
.HDC
== hdc
)
608 if (pdcattr
->ulDirty_
& DC_FONTTEXT_DIRTY
)
610 NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
611 pdcattr
->ulDirty_
&= ~(DC_MODE_DIRTY
|DC_FONTTEXT_DIRTY
);
614 pdcattr
->szlWindowExt
.cx
= nXExtent
;
615 pdcattr
->szlWindowExt
.cy
= nYExtent
;
616 if (pdcattr
->dwLayout
& LAYOUT_RTL
) NtGdiMirrorWindowOrg(hdc
);
617 pdcattr
->flXform
|= (PAGE_EXTENTS_CHANGED
|INVALIDATE_ATTRIBUTES
|DEVICE_TO_WORLD_INVALID
);
628 SetViewportOrgEx(HDC hdc
,
636 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
638 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
639 return MFDRV_SetViewportOrgEx();
642 PLDC pLDC
= GdiGetLDC(hdc
);
645 SetLastError(ERROR_INVALID_HANDLE
);
648 if (pLDC
->iType
== LDC_EMFLDC
)
650 return EMFDRV_SetViewportOrgEx();
655 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
659 lpPoint
->x
= Dc_Attr
->ptlViewportOrg
.x
;
660 lpPoint
->y
= Dc_Attr
->ptlViewportOrg
.y
;
661 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) lpPoint
->x
= -lpPoint
->x
;
663 Dc_Attr
->flXform
|= (PAGE_XLATE_CHANGED
|DEVICE_TO_WORLD_INVALID
);
664 if (Dc_Attr
->dwLayout
& LAYOUT_RTL
) X
= -X
;
665 Dc_Attr
->ptlViewportOrg
.x
= X
;
666 Dc_Attr
->ptlViewportOrg
.y
= Y
;
669 return NtGdiSetViewportOrgEx(hdc
,X
,Y
,lpPoint
);
687 if (GDI_HANDLE_GET_TYPE(a0
) != GDI_OBJECT_TYPE_DC
)
689 if (GDI_HANDLE_GET_TYPE(a0
) == GDI_OBJECT_TYPE_METADC
)
693 PLDC pLDC
= GdiGetLDC(a0
);
696 SetLastError(ERROR_INVALID_HANDLE
);
699 if (pLDC
->iType
== LDC_EMFLDC
)
706 if (!GdiIsHandleValid((HGDIOBJ
) a0
) ||
707 (GDI_HANDLE_GET_TYPE(a0
) != GDI_OBJECT_TYPE_DC
)) return FALSE
;
709 return NtGdiScaleViewportExtEx(a0
, a1
, a2
, a3
, a4
, a5
);
727 if (GDI_HANDLE_GET_TYPE(a0
) != GDI_OBJECT_TYPE_DC
)
729 if (GDI_HANDLE_GET_TYPE(a0
) == GDI_OBJECT_TYPE_METADC
)
733 PLDC pLDC
= GdiGetLDC(a0
);
736 SetLastError(ERROR_INVALID_HANDLE
);
739 if (pLDC
->iType
== LDC_EMFLDC
)
746 if (!GdiIsHandleValid((HGDIOBJ
) a0
) ||
747 (GDI_HANDLE_GET_TYPE(a0
) != GDI_OBJECT_TYPE_DC
)) return FALSE
;
749 return NtGdiScaleWindowExtEx(a0
, a1
, a2
, a3
, a4
, a5
);
761 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return GDI_ERROR
;
762 return Dc_Attr
->dwLayout
;
775 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
777 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
778 return MFDRV_SetLayout( hdc
, dwLayout
);
781 PLDC pLDC
= GdiGetLDC(hdc
);
784 SetLastError(ERROR_INVALID_HANDLE
);
787 if (pLDC
->iType
== LDC_EMFLDC
)
789 return EMFDRV_SetLayout( hdc
, dwLayout
);
794 if (!GdiIsHandleValid((HGDIOBJ
) hdc
) ||
795 (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)) return GDI_ERROR
;
796 return NtGdiSetLayout( hdc
, -1, dwLayout
);
804 SetLayoutWidth(HDC hdc
,LONG wox
,DWORD dwLayout
)
806 if (!GdiIsHandleValid((HGDIOBJ
) hdc
) ||
807 (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)) return GDI_ERROR
;
808 return NtGdiSetLayout( hdc
, wox
, dwLayout
);
820 return NtGdiGetDCPoint( hdc
, GdiGetDCOrg
, (PPOINTL
)lpPoint
);
832 // Officially obsolete by Microsoft
834 if (!GetDCOrgEx(hdc
, &Pt
))
836 return(MAKELONG(Pt
.x
, Pt
.y
));
846 OffsetViewportOrgEx(HDC hdc
,
854 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
856 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
857 return MFDRV_OffsetViewportOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
860 PLDC pLDC
= GdiGetLDC(hdc
);
863 SetLastError(ERROR_INVALID_HANDLE
);
866 if (pLDC
->iType
== LDC_EMFLDC
)
868 return EMFDRV_OffsetWindowOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
873 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
877 *lpPoint
= (POINT
)Dc_Attr
->ptlViewportOrg
;
878 if ( Dc_Attr
->dwLayout
& LAYOUT_RTL
) lpPoint
->x
= -lpPoint
->x
;
881 if ( nXOffset
|| nYOffset
!= nXOffset
)
883 if (NtCurrentTeb()->GdiTebBatch
.HDC
== (ULONG
)hdc
)
885 if (Dc_Attr
->ulDirty_
& DC_MODE_DIRTY
)
888 Dc_Attr
->ulDirty_
&= ~DC_MODE_DIRTY
;
891 Dc_Attr
->flXform
|= (PAGE_XLATE_CHANGED
|DEVICE_TO_WORLD_INVALID
);
892 if ( Dc_Attr
->dwLayout
& LAYOUT_RTL
) nXOffset
= -nXOffset
;
893 Dc_Attr
->ptlViewportOrg
.x
+= nXOffset
;
894 Dc_Attr
->ptlViewportOrg
.y
+= nYOffset
;
898 return NtGdiOffsetViewportOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
907 OffsetWindowOrgEx(HDC hdc
,
915 if (GDI_HANDLE_GET_TYPE(hdc
) != GDI_OBJECT_TYPE_DC
)
917 if (GDI_HANDLE_GET_TYPE(hdc
) == GDI_OBJECT_TYPE_METADC
)
918 return MFDRV_OffsetWindowOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
921 PLDC pLDC
= GdiGetLDC(hdc
);
924 SetLastError(ERROR_INVALID_HANDLE
);
927 if (pLDC
->iType
== LDC_EMFLDC
)
929 return EMFDRV_OffsetWindowOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);
934 if (!GdiGetHandleUserData((HGDIOBJ
) hdc
, GDI_OBJECT_TYPE_DC
, (PVOID
) &Dc_Attr
)) return FALSE
;
938 *lpPoint
= (POINT
)Dc_Attr
->ptlWindowOrg
;
939 lpPoint
->x
= Dc_Attr
->lWindowOrgx
;
942 if ( nXOffset
|| nYOffset
!= nXOffset
)
944 if (NtCurrentTeb()->GdiTebBatch
.HDC
== (ULONG
)hdc
)
946 if (Dc_Attr
->ulDirty_
& DC_MODE_DIRTY
)
949 Dc_Attr
->ulDirty_
&= ~DC_MODE_DIRTY
;
952 Dc_Attr
->flXform
|= (PAGE_XLATE_CHANGED
|DEVICE_TO_WORLD_INVALID
);
953 Dc_Attr
->ptlWindowOrg
.x
+= nXOffset
;
954 Dc_Attr
->ptlWindowOrg
.y
+= nYOffset
;
955 Dc_Attr
->lWindowOrgx
+= nXOffset
;
959 return NtGdiOffsetWindowOrgEx(hdc
, nXOffset
, nYOffset
, lpPoint
);