xref: /reactos/win32ss/gdi/ntgdi/coord.h (revision 405ce532)
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