gdiplus/metafile: Support texture brushes playback.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Vincent Povirk <vincent@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2017-11-02 14:10:40 +03:00 committed by Alexandre Julliard
parent 6d0ca495b8
commit 905bd23b2e
1 changed files with 50 additions and 0 deletions

View File

@ -225,6 +225,18 @@ typedef struct EmfPlusPenData
BYTE OptionalData[1]; BYTE OptionalData[1];
} EmfPlusPenData; } EmfPlusPenData;
enum BrushDataFlags
{
BrushDataPath = 1 << 0,
BrushDataTransform = 1 << 1,
BrushDataPresetColors = 1 << 2,
BrushDataBlendFactorsH = 1 << 3,
BrushDataBlendFactorsV = 1 << 4,
BrushDataFocusScales = 1 << 6,
BrushDataIsGammaCorrected = 1 << 7,
BrushDataDoNotTransform = 1 << 8,
};
typedef struct EmfPlusSolidBrushData typedef struct EmfPlusSolidBrushData
{ {
EmfPlusARGB SolidColor; EmfPlusARGB SolidColor;
@ -237,6 +249,13 @@ typedef struct EmfPlusHatchBrushData
EmfPlusARGB BackColor; EmfPlusARGB BackColor;
} EmfPlusHatchBrushData; } EmfPlusHatchBrushData;
typedef struct EmfPlusTextureBrushData
{
DWORD BrushDataFlags;
INT WrapMode;
BYTE OptionalData[1];
} EmfPlusTextureBrushData;
typedef struct EmfPlusBrush typedef struct EmfPlusBrush
{ {
DWORD Version; DWORD Version;
@ -244,6 +263,7 @@ typedef struct EmfPlusBrush
union { union {
EmfPlusSolidBrushData solid; EmfPlusSolidBrushData solid;
EmfPlusHatchBrushData hatch; EmfPlusHatchBrushData hatch;
EmfPlusTextureBrushData texture;
} BrushData; } BrushData;
} EmfPlusBrush; } EmfPlusBrush;
@ -1848,6 +1868,36 @@ static GpStatus metafile_deserialize_brush(const BYTE *record_data, UINT data_si
status = GdipCreateHatchBrush(data->BrushData.hatch.HatchStyle, data->BrushData.hatch.ForeColor, status = GdipCreateHatchBrush(data->BrushData.hatch.HatchStyle, data->BrushData.hatch.ForeColor,
data->BrushData.hatch.BackColor, (GpHatch **)brush); data->BrushData.hatch.BackColor, (GpHatch **)brush);
break; break;
case BrushTypeTextureFill:
{
UINT offset = header_size + FIELD_OFFSET(EmfPlusTextureBrushData, OptionalData);
EmfPlusTransformMatrix *transform = NULL;
DWORD brushflags;
GpImage *image;
if (data_size <= offset)
return InvalidParameter;
brushflags = data->BrushData.texture.BrushDataFlags;
if (brushflags & BrushDataTransform)
{
if (data_size <= offset + sizeof(EmfPlusTransformMatrix))
return InvalidParameter;
transform = (EmfPlusTransformMatrix *)(record_data + offset);
offset += sizeof(EmfPlusTransformMatrix);
}
status = metafile_deserialize_image(record_data + offset, data_size - offset, &image);
if (status != Ok)
return status;
status = GdipCreateTexture(image, data->BrushData.texture.WrapMode, (GpTexture **)brush);
if (status == Ok && transform && !(brushflags & BrushDataDoNotTransform))
GdipSetTextureTransform((GpTexture *)*brush, (const GpMatrix *)transform);
GdipDisposeImage(image);
break;
}
default: default:
FIXME("brush type %u is not supported.\n", data->Type); FIXME("brush type %u is not supported.\n", data->Type);
return NotImplemented; return NotImplemented;