Module: wine Branch: master Commit: 632aef3d8b3bc4baa0d673980552df288550c72c URL: http://source.winehq.org/git/wine.git/?a=commit;h=632aef3d8b3bc4baa0d6739805...
Author: Andrew Eikum andrew@brightnightgames.com Date: Sun Jul 5 17:04:20 2009 -0500
gdiplus: Implement GdipBeginContainer2 and GdipEndContainer.
---
dlls/gdiplus/gdiplus_private.h | 3 + dlls/gdiplus/graphics.c | 153 ++++++++++++++++++++++++++++++++++++++-- include/gdiplusflat.h | 1 + 3 files changed, 151 insertions(+), 6 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h index 95133ca..be881c7 100644 --- a/dlls/gdiplus/gdiplus_private.h +++ b/dlls/gdiplus/gdiplus_private.h @@ -29,6 +29,7 @@
#include "objbase.h" #include "ocidl.h" +#include "wine/list.h"
#include "gdiplus.h"
@@ -109,6 +110,8 @@ struct GpGraphics{ BOOL busy; /* hdc handle obtained by GdipGetDC */ GpRegion *clip; UINT textcontrast; /* not used yet. get/set only */ + struct list containers; + GraphicsContainer contid; /* last-issued container ID */ };
struct GpBrush{ diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 3525743..b81a984 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -38,6 +38,7 @@ #include "gdiplus.h" #include "gdiplus_private.h" #include "wine/debug.h" +#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(gdiplus);
@@ -941,6 +942,104 @@ GpStatus trace_path(GpGraphics *graphics, GpPath *path) return result; }
+typedef struct _GraphicsContainerItem { + struct list entry; + GraphicsContainer contid; + + SmoothingMode smoothing; + CompositingQuality compqual; + InterpolationMode interpolation; + CompositingMode compmode; + TextRenderingHint texthint; + REAL scale; + GpUnit unit; + PixelOffsetMode pixeloffset; + UINT textcontrast; + GpMatrix* worldtrans; + GpRegion* clip; +} GraphicsContainerItem; + +static GpStatus init_container(GraphicsContainerItem** container, + GDIPCONST GpGraphics* graphics){ + GpStatus sts; + + *container = GdipAlloc(sizeof(GraphicsContainerItem)); + if(!(*container)) + return OutOfMemory; + + (*container)->contid = graphics->contid + 1; + + (*container)->smoothing = graphics->smoothing; + (*container)->compqual = graphics->compqual; + (*container)->interpolation = graphics->interpolation; + (*container)->compmode = graphics->compmode; + (*container)->texthint = graphics->texthint; + (*container)->scale = graphics->scale; + (*container)->unit = graphics->unit; + (*container)->textcontrast = graphics->textcontrast; + (*container)->pixeloffset = graphics->pixeloffset; + + sts = GdipCloneMatrix(graphics->worldtrans, &(*container)->worldtrans); + if(sts != Ok){ + GdipFree(*container); + *container = NULL; + return sts; + } + + sts = GdipCloneRegion(graphics->clip, &(*container)->clip); + if(sts != Ok){ + GdipDeleteMatrix((*container)->worldtrans); + GdipFree(*container); + *container = NULL; + return sts; + } + + return Ok; +} + +static void delete_container(GraphicsContainerItem* container){ + GdipDeleteMatrix(container->worldtrans); + GdipDeleteRegion(container->clip); + GdipFree(container); +} + +static GpStatus restore_container(GpGraphics* graphics, + GDIPCONST GraphicsContainerItem* container){ + GpStatus sts; + GpMatrix *newTrans; + GpRegion *newClip; + + sts = GdipCloneMatrix(container->worldtrans, &newTrans); + if(sts != Ok) + return sts; + + sts = GdipCloneRegion(container->clip, &newClip); + if(sts != Ok){ + GdipDeleteMatrix(newTrans); + return sts; + } + + GdipDeleteMatrix(graphics->worldtrans); + graphics->worldtrans = newTrans; + + GdipDeleteRegion(graphics->clip); + graphics->clip = newClip; + + graphics->contid = container->contid - 1; + + graphics->smoothing = container->smoothing; + graphics->compqual = container->compqual; + graphics->interpolation = container->interpolation; + graphics->compmode = container->compmode; + graphics->texthint = container->texthint; + graphics->scale = container->scale; + graphics->unit = container->unit; + graphics->textcontrast = container->textcontrast; + graphics->pixeloffset = container->pixeloffset; + + return Ok; +} + GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics) { TRACE("(%p, %p)\n", hdc, graphics); @@ -991,6 +1090,8 @@ GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **gra (*graphics)->scale = 1.0; (*graphics)->busy = FALSE; (*graphics)->textcontrast = 4; + list_init(&(*graphics)->containers); + (*graphics)->contid = 0;
return Ok; } @@ -1155,6 +1256,7 @@ GpStatus WINGDIPAPI GdipCreateStreamOnFile(GDIPCONST WCHAR * filename,
GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics) { + GraphicsContainerItem *cont, *next; TRACE("(%p)\n", graphics);
if(!graphics) return InvalidParameter; @@ -1163,6 +1265,11 @@ GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics) if(graphics->owndc) ReleaseDC(graphics->hwnd, graphics->hdc);
+ LIST_FOR_EACH_ENTRY_SAFE(cont, next, &graphics->containers, GraphicsContainerItem, entry){ + list_remove(&cont->entry); + delete_container(cont); + } + GdipDeleteRegion(graphics->clip); GdipDeleteMatrix(graphics->worldtrans); GdipFree(graphics); @@ -3254,14 +3361,24 @@ GpStatus WINGDIPAPI GdipSaveGraphics(GpGraphics *graphics, GraphicsState *state) return Ok; }
-GpStatus WINGDIPAPI GdipBeginContainer2(GpGraphics *graphics, GraphicsContainer *state) +GpStatus WINGDIPAPI GdipBeginContainer2(GpGraphics *graphics, + GraphicsContainer *state) { - FIXME("(%p, %p)\n", graphics, state); + GraphicsContainerItem *container; + GpStatus sts; + + TRACE("(%p, %p)\n", graphics, state);
if(!graphics || !state) return InvalidParameter;
- *state = 0xdeadbeef; + sts = init_container(&container, graphics); + if(sts != Ok) + return sts; + + list_add_head(&graphics->containers, &container->entry); + *state = graphics->contid = container->contid; + return Ok; }
@@ -3285,12 +3402,36 @@ GpStatus WINGDIPAPI GdipComment(GpGraphics *graphics, UINT sizeData, GDIPCONST B
GpStatus WINGDIPAPI GdipEndContainer(GpGraphics *graphics, GraphicsState state) { - FIXME("(%p, 0x%x)\n", graphics, state); + GpStatus sts; + GraphicsContainerItem *container, *container2;
- if(!graphics || !state) + TRACE("(%p, %x)\n", graphics, state); + + if(!graphics) return InvalidParameter;
- return Ok; + LIST_FOR_EACH_ENTRY(container, &graphics->containers, GraphicsContainerItem, entry){ + if(container->contid == state) + break; + } + + /* did not find a matching container */ + if(&container->entry == &graphics->containers) + return Ok; + + /* remove all of the containers on top of the found container */ + LIST_FOR_EACH_ENTRY_SAFE(container, container2, &graphics->containers, GraphicsContainerItem, entry){ + if(container->contid == state) + break; + list_remove(&container->entry); + delete_container(container); + } + + list_remove(&container->entry); + sts = restore_container(graphics, container); + delete_container(container); + + return sts; }
GpStatus WINGDIPAPI GdipScaleWorldTransform(GpGraphics *graphics, REAL sx, diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index 48c188b..0c1e54f 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -127,6 +127,7 @@ GpStatus WINGDIPAPI GdipFlush(GpGraphics*, GpFlushIntention); GpStatus WINGDIPAPI GdipBeginContainer(GpGraphics*,GDIPCONST GpRectF*,GDIPCONST GpRectF*,GpUnit,GraphicsContainer*); GpStatus WINGDIPAPI GdipBeginContainer2(GpGraphics*,GraphicsContainer*); GpStatus WINGDIPAPI GdipBeginContainerI(GpGraphics*,GDIPCONST GpRect*,GDIPCONST GpRect*,GpUnit,GraphicsContainer*); +GpStatus WINGDIPAPI GdipEndContainer(GpGraphics*,GraphicsContainer); GpStatus WINGDIPAPI GdipComment(GpGraphics*,UINT,GDIPCONST BYTE*); GpStatus WINGDIPAPI GdipCreateFromHDC(HDC,GpGraphics**); GpStatus WINGDIPAPI GdipCreateFromHDC2(HDC,HANDLE,GpGraphics**);