ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fttrigon.c
Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  fttrigon.c                                                             */
00004 /*                                                                         */
00005 /*    FreeType trigonometric functions (body).                             */
00006 /*                                                                         */
00007 /*  Copyright 2001, 2002, 2003, 2004, 2005 by                              */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_OBJECTS_H
00021 #include FT_TRIGONOMETRY_H
00022 
00023 
00024   /* the following is 0.2715717684432231 * 2^30 */
00025 #define FT_TRIG_COSCALE  0x11616E8EUL
00026 
00027   /* this table was generated for FT_PI = 180L << 16, i.e. degrees */
00028 #define FT_TRIG_MAX_ITERS  23
00029 
00030   static const FT_Fixed
00031   ft_trig_arctan_table[24] =
00032   {
00033     4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L,
00034     58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
00035     57L, 29L, 14L, 7L, 4L, 2L, 1L
00036   };
00037 
00038   /* the Cordic shrink factor, multiplied by 2^32 */
00039 #define FT_TRIG_SCALE    1166391785UL  /* 0x4585BA38UL */
00040 
00041 
00042 #ifdef FT_CONFIG_HAS_INT64
00043 
00044   /* multiply a given value by the CORDIC shrink factor */
00045   static FT_Fixed
00046   ft_trig_downscale( FT_Fixed  val )
00047   {
00048     FT_Fixed  s;
00049     FT_Int64  v;
00050 
00051 
00052     s   = val;
00053     val = ( val >= 0 ) ? val : -val;
00054 
00055     v   = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL;
00056     val = (FT_Fixed)( v >> 32 );
00057 
00058     return ( s >= 0 ) ? val : -val;
00059   }
00060 
00061 #else /* !FT_CONFIG_HAS_INT64 */
00062 
00063   /* multiply a given value by the CORDIC shrink factor */
00064   static FT_Fixed
00065   ft_trig_downscale( FT_Fixed  val )
00066   {
00067     FT_Fixed   s;
00068     FT_UInt32  v1, v2, k1, k2, hi, lo1, lo2, lo3;
00069 
00070 
00071     s   = val;
00072     val = ( val >= 0 ) ? val : -val;
00073 
00074     v1 = (FT_UInt32)val >> 16;
00075     v2 = (FT_UInt32)(val & 0xFFFFL);
00076 
00077     k1 = (FT_UInt32)FT_TRIG_SCALE >> 16;       /* constant */
00078     k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL);   /* constant */
00079 
00080     hi   = k1 * v1;
00081     lo1  = k1 * v2 + k2 * v1;       /* can't overflow */
00082 
00083     lo2  = ( k2 * v2 ) >> 16;
00084     lo3  = ( lo1 >= lo2 ) ? lo1 : lo2;
00085     lo1 += lo2;
00086 
00087     hi  += lo1 >> 16;
00088     if ( lo1 < lo3 )
00089       hi += (FT_UInt32)0x10000UL;
00090 
00091     val  = (FT_Fixed)hi;
00092 
00093     return ( s >= 0 ) ? val : -val;
00094   }
00095 
00096 #endif /* !FT_CONFIG_HAS_INT64 */
00097 
00098 
00099   static FT_Int
00100   ft_trig_prenorm( FT_Vector*  vec )
00101   {
00102     FT_Fixed  x, y, z;
00103     FT_Int    shift;
00104 
00105 
00106     x = vec->x;
00107     y = vec->y;
00108 
00109     z     = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
00110     shift = 0;
00111 
00112 #if 1
00113     /* determine msb bit index in `shift' */
00114     if ( z >= ( 1L << 16 ) )
00115     {
00116       z     >>= 16;
00117       shift  += 16;
00118     }
00119     if ( z >= ( 1L << 8 ) )
00120     {
00121       z     >>= 8;
00122       shift  += 8;
00123     }
00124     if ( z >= ( 1L << 4 ) )
00125     {
00126       z     >>= 4;
00127       shift  += 4;
00128     }
00129     if ( z >= ( 1L << 2 ) )
00130     {
00131       z     >>= 2;
00132       shift  += 2;
00133     }
00134     if ( z >= ( 1L << 1 ) )
00135     {
00136       z    >>= 1;
00137       shift += 1;
00138     }
00139 
00140     if ( shift <= 27 )
00141     {
00142       shift  = 27 - shift;
00143       vec->x = x << shift;
00144       vec->y = y << shift;
00145     }
00146     else
00147     {
00148       shift -= 27;
00149       vec->x = x >> shift;
00150       vec->y = y >> shift;
00151       shift  = -shift;
00152     }
00153 
00154 #else /* 0 */
00155 
00156     if ( z < ( 1L << 27 ) )
00157     {
00158       do
00159       {
00160         shift++;
00161         z <<= 1;
00162       } while ( z < ( 1L << 27 ) );
00163       vec->x = x << shift;
00164       vec->y = y << shift;
00165     }
00166     else if ( z > ( 1L << 28 ) )
00167     {
00168       do
00169       {
00170         shift++;
00171         z >>= 1;
00172       } while ( z > ( 1L << 28 ) );
00173 
00174       vec->x = x >> shift;
00175       vec->y = y >> shift;
00176       shift  = -shift;
00177     }
00178 
00179 #endif /* 0 */
00180 
00181     return shift;
00182   }
00183 
00184 
00185   static void
00186   ft_trig_pseudo_rotate( FT_Vector*  vec,
00187                          FT_Angle    theta )
00188   {
00189     FT_Int           i;
00190     FT_Fixed         x, y, xtemp;
00191     const FT_Fixed  *arctanptr;
00192 
00193 
00194     x = vec->x;
00195     y = vec->y;
00196 
00197     /* Get angle between -90 and 90 degrees */
00198     while ( theta <= -FT_ANGLE_PI2 )
00199     {
00200       x = -x;
00201       y = -y;
00202       theta += FT_ANGLE_PI;
00203     }
00204 
00205     while ( theta > FT_ANGLE_PI2 )
00206     {
00207       x = -x;
00208       y = -y;
00209       theta -= FT_ANGLE_PI;
00210     }
00211 
00212     /* Initial pseudorotation, with left shift */
00213     arctanptr = ft_trig_arctan_table;
00214 
00215     if ( theta < 0 )
00216     {
00217       xtemp  = x + ( y << 1 );
00218       y      = y - ( x << 1 );
00219       x      = xtemp;
00220       theta += *arctanptr++;
00221     }
00222     else
00223     {
00224       xtemp  = x - ( y << 1 );
00225       y      = y + ( x << 1 );
00226       x      = xtemp;
00227       theta -= *arctanptr++;
00228     }
00229 
00230     /* Subsequent pseudorotations, with right shifts */
00231     i = 0;
00232     do
00233     {
00234       if ( theta < 0 )
00235       {
00236         xtemp  = x + ( y >> i );
00237         y      = y - ( x >> i );
00238         x      = xtemp;
00239         theta += *arctanptr++;
00240       }
00241       else
00242       {
00243         xtemp  = x - ( y >> i );
00244         y      = y + ( x >> i );
00245         x      = xtemp;
00246         theta -= *arctanptr++;
00247       }
00248     } while ( ++i < FT_TRIG_MAX_ITERS );
00249 
00250     vec->x = x;
00251     vec->y = y;
00252   }
00253 
00254 
00255   static void
00256   ft_trig_pseudo_polarize( FT_Vector*  vec )
00257   {
00258     FT_Fixed         theta;
00259     FT_Fixed         yi, i;
00260     FT_Fixed         x, y;
00261     const FT_Fixed  *arctanptr;
00262 
00263 
00264     x = vec->x;
00265     y = vec->y;
00266 
00267     /* Get the vector into the right half plane */
00268     theta = 0;
00269     if ( x < 0 )
00270     {
00271       x = -x;
00272       y = -y;
00273       theta = 2 * FT_ANGLE_PI2;
00274     }
00275 
00276     if ( y > 0 )
00277       theta = - theta;
00278 
00279     arctanptr = ft_trig_arctan_table;
00280 
00281     if ( y < 0 )
00282     {
00283       /* Rotate positive */
00284       yi     = y + ( x << 1 );
00285       x      = x - ( y << 1 );
00286       y      = yi;
00287       theta -= *arctanptr++;  /* Subtract angle */
00288     }
00289     else
00290     {
00291       /* Rotate negative */
00292       yi     = y - ( x << 1 );
00293       x      = x + ( y << 1 );
00294       y      = yi;
00295       theta += *arctanptr++;  /* Add angle */
00296     }
00297 
00298     i = 0;
00299     do
00300     {
00301       if ( y < 0 )
00302       {
00303         /* Rotate positive */
00304         yi     = y + ( x >> i );
00305         x      = x - ( y >> i );
00306         y      = yi;
00307         theta -= *arctanptr++;
00308       }
00309       else
00310       {
00311         /* Rotate negative */
00312         yi     = y - ( x >> i );
00313         x      = x + ( y >> i );
00314         y      = yi;
00315         theta += *arctanptr++;
00316       }
00317     } while ( ++i < FT_TRIG_MAX_ITERS );
00318 
00319     /* round theta */
00320     if ( theta >= 0 )
00321       theta = FT_PAD_ROUND( theta, 32 );
00322     else
00323       theta = -FT_PAD_ROUND( -theta, 32 );
00324 
00325     vec->x = x;
00326     vec->y = theta;
00327   }
00328 
00329 
00330   /* documentation is in fttrigon.h */
00331 
00332   FT_EXPORT_DEF( FT_Fixed )
00333   FT_Cos( FT_Angle  angle )
00334   {
00335     FT_Vector  v;
00336 
00337 
00338     v.x = FT_TRIG_COSCALE >> 2;
00339     v.y = 0;
00340     ft_trig_pseudo_rotate( &v, angle );
00341 
00342     return v.x / ( 1 << 12 );
00343   }
00344 
00345 
00346   /* documentation is in fttrigon.h */
00347 
00348   FT_EXPORT_DEF( FT_Fixed )
00349   FT_Sin( FT_Angle  angle )
00350   {
00351     return FT_Cos( FT_ANGLE_PI2 - angle );
00352   }
00353 
00354 
00355   /* documentation is in fttrigon.h */
00356 
00357   FT_EXPORT_DEF( FT_Fixed )
00358   FT_Tan( FT_Angle  angle )
00359   {
00360     FT_Vector  v;
00361 
00362 
00363     v.x = FT_TRIG_COSCALE >> 2;
00364     v.y = 0;
00365     ft_trig_pseudo_rotate( &v, angle );
00366 
00367     return FT_DivFix( v.y, v.x );
00368   }
00369 
00370 
00371   /* documentation is in fttrigon.h */
00372 
00373   FT_EXPORT_DEF( FT_Angle )
00374   FT_Atan2( FT_Fixed  dx,
00375             FT_Fixed  dy )
00376   {
00377     FT_Vector  v;
00378 
00379 
00380     if ( dx == 0 && dy == 0 )
00381       return 0;
00382 
00383     v.x = dx;
00384     v.y = dy;
00385     ft_trig_prenorm( &v );
00386     ft_trig_pseudo_polarize( &v );
00387 
00388     return v.y;
00389   }
00390 
00391 
00392   /* documentation is in fttrigon.h */
00393 
00394   FT_EXPORT_DEF( void )
00395   FT_Vector_Unit( FT_Vector*  vec,
00396                   FT_Angle    angle )
00397   {
00398     vec->x = FT_TRIG_COSCALE >> 2;
00399     vec->y = 0;
00400     ft_trig_pseudo_rotate( vec, angle );
00401     vec->x >>= 12;
00402     vec->y >>= 12;
00403   }
00404 
00405 
00406   /* these macros return 0 for positive numbers,
00407      and -1 for negative ones */
00408 #define FT_SIGN_LONG( x )   ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) )
00409 #define FT_SIGN_INT( x )    ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) )
00410 #define FT_SIGN_INT32( x )  ( (x) >> 31 )
00411 #define FT_SIGN_INT16( x )  ( (x) >> 15 )
00412 
00413 
00414   /* documentation is in fttrigon.h */
00415 
00416   FT_EXPORT_DEF( void )
00417   FT_Vector_Rotate( FT_Vector*  vec,
00418                     FT_Angle    angle )
00419   {
00420     FT_Int     shift;
00421     FT_Vector  v;
00422 
00423 
00424     v.x   = vec->x;
00425     v.y   = vec->y;
00426 
00427     if ( angle && ( v.x != 0 || v.y != 0 ) )
00428     {
00429       shift = ft_trig_prenorm( &v );
00430       ft_trig_pseudo_rotate( &v, angle );
00431       v.x = ft_trig_downscale( v.x );
00432       v.y = ft_trig_downscale( v.y );
00433 
00434       if ( shift > 0 )
00435       {
00436         FT_Int32  half = (FT_Int32)1L << ( shift - 1 );
00437 
00438 
00439         vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;
00440         vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift;
00441       }
00442       else
00443       {
00444         shift  = -shift;
00445         vec->x = v.x << shift;
00446         vec->y = v.y << shift;
00447       }
00448     }
00449   }
00450 
00451 
00452   /* documentation is in fttrigon.h */
00453 
00454   FT_EXPORT_DEF( FT_Fixed )
00455   FT_Vector_Length( FT_Vector*  vec )
00456   {
00457     FT_Int     shift;
00458     FT_Vector  v;
00459 
00460 
00461     v = *vec;
00462 
00463     /* handle trivial cases */
00464     if ( v.x == 0 )
00465     {
00466       return ( v.y >= 0 ) ? v.y : -v.y;
00467     }
00468     else if ( v.y == 0 )
00469     {
00470       return ( v.x >= 0 ) ? v.x : -v.x;
00471     }
00472 
00473     /* general case */
00474     shift = ft_trig_prenorm( &v );
00475     ft_trig_pseudo_polarize( &v );
00476 
00477     v.x = ft_trig_downscale( v.x );
00478 
00479     if ( shift > 0 )
00480       return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;
00481 
00482     return v.x << -shift;
00483   }
00484 
00485 
00486   /* documentation is in fttrigon.h */
00487 
00488   FT_EXPORT_DEF( void )
00489   FT_Vector_Polarize( FT_Vector*  vec,
00490                       FT_Fixed   *length,
00491                       FT_Angle   *angle )
00492   {
00493     FT_Int     shift;
00494     FT_Vector  v;
00495 
00496 
00497     v = *vec;
00498 
00499     if ( v.x == 0 && v.y == 0 )
00500       return;
00501 
00502     shift = ft_trig_prenorm( &v );
00503     ft_trig_pseudo_polarize( &v );
00504 
00505     v.x = ft_trig_downscale( v.x );
00506 
00507     *length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift );
00508     *angle  = v.y;
00509   }
00510 
00511 
00512   /* documentation is in fttrigon.h */
00513 
00514   FT_EXPORT_DEF( void )
00515   FT_Vector_From_Polar( FT_Vector*  vec,
00516                         FT_Fixed    length,
00517                         FT_Angle    angle )
00518   {
00519     vec->x = length;
00520     vec->y = 0;
00521 
00522     FT_Vector_Rotate( vec, angle );
00523   }
00524 
00525 
00526   /* documentation is in fttrigon.h */
00527 
00528   FT_EXPORT_DEF( FT_Angle )
00529   FT_Angle_Diff( FT_Angle  angle1,
00530                  FT_Angle  angle2 )
00531   {
00532     FT_Angle  delta = angle2 - angle1;
00533 
00534 
00535     delta %= FT_ANGLE_2PI;
00536     if ( delta < 0 )
00537       delta += FT_ANGLE_2PI;
00538 
00539     if ( delta > FT_ANGLE_PI )
00540       delta -= FT_ANGLE_2PI;
00541 
00542     return delta;
00543   }
00544 
00545 
00546 /* END */

Generated on Sun May 27 2012 04:33:47 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.