Nikolay Sivov : gdiplus: Implemented GdipGetClip.

Alexandre Julliard julliard at winehq.org
Wed Aug 27 08:24:16 CDT 2008


Module: wine
Branch: master
Commit: ef50aa330ef66d429c84a6a81a21c3d72f426175
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ef50aa330ef66d429c84a6a81a21c3d72f426175

Author: Nikolay Sivov <bunglehead at gmail.com>
Date:   Wed Aug 27 02:03:27 2008 +0400

gdiplus: Implemented GdipGetClip.

---

 dlls/gdiplus/gdiplus.c         |   22 ++++++++++++++++++++++
 dlls/gdiplus/gdiplus_private.h |   17 +++++++++++++++--
 dlls/gdiplus/graphics.c        |   22 ++++++++++++++++++++--
 dlls/gdiplus/region.c          |   29 -----------------------------
 dlls/gdiplus/tests/graphics.c  |    4 ++--
 5 files changed, 59 insertions(+), 35 deletions(-)

diff --git a/dlls/gdiplus/gdiplus.c b/dlls/gdiplus/gdiplus.c
index 5e449e2..17e4d33 100644
--- a/dlls/gdiplus/gdiplus.c
+++ b/dlls/gdiplus/gdiplus.c
@@ -344,3 +344,25 @@ BOOL lengthen_path(GpPath *path, INT len)
 
     return TRUE;
 }
+
+/* recursive deletion of GpRegion nodes */
+inline void delete_element(region_element* element)
+{
+    switch(element->type)
+    {
+        case RegionDataRect:
+            break;
+        case RegionDataPath:
+            GdipDeletePath(element->elementdata.pathdata.path);
+            break;
+        case RegionDataEmptyRect:
+        case RegionDataInfiniteRect:
+            break;
+        default:
+            delete_element(element->elementdata.combine.left);
+            delete_element(element->elementdata.combine.right);
+            GdipFree(element->elementdata.combine.left);
+            GdipFree(element->elementdata.combine.right);
+            break;
+    }
+}
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 8df1c74..4eb847c 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -54,6 +54,9 @@ extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
 
 extern BOOL lengthen_path(GpPath *path, INT len);
 
+typedef struct region_element region_element;
+extern inline void delete_element(region_element *element);
+
 static inline INT roundr(REAL x)
 {
     return (INT) floorf(x + 0.5);
@@ -96,6 +99,7 @@ struct GpGraphics{
     REAL scale;     /* page scale */
     GpMatrix * worldtrans; /* world transform */
     BOOL busy;      /* hdc handle obtained by GdipGetDC */
+    GpRegion *clip;
 };
 
 struct GpBrush{
@@ -218,7 +222,16 @@ struct GpFontFamily{
     WCHAR FamilyName[LF_FACESIZE];
 };
 
-typedef struct region_element
+/* internal use */
+typedef enum RegionType
+{
+    RegionDataRect          = 0x10000000,
+    RegionDataPath          = 0x10000001,
+    RegionDataEmptyRect     = 0x10000002,
+    RegionDataInfiniteRect  = 0x10000003,
+} RegionType;
+
+struct region_element
 {
     DWORD type; /* Rectangle, Path, SpecialRectangle, or CombineMode */
     union
@@ -241,7 +254,7 @@ typedef struct region_element
             struct region_element *right; /* what *left was combined with */
         } combine;
     } elementdata;
-} region_element;
+};
 
 struct GpRegion{
     struct
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index bf3a638..d5b562c 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -743,6 +743,12 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra
         return retval;
     }
 
+    if((retval = GdipCreateRegion(&(*graphics)->clip)) != Ok){
+        GdipFree((*graphics)->worldtrans);
+        GdipFree(*graphics);
+        return retval;
+    }
+
     (*graphics)->hdc = hdc;
     (*graphics)->hwnd = NULL;
     (*graphics)->smoothing = SmoothingModeDefault;
@@ -894,6 +900,7 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
     if(graphics->hwnd)
         ReleaseDC(graphics->hwnd, graphics->hdc);
 
+    GdipDeleteRegion(graphics->clip);
     GdipDeleteMatrix(graphics->worldtrans);
     GdipFree(graphics);
 
@@ -2874,14 +2881,25 @@ GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics *graphics, HDC hdc)
 
 GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
 {
+    GpRegion *clip;
+    GpStatus status;
+
+    TRACE("(%p, %p)\n", graphics, region);
+
     if(!graphics || !region)
         return InvalidParameter;
 
     if(graphics->busy)
         return ObjectBusy;
 
-    FIXME("(%p, %p): stub\n", graphics, region);
-    return NotImplemented;
+    if((status = GdipCloneRegion(graphics->clip, &clip)) != Ok)
+        return status;
+
+    /* free everything except root node and header */
+    delete_element(&region->node);
+    memcpy(region, clip, sizeof(GpRegion));
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace dst_space,
diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c
index b814450..addc2d2 100644
--- a/dlls/gdiplus/region.c
+++ b/dlls/gdiplus/region.c
@@ -73,14 +73,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
  *
  */
 
-typedef enum RegionType
-{
-    RegionDataRect          = 0x10000000,
-    RegionDataPath          = 0x10000001,
-    RegionDataEmptyRect     = 0x10000002,
-    RegionDataInfiniteRect  = 0x10000003,
-} RegionType;
-
 #define FLAGS_NOFLAGS   0x0
 #define FLAGS_INTPATH   0x4000
 
@@ -141,27 +133,6 @@ static inline GpStatus init_region(GpRegion* region, const RegionType type)
     return Ok;
 }
 
-static inline void delete_element(region_element* element)
-{
-    switch(element->type)
-    {
-        case RegionDataRect:
-            break;
-        case RegionDataPath:
-            GdipDeletePath(element->elementdata.pathdata.path);
-            break;
-        case RegionDataEmptyRect:
-        case RegionDataInfiniteRect:
-            break;
-        default:
-            delete_element(element->elementdata.combine.left);
-            delete_element(element->elementdata.combine.right);
-            GdipFree(element->elementdata.combine.left);
-            GdipFree(element->elementdata.combine.right);
-            break;
-    }
-}
-
 static inline GpStatus clone_element(const region_element* element,
         region_element** element2)
 {
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index 082ffe8..a468de9 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -791,10 +791,10 @@ static void test_getclip(void)
 
     res = FALSE;
     status = GdipGetClip(graphics, clip);
-    todo_wine expect(Ok, status);
+    expect(Ok, status);
     status = GdipIsInfiniteRegion(clip, graphics, &res);
     expect(Ok, status);
-    todo_wine expect(TRUE, res);
+    expect(TRUE, res);
 
     GdipDeleteRegion(clip);
 




More information about the wine-cvs mailing list