diff --git a/reactos/include/reactos/win32k/ntgdihdl.h b/reactos/include/reactos/win32k/ntgdihdl.h index e38622c3635..f30b0c397d8 100644 --- a/reactos/include/reactos/win32k/ntgdihdl.h +++ b/reactos/include/reactos/win32k/ntgdihdl.h @@ -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; diff --git a/reactos/subsystems/win32/win32k/eng/float.c b/reactos/subsystems/win32/win32k/eng/float.c index 0d348dbd8b0..aa080ab9896 100644 --- a/reactos/subsystems/win32/win32k/eng/float.c +++ b/reactos/subsystems/win32/win32k/eng/float.c @@ -33,30 +33,6 @@ #define NDEBUG #include -/* 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 -} diff --git a/reactos/subsystems/win32/win32k/include/coord.h b/reactos/subsystems/win32/win32k/include/coord.h index 5f69aaeb5c8..89c317e0311 100644 --- a/reactos/subsystems/win32/win32k/include/coord.h +++ b/reactos/subsystems/win32/win32k/include/coord.h @@ -3,26 +3,17 @@ #include -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 diff --git a/reactos/subsystems/win32/win32k/include/dc.h b/reactos/subsystems/win32/win32k/include/dc.h index 2d8700df985..fcda0637fad 100644 --- a/reactos/subsystems/win32/win32k/include/dc.h +++ b/reactos/subsystems/win32/win32k/include/dc.h @@ -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; diff --git a/reactos/subsystems/win32/win32k/include/floatobj.h b/reactos/subsystems/win32/win32k/include/floatobj.h new file mode 100644 index 00000000000..631ec8f0cdc --- /dev/null +++ b/reactos/subsystems/win32/win32k/include/floatobj.h @@ -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_ */ diff --git a/reactos/subsystems/win32/win32k/include/gdifloat.h b/reactos/subsystems/win32/win32k/include/gdifloat.h index dabef3beb56..15081a526ed 100644 --- a/reactos/subsystems/win32/win32k/include/gdifloat.h +++ b/reactos/subsystems/win32/win32k/include/gdifloat.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) diff --git a/reactos/subsystems/win32/win32k/include/win32k.h b/reactos/subsystems/win32/win32k/include/win32k.h index a2f3c7cb32c..95423ad799b 100644 --- a/reactos/subsystems/win32/win32k/include/win32k.h +++ b/reactos/subsystems/win32/win32k/include/win32k.h @@ -12,8 +12,6 @@ #define INTERNAL_CALL NTAPI /* Internal Win32k Headers */ -#include - #include #include #include @@ -29,13 +27,16 @@ #include #include #include +#include #include +#include #include #include #include #include #include #include +#include #include #include @@ -74,4 +75,5 @@ #include #include #include + #endif /* __WIN32K_H */ diff --git a/reactos/subsystems/win32/win32k/include/xformobj.h b/reactos/subsystems/win32/win32k/include/xformobj.h new file mode 100644 index 00000000000..5daf643a69d --- /dev/null +++ b/reactos/subsystems/win32/win32k/include/xformobj.h @@ -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_ */ diff --git a/reactos/subsystems/win32/win32k/objects/coord.c b/reactos/subsystems/win32/win32k/objects/coord.c index bc4cc602562..7c673d0f896 100644 --- a/reactos/subsystems/win32/win32k/objects/coord.c +++ b/reactos/subsystems/win32/win32k/objects/coord.c @@ -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, diff --git a/reactos/subsystems/win32/win32k/objects/xformobj.c b/reactos/subsystems/win32/win32k/objects/xformobj.c new file mode 100644 index 00000000000..53697ccc3b7 --- /dev/null +++ b/reactos/subsystems/win32/win32k/objects/xformobj.c @@ -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 +#define NDEBUG +#include + +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 */ diff --git a/reactos/subsystems/win32/win32k/stubs/stubs.c b/reactos/subsystems/win32/win32k/stubs/stubs.c index 2851bbc50c2..c662f170356 100644 --- a/reactos/subsystems/win32/win32k/stubs/stubs.c +++ b/reactos/subsystems/win32/win32k/stubs/stubs.c @@ -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 */ diff --git a/reactos/subsystems/win32/win32k/win32k.rbuild b/reactos/subsystems/win32/win32k/win32k.rbuild index bc25e040634..413cdc26514 100644 --- a/reactos/subsystems/win32/win32k/win32k.rbuild +++ b/reactos/subsystems/win32/win32k/win32k.rbuild @@ -53,6 +53,11 @@ error.c event.c float.c + + + floatobj.S + + gradient.c lineto.c mem.c @@ -82,7 +87,7 @@ copy.c usrheap.c - + cos_asm.s sin_asm.s atan2_asm.s @@ -173,6 +178,7 @@ stockobj.c text.c wingl.c + xformobj.c stubs.c