mirror of
https://github.com/reactos/reactos.git
synced 2024-12-25 03:53:36 +08:00
Change DC and DC_ATTR members from MATRIX_S and EFLOAT_S, which are explicit fpu emulation types, instead use MATRIX and FLOATOBJ which are the class types. Plug in new FLOATOBJ api and remove old fpu using version. Implement XFORMOBJ api using FLOATOBJ. Remove most of the fpu using code from win32k.
svn path=/trunk/; revision=35779
This commit is contained in:
parent
46cc92b9b6
commit
dcae209a08
@ -290,13 +290,13 @@ typedef struct _DC_ATTR
|
||||
LONG lBreakExtra;
|
||||
LONG cBreak;
|
||||
HANDLE hlfntNew;
|
||||
MATRIX_S mxWorldToDevice;
|
||||
MATRIX_S mxDeviceToWorld;
|
||||
MATRIX_S mxWorldToPage;
|
||||
EFLOAT_S efM11PtoD;
|
||||
EFLOAT_S efM22PtoD;
|
||||
EFLOAT_S efDxPtoD;
|
||||
EFLOAT_S efDyPtoD;
|
||||
MATRIX mxWorldToDevice;
|
||||
MATRIX mxDeviceToWorld;
|
||||
MATRIX mxWorldToPage;
|
||||
FLOATOBJ efM11PtoD;
|
||||
FLOATOBJ efM22PtoD;
|
||||
FLOATOBJ efDxPtoD;
|
||||
FLOATOBJ efDyPtoD;
|
||||
INT iMapMode;
|
||||
DWORD dwLayout;
|
||||
LONG lWindowOrgx;
|
||||
|
@ -33,30 +33,6 @@
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* DEFINES *****************************************************************/
|
||||
|
||||
#ifdef _M_IX86
|
||||
#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
|
||||
#else
|
||||
#define FLOAT_TO_INT(in,out) \
|
||||
out = (long)in;
|
||||
#endif
|
||||
|
||||
/* 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))
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOL
|
||||
@ -101,525 +77,3 @@ EngSaveFloatingPointState(OUT VOID *Buffer,
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
EF_Negate(EFLOAT_S * efp)
|
||||
{
|
||||
efp->lMant = -efp->lMant;
|
||||
}
|
||||
|
||||
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
|
||||
if( Sign ) Mant = -Mant;
|
||||
Mant = ((Mant & 0x3fffffff) >> 7);
|
||||
Exp += (EXCESS-1);
|
||||
////
|
||||
Mant = MANT(Mant);
|
||||
return PACK(Sign, Exp, Mant);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
FtoEF( EFLOAT_S * efp, FLOATL f)
|
||||
{
|
||||
long Mant, Exp, Sign = 0;
|
||||
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);
|
||||
if (SIGN(worker.l)) Sign = -1;
|
||||
//// M$ storage emulation
|
||||
Mant = ((Mant << 7) | 0x40000000);
|
||||
Mant ^= Sign;
|
||||
Mant -= Sign;
|
||||
Exp -= (EXCESS-1);
|
||||
////
|
||||
efp->lMant = Mant;
|
||||
efp->lExp = Exp;
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_Add (
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN PFLOATOBJ pf1
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_2i3r.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
EFLOAT_S * efp1 = (EFLOAT_S *)pf1;
|
||||
gxf_long f;
|
||||
gxf_long f1;
|
||||
f.l = EFtoF(efp);
|
||||
f1.l = EFtoF(efp1);
|
||||
f.f = f.f + f1.f;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, f.l );
|
||||
#else
|
||||
FtoEF( efp, f.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_AddFloat(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN FLOATL f
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_0ip3.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long fe;
|
||||
gxf_long f1;
|
||||
fe.l = EFtoF(efp);
|
||||
#ifdef _X86_
|
||||
f1.l = f;
|
||||
#else
|
||||
f1.f = f;
|
||||
#endif
|
||||
fe.f = fe.f + f1.f;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, fe.l );
|
||||
#else
|
||||
FtoEF( efp, fe.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
XForm2MatrixS( MATRIX_S * Matrix, PXFORM XForm)
|
||||
{
|
||||
gxf_long f;
|
||||
f.f = XForm->eM11;
|
||||
FtoEF( &Matrix->efM11, f.l);
|
||||
f.f = XForm->eM12;
|
||||
FtoEF( &Matrix->efM12, f.l);
|
||||
f.f = XForm->eM21;
|
||||
FtoEF( &Matrix->efM21, f.l);
|
||||
f.f = XForm->eM22;
|
||||
FtoEF( &Matrix->efM22, f.l);
|
||||
f.f = XForm->eDx;
|
||||
FtoEF( &Matrix->efDx, f.l);
|
||||
f.f = XForm->eDy;
|
||||
FtoEF( &Matrix->efDy, f.l);
|
||||
Matrix->flAccel = 0;
|
||||
if (XForm->eM12 == 0. && XForm->eM21 == 0.)
|
||||
{
|
||||
Matrix->flAccel |= MX_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
MatrixS2XForm( PXFORM XForm, MATRIX_S * Matrix)
|
||||
{
|
||||
gxf_long f;
|
||||
f.l = EFtoF(&Matrix->efM11);
|
||||
XForm->eM11 = f.f;
|
||||
f.l = EFtoF(&Matrix->efM12);
|
||||
XForm->eM12 = f.f;
|
||||
f.l = EFtoF(&Matrix->efM21);
|
||||
XForm->eM21 = f.f;
|
||||
f.l = EFtoF(&Matrix->efM22);
|
||||
XForm->eM22 = f.f;
|
||||
f.l = EFtoF(&Matrix->efDx);
|
||||
XForm->eDx = f.f;
|
||||
f.l = EFtoF(&Matrix->efDy);
|
||||
XForm->eDy = f.f;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_AddLong(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN LONG l
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_12jr.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long f;
|
||||
f.l = EFtoF(efp);
|
||||
f.f = f.f + l;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, f.l );
|
||||
#else
|
||||
FtoEF( efp, f.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_Div(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN PFLOATOBJ pf1
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_3ndz.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
EFLOAT_S * efp1 = (EFLOAT_S *)pf1;
|
||||
gxf_long f;
|
||||
gxf_long f1;
|
||||
f.l = EFtoF(efp);
|
||||
f1.l = EFtoF(efp1);
|
||||
f.f = f.f / f1.f;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, f.l );
|
||||
#else
|
||||
FtoEF( efp, f.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_DivFloat(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN FLOATL f
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_0gfb.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long fe;
|
||||
gxf_long f1;
|
||||
fe.l = EFtoF(efp);
|
||||
#ifdef _X86_
|
||||
f1.l = f;
|
||||
#else
|
||||
f1.f = f;
|
||||
#endif
|
||||
fe.f = fe.f / f1.f;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, fe.l );
|
||||
#else
|
||||
FtoEF( efp, fe.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_DivLong(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN LONG l
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_6jdz.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long f;
|
||||
f.l = EFtoF(efp);
|
||||
f.f = f.f / l;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, f.l );
|
||||
#else
|
||||
FtoEF( efp, f.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
FLOATOBJ_Equal(
|
||||
IN PFLOATOBJ pf,
|
||||
IN PFLOATOBJ pf1
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_6ysn.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
EFLOAT_S * efp1 = (EFLOAT_S *)pf1;
|
||||
gxf_long f;
|
||||
gxf_long f1;
|
||||
f.l = EFtoF(efp);
|
||||
f1.l = EFtoF(efp1);
|
||||
if (f.f == f1.f) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
FLOATOBJ_EqualLong(
|
||||
IN PFLOATOBJ pf,
|
||||
IN LONG l
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_1pgn.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long f;
|
||||
f.l = EFtoF(efp);
|
||||
if (f.f == l) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LONG
|
||||
STDCALL
|
||||
FLOATOBJ_GetFloat ( IN PFLOATOBJ pf )
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_4d5z.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
return EFtoF(efp);
|
||||
}
|
||||
|
||||
LONG
|
||||
STDCALL
|
||||
FLOATOBJ_GetLong ( IN PFLOATOBJ pf )
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_0tgn.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long f;
|
||||
long l;
|
||||
|
||||
f.l = EFtoF( efp );
|
||||
FLOAT_TO_INT(f.f, l); // Let FPP handle it the fasty haxy way.
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
FLOATOBJ_GreaterThan(
|
||||
IN PFLOATOBJ pf,
|
||||
IN PFLOATOBJ pf1
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_8n53.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
EFLOAT_S * efp1 = (EFLOAT_S *)pf1;
|
||||
gxf_long f;
|
||||
gxf_long f1;
|
||||
f.l = EFtoF(efp);
|
||||
f1.l = EFtoF(efp1);
|
||||
if(f.f > f1.f) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
FLOATOBJ_GreaterThanLong(
|
||||
IN PFLOATOBJ pf,
|
||||
IN LONG l
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_6gx3.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long f;
|
||||
f.l = EFtoF(efp);
|
||||
if (f.f > l) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
FLOATOBJ_LessThan(
|
||||
IN PFLOATOBJ pf,
|
||||
IN PFLOATOBJ pf1
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_1ynb.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
EFLOAT_S * efp1 = (EFLOAT_S *)pf1;
|
||||
gxf_long f;
|
||||
gxf_long f1;
|
||||
f.l = EFtoF(efp);
|
||||
f1.l = EFtoF(efp1);
|
||||
if(f.f < f1.f) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
STDCALL
|
||||
FLOATOBJ_LessThanLong(
|
||||
IN PFLOATOBJ pf,
|
||||
IN LONG l
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_9nzb.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long f;
|
||||
f.l = EFtoF(efp);
|
||||
if (f.f < l) return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_Mul(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN PFLOATOBJ pf1
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_8ppj.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
EFLOAT_S * efp1 = (EFLOAT_S *)pf1;
|
||||
gxf_long f;
|
||||
gxf_long f1;
|
||||
f.l = EFtoF(efp);
|
||||
f1.l = EFtoF(efp1);
|
||||
f.f = f1.f * f.f;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, f.l );
|
||||
#else
|
||||
FtoEF( efp, f.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_MulFloat(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN FLOATL f
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_3puv.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long fe;
|
||||
gxf_long f1;
|
||||
fe.l = EFtoF(efp);
|
||||
#ifdef _X86_
|
||||
f1.l = f;
|
||||
#else
|
||||
f1.f = f;
|
||||
#endif
|
||||
fe.f = f1.f * fe.f;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, fe.l );
|
||||
#else
|
||||
FtoEF( efp, fe.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_MulLong(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN LONG l
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_56lj.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long f;
|
||||
f.l = EFtoF(efp);
|
||||
f.f = f.f * l;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, f.l );
|
||||
#else
|
||||
FtoEF( efp, f.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_Neg ( IN OUT PFLOATOBJ pf )
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_14pz.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
EF_Negate(efp);
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_SetFloat(
|
||||
OUT PFLOATOBJ pf,
|
||||
IN FLOATL f
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_1prb.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
FtoEF( efp, f);
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_SetLong(
|
||||
OUT PFLOATOBJ pf,
|
||||
IN LONG l
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_0gpz.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long f;
|
||||
f.f = (float) l; // Convert it now.
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, f.l );
|
||||
#else
|
||||
FtoEF( efp, f.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_Sub(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN PFLOATOBJ pf1
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_6lyf.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
EFLOAT_S * efp1 = (EFLOAT_S *)pf1;
|
||||
gxf_long f;
|
||||
gxf_long f1;
|
||||
f.l = EFtoF(efp);
|
||||
f1.l = EFtoF(efp1);
|
||||
f.f = f.f - f1.f;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, f.l );
|
||||
#else
|
||||
FtoEF( efp, f.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_SubFloat(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN FLOATL f
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_2zvr.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long fe;
|
||||
gxf_long f1;
|
||||
fe.l = EFtoF(efp);
|
||||
#ifdef _X86_
|
||||
f1.l = f;
|
||||
#else
|
||||
f1.f = f;
|
||||
#endif
|
||||
fe.f = fe.f - f1.f;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, fe.l );
|
||||
#else
|
||||
FtoEF( efp, fe.f );
|
||||
#endif
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
FLOATOBJ_SubLong(
|
||||
IN OUT PFLOATOBJ pf,
|
||||
IN LONG l
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_852f.htm
|
||||
EFLOAT_S * efp = (EFLOAT_S *)pf;
|
||||
gxf_long f;
|
||||
f.l = EFtoF(efp);
|
||||
f.f = f.f - l;
|
||||
#ifdef _X86_
|
||||
FtoEF( efp, f.l );
|
||||
#else
|
||||
FtoEF( efp, f.f );
|
||||
#endif
|
||||
}
|
||||
|
@ -3,26 +3,17 @@
|
||||
|
||||
#include <include/dc.h>
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
IntDPtoLP ( PDC dc, LPPOINT Points, INT Count );
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
CoordDPtoLP ( PDC Dc, LPPOINT Point );
|
||||
#define IntDPtoLP(dc, pp, c) XFORMOBJ_bApplyXform((XFORMOBJ*)&(dc)->DcLevel.mxDeviceToWorld, XF_LTOL, c, pp, pp);
|
||||
#define IntLPtoDP(dc, pp, c) XFORMOBJ_bApplyXform((XFORMOBJ*)&(dc)->DcLevel.mxWorldToDevice, XF_LTOL, c, pp, pp);
|
||||
#define CoordDPtoLP(dc, pp) XFORMOBJ_bApplyXform((XFORMOBJ*)&(dc)->DcLevel.mxDeviceToWorld, XF_LTOL, 1, pp, pp);
|
||||
#define CoordLPtoDP(dc, pp) XFORMOBJ_bApplyXform((XFORMOBJ*)&(dc)->DcLevel.mxWorldToDevice, XF_LTOL, 1, pp, pp);
|
||||
#define XForm2MatrixS(m, x) XFORMOBJ_iSetXform((XFORMOBJ*)m, (XFORML*)x)
|
||||
#define MatrixS2XForm(x, m) XFORMOBJ_iGetXform((XFORMOBJ*)m, (XFORML*)x)
|
||||
|
||||
int
|
||||
FASTCALL
|
||||
IntGetGraphicsMode ( PDC dc );
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
CoordLPtoDP ( PDC Dc, LPPOINT Point );
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
IntLPtoDP ( PDC dc, LPPOINT Points, INT Count );
|
||||
|
||||
int STDCALL IntGdiSetMapMode(PDC, int);
|
||||
|
||||
BOOL
|
||||
|
@ -77,17 +77,17 @@ typedef struct _DCLEVEL
|
||||
BOOL ufiSet;
|
||||
FLONG fl;
|
||||
FLONG flBrush;
|
||||
MATRIX_S mxWorldToDevice;
|
||||
MATRIX_S mxDeviceToWorld;
|
||||
MATRIX_S mxWorldToPage;
|
||||
EFLOAT_S efM11PtoD;
|
||||
EFLOAT_S efM22PtoD;
|
||||
EFLOAT_S efDxPtoD;
|
||||
EFLOAT_S efDyPtoD;
|
||||
EFLOAT_S efM11_TWIPS;
|
||||
EFLOAT_S efM22_TWIPS;
|
||||
EFLOAT_S efPr11;
|
||||
EFLOAT_S efPr22;
|
||||
MATRIX mxWorldToDevice;
|
||||
MATRIX mxDeviceToWorld;
|
||||
MATRIX mxWorldToPage;
|
||||
FLOATOBJ efM11PtoD;
|
||||
FLOATOBJ efM22PtoD;
|
||||
FLOATOBJ efDxPtoD;
|
||||
FLOATOBJ efDyPtoD;
|
||||
FLOATOBJ efM11_TWIPS;
|
||||
FLOATOBJ efM22_TWIPS;
|
||||
FLOATOBJ efPr11;
|
||||
FLOATOBJ efPr22;
|
||||
PBITMAPOBJ pSurface; // SURFACE*
|
||||
SIZE sizl;
|
||||
} DCLEVEL, *PDCLEVEL;
|
||||
|
73
reactos/subsystems/win32/win32k/include/floatobj.h
Normal file
73
reactos/subsystems/win32/win32k/include/floatobj.h
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef _WIN32K_FLOATOBJ_H_
|
||||
#define _WIN32K_FLOATOBJ_H_
|
||||
|
||||
#if defined(_X86_)
|
||||
|
||||
FORCEINLINE
|
||||
BOOL
|
||||
_FLOATOBJ_Equal(FLOATOBJ *pf1, FLOATOBJ *pf2)
|
||||
{
|
||||
EFLOAT_S *pef1 = (EFLOAT_S*)pf1;
|
||||
EFLOAT_S *pef2 = (EFLOAT_S*)pf2;
|
||||
return (pef1->lMant == pef2->lMant && pef1->lExp == pef2->lExp);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
LONG
|
||||
_FLOATOBJ_GetLong(FLOATOBJ *pf)
|
||||
{
|
||||
EFLOAT_S *pef = (EFLOAT_S*)pf;
|
||||
return pef->lMant >> (32 - pef->lExp);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
LONG
|
||||
_FLOATOBJ_GetFix(FLOATOBJ *pf)
|
||||
{
|
||||
EFLOAT_S *pef = (EFLOAT_S*)pf;
|
||||
LONG Shift = (28 - pef->lExp);
|
||||
return (Shift >= 0 ? pef->lMant >> Shift : pef->lMant << -Shift);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOL
|
||||
_FLOATOBJ_IsLong(FLOATOBJ *pf)
|
||||
{
|
||||
EFLOAT_S *pef = (EFLOAT_S*)pf;
|
||||
ULONG Shift = 32 - pef->lExp;
|
||||
return (((pef->lMant >> Shift) << Shift) == pef->lMant);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOL
|
||||
_FLOATOBJ_Equal0(FLOATOBJ *pf)
|
||||
{
|
||||
EFLOAT_S *pef = (EFLOAT_S*)pf;
|
||||
return (pef->lMant == 0 && pef->lExp == 0);
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
BOOL
|
||||
_FLOATOBJ_Equal1(FLOATOBJ *pf)
|
||||
{
|
||||
EFLOAT_S *pef = (EFLOAT_S*)pf;
|
||||
return (pef->lMant == 0x40000000 && pef->lExp == 2);
|
||||
}
|
||||
|
||||
#define FLOATOBJ_Set0(fo) (fo)->ul1 = 0; (fo)->ul2 = 0;
|
||||
#define FLOATOBJ_Set1(fo) (fo)->ul1 = 0x40000000; (fo)->ul2 = 2;
|
||||
|
||||
#else
|
||||
|
||||
#define _FLOATOBJ_Equal(pf,pf1) (*(pf) == *(pf1))
|
||||
#define _FLOATOBJ_GetLong(pf) ((LONG)*(pf))
|
||||
#define _FLOATOBJ_IsLong(pf) ((FLOAT)((LONG)*(pf)) == *(pf))
|
||||
#define _FLOATOBJ_Equal0(pf) (*(pf) == 0.)
|
||||
#define _FLOATOBJ_Equal1(pf) (*(pf) == 1.)
|
||||
|
||||
#define FLOATOBJ_Set0(fo) *(fo) = 0;
|
||||
#define FLOATOBJ_Set1(fo) *(fo) = 1;
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* not _WIN32K_FLOATOBJ_H_ */
|
@ -24,9 +24,8 @@ static __inline INT GDI_ROUND(FLOAT val)
|
||||
}
|
||||
|
||||
|
||||
VOID FASTCALL XForm2MatrixS( MATRIX_S *, PXFORM);
|
||||
VOID FASTCALL MatrixS2XForm( PXFORM, MATRIX_S *);
|
||||
/* Performs a world-to-viewport transformation on the specified point (which
|
||||
/* FIXME: Do not use the fpu in kernel on x86, use FLOATOBJ_Xxx api instead
|
||||
* Performs a world-to-viewport transformation on the specified point (which
|
||||
* is in floating point format).
|
||||
*/
|
||||
static __inline void INTERNAL_LPTODP_FLOAT(DC *dc, FLOAT_POINT *point)
|
||||
|
@ -12,8 +12,6 @@
|
||||
#define INTERNAL_CALL NTAPI
|
||||
|
||||
/* Internal Win32k Headers */
|
||||
#include <include/driver.h>
|
||||
|
||||
#include <include/accelerator.h>
|
||||
#include <include/clipboard.h>
|
||||
#include <include/cliprgn.h>
|
||||
@ -29,13 +27,16 @@
|
||||
#include <include/dc.h>
|
||||
#include <include/dce.h>
|
||||
#include <include/dib.h>
|
||||
#include <include/driver.h>
|
||||
#include <include/error.h>
|
||||
#include <include/floatobj.h>
|
||||
#include <include/gdiobj.h>
|
||||
#include <include/palette.h>
|
||||
#include <include/rect.h>
|
||||
#include <include/win32.h>
|
||||
#include <include/window.h>
|
||||
#include <include/winsta.h>
|
||||
#include <include/xformobj.h>
|
||||
|
||||
#include <include/region.h>
|
||||
#include <include/ntuser.h>
|
||||
@ -74,4 +75,5 @@
|
||||
#include <eng/objects.h>
|
||||
#include <eng/misc.h>
|
||||
#include <dib/dib.h>
|
||||
|
||||
#endif /* __WIN32K_H */
|
||||
|
31
reactos/subsystems/win32/win32k/include/xformobj.h
Normal file
31
reactos/subsystems/win32/win32k/include/xformobj.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef _WIN32K_XFORMOBJ_H_
|
||||
#define _WIN32K_XFORMOBJ_H_
|
||||
|
||||
ULONG
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_iSetXform(
|
||||
OUT XFORMOBJ *pxo,
|
||||
IN XFORML * pxform);
|
||||
|
||||
ULONG
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_iCombine(
|
||||
IN XFORMOBJ *pxo,
|
||||
IN XFORMOBJ *pxo1,
|
||||
IN XFORMOBJ *pxo2);
|
||||
|
||||
ULONG
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_iCombineXform(
|
||||
IN XFORMOBJ *pxo,
|
||||
IN XFORMOBJ *pxo1,
|
||||
IN XFORML *pxform,
|
||||
IN BOOL bLeftMultiply);
|
||||
|
||||
ULONG
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_Inverse(
|
||||
OUT XFORMOBJ *pxoDst,
|
||||
IN XFORMOBJ *pxoSrc);
|
||||
|
||||
#endif /* not _WIN32K_XFORMOBJ_H_ */
|
@ -116,33 +116,6 @@ BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
|
||||
return Ret;
|
||||
}
|
||||
|
||||
VOID FASTCALL
|
||||
CoordDPtoLP(PDC Dc, LPPOINT Point)
|
||||
{
|
||||
FLOAT x, y;
|
||||
x = (FLOAT)Point->x;
|
||||
y = (FLOAT)Point->y;
|
||||
XFORM xformVport2World;
|
||||
|
||||
MatrixS2XForm(&xformVport2World, &Dc->DcLevel.mxDeviceToWorld);
|
||||
|
||||
Point->x = x * xformVport2World.eM11 +
|
||||
y * xformVport2World.eM21 + xformVport2World.eDx;
|
||||
Point->y = x * xformVport2World.eM12 +
|
||||
y * xformVport2World.eM22 + xformVport2World.eDy;
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
IntDPtoLP ( PDC dc, LPPOINT Points, INT Count )
|
||||
{
|
||||
INT i;
|
||||
|
||||
ASSERT ( Points );
|
||||
|
||||
for ( i = 0; i < Count; i++ )
|
||||
CoordDPtoLP ( dc, &Points[i] );
|
||||
}
|
||||
|
||||
int
|
||||
FASTCALL
|
||||
@ -245,38 +218,6 @@ NtGdiGetTransform(HDC hDC,
|
||||
return NT_SUCCESS(Status);
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
CoordLPtoDP ( PDC Dc, LPPOINT Point )
|
||||
{
|
||||
FLOAT x, y;
|
||||
XFORM xformWorld2Vport;
|
||||
|
||||
ASSERT(Dc);
|
||||
ASSERT(Point);
|
||||
|
||||
x = (FLOAT)Point->x;
|
||||
y = (FLOAT)Point->y;
|
||||
|
||||
MatrixS2XForm(&xformWorld2Vport, &Dc->DcLevel.mxWorldToDevice);
|
||||
|
||||
Point->x = x * xformWorld2Vport.eM11 +
|
||||
y * xformWorld2Vport.eM21 + xformWorld2Vport.eDx;
|
||||
Point->y = x * xformWorld2Vport.eM12 +
|
||||
y * xformWorld2Vport.eM22 + xformWorld2Vport.eDy;
|
||||
}
|
||||
|
||||
VOID
|
||||
FASTCALL
|
||||
IntLPtoDP ( PDC dc, LPPOINT Points, INT Count )
|
||||
{
|
||||
INT i;
|
||||
|
||||
ASSERT ( Points );
|
||||
|
||||
for ( i = 0; i < Count; i++ )
|
||||
CoordLPtoDP ( dc, &Points[i] );
|
||||
}
|
||||
|
||||
/*!
|
||||
* Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
|
||||
|
525
reactos/subsystems/win32/win32k/objects/xformobj.c
Normal file
525
reactos/subsystems/win32/win32k/objects/xformobj.c
Normal file
@ -0,0 +1,525 @@
|
||||
/*
|
||||
* PROJECT: ReactOS win32 kernel mode subsystem
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: subsystems/win32/win32k/objects/xformobj.c
|
||||
* PURPOSE: XFORMOBJ api
|
||||
* PROGRAMMER: Timo Kreuzer
|
||||
*/
|
||||
|
||||
/** Includes ******************************************************************/
|
||||
|
||||
#include <w32k.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
C_ASSERT(sizeof(FIX) == sizeof(LONG));
|
||||
#define FIX2LONG(x) ((x) >> 4)
|
||||
#define LONG2FIX(x) ((x) << 4)
|
||||
|
||||
#define FLOATOBJ_Equal _FLOATOBJ_Equal
|
||||
#define FLOATOBJ_GetLong _FLOATOBJ_GetLong
|
||||
#define FLOATOBJ_GetFix _FLOATOBJ_GetFix
|
||||
#define FLOATOBJ_IsLong _FLOATOBJ_IsLong
|
||||
#define FLOATOBJ_Equal0 _FLOATOBJ_Equal0
|
||||
#define FLOATOBJ_Equal1 _FLOATOBJ_Equal1
|
||||
|
||||
/** Inline helper functions ***************************************************/
|
||||
|
||||
/*
|
||||
* Inline helper to calculate pfo1 * pfo2 + pfo3 * pfo4
|
||||
*/
|
||||
VOID FORCEINLINE
|
||||
MulAdd(
|
||||
PFLOATOBJ pfoDest,
|
||||
PFLOATOBJ pfo1,
|
||||
PFLOATOBJ pfo2,
|
||||
PFLOATOBJ pfo3,
|
||||
PFLOATOBJ pfo4)
|
||||
{
|
||||
FLOATOBJ foTmp;
|
||||
|
||||
*pfoDest = *pfo1;
|
||||
FLOATOBJ_Mul(pfoDest, pfo2);
|
||||
foTmp = *pfo3;
|
||||
FLOATOBJ_Mul(&foTmp, pfo4);
|
||||
FLOATOBJ_Add(pfoDest, &foTmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inline helper to calculate pfo1 * l2 + pfo3 * l4
|
||||
*/
|
||||
VOID FORCEINLINE
|
||||
MulAddLong(
|
||||
PFLOATOBJ pfoDest,
|
||||
PFLOATOBJ pfo1,
|
||||
LONG l2,
|
||||
PFLOATOBJ pfo3,
|
||||
LONG l4)
|
||||
{
|
||||
FLOATOBJ foTmp;
|
||||
|
||||
*pfoDest = *pfo1;
|
||||
FLOATOBJ_MulLong(pfoDest, l2);
|
||||
foTmp = *pfo3;
|
||||
FLOATOBJ_MulLong(&foTmp, l4);
|
||||
FLOATOBJ_Add(pfoDest, &foTmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inline helper to calculate pfo1 * pfo2 - pfo3 * pfo4
|
||||
*/
|
||||
VOID FORCEINLINE
|
||||
MulSub(
|
||||
PFLOATOBJ pfoDest,
|
||||
PFLOATOBJ pfo1,
|
||||
PFLOATOBJ pfo2,
|
||||
PFLOATOBJ pfo3,
|
||||
PFLOATOBJ pfo4)
|
||||
{
|
||||
FLOATOBJ foTmp;
|
||||
|
||||
*pfoDest = *pfo1;
|
||||
FLOATOBJ_Mul(pfoDest, pfo2);
|
||||
foTmp = *pfo3;
|
||||
FLOATOBJ_Mul(&foTmp, pfo4);
|
||||
FLOATOBJ_Sub(pfoDest, &foTmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inline helper to get the complexity hint from flAccel
|
||||
*/
|
||||
ULONG FORCEINLINE
|
||||
HintFromAccel(ULONG flAccel)
|
||||
{
|
||||
switch (flAccel & (MX_NOTRANSLATE | MX_IDENTITYSCALE | MX_SCALE))
|
||||
{
|
||||
case (MX_SCALE | MX_IDENTITYSCALE | MX_NOTRANSLATE):
|
||||
return GX_IDENTITY;
|
||||
case (MX_SCALE | MX_IDENTITYSCALE):
|
||||
return GX_OFFSET;
|
||||
case MX_SCALE:
|
||||
return GX_SCALE;
|
||||
default:
|
||||
return GX_GENERAL;
|
||||
}
|
||||
}
|
||||
|
||||
/** Internal functions ********************************************************/
|
||||
|
||||
ULONG
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_UpdateAccel(
|
||||
IN XFORMOBJ *pxo)
|
||||
{
|
||||
PMATRIX pmx = (PMATRIX)pxo;
|
||||
|
||||
/* Copy Dx and Dy to FIX format */
|
||||
pmx->fxDx = FLOATOBJ_GetFix(&pmx->efDx);
|
||||
pmx->fxDy = FLOATOBJ_GetFix(&pmx->efDy);
|
||||
|
||||
pmx->flAccel = 0;
|
||||
|
||||
if (FLOATOBJ_Equal0(&pmx->efDx) &&
|
||||
FLOATOBJ_Equal0(&pmx->efDy))
|
||||
{
|
||||
pmx->flAccel |= MX_NOTRANSLATE;
|
||||
}
|
||||
|
||||
if (FLOATOBJ_Equal0(&pmx->efM12) &&
|
||||
FLOATOBJ_Equal0(&pmx->efM21))
|
||||
{
|
||||
pmx->flAccel |= MX_SCALE;
|
||||
}
|
||||
|
||||
if (FLOATOBJ_Equal1(&pmx->efM11) &&
|
||||
FLOATOBJ_Equal1(&pmx->efM22))
|
||||
{
|
||||
pmx->flAccel |= MX_IDENTITYSCALE;
|
||||
}
|
||||
|
||||
if (FLOATOBJ_IsLong(&pmx->efM11) && FLOATOBJ_IsLong(&pmx->efM12) &&
|
||||
FLOATOBJ_IsLong(&pmx->efM21) && FLOATOBJ_IsLong(&pmx->efM22))
|
||||
{
|
||||
pmx->flAccel |= MX_INTEGER;
|
||||
}
|
||||
|
||||
return HintFromAccel(pmx->flAccel);
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_iSetXform(
|
||||
OUT XFORMOBJ *pxo,
|
||||
IN XFORML * pxform)
|
||||
{
|
||||
PMATRIX pmx = (PMATRIX)pxo;
|
||||
|
||||
/* Check parameters */
|
||||
if (!pxo || !pxform)
|
||||
{
|
||||
return DDI_ERROR;
|
||||
}
|
||||
|
||||
/* Copy members */
|
||||
FLOATOBJ_SetFloat(&pmx->efM11, pxform->eM11);
|
||||
FLOATOBJ_SetFloat(&pmx->efM12, pxform->eM12);
|
||||
FLOATOBJ_SetFloat(&pmx->efM21, pxform->eM21);
|
||||
FLOATOBJ_SetFloat(&pmx->efM22, pxform->eM22);
|
||||
FLOATOBJ_SetFloat(&pmx->efDx, pxform->eDx);
|
||||
FLOATOBJ_SetFloat(&pmx->efDy, pxform->eDy);
|
||||
|
||||
/* Update accelerators and return complexity */
|
||||
return XFORMOBJ_UpdateAccel(pxo);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Multiplies pxo1 with pxo2 and stores the result in pxo.
|
||||
* returns complexity hint
|
||||
* | efM11 efM12 0 |
|
||||
* | efM21 efM22 0 |
|
||||
* | efDx efDy 1 |
|
||||
*/
|
||||
ULONG
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_iCombine(
|
||||
IN XFORMOBJ *pxo,
|
||||
IN XFORMOBJ *pxo1,
|
||||
IN XFORMOBJ *pxo2)
|
||||
{
|
||||
MATRIX mx;
|
||||
PMATRIX pmx, pmx1, pmx2;
|
||||
|
||||
pmx = (PMATRIX)pxo;
|
||||
pmx1 = (PMATRIX)pxo1;
|
||||
pmx2 = (PMATRIX)pxo2;
|
||||
|
||||
/* Do a 3 x 3 matrix multiplication with mx as destinantion */
|
||||
MulAdd(&mx.efM11, &pmx1->efM11, &pmx2->efM11, &pmx1->efM12, &pmx2->efM21);
|
||||
MulAdd(&mx.efM12, &pmx1->efM11, &pmx2->efM12, &pmx1->efM12, &pmx2->efM22);
|
||||
MulAdd(&mx.efM21, &pmx1->efM21, &pmx2->efM11, &pmx1->efM22, &pmx2->efM21);
|
||||
MulAdd(&mx.efM22, &pmx1->efM21, &pmx2->efM12, &pmx1->efM22, &pmx2->efM22);
|
||||
MulAdd(&mx.efDx, &pmx1->efDx, &pmx2->efM11, &pmx1->efDy, &pmx2->efM21);
|
||||
FLOATOBJ_Add(&mx.efDx, &pmx2->efDx);
|
||||
MulAdd(&mx.efDy, &pmx1->efDx, &pmx2->efM12, &pmx1->efDy, &pmx2->efM22);
|
||||
FLOATOBJ_Add(&mx.efDy, &pmx2->efDy);
|
||||
|
||||
/* Copy back */
|
||||
*pmx = mx;
|
||||
|
||||
/* Update accelerators and return complexity */
|
||||
return XFORMOBJ_UpdateAccel(pxo);
|
||||
}
|
||||
|
||||
|
||||
ULONG
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_iCombineXform(
|
||||
IN XFORMOBJ *pxo,
|
||||
IN XFORMOBJ *pxo1,
|
||||
IN XFORML *pxform,
|
||||
IN BOOL bLeftMultiply)
|
||||
{
|
||||
MATRIX mx;
|
||||
XFORMOBJ *pxo2 = (XFORMOBJ*)&mx;
|
||||
|
||||
XFORMOBJ_iSetXform(pxo2, pxform);
|
||||
|
||||
if (bLeftMultiply)
|
||||
{
|
||||
return XFORMOBJ_iCombine(pxo, pxo2, pxo1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return XFORMOBJ_iCombine(pxo, pxo1, pxo2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* A^-1 = adj(A) / det(AT)
|
||||
* A^-1 = 1/(a*d - b*c) * (a22,-a12,a21,-a11)
|
||||
*/
|
||||
ULONG
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_Inverse(
|
||||
OUT XFORMOBJ *pxoDst,
|
||||
IN XFORMOBJ *pxoSrc)
|
||||
{
|
||||
PMATRIX pmxDst, pmxSrc;
|
||||
FLOATOBJ foDet;
|
||||
|
||||
pmxDst = (PMATRIX)pxoDst;
|
||||
pmxSrc = (PMATRIX)pxoSrc;
|
||||
|
||||
/* det = M11 * M22 - M12 * M21 */
|
||||
MulSub(&foDet, &pmxSrc->efM11, &pmxSrc->efM22, &pmxSrc->efM12, &pmxSrc->efM21);
|
||||
|
||||
if (FLOATOBJ_Equal0(&foDet))
|
||||
{
|
||||
/* Determinant is 0! */
|
||||
return DDI_ERROR;
|
||||
}
|
||||
|
||||
/* Calculate adj(A) / det(A) */
|
||||
pmxDst->efM11 = pmxSrc->efM22;
|
||||
FLOATOBJ_Div(&pmxDst->efM11, &foDet);
|
||||
pmxDst->efM22 = pmxSrc->efM11;
|
||||
FLOATOBJ_Div(&pmxDst->efM22, &foDet);
|
||||
|
||||
/* The other 2 are negative, negate foDet for that */
|
||||
FLOATOBJ_Neg(&foDet);
|
||||
pmxDst->efM12 = pmxSrc->efM21;
|
||||
FLOATOBJ_Div(&pmxDst->efM12, &foDet);
|
||||
pmxDst->efM21 = pmxSrc->efM12;
|
||||
FLOATOBJ_Div(&pmxDst->efM22, &foDet);
|
||||
|
||||
/* Update accelerators and return complexity */
|
||||
return XFORMOBJ_UpdateAccel(pxoDst);
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
INTERNAL_CALL
|
||||
XFORMOBJ_bXformFixPoints(
|
||||
IN XFORMOBJ *pxo,
|
||||
IN ULONG cPoints,
|
||||
IN PPOINTL pptIn,
|
||||
OUT PPOINTL pptOut)
|
||||
{
|
||||
PMATRIX pmx;
|
||||
INT i;
|
||||
FLOATOBJ fo1, fo2;
|
||||
FLONG flAccel;
|
||||
|
||||
pmx = (PMATRIX)pxo;
|
||||
flAccel = pmx->flAccel & (MX_INTEGER|MX_SCALE|MX_IDENTITYSCALE);
|
||||
|
||||
switch (flAccel)
|
||||
{
|
||||
case (MX_SCALE | MX_IDENTITYSCALE):
|
||||
case (MX_SCALE | MX_IDENTITYSCALE | MX_INTEGER):
|
||||
/* Identity transformation, nothing todo */
|
||||
break;
|
||||
|
||||
case (MX_IDENTITYSCALE | MX_INTEGER):
|
||||
/* 1-scale integer transform */
|
||||
i = cPoints - 1;
|
||||
do
|
||||
{
|
||||
LONG x = pptIn[i].x + pptIn[i].y * FLOATOBJ_GetLong(&pmx->efM21);
|
||||
LONG y = pptIn[i].y + pptIn[i].x * FLOATOBJ_GetLong(&pmx->efM12);
|
||||
pptOut[i].y = y;
|
||||
pptOut[i].x = x;
|
||||
}
|
||||
while (--i >= 0);
|
||||
break;
|
||||
|
||||
case (MX_SCALE | MX_INTEGER):
|
||||
/* Diagonal integer transform */
|
||||
i = cPoints - 1;
|
||||
do
|
||||
{
|
||||
pptOut[i].x = pptIn[i].x * FLOATOBJ_GetLong(&pmx->efM11);
|
||||
pptOut[i].y = pptIn[i].y * FLOATOBJ_GetLong(&pmx->efM22);
|
||||
}
|
||||
while (--i >= 0);
|
||||
break;
|
||||
|
||||
case (MX_INTEGER):
|
||||
/* Full integer transform */
|
||||
i = cPoints - 1;
|
||||
do
|
||||
{
|
||||
LONG x;
|
||||
x = pptIn[i].x * FLOATOBJ_GetLong(&pmx->efM11);
|
||||
x += pptIn[i].y * FLOATOBJ_GetLong(&pmx->efM21);
|
||||
pptOut[i].y = pptIn[i].y * FLOATOBJ_GetLong(&pmx->efM22);
|
||||
pptOut[i].y += pptIn[i].x * FLOATOBJ_GetLong(&pmx->efM12);
|
||||
pptOut[i].x = x;
|
||||
}
|
||||
while (--i >= 0);
|
||||
break;
|
||||
|
||||
case (MX_IDENTITYSCALE):
|
||||
/* 1-scale transform */
|
||||
i = cPoints - 1;
|
||||
do
|
||||
{
|
||||
fo1 = pmx->efM21;
|
||||
FLOATOBJ_MulLong(&fo1, pptIn[i].y);
|
||||
fo2 = pmx->efM12;
|
||||
FLOATOBJ_MulLong(&fo2, pptIn[i].x);
|
||||
pptOut[i].x = pptIn[i].x + FLOATOBJ_GetLong(&fo1);
|
||||
pptOut[i].y = pptIn[i].y + FLOATOBJ_GetLong(&fo2);
|
||||
}
|
||||
while (--i >= 0);
|
||||
break;
|
||||
|
||||
case (MX_SCALE):
|
||||
/* Diagonal float transform */
|
||||
i = cPoints - 1;
|
||||
do
|
||||
{
|
||||
fo1 = pmx->efM11;
|
||||
FLOATOBJ_MulLong(&fo1, pptIn[i].x);
|
||||
pptOut[i].x = FLOATOBJ_GetLong(&fo1);
|
||||
fo2 = pmx->efM22;
|
||||
FLOATOBJ_MulLong(&fo2, pptIn[i].y);
|
||||
pptOut[i].y = FLOATOBJ_GetLong(&fo2);
|
||||
}
|
||||
while (--i >= 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Full float transform */
|
||||
i = cPoints - 1;
|
||||
do
|
||||
{
|
||||
MulAddLong(&fo1, &pmx->efM11, pptIn[i].x, &pmx->efM21, pptIn[i].y);
|
||||
MulAddLong(&fo2, &pmx->efM12, pptIn[i].x, &pmx->efM22, pptIn[i].y);
|
||||
pptOut[i].x = FLOATOBJ_GetLong(&fo1);
|
||||
pptOut[i].y = FLOATOBJ_GetLong(&fo2);
|
||||
}
|
||||
while (--i >= 0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(pmx->flAccel & MX_NOTRANSLATE))
|
||||
{
|
||||
/* Translate points */
|
||||
i = cPoints - 1;
|
||||
do
|
||||
{
|
||||
// DPRINT1("Translating Points (%d,%d)->(%d,%d)\n", pptOut[i].x, pptOut[i].y, pptOut[i].x + pmx->fxDx, pptOut[i].y + pmx->fxDy);
|
||||
pptOut[i].x += pmx->fxDx;
|
||||
pptOut[i].y += pmx->fxDy;
|
||||
}
|
||||
while (--i >= 0);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** Public functions **********************************************************/
|
||||
|
||||
// www.osr.com/ddk/graphics/gdifncs_0s2v.htm
|
||||
ULONG
|
||||
NTAPI
|
||||
XFORMOBJ_iGetXform(
|
||||
IN XFORMOBJ *pxo,
|
||||
OUT XFORML *pxform)
|
||||
{
|
||||
PMATRIX pmx = (PMATRIX)pxo;
|
||||
|
||||
/* Check parameters */
|
||||
if (!pxo || !pxform)
|
||||
{
|
||||
return DDI_ERROR;
|
||||
}
|
||||
|
||||
/* Copy members */
|
||||
pxform->eM11 = FLOATOBJ_GetFloat(&pmx->efM11);
|
||||
pxform->eM12 = FLOATOBJ_GetFloat(&pmx->efM12);
|
||||
pxform->eM21 = FLOATOBJ_GetFloat(&pmx->efM21);
|
||||
pxform->eM22 = FLOATOBJ_GetFloat(&pmx->efM22);
|
||||
pxform->eDx = FLOATOBJ_GetFloat(&pmx->efDx);
|
||||
pxform->eDy = FLOATOBJ_GetFloat(&pmx->efDy);
|
||||
|
||||
/* Return complexity hint */
|
||||
return HintFromAccel(pmx->flAccel);
|
||||
}
|
||||
|
||||
|
||||
// www.osr.com/ddk/graphics/gdifncs_5ig7.htm
|
||||
ULONG
|
||||
NTAPI
|
||||
XFORMOBJ_iGetFloatObjXform(
|
||||
IN XFORMOBJ *pxo,
|
||||
OUT FLOATOBJ_XFORM *pxfo)
|
||||
{
|
||||
PMATRIX pmx = (PMATRIX)pxo;
|
||||
|
||||
/* Check parameters */
|
||||
if (!pxo || !pxfo)
|
||||
{
|
||||
return DDI_ERROR;
|
||||
}
|
||||
|
||||
/* Copy members */
|
||||
pxfo->eM11 = pmx->efM11;
|
||||
pxfo->eM12 = pmx->efM12;
|
||||
pxfo->eM21 = pmx->efM21;
|
||||
pxfo->eM22 = pmx->efM22;
|
||||
pxfo->eDx = pmx->efDx;
|
||||
pxfo->eDy = pmx->efDy;
|
||||
|
||||
/* Return complexity hint */
|
||||
return HintFromAccel(pmx->flAccel);
|
||||
}
|
||||
|
||||
|
||||
// www.osr.com/ddk/graphics/gdifncs_027b.htm
|
||||
BOOL
|
||||
NTAPI
|
||||
XFORMOBJ_bApplyXform(
|
||||
IN XFORMOBJ *pxo,
|
||||
IN ULONG iMode,
|
||||
IN ULONG cPoints,
|
||||
IN PVOID pvIn,
|
||||
OUT PVOID pvOut)
|
||||
{
|
||||
MATRIX mx;
|
||||
POINTL *pptl;
|
||||
INT i;
|
||||
|
||||
/* Check parameters */
|
||||
if (!pxo || !pvIn || !pvOut || cPoints < 1)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Use inverse xform? */
|
||||
if (iMode == XF_INV_FXTOL || iMode == XF_INV_LTOL)
|
||||
{
|
||||
ULONG ret;
|
||||
ret = XFORMOBJ_Inverse((XFORMOBJ*)&mx, pxo);
|
||||
if (ret == DDI_ERROR)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
pxo = (XFORMOBJ*)&mx;
|
||||
}
|
||||
|
||||
/* Convert POINTL to POINTFIX? */
|
||||
if (iMode == XF_LTOFX || iMode == XF_LTOL || iMode == XF_INV_LTOL)
|
||||
{
|
||||
pptl = pvIn;
|
||||
for (i = cPoints - 1; i >= 0; i--)
|
||||
{
|
||||
pptl[i].x = LONG2FIX(pptl[i].x);
|
||||
pptl[i].y = LONG2FIX(pptl[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
/* Do the actual fixpoint transformation */
|
||||
if (!XFORMOBJ_bXformFixPoints(pxo, cPoints, pvIn, pvOut))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Convert POINTFIX to POINTL? */
|
||||
if (iMode == XF_INV_FXTOL || iMode == XF_INV_LTOL || iMode == XF_LTOL)
|
||||
{
|
||||
pptl = pvOut;
|
||||
for (i = cPoints - 1; i >= 0; i--)
|
||||
{
|
||||
pptl[i].x = FIX2LONG(pptl[i].x);
|
||||
pptl[i].y = FIX2LONG(pptl[i].y);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* EOF */
|
@ -736,45 +736,6 @@ PATHOBJ_vGetBounds(
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
BOOL
|
||||
APIENTRY
|
||||
XFORMOBJ_bApplyXform(
|
||||
IN XFORMOBJ *pxo,
|
||||
IN ULONG iMode,
|
||||
IN ULONG cPoints,
|
||||
IN PVOID pvIn,
|
||||
OUT PVOID pvOut
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_027b.htm
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ULONG
|
||||
APIENTRY
|
||||
XFORMOBJ_iGetFloatObjXform(
|
||||
IN XFORMOBJ *pxo,
|
||||
OUT FLOATOBJ_XFORM *pxfo
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_5ig7.htm
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONG
|
||||
APIENTRY
|
||||
XFORMOBJ_iGetXform(
|
||||
IN XFORMOBJ *pxo,
|
||||
OUT XFORML *pxform
|
||||
)
|
||||
{
|
||||
// www.osr.com/ddk/graphics/gdifncs_0s2v.htm
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
@ -53,6 +53,11 @@
|
||||
<file>error.c</file>
|
||||
<file>event.c</file>
|
||||
<file>float.c</file>
|
||||
<if property="ARCH" value="i386">
|
||||
<directory name="i386">
|
||||
<file>floatobj.S</file>
|
||||
</directory>
|
||||
</if>
|
||||
<file>gradient.c</file>
|
||||
<file>lineto.c</file>
|
||||
<file>mem.c</file>
|
||||
@ -82,7 +87,7 @@
|
||||
<file>copy.c</file>
|
||||
<file>usrheap.c</file>
|
||||
<if property="ARCH" value="i386">
|
||||
<directory name="i386">
|
||||
<directory name="i386">
|
||||
<file>cos_asm.s</file>
|
||||
<file>sin_asm.s</file>
|
||||
<file>atan2_asm.s</file>
|
||||
@ -173,6 +178,7 @@
|
||||
<file>stockobj.c</file>
|
||||
<file>text.c</file>
|
||||
<file>wingl.c</file>
|
||||
<file>xformobj.c</file>
|
||||
</directory>
|
||||
<directory name="stubs">
|
||||
<file>stubs.c</file>
|
||||
|
Loading…
Reference in New Issue
Block a user