Module: wine Branch: master Commit: ef50aa330ef66d429c84a6a81a21c3d72f426175 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ef50aa330ef66d429c84a6a81a...
Author: Nikolay Sivov bunglehead@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(®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);