afangles.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  afangles.c                                                             */
00004 /*                                                                         */
00005 /*    Routines used to compute vector angles with limited accuracy         */
00006 /*    and very high speed.  It also contains sorting routines (body).      */
00007 /*                                                                         */
00008 /*  Copyright 2003, 2004, 2005, 2006 by                                    */
00009 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00010 /*                                                                         */
00011 /*  This file is part of the FreeType project, and may only be used,       */
00012 /*  modified, and distributed under the terms of the FreeType project      */
00013 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00014 /*  this file you indicate that you have read the license and              */
00015 /*  understand and accept it fully.                                        */
00016 /*                                                                         */
00017 /***************************************************************************/
00018 
00019 
00020 #include "aftypes.h"
00021 
00022 
00023 #if 0
00024 
00025   FT_LOCAL_DEF( FT_Int )
00026   af_corner_is_flat( FT_Pos  x_in,
00027                      FT_Pos  y_in,
00028                      FT_Pos  x_out,
00029                      FT_Pos  y_out )
00030   {
00031     FT_Pos  ax = x_in;
00032     FT_Pos  ay = y_in;
00033 
00034     FT_Pos  d_in, d_out, d_corner;
00035 
00036 
00037     if ( ax < 0 )
00038       ax = -ax;
00039     if ( ay < 0 )
00040       ay = -ay;
00041     d_in = ax + ay;
00042 
00043     ax = x_out;
00044     if ( ax < 0 )
00045       ax = -ax;
00046     ay = y_out;
00047     if ( ay < 0 )
00048       ay = -ay;
00049     d_out = ax + ay;
00050 
00051     ax = x_out + x_in;
00052     if ( ax < 0 )
00053       ax = -ax;
00054     ay = y_out + y_in;
00055     if ( ay < 0 )
00056       ay = -ay;
00057     d_corner = ax + ay;
00058 
00059     return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
00060   }
00061 
00062 
00063   FT_LOCAL_DEF( FT_Int )
00064   af_corner_orientation( FT_Pos  x_in,
00065                          FT_Pos  y_in,
00066                          FT_Pos  x_out,
00067                          FT_Pos  y_out )
00068   {
00069     FT_Pos  delta;
00070 
00071 
00072     delta = x_in * y_out - y_in * x_out;
00073 
00074     if ( delta == 0 )
00075       return 0;
00076     else
00077       return 1 - 2 * ( delta < 0 );
00078   }
00079 
00080 #endif
00081 
00082 
00083   /*
00084    *  We are not using `af_angle_atan' anymore, but we keep the source
00085    *  code below just in case...
00086    */
00087 
00088 
00089 #if 0
00090 
00091 
00092   /*
00093    *  The trick here is to realize that we don't need a very accurate angle
00094    *  approximation.  We are going to use the result of `af_angle_atan' to
00095    *  only compare the sign of angle differences, or check whether its
00096    *  magnitude is very small.
00097    *
00098    *  The approximation
00099    *
00100    *    dy * PI / (|dx|+|dy|)
00101    *
00102    *  should be enough, and much faster to compute.
00103    */
00104   FT_LOCAL_DEF( AF_Angle )
00105   af_angle_atan( FT_Fixed  dx,
00106                  FT_Fixed  dy )
00107   {
00108     AF_Angle  angle;
00109     FT_Fixed  ax = dx;
00110     FT_Fixed  ay = dy;
00111 
00112 
00113     if ( ax < 0 )
00114       ax = -ax;
00115     if ( ay < 0 )
00116       ay = -ay;
00117 
00118     ax += ay;
00119 
00120     if ( ax == 0 )
00121       angle = 0;
00122     else
00123     {
00124       angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay );
00125       if ( dx < 0 )
00126       {
00127         if ( angle >= 0 )
00128           angle = AF_ANGLE_PI - angle;
00129         else
00130           angle = -AF_ANGLE_PI - angle;
00131       }
00132     }
00133 
00134     return angle;
00135   }
00136 
00137 
00138 #elif 0
00139 
00140 
00141   /* the following table has been automatically generated with */
00142   /* the `mather.py' Python script                             */
00143 
00144 #define AF_ATAN_BITS  8
00145 
00146   static const FT_Byte  af_arctan[1L << AF_ATAN_BITS] =
00147   {
00148      0,  0,  1,  1,  1,  2,  2,  2,
00149      3,  3,  3,  3,  4,  4,  4,  5,
00150      5,  5,  6,  6,  6,  7,  7,  7,
00151      8,  8,  8,  9,  9,  9, 10, 10,
00152     10, 10, 11, 11, 11, 12, 12, 12,
00153     13, 13, 13, 14, 14, 14, 14, 15,
00154     15, 15, 16, 16, 16, 17, 17, 17,
00155     18, 18, 18, 18, 19, 19, 19, 20,
00156     20, 20, 21, 21, 21, 21, 22, 22,
00157     22, 23, 23, 23, 24, 24, 24, 24,
00158     25, 25, 25, 26, 26, 26, 26, 27,
00159     27, 27, 28, 28, 28, 28, 29, 29,
00160     29, 30, 30, 30, 30, 31, 31, 31,
00161     31, 32, 32, 32, 33, 33, 33, 33,
00162     34, 34, 34, 34, 35, 35, 35, 35,
00163     36, 36, 36, 36, 37, 37, 37, 38,
00164     38, 38, 38, 39, 39, 39, 39, 40,
00165     40, 40, 40, 41, 41, 41, 41, 42,
00166     42, 42, 42, 42, 43, 43, 43, 43,
00167     44, 44, 44, 44, 45, 45, 45, 45,
00168     46, 46, 46, 46, 46, 47, 47, 47,
00169     47, 48, 48, 48, 48, 48, 49, 49,
00170     49, 49, 50, 50, 50, 50, 50, 51,
00171     51, 51, 51, 51, 52, 52, 52, 52,
00172     52, 53, 53, 53, 53, 53, 54, 54,
00173     54, 54, 54, 55, 55, 55, 55, 55,
00174     56, 56, 56, 56, 56, 57, 57, 57,
00175     57, 57, 57, 58, 58, 58, 58, 58,
00176     59, 59, 59, 59, 59, 59, 60, 60,
00177     60, 60, 60, 61, 61, 61, 61, 61,
00178     61, 62, 62, 62, 62, 62, 62, 63,
00179     63, 63, 63, 63, 63, 64, 64, 64
00180   };
00181 
00182 
00183   FT_LOCAL_DEF( AF_Angle )
00184   af_angle_atan( FT_Fixed  dx,
00185                  FT_Fixed  dy )
00186   {
00187     AF_Angle  angle;
00188 
00189 
00190     /* check trivial cases */
00191     if ( dy == 0 )
00192     {
00193       angle = 0;
00194       if ( dx < 0 )
00195         angle = AF_ANGLE_PI;
00196       return angle;
00197     }
00198     else if ( dx == 0 )
00199     {
00200       angle = AF_ANGLE_PI2;
00201       if ( dy < 0 )
00202         angle = -AF_ANGLE_PI2;
00203       return angle;
00204     }
00205 
00206     angle = 0;
00207     if ( dx < 0 )
00208     {
00209       dx = -dx;
00210       dy = -dy;
00211       angle = AF_ANGLE_PI;
00212     }
00213 
00214     if ( dy < 0 )
00215     {
00216       FT_Pos  tmp;
00217 
00218 
00219       tmp = dx;
00220       dx  = -dy;
00221       dy  = tmp;
00222       angle -= AF_ANGLE_PI2;
00223     }
00224 
00225     if ( dx == 0 && dy == 0 )
00226       return 0;
00227 
00228     if ( dx == dy )
00229       angle += AF_ANGLE_PI4;
00230     else if ( dx > dy )
00231       angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )];
00232     else
00233       angle += AF_ANGLE_PI2 -
00234                af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )];
00235 
00236     if ( angle > AF_ANGLE_PI )
00237       angle -= AF_ANGLE_2PI;
00238 
00239     return angle;
00240   }
00241 
00242 
00243 #endif /* 0 */
00244 
00245 
00246   FT_LOCAL_DEF( void )
00247   af_sort_pos( FT_UInt  count,
00248                FT_Pos*  table )
00249   {
00250     FT_UInt  i, j;
00251     FT_Pos   swap;
00252 
00253 
00254     for ( i = 1; i < count; i++ )
00255     {
00256       for ( j = i; j > 0; j-- )
00257       {
00258         if ( table[j] > table[j - 1] )
00259           break;
00260 
00261         swap         = table[j];
00262         table[j]     = table[j - 1];
00263         table[j - 1] = swap;
00264       }
00265     }
00266   }
00267 
00268 
00269   FT_LOCAL_DEF( void )
00270   af_sort_widths( FT_UInt   count,
00271                   AF_Width  table )
00272   {
00273     FT_UInt      i, j;
00274     AF_WidthRec  swap;
00275 
00276 
00277     for ( i = 1; i < count; i++ )
00278     {
00279       for ( j = i; j > 0; j-- )
00280       {
00281         if ( table[j].org > table[j - 1].org )
00282           break;
00283 
00284         swap         = table[j];
00285         table[j]     = table[j - 1];
00286         table[j - 1] = swap;
00287       }
00288     }
00289   }
00290 
00291 
00292 /* END */

Generated on Tue Jul 5 14:13:41 2011 for ROOT_528-00b_version by  doxygen 1.5.1