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/*                                                                         */
7049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  Copyright 2001, 2002, 2003, 2004, 2005 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
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_TRIGONOMETRY_H
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the following is 0.2715717684432231 * 2^30 */
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_TRIG_COSCALE  0x11616E8EUL
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* this table was generated for FT_PI = 180L << 16, i.e. degrees */
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_TRIG_MAX_ITERS  23
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_Fixed
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_arctan_table[24] =
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    4157273L, 2949120L, 1740967L, 919879L, 466945L, 234379L, 117304L,
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    58666L, 29335L, 14668L, 7334L, 3667L, 1833L, 917L, 458L, 229L, 115L,
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    57L, 29L, 14L, 7L, 4L, 2L, 1L
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the Cordic shrink factor, multiplied by 2^32 */
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_TRIG_SCALE    1166391785UL  /* 0x4585BA38UL */
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_CONFIG_HAS_INT64
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* multiply a given value by the CORDIC shrink factor */
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_downscale( FT_Fixed  val )
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed  s;
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int64  v;
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s   = val;
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    val = ( val >= 0 ) ? val : -val;
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v   = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL;
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    val = (FT_Fixed)( v >> 32 );
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s >= 0 ) ? val : -val;
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !FT_CONFIG_HAS_INT64 */
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* multiply a given value by the CORDIC shrink factor */
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_downscale( FT_Fixed  val )
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed   s;
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  v1, v2, k1, k2, hi, lo1, lo2, lo3;
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s   = val;
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    val = ( val >= 0 ) ? val : -val;
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v1 = (FT_UInt32)val >> 16;
75295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    v2 = (FT_UInt32)(val & 0xFFFFL);
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
77295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    k1 = (FT_UInt32)FT_TRIG_SCALE >> 16;       /* constant */
78295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    k2 = (FT_UInt32)(FT_TRIG_SCALE & 0xFFFFL);   /* constant */
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi   = k1 * v1;
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo1  = k1 * v2 + k2 * v1;       /* can't overflow */
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo2  = ( k2 * v2 ) >> 16;
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo3  = ( lo1 >= lo2 ) ? lo1 : lo2;
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo1 += lo2;
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi  += lo1 >> 16;
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( lo1 < lo3 )
89295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      hi += (FT_UInt32)0x10000UL;
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    val  = (FT_Fixed)hi;
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s >= 0 ) ? val : -val;
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* !FT_CONFIG_HAS_INT64 */
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Int
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_prenorm( FT_Vector*  vec )
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed  x, y, z;
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int    shift;
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = vec->x;
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y = vec->y;
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    z     = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    shift = 0;
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* determine msb bit index in `shift' */
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( z >= ( 1L << 16 ) )
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      z     >>= 16;
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift  += 16;
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( z >= ( 1L << 8 ) )
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      z     >>= 8;
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift  += 8;
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( z >= ( 1L << 4 ) )
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      z     >>= 4;
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift  += 4;
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( z >= ( 1L << 2 ) )
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      z     >>= 2;
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift  += 2;
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( z >= ( 1L << 1 ) )
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      z    >>= 1;
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift += 1;
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( shift <= 27 )
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift  = 27 - shift;
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->x = x << shift;
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->y = y << shift;
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift -= 27;
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->x = x >> shift;
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->y = y >> shift;
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift  = -shift;
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* 0 */
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( z < ( 1L << 27 ) )
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      do
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        shift++;
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        z <<= 1;
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      } while ( z < ( 1L << 27 ) );
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->x = x << shift;
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->y = y << shift;
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( z > ( 1L << 28 ) )
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      do
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        shift++;
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        z >>= 1;
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      } while ( z > ( 1L << 28 ) );
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->x = x >> shift;
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->y = y >> shift;
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift  = -shift;
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 0 */
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return shift;
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_pseudo_rotate( FT_Vector*  vec,
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Angle    theta )
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int           i;
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed         x, y, xtemp;
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Fixed  *arctanptr;
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = vec->x;
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y = vec->y;
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Get angle between -90 and 90 degrees */
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( theta <= -FT_ANGLE_PI2 )
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x = -x;
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y = -y;
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta += FT_ANGLE_PI;
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( theta > FT_ANGLE_PI2 )
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x = -x;
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y = -y;
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta -= FT_ANGLE_PI;
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Initial pseudorotation, with left shift */
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arctanptr = ft_trig_arctan_table;
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( theta < 0 )
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      xtemp  = x + ( y << 1 );
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y      = y - ( x << 1 );
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x      = xtemp;
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta += *arctanptr++;
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      xtemp  = x - ( y << 1 );
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y      = y + ( x << 1 );
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x      = xtemp;
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta -= *arctanptr++;
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Subsequent pseudorotations, with right shifts */
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i = 0;
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    do
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( theta < 0 )
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        xtemp  = x + ( y >> i );
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y      = y - ( x >> i );
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x      = xtemp;
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        theta += *arctanptr++;
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        xtemp  = x - ( y >> i );
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y      = y + ( x >> i );
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x      = xtemp;
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        theta -= *arctanptr++;
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    } while ( ++i < FT_TRIG_MAX_ITERS );
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->x = x;
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->y = y;
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_pseudo_polarize( FT_Vector*  vec )
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed         theta;
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed         yi, i;
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed         x, y;
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Fixed  *arctanptr;
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = vec->x;
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y = vec->y;
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Get the vector into the right half plane */
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    theta = 0;
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( x < 0 )
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x = -x;
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y = -y;
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta = 2 * FT_ANGLE_PI2;
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( y > 0 )
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta = - theta;
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arctanptr = ft_trig_arctan_table;
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( y < 0 )
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Rotate positive */
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      yi     = y + ( x << 1 );
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x      = x - ( y << 1 );
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y      = yi;
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta -= *arctanptr++;  /* Subtract angle */
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* Rotate negative */
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      yi     = y - ( x << 1 );
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x      = x + ( y << 1 );
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      y      = yi;
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta += *arctanptr++;  /* Add angle */
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i = 0;
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    do
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( y < 0 )
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Rotate positive */
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        yi     = y + ( x >> i );
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x      = x - ( y >> i );
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y      = yi;
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        theta -= *arctanptr++;
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* Rotate negative */
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        yi     = y - ( x >> i );
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x      = x + ( y >> i );
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y      = yi;
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        theta += *arctanptr++;
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    } while ( ++i < FT_TRIG_MAX_ITERS );
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* round theta */
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( theta >= 0 )
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta = FT_PAD_ROUND( theta, 32 );
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta = -FT_PAD_ROUND( -theta, 32 );
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->x = x;
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->y = theta;
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Cos( FT_Angle  angle )
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.x = FT_TRIG_COSCALE >> 2;
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.y = 0;
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_rotate( &v, angle );
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return v.x / ( 1 << 12 );
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Sin( FT_Angle  angle )
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Cos( FT_ANGLE_PI2 - angle );
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Tan( FT_Angle  angle )
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.x = FT_TRIG_COSCALE >> 2;
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.y = 0;
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_rotate( &v, angle );
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_DivFix( v.y, v.x );
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Angle )
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Atan2( FT_Fixed  dx,
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Fixed  dy )
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx == 0 && dy == 0 )
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.x = dx;
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.y = dy;
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_prenorm( &v );
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_polarize( &v );
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return v.y;
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Unit( FT_Vector*  vec,
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Angle    angle )
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->x = FT_TRIG_COSCALE >> 2;
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->y = 0;
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_rotate( vec, angle );
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->x >>= 12;
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->y >>= 12;
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* these macros return 0 for positive numbers,
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     and -1 for negative ones */
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_LONG( x )   ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) )
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_INT( x )    ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) )
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_INT32( x )  ( (x) >> 31 )
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_INT16( x )  ( (x) >> 15 )
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Rotate( FT_Vector*  vec,
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Angle    angle )
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     shift;
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.x   = vec->x;
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.y   = vec->y;
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( angle && ( v.x != 0 || v.y != 0 ) )
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift = ft_trig_prenorm( &v );
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_trig_pseudo_rotate( &v, angle );
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v.x = ft_trig_downscale( v.x );
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v.y = ft_trig_downscale( v.y );
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( shift > 0 )
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
436295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_Int32  half = (FT_Int32)1L << ( shift - 1 );
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift;
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        shift  = -shift;
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        vec->x = v.x << shift;
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        vec->y = v.y << shift;
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Length( FT_Vector*  vec )
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     shift;
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v = *vec;
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* handle trivial cases */
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( v.x == 0 )
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ( v.y >= 0 ) ? v.y : -v.y;
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( v.y == 0 )
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ( v.x >= 0 ) ? v.x : -v.x;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* general case */
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    shift = ft_trig_prenorm( &v );
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_polarize( &v );
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.x = ft_trig_downscale( v.x );
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( shift > 0 )
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return v.x << -shift;
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Polarize( FT_Vector*  vec,
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Fixed   *length,
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Angle   *angle )
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     shift;
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v = *vec;
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( v.x == 0 && v.y == 0 )
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    shift = ft_trig_prenorm( &v );
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_polarize( &v );
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.x = ft_trig_downscale( v.x );
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *length = ( shift >= 0 ) ? ( v.x >> shift ) : ( v.x << -shift );
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *angle  = v.y;
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_From_Polar( FT_Vector*  vec,
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Fixed    length,
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Angle    angle )
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->x = length;
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->y = 0;
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector_Rotate( vec, angle );
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Angle )
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Angle_Diff( FT_Angle  angle1,
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Angle  angle2 )
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Angle  delta = angle2 - angle1;
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta %= FT_ANGLE_2PI;
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta < 0 )
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta += FT_ANGLE_2PI;
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta > FT_ANGLE_PI )
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta -= FT_ANGLE_2PI;
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return delta;
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
547