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/*                                                                         */
7727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  Copyright 2001-2005, 2012-2013 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
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_Fixed
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  {
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed  s;
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int64  v;
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s   = val;
68727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    val = FT_ABS( val );
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v   = ( val * (FT_Int64)FT_TRIG_SCALE ) + 0x100000000UL;
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    val = (FT_Fixed)( v >> 32 );
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s >= 0 ) ? val : -val;
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
76727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#else /* !FT_LONG64 */
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* multiply a given value by the CORDIC shrink factor */
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Fixed
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_downscale( FT_Fixed  val )
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed   s;
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  v1, v2, k1, k2, hi, lo1, lo2, lo3;
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s   = val;
87727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    val = FT_ABS( val );
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v1 = (FT_UInt32)val >> 16;
90727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    v2 = (FT_UInt32)( val & 0xFFFFL );
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
92727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    k1 = (FT_UInt32)FT_TRIG_SCALE >> 16;           /* constant */
93727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    k2 = (FT_UInt32)( FT_TRIG_SCALE & 0xFFFFL );   /* constant */
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi   = k1 * v1;
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo1  = k1 * v2 + k2 * v1;       /* can't overflow */
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo2  = ( k2 * v2 ) >> 16;
99727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    lo3  = FT_MAX( lo1, lo2 );
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo1 += lo2;
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi  += lo1 >> 16;
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( lo1 < lo3 )
104295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      hi += (FT_UInt32)0x10000UL;
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    val  = (FT_Fixed)hi;
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s >= 0 ) ? val : -val;
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
111727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* !FT_LONG64 */
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_Int
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_prenorm( FT_Vector*  vec )
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
117727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Pos  x, y;
118727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Int  shift;
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = vec->x;
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y = vec->y;
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    shift = FT_MSB( FT_ABS( x ) | FT_ABS( y ) );
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( shift <= FT_TRIG_SAFE_MSB )
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
128727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  = FT_TRIG_SAFE_MSB - shift;
129727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      vec->x = (FT_Pos)( (FT_ULong)x << shift );
130727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      vec->y = (FT_Pos)( (FT_ULong)y << shift );
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
134727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift -= FT_TRIG_SAFE_MSB;
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->x = x >> shift;
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      vec->y = y >> shift;
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift  = -shift;
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return shift;
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_pseudo_rotate( FT_Vector*  vec,
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Angle    theta )
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int           i;
149727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Fixed         x, y, xtemp, b;
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Fixed  *arctanptr;
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = vec->x;
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y = vec->y;
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
156727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* Rotate inside [-PI/4,PI/4] sector */
157727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    while ( theta < -FT_ANGLE_PI4 )
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
159727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      xtemp  =  y;
160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      y      = -x;
161727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      x      =  xtemp;
162727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      theta +=  FT_ANGLE_PI2;
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
165727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    while ( theta > FT_ANGLE_PI4 )
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
167727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      xtemp  = -y;
168727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      y      =  x;
169727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      x      =  xtemp;
170727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      theta -=  FT_ANGLE_PI2;
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arctanptr = ft_trig_arctan_table;
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
175727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* Pseudorotations, with right shifts */
176727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ )
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( theta < 0 )
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
180727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        xtemp  = x + ( ( y + b ) >> i );
181727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        y      = y - ( ( x + b ) >> i );
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x      = xtemp;
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        theta += *arctanptr++;
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
187727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        xtemp  = x - ( ( y + b ) >> i );
188727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        y      = y + ( ( x + b ) >> i );
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x      = xtemp;
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        theta -= *arctanptr++;
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
192727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->x = x;
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->y = y;
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_trig_pseudo_polarize( FT_Vector*  vec )
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
202727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Angle         theta;
203727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Int           i;
204727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Fixed         x, y, xtemp, b;
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Fixed  *arctanptr;
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = vec->x;
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y = vec->y;
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
211727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* Get the vector into [-PI/4,PI/4] sector */
212727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( y > x )
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
214727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( y > -x )
215727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
216727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        theta =  FT_ANGLE_PI2;
217727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        xtemp =  y;
218727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        y     = -x;
219727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        x     =  xtemp;
220727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
221727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
222727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
223727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        theta =  y > 0 ? FT_ANGLE_PI : -FT_ANGLE_PI;
224727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        x     = -x;
225727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        y     = -y;
226727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
230727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( y < -x )
231727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
232727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        theta = -FT_ANGLE_PI2;
233727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        xtemp = -y;
234727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        y     =  x;
235727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        x     =  xtemp;
236727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
237727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      else
238727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
239727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        theta = 0;
240727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
243727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    arctanptr = ft_trig_arctan_table;
244727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
245727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* Pseudorotations, with right shifts */
246727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( i = 1, b = 1; i < FT_TRIG_MAX_ITERS; b <<= 1, i++ )
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
248727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( y > 0 )
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
250727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        xtemp  = x + ( ( y + b ) >> i );
251727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        y      = y - ( ( x + b ) >> i );
252727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        x      = xtemp;
253727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        theta += *arctanptr++;
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
257727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        xtemp  = x - ( ( y + b ) >> i );
258727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        y      = y + ( ( x + b ) >> i );
259727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        x      = xtemp;
260727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        theta -= *arctanptr++;
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
262727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* round theta */
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( theta >= 0 )
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta = FT_PAD_ROUND( theta, 32 );
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      theta = -FT_PAD_ROUND( -theta, 32 );
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->x = x;
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->y = theta;
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Cos( FT_Angle  angle )
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
283727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    v.x = FT_TRIG_SCALE >> 8;
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.y = 0;
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_rotate( &v, angle );
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
287727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return ( v.x + 0x80L ) >> 8;
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Sin( FT_Angle  angle )
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_Cos( FT_ANGLE_PI2 - angle );
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Tan( FT_Angle  angle )
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    v.x = FT_TRIG_SCALE >> 8;
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.y = 0;
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_rotate( &v, angle );
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return FT_DivFix( v.y, v.x );
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Angle )
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Atan2( FT_Fixed  dx,
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Fixed  dy )
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx == 0 && dy == 0 )
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.x = dx;
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.y = dy;
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_prenorm( &v );
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_polarize( &v );
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return v.y;
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Unit( FT_Vector*  vec,
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                  FT_Angle    angle )
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
343727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    vec->x = FT_TRIG_SCALE >> 8;
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->y = 0;
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_rotate( vec, angle );
346727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    vec->x = ( vec->x + 0x80L ) >> 8;
347727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    vec->y = ( vec->y + 0x80L ) >> 8;
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* these macros return 0 for positive numbers,
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     and -1 for negative ones */
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_LONG( x )   ( (x) >> ( FT_SIZEOF_LONG * 8 - 1 ) )
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_INT( x )    ( (x) >> ( FT_SIZEOF_INT * 8 - 1 ) )
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_INT32( x )  ( (x) >> 31 )
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_SIGN_INT16( x )  ( (x) >> 15 )
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Rotate( FT_Vector*  vec,
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    FT_Angle    angle )
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     shift;
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.x   = vec->x;
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.y   = vec->y;
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( angle && ( v.x != 0 || v.y != 0 ) )
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      shift = ft_trig_prenorm( &v );
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_trig_pseudo_rotate( &v, angle );
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v.x = ft_trig_downscale( v.x );
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v.y = ft_trig_downscale( v.y );
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( shift > 0 )
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
381295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        FT_Int32  half = (FT_Int32)1L << ( shift - 1 );
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        vec->x = ( v.x + half + FT_SIGN_LONG( v.x ) ) >> shift;
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        vec->y = ( v.y + half + FT_SIGN_LONG( v.y ) ) >> shift;
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        shift  = -shift;
390727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vec->x = (FT_Pos)( (FT_ULong)v.x << shift );
391727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        vec->y = (FT_Pos)( (FT_ULong)v.y << shift );
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Length( FT_Vector*  vec )
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     shift;
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v = *vec;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* handle trivial cases */
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( v.x == 0 )
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
411727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_ABS( v.y );
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( v.y == 0 )
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
415727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_ABS( v.x );
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* general case */
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    shift = ft_trig_prenorm( &v );
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_trig_pseudo_polarize( &v );
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v.x = ft_trig_downscale( v.x );
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( shift > 0 )
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ( v.x + ( 1 << ( shift - 1 ) ) ) >> shift;
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
427727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return (FT_Fixed)( (FT_UInt32)v.x << -shift );
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Polarize( FT_Vector*  vec,
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Fixed   *length,
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Angle   *angle )
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     shift;
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector  v;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    v = *vec;
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( v.x == 0 && v.y == 0 )
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
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
452727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *length = ( shift >= 0 ) ?                      ( v.x >>  shift )
453727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                             : (FT_Fixed)( (FT_UInt32)v.x << -shift );
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *angle  = v.y;
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_From_Polar( FT_Vector*  vec,
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Fixed    length,
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                        FT_Angle    angle )
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->x = length;
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec->y = 0;
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector_Rotate( vec, angle );
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in fttrigon.h */
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Angle )
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Angle_Diff( FT_Angle  angle1,
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Angle  angle2 )
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Angle  delta = angle2 - angle1;
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta %= FT_ANGLE_2PI;
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta < 0 )
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta += FT_ANGLE_2PI;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta > FT_ANGLE_PI )
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta -= FT_ANGLE_2PI;
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return delta;
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
493