https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6619d0261f266a3e7cec7…
commit 6619d0261f266a3e7cec775a6b227daf3a352540
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Sun May 27 04:10:39 2018 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Sun May 27 04:10:39 2018 +0100
[GDIPLUS] Sync with Wine Staging 3.9. CORE-14656
---
dll/win32/gdiplus/brush.c | 14 ++-
dll/win32/gdiplus/customlinecap.c | 231 +++++++++++++++++++++++++-----------
dll/win32/gdiplus/font.c | 4 +-
dll/win32/gdiplus/gdiplus.spec | 2 +-
dll/win32/gdiplus/gdiplus_private.h | 5 +
dll/win32/gdiplus/graphics.c | 40 +++++--
dll/win32/gdiplus/image.c | 8 +-
dll/win32/gdiplus/metafile.c | 2 +-
dll/win32/gdiplus/pen.c | 7 +-
dll/win32/gdiplus/region.c | 38 +++++-
media/doc/README.WINE | 2 +-
11 files changed, 253 insertions(+), 100 deletions(-)
diff --git a/dll/win32/gdiplus/brush.c b/dll/win32/gdiplus/brush.c
index 51264212ae..d06832045a 100644
--- a/dll/win32/gdiplus/brush.c
+++ b/dll/win32/gdiplus/brush.c
@@ -261,7 +261,7 @@ static const char HatchBrushes[][8] = {
GpStatus get_hatch_data(GpHatchStyle hatchstyle, const char **result)
{
- if (hatchstyle < sizeof(HatchBrushes) / sizeof(HatchBrushes[0]))
+ if (hatchstyle < ARRAY_SIZE(HatchBrushes))
{
*result = HatchBrushes[hatchstyle];
return Ok;
@@ -1715,6 +1715,18 @@ GpStatus WINGDIPAPI
GdipSetPathGradientGammaCorrection(GpPathGradient *grad,
return Ok;
}
+GpStatus WINGDIPAPI GdipSetPathGradientPath(GpPathGradient *grad, GDIPCONST GpPath
*path)
+{
+ static int calls;
+
+ TRACE("(%p, %p)\n", grad, path);
+
+ if (!(calls++))
+ FIXME("not implemented\n");
+
+ return NotImplemented;
+}
+
GpStatus WINGDIPAPI GdipSetPathGradientSigmaBlend(GpPathGradient *grad,
REAL focus, REAL scale)
{
diff --git a/dll/win32/gdiplus/customlinecap.c b/dll/win32/gdiplus/customlinecap.c
index ca81bee217..c74928eeda 100644
--- a/dll/win32/gdiplus/customlinecap.c
+++ b/dll/win32/gdiplus/customlinecap.c
@@ -17,6 +17,7 @@
*/
#include <stdarg.h>
+#include <assert.h>
#include "windef.h"
#include "winbase.h"
@@ -38,11 +39,20 @@ GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap* from,
if(!from || !to)
return InvalidParameter;
- *to = heap_alloc_zero(sizeof(GpCustomLineCap));
- if(!*to) return OutOfMemory;
+ if (from->type == CustomLineCapTypeDefault)
+ *to = heap_alloc_zero(sizeof(GpCustomLineCap));
+ else
+ *to = heap_alloc_zero(sizeof(GpAdjustableArrowCap));
- memcpy(*to, from, sizeof(GpCustomLineCap));
+ if (!*to)
+ return OutOfMemory;
+
+ if (from->type == CustomLineCapTypeDefault)
+ **to = *from;
+ else
+ *(GpAdjustableArrowCap *)*to = *(GpAdjustableArrowCap *)from;
+ /* Duplicate path data */
(*to)->pathdata.Points = heap_alloc_zero(from->pathdata.Count *
sizeof(PointF));
(*to)->pathdata.Types = heap_alloc_zero(from->pathdata.Count);
@@ -62,12 +72,44 @@ GpStatus WINGDIPAPI GdipCloneCustomLineCap(GpCustomLineCap* from,
return Ok;
}
+static GpStatus init_custom_linecap(GpCustomLineCap *cap, GpPathData *pathdata, BOOL
fill, GpLineCap basecap,
+ REAL base_inset)
+{
+ cap->fill = fill;
+
+ cap->pathdata.Points = heap_alloc_zero(pathdata->Count * sizeof(PointF));
+ cap->pathdata.Types = heap_alloc_zero(pathdata->Count);
+
+ if ((!cap->pathdata.Types || !cap->pathdata.Points) &&
pathdata->Count)
+ {
+ heap_free(cap->pathdata.Points);
+ heap_free(cap->pathdata.Types);
+ cap->pathdata.Points = NULL;
+ cap->pathdata.Types = NULL;
+ return OutOfMemory;
+ }
+
+ if (pathdata->Points)
+ memcpy(cap->pathdata.Points, pathdata->Points, pathdata->Count *
sizeof(PointF));
+ if (pathdata->Types)
+ memcpy(cap->pathdata.Types, pathdata->Types, pathdata->Count);
+ cap->pathdata.Count = pathdata->Count;
+
+ cap->inset = base_inset;
+ cap->cap = basecap;
+ cap->join = LineJoinMiter;
+ cap->scale = 1.0;
+
+ return Ok;
+}
+
/* FIXME: Sometimes when fillPath is non-null and stroke path is null, the native
* version of this function returns NotImplemented. I cannot figure out why. */
GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath,
GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap)
{
GpPathData *pathdata;
+ GpStatus stat;
TRACE("%p %p %d %f %p\n", fillPath, strokePath, baseCap, baseInset,
customCap);
@@ -77,37 +119,18 @@ GpStatus WINGDIPAPI GdipCreateCustomLineCap(GpPath* fillPath, GpPath*
strokePath
*customCap = heap_alloc_zero(sizeof(GpCustomLineCap));
if(!*customCap) return OutOfMemory;
- (*customCap)->type = CustomLineCapTypeDefault;
- if(strokePath){
- (*customCap)->fill = FALSE;
+ if (strokePath)
pathdata = &strokePath->pathdata;
- }
- else{
- (*customCap)->fill = TRUE;
+ else
pathdata = &fillPath->pathdata;
- }
- (*customCap)->pathdata.Points = heap_alloc_zero(pathdata->Count *
sizeof(PointF));
- (*customCap)->pathdata.Types = heap_alloc_zero(pathdata->Count);
-
- if((!(*customCap)->pathdata.Types || !(*customCap)->pathdata.Points)
&&
- pathdata->Count){
- heap_free((*customCap)->pathdata.Points);
- heap_free((*customCap)->pathdata.Types);
+ stat = init_custom_linecap(*customCap, pathdata, fillPath != NULL, baseCap,
baseInset);
+ if (stat != Ok)
+ {
heap_free(*customCap);
- return OutOfMemory;
+ return stat;
}
- memcpy((*customCap)->pathdata.Points, pathdata->Points, pathdata->Count
- * sizeof(PointF));
- memcpy((*customCap)->pathdata.Types, pathdata->Types, pathdata->Count);
- (*customCap)->pathdata.Count = pathdata->Count;
-
- (*customCap)->inset = baseInset;
- (*customCap)->cap = baseCap;
- (*customCap)->join = LineJoinMiter;
- (*customCap)->scale = 1.0;
-
TRACE("<-- %p\n", *customCap);
return Ok;
@@ -257,111 +280,175 @@ GpStatus WINGDIPAPI GdipGetCustomLineCapType(GpCustomLineCap
*customCap, CustomL
return Ok;
}
+static void arrowcap_update_path(GpAdjustableArrowCap *cap)
+{
+ static const BYTE types_filled[] =
+ {
+ PathPointTypeStart, PathPointTypeLine, PathPointTypeLine, PathPointTypeLine |
PathPointTypeCloseSubpath
+ };
+ static const BYTE types_unfilled[] =
+ {
+ PathPointTypeStart, PathPointTypeLine, PathPointTypeLine
+ };
+ GpPointF *points;
+
+ assert(cap->cap.pathdata.Count == 3 || cap->cap.pathdata.Count == 4);
+
+ points = cap->cap.pathdata.Points;
+ if (cap->cap.fill)
+ {
+ memcpy(cap->cap.pathdata.Types, types_filled, sizeof(types_filled));
+ cap->cap.pathdata.Count = 4;
+ points[0].X = -cap->width / 2.0;
+ points[0].Y = -cap->height;
+ points[1].X = 0.0;
+ points[1].Y = 0.0;
+ points[2].X = cap->width / 2.0;
+ points[2].Y = -cap->height;
+ points[3].X = 0.0;
+ points[3].Y = -cap->height - cap->middle_inset;
+ }
+ else
+ {
+ memcpy(cap->cap.pathdata.Types, types_unfilled, sizeof(types_unfilled));
+ cap->cap.pathdata.Count = 3;
+ points[0].X = -cap->width / 4.0;
+ points[0].Y = -cap->height / 2.0;
+ points[1].X = 0.0;
+ points[1].Y = 0.0;
+ points[2].X = cap->width / 4.0;
+ points[2].Y = -cap->height / 2.0;
+ }
+
+ if (cap->width == 0.0)
+ cap->cap.inset = 0.0;
+ else
+ cap->cap.inset = cap->height / cap->width;
+}
+
GpStatus WINGDIPAPI GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL fill,
GpAdjustableArrowCap **cap)
{
- static int calls;
+ GpPathData pathdata;
+ GpStatus stat;
TRACE("(%0.2f,%0.2f,%i,%p)\n", height, width, fill, cap);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap)
+ return InvalidParameter;
- return NotImplemented;
+ *cap = heap_alloc_zero(sizeof(**cap));
+ if (!*cap)
+ return OutOfMemory;
+
+ /* We'll need 4 points at most. */
+ pathdata.Count = 4;
+ pathdata.Points = NULL;
+ pathdata.Types = NULL;
+ stat = init_custom_linecap(&(*cap)->cap, &pathdata, fill, LineCapTriangle,
width != 0.0 ? height / width : 0.0);
+ if (stat != Ok)
+ {
+ heap_free(*cap);
+ return stat;
+ }
+
+ (*cap)->cap.type = CustomLineCapTypeAdjustableArrow;
+ (*cap)->height = height;
+ (*cap)->width = width;
+ (*cap)->middle_inset = 0.0;
+ arrowcap_update_path(*cap);
+
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL*
fill)
{
- static int calls;
-
TRACE("(%p,%p)\n", cap, fill);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap || !fill)
+ return InvalidParameter;
- return NotImplemented;
+ *fill = cap->cap.fill;
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL*
height)
{
- static int calls;
-
TRACE("(%p,%p)\n", cap, height);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap || !height)
+ return InvalidParameter;
- return NotImplemented;
+ *height = cap->height;
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL*
middle)
{
- static int calls;
-
TRACE("(%p,%p)\n", cap, middle);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap || !middle)
+ return InvalidParameter;
- return NotImplemented;
+ *middle = cap->middle_inset;
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL*
width)
{
- static int calls;
-
TRACE("(%p,%p)\n", cap, width);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap || !width)
+ return InvalidParameter;
- return NotImplemented;
+ *width = cap->width;
+ return Ok;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL
fill)
{
- static int calls;
-
TRACE("(%p,%i)\n", cap, fill);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap)
+ return InvalidParameter;
- return NotImplemented;
+ cap->cap.fill = fill;
+ arrowcap_update_path(cap);
+ return Ok;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL
height)
{
- static int calls;
-
TRACE("(%p,%0.2f)\n", cap, height);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap)
+ return InvalidParameter;
- return NotImplemented;
+ cap->height = height;
+ arrowcap_update_path(cap);
+ return Ok;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL
middle)
{
- static int calls;
-
TRACE("(%p,%0.2f)\n", cap, middle);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap)
+ return InvalidParameter;
- return NotImplemented;
+ cap->middle_inset = middle;
+ arrowcap_update_path(cap);
+ return Ok;
}
GpStatus WINGDIPAPI GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL
width)
{
- static int calls;
-
TRACE("(%p,%0.2f)\n", cap, width);
- if(!(calls++))
- FIXME("not implemented\n");
+ if (!cap)
+ return InvalidParameter;
- return NotImplemented;
+ cap->width = width;
+ arrowcap_update_path(cap);
+ return Ok;
}
diff --git a/dll/win32/gdiplus/font.c b/dll/win32/gdiplus/font.c
index f99b026b25..64778bb226 100644
--- a/dll/win32/gdiplus/font.c
+++ b/dll/win32/gdiplus/font.c
@@ -1367,7 +1367,7 @@ static int match_name_table_language( const tt_name_record *name,
LANGID lang )
case TT_PLATFORM_MACINTOSH:
if (!IsValidCodePage( get_mac_code_page( name ))) return 0;
name_lang = GET_BE_WORD(name->language_id);
- if (name_lang >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0])) return
0;
+ if (name_lang >= ARRAY_SIZE(mac_langid_table)) return 0;
name_lang = mac_langid_table[name_lang];
break;
case TT_PLATFORM_APPLE_UNICODE:
@@ -1377,7 +1377,7 @@ static int match_name_table_language( const tt_name_record *name,
LANGID lang )
case TT_APPLE_ID_ISO_10646:
case TT_APPLE_ID_UNICODE_2_0:
name_lang = GET_BE_WORD(name->language_id);
- if (name_lang >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0]))
return 0;
+ if (name_lang >= ARRAY_SIZE(mac_langid_table)) return 0;
name_lang = mac_langid_table[name_lang];
break;
default:
diff --git a/dll/win32/gdiplus/gdiplus.spec b/dll/win32/gdiplus/gdiplus.spec
index b29e41ebfa..ed9d50c058 100644
--- a/dll/win32/gdiplus/gdiplus.spec
+++ b/dll/win32/gdiplus/gdiplus.spec
@@ -534,7 +534,7 @@
534 stdcall GdipSetPathGradientFocusScales(ptr float float)
535 stdcall GdipSetPathGradientGammaCorrection(ptr long)
536 stdcall GdipSetPathGradientLinearBlend(ptr float float)
-537 stub GdipSetPathGradientPath
+537 stdcall GdipSetPathGradientPath(ptr ptr)
538 stdcall GdipSetPathGradientPresetBlend(ptr ptr ptr long)
539 stdcall GdipSetPathGradientSigmaBlend(ptr float float)
540 stdcall GdipSetPathGradientSurroundColorsWithCount(ptr ptr ptr)
diff --git a/dll/win32/gdiplus/gdiplus_private.h b/dll/win32/gdiplus/gdiplus_private.h
index ea79f1183c..25b269ba35 100644
--- a/dll/win32/gdiplus/gdiplus_private.h
+++ b/dll/win32/gdiplus/gdiplus_private.h
@@ -35,6 +35,8 @@
#include "gdiplus.h"
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
+
#define GP_DEFAULT_PENSTYLE (PS_GEOMETRIC | PS_SOLID | PS_ENDCAP_FLAT | PS_JOIN_MITER)
#define MAX_ARC_PTS (13)
#define MAX_DASHLEN (16) /* this is a limitation of gdi */
@@ -341,6 +343,9 @@ struct GpCustomLineCap{
struct GpAdjustableArrowCap{
GpCustomLineCap cap;
+ REAL middle_inset;
+ REAL height;
+ REAL width;
};
struct GpImage{
diff --git a/dll/win32/gdiplus/graphics.c b/dll/win32/gdiplus/graphics.c
index f42fca643d..1e2aff14f4 100644
--- a/dll/win32/gdiplus/graphics.c
+++ b/dll/win32/gdiplus/graphics.c
@@ -353,15 +353,20 @@ static GpStatus get_clip_hrgn(GpGraphics *graphics, HRGN *hrgn)
GpRegion *rgn;
GpMatrix transform;
GpStatus stat;
+ BOOL identity;
stat = get_graphics_transform(graphics, WineCoordinateSpaceGdiDevice,
CoordinateSpaceDevice, &transform);
+ if (stat == Ok)
+ stat = GdipIsMatrixIdentity(&transform, &identity);
+
if (stat == Ok)
stat = GdipCloneRegion(graphics->clip, &rgn);
if (stat == Ok)
{
- stat = GdipTransformRegion(rgn, &transform);
+ if (!identity)
+ stat = GdipTransformRegion(rgn, &transform);
if (stat == Ok)
stat = GdipGetRegionHRgn(rgn, NULL, hrgn);
@@ -1695,9 +1700,9 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap
cap, REAL s
ptf[3].X = x2 - dbig;
ptf[2].X = x2 + dsmall;
- gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
CoordinateSpaceWorld, ptf, 3);
+ gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
CoordinateSpaceWorld, ptf, 4);
- round_points(pt, ptf, 3);
+ round_points(pt, ptf, 4);
Polygon(graphics->hdc, pt, 4);
@@ -1735,9 +1740,9 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap
cap, REAL s
ptf[1].X = x2 + dx;
ptf[1].Y = y2 + dy;
- gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
CoordinateSpaceWorld, ptf, 3);
+ gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
CoordinateSpaceWorld, ptf, 2);
- round_points(pt, ptf, 3);
+ round_points(pt, ptf, 2);
Ellipse(graphics->hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y);
@@ -1781,9 +1786,9 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap
cap, REAL s
ptf[3].X = x2 + dx;
ptf[3].Y = y2 + dy;
- gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
CoordinateSpaceWorld, ptf, 3);
+ gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
CoordinateSpaceWorld, ptf, 4);
- round_points(pt, ptf, 3);
+ round_points(pt, ptf, 4);
Pie(graphics->hdc, pt[0].x, pt[0].y, pt[1].x, pt[1].y, pt[2].x,
pt[2].y, pt[3].x, pt[3].y);
@@ -1793,6 +1798,13 @@ static void draw_cap(GpGraphics *graphics, COLORREF color,
GpLineCap cap, REAL s
if(!custom)
break;
+ if (custom->type == CustomLineCapTypeAdjustableArrow)
+ {
+ GpAdjustableArrowCap *arrow = (GpAdjustableArrowCap *)custom;
+ if (arrow->cap.fill && arrow->height <= 0.0)
+ break;
+ }
+
count = custom->pathdata.Count;
custptf = heap_alloc_zero(count * sizeof(PointF));
custpt = heap_alloc_zero(count * sizeof(POINT));
@@ -1810,9 +1822,9 @@ static void draw_cap(GpGraphics *graphics, COLORREF color, GpLineCap
cap, REAL s
GdipTranslateMatrix(&matrix, x2, y2, MatrixOrderAppend);
GdipTransformMatrixPoints(&matrix, custptf, count);
- gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
CoordinateSpaceWorld, ptf, 3);
+ gdip_transform_points(graphics, WineCoordinateSpaceGdiDevice,
CoordinateSpaceWorld, custptf, count);
- round_points(pt, ptf, 3);
+ round_points(custpt, custptf, count);
for(i = 0; i < count; i++)
tp[i] = convert_path_point_type(custom->pathdata.Types[i]);
@@ -6469,9 +6481,12 @@ GpStatus WINGDIPAPI GdipSetClipRect(GpGraphics *graphics, REAL x,
REAL y,
if (status == Ok)
{
GpMatrix world_to_device;
+ BOOL identity;
get_graphics_transform(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld,
&world_to_device);
- status = GdipTransformRegion(region, &world_to_device);
+ status = GdipIsMatrixIdentity(&world_to_device, &identity);
+ if (status == Ok && !identity)
+ status = GdipTransformRegion(region, &world_to_device);
if (status == Ok)
status = GdipCombineRegionRegion(graphics->clip, region, mode);
@@ -6520,9 +6535,12 @@ GpStatus WINGDIPAPI GdipSetClipRegion(GpGraphics *graphics,
GpRegion *region,
if (status == Ok)
{
GpMatrix world_to_device;
+ BOOL identity;
get_graphics_transform(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld,
&world_to_device);
- status = GdipTransformRegion(clip, &world_to_device);
+ status = GdipIsMatrixIdentity(&world_to_device, &identity);
+ if (status == Ok && !identity)
+ status = GdipTransformRegion(clip, &world_to_device);
if (status == Ok)
status = GdipCombineRegionRegion(graphics->clip, clip, mode);
diff --git a/dll/win32/gdiplus/image.c b/dll/win32/gdiplus/image.c
index ff9bd9be7f..afa2afeac7 100644
--- a/dll/win32/gdiplus/image.c
+++ b/dll/win32/gdiplus/image.c
@@ -2560,7 +2560,7 @@ static UINT vt_to_itemtype(UINT vt)
{ VT_BLOB, PropertyTagTypeUndefined }
};
UINT i;
- for (i = 0; i < sizeof(vt2type)/sizeof(vt2type[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(vt2type); i++)
{
if (vt2type[i].vt == vt) return vt2type[i].type;
}
@@ -3460,10 +3460,10 @@ static void png_metadata_reader(GpBitmap *bitmap,
IWICBitmapDecoder *decoder, UI
{
if (name.vt == VT_LPSTR)
{
- for (j=0; j<sizeof(keywords)/sizeof(keywords[0]);
j++)
+ for (j = 0; j < ARRAY_SIZE(keywords); j++)
if (!strcmp(keywords[j].name, name.u.pszVal))
break;
- if (j < sizeof(keywords)/sizeof(keywords[0])
&& !keywords[j].seen)
+ if (j < ARRAY_SIZE(keywords) &&
!keywords[j].seen)
{
keywords[j].seen = TRUE;
item = create_prop(keywords[j].propid, &value);
@@ -4586,7 +4586,7 @@ GpStatus WINGDIPAPI GdipSaveImageToStream(GpImage *image, IStream*
stream,
encode_image_func encode_image;
int i;
- TRACE("%p %p %s %p\n", image, stream, wine_dbgstr_guid(clsid), params);
+ TRACE("%p, %p, %s, %p\n", image, stream, wine_dbgstr_guid(clsid), params);
if(!image || !stream)
return InvalidParameter;
diff --git a/dll/win32/gdiplus/metafile.c b/dll/win32/gdiplus/metafile.c
index 77673a7ea3..08dde2fec6 100644
--- a/dll/win32/gdiplus/metafile.c
+++ b/dll/win32/gdiplus/metafile.c
@@ -606,7 +606,7 @@ void METAFILE_Free(GpMetafile *metafile)
if (metafile->record_stream)
IStream_Release(metafile->record_stream);
- for (i = 0; i < sizeof(metafile->objtable)/sizeof(metafile->objtable[0]);
i++)
+ for (i = 0; i < ARRAY_SIZE(metafile->objtable); i++)
metafile_free_object_table_entry(metafile, i);
}
diff --git a/dll/win32/gdiplus/pen.c b/dll/win32/gdiplus/pen.c
index 2c49371bd5..b86808b87e 100644
--- a/dll/win32/gdiplus/pen.c
+++ b/dll/win32/gdiplus/pen.c
@@ -460,17 +460,12 @@ GpStatus WINGDIPAPI GdipGetPenTransform(GpPen *pen, GpMatrix
*matrix)
GpStatus WINGDIPAPI GdipTranslatePenTransform(GpPen *pen, REAL dx, REAL dy, GpMatrixOrder
order)
{
- static int calls;
-
TRACE("(%p,%0.2f,%0.2f,%u)\n", pen, dx, dy, order);
if(!pen)
return InvalidParameter;
- if(!(calls++))
- FIXME("not implemented\n");
-
- return NotImplemented;
+ return GdipTranslateMatrix(&pen->transform, dx, dy, order);
}
GpStatus WINGDIPAPI GdipScalePenTransform(GpPen *pen, REAL sx, REAL sy, GpMatrixOrder
order)
diff --git a/dll/win32/gdiplus/region.c b/dll/win32/gdiplus/region.c
index 8eb3ff3535..470bcd20ce 100644
--- a/dll/win32/gdiplus/region.c
+++ b/dll/win32/gdiplus/region.c
@@ -1398,10 +1398,46 @@ static GpStatus transform_region_element(region_element* element,
GpMatrix *matr
return Ok;
case RegionDataRect:
{
- /* We can't transform a rectangle, so convert it to a path. */
GpRegion *new_region;
GpPath *path;
+ if (matrix->matrix[1] == 0.0 && matrix->matrix[2] == 0.0)
+ {
+ GpPointF points[2];
+
+ points[0].X = element->elementdata.rect.X;
+ points[0].Y = element->elementdata.rect.Y;
+ points[1].X = element->elementdata.rect.X +
element->elementdata.rect.Width;
+ points[1].Y = element->elementdata.rect.Y +
element->elementdata.rect.Height;
+
+ stat = GdipTransformMatrixPoints(matrix, points, 2);
+ if (stat != Ok)
+ return stat;
+
+ if (points[0].X > points[1].X)
+ {
+ REAL temp;
+ temp = points[0].X;
+ points[0].X = points[1].X;
+ points[1].X = temp;
+ }
+
+ if (points[0].Y > points[1].Y)
+ {
+ REAL temp;
+ temp = points[0].Y;
+ points[0].Y = points[1].Y;
+ points[1].Y = temp;
+ }
+
+ element->elementdata.rect.X = points[0].X;
+ element->elementdata.rect.Y = points[0].Y;
+ element->elementdata.rect.Width = points[1].X - points[0].X;
+ element->elementdata.rect.Height = points[1].Y - points[0].Y;
+ return Ok;
+ }
+
+ /* We can't rotate/shear a rectangle, so convert it to a path. */
stat = GdipCreatePath(FillModeAlternate, &path);
if (stat == Ok)
{
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index 08dcf59cac..e17deddf22 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -68,7 +68,7 @@ reactos/dll/win32/dciman32 # Synced to WineStaging-3.3
reactos/dll/win32/faultrep # Synced to WineStaging-2.9
reactos/dll/win32/fontsub # Synced to WineStaging-2.9
reactos/dll/win32/fusion # Synced to WineStaging-3.3
-reactos/dll/win32/gdiplus # Synced to WineStaging-3.3
+reactos/dll/win32/gdiplus # Synced to WineStaging-3.9
reactos/dll/win32/hhctrl.ocx # Synced to WineStaging-3.3
reactos/dll/win32/hlink # Synced to WineStaging-3.3
reactos/dll/win32/hnetcfg # Synced to WineStaging-3.3