ref: c7bc9b79073562ff7cc2c3499e1b97343430eb88
dir: /src/autofit/afangles.c/
/***************************************************************************/ /* */ /* afangles.c */ /* */ /* Routines used to compute vector angles with limited accuracy */ /* and very high speed. It also contains sorting routines (body). */ /* */ /* Copyright 2003, 2004, 2005, 2006 by */ /* David Turner, Robert Wilhelm, and Werner Lemberg. */ /* */ /* This file is part of the FreeType project, and may only be used, */ /* modified, and distributed under the terms of the FreeType project */ /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ /* this file you indicate that you have read the license and */ /* understand and accept it fully. */ /* */ /***************************************************************************/ #include "aftypes.h" FT_LOCAL_DEF( FT_Int ) af_corner_is_flat( FT_Pos x_in, FT_Pos y_in, FT_Pos x_out, FT_Pos y_out ) { FT_Pos ax = x_in; FT_Pos ay = y_in; FT_Pos d_in, d_out, d_corner; if ( ax < 0 ) ax = -ax; if ( ay < 0 ) ay = -ay; d_in = ax + ay; ax = x_out; if ( ax < 0 ) ax = -ax; ay = y_out; if ( ay < 0 ) ay = -ay; d_out = ax + ay; ax = x_out + x_in; if ( ax < 0 ) ax = -ax; ay = y_out + y_in; if ( ay < 0 ) ay = -ay; d_corner = ax + ay; return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); } FT_LOCAL_DEF( FT_Int ) af_corner_orientation( FT_Pos x_in, FT_Pos y_in, FT_Pos x_out, FT_Pos y_out ) { FT_Pos delta; delta = x_in * y_out - y_in * x_out; if ( delta == 0 ) return 0; else return 1 - 2 * ( delta < 0 ); } /* * We are not using `af_angle_atan' anymore, but we keep the source * code below just in case... */ #if 0 /* * The trick here is to realize that we don't need a very accurate angle * approximation. We are going to use the result of `af_angle_atan' to * only compare the sign of angle differences, or check whether its * magnitude is very small. * * The approximation * * dy * PI / (|dx|+|dy|) * * should be enough, and much faster to compute. */ FT_LOCAL_DEF( AF_Angle ) af_angle_atan( FT_Fixed dx, FT_Fixed dy ) { AF_Angle angle; FT_Fixed ax = dx; FT_Fixed ay = dy; if ( ax < 0 ) ax = -ax; if ( ay < 0 ) ay = -ay; ax += ay; if ( ax == 0 ) angle = 0; else { angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay ); if ( dx < 0 ) { if ( angle >= 0 ) angle = AF_ANGLE_PI - angle; else angle = -AF_ANGLE_PI - angle; } } return angle; } #elif 0 /* the following table has been automatically generated with */ /* the `mather.py' Python script */ #define AF_ATAN_BITS 8 static const FT_Byte af_arctan[1L << AF_ATAN_BITS] = { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 56, 57, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 64, 64, 64 }; FT_LOCAL_DEF( AF_Angle ) af_angle_atan( FT_Fixed dx, FT_Fixed dy ) { AF_Angle angle; /* check trivial cases */ if ( dy == 0 ) { angle = 0; if ( dx < 0 ) angle = AF_ANGLE_PI; return angle; } else if ( dx == 0 ) { angle = AF_ANGLE_PI2; if ( dy < 0 ) angle = -AF_ANGLE_PI2; return angle; } angle = 0; if ( dx < 0 ) { dx = -dx; dy = -dy; angle = AF_ANGLE_PI; } if ( dy < 0 ) { FT_Pos tmp; tmp = dx; dx = -dy; dy = tmp; angle -= AF_ANGLE_PI2; } if ( dx == 0 && dy == 0 ) return 0; if ( dx == dy ) angle += AF_ANGLE_PI4; else if ( dx > dy ) angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )]; else angle += AF_ANGLE_PI2 - af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )]; if ( angle > AF_ANGLE_PI ) angle -= AF_ANGLE_2PI; return angle; } #endif /* 0 */ FT_LOCAL_DEF( void ) af_sort_pos( FT_UInt count, FT_Pos* table ) { FT_UInt i, j; FT_Pos swap; for ( i = 1; i < count; i++ ) { for ( j = i; j > 0; j-- ) { if ( table[j] > table[j - 1] ) break; swap = table[j]; table[j] = table[j - 1]; table[j - 1] = swap; } } } FT_LOCAL_DEF( void ) af_sort_widths( FT_UInt count, AF_Width table ) { FT_UInt i, j; AF_WidthRec swap; for ( i = 1; i < count; i++ ) { for ( j = i; j > 0; j-- ) { if ( table[j].org > table[j - 1].org ) break; swap = table[j]; table[j] = table[j - 1]; table[j - 1] = swap; } } } /* END */