[PATCH 2/4] gdiplus: Add LinearGradient brush object serialization.
Shawn M. Chapla
schapla at codeweavers.com
Wed Jul 22 22:08:10 CDT 2020
Signed-off-by: Shawn M. Chapla <schapla at codeweavers.com>
---
dlls/gdiplus/metafile.c | 81 +++++++++++++++++++++++++++++++++++
dlls/gdiplus/tests/metafile.c | 30 ++++++-------
2 files changed, 96 insertions(+), 15 deletions(-)
diff --git a/dlls/gdiplus/metafile.c b/dlls/gdiplus/metafile.c
index 1d7c0fe3062..ff21b8ed242 100644
--- a/dlls/gdiplus/metafile.c
+++ b/dlls/gdiplus/metafile.c
@@ -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);
}
diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c
index bba44d15dae..29113fc3a05 100644
--- a/dlls/gdiplus/tests/metafile.c
+++ b/dlls/gdiplus/tests/metafile.c
@@ -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);
--
2.28.0.rc1
More information about the wine-devel
mailing list