2018-06-03 22:00:42 +02:00
|
|
|
/****************************************************************************
|
|
|
|
*
|
|
|
|
* ftcalc.h
|
|
|
|
*
|
|
|
|
* Arithmetic computations (specification).
|
|
|
|
*
|
2021-01-17 07:18:48 +01:00
|
|
|
* Copyright (C) 1996-2021 by
|
2018-06-03 22:00:42 +02:00
|
|
|
* David Turner, Robert Wilhelm, and Werner Lemberg.
|
|
|
|
*
|
|
|
|
* This file is part of the FreeType project, and may only be used,
|
|
|
|
* modified, and distributed under the terms of the FreeType project
|
|
|
|
* license, LICENSE.TXT. By continuing to use, modify, or distribute
|
|
|
|
* this file you indicate that you have read the license and
|
|
|
|
* understand and accept it fully.
|
|
|
|
*
|
|
|
|
*/
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
|
2016-01-12 21:37:13 +01:00
|
|
|
#ifndef FTCALC_H_
|
|
|
|
#define FTCALC_H_
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2000-12-09 01:45:38 +01:00
|
|
|
|
2020-06-08 13:31:55 +02:00
|
|
|
#include <freetype/freetype.h>
|
2000-12-09 01:45:38 +01:00
|
|
|
|
2020-07-02 11:09:57 +02:00
|
|
|
#include "compiler-macros.h"
|
2000-12-01 00:12:33 +01:00
|
|
|
|
|
|
|
FT_BEGIN_HEADER
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
|
2018-06-03 22:00:42 +02:00
|
|
|
/**************************************************************************
|
|
|
|
*
|
|
|
|
* FT_MulDiv() and FT_MulFix() are declared in freetype.h.
|
|
|
|
*
|
|
|
|
*/
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2014-08-12 05:39:34 +02:00
|
|
|
#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
|
|
|
|
/* Provide assembler fragments for performance-critical functions. */
|
|
|
|
/* These must be defined `static __inline__' with GCC. */
|
|
|
|
|
|
|
|
#if defined( __CC_ARM ) || defined( __ARMCC__ ) /* RVCT */
|
|
|
|
|
|
|
|
#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
|
|
|
|
|
|
|
|
/* documentation is in freetype.h */
|
|
|
|
|
|
|
|
static __inline FT_Int32
|
|
|
|
FT_MulFix_arm( FT_Int32 a,
|
|
|
|
FT_Int32 b )
|
|
|
|
{
|
2015-11-21 06:30:43 +01:00
|
|
|
FT_Int32 t, t2;
|
2014-08-12 05:39:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
smull t2, t, b, a /* (lo=t2,hi=t) = a*b */
|
|
|
|
mov a, t, asr #31 /* a = (hi >> 31) */
|
|
|
|
add a, a, #0x8000 /* a += 0x8000 */
|
|
|
|
adds t2, t2, a /* t2 += a */
|
|
|
|
adc t, t, #0 /* t += carry */
|
|
|
|
mov a, t2, lsr #16 /* a = t2 >> 16 */
|
|
|
|
orr a, a, t, lsl #16 /* a |= t << 16 */
|
|
|
|
}
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* __CC_ARM || __ARMCC__ */
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
|
|
|
|
#if defined( __arm__ ) && \
|
|
|
|
( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
|
|
|
|
!( defined( __CC_ARM ) || defined( __ARMCC__ ) )
|
|
|
|
|
|
|
|
#define FT_MULFIX_ASSEMBLER FT_MulFix_arm
|
|
|
|
|
|
|
|
/* documentation is in freetype.h */
|
|
|
|
|
|
|
|
static __inline__ FT_Int32
|
|
|
|
FT_MulFix_arm( FT_Int32 a,
|
|
|
|
FT_Int32 b )
|
|
|
|
{
|
2015-11-21 06:30:43 +01:00
|
|
|
FT_Int32 t, t2;
|
2014-08-12 05:39:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
__asm__ __volatile__ (
|
|
|
|
"smull %1, %2, %4, %3\n\t" /* (lo=%1,hi=%2) = a*b */
|
|
|
|
"mov %0, %2, asr #31\n\t" /* %0 = (hi >> 31) */
|
|
|
|
#if defined( __clang__ ) && defined( __thumb2__ )
|
|
|
|
"add.w %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
|
|
|
|
#else
|
|
|
|
"add %0, %0, #0x8000\n\t" /* %0 += 0x8000 */
|
|
|
|
#endif
|
|
|
|
"adds %1, %1, %0\n\t" /* %1 += %0 */
|
|
|
|
"adc %2, %2, #0\n\t" /* %2 += carry */
|
|
|
|
"mov %0, %1, lsr #16\n\t" /* %0 = %1 >> 16 */
|
|
|
|
"orr %0, %0, %2, lsl #16\n\t" /* %0 |= %2 << 16 */
|
|
|
|
: "=r"(a), "=&r"(t2), "=&r"(t)
|
|
|
|
: "r"(a), "r"(b)
|
|
|
|
: "cc" );
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* __arm__ && */
|
|
|
|
/* ( __thumb2__ || !__thumb__ ) && */
|
|
|
|
/* !( __CC_ARM || __ARMCC__ ) */
|
|
|
|
|
|
|
|
|
|
|
|
#if defined( __i386__ )
|
|
|
|
|
|
|
|
#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
|
|
|
|
|
|
|
|
/* documentation is in freetype.h */
|
|
|
|
|
|
|
|
static __inline__ FT_Int32
|
|
|
|
FT_MulFix_i386( FT_Int32 a,
|
|
|
|
FT_Int32 b )
|
|
|
|
{
|
2015-11-21 06:30:43 +01:00
|
|
|
FT_Int32 result;
|
2014-08-12 05:39:34 +02:00
|
|
|
|
|
|
|
|
|
|
|
__asm__ __volatile__ (
|
|
|
|
"imul %%edx\n"
|
|
|
|
"movl %%edx, %%ecx\n"
|
|
|
|
"sarl $31, %%ecx\n"
|
|
|
|
"addl $0x8000, %%ecx\n"
|
|
|
|
"addl %%ecx, %%eax\n"
|
|
|
|
"adcl $0, %%edx\n"
|
|
|
|
"shrl $16, %%eax\n"
|
|
|
|
"shll $16, %%edx\n"
|
|
|
|
"addl %%edx, %%eax\n"
|
|
|
|
: "=a"(result), "=d"(b)
|
|
|
|
: "a"(a), "d"(b)
|
|
|
|
: "%ecx", "cc" );
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* i386 */
|
|
|
|
|
|
|
|
#endif /* __GNUC__ */
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER /* Visual C++ */
|
|
|
|
|
|
|
|
#ifdef _M_IX86
|
|
|
|
|
|
|
|
#define FT_MULFIX_ASSEMBLER FT_MulFix_i386
|
|
|
|
|
|
|
|
/* documentation is in freetype.h */
|
|
|
|
|
|
|
|
static __inline FT_Int32
|
|
|
|
FT_MulFix_i386( FT_Int32 a,
|
|
|
|
FT_Int32 b )
|
|
|
|
{
|
2015-11-21 06:30:43 +01:00
|
|
|
FT_Int32 result;
|
2014-08-12 05:39:34 +02:00
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
mov eax, a
|
|
|
|
mov edx, b
|
|
|
|
imul edx
|
|
|
|
mov ecx, edx
|
|
|
|
sar ecx, 31
|
|
|
|
add ecx, 8000h
|
|
|
|
add eax, ecx
|
|
|
|
adc edx, 0
|
|
|
|
shr eax, 16
|
|
|
|
shl edx, 16
|
|
|
|
add eax, edx
|
|
|
|
mov result, eax
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* _M_IX86 */
|
|
|
|
|
|
|
|
#endif /* _MSC_VER */
|
|
|
|
|
|
|
|
|
|
|
|
#if defined( __GNUC__ ) && defined( __x86_64__ )
|
|
|
|
|
|
|
|
#define FT_MULFIX_ASSEMBLER FT_MulFix_x86_64
|
|
|
|
|
|
|
|
static __inline__ FT_Int32
|
|
|
|
FT_MulFix_x86_64( FT_Int32 a,
|
|
|
|
FT_Int32 b )
|
|
|
|
{
|
|
|
|
/* Temporarily disable the warning that C90 doesn't support */
|
|
|
|
/* `long long'. */
|
2014-10-11 20:09:28 +02:00
|
|
|
#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 )
|
2014-08-12 05:39:34 +02:00
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wlong-long"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
/* Technically not an assembly fragment, but GCC does a really good */
|
|
|
|
/* job at inlining it and generating good machine code for it. */
|
|
|
|
long long ret, tmp;
|
|
|
|
|
|
|
|
|
|
|
|
ret = (long long)a * b;
|
|
|
|
tmp = ret >> 63;
|
|
|
|
ret += 0x8000 + tmp;
|
|
|
|
|
|
|
|
return (FT_Int32)( ret >> 16 );
|
|
|
|
#else
|
|
|
|
|
|
|
|
/* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine */
|
|
|
|
/* code from the lines below. The main issue is that `wide_a' is not */
|
|
|
|
/* properly initialized by sign-extending `a'. Instead, the generated */
|
|
|
|
/* machine code assumes that the register that contains `a' on input */
|
|
|
|
/* can be used directly as a 64-bit value, which is wrong most of the */
|
|
|
|
/* time. */
|
|
|
|
long long wide_a = (long long)a;
|
|
|
|
long long wide_b = (long long)b;
|
|
|
|
long long result;
|
|
|
|
|
|
|
|
|
|
|
|
__asm__ __volatile__ (
|
|
|
|
"imul %2, %1\n"
|
|
|
|
"mov %1, %0\n"
|
|
|
|
"sar $63, %0\n"
|
|
|
|
"lea 0x8000(%1, %0), %0\n"
|
|
|
|
"sar $16, %0\n"
|
|
|
|
: "=&r"(result), "=&r"(wide_a)
|
|
|
|
: "r"(wide_b)
|
|
|
|
: "cc" );
|
|
|
|
|
|
|
|
return (FT_Int32)result;
|
|
|
|
#endif
|
|
|
|
|
2014-10-11 20:09:28 +02:00
|
|
|
#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 6 )
|
2014-08-12 05:39:34 +02:00
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* __GNUC__ && __x86_64__ */
|
|
|
|
|
|
|
|
#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
|
|
|
|
#ifdef FT_MULFIX_ASSEMBLER
|
2014-11-19 06:46:23 +01:00
|
|
|
#define FT_MulFix( a, b ) FT_MULFIX_ASSEMBLER( (FT_Int32)(a), (FT_Int32)(b) )
|
2014-08-12 05:39:34 +02:00
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2018-06-03 22:00:42 +02:00
|
|
|
/**************************************************************************
|
|
|
|
*
|
2018-06-17 21:08:36 +02:00
|
|
|
* @function:
|
2018-06-03 22:00:42 +02:00
|
|
|
* FT_MulDiv_No_Round
|
|
|
|
*
|
2018-06-17 21:08:36 +02:00
|
|
|
* @description:
|
2018-08-24 18:52:30 +02:00
|
|
|
* A very simple function used to perform the computation '(a*b)/c'
|
2018-06-03 22:00:42 +02:00
|
|
|
* (without rounding) with maximum accuracy (it uses a 64-bit
|
|
|
|
* intermediate integer whenever necessary).
|
|
|
|
*
|
2018-07-02 15:52:36 +02:00
|
|
|
* This function isn't necessarily as fast as some processor-specific
|
2018-06-03 22:00:42 +02:00
|
|
|
* operations, but is at least completely portable.
|
|
|
|
*
|
2018-06-17 21:08:36 +02:00
|
|
|
* @input:
|
2018-06-03 22:00:42 +02:00
|
|
|
* a ::
|
|
|
|
* The first multiplier.
|
|
|
|
* b ::
|
|
|
|
* The second multiplier.
|
|
|
|
* c ::
|
|
|
|
* The divisor.
|
|
|
|
*
|
2018-06-17 21:08:36 +02:00
|
|
|
* @return:
|
2018-08-24 18:52:30 +02:00
|
|
|
* The result of '(a*b)/c'. This function never traps when trying to
|
|
|
|
* divide by zero; it simply returns 'MaxInt' or 'MinInt' depending on
|
|
|
|
* the signs of 'a' and 'b'.
|
2018-06-03 22:00:42 +02:00
|
|
|
*/
|
2003-11-25 19:15:56 +01:00
|
|
|
FT_BASE( FT_Long )
|
|
|
|
FT_MulDiv_No_Round( FT_Long a,
|
|
|
|
FT_Long b,
|
|
|
|
FT_Long c );
|
|
|
|
|
2006-11-03 10:40:12 +01:00
|
|
|
|
2008-05-15 01:05:38 +02:00
|
|
|
/*
|
2018-08-24 18:52:30 +02:00
|
|
|
* A variant of FT_Matrix_Multiply which scales its result afterwards. The
|
|
|
|
* idea is that both `a' and `b' are scaled by factors of 10 so that the
|
|
|
|
* values are as precise as possible to get a correct result during the
|
|
|
|
* 64bit multiplication. Let `sa' and `sb' be the scaling factors of `a'
|
|
|
|
* and `b', respectively, then the scaling factor of the result is `sa*sb'.
|
2008-05-15 01:05:38 +02:00
|
|
|
*/
|
|
|
|
FT_BASE( void )
|
|
|
|
FT_Matrix_Multiply_Scaled( const FT_Matrix* a,
|
|
|
|
FT_Matrix *b,
|
|
|
|
FT_Long scaling );
|
|
|
|
|
|
|
|
|
2018-06-24 06:22:48 +02:00
|
|
|
/*
|
|
|
|
* Check a matrix. If the transformation would lead to extreme shear or
|
|
|
|
* extreme scaling, for example, return 0. If everything is OK, return 1.
|
|
|
|
*
|
|
|
|
* Based on geometric considerations we use the following inequality to
|
|
|
|
* identify a degenerate matrix.
|
|
|
|
*
|
|
|
|
* 50 * abs(xx*yy - xy*yx) < xx^2 + xy^2 + yx^2 + yy^2
|
|
|
|
*
|
|
|
|
* Value 50 is heuristic.
|
|
|
|
*/
|
|
|
|
FT_BASE( FT_Bool )
|
|
|
|
FT_Matrix_Check( const FT_Matrix* matrix );
|
|
|
|
|
|
|
|
|
2008-05-15 01:05:38 +02:00
|
|
|
/*
|
2018-06-03 22:00:42 +02:00
|
|
|
* A variant of FT_Vector_Transform. See comments for
|
|
|
|
* FT_Matrix_Multiply_Scaled.
|
2008-05-15 01:05:38 +02:00
|
|
|
*/
|
|
|
|
FT_BASE( void )
|
|
|
|
FT_Vector_Transform_Scaled( FT_Vector* vector,
|
|
|
|
const FT_Matrix* matrix,
|
|
|
|
FT_Long scaling );
|
|
|
|
|
|
|
|
|
2015-06-30 04:32:05 +02:00
|
|
|
/*
|
2018-08-24 18:52:30 +02:00
|
|
|
* This function normalizes a vector and returns its original length. The
|
|
|
|
* normalized vector is a 16.16 fixed-point unit vector with length close
|
|
|
|
* to 0x10000. The accuracy of the returned length is limited to 16 bits
|
|
|
|
* also. The function utilizes quick inverse square root approximation
|
|
|
|
* without divisions and square roots relying on Newton's iterations
|
|
|
|
* instead.
|
2015-06-30 04:32:05 +02:00
|
|
|
*/
|
|
|
|
FT_BASE( FT_UInt32 )
|
|
|
|
FT_Vector_NormLen( FT_Vector* vector );
|
|
|
|
|
|
|
|
|
2006-11-02 18:21:02 +01:00
|
|
|
/*
|
2018-08-24 18:52:30 +02:00
|
|
|
* Return -1, 0, or +1, depending on the orientation of a given corner. We
|
|
|
|
* use the Cartesian coordinate system, with positive vertical values going
|
|
|
|
* upwards. The function returns +1 if the corner turns to the left, -1 to
|
|
|
|
* the right, and 0 for undecidable cases.
|
2006-11-02 18:21:02 +01:00
|
|
|
*/
|
|
|
|
FT_BASE( FT_Int )
|
2006-11-03 10:40:12 +01:00
|
|
|
ft_corner_orientation( FT_Pos in_x,
|
|
|
|
FT_Pos in_y,
|
|
|
|
FT_Pos out_x,
|
|
|
|
FT_Pos out_y );
|
2006-11-02 18:21:02 +01:00
|
|
|
|
2014-10-25 05:50:57 +02:00
|
|
|
|
2006-11-02 18:21:02 +01:00
|
|
|
/*
|
2018-06-03 22:00:42 +02:00
|
|
|
* Return TRUE if a corner is flat or nearly flat. This is equivalent to
|
|
|
|
* saying that the corner point is close to its neighbors, or inside an
|
|
|
|
* ellipse defined by the neighbor focal points to be more precise.
|
2006-11-02 18:21:02 +01:00
|
|
|
*/
|
|
|
|
FT_BASE( FT_Int )
|
2006-11-03 10:40:12 +01:00
|
|
|
ft_corner_is_flat( FT_Pos in_x,
|
|
|
|
FT_Pos in_y,
|
|
|
|
FT_Pos out_x,
|
|
|
|
FT_Pos out_y );
|
|
|
|
|
2003-11-25 19:15:56 +01:00
|
|
|
|
2013-01-24 01:43:28 +01:00
|
|
|
/*
|
2018-06-03 22:00:42 +02:00
|
|
|
* Return the most significant bit index.
|
2013-01-24 13:33:06 +01:00
|
|
|
*/
|
2014-08-15 05:01:01 +02:00
|
|
|
|
|
|
|
#ifndef FT_CONFIG_OPTION_NO_ASSEMBLER
|
2018-05-12 06:16:46 +02:00
|
|
|
|
2014-10-11 20:09:28 +02:00
|
|
|
#if defined( __GNUC__ ) && \
|
|
|
|
( __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 4 ) )
|
2014-08-15 05:01:01 +02:00
|
|
|
|
|
|
|
#if FT_SIZEOF_INT == 4
|
|
|
|
|
|
|
|
#define FT_MSB( x ) ( 31 - __builtin_clz( x ) )
|
|
|
|
|
|
|
|
#elif FT_SIZEOF_LONG == 4
|
|
|
|
|
|
|
|
#define FT_MSB( x ) ( 31 - __builtin_clzl( x ) )
|
|
|
|
|
2021-10-01 17:50:12 +02:00
|
|
|
#endif
|
2018-05-12 06:16:46 +02:00
|
|
|
|
2018-05-18 14:57:30 +02:00
|
|
|
#elif defined( _MSC_VER ) && ( _MSC_VER >= 1400 )
|
2018-05-12 06:16:46 +02:00
|
|
|
|
|
|
|
#if FT_SIZEOF_INT == 4
|
|
|
|
|
|
|
|
#include <intrin.h>
|
2019-06-01 04:31:47 +02:00
|
|
|
#pragma intrinsic( _BitScanReverse )
|
2018-05-12 06:16:46 +02:00
|
|
|
|
2018-05-17 19:40:44 +02:00
|
|
|
static __inline FT_Int32
|
2018-05-12 06:16:46 +02:00
|
|
|
FT_MSB_i386( FT_UInt32 x )
|
|
|
|
{
|
|
|
|
unsigned long where;
|
|
|
|
|
|
|
|
|
|
|
|
_BitScanReverse( &where, x );
|
|
|
|
|
|
|
|
return (FT_Int32)where;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define FT_MSB( x ) ( FT_MSB_i386( x ) )
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2021-10-01 17:50:12 +02:00
|
|
|
#elif defined( __DECC ) || defined( __DECCXX )
|
|
|
|
|
|
|
|
#include <builtins.h>
|
2018-05-18 10:57:51 +02:00
|
|
|
|
2021-10-01 17:50:12 +02:00
|
|
|
#define FT_MSB( x ) (FT_Int)( 63 - _leadz( x ) )
|
|
|
|
|
|
|
|
#elif defined( _CRAYC )
|
|
|
|
|
|
|
|
#include <intrinsics.h>
|
|
|
|
|
|
|
|
#define FT_MSB( x ) (FT_Int)( 31 - _leadz32( x ) )
|
|
|
|
|
|
|
|
#endif /* FT_MSB macro definitions */
|
2018-05-12 06:16:46 +02:00
|
|
|
|
2014-08-15 05:01:01 +02:00
|
|
|
#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
|
|
|
|
|
2021-10-01 17:50:12 +02:00
|
|
|
|
2014-08-15 05:01:01 +02:00
|
|
|
#ifndef FT_MSB
|
|
|
|
|
2013-01-24 01:43:28 +01:00
|
|
|
FT_BASE( FT_Int )
|
2013-01-24 09:12:56 +01:00
|
|
|
FT_MSB( FT_UInt32 z );
|
|
|
|
|
2014-08-15 05:01:01 +02:00
|
|
|
#endif
|
|
|
|
|
2013-01-24 09:12:56 +01:00
|
|
|
|
|
|
|
/*
|
2018-06-03 22:00:42 +02:00
|
|
|
* Return sqrt(x*x+y*y), which is the same as `FT_Vector_Length' but uses
|
|
|
|
* two fixed-point arguments instead.
|
2013-01-24 09:12:56 +01:00
|
|
|
*/
|
|
|
|
FT_BASE( FT_Fixed )
|
|
|
|
FT_Hypot( FT_Fixed x,
|
|
|
|
FT_Fixed y );
|
2013-01-24 01:43:28 +01:00
|
|
|
|
|
|
|
|
2014-08-22 05:44:44 +02:00
|
|
|
#if 0
|
|
|
|
|
2018-06-03 22:00:42 +02:00
|
|
|
/**************************************************************************
|
|
|
|
*
|
2018-06-17 21:08:36 +02:00
|
|
|
* @function:
|
2018-06-03 22:00:42 +02:00
|
|
|
* FT_SqrtFixed
|
|
|
|
*
|
2018-06-17 21:08:36 +02:00
|
|
|
* @description:
|
2018-06-03 22:00:42 +02:00
|
|
|
* Computes the square root of a 16.16 fixed-point value.
|
|
|
|
*
|
2018-06-17 21:08:36 +02:00
|
|
|
* @input:
|
2018-06-03 22:00:42 +02:00
|
|
|
* x ::
|
|
|
|
* The value to compute the root for.
|
|
|
|
*
|
2018-06-17 21:08:36 +02:00
|
|
|
* @return:
|
2018-08-24 18:52:30 +02:00
|
|
|
* The result of 'sqrt(x)'.
|
2018-06-03 22:00:42 +02:00
|
|
|
*
|
2018-06-17 21:08:36 +02:00
|
|
|
* @note:
|
2018-06-03 22:00:42 +02:00
|
|
|
* This function is not very fast.
|
|
|
|
*/
|
2014-08-22 05:44:44 +02:00
|
|
|
FT_BASE( FT_Int32 )
|
|
|
|
FT_SqrtFixed( FT_Int32 x );
|
|
|
|
|
|
|
|
#endif /* 0 */
|
|
|
|
|
|
|
|
|
2017-06-03 06:13:10 +02:00
|
|
|
#define INT_TO_F26DOT6( x ) ( (FT_Long)(x) * 64 ) /* << 6 */
|
|
|
|
#define INT_TO_F2DOT14( x ) ( (FT_Long)(x) * 16384 ) /* << 14 */
|
|
|
|
#define INT_TO_FIXED( x ) ( (FT_Long)(x) * 65536 ) /* << 16 */
|
|
|
|
#define F2DOT14_TO_FIXED( x ) ( (FT_Long)(x) * 4 ) /* << 2 */
|
2009-06-21 20:17:01 +02:00
|
|
|
#define FIXED_TO_INT( x ) ( FT_RoundFix( x ) >> 16 )
|
1999-12-17 00:11:37 +01:00
|
|
|
|
2020-06-20 04:46:30 +02:00
|
|
|
#define ROUND_F26DOT6( x ) ( ( (x) + 32 - ( x < 0 ) ) & -64 )
|
1999-12-17 00:11:37 +01:00
|
|
|
|
Handle some integer overflow run-time errors (#46149, #48979).
This commit (mainly for 32bit CPUs) is the first of a series of
similar commits to handle known integer overflows. Basically, all
of them are harmless, since they affect rendering of glyphs only,
not posing security threats. It is expected that fuzzying will show
up more overflows, to be fixed in due course.
The idea is to mark places where overflows can occur, using macros
that simply cast to unsigned integers, because overflow arithmetic
is well defined in this case. Doing so suppresses run-time errors
of sanitizers without adding computational overhead.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT,
OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG,
OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros.
* src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply,
FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled,
ft_corner_orientation): Use new macros.
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros.
2017-05-29 13:29:28 +02:00
|
|
|
/*
|
2018-06-03 22:00:42 +02:00
|
|
|
* The following macros have two purposes.
|
Handle some integer overflow run-time errors (#46149, #48979).
This commit (mainly for 32bit CPUs) is the first of a series of
similar commits to handle known integer overflows. Basically, all
of them are harmless, since they affect rendering of glyphs only,
not posing security threats. It is expected that fuzzying will show
up more overflows, to be fixed in due course.
The idea is to mark places where overflows can occur, using macros
that simply cast to unsigned integers, because overflow arithmetic
is well defined in this case. Doing so suppresses run-time errors
of sanitizers without adding computational overhead.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT,
OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG,
OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros.
* src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply,
FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled,
ft_corner_orientation): Use new macros.
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros.
2017-05-29 13:29:28 +02:00
|
|
|
*
|
2018-06-03 22:00:42 +02:00
|
|
|
* - Tag places where overflow is expected and harmless.
|
Handle some integer overflow run-time errors (#46149, #48979).
This commit (mainly for 32bit CPUs) is the first of a series of
similar commits to handle known integer overflows. Basically, all
of them are harmless, since they affect rendering of glyphs only,
not posing security threats. It is expected that fuzzying will show
up more overflows, to be fixed in due course.
The idea is to mark places where overflows can occur, using macros
that simply cast to unsigned integers, because overflow arithmetic
is well defined in this case. Doing so suppresses run-time errors
of sanitizers without adding computational overhead.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT,
OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG,
OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros.
* src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply,
FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled,
ft_corner_orientation): Use new macros.
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros.
2017-05-29 13:29:28 +02:00
|
|
|
*
|
2018-06-03 22:00:42 +02:00
|
|
|
* - Avoid run-time sanitizer errors.
|
Handle some integer overflow run-time errors (#46149, #48979).
This commit (mainly for 32bit CPUs) is the first of a series of
similar commits to handle known integer overflows. Basically, all
of them are harmless, since they affect rendering of glyphs only,
not posing security threats. It is expected that fuzzying will show
up more overflows, to be fixed in due course.
The idea is to mark places where overflows can occur, using macros
that simply cast to unsigned integers, because overflow arithmetic
is well defined in this case. Doing so suppresses run-time errors
of sanitizers without adding computational overhead.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT,
OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG,
OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros.
* src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply,
FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled,
ft_corner_orientation): Use new macros.
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros.
2017-05-29 13:29:28 +02:00
|
|
|
*
|
2018-06-03 22:00:42 +02:00
|
|
|
* Use with care!
|
Handle some integer overflow run-time errors (#46149, #48979).
This commit (mainly for 32bit CPUs) is the first of a series of
similar commits to handle known integer overflows. Basically, all
of them are harmless, since they affect rendering of glyphs only,
not posing security threats. It is expected that fuzzying will show
up more overflows, to be fixed in due course.
The idea is to mark places where overflows can occur, using macros
that simply cast to unsigned integers, because overflow arithmetic
is well defined in this case. Doing so suppresses run-time errors
of sanitizers without adding computational overhead.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT,
OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG,
OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros.
* src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply,
FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled,
ft_corner_orientation): Use new macros.
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros.
2017-05-29 13:29:28 +02:00
|
|
|
*/
|
2018-07-16 18:45:23 +02:00
|
|
|
#define ADD_INT( a, b ) \
|
|
|
|
(FT_Int)( (FT_UInt)(a) + (FT_UInt)(b) )
|
|
|
|
#define SUB_INT( a, b ) \
|
|
|
|
(FT_Int)( (FT_UInt)(a) - (FT_UInt)(b) )
|
|
|
|
#define MUL_INT( a, b ) \
|
|
|
|
(FT_Int)( (FT_UInt)(a) * (FT_UInt)(b) )
|
|
|
|
#define NEG_INT( a ) \
|
|
|
|
(FT_Int)( (FT_UInt)0 - (FT_UInt)(a) )
|
|
|
|
|
2017-06-09 11:21:58 +02:00
|
|
|
#define ADD_LONG( a, b ) \
|
Handle some integer overflow run-time errors (#46149, #48979).
This commit (mainly for 32bit CPUs) is the first of a series of
similar commits to handle known integer overflows. Basically, all
of them are harmless, since they affect rendering of glyphs only,
not posing security threats. It is expected that fuzzying will show
up more overflows, to be fixed in due course.
The idea is to mark places where overflows can occur, using macros
that simply cast to unsigned integers, because overflow arithmetic
is well defined in this case. Doing so suppresses run-time errors
of sanitizers without adding computational overhead.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT,
OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG,
OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros.
* src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply,
FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled,
ft_corner_orientation): Use new macros.
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros.
2017-05-29 13:29:28 +02:00
|
|
|
(FT_Long)( (FT_ULong)(a) + (FT_ULong)(b) )
|
2017-06-09 11:21:58 +02:00
|
|
|
#define SUB_LONG( a, b ) \
|
Handle some integer overflow run-time errors (#46149, #48979).
This commit (mainly for 32bit CPUs) is the first of a series of
similar commits to handle known integer overflows. Basically, all
of them are harmless, since they affect rendering of glyphs only,
not posing security threats. It is expected that fuzzying will show
up more overflows, to be fixed in due course.
The idea is to mark places where overflows can occur, using macros
that simply cast to unsigned integers, because overflow arithmetic
is well defined in this case. Doing so suppresses run-time errors
of sanitizers without adding computational overhead.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT,
OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG,
OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros.
* src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply,
FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled,
ft_corner_orientation): Use new macros.
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros.
2017-05-29 13:29:28 +02:00
|
|
|
(FT_Long)( (FT_ULong)(a) - (FT_ULong)(b) )
|
2017-06-09 11:21:58 +02:00
|
|
|
#define MUL_LONG( a, b ) \
|
Handle some integer overflow run-time errors (#46149, #48979).
This commit (mainly for 32bit CPUs) is the first of a series of
similar commits to handle known integer overflows. Basically, all
of them are harmless, since they affect rendering of glyphs only,
not posing security threats. It is expected that fuzzying will show
up more overflows, to be fixed in due course.
The idea is to mark places where overflows can occur, using macros
that simply cast to unsigned integers, because overflow arithmetic
is well defined in this case. Doing so suppresses run-time errors
of sanitizers without adding computational overhead.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT,
OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG,
OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros.
* src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply,
FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled,
ft_corner_orientation): Use new macros.
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros.
2017-05-29 13:29:28 +02:00
|
|
|
(FT_Long)( (FT_ULong)(a) * (FT_ULong)(b) )
|
[cff] 32bit integer overflow run-time errors 2/2 (#46149).
This commit handles the new engine.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT32,
OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, NEG_INT, NEG_LONG,
NEG_INT32): New macros.
* src/cff/cf2ft.c (cf2_getScaleAndHintFlag): Use OVERFLOW_ADD_INT32.
* src/cff/cf2hints.c (cf2_getWindingMomentum, cf2_hint_init,
cf2_hintmap_map, cf2_glyphpath_hintPoint,
cf2_glyphpath_computeIntersection, cf2_glyphpath_computeOffset,
cf2_glyphpath_lineTo, cf2_glyphpath_curveTo): Use
OVERFLOW_ADD_INT32, OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, and
NEG_INT32 where appropriate.
* src/cff/cf2intrp.c (cf2_doFlex, cf2_doBlend,
cf2_interpT2CharString): Ditto.
Also add some other code where needed to avoid overflow.
2017-05-31 16:16:50 +02:00
|
|
|
#define NEG_LONG( a ) \
|
2017-06-28 22:57:41 +02:00
|
|
|
(FT_Long)( (FT_ULong)0 - (FT_ULong)(a) )
|
[cff] 32bit integer overflow run-time errors 2/2 (#46149).
This commit handles the new engine.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT32,
OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, NEG_INT, NEG_LONG,
NEG_INT32): New macros.
* src/cff/cf2ft.c (cf2_getScaleAndHintFlag): Use OVERFLOW_ADD_INT32.
* src/cff/cf2hints.c (cf2_getWindingMomentum, cf2_hint_init,
cf2_hintmap_map, cf2_glyphpath_hintPoint,
cf2_glyphpath_computeIntersection, cf2_glyphpath_computeOffset,
cf2_glyphpath_lineTo, cf2_glyphpath_curveTo): Use
OVERFLOW_ADD_INT32, OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, and
NEG_INT32 where appropriate.
* src/cff/cf2intrp.c (cf2_doFlex, cf2_doBlend,
cf2_interpT2CharString): Ditto.
Also add some other code where needed to avoid overflow.
2017-05-31 16:16:50 +02:00
|
|
|
|
2017-06-09 11:21:58 +02:00
|
|
|
#define ADD_INT32( a, b ) \
|
[cff] 32bit integer overflow run-time errors 2/2 (#46149).
This commit handles the new engine.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT32,
OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, NEG_INT, NEG_LONG,
NEG_INT32): New macros.
* src/cff/cf2ft.c (cf2_getScaleAndHintFlag): Use OVERFLOW_ADD_INT32.
* src/cff/cf2hints.c (cf2_getWindingMomentum, cf2_hint_init,
cf2_hintmap_map, cf2_glyphpath_hintPoint,
cf2_glyphpath_computeIntersection, cf2_glyphpath_computeOffset,
cf2_glyphpath_lineTo, cf2_glyphpath_curveTo): Use
OVERFLOW_ADD_INT32, OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, and
NEG_INT32 where appropriate.
* src/cff/cf2intrp.c (cf2_doFlex, cf2_doBlend,
cf2_interpT2CharString): Ditto.
Also add some other code where needed to avoid overflow.
2017-05-31 16:16:50 +02:00
|
|
|
(FT_Int32)( (FT_UInt32)(a) + (FT_UInt32)(b) )
|
2017-06-09 11:21:58 +02:00
|
|
|
#define SUB_INT32( a, b ) \
|
[cff] 32bit integer overflow run-time errors 2/2 (#46149).
This commit handles the new engine.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT32,
OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, NEG_INT, NEG_LONG,
NEG_INT32): New macros.
* src/cff/cf2ft.c (cf2_getScaleAndHintFlag): Use OVERFLOW_ADD_INT32.
* src/cff/cf2hints.c (cf2_getWindingMomentum, cf2_hint_init,
cf2_hintmap_map, cf2_glyphpath_hintPoint,
cf2_glyphpath_computeIntersection, cf2_glyphpath_computeOffset,
cf2_glyphpath_lineTo, cf2_glyphpath_curveTo): Use
OVERFLOW_ADD_INT32, OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, and
NEG_INT32 where appropriate.
* src/cff/cf2intrp.c (cf2_doFlex, cf2_doBlend,
cf2_interpT2CharString): Ditto.
Also add some other code where needed to avoid overflow.
2017-05-31 16:16:50 +02:00
|
|
|
(FT_Int32)( (FT_UInt32)(a) - (FT_UInt32)(b) )
|
2017-06-09 11:21:58 +02:00
|
|
|
#define MUL_INT32( a, b ) \
|
[cff] 32bit integer overflow run-time errors 2/2 (#46149).
This commit handles the new engine.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT32,
OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, NEG_INT, NEG_LONG,
NEG_INT32): New macros.
* src/cff/cf2ft.c (cf2_getScaleAndHintFlag): Use OVERFLOW_ADD_INT32.
* src/cff/cf2hints.c (cf2_getWindingMomentum, cf2_hint_init,
cf2_hintmap_map, cf2_glyphpath_hintPoint,
cf2_glyphpath_computeIntersection, cf2_glyphpath_computeOffset,
cf2_glyphpath_lineTo, cf2_glyphpath_curveTo): Use
OVERFLOW_ADD_INT32, OVERFLOW_SUB_INT32, OVERFLOW_MUL_INT32, and
NEG_INT32 where appropriate.
* src/cff/cf2intrp.c (cf2_doFlex, cf2_doBlend,
cf2_interpT2CharString): Ditto.
Also add some other code where needed to avoid overflow.
2017-05-31 16:16:50 +02:00
|
|
|
(FT_Int32)( (FT_UInt32)(a) * (FT_UInt32)(b) )
|
|
|
|
#define NEG_INT32( a ) \
|
2017-06-28 22:57:41 +02:00
|
|
|
(FT_Int32)( (FT_UInt32)0 - (FT_UInt32)(a) )
|
Handle some integer overflow run-time errors (#46149, #48979).
This commit (mainly for 32bit CPUs) is the first of a series of
similar commits to handle known integer overflows. Basically, all
of them are harmless, since they affect rendering of glyphs only,
not posing security threats. It is expected that fuzzying will show
up more overflows, to be fixed in due course.
The idea is to mark places where overflows can occur, using macros
that simply cast to unsigned integers, because overflow arithmetic
is well defined in this case. Doing so suppresses run-time errors
of sanitizers without adding computational overhead.
* include/freetype/internal/ftcalc.h (OVERFLOW_ADD_INT,
OVERFLOW_SUB_INT, OVERFLOW_MUL_INT, OVERFLOW_ADD_LONG,
OVERFLOW_SUB_LONG, OVERFLOW_MUL_LONG): New macros.
* src/base/ftcalc.c (FT_RoundFix, FT_CeilFix, FT_Matrix_Multiply,
FT_Matrix_Multiply_Scaled, FT_Vector_Transform_Scaled,
ft_corner_orientation): Use new macros.
* src/base/ftoutln.c (FT_Outline_Get_Orientation): Use new macros.
2017-05-29 13:29:28 +02:00
|
|
|
|
2021-08-19 05:05:51 +02:00
|
|
|
#ifdef FT_INT64
|
2018-08-23 17:53:54 +02:00
|
|
|
|
|
|
|
#define ADD_INT64( a, b ) \
|
|
|
|
(FT_Int64)( (FT_UInt64)(a) + (FT_UInt64)(b) )
|
|
|
|
#define SUB_INT64( a, b ) \
|
|
|
|
(FT_Int64)( (FT_UInt64)(a) - (FT_UInt64)(b) )
|
|
|
|
#define MUL_INT64( a, b ) \
|
|
|
|
(FT_Int64)( (FT_UInt64)(a) * (FT_UInt64)(b) )
|
|
|
|
#define NEG_INT64( a ) \
|
|
|
|
(FT_Int64)( (FT_UInt64)0 - (FT_UInt64)(a) )
|
|
|
|
|
2021-08-19 05:05:51 +02:00
|
|
|
#endif /* FT_INT64 */
|
2018-08-23 17:53:54 +02:00
|
|
|
|
2000-12-09 01:45:38 +01:00
|
|
|
|
2000-12-01 00:12:33 +01:00
|
|
|
FT_END_HEADER
|
2000-07-18 08:50:03 +02:00
|
|
|
|
2016-01-12 21:37:13 +01:00
|
|
|
#endif /* FTCALC_H_ */
|
1999-12-17 00:11:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
/* END */
|