sdk-world
v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Toggle main menu visibility
Loading...
Searching...
No Matches
ftcalc.h
Go to the documentation of this file.
1
/****************************************************************************
2
*
3
* ftcalc.h
4
*
5
* Arithmetic computations (specification).
6
*
7
* Copyright (C) 1996-2025 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
23
#ifndef FTCALC_H_
24
#define FTCALC_H_
25
26
27
#include <
freetype/freetype.h
>
28
29
#include "
compiler-macros.h
"
30
31
FT_BEGIN_HEADER
32
33
34
/*
35
* The following macros have two purposes.
36
*
37
* - Tag places where overflow is expected and harmless.
38
*
39
* - Avoid run-time undefined behavior sanitizer errors.
40
*
41
* Use with care!
42
*/
43
#define ADD_INT( a, b ) \
44
(FT_Int)( (FT_UInt)(a) + (FT_UInt)(b) )
45
#define SUB_INT( a, b ) \
46
(FT_Int)( (FT_UInt)(a) - (FT_UInt)(b) )
47
#define MUL_INT( a, b ) \
48
(FT_Int)( (FT_UInt)(a) * (FT_UInt)(b) )
49
#define NEG_INT( a ) \
50
(FT_Int)( (FT_UInt)0 - (FT_UInt)(a) )
51
52
#define ADD_LONG( a, b ) \
53
(FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) )
54
#define SUB_LONG( a, b ) \
55
(FT_Long)( (FT_ULong)(a) - (FT_ULong)(b) )
56
#define MUL_LONG( a, b ) \
57
(FT_Long)( (FT_ULong)(a) * (FT_ULong)(b) )
58
#define NEG_LONG( a ) \
59
(FT_Long)( (FT_ULong)0 - (FT_ULong)(a) )
60
61
#define ADD_INT32( a, b ) \
62
(FT_Int32)( (FT_UInt32)(a) + (FT_UInt32)(b) )
63
#define SUB_INT32( a, b ) \
64
(FT_Int32)( (FT_UInt32)(a) - (FT_UInt32)(b) )
65
#define MUL_INT32( a, b ) \
66
(FT_Int32)( (FT_UInt32)(a) * (FT_UInt32)(b) )
67
#define NEG_INT32( a ) \
68
(FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) )
69
70
#ifdef FT_INT64
71
72
#define ADD_INT64( a, b ) \
73
(FT_Int64)( (FT_UInt64)(a) + (FT_UInt64)(b) )
74
#define SUB_INT64( a, b ) \
75
(FT_Int64)( (FT_UInt64)(a) - (FT_UInt64)(b) )
76
#define MUL_INT64( a, b ) \
77
(FT_Int64)( (FT_UInt64)(a) * (FT_UInt64)(b) )
78
#define NEG_INT64( a ) \
79
(FT_Int64)( (FT_UInt64)0 - (FT_UInt64)(a) )
80
81
#endif
/* FT_INT64 */
82
83
84
/**************************************************************************
85
*
86
* FT_MulDiv() and FT_MulFix() are declared in freetype.h.
87
*
88
*/
89
90
#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
91
92
#ifdef FT_INT64
93
94
static
inline
FT_Long
95
FT_MulFix_64( FT_Long a,
96
FT_Long b )
97
{
98
FT_Int64 ab = MUL_INT64( a, b );
99
100
101
ab = ADD_INT64( ab, 0x8000 + ( ab >> 63 ) );
/* rounding phase */
102
103
return
(FT_Long)( ab >> 16 );
104
}
105
106
107
#define FT_MulFix( a, b ) FT_MulFix_64( a, b )
108
109
#elif !defined( FT_CONFIG_OPTION_NO_ASSEMBLER )
110
/* Provide 32-bit assembler fragments for optimized FT_MulFix. */
111
/* These must be defined `static __inline__' or similar. */
112
113
#if defined( __arm__ ) && \
114
( defined( __thumb2__ ) || !defined( __thumb__ ) )
115
116
#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
117
118
/* documentation is in freetype.h */
119
120
static
__inline FT_Int32
121
FT_MulFix_arm( FT_Int32 a,
122
FT_Int32 b )
123
{
124
FT_Int32 t, t2;
125
126
#if defined( __CC_ARM ) || defined( __ARMCC__ )
/* RVCT */
127
128
__asm
129
{
130
smull t2, t, b, a
/* (lo=t2,hi=t) = a*b */
131
mov a, t, asr #31
/* a = (hi >> 31) */
132
add a, a, #0x8000
/* a += 0x8000 */
133
adds t2, t2, a
/* t2 += a */
134
adc t, t, #0
/* t += carry */
135
mov a, t2, lsr #16
/* a = t2 >> 16 */
136
orr a, a, t, lsl #16
/* a |= t << 16 */
137
}
138
139
#elif defined( __GNUC__ )
140
141
__asm__ __volatile__ (
142
"smull %1, %2, %4, %3\n\t"
/* (lo=%1,hi=%2) = a*b */
143
"mov %0, %2, asr #31\n\t"
/* %0 = (hi >> 31) */
144
#
if
defined( __clang__ ) && defined( __thumb2__ )
145
"add.w %0, %0, #0x8000\n\t"
/* %0 += 0x8000 */
146
#
else
147
"add %0, %0, #0x8000\n\t"
/* %0 += 0x8000 */
148
#endif
149
"adds %1, %1, %0\n\t"
/* %1 += %0 */
150
"adc %2, %2, #0\n\t"
/* %2 += carry */
151
"mov %0, %1, lsr #16\n\t"
/* %0 = %1 >> 16 */
152
"orr %0, %0, %2, lsl #16\n\t"
/* %0 |= %2 << 16 */
153
:
"=r"
(a),
"=&r"
(t2),
"=&r"
(t)
154
:
"r"
(a),
"r"
(b)
155
:
"cc"
);
156
157
#endif
158
159
return
a;
160
}
161
162
#elif defined( __i386__ ) || defined( _M_IX86 )
163
164
#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
165
166
/* documentation is in freetype.h */
167
168
static
__inline FT_Int32
169
FT_MulFix_i386( FT_Int32 a,
170
FT_Int32 b )
171
{
172
FT_Int32 result;
173
174
#if defined( __GNUC__ )
175
176
__asm__ __volatile__ (
177
"imul %%edx\n"
178
"movl %%edx, %%ecx\n"
179
"sarl $31, %%ecx\n"
180
"addl $0x8000, %%ecx\n"
181
"addl %%ecx, %%eax\n"
182
"adcl $0, %%edx\n"
183
"shrl $16, %%eax\n"
184
"shll $16, %%edx\n"
185
"addl %%edx, %%eax\n"
186
:
"=a"
(result),
"=d"
(b)
187
:
"a"
(a),
"d"
(b)
188
:
"%ecx"
,
"cc"
);
189
190
#elif defined( _MSC_VER )
191
192
__asm
193
{
194
mov eax, a
195
mov edx, b
196
imul edx
197
mov ecx, edx
198
sar ecx, 31
199
add ecx, 8000h
200
add eax, ecx
201
adc edx, 0
202
shr eax, 16
203
shl edx, 16
204
add eax, edx
205
mov result, eax
206
}
207
208
#endif
209
210
return
result;
211
}
212
213
#endif
/* __i386__ || _M_IX86 */
214
215
#ifdef FT_MULFIX_ASSEMBLER
216
#define FT_MulFix( a, b ) FT_MULFIX_ASSEMBLER( (FT_Int32)(a), (FT_Int32)(b) )
217
#endif
218
219
#endif
/* !FT_CONFIG_OPTION_NO_ASSEMBLER */
220
221
#endif
/* FT_CONFIG_OPTION_INLINE_MULFIX */
222
223
224
/**************************************************************************
225
*
226
* @function:
227
* FT_MulDiv_No_Round
228
*
229
* @description:
230
* A very simple function used to perform the computation '(a*b)/c'
231
* (without rounding) with maximum accuracy (it uses a 64-bit
232
* intermediate integer whenever necessary).
233
*
234
* This function isn't necessarily as fast as some processor-specific
235
* operations, but is at least completely portable.
236
*
237
* @input:
238
* a ::
239
* The first multiplier.
240
* b ::
241
* The second multiplier.
242
* c ::
243
* The divisor.
244
*
245
* @return:
246
* The result of '(a*b)/c'. This function never traps when trying to
247
* divide by zero; it simply returns 'MaxInt' or 'MinInt' depending on
248
* the signs of 'a' and 'b'.
249
*/
250
FT_BASE( FT_Long )
251
FT_MulDiv_No_Round( FT_Long a,
252
FT_Long b,
253
FT_Long c );
254
255
256
/*
257
* A variant of FT_Matrix_Multiply which scales its result afterwards. The
258
* idea is that both `a' and `b' are scaled by factors of 10 so that the
259
* values are as precise as possible to get a correct result during the
260
* 64bit multiplication. Let `sa' and `sb' be the scaling factors of `a'
261
* and `b', respectively, then the scaling factor of the result is `sa*sb'.
262
*/
263
FT_BASE(
void
)
264
FT_Matrix_Multiply_Scaled(
const
FT_Matrix* a,
265
FT_Matrix *b,
266
FT_Long scaling );
267
268
269
/*
270
* Check a matrix. If the transformation would lead to extreme shear or
271
* extreme scaling, for example, return 0. If everything is OK, return 1.
272
*
273
* Based on geometric considerations we use the following inequality to
274
* identify a degenerate matrix.
275
*
276
* 32 * abs(xx*yy - xy*yx) < xx^2 + xy^2 + yx^2 + yy^2
277
*
278
* Value 32 is heuristic.
279
*/
280
FT_BASE( FT_Bool )
281
FT_Matrix_Check(
const
FT_Matrix* matrix );
282
283
284
/*
285
* A variant of FT_Vector_Transform. See comments for
286
* FT_Matrix_Multiply_Scaled.
287
*/
288
FT_BASE(
void
)
289
FT_Vector_Transform_Scaled( FT_Vector* vector,
290
const
FT_Matrix* matrix,
291
FT_Long scaling );
292
293
294
/*
295
* This function normalizes a vector and returns its original length. The
296
* normalized vector is a 16.16 fixed-point unit vector with length close
297
* to 0x10000. The accuracy of the returned length is limited to 16 bits
298
* also. The function utilizes quick inverse square root approximation
299
* without divisions and square roots relying on Newton's iterations
300
* instead.
301
*/
302
FT_BASE( FT_UInt32 )
303
FT_Vector_NormLen( FT_Vector* vector );
304
305
306
/*
307
* Return -1, 0, or +1, depending on the orientation of a given corner. We
308
* use the Cartesian coordinate system, with positive vertical values going
309
* upwards. The function returns +1 if the corner turns to the left, -1 to
310
* the right, and 0 for undecidable cases.
311
*/
312
FT_BASE( FT_Int )
313
ft_corner_orientation( FT_Pos in_x,
314
FT_Pos in_y,
315
FT_Pos out_x,
316
FT_Pos out_y );
317
318
319
/*
320
* Return TRUE if a corner is flat or nearly flat. This is equivalent to
321
* saying that the corner point is close to its neighbors, or inside an
322
* ellipse defined by the neighbor focal points to be more precise.
323
*/
324
FT_BASE( FT_Int )
325
ft_corner_is_flat( FT_Pos in_x,
326
FT_Pos in_y,
327
FT_Pos out_x,
328
FT_Pos out_y );
329
330
331
/*
332
* Return the most significant bit index.
333
*/
334
335
#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
336
337
#if defined( __clang__ ) || ( defined( __GNUC__ ) && \
338
( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) ) )
339
340
#if FT_SIZEOF_INT == 4
341
342
#define FT_MSB( x ) ( 31 - __builtin_clz( x ) )
343
344
#elif FT_SIZEOF_LONG == 4
345
346
#define FT_MSB( x ) ( 31 - __builtin_clzl( x ) )
347
348
#endif
349
350
#elif defined( _MSC_VER ) && _MSC_VER >= 1400
351
352
#if defined( _WIN32_WCE )
353
354
#include <cmnintrin.h>
355
#pragma intrinsic( _CountLeadingZeros )
356
357
#define FT_MSB( x ) ( 31 - _CountLeadingZeros( x ) )
358
359
#elif defined( _M_ARM64 ) || defined( _M_ARM ) || defined( _M_ARM64EC )
360
361
#include <intrin.h>
362
#pragma intrinsic( _CountLeadingZeros )
363
364
#define FT_MSB( x ) ( 31 - _CountLeadingZeros( x ) )
365
366
#elif defined( _M_IX86 ) || defined( _M_AMD64 ) || defined( _M_IA64 )
367
368
#include <intrin.h>
369
#pragma intrinsic( _BitScanReverse )
370
371
static
__inline FT_Int32
372
FT_MSB_i386( FT_UInt32 x )
373
{
374
unsigned
long
where;
375
376
377
_BitScanReverse( &where, x );
378
379
return
(FT_Int32)where;
380
}
381
382
#define FT_MSB( x ) FT_MSB_i386( x )
383
384
#endif
385
386
#elif defined( __WATCOMC__ ) && defined( __386__ )
387
388
extern
__inline FT_Int32
389
FT_MSB_i386( FT_UInt32 x );
390
391
#pragma aux FT_MSB_i386 = \
392
"bsr eax, eax" \
393
__parm [__eax] __nomemory \
394
__value [__eax] \
395
__modify __exact [__eax] __nomemory;
396
397
#define FT_MSB( x ) FT_MSB_i386( x )
398
399
#elif defined( __CC_ARM )
400
401
#define FT_MSB( x ) ( 31 - __clz( x ) )
402
403
#elif defined( __SunOS_5_11 )
404
405
#include <string.h>
406
407
#define FT_MSB( x ) ( fls( x ) - 1 )
408
409
#elif defined( __DECC ) || defined( __DECCXX )
410
411
#include <builtins.h>
412
413
#define FT_MSB( x ) (FT_Int)( 63 - _leadz( x ) )
414
415
#elif defined( _CRAYC )
416
417
#include <intrinsics.h>
418
419
#define FT_MSB( x ) (FT_Int)( 31 - _leadz32( x ) )
420
421
#endif
/* FT_MSB macro definitions */
422
423
#endif
/* !FT_CONFIG_OPTION_NO_ASSEMBLER */
424
425
426
#ifndef FT_MSB
427
428
FT_BASE( FT_Int )
429
FT_MSB( FT_UInt32 z );
430
431
#endif
432
433
434
/*
435
* Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses
436
* two fixed-point arguments instead.
437
*/
438
FT_BASE( FT_Fixed )
439
FT_Hypot( FT_Fixed x,
440
FT_Fixed y );
441
442
443
/**************************************************************************
444
*
445
* @function:
446
* FT_SqrtFixed
447
*
448
* @description:
449
* Computes the square root of a 16.16 fixed-point value.
450
*
451
* @input:
452
* x ::
453
* The value to compute the root for.
454
*
455
* @return:
456
* The result of 'sqrt(x)'.
457
*
458
* @note:
459
* This function is slow and should be avoided. Consider @FT_Hypot or
460
* @FT_Vector_NormLen instead.
461
*/
462
FT_BASE( FT_UInt32 )
463
FT_SqrtFixed( FT_UInt32 x );
464
465
466
#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 )
/* << 6 */
467
#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) * 16384 )
/* << 14 */
468
#define INT_TO_FIXED( x ) ( (FT_Long)(x) * 65536 )
/* << 16 */
469
#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) * 4 )
/* << 2 */
470
#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 )
471
472
#define ROUND_F26DOT6( x ) ( ( (x) + 32 - ( x < 0 ) ) & -64 )
473
474
475
FT_END_HEADER
476
477
#endif
/* FTCALC_H_ */
478
479
480
/* END */
compiler-macros.h
freetype.h
freetype
include
freetype
internal
ftcalc.h
Generated by
1.18.0