QtBase  v6.3.1
ftcalc.h
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * ftcalc.h
4  *
5  * Arithmetic computations (specification).
6  *
7  * Copyright (C) 1996-2020 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 <freetype/freetype.h>
24 
25 #include "compiler-macros.h"
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 ::
264  * The first multiplier.
265  * b ::
266  * The second multiplier.
267  * c ::
268  * The divisor.
269  *
270  * @return:
271  * The result of '(a*b)/c'. This function never traps when trying to
272  * divide by zero; it simply returns 'MaxInt' or 'MinInt' depending on
273  * the signs of 'a' and 'b'.
274  */
275  FT_BASE( FT_Long )
277  FT_Long b,
278  FT_Long c );
279 
280 
281  /*
282  * A variant of FT_Matrix_Multiply which scales its result afterwards. The
283  * idea is that both `a' and `b' are scaled by factors of 10 so that the
284  * values are as precise as possible to get a correct result during the
285  * 64bit multiplication. Let `sa' and `sb' be the scaling factors of `a'
286  * and `b', respectively, then the scaling factor of the result is `sa*sb'.
287  */
288  FT_BASE( void )
290  FT_Matrix *b,
291  FT_Long scaling );
292 
293 
294  /*
295  * Check a matrix. If the transformation would lead to extreme shear or
296  * extreme scaling, for example, return 0. If everything is OK, return 1.
297  *
298  * Based on geometric considerations we use the following inequality to
299  * identify a degenerate matrix.
300  *
301  * 50 * abs(xx*yy - xy*yx) < xx^2 + xy^2 + yx^2 + yy^2
302  *
303  * Value 50 is heuristic.
304  */
305  FT_BASE( FT_Bool )
306  FT_Matrix_Check( const FT_Matrix* matrix );
307 
308 
309  /*
310  * A variant of FT_Vector_Transform. See comments for
311  * FT_Matrix_Multiply_Scaled.
312  */
313  FT_BASE( void )
315  const FT_Matrix* matrix,
316  FT_Long scaling );
317 
318 
319  /*
320  * This function normalizes a vector and returns its original length. The
321  * normalized vector is a 16.16 fixed-point unit vector with length close
322  * to 0x10000. The accuracy of the returned length is limited to 16 bits
323  * also. The function utilizes quick inverse square root approximation
324  * without divisions and square roots relying on Newton's iterations
325  * instead.
326  */
327  FT_BASE( FT_UInt32 )
329 
330 
331  /*
332  * Return -1, 0, or +1, depending on the orientation of a given corner. We
333  * use the Cartesian coordinate system, with positive vertical values going
334  * upwards. The function returns +1 if the corner turns to the left, -1 to
335  * the right, and 0 for undecidable cases.
336  */
337  FT_BASE( FT_Int )
339  FT_Pos in_y,
340  FT_Pos out_x,
341  FT_Pos out_y );
342 
343 
344  /*
345  * Return TRUE if a corner is flat or nearly flat. This is equivalent to
346  * saying that the corner point is close to its neighbors, or inside an
347  * ellipse defined by the neighbor focal points to be more precise.
348  */
349  FT_BASE( FT_Int )
351  FT_Pos in_y,
352  FT_Pos out_x,
353  FT_Pos out_y );
354 
355 
356  /*
357  * Return the most significant bit index.
358  */
359 
360 #ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
361 
362 #if defined( __GNUC__ ) && \
363  ( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) )
364 
365 #if FT_SIZEOF_INT == 4
366 
367 #define FT_MSB( x ) ( 31 - __builtin_clz( x ) )
368 
369 #elif FT_SIZEOF_LONG == 4
370 
371 #define FT_MSB( x ) ( 31 - __builtin_clzl( x ) )
372 
373 #endif /* __GNUC__ */
374 
375 
376 #elif defined( _MSC_VER ) && ( _MSC_VER >= 1400 )
377 
378 #if FT_SIZEOF_INT == 4
379 
380 #include <intrin.h>
381 #pragma intrinsic( _BitScanReverse )
382 
383  static __inline FT_Int32
384  FT_MSB_i386( FT_UInt32 x )
385  {
386  unsigned long where;
387 
388 
389  _BitScanReverse( &where, x );
390 
391  return (FT_Int32)where;
392  }
393 
394 #define FT_MSB( x ) ( FT_MSB_i386( x ) )
395 
396 #endif
397 
398 #endif /* _MSC_VER */
399 
400 
401 #endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
402 
403 #ifndef FT_MSB
404 
405  FT_BASE( FT_Int )
406  FT_MSB( FT_UInt32 z );
407 
408 #endif
409 
410 
411  /*
412  * Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses
413  * two fixed-point arguments instead.
414  */
415  FT_BASE( FT_Fixed )
417  FT_Fixed y );
418 
419 
420 #if 0
421 
422  /**************************************************************************
423  *
424  * @function:
425  * FT_SqrtFixed
426  *
427  * @description:
428  * Computes the square root of a 16.16 fixed-point value.
429  *
430  * @input:
431  * x ::
432  * The value to compute the root for.
433  *
434  * @return:
435  * The result of 'sqrt(x)'.
436  *
437  * @note:
438  * This function is not very fast.
439  */
440  FT_BASE( FT_Int32 )
441  FT_SqrtFixed( FT_Int32 x );
442 
443 #endif /* 0 */
444 
445 
446 #define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 ) /* << 6 */
447 #define INT_TO_F2DOT14( x ) ( (FT_Long)(x) * 16384 ) /* << 14 */
448 #define INT_TO_FIXED( x ) ( (FT_Long)(x) * 65536 ) /* << 16 */
449 #define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) * 4 ) /* << 2 */
450 #define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 )
451 
452 #define ROUND_F26DOT6( x ) ( ( (x) + 32 - ( x < 0 ) ) & -64 )
453 
454  /*
455  * The following macros have two purposes.
456  *
457  * - Tag places where overflow is expected and harmless.
458  *
459  * - Avoid run-time sanitizer errors.
460  *
461  * Use with care!
462  */
463 #define ADD_INT( a, b ) \
464  (FT_Int)( (FT_UInt)(a) + (FT_UInt)(b) )
465 #define SUB_INT( a, b ) \
466  (FT_Int)( (FT_UInt)(a) - (FT_UInt)(b) )
467 #define MUL_INT( a, b ) \
468  (FT_Int)( (FT_UInt)(a) * (FT_UInt)(b) )
469 #define NEG_INT( a ) \
470  (FT_Int)( (FT_UInt)0 - (FT_UInt)(a) )
471 
472 #define ADD_LONG( a, b ) \
473  (FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) )
474 #define SUB_LONG( a, b ) \
475  (FT_Long)( (FT_ULong)(a) - (FT_ULong)(b) )
476 #define MUL_LONG( a, b ) \
477  (FT_Long)( (FT_ULong)(a) * (FT_ULong)(b) )
478 #define NEG_LONG( a ) \
479  (FT_Long)( (FT_ULong)0 - (FT_ULong)(a) )
480 
481 #define ADD_INT32( a, b ) \
482  (FT_Int32)( (FT_UInt32)(a) + (FT_UInt32)(b) )
483 #define SUB_INT32( a, b ) \
484  (FT_Int32)( (FT_UInt32)(a) - (FT_UInt32)(b) )
485 #define MUL_INT32( a, b ) \
486  (FT_Int32)( (FT_UInt32)(a) * (FT_UInt32)(b) )
487 #define NEG_INT32( a ) \
488  (FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) )
489 
490 #ifdef FT_LONG64
491 
492 #define ADD_INT64( a, b ) \
493  (FT_Int64)( (FT_UInt64)(a) + (FT_UInt64)(b) )
494 #define SUB_INT64( a, b ) \
495  (FT_Int64)( (FT_UInt64)(a) - (FT_UInt64)(b) )
496 #define MUL_INT64( a, b ) \
497  (FT_Int64)( (FT_UInt64)(a) * (FT_UInt64)(b) )
498 #define NEG_INT64( a ) \
499  (FT_Int64)( (FT_UInt64)0 - (FT_UInt64)(a) )
500 
501 #endif /* FT_LONG64 */
502 
503 
505 
506 #endif /* FTCALC_H_ */
507 
508 
509 /* END */
#define FT_BASE(x)
ft_corner_is_flat(FT_Pos in_x, FT_Pos in_y, FT_Pos out_x, FT_Pos out_y)
Definition: ftcalc.c:1046
FT_MSB(FT_UInt32 z)
Definition: ftcalc.c:113
FT_BEGIN_HEADER FT_MulDiv_No_Round(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:463
FT_Vector_NormLen(FT_Vector *vector)
Definition: ftcalc.c:845
FT_Vector_Transform_Scaled(FT_Vector *vector, const FT_Matrix *matrix, FT_Long scaling)
Definition: ftcalc.c:820
FT_Matrix_Multiply_Scaled(const FT_Matrix *a, FT_Matrix *b, FT_Long scaling)
Definition: ftcalc.c:719
FT_Matrix_Check(const FT_Matrix *matrix)
Definition: ftcalc.c:750
FT_Hypot(FT_Fixed x, FT_Fixed y)
Definition: ftcalc.c:154
ft_corner_orientation(FT_Pos in_x, FT_Pos in_y, FT_Pos out_x, FT_Pos out_y)
Definition: ftcalc.c:980
#define FT_END_HEADER
Definition: ftheader.h:57
#define FT_BEGIN_HEADER
Definition: ftheader.h:37
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:57
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
signed long FT_Fixed
Definition: fttypes.h:287
signed long FT_Long
Definition: fttypes.h:242
signed int FT_Int
Definition: fttypes.h:220
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro vuzp8 reg2 vuzp d d &reg2 endm macro vzip8 reg2 vzip d d &reg2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld endif[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1 beq endif SRC MASK if dst_r_bpp DST_R else add endif PF add sub src_basereg pixdeinterleave mask_basereg pixdeinterleave dst_r_basereg process_pixblock_head pixblock_size cache_preload_simple process_pixblock_tail pixinterleave dst_w_basereg irp beq endif process_pixblock_tail_head tst beq irp if pixblock_size chunk_size tst beq pixld SRC pixld MASK if DST_R else pixld DST_R endif if
GLboolean GLboolean GLboolean b
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat z
GLint GLint GLint GLint GLint x
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLint y
GLfloat GLfloat GLfloat GLfloat h
const GLubyte * c
Definition: qopenglext.h:12701
GLuint GLenum matrix
Definition: qopenglext.h:11564
GLdouble GLdouble t
[9]
Definition: qopenglext.h:243
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
QList< int > vector
[14]
QSize t2(10, 12)
void add(int &result, const int &sum)