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