1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* fttrigon.c */ 4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* FreeType trigonometric functions (body). */ 6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 7ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki/* Copyright 2001-2015 by */ 8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* This file is part of the FreeType project, and may only be used, */ 11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* modified, and distributed under the terms of the FreeType project */ 12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* this file you indicate that you have read the license and */ 14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* understand and accept it fully. */ 15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* */ 16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/ 17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 18727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /*************************************************************************/ 19727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* */ 20727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* This is a fixed-point CORDIC implementation of trigonometric */ 21727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* functions as well as transformations between Cartesian and polar */ 22727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* coordinates. The angles are represented as 16.16 fixed-point values */ 23727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* in degrees, i.e., the angular resolution is 2^-16 degrees. Note that */ 24727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* only vectors longer than 2^16*180/pi (or at least 22 bits) on a */ 25727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* discrete Cartesian grid can have the same or better angular */ 26727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* resolution. Therefore, to maintain this precision, some functions */ 27727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* require an interim upscaling of the vectors, whereas others operate */ 28727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* with 24-bit long vectors directly. */ 29727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* */ 30727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /*************************************************************************/ 31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h> 33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H 34727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_INTERNAL_CALC_H 35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRIGONOMETRY_H 36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 38727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* the Cordic shrink factor 0.858785336480436 * 2^32 */ 39727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_TRIG_SCALE 0xDBD95B16UL 40727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 41727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* the highest bit in overflow-safe vector components, */ 42727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* MSB of 0.858785336480436 * sqrt(0.5) * 2^30 */ 43727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_TRIG_SAFE_MSB 29 44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* this table was generated for FT_PI = 180L << 16, i.e. degrees */ 46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_TRIG_MAX_ITERS 23 47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 48ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki static const FT_Angle 49727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease ft_trig_arctan_table[] = 50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 51727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 1740967L, 919879L, 466945L, 234379L, 117304L, 58666L, 29335L, 52727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L, 53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 57L, 29L, 14L, 7L, 4L, 2L, 1L 54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project }; 55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 57727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifdef FT_LONG64 58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* multiply a given value by the CORDIC shrink factor */ 60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Fixed 61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_downscale( FT_Fixed val ) 62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 63ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Int s = 1; 64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 66ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( val < 0 ) 67ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki { 68ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki val = -val; 69ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki s = -1; 70ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki } 71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 72ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* 0x40000000 comes from regression analysis between true */ 73ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* and CORDIC hypotenuse, so it minimizes the error */ 74ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki val = (FT_Fixed)( ( (FT_Int64)val * FT_TRIG_SCALE + 0x40000000UL ) >> 32 ); 75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 76ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return s < 0 ? -val : val; 77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 79727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#else /* !FT_LONG64 */ 80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* multiply a given value by the CORDIC shrink factor */ 82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Fixed 83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_downscale( FT_Fixed val ) 84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 85ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Int s = 1; 86ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; 87ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 88ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 89ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( val < 0 ) 90ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki { 91ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki val = -val; 92ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki s = -1; 93ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki } 94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 95ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki lo1 = (FT_UInt32)val & 0x0000FFFFU; 96ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki hi1 = (FT_UInt32)val >> 16; 97ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki lo2 = FT_TRIG_SCALE & 0x0000FFFFU; 98ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki hi2 = FT_TRIG_SCALE >> 16; 99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 100ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki lo = lo1 * lo2; 101ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki i1 = lo1 * hi2; 102ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki i2 = lo2 * hi1; 103ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki hi = hi1 * hi2; 104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 105ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* Check carry overflow of i1 + i2 */ 106ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki i1 += i2; 107ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki hi += (FT_UInt32)( i1 < i2 ) << 16; 108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 109ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki hi += i1 >> 16; 110ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki i1 = i1 << 16; 111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 112ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* Check carry overflow of i1 + lo */ 113ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki lo += i1; 114ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki hi += ( lo < i1 ); 115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 116ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* 0x40000000 comes from regression analysis between true */ 117ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* and CORDIC hypotenuse, so it minimizes the error */ 118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 119ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* Check carry overflow of lo + 0x40000000 */ 120ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki lo += 0x40000000UL; 121ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki hi += ( lo < 0x40000000UL ); 122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 123ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki val = (FT_Fixed)hi; 124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 125ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return s < 0 ? -val : val; 126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 128727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* !FT_LONG64 */ 129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 131ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* undefined and never called for zero vector */ 132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static FT_Int 133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_prenorm( FT_Vector* vec ) 134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 135727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Pos x, y; 136727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int shift; 137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x = vec->x; 140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project y = vec->y; 141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 142ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki shift = FT_MSB( (FT_UInt32)( FT_ABS( x ) | FT_ABS( y ) ) ); 143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 144727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( shift <= FT_TRIG_SAFE_MSB ) 145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 146727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease shift = FT_TRIG_SAFE_MSB - shift; 147727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease vec->x = (FT_Pos)( (FT_ULong)x << shift ); 148727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease vec->y = (FT_Pos)( (FT_ULong)y << shift ); 149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 152727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease shift -= FT_TRIG_SAFE_MSB; 153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->x = x >> shift; 154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->y = y >> shift; 155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project shift = -shift; 156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return shift; 159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_pseudo_rotate( FT_Vector* vec, 164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Angle theta ) 165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int i; 167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Fixed x, y, xtemp, b; 168ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki const FT_Angle *arctanptr; 169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x = vec->x; 172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project y = vec->y; 173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 174727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Rotate inside [-PI/4,PI/4] sector */ 175727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease while ( theta < -FT_ANGLE_PI4 ) 176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 177727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease xtemp = y; 178727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y = -x; 179727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x = xtemp; 180727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease theta += FT_ANGLE_PI2; 181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 183727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease while ( theta > FT_ANGLE_PI4 ) 184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 185727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease xtemp = -y; 186727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y = x; 187727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x = xtemp; 188727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease theta -= FT_ANGLE_PI2; 189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project arctanptr = ft_trig_arctan_table; 192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 193727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Pseudorotations, with right shifts */ 194727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ ) 195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( theta < 0 ) 197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 198727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease xtemp = x + ( ( y + b ) >> i ); 199727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y = y - ( ( x + b ) >> i ); 200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x = xtemp; 201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project theta += *arctanptr++; 202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 205727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease xtemp = x - ( ( y + b ) >> i ); 206727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y = y + ( ( x + b ) >> i ); 207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x = xtemp; 208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project theta -= *arctanptr++; 209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 210727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->x = x; 213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->y = y; 214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project static void 218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_pseudo_polarize( FT_Vector* vec ) 219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 220727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Angle theta; 221727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Int i; 222727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease FT_Fixed x, y, xtemp, b; 223ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki const FT_Angle *arctanptr; 224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project x = vec->x; 227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project y = vec->y; 228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 229727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Get the vector into [-PI/4,PI/4] sector */ 230727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( y > x ) 231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 232727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( y > -x ) 233727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 234727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease theta = FT_ANGLE_PI2; 235727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease xtemp = y; 236727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y = -x; 237727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x = xtemp; 238727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 239727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 240727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 241727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease theta = y > 0 ? FT_ANGLE_PI : -FT_ANGLE_PI; 242727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x = -x; 243727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y = -y; 244727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 248727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( y < -x ) 249727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 250727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease theta = -FT_ANGLE_PI2; 251727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease xtemp = -y; 252727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y = x; 253727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x = xtemp; 254727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 255727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease else 256727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease { 257727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease theta = 0; 258727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 261727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease arctanptr = ft_trig_arctan_table; 262727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease 263727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease /* Pseudorotations, with right shifts */ 264727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ ) 265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 266727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease if ( y > 0 ) 267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 268727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease xtemp = x + ( ( y + b ) >> i ); 269727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y = y - ( ( x + b ) >> i ); 270727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x = xtemp; 271727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease theta += *arctanptr++; 272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 275727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease xtemp = x - ( ( y + b ) >> i ); 276727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease y = y + ( ( x + b ) >> i ); 277727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease x = xtemp; 278727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease theta -= *arctanptr++; 279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 280727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease } 281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 282ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* round theta to acknowledge its error that mostly comes */ 283ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki /* from accumulated rounding errors in the arctan table */ 284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( theta >= 0 ) 285ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki theta = FT_PAD_ROUND( theta, 16 ); 286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else 287ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki theta = -FT_PAD_ROUND( -theta, 16 ); 288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->x = x; 290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->y = theta; 291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( FT_Fixed ) 297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Cos( FT_Angle angle ) 298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector v; 300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 302ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Vector_Unit( &v, angle ); 303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 304ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return v.x; 305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( FT_Fixed ) 311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Sin( FT_Angle angle ) 312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 313ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Vector v; 314ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 315ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 316ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Vector_Unit( &v, angle ); 317ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 318ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return v.y; 319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( FT_Fixed ) 325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Tan( FT_Angle angle ) 326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector v; 328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 330ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Vector_Unit( &v, angle ); 331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return FT_DivFix( v.y, v.x ); 333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( FT_Angle ) 339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Atan2( FT_Fixed dx, 340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed dy ) 341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector v; 343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( dx == 0 && dy == 0 ) 346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return 0; 347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project v.x = dx; 349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project v.y = dy; 350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_prenorm( &v ); 351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_pseudo_polarize( &v ); 352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return v.y; 354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( void ) 360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector_Unit( FT_Vector* vec, 361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Angle angle ) 362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 363ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( !vec ) 364ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return; 365ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 366727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease vec->x = FT_TRIG_SCALE >> 8; 367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->y = 0; 368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_pseudo_rotate( vec, angle ); 369727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease vec->x = ( vec->x + 0x80L ) >> 8; 370727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease vec->y = ( vec->y + 0x80L ) >> 8; 371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* these macros return 0 for positive numbers, 375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project and -1 for negative ones */ 376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_LONG( x ) ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) ) 377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_INT( x ) ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) ) 378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_INT32( x ) ( (x) >> 31 ) 379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_INT16( x ) ( (x) >> 15 ) 380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( void ) 385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector_Rotate( FT_Vector* vec, 386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Angle angle ) 387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int shift; 389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector v; 390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 392ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( !vec || !angle ) 393ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return; 394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 395ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki v = *vec; 396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 397ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( v.x == 0 && v.y == 0 ) 398ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return; 399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 400ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki shift = ft_trig_prenorm( &v ); 401ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki ft_trig_pseudo_rotate( &v, angle ); 402ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki v.x = ft_trig_downscale( v.x ); 403ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki v.y = ft_trig_downscale( v.y ); 404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 405ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( shift > 0 ) 406ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki { 407ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki FT_Int32 half = (FT_Int32)1L << ( shift - 1 ); 408ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 409ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 410ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift; 411ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift; 412ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki } 413ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki else 414ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki { 415ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki shift = -shift; 416ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki vec->x = (FT_Pos)( (FT_ULong)v.x << shift ); 417ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki vec->y = (FT_Pos)( (FT_ULong)v.y << shift ); 418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( FT_Fixed ) 425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector_Length( FT_Vector* vec ) 426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int shift; 428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector v; 429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 431ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( !vec ) 432ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return 0; 433ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project v = *vec; 435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* handle trivial cases */ 437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( v.x == 0 ) 438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 439727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_ABS( v.y ); 440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project else if ( v.y == 0 ) 442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 443727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return FT_ABS( v.x ); 444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* general case */ 447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project shift = ft_trig_prenorm( &v ); 448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_pseudo_polarize( &v ); 449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project v.x = ft_trig_downscale( v.x ); 451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( shift > 0 ) 453ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return ( v.x + ( 1L << ( shift - 1 ) ) ) >> shift; 454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 455727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease return (FT_Fixed)( (FT_UInt32)v.x << -shift ); 456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( void ) 462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector_Polarize( FT_Vector* vec, 463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed *length, 464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Angle *angle ) 465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Int shift; 467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector v; 468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 470ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( !vec || !length || !angle ) 471ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return; 472ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project v = *vec; 474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project if ( v.x == 0 && v.y == 0 ) 476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return; 477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project shift = ft_trig_prenorm( &v ); 479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project ft_trig_pseudo_polarize( &v ); 480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project v.x = ft_trig_downscale( v.x ); 482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 483ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki *length = shift >= 0 ? ( v.x >> shift ) 484ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki : (FT_Fixed)( (FT_UInt32)v.x << -shift ); 485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project *angle = v.y; 486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( void ) 492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector_From_Polar( FT_Vector* vec, 493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Fixed length, 494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Angle angle ) 495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 496ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki if ( !vec ) 497ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki return; 498ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki 499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->x = length; 500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project vec->y = 0; 501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Vector_Rotate( vec, angle ); 503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project /* documentation is in fttrigon.h */ 507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_EXPORT_DEF( FT_Angle ) 509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Angle_Diff( FT_Angle angle1, 510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Angle angle2 ) 511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project { 512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project FT_Angle delta = angle2 - angle1; 513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 515ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki while ( delta <= -FT_ANGLE_PI ) 516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta += FT_ANGLE_2PI; 517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 518ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki while ( delta > FT_ANGLE_PI ) 519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project delta -= FT_ANGLE_2PI; 520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project return delta; 522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project } 523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project 525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */ 526