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.rbui…
==============================================================================
--- 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/gd…
==============================================================================
--- 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/co…
==============================================================================
--- 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/ef…
==============================================================================
--- 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