Author: akhaldi
Date: Fri Aug 19 09:28:13 2016
New Revision: 72341

URL: http://svn.reactos.org/svn/reactos?rev=72341&view=rev
Log:
[GDIPLUS] Sync with Wine Staging 1.9.16. CORE-11866

Modified:
    trunk/reactos/dll/win32/gdiplus/brush.c
    trunk/reactos/dll/win32/gdiplus/gdiplus.spec
    trunk/reactos/dll/win32/gdiplus/gdiplus_private.h
    trunk/reactos/dll/win32/gdiplus/graphics.c
    trunk/reactos/dll/win32/gdiplus/image.c
    trunk/reactos/dll/win32/gdiplus/imageattributes.c
    trunk/reactos/dll/win32/gdiplus/metafile.c
    trunk/reactos/dll/win32/gdiplus/region.c
    trunk/reactos/media/doc/README.WINE

Modified: trunk/reactos/dll/win32/gdiplus/brush.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/brush.c?rev=72341&r1=72340&r2=72341&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/brush.c     [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/brush.c     [iso-8859-1] Fri Aug 19 
09:28:13 2016
@@ -191,7 +191,7 @@
             if (stat == Ok)
             {
                 new_texture->transform = texture->transform;
-                *clone = (GpBrush*)new_texture;
+                *clone = &new_texture->brush;
             }
             else
                 *clone = NULL;

Modified: trunk/reactos/dll/win32/gdiplus/gdiplus.spec
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus.spec?rev=72341&r1=72340&r2=72341&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus.spec        [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus.spec        [iso-8859-1] Fri Aug 19 
09:28:13 2016
@@ -264,7 +264,7 @@
 264 stdcall GdipGetHatchForegroundColor(ptr ptr)
 265 stdcall GdipGetHatchStyle(ptr ptr)
 266 stdcall GdipGetHemfFromMetafile(ptr ptr)
-267 stub GdipGetImageAttributesAdjustedPalette
+267 stdcall GdipGetImageAttributesAdjustedPalette(ptr ptr long)
 268 stdcall GdipGetImageBounds(ptr ptr ptr)
 269 stdcall GdipGetImageDecoders(long long ptr)
 270 stdcall GdipGetImageDecodersSize(ptr ptr)

Modified: trunk/reactos/dll/win32/gdiplus/gdiplus_private.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/gdiplus_private.h?rev=72341&r1=72340&r2=72341&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/gdiplus_private.h   [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/gdiplus_private.h   [iso-8859-1] Fri Aug 19 
09:28:13 2016
@@ -94,9 +94,12 @@
 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_GraphicsClear(GpMetafile* metafile, ARGB color) 
DECLSPEC_HIDDEN;
 extern GpStatus METAFILE_FillRectangles(GpMetafile* metafile, GpBrush* brush,
     GDIPCONST GpRectF* rects, INT count) DECLSPEC_HIDDEN;
 extern GpStatus METAFILE_SetPageTransform(GpMetafile* metafile, GpUnit unit, 
REAL scale) DECLSPEC_HIDDEN;
+extern GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, 
REAL sy, MatrixOrder order) DECLSPEC_HIDDEN;
+extern GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile) 
DECLSPEC_HIDDEN;
 extern GpStatus METAFILE_GraphicsDeleted(GpMetafile* metafile) DECLSPEC_HIDDEN;
 
 extern void calc_curve_bezier(const GpPointF *pts, REAL tension, REAL *x1,
@@ -183,6 +186,9 @@
 extern GpStatus convert_pixels(INT width, INT height,
     INT dst_stride, BYTE *dst_bits, PixelFormat dst_format,
     INT src_stride, const BYTE *src_bits, PixelFormat src_format, ColorPalette 
*palette) DECLSPEC_HIDDEN;
+
+extern PixelFormat apply_image_attributes(const GpImageAttributes *attributes, 
LPBYTE data,
+    UINT width, UINT height, INT stride, ColorAdjustType type, PixelFormat 
fmt) DECLSPEC_HIDDEN;
 
 struct GpMatrix{
     REAL matrix[6];
@@ -322,7 +328,7 @@
     REAL scale;
 };
 
-struct GpAdustableArrowCap{
+struct GpAdjustableArrowCap{
     GpCustomLineCap cap;
 };
 
@@ -351,6 +357,8 @@
     DWORD comment_data_size;
     DWORD comment_data_length;
     IStream *record_stream;
+    BOOL auto_frame; /* If true, determine the frame automatically */
+    GpPointF auto_frame_min, auto_frame_max;
 
     /* playback */
     GpGraphics *playback_graphics;
@@ -362,6 +370,7 @@
     GpMatrix *world_transform;
     GpUnit page_unit;
     REAL page_scale;
+    GpRegion *base_clip; /* clip region in device space for all metafile 
output */
 };
 
 struct GpBitmap{

Modified: trunk/reactos/dll/win32/gdiplus/graphics.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/graphics.c?rev=72341&r1=72340&r2=72341&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/graphics.c  [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/graphics.c  [iso-8859-1] Fri Aug 19 
09:28:13 2016
@@ -657,7 +657,7 @@
 }
 
 /* returns preferred pixel format for the applied attributes */
-static PixelFormat apply_image_attributes(const GpImageAttributes *attributes, 
LPBYTE data,
+PixelFormat apply_image_attributes(const GpImageAttributes *attributes, LPBYTE 
data,
     UINT width, UINT height, INT stride, ColorAdjustType type, PixelFormat fmt)
 {
     UINT x, y;
@@ -4277,6 +4277,7 @@
 {
     GpRegion *clip_rgn;
     GpStatus stat;
+    GpMatrix device_to_world;
 
     TRACE("(%p, %p)\n", graphics, rect);
 
@@ -4291,6 +4292,13 @@
         return stat;
 
     if((stat = get_visible_clip_region(graphics, clip_rgn)) != Ok)
+        goto cleanup;
+
+    /* transform to world coordinates */
+    if((stat = get_graphics_transform(graphics, CoordinateSpaceWorld, 
CoordinateSpaceDevice, &device_to_world)) != Ok)
+        goto cleanup;
+
+    if((stat = GdipTransformRegion(clip_rgn, &device_to_world)) != Ok)
         goto cleanup;
 
     /* get bounds of the region */
@@ -4351,10 +4359,13 @@
     if(graphics->busy)
         return ObjectBusy;
 
+    if (graphics->image && graphics->image->type == ImageTypeMetafile)
+        return METAFILE_GraphicsClear((GpMetafile*)graphics->image, color);
+
     if((stat = GdipCreateSolidFill(color, &brush)) != Ok)
         return stat;
 
-    if((stat = get_graphics_bounds(graphics, &wnd_rect)) != Ok){
+    if((stat = GdipGetVisibleClipBounds(graphics, &wnd_rect)) != Ok){
         GdipDeleteBrush((GpBrush*)brush);
         return stat;
     }
@@ -5097,6 +5108,8 @@
 
 GpStatus WINGDIPAPI GdipResetWorldTransform(GpGraphics *graphics)
 {
+    GpStatus stat;
+
     TRACE("(%p)\n", graphics);
 
     if(!graphics)
@@ -5104,6 +5117,13 @@
 
     if(graphics->busy)
         return ObjectBusy;
+
+    if (graphics->image && graphics->image->type == ImageTypeMetafile) {
+        stat = METAFILE_ResetWorldTransform((GpMetafile*)graphics->image);
+
+        if (stat != Ok)
+            return stat;
+    }
 
     return GdipSetMatrixElements(&graphics->worldtrans, 1.0, 0.0, 0.0, 1.0, 
0.0, 0.0);
 }
@@ -5211,6 +5231,8 @@
 GpStatus WINGDIPAPI GdipScaleWorldTransform(GpGraphics *graphics, REAL sx,
     REAL sy, GpMatrixOrder order)
 {
+    GpStatus stat;
+
     TRACE("(%p, %.2f, %.2f, %d)\n", graphics, sx, sy, order);
 
     if(!graphics)
@@ -5218,6 +5240,13 @@
 
     if(graphics->busy)
         return ObjectBusy;
+
+    if (graphics->image && graphics->image->type == ImageTypeMetafile) {
+        stat = METAFILE_ScaleWorldTransform((GpMetafile*)graphics->image, sx, 
sy, order);
+
+        if (stat != Ok)
+            return stat;
+    }
 
     return GdipScaleMatrix(&graphics->worldtrans, sx, sy, order);
 }

Modified: trunk/reactos/dll/win32/gdiplus/image.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/image.c?rev=72341&r1=72340&r2=72341&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/image.c     [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/image.c     [iso-8859-1] Fri Aug 19 
09:28:13 2016
@@ -1245,7 +1245,7 @@
         }
 
         if (stat != Ok)
-            GdipDisposeImage((GpImage*)*dstBitmap);
+            GdipDisposeImage(&(*dstBitmap)->image);
     }
 
     if (stat != Ok)
@@ -1445,8 +1445,8 @@
 
     if (!bitmap || !hbmReturn) return InvalidParameter;
 
-    GdipGetImageWidth((GpImage*)bitmap, &width);
-    GdipGetImageHeight((GpImage*)bitmap, &height);
+    GdipGetImageWidth(&bitmap->image, &width);
+    GdipGetImageHeight(&bitmap->image, &height);
 
     bih.biSize = sizeof(bih);
     bih.biWidth = width;
@@ -1570,7 +1570,7 @@
     if (stat != Ok) {
         DeleteObject(iinfo.hbmColor);
         DeleteObject(iinfo.hbmMask);
-        GdipDisposeImage((GpImage*)*bitmap);
+        GdipDisposeImage(&(*bitmap)->image);
         return stat;
     }
 
@@ -2932,7 +2932,7 @@
         UINT i;
         char *item_value;
 
-        GdipGetPropertySize((GpImage *)bitmap, &prop_size, &prop_count);
+        GdipGetPropertySize(&bitmap->image, &prop_size, &prop_count);
 
         prop_item = heap_alloc_zero(prop_size + item->length + 
sizeof(PropertyItem));
         if (!prop_item) return;
@@ -3388,7 +3388,7 @@
         { "Source", PropertyTagEquipModel },
         { "Comment", PropertyTagExifUserComment },
     };
-    BOOL seen_gamma=FALSE;
+    BOOL seen_gamma=FALSE, seen_whitepoint=FALSE, seen_chrm=FALSE;
 
     hr = IWICBitmapDecoder_GetFrame(decoder, active_frame, &frame);
     if (hr != S_OK) return;
@@ -3454,6 +3454,57 @@
                                 add_property(bitmap, item);
                                 seen_gamma = TRUE;
                                 heap_free(item);
+                            }
+                        }
+                    }
+                    else if (SUCCEEDED(hr) && 
IsEqualGUID(&GUID_MetadataFormatChunkcHRM, &format))
+                    {
+                        PropertyItem* item;
+
+                        if (!seen_whitepoint)
+                        {
+                            item = GdipAlloc(sizeof(PropertyItem) + 
sizeof(ULONG) * 4);
+                            if (item)
+                            {
+                                ULONG *rational;
+                                item->length = sizeof(ULONG) * 4;
+                                item->type = PropertyTagTypeRational;
+                                item->id = PropertyTagWhitePoint;
+                                rational = item->value = item + 1;
+                                rational[0] = get_ulong_by_index(reader, 0);
+                                rational[1] = 100000;
+                                rational[2] = get_ulong_by_index(reader, 1);
+                                rational[3] = 100000;
+                                add_property(bitmap, item);
+                                seen_whitepoint = TRUE;
+                                GdipFree(item);
+                            }
+                        }
+                        if (!seen_chrm)
+                        {
+                            item = GdipAlloc(sizeof(PropertyItem) + 
sizeof(ULONG) * 12);
+                            if (item)
+                            {
+                                ULONG *rational;
+                                item->length = sizeof(ULONG) * 12;
+                                item->type = PropertyTagTypeRational;
+                                item->id = PropertyTagPrimaryChromaticities;
+                                rational = item->value = item + 1;
+                                rational[0] = get_ulong_by_index(reader, 2);
+                                rational[1] = 100000;
+                                rational[2] = get_ulong_by_index(reader, 3);
+                                rational[3] = 100000;
+                                rational[4] = get_ulong_by_index(reader, 4);
+                                rational[5] = 100000;
+                                rational[6] = get_ulong_by_index(reader, 5);
+                                rational[7] = 100000;
+                                rational[8] = get_ulong_by_index(reader, 6);
+                                rational[9] = 100000;
+                                rational[10] = get_ulong_by_index(reader, 7);
+                                rational[11] = 100000;
+                                add_property(bitmap, item);
+                                seen_chrm = TRUE;
+                                GdipFree(item);
                             }
                         }
                     }
@@ -3568,11 +3619,11 @@
                 }
 
                 if (SUCCEEDED(hr) && status == Ok)
-                    *image = (GpImage*)bitmap;
+                    *image = &bitmap->image;
                 else
                 {
                     *image = NULL;
-                    GdipDisposeImage((GpImage*)bitmap);
+                    GdipDisposeImage(&bitmap->image);
                 }
 
                 if (SUCCEEDED(hr) && status == Ok)
@@ -3614,7 +3665,14 @@
     if (status == Ok)
     {
         /* Native GDI+ used to be smarter, but since Win7 it just sets these 
flags. */
-        bitmap->image.flags |= 
ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI|ImageFlagsColorSpaceRGB;
+        bitmap->image.flags |= 
ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI;
+        if (IsEqualGUID(&wic_format, &GUID_WICPixelFormat2bppGray) ||
+            IsEqualGUID(&wic_format, &GUID_WICPixelFormat4bppGray) ||
+            IsEqualGUID(&wic_format, &GUID_WICPixelFormat8bppGray) ||
+            IsEqualGUID(&wic_format, &GUID_WICPixelFormat16bppGray))
+            bitmap->image.flags |= ImageFlagsColorSpaceGRAY;
+        else
+            bitmap->image.flags |= ImageFlagsColorSpaceRGB;
         bitmap->image.frame_count = frame_count;
         bitmap->image.current_frame = active_frame;
         bitmap->image.decoder = decoder;
@@ -3856,7 +3914,37 @@
 
 static GpStatus decode_image_png(IStream* stream, GpImage **image)
 {
-    return decode_image_wic(stream, &GUID_ContainerFormatPng, 
png_metadata_reader, image);
+    IWICBitmapDecoder *decoder;
+    IWICBitmapFrameDecode *frame;
+    GpStatus status;
+    HRESULT hr;
+    GUID format;
+    BOOL force_conversion = FALSE;
+
+    status = initialize_decoder_wic(stream, &GUID_ContainerFormatPng, 
&decoder);
+    if (status != Ok)
+        return status;
+
+    hr = IWICBitmapDecoder_GetFrame(decoder, 0, &frame);
+    if (hr == S_OK)
+    {
+        hr = IWICBitmapFrameDecode_GetPixelFormat(frame, &format);
+        if (hr == S_OK)
+        {
+            if (IsEqualGUID(&format, &GUID_WICPixelFormat8bppGray))
+                force_conversion = TRUE;
+            status = decode_frame_wic(decoder, force_conversion, 0, 
png_metadata_reader, image);
+        }
+        else
+            status = hresult_to_status(hr);
+
+        IWICBitmapFrameDecode_Release(frame);
+    }
+    else
+        status = hresult_to_status(hr);
+
+    IWICBitmapDecoder_Release(decoder);
+    return status;
 }
 
 static GpStatus decode_image_gif(IStream* stream, GpImage **image)
@@ -4987,7 +5075,7 @@
                                           entry[i].peGreen << 8 | 
entry[i].peBlue;
                 }
 
-                retval = GdipSetImagePalette((GpImage*)*bitmap, palette);
+                retval = GdipSetImagePalette(&(*bitmap)->image, palette);
             }
 
             heap_free(palette);
@@ -4995,7 +5083,7 @@
 
         if (retval != Ok)
         {
-            GdipDisposeImage((GpImage*)*bitmap);
+            GdipDisposeImage(&(*bitmap)->image);
             *bitmap = NULL;
         }
     }
@@ -5250,7 +5338,7 @@
     if (stat == Ok)
         move_bitmap(bitmap, new_bitmap, FALSE);
     else
-        GdipDisposeImage((GpImage*)new_bitmap);
+        GdipDisposeImage(&new_bitmap->image);
 
     return stat;
 }

Modified: trunk/reactos/dll/win32/gdiplus/imageattributes.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/imageattributes.c?rev=72341&r1=72340&r2=72341&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/imageattributes.c   [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/imageattributes.c   [iso-8859-1] Fri Aug 19 
09:28:13 2016
@@ -68,6 +68,21 @@
     return Ok;
 }
 
+GpStatus WINGDIPAPI GdipGetImageAttributesAdjustedPalette(GpImageAttributes 
*imageattr,
+    ColorPalette *palette, ColorAdjustType type)
+{
+    TRACE("(%p,%p,%u)\n", imageattr, palette, type);
+
+    if (!imageattr || !palette || !palette->Count ||
+        type >= ColorAdjustTypeCount || type == ColorAdjustTypeDefault)
+        return InvalidParameter;
+
+    apply_image_attributes(imageattr, (LPBYTE)palette->Entries, 
palette->Count, 1, 0,
+        type, PixelFormat32bppARGB);
+
+    return Ok;
+}
+
 GpStatus WINGDIPAPI GdipSetImageAttributesColorKeys(GpImageAttributes 
*imageattr,
     ColorAdjustType type, BOOL enableFlag, ARGB colorLow, ARGB colorHigh)
 {

Modified: trunk/reactos/dll/win32/gdiplus/metafile.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/metafile.c?rev=72341&r1=72340&r2=72341&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/metafile.c  [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/metafile.c  [iso-8859-1] Fri Aug 19 
09:28:13 2016
@@ -35,6 +35,12 @@
     DWORD LogicalDpiY;
 } EmfPlusHeader;
 
+typedef struct EmfPlusClear
+{
+    EmfPlusRecordHeader Header;
+    DWORD Color;
+} EmfPlusClear;
+
 typedef struct EmfPlusFillRects
 {
     EmfPlusRecordHeader Header;
@@ -55,6 +61,13 @@
     SHORT Width;
     SHORT Height;
 } EmfPlusRect;
+
+typedef struct EmfPlusScaleWorldTransform
+{
+    EmfPlusRecordHeader Header;
+    REAL Sx;
+    REAL Sy;
+} EmfPlusScaleWorldTransform;
 
 static GpStatus METAFILE_AllocateRecord(GpMetafile *metafile, DWORD size, void 
**result)
 {
@@ -248,6 +261,15 @@
     (*metafile)->comment_data_length = 0;
     (*metafile)->hemf = NULL;
 
+    if (!frameRect)
+    {
+        (*metafile)->auto_frame = TRUE;
+        (*metafile)->auto_frame_min.X = 0;
+        (*metafile)->auto_frame_min.Y = 0;
+        (*metafile)->auto_frame_max.X = -1;
+        (*metafile)->auto_frame_max.Y = -1;
+    }
+
     stat = METAFILE_WriteHeader(*metafile, hdc);
 
     if (stat != Ok)
@@ -306,6 +328,30 @@
     return stat;
 }
 
+static void METAFILE_AdjustFrame(GpMetafile* metafile, const GpPointF *points,
+    UINT num_points)
+{
+    int i;
+
+    if (!metafile->auto_frame || !num_points)
+        return;
+
+    if (metafile->auto_frame_max.X < metafile->auto_frame_min.X)
+        metafile->auto_frame_max = metafile->auto_frame_min = points[0];
+
+    for (i=0; i<num_points; i++)
+    {
+        if (points[i].X < metafile->auto_frame_min.X)
+            metafile->auto_frame_min.X = points[i].X;
+        if (points[i].X > metafile->auto_frame_max.X)
+            metafile->auto_frame_max.X = points[i].X;
+        if (points[i].Y < metafile->auto_frame_min.Y)
+            metafile->auto_frame_min.Y = points[i].Y;
+        if (points[i].Y > metafile->auto_frame_max.Y)
+            metafile->auto_frame_max.Y = points[i].Y;
+    }
+}
+
 GpStatus METAFILE_GetGraphicsContext(GpMetafile* metafile, GpGraphics **result)
 {
     GpStatus stat;
@@ -343,6 +389,27 @@
     }
 
     *hdc = metafile->record_dc;
+
+    return Ok;
+}
+
+GpStatus METAFILE_GraphicsClear(GpMetafile* metafile, ARGB color)
+{
+    if (metafile->metafile_type == MetafileTypeEmfPlusOnly || 
metafile->metafile_type == MetafileTypeEmfPlusDual)
+    {
+        EmfPlusClear *record;
+        GpStatus stat;
+
+        stat = METAFILE_AllocateRecord(metafile, sizeof(EmfPlusClear), 
(void**)&record);
+        if (stat != Ok)
+            return stat;
+
+        record->Header.Type = EmfPlusRecordTypeClear;
+        record->Header.Flags = 0;
+        record->Color = color;
+
+        METAFILE_WriteRecords(metafile);
+    }
 
     return Ok;
 }
@@ -423,6 +490,29 @@
         METAFILE_WriteRecords(metafile);
     }
 
+    if (metafile->auto_frame)
+    {
+        GpPointF corners[4];
+        int i;
+
+        for (i=0; i<count; i++)
+        {
+            corners[0].X = rects[i].X;
+            corners[0].Y = rects[i].Y;
+            corners[1].X = rects[i].X + rects[i].Width;
+            corners[1].Y = rects[i].Y;
+            corners[2].X = rects[i].X;
+            corners[2].Y = rects[i].Y + rects[i].Height;
+            corners[3].X = rects[i].X + rects[i].Width;
+            corners[3].Y = rects[i].Y + rects[i].Height;
+
+            GdipTransformPoints(metafile->record_graphics, 
CoordinateSpaceDevice,
+                CoordinateSpaceWorld, corners, 4);
+
+            METAFILE_AdjustFrame(metafile, corners, 4);
+        }
+    }
+
     return Ok;
 }
 
@@ -449,6 +539,52 @@
     return Ok;
 }
 
+GpStatus METAFILE_ScaleWorldTransform(GpMetafile* metafile, REAL sx, REAL sy, 
MatrixOrder order)
+{
+    if (metafile->metafile_type == MetafileTypeEmfPlusOnly || 
metafile->metafile_type == MetafileTypeEmfPlusDual)
+    {
+        EmfPlusScaleWorldTransform *record;
+        GpStatus stat;
+
+        stat = METAFILE_AllocateRecord(metafile,
+            sizeof(EmfPlusScaleWorldTransform),
+            (void**)&record);
+        if (stat != Ok)
+            return stat;
+
+        record->Header.Type = EmfPlusRecordTypeScaleWorldTransform;
+        record->Header.Flags = (order == MatrixOrderAppend ? 4 : 0);
+        record->Sx = sx;
+        record->Sy = sy;
+
+        METAFILE_WriteRecords(metafile);
+    }
+
+    return Ok;
+}
+
+GpStatus METAFILE_ResetWorldTransform(GpMetafile* metafile)
+{
+    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 = EmfPlusRecordTypeResetWorldTransform;
+        record->Flags = 0;
+
+        METAFILE_WriteRecords(metafile);
+    }
+
+    return Ok;
+}
+
 GpStatus METAFILE_ReleaseDC(GpMetafile* metafile, HDC hdc)
 {
     if (hdc != metafile->record_dc)
@@ -476,6 +612,57 @@
         MetafileHeader header;
 
         stat = GdipGetMetafileHeaderFromEmf(metafile->hemf, &header);
+        if (stat == Ok && metafile->auto_frame &&
+            metafile->auto_frame_max.X >= metafile->auto_frame_min.X)
+        {
+            RECTL bounds_rc, gdi_bounds_rc;
+            REAL x_scale = 2540.0 / header.DpiX;
+            REAL y_scale = 2540.0 / header.DpiY;
+            BYTE* buffer;
+            UINT buffer_size;
+
+            bounds_rc.left = floorf(metafile->auto_frame_min.X * x_scale);
+            bounds_rc.top = floorf(metafile->auto_frame_min.Y * y_scale);
+            bounds_rc.right = ceilf(metafile->auto_frame_max.X * x_scale);
+            bounds_rc.bottom = ceilf(metafile->auto_frame_max.Y * y_scale);
+
+            gdi_bounds_rc = header.u.EmfHeader.rclBounds;
+            if (gdi_bounds_rc.right > gdi_bounds_rc.left && 
gdi_bounds_rc.bottom > gdi_bounds_rc.top)
+            {
+                bounds_rc.left = min(bounds_rc.left, gdi_bounds_rc.left);
+                bounds_rc.top = min(bounds_rc.top, gdi_bounds_rc.top);
+                bounds_rc.right = max(bounds_rc.right, gdi_bounds_rc.right);
+                bounds_rc.bottom = max(bounds_rc.bottom, gdi_bounds_rc.bottom);
+            }
+
+            buffer_size = GetEnhMetaFileBits(metafile->hemf, 0, NULL);
+            buffer = heap_alloc(buffer_size);
+            if (buffer)
+            {
+                HENHMETAFILE new_hemf;
+
+                GetEnhMetaFileBits(metafile->hemf, buffer_size, buffer);
+
+                ((ENHMETAHEADER*)buffer)->rclFrame = bounds_rc;
+
+                new_hemf = SetEnhMetaFileBits(buffer_size, buffer);
+
+                if (new_hemf)
+                {
+                    DeleteEnhMetaFile(metafile->hemf);
+                    metafile->hemf = new_hemf;
+                }
+                else
+                    stat = OutOfMemory;
+
+                heap_free(buffer);
+            }
+            else
+                stat = OutOfMemory;
+
+            if (stat == Ok)
+                stat = GdipGetMetafileHeaderFromEmf(metafile->hemf, &header);
+        }
         if (stat == Ok)
         {
             metafile->bounds.X = header.X;
@@ -568,6 +755,11 @@
     }
 }
 
+static GpStatus METAFILE_PlaybackUpdateClip(GpMetafile *metafile)
+{
+    return GdipCombineRegionRegion(metafile->playback_graphics->clip, 
metafile->base_clip, CombineModeReplace);
+}
+
 static GpStatus METAFILE_PlaybackUpdateWorldTransform(GpMetafile *metafile)
 {
     GpMatrix *real_transform;
@@ -645,6 +837,12 @@
         case EmfPlusRecordTypeGetDC:
             METAFILE_PlaybackGetDC((GpMetafile*)metafile);
             break;
+        case EmfPlusRecordTypeClear:
+        {
+            EmfPlusClear *record = (EmfPlusClear*)header;
+
+            return GdipGraphicsClear(metafile->playback_graphics, 
record->Color);
+        }
         case EmfPlusRecordTypeFillRects:
         {
             EmfPlusFillRects *record = (EmfPlusFillRects*)header;
@@ -724,6 +922,24 @@
 
             return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
         }
+        case EmfPlusRecordTypeScaleWorldTransform:
+        {
+            EmfPlusScaleWorldTransform *record = 
(EmfPlusScaleWorldTransform*)header;
+            MatrixOrder order = (flags & 0x4) ? MatrixOrderAppend : 
MatrixOrderPrepend;
+
+            if (dataSize + sizeof(EmfPlusRecordHeader) < 
sizeof(EmfPlusScaleWorldTransform))
+                return InvalidParameter;
+
+            GdipScaleMatrix(real_metafile->world_transform, record->Sx, 
record->Sy, order);
+
+            return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
+        }
+        case EmfPlusRecordTypeResetWorldTransform:
+        {
+            GdipSetMatrixElements(real_metafile->world_transform, 1.0, 0.0, 
0.0, 1.0, 0.0, 0.0);
+
+            return METAFILE_PlaybackUpdateWorldTransform(real_metafile);
+        }
         default:
             FIXME("Not implemented for record type %x\n", recordType);
             return NotImplemented;
@@ -799,6 +1015,7 @@
     GpStatus stat;
     GpMetafile *real_metafile = (GpMetafile*)metafile; /* whoever made this 
const was joking */
     GraphicsContainer state;
+    GpPath *dst_path;
 
     TRACE("(%p,%p,%p,%i,%p,%i,%p,%p,%p)\n", graphics, metafile,
         destPoints, count, srcRect, srcUnit, callback, callbackData,
@@ -839,6 +1056,38 @@
             stat = GdipSetPageUnit(graphics, UnitPixel);
 
         if (stat == Ok)
+            stat = GdipResetWorldTransform(graphics);
+
+        if (stat == Ok)
+            stat = GdipCreateRegion(&real_metafile->base_clip);
+
+        if (stat == Ok)
+            stat = GdipGetClip(graphics, real_metafile->base_clip);
+
+        if (stat == Ok)
+            stat = GdipCreatePath(FillModeAlternate, &dst_path);
+
+        if (stat == Ok)
+        {
+            GpPointF clip_points[4];
+
+            clip_points[0] = real_metafile->playback_points[0];
+            clip_points[1] = real_metafile->playback_points[1];
+            clip_points[2].X = real_metafile->playback_points[1].X + 
real_metafile->playback_points[2].X
+                - real_metafile->playback_points[0].X;
+            clip_points[2].Y = real_metafile->playback_points[1].Y + 
real_metafile->playback_points[2].Y
+                - real_metafile->playback_points[0].Y;
+            clip_points[3] = real_metafile->playback_points[2];
+
+            stat = GdipAddPathPolygon(dst_path, clip_points, 4);
+
+            if (stat == Ok)
+                stat = GdipCombineRegionPath(real_metafile->base_clip, 
dst_path, CombineModeIntersect);
+
+            GdipDeletePath(dst_path);
+        }
+
+        if (stat == Ok)
             stat = GdipCreateMatrix(&real_metafile->world_transform);
 
         if (stat == Ok)
@@ -846,6 +1095,11 @@
             real_metafile->page_unit = UnitDisplay;
             real_metafile->page_scale = 1.0;
             stat = METAFILE_PlaybackUpdateWorldTransform(real_metafile);
+        }
+
+        if (stat == Ok)
+        {
+            stat = METAFILE_PlaybackUpdateClip(real_metafile);
         }
 
         if (stat == Ok && (metafile->metafile_type == MetafileTypeEmf ||
@@ -860,6 +1114,9 @@
 
         GdipDeleteMatrix(real_metafile->world_transform);
         real_metafile->world_transform = NULL;
+
+        GdipDeleteRegion(real_metafile->base_clip);
+        real_metafile->base_clip = NULL;
 
         GdipEndContainer(graphics, state);
     }
@@ -1205,8 +1462,22 @@
 GpStatus WINGDIPAPI GdipCreateMetafileFromFile(GDIPCONST WCHAR *file,
     GpMetafile **metafile)
 {
-    FIXME("(%p, %p): stub\n", file, metafile);
-    return NotImplemented;
+    GpStatus status;
+    IStream *stream;
+
+    TRACE("(%p, %p)\n", file, metafile);
+
+    if (!file || !metafile) return InvalidParameter;
+
+    *metafile = NULL;
+
+    status = GdipCreateStreamOnFile(file, GENERIC_READ, &stream);
+    if (status == Ok)
+    {
+        status = GdipCreateMetafileFromStream(stream, metafile);
+        IStream_Release(stream);
+    }
+    return status;
 }
 
 GpStatus WINGDIPAPI GdipCreateMetafileFromStream(IStream *stream,

Modified: trunk/reactos/dll/win32/gdiplus/region.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdiplus/region.c?rev=72341&r1=72340&r2=72341&view=diff
==============================================================================
--- trunk/reactos/dll/win32/gdiplus/region.c    [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdiplus/region.c    [iso-8859-1] Fri Aug 19 
09:28:13 2016
@@ -809,7 +809,7 @@
  *  their code followed by a second header for the path followed by the actual
  *  path data. Followed by the flags for each point. The pathheader contains
  *  the size of the data to follow, a version number again, followed by a count
- *  of how many points, and any special flags which may apply. 0x4000 means its
+ *  of how many points, and any special flags which may apply. 0x4000 means 
it's
  *  a path of shorts instead of FLOAT.
  *
  *  Combining Ops are stored in reverse order from when they were constructed;
@@ -1101,6 +1101,12 @@
     GpGraphics *new_graphics=NULL;
     GpStatus stat;
     INT save_state;
+
+    if (!path->pathdata.Count)  /* PathToRegion doesn't support empty paths */
+    {
+        *hrgn = CreateRectRgn( 0, 0, 0, 0 );
+        return *hrgn ? Ok : OutOfMemory;
+    }
 
     if (!graphics)
     {
@@ -1384,11 +1390,7 @@
         return Ok;
     }
 
-    rect.left = ceilr(x);
-    rect.top = ceilr(y);
-    rect.right = ceilr(x + w);
-    rect.bottom = ceilr(y + h);
-
+    SetRect(&rect, ceilr(x), ceilr(y), ceilr(x + w), ceilr(y + h));
     *res = RectInRegion(hrgn, &rect);
 
     DeleteObject(hrgn);

Modified: trunk/reactos/media/doc/README.WINE
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/media/doc/README.WINE?rev=72341&r1=72340&r2=72341&view=diff
==============================================================================
--- trunk/reactos/media/doc/README.WINE [iso-8859-1] (original)
+++ trunk/reactos/media/doc/README.WINE [iso-8859-1] Fri Aug 19 09:28:13 2016
@@ -68,7 +68,7 @@
 reactos/dll/win32/faultrep            # Synced to WineStaging-1.9.11
 reactos/dll/win32/fontsub             # Synced to WineStaging-1.9.13
 reactos/dll/win32/fusion              # Synced to WineStaging-1.9.11
-reactos/dll/win32/gdiplus             # Synced to WineStaging-1.9.11
+reactos/dll/win32/gdiplus             # Synced to WineStaging-1.9.16
 reactos/dll/win32/hhctrl.ocx          # Synced to WineStaging-1.9.16
 reactos/dll/win32/hlink               # Synced to WineStaging-1.9.16
 reactos/dll/win32/hnetcfg             # Synced to WineStaging-1.9.11


Reply via email to