1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  afangles.c                                                             */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    Routines used to compute vector angles with limited accuracy         */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    and very high speed.  It also contains sorting routines (body).      */
7049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
8727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/*  Copyright 2003-2006, 2011-2012 by                                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "aftypes.h"
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Int )
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  af_corner_is_flat( FT_Pos  x_in,
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pos  y_in,
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pos  x_out,
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pos  y_out )
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos  ax = x_in;
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos  ay = y_in;
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos  d_in, d_out, d_corner;
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ax < 0 )
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ax = -ax;
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ay < 0 )
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ay = -ay;
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d_in = ax + ay;
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ax = x_out;
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ax < 0 )
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ax = -ax;
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ay = y_out;
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ay < 0 )
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ay = -ay;
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d_out = ax + ay;
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ax = x_out + x_in;
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ax < 0 )
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ax = -ax;
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ay = y_out + y_in;
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ay < 0 )
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ay = -ay;
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d_corner = ax + ay;
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( FT_Int )
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  af_corner_orientation( FT_Pos  x_in,
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos  y_in,
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos  x_out,
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos  y_out )
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos  delta;
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta = x_in * y_out - y_in * x_out;
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( delta == 0 )
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 1 - 2 * ( delta < 0 );
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
80aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner#endif /* 0 */
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  We are not using `af_angle_atan' anymore, but we keep the source
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  code below just in case...
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   */
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  The trick here is to realize that we don't need a very accurate angle
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  approximation.  We are going to use the result of `af_angle_atan' to
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  only compare the sign of angle differences, or check whether its
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  magnitude is very small.
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  The approximation
99049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *
100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *    dy * PI / (|dx|+|dy|)
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   *  should be enough, and much faster to compute.
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   */
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( AF_Angle )
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  af_angle_atan( FT_Fixed  dx,
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Fixed  dy )
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    AF_Angle  angle;
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed  ax = dx;
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed  ay = dy;
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ax < 0 )
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ax = -ax;
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ay < 0 )
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ay = -ay;
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ax += ay;
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ax == 0 )
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle = 0;
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle = ( AF_ANGLE_PI2 * dy ) / ( ax + ay );
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( dx < 0 )
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( angle >= 0 )
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          angle = AF_ANGLE_PI - angle;
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          angle = -AF_ANGLE_PI - angle;
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return angle;
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#elif 0
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the following table has been automatically generated with */
142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* the `mather.py' Python script                             */
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define AF_ATAN_BITS  8
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static const FT_Byte  af_arctan[1L << AF_ATAN_BITS] =
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     0,  0,  1,  1,  1,  2,  2,  2,
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     3,  3,  3,  3,  4,  4,  4,  5,
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     5,  5,  6,  6,  6,  7,  7,  7,
151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project     8,  8,  8,  9,  9,  9, 10, 10,
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    10, 10, 11, 11, 11, 12, 12, 12,
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    13, 13, 13, 14, 14, 14, 14, 15,
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    15, 15, 16, 16, 16, 17, 17, 17,
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    18, 18, 18, 18, 19, 19, 19, 20,
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    20, 20, 21, 21, 21, 21, 22, 22,
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    22, 23, 23, 23, 24, 24, 24, 24,
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    25, 25, 25, 26, 26, 26, 26, 27,
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    27, 27, 28, 28, 28, 28, 29, 29,
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    29, 30, 30, 30, 30, 31, 31, 31,
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    31, 32, 32, 32, 33, 33, 33, 33,
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    34, 34, 34, 34, 35, 35, 35, 35,
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    36, 36, 36, 36, 37, 37, 37, 38,
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    38, 38, 38, 39, 39, 39, 39, 40,
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    40, 40, 40, 41, 41, 41, 41, 42,
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    42, 42, 42, 42, 43, 43, 43, 43,
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    44, 44, 44, 44, 45, 45, 45, 45,
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    46, 46, 46, 46, 46, 47, 47, 47,
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    47, 48, 48, 48, 48, 48, 49, 49,
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    49, 49, 50, 50, 50, 50, 50, 51,
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    51, 51, 51, 51, 52, 52, 52, 52,
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    52, 53, 53, 53, 53, 53, 54, 54,
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    54, 54, 54, 55, 55, 55, 55, 55,
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    56, 56, 56, 56, 56, 57, 57, 57,
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    57, 57, 57, 58, 58, 58, 58, 58,
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    59, 59, 59, 59, 59, 59, 60, 60,
177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    60, 60, 60, 61, 61, 61, 61, 61,
178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    61, 62, 62, 62, 62, 62, 62, 63,
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    63, 63, 63, 63, 63, 64, 64, 64
180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  };
181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( AF_Angle )
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  af_angle_atan( FT_Fixed  dx,
185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_Fixed  dy )
186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    AF_Angle  angle;
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* check trivial cases */
191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dy == 0 )
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle = 0;
194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( dx < 0 )
195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        angle = AF_ANGLE_PI;
196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return angle;
197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( dx == 0 )
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle = AF_ANGLE_PI2;
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( dy < 0 )
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        angle = -AF_ANGLE_PI2;
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return angle;
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    angle = 0;
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < 0 )
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx = -dx;
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dy = -dy;
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle = AF_ANGLE_PI;
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dy < 0 )
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Pos  tmp;
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      tmp = dx;
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx  = -dy;
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dy  = tmp;
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle -= AF_ANGLE_PI2;
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx == 0 && dy == 0 )
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx == dy )
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle += AF_ANGLE_PI4;
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( dx > dy )
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle += af_arctan[FT_DivFix( dy, dx ) >> ( 16 - AF_ATAN_BITS )];
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle += AF_ANGLE_PI2 -
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               af_arctan[FT_DivFix( dx, dy ) >> ( 16 - AF_ATAN_BITS )];
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( angle > AF_ANGLE_PI )
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      angle -= AF_ANGLE_2PI;
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return angle;
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 0 */
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  af_sort_pos( FT_UInt  count,
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project               FT_Pos*  table )
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt  i, j;
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos   swap;
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 1; i < count; i++ )
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( j = i; j > 0; j-- )
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
258727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( table[j] >= table[j - 1] )
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        swap         = table[j];
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table[j]     = table[j - 1];
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table[j - 1] = swap;
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_LOCAL_DEF( void )
270727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  af_sort_and_quantize_widths( FT_UInt*  count,
271727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                               AF_Width  table,
272727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                               FT_Pos    threshold )
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt      i, j;
275727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_UInt      cur_idx;
276727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Pos       cur_val;
277727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Pos       sum;
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    AF_WidthRec  swap;
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
281727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( *count == 1 )
282727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return;
283727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
284727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* sort */
285727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( i = 1; i < *count; i++ )
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( j = i; j > 0; j-- )
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
289727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( table[j].org >= table[j - 1].org )
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          break;
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        swap         = table[j];
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table[j]     = table[j - 1];
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        table[j - 1] = swap;
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
297727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
298727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cur_idx = 0;
299727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cur_val = table[cur_idx].org;
300727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
301727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* compute and use mean values for clusters not larger than  */
302727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* `threshold'; this is very primitive and might not yield   */
303727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* the best result, but normally, using reference character  */
304727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* `o', `*count' is 2, so the code below is fully sufficient */
305727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( i = 1; i < *count; i++ )
306727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
307727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( table[i].org - cur_val > threshold ||
308727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease           i == *count - 1                    )
309727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      {
310727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        sum = 0;
311727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
312727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        /* fix loop for end of array */
313727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( table[i].org - cur_val <= threshold &&
314727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease             i == *count - 1                     )
315727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          i++;
316727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
317727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        for ( j = cur_idx; j < i; j++ )
318727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
319727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          sum         += table[j].org;
320727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          table[j].org = 0;
321727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
322727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        table[cur_idx].org = sum / j;
323727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
324727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        if ( i < *count - 1 )
325727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        {
326727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cur_idx = i + 1;
327727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          cur_val = table[cur_idx].org;
328727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        }
329727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      }
330727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
331727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
332727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    cur_idx = 1;
333727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
334727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* compress array to remove zero values */
335727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    for ( i = 1; i < *count; i++ )
336727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
337727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      if ( table[i].org )
338727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        table[cur_idx++] = table[i];
339727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
340727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
341727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    *count = cur_idx;
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
346