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