From 8ac9f950224cf45c51b338a57d4720a8ca110537 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 23 Mar 2009 16:34:12 -0500 Subject: [PATCH] gdiplus: implement GdipTransformPoints --- dlls/gdiplus/graphics.c | 41 +++++++++++++++++- dlls/gdiplus/tests/graphics.c | 94 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 126 insertions(+), 9 deletions(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 5e5883f..b827faa 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3592,15 +3592,52 @@ GpStatus WINGDIPAPI GdipGetClip(GpGraphics *graphics, GpRegion *region) GpStatus WINGDIPAPI GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace dst_space, GpCoordinateSpace src_space, GpPointF *points, INT count) { + GpMatrix *matrix; + GpStatus stat; + REAL unitscale; + if(!graphics || !points || count <= 0) return InvalidParameter; if(graphics->busy) return ObjectBusy; - FIXME("(%p, %d, %d, %p, %d): stub\n", graphics, dst_space, src_space, points, count); + TRACE("(%p, %d, %d, %p, %d)\n", graphics, dst_space, src_space, points, count); - return NotImplemented; + stat = GdipCreateMatrix(&matrix); + if (stat == Ok) + { + unitscale = convert_unit(graphics->hdc, graphics->unit); + + if(graphics->unit != UnitDisplay) + unitscale *= graphics->scale; + + if (src_space == CoordinateSpaceWorld && dst_space != CoordinateSpaceWorld) + GdipMultiplyMatrix(matrix, graphics->worldtrans, MatrixOrderAppend); + if (src_space != CoordinateSpaceDevice && dst_space == CoordinateSpaceDevice) + GdipScaleMatrix(matrix, unitscale, unitscale, MatrixOrderAppend); + + if (src_space == CoordinateSpaceDevice && dst_space != CoordinateSpaceDevice) + GdipScaleMatrix(matrix, 1.0/unitscale, 1.0/unitscale, MatrixOrderAppend); + if (src_space != CoordinateSpaceWorld && dst_space == CoordinateSpaceWorld) + { + GpMatrix *inverted_transform; + stat = GdipCloneMatrix(graphics->worldtrans, &inverted_transform); + if (stat == Ok) + { + GdipInvertMatrix(inverted_transform); + GdipMultiplyMatrix(matrix, inverted_transform, MatrixOrderAppend); + GdipDeleteMatrix(inverted_transform); + } + } + + if (stat == Ok) + stat = GdipTransformMatrixPoints(matrix, points, count); + + GdipDeleteMatrix(matrix); + } + + return stat; } GpStatus WINGDIPAPI GdipTransformPointsI(GpGraphics *graphics, GpCoordinateSpace dst_space, diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index 7199151..510a148 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -22,8 +22,10 @@ #include "gdiplus.h" #include "wingdi.h" #include "wine/test.h" +#include #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) #define TABLE_LEN (23) static void test_constructor_destructor(void) @@ -767,17 +769,11 @@ static void test_transformpoints(void) GpStatus status; GpGraphics *graphics = NULL; HDC hdc = GetDC(0); - GpPointF ptf[5]; - INT i; + GpPointF ptf[2]; status = GdipCreateFromHDC(hdc, &graphics); expect(Ok, status); - for(i = 0; i < 5; i++){ - ptf[i].X = 200.0 + i * 50.0 * (i % 2); - ptf[i].Y = 200.0 + i * 50.0 * !(i % 2); - } - /* NULL arguments */ status = GdipTransformPoints(NULL, CoordinateSpacePage, CoordinateSpaceWorld, NULL, 0); expect(InvalidParameter, status); @@ -788,6 +784,90 @@ static void test_transformpoints(void) status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, -1); expect(InvalidParameter, status); + ptf[0].X = 1.0; + ptf[0].Y = 0.0; + ptf[1].X = 0.0; + ptf[1].Y = 1.0; + status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2); + expect(Ok, status); + expectf(1.0, ptf[0].X); + expectf(0.0, ptf[0].Y); + expectf(0.0, ptf[1].X); + expectf(1.0, ptf[1].Y); + + status = GdipTranslateWorldTransform(graphics, 5.0, 5.0, MatrixOrderAppend); + expect(Ok, status); + status = GdipSetPageUnit(graphics, UnitPixel); + expect(Ok, status); + status = GdipSetPageScale(graphics, 3.0); + expect(Ok, status); + + ptf[0].X = 1.0; + ptf[0].Y = 0.0; + ptf[1].X = 0.0; + ptf[1].Y = 1.0; + status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpaceWorld, ptf, 2); + expect(Ok, status); + expectf(18.0, ptf[0].X); + expectf(15.0, ptf[0].Y); + expectf(15.0, ptf[1].X); + expectf(18.0, ptf[1].Y); + + ptf[0].X = 1.0; + ptf[0].Y = 0.0; + ptf[1].X = 0.0; + ptf[1].Y = 1.0; + status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceWorld, ptf, 2); + expect(Ok, status); + expectf(6.0, ptf[0].X); + expectf(5.0, ptf[0].Y); + expectf(5.0, ptf[1].X); + expectf(6.0, ptf[1].Y); + + ptf[0].X = 1.0; + ptf[0].Y = 0.0; + ptf[1].X = 0.0; + ptf[1].Y = 1.0; + status = GdipTransformPoints(graphics, CoordinateSpaceDevice, CoordinateSpacePage, ptf, 2); + expect(Ok, status); + expectf(3.0, ptf[0].X); + expectf(0.0, ptf[0].Y); + expectf(0.0, ptf[1].X); + expectf(3.0, ptf[1].Y); + + ptf[0].X = 18.0; + ptf[0].Y = 15.0; + ptf[1].X = 15.0; + ptf[1].Y = 18.0; + status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpaceDevice, ptf, 2); + expect(Ok, status); + expectf(1.0, ptf[0].X); + expectf(0.0, ptf[0].Y); + expectf(0.0, ptf[1].X); + expectf(1.0, ptf[1].Y); + + ptf[0].X = 6.0; + ptf[0].Y = 5.0; + ptf[1].X = 5.0; + ptf[1].Y = 6.0; + status = GdipTransformPoints(graphics, CoordinateSpaceWorld, CoordinateSpacePage, ptf, 2); + expect(Ok, status); + expectf(1.0, ptf[0].X); + expectf(0.0, ptf[0].Y); + expectf(0.0, ptf[1].X); + expectf(1.0, ptf[1].Y); + + ptf[0].X = 3.0; + ptf[0].Y = 0.0; + ptf[1].X = 0.0; + ptf[1].Y = 3.0; + status = GdipTransformPoints(graphics, CoordinateSpacePage, CoordinateSpaceDevice, ptf, 2); + expect(Ok, status); + expectf(1.0, ptf[0].X); + expectf(0.0, ptf[0].Y); + expectf(0.0, ptf[1].X); + expectf(1.0, ptf[1].Y); + GdipDeleteGraphics(graphics); ReleaseDC(0, hdc); } -- 1.5.4.3