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:
Timo Kreuzer 2008-08-30 01:01:52 +00:00
parent 46cc92b9b6
commit dcae209a08
12 changed files with 666 additions and 683 deletions

View file

@ -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;

View file

@ -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
}

View file

@ -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

View file

@ -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;

View 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_ */

View file

@ -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)

View file

@ -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 */

View 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_ */

View file

@ -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,

View 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 */

View file

@ -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
*/

View file

@ -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>