[WIN32K]
[reactos.git] / reactos / win32ss / gdi / eng / clip.c
index bce0502..61ffb0d 100644 (file)
@@ -7,9 +7,8 @@
  */
 
 #include <win32k.h>
+DBG_DEFAULT_CHANNEL(EngClip);
 
-#define NDEBUG
-#include <debug.h>
 
 static __inline int
 CompareRightDown(
@@ -190,63 +189,63 @@ CompareSpans(
 
 VOID
 FASTCALL
-IntEngDeleteClipRegion(CLIPOBJ *ClipObj)
+IntEngInitClipObj(XCLIPOBJ *Clip)
 {
-    EngFreeMem(ObjToGDI(ClipObj, CLIP));
+    Clip->Rects = &Clip->ClipObj.rclBounds;
 }
 
-CLIPOBJ*
-FASTCALL
-IntEngCreateClipRegion(ULONG count, PRECTL pRect, PRECTL rcBounds)
+VOID FASTCALL
+IntEngFreeClipResources(XCLIPOBJ *Clip)
 {
-    CLIPGDI *Clip;
+    if (Clip->Rects != &Clip->ClipObj.rclBounds)
+        EngFreeMem(Clip->Rects);
+}
+
 
+VOID
+FASTCALL
+IntEngUpdateClipRegion(
+    XCLIPOBJ* Clip,
+    ULONG count,
+    const RECTL* pRect,
+    const RECTL* rcBounds)
+{
     if(count > 1)
     {
-        RECTL *dest;
-
-        Clip = EngAllocMem(0, sizeof(CLIPGDI) + ((count - 1) * sizeof(RECTL)), GDITAG_CLIPOBJ);
+        RECTL* NewRects = EngAllocMem(0, FIELD_OFFSET(ENUMRECTS, arcl[count]), GDITAG_CLIPOBJ);
 
-        if(Clip != NULL)
+        if(NewRects != NULL)
         {
-            Clip->EnumRects.c = count;
+            Clip->RectCount = count;
             Clip->EnumOrder = CD_ANY;
-            for(dest = Clip->EnumRects.arcl;count > 0; count--, dest++, pRect++)
-            {
-                *dest = *pRect;
-            }
+            RtlCopyMemory(NewRects, pRect, count * sizeof(RECTL));
 
             Clip->ClipObj.iDComplexity = DC_COMPLEX;
-            Clip->ClipObj.iFComplexity = ((Clip->EnumRects.c <= 4) ? FC_RECT4 : FC_COMPLEX);
+            Clip->ClipObj.iFComplexity = ((Clip->RectCount <= 4) ? FC_RECT4 : FC_COMPLEX);
             Clip->ClipObj.iMode = TC_RECTANGLES;
             Clip->ClipObj.rclBounds = *rcBounds;
 
-            return GDIToObj(Clip, CLIP);
+            if (Clip->Rects != &Clip->ClipObj.rclBounds)
+                EngFreeMem(Clip->Rects);
+            Clip->Rects = NewRects;
         }
     }
     else
     {
-        Clip = EngAllocMem(0, sizeof(CLIPGDI), GDITAG_CLIPOBJ);
-
-        if(Clip != NULL)
-        {
-            Clip->EnumRects.c = 1;
-            Clip->EnumOrder = CD_ANY;
-            Clip->EnumRects.arcl[0] = *rcBounds;
-
-            Clip->ClipObj.iDComplexity = (((rcBounds->top == rcBounds->bottom) &&
-                                         (rcBounds->left == rcBounds->right))
-                                         ? DC_TRIVIAL : DC_RECT);
-
-            Clip->ClipObj.iFComplexity = FC_RECT;
-            Clip->ClipObj.iMode = TC_RECTANGLES;
-            Clip->ClipObj.rclBounds = *rcBounds;
-
-            return GDIToObj(Clip, CLIP);
-        }
+        Clip->EnumOrder = CD_ANY;
+
+        Clip->ClipObj.iDComplexity = (((rcBounds->top == rcBounds->bottom) &&
+                                     (rcBounds->left == rcBounds->right))
+                                     ? DC_TRIVIAL : DC_RECT);
+
+        Clip->ClipObj.iFComplexity = FC_RECT;
+        Clip->ClipObj.iMode = TC_RECTANGLES;
+        Clip->ClipObj.rclBounds = *rcBounds;
+        Clip->RectCount = 1;
+        if (Clip->Rects != &Clip->ClipObj.rclBounds)
+            EngFreeMem(Clip->Rects);
+        Clip->Rects = &Clip->ClipObj.rclBounds;
     }
-
-    return NULL;
 }
 
 /*
@@ -256,12 +255,15 @@ CLIPOBJ *
 APIENTRY
 EngCreateClip(VOID)
 {
-    CLIPGDI *Clip = EngAllocMem(FL_ZERO_MEMORY, sizeof(CLIPGDI), GDITAG_CLIPOBJ);
+    XCLIPOBJ *Clip = EngAllocMem(FL_ZERO_MEMORY, sizeof(XCLIPOBJ), GDITAG_CLIPOBJ);
     if(Clip != NULL)
     {
-        return GDIToObj(Clip, CLIP);
+        IntEngInitClipObj(Clip);
+        TRACE("Created Clip Obj %p.\n", Clip);
+        return &Clip->ClipObj;
     }
 
+    ERR("Clip object allocation failed!\n");
     return NULL;
 }
 
@@ -273,7 +275,10 @@ APIENTRY
 EngDeleteClip(
     _In_ _Post_ptr_invalid_ CLIPOBJ *pco)
 {
-    EngFreeMem(ObjToGDI(pco, CLIP));
+    XCLIPOBJ* Clip = CONTAINING_RECORD(pco, XCLIPOBJ, ClipObj);
+    TRACE("Deleting %p.\n");
+    IntEngFreeClipResources(Clip);
+    EngFreeMem(Clip);
 }
 
 /*
@@ -288,13 +293,13 @@ CLIPOBJ_cEnumStart(
     _In_ ULONG iDirection,
     _In_ ULONG cMaxRects)
 {
-    CLIPGDI *ClipGDI = ObjToGDI(pco, CLIP);
+    XCLIPOBJ* Clip = CONTAINING_RECORD(pco, XCLIPOBJ, ClipObj);
     SORTCOMP CompareFunc;
 
-    ClipGDI->EnumPos = 0;
-    ClipGDI->EnumMax = (cMaxRects > 0) ? cMaxRects : ClipGDI->EnumRects.c;
+    Clip->EnumPos = 0;
+    Clip->EnumMax = (cMaxRects > 0) ? cMaxRects : Clip->RectCount;
 
-    if (CD_ANY != iDirection && ClipGDI->EnumOrder != iDirection)
+    if (CD_ANY != iDirection && Clip->EnumOrder != iDirection)
     {
         switch (iDirection)
         {
@@ -315,27 +320,27 @@ CLIPOBJ_cEnumStart(
                 break;
 
             default:
-                DPRINT1("Invalid iDirection %lu\n", iDirection);
-                iDirection = ClipGDI->EnumOrder;
+                ERR("Invalid iDirection %lu\n", iDirection);
+                iDirection = Clip->EnumOrder;
                 CompareFunc = NULL;
                 break;
         }
 
         if (NULL != CompareFunc)
         {
-            EngSort((PBYTE) ClipGDI->EnumRects.arcl, sizeof(RECTL), ClipGDI->EnumRects.c, CompareFunc);
+            EngSort((PBYTE) Clip->Rects, sizeof(RECTL), Clip->RectCount, CompareFunc);
         }
 
-        ClipGDI->EnumOrder = iDirection;
+        Clip->EnumOrder = iDirection;
     }
 
     /* Return the number of rectangles enumerated */
-    if ((cMaxRects > 0) && (ClipGDI->EnumRects.c > cMaxRects))
+    if ((cMaxRects > 0) && (Clip->RectCount > cMaxRects))
     {
         return 0xFFFFFFFF;
     }
 
-    return ClipGDI->EnumRects.c;
+    return Clip->RectCount;
 }
 
 /*
@@ -348,14 +353,14 @@ CLIPOBJ_bEnum(
     _In_ ULONG cj,
     _Out_bytecap_(cj) ULONG *pulEnumRects)
 {
-    RECTL *dest, *src;
-    CLIPGDI *ClipGDI = ObjToGDI(pco, CLIP);
-    ULONG nCopy, i;
+    const RECTL* src;
+    XCLIPOBJ* Clip = CONTAINING_RECORD(pco, XCLIPOBJ, ClipObj);
+    ULONG nCopy;
     ENUMRECTS* pERects = (ENUMRECTS*)pulEnumRects;
 
     // Calculate how many rectangles we should copy
-    nCopy = min( ClipGDI->EnumMax - ClipGDI->EnumPos,
-            min( ClipGDI->EnumRects.c - ClipGDI->EnumPos,
+    nCopy = min( Clip->EnumMax - Clip->EnumPos,
+            min( Clip->RectCount - Clip->EnumPos,
             (cj - sizeof(ULONG)) / sizeof(RECTL)));
 
     if(nCopy == 0)
@@ -364,17 +369,14 @@ CLIPOBJ_bEnum(
     }
 
     /* Copy rectangles */
-    src = ClipGDI->EnumRects.arcl + ClipGDI->EnumPos;
-    for(i = 0, dest = pERects->arcl; i < nCopy; i++, dest++, src++)
-    {
-        *dest = *src;
-    }
+    src = &Clip->Rects[Clip->EnumPos];
+    RtlCopyMemory(pERects->arcl, src, nCopy * sizeof(RECTL));
 
     pERects->c = nCopy;
 
-    ClipGDI->EnumPos+=nCopy;
+    Clip->EnumPos+=nCopy;
 
-    return ClipGDI->EnumPos < ClipGDI->EnumRects.c;
+    return Clip->EnumPos < Clip->RectCount;
 }
 
 /* EOF */