mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added patch to implement a better stub for IPicture::SaveAsFile.
This commit is contained in:
parent
4e02a7a17b
commit
66f37bcf33
@ -0,0 +1,418 @@
|
||||
From 0f30681ee760c8197b95273e6c38cd6c2a4164a6 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Mon, 21 Mar 2016 14:34:04 +0800
|
||||
Subject: gdiplus: Reimplement metafile loading using gdi32 instead of
|
||||
IPicture. (v2)
|
||||
|
||||
---
|
||||
dlls/gdiplus/Makefile.in | 2 +-
|
||||
dlls/gdiplus/gdiplus_private.h | 1 -
|
||||
dlls/gdiplus/graphics.c | 18 +---
|
||||
dlls/gdiplus/image.c | 204 +++++++++++++++++++++--------------------
|
||||
dlls/gdiplus/metafile.c | 1 -
|
||||
dlls/gdiplus/tests/image.c | 10 +-
|
||||
6 files changed, 113 insertions(+), 123 deletions(-)
|
||||
|
||||
diff --git a/dlls/gdiplus/Makefile.in b/dlls/gdiplus/Makefile.in
|
||||
index 6495eb7..ac12bd1 100644
|
||||
--- a/dlls/gdiplus/Makefile.in
|
||||
+++ b/dlls/gdiplus/Makefile.in
|
||||
@@ -1,6 +1,6 @@
|
||||
MODULE = gdiplus.dll
|
||||
IMPORTLIB = gdiplus
|
||||
-IMPORTS = uuid shlwapi oleaut32 ole32 user32 gdi32
|
||||
+IMPORTS = uuid shlwapi ole32 user32 gdi32
|
||||
DELAYIMPORTS = windowscodecs
|
||||
|
||||
C_SRCS = \
|
||||
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
|
||||
index 0013d75..5c8e7a4 100644
|
||||
--- a/dlls/gdiplus/gdiplus_private.h
|
||||
+++ b/dlls/gdiplus/gdiplus_private.h
|
||||
@@ -319,7 +319,6 @@ struct GpAdustableArrowCap{
|
||||
};
|
||||
|
||||
struct GpImage{
|
||||
- IPicture *picture;
|
||||
IWICBitmapDecoder *decoder;
|
||||
ImageType type;
|
||||
GUID format;
|
||||
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
|
||||
index 15c0bed..a51b689 100644
|
||||
--- a/dlls/gdiplus/graphics.c
|
||||
+++ b/dlls/gdiplus/graphics.c
|
||||
@@ -2897,23 +2897,7 @@ GpStatus WINGDIPAPI GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image
|
||||
srcheight = units_to_pixels(srcheight, srcUnit, image->yres);
|
||||
TRACE("src pixels: %f,%f %fx%f\n", srcx, srcy, srcwidth, srcheight);
|
||||
|
||||
- if (image->picture)
|
||||
- {
|
||||
- if (!graphics->hdc)
|
||||
- {
|
||||
- FIXME("graphics object has no HDC\n");
|
||||
- }
|
||||
-
|
||||
- if(IPicture_Render(image->picture, graphics->hdc,
|
||||
- pti[0].x, pti[0].y, pti[1].x - pti[0].x, pti[2].y - pti[0].y,
|
||||
- srcx, srcy, srcwidth, srcheight, NULL) != S_OK)
|
||||
- {
|
||||
- if(callback)
|
||||
- callback(callbackData);
|
||||
- return GenericError;
|
||||
- }
|
||||
- }
|
||||
- else if (image->type == ImageTypeBitmap)
|
||||
+ if (image->type == ImageTypeBitmap)
|
||||
{
|
||||
GpBitmap* bitmap = (GpBitmap*)image;
|
||||
BOOL do_resampling = FALSE;
|
||||
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
|
||||
index f803efa..2402c9d 100644
|
||||
--- a/dlls/gdiplus/image.c
|
||||
+++ b/dlls/gdiplus/image.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2007 Google (Evan Stade)
|
||||
- * Copyright (C) 2012 Dmitry Timoshkov
|
||||
+ * Copyright (C) 2012,2016 Dmitry Timoshkov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -124,34 +124,6 @@ static ColorPalette *get_palette(IWICBitmapFrameDecode *frame, WICBitmapPaletteT
|
||||
return palette;
|
||||
}
|
||||
|
||||
-static INT ipicture_pixel_height(IPicture *pic)
|
||||
-{
|
||||
- HDC hdcref;
|
||||
- OLE_YSIZE_HIMETRIC y;
|
||||
-
|
||||
- IPicture_get_Height(pic, &y);
|
||||
-
|
||||
- hdcref = CreateCompatibleDC(0);
|
||||
- y = MulDiv(y, GetDeviceCaps(hdcref, LOGPIXELSY), INCH_HIMETRIC);
|
||||
- DeleteDC(hdcref);
|
||||
-
|
||||
- return y;
|
||||
-}
|
||||
-
|
||||
-static INT ipicture_pixel_width(IPicture *pic)
|
||||
-{
|
||||
- HDC hdcref;
|
||||
- OLE_XSIZE_HIMETRIC x;
|
||||
-
|
||||
- IPicture_get_Width(pic, &x);
|
||||
-
|
||||
- hdcref = CreateCompatibleDC(0);
|
||||
- x = MulDiv(x, GetDeviceCaps(hdcref, LOGPIXELSX), INCH_HIMETRIC);
|
||||
- DeleteDC(hdcref);
|
||||
-
|
||||
- return x;
|
||||
-}
|
||||
-
|
||||
GpStatus WINGDIPAPI GdipBitmapApplyEffect(GpBitmap* bitmap, CGpEffect* effect,
|
||||
RECT* roi, BOOL useAuxData, VOID** auxData, INT* auxDataSize)
|
||||
{
|
||||
@@ -1309,45 +1281,12 @@ GpStatus WINGDIPAPI GdipCloneBitmapAreaI(INT x, INT y, INT width, INT height,
|
||||
|
||||
GpStatus WINGDIPAPI GdipCloneImage(GpImage *image, GpImage **cloneImage)
|
||||
{
|
||||
- GpStatus stat = GenericError;
|
||||
-
|
||||
TRACE("%p, %p\n", image, cloneImage);
|
||||
|
||||
if (!image || !cloneImage)
|
||||
return InvalidParameter;
|
||||
|
||||
- if (image->picture)
|
||||
- {
|
||||
- IStream* stream;
|
||||
- HRESULT hr;
|
||||
- INT size;
|
||||
- LARGE_INTEGER move;
|
||||
-
|
||||
- hr = CreateStreamOnHGlobal(0, TRUE, &stream);
|
||||
- if (FAILED(hr))
|
||||
- return GenericError;
|
||||
-
|
||||
- hr = IPicture_SaveAsFile(image->picture, stream, FALSE, &size);
|
||||
- if(FAILED(hr))
|
||||
- {
|
||||
- WARN("Failed to save image on stream\n");
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- /* Set seek pointer back to the beginning of the picture */
|
||||
- move.QuadPart = 0;
|
||||
- hr = IStream_Seek(stream, move, STREAM_SEEK_SET, NULL);
|
||||
- if (FAILED(hr))
|
||||
- goto out;
|
||||
-
|
||||
- stat = GdipLoadImageFromStream(stream, cloneImage);
|
||||
- if (stat != Ok) WARN("Failed to load image from stream\n");
|
||||
-
|
||||
- out:
|
||||
- IStream_Release(stream);
|
||||
- return stat;
|
||||
- }
|
||||
- else if (image->type == ImageTypeBitmap)
|
||||
+ if (image->type == ImageTypeBitmap)
|
||||
{
|
||||
GpBitmap *bitmap = (GpBitmap *)image;
|
||||
|
||||
@@ -1884,7 +1823,6 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
|
||||
(*bitmap)->width = width;
|
||||
(*bitmap)->height = height;
|
||||
(*bitmap)->format = format;
|
||||
- (*bitmap)->image.picture = NULL;
|
||||
(*bitmap)->image.decoder = NULL;
|
||||
(*bitmap)->hbitmap = hbitmap;
|
||||
(*bitmap)->hdc = NULL;
|
||||
@@ -2148,8 +2086,6 @@ static GpStatus free_image_data(GpImage *image)
|
||||
WARN("invalid image: %p\n", image);
|
||||
return ObjectBusy;
|
||||
}
|
||||
- if (image->picture)
|
||||
- IPicture_Release(image->picture);
|
||||
if (image->decoder)
|
||||
IWICBitmapDecoder_Release(image->decoder);
|
||||
heap_free(image->palette);
|
||||
@@ -2215,12 +2151,6 @@ GpStatus WINGDIPAPI GdipGetImageBounds(GpImage *image, GpRectF *srcRect,
|
||||
srcRect->Height = (REAL) ((GpBitmap*)image)->height;
|
||||
*srcUnit = UnitPixel;
|
||||
}
|
||||
- else{
|
||||
- srcRect->X = srcRect->Y = 0.0;
|
||||
- srcRect->Width = ipicture_pixel_width(image->picture);
|
||||
- srcRect->Height = ipicture_pixel_height(image->picture);
|
||||
- *srcUnit = UnitPixel;
|
||||
- }
|
||||
|
||||
TRACE("returning (%f, %f) (%f, %f) unit type %d\n", srcRect->X, srcRect->Y,
|
||||
srcRect->Width, srcRect->Height, *srcUnit);
|
||||
@@ -2244,10 +2174,6 @@ GpStatus WINGDIPAPI GdipGetImageDimension(GpImage *image, REAL *width,
|
||||
*height = ((GpBitmap*)image)->height;
|
||||
*width = ((GpBitmap*)image)->width;
|
||||
}
|
||||
- else{
|
||||
- *height = ipicture_pixel_height(image->picture);
|
||||
- *width = ipicture_pixel_width(image->picture);
|
||||
- }
|
||||
|
||||
TRACE("returning (%f, %f)\n", *height, *width);
|
||||
return Ok;
|
||||
@@ -2302,8 +2228,6 @@ GpStatus WINGDIPAPI GdipGetImageHeight(GpImage *image, UINT *height)
|
||||
*height = units_to_pixels(((GpMetafile*)image)->bounds.Height, ((GpMetafile*)image)->unit, image->yres);
|
||||
else if(image->type == ImageTypeBitmap)
|
||||
*height = ((GpBitmap*)image)->height;
|
||||
- else
|
||||
- *height = ipicture_pixel_height(image->picture);
|
||||
|
||||
TRACE("returning %d\n", *height);
|
||||
|
||||
@@ -2402,8 +2326,6 @@ GpStatus WINGDIPAPI GdipGetImageWidth(GpImage *image, UINT *width)
|
||||
*width = units_to_pixels(((GpMetafile*)image)->bounds.Width, ((GpMetafile*)image)->unit, image->xres);
|
||||
else if(image->type == ImageTypeBitmap)
|
||||
*width = ((GpBitmap*)image)->width;
|
||||
- else
|
||||
- *width = ipicture_pixel_width(image->picture);
|
||||
|
||||
TRACE("returning %d\n", *width);
|
||||
|
||||
@@ -3982,32 +3904,118 @@ static GpStatus decode_image_tiff(IStream* stream, GpImage **image)
|
||||
return decode_image_wic(stream, &GUID_ContainerFormatTiff, NULL, image);
|
||||
}
|
||||
|
||||
-static GpStatus decode_image_olepicture_metafile(IStream* stream, GpImage **image)
|
||||
+static GpStatus load_wmf(IStream *stream, GpMetafile **metafile)
|
||||
+{
|
||||
+ GpStatus status = GenericError;
|
||||
+ HRESULT hr;
|
||||
+ UINT size;
|
||||
+ LARGE_INTEGER pos;
|
||||
+ WmfPlaceableFileHeader pfh;
|
||||
+ BOOL is_placeable = FALSE;
|
||||
+ METAHEADER mh;
|
||||
+ HMETAFILE hmf;
|
||||
+ void *buf;
|
||||
+
|
||||
+ pos.QuadPart = 0;
|
||||
+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
|
||||
+
|
||||
+ hr = IStream_Read(stream, &mh, sizeof(mh), &size);
|
||||
+ if (hr != S_OK || size != sizeof(mh))
|
||||
+ return GenericError;
|
||||
+
|
||||
+ if (mh.mtType == 0xcdd7 && mh.mtHeaderSize == 0x9ac6)
|
||||
+ {
|
||||
+ is_placeable = TRUE;
|
||||
+
|
||||
+ pos.QuadPart = 0;
|
||||
+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
|
||||
+
|
||||
+ hr = IStream_Read(stream, &pfh, sizeof(pfh), &size);
|
||||
+ if (hr != S_OK || size != sizeof(pfh))
|
||||
+ return GenericError;
|
||||
+
|
||||
+ hr = IStream_Read(stream, &mh, sizeof(mh), &size);
|
||||
+ if (hr != S_OK || size != sizeof(mh))
|
||||
+ return GenericError;
|
||||
+ }
|
||||
+
|
||||
+ pos.QuadPart = is_placeable ? sizeof(pfh) : 0;
|
||||
+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
|
||||
+
|
||||
+ buf = heap_alloc(mh.mtSize * 2);
|
||||
+ if (!buf) return OutOfMemory;
|
||||
+
|
||||
+ hr = IStream_Read(stream, buf, mh.mtSize * 2, &size);
|
||||
+ if (hr == S_OK && size == mh.mtSize * 2)
|
||||
+ {
|
||||
+ hmf = SetMetaFileBitsEx(mh.mtSize * 2, buf);
|
||||
+ if (hmf)
|
||||
+ {
|
||||
+ status = GdipCreateMetafileFromWmf(hmf, TRUE, is_placeable ? &pfh : NULL, metafile);
|
||||
+ if (status != Ok)
|
||||
+ DeleteMetaFile(hmf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ heap_free(buf);
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+static GpStatus load_emf(IStream *stream, GpMetafile **metafile)
|
||||
{
|
||||
- IPicture *pic;
|
||||
+ GpStatus status = GenericError;
|
||||
+ HRESULT hr;
|
||||
+ UINT size;
|
||||
+ LARGE_INTEGER pos;
|
||||
+ ENHMETAHEADER emh;
|
||||
+ HENHMETAFILE hemf;
|
||||
+ void *buf;
|
||||
+
|
||||
+ pos.QuadPart = 0;
|
||||
+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
|
||||
+
|
||||
+ hr = IStream_Read(stream, &emh, sizeof(emh), &size);
|
||||
+ if (hr != S_OK || size != sizeof(emh) || emh.dSignature != ENHMETA_SIGNATURE)
|
||||
+ return GenericError;
|
||||
+
|
||||
+ pos.QuadPart = 0;
|
||||
+ IStream_Seek(stream, pos, STREAM_SEEK_SET, NULL);
|
||||
+
|
||||
+ buf = heap_alloc(emh.nBytes);
|
||||
+ if (!buf) return OutOfMemory;
|
||||
+
|
||||
+ hr = IStream_Read(stream, buf, emh.nBytes, &size);
|
||||
+ if (hr == S_OK && size == emh.nBytes)
|
||||
+ {
|
||||
+ hemf = SetEnhMetaFileBits(emh.nBytes, buf);
|
||||
+ if (hemf)
|
||||
+ {
|
||||
+ status = GdipCreateMetafileFromEmf(hemf, FALSE, metafile);
|
||||
+ if (status != Ok)
|
||||
+ DeleteEnhMetaFile(hemf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ heap_free(buf);
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+static GpStatus decode_image_metafile(IStream *stream, GpImage **image)
|
||||
+{
|
||||
+ GpMetafile *metafile;
|
||||
|
||||
TRACE("%p %p\n", stream, image);
|
||||
|
||||
if(!stream || !image)
|
||||
return InvalidParameter;
|
||||
|
||||
- if(OleLoadPicture(stream, 0, FALSE, &IID_IPicture,
|
||||
- (LPVOID*) &pic) != S_OK){
|
||||
- TRACE("Could not load picture\n");
|
||||
+ if (load_emf(stream, &metafile) != Ok && load_wmf(stream, &metafile) != Ok)
|
||||
+ {
|
||||
+ TRACE("Could not load metafile\n");
|
||||
return GenericError;
|
||||
}
|
||||
|
||||
- /* FIXME: missing initialization code */
|
||||
- *image = heap_alloc_zero(sizeof(GpMetafile));
|
||||
- if(!*image) return OutOfMemory;
|
||||
- (*image)->type = ImageTypeMetafile;
|
||||
- (*image)->decoder = NULL;
|
||||
- (*image)->picture = pic;
|
||||
- (*image)->flags = ImageFlagsNone;
|
||||
- (*image)->frame_count = 1;
|
||||
- (*image)->current_frame = 0;
|
||||
- (*image)->palette = NULL;
|
||||
-
|
||||
+ *image = (GpImage *)metafile;
|
||||
TRACE("<-- %p\n", *image);
|
||||
|
||||
return Ok;
|
||||
@@ -4665,7 +4673,7 @@ static const struct image_codec codecs[NUM_CODECS] = {
|
||||
/* SigMask */ emf_sig_mask,
|
||||
},
|
||||
NULL,
|
||||
- decode_image_olepicture_metafile,
|
||||
+ decode_image_metafile,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
@@ -4685,7 +4693,7 @@ static const struct image_codec codecs[NUM_CODECS] = {
|
||||
/* SigMask */ wmf_sig_mask,
|
||||
},
|
||||
NULL,
|
||||
- decode_image_olepicture_metafile,
|
||||
+ decode_image_metafile,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c
|
||||
index 922c101..e8bab06 100644
|
||||
--- a/dlls/gdiplus/metafile.c
|
||||
+++ b/dlls/gdiplus/metafile.c
|
||||
@@ -255,7 +255,6 @@ GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF
|
||||
}
|
||||
|
||||
(*metafile)->image.type = ImageTypeMetafile;
|
||||
- (*metafile)->image.picture = NULL;
|
||||
(*metafile)->image.flags = ImageFlagsNone;
|
||||
(*metafile)->image.palette = NULL;
|
||||
(*metafile)->image.xres = dpix;
|
||||
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
|
||||
index 6a51714..e6de9db 100644
|
||||
--- a/dlls/gdiplus/tests/image.c
|
||||
+++ b/dlls/gdiplus/tests/image.c
|
||||
@@ -1446,19 +1446,19 @@ static void test_loadwmf(void)
|
||||
|
||||
stat = GdipGetImageBounds(img, &bounds, &unit);
|
||||
expect(Ok, stat);
|
||||
- todo_wine expect(UnitPixel, unit);
|
||||
+ expect(UnitPixel, unit);
|
||||
expectf(0.0, bounds.X);
|
||||
expectf(0.0, bounds.Y);
|
||||
- todo_wine expectf(320.0, bounds.Width);
|
||||
- todo_wine expectf(320.0, bounds.Height);
|
||||
+ expectf(320.0, bounds.Width);
|
||||
+ expectf(320.0, bounds.Height);
|
||||
|
||||
stat = GdipGetImageHorizontalResolution(img, &res);
|
||||
expect(Ok, stat);
|
||||
- todo_wine expectf(1440.0, res);
|
||||
+ expectf(1440.0, res);
|
||||
|
||||
stat = GdipGetImageVerticalResolution(img, &res);
|
||||
expect(Ok, stat);
|
||||
- todo_wine expectf(1440.0, res);
|
||||
+ expectf(1440.0, res);
|
||||
|
||||
memset(&header, 0, sizeof(header));
|
||||
stat = GdipGetMetafileHeaderFromMetafile((GpMetafile*)img, &header);
|
||||
--
|
||||
2.7.1
|
||||
|
@ -0,0 +1,179 @@
|
||||
From bbb052887041a94a770154f5b9e266b17876fe9a Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Tue, 24 Nov 2015 17:22:02 +0800
|
||||
Subject: oleaut32: Implement a better stub for IPicture::SaveAsFile.
|
||||
|
||||
Based on OLEPictureImpl_Save implementation.
|
||||
|
||||
For bug 8532.
|
||||
---
|
||||
dlls/oleaut32/olepicture.c | 92 ++++++++++++++++++++++++++++++++++------
|
||||
dlls/oleaut32/tests/olepicture.c | 9 ----
|
||||
2 files changed, 79 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c
|
||||
index 44157de..c57b878 100644
|
||||
--- a/dlls/oleaut32/olepicture.c
|
||||
+++ b/dlls/oleaut32/olepicture.c
|
||||
@@ -834,19 +834,6 @@ static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface)
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
- * OLEPictureImpl_SaveAsFile
|
||||
- */
|
||||
-static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
|
||||
- IStream *pstream,
|
||||
- BOOL SaveMemCopy,
|
||||
- LONG *pcbSize)
|
||||
-{
|
||||
- OLEPictureImpl *This = impl_from_IPicture(iface);
|
||||
- FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This, pstream, SaveMemCopy, pcbSize);
|
||||
- return IStream_Write(pstream,This->data,This->datalen,(ULONG*)pcbSize);
|
||||
-}
|
||||
-
|
||||
-/************************************************************************
|
||||
* OLEPictureImpl_get_Attributes
|
||||
*/
|
||||
static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
|
||||
@@ -1859,6 +1846,85 @@ static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
+/************************************************************************
|
||||
+ * OLEPictureImpl_SaveAsFile
|
||||
+ */
|
||||
+static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
|
||||
+ IStream *stream, BOOL mem_copy, LONG *size)
|
||||
+{
|
||||
+ OLEPictureImpl *This = impl_from_IPicture(iface);
|
||||
+ void *data;
|
||||
+ unsigned data_size;
|
||||
+ ULONG written;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ FIXME("(%p)->(%p,%d,%p): semi-stub\n", This, stream, mem_copy, size);
|
||||
+
|
||||
+ switch (This->desc.picType)
|
||||
+ {
|
||||
+ case PICTYPE_NONE:
|
||||
+ return S_OK;
|
||||
+
|
||||
+ case PICTYPE_ICON:
|
||||
+ if (!mem_copy) return E_FAIL;
|
||||
+
|
||||
+ if (This->bIsDirty || !This->data)
|
||||
+ {
|
||||
+ if (!serializeIcon(This->desc.u.icon.hicon, &data, &data_size))
|
||||
+ return E_FAIL;
|
||||
+ HeapFree(GetProcessHeap(), 0, This->data);
|
||||
+ This->data = data;
|
||||
+ This->datalen = data_size;
|
||||
+ }
|
||||
+ hr = IStream_Write(stream, This->data, This->datalen, &written);
|
||||
+ if (hr == S_OK && size) *size = written;
|
||||
+ return hr;
|
||||
+
|
||||
+ case PICTYPE_BITMAP:
|
||||
+ if (!mem_copy) return E_FAIL;
|
||||
+
|
||||
+ if (This->bIsDirty || !This->data)
|
||||
+ {
|
||||
+ switch (This->keepOrigFormat ? This->loadtime_format : BITMAP_FORMAT_BMP)
|
||||
+ {
|
||||
+ case BITMAP_FORMAT_BMP:
|
||||
+ if (!serializeBMP(This->desc.u.bmp.hbitmap, &data, &data_size))
|
||||
+ return E_FAIL;
|
||||
+ break;
|
||||
+ case BITMAP_FORMAT_JPEG:
|
||||
+ FIXME("BITMAP_FORMAT_JPEG is not implemented\n");
|
||||
+ return E_NOTIMPL;
|
||||
+ case BITMAP_FORMAT_GIF:
|
||||
+ FIXME("BITMAP_FORMAT_GIF is not implemented\n");
|
||||
+ return E_NOTIMPL;
|
||||
+ case BITMAP_FORMAT_PNG:
|
||||
+ FIXME("BITMAP_FORMAT_PNG is not implemented\n");
|
||||
+ return E_NOTIMPL;
|
||||
+ default:
|
||||
+ FIXME("PICTYPE_BITMAP/%#x is not implemented\n", This->loadtime_format);
|
||||
+ return E_NOTIMPL;
|
||||
+ }
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, This->data);
|
||||
+ This->data = data;
|
||||
+ This->datalen = data_size;
|
||||
+ }
|
||||
+ hr = IStream_Write(stream, This->data, This->datalen, &written);
|
||||
+ if (hr == S_OK && size) *size = written;
|
||||
+ return hr;
|
||||
+
|
||||
+ case PICTYPE_METAFILE:
|
||||
+ FIXME("PICTYPE_METAFILE is not implemented\n");
|
||||
+ return E_NOTIMPL;
|
||||
+ case PICTYPE_ENHMETAFILE:
|
||||
+ FIXME("ENHMETAFILE is not implemented\n");
|
||||
+ return E_NOTIMPL;
|
||||
+ default:
|
||||
+ FIXME("%#x is not implemented\n", This->desc.picType);
|
||||
+ break;
|
||||
+ }
|
||||
+ return E_NOTIMPL;
|
||||
+}
|
||||
|
||||
/************************************************************************
|
||||
* IDispatch
|
||||
diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c
|
||||
index 0903298..0c69cbd 100644
|
||||
--- a/dlls/oleaut32/tests/olepicture.c
|
||||
+++ b/dlls/oleaut32/tests/olepicture.c
|
||||
@@ -1079,18 +1079,14 @@ static void test_load_save_bmp(void)
|
||||
size = -1;
|
||||
hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
|
||||
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
|
||||
-todo_wine
|
||||
ok(size == 66, "expected 66, got %d\n", size);
|
||||
mem = GlobalLock(hmem);
|
||||
-todo_wine
|
||||
ok(!memcmp(&mem[0], "BM", 2), "got wrong bmp header %04x\n", mem[0]);
|
||||
GlobalUnlock(hmem);
|
||||
|
||||
size = -1;
|
||||
hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
|
||||
-todo_wine
|
||||
ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr);
|
||||
-todo_wine
|
||||
ok(size == -1, "expected -1, got %d\n", size);
|
||||
|
||||
offset.QuadPart = 0;
|
||||
@@ -1157,15 +1153,12 @@ static void test_load_save_icon(void)
|
||||
todo_wine
|
||||
ok(size == 766, "expected 766, got %d\n", size);
|
||||
mem = GlobalLock(hmem);
|
||||
-todo_wine
|
||||
ok(mem[0] == 0x00010000, "got wrong icon header %04x\n", mem[0]);
|
||||
GlobalUnlock(hmem);
|
||||
|
||||
size = -1;
|
||||
hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
|
||||
-todo_wine
|
||||
ok(hr == E_FAIL, "expected E_FAIL, got %#x\n", hr);
|
||||
-todo_wine
|
||||
ok(size == -1, "expected -1, got %d\n", size);
|
||||
|
||||
offset.QuadPart = 0;
|
||||
@@ -1231,13 +1224,11 @@ static void test_load_save_empty_picture(void)
|
||||
size = -1;
|
||||
hr = IPicture_SaveAsFile(pic, dst_stream, TRUE, &size);
|
||||
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
|
||||
-todo_wine
|
||||
ok(size == -1, "expected -1, got %d\n", size);
|
||||
|
||||
size = -1;
|
||||
hr = IPicture_SaveAsFile(pic, dst_stream, FALSE, &size);
|
||||
ok(hr == S_OK, "IPicture_SaveasFile error %#x\n", hr);
|
||||
-todo_wine
|
||||
ok(size == -1, "expected -1, got %d\n", size);
|
||||
|
||||
hr = IPicture_QueryInterface(pic, &IID_IPersistStream, (void **)&src_stream);
|
||||
--
|
||||
2.7.1
|
||||
|
1
patches/oleaut32-OLEPictureImpl_SaveAsFile/definition
Normal file
1
patches/oleaut32-OLEPictureImpl_SaveAsFile/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: [8532] Implement a better stub for IPicture::SaveAsFile
|
@ -254,6 +254,7 @@ patch_enable_all ()
|
||||
enable_nvencodeapi_Video_Encoder="$1"
|
||||
enable_ole32_HGLOBALStream="$1"
|
||||
enable_oleaut32_CreateTypeLib="$1"
|
||||
enable_oleaut32_OLEPictureImpl_SaveAsFile="$1"
|
||||
enable_oleaut32_TKIND_COCLASS="$1"
|
||||
enable_oleaut32_x86_64_Marshaller="$1"
|
||||
enable_openal32_EFX_Extension="$1"
|
||||
@ -933,6 +934,9 @@ patch_enable ()
|
||||
oleaut32-CreateTypeLib)
|
||||
enable_oleaut32_CreateTypeLib="$2"
|
||||
;;
|
||||
oleaut32-OLEPictureImpl_SaveAsFile)
|
||||
enable_oleaut32_OLEPictureImpl_SaveAsFile="$2"
|
||||
;;
|
||||
oleaut32-TKIND_COCLASS)
|
||||
enable_oleaut32_TKIND_COCLASS="$2"
|
||||
;;
|
||||
@ -5523,6 +5527,24 @@ if test "$enable_oleaut32_CreateTypeLib" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset oleaut32-OLEPictureImpl_SaveAsFile
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#8532] Implement a better stub for IPicture::SaveAsFile
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/gdiplus/Makefile.in, dlls/gdiplus/gdiplus_private.h, dlls/gdiplus/graphics.c, dlls/gdiplus/image.c,
|
||||
# | dlls/gdiplus/metafile.c, dlls/gdiplus/tests/image.c, dlls/oleaut32/olepicture.c, dlls/oleaut32/tests/olepicture.c
|
||||
# |
|
||||
if test "$enable_oleaut32_OLEPictureImpl_SaveAsFile" -eq 1; then
|
||||
patch_apply oleaut32-OLEPictureImpl_SaveAsFile/0001-gdiplus-Reimplement-metafile-loading-using-gdi32-ins.patch
|
||||
patch_apply oleaut32-OLEPictureImpl_SaveAsFile/0002-oleaut32-Implement-a-better-stub-for-IPicture-SaveAs.patch
|
||||
(
|
||||
echo '+ { "Dmitry Timoshkov", "gdiplus: Reimplement metafile loading using gdi32 instead of IPicture.", 2 },';
|
||||
echo '+ { "Dmitry Timoshkov", "oleaut32: Implement a better stub for IPicture::SaveAsFile.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset oleaut32-TKIND_COCLASS
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
|
Loading…
Reference in New Issue
Block a user