[FONT][WIN32SS] Refactor the loop (4 of 5)
[reactos.git] / win32ss / gdi / ntgdi / gdifloat.h
1 #pragma once
2
3 #ifdef _MSC_VER
4 #pragma warning(push)
5 #pragma warning(disable:28110) // disable "Drivers must protect floating point hardware state" warning
6 #endif
7
8 typedef struct tagFLOAT_POINT
9 {
10 FLOAT x, y;
11 } FLOAT_POINT;
12
13 /* Rounds a floating point number to integer. The world-to-viewport
14 * transformation process is done in floating point internally. This function
15 * is then used to round these coordinates to integer values.
16 */
17 static __inline INT GDI_ROUND(FLOAT val)
18 {
19 return (int)floor(val + 0.5);
20 }
21
22
23 /* FIXME: Do not use the fpu in kernel on x86, use FLOATOBJ_Xxx api instead
24 * Performs a world-to-viewport transformation on the specified point (which
25 * is in floating point format).
26 */
27 static __inline void INTERNAL_LPTODP_FLOAT(DC *dc, FLOAT_POINT *point)
28 {
29 FLOAT x, y;
30 XFORM xformWorld2Vport;
31
32 MatrixS2XForm(&xformWorld2Vport, &dc->pdcattr->mxWorldToDevice);
33
34 /* Perform the transformation */
35 x = point->x;
36 y = point->y;
37 point->x = x * xformWorld2Vport.eM11 +
38 y * xformWorld2Vport.eM21 +
39 xformWorld2Vport.eDx;
40
41 point->y = x * xformWorld2Vport.eM12 +
42 y * xformWorld2Vport.eM22 +
43 xformWorld2Vport.eDy;
44 }
45
46 /* Performs a viewport-to-world transformation on the specified point (which
47 * is in integer format). Returns TRUE if successful, else FALSE.
48 */
49 #if 0
50 static __inline BOOL INTERNAL_DPTOLP(DC *dc, LPPOINT point)
51 {
52 FLOAT_POINT floatPoint;
53
54 /* Perform operation with floating point */
55 floatPoint.x=(FLOAT)point->x;
56 floatPoint.y=(FLOAT)point->y;
57 if (!INTERNAL_DPTOLP_FLOAT(dc, &floatPoint))
58 return FALSE;
59
60 /* Round to integers */
61 point->x = GDI_ROUND(floatPoint.x);
62 point->y = GDI_ROUND(floatPoint.y);
63
64 return TRUE;
65 }
66
67 /* Performs a world-to-viewport transformation on the specified point (which
68 * is in integer format).
69 */
70 static __inline void INTERNAL_LPTODP(DC *dc, LPPOINT point)
71 {
72 FLOAT_POINT floatPoint;
73
74 /* Perform operation with floating point */
75 floatPoint.x=(FLOAT)point->x;
76 floatPoint.y=(FLOAT)point->y;
77 INTERNAL_LPTODP_FLOAT(dc, &floatPoint);
78
79 /* Round to integers */
80 point->x = GDI_ROUND(floatPoint.x);
81 point->y = GDI_ROUND(floatPoint.y);
82 }
83
84 #endif
85
86 #define MulDiv( x, y, z ) EngMulDiv( x, y, z )
87
88 #define XDPTOLP(pdcattr,tx) \
89 (MulDiv(((tx)-(pdcattr)->ptlViewportOrg.x), (pdcattr)->szlWindowExt.cx, (pdcattr)->szlViewportExt.cx) + (pdcattr)->ptlWindowOrg.x)
90 #define YDPTOLP(pdcattr,ty) \
91 (MulDiv(((ty)-(pdcattr)->ptlViewportOrg.y), (pdcattr)->szlWindowExt.cy, (pdcattr)->szlViewportExt.cy) + (pdcattr)->ptlWindowOrg.y)
92 #define XLPTODP(pdcattr,tx) \
93 (MulDiv(((tx)-(pdcattr)->ptlWindowOrg.x), (pdcattr)->szlViewportExt.cx, (pdcattr)->szlWindowExt.cx) + (pdcattr)->ptlViewportOrg.x)
94 #define YLPTODP(pdcattr,ty) \
95 (MulDiv(((ty)-(pdcattr)->ptlWindowOrg.y), (pdcattr)->szlViewportExt.cy, (pdcattr)->szlWindowExt.cy) + (pdcattr)->ptlViewportOrg.y)
96
97 /* Device <-> logical size conversion */
98
99 #define XDSTOLS(pdcattr,tx) \
100 MulDiv((tx), (pdcattr)->szlWindowExt.cx, (pdcattr)->szlViewportExt.cx)
101 #define YDSTOLS(DC_Attr,ty) \
102 MulDiv((ty), (pdcattr)->szlWindowExt.cy, (pdcattr)->szlViewportExt.cy)
103 #define XLSTODS(pdcattr,tx) \
104 MulDiv((tx), (pdcattr)->szlViewportExt.cx, (pdcattr)->szlWindowExt.cx)
105 #define YLSTODS(pdcattr,ty) \
106 MulDiv((ty), (pdcattr)->szlViewportExt.cy, (pdcattr)->szlWindowExt.cy)
107
108 #ifdef _MSC_VER
109 #pragma warning(pop)
110 #endif