[NtGDI] Fix ExtSelectClipRgn Tests
authorjimtabor <james.tabor@reactos.org>
Thu, 9 May 2019 17:33:21 +0000 (12:33 -0500)
committerjimtabor <james.tabor@reactos.org>
Thu, 9 May 2019 17:33:21 +0000 (12:33 -0500)
Fix results from tests, add (last one) gdi batch support for
ExtSelectClipRgn. Left commented out test code in tree this time.
Pass Katayama Hirofumi MZ SelectClipRgn tests. After commit will plug in
the last batch. After 12 years.

See CORE-13817 and CORE-15906.

win32ss/gdi/ntgdi/cliprgn.c
win32ss/gdi/ntgdi/cliprgn.h
win32ss/gdi/ntgdi/dclife.c
win32ss/gdi/ntgdi/dcstate.c
win32ss/gdi/ntgdi/dcutil.c
win32ss/gdi/ntgdi/fillshap.c
win32ss/gdi/ntgdi/gdibatch.c
win32ss/gdi/ntgdi/line.c

index 2f4f53c..566ce3f 100644 (file)
@@ -18,25 +18,40 @@ IntGdiReleaseRaoRgn(PDC pDC)
     INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
     PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
     pDC->fs |= DC_FLAG_DIRTY_RAO;
     INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
     PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
     pDC->fs |= DC_FLAG_DIRTY_RAO;
-    Entry->Flags |= GDI_ENTRY_VALIDATE_VIS;
-    RECTL_vSetEmptyRect(&pDC->erclClip);
-    REGION_Delete(pDC->prgnRao);
-    pDC->prgnRao = NULL;
+    Entry->Flags |= GDI_ENTRY_VALIDATE_VIS; // Need to validate Vis.
 }
 
 VOID
 FASTCALL
 IntGdiReleaseVisRgn(PDC pDC)
 {
 }
 
 VOID
 FASTCALL
 IntGdiReleaseVisRgn(PDC pDC)
 {
-    INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr);
-    PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index];
-    pDC->fs |= DC_FLAG_DIRTY_RAO;
-    Entry->Flags |= GDI_ENTRY_VALIDATE_VIS;
-    RECTL_vSetEmptyRect(&pDC->erclClip);
+    IntGdiReleaseRaoRgn(pDC);
     REGION_Delete(pDC->prgnVis);
     REGION_Delete(pDC->prgnVis);
-    pDC->prgnVis = prgnDefault;
+    pDC->prgnVis = prgnDefault; // Vis can not be NULL!!!
 }
 
 }
 
+//
+// Updating Vis Region Attribute the for DC Attributes.
+// BTW: This system region has an user attribute for it.
+//
+VOID
+FASTCALL
+UpdateVisRgn(
+    PDC pdc)
+{
+    INT Index = GDI_HANDLE_GET_INDEX(pdc->BaseObject.hHmgr);
+    PGDI_TABLE_ENTRY pEntry = &GdiHandleTable->Entries[Index];
+
+    /* Setup Vis Region Attribute information to User side */
+    pEntry->Flags |= GDI_ENTRY_VALIDATE_VIS;
+    pdc->pdcattr->VisRectRegion.iComplexity = REGION_GetRgnBox(pdc->prgnVis, &pdc->pdcattr->VisRectRegion.Rect);
+    pdc->pdcattr->VisRectRegion.AttrFlags = ATTR_RGN_VALID;
+    pEntry->Flags &= ~GDI_ENTRY_VALIDATE_VIS;
+}
+
+//
+//  Selecting Vis Region.
+//
 VOID
 FASTCALL
 GdiSelectVisRgn(
 VOID
 FASTCALL
 GdiSelectVisRgn(
@@ -51,61 +66,241 @@ GdiSelectVisRgn(
         return;
     }
 
         return;
     }
 
+    if (!prgn)
+    {
+       DPRINT1("SVR: Setting NULL Region\n");
+       IntGdiReleaseVisRgn(dc);
+       IntSetDefaultRegion(dc);
+       DC_UnlockDc(dc);
+       return;
+    }
+
     dc->fs |= DC_FLAG_DIRTY_RAO;
 
     ASSERT(dc->prgnVis != NULL);
     ASSERT(prgn != NULL);
 
     dc->fs |= DC_FLAG_DIRTY_RAO;
 
     ASSERT(dc->prgnVis != NULL);
     ASSERT(prgn != NULL);
 
-    IntGdiCombineRgn(dc->prgnVis, prgn, NULL, RGN_COPY);
+    REGION_bCopy(dc->prgnVis, prgn);
     REGION_bOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
 
     DC_UnlockDc(dc);
 }
 
     REGION_bOffsetRgn(dc->prgnVis, -dc->ptlDCOrig.x, -dc->ptlDCOrig.y);
 
     DC_UnlockDc(dc);
 }
 
-
+_Success_(return!=ERROR)
 int
 FASTCALL
 int
 FASTCALL
-IntGdiExtSelectClipRgn(
-    PDC dc,
-    PREGION prgn,
-    int fnMode)
+IntSelectClipRgn(
+    _In_ PDC dc,
+    _In_ PREGION prgn,
+    _In_ int fnMode)
 {
 {
-    if (fnMode == RGN_COPY)
+    int Ret = ERROR;
+    PREGION prgnNClip, prgnOrigClip = dc->dclevel.prgnClip;
+
+    //
+    // No Coping Regions and no intersecting Regions or an User calling w NULL Region or have the Original Clip Region.
+    //
+    if (fnMode != RGN_COPY && (fnMode != RGN_AND || !prgn || prgnOrigClip))
     {
     {
-        if (!prgn)
+        prgnNClip = IntSysCreateRectpRgn(0, 0, 0, 0);
+
+        // Have Original Clip Region.
+        if (prgnOrigClip)
+        {
+           // This will fail on NULL prgn.
+           Ret = IntGdiCombineRgn(prgnNClip, prgnOrigClip, prgn, fnMode);
+
+           if (Ret)
+           {
+              REGION_Delete(prgnOrigClip);
+              dc->dclevel.prgnClip = prgnNClip;
+              IntGdiReleaseRaoRgn(dc);
+           }
+           else
+              REGION_Delete(prgnNClip);
+        }
+        else // NULL Original Clip Region, setup a new one and process mode.
         {
         {
-            if (dc->dclevel.prgnClip != NULL)
+            PREGION prgnClip;
+            RECTL rcl;
+            PSURFACE pSurface;
+
+            // See IntSetDefaultRegion.
+
+            rcl.left   = 0;
+            rcl.top    = 0;
+            rcl.right  = dc->dclevel.sizl.cx;
+            rcl.bottom = dc->dclevel.sizl.cy;
+
+            //EngAcquireSemaphoreShared(pdc->ppdev->hsemDevLock);
+            if (dc->ppdev->flFlags & PDEV_META_DEVICE)
+            {
+                pSurface = dc->dclevel.pSurface;
+                if (pSurface && pSurface->flags & PDEV_SURFACE)
+                {
+                   rcl.left   += dc->ppdev->ptlOrigion.x;
+                   rcl.top    += dc->ppdev->ptlOrigion.y;
+                   rcl.right  += dc->ppdev->ptlOrigion.x;
+                   rcl.bottom += dc->ppdev->ptlOrigion.y;
+                }
+            }
+            //EngReleaseSemaphore(pdc->ppdev->hsemDevLock);
+
+            rcl.left   += dc->ptlDCOrig.x;
+            rcl.top    += dc->ptlDCOrig.y;
+            rcl.right  += dc->ptlDCOrig.x;
+            rcl.bottom += dc->ptlDCOrig.y;
+
+            prgnClip = IntSysCreateRectpRgnIndirect(&rcl);
+
+            Ret = IntGdiCombineRgn(prgnNClip, prgnClip, prgn, fnMode);
+
+            if (Ret)
             {
             {
-                REGION_Delete(dc->dclevel.prgnClip);
-                dc->dclevel.prgnClip = NULL;
-                dc->fs |= DC_FLAG_DIRTY_RAO;
+                dc->dclevel.prgnClip = prgnNClip;
+                IntGdiReleaseRaoRgn(dc);
             }
             }
-            return SIMPLEREGION;
+            else
+                REGION_Delete(prgnNClip);
+
+            REGION_Delete(prgnClip);
         }
         }
+        return Ret;
+    }
 
 
-        if (!dc->dclevel.prgnClip)
-            dc->dclevel.prgnClip = IntSysCreateRectpRgn(0, 0, 0, 0);
+    // Fall through to normal RectOS mode.
 
 
-        dc->fs |= DC_FLAG_DIRTY_RAO;
+    //
+    // Handle NULL Region and Original Clip Region.
+    //
+    if (!prgn)
+    {
+        if (prgnOrigClip)
+        {
+            REGION_Delete(dc->dclevel.prgnClip);
+            dc->dclevel.prgnClip = NULL;
+            IntGdiReleaseRaoRgn(dc);
+        }
+        return SIMPLEREGION;
+    }
 
 
-        return IntGdiCombineRgn(dc->dclevel.prgnClip, prgn, NULL, RGN_COPY);
+    //
+    // Combine the new Clip region with original Clip and caller Region.
+    //
+    if ( prgnOrigClip &&
+        (Ret = IntGdiCombineRgn(prgnOrigClip, prgn, NULL, RGN_COPY)) ) // Clip could fail.
+    {
+        IntGdiReleaseRaoRgn(dc);
     }
     }
+    else // NULL original Clip, just copy caller region to new.
+    {
+       prgnNClip = IntSysCreateRectpRgn(0, 0, 0, 0);
+       REGION_bCopy(prgnNClip, prgn);
+       Ret = REGION_Complexity(prgnNClip);
+       dc->dclevel.prgnClip = prgnNClip;
+       IntGdiReleaseRaoRgn(dc);
+    }
+    return Ret;
+}
 
 
-    ASSERT(prgn != NULL);
+//
+// Call from Gdi Batch Subsystem.
+//
+// Was setup to just handle RGN_COPY only and return VOID, since this was called from Gdi32.
+// Tested in place of the other, complexity aside.
+//
 
 
-    if (!dc->dclevel.prgnClip)
+_Success_(return!=ERROR)
+int
+FASTCALL
+IntGdiExtSelectClipRect(
+    _In_ PDC dc,
+    _In_ PRECTL prcl,
+    _In_ int fnMode)
+{
+    int Ret = ERROR;
+    PREGION prgn;
+    RECTL rect;
+    BOOL NoRegion = fnMode & GDIBS_NORECT;
+
+    fnMode &= ~GDIBS_NORECT;
+
+    if (NoRegion) // NULL Region.
     {
     {
-        RECTL rect;
+        if (fnMode == RGN_COPY)
+        {
+           Ret = IntSelectClipRgn( dc, NULL, RGN_COPY);
+
+           if (dc->fs & DC_FLAG_DIRTY_RAO)
+               CLIPPING_UpdateGCRegion(dc);
 
 
-        REGION_GetRgnBox(dc->prgnVis, &rect);
-        dc->dclevel.prgnClip = IntSysCreateRectpRgnIndirect(&rect);
+           if (Ret) // Copy? Return Vis complexity.
+               Ret = REGION_Complexity(dc->prgnVis);
+        }
     }
     }
+    else // Have a box to build a region with.
+    {
+        if (dc->dclevel.prgnClip)
+        {
+            REGION_GetRgnBox(dc->dclevel.prgnClip, &rect);
 
 
-    dc->fs |= DC_FLAG_DIRTY_RAO;
+            if (prcl->left   == rect.left  &&
+                prcl->top    == rect.top   &&
+                prcl->right  == rect.right &&
+                prcl->bottom == rect.bottom)
+            {
+                return REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
+            }
+        }
+
+        prgn = IntSysCreateRectpRgnIndirect(prcl);
 
 
-    return IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, prgn, fnMode);
+        Ret = IntSelectClipRgn( dc, prgn, fnMode);
+
+        if (dc->fs & DC_FLAG_DIRTY_RAO)
+            CLIPPING_UpdateGCRegion(dc);
+
+        if (Ret) // In this case NtGdiExtSelectClipRgn tests pass.
+            Ret = REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
+
+        REGION_Delete(prgn);
+    }
+    return Ret;
 }
 
 }
 
+_Success_(return!=ERROR)
+int
+FASTCALL
+IntGdiExtSelectClipRgn(
+    _In_ PDC dc,
+    _In_ PREGION prgn,
+    _In_ int fnMode)
+{
+    int Ret = ERROR;
+
+    if (!prgn)
+    {
+        if (fnMode == RGN_COPY)
+        {
+           if ((Ret = IntSelectClipRgn( dc, NULL, RGN_COPY)))
+               Ret = REGION_Complexity(dc->prgnVis);
+        }
+    }
+    else
+    {
+        if ((Ret = IntSelectClipRgn( dc, prgn, fnMode)))
+        {
+            DPRINT("IntGdiExtSelectClipRgn A %d\n",Ret);
+            // Update the Rao, it must be this way for now.
+            if (dc->fs & DC_FLAG_DIRTY_RAO)
+                CLIPPING_UpdateGCRegion(dc);
+
+            Ret = REGION_Complexity( dc->prgnRao ? dc->prgnRao : dc->prgnVis );
+            DPRINT("IntGdiExtSelectClipRgn B %d\n",Ret);
+        }
+    }
+    return Ret;
+}
 
 int
 APIENTRY
 
 int
 APIENTRY
@@ -118,6 +313,12 @@ NtGdiExtSelectClipRgn(
     DC *dc;
     PREGION prgn;
 
     DC *dc;
     PREGION prgn;
 
+    if ( fnMode < RGN_AND || fnMode > RGN_COPY )
+    {
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        return ERROR;
+    }
+
     if (!(dc = DC_LockDc(hDC)))
     {
         EngSetLastError(ERROR_INVALID_HANDLE);
     if (!(dc = DC_LockDc(hDC)))
     {
         EngSetLastError(ERROR_INVALID_HANDLE);
@@ -128,12 +329,23 @@ NtGdiExtSelectClipRgn(
 
     if ((prgn == NULL) && (fnMode != RGN_COPY))
     {
 
     if ((prgn == NULL) && (fnMode != RGN_COPY))
     {
-        EngSetLastError(ERROR_INVALID_HANDLE);
+        //EngSetLastError(ERROR_INVALID_HANDLE); doesn't set this.
         retval = ERROR;
     }
     else
     {
         retval = ERROR;
     }
     else
     {
+#if 0   // Testing GDI Batch.
+        {
+            RECTL rcl;
+            if (prgn)
+                REGION_GetRgnBox(prgn, &rcl);
+            else
+                fnMode |= GDIBS_NORECT;
+            retval = IntGdiExtSelectClipRect(dc, &rcl, fnMode);
+        }
+#else
         retval = IntGdiExtSelectClipRgn(dc, prgn, fnMode);
         retval = IntGdiExtSelectClipRgn(dc, prgn, fnMode);
+#endif
     }
 
     if (prgn)
     }
 
     if (prgn)
@@ -367,6 +579,7 @@ NtGdiOffsetClipRgn(
     pdc = DC_LockDc(hdc);
     if (pdc == NULL)
     {
     pdc = DC_LockDc(hdc);
     if (pdc == NULL)
     {
+        if (!hdc) EngSetLastError(ERROR_INVALID_HANDLE);
         return ERROR;
     }
 
         return ERROR;
     }
 
@@ -390,6 +603,8 @@ NtGdiOffsetClipRgn(
         }
         else
         {
         }
         else
         {
+            IntGdiReleaseRaoRgn(pdc);
+            UpdateVisRgn(pdc);
             iComplexity = REGION_Complexity(pdc->dclevel.prgnClip);
         }
 
             iComplexity = REGION_Complexity(pdc->dclevel.prgnClip);
         }
 
@@ -413,6 +628,7 @@ BOOL APIENTRY NtGdiPtVisible(HDC  hDC,
 {
     BOOL ret = FALSE;
     PDC dc;
 {
     BOOL ret = FALSE;
     PDC dc;
+    PREGION prgn;
 
     if(!(dc = DC_LockDc(hDC)))
     {
 
     if(!(dc = DC_LockDc(hDC)))
     {
@@ -420,11 +636,13 @@ BOOL APIENTRY NtGdiPtVisible(HDC  hDC,
         return FALSE;
     }
 
         return FALSE;
     }
 
-    if (dc->prgnRao)
+    prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
+
+    if (prgn)
     {
         POINT pt = {X, Y};
         IntLPtoDP(dc, &pt, 1);
     {
         POINT pt = {X, Y};
         IntLPtoDP(dc, &pt, 1);
-        ret = REGION_PtInRegion(dc->prgnRao, pt.x, pt.y);
+        ret = REGION_PtInRegion(prgn, pt.x, pt.y);
     }
 
     DC_UnlockDc(dc);
     }
 
     DC_UnlockDc(dc);
@@ -442,6 +660,7 @@ NtGdiRectVisible(
     PDC dc = DC_LockDc(hDC);
     BOOL Result = FALSE;
     RECTL Rect;
     PDC dc = DC_LockDc(hDC);
     BOOL Result = FALSE;
     RECTL Rect;
+    PREGION prgn;
 
     if (!dc)
     {
 
     if (!dc)
     {
@@ -472,10 +691,11 @@ NtGdiRectVisible(
     if (dc->fs & DC_FLAG_DIRTY_RAO)
         CLIPPING_UpdateGCRegion(dc);
 
     if (dc->fs & DC_FLAG_DIRTY_RAO)
         CLIPPING_UpdateGCRegion(dc);
 
-    if (dc->prgnRao)
+    prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
+    if (prgn)
     {
          IntLPtoDP(dc, (LPPOINT)&Rect, 2);
     {
          IntLPtoDP(dc, (LPPOINT)&Rect, 2);
-         Result = REGION_RectInRegion(dc->prgnRao, &Rect);
+         Result = REGION_RectInRegion(prgn, &Rect);
     }
     DC_UnlockDc(dc);
 
     }
     DC_UnlockDc(dc);
 
@@ -492,13 +712,23 @@ IntGdiSetMetaRgn(PDC pDC)
     {
         if ( pDC->dclevel.prgnClip )
         {
     {
         if ( pDC->dclevel.prgnClip )
         {
-            // preferably REGION_IntersectRegion
-            Ret = IntGdiCombineRgn(pDC->dclevel.prgnMeta, pDC->dclevel.prgnMeta, pDC->dclevel.prgnClip, RGN_AND);
-            if (Ret != ERROR)
+            PREGION prgn = IntSysCreateRectpRgn(0,0,0,0);
+            if ( prgn )
             {
             {
-                REGION_Delete(pDC->dclevel.prgnClip);
-                pDC->dclevel.prgnClip = NULL;
-                IntGdiReleaseRaoRgn(pDC);
+                if (REGION_bIntersectRegion(prgn, pDC->dclevel.prgnMeta, pDC->dclevel.prgnClip))
+                {
+                    // See Restore/SaveDC
+                    REGION_Delete(pDC->dclevel.prgnMeta);
+                    pDC->dclevel.prgnMeta = prgn;
+
+                    REGION_Delete(pDC->dclevel.prgnClip);
+                    pDC->dclevel.prgnClip = NULL;
+                    IntGdiReleaseRaoRgn(pDC);
+
+                    Ret = REGION_Complexity(pDC->dclevel.prgnMeta);
+                }
+                else
+                    REGION_Delete(prgn);
             }
         }
         else
             }
         }
         else
@@ -516,9 +746,6 @@ IntGdiSetMetaRgn(PDC pDC)
             Ret = SIMPLEREGION;
     }
 
             Ret = SIMPLEREGION;
     }
 
-    if (Ret != ERROR)
-        pDC->fs |= DC_FLAG_DIRTY_RAO;
-
     return Ret;
 }
 
     return Ret;
 }
 
@@ -543,9 +770,38 @@ VOID
 FASTCALL
 CLIPPING_UpdateGCRegion(PDC pDC)
 {
 FASTCALL
 CLIPPING_UpdateGCRegion(PDC pDC)
 {
+    // Moved from Release Rao. Though it still gets over written.
+    RECTL_vSetEmptyRect(&pDC->erclClip);
+
     /* Must have VisRgn set to a valid state! */
     ASSERT (pDC->prgnVis);
     /* Must have VisRgn set to a valid state! */
     ASSERT (pDC->prgnVis);
+#if 0 // (w2k3) This works with limitations. (w7u) ReactOS relies on Rao.
+    if ( !pDC->dclevel.prgnClip &&
+         !pDC->dclevel.prgnMeta &&
+         !pDC->prgnAPI)
+    {
+        if (pDC->prgnRao)
+            REGION_Delete(pDC->prgnRao);
+        pDC->prgnRao = NULL;
 
 
+        REGION_bOffsetRgn(pDC->prgnVis, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
+
+        RtlCopyMemory(&pDC->erclClip,
+                      &pDC->prgnVis->rdh.rcBound,
+                       sizeof(RECTL));
+
+        IntEngUpdateClipRegion(&pDC->co,
+                                pDC->prgnVis->rdh.nCount,
+                                pDC->prgnVis->Buffer,
+                               &pDC->erclClip);
+
+        REGION_bOffsetRgn(pDC->prgnVis, -pDC->ptlDCOrig.x, -pDC->ptlDCOrig.y);
+
+        pDC->fs &= ~DC_FLAG_DIRTY_RAO;
+        UpdateVisRgn(pDC);
+        return;
+    }
+#endif
     if (pDC->prgnAPI)
     {
         REGION_Delete(pDC->prgnAPI);
     if (pDC->prgnAPI)
     {
         REGION_Delete(pDC->prgnAPI);
@@ -564,50 +820,43 @@ CLIPPING_UpdateGCRegion(PDC pDC)
         pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
         if (!pDC->dclevel.prgnMeta)
         {
         pDC->prgnAPI = IntSysCreateRectpRgn(0,0,0,0);
         if (!pDC->dclevel.prgnMeta)
         {
-            IntGdiCombineRgn(pDC->prgnAPI,
-                             pDC->dclevel.prgnClip,
-                             NULL,
-                             RGN_COPY);
+            REGION_bCopy(pDC->prgnAPI,
+                         pDC->dclevel.prgnClip);
         }
         else if (!pDC->dclevel.prgnClip)
         {
         }
         else if (!pDC->dclevel.prgnClip)
         {
-            IntGdiCombineRgn(pDC->prgnAPI,
-                             pDC->dclevel.prgnMeta,
-                             NULL,
-                             RGN_COPY);
+            REGION_bCopy(pDC->prgnAPI,
+                         pDC->dclevel.prgnMeta);
         }
         else
         {
         }
         else
         {
-            IntGdiCombineRgn(pDC->prgnAPI,
-                             pDC->dclevel.prgnClip,
-                             pDC->dclevel.prgnMeta,
-                             RGN_AND);
+            REGION_bIntersectRegion(pDC->prgnAPI,
+                                    pDC->dclevel.prgnClip,
+                                    pDC->dclevel.prgnMeta);
         }
     }
 
     if (pDC->prgnAPI)
     {
         }
     }
 
     if (pDC->prgnAPI)
     {
-        IntGdiCombineRgn(pDC->prgnRao,
-                         pDC->prgnVis,
-                         pDC->prgnAPI,
-                         RGN_AND);
+        REGION_bIntersectRegion(pDC->prgnRao,
+                                pDC->prgnVis,
+                                pDC->prgnAPI);
     }
     else
     {
     }
     else
     {
-        IntGdiCombineRgn(pDC->prgnRao,
-                         pDC->prgnVis,
-                         NULL,
-                         RGN_COPY);
+        REGION_bCopy(pDC->prgnRao,
+                     pDC->prgnVis);
     }
 
 
     REGION_bOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
 
     RtlCopyMemory(&pDC->erclClip,
     }
 
 
     REGION_bOffsetRgn(pDC->prgnRao, pDC->ptlDCOrig.x, pDC->ptlDCOrig.y);
 
     RtlCopyMemory(&pDC->erclClip,
-                &pDC->prgnRao->rdh.rcBound,
-                sizeof(RECTL));
+                  &pDC->prgnRao->rdh.rcBound,
+                  sizeof(RECTL));
 
     pDC->fs &= ~DC_FLAG_DIRTY_RAO;
 
     pDC->fs &= ~DC_FLAG_DIRTY_RAO;
+    UpdateVisRgn(pDC);
 
     // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
     // the rects from region objects rects in pClipRgn->Buffer.
 
     // pDC->co should be used. Example, CLIPOBJ_cEnumStart uses XCLIPOBJ to build
     // the rects from region objects rects in pClipRgn->Buffer.
index af7933b..d8230b9 100644 (file)
@@ -12,3 +12,7 @@ INT FASTCALL IntGdiExtSelectClipRgn (PDC dc, PREGION prgn, int fnMode);
 VOID FASTCALL CLIPPING_UpdateGCRegion(DC* Dc);
 VOID FASTCALL IntGdiReleaseRaoRgn(PDC);
 VOID FASTCALL IntGdiReleaseVisRgn(PDC);
 VOID FASTCALL CLIPPING_UpdateGCRegion(DC* Dc);
 VOID FASTCALL IntGdiReleaseRaoRgn(PDC);
 VOID FASTCALL IntGdiReleaseVisRgn(PDC);
+VOID FASTCALL UpdateVisRgn(PDC);
+BOOL FASTCALL REGION_bCopy(PREGION,PREGION);
+BOOL FASTCALL REGION_bIntersectRegion(PREGION,PREGION,PREGION);
+int FASTCALL IntGdiExtSelectClipRect(PDC,PRECTL,int);
index d27481c..3f25639 100644 (file)
@@ -112,6 +112,11 @@ DC_InitHack(PDC pdc)
         DC_vCopyState(pdc, defaultDCstate, TRUE);
     }
 
         DC_vCopyState(pdc, defaultDCstate, TRUE);
     }
 
+    if (prgnDefault == NULL)
+    {
+        prgnDefault = IntSysCreateRectpRgn(0, 0, 0, 0);
+    }
+
     TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
     pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
 
     TextIntRealizeFont(pdc->pdcattr->hlfntNew,NULL);
     pdc->pdcattr->iCS_CP = ftGdiGetTextCharsetInfo(pdc,NULL,0);
 
@@ -247,6 +252,9 @@ DC_vInitDc(
     pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
        ASSERT(pdc->prgnVis);
 
     pdc->prgnVis = IntSysCreateRectpRgn(0, 0, pdc->dclevel.sizl.cx, pdc->dclevel.sizl.cy);
        ASSERT(pdc->prgnVis);
 
+    /* Setup Vis Region Attribute information */
+    UpdateVisRgn(pdc);
+
        /* Initialize Clip object */
        IntEngInitClipObj(&pdc->co);
 
        /* Initialize Clip object */
        IntEngInitClipObj(&pdc->co);
 
@@ -637,7 +645,7 @@ GreOpenDCW(
     BOOL bDisplay,
     HANDLE hspool,
     VOID *pDriverInfo2,
     BOOL bDisplay,
     HANDLE hspool,
     VOID *pDriverInfo2,
-    VOID *pUMdhpdev)
+    PVOID *pUMdhpdev)
 {
     PPDEVOBJ ppdev;
     PDC pdc;
 {
     PPDEVOBJ ppdev;
     PDC pdc;
@@ -667,6 +675,7 @@ GreOpenDCW(
 
     /* Lock ppdev and initialize the new DC */
     DC_vInitDc(pdc, iType, ppdev);
 
     /* Lock ppdev and initialize the new DC */
     DC_vInitDc(pdc, iType, ppdev);
+    if (pUMdhpdev) *pUMdhpdev = ppdev->dhpdev;
     /* FIXME: HACK! */
     DC_InitHack(pdc);
 
     /* FIXME: HACK! */
     DC_InitHack(pdc);
 
@@ -689,6 +698,7 @@ NtGdiOpenDCW(
     _In_ ULONG iType,
     _In_ BOOL bDisplay,
     _In_opt_ HANDLE hspool,
     _In_ ULONG iType,
     _In_ BOOL bDisplay,
     _In_opt_ HANDLE hspool,
+    /*_In_opt_ DRIVER_INFO2W *pdDriverInfo2, Need this soon!!!! */
     _At_((PUMDHPDEV*)pUMdhpdev, _Out_) PVOID pUMdhpdev)
 {
     UNICODE_STRING ustrDevice;
     _At_((PUMDHPDEV*)pUMdhpdev, _Out_) PVOID pUMdhpdev)
 {
     UNICODE_STRING ustrDevice;
@@ -752,6 +762,7 @@ NtGdiOpenDCW(
     {
         pdmInit = NULL;
         pUMdhpdev = NULL;
     {
         pdmInit = NULL;
         pUMdhpdev = NULL;
+        // return UserGetDesktopDC(iType, FALSE, TRUE);
     }
 
     /* FIXME: HACK! */
     }
 
     /* FIXME: HACK! */
@@ -777,7 +788,7 @@ NtGdiOpenDCW(
     /* If we got a HDC and a UM dhpdev is requested,... */
     if (hdc && pUMdhpdev)
     {
     /* If we got a HDC and a UM dhpdev is requested,... */
     if (hdc && pUMdhpdev)
     {
-        /* Copy dhpdev to caller (FIXME: use dhpdev?) */
+        /* Copy dhpdev to caller */
         _SEH2_TRY
         {
             /* Pointer was already probed */
         _SEH2_TRY
         {
             /* Pointer was already probed */
index 8902d95..ccf7c13 100644 (file)
@@ -57,6 +57,7 @@ DC_vCopyState(PDC pdcSrc, PDC pdcDst, BOOL To)
             REGION_Delete(pdcDst->dclevel.prgnMeta);
             pdcDst->dclevel.prgnMeta = NULL;
         }
             REGION_Delete(pdcDst->dclevel.prgnMeta);
             pdcDst->dclevel.prgnMeta = NULL;
         }
+        /* The only way to reset the Meta Region to its original state is to return to a previously saved version of the DC with SaveDC. */
         if (pdcSrc->dclevel.prgnMeta)
         {
             pdcDst->dclevel.prgnMeta = IntSysCreateRectpRgn(0, 0, 0, 0);
         if (pdcSrc->dclevel.prgnMeta)
         {
             pdcDst->dclevel.prgnMeta = IntSysCreateRectpRgn(0, 0, 0, 0);
index aa130f0..0ac907f 100644 (file)
@@ -401,11 +401,10 @@ IntSetDefaultRegion(PDC pdc)
         pdc->erclWindow = rclWnd;
         pdc->erclClip = rclClip;
         /* Might be an InitDC or DCE... */
         pdc->erclWindow = rclWnd;
         pdc->erclClip = rclClip;
         /* Might be an InitDC or DCE... */
-        pdc->ptlFillOrigin.x = pdc->dcattr.ptlBrushOrigin.x;
-        pdc->ptlFillOrigin.y = pdc->dcattr.ptlBrushOrigin.y;
+        pdc->ptlFillOrigin = pdc->dcattr.ptlBrushOrigin;
         return TRUE;
     }
         return TRUE;
     }
-
+    // No Vis use the Default System Region.
     pdc->prgnVis = prgnDefault;
     return FALSE;
 }
     pdc->prgnVis = prgnDefault;
     return FALSE;
 }
index a42a341..c18ff00 100644 (file)
@@ -1081,6 +1081,7 @@ NtGdiExtFloodFill(
     RECTL      DestRect;
     POINTL     Pt;
     ULONG      ConvColor;
     RECTL      DestRect;
     POINTL     Pt;
     ULONG      ConvColor;
+    PREGION    prgn;
 
     dc = DC_LockDc(hDC);
     if (!dc)
 
     dc = DC_LockDc(hDC);
     if (!dc)
@@ -1105,13 +1106,14 @@ NtGdiExtFloodFill(
 
     DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
 
 
     DC_vPrepareDCsForBlit(dc, &DestRect, NULL, NULL);
 
-    /// FIXME: what about prgnVIS? And what about REAL clipping?
     psurf = dc->dclevel.pSurface;
     psurf = dc->dclevel.pSurface;
-    if (dc->prgnRao)
+
+    prgn = dc->prgnRao ? dc->prgnRao : dc->prgnVis;
+    if (prgn)
     {
     {
-        Ret = REGION_PtInRegion(dc->prgnRao, Pt.x, Pt.y);
+        Ret = REGION_PtInRegion(prgn, Pt.x, Pt.y);
         if (Ret)
         if (Ret)
-            REGION_GetRgnBox(dc->prgnRao, (LPRECT)&DestRect);
+            REGION_GetRgnBox(prgn, (LPRECT)&DestRect);
         else
         {
             DC_vFinishBlit(dc, NULL);
         else
         {
             DC_vFinishBlit(dc, NULL);
index cccc706..ab68c50 100644 (file)
@@ -424,7 +424,13 @@ GdiFlushUserBatch(PDC dc, PGDIBATCHHDR pHdr)
      }
 
      case GdiBCExtSelClipRgn:
      }
 
      case GdiBCExtSelClipRgn:
+     {
+        PGDIBSEXTSELCLPRGN pgO;
+        if (!dc) break;
+        pgO = (PGDIBSEXTSELCLPRGN) pHdr;
+        IntGdiExtSelectClipRect( dc, &pgO->rcl, pgO->fnMode);
         break;
         break;
+     }
 
      case GdiBCSelObj:
      {
 
      case GdiBCSelObj:
      {
index 5e53b0b..5274fa2 100644 (file)
@@ -63,14 +63,12 @@ AddPenLinesBounds(PDC dc, int count, POINT *points)
     DPRINT("                 r %d b %d\n",rect.right,rect.bottom);
 
     {
     DPRINT("                 r %d b %d\n",rect.right,rect.bottom);
 
     {
-       RECTL rcRgn;
-       if (dc->fs & DC_FLAG_DIRTY_RAO) CLIPPING_UpdateGCRegion(dc);
-       if (REGION_GetRgnBox(dc->prgnRao, &rcRgn))
-       {
-          if (RECTL_bIntersectRect( &rcRgn, &rcRgn, &bounds )) IntUpdateBoundsRect(dc, &rcRgn);
-       }
+       RECTL rcRgn = dc->erclClip; // Use the clip box for now.
+
+       if (RECTL_bIntersectRect( &rcRgn, &rcRgn, &bounds ))
+           IntUpdateBoundsRect(dc, &rcRgn);
        else
        else
-          IntUpdateBoundsRect(dc, &bounds);
+           IntUpdateBoundsRect(dc, &bounds);
     }
 }
 
     }
 }