* Reorganize the whole ReactOS codebase into a new layout. Discussing it will only...
[reactos.git] / reactos / subsystems / win32 / win32k / objects / coord.c
diff --git a/reactos/subsystems/win32/win32k/objects/coord.c b/reactos/subsystems/win32/win32k/objects/coord.c
deleted file mode 100644 (file)
index cf01ab7..0000000
+++ /dev/null
@@ -1,1321 +0,0 @@
-/*
- * COPYRIGHT:        GNU GPL, See COPYING in the top level directory
- * PROJECT:          ReactOS kernel
- * PURPOSE:          Coordinate systems
- * FILE:             subsystems/win32/win32k/objects/coord.c
- * PROGRAMER:        Timo Kreuzer (timo.kreuzer@rectos.org)
- */
-
-/* Coordinate translation overview
- * -------------------------------
- *
- * Windows uses 3 different coordinate systems, referred to as world space,
- * page space and device space.
- *
- * Device space:
- * This is the coordinate system of the physical device that displays the
- * graphics. One unit matches one pixel of the surface. The coordinate system
- * is always orthogonal.
- *
- * Page space:
- * This is the coordinate system on the screen or on the paper layout for
- * printer devices. The coordinate system is also orthogonal but one unit
- * does not neccesarily match one pixel. Instead there are different mapping
- * modes that can be set using SetMapMode() that specify how page space units
- * are transformed into device space units. These mapping modes are:
- * - MM_TEXT: One unit matches one unit in device space (one pixel)
- * - MM_TWIPS One unit matches 1/20 point (1/1440 inch)
- * - MM_LOMETRIC: One unit matches 0.1 millimeter
- * - MM_HIMETRIC: One unit matches 0.01 millimeter
- * - MM_LOENGLISH: One unit matches 0.01 inch
- * - MM_HIENGLISH: One unit matches 0.001 inch
- * - MM_ISOTROPIC:
- * - MM_ANISOTROPIC:
- * If the mapping mode is either MM_ISOTROPIC or MM_ANISOTROPIC, the actual
- * transormation is calculated from the window and viewport extension.
- * The window extension can be set using SetWindowExtEx() and describes the
- * extents of an arbitrary window (not to confuse with the gui element!) in
- * page space coordinates.
- * The viewport extension can be set using SetViewportExtEx() and describes
- * the extent of the same window in device space coordinates. If the mapping
- * mode is MM_ISOTROPIC one of the viewport extensions can be adjusted by GDI
- * to make sure the mapping stays isotropic, that is it has the same x/y ratio
- * as the window extension.
- *
- * World space:
- * World space is the coordinate system that is used for all GDI drawing
- * operations. The metrics of this coordinate system depend on the DCs
- * graphics mode, which can be set using SetGraphicsMode().
- * If the graphics mode is GM_COMPATIBLE, world space is identical to page
- * space and no additional transformation is applied.
- * If the graphics mode is GM_ADVANCED, an arbitrary coordinate transformation
- * can be set using SetWorldTransform(), which is applied to transform world
- * space coordinates into page space coordinates.
- *
- * User mode data
- * All coordinate translation data is stored in the dc attribute, so the values
- * might be invalid. This has to be taken into account. Integer values might be
- * zero, so when a division is made, the value has to be read first and then
- * checked! For floating point values (FLOATOBJ as well) these restrictions do
- * not apply, since we cannot get dividy-by-zero exceptions.
- * Though the result might be a completely random and invalid value, if it was
- * messed with in an illegal way in user mode. This is not a problem, since the
- * result of coordinate transformations are never expected to be "valid" values.
- * In the worst case, the drawing operation draws rubbish into the DC.
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <win32k.h>
-
-#define NDEBUG
-#include <debug.h>
-C_ASSERT(sizeof(XFORML) == sizeof(XFORM));
-
-
-/* GLOBALS *******************************************************************/
-
-const MATRIX gmxIdentity =
-{
-    FLOATOBJ_1, FLOATOBJ_0,
-    FLOATOBJ_0, FLOATOBJ_1,
-    FLOATOBJ_0, FLOATOBJ_0,
-    0, 0, XFORM_NO_TRANSLATION|XFORM_FORMAT_LTOL|XFORM_UNITY|XFORM_SCALE
-};
-
-
-/* FUNCTIONS *****************************************************************/
-
-VOID
-FASTCALL
-DC_vFixIsotropicMapping(PDC pdc)
-{
-    PDC_ATTR pdcattr;
-    LONG64 fx, fy;
-    LONG s;
-    SIZEL szlWindowExt, szlViewportExt;
-    ASSERT(pdc->pdcattr->iMapMode == MM_ISOTROPIC);
-
-    /* Get a pointer to the DC_ATTR */
-    pdcattr = pdc->pdcattr;
-
-    /* Read the extents, we rely on non-null values */
-    szlWindowExt = pdcattr->szlWindowExt;
-    szlViewportExt = pdcattr->szlViewportExt;
-
-    /* Check if all values are valid */
-    if ((szlWindowExt.cx == 0) || (szlWindowExt.cy == 0) ||
-        (szlViewportExt.cx == 0) || (szlViewportExt.cy == 0))
-    {
-        /* Someone put rubbish into the fields, just ignore it. */
-        return;
-    }
-
-    fx = abs((LONG64)szlWindowExt.cx * szlViewportExt.cy);
-    fy = abs((LONG64)szlWindowExt.cy * szlViewportExt.cx);
-
-    if (fx < fy)
-    {
-        s = (szlWindowExt.cy ^ szlViewportExt.cx) > 0 ? 1 : -1;
-        pdcattr->szlViewportExt.cx = (LONG)(fx * s / szlWindowExt.cy);
-    }
-    else if (fx > fy)
-    {
-        s = (szlWindowExt.cx ^ szlViewportExt.cy) > 0 ? 1 : -1;
-        pdcattr->szlViewportExt.cy = (LONG)(fy * s / szlWindowExt.cx);
-    }
-
-    /* Reset the flag */
-    pdc->pdcattr->flXform &= ~PAGE_EXTENTS_CHANGED;
-}
-
-VOID
-FASTCALL
-DC_vGetPageToDevice(PDC pdc, MATRIX *pmx)
-{
-    PDC_ATTR pdcattr = pdc->pdcattr;
-    PSIZEL pszlViewPortExt;
-
-    /* Get the viewport extension */
-    pszlViewPortExt = DC_pszlViewportExt(pdc);
-
-    /* No shearing / rotation */
-    FLOATOBJ_SetLong(&pmx->efM12, 0);
-    FLOATOBJ_SetLong(&pmx->efM21, 0);
-
-    /* Calculate scaling */
-    if (pdcattr->szlWindowExt.cx != 0)
-    {
-        FLOATOBJ_SetLong(&pmx->efM11, pszlViewPortExt->cx);
-        FLOATOBJ_DivLong(&pmx->efM11, pdcattr->szlWindowExt.cx);
-    }
-    else
-        FLOATOBJ_SetLong(&pmx->efM11, 1);
-
-    if (pdcattr->szlWindowExt.cy != 0)
-    {
-        FLOATOBJ_SetLong(&pmx->efM22, pszlViewPortExt->cy);
-        FLOATOBJ_DivLong(&pmx->efM22, pdcattr->szlWindowExt.cy);
-    }
-    else
-        FLOATOBJ_SetLong(&pmx->efM22, 1);
-
-    /* Calculate x offset */
-    FLOATOBJ_SetLong(&pmx->efDx, -pdcattr->ptlWindowOrg.x);
-    FLOATOBJ_Mul(&pmx->efDx, &pmx->efM11);
-    FLOATOBJ_AddLong(&pmx->efDx, pdcattr->ptlViewportOrg.x);
-
-    /* Calculate y offset */
-    FLOATOBJ_SetLong(&pmx->efDy, -pdcattr->ptlWindowOrg.y);
-    FLOATOBJ_Mul(&pmx->efDy, &pmx->efM22);
-    FLOATOBJ_AddLong(&pmx->efDy, pdcattr->ptlViewportOrg.y);
-}
-
-VOID
-FASTCALL
-DC_vUpdateWorldToDevice(PDC pdc)
-{
-    XFORMOBJ xoPageToDevice, xoWorldToPage, xoWorldToDevice;
-    MATRIX mxPageToDevice;
-
-    // FIXME: make sure world-to-page is valid!
-
-    /* Construct a transformation to do the page-to-device conversion */
-    DC_vGetPageToDevice(pdc, &mxPageToDevice);
-    XFORMOBJ_vInit(&xoPageToDevice, &mxPageToDevice);
-
-    /* Recalculate the world-to-device xform */
-    XFORMOBJ_vInit(&xoWorldToPage, &pdc->pdcattr->mxWorldToPage);
-    XFORMOBJ_vInit(&xoWorldToDevice, &pdc->pdcattr->mxWorldToDevice);
-    XFORMOBJ_iCombine(&xoWorldToDevice, &xoWorldToPage, &xoPageToDevice);
-
-    /* Reset the flags */
-    pdc->pdcattr->flXform &= ~(PAGE_XLATE_CHANGED|PAGE_EXTENTS_CHANGED|WORLD_XFORM_CHANGED);
-}
-
-VOID
-FASTCALL
-DC_vUpdateDeviceToWorld(PDC pdc)
-{
-    XFORMOBJ xoWorldToDevice, xoDeviceToWorld;
-    PMATRIX pmxWorldToDevice;
-
-    /* Get the world-to-device translation */
-    pmxWorldToDevice = DC_pmxWorldToDevice(pdc);
-    XFORMOBJ_vInit(&xoWorldToDevice, pmxWorldToDevice);
-
-    /* Create inverse of world-to-device transformation */
-    XFORMOBJ_vInit(&xoDeviceToWorld, &pdc->pdcattr->mxDeviceToWorld);
-    if (XFORMOBJ_iInverse(&xoDeviceToWorld, &xoWorldToDevice) == DDI_ERROR)
-    {
-        // FIXME: do we need to reset anything?
-        return;
-    }
-
-    /* Reset the flag */
-    pdc->pdcattr->flXform &= ~DEVICE_TO_WORLD_INVALID;
-}
-
-BOOL
-NTAPI
-GreCombineTransform(
-    XFORML *pxformDest,
-    XFORML *pxform1,
-    XFORML *pxform2)
-{
-    MATRIX mxDest, mx1, mx2;
-    XFORMOBJ xoDest, xo1, xo2;
-
-    /* Check for illegal parameters */
-    if (!pxformDest || !pxform1 || !pxform2) return FALSE;
-
-    /* Initialize XFORMOBJs */
-    XFORMOBJ_vInit(&xoDest, &mxDest);
-    XFORMOBJ_vInit(&xo1, &mx1);
-    XFORMOBJ_vInit(&xo2, &mx2);
-
-    /* Convert the XFORMLs into XFORMOBJs */
-    XFORMOBJ_iSetXform(&xo1, pxform1);
-    XFORMOBJ_iSetXform(&xo2, pxform2);
-
-    /* Combine them */
-    XFORMOBJ_iCombine(&xoDest, &xo1, &xo2);
-
-    /* Translate back into XFORML */
-    XFORMOBJ_iGetXform(&xoDest, pxformDest);
-
-    return TRUE;
-}
-
-BOOL
-APIENTRY
-NtGdiCombineTransform(
-    LPXFORM UnsafeXFormResult,
-    LPXFORM Unsafexform1,
-    LPXFORM Unsafexform2)
-{
-    BOOL Ret;
-
-    _SEH2_TRY
-    {
-        ProbeForWrite(UnsafeXFormResult, sizeof(XFORM), 1);
-        ProbeForRead(Unsafexform1, sizeof(XFORM), 1);
-        ProbeForRead(Unsafexform2, sizeof(XFORM), 1);
-        Ret = GreCombineTransform((XFORML*)UnsafeXFormResult,
-                                  (XFORML*)Unsafexform1,
-                                  (XFORML*)Unsafexform2);
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        Ret = FALSE;
-    }
-    _SEH2_END;
-
-    return Ret;
-}
-
-// FIXME: Should be XFORML and use XFORMOBJ functions directly
-BOOL
-APIENTRY
-NtGdiGetTransform(
-    HDC hdc,
-    DWORD iXform,
-    LPXFORM pXForm)
-{
-    PDC pdc;
-    BOOL ret = TRUE;
-    MATRIX mxPageToDevice;
-    XFORMOBJ xo;
-    PMATRIX pmx;
-
-    if (!pXForm)
-    {
-        EngSetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    pdc = DC_LockDc(hdc);
-    if (!pdc)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-
-    switch (iXform)
-    {
-        case GdiWorldSpaceToPageSpace:
-            pmx = DC_pmxWorldToPage(pdc);
-            break;
-
-        case GdiWorldSpaceToDeviceSpace:
-            pmx = DC_pmxWorldToDevice(pdc);
-            break;
-
-        case GdiDeviceSpaceToWorldSpace:
-            pmx = DC_pmxDeviceToWorld(pdc);
-            break;
-
-        case GdiPageSpaceToDeviceSpace:
-            DC_vGetPageToDevice(pdc, &mxPageToDevice);
-            pmx = &mxPageToDevice;
-            break;
-
-        default:
-            DPRINT1("Unknown transform %lu\n", iXform);
-            ret = FALSE;
-            goto leave;
-    }
-
-    /* Initialize an XFORMOBJ */
-    XFORMOBJ_vInit(&xo, pmx);
-
-    _SEH2_TRY
-    {
-        ProbeForWrite(pXForm, sizeof(XFORML), 1);
-        XFORMOBJ_iGetXform(&xo, (XFORML*)pXForm);
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        ret = FALSE;
-    }
-    _SEH2_END;
-
-leave:
-    DC_UnlockDc(pdc);
-    return ret;
-}
-
-
-/*!
- * 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, FALSE otherwise.
-*/
-BOOL
-APIENTRY
-NtGdiTransformPoints(
-    HDC hDC,
-    PPOINT UnsafePtsIn,
-    PPOINT UnsafePtOut,
-    INT Count,
-    INT iMode)
-{
-    PDC pdc;
-    LPPOINT Points;
-    ULONG Size;
-    BOOL ret = TRUE;
-
-    if (Count <= 0)
-        return TRUE;
-
-    pdc = DC_LockDc(hDC);
-    if (!pdc)
-    {
-        EngSetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    Size = Count * sizeof(POINT);
-
-    // FIXME: It would be wise to have a small stack buffer as optimization
-    Points = ExAllocatePoolWithTag(PagedPool, Size, GDITAG_TEMP);
-    if (!Points)
-    {
-        DC_UnlockDc(pdc);
-        EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
-    }
-
-    _SEH2_TRY
-    {
-        ProbeForWrite(UnsafePtOut, Size, 1);
-        ProbeForRead(UnsafePtsIn, Size, 1);
-        RtlCopyMemory(Points, UnsafePtsIn, Size);
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        /* Do not set last error */
-        _SEH2_YIELD(goto leave;)
-    }
-    _SEH2_END;
-
-    switch (iMode)
-    {
-        case GdiDpToLp:
-            DC_vXformDeviceToWorld(pdc, Count, Points, Points);
-            break;
-
-        case GdiLpToDp:
-            DC_vXformWorldToDevice(pdc, Count, Points, Points);
-            break;
-
-        case 2: // Not supported yet. Need testing.
-        default:
-        {
-            EngSetLastError(ERROR_INVALID_PARAMETER);
-            ret = FALSE;
-            goto leave;
-        }
-    }
-
-    _SEH2_TRY
-    {
-        /* Pointer was already probed! */
-        RtlCopyMemory(UnsafePtOut, Points, Size);
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        /* Do not set last error */
-    }
-    _SEH2_END;
-
-//
-// If we are getting called that means User XForms is a mess!
-//
-leave:
-    DC_UnlockDc(pdc);
-    ExFreePoolWithTag(Points, GDITAG_TEMP);
-    return ret;
-}
-
-BOOL
-NTAPI
-GreModifyWorldTransform(
-    PDC pdc,
-    const XFORML *pxform,
-    DWORD dwMode)
-{
-    MATRIX mxSrc;
-    XFORMOBJ xoSrc, xoDC;
-
-    switch (dwMode)
-    {
-        case MWT_IDENTITY:
-            pdc->pdcattr->mxWorldToPage = gmxIdentity;
-            break;
-
-        case MWT_LEFTMULTIPLY:
-            XFORMOBJ_vInit(&xoDC, &pdc->pdcattr->mxWorldToPage);
-            XFORMOBJ_vInit(&xoSrc, &mxSrc);
-            XFORMOBJ_iSetXform(&xoSrc, pxform);
-            XFORMOBJ_iCombine(&xoDC, &xoSrc, &xoDC);
-            break;
-
-        case MWT_RIGHTMULTIPLY:
-            XFORMOBJ_vInit(&xoDC, &pdc->pdcattr->mxWorldToPage);
-            XFORMOBJ_vInit(&xoSrc, &mxSrc);
-            XFORMOBJ_iSetXform(&xoSrc, pxform);
-            XFORMOBJ_iCombine(&xoDC, &xoDC, &xoSrc);
-            break;
-
-        case MWT_MAX+1: // Must be MWT_SET????
-            XFORMOBJ_vInit(&xoDC, &pdc->pdcattr->mxWorldToPage);
-            XFORMOBJ_iSetXform(&xoDC, pxform);
-            break;
-
-        default:
-            return FALSE;
-    }
-
-    /*Set invalidation flags */
-    pdc->pdcattr->flXform |= WORLD_XFORM_CHANGED|DEVICE_TO_WORLD_INVALID;
-
-    return TRUE;
-}
-
-BOOL
-APIENTRY
-NtGdiModifyWorldTransform(
-    HDC hdc,
-    LPXFORM pxformUnsafe,
-    DWORD dwMode)
-{
-    PDC pdc;
-    XFORML xformSafe;
-    BOOL Ret = TRUE;
-
-    pdc = DC_LockDc(hdc);
-    if (!pdc)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-
-    /* 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 (pxformUnsafe != NULL || dwMode != MWT_IDENTITY)
-    {
-        _SEH2_TRY
-        {
-            ProbeForRead(pxformUnsafe, sizeof(XFORML), 1);
-            RtlCopyMemory(&xformSafe, pxformUnsafe, sizeof(XFORML));
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            Ret = FALSE;
-        }
-        _SEH2_END;
-    }
-
-    /* Safe to handle kernel mode data. */
-    if (Ret) Ret = GreModifyWorldTransform(pdc, &xformSafe, dwMode);
-    DC_UnlockDc(pdc);
-    return Ret;
-}
-
-BOOL
-APIENTRY
-NtGdiOffsetViewportOrgEx(
-    HDC hDC,
-    int XOffset,
-    int YOffset,
-    LPPOINT UnsafePoint)
-{
-    PDC      dc;
-    PDC_ATTR pdcattr;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    dc = DC_LockDc(hDC);
-    if (!dc)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    pdcattr = dc->pdcattr;
-
-    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;
-
-        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;
-    pdcattr->flXform |= PAGE_XLATE_CHANGED;
-
-    DC_UnlockDc(dc);
-
-    return TRUE;
-}
-
-BOOL
-APIENTRY
-NtGdiOffsetWindowOrgEx(
-    HDC hDC,
-    int XOffset,
-    int YOffset,
-    LPPOINT Point)
-{
-    PDC dc;
-    PDC_ATTR pdcattr;
-
-    dc = DC_LockDc(hDC);
-    if (!dc)
-    {
-        EngSetLastError(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;
-    pdcattr->flXform |= PAGE_XLATE_CHANGED;
-
-    DC_UnlockDc(dc);
-
-    return TRUE;
-}
-
-BOOL
-APIENTRY
-NtGdiScaleViewportExtEx(
-    HDC hDC,
-    int Xnum,
-    int Xdenom,
-    int Ynum,
-    int Ydenom,
-    LPSIZE pSize)
-{
-    PDC pDC;
-    PDC_ATTR pdcattr;
-    BOOL Ret = FALSE;
-    LONG X, Y;
-
-    pDC = DC_LockDc(hDC);
-    if (!pDC)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    pdcattr = pDC->pdcattr;
-
-    if (pdcattr->iMapMode > MM_TWIPS)
-    {
-        if (Xdenom && Ydenom)
-        {
-            DC_pszlViewportExt(pDC);
-            X = Xnum * pdcattr->szlViewportExt.cx / Xdenom;
-            if (X)
-            {
-                Y = Ynum * pdcattr->szlViewportExt.cy / Ydenom;
-                if (Y)
-                {
-                    pdcattr->szlViewportExt.cx = X;
-                    pdcattr->szlViewportExt.cy = Y;
-                    pdcattr->flXform |= PAGE_XLATE_CHANGED;
-
-                    IntMirrorWindowOrg(pDC);
-
-                    pdcattr->flXform |= (PAGE_EXTENTS_CHANGED |
-                                         INVALIDATE_ATTRIBUTES |
-                                         DEVICE_TO_WORLD_INVALID);
-
-                    if (pdcattr->iMapMode == MM_ISOTROPIC)
-                    {
-                        DC_vFixIsotropicMapping(pDC);
-                    }
-
-                    Ret = TRUE;
-                }
-            }
-        }
-    }
-    else
-        Ret = TRUE;
-
-    if (pSize)
-    {
-        _SEH2_TRY
-        {
-            ProbeForWrite(pSize, sizeof(SIZE), 1);
-
-            pSize->cx = pdcattr->szlViewportExt.cx;
-            pSize->cy = pdcattr->szlViewportExt.cy;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            SetLastNtError(_SEH2_GetExceptionCode());
-            Ret = FALSE;
-        }
-        _SEH2_END;
-    }
-
-    DC_UnlockDc(pDC);
-    return Ret;
-}
-
-BOOL
-APIENTRY
-NtGdiScaleWindowExtEx(
-    HDC hDC,
-    int Xnum,
-    int Xdenom,
-    int Ynum,
-    int Ydenom,
-    LPSIZE pSize)
-{
-    PDC pDC;
-    PDC_ATTR pdcattr;
-    BOOL Ret = FALSE;
-    LONG X, Y;
-
-    pDC = DC_LockDc(hDC);
-    if (!pDC)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    pdcattr = pDC->pdcattr;
-
-    if (pSize)
-    {
-        NTSTATUS Status = STATUS_SUCCESS;
-
-        _SEH2_TRY
-        {
-            ProbeForWrite(pSize, sizeof(SIZE), 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;
-        }
-    }
-
-    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);
-
-                    Ret = TRUE;
-                }
-            }
-        }
-    }
-    else
-        Ret = TRUE;
-
-    DC_UnlockDc(pDC);
-    return Ret;
-}
-
-int
-APIENTRY
-IntGdiSetMapMode(
-    PDC dc,
-    int MapMode)
-{
-    int PrevMapMode;
-    PDC_ATTR pdcattr = dc->pdcattr;
-
-    PrevMapMode = pdcattr->iMapMode;
-
-    pdcattr->iMapMode = MapMode;
-    pdcattr->flXform &= ~(ISO_OR_ANISO_MAP_MODE|PTOD_EFM22_NEGATIVE|
-        PTOD_EFM11_NEGATIVE|POSITIVE_Y_IS_UP|PAGE_TO_DEVICE_SCALE_IDENTITY|
-        PAGE_TO_DEVICE_IDENTITY);
-
-    switch (MapMode)
-    {
-        case MM_TEXT:
-            pdcattr->szlWindowExt.cx = 1;
-            pdcattr->szlWindowExt.cy = 1;
-            pdcattr->szlViewportExt.cx = 1;
-            pdcattr->szlViewportExt.cy = 1;
-            pdcattr->flXform |= PAGE_TO_DEVICE_SCALE_IDENTITY;
-            break;
-
-        case MM_ISOTROPIC:
-            pdcattr->flXform |= ISO_OR_ANISO_MAP_MODE;
-            /* Fall through */
-
-        case MM_LOMETRIC:
-            pdcattr->szlWindowExt.cx = pdcattr->szlVirtualDeviceMm.cx * 10;
-            pdcattr->szlWindowExt.cy = pdcattr->szlVirtualDeviceMm.cy * 10;
-            pdcattr->szlViewportExt.cx =  pdcattr->szlVirtualDevicePixel.cx;
-            pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
-            break;
-
-        case MM_HIMETRIC:
-            pdcattr->szlWindowExt.cx = pdcattr->szlVirtualDeviceMm.cx * 100;
-            pdcattr->szlWindowExt.cy = pdcattr->szlVirtualDeviceMm.cy * 100;
-            pdcattr->szlViewportExt.cx =  pdcattr->szlVirtualDevicePixel.cx;
-            pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
-            break;
-
-        case MM_LOENGLISH:
-            pdcattr->szlWindowExt.cx = MulDiv(1000, pdcattr->szlVirtualDeviceMm.cx, 254);
-            pdcattr->szlWindowExt.cy = MulDiv(1000, pdcattr->szlVirtualDeviceMm.cy, 254);
-            pdcattr->szlViewportExt.cx =  pdcattr->szlVirtualDevicePixel.cx;
-            pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
-            break;
-
-        case MM_HIENGLISH:
-            pdcattr->szlWindowExt.cx = MulDiv(10000, pdcattr->szlVirtualDeviceMm.cx, 254);
-            pdcattr->szlWindowExt.cy = MulDiv(10000, pdcattr->szlVirtualDeviceMm.cy, 254);
-            pdcattr->szlViewportExt.cx =  pdcattr->szlVirtualDevicePixel.cx;
-            pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
-            break;
-
-        case MM_TWIPS:
-            pdcattr->szlWindowExt.cx = MulDiv(14400, pdcattr->szlVirtualDeviceMm.cx, 254);
-            pdcattr->szlWindowExt.cy = MulDiv(14400, pdcattr->szlVirtualDeviceMm.cy, 254);
-            pdcattr->szlViewportExt.cx =  pdcattr->szlVirtualDevicePixel.cx;
-            pdcattr->szlViewportExt.cy = -pdcattr->szlVirtualDevicePixel.cy;
-            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;
-    }
-
-    pdcattr->flXform |= (PAGE_XLATE_CHANGED|PAGE_EXTENTS_CHANGED|
-        INVALIDATE_ATTRIBUTES|DEVICE_TO_PAGE_INVALID|DEVICE_TO_WORLD_INVALID);
-
-    return PrevMapMode;
-}
-
-
-BOOL
-APIENTRY
-NtGdiSetViewportOrgEx(
-    HDC hDC,
-    int X,
-    int Y,
-    LPPOINT Point)
-{
-    PDC dc;
-    PDC_ATTR pdcattr;
-
-    dc = DC_LockDc(hDC);
-    if (!dc)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    pdcattr = dc->pdcattr;
-
-    if (Point)
-    {
-        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;
-        }
-    }
-
-    pdcattr->ptlViewportOrg.x = X;
-    pdcattr->ptlViewportOrg.y = Y;
-    pdcattr->flXform |= PAGE_XLATE_CHANGED;
-
-    DC_UnlockDc(dc);
-
-    return TRUE;
-}
-
-BOOL
-APIENTRY
-NtGdiSetWindowOrgEx(
-    HDC hDC,
-    int X,
-    int Y,
-    LPPOINT Point)
-{
-    PDC dc;
-    PDC_ATTR pdcattr;
-
-    dc = DC_LockDc(hDC);
-    if (!dc)
-    {
-        EngSetLastError(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 = X;
-    pdcattr->ptlWindowOrg.y = Y;
-    pdcattr->flXform |= PAGE_XLATE_CHANGED;
-
-    DC_UnlockDc(dc);
-
-    return TRUE;
-}
-
-//
-// Mirror Window function.
-//
-VOID
-FASTCALL
-IntMirrorWindowOrg(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
-
-    X = (X * pdcattr->szlWindowExt.cx) / pdcattr->szlViewportExt.cx;
-
-    pdcattr->ptlWindowOrg.x = pdcattr->lWindowOrgx - X; // Now set the inverted win origion.
-    pdcattr->flXform |= PAGE_XLATE_CHANGED;
-
-    return;
-}
-
-VOID
-NTAPI
-DC_vSetLayout(
-    IN PDC pdc,
-    IN LONG wox,
-    IN DWORD dwLayout)
-{
-    PDC_ATTR pdcattr = pdc->pdcattr;
-
-    pdcattr->dwLayout = dwLayout;
-
-    if (!(dwLayout & LAYOUT_ORIENTATIONMASK)) return;
-
-    if (dwLayout & LAYOUT_RTL)
-    {
-        pdcattr->iMapMode = MM_ANISOTROPIC;
-    }
-
-    //pdcattr->szlWindowExt.cy = -pdcattr->szlWindowExt.cy;
-    //pdcattr->ptlWindowOrg.x  = -pdcattr->ptlWindowOrg.x;
-
-    //if (wox == -1)
-    //    IntMirrorWindowOrg(pdc);
-    //else
-    //    pdcattr->ptlWindowOrg.x = wox - pdcattr->ptlWindowOrg.x;
-
-    if (!(pdcattr->flTextAlign & TA_CENTER)) pdcattr->flTextAlign |= TA_RIGHT;
-
-    if (pdc->dclevel.flPath & DCPATH_CLOCKWISE)
-        pdc->dclevel.flPath &= ~DCPATH_CLOCKWISE;
-    else
-        pdc->dclevel.flPath |= DCPATH_CLOCKWISE;
-
-    pdcattr->flXform |= (PAGE_EXTENTS_CHANGED |
-                         INVALIDATE_ATTRIBUTES |
-                         DEVICE_TO_WORLD_INVALID);
-
-//  DC_UpdateXforms(pdc);
-}
-
-// 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 pdc;
-    DWORD dwOldLayout;
-
-    pdc = DC_LockDc(hdc);
-    if (!pdc)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return GDI_ERROR;
-    }
-
-    dwOldLayout = pdc->pdcattr->dwLayout;
-    DC_vSetLayout(pdc, wox, dwLayout);
-
-    DC_UnlockDc(pdc);
-    return dwOldLayout;
-}
-
-/*
- * @implemented
- */
-LONG
-APIENTRY
-NtGdiGetDeviceWidth(
-    IN HDC hdc)
-{
-    PDC dc;
-    LONG Ret;
-    dc = DC_LockDc(hdc);
-    if (!dc)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return 0;
-    }
-    Ret = dc->erclWindow.right - dc->erclWindow.left;
-    DC_UnlockDc(dc);
-    return Ret;
-}
-
-/*
- * @implemented
- */
-BOOL
-APIENTRY
-NtGdiMirrorWindowOrg(
-    IN HDC hdc)
-{
-    PDC dc;
-    dc = DC_LockDc(hdc);
-    if (!dc)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    IntMirrorWindowOrg(dc);
-    DC_UnlockDc(dc);
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-BOOL
-APIENTRY
-NtGdiSetSizeDevice(
-    IN HDC hdc,
-    IN INT cxVirtualDevice,
-    IN INT cyVirtualDevice)
-{
-    PDC dc;
-    PDC_ATTR pdcattr;
-
-    if (!cxVirtualDevice || !cyVirtualDevice)
-    {
-        return FALSE;
-    }
-
-    dc = DC_LockDc(hdc);
-    if (!dc) return FALSE;
-
-    pdcattr = dc->pdcattr;
-
-    pdcattr->szlVirtualDeviceSize.cx = cxVirtualDevice;
-    pdcattr->szlVirtualDeviceSize.cy = cyVirtualDevice;
-
-    DC_UnlockDc(dc);
-
-    return TRUE;
-}
-
-/*
- * @implemented
- */
-BOOL
-APIENTRY
-NtGdiSetVirtualResolution(
-    IN HDC hdc,
-    IN INT cxVirtualDevicePixel,
-    IN INT cyVirtualDevicePixel,
-    IN INT cxVirtualDeviceMm,
-    IN INT cyVirtualDeviceMm)
-{
-    PDC dc;
-    PDC_ATTR pdcattr;
-
-    /* Check parameters (all zeroes resets to real resolution) */
-    if (cxVirtualDevicePixel == 0 && cyVirtualDevicePixel == 0 &&
-        cxVirtualDeviceMm == 0 && cyVirtualDeviceMm == 0)
-    {
-        cxVirtualDevicePixel = NtGdiGetDeviceCaps(hdc, HORZRES);
-        cyVirtualDevicePixel = NtGdiGetDeviceCaps(hdc, VERTRES);
-        cxVirtualDeviceMm = NtGdiGetDeviceCaps(hdc, HORZSIZE);
-        cyVirtualDeviceMm = NtGdiGetDeviceCaps(hdc, VERTSIZE);
-    }
-    else if (cxVirtualDevicePixel == 0 || cyVirtualDevicePixel == 0 ||
-             cxVirtualDeviceMm == 0 || cyVirtualDeviceMm == 0)
-    {
-        return FALSE;
-    }
-
-    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_vUpdateXforms(dc);
-    DC_UnlockDc(dc);
-    return TRUE;
-}
-
-PPOINTL
-FASTCALL
-IntptlBrushOrigin(PDC pdc, LONG x, LONG y )
-{
-    pdc->dclevel.ptlBrushOrigin.x = x;
-    pdc->dclevel.ptlBrushOrigin.y = y;
-    pdc->ptlFillOrigin.x = pdc->dclevel.ptlBrushOrigin.x + pdc->ptlDCOrig.x;
-    pdc->ptlFillOrigin.y = pdc->dclevel.ptlBrushOrigin.y + pdc->ptlDCOrig.y;
-    return &pdc->dclevel.ptlBrushOrigin;
-}
-
-static
-VOID FASTCALL
-DC_vGetAspectRatioFilter(PDC pDC, LPSIZE AspectRatio)
-{
-    if (pDC->pdcattr->flFontMapper & 1) // TRUE assume 1.
-    {
-        // "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;
-    }
-}
-
-BOOL APIENTRY
-NtGdiGetDCPoint(
-    HDC hDC,
-    UINT iPoint,
-    PPOINTL Point)
-{
-    BOOL Ret = TRUE;
-    DC *pdc;
-    POINTL SafePoint;
-    SIZE Size;
-    PSIZEL pszlViewportExt;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    if (!Point)
-    {
-        EngSetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    pdc = DC_LockDc(hDC);
-    if (!pdc)
-    {
-        EngSetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-
-    switch (iPoint)
-    {
-        case GdiGetViewPortExt:
-            pszlViewportExt = DC_pszlViewportExt(pdc);
-            SafePoint.x = pszlViewportExt->cx;
-            SafePoint.y = pszlViewportExt->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:
-            EngSetLastError(ERROR_INVALID_PARAMETER);
-            Ret = FALSE;
-            break;
-    }
-
-    if (Ret)
-    {
-        _SEH2_TRY
-        {
-            ProbeForWrite(Point, sizeof(POINT), 1);
-            *Point = SafePoint;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            Status = _SEH2_GetExceptionCode();
-        }
-        _SEH2_END;
-
-        if (!NT_SUCCESS(Status))
-        {
-            SetLastNtError(Status);
-            Ret = FALSE;
-        }
-    }
-
-    DC_UnlockDc(pdc);
-    return Ret;
-}
-
-/* EOF */