[GDIPLUS] Sync with Wine Staging 1.9.11. CORE-11368
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 5 Jun 2016 19:08:07 +0000 (19:08 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 5 Jun 2016 19:08:07 +0000 (19:08 +0000)
svn path=/trunk/; revision=71546

reactos/dll/win32/gdiplus/gdiplus.spec
reactos/dll/win32/gdiplus/gdiplus_private.h
reactos/dll/win32/gdiplus/graphics.c
reactos/dll/win32/gdiplus/graphicspath.c
reactos/dll/win32/gdiplus/image.c
reactos/dll/win32/gdiplus/metafile.c
reactos/media/doc/README.WINE

index 9f7ce5f..893796e 100644 (file)
 303 stdcall GdipGetMetafileHeaderFromFile(wstr ptr)
 304 stdcall GdipGetMetafileHeaderFromMetafile(ptr ptr)
 305 stdcall GdipGetMetafileHeaderFromStream(ptr ptr)
-306 stub GdipGetMetafileHeaderFromWmf
+306 stdcall GdipGetMetafileHeaderFromWmf(ptr ptr ptr)
 307 stdcall GdipGetNearestColor(ptr ptr)
 308 stdcall GdipGetPageScale(ptr ptr)
 309 stdcall GdipGetPageUnit(ptr ptr)
index d52eb5d..316e25a 100644 (file)
@@ -327,7 +327,6 @@ struct GpAdustableArrowCap{
 };
 
 struct GpImage{
-    IPicture *picture;
     IWICBitmapDecoder *decoder;
     ImageType type;
     GUID format;
@@ -351,6 +350,7 @@ struct GpMetafile{
     BYTE *comment_data;
     DWORD comment_data_size;
     DWORD comment_data_length;
+    IStream *record_stream;
 
     /* playback */
     GpGraphics *playback_graphics;
index 0a4eedd..b6daf84 100644 (file)
@@ -2893,23 +2893,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;
@@ -6432,13 +6416,6 @@ GpStatus WINGDIPAPI GdipDrawDriverString(GpGraphics *graphics, GDIPCONST UINT16
                               brush, positions, flags, matrix);
 }
 
-GpStatus WINGDIPAPI GdipRecordMetafileStream(IStream *stream, HDC hdc, EmfType type, GDIPCONST GpRect *frameRect,
-                                        MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
-{
-    FIXME("(%p %p %d %p %d %p %p): stub\n", stream, hdc, type, frameRect, frameUnit, desc, metafile);
-    return NotImplemented;
-}
-
 /*****************************************************************************
  * GdipIsVisibleClipEmpty [GDIPLUS.@]
  */
index 9901502..06962fb 100644 (file)
@@ -1202,11 +1202,9 @@ GpStatus WINGDIPAPI GdipFlattenPath(GpPath *path, GpMatrix* matrix, REAL flatnes
     if(path->pathdata.Count == 0)
         return Ok;
 
-    if(matrix){
-        stat = GdipTransformPath(path, matrix);
-        if (stat != Ok)
-            return stat;
-    }
+    stat = GdipTransformPath(path, matrix);
+    if(stat != Ok)
+        return stat;
 
     pt = path->pathdata.Points[0];
     if(!init_path_list(&list, pt.X, pt.Y))
@@ -1663,7 +1661,7 @@ GpStatus WINGDIPAPI GdipTransformPath(GpPath *path, GpMatrix *matrix)
     if(!path)
         return InvalidParameter;
 
-    if(path->pathdata.Count == 0)
+    if(path->pathdata.Count == 0 || !matrix)
         return Ok;
 
     return GdipTransformMatrixPoints(matrix, path->pathdata.Points,
index 7d6849d..12fe092 100644 (file)
@@ -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
@@ -107,34 +107,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)
 {
@@ -1292,45 +1264,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;
 
@@ -1867,7 +1806,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;
@@ -2125,14 +2063,16 @@ static GpStatus free_image_data(GpImage *image)
             metafile->record_graphics->image = NULL;
             metafile->record_graphics->busy = TRUE;
         }
+        if (metafile->record_stream)
+        {
+            IStream_Release(metafile->record_stream);
+        }
     }
     else
     {
         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);
@@ -2198,12 +2138,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);
@@ -2227,10 +2161,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;
@@ -2285,8 +2215,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);
 
@@ -2385,8 +2313,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);
 
@@ -3965,32 +3891,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;
@@ -4648,7 +4660,7 @@ static const struct image_codec codecs[NUM_CODECS] = {
             /* SigMask */            emf_sig_mask,
         },
         NULL,
-        decode_image_olepicture_metafile,
+        decode_image_metafile,
         NULL
     },
     {
@@ -4668,7 +4680,7 @@ static const struct image_codec codecs[NUM_CODECS] = {
             /* SigMask */            wmf_sig_mask,
         },
         NULL,
-        decode_image_olepicture_metafile,
+        decode_image_metafile,
         NULL
     },
     {
index 40a03e2..77c9eb3 100644 (file)
@@ -173,7 +173,7 @@ GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF
     HDC record_dc;
     REAL dpix, dpiy;
     REAL framerect_factor_x, framerect_factor_y;
-    RECT rc;
+    RECT rc, *lprc;
     GpStatus stat;
 
     TRACE("(%p %d %p %d %p %p)\n", hdc, type, frameRect, frameUnit, desc, metafile);
@@ -181,46 +181,47 @@ GpStatus WINGDIPAPI GdipRecordMetafile(HDC hdc, EmfType type, GDIPCONST GpRectF
     if (!hdc || type < EmfTypeEmfOnly || type > EmfTypeEmfPlusDual || !metafile)
         return InvalidParameter;
 
-    if (!frameRect)
-    {
-        FIXME("not implemented for NULL rect\n");
-        return NotImplemented;
-    }
-
     dpix = (REAL)GetDeviceCaps(hdc, HORZRES) / GetDeviceCaps(hdc, HORZSIZE) * 25.4;
     dpiy = (REAL)GetDeviceCaps(hdc, VERTRES) / GetDeviceCaps(hdc, VERTSIZE) * 25.4;
 
-    switch (frameUnit)
+    if (frameRect)
     {
-    case MetafileFrameUnitPixel:
-        framerect_factor_x = 2540.0 / dpix;
-        framerect_factor_y = 2540.0 / dpiy;
-        break;
-    case MetafileFrameUnitPoint:
-        framerect_factor_x = framerect_factor_y = 2540.0 / 72.0;
-        break;
-    case MetafileFrameUnitInch:
-        framerect_factor_x = framerect_factor_y = 2540.0;
-        break;
-    case MetafileFrameUnitDocument:
-        framerect_factor_x = framerect_factor_y = 2540.0 / 300.0;
-        break;
-    case MetafileFrameUnitMillimeter:
-        framerect_factor_x = framerect_factor_y = 100.0;
-        break;
-    case MetafileFrameUnitGdi:
-        framerect_factor_x = framerect_factor_y = 1.0;
-        break;
-    default:
-        return InvalidParameter;
-    }
+        switch (frameUnit)
+        {
+        case MetafileFrameUnitPixel:
+            framerect_factor_x = 2540.0 / dpix;
+            framerect_factor_y = 2540.0 / dpiy;
+            break;
+        case MetafileFrameUnitPoint:
+            framerect_factor_x = framerect_factor_y = 2540.0 / 72.0;
+            break;
+        case MetafileFrameUnitInch:
+            framerect_factor_x = framerect_factor_y = 2540.0;
+            break;
+        case MetafileFrameUnitDocument:
+            framerect_factor_x = framerect_factor_y = 2540.0 / 300.0;
+            break;
+        case MetafileFrameUnitMillimeter:
+            framerect_factor_x = framerect_factor_y = 100.0;
+            break;
+        case MetafileFrameUnitGdi:
+            framerect_factor_x = framerect_factor_y = 1.0;
+            break;
+        default:
+            return InvalidParameter;
+        }
+
+        rc.left = framerect_factor_x * frameRect->X;
+        rc.top = framerect_factor_y * frameRect->Y;
+        rc.right = rc.left + framerect_factor_x * frameRect->Width;
+        rc.bottom = rc.top + framerect_factor_y * frameRect->Height;
 
-    rc.left = framerect_factor_x * frameRect->X;
-    rc.top = framerect_factor_y * frameRect->Y;
-    rc.right = rc.left + framerect_factor_x * frameRect->Width;
-    rc.bottom = rc.top + framerect_factor_y * frameRect->Height;
+        lprc = &rc;
+    }
+    else
+        lprc = NULL;
 
-    record_dc = CreateEnhMetaFileW(hdc, NULL, &rc, desc);
+    record_dc = CreateEnhMetaFileW(hdc, NULL, lprc, desc);
 
     if (!record_dc)
         return GenericError;
@@ -233,13 +234,13 @@ 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;
     (*metafile)->image.yres = dpiy;
-    (*metafile)->bounds = *frameRect;
-    (*metafile)->unit = frameUnit;
+    (*metafile)->bounds.X = (*metafile)->bounds.Y = 0.0;
+    (*metafile)->bounds.Width = (*metafile)->bounds.Height = 1.0;
+    (*metafile)->unit = UnitPixel;
     (*metafile)->metafile_type = type;
     (*metafile)->record_dc = record_dc;
     (*metafile)->comment_data = NULL;
@@ -284,6 +285,27 @@ GpStatus WINGDIPAPI GdipRecordMetafileI(HDC hdc, EmfType type, GDIPCONST GpRect
     return GdipRecordMetafile(hdc, type, pFrameRectF, frameUnit, desc, metafile);
 }
 
+GpStatus WINGDIPAPI GdipRecordMetafileStream(IStream *stream, HDC hdc, EmfType type, GDIPCONST GpRectF *frameRect,
+                                        MetafileFrameUnit frameUnit, GDIPCONST WCHAR *desc, GpMetafile **metafile)
+{
+    GpStatus stat;
+
+    TRACE("(%p %p %d %p %d %p %p)\n", stream, hdc, type, frameRect, frameUnit, desc, metafile);
+
+    if (!stream)
+        return InvalidParameter;
+
+    stat = GdipRecordMetafile(hdc, type, frameRect, frameUnit, desc, metafile);
+
+    if (stat == Ok)
+    {
+        (*metafile)->record_stream = stream;
+        IStream_AddRef(stream);
+    }
+
+    return stat;
+}
+
 GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result)
 {
     GpStatus stat;
@@ -449,6 +471,51 @@ GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile)
     metafile->comment_data = NULL;
     metafile->comment_data_size = 0;
 
+    if (stat == Ok)
+    {
+        MetafileHeader header;
+
+        stat = GdipGetMetafileHeaderFromEmf(metafile->hemf, &header);
+        if (stat == Ok)
+        {
+            metafile->bounds.X = header.X;
+            metafile->bounds.Y = header.Y;
+            metafile->bounds.Width = header.Width;
+            metafile->bounds.Height = header.Height;
+        }
+    }
+
+    if (stat == Ok && metafile->record_stream)
+    {
+        BYTE *buffer;
+        UINT buffer_size;
+
+        buffer_size = GetEnhMetaFileBits(metafile->hemf, 0, NULL);
+
+        buffer = heap_alloc(buffer_size);
+        if (buffer)
+        {
+            HRESULT hr;
+
+            GetEnhMetaFileBits(metafile->hemf, buffer_size, buffer);
+
+            hr = IStream_Write(metafile->record_stream, buffer, buffer_size, NULL);
+
+            if (FAILED(hr))
+                stat = hresult_to_status(hr);
+
+            heap_free(buffer);
+        }
+        else
+            stat = OutOfMemory;
+    }
+
+    if (metafile->record_stream)
+    {
+        IStream_Release(metafile->record_stream);
+        metafile->record_stream = NULL;
+    }
+
     return stat;
 }
 
@@ -868,17 +935,24 @@ GpStatus WINGDIPAPI GdipEnumerateMetafileDestPointI(GpGraphics *graphics,
 GpStatus WINGDIPAPI GdipGetMetafileHeaderFromMetafile(GpMetafile * metafile,
     MetafileHeader * header)
 {
-    static int calls;
+    GpStatus status;
 
     TRACE("(%p, %p)\n", metafile, header);
 
     if(!metafile || !header)
         return InvalidParameter;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
+    if (!metafile->hemf)
+        return InvalidParameter;
+
+    status = GdipGetMetafileHeaderFromEmf(metafile->hemf, header);
+    if (status != Ok) return status;
 
-    memset(header, 0, sizeof(MetafileHeader));
+    header->Type = metafile->metafile_type;
+    header->DpiX = metafile->image.xres;
+    header->DpiY = metafile->image.yres;
+    header->Width = metafile->bounds.Width;
+    header->Height = metafile->bounds.Height;
 
     return Ok;
 }
@@ -968,40 +1042,61 @@ GpStatus WINGDIPAPI GdipGetMetafileHeaderFromEmf(HENHMETAFILE hemf,
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetMetafileHeaderFromWmf(HMETAFILE hwmf,
+    GDIPCONST WmfPlaceableFileHeader *placeable, MetafileHeader *header)
+{
+    GpStatus status;
+    GpMetafile *metafile;
+
+    TRACE("(%p,%p,%p)\n", hwmf, placeable, header);
+
+    status = GdipCreateMetafileFromWmf(hwmf, FALSE, placeable, &metafile);
+    if (status == Ok)
+    {
+        status = GdipGetMetafileHeaderFromMetafile(metafile, header);
+        GdipDisposeImage(&metafile->image);
+    }
+    return status;
+}
+
 GpStatus WINGDIPAPI GdipGetMetafileHeaderFromFile(GDIPCONST WCHAR *filename,
     MetafileHeader *header)
 {
-    static int calls;
+    GpStatus status;
+    GpMetafile *metafile;
 
     TRACE("(%s,%p)\n", debugstr_w(filename), header);
 
-    if(!filename || !header)
+    if (!filename || !header)
         return InvalidParameter;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
-
-    memset(header, 0, sizeof(MetafileHeader));
-
-    return Ok;
+    status = GdipCreateMetafileFromFile(filename, &metafile);
+    if (status == Ok)
+    {
+        status = GdipGetMetafileHeaderFromMetafile(metafile, header);
+        GdipDisposeImage(&metafile->image);
+    }
+    return status;
 }
 
 GpStatus WINGDIPAPI GdipGetMetafileHeaderFromStream(IStream *stream,
     MetafileHeader *header)
 {
-    static int calls;
+    GpStatus status;
+    GpMetafile *metafile;
 
     TRACE("(%p,%p)\n", stream, header);
 
-    if(!stream || !header)
+    if (!stream || !header)
         return InvalidParameter;
 
-    if(!(calls++))
-        FIXME("not implemented\n");
-
-    memset(header, 0, sizeof(MetafileHeader));
-
-    return Ok;
+    status = GdipCreateMetafileFromStream(stream, &metafile);
+    if (status == Ok)
+    {
+        status = GdipGetMetafileHeaderFromMetafile(metafile, header);
+        GdipDisposeImage(&metafile->image);
+    }
+    return status;
 }
 
 GpStatus WINGDIPAPI GdipCreateMetafileFromEmf(HENHMETAFILE hemf, BOOL delete,
@@ -1117,8 +1212,21 @@ GpStatus WINGDIPAPI GdipCreateMetafileFromFile(GDIPCONST WCHAR *file,
 GpStatus WINGDIPAPI GdipCreateMetafileFromStream(IStream *stream,
     GpMetafile **metafile)
 {
-    FIXME("(%p, %p): stub\n", stream, metafile);
-    return NotImplemented;
+    GpStatus stat;
+
+    TRACE("%p %p\n", stream, metafile);
+
+    stat = GdipLoadImageFromStream(stream, (GpImage **)metafile);
+    if (stat != Ok) return stat;
+
+    if ((*metafile)->image.type != ImageTypeMetafile)
+    {
+        GdipDisposeImage(&(*metafile)->image);
+        *metafile = NULL;
+        return GenericError;
+    }
+
+    return Ok;
 }
 
 GpStatus WINGDIPAPI GdipSetMetafileDownLevelRasterizationLimit(GpMetafile *metafile,
index a6095ef..328e3ea 100644 (file)
@@ -68,7 +68,7 @@ reactos/dll/win32/dciman32            # Synced to WineStaging-1.9.4
 reactos/dll/win32/faultrep            # Synced to WineStaging-1.9.4
 reactos/dll/win32/fltlib              # Synced to WineStaging-1.9.4
 reactos/dll/win32/fusion              # Synced to WineStaging-1.9.4
-reactos/dll/win32/gdiplus             # Synced to WineStaging-1.9.4
+reactos/dll/win32/gdiplus             # Synced to WineStaging-1.9.11
 reactos/dll/win32/hhctrl.ocx          # Synced to WineStaging-1.9.4
 reactos/dll/win32/hlink               # Synced to WineStaging-1.9.4
 reactos/dll/win32/hnetcfg             # Synced to WineStaging-1.9.4