1 /***************************************************************************/
5 /* Arithmetic computations (body). */
7 /* Copyright 1996-2006, 2008, 2012-2014 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
18 /*************************************************************************/
20 /* Support for 1-complement arithmetic has been totally dropped in this */
21 /* release. You can still write your own code if you need it. */
23 /*************************************************************************/
25 /*************************************************************************/
27 /* Implementing basic computation routines. */
29 /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */
30 /* and FT_FloorFix() are declared in freetype.h. */
32 /*************************************************************************/
37 #include FT_TRIGONOMETRY_H
38 #include FT_INTERNAL_CALC_H
39 #include FT_INTERNAL_DEBUG_H
40 #include FT_INTERNAL_OBJECTS_H
43 #ifdef FT_MULFIX_ASSEMBLER
47 /* we need to emulate a 64-bit data type if a real one isn't available */
51 typedef struct FT_Int64_
58 #endif /* !FT_LONG64 */
61 /*************************************************************************/
63 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
64 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
65 /* messages during execution. */
68 #define FT_COMPONENT trace_calc
71 /* transfer sign leaving a positive number */
72 #define FT_MOVE_SIGN( x, s ) \
81 /* The following three functions are available regardless of whether */
82 /* FT_LONG64 is defined. */
84 /* documentation is in freetype.h */
86 FT_EXPORT_DEF( FT_Fixed )
87 FT_RoundFix( FT_Fixed a )
89 return a >= 0 ? ( a + 0x8000L ) & ~0xFFFFL
90 : -((-a + 0x8000L ) & ~0xFFFFL );
94 /* documentation is in freetype.h */
96 FT_EXPORT_DEF( FT_Fixed )
97 FT_CeilFix( FT_Fixed a )
99 return a >= 0 ? ( a + 0xFFFFL ) & ~0xFFFFL
100 : -((-a + 0xFFFFL ) & ~0xFFFFL );
104 /* documentation is in freetype.h */
106 FT_EXPORT_DEF( FT_Fixed )
107 FT_FloorFix( FT_Fixed a )
109 return a >= 0 ? a & ~0xFFFFL
110 : -((-a) & ~0xFFFFL );
115 FT_BASE_DEF ( FT_Int )
116 FT_MSB( FT_UInt32 z )
121 /* determine msb bit index in `shift' */
122 if ( z & 0xFFFF0000UL )
127 if ( z & 0x0000FF00UL )
132 if ( z & 0x000000F0UL )
137 if ( z & 0x0000000CUL )
142 if ( z & 0x00000002UL )
154 /* documentation is in ftcalc.h */
156 FT_BASE_DEF( FT_Fixed )
157 FT_Hypot( FT_Fixed x,
166 return FT_Vector_Length( &v );
173 /* documentation is in freetype.h */
175 FT_EXPORT_DEF( FT_Long )
176 FT_MulDiv( FT_Long a,
184 FT_MOVE_SIGN( a, s );
185 FT_MOVE_SIGN( b, s );
186 FT_MOVE_SIGN( c, s );
188 d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c
191 return s < 0 ? -d : d;
195 /* documentation is in ftcalc.h */
197 FT_BASE_DEF( FT_Long )
198 FT_MulDiv_No_Round( FT_Long a,
206 FT_MOVE_SIGN( a, s );
207 FT_MOVE_SIGN( b, s );
208 FT_MOVE_SIGN( c, s );
210 d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c
213 return s < 0 ? -d : d;
217 /* documentation is in freetype.h */
219 FT_EXPORT_DEF( FT_Long )
220 FT_MulFix( FT_Long a,
223 #ifdef FT_MULFIX_ASSEMBLER
225 return FT_MULFIX_ASSEMBLER( a, b );
233 FT_MOVE_SIGN( a, s );
234 FT_MOVE_SIGN( b, s );
236 c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 );
238 return s < 0 ? -c : c;
240 #endif /* FT_MULFIX_ASSEMBLER */
244 /* documentation is in freetype.h */
246 FT_EXPORT_DEF( FT_Long )
247 FT_DivFix( FT_Long a,
254 FT_MOVE_SIGN( a, s );
255 FT_MOVE_SIGN( b, s );
257 q = (FT_Long)( b > 0 ? ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b
260 return s < 0 ? -q : q;
264 #else /* !FT_LONG64 */
268 ft_multo64( FT_UInt32 x,
272 FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2;
275 lo1 = x & 0x0000FFFFU; hi1 = x >> 16;
276 lo2 = y & 0x0000FFFFU; hi2 = y >> 16;
283 /* Check carry overflow of i1 + i2 */
285 hi += (FT_UInt32)( i1 < i2 ) << 16;
290 /* Check carry overflow of i1 + lo */
300 ft_div64by32( FT_UInt32 hi,
309 return (FT_UInt32)0x7FFFFFFFL;
311 /* We shift as many bits as we can into the high register, perform */
312 /* 32-bit division with modulo there, then work through the remaining */
313 /* bits with long division. This optimization is especially noticeable */
314 /* for smaller dividends that barely use the high register. */
316 i = 31 - FT_MSB( hi );
317 r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i; /* left 64-bit shift */
319 r -= q * y; /* remainder */
321 i = 32 - i; /* bits remaining in low register */
325 r = ( r << 1 ) | ( lo >> 31 ); lo <<= 1;
339 FT_Add64( FT_Int64* x,
347 hi = x->hi + y->hi + ( lo < x->lo );
354 /* The FT_MulDiv function has been optimized thanks to ideas from */
355 /* Graham Asher and Alexei Podtelezhnikov. The trick is to optimize */
356 /* a rather common case when everything fits within 32-bits. */
358 /* We compute 'a*b+c/2', then divide it by 'c' (all positive values). */
360 /* The product of two positive numbers never exceeds the square of */
361 /* its mean values. Therefore, we always avoid the overflow by */
364 /* (a + b) / 2 <= sqrt(X - c/2) , */
366 /* where X = 2^32 - 1, the maximum unsigned 32-bit value, and using */
367 /* unsigned arithmetic. Now we replace `sqrt' with a linear function */
368 /* that is smaller or equal for all values of c in the interval */
369 /* [0;X/2]; it should be equal to sqrt(X) and sqrt(3X/4) at the */
370 /* endpoints. Substituting the linear solution and explicit numbers */
373 /* a + b <= 131071.99 - c / 122291.84 . */
375 /* In practice, we should use a faster and even stronger inequality */
377 /* a + b <= 131071 - (c >> 16) */
379 /* or, alternatively, */
381 /* a + b <= 129894 - (c >> 17) . */
383 /* FT_MulFix, on the other hand, is optimized for a small value of */
384 /* the first argument, when the second argument can be much larger. */
385 /* This can be achieved by scaling the second argument and the limit */
386 /* in the above inequalities. For example, */
388 /* a + (b >> 8) <= (131071 >> 4) */
390 /* covers the practical range of use. The actual test below is a bit */
391 /* tighter to avoid the border case overflows. */
393 /* In the case of FT_DivFix, the exact overflow check */
395 /* a << 16 <= X - c/2 */
397 /* is scaled down by 2^16 and we use */
399 /* a <= 65535 - (c >> 17) . */
401 /* documentation is in freetype.h */
403 FT_EXPORT_DEF( FT_Long )
404 FT_MulDiv( FT_Long a,
411 /* XXX: this function does not allow 64-bit arguments */
412 if ( a == 0 || b == c )
415 FT_MOVE_SIGN( a, s );
416 FT_MOVE_SIGN( b, s );
417 FT_MOVE_SIGN( c, s );
422 else if ( (FT_ULong)a + b <= 129894UL - ( c >> 17 ) )
423 a = ( (FT_ULong)a * b + ( c >> 1 ) ) / c;
427 FT_Int64 temp, temp2;
430 ft_multo64( a, b, &temp );
435 FT_Add64( &temp, &temp2, &temp );
437 /* last attempt to ditch long division */
438 a = temp.hi == 0 ? temp.lo / c
439 : ft_div64by32( temp.hi, temp.lo, c );
442 return s < 0 ? -a : a;
446 FT_BASE_DEF( FT_Long )
447 FT_MulDiv_No_Round( FT_Long a,
454 if ( a == 0 || b == c )
457 FT_MOVE_SIGN( a, s );
458 FT_MOVE_SIGN( b, s );
459 FT_MOVE_SIGN( c, s );
464 else if ( (FT_ULong)a + b <= 131071UL )
465 a = (FT_ULong)a * b / c;
472 ft_multo64( a, b, &temp );
474 /* last attempt to ditch long division */
475 a = temp.hi == 0 ? temp.lo / c
476 : ft_div64by32( temp.hi, temp.lo, c );
479 return s < 0 ? -a : a;
483 /* documentation is in freetype.h */
485 FT_EXPORT_DEF( FT_Long )
486 FT_MulFix( FT_Long a,
489 #ifdef FT_MULFIX_ASSEMBLER
491 return FT_MULFIX_ASSEMBLER( a, b );
496 * This code is nonportable. See comment below.
498 * However, on a platform where right-shift of a signed quantity fills
499 * the leftmost bits by copying the sign bit, it might be faster.
506 if ( a == 0 || b == 0x10000L )
510 * This is a clever way of converting a signed number `a' into its
511 * absolute value (stored back into `a') and its sign. The sign is
512 * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a'
513 * was negative. (Similarly for `b' and `sb').
515 * Unfortunately, it doesn't work (at least not portably).
517 * It makes the assumption that right-shift on a negative signed value
518 * fills the leftmost bits by copying the sign bit. This is wrong.
519 * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206,
520 * the result of right-shift of a negative signed value is
521 * implementation-defined. At least one implementation fills the
522 * leftmost bits with 0s (i.e., it is exactly the same as an unsigned
523 * right shift). This means that when `a' is negative, `sa' ends up
524 * with the value 1 rather than -1. After that, everything else goes
527 sa = ( a >> ( sizeof ( a ) * 8 - 1 ) );
529 sb = ( b >> ( sizeof ( b ) * 8 - 1 ) );
535 if ( ua + ( ub >> 8 ) <= 8190UL )
536 ua = ( ua * ub + 0x8000U ) >> 16;
539 FT_ULong al = ua & 0xFFFFU;
542 ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) +
543 ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 );
547 ua = (FT_ULong)(( ua ^ sa ) - sa);
557 if ( a == 0 || b == 0x10000L )
560 FT_MOVE_SIGN( a, s );
561 FT_MOVE_SIGN( b, s );
566 if ( ua + ( ub >> 8 ) <= 8190UL )
567 ua = ( ua * ub + 0x8000UL ) >> 16;
570 FT_ULong al = ua & 0xFFFFUL;
573 ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) +
574 ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 );
577 return s < 0 ? -(FT_Long)ua : (FT_Long)ua;
584 /* documentation is in freetype.h */
586 FT_EXPORT_DEF( FT_Long )
587 FT_DivFix( FT_Long a,
594 /* XXX: this function does not allow 64-bit arguments */
596 FT_MOVE_SIGN( a, s );
597 FT_MOVE_SIGN( b, s );
601 /* check for division by 0 */
604 else if ( a <= 65535L - ( b >> 17 ) )
606 /* compute result directly */
607 q = (FT_Long)( ( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / b );
611 /* we need more bits; we have to do it by hand */
612 FT_Int64 temp, temp2;
620 FT_Add64( &temp, &temp2, &temp );
621 q = (FT_Long)ft_div64by32( temp.hi, temp.lo, b );
624 return s < 0 ? -q : q;
628 #endif /* FT_LONG64 */
631 /* documentation is in ftglyph.h */
633 FT_EXPORT_DEF( void )
634 FT_Matrix_Multiply( const FT_Matrix* a,
637 FT_Fixed xx, xy, yx, yy;
643 xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );
644 xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );
645 yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );
646 yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );
648 b->xx = xx; b->xy = xy;
649 b->yx = yx; b->yy = yy;
653 /* documentation is in ftglyph.h */
655 FT_EXPORT_DEF( FT_Error )
656 FT_Matrix_Invert( FT_Matrix* matrix )
658 FT_Pos delta, xx, yy;
662 return FT_THROW( Invalid_Argument );
664 /* compute discriminant */
665 delta = FT_MulFix( matrix->xx, matrix->yy ) -
666 FT_MulFix( matrix->xy, matrix->yx );
669 return FT_THROW( Invalid_Argument ); /* matrix can't be inverted */
671 matrix->xy = - FT_DivFix( matrix->xy, delta );
672 matrix->yx = - FT_DivFix( matrix->yx, delta );
677 matrix->xx = FT_DivFix( yy, delta );
678 matrix->yy = FT_DivFix( xx, delta );
684 /* documentation is in ftcalc.h */
687 FT_Matrix_Multiply_Scaled( const FT_Matrix* a,
691 FT_Fixed xx, xy, yx, yy;
693 FT_Long val = 0x10000L * scaling;
699 xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val );
700 xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val );
701 yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val );
702 yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val );
704 b->xx = xx; b->xy = xy;
705 b->yx = yx; b->yy = yy;
709 /* documentation is in ftcalc.h */
712 FT_Vector_Transform_Scaled( FT_Vector* vector,
713 const FT_Matrix* matrix,
718 FT_Long val = 0x10000L * scaling;
721 if ( !vector || !matrix )
724 xz = FT_MulDiv( vector->x, matrix->xx, val ) +
725 FT_MulDiv( vector->y, matrix->xy, val );
727 yz = FT_MulDiv( vector->x, matrix->yx, val ) +
728 FT_MulDiv( vector->y, matrix->yy, val );
737 /* documentation is in ftcalc.h */
739 FT_BASE_DEF( FT_Int32 )
740 FT_SqrtFixed( FT_Int32 x )
742 FT_UInt32 root, rem_hi, rem_lo, test_div;
755 rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 );
758 test_div = ( root << 1 ) + 1;
760 if ( rem_hi >= test_div )
768 return (FT_Int32)root;
774 /* documentation is in ftcalc.h */
776 FT_BASE_DEF( FT_Int )
777 ft_corner_orientation( FT_Pos in_x,
782 FT_Long result; /* avoid overflow on 16-bit system */
785 /* deal with the trivial cases quickly */
793 else if ( in_x == 0 )
800 else if ( out_y == 0 )
807 else if ( out_x == 0 )
814 else /* general case */
818 FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
824 result = 1 - 2 * ( delta < 0 );
831 /* XXX: this function does not allow 64-bit arguments */
832 ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 );
833 ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 );
837 else if ( z1.hi < z2.hi )
839 else if ( z1.lo > z2.lo )
841 else if ( z1.lo < z2.lo )
849 /* XXX: only the sign of return value, +1/0/-1 must be used */
850 return (FT_Int)result;
854 /* documentation is in ftcalc.h */
856 FT_BASE_DEF( FT_Int )
857 ft_corner_is_flat( FT_Pos in_x,
862 FT_Pos ax = in_x + out_x;
863 FT_Pos ay = in_y + out_y;
865 FT_Pos d_in, d_out, d_hypot;
868 /* The idea of this function is to compare the length of the */
869 /* hypotenuse with the `in' and `out' length. The `corner' */
870 /* represented by `in' and `out' is flat if the hypotenuse's */
871 /* length isn't too large. */
873 /* This approach has the advantage that the angle between */
874 /* `in' and `out' is not checked. In case one of the two */
875 /* vectors is `dominant', this is, much larger than the */
876 /* other vector, we thus always have a flat corner. */
879 /* x---------------------------x */
887 d_in = FT_HYPOT( in_x, in_y );
888 d_out = FT_HYPOT( out_x, out_y );
889 d_hypot = FT_HYPOT( ax, ay );
891 /* now do a simple length comparison: */
893 /* d_in + d_out < 17/16 d_hypot */
895 return ( d_in + d_out - d_hypot ) < ( d_hypot >> 4 );