[4/4] gdiplus: implemented GdipGetClip
Nikolay Sivov
bunglehead at gmail.com
Tue Aug 26 17:03:27 CDT 2008
Changelog:
- delete_element helper moved to gdiplus.c
- clip member added to Graphics
- implemented GdipGetClip
---
dlls/gdiplus/gdiplus.c | 23 +++++++++++++++++++++++
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, 60 insertions(+), 35 deletions(-)
diff --git a/dlls/gdiplus/gdiplus.c b/dlls/gdiplus/gdiplus.c
index 5e449e2..1ed70b0 100644
--- a/dlls/gdiplus/gdiplus.c
+++ b/dlls/gdiplus/gdiplus.c
@@ -344,3 +344,26 @@ 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(®ion->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);
--
1.4.4.4
More information about the wine-patches
mailing list