[WIN32K]
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 23 Sep 2014 20:21:13 +0000 (20:21 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Tue, 23 Sep 2014 20:21:13 +0000 (20:21 +0000)
- Modify REGION_CropAndOffsetRegion to return the region complexity
- Improve NtGdiIntersectClipRect to only allocate a new region, if we don't have one yet, otherwise crop it using REGION_CropAndOffsetRegion

svn path=/trunk/; revision=64249

reactos/win32ss/gdi/ntgdi/cliprgn.c
reactos/win32ss/gdi/ntgdi/region.c
reactos/win32ss/gdi/ntgdi/region.h

index f6a89e3..9c96225 100644 (file)
@@ -241,54 +241,71 @@ int APIENTRY NtGdiExcludeClipRect(HDC  hDC,
     return Result;
 }
 
-int APIENTRY NtGdiIntersectClipRect(HDC  hDC,
-                           int  LeftRect,
-                           int  TopRect,
-                           int  RightRect,
-                           int  BottomRect)
+INT
+APIENTRY
+NtGdiIntersectClipRect(
+    _In_ HDC hdc,
+    _In_ INT xLeft,
+    _In_ INT yTop,
+    _In_ INT xRight,
+    _In_ INT yBottom)
 {
-    INT Result;
-    RECTL Rect;
-    PREGION pNewRgn;
-    PDC dc = DC_LockDc(hDC);
+    INT iComplexity;
+    RECTL rect;
+    PREGION prgnNew;
+    PDC pdc;
 
     DPRINT("NtGdiIntersectClipRect(%p, %d,%d-%d,%d)\n",
-            hDC, LeftRect, TopRect, RightRect, BottomRect);
+            hdc, xLeft, yTop, xRight, yBottom);
 
-    if (!dc)
+    /* Lock the DC */
+    pdc = DC_LockDc(hdc);
+    if (!pdc)
     {
         EngSetLastError(ERROR_INVALID_HANDLE);
         return ERROR;
     }
 
-    Rect.left = LeftRect;
-    Rect.top = TopRect;
-    Rect.right = RightRect;
-    Rect.bottom = BottomRect;
-
-    IntLPtoDP(dc, (LPPOINT)&Rect, 2);
+    /* Convert coordinates to device space */
+    rect.left = xLeft;
+    rect.top = yTop;
+    rect.right = xRight;
+    rect.bottom = yBottom;
+    IntLPtoDP(pdc, (LPPOINT)&rect, 2);
 
-    pNewRgn = IntSysCreateRectpRgnIndirect(&Rect);
-    if (!pNewRgn)
+    /* Check if we already have a clip region */
+    if (pdc->dclevel.prgnClip != NULL)
     {
-        Result = ERROR;
-    }
-    else if (!dc->dclevel.prgnClip)
-    {
-        dc->dclevel.prgnClip = pNewRgn;
-        Result = SIMPLEREGION;
+        /* We have a region, crop it */
+        iComplexity = REGION_CropAndOffsetRegion(pdc->dclevel.prgnClip,
+                                                 pdc->dclevel.prgnClip,
+                                                 &rect,
+                                                 NULL);
     }
     else
     {
-        Result = IntGdiCombineRgn(dc->dclevel.prgnClip, dc->dclevel.prgnClip, pNewRgn, RGN_AND);
-        REGION_Delete(pNewRgn);
+        /* We don't have a region yet, allocate a new one */
+        prgnNew = IntSysCreateRectpRgnIndirect(&rect);
+        if (prgnNew == NULL)
+        {
+            iComplexity = ERROR;
+        }
+        else
+        {
+            /* Set the new region */
+            pdc->dclevel.prgnClip = prgnNew;
+            iComplexity = SIMPLEREGION;
+        }
     }
-    if (Result != ERROR)
-        dc->fs |= DC_FLAG_DIRTY_RAO;
 
-    DC_UnlockDc(dc);
+    /* If we succeeded, mark the RAO region as dirty */
+    if (iComplexity != ERROR)
+        pdc->fs |= DC_FLAG_DIRTY_RAO;
 
-    return Result;
+    /* Unlock the DC */
+    DC_UnlockDc(pdc);
+
+    return iComplexity;
 }
 
 int APIENTRY NtGdiOffsetClipRgn(HDC  hDC,
index 4efcc6f..0c20aff 100644 (file)
@@ -489,12 +489,12 @@ IntDumpRegion(HRGN hRgn)
 
 INT
 FASTCALL
-REGION_Complexity( PROSRGNDATA obj )
+REGION_Complexity(PREGION prgn)
 {
-    if (!obj) return NULLREGION;
-    switch(obj->rdh.nCount)
+    if (!prgn) return NULLREGION;
+    switch(prgn->rdh.nCount)
     {
-       DPRINT("Region Complexity -> %lu",obj->rdh.nCount);
+       DPRINT("Region Complexity -> %lu", prgn->rdh.nCount);
        case 0:  return NULLREGION;
        case 1:  return SIMPLEREGION;
        default: return COMPLEXREGION;
@@ -581,13 +581,13 @@ REGION_SetExtents(ROSRGNDATA *pReg)
 /***********************************************************************
  *           REGION_CropAndOffsetRegion
  */
-BOOL FASTCALL
+INT
+FASTCALL
 REGION_CropAndOffsetRegion(
-    PROSRGNDATA rgnDst,
-    PROSRGNDATA rgnSrc,
+    PREGION rgnDst,
+    PREGION rgnSrc,
     const RECTL *rect,
-    const POINTL *offset
-)
+    const POINTL *offset) // FIXME: we should probably remove offset from here
 {
     POINT pt = {0,0};
     const POINT *off = offset;
@@ -602,13 +602,13 @@ REGION_CropAndOffsetRegion(
             if (off->x || off->y)
                 xrect = rgnDst->Buffer;
             else
-                return TRUE;
+                return REGION_Complexity(rgnDst);
         }
         else
         {
             xrect = ExAllocatePoolWithTag(PagedPool, rgnSrc->rdh.nCount * sizeof(RECT), TAG_REGION);
                        if(!xrect)
-                               return FALSE;
+                               return ERROR;
             if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound)
                 ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); // Free the old buffer. Will be assigned to xrect below.
         }
@@ -669,7 +669,7 @@ REGION_CropAndOffsetRegion(
             PRECTL temp;
             temp = ExAllocatePoolWithTag(PagedPool, i * sizeof(RECT), TAG_REGION);
             if (!temp)
-                return FALSE;
+                return ERROR;
 
             if (rgnDst->Buffer && rgnDst->Buffer != &rgnDst->rdh.rcBound)
                 ExFreePoolWithTag(rgnDst->Buffer, TAG_REGION); // free the old buffer
@@ -727,7 +727,7 @@ REGION_CropAndOffsetRegion(
         rgnDst->rdh.iType = RDH_RECTANGLES;
     }
 
-    return TRUE;
+    return REGION_Complexity(rgnDst);
 
 empty:
     if (!rgnDst->Buffer)
@@ -739,10 +739,10 @@ empty:
             rgnDst->rdh.nRgnSize = RGN_DEFAULT_RECTS * sizeof(RECT);
         }
         else
-            return FALSE;
+            return ERROR;
     }
     EMPTY_REGION(rgnDst);
-    return TRUE;
+    return NULLREGION;
 }
 
 
index bfc2c3e..e735b15 100644 (file)
@@ -28,7 +28,7 @@ VOID FASTCALL REGION_UnionRectWithRgn(ROSRGNDATA *rgn, const RECTL *rect);
 INT FASTCALL REGION_GetRgnBox(PROSRGNDATA Rgn, RECTL *pRect);
 BOOL FASTCALL REGION_RectInRegion(PROSRGNDATA Rgn, const RECTL *rc);
 BOOL FASTCALL REGION_PtInRegion(PREGION, INT, INT);
-BOOL FASTCALL REGION_CropAndOffsetRegion(PROSRGNDATA rgnDst, PROSRGNDATA rgnSrc, const RECTL *rect, const POINT *off);
+INT FASTCALL REGION_CropAndOffsetRegion(PROSRGNDATA rgnDst, PROSRGNDATA rgnSrc, const RECTL *rect, const POINT *off);
 VOID FASTCALL REGION_SetRectRgn(PROSRGNDATA pRgn, INT LeftRect, INT TopRect, INT RightRect, INT BottomRect);
 VOID NTAPI REGION_vCleanup(PVOID ObjectBody);