Kirill K. Smirnov : oleaut32: Add tests for metafiles, make them pass under Wine.

Alexandre Julliard julliard at winehq.org
Mon Oct 6 09:35:18 CDT 2008


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

Author: Kirill K. Smirnov <lich at math.spbu.ru>
Date:   Sat Oct  4 03:24:37 2008 +0400

oleaut32: Add tests for metafiles, make them pass under Wine.

---

 dlls/oleaut32/olepicture.c       |   57 ++++++++++----------
 dlls/oleaut32/tests/olepicture.c |  110 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 139 insertions(+), 28 deletions(-)

diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c
index 8dc10ed..09d2c32 100644
--- a/dlls/oleaut32/olepicture.c
+++ b/dlls/oleaut32/olepicture.c
@@ -5,6 +5,7 @@
  *
  * Copyright 2000 Huw D M Davies for CodeWeavers.
  * Copyright 2001 Marcus Meissner
+ * Copyright 2008 Kirill K. Smirnov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -1686,39 +1687,24 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x
     }
 }
 
-static HRESULT OLEPictureImpl_LoadMetafile(OLEPictureImpl *This,
-                                           const BYTE *data, ULONG size)
+static HRESULT OLEPictureImpl_LoadEnhMetafile(OLEPictureImpl *This,
+                                              const BYTE *data, ULONG size)
 {
-    HMETAFILE hmf;
     HENHMETAFILE hemf;
-
-    /* SetMetaFileBitsEx performs data check on its own */
-    hmf = SetMetaFileBitsEx(size, data);
-    if (hmf)
-    {
-        This->desc.picType = PICTYPE_METAFILE;
-        This->desc.u.wmf.hmeta = hmf;
-        This->desc.u.wmf.xExt = 0;
-        This->desc.u.wmf.yExt = 0;
-
-        This->origWidth = 0;
-        This->origHeight = 0;
-        This->himetricWidth = 0;
-        This->himetricHeight = 0;
-
-        return S_OK;
-    }
+    ENHMETAHEADER hdr;
 
     hemf = SetEnhMetaFileBits(size, data);
     if (!hemf) return E_FAIL;
 
+    GetEnhMetaFileHeader(hemf, sizeof(hdr), &hdr);
+
     This->desc.picType = PICTYPE_ENHMETAFILE;
     This->desc.u.emf.hemf = hemf;
 
     This->origWidth = 0;
     This->origHeight = 0;
-    This->himetricWidth = 0;
-    This->himetricHeight = 0;
+    This->himetricWidth = hdr.rclFrame.right - hdr.rclFrame.left;
+    This->himetricHeight = hdr.rclFrame.bottom - hdr.rclFrame.top;
 
     return S_OK;
 }
@@ -1727,16 +1713,24 @@ static HRESULT OLEPictureImpl_LoadAPM(OLEPictureImpl *This,
                                       const BYTE *data, ULONG size)
 {
     APM_HEADER *header = (APM_HEADER *)data;
-    HRESULT hr;
+    HMETAFILE hmf;
 
     if (size < sizeof(APM_HEADER))
         return E_FAIL;
     if (header->key != 0x9ac6cdd7)
         return E_FAIL;
 
-    if ((hr = OLEPictureImpl_LoadMetafile(This, data + sizeof(APM_HEADER), size - sizeof(*header))) != S_OK)
-        return hr;
+    /* SetMetaFileBitsEx performs data check on its own */
+    hmf = SetMetaFileBitsEx(size - sizeof(*header), data + sizeof(*header));
+    if (!hmf) return E_FAIL;
 
+    This->desc.picType = PICTYPE_METAFILE;
+    This->desc.u.wmf.hmeta = hmf;
+    This->desc.u.wmf.xExt = 0;
+    This->desc.u.wmf.yExt = 0;
+
+    This->origWidth = 0;
+    This->origHeight = 0;
     This->himetricWidth = MulDiv((INT)header->right - header->left, 2540, header->inch);
     This->himetricHeight = MulDiv((INT)header->bottom - header->top, 2540, header->inch);
     return S_OK;
@@ -1924,8 +1918,8 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
   {
     unsigned int i;
 
-    /* let's see if it's a metafile */
-    hr = OLEPictureImpl_LoadMetafile(This, xbuf, xread);
+    /* let's see if it's a EMF */
+    hr = OLEPictureImpl_LoadEnhMetafile(This, xbuf, xread);
     if (hr == S_OK) break;
 
     FIXME("Unknown magic %04x, %d read bytes:\n",magic,xread);
@@ -2687,8 +2681,15 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
       *ppvObj = NULL;
       return hr;
   }
-  IPersistStream_Load(ps,lpstream);
+  hr = IPersistStream_Load(ps,lpstream);
   IPersistStream_Release(ps);
+  if (FAILED(hr))
+  {
+      ERR("IPersistStream_Load failed\n");
+      IPicture_Release(newpic);
+      *ppvObj = NULL;
+      return hr;
+  }
   hr = IPicture_QueryInterface(newpic,riid,ppvObj);
   if (hr)
       FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c
index c0d0de9..3f44696 100644
--- a/dlls/oleaut32/tests/olepicture.c
+++ b/dlls/oleaut32/tests/olepicture.c
@@ -121,6 +121,53 @@ static const unsigned char apmdata[] = {
 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00
 };
 
+/* MF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
+static const unsigned char metafile[] = {
+    0x01, 0x00, 0x09, 0x00, 0x00, 0x03, 0x19, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x0a,
+    0x16, 0x00, 0x0b, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x54, 0x65, 0x73, 0x74, 0x03, 0x00, 0x05, 0x00,
+    0x08, 0x00, 0x0c, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x00, 0x00
+};
+
+/* EMF_TEXTOUT_ON_PATH_BITS from gdi32/tests/metafile.c */
+static const unsigned char enhmetafile[] = {
+    0x01, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xe7, 0xff, 0xff, 0xff, 0xe9, 0xff, 0xff, 0xff,
+    0x20, 0x45, 0x4d, 0x46, 0x00, 0x00, 0x01, 0x00,
+    0xf4, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+    0x40, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x04, 0x00,
+    0x80, 0xa9, 0x03, 0x00, 0x3b, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00,
+    0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xc8, 0x41, 0x00, 0x80, 0xbb, 0x41,
+    0x0b, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x54, 0x00, 0x00, 0x00,
+    0x54, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+    0x3c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x14, 0x00, 0x00, 0x00
+};
+
+
 struct NoStatStreamImpl
 {
 	const IStreamVtbl	*lpVtbl;   
@@ -478,6 +525,67 @@ static void test_apm()
     ole_expect(IPicture_get_hPal(pict, &handle), E_FAIL);
     IPicture_Release(pict);
     IStream_Release(stream);
+    GlobalUnlock(hglob);
+    GlobalFree(hglob);
+}
+
+static void test_metafile(void)
+{
+    LPSTREAM stream;
+    IPicture *pict;
+    HGLOBAL hglob;
+    LPBYTE *data;
+
+    hglob = GlobalAlloc (0, sizeof(metafile));
+    data = GlobalLock(hglob);
+    memcpy(data, metafile, sizeof(metafile));
+
+    ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
+    /* Windows does not load simple metafiles */
+    ole_expect(OleLoadPictureEx(stream, sizeof(metafile), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict), E_FAIL);
+
+    IStream_Release(stream);
+    GlobalUnlock(hglob);
+    GlobalFree(hglob);
+}
+
+static void test_enhmetafile(void)
+{
+    OLE_HANDLE handle;
+    LPSTREAM stream;
+    IPicture *pict;
+    HGLOBAL hglob;
+    LPBYTE *data;
+    LONG cxy;
+    BOOL keep;
+    short type;
+
+    hglob = GlobalAlloc (0, sizeof(enhmetafile));
+    data = GlobalLock(hglob);
+    memcpy(data, enhmetafile, sizeof(enhmetafile));
+
+    ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream));
+    ole_check(OleLoadPictureEx(stream, sizeof(enhmetafile), TRUE, &IID_IPicture, 10, 10, 0, (LPVOID *)&pict));
+
+    ole_check(IPicture_get_Handle(pict, &handle));
+    ok(handle != 0, "handle is null\n");
+
+    ole_check(IPicture_get_Type(pict, &type));
+    expect_eq(type, PICTYPE_ENHMETAFILE, short, "%d");
+
+    ole_check(IPicture_get_Height(pict, &cxy));
+    expect_eq(cxy, -23, LONG, "%d");
+
+    ole_check(IPicture_get_Width(pict, &cxy));
+    expect_eq(cxy, -25, LONG, "%d");
+
+    ole_check(IPicture_get_KeepOriginalFormat(pict, &keep));
+    todo_wine expect_eq(keep, FALSE, LONG, "%d");
+
+    IPicture_Release(pict);
+    IStream_Release(stream);
+    GlobalUnlock(hglob);
+    GlobalFree(hglob);
 }
 
 START_TEST(olepicture)
@@ -501,6 +609,8 @@ START_TEST(olepicture)
 	test_empty_image();
 	test_empty_image_2();
         test_apm();
+        test_metafile();
+        test_enhmetafile();
 
 	test_Invoke();
         test_OleCreatePictureIndirect();




More information about the wine-cvs mailing list