1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
/*
* This file is part of LibCSS.
* Licensed under the MIT License,
* http://www.opensource.org/licenses/mit-license.php
* Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org>
*/
#ifndef libcss_fpmath_h_
#define libcss_fpmath_h_
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdint.h>
#include <limits.h>
/* 22:10 fixed point math */
#define CSS_RADIX_POINT 10
/* type for fixed point numbers */
typedef int32_t css_fixed;
static inline css_fixed
css_add_fixed(const css_fixed x, const css_fixed y) {
int32_t ux = x;
int32_t uy = y;
int32_t res = ux + uy;
/* Calculate overflowed result. (Don't change the sign bit of ux) */
ux = (ux >> 31) + INT_MAX;
/* Force compiler to use cmovns instruction */
if ((int32_t) ((ux ^ uy) | ~(uy ^ res)) >= 0) {
res = ux;
}
return res;
}
static inline css_fixed
css_subtract_fixed(const css_fixed x, const css_fixed y) {
int32_t ux = x;
int32_t uy = y;
int32_t res = ux - uy;
ux = (ux >> 31) + INT_MAX;
/* Force compiler to use cmovns instruction */
if ((int32_t)((ux ^ uy) & (ux ^ res)) < 0) {
res = ux;
}
return res;
}
static inline css_fixed
css_divide_fixed(const css_fixed x, const css_fixed y) {
int64_t xx = ((int64_t)x << CSS_RADIX_POINT) / y;
if (xx < INT_MIN)
xx = INT_MIN;
if (xx > INT_MAX)
xx = INT_MAX;
return xx;
}
static inline css_fixed
css_multiply_fixed(const css_fixed x, const css_fixed y) {
int64_t xx = ((int64_t)x * (int64_t)y) >> CSS_RADIX_POINT;
if (xx < INT_MIN)
xx = INT_MIN;
if (xx > INT_MAX)
xx = INT_MAX;
return xx;
}
static inline css_fixed
css_int_to_fixed(const int a) {
int64_t xx = ((int64_t) a) << CSS_RADIX_POINT;
if (xx < INT_MIN)
xx = INT_MIN;
if (xx > INT_MAX)
xx = INT_MAX;
return xx;
}
static inline css_fixed
css_float_to_fixed(const float a) {
float xx = a * (float) (1 << CSS_RADIX_POINT);
if (xx < INT_MIN)
xx = INT_MIN;
if (xx > INT_MAX)
xx = INT_MAX;
return (css_fixed) xx;
}
/* Add two fixed point values */
#define FADD(a, b) (css_add_fixed((a), (b)))
/* Subtract two fixed point values */
#define FSUB(a, b) (css_subtract_fixed((a), (b)))
/* Multiply two fixed point values */
#define FMUL(a, b) (css_multiply_fixed((a), (b)))
/* Divide two fixed point values */
#define FDIV(a, b) (css_divide_fixed((a), (b)))
/* Convert a floating point value to fixed point */
#define FLTTOFIX(a) ((css_fixed) ((a) * (float) (1 << CSS_RADIX_POINT)))
/* Convert a fixed point value to floating point */
#define FIXTOFLT(a) ((float) (a) / (float) (1 << CSS_RADIX_POINT))
/* Convert an integer to a fixed point value */
#define INTTOFIX(a) (css_int_to_fixed(a))
/* Convert a fixed point value to an integer */
#define FIXTOINT(a) ((a) >> CSS_RADIX_POINT)
/* truncate a fixed point value */
#define TRUNCATEFIX(a) (a & ~((1 << CSS_RADIX_POINT)- 1 ))
/* Useful values */
#define F_PI_2 0x00000648 /* 1.5708 (PI/2) */
#define F_PI 0x00000c91 /* 3.1415 (PI) */
#define F_3PI_2 0x000012d9 /* 4.7124 (3PI/2) */
#define F_2PI 0x00001922 /* 6.2831 (2 PI) */
#define F_90 0x00016800 /* 90 */
#define F_180 0x0002d000 /* 180 */
#define F_270 0x00043800 /* 270 */
#define F_360 0x0005a000 /* 360 */
#define F_0_5 0x00000200 /* 0.5 */
#define F_1 0x00000400 /* 1 */
#define F_10 0x00002800 /* 10 */
#define F_72 0x00012000 /* 72 */
#define F_96 0x00018000 /* 96 */
#define F_100 0x00019000 /* 100 */
#define F_200 0x00032000 /* 200 */
#define F_255 0x0003FC00 /* 255 */
#define F_300 0x0004b000 /* 300 */
#define F_400 0x00064000 /* 400 */
#ifdef __cplusplus
}
#endif
#endif
|