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?…
==============================================================================
--- 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.…
==============================================================================
--- 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_…
==============================================================================
--- 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…
==============================================================================
--- 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?…
==============================================================================
--- 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/imageatt…
==============================================================================
--- 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…
==============================================================================
--- 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…
==============================================================================
--- 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=…
==============================================================================
--- 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