#include <freetype/ftglyph.h>
#include <freetype/fttrigon.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftobjs.h>
#ifdef FT_MULFIX_ASSEMBLER
#undef FT_MulFix
#endif
#ifndef FT_INT64
typedef struct FT_Int64_
{
FT_UInt32 lo;
FT_UInt32 hi;
} FT_Int64;
#endif
#undef FT_COMPONENT
#define FT_COMPONENT …
#define FT_MOVE_SIGN( x, x_unsigned, s ) …
FT_EXPORT_DEF( FT_Fixed )
FT_RoundFix( FT_Fixed a )
{ … }
FT_EXPORT_DEF( FT_Fixed )
FT_CeilFix( FT_Fixed a )
{ … }
FT_EXPORT_DEF( FT_Fixed )
FT_FloorFix( FT_Fixed a )
{ … }
#ifndef FT_MSB
FT_BASE_DEF( FT_Int )
FT_MSB( FT_UInt32 z )
{
FT_Int shift = 0;
if ( z & 0xFFFF0000UL )
{
z >>= 16;
shift += 16;
}
if ( z & 0x0000FF00UL )
{
z >>= 8;
shift += 8;
}
if ( z & 0x000000F0UL )
{
z >>= 4;
shift += 4;
}
if ( z & 0x0000000CUL )
{
z >>= 2;
shift += 2;
}
if ( z & 0x00000002UL )
{
shift += 1;
}
return shift;
}
#endif
FT_BASE_DEF( FT_Fixed )
FT_Hypot( FT_Fixed x,
FT_Fixed y )
{ … }
#ifdef FT_INT64
FT_EXPORT_DEF( FT_Long )
FT_MulDiv( FT_Long a_,
FT_Long b_,
FT_Long c_ )
{ … }
FT_BASE_DEF( FT_Long )
FT_MulDiv_No_Round( FT_Long a_,
FT_Long b_,
FT_Long c_ )
{ … }
FT_EXPORT_DEF( FT_Long )
FT_MulFix( FT_Long a_,
FT_Long b_ )
{ … }
FT_EXPORT_DEF( FT_Long )
FT_DivFix( FT_Long a_,
FT_Long b_ )
{ … }
#else
static void
ft_multo64( FT_UInt32 x,
FT_UInt32 y,
FT_Int64 *z )
{
FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2;
lo1 = x & 0x0000FFFFU; hi1 = x >> 16;
lo2 = y & 0x0000FFFFU; hi2 = y >> 16;
lo = lo1 * lo2;
i1 = lo1 * hi2;
i2 = lo2 * hi1;
hi = hi1 * hi2;
i1 += i2;
hi += (FT_UInt32)( i1 < i2 ) << 16;
hi += i1 >> 16;
i1 = i1 << 16;
lo += i1;
hi += ( lo < i1 );
z->lo = lo;
z->hi = hi;
}
static FT_UInt32
ft_div64by32( FT_UInt32 hi,
FT_UInt32 lo,
FT_UInt32 y )
{
FT_UInt32 r, q;
FT_Int i;
if ( hi >= y )
return (FT_UInt32)0x7FFFFFFFL;
i = 31 - FT_MSB( hi );
r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i;
q = r / y;
r -= q * y;
i = 32 - i;
do
{
q <<= 1;
r = ( r << 1 ) | ( lo >> 31 ); lo <<= 1;
if ( r >= y )
{
r -= y;
q |= 1;
}
} while ( --i );
return q;
}
static void
FT_Add64( FT_Int64* x,
FT_Int64* y,
FT_Int64 *z )
{
FT_UInt32 lo, hi;
lo = x->lo + y->lo;
hi = x->hi + y->hi + ( lo < x->lo );
z->lo = lo;
z->hi = hi;
}
FT_EXPORT_DEF( FT_Long )
FT_MulDiv( FT_Long a_,
FT_Long b_,
FT_Long c_ )
{
FT_Int s = 1;
FT_UInt32 a, b, c;
a = (FT_UInt32)a_;
b = (FT_UInt32)b_;
c = (FT_UInt32)c_;
FT_MOVE_SIGN( a_, a, s );
FT_MOVE_SIGN( b_, b, s );
FT_MOVE_SIGN( c_, c, s );
if ( c == 0 )
a = 0x7FFFFFFFUL;
else if ( a + b <= 129894UL - ( c >> 17 ) )
a = ( a * b + ( c >> 1 ) ) / c;
else
{
FT_Int64 temp, temp2;
ft_multo64( a, b, &temp );
temp2.hi = 0;
temp2.lo = c >> 1;
FT_Add64( &temp, &temp2, &temp );
a = ( temp.hi == 0 ) ? temp.lo / c
: ft_div64by32( temp.hi, temp.lo, c );
}
a_ = (FT_Long)a;
return s < 0 ? NEG_LONG( a_ ) : a_;
}
FT_BASE_DEF( FT_Long )
FT_MulDiv_No_Round( FT_Long a_,
FT_Long b_,
FT_Long c_ )
{
FT_Int s = 1;
FT_UInt32 a, b, c;
a = (FT_UInt32)a_;
b = (FT_UInt32)b_;
c = (FT_UInt32)c_;
FT_MOVE_SIGN( a_, a, s );
FT_MOVE_SIGN( b_, b, s );
FT_MOVE_SIGN( c_, c, s );
if ( c == 0 )
a = 0x7FFFFFFFUL;
else if ( a + b <= 131071UL )
a = a * b / c;
else
{
FT_Int64 temp;
ft_multo64( a, b, &temp );
a = ( temp.hi == 0 ) ? temp.lo / c
: ft_div64by32( temp.hi, temp.lo, c );
}
a_ = (FT_Long)a;
return s < 0 ? NEG_LONG( a_ ) : a_;
}
FT_EXPORT_DEF( FT_Long )
FT_MulFix( FT_Long a_,
FT_Long b_ )
{
#ifdef FT_MULFIX_ASSEMBLER
return FT_MULFIX_ASSEMBLER( a_, b_ );
#elif 0
FT_Long sa, sb;
FT_UInt32 a, b;
sa = ( a_ >> ( sizeof ( a_ ) * 8 - 1 ) );
a = ( a_ ^ sa ) - sa;
sb = ( b_ >> ( sizeof ( b_ ) * 8 - 1 ) );
b = ( b_ ^ sb ) - sb;
a = (FT_UInt32)a_;
b = (FT_UInt32)b_;
if ( a + ( b >> 8 ) <= 8190UL )
a = ( a * b + 0x8000U ) >> 16;
else
{
FT_UInt32 al = a & 0xFFFFUL;
a = ( a >> 16 ) * b + al * ( b >> 16 ) +
( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 );
}
sa ^= sb;
a = ( a ^ sa ) - sa;
return (FT_Long)a;
#else
FT_Int s = 1;
FT_UInt32 a, b;
a = (FT_UInt32)a_;
b = (FT_UInt32)b_;
FT_MOVE_SIGN( a_, a, s );
FT_MOVE_SIGN( b_, b, s );
if ( a + ( b >> 8 ) <= 8190UL )
a = ( a * b + 0x8000UL ) >> 16;
else
{
FT_UInt32 al = a & 0xFFFFUL;
a = ( a >> 16 ) * b + al * ( b >> 16 ) +
( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 );
}
a_ = (FT_Long)a;
return s < 0 ? NEG_LONG( a_ ) : a_;
#endif
}
FT_EXPORT_DEF( FT_Long )
FT_DivFix( FT_Long a_,
FT_Long b_ )
{
FT_Int s = 1;
FT_UInt32 a, b, q;
FT_Long q_;
a = (FT_UInt32)a_;
b = (FT_UInt32)b_;
FT_MOVE_SIGN( a_, a, s );
FT_MOVE_SIGN( b_, b, s );
if ( b == 0 )
{
q = 0x7FFFFFFFUL;
}
else if ( a <= 65535UL - ( b >> 17 ) )
{
q = ( ( a << 16 ) + ( b >> 1 ) ) / b;
}
else
{
FT_Int64 temp, temp2;
temp.hi = a >> 16;
temp.lo = a << 16;
temp2.hi = 0;
temp2.lo = b >> 1;
FT_Add64( &temp, &temp2, &temp );
q = ft_div64by32( temp.hi, temp.lo, b );
}
q_ = (FT_Long)q;
return s < 0 ? NEG_LONG( q_ ) : q_;
}
#endif
FT_EXPORT_DEF( void )
FT_Matrix_Multiply( const FT_Matrix* a,
FT_Matrix *b )
{ … }
FT_EXPORT_DEF( FT_Error )
FT_Matrix_Invert( FT_Matrix* matrix )
{ … }
FT_BASE_DEF( void )
FT_Matrix_Multiply_Scaled( const FT_Matrix* a,
FT_Matrix *b,
FT_Long scaling )
{ … }
FT_BASE_DEF( FT_Bool )
FT_Matrix_Check( const FT_Matrix* matrix )
{ … }
FT_BASE_DEF( void )
FT_Vector_Transform_Scaled( FT_Vector* vector,
const FT_Matrix* matrix,
FT_Long scaling )
{ … }
FT_BASE_DEF( FT_UInt32 )
FT_Vector_NormLen( FT_Vector* vector )
{ … }
#if 0
FT_BASE_DEF( FT_Int32 )
FT_SqrtFixed( FT_Int32 x )
{
FT_UInt32 root, rem_hi, rem_lo, test_div;
FT_Int count;
root = 0;
if ( x > 0 )
{
rem_hi = 0;
rem_lo = (FT_UInt32)x;
count = 24;
do
{
rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 );
rem_lo <<= 2;
root <<= 1;
test_div = ( root << 1 ) + 1;
if ( rem_hi >= test_div )
{
rem_hi -= test_div;
root += 1;
}
} while ( --count );
}
return (FT_Int32)root;
}
#endif
FT_BASE_DEF( FT_Int )
ft_corner_orientation( FT_Pos in_x,
FT_Pos in_y,
FT_Pos out_x,
FT_Pos out_y )
{ … }
FT_BASE_DEF( FT_Int )
ft_corner_is_flat( FT_Pos in_x,
FT_Pos in_y,
FT_Pos out_x,
FT_Pos out_y )
{ … }
FT_BASE_DEF( FT_Int32 )
FT_MulAddFix( FT_Fixed* s,
FT_Int32* f,
FT_UInt count )
{ … }