ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ftcalc.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.