-- v4: gdiplus: Fix matrix transformations for GdipGetPathWorldBounds
From: Bartosz Kosiorek gang65@poczta.onet.pl
--- dlls/gdiplus/tests/graphicspath.c | 78 ++++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 7 deletions(-)
diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index 81b4b40eed4..ed85b3445e8 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -24,7 +24,7 @@ #include <math.h>
#define expect(expected, got) ok(got == expected, "Expected %.8x, got %.8x\n", expected, got) -#define expectf(expected, got) ok(fabs(expected - got) < 2.0, "Expected %.2f, got %.2f\n", expected, got) +#define expectf(expected, got) ok(fabs(expected - got) < 0.1, "Expected %.2f, got %.2f\n", expected, got) #define POINT_TYPE_MAX_LEN (75)
static void stringify_point_type(PathPointType type, char * name) @@ -596,18 +596,82 @@ static void test_worldbounds(void) expectf(0.0, bounds.Width); expectf(0.0, bounds.Height);
+ /* GetPathWorldBounds with pen */ + GdipCreatePath(FillModeAlternate, &path); + GdipAddPathLine2(path, &(line2_points[0]), 2); + status = GdipGetPathWorldBounds(path, &bounds, NULL, pen); + expect(Ok, status); + GdipDeletePath(path); + + expectf(156.0, bounds.X); + expectf(156.0, bounds.Y); + expectf(138.0, bounds.Width); + expectf(88.0, bounds.Height); + + /* GetPathWorldBounds with matrix */ + GdipCreatePath(FillModeAlternate, &path); + GdipAddPathLine2(path, &(line2_points[0]), 2); + status = GdipGetPathWorldBounds(path, &bounds, matrix, NULL); + expect(Ok, status); + GdipDeletePath(path); + + expectf(510.4, bounds.X); + expectf(250.2, bounds.Y); + expectf(75.0, bounds.Width); + expectf(0.0, bounds.Height); + + /* GetPathWorldBounds with pen and matrix */ GdipCreatePath(FillModeAlternate, &path); GdipAddPathLine2(path, &(line2_points[0]), 2); status = GdipGetPathWorldBounds(path, &bounds, matrix, pen); expect(Ok, status); GdipDeletePath(path);
- todo_wine{ - expectf(427.9, bounds.X); - expectf(167.7, bounds.Y); - expectf(239.9, bounds.Width); - expectf(164.9, bounds.Height); - } + todo_wine expectf(427.9, bounds.X); + todo_wine expectf(167.7, bounds.Y); + todo_wine expectf(239.9, bounds.Width); + todo_wine expectf(164.9, bounds.Height); + + /* GetPathWorldBounds with pen and matrix without Cap */ + GdipCreatePath(FillModeAlternate, &path); + GdipAddPathLine2(path, &(line2_points[0]), 2); + GdipSetPenEndCap(pen, LineCapFlat); + status = GdipGetPathWorldBounds(path, &bounds, matrix, pen); + expect(Ok, status); + GdipDeletePath(path); + + todo_wine expectf(471.17, bounds.X); + todo_wine expectf(210.97, bounds.Y); + todo_wine expectf(153.47, bounds.Width); + todo_wine expectf(78.47, bounds.Height); + + /* GetPathWorldBounds with pen and scaled matrix without Cap */ + GdipCreatePath(FillModeAlternate, &path); + GdipAddPathLine2(path, &(line2_points[0]), 2); + GdipSetMatrixElements(matrix, 4.0, 0.0, 0.0, 2.0, 0.0, 0.0); + GdipSetPenEndCap(pen, LineCapFlat); + status = GdipGetPathWorldBounds(path, &bounds, matrix, pen); + expect(Ok, status); + GdipDeletePath(path); + + todo_wine expectf(720.0, bounds.X); + todo_wine expectf(320.0, bounds.Y); + todo_wine expectf(360.0, bounds.Width); + todo_wine expectf(160.0, bounds.Height); + + /* GetPathWorldBounds with pen and singular matrix without Cap */ + GdipCreatePath(FillModeAlternate, &path); + GdipAddPathLine2(path, &(line2_points[0]), 2); + GdipSetMatrixElements(matrix, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0); + GdipSetPenEndCap(pen, LineCapFlat); + status = GdipGetPathWorldBounds(path, &bounds, matrix, pen); + expect(Ok, status); + GdipDeletePath(path); + + todo_wine expectf(180.0, bounds.X); + todo_wine expectf(180.0, bounds.Y); + todo_wine expectf(90.0, bounds.Width); + todo_wine expectf(40.0, bounds.Height);
GdipDeleteMatrix(matrix); GdipCreateMatrix2(0.9, -0.5, -0.5, -1.2, 10.4, 10.2, &matrix);
From: Bartosz Kosiorek gang65@poczta.onet.pl
--- dlls/gdiplus/graphicspath.c | 23 +++++++++------------- dlls/gdiplus/tests/graphicspath.c | 32 +++++++++++++++---------------- 2 files changed, 25 insertions(+), 30 deletions(-)
diff --git a/dlls/gdiplus/graphicspath.c b/dlls/gdiplus/graphicspath.c index cbf8e74340b..e30ee307dbf 100644 --- a/dlls/gdiplus/graphicspath.c +++ b/dlls/gdiplus/graphicspath.c @@ -1614,7 +1614,7 @@ GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath* path, GpRectF* bounds, { GpPointF * points, temp_pts[4]; INT count, i; - REAL path_width = 1.0, width, height, temp, low_x, low_y, high_x, high_y; + REAL path_width = 1.0, low_x, low_y, high_x, high_y;
TRACE("(%p, %p, %s, %p)\n", path, bounds, debugstr_matrix(matrix), pen);
@@ -1641,10 +1641,6 @@ GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath* path, GpRectF* bounds, high_y = max(high_y, points[i].Y); }
- width = high_x - low_x; - height = high_y - low_y; - - /* This looks unusual but it's the only way I can imitate windows. */ if(matrix){ temp_pts[0].X = low_x; temp_pts[0].Y = low_y; @@ -1656,17 +1652,16 @@ GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath* path, GpRectF* bounds, temp_pts[3].Y = low_y;
GdipTransformMatrixPoints((GpMatrix*)matrix, temp_pts, 4); - low_x = temp_pts[0].X; - low_y = temp_pts[0].Y; + low_x = high_x = temp_pts[0].X; + low_y = high_y = temp_pts[0].Y;
for(i = 1; i < 4; i++){ low_x = min(low_x, temp_pts[i].X); low_y = min(low_y, temp_pts[i].Y); + high_x = max(high_x, temp_pts[i].X); + high_y = max(high_y, temp_pts[i].Y); }
- temp = width; - width = height * fabs(matrix->matrix[2]) + width * fabs(matrix->matrix[0]); - height = height * fabs(matrix->matrix[3]) + temp * fabs(matrix->matrix[1]); }
if(pen){ @@ -1680,14 +1675,14 @@ GpStatus WINGDIPAPI GdipGetPathWorldBounds(GpPath* path, GpRectF* bounds,
low_x -= path_width; low_y -= path_width; - width += 2.0 * path_width; - height += 2.0 * path_width; + high_x += path_width; + high_y += path_width; }
bounds->X = low_x; bounds->Y = low_y; - bounds->Width = width; - bounds->Height = height; + bounds->Width = high_x - low_x; + bounds->Height = high_y - low_y;
return Ok; } diff --git a/dlls/gdiplus/tests/graphicspath.c b/dlls/gdiplus/tests/graphicspath.c index ed85b3445e8..da79d083b5c 100644 --- a/dlls/gdiplus/tests/graphicspath.c +++ b/dlls/gdiplus/tests/graphicspath.c @@ -627,10 +627,10 @@ static void test_worldbounds(void) expect(Ok, status); GdipDeletePath(path);
- todo_wine expectf(427.9, bounds.X); - todo_wine expectf(167.7, bounds.Y); - todo_wine expectf(239.9, bounds.Width); - todo_wine expectf(164.9, bounds.Height); + expectf(427.9, bounds.X); + expectf(167.7, bounds.Y); + expectf(239.9, bounds.Width); + expectf(164.9, bounds.Height);
/* GetPathWorldBounds with pen and matrix without Cap */ GdipCreatePath(FillModeAlternate, &path); @@ -640,10 +640,10 @@ static void test_worldbounds(void) expect(Ok, status); GdipDeletePath(path);
- todo_wine expectf(471.17, bounds.X); - todo_wine expectf(210.97, bounds.Y); - todo_wine expectf(153.47, bounds.Width); - todo_wine expectf(78.47, bounds.Height); + expectf(471.17, bounds.X); + expectf(210.97, bounds.Y); + expectf(153.47, bounds.Width); + expectf(78.47, bounds.Height);
/* GetPathWorldBounds with pen and scaled matrix without Cap */ GdipCreatePath(FillModeAlternate, &path); @@ -654,10 +654,10 @@ static void test_worldbounds(void) expect(Ok, status); GdipDeletePath(path);
- todo_wine expectf(720.0, bounds.X); - todo_wine expectf(320.0, bounds.Y); - todo_wine expectf(360.0, bounds.Width); - todo_wine expectf(160.0, bounds.Height); + expectf(720.0, bounds.X); + expectf(320.0, bounds.Y); + expectf(360.0, bounds.Width); + expectf(160.0, bounds.Height);
/* GetPathWorldBounds with pen and singular matrix without Cap */ GdipCreatePath(FillModeAlternate, &path); @@ -668,10 +668,10 @@ static void test_worldbounds(void) expect(Ok, status); GdipDeletePath(path);
- todo_wine expectf(180.0, bounds.X); - todo_wine expectf(180.0, bounds.Y); - todo_wine expectf(90.0, bounds.Width); - todo_wine expectf(40.0, bounds.Height); + expectf(180.0, bounds.X); + expectf(180.0, bounds.Y); + expectf(90.0, bounds.Width); + expectf(40.0, bounds.Height);
GdipDeleteMatrix(matrix); GdipCreateMatrix2(0.9, -0.5, -0.5, -1.2, 10.4, 10.2, &matrix);