/modules/freetype2/src/base/fttrigon.c

http://github.com/zpao/v8monkey · C · 546 lines · 373 code · 127 blank · 46 comment · 45 complexity · 3609d7603f55593b9303d7a2d528dac0 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* fttrigon.c */
  4. /* */
  5. /* FreeType trigonometric functions (body). */
  6. /* */
  7. /* Copyright 2001, 2002, 2003, 2004, 2005 by */
  8. /* David Turner, Robert Wilhelm, and Werner Lemberg. */
  9. /* */
  10. /* This file is part of the FreeType project, and may only be used, */
  11. /* modified, and distributed under the terms of the FreeType project */
  12. /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
  13. /* this file you indicate that you have read the license and */
  14. /* understand and accept it fully. */
  15. /* */
  16. /***************************************************************************/
  17. #include <ft2build.h>
  18. #include FT_INTERNAL_OBJECTS_H
  19. #include FT_TRIGONOMETRY_H
  20. /* the following is 0.2715717684432231 * 2^30 */
  21. #define FT_TRIG_COSCALE 0x11616E8EUL
  22. /* this table was generated for FT_PI = 180L << 16, i.e. degrees */
  23. #define FT_TRIG_MAX_ITERS 23
  24. static const FT_Fixed
  25. ft_trig_arctan_table[24] =
  26. {
  27. 4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L,
  28. 58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
  29. 57L, 29L, 14L, 7L, 4L, 2L, 1L
  30. };
  31. /* the Cordic shrink factor, multiplied by 2^32 */
  32. #define FT_TRIG_SCALE 1166391785UL /* 0x4585BA38UL */
  33. #ifdef FT_CONFIG_HAS_INT64
  34. /* multiply a given value by the CORDIC shrink factor */
  35. static FT_Fixed
  36. ft_trig_downscale( FT_Fixed val )
  37. {
  38. FT_Fixed s;
  39. FT_Int64 v;
  40. s = val;
  41. val = ( val >= 0 ) ? val : -val;
  42. v = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL;
  43. val = (FT_Fixed)( v >> 32 );
  44. return ( s >= 0 ) ? val : -val;
  45. }
  46. #else /* !FT_CONFIG_HAS_INT64 */
  47. /* multiply a given value by the CORDIC shrink factor */
  48. static FT_Fixed
  49. ft_trig_downscale( FT_Fixed val )
  50. {
  51. FT_Fixed s;
  52. FT_UInt32 v1, v2, k1, k2, hi, lo1, lo2, lo3;
  53. s = val;
  54. val = ( val >= 0 ) ? val : -val;
  55. v1 = (FT_UInt32)val >> 16;
  56. v2 = (FT_UInt32)(val & 0xFFFFL);
  57. k1 = (FT_UInt32)FT_TRIG_SCALE >> 16; /* constant */
  58. k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL); /* constant */
  59. hi = k1 * v1;
  60. lo1 = k1 * v2 + k2 * v1; /* can't overflow */
  61. lo2 = ( k2 * v2 ) >> 16;
  62. lo3 = ( lo1 >= lo2 ) ? lo1 : lo2;
  63. lo1 += lo2;
  64. hi += lo1 >> 16;
  65. if ( lo1 < lo3 )
  66. hi += (FT_UInt32)0x10000UL;
  67. val = (FT_Fixed)hi;
  68. return ( s >= 0 ) ? val : -val;
  69. }
  70. #endif /* !FT_CONFIG_HAS_INT64 */
  71. static FT_Int
  72. ft_trig_prenorm( FT_Vector* vec )
  73. {
  74. FT_Fixed x, y, z;
  75. FT_Int shift;
  76. x = vec->x;
  77. y = vec->y;
  78. z = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
  79. shift = 0;
  80. #if 1
  81. /* determine msb bit index in `shift' */
  82. if ( z >= ( 1L << 16 ) )
  83. {
  84. z >>= 16;
  85. shift += 16;
  86. }
  87. if ( z >= ( 1L << 8 ) )
  88. {
  89. z >>= 8;
  90. shift += 8;
  91. }
  92. if ( z >= ( 1L << 4 ) )
  93. {
  94. z >>= 4;
  95. shift += 4;
  96. }
  97. if ( z >= ( 1L << 2 ) )
  98. {
  99. z >>= 2;
  100. shift += 2;
  101. }
  102. if ( z >= ( 1L << 1 ) )
  103. {
  104. z >>= 1;
  105. shift += 1;
  106. }
  107. if ( shift <= 27 )
  108. {
  109. shift = 27 - shift;
  110. vec->x = x << shift;
  111. vec->y = y << shift;
  112. }
  113. else
  114. {
  115. shift -= 27;
  116. vec->x = x >> shift;
  117. vec->y = y >> shift;
  118. shift = -shift;
  119. }
  120. #else /* 0 */
  121. if ( z < ( 1L << 27 ) )
  122. {
  123. do
  124. {
  125. shift++;
  126. z <<= 1;
  127. } while ( z < ( 1L << 27 ) );
  128. vec->x = x << shift;
  129. vec->y = y << shift;
  130. }
  131. else if ( z > ( 1L << 28 ) )
  132. {
  133. do
  134. {
  135. shift++;
  136. z >>= 1;
  137. } while ( z > ( 1L << 28 ) );
  138. vec->x = x >> shift;
  139. vec->y = y >> shift;
  140. shift = -shift;
  141. }
  142. #endif /* 0 */
  143. return shift;
  144. }
  145. static void
  146. ft_trig_pseudo_rotate( FT_Vector* vec,
  147. FT_Angle theta )
  148. {
  149. FT_Int i;
  150. FT_Fixed x, y, xtemp;
  151. const FT_Fixed *arctanptr;
  152. x = vec->x;
  153. y = vec->y;
  154. /* Get angle between -90 and 90 degrees */
  155. while ( theta <= -FT_ANGLE_PI2 )
  156. {
  157. x = -x;
  158. y = -y;
  159. theta += FT_ANGLE_PI;
  160. }
  161. while ( theta > FT_ANGLE_PI2 )
  162. {
  163. x = -x;
  164. y = -y;
  165. theta -= FT_ANGLE_PI;
  166. }
  167. /* Initial pseudorotation, with left shift */
  168. arctanptr = ft_trig_arctan_table;
  169. if ( theta < 0 )
  170. {
  171. xtemp = x + ( y << 1 );
  172. y = y - ( x << 1 );
  173. x = xtemp;
  174. theta += *arctanptr++;
  175. }
  176. else
  177. {
  178. xtemp = x - ( y << 1 );
  179. y = y + ( x << 1 );
  180. x = xtemp;
  181. theta -= *arctanptr++;
  182. }
  183. /* Subsequent pseudorotations, with right shifts */
  184. i = 0;
  185. do
  186. {
  187. if ( theta < 0 )
  188. {
  189. xtemp = x + ( y >> i );
  190. y = y - ( x >> i );
  191. x = xtemp;
  192. theta += *arctanptr++;
  193. }
  194. else
  195. {
  196. xtemp = x - ( y >> i );
  197. y = y + ( x >> i );
  198. x = xtemp;
  199. theta -= *arctanptr++;
  200. }
  201. } while ( ++i < FT_TRIG_MAX_ITERS );
  202. vec->x = x;
  203. vec->y = y;
  204. }
  205. static void
  206. ft_trig_pseudo_polarize( FT_Vector* vec )
  207. {
  208. FT_Fixed theta;
  209. FT_Fixed yi, i;
  210. FT_Fixed x, y;
  211. const FT_Fixed *arctanptr;
  212. x = vec->x;
  213. y = vec->y;
  214. /* Get the vector into the right half plane */
  215. theta = 0;
  216. if ( x < 0 )
  217. {
  218. x = -x;
  219. y = -y;
  220. theta = 2 * FT_ANGLE_PI2;
  221. }
  222. if ( y > 0 )
  223. theta = - theta;
  224. arctanptr = ft_trig_arctan_table;
  225. if ( y < 0 )
  226. {
  227. /* Rotate positive */
  228. yi = y + ( x << 1 );
  229. x = x - ( y << 1 );
  230. y = yi;
  231. theta -= *arctanptr++; /* Subtract angle */
  232. }
  233. else
  234. {
  235. /* Rotate negative */
  236. yi = y - ( x << 1 );
  237. x = x + ( y << 1 );
  238. y = yi;
  239. theta += *arctanptr++; /* Add angle */
  240. }
  241. i = 0;
  242. do
  243. {
  244. if ( y < 0 )
  245. {
  246. /* Rotate positive */
  247. yi = y + ( x >> i );
  248. x = x - ( y >> i );
  249. y = yi;
  250. theta -= *arctanptr++;
  251. }
  252. else
  253. {
  254. /* Rotate negative */
  255. yi = y - ( x >> i );
  256. x = x + ( y >> i );
  257. y = yi;
  258. theta += *arctanptr++;
  259. }
  260. } while ( ++i < FT_TRIG_MAX_ITERS );
  261. /* round theta */
  262. if ( theta >= 0 )
  263. theta = FT_PAD_ROUND( theta, 32 );
  264. else
  265. theta = -FT_PAD_ROUND( -theta, 32 );
  266. vec->x = x;
  267. vec->y = theta;
  268. }
  269. /* documentation is in fttrigon.h */
  270. FT_EXPORT_DEF( FT_Fixed )
  271. FT_Cos( FT_Angle angle )
  272. {
  273. FT_Vector v;
  274. v.x = FT_TRIG_COSCALE >> 2;
  275. v.y = 0;
  276. ft_trig_pseudo_rotate( &v, angle );
  277. return v.x / ( 1 << 12 );
  278. }
  279. /* documentation is in fttrigon.h */
  280. FT_EXPORT_DEF( FT_Fixed )
  281. FT_Sin( FT_Angle angle )
  282. {
  283. return FT_Cos( FT_ANGLE_PI2 - angle );
  284. }
  285. /* documentation is in fttrigon.h */
  286. FT_EXPORT_DEF( FT_Fixed )
  287. FT_Tan( FT_Angle angle )
  288. {
  289. FT_Vector v;
  290. v.x = FT_TRIG_COSCALE >> 2;
  291. v.y = 0;
  292. ft_trig_pseudo_rotate( &v, angle );
  293. return FT_DivFix( v.y, v.x );
  294. }
  295. /* documentation is in fttrigon.h */
  296. FT_EXPORT_DEF( FT_Angle )
  297. FT_Atan2( FT_Fixed dx,
  298. FT_Fixed dy )
  299. {
  300. FT_Vector v;
  301. if ( dx == 0 && dy == 0 )
  302. return 0;
  303. v.x = dx;
  304. v.y = dy;
  305. ft_trig_prenorm( &v );
  306. ft_trig_pseudo_polarize( &v );
  307. return v.y;
  308. }
  309. /* documentation is in fttrigon.h */
  310. FT_EXPORT_DEF( void )
  311. FT_Vector_Unit( FT_Vector* vec,
  312. FT_Angle angle )
  313. {
  314. vec->x = FT_TRIG_COSCALE >> 2;
  315. vec->y = 0;
  316. ft_trig_pseudo_rotate( vec, angle );
  317. vec->x >>= 12;
  318. vec->y >>= 12;
  319. }
  320. /* these macros return 0 for positive numbers,
  321. and -1 for negative ones */
  322. #define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) )
  323. #define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) )
  324. #define FT_SIGN_INT32( x ) ( (x) >> 31 )
  325. #define FT_SIGN_INT16( x ) ( (x) >> 15 )
  326. /* documentation is in fttrigon.h */
  327. FT_EXPORT_DEF( void )
  328. FT_Vector_Rotate( FT_Vector* vec,
  329. FT_Angle angle )
  330. {
  331. FT_Int shift;
  332. FT_Vector v;
  333. v.x = vec->x;
  334. v.y = vec->y;
  335. if ( angle && ( v.x != 0 || v.y != 0 ) )
  336. {
  337. shift = ft_trig_prenorm( &v );
  338. ft_trig_pseudo_rotate( &v, angle );
  339. v.x = ft_trig_downscale( v.x );
  340. v.y = ft_trig_downscale( v.y );
  341. if ( shift > 0 )
  342. {
  343. FT_Int32 half = (FT_Int32)1L << ( shift - 1 );
  344. vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;
  345. vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift;
  346. }
  347. else
  348. {
  349. shift = -shift;
  350. vec->x = v.x << shift;
  351. vec->y = v.y << shift;
  352. }
  353. }
  354. }
  355. /* documentation is in fttrigon.h */
  356. FT_EXPORT_DEF( FT_Fixed )
  357. FT_Vector_Length( FT_Vector* vec )
  358. {
  359. FT_Int shift;
  360. FT_Vector v;
  361. v = *vec;
  362. /* handle trivial cases */
  363. if ( v.x == 0 )
  364. {
  365. return ( v.y >= 0 ) ? v.y : -v.y;
  366. }
  367. else if ( v.y == 0 )
  368. {
  369. return ( v.x >= 0 ) ? v.x : -v.x;
  370. }
  371. /* general case */
  372. shift = ft_trig_prenorm( &v );
  373. ft_trig_pseudo_polarize( &v );
  374. v.x = ft_trig_downscale( v.x );
  375. if ( shift > 0 )
  376. return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;
  377. return v.x << -shift;
  378. }
  379. /* documentation is in fttrigon.h */
  380. FT_EXPORT_DEF( void )
  381. FT_Vector_Polarize( FT_Vector* vec,
  382. FT_Fixed *length,
  383. FT_Angle *angle )
  384. {
  385. FT_Int shift;
  386. FT_Vector v;
  387. v = *vec;
  388. if ( v.x == 0 && v.y == 0 )
  389. return;
  390. shift = ft_trig_prenorm( &v );
  391. ft_trig_pseudo_polarize( &v );
  392. v.x = ft_trig_downscale( v.x );
  393. *length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift );
  394. *angle = v.y;
  395. }
  396. /* documentation is in fttrigon.h */
  397. FT_EXPORT_DEF( void )
  398. FT_Vector_From_Polar( FT_Vector* vec,
  399. FT_Fixed length,
  400. FT_Angle angle )
  401. {
  402. vec->x = length;
  403. vec->y = 0;
  404. FT_Vector_Rotate( vec, angle );
  405. }
  406. /* documentation is in fttrigon.h */
  407. FT_EXPORT_DEF( FT_Angle )
  408. FT_Angle_Diff( FT_Angle angle1,
  409. FT_Angle angle2 )
  410. {
  411. FT_Angle delta = angle2 - angle1;
  412. delta %= FT_ANGLE_2PI;
  413. if ( delta < 0 )
  414. delta += FT_ANGLE_2PI;
  415. if ( delta > FT_ANGLE_PI )
  416. delta -= FT_ANGLE_2PI;
  417. return delta;
  418. }
  419. /* END */