Vincent Povirk : gdiplus: Implement GdipGetRegionHRgn for combined regions.
Alexandre Julliard
julliard at winehq.org
Thu Dec 4 09:02:26 CST 2008
Module: wine
Branch: master
Commit: 28a71b3da3ab98f039cccaf13ea835ca3376eac1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=28a71b3da3ab98f039cccaf13ea835ca3376eac1
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Mon Nov 24 17:20:00 2008 -0600
gdiplus: Implement GdipGetRegionHRgn for combined regions.
---
dlls/gdiplus/region.c | 92 +++++++++++++++++++++++++++++++++++++++++++
dlls/gdiplus/tests/region.c | 49 +++++++++++++++++++++++
2 files changed, 141 insertions(+), 0 deletions(-)
diff --git a/dlls/gdiplus/region.c b/dlls/gdiplus/region.c
index 509c7ce..d28292c 100644
--- a/dlls/gdiplus/region.c
+++ b/dlls/gdiplus/region.c
@@ -841,6 +841,98 @@ static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *grap
return stat;
}
+ case CombineModeIntersect:
+ case CombineModeUnion:
+ case CombineModeXor:
+ case CombineModeExclude:
+ case CombineModeComplement:
+ {
+ HRGN left, right;
+ GpStatus stat;
+ int ret;
+
+ stat = get_region_hrgn(element->elementdata.combine.left, graphics, &left);
+ if (stat != Ok)
+ {
+ *hrgn = NULL;
+ return stat;
+ }
+
+ if (left == NULL)
+ {
+ /* existing region is infinite */
+ switch (element->type)
+ {
+ case CombineModeIntersect:
+ return get_region_hrgn(element->elementdata.combine.right, graphics, hrgn);
+ case CombineModeXor: case CombineModeExclude:
+ FIXME("cannot exclude from an infinite region\n");
+ /* fall-through */
+ case CombineModeUnion: case CombineModeComplement:
+ *hrgn = NULL;
+ return Ok;
+ }
+ }
+
+ stat = get_region_hrgn(element->elementdata.combine.right, graphics, &right);
+ if (stat != Ok)
+ {
+ DeleteObject(left);
+ *hrgn = NULL;
+ return stat;
+ }
+
+ if (right == NULL)
+ {
+ /* new region is infinite */
+ switch (element->type)
+ {
+ case CombineModeIntersect:
+ *hrgn = left;
+ return Ok;
+ case CombineModeXor: case CombineModeComplement:
+ FIXME("cannot exclude from an infinite region\n");
+ /* fall-through */
+ case CombineModeUnion: case CombineModeExclude:
+ DeleteObject(left);
+ *hrgn = NULL;
+ return Ok;
+ }
+ }
+
+ switch (element->type)
+ {
+ case CombineModeIntersect:
+ ret = CombineRgn(left, left, right, RGN_AND);
+ break;
+ case CombineModeUnion:
+ ret = CombineRgn(left, left, right, RGN_OR);
+ break;
+ case CombineModeXor:
+ ret = CombineRgn(left, left, right, RGN_XOR);
+ break;
+ case CombineModeExclude:
+ ret = CombineRgn(left, left, right, RGN_DIFF);
+ break;
+ case CombineModeComplement:
+ ret = CombineRgn(left, right, left, RGN_DIFF);
+ break;
+ default:
+ ret = ERROR;
+ }
+
+ DeleteObject(right);
+
+ if (ret == ERROR)
+ {
+ DeleteObject(left);
+ *hrgn = NULL;
+ return GenericError;
+ }
+
+ *hrgn = left;
+ return Ok;
+ }
default:
FIXME("GdipGetRegionHRgn unimplemented for region type=%x\n", element->type);
*hrgn = NULL;
diff --git a/dlls/gdiplus/tests/region.c b/dlls/gdiplus/tests/region.c
index 34024be..15363f2 100644
--- a/dlls/gdiplus/tests/region.c
+++ b/dlls/gdiplus/tests/region.c
@@ -806,6 +806,10 @@ static void test_gethrgn(void)
static const RECT test_rect = {10, 11, 20, 21};
static const GpRectF test_rectF = {10.0, 11.0, 10.0, 10.0};
static const RECT scaled_rect = {20, 22, 40, 42};
+ static const RECT test_rect2 = {10, 21, 20, 31};
+ static const GpRectF test_rect2F = {10.0, 21.0, 10.0, 10.0};
+ static const RECT test_rect3 = {10, 11, 20, 31};
+ static const GpRectF test_rect3F = {10.0, 11.0, 10.0, 20.0};
status = GdipCreateFromHDC(hdc, &graphics);
ok(status == Ok, "status %08x\n", status);
@@ -867,6 +871,51 @@ static void test_gethrgn(void)
verify_region(hrgn, &scaled_rect);
DeleteObject(hrgn);
+ status = GdipSetInfinite(region);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipCombineRegionRect(region, &test_rectF, CombineModeIntersect);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipGetRegionHRgn(region, NULL, &hrgn);
+ ok(status == Ok, "status %08x\n", status);
+ verify_region(hrgn, &test_rect);
+ DeleteObject(hrgn);
+
+ status = GdipCombineRegionRect(region, &test_rectF, CombineModeReplace);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipCombineRegionRect(region, &test_rect2F, CombineModeUnion);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipGetRegionHRgn(region, NULL, &hrgn);
+ ok(status == Ok, "status %08x\n", status);
+ verify_region(hrgn, &test_rect3);
+ DeleteObject(hrgn);
+
+ status = GdipCombineRegionRect(region, &test_rect3F, CombineModeReplace);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipCombineRegionRect(region, &test_rect2F, CombineModeXor);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipGetRegionHRgn(region, NULL, &hrgn);
+ ok(status == Ok, "status %08x\n", status);
+ verify_region(hrgn, &test_rect);
+ DeleteObject(hrgn);
+
+ status = GdipCombineRegionRect(region, &test_rect3F, CombineModeReplace);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipCombineRegionRect(region, &test_rectF, CombineModeExclude);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipGetRegionHRgn(region, NULL, &hrgn);
+ ok(status == Ok, "status %08x\n", status);
+ verify_region(hrgn, &test_rect2);
+ DeleteObject(hrgn);
+
+ status = GdipCombineRegionRect(region, &test_rectF, CombineModeReplace);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipCombineRegionRect(region, &test_rect3F, CombineModeComplement);
+ ok(status == Ok, "status %08x\n", status);
+ status = GdipGetRegionHRgn(region, NULL, &hrgn);
+ ok(status == Ok, "status %08x\n", status);
+ verify_region(hrgn, &test_rect2);
+ DeleteObject(hrgn);
+
status = GdipDeletePath(path);
ok(status == Ok, "status %08x\n", status);
status = GdipDeleteRegion(region);
More information about the wine-cvs
mailing list