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 Tue Jul 5 14:13:42 2011 for ROOT_528-00b_version by  doxygen 1.5.1