Vincent Povirk : gdiplus: Implement GetDC for metafiles.

Alexandre Julliard julliard at winehq.org
Fri Jul 8 11:23:41 CDT 2011


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

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Thu Jul  7 11:30:06 2011 -0500

gdiplus: Implement GetDC for metafiles.

---

 dlls/gdiplus/gdiplus_private.h |    2 ++
 dlls/gdiplus/graphics.c        |   36 +++++++++++++++++++++++++-----------
 dlls/gdiplus/metafile.c        |   30 ++++++++++++++++++++++++++++++
 dlls/gdiplus/tests/metafile.c  |    6 +++---
 4 files changed, 60 insertions(+), 14 deletions(-)

diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 9cae489..d6888d9 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -52,6 +52,8 @@ extern REAL convert_unit(REAL logpixels, GpUnit unit) DECLSPEC_HIDDEN;
 extern GpStatus graphics_from_image(GpImage *image, GpGraphics **graphics) DECLSPEC_HIDDEN;
 
 extern GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result) DECLSPEC_HIDDEN;
+extern GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc) DECLSPEC_HIDDEN;
+extern GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc) DECLSPEC_HIDDEN;
 extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;
 
 extern void calc_curve_bezier(CONST GpPointF *pts, REAL tension, REAL *x1,
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index be25653..1e3f946 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -5311,6 +5311,8 @@ static const COLORREF DC_BACKGROUND_KEY = 0x0c0b0d;
 
 GpStatus WINGDIPAPI GdipGetDC(GpGraphics *graphics, HDC *hdc)
 {
+    GpStatus stat=Ok;
+
     TRACE("(%p, %p)\n", graphics, hdc);
 
     if(!graphics || !hdc)
@@ -5319,13 +5321,16 @@ GpStatus WINGDIPAPI GdipGetDC(GpGraphics *graphics, HDC *hdc)
     if(graphics->busy)
         return ObjectBusy;
 
-    if (!graphics->hdc ||
+    if (graphics->image && graphics->image->type == ImageTypeMetafile)
+    {
+        stat = METAFILE_GetDC((GpMetafile*)graphics->image, hdc);
+    }
+    else if (!graphics->hdc ||
         (graphics->image && graphics->image->type == ImageTypeBitmap && ((GpBitmap*)graphics->image)->format & PixelFormatAlpha))
     {
         /* Create a fake HDC and fill it with a constant color. */
         HDC temp_hdc;
         HBITMAP hbitmap;
-        GpStatus stat;
         GpRectF bounds;
         BITMAPINFOHEADER bmih;
         int i;
@@ -5374,22 +5379,26 @@ GpStatus WINGDIPAPI GdipGetDC(GpGraphics *graphics, HDC *hdc)
         *hdc = graphics->hdc;
     }
 
-    graphics->busy = TRUE;
+    if (stat == Ok)
+        graphics->busy = TRUE;
 
-    return Ok;
+    return stat;
 }
 
 GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics *graphics, HDC hdc)
 {
-    TRACE("(%p, %p)\n", graphics, hdc);
+    GpStatus stat=Ok;
 
-    if(!graphics || !hdc)
-        return InvalidParameter;
+    TRACE("(%p, %p)\n", graphics, hdc);
 
-    if((graphics->hdc != hdc && graphics->temp_hdc != hdc) || !(graphics->busy))
+    if(!graphics || !hdc || !graphics->busy)
         return InvalidParameter;
 
-    if (graphics->temp_hdc == hdc)
+    if (graphics->image && graphics->image->type == ImageTypeMetafile)
+    {
+        stat = METAFILE_ReleaseDC((GpMetafile*)graphics->image, hdc);
+    }
+    else if (graphics->temp_hdc == hdc)
     {
         DWORD* pos;
         int i;
@@ -5416,10 +5425,15 @@ GpStatus WINGDIPAPI GdipReleaseDC(GpGraphics *graphics, HDC hdc)
         graphics->temp_hdc = NULL;
         graphics->temp_hbitmap = NULL;
     }
+    else if (hdc != graphics->hdc)
+    {
+        stat = InvalidParameter;
+    }
 
-    graphics->busy = FALSE;
+    if (stat == Ok)
+        graphics->busy = FALSE;
 
-    return Ok;
+    return stat;
 }
 
 GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region)
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c
index 3d26b5c..3e79eb7 100644
--- a/dlls/gdiplus/metafile.c
+++ b/dlls/gdiplus/metafile.c
@@ -297,6 +297,36 @@ GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result)
     return stat;
 }
 
+GpStatus METAFILE_GetDC(GpMetafile* metafile, HDC *hdc)
+{
+    if (metafile->metafile_type == MetafileTypeEmfPlusOnly || metafile->metafile_type == MetafileTypeEmfPlusDual)
+    {
+        EmfPlusRecordHeader *record;
+        GpStatus stat;
+
+        stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusRecordHeader), (void**)&record);
+        if (stat != Ok)
+            return stat;
+
+        record->Type = EmfPlusRecordTypeGetDC;
+        record->Flags = 0;
+
+        METAFILE_WriteRecords(metafile);
+    }
+
+    *hdc = metafile->record_dc;
+
+    return Ok;
+}
+
+GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc)
+{
+    if (hdc != metafile->record_dc)
+        return InvalidParameter;
+
+    return Ok;
+}
+
 GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile)
 {
     GpStatus stat;
diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c
index c85de00..1a0da15 100644
--- a/dlls/gdiplus/tests/metafile.c
+++ b/dlls/gdiplus/tests/metafile.c
@@ -278,9 +278,9 @@ static void test_empty(void)
 static const emfplus_record getdc_records[] = {
     {0, EMR_HEADER},
     {0, EmfPlusRecordTypeHeader},
-    {1, EmfPlusRecordTypeGetDC},
-    {1, EMR_CREATEBRUSHINDIRECT},
-    {1, EMR_SELECTOBJECT},
+    {0, EmfPlusRecordTypeGetDC},
+    {0, EMR_CREATEBRUSHINDIRECT},
+    {0, EMR_SELECTOBJECT},
     {0, EMR_RECTANGLE},
     {0, EMR_SELECTOBJECT},
     {0, EMR_DELETEOBJECT},




More information about the wine-cvs mailing list