diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index 2fc4686478c..bda241ed93b 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -429,7 +429,7 @@ @ stdcall GdipIsVisiblePathPointI(ptr long long ptr ptr) @ stdcall GdipIsVisiblePoint(ptr long long ptr) @ stdcall GdipIsVisiblePointI(ptr long long ptr) -@ stub GdipIsVisibleRect +@ stdcall GdipIsVisibleRect(ptr long long long long ptr) @ stdcall GdipIsVisibleRectI(ptr long long long long ptr) @ stdcall GdipIsVisibleRegionPoint(ptr long long ptr ptr) @ stdcall GdipIsVisibleRegionPointI(ptr long long ptr ptr) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 3d35f74883f..52639103ab1 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -3288,6 +3288,50 @@ GpStatus WINGDIPAPI GdipIsVisiblePointI(GpGraphics *graphics, INT x, INT y, BOOL return GdipIsVisiblePoint(graphics, (REAL)x, (REAL)y, result); } +GpStatus WINGDIPAPI GdipIsVisibleRect(GpGraphics *graphics, REAL x, REAL y, REAL width, REAL height, BOOL *result) +{ + GpStatus stat; + GpRegion* rgn; + GpPointF pts[2]; + + TRACE("(%p %.2f %.2f %.2f %.2f %p)\n", graphics, x, y, width, height, result); + + if(!graphics || !result) + return InvalidParameter; + + if(graphics->busy) + return ObjectBusy; + + pts[0].X = x; + pts[0].Y = y; + pts[1].X = x + width; + pts[1].Y = y + height; + + if((stat = GdipTransformPoints(graphics, CoordinateSpaceDevice, + CoordinateSpaceWorld, pts, 2)) != Ok) + return stat; + + pts[1].X -= pts[0].X; + pts[1].Y -= pts[0].Y; + + if((stat = GdipCreateRegion(&rgn)) != Ok) + return stat; + + if((stat = get_visible_clip_region(graphics, rgn)) != Ok) + goto cleanup; + + stat = GdipIsVisibleRegionRect(rgn, pts[0].X, pts[0].Y, pts[1].X, pts[1].Y, graphics, result); + +cleanup: + GdipDeleteRegion(rgn); + return stat; +} + +GpStatus WINGDIPAPI GdipIsVisibleRectI(GpGraphics *graphics, INT x, INT y, INT width, INT height, BOOL *result) +{ + return GdipIsVisibleRect(graphics, (REAL)x, (REAL)y, (REAL)width, (REAL)height, result); +} + GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics, GDIPCONST WCHAR* string, INT length, GDIPCONST GpFont* font, GDIPCONST RectF* layoutRect, GDIPCONST GpStringFormat *stringFormat, @@ -4190,12 +4234,3 @@ GpStatus WINGDIPAPI GdipRecordMetafileI(HDC hdc, EmfType type, GDIPCONST GpRect FIXME("(%p %d %p %d %p %p): stub\n", hdc, type, frameRect, frameUnit, desc, metafile); return NotImplemented; } - -/***************************************************************************** - * GdipIsVisibleRectI [GDIPLUS.@] - */ -GpStatus WINGDIPAPI GdipIsVisibleRectI(GpGraphics *graphics, INT x, INT y, INT width, INT height, BOOL *result) -{ - FIXME("(%p %d %d %d %d %p): stub\n", graphics, x, y, width, height, result); - return NotImplemented; -} diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index f74f7af8aaf..2a03aadb177 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -2107,6 +2107,168 @@ static void test_GdipIsVisiblePoint(void) ReleaseDC(0, hdc); } +static void test_GdipIsVisibleRect(void) +{ + GpStatus status; + GpGraphics *graphics = NULL; + HDC hdc = GetDC(0); + REAL x, y, width, height; + BOOL val; + + ok(hdc != NULL, "Expected HDC to be initialized\n"); + + status = GdipCreateFromHDC(hdc, &graphics); + expect(Ok, status); + ok(graphics != NULL, "Expected graphics to be initialized\n"); + + status = GdipIsVisibleRect(NULL, 0, 0, 0, 0, &val); + expect(InvalidParameter, status); + + status = GdipIsVisibleRect(graphics, 0, 0, 0, 0, NULL); + expect(InvalidParameter, status); + + status = GdipIsVisibleRectI(NULL, 0, 0, 0, 0, &val); + expect(InvalidParameter, status); + + status = GdipIsVisibleRectI(graphics, 0, 0, 0, 0, NULL); + expect(InvalidParameter, status); + + /* entirely within the visible region */ + x = 0; width = 10; + y = 0; height = 10; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + /* partially outside */ + x = -10; width = 20; + y = -10; height = 20; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + /* entirely outside */ + x = -10; width = 5; + y = -10; height = 5; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height); + + status = GdipSetClipRect(graphics, 10, 20, 30, 40, CombineModeReplace); + expect(Ok, status); + + /* entirely within the visible region */ + x = 12; width = 10; + y = 22; height = 10; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + /* partially outside */ + x = 35; width = 10; + y = 55; height = 10; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + /* entirely outside */ + x = 45; width = 5; + y = 65; height = 5; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height); + + /* translate into center of clipping rect */ + GdipTranslateWorldTransform(graphics, 25, 40, MatrixOrderAppend); + + x = 0; width = 10; + y = 0; height = 10; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + x = 25; width = 5; + y = 40; height = 5; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height); + + GdipTranslateWorldTransform(graphics, -25, -40, MatrixOrderAppend); + + /* corners entirely outside, but some intersections */ + x = 0; width = 70; + y = 0; height = 90; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + x = 0; width = 70; + y = 0; height = 30; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + x = 0; width = 30; + y = 0; height = 90; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + /* edge cases */ + x = 0; width = 10; + y = 20; height = 40; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height); + + x = 10; width = 30; + y = 0; height = 20; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height); + + x = 40; width = 10; + y = 20; height = 40; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height); + + x = 10; width = 30; + y = 60; height = 10; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == FALSE, "Expected (%.2f, %.2f, %.2f, %.2f) not to be visible\n", x, y, width, height); + + /* rounding tests */ + x = 0.4; width = 10.4; + y = 20; height = 40; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + x = 10; width = 30; + y = 0.4; height = 20.4; + status = GdipIsVisibleRect(graphics, x, y, width, height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + /* integer version */ + x = 0; width = 30; + y = 0; height = 90; + status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + x = 12; width = 10; + y = 22; height = 10; + status = GdipIsVisibleRectI(graphics, (INT)x, (INT)y, (INT)width, (INT)height, &val); + expect(Ok, status); + ok(val == TRUE, "Expected (%.2f, %.2f, %.2f, %.2f) to be visible\n", x, y, width, height); + + GdipDeleteGraphics(graphics); + ReleaseDC(0, hdc); +} + START_TEST(graphics) { struct GdiplusStartupInput gdiplusStartupInput; @@ -2135,6 +2297,7 @@ START_TEST(graphics) test_GdipDrawString(); test_GdipGetVisibleClipBounds(); test_GdipIsVisiblePoint(); + test_GdipIsVisibleRect(); test_Get_Release_DC(); test_BeginContainer2(); test_transformpoints(); diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index fd8302dc9d0..6bad8bde534 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -232,6 +232,8 @@ GpStatus WINGDIPAPI GdipGetVisibleClipBoundsI(GpGraphics*,GpRect*); GpStatus WINGDIPAPI GdipIsClipEmpty(GpGraphics*, BOOL*); GpStatus WINGDIPAPI GdipIsVisiblePoint(GpGraphics*,REAL,REAL,BOOL*); GpStatus WINGDIPAPI GdipIsVisiblePointI(GpGraphics*,INT,INT,BOOL*); +GpStatus WINGDIPAPI GdipIsVisibleRect(GpGraphics*,REAL,REAL,REAL,REAL,BOOL*); +GpStatus WINGDIPAPI GdipIsVisibleRectI(GpGraphics*,INT,INT,INT,INT,BOOL*); GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics*, GDIPCONST WCHAR*, INT, GDIPCONST GpFont*, GDIPCONST RectF*, GDIPCONST GpStringFormat*, INT, GpRegion**);