1 #pragma once
2
3 /* Maximum extend of coordinate space */
4 #define MIN_COORD (INT_MIN / 16)
5 #define MAX_COORD (INT_MAX / 16)
6
7 /*
8 * Applies matrix (which is made of FLOATOBJs) to the points array, which are made of integers.
9 */
10 static
11 inline
12 BOOLEAN
INTERNAL_APPLY_MATRIX(PMATRIX matrix,LPPOINT points,UINT count)13 INTERNAL_APPLY_MATRIX(PMATRIX matrix, LPPOINT points, UINT count)
14 {
15 while (count--)
16 {
17 FLOATOBJ x, y;
18 FLOATOBJ tmp;
19
20 /* x = x * matrix->efM11 + y * matrix->efM21 + matrix->efDx; */
21 FLOATOBJ_SetLong(&x, points[count].x);
22 FLOATOBJ_Mul(&x, &matrix->efM11);
23 tmp = matrix->efM21;
24 FLOATOBJ_MulLong(&tmp, points[count].y);
25 FLOATOBJ_Add(&x, &tmp);
26 FLOATOBJ_Add(&x, &matrix->efDx);
27
28 /* y = x * matrix->efM12 + y * matrix->efM22 + matrix->efDy; */
29 FLOATOBJ_SetLong(&y, points[count].y);
30 FLOATOBJ_Mul(&y, &matrix->efM22);
31 tmp = matrix->efM12;
32 FLOATOBJ_MulLong(&tmp, points[count].x);
33 FLOATOBJ_Add(&y, &tmp);
34 FLOATOBJ_Add(&y, &matrix->efDy);
35
36 if (!FLOATOBJ_bConvertToLong(&x, &points[count].x))
37 return FALSE;
38 if (!FLOATOBJ_bConvertToLong(&y, &points[count].y))
39 return FALSE;
40 }
41 return TRUE;
42 }
43
44 static
45 inline
46 BOOLEAN
INTERNAL_LPTODP(DC * dc,LPPOINT points,UINT count)47 INTERNAL_LPTODP(DC *dc, LPPOINT points, UINT count)
48 {
49 return INTERNAL_APPLY_MATRIX(&dc->pdcattr->mxWorldToDevice, points, count);
50 }
51
52 static
53 inline
54 BOOLEAN
INTERNAL_DPTOLP(DC * dc,LPPOINT points,UINT count)55 INTERNAL_DPTOLP(DC *dc, LPPOINT points, UINT count)
56 {
57 return INTERNAL_APPLY_MATRIX(&dc->pdcattr->mxDeviceToWorld, points, count);
58 }
59
60 FORCEINLINE
61 void
XFormToMatrix(MATRIX * pmx,const XFORML * pxform)62 XFormToMatrix(
63 MATRIX *pmx,
64 const XFORML *pxform)
65 {
66 XFORMOBJ xo;
67 XFORMOBJ_vInit(&xo, pmx);
68 XFORMOBJ_iSetXform(&xo, pxform);
69 }
70
71 FORCEINLINE
72 void
MatrixToXForm(XFORML * pxform,const MATRIX * pmx)73 MatrixToXForm(
74 XFORML *pxform,
75 const MATRIX *pmx)
76 {
77 XFORMOBJ xo;
78 XFORMOBJ_vInit(&xo, (MATRIX*)pmx);
79 XFORMOBJ_iGetXform(&xo, pxform);
80 }
81
82 FORCEINLINE
83 void
InvertXform(XFORML * pxformDest,const XFORML * pxformSource)84 InvertXform(
85 XFORML *pxformDest,
86 const XFORML *pxformSource)
87 {
88 XFORMOBJ xo;
89 MATRIX mx;
90
91 XFORMOBJ_vInit(&xo, &mx);
92 XFORMOBJ_iSetXform(&xo, pxformSource);
93 XFORMOBJ_iInverse(&xo, &xo);
94 XFORMOBJ_iGetXform(&xo, pxformDest);
95 }
96
97 VOID
98 FASTCALL
99 DC_vFixIsotropicMapping(PDC pdc);
100
101 VOID
102 FASTCALL
103 DC_vUpdateWorldToDevice(PDC pdc);
104
105 VOID
106 FASTCALL
107 DC_vUpdateDeviceToWorld(PDC pdc);
108
109 FORCEINLINE
110 PSIZEL
DC_pszlViewportExt(PDC pdc)111 DC_pszlViewportExt(PDC pdc)
112 {
113 PDC_ATTR pdcattr = pdc->pdcattr;
114
115 /* Check if we need isotropic fixup */
116 if ((pdcattr->flXform & PAGE_EXTENTS_CHANGED) &&
117 (pdcattr->iMapMode == MM_ISOTROPIC))
118 {
119 /* Fixup viewport extension */
120 DC_vFixIsotropicMapping(pdc);
121 }
122
123 return &pdcattr->szlViewportExt;
124 }
125
126 FORCEINLINE
127 PMATRIX
DC_pmxWorldToPage(PDC pdc)128 DC_pmxWorldToPage(PDC pdc)
129 {
130 return &pdc->pdcattr->mxWorldToPage;
131 }
132
133 FORCEINLINE
134 PMATRIX
DC_pmxWorldToDevice(PDC pdc)135 DC_pmxWorldToDevice(PDC pdc)
136 {
137 /* Check if world or page xform was changed */
138 if (pdc->pdcattr->flXform & (PAGE_XLATE_CHANGED|PAGE_EXTENTS_CHANGED|WORLD_XFORM_CHANGED))
139 {
140 /* Update the world-to-device xform */
141 DC_vUpdateWorldToDevice(pdc);
142 }
143
144 return &pdc->pdcattr->mxWorldToDevice;
145 }
146
147 FORCEINLINE
148 PMATRIX
DC_pmxDeviceToWorld(PDC pdc)149 DC_pmxDeviceToWorld(PDC pdc)
150 {
151 /* Check if the device-to-world xform is invalid */
152 if (pdc->pdcattr->flXform & DEVICE_TO_WORLD_INVALID)
153 {
154 /* Update the world-to-device xform */
155 DC_vUpdateDeviceToWorld(pdc);
156 }
157
158 return &pdc->pdcattr->mxDeviceToWorld;
159 }
160
161 BOOL
162 NTAPI
163 GreModifyWorldTransform(
164 PDC pdc,
165 const XFORML *pXForm,
166 DWORD dwMode);
167
168 VOID FASTCALL IntMirrorWindowOrg(PDC);
169 int APIENTRY IntGdiSetMapMode(PDC, int);
170 BOOL FASTCALL GreLPtoDP(HDC, LPPOINT, INT);
171 BOOL FASTCALL GreDPtoLP(HDC, LPPOINT, INT);
172 BOOL APIENTRY GreGetDCPoint(HDC,UINT,PPOINTL);
173 BOOL WINAPI GreGetWindowExtEx( _In_ HDC hdc, _Out_ LPSIZE lpSize);
174 BOOL WINAPI GreGetViewportExtEx( _In_ HDC hdc, _Out_ LPSIZE lpSize);
175 BOOL FASTCALL GreSetViewportOrgEx(HDC,int,int,LPPOINT);
176 BOOL WINAPI GreGetDCOrgEx(_In_ HDC, _Out_ PPOINTL, _Out_ PRECTL);
177 BOOL WINAPI GreSetDCOrg(_In_ HDC, _In_ LONG, _In_ LONG, _In_opt_ PRECTL);
178
179 static
180 inline
181 BOOLEAN
IntLPtoDP(DC * pdc,PPOINTL ppt,UINT count)182 IntLPtoDP(DC* pdc, PPOINTL ppt, UINT count)
183 {
184 DC_vUpdateWorldToDevice(pdc);
185 return INTERNAL_LPTODP(pdc, (LPPOINT)ppt, count);
186 }
187 #define CoordLPtoDP(pdc, ppt) INTERNAL_LPTODP(pdc, ppt, 1)
188
189 static
190 inline
191 BOOLEAN
IntDPtoLP(DC * pdc,PPOINTL ppt,UINT count)192 IntDPtoLP(DC* pdc, PPOINTL ppt, UINT count)
193 {
194 DC_vUpdateDeviceToWorld(pdc);
195 return INTERNAL_DPTOLP(pdc, (LPPOINT)ppt, count);
196 }
197 #define CoordDPtoLP(pdc, ppt) INTERNAL_DPTOLP(pdc, ppt, 1)
198
199 #define XForm2MatrixS(m, x) XFormToMatrix(m, (XFORML*)x)
200 #define MatrixS2XForm(x, m) MatrixToXForm((XFORML*)x, m)
201