Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenftcalc.c
Go to the documentation of this file.
00001 /***************************************************************************/ 00002 /* */ 00003 /* ftcalc.c */ 00004 /* */ 00005 /* Arithmetic computations (body). */ 00006 /* */ 00007 /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2008 by */ 00008 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 00009 /* */ 00010 /* This file is part of the FreeType project, and may only be used, */ 00011 /* modified, and distributed under the terms of the FreeType project */ 00012 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 00013 /* this file you indicate that you have read the license and */ 00014 /* understand and accept it fully. */ 00015 /* */ 00016 /***************************************************************************/ 00017 00018 /*************************************************************************/ 00019 /* */ 00020 /* Support for 1-complement arithmetic has been totally dropped in this */ 00021 /* release. You can still write your own code if you need it. */ 00022 /* */ 00023 /*************************************************************************/ 00024 00025 /*************************************************************************/ 00026 /* */ 00027 /* Implementing basic computation routines. */ 00028 /* */ 00029 /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(), */ 00030 /* and FT_FloorFix() are declared in freetype.h. */ 00031 /* */ 00032 /*************************************************************************/ 00033 00034 00035 #include <ft2build.h> 00036 #include FT_GLYPH_H 00037 #include FT_INTERNAL_CALC_H 00038 #include FT_INTERNAL_DEBUG_H 00039 #include FT_INTERNAL_OBJECTS_H 00040 00041 #ifdef FT_MULFIX_INLINED 00042 #undef FT_MulFix 00043 #endif 00044 00045 /* we need to define a 64-bits data type here */ 00046 00047 #ifdef FT_LONG64 00048 00049 typedef FT_INT64 FT_Int64; 00050 00051 #else 00052 00053 typedef struct FT_Int64_ 00054 { 00055 FT_UInt32 lo; 00056 FT_UInt32 hi; 00057 00058 } FT_Int64; 00059 00060 #endif /* FT_LONG64 */ 00061 00062 00063 /*************************************************************************/ 00064 /* */ 00065 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 00066 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 00067 /* messages during execution. */ 00068 /* */ 00069 #undef FT_COMPONENT 00070 #define FT_COMPONENT trace_calc 00071 00072 00073 /* The following three functions are available regardless of whether */ 00074 /* FT_LONG64 is defined. */ 00075 00076 /* documentation is in freetype.h */ 00077 00078 FT_EXPORT_DEF( FT_Fixed ) 00079 FT_RoundFix( FT_Fixed a ) 00080 { 00081 return ( a >= 0 ) ? ( a + 0x8000L ) & ~0xFFFFL 00082 : -((-a + 0x8000L ) & ~0xFFFFL ); 00083 } 00084 00085 00086 /* documentation is in freetype.h */ 00087 00088 FT_EXPORT_DEF( FT_Fixed ) 00089 FT_CeilFix( FT_Fixed a ) 00090 { 00091 return ( a >= 0 ) ? ( a + 0xFFFFL ) & ~0xFFFFL 00092 : -((-a + 0xFFFFL ) & ~0xFFFFL ); 00093 } 00094 00095 00096 /* documentation is in freetype.h */ 00097 00098 FT_EXPORT_DEF( FT_Fixed ) 00099 FT_FloorFix( FT_Fixed a ) 00100 { 00101 return ( a >= 0 ) ? a & ~0xFFFFL 00102 : -((-a) & ~0xFFFFL ); 00103 } 00104 00105 00106 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS 00107 00108 /* documentation is in ftcalc.h */ 00109 00110 FT_EXPORT_DEF( FT_Int32 ) 00111 FT_Sqrt32( FT_Int32 x ) 00112 { 00113 FT_UInt32 val, root, newroot, mask; 00114 00115 00116 root = 0; 00117 mask = (FT_UInt32)0x40000000UL; 00118 val = (FT_UInt32)x; 00119 00120 do 00121 { 00122 newroot = root + mask; 00123 if ( newroot <= val ) 00124 { 00125 val -= newroot; 00126 root = newroot + mask; 00127 } 00128 00129 root >>= 1; 00130 mask >>= 2; 00131 00132 } while ( mask != 0 ); 00133 00134 return root; 00135 } 00136 00137 #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */ 00138 00139 00140 #ifdef FT_LONG64 00141 00142 00143 /* documentation is in freetype.h */ 00144 00145 FT_EXPORT_DEF( FT_Long ) 00146 FT_MulDiv( FT_Long a, 00147 FT_Long b, 00148 FT_Long c ) 00149 { 00150 FT_Int s; 00151 FT_Long d; 00152 00153 00154 s = 1; 00155 if ( a < 0 ) { a = -a; s = -1; } 00156 if ( b < 0 ) { b = -b; s = -s; } 00157 if ( c < 0 ) { c = -c; s = -s; } 00158 00159 d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c 00160 : 0x7FFFFFFFL ); 00161 00162 return ( s > 0 ) ? d : -d; 00163 } 00164 00165 00166 #ifdef TT_USE_BYTECODE_INTERPRETER 00167 00168 /* documentation is in ftcalc.h */ 00169 00170 FT_BASE_DEF( FT_Long ) 00171 FT_MulDiv_No_Round( FT_Long a, 00172 FT_Long b, 00173 FT_Long c ) 00174 { 00175 FT_Int s; 00176 FT_Long d; 00177 00178 00179 s = 1; 00180 if ( a < 0 ) { a = -a; s = -1; } 00181 if ( b < 0 ) { b = -b; s = -s; } 00182 if ( c < 0 ) { c = -c; s = -s; } 00183 00184 d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c 00185 : 0x7FFFFFFFL ); 00186 00187 return ( s > 0 ) ? d : -d; 00188 } 00189 00190 #endif /* TT_USE_BYTECODE_INTERPRETER */ 00191 00192 00193 /* documentation is in freetype.h */ 00194 00195 FT_EXPORT_DEF( FT_Long ) 00196 FT_MulFix( FT_Long a, 00197 FT_Long b ) 00198 { 00199 #ifdef FT_MULFIX_ASSEMBLER 00200 00201 return FT_MULFIX_ASSEMBLER( a, b ); 00202 00203 #else 00204 00205 FT_Int s = 1; 00206 FT_Long c; 00207 00208 00209 if ( a < 0 ) 00210 { 00211 a = -a; 00212 s = -1; 00213 } 00214 00215 if ( b < 0 ) 00216 { 00217 b = -b; 00218 s = -s; 00219 } 00220 00221 c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 ); 00222 00223 return ( s > 0 ) ? c : -c; 00224 00225 #endif /* FT_MULFIX_ASSEMBLER */ 00226 } 00227 00228 00229 /* documentation is in freetype.h */ 00230 00231 FT_EXPORT_DEF( FT_Long ) 00232 FT_DivFix( FT_Long a, 00233 FT_Long b ) 00234 { 00235 FT_Int32 s; 00236 FT_UInt32 q; 00237 00238 s = 1; 00239 if ( a < 0 ) { a = -a; s = -1; } 00240 if ( b < 0 ) { b = -b; s = -s; } 00241 00242 if ( b == 0 ) 00243 /* check for division by 0 */ 00244 q = 0x7FFFFFFFL; 00245 else 00246 /* compute result directly */ 00247 q = (FT_UInt32)( ( ( (FT_Int64)a << 16 ) + ( b >> 1 ) ) / b ); 00248 00249 return ( s < 0 ? -(FT_Long)q : (FT_Long)q ); 00250 } 00251 00252 00253 #else /* !FT_LONG64 */ 00254 00255 00256 static void 00257 ft_multo64( FT_UInt32 x, 00258 FT_UInt32 y, 00259 FT_Int64 *z ) 00260 { 00261 FT_UInt32 lo1, hi1, lo2, hi2, lo, hi, i1, i2; 00262 00263 00264 lo1 = x & 0x0000FFFFU; hi1 = x >> 16; 00265 lo2 = y & 0x0000FFFFU; hi2 = y >> 16; 00266 00267 lo = lo1 * lo2; 00268 i1 = lo1 * hi2; 00269 i2 = lo2 * hi1; 00270 hi = hi1 * hi2; 00271 00272 /* Check carry overflow of i1 + i2 */ 00273 i1 += i2; 00274 hi += (FT_UInt32)( i1 < i2 ) << 16; 00275 00276 hi += i1 >> 16; 00277 i1 = i1 << 16; 00278 00279 /* Check carry overflow of i1 + lo */ 00280 lo += i1; 00281 hi += ( lo < i1 ); 00282 00283 z->lo = lo; 00284 z->hi = hi; 00285 } 00286 00287 00288 static FT_UInt32 00289 ft_div64by32( FT_UInt32 hi, 00290 FT_UInt32 lo, 00291 FT_UInt32 y ) 00292 { 00293 FT_UInt32 r, q; 00294 FT_Int i; 00295 00296 00297 q = 0; 00298 r = hi; 00299 00300 if ( r >= y ) 00301 return (FT_UInt32)0x7FFFFFFFL; 00302 00303 i = 32; 00304 do 00305 { 00306 r <<= 1; 00307 q <<= 1; 00308 r |= lo >> 31; 00309 00310 if ( r >= (FT_UInt32)y ) 00311 { 00312 r -= y; 00313 q |= 1; 00314 } 00315 lo <<= 1; 00316 } while ( --i ); 00317 00318 return q; 00319 } 00320 00321 00322 static void 00323 FT_Add64( FT_Int64* x, 00324 FT_Int64* y, 00325 FT_Int64 *z ) 00326 { 00327 register FT_UInt32 lo, hi; 00328 00329 00330 lo = x->lo + y->lo; 00331 hi = x->hi + y->hi + ( lo < x->lo ); 00332 00333 z->lo = lo; 00334 z->hi = hi; 00335 } 00336 00337 00338 /* documentation is in freetype.h */ 00339 00340 /* The FT_MulDiv function has been optimized thanks to ideas from */ 00341 /* Graham Asher. The trick is to optimize computation when everything */ 00342 /* fits within 32-bits (a rather common case). */ 00343 /* */ 00344 /* we compute 'a*b+c/2', then divide it by 'c'. (positive values) */ 00345 /* */ 00346 /* 46340 is FLOOR(SQRT(2^31-1)). */ 00347 /* */ 00348 /* if ( a <= 46340 && b <= 46340 ) then ( a*b <= 0x7FFEA810 ) */ 00349 /* */ 00350 /* 0x7FFFFFFF - 0x7FFEA810 = 0x157F0 */ 00351 /* */ 00352 /* if ( c < 0x157F0*2 ) then ( a*b+c/2 <= 0x7FFFFFFF ) */ 00353 /* */ 00354 /* and 2*0x157F0 = 176096 */ 00355 /* */ 00356 00357 FT_EXPORT_DEF( FT_Long ) 00358 FT_MulDiv( FT_Long a, 00359 FT_Long b, 00360 FT_Long c ) 00361 { 00362 long s; 00363 00364 00365 /* XXX: this function does not allow 64-bit arguments */ 00366 if ( a == 0 || b == c ) 00367 return a; 00368 00369 s = a; a = FT_ABS( a ); 00370 s ^= b; b = FT_ABS( b ); 00371 s ^= c; c = FT_ABS( c ); 00372 00373 if ( a <= 46340L && b <= 46340L && c <= 176095L && c > 0 ) 00374 a = ( a * b + ( c >> 1 ) ) / c; 00375 00376 else if ( c > 0 ) 00377 { 00378 FT_Int64 temp, temp2; 00379 00380 00381 ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); 00382 00383 temp2.hi = 0; 00384 temp2.lo = (FT_UInt32)(c >> 1); 00385 FT_Add64( &temp, &temp2, &temp ); 00386 a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); 00387 } 00388 else 00389 a = 0x7FFFFFFFL; 00390 00391 return ( s < 0 ? -a : a ); 00392 } 00393 00394 00395 #ifdef TT_USE_BYTECODE_INTERPRETER 00396 00397 FT_BASE_DEF( FT_Long ) 00398 FT_MulDiv_No_Round( FT_Long a, 00399 FT_Long b, 00400 FT_Long c ) 00401 { 00402 long s; 00403 00404 00405 if ( a == 0 || b == c ) 00406 return a; 00407 00408 s = a; a = FT_ABS( a ); 00409 s ^= b; b = FT_ABS( b ); 00410 s ^= c; c = FT_ABS( c ); 00411 00412 if ( a <= 46340L && b <= 46340L && c > 0 ) 00413 a = a * b / c; 00414 00415 else if ( c > 0 ) 00416 { 00417 FT_Int64 temp; 00418 00419 00420 ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp ); 00421 a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c ); 00422 } 00423 else 00424 a = 0x7FFFFFFFL; 00425 00426 return ( s < 0 ? -a : a ); 00427 } 00428 00429 #endif /* TT_USE_BYTECODE_INTERPRETER */ 00430 00431 00432 /* documentation is in freetype.h */ 00433 00434 FT_EXPORT_DEF( FT_Long ) 00435 FT_MulFix( FT_Long a, 00436 FT_Long b ) 00437 { 00438 #ifdef FT_MULFIX_ASSEMBLER 00439 00440 return FT_MULFIX_ASSEMBLER( a, b ); 00441 00442 #elif 0 00443 00444 /* 00445 * This code is nonportable. See comment below. 00446 * 00447 * However, on a platform where right-shift of a signed quantity fills 00448 * the leftmost bits by copying the sign bit, it might be faster. 00449 */ 00450 00451 FT_Long sa, sb; 00452 FT_ULong ua, ub; 00453 00454 00455 if ( a == 0 || b == 0x10000L ) 00456 return a; 00457 00458 /* 00459 * This is a clever way of converting a signed number `a' into its 00460 * absolute value (stored back into `a') and its sign. The sign is 00461 * stored in `sa'; 0 means `a' was positive or zero, and -1 means `a' 00462 * was negative. (Similarly for `b' and `sb'). 00463 * 00464 * Unfortunately, it doesn't work (at least not portably). 00465 * 00466 * It makes the assumption that right-shift on a negative signed value 00467 * fills the leftmost bits by copying the sign bit. This is wrong. 00468 * According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206, 00469 * the result of right-shift of a negative signed value is 00470 * implementation-defined. At least one implementation fills the 00471 * leftmost bits with 0s (i.e., it is exactly the same as an unsigned 00472 * right shift). This means that when `a' is negative, `sa' ends up 00473 * with the value 1 rather than -1. After that, everything else goes 00474 * wrong. 00475 */ 00476 sa = ( a >> ( sizeof ( a ) * 8 - 1 ) ); 00477 a = ( a ^ sa ) - sa; 00478 sb = ( b >> ( sizeof ( b ) * 8 - 1 ) ); 00479 b = ( b ^ sb ) - sb; 00480 00481 ua = (FT_ULong)a; 00482 ub = (FT_ULong)b; 00483 00484 if ( ua <= 2048 && ub <= 1048576L ) 00485 ua = ( ua * ub + 0x8000U ) >> 16; 00486 else 00487 { 00488 FT_ULong al = ua & 0xFFFFU; 00489 00490 00491 ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + 00492 ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 ); 00493 } 00494 00495 sa ^= sb, 00496 ua = (FT_ULong)(( ua ^ sa ) - sa); 00497 00498 return (FT_Long)ua; 00499 00500 #else /* 0 */ 00501 00502 FT_Long s; 00503 FT_ULong ua, ub; 00504 00505 00506 if ( a == 0 || b == 0x10000L ) 00507 return a; 00508 00509 s = a; a = FT_ABS( a ); 00510 s ^= b; b = FT_ABS( b ); 00511 00512 ua = (FT_ULong)a; 00513 ub = (FT_ULong)b; 00514 00515 if ( ua <= 2048 && ub <= 1048576L ) 00516 ua = ( ua * ub + 0x8000UL ) >> 16; 00517 else 00518 { 00519 FT_ULong al = ua & 0xFFFFUL; 00520 00521 00522 ua = ( ua >> 16 ) * ub + al * ( ub >> 16 ) + 00523 ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 ); 00524 } 00525 00526 return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua ); 00527 00528 #endif /* 0 */ 00529 00530 } 00531 00532 00533 /* documentation is in freetype.h */ 00534 00535 FT_EXPORT_DEF( FT_Long ) 00536 FT_DivFix( FT_Long a, 00537 FT_Long b ) 00538 { 00539 FT_Int32 s; 00540 FT_UInt32 q; 00541 00542 00543 /* XXX: this function does not allow 64-bit arguments */ 00544 s = (FT_Int32)a; a = FT_ABS( a ); 00545 s ^= (FT_Int32)b; b = FT_ABS( b ); 00546 00547 if ( b == 0 ) 00548 { 00549 /* check for division by 0 */ 00550 q = (FT_UInt32)0x7FFFFFFFL; 00551 } 00552 else if ( ( a >> 16 ) == 0 ) 00553 { 00554 /* compute result directly */ 00555 q = (FT_UInt32)( (a << 16) + (b >> 1) ) / (FT_UInt32)b; 00556 } 00557 else 00558 { 00559 /* we need more bits; we have to do it by hand */ 00560 FT_Int64 temp, temp2; 00561 00562 temp.hi = (FT_Int32) (a >> 16); 00563 temp.lo = (FT_UInt32)(a << 16); 00564 temp2.hi = 0; 00565 temp2.lo = (FT_UInt32)( b >> 1 ); 00566 FT_Add64( &temp, &temp2, &temp ); 00567 q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b ); 00568 } 00569 00570 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 00571 } 00572 00573 00574 #if 0 00575 00576 /* documentation is in ftcalc.h */ 00577 00578 FT_EXPORT_DEF( void ) 00579 FT_MulTo64( FT_Int32 x, 00580 FT_Int32 y, 00581 FT_Int64 *z ) 00582 { 00583 FT_Int32 s; 00584 00585 00586 s = x; x = FT_ABS( x ); 00587 s ^= y; y = FT_ABS( y ); 00588 00589 ft_multo64( x, y, z ); 00590 00591 if ( s < 0 ) 00592 { 00593 z->lo = (FT_UInt32)-(FT_Int32)z->lo; 00594 z->hi = ~z->hi + !( z->lo ); 00595 } 00596 } 00597 00598 00599 /* apparently, the second version of this code is not compiled correctly */ 00600 /* on Mac machines with the MPW C compiler.. tsk, tsk, tsk... */ 00601 00602 #if 1 00603 00604 FT_EXPORT_DEF( FT_Int32 ) 00605 FT_Div64by32( FT_Int64* x, 00606 FT_Int32 y ) 00607 { 00608 FT_Int32 s; 00609 FT_UInt32 q, r, i, lo; 00610 00611 00612 s = x->hi; 00613 if ( s < 0 ) 00614 { 00615 x->lo = (FT_UInt32)-(FT_Int32)x->lo; 00616 x->hi = ~x->hi + !x->lo; 00617 } 00618 s ^= y; y = FT_ABS( y ); 00619 00620 /* Shortcut */ 00621 if ( x->hi == 0 ) 00622 { 00623 if ( y > 0 ) 00624 q = x->lo / y; 00625 else 00626 q = 0x7FFFFFFFL; 00627 00628 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 00629 } 00630 00631 r = x->hi; 00632 lo = x->lo; 00633 00634 if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */ 00635 return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL ); 00636 /* Return Max/Min Int32 if division overflow. */ 00637 /* This includes division by zero! */ 00638 q = 0; 00639 for ( i = 0; i < 32; i++ ) 00640 { 00641 r <<= 1; 00642 q <<= 1; 00643 r |= lo >> 31; 00644 00645 if ( r >= (FT_UInt32)y ) 00646 { 00647 r -= y; 00648 q |= 1; 00649 } 00650 lo <<= 1; 00651 } 00652 00653 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 00654 } 00655 00656 #else /* 0 */ 00657 00658 FT_EXPORT_DEF( FT_Int32 ) 00659 FT_Div64by32( FT_Int64* x, 00660 FT_Int32 y ) 00661 { 00662 FT_Int32 s; 00663 FT_UInt32 q; 00664 00665 00666 s = x->hi; 00667 if ( s < 0 ) 00668 { 00669 x->lo = (FT_UInt32)-(FT_Int32)x->lo; 00670 x->hi = ~x->hi + !x->lo; 00671 } 00672 s ^= y; y = FT_ABS( y ); 00673 00674 /* Shortcut */ 00675 if ( x->hi == 0 ) 00676 { 00677 if ( y > 0 ) 00678 q = ( x->lo + ( y >> 1 ) ) / y; 00679 else 00680 q = 0x7FFFFFFFL; 00681 00682 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 00683 } 00684 00685 q = ft_div64by32( x->hi, x->lo, y ); 00686 00687 return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q ); 00688 } 00689 00690 #endif /* 0 */ 00691 00692 #endif /* 0 */ 00693 00694 00695 #endif /* FT_LONG64 */ 00696 00697 00698 /* documentation is in ftglyph.h */ 00699 00700 FT_EXPORT_DEF( void ) 00701 FT_Matrix_Multiply( const FT_Matrix* a, 00702 FT_Matrix *b ) 00703 { 00704 FT_Fixed xx, xy, yx, yy; 00705 00706 00707 if ( !a || !b ) 00708 return; 00709 00710 xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx ); 00711 xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy ); 00712 yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx ); 00713 yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy ); 00714 00715 b->xx = xx; b->xy = xy; 00716 b->yx = yx; b->yy = yy; 00717 } 00718 00719 00720 /* documentation is in ftglyph.h */ 00721 00722 FT_EXPORT_DEF( FT_Error ) 00723 FT_Matrix_Invert( FT_Matrix* matrix ) 00724 { 00725 FT_Pos delta, xx, yy; 00726 00727 00728 if ( !matrix ) 00729 return FT_Err_Invalid_Argument; 00730 00731 /* compute discriminant */ 00732 delta = FT_MulFix( matrix->xx, matrix->yy ) - 00733 FT_MulFix( matrix->xy, matrix->yx ); 00734 00735 if ( !delta ) 00736 return FT_Err_Invalid_Argument; /* matrix can't be inverted */ 00737 00738 matrix->xy = - FT_DivFix( matrix->xy, delta ); 00739 matrix->yx = - FT_DivFix( matrix->yx, delta ); 00740 00741 xx = matrix->xx; 00742 yy = matrix->yy; 00743 00744 matrix->xx = FT_DivFix( yy, delta ); 00745 matrix->yy = FT_DivFix( xx, delta ); 00746 00747 return FT_Err_Ok; 00748 } 00749 00750 00751 /* documentation is in ftcalc.h */ 00752 00753 FT_BASE_DEF( void ) 00754 FT_Matrix_Multiply_Scaled( const FT_Matrix* a, 00755 FT_Matrix *b, 00756 FT_Long scaling ) 00757 { 00758 FT_Fixed xx, xy, yx, yy; 00759 00760 FT_Long val = 0x10000L * scaling; 00761 00762 00763 if ( !a || !b ) 00764 return; 00765 00766 xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val ); 00767 xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val ); 00768 yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val ); 00769 yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val ); 00770 00771 b->xx = xx; b->xy = xy; 00772 b->yx = yx; b->yy = yy; 00773 } 00774 00775 00776 /* documentation is in ftcalc.h */ 00777 00778 FT_BASE_DEF( void ) 00779 FT_Vector_Transform_Scaled( FT_Vector* vector, 00780 const FT_Matrix* matrix, 00781 FT_Long scaling ) 00782 { 00783 FT_Pos xz, yz; 00784 00785 FT_Long val = 0x10000L * scaling; 00786 00787 00788 if ( !vector || !matrix ) 00789 return; 00790 00791 xz = FT_MulDiv( vector->x, matrix->xx, val ) + 00792 FT_MulDiv( vector->y, matrix->xy, val ); 00793 00794 yz = FT_MulDiv( vector->x, matrix->yx, val ) + 00795 FT_MulDiv( vector->y, matrix->yy, val ); 00796 00797 vector->x = xz; 00798 vector->y = yz; 00799 } 00800 00801 00802 /* documentation is in ftcalc.h */ 00803 00804 FT_BASE_DEF( FT_Int32 ) 00805 FT_SqrtFixed( FT_Int32 x ) 00806 { 00807 FT_UInt32 root, rem_hi, rem_lo, test_div; 00808 FT_Int count; 00809 00810 00811 root = 0; 00812 00813 if ( x > 0 ) 00814 { 00815 rem_hi = 0; 00816 rem_lo = x; 00817 count = 24; 00818 do 00819 { 00820 rem_hi = ( rem_hi << 2 ) | ( rem_lo >> 30 ); 00821 rem_lo <<= 2; 00822 root <<= 1; 00823 test_div = ( root << 1 ) + 1; 00824 00825 if ( rem_hi >= test_div ) 00826 { 00827 rem_hi -= test_div; 00828 root += 1; 00829 } 00830 } while ( --count ); 00831 } 00832 00833 return (FT_Int32)root; 00834 } 00835 00836 00837 /* documentation is in ftcalc.h */ 00838 00839 FT_BASE_DEF( FT_Int ) 00840 ft_corner_orientation( FT_Pos in_x, 00841 FT_Pos in_y, 00842 FT_Pos out_x, 00843 FT_Pos out_y ) 00844 { 00845 FT_Long result; /* avoid overflow on 16-bit system */ 00846 00847 00848 /* deal with the trivial cases quickly */ 00849 if ( in_y == 0 ) 00850 { 00851 if ( in_x >= 0 ) 00852 result = out_y; 00853 else 00854 result = -out_y; 00855 } 00856 else if ( in_x == 0 ) 00857 { 00858 if ( in_y >= 0 ) 00859 result = -out_x; 00860 else 00861 result = out_x; 00862 } 00863 else if ( out_y == 0 ) 00864 { 00865 if ( out_x >= 0 ) 00866 result = in_y; 00867 else 00868 result = -in_y; 00869 } 00870 else if ( out_x == 0 ) 00871 { 00872 if ( out_y >= 0 ) 00873 result = -in_x; 00874 else 00875 result = in_x; 00876 } 00877 else /* general case */ 00878 { 00879 #ifdef FT_LONG64 00880 00881 FT_Int64 delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x; 00882 00883 00884 if ( delta == 0 ) 00885 result = 0; 00886 else 00887 result = 1 - 2 * ( delta < 0 ); 00888 00889 #else 00890 00891 FT_Int64 z1, z2; 00892 00893 00894 /* XXX: this function does not allow 64-bit arguments */ 00895 ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 ); 00896 ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 ); 00897 00898 if ( z1.hi > z2.hi ) 00899 result = +1; 00900 else if ( z1.hi < z2.hi ) 00901 result = -1; 00902 else if ( z1.lo > z2.lo ) 00903 result = +1; 00904 else if ( z1.lo < z2.lo ) 00905 result = -1; 00906 else 00907 result = 0; 00908 00909 #endif 00910 } 00911 00912 /* XXX: only the sign of return value, +1/0/-1 must be used */ 00913 return (FT_Int)result; 00914 } 00915 00916 00917 /* documentation is in ftcalc.h */ 00918 00919 FT_BASE_DEF( FT_Int ) 00920 ft_corner_is_flat( FT_Pos in_x, 00921 FT_Pos in_y, 00922 FT_Pos out_x, 00923 FT_Pos out_y ) 00924 { 00925 FT_Pos ax = in_x; 00926 FT_Pos ay = in_y; 00927 00928 FT_Pos d_in, d_out, d_corner; 00929 00930 00931 if ( ax < 0 ) 00932 ax = -ax; 00933 if ( ay < 0 ) 00934 ay = -ay; 00935 d_in = ax + ay; 00936 00937 ax = out_x; 00938 if ( ax < 0 ) 00939 ax = -ax; 00940 ay = out_y; 00941 if ( ay < 0 ) 00942 ay = -ay; 00943 d_out = ax + ay; 00944 00945 ax = out_x + in_x; 00946 if ( ax < 0 ) 00947 ax = -ax; 00948 ay = out_y + in_y; 00949 if ( ay < 0 ) 00950 ay = -ay; 00951 d_corner = ax + ay; 00952 00953 return ( d_in + d_out - d_corner ) < ( d_corner >> 4 ); 00954 } 00955 00956 00957 /* END */ Generated on Sat May 26 2012 04:32:37 for ReactOS by
1.7.6.1
|