From ef50aa330ef66d429c84a6a81a21c3d72f426175 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Wed, 27 Aug 2008 02:03:27 +0400 Subject: [PATCH] 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 5e449e2f348..17e4d3329f2 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 8df1c74b5b0..4eb847c8c47 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 bf3a6381ab4..d5b562cacf0 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 b8144506fea..addc2d2387c 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 082ffe80e6c..a468de9d9fd 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);