2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: Coordinate systems
24 * FILE: subsys/win32k/objects/coord.c
28 /* INCLUDES ******************************************************************/
35 /* FUNCTIONS *****************************************************************/
38 IntFixIsotropicMapping(PDC dc
)
43 /* Get a pointer to the DC_ATTR */
44 pdcattr
= dc
->pdcattr
;
46 /* Check if all values are valid */
47 if (pdcattr
->szlWindowExt
.cx
== 0 || pdcattr
->szlWindowExt
.cy
== 0 ||
48 pdcattr
->szlViewportExt
.cx
== 0 || pdcattr
->szlViewportExt
.cy
== 0)
50 /* Don't recalculate */
54 fx
= abs(pdcattr
->szlWindowExt
.cx
* pdcattr
->szlViewportExt
.cy
);
55 fy
= abs(pdcattr
->szlWindowExt
.cy
* pdcattr
->szlViewportExt
.cx
);
59 s
= pdcattr
->szlWindowExt
.cy
* pdcattr
->szlViewportExt
.cx
> 0 ? 1 : -1;
60 pdcattr
->szlViewportExt
.cx
= s
* fx
/ pdcattr
->szlWindowExt
.cy
;
64 s
= pdcattr
->szlWindowExt
.cx
* pdcattr
->szlViewportExt
.cy
> 0 ? 1 : -1;
65 pdcattr
->szlViewportExt
.cy
= s
* fy
/ pdcattr
->szlWindowExt
.cx
;
69 // FIXME: don't use floating point in the kernel! use XFORMOBJ function
71 IntGdiCombineTransform(
77 /* Check for illegal parameters */
78 if (!XFormResult
|| !xform1
|| !xform2
)
83 /* Create the result in a temporary XFORM, since xformResult may be
84 * equal to xform1 or xform2 */
85 xformTemp
.eM11
= xform1
->eM11
* xform2
->eM11
+ xform1
->eM12
* xform2
->eM21
;
86 xformTemp
.eM12
= xform1
->eM11
* xform2
->eM12
+ xform1
->eM12
* xform2
->eM22
;
87 xformTemp
.eM21
= xform1
->eM21
* xform2
->eM11
+ xform1
->eM22
* xform2
->eM21
;
88 xformTemp
.eM22
= xform1
->eM21
* xform2
->eM12
+ xform1
->eM22
* xform2
->eM22
;
89 xformTemp
.eDx
= xform1
->eDx
* xform2
->eM11
+ xform1
->eDy
* xform2
->eM21
+ xform2
->eDx
;
90 xformTemp
.eDy
= xform1
->eDx
* xform2
->eM12
+ xform1
->eDy
* xform2
->eM22
+ xform2
->eDy
;
91 *XFormResult
= xformTemp
;
96 // FIXME: should be XFORML and use XFORMOBJ functions
97 BOOL APIENTRY
NtGdiCombineTransform(
98 LPXFORM UnsafeXFormResult
,
100 LPXFORM Unsafexform2
)
106 ProbeForWrite(UnsafeXFormResult
, sizeof(XFORM
), 1);
107 ProbeForRead(Unsafexform1
, sizeof(XFORM
), 1);
108 ProbeForRead(Unsafexform2
, sizeof(XFORM
), 1);
109 Ret
= IntGdiCombineTransform(UnsafeXFormResult
,
113 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
122 // FIXME: Don't use floating point in the kernel
125 IntGdiModifyWorldTransform(
127 CONST LPXFORM lpXForm
,
130 XFORM xformWorld2Wnd
;
136 xformWorld2Wnd
.eM11
= 1.0f
;
137 xformWorld2Wnd
.eM12
= 0.0f
;
138 xformWorld2Wnd
.eM21
= 0.0f
;
139 xformWorld2Wnd
.eM22
= 1.0f
;
140 xformWorld2Wnd
.eDx
= 0.0f
;
141 xformWorld2Wnd
.eDy
= 0.0f
;
142 XForm2MatrixS(&pDc
->dclevel
.mxWorldToPage
, &xformWorld2Wnd
);
145 case MWT_LEFTMULTIPLY
:
146 MatrixS2XForm(&xformWorld2Wnd
, &pDc
->dclevel
.mxWorldToPage
);
147 IntGdiCombineTransform(&xformWorld2Wnd
, lpXForm
, &xformWorld2Wnd
);
148 XForm2MatrixS(&pDc
->dclevel
.mxWorldToPage
, &xformWorld2Wnd
);
151 case MWT_RIGHTMULTIPLY
:
152 MatrixS2XForm(&xformWorld2Wnd
, &pDc
->dclevel
.mxWorldToPage
);
153 IntGdiCombineTransform(&xformWorld2Wnd
, &xformWorld2Wnd
, lpXForm
);
154 XForm2MatrixS(&pDc
->dclevel
.mxWorldToPage
, &xformWorld2Wnd
);
157 case MWT_MAX
+1: // Must be MWT_SET????
158 XForm2MatrixS(&pDc
->dclevel
.mxWorldToPage
, lpXForm
); // Do it like Wine.
164 DC_UpdateXforms(pDc
);
168 // FIXME: Should be XFORML and use XFORMOBJ functions directly
177 NTSTATUS Status
= STATUS_SUCCESS
;
182 SetLastWin32Error(ERROR_INVALID_HANDLE
);
188 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
194 ProbeForWrite(XForm
, sizeof(XFORM
), 1);
197 case GdiWorldSpaceToPageSpace
:
198 MatrixS2XForm(XForm
, &dc
->dclevel
.mxWorldToPage
);
201 case GdiWorldSpaceToDeviceSpace
:
202 MatrixS2XForm(XForm
, &dc
->dclevel
.mxWorldToDevice
);
205 case GdiPageSpaceToDeviceSpace
:
206 DPRINT1("Page space -> device space is unsupported!\n");
209 case GdiDeviceSpaceToWorldSpace
:
210 MatrixS2XForm(XForm
, &dc
->dclevel
.mxDeviceToWorld
);
214 DPRINT1("Unknown transform %lu\n", iXform
);
215 Status
= STATUS_INVALID_PARAMETER
;
219 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
221 Status
= _SEH2_GetExceptionCode();
226 return NT_SUCCESS(Status
);
231 * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
232 * world transfrom, viewport origin settings for the given device context.
233 * \param hDC device context.
234 * \param Points an array of POINT structures (in/out).
235 * \param Count number of elements in the array of POINT structures.
236 * \return TRUE if success.
240 NtGdiTransformPoints(
248 NTSTATUS Status
= STATUS_SUCCESS
;
255 SetLastWin32Error(ERROR_INVALID_HANDLE
);
259 if (!UnsafePtsIn
|| !UnsafePtOut
|| Count
<= 0)
262 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
266 Size
= Count
* sizeof(POINT
);
268 // FIXME: It would be wise to have a small stack buffer as optimization
269 Points
= ExAllocatePoolWithTag(PagedPool
, Size
, TAG_COORD
);
273 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
279 ProbeForWrite(UnsafePtOut
, Size
, 1);
280 ProbeForRead(UnsafePtsIn
, Size
, 1);
281 RtlCopyMemory(Points
, UnsafePtsIn
, Size
);
283 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
285 Status
= _SEH2_GetExceptionCode();
289 if (!NT_SUCCESS(Status
))
292 ExFreePoolWithTag(Points
, TAG_COORD
);
293 SetLastNtError(Status
);
300 IntDPtoLP(dc
, Points
, Count
);
304 IntLPtoDP(dc
, Points
, Count
);
307 case 2: // Not supported yet. Need testing.
311 ExFreePoolWithTag(Points
, TAG_COORD
);
312 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
319 /* pointer was already probed! */
320 RtlCopyMemory(UnsafePtOut
, Points
, Size
);
322 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
324 Status
= _SEH2_GetExceptionCode();
328 if (!NT_SUCCESS(Status
))
331 ExFreePoolWithTag(Points
, TAG_COORD
);
332 SetLastNtError(Status
);
336 // If we are getting called that means User XForms is a mess!
339 ExFreePoolWithTag(Points
, TAG_COORD
);
345 NtGdiModifyWorldTransform(
357 SetLastWin32Error(ERROR_INVALID_HANDLE
);
361 // The xform is permitted to be NULL for MWT_IDENTITY.
362 // However, if it is not NULL, then it must be valid even though it is not used.
363 if (UnsafeXForm
!= NULL
|| Mode
!= MWT_IDENTITY
)
367 ProbeForRead(UnsafeXForm
, sizeof(XFORM
), 1);
368 RtlCopyMemory(&SafeXForm
, UnsafeXForm
, sizeof(XFORM
));
370 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
377 // Safe to handle kernel mode data.
378 if (Ret
) Ret
= IntGdiModifyWorldTransform(dc
, &SafeXForm
, Mode
);
385 NtGdiOffsetViewportOrgEx(
393 NTSTATUS Status
= STATUS_SUCCESS
;
398 SetLastWin32Error(ERROR_INVALID_HANDLE
);
401 pdcattr
= dc
->pdcattr
;
407 ProbeForWrite(UnsafePoint
, sizeof(POINT
), 1);
408 UnsafePoint
->x
= pdcattr
->ptlViewportOrg
.x
;
409 UnsafePoint
->y
= pdcattr
->ptlViewportOrg
.y
;
410 if (pdcattr
->dwLayout
& LAYOUT_RTL
)
412 UnsafePoint
->x
= -UnsafePoint
->x
;
415 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
417 Status
= _SEH2_GetExceptionCode();
421 if (!NT_SUCCESS(Status
))
423 SetLastNtError(Status
);
429 if (pdcattr
->dwLayout
& LAYOUT_RTL
)
433 pdcattr
->ptlViewportOrg
.x
+= XOffset
;
434 pdcattr
->ptlViewportOrg
.y
+= YOffset
;
443 NtGdiOffsetWindowOrgEx(
455 SetLastWin32Error(ERROR_INVALID_HANDLE
);
458 pdcattr
= dc
->pdcattr
;
462 NTSTATUS Status
= STATUS_SUCCESS
;
466 ProbeForWrite(Point
, sizeof(POINT
), 1);
467 Point
->x
= pdcattr
->ptlWindowOrg
.x
;
468 Point
->y
= pdcattr
->ptlWindowOrg
.y
;
470 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
472 Status
= _SEH2_GetExceptionCode();
476 if (!NT_SUCCESS(Status
))
478 SetLastNtError(Status
);
484 pdcattr
->ptlWindowOrg
.x
+= XOffset
;
485 pdcattr
->ptlWindowOrg
.y
+= YOffset
;
495 NtGdiScaleViewportExtEx(
508 pDC
= DC_LockDc(hDC
);
511 SetLastWin32Error(ERROR_INVALID_HANDLE
);
514 pdcattr
= pDC
->pdcattr
;
518 NTSTATUS Status
= STATUS_SUCCESS
;
522 ProbeForWrite(pSize
, sizeof(LPSIZE
), 1);
524 pSize
->cx
= pdcattr
->szlViewportExt
.cx
;
525 pSize
->cy
= pdcattr
->szlViewportExt
.cy
;
527 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
529 Status
= _SEH2_GetExceptionCode();
533 if (!NT_SUCCESS(Status
))
535 SetLastNtError(Status
);
541 if (pdcattr
->iMapMode
> MM_TWIPS
)
543 if (Xdenom
&& Ydenom
)
545 X
= Xnum
* pdcattr
->szlViewportExt
.cx
/ Xdenom
;
548 Y
= Ynum
* pdcattr
->szlViewportExt
.cy
/ Ydenom
;
551 pdcattr
->szlViewportExt
.cx
= X
;
552 pdcattr
->szlViewportExt
.cy
= Y
;
554 IntMirrorWindowOrg(pDC
);
556 pdcattr
->flXform
|= (PAGE_EXTENTS_CHANGED
|
557 INVALIDATE_ATTRIBUTES
|
558 DEVICE_TO_WORLD_INVALID
);
560 if (pdcattr
->iMapMode
== MM_ISOTROPIC
)
562 IntFixIsotropicMapping(pDC
);
564 DC_UpdateXforms(pDC
);
580 NtGdiScaleWindowExtEx(
593 pDC
= DC_LockDc(hDC
);
596 SetLastWin32Error(ERROR_INVALID_HANDLE
);
599 pdcattr
= pDC
->pdcattr
;
603 NTSTATUS Status
= STATUS_SUCCESS
;
607 ProbeForWrite(pSize
, sizeof(LPSIZE
), 1);
609 X
= pdcattr
->szlWindowExt
.cx
;
610 if (pdcattr
->dwLayout
& LAYOUT_RTL
) X
= -X
;
612 pSize
->cy
= pdcattr
->szlWindowExt
.cy
;
614 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
616 Status
= _SEH2_GetExceptionCode();
620 if (!NT_SUCCESS(Status
))
622 SetLastNtError(Status
);
628 if (pdcattr
->iMapMode
> MM_TWIPS
)
630 if (Xdenom
&& Ydenom
)
632 X
= Xnum
* pdcattr
->szlWindowExt
.cx
/ Xdenom
;
635 Y
= Ynum
* pdcattr
->szlWindowExt
.cy
/ Ydenom
;
638 pdcattr
->szlWindowExt
.cx
= X
;
639 pdcattr
->szlWindowExt
.cy
= Y
;
641 IntMirrorWindowOrg(pDC
);
643 pdcattr
->flXform
|= (PAGE_EXTENTS_CHANGED
|INVALIDATE_ATTRIBUTES
|DEVICE_TO_WORLD_INVALID
);
645 if (pdcattr
->iMapMode
== MM_ISOTROPIC
) IntFixIsotropicMapping(pDC
);
646 DC_UpdateXforms(pDC
);
667 PDC_ATTR pdcattr
= dc
->pdcattr
;
669 PrevMapMode
= pdcattr
->iMapMode
;
671 pdcattr
->iMapMode
= MapMode
;
676 pdcattr
->szlWindowExt
.cx
= 1;
677 pdcattr
->szlWindowExt
.cy
= 1;
678 pdcattr
->szlViewportExt
.cx
= 1;
679 pdcattr
->szlViewportExt
.cy
= 1;
680 pdcattr
->flXform
&= ~(ISO_OR_ANISO_MAP_MODE
|PTOD_EFM22_NEGATIVE
|
681 PTOD_EFM11_NEGATIVE
|POSITIVE_Y_IS_UP
);
682 pdcattr
->flXform
|= (PAGE_XLATE_CHANGED
|PAGE_TO_DEVICE_SCALE_IDENTITY
|
683 INVALIDATE_ATTRIBUTES
|DEVICE_TO_WORLD_INVALID
);
687 pdcattr
->flXform
|= ISO_OR_ANISO_MAP_MODE
;
691 pdcattr
->szlWindowExt
.cx
= dc
->ppdev
->gdiinfo
.ulHorzSize
* 10;
692 pdcattr
->szlWindowExt
.cy
= dc
->ppdev
->gdiinfo
.ulVertSize
* 10;
693 pdcattr
->szlViewportExt
.cx
= dc
->ppdev
->gdiinfo
.ulHorzRes
;
694 pdcattr
->szlViewportExt
.cy
= -dc
->ppdev
->gdiinfo
.ulVertRes
;
698 pdcattr
->szlWindowExt
.cx
= dc
->ppdev
->gdiinfo
.ulHorzSize
* 100;
699 pdcattr
->szlWindowExt
.cy
= dc
->ppdev
->gdiinfo
.ulVertSize
* 100;
700 pdcattr
->szlViewportExt
.cx
= dc
->ppdev
->gdiinfo
.ulHorzRes
;
701 pdcattr
->szlViewportExt
.cy
= -dc
->ppdev
->gdiinfo
.ulVertRes
;
705 pdcattr
->szlWindowExt
.cx
= MulDiv(1000, dc
->ppdev
->gdiinfo
.ulHorzSize
, 254);
706 pdcattr
->szlWindowExt
.cy
= MulDiv(1000, dc
->ppdev
->gdiinfo
.ulVertSize
, 254);
707 pdcattr
->szlViewportExt
.cx
= dc
->ppdev
->gdiinfo
.ulHorzRes
;
708 pdcattr
->szlViewportExt
.cy
= -dc
->ppdev
->gdiinfo
.ulVertRes
;
712 pdcattr
->szlWindowExt
.cx
= MulDiv(10000, dc
->ppdev
->gdiinfo
.ulHorzSize
, 254);
713 pdcattr
->szlWindowExt
.cy
= MulDiv(10000, dc
->ppdev
->gdiinfo
.ulVertSize
, 254);
714 pdcattr
->szlViewportExt
.cx
= dc
->ppdev
->gdiinfo
.ulHorzRes
;
715 pdcattr
->szlViewportExt
.cy
= -dc
->ppdev
->gdiinfo
.ulVertRes
;
719 pdcattr
->szlWindowExt
.cx
= MulDiv(14400, dc
->ppdev
->gdiinfo
.ulHorzSize
, 254);
720 pdcattr
->szlWindowExt
.cy
= MulDiv(14400, dc
->ppdev
->gdiinfo
.ulVertSize
, 254);
721 pdcattr
->szlViewportExt
.cx
= dc
->ppdev
->gdiinfo
.ulHorzRes
;
722 pdcattr
->szlViewportExt
.cy
= -dc
->ppdev
->gdiinfo
.ulVertRes
;
726 pdcattr
->flXform
&= ~(PAGE_TO_DEVICE_IDENTITY
|POSITIVE_Y_IS_UP
);
727 pdcattr
->flXform
|= ISO_OR_ANISO_MAP_MODE
;
731 pdcattr
->iMapMode
= PrevMapMode
;
742 NtGdiSetViewportOrgEx(
754 SetLastWin32Error(ERROR_INVALID_HANDLE
);
757 pdcattr
= dc
->pdcattr
;
761 NTSTATUS Status
= STATUS_SUCCESS
;
765 ProbeForWrite(Point
, sizeof(POINT
), 1);
766 Point
->x
= pdcattr
->ptlViewportOrg
.x
;
767 Point
->y
= pdcattr
->ptlViewportOrg
.y
;
769 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
771 Status
= _SEH2_GetExceptionCode();
775 if (!NT_SUCCESS(Status
))
777 SetLastNtError(Status
);
783 pdcattr
->ptlViewportOrg
.x
= X
;
784 pdcattr
->ptlViewportOrg
.y
= Y
;
806 SetLastWin32Error(ERROR_INVALID_HANDLE
);
809 pdcattr
= dc
->pdcattr
;
813 NTSTATUS Status
= STATUS_SUCCESS
;
817 ProbeForWrite(Point
, sizeof(POINT
), 1);
818 Point
->x
= pdcattr
->ptlWindowOrg
.x
;
819 Point
->y
= pdcattr
->ptlWindowOrg
.y
;
821 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
823 Status
= _SEH2_GetExceptionCode();
827 if (!NT_SUCCESS(Status
))
829 SetLastNtError(Status
);
835 pdcattr
->ptlWindowOrg
.x
= X
;
836 pdcattr
->ptlWindowOrg
.y
= Y
;
845 // Mirror Window function.
849 IntMirrorWindowOrg(PDC dc
)
854 pdcattr
= dc
->pdcattr
;
856 if (!(pdcattr
->dwLayout
& LAYOUT_RTL
))
858 pdcattr
->ptlWindowOrg
.x
= pdcattr
->lWindowOrgx
; // Flip it back.
861 if (!pdcattr
->szlViewportExt
.cx
) return;
863 // WOrgx = wox - (Width - 1) * WExtx / VExtx
865 X
= (dc
->erclWindow
.right
- dc
->erclWindow
.left
) - 1; // Get device width - 1
867 X
= (X
* pdcattr
->szlWindowExt
.cx
) / pdcattr
->szlViewportExt
.cx
;
869 pdcattr
->ptlWindowOrg
.x
= pdcattr
->lWindowOrgx
- X
; // Now set the inverted win origion.
876 // The default is left to right. This function changes it to right to left, which
877 // is the standard in Arabic and Hebrew cultures.
896 SetLastWin32Error(ERROR_INVALID_HANDLE
);
899 pdcattr
= dc
->pdcattr
;
901 pdcattr
->dwLayout
= dwLayout
;
902 oLayout
= pdcattr
->dwLayout
;
904 if (!(dwLayout
& LAYOUT_ORIENTATIONMASK
))
910 if (dwLayout
& LAYOUT_RTL
)
912 pdcattr
->iMapMode
= MM_ANISOTROPIC
;
915 pdcattr
->szlWindowExt
.cy
= -pdcattr
->szlWindowExt
.cy
;
916 pdcattr
->ptlWindowOrg
.x
= -pdcattr
->ptlWindowOrg
.x
;
919 IntMirrorWindowOrg(dc
);
921 pdcattr
->ptlWindowOrg
.x
= wox
- pdcattr
->ptlWindowOrg
.x
;
923 if (!(pdcattr
->flTextAlign
& TA_CENTER
)) pdcattr
->flTextAlign
|= TA_RIGHT
;
925 if (dc
->dclevel
.flPath
& DCPATH_CLOCKWISE
)
926 dc
->dclevel
.flPath
&= ~DCPATH_CLOCKWISE
;
928 dc
->dclevel
.flPath
|= DCPATH_CLOCKWISE
;
930 pdcattr
->flXform
|= (PAGE_EXTENTS_CHANGED
|
931 INVALIDATE_ATTRIBUTES
|
932 DEVICE_TO_WORLD_INVALID
);
934 // DC_UpdateXforms(dc);
952 SetLastWin32Error(ERROR_INVALID_HANDLE
);
955 Ret
= dc
->erclWindow
.right
- dc
->erclWindow
.left
;
965 NtGdiMirrorWindowOrg(
972 SetLastWin32Error(ERROR_INVALID_HANDLE
);
975 IntMirrorWindowOrg(dc
);
987 IN INT cxVirtualDevice
,
988 IN INT cyVirtualDevice
)
993 if (!cxVirtualDevice
|| !cyVirtualDevice
)
999 if (!dc
) return FALSE
;
1001 pdcattr
= dc
->pdcattr
;
1003 pdcattr
->szlVirtualDeviceSize
.cx
= cxVirtualDevice
;
1004 pdcattr
->szlVirtualDeviceSize
.cy
= cyVirtualDevice
;
1006 // DC_UpdateXforms(dc);
1017 NtGdiSetVirtualResolution(
1019 IN INT cxVirtualDevicePixel
,
1020 IN INT cyVirtualDevicePixel
,
1021 IN INT cxVirtualDeviceMm
,
1022 IN INT cyVirtualDeviceMm
)
1027 // Need test types for zeros and non zeros
1029 dc
= DC_LockDc(hdc
);
1030 if (!dc
) return FALSE
;
1032 pdcattr
= dc
->pdcattr
;
1034 pdcattr
->szlVirtualDevicePixel
.cx
= cxVirtualDevicePixel
;
1035 pdcattr
->szlVirtualDevicePixel
.cy
= cyVirtualDevicePixel
;
1036 pdcattr
->szlVirtualDeviceMm
.cx
= cxVirtualDeviceMm
;
1037 pdcattr
->szlVirtualDeviceMm
.cy
= cyVirtualDeviceMm
;
1039 // DC_UpdateXforms(dc);
1045 // FIXME: Don't use floating point in the kernel!
1047 DC_InvertXform(const XFORM
*xformSrc
,
1052 determinant
= xformSrc
->eM11
*xformSrc
->eM22
- xformSrc
->eM12
*xformSrc
->eM21
;
1053 if (determinant
> -1e-12 && determinant
< 1e-12)
1058 xformDest
->eM11
= xformSrc
->eM22
/ determinant
;
1059 xformDest
->eM12
= -xformSrc
->eM12
/ determinant
;
1060 xformDest
->eM21
= -xformSrc
->eM21
/ determinant
;
1061 xformDest
->eM22
= xformSrc
->eM11
/ determinant
;
1062 xformDest
->eDx
= -xformSrc
->eDx
* xformDest
->eM11
- xformSrc
->eDy
* xformDest
->eM21
;
1063 xformDest
->eDy
= -xformSrc
->eDx
* xformDest
->eM12
- xformSrc
->eDy
* xformDest
->eM22
;
1069 // FIXME: Don't use floating point in the kernel!
1071 DC_UpdateXforms(PDC dc
)
1073 XFORM xformWnd2Vport
;
1074 FLOAT scaleX
, scaleY
;
1075 PDC_ATTR pdcattr
= dc
->pdcattr
;
1076 XFORM xformWorld2Vport
, xformWorld2Wnd
, xformVport2World
;
1078 /* Construct a transformation to do the window-to-viewport conversion */
1079 scaleX
= (pdcattr
->szlWindowExt
.cx
? (FLOAT
)pdcattr
->szlViewportExt
.cx
/ (FLOAT
)pdcattr
->szlWindowExt
.cx
: 0.0f
);
1080 scaleY
= (pdcattr
->szlWindowExt
.cy
? (FLOAT
)pdcattr
->szlViewportExt
.cy
/ (FLOAT
)pdcattr
->szlWindowExt
.cy
: 0.0f
);
1081 xformWnd2Vport
.eM11
= scaleX
;
1082 xformWnd2Vport
.eM12
= 0.0;
1083 xformWnd2Vport
.eM21
= 0.0;
1084 xformWnd2Vport
.eM22
= scaleY
;
1085 xformWnd2Vport
.eDx
= (FLOAT
)pdcattr
->ptlViewportOrg
.x
- scaleX
* (FLOAT
)pdcattr
->ptlWindowOrg
.x
;
1086 xformWnd2Vport
.eDy
= (FLOAT
)pdcattr
->ptlViewportOrg
.y
- scaleY
* (FLOAT
)pdcattr
->ptlWindowOrg
.y
;
1088 /* Combine with the world transformation */
1089 MatrixS2XForm(&xformWorld2Vport
, &dc
->dclevel
.mxWorldToDevice
);
1090 MatrixS2XForm(&xformWorld2Wnd
, &dc
->dclevel
.mxWorldToPage
);
1091 IntGdiCombineTransform(&xformWorld2Vport
, &xformWorld2Wnd
, &xformWnd2Vport
);
1093 /* Create inverse of world-to-viewport transformation */
1094 MatrixS2XForm(&xformVport2World
, &dc
->dclevel
.mxDeviceToWorld
);
1095 if (DC_InvertXform(&xformWorld2Vport
, &xformVport2World
))
1097 pdcattr
->flXform
&= ~DEVICE_TO_WORLD_INVALID
;
1101 pdcattr
->flXform
|= DEVICE_TO_WORLD_INVALID
;
1104 XForm2MatrixS(&dc
->dclevel
.mxWorldToDevice
, &xformWorld2Vport
);
1109 IntCalcFillOrigin(PDC pdc
)
1111 pdc
->ptlFillOrigin
.x
= pdc
->dclevel
.ptlBrushOrigin
.x
+ pdc
->ptlDCOrig
.x
;
1112 pdc
->ptlFillOrigin
.y
= pdc
->dclevel
.ptlBrushOrigin
.y
+ pdc
->ptlDCOrig
.y
;
1114 return pdc
->ptlFillOrigin
.y
;
1119 GdiSetDCOrg(HDC hDC
, LONG Left
, LONG Top
, PRECTL prc
)
1123 pdc
= DC_LockDc(hDC
);
1126 pdc
->ptlDCOrig
.x
= Left
;
1127 pdc
->ptlDCOrig
.y
= Top
;
1129 IntCalcFillOrigin(pdc
);
1131 if (prc
) pdc
->erclWindow
= *prc
;
1138 IntGdiGetDCOrg(PDC pDc
, PPOINTL ppt
)
1140 *ppt
= pDc
->ptlDCOrig
;
1146 GdiGetDCOrgEx(HDC hDC
, PPOINTL ppt
, PRECTL prc
)
1150 pdc
= DC_LockDc(hDC
);
1151 if (!pdc
) return FALSE
;
1153 *prc
= pdc
->erclWindow
;
1154 *ppt
= pdc
->ptlDCOrig
;
1162 DC_vGetAspectRatioFilter(PDC pDC
, LPSIZE AspectRatio
)
1164 if (pDC
->pdcattr
->flFontMapper
& 1) // TRUE assume 1.
1166 // "This specifies that Windows should only match fonts that have the
1167 // same aspect ratio as the display.", Programming Windows, Fifth Ed.
1168 AspectRatio
->cx
= pDC
->ppdev
->gdiinfo
.ulLogPixelsX
;
1169 AspectRatio
->cy
= pDC
->ppdev
->gdiinfo
.ulLogPixelsY
;
1173 AspectRatio
->cx
= 0;
1174 AspectRatio
->cy
= 0;
1180 DC_vUpdateViewportExt(PDC pdc
)
1184 /* Get a pointer to the dc attribute */
1185 pdcattr
= pdc
->pdcattr
;
1187 /* Check if we need to recalculate */
1188 if (pdcattr
->flXform
& PAGE_EXTENTS_CHANGED
)
1190 /* Check if we need to do isotropic fixup */
1191 if (pdcattr
->iMapMode
== MM_ISOTROPIC
)
1193 IntFixIsotropicMapping(pdc
);
1196 /* Update xforms, CHECKME: really done here? */
1197 DC_UpdateXforms(pdc
);
1211 NTSTATUS Status
= STATUS_SUCCESS
;
1215 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1219 pdc
= DC_LockDc(hDC
);
1222 SetLastWin32Error(ERROR_INVALID_HANDLE
);
1228 case GdiGetViewPortExt
:
1229 DC_vUpdateViewportExt(pdc
);
1230 SafePoint
.x
= pdc
->pdcattr
->szlViewportExt
.cx
;
1231 SafePoint
.y
= pdc
->pdcattr
->szlViewportExt
.cy
;
1234 case GdiGetWindowExt
:
1235 SafePoint
.x
= pdc
->pdcattr
->szlWindowExt
.cx
;
1236 SafePoint
.y
= pdc
->pdcattr
->szlWindowExt
.cy
;
1239 case GdiGetViewPortOrg
:
1240 SafePoint
= pdc
->pdcattr
->ptlViewportOrg
;
1243 case GdiGetWindowOrg
:
1244 SafePoint
= pdc
->pdcattr
->ptlWindowOrg
;
1248 SafePoint
= pdc
->ptlDCOrig
;
1251 case GdiGetAspectRatioFilter
:
1252 DC_vGetAspectRatioFilter(pdc
, &Size
);
1253 SafePoint
.x
= Size
.cx
;
1254 SafePoint
.y
= Size
.cy
;
1258 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1267 ProbeForWrite(Point
, sizeof(POINT
), 1);
1270 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1272 Status
= _SEH2_GetExceptionCode();
1276 if (!NT_SUCCESS(Status
))
1278 SetLastNtError(Status
);
1296 return DCB_RESET
; /* bounding rectangle always empty */
1307 return DCB_DISABLE
; /* bounding rectangle always empty */