some fixes

svn path=/trunk/; revision=7454
This commit is contained in:
Thomas Bluemel 2004-01-04 21:26:59 +00:00
parent 73990aee98
commit c82235044d
3 changed files with 350 additions and 160 deletions

View file

@ -114,5 +114,12 @@ IntGdiCreateDC(PUNICODE_STRING Driver,
PUNICODE_STRING Output, PUNICODE_STRING Output,
CONST PDEVMODEW InitData); CONST PDEVMODEW InitData);
/* Coord functions */
BOOL FASTCALL
IntGdiCombineTransform(LPXFORM XFormResult,
LPXFORM xform1,
LPXFORM xform2);
#endif /* _WIN32K_INTGDI_H */ #endif /* _WIN32K_INTGDI_H */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: coord.c,v 1.20 2003/12/21 18:38:37 navaraf Exp $ /* $Id: coord.c,v 1.21 2004/01/04 21:26:59 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -38,35 +38,63 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
BOOL FASTCALL
IntGdiCombineTransform(LPXFORM XFormResult,
LPXFORM xform1,
LPXFORM xform2)
{
/* Check for illegal parameters */
if (!XFormResult || !xform1 || !xform2)
{
return FALSE;
}
/* Create the result in a temporary XFORM, since xformResult may be
* equal to xform1 or xform2 */
XFormResult->eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
XFormResult->eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
XFormResult->eM21 = xform1->eM21 * xform2->eM11 + xform1->eM22 * xform2->eM21;
XFormResult->eM22 = xform1->eM21 * xform2->eM12 + xform1->eM22 * xform2->eM22;
XFormResult->eDx = xform1->eDx * xform2->eM11 + xform1->eDy * xform2->eM21 + xform2->eDx;
XFormResult->eDy = xform1->eDx * xform2->eM12 + xform1->eDy * xform2->eM22 + xform2->eDy;
return TRUE;
}
BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult, BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
CONST LPXFORM Unsafexform1, CONST LPXFORM Unsafexform1,
CONST LPXFORM Unsafexform2) CONST LPXFORM Unsafexform2)
{ {
XFORM xformTemp; XFORM xformTemp;
XFORM xform1, xform2; XFORM xform1, xform2;
NTSTATUS Status;
BOOL Ret;
/* Check for illegal parameters */
if (!UnsafeXFormResult || !Unsafexform1 || !Unsafexform2) Status = MmCopyFromCaller( &xform1, Unsafexform1, sizeof(XFORM) );
if(!NT_SUCCESS(Status))
{ {
return FALSE; SetLastNtError(Status);
return FALSE;
} }
Status = MmCopyFromCaller( &xform2, Unsafexform2, sizeof(XFORM) );
MmCopyFromCaller( &xform1, Unsafexform1, sizeof(XFORM) ); if(!NT_SUCCESS(Status))
MmCopyFromCaller( &xform2, Unsafexform2, sizeof(XFORM) ); {
SetLastNtError(Status);
/* Create the result in a temporary XFORM, since xformResult may be return FALSE;
* equal to xform1 or xform2 */ }
xformTemp.eM11 = xform1.eM11 * xform2.eM11 + xform1.eM12 * xform2.eM21;
xformTemp.eM12 = xform1.eM11 * xform2.eM12 + xform1.eM12 * xform2.eM22; Ret = IntGdiCombineTransform(&xformTemp, &xform1, &xform2);
xformTemp.eM21 = xform1.eM21 * xform2.eM11 + xform1.eM22 * xform2.eM21;
xformTemp.eM22 = xform1.eM21 * xform2.eM12 + xform1.eM22 * xform2.eM22;
xformTemp.eDx = xform1.eDx * xform2.eM11 + xform1.eDy * xform2.eM21 + xform2.eDx;
xformTemp.eDy = xform1.eDx * xform2.eM12 + xform1.eDy * xform2.eM22 + xform2.eDy;
/* Copy the result to xformResult */ /* Copy the result to xformResult */
MmCopyToCaller( UnsafeXFormResult, &xformTemp, sizeof(XFORM) ); Status = MmCopyToCaller( UnsafeXFormResult, &xformTemp, sizeof(XFORM) );
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
return FALSE;
}
return TRUE; return Ret;
} }
VOID FASTCALL VOID FASTCALL
@ -107,24 +135,57 @@ NtGdiDPtoLP(HDC hDC,
int Count) int Count)
{ {
PDC dc; PDC dc;
LPPOINT Points = (LPPOINT)ExAllocatePool(PagedPool, Count * sizeof(POINT)); NTSTATUS Status;
BOOL ret = FALSE; // default to failure LPPOINT Points;
ULONG Size;
if (!Points)
return FALSE;
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (dc) if (!dc)
{ {
ret = TRUE; SetLastWin32Error(ERROR_INVALID_HANDLE);
MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT)); return FALSE;
IntDPtoLP(dc, Points, Count);
MmCopyToCaller(UnsafePoints, Points, Count * sizeof(POINT));
DC_UnlockDc(hDC);
} }
if (!UnsafePoints || Count <= 0)
{
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
Size = Count * sizeof(POINT);
Points = (LPPOINT)ExAllocatePool(PagedPool, Size);
if(!Points)
{
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
Status = MmCopyFromCaller(Points, UnsafePoints, Size);
if(!NT_SUCCESS(Status))
{
DC_UnlockDc(hDC);
ExFreePool(Points);
SetLastNtError(Status);
return FALSE;
}
IntDPtoLP(dc, Points, Count);
Status = MmCopyToCaller(UnsafePoints, Points, Size);
if(!NT_SUCCESS(Status))
{
DC_UnlockDc(hDC);
ExFreePool(Points);
SetLastNtError(Status);
return FALSE;
}
DC_UnlockDc(hDC);
ExFreePool(Points); ExFreePool(Points);
return TRUE;
return ret;
} }
int int
@ -139,15 +200,19 @@ int
STDCALL STDCALL
NtGdiGetGraphicsMode ( HDC hDC ) NtGdiGetGraphicsMode ( HDC hDC )
{ {
PDC dc = DC_LockDc ( hDC ); PDC dc;
int GraphicsMode = 0; // default to failure int GraphicsMode; // default to failure
if ( dc ) dc = DC_LockDc ( hDC );
if (!dc)
{ {
GraphicsMode = dc->w.GraphicsMode; SetLastWin32Error(ERROR_INVALID_HANDLE);
DC_UnlockDc ( hDC ); return 0;
} }
GraphicsMode = dc->w.GraphicsMode;
DC_UnlockDc ( hDC );
return GraphicsMode; return GraphicsMode;
} }
@ -157,19 +222,25 @@ NtGdiGetWorldTransform(HDC hDC,
LPXFORM XForm) LPXFORM XForm)
{ {
PDC dc; PDC dc;
NTSTATUS Status;
if (!XForm)
return FALSE; dc = DC_LockDc ( hDC );
dc = DC_LockDc (hDC);
if (!dc) if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
}
*XForm = dc->w.xformWorld2Wnd; if (!XForm)
{
DC_UnlockDc ( hDC );
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
Status = MmCopyToCaller(XForm, &dc->w.xformWorld2Wnd, sizeof(XFORM));
DC_UnlockDc ( hDC ); DC_UnlockDc ( hDC );
return NT_SUCCESS(Status);
return TRUE;
} }
VOID VOID
@ -212,32 +283,58 @@ IntLPtoDP ( PDC dc, LPPOINT Points, INT Count )
BOOL STDCALL BOOL STDCALL
NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count ) NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count )
{ {
PDC dc; PDC dc;
LPPOINT Points = (LPPOINT)ExAllocatePool ( PagedPool, Count*sizeof(POINT) ); NTSTATUS Status;
BOOL ret = FALSE; // default to failure LPPOINT Points;
ULONG Size;
ASSERT(Points); dc = DC_LockDc(hDC);
if ( !Points ) if (!dc)
return FALSE; {
SetLastWin32Error(ERROR_INVALID_HANDLE);
dc = DC_LockDc ( hDC ); return FALSE;
}
if ( dc )
{ if (!UnsafePoints || Count <= 0)
ret = TRUE; {
DC_UnlockDc(hDC);
MmCopyFromCaller( Points, UnsafePoints, Count*sizeof(POINT) ); SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
IntLPtoDP ( dc, Points, Count ); }
MmCopyToCaller ( UnsafePoints, Points, Count*sizeof(POINT) ); Size = Count * sizeof(POINT);
DC_UnlockDc ( hDC ); Points = (LPPOINT)ExAllocatePool(PagedPool, Size);
} if(!Points)
{
ExFreePool ( Points ); DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return ret; return FALSE;
}
Status = MmCopyFromCaller(Points, UnsafePoints, Size);
if(!NT_SUCCESS(Status))
{
DC_UnlockDc(hDC);
ExFreePool(Points);
SetLastNtError(Status);
return FALSE;
}
IntLPtoDP(dc, Points, Count);
Status = MmCopyToCaller(UnsafePoints, Points, Size);
if(!NT_SUCCESS(Status))
{
DC_UnlockDc(hDC);
ExFreePool(Points);
SetLastNtError(Status);
return FALSE;
}
DC_UnlockDc(hDC);
ExFreePool(Points);
return TRUE;
} }
BOOL BOOL
@ -246,53 +343,60 @@ NtGdiModifyWorldTransform(HDC hDC,
CONST LPXFORM UnsafeXForm, CONST LPXFORM UnsafeXForm,
DWORD Mode) DWORD Mode)
{ {
PDC dc; PDC dc;
LPXFORM XForm = (LPXFORM) ExAllocatePool( PagedPool, sizeof( XFORM ) ); XFORM SafeXForm;
BOOL ret = FALSE; // default to failure NTSTATUS Status;
ASSERT( XForm ); dc = DC_LockDc(hDC);
if (!XForm) if (!dc)
return FALSE; {
SetLastWin32Error(ERROR_INVALID_HANDLE);
MmCopyFromCaller( XForm, UnsafeXForm, sizeof( XFORM ) ); return FALSE;
}
dc = DC_LockDc (hDC);
if ( dc ) if (!UnsafeXForm)
{ {
/* Check that graphics mode is GM_ADVANCED */ DC_UnlockDc(hDC);
if ( dc->w.GraphicsMode == GM_ADVANCED ) SetLastWin32Error(ERROR_INVALID_PARAMETER);
{ return FALSE;
ret = TRUE; // switch to a default of success }
switch (Mode)
{ Status = MmCopyFromCaller(&SafeXForm, UnsafeXForm, sizeof(XFORM));
case MWT_IDENTITY: if(!NT_SUCCESS(Status))
dc->w.xformWorld2Wnd.eM11 = 1.0f; {
dc->w.xformWorld2Wnd.eM12 = 0.0f; DC_UnlockDc(hDC);
dc->w.xformWorld2Wnd.eM21 = 0.0f; SetLastNtError(Status);
dc->w.xformWorld2Wnd.eM22 = 1.0f; return FALSE;
dc->w.xformWorld2Wnd.eDx = 0.0f; }
dc->w.xformWorld2Wnd.eDy = 0.0f;
break; switch(Mode)
{
case MWT_LEFTMULTIPLY: case MWT_IDENTITY:
NtGdiCombineTransform(&dc->w.xformWorld2Wnd, XForm, &dc->w.xformWorld2Wnd ); dc->w.xformWorld2Wnd.eM11 = 1.0f;
break; dc->w.xformWorld2Wnd.eM12 = 0.0f;
dc->w.xformWorld2Wnd.eM21 = 0.0f;
case MWT_RIGHTMULTIPLY: dc->w.xformWorld2Wnd.eM22 = 1.0f;
NtGdiCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, XForm); dc->w.xformWorld2Wnd.eDx = 0.0f;
break; dc->w.xformWorld2Wnd.eDy = 0.0f;
break;
default:
ret = FALSE; case MWT_LEFTMULTIPLY:
break; IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &SafeXForm, &dc->w.xformWorld2Wnd );
} break;
if ( ret )
DC_UpdateXforms ( dc ); case MWT_RIGHTMULTIPLY:
} IntGdiCombineTransform(&dc->w.xformWorld2Wnd, &dc->w.xformWorld2Wnd, &SafeXForm);
DC_UnlockDc ( hDC ); break;
default:
DC_UnlockDc(hDC);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
} }
ExFreePool ( XForm );
return ret; DC_UpdateXforms(dc);
DC_UnlockDc(hDC);
return TRUE;
} }
BOOL BOOL
@ -305,36 +409,35 @@ NtGdiOffsetViewportOrgEx(HDC hDC,
PDC dc; PDC dc;
POINT Point; POINT Point;
NTSTATUS Status; NTSTATUS Status;
BOOL ret = FALSE; // default to failure
dc = DC_LockDc ( hDC ); dc = DC_LockDc ( hDC );
if ( dc ) if(!dc)
{ {
ret = TRUE; SetLastWin32Error(ERROR_INVALID_HANDLE);
if (NULL != UnsafePoint) return FALSE;
{ }
if (UnsafePoint)
{
Point.x = dc->vportOrgX; Point.x = dc->vportOrgX;
Point.y = dc->vportOrgY; Point.y = dc->vportOrgY;
Status = MmCopyToCaller(UnsafePoint, &Point, sizeof(POINT)); Status = MmCopyToCaller(UnsafePoint, &Point, sizeof(POINT));
if ( !NT_SUCCESS(Status) ) if ( !NT_SUCCESS(Status) )
{ {
SetLastNtError(Status); SetLastNtError(Status);
ret = FALSE; DC_UnlockDc ( hDC );
return FALSE;
} }
}
if ( ret )
{
dc->vportOrgX += XOffset;
dc->vportOrgY += YOffset;
DC_UpdateXforms(dc);
dc->w.DCOrgX += XOffset;
dc->w.DCOrgY += YOffset;
} }
DC_UnlockDc ( hDC ); dc->vportOrgX += XOffset;
} dc->vportOrgY += YOffset;
DC_UpdateXforms(dc);
dc->w.DCOrgX += XOffset;
dc->w.DCOrgY += YOffset;
DC_UnlockDc ( hDC );
return TRUE; return TRUE;
} }
@ -350,13 +453,25 @@ NtGdiOffsetWindowOrgEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (Point) if (Point)
{ {
Point->x = dc->wndOrgX; POINT SafePoint;
Point->y = dc->wndOrgY; NTSTATUS Status;
SafePoint.x = dc->wndOrgX;
SafePoint.y = dc->wndOrgY;
Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->wndOrgX += XOffset; dc->wndOrgX += XOffset;
@ -402,6 +517,7 @@ NtGdiSetGraphicsMode(HDC hDC,
dc = DC_LockDc (hDC); dc = DC_LockDc (hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
@ -414,6 +530,7 @@ NtGdiSetGraphicsMode(HDC hDC,
if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED)) if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
{ {
DC_UnlockDc( hDC ); DC_UnlockDc( hDC );
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@ -433,7 +550,10 @@ NtGdiSetMapMode(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0; return 0;
}
PrevMapMode = dc->w.MapMode; PrevMapMode = dc->w.MapMode;
dc->w.MapMode = MapMode; dc->w.MapMode = MapMode;
@ -454,7 +574,10 @@ NtGdiSetViewportExtEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if ( !dc ) if ( !dc )
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
}
switch (dc->w.MapMode) switch (dc->w.MapMode)
{ {
@ -475,8 +598,19 @@ NtGdiSetViewportExtEx(HDC hDC,
if (Size) if (Size)
{ {
Size->cx = dc->vportExtX; SIZE SafeSize;
Size->cy = dc->vportExtY; NTSTATUS Status;
SafeSize.cx = dc->vportExtX;
SafeSize.cy = dc->vportExtY;
Status = MmCopyToCaller(Size, &SafeSize, sizeof(SIZE));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->vportExtX = XExtent; dc->vportExtX = XExtent;
@ -499,13 +633,25 @@ NtGdiSetViewportOrgEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (Point) if (Point)
{ {
Point->x = dc->vportOrgX; POINT SafePoint;
Point->y = dc->vportOrgY; NTSTATUS Status;
SafePoint.x = dc->vportOrgX;
SafePoint.y = dc->vportOrgY;
Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->vportOrgX = X; dc->vportOrgX = X;
@ -528,6 +674,7 @@ NtGdiSetWindowExtEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@ -542,16 +689,27 @@ NtGdiSetWindowExtEx(HDC hDC,
DC_UnlockDc(hDC); DC_UnlockDc(hDC);
return FALSE; return FALSE;
} }
if (Size) if (Size)
{ {
Size->cx = dc->wndExtX; SIZE SafeSize;
Size->cy = dc->wndExtY; NTSTATUS Status;
SafeSize.cx = dc->wndExtX;
SafeSize.cy = dc->wndExtY;
Status = MmCopyToCaller(Size, &SafeSize, sizeof(SIZE));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->wndExtX = XExtent; dc->wndExtX = XExtent;
dc->wndExtY = YExtent; dc->wndExtY = YExtent;
DC_UnlockDc(hDC); DC_UnlockDc(hDC);
return TRUE; return TRUE;
@ -569,18 +727,30 @@ NtGdiSetWindowOrgEx(HDC hDC,
dc = DC_LockDc(hDC); dc = DC_LockDc(hDC);
if (!dc) if (!dc)
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (Point) if (Point)
{ {
Point->x = dc->wndOrgX; POINT SafePoint;
Point->y = dc->wndOrgY; NTSTATUS Status;
SafePoint.x = dc->wndOrgX;
SafePoint.y = dc->wndOrgY;
Status = MmCopyToCaller(Point, &SafePoint, sizeof(POINT));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
DC_UnlockDc(hDC);
return FALSE;
}
} }
dc->wndOrgX = X; dc->wndOrgX = X;
dc->wndOrgY = Y; dc->wndOrgY = Y;
DC_UnlockDc(hDC); DC_UnlockDc(hDC);
return TRUE; return TRUE;
@ -592,23 +762,36 @@ NtGdiSetWorldTransform(HDC hDC,
CONST LPXFORM XForm) CONST LPXFORM XForm)
{ {
PDC dc; PDC dc;
NTSTATUS Status;
if (!XForm)
return FALSE;
dc = DC_LockDc (hDC); dc = DC_LockDc (hDC);
if ( !dc ) if ( !dc )
{ {
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (!XForm)
{
DC_UnlockDc( hDC );
/* Win doesn't set LastError */
return FALSE;
}
/* Check that graphics mode is GM_ADVANCED */ /* Check that graphics mode is GM_ADVANCED */
if ( dc->w.GraphicsMode != GM_ADVANCED ) if ( dc->w.GraphicsMode != GM_ADVANCED )
{ {
DC_UnlockDc( hDC ); DC_UnlockDc( hDC );
return FALSE; return FALSE;
} }
dc->w.xformWorld2Wnd = *XForm;
Status = MmCopyFromCaller(&dc->w.xformWorld2Wnd, XForm, sizeof(XFORM));
if(!NT_SUCCESS(Status))
{
DC_UnlockDc( hDC );
return FALSE;
}
DC_UpdateXforms (dc); DC_UpdateXforms (dc);
DC_UnlockDc( hDC ); DC_UnlockDc( hDC );
return TRUE; return TRUE;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: dc.c,v 1.114 2003/12/23 18:19:07 navaraf Exp $ /* $Id: dc.c,v 1.115 2004/01/04 21:26:59 weiden Exp $
* *
* DC.C - Device context functions * DC.C - Device context functions
* *
@ -2010,7 +2010,7 @@ DC_UpdateXforms(PDC dc)
xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY - scaleY * (FLOAT)dc->wndOrgY; xformWnd2Vport.eDy = (FLOAT)dc->vportOrgY - scaleY * (FLOAT)dc->wndOrgY;
/* Combine with the world transformation */ /* Combine with the world transformation */
NtGdiCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport); IntGdiCombineTransform(&dc->w.xformWorld2Vport, &dc->w.xformWorld2Wnd, &xformWnd2Vport);
/* Create inverse of world-to-viewport transformation */ /* Create inverse of world-to-viewport transformation */
dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, &dc->w.xformVport2World); dc->w.vport2WorldValid = DC_InvertXform(&dc->w.xformWorld2Vport, &dc->w.xformVport2World);