Author: jimtabor Date: Mon May 14 07:18:42 2007 New Revision: 26772
URL: http://svn.reactos.org/svn/reactos?rev=26772&view=rev Log: Update painting.c with new storage method for floating point operations.
Modified: trunk/reactos/dll/win32/gdi32/objects/painting.c
Modified: trunk/reactos/dll/win32/gdi32/objects/painting.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/pai... ============================================================================== --- trunk/reactos/dll/win32/gdi32/objects/painting.c (original) +++ trunk/reactos/dll/win32/gdi32/objects/painting.c Mon May 14 07:18:42 2007 @@ -1,15 +1,66 @@ #include "precomp.h"
- -typedef union -{ - FLOAT f; - ULONG l; -} gxf_long; - -#define XFPMANT(fp) ((fp.l) & 0x7fffff) -#define XFPEXP(fp) ((fp.l) >> 23) & 0xff) -#define XFPBUILD(e, m) (((e << 23) & 0x7f800000) | (m & 0x7fffff)) +/* the following deal with IEEE single-precision numbers */ +#define EXCESS 126L +#define SIGNBIT 0x80000000L +#define SIGN(fp) ((fp) & SIGNBIT) +#define EXP(fp) (((fp) >> 23L) & 0xFF) +#define MANT(fp) ((fp) & 0x7FFFFFL) +#define PACK(s,e,m) ((s) | ((e) << 23L) | (m)) + +// Sames as lrintf. +#ifdef __GNUC__ +#define FLOAT_TO_INT(in,out) \ + __asm__ __volatile__ ("fistpl %0" : "=m" (out) : "t" (in) : "st"); +#else +#define FLOAT_TO_INT(in,out) \ + __asm fld in \ + __asm fistp out +#endif + +LONG +FASTCALL +EFtoF( EFLOAT_S * efp) +{ + long Mant, Exp, Sign = 0; + + if (!efp->lMant) return 0; + + Mant = efp->lMant; + Exp = efp->lExp; + Sign = SIGN(Mant); + +//// M$ storage emulation + Mant = ((Mant & 0x3fffffff) >> 7); + Exp += (1 - EXCESS); +//// + Mant = MANT(Mant); + return PACK(Sign, Exp, Mant); +} + +VOID +FASTCALL +FtoEF( EFLOAT_S * efp, FLOATL f) +{ + long Mant, Exp; + gxf_long worker; + +#ifdef _X86_ + worker.l = f; // It's a float stored in a long. +#else + worker.f = f; +#endif + + Exp = EXP(worker.l); + Mant = MANT(worker.l); + +//// M$ storage emulation + Mant = ((Mant << 7) | 0x40000000 | SIGN(worker.l)); + Exp -= (1 - EXCESS); +//// + efp->lMant = Mant; + efp->lExp = Exp; +}
VOID FASTCALL @@ -21,15 +72,16 @@ x = (FLOAT)Point->x; y = (FLOAT)Point->y;
- a.l = XFPBUILD( mx->efM11.lExp, mx->efM11.lMant); - b.l = XFPBUILD( mx->efM21.lExp, mx->efM21.lMant); - - Point->x = x * a.f + y * b.f + mx->fxDx; - - a.l = XFPBUILD( mx->efM12.lExp, mx->efM12.lMant); - b.l = XFPBUILD( mx->efM22.lExp, mx->efM22.lMant); - - Point->y = x * a.f + y * b.f + mx->fxDy; + a.l = EFtoF( &mx->efM11 ); + b.l = EFtoF( &mx->efM21 ); + x = x * a.f + y * b.f + mx->fxDx; + + a.l = EFtoF( &mx->efM12 ); + b.l = EFtoF( &mx->efM22 ); + y = x * a.f + y * b.f + mx->fxDy; + + FLOAT_TO_INT(x, Point->x ); + FLOAT_TO_INT(y, Point->y ); }