* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id$
+/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
void FASTCALL
IntFixIsotropicMapping(PDC dc)
{
- ULONG xdim = EngMulDiv(dc->vportExtX, dc->GDIInfo->ulHorzSize, dc->GDIInfo->ulHorzRes) / dc->wndExtX;
- ULONG ydim = EngMulDiv(dc->vportExtY, dc->GDIInfo->ulVertSize, dc->GDIInfo->ulVertRes) / dc->wndExtY;
-
- if (xdim > ydim)
- {
- dc->vportExtX = dc->vportExtX * abs(ydim / xdim);
- if (!dc->vportExtX) dc->vportExtX = 1;
- }
- else
- {
- dc->vportExtY = dc->vportExtY * abs(xdim / ydim);
- if (!dc->vportExtY) dc->vportExtY = 1;
- }
+ PDC_ATTR pdcattr;
+ LONG fx, fy, s;
+
+ /* Get a pointer to the DC_ATTR */
+ pdcattr = dc->pdcattr;
+
+ /* Check if all values are valid */
+ if (pdcattr->szlWindowExt.cx == 0 || pdcattr->szlWindowExt.cy == 0 ||
+ pdcattr->szlViewportExt.cx == 0 || pdcattr->szlViewportExt.cy == 0)
+ {
+ /* Don't recalculate */
+ return;
+ }
+
+ fx = abs(pdcattr->szlWindowExt.cx * pdcattr->szlViewportExt.cy);
+ fy = abs(pdcattr->szlWindowExt.cy * pdcattr->szlViewportExt.cx);
+
+ if (fy > fx)
+ {
+ s = pdcattr->szlWindowExt.cy * pdcattr->szlViewportExt.cx > 0 ? 1 : -1;
+ pdcattr->szlViewportExt.cx = s * fx / pdcattr->szlWindowExt.cy;
+ }
+ else if (fx > fy)
+ {
+ s = pdcattr->szlWindowExt.cx * pdcattr->szlViewportExt.cy > 0 ? 1 : -1;
+ pdcattr->szlViewportExt.cy = s * fy / pdcattr->szlWindowExt.cx;
+ }
}
+// FIXME: don't use floating point in the kernel! use XFORMOBJ function
BOOL FASTCALL
-IntGdiCombineTransform(LPXFORM XFormResult,
- LPXFORM xform1,
- LPXFORM xform2)
+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;
+ XFORM xformTemp;
+ /* 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 */
+ xformTemp.eM11 = xform1->eM11 * xform2->eM11 + xform1->eM12 * xform2->eM21;
+ xformTemp.eM12 = xform1->eM11 * xform2->eM12 + xform1->eM12 * xform2->eM22;
+ 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;
+ *XFormResult = xformTemp;
+
+ return TRUE;
}
-BOOL STDCALL NtGdiCombineTransform(LPXFORM UnsafeXFormResult,
- CONST LPXFORM Unsafexform1,
- CONST LPXFORM Unsafexform2)
+// FIXME: should be XFORML and use XFORMOBJ functions
+BOOL APIENTRY NtGdiCombineTransform(
+ LPXFORM UnsafeXFormResult,
+ LPXFORM Unsafexform1,
+ LPXFORM Unsafexform2)
{
- XFORM xformTemp;
- XFORM xform1 = {0}, xform2 = {0};
- NTSTATUS Status = STATUS_SUCCESS;
- BOOL Ret;
-
- _SEH_TRY
- {
- ProbeForWrite(UnsafeXFormResult,
- sizeof(XFORM),
- 1);
- ProbeForRead(Unsafexform1,
- sizeof(XFORM),
- 1);
- ProbeForRead(Unsafexform2,
- sizeof(XFORM),
- 1);
- xform1 = *Unsafexform1;
- xform2 = *Unsafexform2;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- return FALSE;
- }
-
- Ret = IntGdiCombineTransform(&xformTemp, &xform1, &xform2);
-
- /* Copy the result to xformResult */
- _SEH_TRY
- {
- /* pointer was already probed! */
- *UnsafeXFormResult = xformTemp;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- return FALSE;
- }
-
- return Ret;
+ BOOL Ret;
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(UnsafeXFormResult, sizeof(XFORM), 1);
+ ProbeForRead(Unsafexform1, sizeof(XFORM), 1);
+ ProbeForRead(Unsafexform2, sizeof(XFORM), 1);
+ Ret = IntGdiCombineTransform(UnsafeXFormResult,
+ Unsafexform1,
+ Unsafexform2);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ }
+ _SEH2_END;
+
+ return Ret;
}
-VOID FASTCALL
-CoordDPtoLP(PDC Dc, LPPOINT Point)
+// FIXME: Don't use floating point in the kernel
+BOOL
+FASTCALL
+IntGdiModifyWorldTransform(
+ PDC pDc,
+ CONST LPXFORM lpXForm,
+ DWORD Mode)
{
-FLOAT x, y;
- x = (FLOAT)Point->x;
- y = (FLOAT)Point->y;
- Point->x = x * Dc->w.xformVport2World.eM11 +
- y * Dc->w.xformVport2World.eM21 + Dc->w.xformVport2World.eDx;
- Point->y = x * Dc->w.xformVport2World.eM12 +
- y * Dc->w.xformVport2World.eM22 + Dc->w.xformVport2World.eDy;
+ ASSERT(pDc);
+ XFORM xformWorld2Wnd;
+
+ switch (Mode)
+ {
+ case MWT_IDENTITY:
+ xformWorld2Wnd.eM11 = 1.0f;
+ xformWorld2Wnd.eM12 = 0.0f;
+ xformWorld2Wnd.eM21 = 0.0f;
+ xformWorld2Wnd.eM22 = 1.0f;
+ xformWorld2Wnd.eDx = 0.0f;
+ xformWorld2Wnd.eDy = 0.0f;
+ XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
+ break;
+
+ case MWT_LEFTMULTIPLY:
+ MatrixS2XForm(&xformWorld2Wnd, &pDc->dclevel.mxWorldToPage);
+ IntGdiCombineTransform(&xformWorld2Wnd, lpXForm, &xformWorld2Wnd);
+ XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
+ break;
+
+ case MWT_RIGHTMULTIPLY:
+ MatrixS2XForm(&xformWorld2Wnd, &pDc->dclevel.mxWorldToPage);
+ IntGdiCombineTransform(&xformWorld2Wnd, &xformWorld2Wnd, lpXForm);
+ XForm2MatrixS(&pDc->dclevel.mxWorldToPage, &xformWorld2Wnd);
+ break;
+
+ case MWT_MAX+1: // Must be MWT_SET????
+ XForm2MatrixS(&pDc->dclevel.mxWorldToPage, lpXForm); // Do it like Wine.
+ break;
+
+ default:
+ return FALSE;
+ }
+ DC_UpdateXforms(pDc);
+ return TRUE;
}
-VOID
-FASTCALL
-IntDPtoLP ( PDC dc, LPPOINT Points, INT Count )
+// FIXME: Should be XFORML and use XFORMOBJ functions directly
+BOOL
+APIENTRY
+NtGdiGetTransform(
+ HDC hDC,
+ DWORD iXform,
+ LPXFORM XForm)
{
- INT i;
+ PDC dc;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ dc = DC_LockDc(hDC);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ if (!XForm)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(XForm, sizeof(XFORM), 1);
+ switch (iXform)
+ {
+ case GdiWorldSpaceToPageSpace:
+ MatrixS2XForm(XForm, &dc->dclevel.mxWorldToPage);
+ break;
- ASSERT ( Points );
+ default:
+ break;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
- for ( i = 0; i < Count; i++ )
- CoordDPtoLP ( dc, &Points[i] );
+ DC_UnlockDc(dc);
+ return NT_SUCCESS(Status);
}
+
/*!
- * Converts points from device coordinates into logical coordinates. Conversion depends on the mapping mode,
+ * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
* world transfrom, viewport origin settings for the given device context.
* \param hDC device context.
* \param Points an array of POINT structures (in/out).
* \param Count number of elements in the array of POINT structures.
* \return TRUE if success.
*/
-BOOL STDCALL
-NtGdiDPtoLP(HDC hDC,
- LPPOINT UnsafePoints,
- int Count)
+BOOL
+APIENTRY
+NtGdiTransformPoints(
+ HDC hDC,
+ PPOINT UnsafePtsIn,
+ PPOINT UnsafePtOut,
+ INT Count,
+ INT iMode)
{
- PDC dc;
- NTSTATUS Status = STATUS_SUCCESS;
- LPPOINT Points;
- ULONG Size;
-
- dc = DC_LockDc(hDC);
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if (!UnsafePoints || Count <= 0)
- {
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- Size = Count * sizeof(POINT);
-
- Points = (LPPOINT)ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
- if(!Points)
- {
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
-
- _SEH_TRY
- {
- ProbeForWrite(UnsafePoints,
- Size,
- 1);
- RtlCopyMemory(Points,
- UnsafePoints,
- Size);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- DC_UnlockDc(dc);
- ExFreePool(Points);
- SetLastNtError(Status);
- return FALSE;
- }
-
- IntDPtoLP(dc, Points, Count);
-
- _SEH_TRY
- {
- /* pointer was already probed! */
- RtlCopyMemory(UnsafePoints,
- Points,
- Size);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- DC_UnlockDc(dc);
- ExFreePool(Points);
- SetLastNtError(Status);
- return FALSE;
- }
-
- DC_UnlockDc(dc);
- ExFreePool(Points);
- return TRUE;
-}
+ PDC dc;
+ NTSTATUS Status = STATUS_SUCCESS;
+ LPPOINT Points;
+ ULONG Size;
-int
-FASTCALL
-IntGetGraphicsMode ( PDC dc )
-{
- ASSERT ( dc );
- return dc->w.GraphicsMode;
-}
+ dc = DC_LockDc(hDC);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
-BOOL
-FASTCALL
-IntGdiModifyWorldTransform(PDC pDc,
- CONST LPXFORM lpXForm,
- DWORD Mode)
-{
- ASSERT(pDc && lpXForm);
-
- switch(Mode)
- {
- case MWT_IDENTITY:
- pDc->w.xformWorld2Wnd.eM11 = 1.0f;
- pDc->w.xformWorld2Wnd.eM12 = 0.0f;
- pDc->w.xformWorld2Wnd.eM21 = 0.0f;
- pDc->w.xformWorld2Wnd.eM22 = 1.0f;
- pDc->w.xformWorld2Wnd.eDx = 0.0f;
- pDc->w.xformWorld2Wnd.eDy = 0.0f;
- break;
-
- case MWT_LEFTMULTIPLY:
- IntGdiCombineTransform(&pDc->w.xformWorld2Wnd, lpXForm, &pDc->w.xformWorld2Wnd );
- break;
-
- case MWT_RIGHTMULTIPLY:
- IntGdiCombineTransform(&pDc->w.xformWorld2Wnd, &pDc->w.xformWorld2Wnd, lpXForm);
- break;
-
- default:
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- DC_UpdateXforms(pDc);
- DC_UnlockDc(pDc);
- return TRUE;
-}
+ if (!UnsafePtsIn || !UnsafePtOut || Count <= 0)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
-int
-STDCALL
-NtGdiGetGraphicsMode ( HDC hDC )
-{
- PDC dc;
- int GraphicsMode; // default to failure
+ Size = Count * sizeof(POINT);
- dc = DC_LockDc ( hDC );
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
+ // FIXME: It would be wise to have a small stack buffer as optimization
+ Points = ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
+ if (!Points)
+ {
+ DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
- GraphicsMode = dc->w.GraphicsMode;
+ _SEH2_TRY
+ {
+ ProbeForWrite(UnsafePtOut, Size, 1);
+ ProbeForRead(UnsafePtsIn, Size, 1);
+ RtlCopyMemory(Points, UnsafePtsIn, Size);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
- DC_UnlockDc(dc);
- return GraphicsMode;
-}
+ if (!NT_SUCCESS(Status))
+ {
+ DC_UnlockDc(dc);
+ ExFreePoolWithTag(Points, TAG_COORD);
+ SetLastNtError(Status);
+ return FALSE;
+ }
-BOOL
-STDCALL
-NtGdiGetWorldTransform(HDC hDC,
- LPXFORM XForm)
-{
- PDC dc;
- NTSTATUS Status = STATUS_SUCCESS;
-
- dc = DC_LockDc ( hDC );
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (!XForm)
- {
+ switch (iMode)
+ {
+ case GdiDpToLp:
+ IntDPtoLP(dc, Points, Count);
+ break;
+
+ case GdiLpToDp:
+ IntLPtoDP(dc, Points, Count);
+ break;
+
+ case 2: // Not supported yet. Need testing.
+ default:
+ {
+ DC_UnlockDc(dc);
+ ExFreePoolWithTag(Points, TAG_COORD);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ }
+
+ _SEH2_TRY
+ {
+ /* pointer was already probed! */
+ RtlCopyMemory(UnsafePtOut, Points, Size);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ DC_UnlockDc(dc);
+ ExFreePoolWithTag(Points, TAG_COORD);
+ SetLastNtError(Status);
+ return FALSE;
+ }
+//
+// If we are getting called that means User XForms is a mess!
+//
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- _SEH_TRY
- {
- ProbeForWrite(XForm,
- sizeof(XFORM),
- 1);
- *XForm = dc->w.xformWorld2Wnd;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- DC_UnlockDc(dc);
- return NT_SUCCESS(Status);
+ ExFreePoolWithTag(Points, TAG_COORD);
+ return TRUE;
}
-VOID
-FASTCALL
-CoordLPtoDP ( PDC Dc, LPPOINT Point )
+BOOL
+APIENTRY
+NtGdiModifyWorldTransform(
+ HDC hDC,
+ LPXFORM UnsafeXForm,
+ DWORD Mode)
{
- FLOAT x, y;
+ PDC dc;
+ XFORM SafeXForm;
+ BOOL Ret = TRUE;
+
+ dc = DC_LockDc(hDC);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
- ASSERT ( Dc );
- ASSERT ( Point );
+ // The xform is permitted to be NULL for MWT_IDENTITY.
+ // However, if it is not NULL, then it must be valid even though it is not used.
+ if (UnsafeXForm != NULL || Mode != MWT_IDENTITY)
+ {
+ _SEH2_TRY
+ {
+ ProbeForRead(UnsafeXForm, sizeof(XFORM), 1);
+ RtlCopyMemory(&SafeXForm, UnsafeXForm, sizeof(XFORM));
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ }
+ _SEH2_END;
+ }
- x = (FLOAT)Point->x;
- y = (FLOAT)Point->y;
- Point->x = x * Dc->w.xformWorld2Vport.eM11 +
- y * Dc->w.xformWorld2Vport.eM21 + Dc->w.xformWorld2Vport.eDx;
- Point->y = x * Dc->w.xformWorld2Vport.eM12 +
- y * Dc->w.xformWorld2Vport.eM22 + Dc->w.xformWorld2Vport.eDy;
+ // Safe to handle kernel mode data.
+ if (Ret) Ret = IntGdiModifyWorldTransform(dc, &SafeXForm, Mode);
+ DC_UnlockDc(dc);
+ return Ret;
}
-VOID
-FASTCALL
-IntLPtoDP ( PDC dc, LPPOINT Points, INT Count )
+BOOL
+APIENTRY
+NtGdiOffsetViewportOrgEx(
+ HDC hDC,
+ int XOffset,
+ int YOffset,
+ LPPOINT UnsafePoint)
{
- INT i;
+ PDC dc;
+ PDC_ATTR pdcattr;
+ NTSTATUS Status = STATUS_SUCCESS;
- ASSERT ( Points );
+ dc = DC_LockDc(hDC);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ pdcattr = dc->pdcattr;
- for ( i = 0; i < Count; i++ )
- CoordLPtoDP ( dc, &Points[i] );
-}
+ if (UnsafePoint)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(UnsafePoint, sizeof(POINT), 1);
+ UnsafePoint->x = pdcattr->ptlViewportOrg.x;
+ UnsafePoint->y = pdcattr->ptlViewportOrg.y;
+ if (pdcattr->dwLayout & LAYOUT_RTL)
+ {
+ UnsafePoint->x = -UnsafePoint->x;
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
-/*!
- * Converts points from logical coordinates into device coordinates. Conversion depends on the mapping mode,
- * world transfrom, viewport origin settings for the given device context.
- * \param hDC device context.
- * \param Points an array of POINT structures (in/out).
- * \param Count number of elements in the array of POINT structures.
- * \return TRUE if success.
-*/
-BOOL STDCALL
-NtGdiLPtoDP ( HDC hDC, LPPOINT UnsafePoints, INT Count )
-{
- PDC dc;
- NTSTATUS Status = STATUS_SUCCESS;
- LPPOINT Points;
- ULONG Size;
-
- dc = DC_LockDc(hDC);
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if (!UnsafePoints || Count <= 0)
- {
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- Size = Count * sizeof(POINT);
-
- Points = (LPPOINT)ExAllocatePoolWithTag(PagedPool, Size, TAG_COORD);
- if(!Points)
- {
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
-
- _SEH_TRY
- {
- ProbeForWrite(UnsafePoints,
- Size,
- 1);
- RtlCopyMemory(Points,
- UnsafePoints,
- Size);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- DC_UnlockDc(dc);
- ExFreePool(Points);
- SetLastNtError(Status);
- return FALSE;
- }
-
- IntLPtoDP(dc, Points, Count);
-
- _SEH_TRY
- {
- /* pointer was already probed! */
- RtlCopyMemory(UnsafePoints,
- Points,
- Size);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- DC_UnlockDc(dc);
- ExFreePool(Points);
- SetLastNtError(Status);
- return FALSE;
- }
-
- DC_UnlockDc(dc);
- ExFreePool(Points);
- return TRUE;
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ DC_UnlockDc(dc);
+ return FALSE;
+ }
+ }
+
+ if (pdcattr->dwLayout & LAYOUT_RTL)
+ {
+ XOffset = -XOffset;
+ }
+ pdcattr->ptlViewportOrg.x += XOffset;
+ pdcattr->ptlViewportOrg.y += YOffset;
+ DC_UpdateXforms(dc);
+ DC_UnlockDc(dc);
+
+ return TRUE;
}
BOOL
-STDCALL
-NtGdiModifyWorldTransform(HDC hDC,
- CONST LPXFORM UnsafeXForm,
- DWORD Mode)
+APIENTRY
+NtGdiOffsetWindowOrgEx(
+ HDC hDC,
+ int XOffset,
+ int YOffset,
+ LPPOINT Point)
{
- PDC dc;
- XFORM SafeXForm;
- BOOL Ret = FALSE;
-
- if (!UnsafeXForm)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- dc = DC_LockDc(hDC);
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- _SEH_TRY
- {
- ProbeForRead(UnsafeXForm, sizeof(XFORM), 1);
- RtlCopyMemory(&SafeXForm, UnsafeXForm, sizeof(XFORM));
-
- Ret = IntGdiModifyWorldTransform(dc, &SafeXForm, Mode);
- }
- _SEH_HANDLE
- {
- SetLastNtError(_SEH_GetExceptionCode());
- }
- _SEH_END;
-
- DC_UnlockDc(dc);
- return Ret;
+ PDC dc;
+ PDC_ATTR pdcattr;
+
+ dc = DC_LockDc(hDC);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ pdcattr = dc->pdcattr;
+
+ if (Point)
+ {
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(Point, sizeof(POINT), 1);
+ Point->x = pdcattr->ptlWindowOrg.x;
+ Point->y = pdcattr->ptlWindowOrg.y;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ DC_UnlockDc(dc);
+ return FALSE;
+ }
+ }
+
+ pdcattr->ptlWindowOrg.x += XOffset;
+ pdcattr->ptlWindowOrg.y += YOffset;
+
+ DC_UpdateXforms(dc);
+ DC_UnlockDc(dc);
+
+ return TRUE;
}
BOOL
-STDCALL
-NtGdiOffsetViewportOrgEx(HDC hDC,
- int XOffset,
- int YOffset,
- LPPOINT UnsafePoint)
+APIENTRY
+NtGdiScaleViewportExtEx(
+ HDC hDC,
+ int Xnum,
+ int Xdenom,
+ int Ynum,
+ int Ydenom,
+ LPSIZE pSize)
{
- PDC dc;
- NTSTATUS Status = STATUS_SUCCESS;
+ PDC pDC;
+ PDC_ATTR pdcattr;
+ BOOL Ret = FALSE;
+ LONG X, Y;
- dc = DC_LockDc ( hDC );
- if(!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
+ pDC = DC_LockDc(hDC);
+ if (!pDC)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ pdcattr = pDC->pdcattr;
- if (UnsafePoint)
+ if (pSize)
{
- _SEH_TRY
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(pSize, sizeof(LPSIZE), 1);
+
+ pSize->cx = pdcattr->szlViewportExt.cx;
+ pSize->cy = pdcattr->szlViewportExt.cy;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- ProbeForWrite(UnsafePoint,
- sizeof(POINT),
- 1);
- UnsafePoint->x = dc->vportOrgX;
- UnsafePoint->y = dc->vportOrgY;
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_HANDLE
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
{
- Status = _SEH_GetExceptionCode();
+ SetLastNtError(Status);
+ DC_UnlockDc(pDC);
+ return FALSE;
}
- _SEH_END;
-
- if ( !NT_SUCCESS(Status) )
- {
- SetLastNtError(Status);
- DC_UnlockDc(dc);
- return FALSE;
- }
}
- dc->vportOrgX += XOffset;
- dc->vportOrgY += YOffset;
- DC_UpdateXforms(dc);
+ if (pdcattr->iMapMode > MM_TWIPS)
+ {
+ if (Xdenom && Ydenom)
+ {
+ X = Xnum * pdcattr->szlViewportExt.cx / Xdenom;
+ if (X)
+ {
+ Y = Ynum * pdcattr->szlViewportExt.cy / Ydenom;
+ if (Y)
+ {
+ pdcattr->szlViewportExt.cx = X;
+ pdcattr->szlViewportExt.cy = Y;
+
+ IntMirrorWindowOrg(pDC);
+
+ pdcattr->flXform |= (PAGE_EXTENTS_CHANGED |
+ INVALIDATE_ATTRIBUTES |
+ DEVICE_TO_WORLD_INVALID);
+
+ if (pdcattr->iMapMode == MM_ISOTROPIC)
+ {
+ IntFixIsotropicMapping(pDC);
+ }
+ DC_UpdateXforms(pDC);
+
+ Ret = TRUE;
+ }
+ }
+ }
+ }
+ else
+ Ret = TRUE;
- DC_UnlockDc(dc);
- return TRUE;
+ DC_UnlockDc(pDC);
+ return Ret;
}
BOOL
-STDCALL
-NtGdiOffsetWindowOrgEx(HDC hDC,
- int XOffset,
- int YOffset,
- LPPOINT Point)
+APIENTRY
+NtGdiScaleWindowExtEx(
+ HDC hDC,
+ int Xnum,
+ int Xdenom,
+ int Ynum,
+ int Ydenom,
+ LPSIZE pSize)
{
- PDC dc;
+ PDC pDC;
+ PDC_ATTR pdcattr;
+ BOOL Ret = FALSE;
+ LONG X, Y;
- dc = DC_LockDc(hDC);
- if (!dc)
+ pDC = DC_LockDc(hDC);
+ if (!pDC)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
}
+ pdcattr = pDC->pdcattr;
- if (Point)
+ if (pSize)
{
- NTSTATUS Status = STATUS_SUCCESS;
-
- _SEH_TRY
- {
- ProbeForWrite(Point,
- sizeof(POINT),
- 1);
- Point->x = dc->wndOrgX;
- Point->y = dc->wndOrgY;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- DC_UnlockDc(dc);
- return FALSE;
- }
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(pSize, sizeof(LPSIZE), 1);
+
+ X = pdcattr->szlWindowExt.cx;
+ if (pdcattr->dwLayout & LAYOUT_RTL) X = -X;
+ pSize->cx = X;
+ pSize->cy = pdcattr->szlWindowExt.cy;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ DC_UnlockDc(pDC);
+ return FALSE;
+ }
}
- dc->wndOrgX += XOffset;
- dc->wndOrgY += YOffset;
+ if (pdcattr->iMapMode > MM_TWIPS)
+ {
+ if (Xdenom && Ydenom)
+ {
+ X = Xnum * pdcattr->szlWindowExt.cx / Xdenom;
+ if (X)
+ {
+ Y = Ynum * pdcattr->szlWindowExt.cy / Ydenom;
+ if (Y)
+ {
+ pdcattr->szlWindowExt.cx = X;
+ pdcattr->szlWindowExt.cy = Y;
+
+ IntMirrorWindowOrg(pDC);
+
+ pdcattr->flXform |= (PAGE_EXTENTS_CHANGED|INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
- DC_UpdateXforms(dc);
- DC_UnlockDc(dc);
+ if (pdcattr->iMapMode == MM_ISOTROPIC) IntFixIsotropicMapping(pDC);
+ DC_UpdateXforms(pDC);
+
+ Ret = TRUE;
+ }
+ }
+ }
+ }
+ else
+ Ret = TRUE;
- return TRUE;
+ DC_UnlockDc(pDC);
+ return Ret;
}
-BOOL
-STDCALL
-NtGdiScaleViewportExtEx(HDC hDC,
- int Xnum,
- int Xdenom,
- int Ynum,
- int Ydenom,
- LPSIZE Size)
+int
+APIENTRY
+IntGdiSetMapMode(
+ PDC dc,
+ int MapMode)
{
- UNIMPLEMENTED;
- return FALSE;
+ int PrevMapMode;
+ PDC_ATTR pdcattr = dc->pdcattr;
+
+ PrevMapMode = pdcattr->iMapMode;
+
+ pdcattr->iMapMode = MapMode;
+
+ switch (MapMode)
+ {
+ case MM_TEXT:
+ pdcattr->szlWindowExt.cx = 1;
+ pdcattr->szlWindowExt.cy = 1;
+ pdcattr->szlViewportExt.cx = 1;
+ pdcattr->szlViewportExt.cy = 1;
+ pdcattr->flXform &= ~(ISO_OR_ANISO_MAP_MODE|PTOD_EFM22_NEGATIVE|
+ PTOD_EFM11_NEGATIVE|POSITIVE_Y_IS_UP);
+ pdcattr->flXform |= (PAGE_XLATE_CHANGED|PAGE_TO_DEVICE_SCALE_IDENTITY|
+ INVALIDATE_ATTRIBUTES|DEVICE_TO_WORLD_INVALID);
+ break;
+
+ case MM_ISOTROPIC:
+ pdcattr->flXform |= ISO_OR_ANISO_MAP_MODE;
+ /* Fall through */
+
+ case MM_LOMETRIC:
+ pdcattr->szlWindowExt.cx = dc->ppdev->GDIInfo.ulHorzSize * 10;
+ pdcattr->szlWindowExt.cy = dc->ppdev->GDIInfo.ulVertSize * 10;
+ pdcattr->szlViewportExt.cx = dc->ppdev->GDIInfo.ulHorzRes;
+ pdcattr->szlViewportExt.cy = -dc->ppdev->GDIInfo.ulVertRes;
+ break;
+
+ case MM_HIMETRIC:
+ pdcattr->szlWindowExt.cx = dc->ppdev->GDIInfo.ulHorzSize * 100;
+ pdcattr->szlWindowExt.cy = dc->ppdev->GDIInfo.ulVertSize * 100;
+ pdcattr->szlViewportExt.cx = dc->ppdev->GDIInfo.ulHorzRes;
+ pdcattr->szlViewportExt.cy = -dc->ppdev->GDIInfo.ulVertRes;
+ break;
+
+ case MM_LOENGLISH:
+ pdcattr->szlWindowExt.cx = MulDiv(1000, dc->ppdev->GDIInfo.ulHorzSize, 254);
+ pdcattr->szlWindowExt.cy = MulDiv(1000, dc->ppdev->GDIInfo.ulVertSize, 254);
+ pdcattr->szlViewportExt.cx = dc->ppdev->GDIInfo.ulHorzRes;
+ pdcattr->szlViewportExt.cy = -dc->ppdev->GDIInfo.ulVertRes;
+ break;
+
+ case MM_HIENGLISH:
+ pdcattr->szlWindowExt.cx = MulDiv(10000, dc->ppdev->GDIInfo.ulHorzSize, 254);
+ pdcattr->szlWindowExt.cy = MulDiv(10000, dc->ppdev->GDIInfo.ulVertSize, 254);
+ pdcattr->szlViewportExt.cx = dc->ppdev->GDIInfo.ulHorzRes;
+ pdcattr->szlViewportExt.cy = -dc->ppdev->GDIInfo.ulVertRes;
+ break;
+
+ case MM_TWIPS:
+ pdcattr->szlWindowExt.cx = MulDiv(14400, dc->ppdev->GDIInfo.ulHorzSize, 254);
+ pdcattr->szlWindowExt.cy = MulDiv(14400, dc->ppdev->GDIInfo.ulVertSize, 254);
+ pdcattr->szlViewportExt.cx = dc->ppdev->GDIInfo.ulHorzRes;
+ pdcattr->szlViewportExt.cy = -dc->ppdev->GDIInfo.ulVertRes;
+ break;
+
+ case MM_ANISOTROPIC:
+ pdcattr->flXform &= ~(PAGE_TO_DEVICE_IDENTITY|POSITIVE_Y_IS_UP);
+ pdcattr->flXform |= ISO_OR_ANISO_MAP_MODE;
+ break;
+
+ default:
+ pdcattr->iMapMode = PrevMapMode;
+ PrevMapMode = 0;
+ }
+ DC_UpdateXforms(dc);
+
+ return PrevMapMode;
}
+
BOOL
-STDCALL
-NtGdiScaleWindowExtEx(HDC hDC,
- int Xnum,
- int Xdenom,
- int Ynum,
- int Ydenom,
- LPSIZE Size)
+APIENTRY
+NtGdiSetViewportOrgEx(
+ HDC hDC,
+ int X,
+ int Y,
+ LPPOINT Point)
{
- UNIMPLEMENTED;
- return FALSE;
-}
+ PDC dc;
+ PDC_ATTR pdcattr;
-int
-STDCALL
-NtGdiSetGraphicsMode(HDC hDC,
- int Mode)
-{
- INT ret;
- PDC dc;
-
- dc = DC_LockDc (hDC);
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
-
- /* One would think that setting the graphics mode to GM_COMPATIBLE
- * would also reset the world transformation matrix to the unity
- * matrix. However, in Windows, this is not the case. This doesn't
- * make a lot of sense to me, but that's the way it is.
- */
-
- if ((Mode != GM_COMPATIBLE) && (Mode != GM_ADVANCED))
+ dc = DC_LockDc(hDC);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ pdcattr = dc->pdcattr;
+
+ if (Point)
{
- DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ _SEH2_TRY
+ {
+ ProbeForWrite(Point, sizeof(POINT), 1);
+ Point->x = pdcattr->ptlViewportOrg.x;
+ Point->y = pdcattr->ptlViewportOrg.y;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ DC_UnlockDc(dc);
+ return FALSE;
+ }
}
- ret = dc->w.GraphicsMode;
- dc->w.GraphicsMode = Mode;
- DC_UnlockDc(dc);
- return ret;
+ pdcattr->ptlViewportOrg.x = X;
+ pdcattr->ptlViewportOrg.y = Y;
+
+ DC_UpdateXforms(dc);
+ DC_UnlockDc(dc);
+
+ return TRUE;
}
-int
-STDCALL
-NtGdiSetMapMode(HDC hDC,
- int MapMode)
+BOOL
+APIENTRY
+NtGdiSetWindowOrgEx(
+ HDC hDC,
+ int X,
+ int Y,
+ LPPOINT Point)
{
- int PrevMapMode;
- PDC dc;
+ PDC dc;
+ PDC_ATTR pdcattr;
- dc = DC_LockDc(hDC);
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return 0;
- }
+ dc = DC_LockDc(hDC);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ pdcattr = dc->pdcattr;
- PrevMapMode = dc->w.MapMode;
+ if (Point)
+ {
+ NTSTATUS Status = STATUS_SUCCESS;
- if (MapMode != dc->w.MapMode || (MapMode != MM_ISOTROPIC && MapMode != MM_ANISOTROPIC))
- {
- dc->w.MapMode = MapMode;
+ _SEH2_TRY
+ {
+ ProbeForWrite(Point, sizeof(POINT), 1);
+ Point->x = pdcattr->ptlWindowOrg.x;
+ Point->y = pdcattr->ptlWindowOrg.y;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
- switch (MapMode)
- {
- case MM_TEXT:
- dc->wndExtX = 1;
- dc->wndExtY = 1;
- dc->vportExtX = 1;
- dc->vportExtY = 1;
- break;
-
- case MM_LOMETRIC:
- case MM_ISOTROPIC:
- dc->wndExtX = dc->GDIInfo->ulHorzSize * 10;
- dc->wndExtY = dc->GDIInfo->ulVertSize * 10;
- dc->vportExtX = dc->GDIInfo->ulHorzRes;
- dc->vportExtY = -dc->GDIInfo->ulVertRes;
- break;
-
- case MM_HIMETRIC:
- dc->wndExtX = dc->GDIInfo->ulHorzSize * 100;
- dc->wndExtY = dc->GDIInfo->ulVertSize * 100;
- dc->vportExtX = dc->GDIInfo->ulHorzRes;
- dc->vportExtY = -dc->GDIInfo->ulVertRes;
- break;
-
- case MM_LOENGLISH:
- dc->wndExtX = EngMulDiv(1000, dc->GDIInfo->ulHorzSize, 254);
- dc->wndExtY = EngMulDiv(1000, dc->GDIInfo->ulVertSize, 254);
- dc->vportExtX = dc->GDIInfo->ulHorzRes;
- dc->vportExtY = -dc->GDIInfo->ulVertRes;
- break;
-
- case MM_HIENGLISH:
- dc->wndExtX = EngMulDiv(10000, dc->GDIInfo->ulHorzSize, 254);
- dc->wndExtY = EngMulDiv(10000, dc->GDIInfo->ulVertSize, 254);
- dc->vportExtX = dc->GDIInfo->ulHorzRes;
- dc->vportExtY = -dc->GDIInfo->ulVertRes;
- break;
-
- case MM_TWIPS:
- dc->wndExtX = EngMulDiv(14400, dc->GDIInfo->ulHorzSize, 254);
- dc->wndExtY = EngMulDiv(14400, dc->GDIInfo->ulVertSize, 254);
- dc->vportExtX = dc->GDIInfo->ulHorzRes;
- dc->vportExtY = -dc->GDIInfo->ulVertRes;
- break;
-
- case MM_ANISOTROPIC:
- break;
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ DC_UnlockDc(dc);
+ return FALSE;
+ }
}
- DC_UpdateXforms(dc);
- }
+ pdcattr->ptlWindowOrg.x = X;
+ pdcattr->ptlWindowOrg.y = Y;
- DC_UnlockDc(dc);
+ DC_UpdateXforms(dc);
+ DC_UnlockDc(dc);
- return PrevMapMode;
+ return TRUE;
}
-BOOL
-STDCALL
-NtGdiSetViewportExtEx(HDC hDC,
- int XExtent,
- int YExtent,
- LPSIZE Size)
+//
+// Mirror Window function.
+//
+VOID
+FASTCALL
+IntMirrorWindowOrg(PDC dc)
{
- PDC dc;
+ PDC_ATTR pdcattr;
+ LONG X;
+
+ pdcattr = dc->pdcattr;
+
+ if (!(pdcattr->dwLayout & LAYOUT_RTL))
+ {
+ pdcattr->ptlWindowOrg.x = pdcattr->lWindowOrgx; // Flip it back.
+ return;
+ }
+ if (!pdcattr->szlViewportExt.cx) return;
+ //
+ // WOrgx = wox - (Width - 1) * WExtx / VExtx
+ //
+ X = (dc->erclWindow.right - dc->erclWindow.left) - 1; // Get device width - 1
- dc = DC_LockDc(hDC);
- if ( !dc )
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
+ X = (X * pdcattr->szlWindowExt.cx) / pdcattr->szlViewportExt.cx;
- switch (dc->w.MapMode)
+ pdcattr->ptlWindowOrg.x = pdcattr->lWindowOrgx - X; // Now set the inverted win origion.
+
+ return;
+}
+
+// NtGdiSetLayout
+//
+// The default is left to right. This function changes it to right to left, which
+// is the standard in Arabic and Hebrew cultures.
+//
+/*
+ * @implemented
+ */
+DWORD
+APIENTRY
+NtGdiSetLayout(
+ IN HDC hdc,
+ IN LONG wox,
+ IN DWORD dwLayout)
+{
+ PDC dc;
+ PDC_ATTR pdcattr;
+ DWORD oLayout;
+
+ dc = DC_LockDc(hdc);
+ if (!dc)
{
- case MM_HIENGLISH:
- case MM_HIMETRIC:
- case MM_LOENGLISH:
- case MM_LOMETRIC:
- case MM_TEXT:
- case MM_TWIPS:
- DC_UnlockDc(dc);
- return FALSE;
-
- case MM_ISOTROPIC:
- // Here we should (probably) check that SetWindowExtEx *really* has
- // been called
- break;
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return GDI_ERROR;
}
+ pdcattr = dc->pdcattr;
+
+ pdcattr->dwLayout = dwLayout;
+ oLayout = pdcattr->dwLayout;
- if (Size)
+ if (!(dwLayout & LAYOUT_ORIENTATIONMASK))
{
- NTSTATUS Status = STATUS_SUCCESS;
-
- _SEH_TRY
- {
- ProbeForWrite(Size,
- sizeof(SIZE),
- 1);
- Size->cx = dc->vportExtX;
- Size->cy = dc->vportExtY;
-
- dc->vportExtX = XExtent;
- dc->vportExtY = YExtent;
-
- if (dc->w.MapMode == MM_ISOTROPIC)
- IntFixIsotropicMapping(dc);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
DC_UnlockDc(dc);
- return FALSE;
- }
+ return oLayout;
}
-
- DC_UpdateXforms(dc);
- DC_UnlockDc(dc);
+ if (dwLayout & LAYOUT_RTL)
+ {
+ pdcattr->iMapMode = MM_ANISOTROPIC;
+ }
- return TRUE;
+ pdcattr->szlWindowExt.cy = -pdcattr->szlWindowExt.cy;
+ pdcattr->ptlWindowOrg.x = -pdcattr->ptlWindowOrg.x;
+
+ if (wox == -1)
+ IntMirrorWindowOrg(dc);
+ else
+ pdcattr->ptlWindowOrg.x = wox - pdcattr->ptlWindowOrg.x;
+
+ if (!(pdcattr->flTextAlign & TA_CENTER)) pdcattr->flTextAlign |= TA_RIGHT;
+
+ if (dc->dclevel.flPath & DCPATH_CLOCKWISE)
+ dc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
+ else
+ dc->dclevel.flPath |= DCPATH_CLOCKWISE;
+
+ pdcattr->flXform |= (PAGE_EXTENTS_CHANGED |
+ INVALIDATE_ATTRIBUTES |
+ DEVICE_TO_WORLD_INVALID);
+
+// DC_UpdateXforms(dc);
+ DC_UnlockDc(dc);
+ return oLayout;
}
-BOOL
-STDCALL
-NtGdiSetViewportOrgEx(HDC hDC,
- int X,
- int Y,
- LPPOINT Point)
+/*
+ * @implemented
+ */
+LONG
+APIENTRY
+NtGdiGetDeviceWidth(
+ IN HDC hdc)
{
- PDC dc;
+ PDC dc;
+ LONG Ret;
+ dc = DC_LockDc(hdc);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+ Ret = dc->erclWindow.right - dc->erclWindow.left;
+ DC_UnlockDc(dc);
+ return Ret;
+}
- dc = DC_LockDc(hDC);
- if (!dc)
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtGdiMirrorWindowOrg(
+ IN HDC hdc)
+{
+ PDC dc;
+ dc = DC_LockDc(hdc);
+ if (!dc)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
}
+ IntMirrorWindowOrg(dc);
+ DC_UnlockDc(dc);
+ return TRUE;
+}
- if (Point)
+/*
+ * @implemented
+ */
+BOOL
+APIENTRY
+NtGdiSetSizeDevice(
+ IN HDC hdc,
+ IN INT cxVirtualDevice,
+ IN INT cyVirtualDevice)
+{
+ PDC dc;
+ PDC_ATTR pdcattr;
+
+ if (!cxVirtualDevice || !cyVirtualDevice)
{
- NTSTATUS Status = STATUS_SUCCESS;
-
- _SEH_TRY
- {
- ProbeForWrite(Point,
- sizeof(POINT),
- 1);
- Point->x = dc->vportOrgX;
- Point->y = dc->vportOrgY;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- DC_UnlockDc(dc);
return FALSE;
- }
}
- dc->vportOrgX = X;
- dc->vportOrgY = Y;
+ dc = DC_LockDc(hdc);
+ if (!dc) return FALSE;
+
+ pdcattr = dc->pdcattr;
+
+ pdcattr->szlVirtualDeviceSize.cx = cxVirtualDevice;
+ pdcattr->szlVirtualDeviceSize.cy = cyVirtualDevice;
- DC_UpdateXforms(dc);
- DC_UnlockDc(dc);
+// DC_UpdateXforms(dc);
+ DC_UnlockDc(dc);
- return TRUE;
+ return TRUE;
}
+/*
+ * @implemented
+ */
BOOL
-STDCALL
-NtGdiSetWindowExtEx(HDC hDC,
- int XExtent,
- int YExtent,
- LPSIZE Size)
+APIENTRY
+NtGdiSetVirtualResolution(
+ IN HDC hdc,
+ IN INT cxVirtualDevicePixel,
+ IN INT cyVirtualDevicePixel,
+ IN INT cxVirtualDeviceMm,
+ IN INT cyVirtualDeviceMm)
+{
+ PDC dc;
+ PDC_ATTR pdcattr;
+
+ // Need test types for zeros and non zeros
+
+ dc = DC_LockDc(hdc);
+ if (!dc) return FALSE;
+
+ pdcattr = dc->pdcattr;
+
+ pdcattr->szlVirtualDevicePixel.cx = cxVirtualDevicePixel;
+ pdcattr->szlVirtualDevicePixel.cy = cyVirtualDevicePixel;
+ pdcattr->szlVirtualDeviceMm.cx = cxVirtualDeviceMm;
+ pdcattr->szlVirtualDeviceMm.cy = cyVirtualDeviceMm;
+
+// DC_UpdateXforms(dc);
+ DC_UnlockDc(dc);
+ return TRUE;
+}
+
+
+// FIXME: Don't use floating point in the kernel!
+BOOL FASTCALL
+DC_InvertXform(const XFORM *xformSrc,
+ XFORM *xformDest)
{
- PDC dc;
+ FLOAT determinant;
- dc = DC_LockDc(hDC);
- if (!dc)
+ determinant = xformSrc->eM11*xformSrc->eM22 - xformSrc->eM12*xformSrc->eM21;
+ if (determinant > -1e-12 && determinant < 1e-12)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
+ return FALSE;
}
- switch (dc->w.MapMode)
+ xformDest->eM11 = xformSrc->eM22 / determinant;
+ xformDest->eM12 = -xformSrc->eM12 / determinant;
+ xformDest->eM21 = -xformSrc->eM21 / determinant;
+ xformDest->eM22 = xformSrc->eM11 / determinant;
+ xformDest->eDx = -xformSrc->eDx * xformDest->eM11 - xformSrc->eDy * xformDest->eM21;
+ xformDest->eDy = -xformSrc->eDx * xformDest->eM12 - xformSrc->eDy * xformDest->eM22;
+
+ return TRUE;
+}
+
+
+// FIXME: Don't use floating point in the kernel!
+VOID FASTCALL
+DC_UpdateXforms(PDC dc)
+{
+ XFORM xformWnd2Vport;
+ DOUBLE scaleX, scaleY;
+ PDC_ATTR pdcattr = dc->pdcattr;
+ XFORM xformWorld2Vport, xformWorld2Wnd, xformVport2World;
+
+ /* Construct a transformation to do the window-to-viewport conversion */
+ scaleX = (pdcattr->szlWindowExt.cx ? (DOUBLE)pdcattr->szlViewportExt.cx / (DOUBLE)pdcattr->szlWindowExt.cx : 0.0f);
+ scaleY = (pdcattr->szlWindowExt.cy ? (DOUBLE)pdcattr->szlViewportExt.cy / (DOUBLE)pdcattr->szlWindowExt.cy : 0.0f);
+ xformWnd2Vport.eM11 = scaleX;
+ xformWnd2Vport.eM12 = 0.0;
+ xformWnd2Vport.eM21 = 0.0;
+ xformWnd2Vport.eM22 = scaleY;
+ xformWnd2Vport.eDx = (DOUBLE)pdcattr->ptlViewportOrg.x - scaleX * (DOUBLE)pdcattr->ptlWindowOrg.x;
+ xformWnd2Vport.eDy = (DOUBLE)pdcattr->ptlViewportOrg.y - scaleY * (DOUBLE)pdcattr->ptlWindowOrg.y;
+
+ /* Combine with the world transformation */
+ MatrixS2XForm(&xformWorld2Vport, &dc->dclevel.mxWorldToDevice);
+ MatrixS2XForm(&xformWorld2Wnd, &dc->dclevel.mxWorldToPage);
+ IntGdiCombineTransform(&xformWorld2Vport, &xformWorld2Wnd, &xformWnd2Vport);
+
+ /* Create inverse of world-to-viewport transformation */
+ MatrixS2XForm(&xformVport2World, &dc->dclevel.mxDeviceToWorld);
+ if (DC_InvertXform(&xformWorld2Vport, &xformVport2World))
+ {
+ pdcattr->flXform &= ~DEVICE_TO_WORLD_INVALID;
+ }
+ else
{
- case MM_HIENGLISH:
- case MM_HIMETRIC:
- case MM_LOENGLISH:
- case MM_LOMETRIC:
- case MM_TEXT:
- case MM_TWIPS:
- DC_UnlockDc(dc);
- return FALSE;
+ pdcattr->flXform |= DEVICE_TO_WORLD_INVALID;
}
- if (Size)
+ XForm2MatrixS(&dc->dclevel.mxWorldToDevice, &xformWorld2Vport);
+
+}
+
+LONG FASTCALL
+IntCalcFillOrigin(PDC pdc)
+{
+ pdc->ptlFillOrigin.x = pdc->dclevel.ptlBrushOrigin.x + pdc->ptlDCOrig.x;
+ pdc->ptlFillOrigin.y = pdc->dclevel.ptlBrushOrigin.y + pdc->ptlDCOrig.y;
+
+ return pdc->ptlFillOrigin.y;
+}
+
+VOID
+APIENTRY
+GdiSetDCOrg(HDC hDC, LONG Left, LONG Top, PRECTL prc)
+{
+ PDC pdc;
+
+ pdc = DC_LockDc(hDC);
+ if (!pdc) return;
+
+ pdc->ptlDCOrig.x = Left;
+ pdc->ptlDCOrig.y = Top;
+
+ IntCalcFillOrigin(pdc);
+
+ if (prc) pdc->erclWindow = *prc;
+
+ DC_UnlockDc(pdc);
+}
+
+// FIXME: remove me
+BOOL FASTCALL
+IntGdiGetDCOrg(PDC pDc, PPOINTL ppt)
+{
+ *ppt = pDc->ptlDCOrig;
+ return TRUE;
+}
+
+// FIXME: remove me
+BOOL APIENTRY
+GdiGetDCOrgEx(HDC hDC, PPOINTL ppt, PRECTL prc)
+{
+ PDC pdc;
+
+ pdc = DC_LockDc(hDC);
+ if (!pdc) return FALSE;
+
+ *prc = pdc->erclWindow;
+ *ppt = pdc->ptlDCOrig;
+
+ DC_UnlockDc(pdc);
+ return TRUE;
+}
+
+static
+VOID FASTCALL
+DC_vGetAspectRatioFilter(PDC pDC, LPSIZE AspectRatio)
+{
+ if (pDC->pdcattr->flFontMapper & 1) // TRUE assume 1.
{
- NTSTATUS Status = STATUS_SUCCESS;
-
- _SEH_TRY
- {
- ProbeForWrite(Size,
- sizeof(SIZE),
- 1);
- Size->cx = dc->wndExtX;
- Size->cy = dc->wndExtY;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- DC_UnlockDc(dc);
- return FALSE;
- }
+ // "This specifies that Windows should only match fonts that have the
+ // same aspect ratio as the display.", Programming Windows, Fifth Ed.
+ AspectRatio->cx = pDC->ppdev->GDIInfo.ulLogPixelsX;
+ AspectRatio->cy = pDC->ppdev->GDIInfo.ulLogPixelsY;
}
+ else
+ {
+ AspectRatio->cx = 0;
+ AspectRatio->cy = 0;
+ }
+}
+
+VOID
+FASTCALL
+DC_vUpdateViewportExt(PDC pdc)
+{
+ PDC_ATTR pdcattr;
- dc->wndExtX = XExtent;
- dc->wndExtY = YExtent;
+ /* Get a pointer to the dc attribute */
+ pdcattr = pdc->pdcattr;
- DC_UpdateXforms(dc);
- DC_UnlockDc(dc);
+ /* Check if we need to recalculate */
+ if (pdcattr->flXform & PAGE_EXTENTS_CHANGED)
+ {
+ /* Check if we need to do isotropic fixup */
+ if (pdcattr->iMapMode == MM_ISOTROPIC)
+ {
+ IntFixIsotropicMapping(pdc);
+ }
- return TRUE;
+ /* Update xforms, CHECKME: really done here? */
+ DC_UpdateXforms(pdc);
+ }
}
-BOOL
-STDCALL
-NtGdiSetWindowOrgEx(HDC hDC,
- int X,
- int Y,
- LPPOINT Point)
+BOOL APIENTRY
+NtGdiGetDCPoint(
+ HDC hDC,
+ UINT iPoint,
+ PPOINTL Point)
{
- PDC dc;
+ BOOL Ret = TRUE;
+ DC *pdc;
+ POINTL SafePoint;
+ SIZE Size;
+ NTSTATUS Status = STATUS_SUCCESS;
- dc = DC_LockDc(hDC);
- if (!dc)
+ if (!Point)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
- if (Point)
+ pdc = DC_LockDc(hDC);
+ if (!pdc)
{
- NTSTATUS Status = STATUS_SUCCESS;
-
- _SEH_TRY
- {
- ProbeForWrite(Point,
- sizeof(POINT),
- 1);
- Point->x = dc->wndOrgX;
- Point->y = dc->wndOrgY;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- DC_UnlockDc(dc);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
- }
}
- dc->wndOrgX = X;
- dc->wndOrgY = Y;
+ switch (iPoint)
+ {
+ case GdiGetViewPortExt:
+ DC_vUpdateViewportExt(pdc);
+ SafePoint.x = pdc->pdcattr->szlViewportExt.cx;
+ SafePoint.y = pdc->pdcattr->szlViewportExt.cy;
+ break;
+
+ case GdiGetWindowExt:
+ SafePoint.x = pdc->pdcattr->szlWindowExt.cx;
+ SafePoint.y = pdc->pdcattr->szlWindowExt.cy;
+ break;
+
+ case GdiGetViewPortOrg:
+ SafePoint = pdc->pdcattr->ptlViewportOrg;
+ break;
+
+ case GdiGetWindowOrg:
+ SafePoint = pdc->pdcattr->ptlWindowOrg;
+ break;
+
+ case GdiGetDCOrg:
+ SafePoint = pdc->ptlDCOrig;
+ break;
+
+ case GdiGetAspectRatioFilter:
+ DC_vGetAspectRatioFilter(pdc, &Size);
+ SafePoint.x = Size.cx;
+ SafePoint.y = Size.cy;
+ break;
+
+ default:
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ Ret = FALSE;
+ break;
+ }
- DC_UpdateXforms(dc);
- DC_UnlockDc(dc);
+ if (Ret)
+ {
+ _SEH2_TRY
+ {
+ ProbeForWrite(Point, sizeof(POINT), 1);
+ *Point = SafePoint;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
- return TRUE;
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ Ret = FALSE;
+ }
+ }
+
+ DC_UnlockDc(pdc);
+ return Ret;
}
-BOOL
-STDCALL
-NtGdiSetWorldTransform(HDC hDC,
- CONST LPXFORM XForm)
-{
- PDC dc;
- NTSTATUS Status = STATUS_SUCCESS;
-
- dc = DC_LockDc (hDC);
- if ( !dc )
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
- if (!XForm)
- {
- DC_UnlockDc(dc);
- /* Win doesn't set LastError */
- return FALSE;
- }
- /* Check that graphics mode is GM_ADVANCED */
- if ( dc->w.GraphicsMode != GM_ADVANCED )
- {
- DC_UnlockDc(dc);
- return FALSE;
- }
-
- _SEH_TRY
- {
- ProbeForRead(XForm,
- sizeof(XFORM),
- 1);
- dc->w.xformWorld2Wnd = *XForm;
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if(!NT_SUCCESS(Status))
- {
- DC_UnlockDc(dc);
- return FALSE;
- }
+DWORD
+APIENTRY
+NtGdiGetBoundsRect(
+ IN HDC hdc,
+ OUT LPRECT prc,
+ IN DWORD f)
+{
+ DPRINT1("stub\n");
+ return DCB_RESET; /* bounding rectangle always empty */
+}
- DC_UpdateXforms(dc);
- DC_UnlockDc(dc);
- return TRUE;
+DWORD
+APIENTRY
+NtGdiSetBoundsRect(
+ IN HDC hdc,
+ IN LPRECT prc,
+ IN DWORD f)
+{
+ DPRINT1("stub\n");
+ return DCB_DISABLE; /* bounding rectangle always empty */
}
+
/* EOF */