1 /***************************************************************************/
5 /* FreeType trigonometric functions (body). */
7 /* Copyright 2001-2016 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
18 /*************************************************************************/
20 /* This is a fixed-point CORDIC implementation of trigonometric */
21 /* functions as well as transformations between Cartesian and polar */
22 /* coordinates. The angles are represented as 16.16 fixed-point values */
23 /* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */
24 /* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */
25 /* discrete Cartesian grid can have the same or better angular */
26 /* resolution. Therefore, to maintain this precision, some functions */
27 /* require an interim upscaling of the vectors, whereas others operate */
28 /* with 24-bit long vectors directly. */
30 /*************************************************************************/
33 #include FT_INTERNAL_OBJECTS_H
34 #include FT_INTERNAL_CALC_H
35 #include FT_TRIGONOMETRY_H
38 /* the Cordic shrink factor 0.858785336480436 * 2^32 */
39 #define FT_TRIG_SCALE 0xDBD95B16UL
41 /* the highest bit in overflow-safe vector components, */
42 /* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */
43 #define FT_TRIG_SAFE_MSB 29
45 /* this table was generated for FT_PI = 180L << 16, i.e. degrees */
46 #define FT_TRIG_MAX_ITERS 23
49 ft_trig_arctan_table[] =
51 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L,
52 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
53 57L, 29L, 14L, 7L, 4L, 2L, 1L
59 /* multiply a given value by the CORDIC shrink factor */
61 ft_trig_downscale( FT_Fixed val )
72 /* 0x40000000 comes from regression analysis between true */
73 /* and CORDIC hypotenuse, so it minimizes the error */
75 ( (FT_UInt64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 );
77 return s < 0 ? -val : val;
80 #else /* !FT_LONG64 */
82 /* multiply a given value by the CORDIC shrink factor */
84 ft_trig_downscale( FT_Fixed val )
87 FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2;
96 lo1 = (FT_UInt32)val & 0x0000FFFFU;
97 hi1 = (FT_UInt32)val >> 16;
98 lo2 = FT_TRIG_SCALE & 0x0000FFFFU;
99 hi2 = FT_TRIG_SCALE >> 16;
106 /* Check carry overflow of i1 + i2 */
108 hi += (FT_UInt32)( i1 < i2 ) << 16;
113 /* Check carry overflow of i1 + lo */
117 /* 0x40000000 comes from regression analysis between true */
118 /* and CORDIC hypotenuse, so it minimizes the error */
120 /* Check carry overflow of lo + 0x40000000 */
122 hi += ( lo < 0x40000000UL );
126 return s < 0 ? -val : val;
129 #endif /* !FT_LONG64 */
132 /* undefined and never called for zero vector */
134 ft_trig_prenorm( FT_Vector* vec )
143 shift = FT_MSB( (FT_UInt32)( FT_ABS( x ) | FT_ABS( y ) ) );
145 if ( shift <= FT_TRIG_SAFE_MSB )
147 shift = FT_TRIG_SAFE_MSB - shift;
148 vec->x = (FT_Pos)( (FT_ULong)x << shift );
149 vec->y = (FT_Pos)( (FT_ULong)y << shift );
153 shift -= FT_TRIG_SAFE_MSB;
164 ft_trig_pseudo_rotate( FT_Vector* vec,
168 FT_Fixed x, y, xtemp, b;
169 const FT_Angle *arctanptr;
175 /* Rotate inside [-PI/4,PI/4] sector */
176 while ( theta < -FT_ANGLE_PI4 )
181 theta += FT_ANGLE_PI2;
184 while ( theta > FT_ANGLE_PI4 )
189 theta -= FT_ANGLE_PI2;
192 arctanptr = ft_trig_arctan_table;
194 /* Pseudorotations, with right shifts */
195 for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ )
199 xtemp = x + ( ( y + b ) >> i );
200 y = y - ( ( x + b ) >> i );
202 theta += *arctanptr++;
206 xtemp = x - ( ( y + b ) >> i );
207 y = y + ( ( x + b ) >> i );
209 theta -= *arctanptr++;
219 ft_trig_pseudo_polarize( FT_Vector* vec )
223 FT_Fixed x, y, xtemp, b;
224 const FT_Angle *arctanptr;
230 /* Get the vector into [-PI/4,PI/4] sector */
235 theta = FT_ANGLE_PI2;
242 theta = y > 0 ? FT_ANGLE_PI : -FT_ANGLE_PI;
251 theta = -FT_ANGLE_PI2;
262 arctanptr = ft_trig_arctan_table;
264 /* Pseudorotations, with right shifts */
265 for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ )
269 xtemp = x + ( ( y + b ) >> i );
270 y = y - ( ( x + b ) >> i );
272 theta += *arctanptr++;
276 xtemp = x - ( ( y + b ) >> i );
277 y = y + ( ( x + b ) >> i );
279 theta -= *arctanptr++;
283 /* round theta to acknowledge its error that mostly comes */
284 /* from accumulated rounding errors in the arctan table */
286 theta = FT_PAD_ROUND( theta, 16 );
288 theta = -FT_PAD_ROUND( -theta, 16 );
295 /* documentation is in fttrigon.h */
297 FT_EXPORT_DEF( FT_Fixed )
298 FT_Cos( FT_Angle angle )
303 FT_Vector_Unit( &v, angle );
309 /* documentation is in fttrigon.h */
311 FT_EXPORT_DEF( FT_Fixed )
312 FT_Sin( FT_Angle angle )
317 FT_Vector_Unit( &v, angle );
323 /* documentation is in fttrigon.h */
325 FT_EXPORT_DEF( FT_Fixed )
326 FT_Tan( FT_Angle angle )
331 FT_Vector_Unit( &v, angle );
333 return FT_DivFix( v.y, v.x );
337 /* documentation is in fttrigon.h */
339 FT_EXPORT_DEF( FT_Angle )
340 FT_Atan2( FT_Fixed dx,
346 if ( dx == 0 && dy == 0 )
351 ft_trig_prenorm( &v );
352 ft_trig_pseudo_polarize( &v );
358 /* documentation is in fttrigon.h */
360 FT_EXPORT_DEF( void )
361 FT_Vector_Unit( FT_Vector* vec,
367 vec->x = FT_TRIG_SCALE >> 8;
369 ft_trig_pseudo_rotate( vec, angle );
370 vec->x = ( vec->x + 0x80L ) >> 8;
371 vec->y = ( vec->y + 0x80L ) >> 8;
375 /* these macros return 0 for positive numbers,
376 and -1 for negative ones */
377 #define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) )
378 #define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) )
379 #define FT_SIGN_INT32( x ) ( (x) >> 31 )
380 #define FT_SIGN_INT16( x ) ( (x) >> 15 )
383 /* documentation is in fttrigon.h */
385 FT_EXPORT_DEF( void )
386 FT_Vector_Rotate( FT_Vector* vec,
393 if ( !vec || !angle )
398 if ( v.x == 0 && v.y == 0 )
401 shift = ft_trig_prenorm( &v );
402 ft_trig_pseudo_rotate( &v, angle );
403 v.x = ft_trig_downscale( v.x );
404 v.y = ft_trig_downscale( v.y );
408 FT_Int32 half = (FT_Int32)1L << ( shift - 1 );
411 vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;
412 vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift;
417 vec->x = (FT_Pos)( (FT_ULong)v.x << shift );
418 vec->y = (FT_Pos)( (FT_ULong)v.y << shift );
423 /* documentation is in fttrigon.h */
425 FT_EXPORT_DEF( FT_Fixed )
426 FT_Vector_Length( FT_Vector* vec )
437 /* handle trivial cases */
440 return FT_ABS( v.y );
444 return FT_ABS( v.x );
448 shift = ft_trig_prenorm( &v );
449 ft_trig_pseudo_polarize( &v );
451 v.x = ft_trig_downscale( v.x );
454 return ( v.x + ( 1L << ( shift - 1 ) ) ) >> shift;
456 return (FT_Fixed)( (FT_UInt32)v.x << -shift );
460 /* documentation is in fttrigon.h */
462 FT_EXPORT_DEF( void )
463 FT_Vector_Polarize( FT_Vector* vec,
471 if ( !vec || !length || !angle )
476 if ( v.x == 0 && v.y == 0 )
479 shift = ft_trig_prenorm( &v );
480 ft_trig_pseudo_polarize( &v );
482 v.x = ft_trig_downscale( v.x );
484 *length = shift >= 0 ? ( v.x >> shift )
485 : (FT_Fixed)( (FT_UInt32)v.x << -shift );
490 /* documentation is in fttrigon.h */
492 FT_EXPORT_DEF( void )
493 FT_Vector_From_Polar( FT_Vector* vec,
503 FT_Vector_Rotate( vec, angle );
507 /* documentation is in fttrigon.h */
509 FT_EXPORT_DEF( FT_Angle )
510 FT_Angle_Diff( FT_Angle angle1,
513 FT_Angle delta = angle2 - angle1;
516 while ( delta <= -FT_ANGLE_PI )
517 delta += FT_ANGLE_2PI;
519 while ( delta > FT_ANGLE_PI )
520 delta -= FT_ANGLE_2PI;