Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  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
  12. extern "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 */
  23. typedef int32_t css_fixed;
  24.  
  25. static inline css_fixed
  26. css_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.  
  42. static inline css_fixed
  43. css_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.  
  58. static inline css_fixed
  59. css_divide_fixed(const css_fixed x, const css_fixed y) {
  60.         int64_t xx = ((int64_t)x << 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.  
  71. static inline css_fixed
  72. css_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.  
  84. static inline css_fixed
  85. css_int_to_fixed(const int a) {
  86.         int64_t xx = ((int64_t) a) << 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.  
  97. static inline css_fixed
  98. css_float_to_fixed(const float a) {
  99.         float xx = a * (float) (1 << CSS_RADIX_POINT);
  100.  
  101.         if (xx < INT_MIN)
  102.                 xx = INT_MIN;
  103.  
  104.         if (xx > INT_MAX)
  105.                 xx = INT_MAX;
  106.        
  107.         return (css_fixed) xx;
  108. }
  109.  
  110. /* Add two fixed point values */
  111. #define FADD(a, b) (css_add_fixed((a), (b)))
  112. /* Subtract two fixed point values */
  113. #define FSUB(a, b) (css_subtract_fixed((a), (b)))
  114. /* Multiply two fixed point values */
  115. #define FMUL(a, b) (css_multiply_fixed((a), (b)))
  116. /* Divide two fixed point values */
  117. #define FDIV(a, b) (css_divide_fixed((a), (b)))
  118.  
  119. /* Convert a floating point value to fixed point */
  120. #define FLTTOFIX(a) ((css_fixed) ((a) * (float) (1 << CSS_RADIX_POINT)))
  121. /* Convert a fixed point value to floating point */
  122. #define FIXTOFLT(a) ((float) (a) / (float) (1 << CSS_RADIX_POINT))
  123.  
  124. /* Convert an integer to a fixed point value */
  125. #define INTTOFIX(a) (css_int_to_fixed(a))
  126. /* Convert a fixed point value to an integer */
  127. #define FIXTOINT(a) ((a) >> CSS_RADIX_POINT)
  128.  
  129. /* truncate a fixed point value */
  130. #define TRUNCATEFIX(a) (a & ~((1 << CSS_RADIX_POINT)- 1 ))
  131.  
  132. /* Useful values */
  133. #define F_PI_2  0x00000648      /* 1.5708 (PI/2) */
  134. #define F_PI    0x00000c91      /* 3.1415 (PI) */
  135. #define F_3PI_2 0x000012d9      /* 4.7124 (3PI/2) */
  136. #define F_2PI   0x00001922      /* 6.2831 (2 PI) */
  137.  
  138. #define F_90    0x00016800      /*  90 */
  139. #define F_180   0x0002d000      /* 180 */
  140. #define F_270   0x00043800      /* 270 */
  141. #define F_360   0x0005a000      /* 360 */
  142.  
  143. #define F_0_5   0x00000200      /* 0.5 */
  144. #define F_1     0x00000400      /*   1 */
  145. #define F_10    0x00002800      /*  10 */
  146. #define F_72    0x00012000      /*  72 */
  147. #define F_100   0x00019000      /* 100 */
  148. #define F_200   0x00032000      /* 200 */
  149. #define F_255   0x0003FC00      /* 255 */
  150. #define F_300   0x0004b000      /* 300 */
  151. #define F_400   0x00064000      /* 400 */
  152.  
  153. #ifdef __cplusplus
  154. }
  155. #endif
  156.  
  157. #endif
  158.  
  159.