~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/3rdparty/freetype/src/autofit/afangles.c

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "aftypes.h"
 
2
 
 
3
/*
 
4
 * a python script used to generate the following table
 
5
 *
 
6
 
 
7
import sys, math
 
8
 
 
9
units  = 256
 
10
scale  = units/math.pi
 
11
comma  = ""
 
12
 
 
13
print ""
 
14
print "table of arctan( 1/2^n ) for PI = " + repr(units/65536.0) + " units"
 
15
 
 
16
r = [-1] + range(32)
 
17
 
 
18
for n in r:
 
19
 
 
20
    if n >= 0:
 
21
        x = 1.0/(2.0**n)    # tangent value
 
22
    else:
 
23
        x = 2.0**(-n)
 
24
 
 
25
    angle  = math.atan(x)    # arctangent
 
26
    angle2 = angle*scale     # arctangent in FT_Angle units
 
27
 
 
28
    # determine which integer value for angle gives the best tangent
 
29
    lo  = int(angle2)
 
30
    hi  = lo + 1
 
31
    tlo = math.tan(lo/scale)
 
32
    thi = math.tan(hi/scale)
 
33
 
 
34
    errlo = abs( tlo - x )
 
35
    errhi = abs( thi - x )
 
36
 
 
37
    angle2 = hi
 
38
    if errlo < errhi:
 
39
        angle2 = lo
 
40
 
 
41
    if angle2 <= 0:
 
42
        break
 
43
 
 
44
    sys.stdout.write( comma + repr( int(angle2) ) )
 
45
    comma = ", "
 
46
 
 
47
*
 
48
* end of python script
 
49
*/
 
50
 
 
51
 
 
52
  /* this table was generated for AF_ANGLE_PI = 256 */
 
53
#define AF_ANGLE_MAX_ITERS  8
 
54
#define AF_TRIG_MAX_ITERS   8
 
55
 
 
56
  static const FT_Fixed
 
57
  af_angle_arctan_table[9] =
 
58
  {
 
59
    90, 64, 38, 20, 10, 5, 3, 1, 1
 
60
  };
 
61
 
 
62
 
 
63
  static FT_Int
 
64
  af_angle_prenorm( FT_Vector*  vec )
 
65
  {
 
66
    FT_Fixed  x, y, z;
 
67
    FT_Int    shift;
 
68
 
 
69
 
 
70
    x = vec->x;
 
71
    y = vec->y;
 
72
 
 
73
    z     = ( ( x >= 0 ) ? x : - x ) | ( (y >= 0) ? y : -y );
 
74
    shift = 0;
 
75
 
 
76
    if ( z < ( 1L << 27 ) )
 
77
    {
 
78
      do
 
79
      {
 
80
        shift++;
 
81
        z <<= 1;
 
82
      } while ( z < ( 1L << 27 ) );
 
83
 
 
84
      vec->x = x << shift;
 
85
      vec->y = y << shift;
 
86
    }
 
87
    else if ( z > ( 1L << 28 ) )
 
88
    {
 
89
      do
 
90
      {
 
91
        shift++;
 
92
        z >>= 1;
 
93
      } while ( z > ( 1L << 28 ) );
 
94
 
 
95
      vec->x = x >> shift;
 
96
      vec->y = y >> shift;
 
97
      shift  = -shift;
 
98
    }
 
99
    return shift;
 
100
  }
 
101
 
 
102
 
 
103
  static void
 
104
  af_angle_pseudo_polarize( FT_Vector*  vec )
 
105
  {
 
106
    FT_Fixed         theta;
 
107
    FT_Fixed         yi, i;
 
108
    FT_Fixed         x, y;
 
109
    const FT_Fixed  *arctanptr;
 
110
 
 
111
 
 
112
    x = vec->x;
 
113
    y = vec->y;
 
114
 
 
115
    /* Get the vector into the right half plane */
 
116
    theta = 0;
 
117
    if ( x < 0 )
 
118
    {
 
119
      x = -x;
 
120
      y = -y;
 
121
      theta = AF_ANGLE_PI;
 
122
    }
 
123
 
 
124
    if ( y > 0 )
 
125
      theta = - theta;
 
126
 
 
127
    arctanptr = af_angle_arctan_table;
 
128
 
 
129
    if ( y < 0 )
 
130
    {
 
131
      /* Rotate positive */
 
132
      yi     = y + ( x << 1 );
 
133
      x      = x - ( y << 1 );
 
134
      y      = yi;
 
135
      theta -= *arctanptr++;  /* Subtract angle */
 
136
    }
 
137
    else
 
138
    {
 
139
      /* Rotate negative */
 
140
      yi     = y - ( x << 1 );
 
141
      x      = x + ( y << 1 );
 
142
      y      = yi;
 
143
      theta += *arctanptr++;  /* Add angle */
 
144
    }
 
145
 
 
146
    i = 0;
 
147
    do
 
148
    {
 
149
      if ( y < 0 )
 
150
      {
 
151
        /* Rotate positive */
 
152
        yi     = y + ( x >> i );
 
153
        x      = x - ( y >> i );
 
154
        y      = yi;
 
155
        theta -= *arctanptr++;
 
156
      }
 
157
      else
 
158
      {
 
159
        /* Rotate negative */
 
160
        yi     = y - ( x >> i );
 
161
        x      = x + ( y >> i );
 
162
        y      = yi;
 
163
        theta += *arctanptr++;
 
164
      }
 
165
    } while ( ++i < AF_TRIG_MAX_ITERS );
 
166
 
 
167
#if 0
 
168
    /* round theta */
 
169
    if ( theta >= 0 )
 
170
      theta =   FT_PAD_ROUND( theta, 2 );
 
171
    else
 
172
      theta = - FT_PAD_ROUND( -theta, 2 );
 
173
#endif
 
174
 
 
175
    vec->x = x;
 
176
    vec->y = theta;
 
177
  }
 
178
 
 
179
 
 
180
  /* documentation is in fttrigon.h */
 
181
 
 
182
  FT_LOCAL_DEF( AF_Angle )
 
183
  af_angle_atan( FT_Fixed  dx,
 
184
                 FT_Fixed  dy )
 
185
  {
 
186
    FT_Vector  v;
 
187
 
 
188
 
 
189
    if ( dx == 0 && dy == 0 )
 
190
      return 0;
 
191
 
 
192
    v.x = dx;
 
193
    v.y = dy;
 
194
    af_angle_prenorm( &v );
 
195
    af_angle_pseudo_polarize( &v );
 
196
 
 
197
    return v.y;
 
198
  }
 
199
 
 
200
 
 
201
 
 
202
  FT_LOCAL_DEF( AF_Angle )
 
203
  af_angle_diff( AF_Angle  angle1,
 
204
                 AF_Angle  angle2 )
 
205
  {
 
206
    AF_Angle  delta = angle2 - angle1;
 
207
 
 
208
    delta %= AF_ANGLE_2PI;
 
209
    if ( delta < 0 )
 
210
      delta += AF_ANGLE_2PI;
 
211
 
 
212
    if ( delta > AF_ANGLE_PI )
 
213
      delta -= AF_ANGLE_2PI;
 
214
 
 
215
    return delta;
 
216
  }
 
217
 
 
218
 
 
219
 /* well, this needs to be somewhere, right :-)
 
220
  */
 
221
 
 
222
  FT_LOCAL_DEF( void )
 
223
  af_sort_pos( FT_UInt   count,
 
224
               FT_Pos*   table )
 
225
  {
 
226
    FT_UInt  i, j;
 
227
    FT_Pos   swap;
 
228
 
 
229
 
 
230
    for ( i = 1; i < count; i++ )
 
231
    {
 
232
      for ( j = i; j > 0; j-- )
 
233
      {
 
234
        if ( table[j] > table[j - 1] )
 
235
          break;
 
236
 
 
237
        swap         = table[j];
 
238
        table[j]     = table[j - 1];
 
239
        table[j - 1] = swap;
 
240
      }
 
241
    }
 
242
  }
 
243
 
 
244
 
 
245
  FT_LOCAL_DEF( void )
 
246
  af_sort_widths( FT_UInt   count,
 
247
                  AF_Width  table )
 
248
  {
 
249
    FT_UInt      i, j;
 
250
    AF_WidthRec  swap;
 
251
 
 
252
 
 
253
    for ( i = 1; i < count; i++ )
 
254
    {
 
255
      for ( j = i; j > 0; j-- )
 
256
      {
 
257
        if ( table[j].org > table[j - 1].org )
 
258
          break;
 
259
 
 
260
        swap         = table[j];
 
261
        table[j]     = table[j - 1];
 
262
        table[j - 1] = swap;
 
263
      }
 
264
    }
 
265
  }
 
266
 
 
267
 
 
268
#ifdef TEST
 
269
#include <stdio.h>
 
270
#include <math.h>
 
271
 
 
272
int main( void )
 
273
{
 
274
  int  angle;
 
275
  int  dist;
 
276
 
 
277
  for ( dist = 100; dist < 1000; dist++ )
 
278
  {
 
279
    for ( angle = AF_ANGLE_PI; angle < AF_ANGLE_2PI*4; angle++ )
 
280
    {
 
281
      double a = (angle*3.1415926535)/(1.0*AF_ANGLE_PI);
 
282
      int    dx, dy, angle1, angle2, delta;
 
283
 
 
284
      dx = dist * cos(a);
 
285
      dy = dist * sin(a);
 
286
 
 
287
      angle1  = ((atan2(dy,dx)*AF_ANGLE_PI)/3.1415926535);
 
288
      angle2  = af_angle_atan( dx, dy );
 
289
      delta   = (angle2 - angle1) % AF_ANGLE_2PI;
 
290
      if ( delta < 0 )
 
291
        delta = -delta;
 
292
 
 
293
      if ( delta >= 2 )
 
294
      {
 
295
        printf( "dist:%4d angle:%4d => (%4d,%4d) angle1:%4d angle2:%4d\n",
 
296
                dist, angle, dx, dy, angle1, angle2 );
 
297
      }
 
298
    }
 
299
  }
 
300
  return 0;
 
301
}
 
302
#endif