Author: tkreuzer Date: Sat Jan 8 19:06:38 2011 New Revision: 50330
URL: http://svn.reactos.org/svn/reactos?rev=50330&view=rev Log: [GDI32] - Move EFLOAT handling in seperate file, its x86 specific - Implement CombineTransform fully in usermode instead of forwarding to NtGdiCombineTransform - Implement MatrixToXForm - Implement GdiTransformPoints
Added: trunk/reactos/dll/win32/gdi32/objects/efloat.c (with props) Modified: trunk/reactos/dll/win32/gdi32/gdi32.rbuild trunk/reactos/dll/win32/gdi32/gdi32.spec trunk/reactos/dll/win32/gdi32/include/gdi32p.h trunk/reactos/dll/win32/gdi32/objects/coord.c
Modified: trunk/reactos/dll/win32/gdi32/gdi32.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/gdi32.rbuil... ============================================================================== --- trunk/reactos/dll/win32/gdi32/gdi32.rbuild [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdi32/gdi32.rbuild [iso-8859-1] Sat Jan 8 19:06:38 2011 @@ -31,6 +31,9 @@ <file>brush.c</file> <file>coord.c</file> <file>dc.c</file> + <if property="ARCH" value="i386"> + <file>efloat.c</file> + </if> <file>eng.c</file> <file>enhmfile.c</file> <file>font.c</file>
Modified: trunk/reactos/dll/win32/gdi32/gdi32.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/gdi32.spec?... ============================================================================== --- trunk/reactos/dll/win32/gdi32/gdi32.spec [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdi32/gdi32.spec [iso-8859-1] Sat Jan 8 19:06:38 2011 @@ -32,7 +32,7 @@ @ stdcall ColorCorrectPalette(ptr ptr long long) @ stdcall ColorMatchToTarget(ptr ptr long) @ stdcall CombineRgn(long long long long) -@ stdcall CombineTransform(ptr ptr ptr) NtGdiCombineTransform +@ stdcall CombineTransform(ptr ptr ptr) @ stdcall CopyEnhMetaFileA(long str) @ stdcall CopyEnhMetaFileW(long wstr) @ stdcall CopyMetaFileA(long str) @@ -285,7 +285,7 @@ @ stdcall GdiEntry9(ptr ptr ptr ptr ptr ptr) @ stdcall GdiFixUpHandle(ptr) @ stdcall GdiFlush() -@ stdcall GdiFullscreenControl(ptr ptr long ptr ptr) NtGdiFullscreenControl +@ stdcall GdiFullscreenControl(ptr ptr long ptr ptr) NtGdiFullscreenControl @ stdcall GdiGetBatchLimit() @ stdcall GdiGetBitmapBitsSize(ptr) @ stdcall GdiGetCharDimensions(long ptr ptr) @@ -299,7 +299,7 @@ @ stdcall GdiGetPageHandle(ptr long ptr) @ stdcall GdiGetSpoolFileHandle(wstr ptr wstr) @ stdcall GdiGetSpoolMessage(ptr long ptr long) NtGdiGetSpoolMessage -@ stdcall GdiGradientFill(long ptr long ptr long long) +@ stdcall GdiGradientFill(long ptr long ptr long long) @ stdcall GdiInitSpool() NtGdiInitSpool @ stdcall GdiInitializeLanguagePack(long) @ stdcall GdiIsMetaFileDC(long)
Modified: trunk/reactos/dll/win32/gdi32/include/gdi32p.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/include/gdi... ============================================================================== --- trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] Sat Jan 8 19:06:38 2011 @@ -292,7 +292,6 @@ BOOL FASTCALL EndPagePrinterEx(PVOID,HANDLE); BOOL FASTCALL LoadTheSpoolerDrv(VOID);
- FORCEINLINE PVOID GdiAllocBatchCommand( @@ -389,4 +388,33 @@ return pdcattr; }
+#ifdef _M_IX86 +FLOATL FASTCALL EFtoF(EFLOAT_S * efp); +#define FOtoF(pfo) EFtoF((EFLOAT_S*)pfo) +#else +#define FOtoF(pfo) (*(pfo)) +#endif + +/* This is an inlined version of lrintf. */ +FORCEINLINE +int +_lrintf(float f) +{ +#if defined(_M_IX86) && defined(__GNUC__) + int ret; + __asm__ __volatile__ ("fistpl %0" : "=m" (ret) : "t" (f) : "st"); + return ret; +#elif defined(_M_IX86) && defined(_MSC_VER) + int ret; + __asm + { + fld f; + fistp ret; + } +#else + /* slow, but portable */ + return (int)floor(x >= 0 ? x+0.5 : x-0.5); +#endif +} + /* EOF */
Modified: trunk/reactos/dll/win32/gdi32/objects/coord.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/coo... ============================================================================== --- trunk/reactos/dll/win32/gdi32/objects/coord.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdi32/objects/coord.c [iso-8859-1] Sat Jan 8 19:06:38 2011 @@ -1,145 +1,152 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS System Libraries + * FILE: dll/gdi32/objects/coord.c + * PURPOSE: Functions for coordinate transformation + * PROGRAMMER: + */ #include "precomp.h"
-/* the following deal with IEEE single-precision numbers */ -#define EXCESS 126L -#define SIGNBIT 0x80000000L -#define SIGN(fp) ((fp) & SIGNBIT) -#define EXP(fp) (((fp) >> 23L) & 0xFF) -#define MANT(fp) ((fp) & 0x7FFFFFL) -#define PACK(s,e,m) ((s) | ((e) << 23L) | (m)) - -// Sames as lrintf. -#ifdef __GNUC__ -#define FLOAT_TO_INT(in,out) \ - __asm__ __volatile__ ("fistpl %0" : "=m" (out) : "t" (in) : "st"); -#else -#define FLOAT_TO_INT(in,out) \ - __asm fld in; \ - __asm fistp out; -#endif - -LONG -FASTCALL -EFtoF( EFLOAT_S * efp) -{ - long Mant, Exp, Sign = 0; - - if (!efp->lMant) return 0; - - Mant = efp->lMant; - Exp = efp->lExp; - Sign = SIGN(Mant); - -//// M$ storage emulation - 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 FASTCALL -CoordCnvP(MATRIX_S * mx, LPPOINT Point) -{ +/* Currently we use a MATRIX inside the DC_ATTR containing the + coordinate transformations, while we deal with XFORM structures + internally. If we move all coordinate transformation to gdi32, + we might as well have an XFORM structure in the DC_ATTR. */ +void +MatrixToXForm(XFORM *pxform, const MATRIX *pmx) +{ + XFORML *pxforml = (XFORML*)pxform; + pxforml->eM11 = FOtoF(&pmx->efM11); + pxforml->eM12 = FOtoF(&pmx->efM12); + pxforml->eM21 = FOtoF(&pmx->efM21); + pxforml->eM22 = FOtoF(&pmx->efM22); + pxforml->eDx = FOtoF(&pmx->efDx); + pxforml->eDy = FOtoF(&pmx->efDy); +} + +void +GdiTransformPoints2( + XFORM *pxform, + PPOINT pptOut, + PPOINT pptIn, + ULONG nCount) +{ + ULONG i; FLOAT x, y; - gxf_long a, b, c; - - x = (FLOAT)Point->x; - y = (FLOAT)Point->y; - - a.l = EFtoF( &mx->efM11 ); - b.l = EFtoF( &mx->efM21 ); - c.l = EFtoF( &mx->efDx ); - x = x * a.f + y * b.f + c.f; - - a.l = EFtoF( &mx->efM12 ); - b.l = EFtoF( &mx->efM22 ); - c.l = EFtoF( &mx->efDy ); - y = x * a.f + y * b.f + c.f; - - FLOAT_TO_INT(x, Point->x ); - FLOAT_TO_INT(y, Point->y ); -} - - -BOOL -WINAPI -DPtoLP ( HDC hDC, LPPOINT Points, INT Count ) + + for (i = 0; i < nCount; i++) + { + x = pptIn[i].x * pxform->eM11 + pptIn[i].y * pxform->eM12 + pxform->eDx; + pptOut[i].x = _lrintf(x); + y = pptIn[i].x * pxform->eM21 + pptIn[i].y * pxform->eM22 + pxform->eDy; + pptOut[i].y = _lrintf(y); + } +} + +FORCEINLINE +void +GdiTransformPoints( + MATRIX *pmx, + PPOINT pptOut, + PPOINT pptIn, + ULONG nCount) +{ + XFORM xform; + + MatrixToXForm(&xform, pmx); + GdiTransformPoints2(&xform, pptOut, pptIn, nCount); +} + +#define MAX_OFFSET 4294967040.0 + +BOOL +WINAPI +CombineTransform( + LPXFORM pxfResult, + const XFORM *pxf1, + const XFORM *pxf2) +{ + XFORM xformTmp; + + /* Do matrix multiplication */ + xformTmp.eM11 = pxf1->eM11 * pxf2->eM11 + pxf1->eM12 * pxf2->eM21; + xformTmp.eM12 = pxf1->eM11 * pxf2->eM12 + pxf1->eM12 * pxf2->eM22; + xformTmp.eM21 = pxf1->eM21 * pxf2->eM11 + pxf1->eM22 * pxf2->eM21; + xformTmp.eM22 = pxf1->eM21 * pxf2->eM12 + pxf1->eM22 * pxf2->eM22; + xformTmp.eDx = pxf1->eDx * pxf2->eM11 + pxf1->eDy * pxf2->eM21 + pxf2->eDx; + xformTmp.eDy = pxf1->eDx * pxf2->eM12 + pxf1->eDy * pxf2->eM22 + pxf2->eDy; + + *pxfResult = xformTmp; +#if 0 + /* windows compatibility fixups (needs more work) */ + if (_isnan(xformTmp.eM12)) + { + if (pxf1->eM11 == 0 || pxf2->eM12 == 0) pxfResult->eM12 = 0.; + } +#endif + /* Check for invalid offset ranges */ + if (xformTmp.eDx > MAX_OFFSET || xformTmp.eDx < -MAX_OFFSET || + xformTmp.eDy > MAX_OFFSET || xformTmp.eDy < -MAX_OFFSET) + { + return FALSE; + } + + return TRUE; +} + +BOOL +WINAPI +DPtoLP(HDC hdc, LPPOINT lpPoints, INT nCount) { #if 0 INT i; - PDC_ATTR Dc_Attr; - - if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; - - if (Dc_Attr->flXform & ( DEVICE_TO_WORLD_INVALID | // Force a full recalibration! - PAGE_XLATE_CHANGED | // Changes or Updates have been made, - PAGE_EXTENTS_CHANGED | // do processing in kernel space. - WORLD_XFORM_CHANGED )) -#endif - return NtGdiTransformPoints( hDC, Points, Points, Count, GdiDpToLp); // DPtoLP mode. -#if 0 - else - { - for ( i = 0; i < Count; i++ ) - CoordCnvP ( &Dc_Attr->mxDeviceToWorld, &Points[i] ); - } - return TRUE; -#endif -} - - -BOOL -WINAPI -LPtoDP ( HDC hDC, LPPOINT Points, INT Count ) + PDC_ATTR pdcattr; + + pdcattr = GdiGetDcAttr(hdc); + if (!pdcattr) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if (pdcattr->flXform & ANY_XFORM_CHANGES) + { + GdiFixupTransforms(pdcattr); + } + + // FIXME: can this fail on Windows? + GdiTransformPoints(&pdcattr->mxDeviceToWorld, lpPoints, lpPoints, nCount); + + return TRUE; +#endif + return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiDpToLp); +} + +BOOL +WINAPI +LPtoDP(HDC hdc, LPPOINT lpPoints, INT nCount) { #if 0 INT i; - PDC_ATTR Dc_Attr; - - if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE; - - if (Dc_Attr->flXform & ( PAGE_XLATE_CHANGED | // Check for Changes and Updates - PAGE_EXTENTS_CHANGED | - WORLD_XFORM_CHANGED )) -#endif - return NtGdiTransformPoints( hDC, Points, Points, Count, GdiLpToDp); // LPtoDP mode -#if 0 - else - { - for ( i = 0; i < Count; i++ ) - CoordCnvP ( &Dc_Attr->mxWorldToDevice, &Points[i] ); - } - return TRUE; -#endif + PDC_ATTR pdcattr; + + pdcattr = GdiGetDcAttr(hdc); + if (!pdcattr) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if (pdcattr->flXform & ANY_XFORM_CHANGES) + { + GdiFixupTransforms(pdcattr); + } + + // FIXME: can this fail on Windows? + GdiTransformPoints(&pdcattr->mxWorldToDevice, lpPoints, lpPoints, nCount); + + return TRUE; +#endif + return NtGdiTransformPoints(hdc, lpPoints, lpPoints, nCount, GdiLpToDp); }
/* @@ -185,9 +192,26 @@ */ BOOL WINAPI -GetWorldTransform( HDC hDC, LPXFORM lpXform ) -{ - return NtGdiGetTransform( hDC, GdiWorldSpaceToPageSpace, lpXform); +GetWorldTransform(HDC hDC, LPXFORM lpXform) +{ +#if 0 + PDC_ATTR pdcattr; + + pdcattr = GdiGetDcAttr(hdc); + if (!pdcattr) + { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if (pdcattr->flXform & ANY_XFORM_INVALID) + { + GdiFixupTransforms(pdcattr); + } + + MatrixToXForm(lpXform, &pdcattr->mxWorldToDevice); +#endif + return NtGdiGetTransform(hDC, GdiWorldSpaceToPageSpace, lpXform); }
Added: trunk/reactos/dll/win32/gdi32/objects/efloat.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/efl... ============================================================================== --- trunk/reactos/dll/win32/gdi32/objects/efloat.c (added) +++ trunk/reactos/dll/win32/gdi32/objects/efloat.c [iso-8859-1] Sat Jan 8 19:06:38 2011 @@ -1,0 +1,62 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS System Libraries + * FILE: dll/gdi32/objects/coord.c + * PURPOSE: Functions to convert between FLOAT and EFLOAT + * PROGRAMMER: James Tabor + */ +#include "precomp.h" + +/* 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)) + +FLOATL +FASTCALL +EFtoF(EFLOAT_S * efp) +{ + ULONG Mant, Exp, Sign; + + if (!efp->lMant) return 0; + + Mant = efp->lMant; + Exp = efp->lExp; + Sign = SIGN(Mant); + + if (Sign) Mant = -Mant; + Mant >>= 7; + Exp += (EXCESS-1); + + Mant = MANT(Mant); + return PACK(Sign, Exp, Mant); +} + +VOID +FASTCALL +FtoEF( EFLOAT_S * efp, FLOATL f) +{ + ULONG 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; + + Mant = ((Mant << 7) | 0x40000000); + Mant ^= Sign; + Mant -= Sign; + Exp -= (EXCESS-1); + + efp->lMant = Mant; + efp->lExp = Exp; +}
Propchange: trunk/reactos/dll/win32/gdi32/objects/efloat.c ------------------------------------------------------------------------------ svn:eol-style = native