gdiplus: Add LinearGradient brush object serialization.

Signed-off-by: Shawn M. Chapla <schapla@codeweavers.com>
Signed-off-by: Esme Povirk <esme@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Shawn M. Chapla 2020-07-22 23:08:10 -04:00 committed by Alexandre Julliard
parent 6c57cf5eee
commit 60fd827d8b
2 changed files with 96 additions and 15 deletions

View file

@ -1036,6 +1036,26 @@ static GpStatus METAFILE_PrepareBrushData(GDIPCONST GpBrush *brush, DWORD *size)
case BrushTypeHatchFill:
*size = FIELD_OFFSET(EmfPlusBrush, BrushData) + sizeof(EmfPlusHatchBrushData);
break;
case BrushTypeLinearGradient:
{
BOOL ignore_xform;
GpLineGradient *gradient = (GpLineGradient*)brush;
*size = FIELD_OFFSET(EmfPlusBrush, BrushData.lineargradient.OptionalData);
GdipIsMatrixIdentity(&gradient->transform, &ignore_xform);
if (!ignore_xform)
*size += sizeof(gradient->transform);
if (gradient->pblendcount > 1 && gradient->pblendcolor && gradient->pblendpos)
*size += sizeof(DWORD) + gradient->pblendcount *
(sizeof(*gradient->pblendcolor) + sizeof(*gradient->pblendpos));
else if (gradient->blendcount > 1 && gradient->blendfac && gradient->blendpos)
*size += sizeof(DWORD) + gradient->blendcount *
(sizeof(*gradient->blendfac) + sizeof(*gradient->blendpos));
break;
}
default:
FIXME("unsupported brush type: %d\n", brush->bt);
return NotImplemented;
@ -1065,6 +1085,67 @@ static void METAFILE_FillBrushData(GDIPCONST GpBrush *brush, EmfPlusBrush *data)
data->BrushData.hatch.BackColor = hatch->backcol;
break;
}
case BrushTypeLinearGradient:
{
BYTE *cursor;
BOOL ignore_xform;
GpLineGradient *gradient = (GpLineGradient*)brush;
data->BrushData.lineargradient.BrushDataFlags = 0;
data->BrushData.lineargradient.WrapMode = gradient->wrap;
data->BrushData.lineargradient.RectF.X = gradient->rect.X;
data->BrushData.lineargradient.RectF.Y = gradient->rect.Y;
data->BrushData.lineargradient.RectF.Width = gradient->rect.Width;
data->BrushData.lineargradient.RectF.Height = gradient->rect.Height;
data->BrushData.lineargradient.StartColor = gradient->startcolor;
data->BrushData.lineargradient.EndColor = gradient->endcolor;
data->BrushData.lineargradient.Reserved1 = gradient->startcolor;
data->BrushData.lineargradient.Reserved2 = gradient->endcolor;
if (gradient->gamma)
data->BrushData.lineargradient.BrushDataFlags |= BrushDataIsGammaCorrected;
cursor = &data->BrushData.lineargradient.OptionalData[0];
GdipIsMatrixIdentity(&gradient->transform, &ignore_xform);
if (!ignore_xform)
{
data->BrushData.lineargradient.BrushDataFlags |= BrushDataTransform;
memcpy(cursor, &gradient->transform, sizeof(gradient->transform));
cursor += sizeof(gradient->transform);
}
if (gradient->pblendcount > 1 && gradient->pblendcolor && gradient->pblendpos)
{
const DWORD count = gradient->pblendcount;
data->BrushData.lineargradient.BrushDataFlags |= BrushDataPresetColors;
memcpy(cursor, &count, sizeof(count));
cursor += sizeof(count);
memcpy(cursor, gradient->pblendpos, count * sizeof(*gradient->pblendpos));
cursor += count * sizeof(*gradient->pblendpos);
memcpy(cursor, gradient->pblendcolor, count * sizeof(*gradient->pblendcolor));
}
else if (gradient->blendcount > 1 && gradient->blendfac && gradient->blendpos)
{
const DWORD count = gradient->blendcount;
data->BrushData.lineargradient.BrushDataFlags |= BrushDataBlendFactorsH;
memcpy(cursor, &count, sizeof(count));
cursor += sizeof(count);
memcpy(cursor, gradient->blendpos, count * sizeof(*gradient->blendpos));
cursor += count * sizeof(*gradient->blendpos);
memcpy(cursor, gradient->blendfac, count * sizeof(*gradient->blendfac));
}
break;
}
default:
FIXME("unsupported brush type: %d\n", brush->bt);
}

View file

@ -3273,14 +3273,14 @@ static void test_fillregion(void)
static const emfplus_record lineargradient_records[] = {
{ EMR_HEADER },
{ EmfPlusRecordTypeHeader },
{ EmfPlusRecordTypeObject, ObjectTypeBrush << 8, 1 },
{ EmfPlusRecordTypeFillRects, 0x4000, 1 },
{ EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 1, 1 },
{ EmfPlusRecordTypeFillRects, 0x4000, 1 },
{ EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 2, 1 },
{ EmfPlusRecordTypeFillRects, 0x4000, 1 },
{ EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 3, 1 },
{ EmfPlusRecordTypeFillRects, 0x4000, 1 },
{ EmfPlusRecordTypeObject, ObjectTypeBrush << 8, 0, 1 },
{ EmfPlusRecordTypeFillRects, 0x4000, 0, 1 },
{ EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 1, 0, 1 },
{ EmfPlusRecordTypeFillRects, 0x4000, 0, 1 },
{ EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 2 },
{ EmfPlusRecordTypeFillRects, 0x4000 },
{ EmfPlusRecordTypeObject, (ObjectTypeBrush << 8) | 3 },
{ EmfPlusRecordTypeFillRects, 0x4000 },
{ EmfPlusRecordTypeEndOfFile },
{ EMR_EOF },
{ 0 }
@ -3342,16 +3342,16 @@ static void test_lineargradient(void)
expect(Ok, stat);
stat = GdipFillRectangles(graphics, vertbrush, &vertrect, 1);
todo_wine expect(Ok, stat);
expect(Ok, stat);
stat = GdipFillRectangles(graphics, horizbrush, &horizrect, 1);
todo_wine expect(Ok, stat);
expect(Ok, stat);
stat = GdipFillRectangles(graphics, blendbrush, &blendrect, 1);
todo_wine expect(Ok, stat);
expect(Ok, stat);
stat = GdipFillRectangles(graphics, presetbrush, &presetrect, 1);
todo_wine expect(Ok, stat);
expect(Ok, stat);
stat = GdipDeleteGraphics(graphics);
graphics = NULL;
@ -3391,7 +3391,7 @@ static void test_lineargradient(void)
/* Verify custom blend gradient fill. */
stat = GdipBitmapGetPixel(bitmap, 10, 50, &color);
expect(Ok, stat);
todo_wine expect(0xffff0000, color);
expect(0xffff0000, color);
stat = GdipBitmapGetPixel(bitmap, 18, 50, &color);
expect(Ok, stat);
@ -3400,11 +3400,11 @@ static void test_lineargradient(void)
/* Verify preset color gradient fill. */
stat = GdipBitmapGetPixel(bitmap, 50, 50, &color);
expect(Ok, stat);
todo_wine expect(0xffff0000, color);
expect(0xffff0000, color);
stat = GdipBitmapGetPixel(bitmap, 50, 60, &color);
expect(Ok, stat);
todo_wine expect(0xff00ff00, color);
expect(0xff00ff00, color);
GdipDeleteBrush(vertbrush);
GdipDeleteBrush(horizbrush);