1/***************************************************************************/ 2/* */ 3/* ftcalc.c */ 4/* */ 5/* Arithmetic computations (body). */ 6/* */ 7/* Copyright 1996-2006, 2008, 2012-2013 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 /* */ 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. */ 22 /* */ 23 /*************************************************************************/ 24 25 /*************************************************************************/ 26 /* */ 27 /* Implementing basic computation routines. */ 28 /* */ 29 /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ 30 /* and FT_FloorFix() are declared in freetype.h. */ 31 /* */ 32 /*************************************************************************/ 33 34 35#include <ft2build.h> 36#include FT_GLYPH_H 37#include FT_TRIGONOMETRY_H 38#include FT_INTERNAL_CALC_H 39#include FT_INTERNAL_DEBUG_H 40#include FT_INTERNAL_OBJECTS_H 41 42#ifdef FT_MULFIX_INLINED 43#undef FT_MulFix 44#endif 45 46/* we need to emulate a 64-bit data type if a real one isn't available */ 47 48#ifndef FT_LONG64 49 50 typedef struct FT_Int64_ 51 { 52 FT_UInt32 lo; 53 FT_UInt32 hi; 54 55 } FT_Int64; 56 57#endif /* !FT_LONG64 */ 58 59 60 /*************************************************************************/ 61 /* */ 62 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 63 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 64 /* messages during execution. */ 65 /* */ 66#undef FT_COMPONENT 67#define FT_COMPONENT trace_calc 68 69 70 /* The following three functions are available regardless of whether */ 71 /* FT_LONG64 is defined. */ 72 73 /* documentation is in freetype.h */ 74 75 FT_EXPORT_DEF( FT_Fixed ) 76 FT_RoundFix( FT_Fixed a ) 77 { 78 return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL 79 : -((-a + 0x8000L ) & ~0xFFFFL ); 80 } 81 82 83 /* documentation is in freetype.h */ 84 85 FT_EXPORT_DEF( FT_Fixed ) 86 FT_CeilFix( FT_Fixed a ) 87 { 88 return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL 89 : -((-a + 0xFFFFL ) & ~0xFFFFL ); 90 } 91 92 93 /* documentation is in freetype.h */ 94 95 FT_EXPORT_DEF( FT_Fixed ) 96 FT_FloorFix( FT_Fixed a ) 97 { 98 return ( a >= 0 ) ? a & ~0xFFFFL 99 : -((-a) & ~0xFFFFL ); 100 } 101 102 103 FT_BASE_DEF ( FT_Int ) 104 FT_MSB( FT_UInt32 z ) 105 { 106 FT_Int shift = 0; 107 108 /* determine msb bit index in `shift' */ 109 if ( z >= ( 1L << 16 ) ) 110 { 111 z >>= 16; 112 shift += 16; 113 } 114 if ( z >= ( 1L << 8 ) ) 115 { 116 z >>= 8; 117 shift += 8; 118 } 119 if ( z >= ( 1L << 4 ) ) 120 { 121 z >>= 4; 122 shift += 4; 123 } 124 if ( z >= ( 1L << 2 ) ) 125 { 126 z >>= 2; 127 shift += 2; 128 } 129 if ( z >= ( 1L << 1 ) ) 130 { 131 z >>= 1; 132 shift += 1; 133 } 134 135 return shift; 136 } 137 138 139 /* documentation is in ftcalc.h */ 140 141 FT_BASE_DEF( FT_Fixed ) 142 FT_Hypot( FT_Fixed x, 143 FT_Fixed y ) 144 { 145 FT_Vector v; 146 147 148 v.x = x; 149 v.y = y; 150 151 return FT_Vector_Length( &v ); 152 } 153 154 155#ifdef FT_LONG64 156 157 158 /* documentation is in freetype.h */ 159 160 FT_EXPORT_DEF( FT_Long ) 161 FT_MulDiv( FT_Long a, 162 FT_Long b, 163 FT_Long c ) 164 { 165 FT_Int s; 166 FT_Long d; 167 168 169 s = 1; 170 if ( a < 0 ) { a = -a; s = -1; } 171 if ( b < 0 ) { b = -b; s = -s; } 172 if ( c < 0 ) { c = -c; s = -s; } 173 174 d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c 175 : 0x7FFFFFFFL ); 176 177 return ( s > 0 ) ? d : -d; 178 } 179 180 181 /* documentation is in ftcalc.h */ 182 183 FT_BASE_DEF( FT_Long ) 184 FT_MulDiv_No_Round( FT_Long a, 185 FT_Long b, 186 FT_Long c ) 187 { 188 FT_Int s; 189 FT_Long d; 190 191 192 s = 1; 193 if ( a < 0 ) { a = -a; s = -1; } 194 if ( b < 0 ) { b = -b; s = -s; } 195 if ( c < 0 ) { c = -c; s = -s; } 196 197 d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c 198 : 0x7FFFFFFFL ); 199 200 return ( s > 0 ) ? d : -d; 201 } 202 203 204 /* documentation is in freetype.h */ 205 206 FT_EXPORT_DEF( FT_Long ) 207 FT_MulFix( FT_Long a, 208 FT_Long b ) 209 { 210#ifdef FT_MULFIX_ASSEMBLER 211 212 return FT_MULFIX_ASSEMBLER( a, b ); 213 214#else 215 216 FT_Int s = 1; 217 FT_Long c; 218 219 220 if ( a < 0 ) 221 { 222 a = -a; 223 s = -1; 224 } 225 226 if ( b < 0 ) 227 { 228 b = -b; 229 s = -s; 230 } 231 232 c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); 233 234 return ( s > 0 ) ? c : -c; 235 236#endif /* FT_MULFIX_ASSEMBLER */ 237 } 238 239 240 /* documentation is in freetype.h */ 241 242 FT_EXPORT_DEF( FT_Long ) 243 FT_DivFix( FT_Long a, 244 FT_Long b ) 245 { 246 FT_Int32 s; 247 FT_UInt32 q; 248 249 250 s = 1; 251 if ( a < 0 ) 252 { 253 a = -a; 254 s = -1; 255 } 256 if ( b < 0 ) 257 { 258 b = -b; 259 s = -s; 260 } 261 262 if ( b == 0 ) 263 /* check for division by 0 */ 264 q = 0x7FFFFFFFL; 265 else 266 /* compute result directly */ 267 q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b ); 268 269 return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); 270 } 271 272 273#else /* !FT_LONG64 */ 274 275 276 static void 277 ft_multo64( FT_UInt32 x, 278 FT_UInt32 y, 279 FT_Int64 *z ) 280 { 281 FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; 282 283 284 lo1 = x & 0x0000FFFFU; hi1 = x >> 16; 285 lo2 = y & 0x0000FFFFU; hi2 = y >> 16; 286 287 lo = lo1 * lo2; 288 i1 = lo1 * hi2; 289 i2 = lo2 * hi1; 290 hi = hi1 * hi2; 291 292 /* Check carry overflow of i1 + i2 */ 293 i1 += i2; 294 hi += (FT_UInt32)( i1 < i2 ) << 16; 295 296 hi += i1 >> 16; 297 i1 = i1 << 16; 298 299 /* Check carry overflow of i1 + lo */ 300 lo += i1; 301 hi += ( lo < i1 ); 302 303 z->lo = lo; 304 z->hi = hi; 305 } 306 307 308 static FT_UInt32 309 ft_div64by32( FT_UInt32 hi, 310 FT_UInt32 lo, 311 FT_UInt32 y ) 312 { 313 FT_UInt32 r, q; 314 FT_Int i; 315 316 317 q = 0; 318 r = hi; 319 320 if ( r >= y ) 321 return (FT_UInt32)0x7FFFFFFFL; 322 323 i = 32; 324 do 325 { 326 r <<= 1; 327 q <<= 1; 328 r |= lo >> 31; 329 330 if ( r >= y ) 331 { 332 r -= y; 333 q |= 1; 334 } 335 lo <<= 1; 336 } while ( --i ); 337 338 return q; 339 } 340 341 342 static void 343 FT_Add64( FT_Int64* x, 344 FT_Int64* y, 345 FT_Int64 *z ) 346 { 347 register FT_UInt32 lo, hi; 348 349 350 lo = x->lo + y->lo; 351 hi = x->hi + y->hi + ( lo < x->lo ); 352 353 z->lo = lo; 354 z->hi = hi; 355 } 356 357 358 /* documentation is in freetype.h */ 359 360 /* The FT_MulDiv function has been optimized thanks to ideas from */ 361 /* Graham Asher. The trick is to optimize computation when everything */ 362 /* fits within 32-bits (a rather common case). */ 363 /* */ 364 /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ 365 /* */ 366 /* 46340 is FLOOR(SQRT(2^31-1)). */ 367 /* */ 368 /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ 369 /* */ 370 /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ 371 /* */ 372 /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ 373 /* */ 374 /* and 2*0x157F0 = 176096 */ 375 /* */ 376 377 FT_EXPORT_DEF( FT_Long ) 378 FT_MulDiv( FT_Long a, 379 FT_Long b, 380 FT_Long c ) 381 { 382 long s; 383 384 385 /* XXX: this function does not allow 64-bit arguments */ 386 if ( a == 0 || b == c ) 387 return a; 388 389 s = a; a = FT_ABS( a ); 390 s ^= b; b = FT_ABS( b ); 391 s ^= c; c = FT_ABS( c ); 392 393 if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) 394 a = ( a * b + ( c >> 1 ) ) / c; 395 396 else if ( (FT_Int32)c > 0 ) 397 { 398 FT_Int64 temp, temp2; 399 400 401 ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); 402 403 temp2.hi = 0; 404 temp2.lo = (FT_UInt32)(c >> 1); 405 FT_Add64( &temp, &temp2, &temp ); 406 a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); 407 } 408 else 409 a = 0x7FFFFFFFL; 410 411 return ( s < 0 ? -a : a ); 412 } 413 414 415 FT_BASE_DEF( FT_Long ) 416 FT_MulDiv_No_Round( FT_Long a, 417 FT_Long b, 418 FT_Long c ) 419 { 420 long s; 421 422 423 if ( a == 0 || b == c ) 424 return a; 425 426 s = a; a = FT_ABS( a ); 427 s ^= b; b = FT_ABS( b ); 428 s ^= c; c = FT_ABS( c ); 429 430 if ( a <= 46340L && b <= 46340L && c > 0 ) 431 a = a * b / c; 432 433 else if ( (FT_Int32)c > 0 ) 434 { 435 FT_Int64 temp; 436 437 438 ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); 439 a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); 440 } 441 else 442 a = 0x7FFFFFFFL; 443 444 return ( s < 0 ? -a : a ); 445 } 446 447 448 /* documentation is in freetype.h */ 449 450 FT_EXPORT_DEF( FT_Long ) 451 FT_MulFix( FT_Long a, 452 FT_Long b ) 453 { 454#ifdef FT_MULFIX_ASSEMBLER 455 456 return FT_MULFIX_ASSEMBLER( a, b ); 457 458#elif 0 459 460 /* 461 * This code is nonportable. See comment below. 462 * 463 * However, on a platform where right-shift of a signed quantity fills 464 * the leftmost bits by copying the sign bit, it might be faster. 465 */ 466 467 FT_Long sa, sb; 468 FT_ULong ua, ub; 469 470 471 if ( a == 0 || b == 0x10000L ) 472 return a; 473 474 /* 475 * This is a clever way of converting a signed number `a' into its 476 * absolute value (stored back into `a') and its sign. The sign is 477 * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' 478 * was negative. (Similarly for `b' and `sb'). 479 * 480 * Unfortunately, it doesn't work (at least not portably). 481 * 482 * It makes the assumption that right-shift on a negative signed value 483 * fills the leftmost bits by copying the sign bit. This is wrong. 484 * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, 485 * the result of right-shift of a negative signed value is 486 * implementation-defined. At least one implementation fills the 487 * leftmost bits with 0s (i.e., it is exactly the same as an unsigned 488 * right shift). This means that when `a' is negative, `sa' ends up 489 * with the value 1 rather than -1. After that, everything else goes 490 * wrong. 491 */ 492 sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); 493 a = ( a ^ sa ) - sa; 494 sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); 495 b = ( b ^ sb ) - sb; 496 497 ua = (FT_ULong)a; 498 ub = (FT_ULong)b; 499 500 if ( ua <= 2048 && ub <= 1048576L ) 501 ua = ( ua * ub + 0x8000U ) >> 16; 502 else 503 { 504 FT_ULong al = ua & 0xFFFFU; 505 506 507 ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + 508 ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); 509 } 510 511 sa ^= sb, 512 ua = (FT_ULong)(( ua ^ sa ) - sa); 513 514 return (FT_Long)ua; 515 516#else /* 0 */ 517 518 FT_Long s; 519 FT_ULong ua, ub; 520 521 522 if ( a == 0 || b == 0x10000L ) 523 return a; 524 525 s = a; a = FT_ABS( a ); 526 s ^= b; b = FT_ABS( b ); 527 528 ua = (FT_ULong)a; 529 ub = (FT_ULong)b; 530 531 if ( ua <= 2048 && ub <= 1048576L ) 532 ua = ( ua * ub + 0x8000UL ) >> 16; 533 else 534 { 535 FT_ULong al = ua & 0xFFFFUL; 536 537 538 ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + 539 ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); 540 } 541 542 return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); 543 544#endif /* 0 */ 545 546 } 547 548 549 /* documentation is in freetype.h */ 550 551 FT_EXPORT_DEF( FT_Long ) 552 FT_DivFix( FT_Long a, 553 FT_Long b ) 554 { 555 FT_Int32 s; 556 FT_UInt32 q; 557 558 559 /* XXX: this function does not allow 64-bit arguments */ 560 s = (FT_Int32)a; a = FT_ABS( a ); 561 s ^= (FT_Int32)b; b = FT_ABS( b ); 562 563 if ( (FT_UInt32)b == 0 ) 564 { 565 /* check for division by 0 */ 566 q = (FT_UInt32)0x7FFFFFFFL; 567 } 568 else if ( ( a >> 16 ) == 0 ) 569 { 570 /* compute result directly */ 571 q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b; 572 } 573 else 574 { 575 /* we need more bits; we have to do it by hand */ 576 FT_Int64 temp, temp2; 577 578 579 temp.hi = (FT_Int32)( a >> 16 ); 580 temp.lo = (FT_UInt32)a << 16; 581 temp2.hi = 0; 582 temp2.lo = (FT_UInt32)( b >> 1 ); 583 FT_Add64( &temp, &temp2, &temp ); 584 q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); 585 } 586 587 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 588 } 589 590 591#if 0 592 593 /* documentation is in ftcalc.h */ 594 595 FT_EXPORT_DEF( void ) 596 FT_MulTo64( FT_Int32 x, 597 FT_Int32 y, 598 FT_Int64 *z ) 599 { 600 FT_Int32 s; 601 602 603 s = x; x = FT_ABS( x ); 604 s ^= y; y = FT_ABS( y ); 605 606 ft_multo64( x, y, z ); 607 608 if ( s < 0 ) 609 { 610 z->lo = (FT_UInt32)-(FT_Int32)z->lo; 611 z->hi = ~z->hi + !( z->lo ); 612 } 613 } 614 615 616 /* apparently, the second version of this code is not compiled correctly */ 617 /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ 618 619#if 1 620 621 FT_EXPORT_DEF( FT_Int32 ) 622 FT_Div64by32( FT_Int64* x, 623 FT_Int32 y ) 624 { 625 FT_Int32 s; 626 FT_UInt32 q, r, i, lo; 627 628 629 s = x->hi; 630 if ( s < 0 ) 631 { 632 x->lo = (FT_UInt32)-(FT_Int32)x->lo; 633 x->hi = ~x->hi + !x->lo; 634 } 635 s ^= y; y = FT_ABS( y ); 636 637 /* Shortcut */ 638 if ( x->hi == 0 ) 639 { 640 if ( y > 0 ) 641 q = x->lo / y; 642 else 643 q = 0x7FFFFFFFL; 644 645 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 646 } 647 648 r = x->hi; 649 lo = x->lo; 650 651 if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ 652 return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); 653 /* Return Max/Min Int32 if division overflow. */ 654 /* This includes division by zero! */ 655 q = 0; 656 for ( i = 0; i < 32; i++ ) 657 { 658 r <<= 1; 659 q <<= 1; 660 r |= lo >> 31; 661 662 if ( r >= (FT_UInt32)y ) 663 { 664 r -= y; 665 q |= 1; 666 } 667 lo <<= 1; 668 } 669 670 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 671 } 672 673#else /* 0 */ 674 675 FT_EXPORT_DEF( FT_Int32 ) 676 FT_Div64by32( FT_Int64* x, 677 FT_Int32 y ) 678 { 679 FT_Int32 s; 680 FT_UInt32 q; 681 682 683 s = x->hi; 684 if ( s < 0 ) 685 { 686 x->lo = (FT_UInt32)-(FT_Int32)x->lo; 687 x->hi = ~x->hi + !x->lo; 688 } 689 s ^= y; y = FT_ABS( y ); 690 691 /* Shortcut */ 692 if ( x->hi == 0 ) 693 { 694 if ( y > 0 ) 695 q = ( x->lo + ( y >> 1 ) ) / y; 696 else 697 q = 0x7FFFFFFFL; 698 699 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 700 } 701 702 q = ft_div64by32( x->hi, x->lo, y ); 703 704 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 705 } 706 707#endif /* 0 */ 708 709#endif /* 0 */ 710 711 712#endif /* FT_LONG64 */ 713 714 715 /* documentation is in ftglyph.h */ 716 717 FT_EXPORT_DEF( void ) 718 FT_Matrix_Multiply( const FT_Matrix* a, 719 FT_Matrix *b ) 720 { 721 FT_Fixed xx, xy, yx, yy; 722 723 724 if ( !a || !b ) 725 return; 726 727 xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); 728 xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); 729 yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); 730 yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); 731 732 b->xx = xx; b->xy = xy; 733 b->yx = yx; b->yy = yy; 734 } 735 736 737 /* documentation is in ftglyph.h */ 738 739 FT_EXPORT_DEF( FT_Error ) 740 FT_Matrix_Invert( FT_Matrix* matrix ) 741 { 742 FT_Pos delta, xx, yy; 743 744 745 if ( !matrix ) 746 return FT_THROW( Invalid_Argument ); 747 748 /* compute discriminant */ 749 delta = FT_MulFix( matrix->xx, matrix->yy ) - 750 FT_MulFix( matrix->xy, matrix->yx ); 751 752 if ( !delta ) 753 return FT_THROW( Invalid_Argument ); /* matrix can't be inverted */ 754 755 matrix->xy = - FT_DivFix( matrix->xy, delta ); 756 matrix->yx = - FT_DivFix( matrix->yx, delta ); 757 758 xx = matrix->xx; 759 yy = matrix->yy; 760 761 matrix->xx = FT_DivFix( yy, delta ); 762 matrix->yy = FT_DivFix( xx, delta ); 763 764 return FT_Err_Ok; 765 } 766 767 768 /* documentation is in ftcalc.h */ 769 770 FT_BASE_DEF( void ) 771 FT_Matrix_Multiply_Scaled( const FT_Matrix* a, 772 FT_Matrix *b, 773 FT_Long scaling ) 774 { 775 FT_Fixed xx, xy, yx, yy; 776 777 FT_Long val = 0x10000L * scaling; 778 779 780 if ( !a || !b ) 781 return; 782 783 xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); 784 xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); 785 yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); 786 yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); 787 788 b->xx = xx; b->xy = xy; 789 b->yx = yx; b->yy = yy; 790 } 791 792 793 /* documentation is in ftcalc.h */ 794 795 FT_BASE_DEF( void ) 796 FT_Vector_Transform_Scaled( FT_Vector* vector, 797 const FT_Matrix* matrix, 798 FT_Long scaling ) 799 { 800 FT_Pos xz, yz; 801 802 FT_Long val = 0x10000L * scaling; 803 804 805 if ( !vector || !matrix ) 806 return; 807 808 xz = FT_MulDiv( vector->x, matrix->xx, val ) + 809 FT_MulDiv( vector->y, matrix->xy, val ); 810 811 yz = FT_MulDiv( vector->x, matrix->yx, val ) + 812 FT_MulDiv( vector->y, matrix->yy, val ); 813 814 vector->x = xz; 815 vector->y = yz; 816 } 817 818 819 /* documentation is in ftcalc.h */ 820 821 FT_BASE_DEF( FT_Int32 ) 822 FT_SqrtFixed( FT_Int32 x ) 823 { 824 FT_UInt32 root, rem_hi, rem_lo, test_div; 825 FT_Int count; 826 827 828 root = 0; 829 830 if ( x > 0 ) 831 { 832 rem_hi = 0; 833 rem_lo = x; 834 count = 24; 835 do 836 { 837 rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); 838 rem_lo <<= 2; 839 root <<= 1; 840 test_div = ( root << 1 ) + 1; 841 842 if ( rem_hi >= test_div ) 843 { 844 rem_hi -= test_div; 845 root += 1; 846 } 847 } while ( --count ); 848 } 849 850 return (FT_Int32)root; 851 } 852 853 854 /* documentation is in ftcalc.h */ 855 856 FT_BASE_DEF( FT_Int ) 857 ft_corner_orientation( FT_Pos in_x, 858 FT_Pos in_y, 859 FT_Pos out_x, 860 FT_Pos out_y ) 861 { 862 FT_Long result; /* avoid overflow on 16-bit system */ 863 864 865 /* deal with the trivial cases quickly */ 866 if ( in_y == 0 ) 867 { 868 if ( in_x >= 0 ) 869 result = out_y; 870 else 871 result = -out_y; 872 } 873 else if ( in_x == 0 ) 874 { 875 if ( in_y >= 0 ) 876 result = -out_x; 877 else 878 result = out_x; 879 } 880 else if ( out_y == 0 ) 881 { 882 if ( out_x >= 0 ) 883 result = in_y; 884 else 885 result = -in_y; 886 } 887 else if ( out_x == 0 ) 888 { 889 if ( out_y >= 0 ) 890 result = -in_x; 891 else 892 result = in_x; 893 } 894 else /* general case */ 895 { 896#ifdef FT_LONG64 897 898 FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; 899 900 901 if ( delta == 0 ) 902 result = 0; 903 else 904 result = 1 - 2 * ( delta < 0 ); 905 906#else 907 908 FT_Int64 z1, z2; 909 910 911 /* XXX: this function does not allow 64-bit arguments */ 912 ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); 913 ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); 914 915 if ( z1.hi > z2.hi ) 916 result = +1; 917 else if ( z1.hi < z2.hi ) 918 result = -1; 919 else if ( z1.lo > z2.lo ) 920 result = +1; 921 else if ( z1.lo < z2.lo ) 922 result = -1; 923 else 924 result = 0; 925 926#endif 927 } 928 929 /* XXX: only the sign of return value, +1/0/-1 must be used */ 930 return (FT_Int)result; 931 } 932 933 934 /* documentation is in ftcalc.h */ 935 936 FT_BASE_DEF( FT_Int ) 937 ft_corner_is_flat( FT_Pos in_x, 938 FT_Pos in_y, 939 FT_Pos out_x, 940 FT_Pos out_y ) 941 { 942 FT_Pos ax = in_x; 943 FT_Pos ay = in_y; 944 945 FT_Pos d_in, d_out, d_corner; 946 947 948 if ( ax < 0 ) 949 ax = -ax; 950 if ( ay < 0 ) 951 ay = -ay; 952 d_in = ax + ay; 953 954 ax = out_x; 955 if ( ax < 0 ) 956 ax = -ax; 957 ay = out_y; 958 if ( ay < 0 ) 959 ay = -ay; 960 d_out = ax + ay; 961 962 ax = out_x + in_x; 963 if ( ax < 0 ) 964 ax = -ax; 965 ay = out_y + in_y; 966 if ( ay < 0 ) 967 ay = -ay; 968 d_corner = ax + ay; 969 970 return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); 971 } 972 973 974/* END */ 975