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