xref: /reactos/win32ss/gdi/eng/floatobj.h (revision 98e8827a)
1 #pragma once
2 
3 C_ASSERT(sizeof(FIX) == sizeof(LONG));
4 #define FIX2LONG(x) (((x) + 8) >> 4)
5 #define LONG2FIX(x) ((x) << 4)
6 
7 #if defined(_M_IX86)
8 
9 FORCEINLINE
10 BOOL
11 _FLOATOBJ_Equal(FLOATOBJ *pf1, FLOATOBJ *pf2)
12 {
13     EFLOAT_S *pef1 = (EFLOAT_S*)pf1;
14     EFLOAT_S *pef2 = (EFLOAT_S*)pf2;
15     return (pef1->lMant == pef2->lMant && pef1->lExp == pef2->lExp);
16 }
17 #define FLOATOBJ_Equal _FLOATOBJ_Equal
18 
19 /*!
20  * \brief Converts a FLOATOBJ into a LONG by truncating the value to integer
21  *
22  * \param pf - Pointer to a FLOATOBJ containing the value to convert
23  *
24  * \param pl - Pointer to a variable that receives the result
25  *
26  * \return TRUE if the function succeeded, FALSE if the result would overflow
27  *         a LONG.
28  */
29 FORCEINLINE
30 BOOL
31 FLOATOBJ_bConvertToLong(FLOATOBJ *pf, PLONG pl)
32 {
33     EFLOAT_S *pef = (EFLOAT_S*)pf;
34 
35     if (pef->lExp > 32)
36     {
37         return FALSE;
38     }
39 
40     if (pef->lExp < 2)
41     {
42         *pl = 0;
43         return TRUE;
44     }
45 
46     *pl = EngMulDiv(pef->lMant, 1 << (pef->lExp - 2), 0x40000000);
47     return TRUE;
48 }
49 
50 FORCEINLINE
51 LONG
52 FLOATOBJ_GetFix(FLOATOBJ *pf)
53 {
54     EFLOAT_S *pef = (EFLOAT_S*)pf;
55     LONG Shift = (28 - pef->lExp);
56     return (Shift >= 0 ? pef->lMant >> Shift : pef->lMant << -Shift);
57 }
58 
59 FORCEINLINE
60 BOOL
61 FLOATOBJ_IsLong(FLOATOBJ *pf)
62 {
63     EFLOAT_S *pef = (EFLOAT_S*)pf;
64     ULONG ulShift = pef->lExp;
65     if (ulShift < 32)
66         return ((pef->lMant << ulShift) == 0);
67     else
68         return (ulShift == 32);
69 }
70 
71 FORCEINLINE
72 BOOL
73 FLOATOBJ_Equal0(FLOATOBJ *pf)
74 {
75     EFLOAT_S *pef = (EFLOAT_S*)pf;
76     return (pef->lMant == 0 && pef->lExp == 0);
77 }
78 
79 FORCEINLINE
80 BOOL
81 FLOATOBJ_Equal1(FLOATOBJ *pf)
82 {
83     EFLOAT_S *pef = (EFLOAT_S*)pf;
84     return (pef->lMant == 0x40000000 && pef->lExp == 2);
85 }
86 
87 extern const FLOATOBJ gef0;
88 extern const FLOATOBJ gef1;
89 extern const FLOATOBJ gef2;
90 extern const FLOATOBJ gef16;
91 
92 #define FLOATOBJ_0 {0x00000000, 0x00000000}
93 #define FLOATOBJ_1 {0x40000000, 0x00000002}
94 #define FLOATOBJ_16 {0x40000000, 0x00000006}
95 #define FLOATOBJ_1_16 {0x40000000, 0xfffffffe}
96 
97 #define FLOATOBJ_Set0(fo) do { (fo)->ul1 = 0; (fo)->ul2 = 0; } while (0)
98 #define FLOATOBJ_Set1(fo) do { (fo)->ul1 = 0x40000000; (fo)->ul2 = 2; } while (0)
99 
100 #else
101 
102 #define FLOATOBJ_bConvertToLong(pf, pl) (*pl = (LONG)*pf, TRUE)
103 #define FLOATOBJ_IsLong(pf) ((FLOAT)((LONG)*(pf)) == *(pf))
104 #define FLOATOBJ_Equal0(pf) (*(pf) == 0.)
105 #define FLOATOBJ_Equal1(pf) (*(pf) == 1.)
106 #define FLOATOBJ_GetFix(pf) ((LONG)(*(pf) * 16.))
107 
108 #define FLOATOBJ_0 0.
109 #define FLOATOBJ_1 1.
110 #define FLOATOBJ_16 16.
111 #define FLOATOBJ_1_16 (1./16.)
112 
113 static const FLOATOBJ gef0 = 0.;
114 static const FLOATOBJ gef1 = 1.;
115 static const FLOATOBJ gef2 = 2.;
116 static const FLOATOBJ gef16 = 16.;
117 
118 #define FLOATOBJ_Set0(fo) *(fo) = 0;
119 #define FLOATOBJ_Set1(fo) *(fo) = 1;
120 
121 #endif
122