ReactOS  0.4.13-dev-982-g9853eab
ftcalc.h
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ftcalc.h */
4 /* */
5 /* Arithmetic computations (specification). */
6 /* */
7 /* Copyright 1996-2018 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17 
18 
19 #ifndef FTCALC_H_
20 #define FTCALC_H_
21 
22 
23 #include <ft2build.h>
24 #include FT_FREETYPE_H
25 
26 
28 
29 
30  /*************************************************************************/
31  /* */
32  /* FT_MulDiv() and FT_MulFix() are declared in freetype.h. */
33  /* */
34  /*************************************************************************/
35 
36 #ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
37  /* Provide assembler fragments for performance-critical functions. */
38  /* These must be defined `static __inline__' with GCC. */
39 
40 #if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */
41 
42 #define FT_MULFIX_ASSEMBLER FT_MulFix_arm
43 
44  /* documentation is in freetype.h */
45 
46  static __inline FT_Int32
47  FT_MulFix_arm( FT_Int32 a,
48  FT_Int32 b )
49  {
50  FT_Int32 t, t2;
51 
52 
53  __asm
54  {
55  smull t2, t, b, a /* (lo=t2,hi=t) = a*b */
56  mov a, t, asr #31 /* a = (hi >> 31) */
57  add a, a, #0x8000 /* a += 0x8000 */
58  adds t2, t2, a /* t2 += a */
59  adc t, t, #0 /* t += carry */
60  mov a, t2, lsr #16 /* a = t2 >> 16 */
61  orr a, a, t, lsl #16 /* a |= t << 16 */
62  }
63  return a;
64  }
65 
66 #endif /* __CC_ARM || __ARMCC__ */
67 
68 
69 #ifdef __GNUC__
70 
71 #if defined( __arm__ ) && \
72  ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
73  !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
74 
75 #define FT_MULFIX_ASSEMBLER FT_MulFix_arm
76 
77  /* documentation is in freetype.h */
78 
79  static __inline__ FT_Int32
80  FT_MulFix_arm( FT_Int32 a,
81  FT_Int32 b )
82  {
83  FT_Int32 t, t2;
84 
85 
86  __asm__ __volatile__ (
87  "smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
88  "mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
89 #if defined( __clang__ ) && defined( __thumb2__ )
90  "add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
91 #else
92  "add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
93 #endif
94  "adds %1, %1, %0\n\t" /* %1 += %0 */
95  "adc %2, %2, #0\n\t" /* %2 += carry */
96  "mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */
97  "orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */
98  : "=r"(a), "=&r"(t2), "=&r"(t)
99  : "r"(a), "r"(b)
100  : "cc" );
101  return a;
102  }
103 
104 #endif /* __arm__ && */
105  /* ( __thumb2__ || !__thumb__ ) && */
106  /* !( __CC_ARM || __ARMCC__ ) */
107 
108 
109 #if defined( __i386__ )
110 
111 #define FT_MULFIX_ASSEMBLER FT_MulFix_i386
112 
113  /* documentation is in freetype.h */
114 
115  static __inline__ FT_Int32
116  FT_MulFix_i386( FT_Int32 a,
117  FT_Int32 b )
118  {
119  FT_Int32 result;
120 
121 
122  __asm__ __volatile__ (
123  "imul %%edx\n"
124  "movl %%edx, %%ecx\n"
125  "sarl $31, %%ecx\n"
126  "addl $0x8000, %%ecx\n"
127  "addl %%ecx, %%eax\n"
128  "adcl $0, %%edx\n"
129  "shrl $16, %%eax\n"
130  "shll $16, %%edx\n"
131  "addl %%edx, %%eax\n"
132  : "=a"(result), "=d"(b)
133  : "a"(a), "d"(b)
134  : "%ecx", "cc" );
135  return result;
136  }
137 
138 #endif /* i386 */
139 
140 #endif /* __GNUC__ */
141 
142 
143 #ifdef _MSC_VER /* Visual C++ */
144 
145 #ifdef _M_IX86
146 
147 #define FT_MULFIX_ASSEMBLER FT_MulFix_i386
148 
149  /* documentation is in freetype.h */
150 
151  static __inline FT_Int32
152  FT_MulFix_i386( FT_Int32 a,
153  FT_Int32 b )
154  {
155  FT_Int32 result;
156 
157  __asm
158  {
159  mov eax, a
160  mov edx, b
161  imul edx
162  mov ecx, edx
163  sar ecx, 31
164  add ecx, 8000h
165  add eax, ecx
166  adc edx, 0
167  shr eax, 16
168  shl edx, 16
169  add eax, edx
170  mov result, eax
171  }
172  return result;
173  }
174 
175 #endif /* _M_IX86 */
176 
177 #endif /* _MSC_VER */
178 
179 
180 #if defined( __GNUC__ ) && defined( __x86_64__ )
181 
182 #define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64
183 
184  static __inline__ FT_Int32
185  FT_MulFix_x86_64( FT_Int32 a,
186  FT_Int32 b )
187  {
188  /* Temporarily disable the warning that C90 doesn't support */
189  /* `long long'. */
190 #if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 )
191 #pragma GCC diagnostic push
192 #pragma GCC diagnostic ignored "-Wlong-long"
193 #endif
194 
195 #if 1
196  /* Technically not an assembly fragment, but GCC does a really good */
197  /* job at inlining it and generating good machine code for it. */
198  long long ret, tmp;
199 
200 
201  ret = (long long)a * b;
202  tmp = ret >> 63;
203  ret += 0x8000 + tmp;
204 
205  return (FT_Int32)( ret >> 16 );
206 #else
207 
208  /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */
209  /* code from the lines below. The main issue is that `wide_a' is not */
210  /* properly initialized by sign-extending `a'. Instead, the generated */
211  /* machine code assumes that the register that contains `a' on input */
212  /* can be used directly as a 64-bit value, which is wrong most of the */
213  /* time. */
214  long long wide_a = (long long)a;
215  long long wide_b = (long long)b;
216  long long result;
217 
218 
219  __asm__ __volatile__ (
220  "imul %2, %1\n"
221  "mov %1, %0\n"
222  "sar $63, %0\n"
223  "lea 0x8000(%1, %0), %0\n"
224  "sar $16, %0\n"
225  : "=&r"(result), "=&r"(wide_a)
226  : "r"(wide_b)
227  : "cc" );
228 
229  return (FT_Int32)result;
230 #endif
231 
232 #if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 )
233 #pragma GCC diagnostic pop
234 #endif
235  }
236 
237 #endif /* __GNUC__ && __x86_64__ */
238 
239 #endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
240 
241 
242 #ifdef FT_CONFIG_OPTION_INLINE_MULFIX
243 #ifdef FT_MULFIX_ASSEMBLER
244 #define FT_MulFix( a, b ) FT_MULFIX_ASSEMBLER( (FT_Int32)(a), (FT_Int32)(b) )
245 #endif
246 #endif
247 
248 
249  /*************************************************************************/
250  /* */
251  /* <Function> */
252  /* FT_MulDiv_No_Round */
253  /* */
254  /* <Description> */
255  /* A very simple function used to perform the computation `(a*b)/c' */
256  /* (without rounding) with maximum accuracy (it uses a 64-bit */
257  /* intermediate integer whenever necessary). */
258  /* */
259  /* This function isn't necessarily as fast as some processor specific */
260  /* operations, but is at least completely portable. */
261  /* */
262  /* <Input> */
263  /* a :: The first multiplier. */
264  /* b :: The second multiplier. */
265  /* c :: The divisor. */
266  /* */
267  /* <Return> */
268  /* The result of `(a*b)/c'. This function never traps when trying to */
269  /* divide by zero; it simply returns `MaxInt' or `MinInt' depending */
270  /* on the signs of `a' and `b'. */
271  /* */
272  FT_BASE( FT_Long )
274  FT_Long b,
275  FT_Long c );
276 
277 
278  /*
279  * A variant of FT_Matrix_Multiply which scales its result afterwards.
280  * The idea is that both `a' and `b' are scaled by factors of 10 so that
281  * the values are as precise as possible to get a correct result during
282  * the 64bit multiplication. Let `sa' and `sb' be the scaling factors of
283  * `a' and `b', respectively, then the scaling factor of the result is
284  * `sa*sb'.
285  */
286  FT_BASE( void )
288  FT_Matrix *b,
289  FT_Long scaling );
290 
291 
292  /*
293  * A variant of FT_Vector_Transform. See comments for
294  * FT_Matrix_Multiply_Scaled.
295  */
296  FT_BASE( void )
298  const FT_Matrix* matrix,
299  FT_Long scaling );
300 
301 
302  /*
303  * This function normalizes a vector and returns its original length.
304  * The normalized vector is a 16.16 fixed-point unit vector with length
305  * close to 0x10000. The accuracy of the returned length is limited to
306  * 16 bits also. The function utilizes quick inverse square root
307  * approximation without divisions and square roots relying on Newton's
308  * iterations instead.
309  */
310  FT_BASE( FT_UInt32 )
312 
313 
314  /*
315  * Return -1, 0, or +1, depending on the orientation of a given corner.
316  * We use the Cartesian coordinate system, with positive vertical values
317  * going upwards. The function returns +1 if the corner turns to the
318  * left, -1 to the right, and 0 for undecidable cases.
319  */
320  FT_BASE( FT_Int )
322  FT_Pos in_y,
323  FT_Pos out_x,
324  FT_Pos out_y );
325 
326 
327  /*
328  * Return TRUE if a corner is flat or nearly flat. This is equivalent to
329  * saying that the corner point is close to its neighbors, or inside an
330  * ellipse defined by the neighbor focal points to be more precise.
331  */
332  FT_BASE( FT_Int )
334  FT_Pos in_y,
335  FT_Pos out_x,
336  FT_Pos out_y );
337 
338 
339  /*
340  * Return the most significant bit index.
341  */
342 
343 #ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
344 #if defined( __GNUC__ ) && \
345  ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) )
346 
347 #if FT_SIZEOF_INT == 4
348 
349 #define FT_MSB( x ) ( 31 - __builtin_clz( x ) )
350 
351 #elif FT_SIZEOF_LONG == 4
352 
353 #define FT_MSB( x ) ( 31 - __builtin_clzl( x ) )
354 
355 #endif
356 
357 #endif /* __GNUC__ */
358 #endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
359 
360 #ifndef FT_MSB
361 
362  FT_BASE( FT_Int )
363  FT_MSB( FT_UInt32 z );
364 
365 #endif
366 
367 
368  /*
369  * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses
370  * two fixed-point arguments instead.
371  */
372  FT_BASE( FT_Fixed )
374  FT_Fixed y );
375 
376 
377 #if 0
378 
379  /*************************************************************************/
380  /* */
381  /* <Function> */
382  /* FT_SqrtFixed */
383  /* */
384  /* <Description> */
385  /* Computes the square root of a 16.16 fixed-point value. */
386  /* */
387  /* <Input> */
388  /* x :: The value to compute the root for. */
389  /* */
390  /* <Return> */
391  /* The result of `sqrt(x)'. */
392  /* */
393  /* <Note> */
394  /* This function is not very fast. */
395  /* */
396  FT_BASE( FT_Int32 )
397  FT_SqrtFixed( FT_Int32 x );
398 
399 #endif /* 0 */
400 
401 
402 #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 ) /* << 6 */
403 #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) * 16384 ) /* << 14 */
404 #define INT_TO_FIXED( x ) ( (FT_Long)(x) * 65536 ) /* << 16 */
405 #define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) * 4 ) /* << 2 */
406 #define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 )
407 
408 #define ROUND_F26DOT6( x ) ( x >= 0 ? ( ( (x) + 32 ) & -64 ) \
409  : ( -( ( 32 - (x) ) & -64 ) ) )
410 
411  /*
412  * The following macros have two purposes.
413  *
414  * . Tag places where overflow is expected and harmless.
415  *
416  * . Avoid run-time sanitizer errors.
417  *
418  * Use with care!
419  */
420 #define ADD_LONG( a, b ) \
421  (FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) )
422 #define SUB_LONG( a, b ) \
423  (FT_Long)( (FT_ULong)(a) - (FT_ULong)(b) )
424 #define MUL_LONG( a, b ) \
425  (FT_Long)( (FT_ULong)(a) * (FT_ULong)(b) )
426 #define NEG_LONG( a ) \
427  (FT_Long)( (FT_ULong)0 - (FT_ULong)(a) )
428 
429 #define ADD_INT32( a, b ) \
430  (FT_Int32)( (FT_UInt32)(a) + (FT_UInt32)(b) )
431 #define SUB_INT32( a, b ) \
432  (FT_Int32)( (FT_UInt32)(a) - (FT_UInt32)(b) )
433 #define MUL_INT32( a, b ) \
434  (FT_Int32)( (FT_UInt32)(a) * (FT_UInt32)(b) )
435 #define NEG_INT32( a ) \
436  (FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) )
437 
438 
440 
441 #endif /* FTCALC_H_ */
442 
443 
444 /* END */
int add
Definition: i386-dis.c:3122
FT_BEGIN_HEADER FT_MulDiv_No_Round(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:464
signed long FT_Long
Definition: fttypes.h:242
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_END_HEADER
Definition: ftheader.h:54
signed int FT_Int
Definition: fttypes.h:220
GLuint GLenum matrix
Definition: glext.h:9407
GLdouble GLdouble t
Definition: gl.h:2047
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
ft_corner_is_flat(FT_Pos in_x, FT_Pos in_y, FT_Pos out_x, FT_Pos out_y)
Definition: ftcalc.c:975
#define FT_BEGIN_HEADER
Definition: ftheader.h:36
__asm__("\t.globl GetPhys\n" "GetPhys:\t\n" "mflr 0\n\t" "stwu 0,-16(1)\n\t" "mfmsr 5\n\t" "andi. 6,5,0xffef\n\t" "mtmsr 6\n\t" "isync\n\t" "sync\n\t" "lwz 3,0(3)\n\t" "mtmsr 5\n\t" "isync\n\t" "sync\n\t" "lwz 0,0(1)\n\t" "addi 1,1,16\n\t" "mtlr 0\n\t" "blr")
#define a
Definition: ke_i.h:78
FT_Vector_NormLen(FT_Vector *vector)
Definition: ftcalc.c:776
GLdouble GLdouble z
Definition: glext.h:5874
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl eax
Definition: synth_sse3d.h:85
const GLubyte * c
Definition: glext.h:8905
int ret
ft_corner_orientation(FT_Pos in_x, FT_Pos in_y, FT_Pos out_x, FT_Pos out_y)
Definition: ftcalc.c:911
FT_MSB(FT_UInt32 z)
Definition: ftcalc.c:114
FT_Vector_Transform_Scaled(FT_Vector *vector, const FT_Matrix *matrix, FT_Long scaling)
Definition: ftcalc.c:751
signed long FT_Fixed
Definition: fttypes.h:288
#define long
Definition: qsort.c:33
FT_Matrix_Multiply_Scaled(const FT_Matrix *a, FT_Matrix *b, FT_Long scaling)
Definition: ftcalc.c:720
#define __inline__
Definition: bzlib_private.h:53
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define FT_BASE(x)
Definition: ftconfig.h:408
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
ecx edi ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx
Definition: synth_sse3d.h:85
FT_Hypot(FT_Fixed x, FT_Fixed y)
Definition: ftcalc.c:155
GLuint64EXT * result
Definition: glext.h:11304