mirror of
https://github.com/reactos/reactos.git
synced 2024-10-05 00:43:21 +00:00
[GDI32]
- Move EFLOAT handling in seperate file, its x86 specific - Implement CombineTransform fully in usermode instead of forwarding to NtGdiCombineTransform - Implement MatrixToXForm - Implement GdiTransformPoints svn path=/trunk/; revision=50330
This commit is contained in:
parent
281dd88c8c
commit
ae1bdd5334
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -292,7 +292,6 @@ int FASTCALL DocumentEventEx(PVOID,HANDLE,HDC,int,ULONG,PVOID,ULONG,PVOID);
|
|||
BOOL FASTCALL EndPagePrinterEx(PVOID,HANDLE);
|
||||
BOOL FASTCALL LoadTheSpoolerDrv(VOID);
|
||||
|
||||
|
||||
FORCEINLINE
|
||||
PVOID
|
||||
GdiAllocBatchCommand(
|
||||
|
@ -389,4 +388,33 @@ GdiGetDcAttr(HDC hdc)
|
|||
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 */
|
||||
|
|
|
@ -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)
|
||||
/* 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)
|
||||
{
|
||||
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);
|
||||
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
|
||||
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)
|
||||
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 );
|
||||
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
|
||||
DPtoLP ( HDC hDC, LPPOINT Points, INT Count )
|
||||
CombineTransform(
|
||||
LPXFORM pxfResult,
|
||||
const XFORM *pxf1,
|
||||
const XFORM *pxf2)
|
||||
{
|
||||
#if 0
|
||||
INT i;
|
||||
PDC_ATTR Dc_Attr;
|
||||
XFORM xformTmp;
|
||||
|
||||
if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
|
||||
/* 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;
|
||||
|
||||
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.
|
||||
*pxfResult = xformTmp;
|
||||
#if 0
|
||||
else
|
||||
/* windows compatibility fixups (needs more work) */
|
||||
if (_isnan(xformTmp.eM12))
|
||||
{
|
||||
for ( i = 0; i < Count; i++ )
|
||||
CoordCnvP ( &Dc_Attr->mxDeviceToWorld, &Points[i] );
|
||||
if (pxf1->eM11 == 0 || pxf2->eM12 == 0) pxfResult->eM12 = 0.;
|
||||
}
|
||||
return TRUE;
|
||||
#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
|
||||
LPtoDP ( HDC hDC, LPPOINT Points, INT Count )
|
||||
DPtoLP(HDC hdc, LPPOINT lpPoints, INT nCount)
|
||||
{
|
||||
#if 0
|
||||
INT i;
|
||||
PDC_ATTR Dc_Attr;
|
||||
PDC_ATTR pdcattr;
|
||||
|
||||
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
|
||||
pdcattr = GdiGetDcAttr(hdc);
|
||||
if (!pdcattr)
|
||||
{
|
||||
for ( i = 0; i < Count; i++ )
|
||||
CoordCnvP ( &Dc_Attr->mxWorldToDevice, &Points[i] );
|
||||
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 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 @@ GetCurrentPositionEx(HDC hdc,
|
|||
*/
|
||||
BOOL
|
||||
WINAPI
|
||||
GetWorldTransform( HDC hDC, LPXFORM lpXform )
|
||||
GetWorldTransform(HDC hDC, LPXFORM lpXform)
|
||||
{
|
||||
return NtGdiGetTransform( hDC, GdiWorldSpaceToPageSpace, 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
62
reactos/dll/win32/gdi32/objects/efloat.c
Normal file
62
reactos/dll/win32/gdi32/objects/efloat.c
Normal file
|
@ -0,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;
|
||||
}
|
Loading…
Reference in a new issue