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