Author: akhaldi
Date: Sun Mar 22 18:33:30 2015
New Revision: 66857
URL:
http://svn.reactos.org/svn/reactos?rev=66857&view=rev
Log:
[GDIPLUS] Sync with Wine Staging 1.7.37. CORE-9246
Modified:
trunk/reactos/dll/win32/gdiplus/graphics.c
trunk/reactos/dll/win32/gdiplus/image.c
trunk/reactos/dll/win32/gdiplus/region.c
trunk/reactos/media/doc/README.WINE
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] Sun Mar 22 18:33:30 2015
@@ -823,6 +823,10 @@
right = bitmap->width-1;
if (bottom >= bitmap->height)
bottom = bitmap->height-1;
+ if (bottom < top || right < left)
+ /* entirely outside image, just sample a pixel so we don't have to
+ * special-case this later */
+ left = top = right = bottom = 0;
}
else
{
@@ -1775,7 +1779,7 @@
for(i = 1; i < count; i++){
if((types[i] & PathPointTypePathTypeMask) == PathPointTypeBezier){
if((i + 2 >= count) || !(types[i + 1] & PathPointTypeBezier)
- || !(types[i + 1] & PathPointTypeBezier)){
+ || !(types[i + 2] & PathPointTypeBezier)){
ERR("Bad bezier points\n");
goto end;
}
@@ -2021,8 +2025,7 @@
rect->Height = GetDeviceCaps(graphics->hdc, VERTRES);
}
- if (graphics->hdc &&
- (GetMapMode(graphics->hdc) != MM_TEXT || GetGraphicsMode(graphics->hdc) !=
GM_COMPATIBLE))
+ if (graphics->hdc)
{
POINT points[2];
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] Sun Mar 22 18:33:30 2015
@@ -565,8 +565,8 @@
}
#define convert_indexed_to_rgb(getpixel_function, setpixel_function) do { \
- for (x=0; x<width; x++) \
- for (y=0; y<height; y++) { \
+ for (y=0; y<height; y++) \
+ for (x=0; x<width; x++) { \
BYTE index; \
ARGB argb; \
BYTE *color = (BYTE *)&argb; \
@@ -578,8 +578,8 @@
} while (0);
#define convert_rgb_to_rgb(getpixel_function, setpixel_function) do { \
- for (x=0; x<width; x++) \
- for (y=0; y<height; y++) { \
+ for (y=0; y<height; y++) \
+ for (x=0; x<width; x++) { \
BYTE r, g, b, a; \
getpixel_function(&r, &g, &b, &a, src_bits+src_stride*y, x);
\
setpixel_function(r, g, b, a, dst_bits+dst_stride*y, x); \
@@ -588,8 +588,8 @@
} while (0);
#define convert_rgb_to_indexed(getpixel_function, setpixel_function) do { \
- for (x=0; x<width; x++) \
- for (y=0; y<height; y++) { \
+ for (y=0; y<height; y++) \
+ for (x=0; x<width; x++) { \
BYTE r, g, b, a; \
getpixel_function(&r, &g, &b, &a, src_bits+src_stride*y, x);
\
setpixel_function(r, g, b, a, dst_bits+dst_stride*y, x, palette); \
@@ -1466,6 +1466,18 @@
return stat;
}
+static inline DWORD blend_argb_no_bkgnd_alpha(DWORD src, DWORD bkgnd)
+{
+ BYTE b = (BYTE)src;
+ BYTE g = (BYTE)(src >> 8);
+ BYTE r = (BYTE)(src >> 16);
+ DWORD alpha = (BYTE)(src >> 24);
+ return ((b + ((BYTE)bkgnd * (255 - alpha) + 127) / 255) |
+ (g + ((BYTE)(bkgnd >> 8) * (255 - alpha) + 127) / 255) << 8
|
+ (r + ((BYTE)(bkgnd >> 16) * (255 - alpha) + 127) / 255) << 16
|
+ (alpha << 24));
+}
+
GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
HBITMAP* hbmReturn, ARGB background)
{
@@ -1506,6 +1518,17 @@
if (stat == Ok)
stat = GdipBitmapUnlockBits(bitmap, &lockeddata);
+
+ if (stat == Ok && (background & 0xffffff))
+ {
+ DWORD *ptr;
+ UINT i;
+ for (ptr = (DWORD*)bits, i = 0; i < width * height; ptr++, i++)
+ {
+ if ((*ptr & 0xff000000) == 0xff000000) continue;
+ *ptr = blend_argb_no_bkgnd_alpha(*ptr, background);
+ }
+ }
}
else
stat = GenericError;
@@ -3836,11 +3859,6 @@
* Encoding functions -
* These functions encode an image in different image file formats.
*/
-#define BITMAP_FORMAT_BMP 0x4d42 /* "BM" */
-#define BITMAP_FORMAT_JPEG 0xd8ff
-#define BITMAP_FORMAT_GIF 0x4947
-#define BITMAP_FORMAT_PNG 0x5089
-#define BITMAP_FORMAT_APM 0xcdd7
static GpStatus encode_image_WIC(GpImage *image, IStream* stream,
GDIPCONST CLSID* clsid, GDIPCONST EncoderParameters* params)
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] Sun Mar 22 18:33:30 2015
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2008 Google (Lei Zhang)
+ * Copyright (C) 2013 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -63,6 +64,28 @@
#define FLAGS_NOFLAGS 0x0
#define FLAGS_INTPATH 0x4000
+
+struct memory_buffer
+{
+ const BYTE *buffer;
+ INT size, pos;
+};
+
+struct region_header
+{
+ DWORD size;
+ DWORD checksum;
+ DWORD magic;
+ DWORD num_children;
+};
+
+struct path_header
+{
+ DWORD size;
+ DWORD magic;
+ DWORD count;
+ DWORD flags;
+};
/* Header size as far as header->size is concerned. This doesn't include
* header->size or header->checksum
@@ -510,12 +533,221 @@
return GdipCreateRegionRect(&rectf, region);
}
+static inline void init_memory_buffer(struct memory_buffer *mbuf, const BYTE *buffer, INT
size)
+{
+ mbuf->buffer = buffer;
+ mbuf->size = size;
+ mbuf->pos = 0;
+}
+
+static inline const void *buffer_read(struct memory_buffer *mbuf, INT size)
+{
+ if (mbuf->size - mbuf->pos >= size)
+ {
+ const void *data = mbuf->buffer + mbuf->pos;
+ mbuf->pos += size;
+ return data;
+ }
+ return NULL;
+}
+
+static GpStatus read_element(struct memory_buffer *mbuf, GpRegion *region, region_element
*node, INT *count)
+{
+ GpStatus status;
+ const DWORD *type;
+
+ type = buffer_read(mbuf, sizeof(DWORD));
+ if (!type) return Ok;
+
+ TRACE("type %#x\n", *type);
+
+ node->type = *type;
+
+ switch (node->type)
+ {
+ case CombineModeReplace:
+ case CombineModeIntersect:
+ case CombineModeUnion:
+ case CombineModeXor:
+ case CombineModeExclude:
+ case CombineModeComplement:
+ {
+ region_element *left, *right;
+
+ left = GdipAlloc(sizeof(region_element));
+ if (!left) return OutOfMemory;
+ right = GdipAlloc(sizeof(region_element));
+ if (!right)
+ {
+ GdipFree(left);
+ return OutOfMemory;
+ }
+
+ status = read_element(mbuf, region, left, count);
+ if (status == Ok)
+ {
+ status = read_element(mbuf, region, right, count);
+ if (status == Ok)
+ {
+ node->elementdata.combine.left = left;
+ node->elementdata.combine.right = right;
+ region->num_children += 2;
+ return Ok;
+ }
+ }
+
+ GdipFree(left);
+ GdipFree(right);
+ return status;
+ }
+
+ case RegionDataRect:
+ {
+ const GpRectF *rc;
+
+ rc = buffer_read(mbuf, sizeof(GpRectF));
+ if (!rc)
+ {
+ ERR("failed to read rect data\n");
+ return InvalidParameter;
+ }
+
+ node->elementdata.rect = *rc;
+ *count += 1;
+ return Ok;
+ }
+
+ case RegionDataPath:
+ {
+ GpPath *path;
+ const struct path_header *path_header;
+ const BYTE *types;
+
+ path_header = buffer_read(mbuf, sizeof(struct path_header));
+ if (!path_header)
+ {
+ ERR("failed to read path header\n");
+ return InvalidParameter;
+ }
+ if (path_header->magic != VERSION_MAGIC)
+ {
+ ERR("invalid path header magic %#x\n", path_header->magic);
+ return InvalidParameter;
+ }
+
+ /* Windows always fails to create an empty path in a region */
+ if (!path_header->count)
+ {
+ TRACE("refusing to create an empty path in a region\n");
+ return GenericError;
+ }
+
+ status = GdipCreatePath(FillModeAlternate, &path);
+ if (status) return status;
+
+ node->elementdata.path = path;
+
+ if (!lengthen_path(path, path_header->count))
+ return OutOfMemory;
+
+ path->pathdata.Count = path_header->count;
+
+ if (path_header->flags & ~FLAGS_INTPATH)
+ FIXME("unhandled path flags %#x\n", path_header->flags);
+
+ if (path_header->flags & FLAGS_INTPATH)
+ {
+ const packed_point *pt;
+ DWORD i;
+
+ pt = buffer_read(mbuf, sizeof(packed_point) * path_header->count);
+ if (!pt)
+ {
+ ERR("failed to read packed %u path points\n",
path_header->count);
+ return InvalidParameter;
+ }
+
+ for (i = 0; i < path_header->count; i++)
+ {
+ path->pathdata.Points[i].X = (REAL)pt[i].X;
+ path->pathdata.Points[i].Y = (REAL)pt[i].Y;
+ }
+ }
+ else
+ {
+ const GpPointF *ptf;
+
+ ptf = buffer_read(mbuf, sizeof(GpPointF) * path_header->count);
+ if (!ptf)
+ {
+ ERR("failed to read %u path points\n", path_header->count);
+ return InvalidParameter;
+ }
+ memcpy(path->pathdata.Points, ptf, sizeof(GpPointF) *
path_header->count);
+ }
+
+ types = buffer_read(mbuf, path_header->count);
+ if (!types)
+ {
+ ERR("failed to read %u path types\n", path_header->count);
+ return InvalidParameter;
+ }
+ memcpy(path->pathdata.Types, types, path_header->count);
+ if (path_header->count & 3)
+ {
+ if (!buffer_read(mbuf, 4 - (path_header->count & 3)))
+ {
+ ERR("failed to read rounding %u bytes\n", 4 -
(path_header->count & 3));
+ return InvalidParameter;
+ }
+ }
+
+ *count += 1;
+ return Ok;
+ }
+
+ case RegionDataEmptyRect:
+ case RegionDataInfiniteRect:
+ *count += 1;
+ return Ok;
+
+ default:
+ FIXME("element type %#x is not supported\n", *type);
+ break;
+ }
+
+ return InvalidParameter;
+}
+
GpStatus WINGDIPAPI GdipCreateRegionRgnData(GDIPCONST BYTE *data, INT size, GpRegion
**region)
{
- FIXME("(%p, %d, %p): stub\n", data, size, region);
-
- *region = NULL;
- return NotImplemented;
+ GpStatus status;
+ struct memory_buffer mbuf;
+ const struct region_header *region_header;
+ INT count;
+
+ if (!data || !size) return InvalidParameter;
+
+ TRACE("%p, %d, %p\n", data, size, region);
+
+ init_memory_buffer(&mbuf, data, size);
+
+ region_header = buffer_read(&mbuf, sizeof(struct region_header));
+ if (!region_header || region_header->magic != VERSION_MAGIC)
+ return InvalidParameter;
+
+ status = GdipCreateRegion(region);
+ if (status != Ok) return status;
+
+ count = 0;
+ status = read_element(&mbuf, *region, &(*region)->node, &count);
+ if (status == Ok && !count)
+ status = InvalidParameter;
+
+ if (status != Ok)
+ GdipDeleteRegion(*region);
+
+ return status;
}
@@ -726,15 +958,9 @@
{
INT i;
const GpPath* path = element->elementdata.path;
- struct _pathheader
- {
- DWORD size;
- DWORD magic;
- DWORD count;
- DWORD flags;
- } *pathheader;
-
- pathheader = (struct _pathheader *)(buffer + *filled);
+ struct path_header *pathheader;
+
+ pathheader = (struct path_header *)(buffer + *filled);
pathheader->flags = is_integer_path(path) ? FLAGS_INTPATH :
FLAGS_NOFLAGS;
/* 3 for headers, once again size doesn't count itself */
@@ -811,13 +1037,7 @@
GpStatus WINGDIPAPI GdipGetRegionData(GpRegion *region, BYTE *buffer, UINT size,
UINT *needed)
{
- struct _region_header
- {
- DWORD size;
- DWORD checksum;
- DWORD magic;
- DWORD num_children;
- } *region_header;
+ struct region_header *region_header;
INT filled = 0;
UINT required;
GpStatus status;
@@ -835,7 +1055,7 @@
return InsufficientBuffer;
}
- region_header = (struct _region_header *)buffer;
+ region_header = (struct region_header *)buffer;
region_header->size = sizeheader_size + get_element_size(®ion->node);
region_header->checksum = 0;
region_header->magic = VERSION_MAGIC;
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] Sun Mar 22 18:33:30 2015
@@ -76,7 +76,7 @@
reactos/dll/win32/faultrep # Synced to Wine-1.7.27
reactos/dll/win32/fltlib # Synced to Wine-1.7.27
reactos/dll/win32/fusion # Synced to WineStaging-1.7.37
-reactos/dll/win32/gdiplus # Synced to Wine-1.7.27
+reactos/dll/win32/gdiplus # Synced to WineStaging-1.7.37
reactos/dll/win32/hhctrl.ocx # Synced to Wine-1.7.27
reactos/dll/win32/hlink # Synced to Wine-1.7.27
reactos/dll/win32/hnetcfg # Synced to Wine-1.7.27