[1/8] gdiplus: partial implementation of GdipCreateMetafileFromWMF

Evan Stade estade at gmail.com
Mon Jul 30 21:10:03 CDT 2007


Hi,

This series of patches (along with the oleaut32 one) allows PPTViewer
to render WMFs. (PPTViewer fails to do this using native gdiplus).
They use the IPicture interface to load and render images (right now
only WMF). This implementation is kind of a just-enough approach, as a
lot of functions are somewhere between fully implemented and stubs,
and I plan to elaborate the functions as I find presentations that
need it.

 dlls/gdiplus/Makefile.in       |    2 +
 dlls/gdiplus/gdiplus_private.h |   18 ++++++++++++
 dlls/gdiplus/graphics.c        |   58 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 75 insertions(+), 3 deletions(-)

-- 
Evan Stade
-------------- next part --------------
diff --git a/dlls/gdiplus/Makefile.in b/dlls/gdiplus/Makefile.in
index dc4e2e0..75feb39 100644
--- a/dlls/gdiplus/Makefile.in
+++ b/dlls/gdiplus/Makefile.in
@@ -4,7 +4,7 @@ SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = gdiplus.dll
 IMPORTLIB = libgdiplus.$(IMPLIBEXT)
-IMPORTS   = user32 gdi32 advapi32 kernel32 ntdll
+IMPORTS   = user32 gdi32 advapi32 kernel32 ntdll ole32 oleaut32
 
 C_SRCS = \
 	brush.c \
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index b9420a3..8050125 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -20,13 +20,22 @@ #ifndef __WINE_GP_PRIVATE_H_
 #define __WINE_GP_PRIVATE_H_
 
 #include <math.h>
+#include <stdarg.h>
+
 #include "windef.h"
 #include "wingdi.h"
+#include "winbase.h"
+#include "winuser.h"
+
+#include "objbase.h"
+#include "ocidl.h"
+
 #include "gdiplus.h"
 
 #define GP_DEFAULT_PENSTYLE (PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_FLAT | PS_JOIN_MITER)
 #define MAX_ARC_PTS (13)
 #define MAX_DASHLEN (16) /* this is a limitation of gdi */
+#define INCH_HIMETRIC (2540)
 
 COLORREF ARGB2COLORREF(ARGB color);
 extern INT arc2polybezier(GpPointF * points, REAL x1, REAL y1, REAL x2, REAL y2,
@@ -108,4 +117,13 @@ struct GpCustomLineCap{
     REAL inset;     /* how much to adjust the end of the line */
 };
 
+struct GpImage{
+    IPicture* picture;
+    ImageType type;
+};
+
+struct GpMetafile{
+    GpImage image;
+};
+
 #endif
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index f89db61..048f715 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -19,10 +19,18 @@
 #include <stdarg.h>
 #include <math.h>
 
+#define INITGUID
 #include "windef.h"
 #include "winbase.h"
 #include "winuser.h"
 #include "wingdi.h"
+
+#define COBJMACROS
+#include "objbase.h"
+#include "ocidl.h"
+#include "olectl.h"
+#include "ole2.h"
+
 #include "gdiplus.h"
 #include "gdiplus_private.h"
 #include "wine/debug.h"
@@ -835,14 +843,60 @@ GpStatus WINGDIPAPI GdipCreateMetafileFr
     GDIPCONST WmfPlaceableFileHeader * placeable, GpMetafile **metafile)
 {
     static int calls;
+    IStream *stream;
+    UINT read;
+    BYTE* copy;
+    METAFILEPICT mfp;
+    HENHMETAFILE hemf;
 
     if(!hwmf || !metafile || !placeable)
         return InvalidParameter;
 
     if(!(calls++))
-        FIXME("not implemented\n");
+        FIXME("partially implemented\n");
 
-    return NotImplemented;
+    if(placeable->Inch != INCH_HIMETRIC)
+        return NotImplemented;
+
+    mfp.mm   = MM_HIMETRIC;
+    mfp.xExt = placeable->BoundingBox.Right - placeable->BoundingBox.Left;
+    mfp.yExt = placeable->BoundingBox.Bottom - placeable->BoundingBox.Top;
+    mfp.hMF  = NULL;
+
+    read = GetMetaFileBitsEx(hwmf, 0, NULL);
+    if(!read)
+        return GenericError;
+    copy = GdipAlloc(read);
+    GetMetaFileBitsEx(hwmf, read, copy);
+
+    hemf = SetWinMetaFileBits(read, copy, NULL, &mfp);
+    GdipFree(copy);
+
+    read = GetEnhMetaFileBits(hemf, 0, NULL);
+    copy = GdipAlloc(read);
+    GetEnhMetaFileBits(hemf, read, copy);
+    DeleteEnhMetaFile(hemf);
+
+    if(CreateStreamOnHGlobal(copy, TRUE, &stream) != S_OK){
+        ERR("could not make stream\n");
+        return GenericError;
+    }
+
+    *metafile = GdipAlloc(sizeof(GpMetafile));
+    if(!*metafile)  return OutOfMemory;
+
+    if(OleLoadPicture(stream, 0, FALSE, &IID_IPicture,
+        (LPVOID*) &((*metafile)->image.picture)) != S_OK){
+        GdipFree(*metafile);
+        return GenericError;
+    }
+
+    (*metafile)->image.type = ImageTypeMetafile;
+
+    if(delete)
+        DeleteMetaFile(hwmf);
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipDeleteGraphics(GpGraphics *graphics)
-- 
1.4.1


More information about the wine-patches mailing list