[PATCH] gdiplus: Implement transform matrix for line gradient brushes
Andrew Eikum
aeikum at codeweavers.com
Mon Aug 14 11:10:34 CDT 2017
Signed-off-by: Andrew Eikum <aeikum at codeweavers.com>
---
dlls/gdiplus/brush.c | 99 +++++++----
dlls/gdiplus/gdiplus_private.h | 1 +
dlls/gdiplus/graphics.c | 22 +--
dlls/gdiplus/tests/brush.c | 386 ++++++++++++++++++++++++++++++++---------
include/gdiplusflat.h | 1 +
5 files changed, 377 insertions(+), 132 deletions(-)
diff --git a/dlls/gdiplus/brush.c b/dlls/gdiplus/brush.c
index a184276804..90df36b9fc 100644
--- a/dlls/gdiplus/brush.c
+++ b/dlls/gdiplus/brush.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2007 Google (Evan Stade)
+ * Copyright (C) 2003-2004,2007 Novell, Inc. http://www.novell.com (Ravindra (rkumar at novell.com))
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -149,6 +150,8 @@ GpStatus WINGDIPAPI GdipCloneBrush(GpBrush *brush, GpBrush **clone)
return OutOfMemory;
}
+ dest->transform = src->transform;
+
memcpy(dest->blendfac, src->blendfac, count * sizeof(REAL));
memcpy(dest->blendpos, src->blendpos, count * sizeof(REAL));
@@ -259,6 +262,41 @@ GpStatus WINGDIPAPI GdipCreateHatchBrush(HatchStyle hatchstyle, ARGB forecol, AR
return Ok;
}
+static void linegradient_init_transform(GpLineGradient *line)
+{
+ float dx = line->rect.X + (line->rect.Width / 2.f);
+ float dy = line->rect.Y + (line->rect.Height / 2.f);
+ float t, t_cos, t_sin, w_ratio, h_ratio;
+ GpMatrix rot;
+
+ if (line->startpoint.X == line->endpoint.X)
+ t = line->startpoint.Y > line->endpoint.Y ? 3.f * M_PI / 2.f : M_PI / 2.f;
+ else
+ t = atanf((line->endpoint.Y - line->startpoint.Y) / (line->endpoint.X - line->startpoint.X));
+
+ t_cos = cosf(t);
+ t_sin = sinf(t);
+
+ w_ratio = (fabs(t_cos) * line->rect.Width + fabs(t_sin) * line->rect.Height) / line->rect.Width;
+ h_ratio = (fabs(t_sin) * line->rect.Width + fabs(t_cos) * line->rect.Height) / line->rect.Height;
+
+ GdipSetMatrixElements(&line->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
+
+ GdipSetMatrixElements(&rot, t_cos, t_sin, -1.f * t_sin, t_cos, 0, 0);
+
+ /* center about the origin */
+ GdipTranslateMatrix(&line->transform, -dx, -dy, MatrixOrderAppend);
+
+ /* scale to normalize gradient along gradient line (?) */
+ GdipScaleMatrix(&line->transform, w_ratio, h_ratio, MatrixOrderAppend);
+
+ /* rotate so the gradient is horizontal */
+ GdipMultiplyMatrix(&line->transform, &rot, MatrixOrderAppend);
+
+ /* restore original offset in new coords */
+ GdipTranslateMatrix(&line->transform, dx, dy, MatrixOrderAppend);
+}
+
/******************************************************************************
* GdipCreateLineBrush [GDIPLUS.@]
*/
@@ -325,6 +363,8 @@ GpStatus WINGDIPAPI GdipCreateLineBrush(GDIPCONST GpPointF* startpoint,
(*line)->pblendpos = NULL;
(*line)->pblendcount = 0;
+ linegradient_init_transform(*line);
+
TRACE("<-- %p\n", *line);
return Ok;
@@ -497,6 +537,8 @@ GpStatus WINGDIPAPI GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect
(*line)->startpoint.X = rect->X + exofs;
(*line)->startpoint.Y = rect->Y + eyofs;
}
+
+ linegradient_init_transform(*line);
}
return stat;
@@ -2005,78 +2047,73 @@ GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient *brush,
GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient *brush)
{
- static int calls;
-
TRACE("(%p)\n", brush);
- if(!(calls++))
- FIXME("not implemented\n");
+ if(!brush)
+ return InvalidParameter;
- return NotImplemented;
+ return GdipSetMatrixElements(&brush->transform, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
}
GpStatus WINGDIPAPI GdipSetLineTransform(GpLineGradient *brush,
GDIPCONST GpMatrix *matrix)
{
- static int calls;
-
TRACE("(%p,%p)\n", brush, matrix);
- if(!(calls++))
- FIXME("not implemented\n");
+ if(!brush || !matrix)
+ return InvalidParameter;
- return NotImplemented;
+ brush->transform = *matrix;
+
+ return Ok;
}
GpStatus WINGDIPAPI GdipGetLineTransform(GpLineGradient *brush, GpMatrix *matrix)
{
- static int calls;
-
TRACE("(%p,%p)\n", brush, matrix);
- if(!(calls++))
- FIXME("not implemented\n");
+ if(!brush || !matrix)
+ return InvalidParameter;
- return NotImplemented;
+ *matrix = brush->transform;
+
+ return Ok;
}
GpStatus WINGDIPAPI GdipScaleLineTransform(GpLineGradient *brush, REAL sx, REAL sy,
GpMatrixOrder order)
{
- static int calls;
-
TRACE("(%p,%0.2f,%0.2f,%u)\n", brush, sx, sy, order);
- if(!(calls++))
- FIXME("not implemented\n");
+ if(!brush)
+ return InvalidParameter;
- return NotImplemented;
+ return GdipScaleMatrix(&brush->transform, sx, sy, order);
}
GpStatus WINGDIPAPI GdipMultiplyLineTransform(GpLineGradient *brush,
GDIPCONST GpMatrix *matrix, GpMatrixOrder order)
{
- static int calls;
-
TRACE("(%p,%p,%u)\n", brush, matrix, order);
- if(!(calls++))
- FIXME("not implemented\n");
+ if(!brush)
+ return InvalidParameter;
- return NotImplemented;
+ if(!matrix)
+ return Ok;
+
+ return GdipMultiplyMatrix(&brush->transform, matrix, order);
}
-GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient* brush,
+GpStatus WINGDIPAPI GdipTranslateLineTransform(GpLineGradient *brush,
REAL dx, REAL dy, GpMatrixOrder order)
{
- static int calls;
-
TRACE("(%p,%f,%f,%d)\n", brush, dx, dy, order);
- if(!(calls++))
- FIXME("not implemented\n");
+ if(!brush)
+ return InvalidParameter;
- return Ok;
+ return GdipTranslateMatrix(&brush->transform, dx, dy, order);
}
/******************************************************************************
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 33966767cc..e1169c6cdf 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -312,6 +312,7 @@ struct GpLineGradient{
ARGB* pblendcolor; /* preset blend colors */
REAL* pblendpos; /* preset blend positions */
INT pblendcount;
+ GpMatrix transform;
};
struct GpTexture{
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index e45618eefe..3024b4496a 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -547,6 +547,7 @@ static ARGB blend_line_gradient(GpLineGradient* brush, REAL position)
REAL blendfac;
/* clamp to between 0.0 and 1.0, using the wrap mode */
+ position = (position + brush->rect.X) / brush->rect.Width;
if (brush->wrap == WrapModeTile)
{
position = fmodf(position, 1.0f);
@@ -1138,10 +1139,8 @@ static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush,
case BrushTypeLinearGradient:
{
GpLineGradient *fill = (GpLineGradient*)brush;
- GpPointF draw_points[3], line_points[3];
+ GpPointF draw_points[3];
GpStatus stat;
- static const GpRectF box_1 = { 0.0, 0.0, 1.0, 1.0 };
- GpMatrix *world_to_gradient; /* FIXME: Store this in the brush? */
int x, y;
draw_points[0].X = fill_area->X;
@@ -1159,22 +1158,11 @@ static GpStatus brush_fill_pixels(GpGraphics *graphics, GpBrush *brush,
if (stat == Ok)
{
- line_points[0] = fill->startpoint;
- line_points[1] = fill->endpoint;
- line_points[2].X = fill->startpoint.X + (fill->startpoint.Y - fill->endpoint.Y);
- line_points[2].Y = fill->startpoint.Y + (fill->endpoint.X - fill->startpoint.X);
-
- stat = GdipCreateMatrix3(&box_1, line_points, &world_to_gradient);
- }
-
- if (stat == Ok)
- {
- stat = GdipInvertMatrix(world_to_gradient);
+ GpMatrix world_to_gradient = fill->transform;
+ stat = GdipInvertMatrix(&world_to_gradient);
if (stat == Ok)
- stat = GdipTransformMatrixPoints(world_to_gradient, draw_points, 3);
-
- GdipDeleteMatrix(world_to_gradient);
+ stat = GdipTransformMatrixPoints(&world_to_gradient, draw_points, 3);
}
if (stat == Ok)
diff --git a/dlls/gdiplus/tests/brush.c b/dlls/gdiplus/tests/brush.c
index 9fd80d2305..6d35073a67 100644
--- a/dlls/gdiplus/tests/brush.c
+++ b/dlls/gdiplus/tests/brush.c
@@ -27,6 +27,8 @@
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got)
#define expectf(expected, got) ok(fabs(expected - got) < 0.0001, "Expected %.2f, got %.2f\n", expected, got)
+static HWND hwnd;
+
static void test_constructor_destructor(void)
{
GpStatus status;
@@ -174,12 +176,17 @@ static void test_transform(void)
{
GpStatus status;
GpTexture *texture;
+ GpLineGradient *line;
GpGraphics *graphics = NULL;
GpBitmap *bitmap;
HDC hdc = GetDC(0);
GpMatrix *m, *m1;
BOOL res;
+ GpPointF start, end;
+ GpRectF rectf;
+ REAL elements[6];
+ /* GpTexture */
status = GdipCreateMatrix2(2.0, 0.0, 0.0, 0.0, 0.0, 0.0, &m);
expect(Ok, status);
@@ -233,6 +240,216 @@ static void test_transform(void)
expect(Ok, status);
status = GdipDeleteGraphics(graphics);
expect(Ok, status);
+
+
+
+ status = GdipCreateFromHWND(hwnd, &graphics);
+ expect(Ok, status);
+
+ /* GpLineGradient */
+ /* create with vertical gradient line */
+ start.X = start.Y = end.X = 0.0;
+ end.Y = 100.0;
+
+ status = GdipCreateLineBrush(&start, &end, (ARGB)0xffff0000, 0xff00ff00, WrapModeTile, &line);
+ expect(Ok, status);
+
+ status = GdipCreateMatrix2(1.0, 0.0, 0.0, 1.0, 0.0, 0.0, &m);
+ expect(Ok, status);
+
+ /* NULL arguments */
+ status = GdipResetLineTransform(NULL);
+ expect(InvalidParameter, status);
+ status = GdipSetLineTransform(NULL, m);
+ expect(InvalidParameter, status);
+ status = GdipSetLineTransform(line, NULL);
+ expect(InvalidParameter, status);
+ status = GdipGetLineTransform(NULL, m);
+ expect(InvalidParameter, status);
+ status = GdipGetLineTransform(line, NULL);
+ expect(InvalidParameter, status);
+ status = GdipScaleLineTransform(NULL, 1, 1, MatrixOrderPrepend);
+ expect(InvalidParameter, status);
+ status = GdipMultiplyLineTransform(NULL, m, MatrixOrderPrepend);
+ expect(InvalidParameter, status);
+ status = GdipTranslateLineTransform(NULL, 0, 0, MatrixOrderPrepend);
+ expect(InvalidParameter, status);
+
+ /* initial transform */
+ status = GdipGetLineTransform(line, m);
+ expect(Ok, status);
+
+ status = GdipGetMatrixElements(m, elements);
+ expect(Ok, status);
+ expectf(0.0, elements[0]);
+ expectf(1.0, elements[1]);
+ expectf(-1.0, elements[2]);
+ expectf(0.0, elements[3]);
+ expectf(50.0, elements[4]);
+ expectf(50.0, elements[5]);
+
+ status = GdipGetLineRect(line, &rectf);
+ expect(Ok, status);
+ expectf(-50.0, rectf.X);
+ expectf(0.0, rectf.Y);
+ expectf(100.0, rectf.Width);
+ expectf(100.0, rectf.Height);
+
+ status = GdipFillRectangle(graphics, (GpBrush*)line, 0, 0, 200, 200);
+ expect(Ok, status);
+
+ /* manually set transform */
+ GdipSetMatrixElements(m, 2.0, 0.0, 0.0, 4.0, 0.0, 0.0);
+
+ status = GdipSetLineTransform(line, m);
+ expect(Ok, status);
+
+ status = GdipGetLineTransform(line, m);
+ expect(Ok, status);
+
+ status = GdipGetMatrixElements(m, elements);
+ expect(Ok, status);
+ expectf(2.0, elements[0]);
+ expectf(0.0, elements[1]);
+ expectf(0.0, elements[2]);
+ expectf(4.0, elements[3]);
+ expectf(0.0, elements[4]);
+ expectf(0.0, elements[5]);
+
+ status = GdipGetLineRect(line, &rectf);
+ expect(Ok, status);
+ expectf(-50.0, rectf.X);
+ expectf(0.0, rectf.Y);
+ expectf(100.0, rectf.Width);
+ expectf(100.0, rectf.Height);
+
+ status = GdipFillRectangle(graphics, (GpBrush*)line, 200, 0, 200, 200);
+ expect(Ok, status);
+
+ /* scale transform */
+ status = GdipScaleLineTransform(line, 4.0, 0.5, MatrixOrderAppend);
+ expect(Ok, status);
+
+ status = GdipGetLineTransform(line, m);
+ expect(Ok, status);
+
+ status = GdipGetMatrixElements(m, elements);
+ expect(Ok, status);
+ expectf(8.0, elements[0]);
+ expectf(0.0, elements[1]);
+ expectf(0.0, elements[2]);
+ expectf(2.0, elements[3]);
+ expectf(0.0, elements[4]);
+ expectf(0.0, elements[5]);
+
+ status = GdipGetLineRect(line, &rectf);
+ expect(Ok, status);
+ expectf(-50.0, rectf.X);
+ expectf(0.0, rectf.Y);
+ expectf(100.0, rectf.Width);
+ expectf(100.0, rectf.Height);
+
+ status = GdipFillRectangle(graphics, (GpBrush*)line, 400, 0, 200, 200);
+ expect(Ok, status);
+
+ /* translate transform */
+ status = GdipTranslateLineTransform(line, 10.0, -20.0, MatrixOrderAppend);
+ expect(Ok, status);
+
+ status = GdipGetLineTransform(line, m);
+ expect(Ok, status);
+
+ status = GdipGetMatrixElements(m, elements);
+ expect(Ok, status);
+ expectf(8.0, elements[0]);
+ expectf(0.0, elements[1]);
+ expectf(0.0, elements[2]);
+ expectf(2.0, elements[3]);
+ expectf(10.0, elements[4]);
+ expectf(-20.0, elements[5]);
+
+ status = GdipGetLineRect(line, &rectf);
+ expect(Ok, status);
+ expectf(-50.0, rectf.X);
+ expectf(0.0, rectf.Y);
+ expectf(100.0, rectf.Width);
+ expectf(100.0, rectf.Height);
+
+ status = GdipFillRectangle(graphics, (GpBrush*)line, 0, 200, 200, 200);
+ expect(Ok, status);
+
+ /* multiply transform */
+ GdipSetMatrixElements(m, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
+ GdipRotateMatrix(m, 45.0, MatrixOrderAppend);
+ GdipScaleMatrix(m, 0.25, 0.5, MatrixOrderAppend);
+
+ status = GdipMultiplyLineTransform(line, m, MatrixOrderAppend);
+ expect(Ok, status);
+
+ /* NULL transform does nothing */
+ status = GdipMultiplyLineTransform(line, NULL, MatrixOrderAppend);
+ expect(Ok, status);
+
+ status = GdipGetLineTransform(line, m);
+ expect(Ok, status);
+
+ status = GdipGetMatrixElements(m, elements);
+ expect(Ok, status);
+ expectf(1.414214, elements[0]);
+ expectf(2.828427, elements[1]);
+ expectf(-0.353553, elements[2]);
+ expectf(0.707107, elements[3]);
+ expectf(5.303300, elements[4]);
+ expectf(-3.535534, elements[5]);
+
+ status = GdipGetLineRect(line, &rectf);
+ expect(Ok, status);
+ expectf(-50.0, rectf.X);
+ expectf(0.0, rectf.Y);
+ expectf(100.0, rectf.Width);
+ expectf(100.0, rectf.Height);
+
+ status = GdipFillRectangle(graphics, (GpBrush*)line, 200, 200, 200, 200);
+ expect(Ok, status);
+
+ /* reset transform sets to identity */
+ status = GdipResetLineTransform(line);
+ expect(Ok, status);
+
+ status = GdipGetLineTransform(line, m);
+ expect(Ok, status);
+
+ status = GdipGetMatrixElements(m, elements);
+ expect(Ok, status);
+ expectf(1.0, elements[0]);
+ expectf(0.0, elements[1]);
+ expectf(0.0, elements[2]);
+ expectf(1.0, elements[3]);
+ expectf(0.0, elements[4]);
+ expectf(0.0, elements[5]);
+
+ status = GdipGetLineRect(line, &rectf);
+ expect(Ok, status);
+ expectf(-50.0, rectf.X);
+ expectf(0.0, rectf.Y);
+ expectf(100.0, rectf.Width);
+ expectf(100.0, rectf.Height);
+
+ status = GdipFillRectangle(graphics, (GpBrush*)line, 400, 200, 200, 200);
+ expect(Ok, status);
+
+ if(0){
+ /* enable to visually compare with Windows */
+ MSG msg;
+ while(GetMessageW(&msg, hwnd, 0, 0) > 0){
+ TranslateMessage(&msg);
+ DispatchMessageW(&msg);
+ }
+ }
+
+ GdipDeleteBrush((GpBrush*)line);
+ GdipDeleteMatrix(m);
+ GdipDeleteGraphics(graphics);
ReleaseDC(0, hdc);
}
@@ -308,20 +525,18 @@ static void test_gradientgetrect(void)
expectf(99.0, rectf.Width);
expectf(99.0, rectf.Height);
status = GdipGetLineTransform(brush, transform);
- todo_wine expect(Ok, status);
- if (status == Ok)
- {
- status = GdipGetMatrixElements(transform, elements);
- expect(Ok, status);
- expectf(1.0, elements[0]);
- expectf(1.0, elements[1]);
- expectf(-1.0, elements[2]);
- expectf(1.0, elements[3]);
- expectf(50.50, elements[4]);
- expectf(-50.50, elements[5]);
- }
+ expect(Ok, status);
+ status = GdipGetMatrixElements(transform, elements);
+ expect(Ok, status);
+ expectf(1.0, elements[0]);
+ expectf(1.0, elements[1]);
+ expectf(-1.0, elements[2]);
+ expectf(1.0, elements[3]);
+ expectf(50.50, elements[4]);
+ expectf(-50.50, elements[5]);
status = GdipDeleteBrush((GpBrush*)brush);
expect(Ok, status);
+
/* vertical gradient */
pt1.X = pt1.Y = pt2.X = 0.0;
pt2.Y = 10.0;
@@ -335,20 +550,18 @@ static void test_gradientgetrect(void)
expectf(10.0, rectf.Width);
expectf(10.0, rectf.Height);
status = GdipGetLineTransform(brush, transform);
- todo_wine expect(Ok, status);
- if (status == Ok)
- {
- status = GdipGetMatrixElements(transform, elements);
- expect(Ok, status);
- expectf(0.0, elements[0]);
- expectf(1.0, elements[1]);
- expectf(-1.0, elements[2]);
- expectf(0.0, elements[3]);
- expectf(5.0, elements[4]);
- expectf(5.0, elements[5]);
- }
+ expect(Ok, status);
+ status = GdipGetMatrixElements(transform, elements);
+ expect(Ok, status);
+ expectf(0.0, elements[0]);
+ expectf(1.0, elements[1]);
+ expectf(-1.0, elements[2]);
+ expectf(0.0, elements[3]);
+ expectf(5.0, elements[4]);
+ expectf(5.0, elements[5]);
status = GdipDeleteBrush((GpBrush*)brush);
expect(Ok, status);
+
/* horizontal gradient */
pt1.X = pt1.Y = pt2.Y = 0.0;
pt2.X = 10.0;
@@ -362,20 +575,18 @@ static void test_gradientgetrect(void)
expectf(10.0, rectf.Width);
expectf(10.0, rectf.Height);
status = GdipGetLineTransform(brush, transform);
- todo_wine expect(Ok, status);
- if (status == Ok)
- {
- status = GdipGetMatrixElements(transform, elements);
- expect(Ok, status);
- expectf(1.0, elements[0]);
- expectf(0.0, elements[1]);
- expectf(0.0, elements[2]);
- expectf(1.0, elements[3]);
- expectf(0.0, elements[4]);
- expectf(0.0, elements[5]);
- }
+ expect(Ok, status);
+ status = GdipGetMatrixElements(transform, elements);
+ expect(Ok, status);
+ expectf(1.0, elements[0]);
+ expectf(0.0, elements[1]);
+ expectf(0.0, elements[2]);
+ expectf(1.0, elements[3]);
+ expectf(0.0, elements[4]);
+ expectf(0.0, elements[5]);
status = GdipDeleteBrush((GpBrush*)brush);
expect(Ok, status);
+
/* slope = -1 */
pt1.X = pt1.Y = 0.0;
pt2.X = 20.0;
@@ -390,20 +601,18 @@ static void test_gradientgetrect(void)
expectf(20.0, rectf.Width);
expectf(20.0, rectf.Height);
status = GdipGetLineTransform(brush, transform);
- todo_wine expect(Ok, status);
- if (status == Ok)
- {
- status = GdipGetMatrixElements(transform, elements);
- expect(Ok, status);
- expectf(1.0, elements[0]);
- expectf(-1.0, elements[1]);
- expectf(1.0, elements[2]);
- expectf(1.0, elements[3]);
- expectf(10.0, elements[4]);
- expectf(10.0, elements[5]);
- }
+ expect(Ok, status);
+ status = GdipGetMatrixElements(transform, elements);
+ expect(Ok, status);
+ expectf(1.0, elements[0]);
+ expectf(-1.0, elements[1]);
+ expectf(1.0, elements[2]);
+ expectf(1.0, elements[3]);
+ expectf(10.0, elements[4]);
+ expectf(10.0, elements[5]);
status = GdipDeleteBrush((GpBrush*)brush);
expect(Ok, status);
+
/* slope = 1/100 */
pt1.X = pt1.Y = 0.0;
pt2.X = 100.0;
@@ -418,20 +627,18 @@ static void test_gradientgetrect(void)
expectf(100.0, rectf.Width);
expectf(1.0, rectf.Height);
status = GdipGetLineTransform(brush, transform);
- todo_wine expect(Ok, status);
- if (status == Ok)
- {
- status = GdipGetMatrixElements(transform, elements);
- expect(Ok,status);
- expectf(1.0, elements[0]);
- expectf(0.01, elements[1]);
- expectf(-0.02, elements[2]);
- /* expectf(2.0, elements[3]); */
- expectf(0.01, elements[4]);
- /* expectf(-1.0, elements[5]); */
- }
+ expect(Ok, status);
+ status = GdipGetMatrixElements(transform, elements);
+ expect(Ok,status);
+ expectf(1.0, elements[0]);
+ expectf(0.01, elements[1]);
+ expectf(-0.02, elements[2]);
+ /* expectf(2.0, elements[3]); */
+ expectf(0.01, elements[4]);
+ /* expectf(-1.0, elements[5]); */
status = GdipDeleteBrush((GpBrush*)brush);
expect(Ok,status);
+
/* zero height rect */
rectf.X = rectf.Y = 10.0;
rectf.Width = 100.0;
@@ -439,6 +646,7 @@ static void test_gradientgetrect(void)
status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeVertical,
WrapModeTile, &brush);
expect(OutOfMemory, status);
+
/* zero width rect */
rectf.X = rectf.Y = 10.0;
rectf.Width = 0.0;
@@ -446,6 +654,7 @@ static void test_gradientgetrect(void)
status = GdipCreateLineBrushFromRect(&rectf, 0, 0, LinearGradientModeHorizontal,
WrapModeTile, &brush);
expect(OutOfMemory, status);
+
/* from rect with LinearGradientModeHorizontal */
rectf.X = rectf.Y = 10.0;
rectf.Width = rectf.Height = 100.0;
@@ -460,20 +669,18 @@ static void test_gradientgetrect(void)
expectf(100.0, rectf.Width);
expectf(100.0, rectf.Height);
status = GdipGetLineTransform(brush, transform);
- todo_wine expect(Ok, status);
- if (status == Ok)
- {
- status = GdipGetMatrixElements(transform, elements);
- expect(Ok,status);
- expectf(1.0, elements[0]);
- expectf(0.0, elements[1]);
- expectf(0.0, elements[2]);
- expectf(1.0, elements[3]);
- expectf(0.0, elements[4]);
- expectf(0.0, elements[5]);
- }
+ expect(Ok, status);
+ status = GdipGetMatrixElements(transform, elements);
+ expect(Ok,status);
+ expectf(1.0, elements[0]);
+ expectf(0.0, elements[1]);
+ expectf(0.0, elements[2]);
+ expectf(1.0, elements[3]);
+ expectf(0.0, elements[4]);
+ expectf(0.0, elements[5]);
status = GdipDeleteBrush((GpBrush*)brush);
expect(Ok,status);
+
/* passing negative Width/Height to LinearGradientModeHorizontal */
rectf.X = rectf.Y = 10.0;
rectf.Width = rectf.Height = -100.0;
@@ -488,18 +695,15 @@ static void test_gradientgetrect(void)
expectf(-100.0, rectf.Width);
expectf(-100.0, rectf.Height);
status = GdipGetLineTransform(brush, transform);
- todo_wine expect(Ok, status);
- if (status == Ok)
- {
- status = GdipGetMatrixElements(transform, elements);
- expect(Ok,status);
- expectf(1.0, elements[0]);
- expectf(0.0, elements[1]);
- expectf(0.0, elements[2]);
- expectf(1.0, elements[3]);
- expectf(0.0, elements[4]);
- expectf(0.0, elements[5]);
- }
+ expect(Ok, status);
+ status = GdipGetMatrixElements(transform, elements);
+ expect(Ok,status);
+ expectf(1.0, elements[0]);
+ expectf(0.0, elements[1]);
+ expectf(0.0, elements[2]);
+ expectf(1.0, elements[3]);
+ expectf(0.0, elements[4]);
+ expectf(0.0, elements[5]);
status = GdipDeleteBrush((GpBrush*)brush);
expect(Ok,status);
@@ -1275,12 +1479,26 @@ START_TEST(brush)
ULONG_PTR gdiplusToken;
HMODULE hmsvcrt;
int (CDECL * _controlfp_s)(unsigned int *cur, unsigned int newval, unsigned int mask);
+ WNDCLASSA class;
/* Enable all FP exceptions except _EM_INEXACT, which gdi32 can trigger */
hmsvcrt = LoadLibraryA("msvcrt");
_controlfp_s = (void*)GetProcAddress(hmsvcrt, "_controlfp_s");
if (_controlfp_s) _controlfp_s(0, 0, 0x0008001e);
+ memset( &class, 0, sizeof(class) );
+ class.lpszClassName = "gdiplus_test";
+ class.style = CS_HREDRAW | CS_VREDRAW;
+ class.lpfnWndProc = DefWindowProcA;
+ class.hInstance = GetModuleHandleA(0);
+ class.hIcon = LoadIconA(0, (LPCSTR)IDI_APPLICATION);
+ class.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
+ class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ RegisterClassA( &class );
+ hwnd = CreateWindowA( "gdiplus_test", "graphics test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, 0, 0, GetModuleHandleA(0), 0 );
+ ok(hwnd != NULL, "Expected window to be created\n");
+
gdiplusStartupInput.GdiplusVersion = 1;
gdiplusStartupInput.DebugEventCallback = NULL;
gdiplusStartupInput.SuppressBackgroundThread = 0;
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h
index 10d537a017..f2ac91e83d 100644
--- a/include/gdiplusflat.h
+++ b/include/gdiplusflat.h
@@ -495,6 +495,7 @@ GpStatus WINGDIPAPI GdipSetLinePresetBlend(GpLineGradient*,GDIPCONST ARGB*,
GpStatus WINGDIPAPI GdipGetLinePresetBlend(GpLineGradient*,ARGB*,REAL*,INT);
GpStatus WINGDIPAPI GdipGetLinePresetBlendCount(GpLineGradient*,INT*);
GpStatus WINGDIPAPI GdipGetLineTransform(GpLineGradient*,GpMatrix*);
+GpStatus WINGDIPAPI GdipMultiplyLineTransform(GpLineGradient*,GDIPCONST GpMatrix*,GpMatrixOrder);
GpStatus WINGDIPAPI GdipResetLineTransform(GpLineGradient*);
GpStatus WINGDIPAPI GdipRotateLineTransform(GpLineGradient*,REAL,GpMatrixOrder);
GpStatus WINGDIPAPI GdipScaleLineTransform(GpLineGradient*,REAL,REAL,
--
2.14.0
More information about the wine-patches
mailing list