/***************************************************************************** * GdipCreateRegionRectI [GDIPLUS.@] */ GpStatus WINGDIPAPI GdipCreateRegionRectI(GDIPCONST GpRect *rect, GpRegion **region) { GpRectF rectf; TRACE("%p, %p\n", rect, region); rectf.X = (REAL)rect->X; rectf.Y = (REAL)rect->Y; rectf.Width = (REAL)rect->Width; rectf.Height = (REAL)rect->Height; return GdipCreateRegionRect(&rectf, region); }
/***************************************************************************** * GdipCombineRegionRect [GDIPLUS.@] */ GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect, CombineMode mode) { GpRegion *rect_region; region_element *left, *right = NULL; GpStatus stat; TRACE("%p %p %d\n", region, rect, mode); if (!(region && rect)) return InvalidParameter; stat = GdipCreateRegionRect(rect, &rect_region); if (stat != Ok) return stat; /* simply replace region data */ if(mode == CombineModeReplace){ delete_element(®ion->node); memcpy(region, rect_region, sizeof(GpRegion)); GdipFree(rect_region); return Ok; } left = GdipAlloc(sizeof(region_element)); if (!left) goto out; memcpy(left, ®ion->node, sizeof(region_element)); stat = clone_element(&rect_region->node, &right); if (stat != Ok) goto out; fuse_region(region, left, right, mode); GdipDeleteRegion(rect_region); return Ok; out: GdipFree(left); GdipDeleteRegion(rect_region); return stat; }
/***************************************************************************** * GdipCombineRegionRect [GDIPLUS.@] */ GpStatus WINGDIPAPI GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect, CombineMode mode) { GpRegion *rect_region; region_element *left, *right = NULL; GpStatus stat; TRACE("%p %s %d\n", region, debugstr_rectf(rect), mode); if (!(region && rect)) return InvalidParameter; stat = GdipCreateRegionRect(rect, &rect_region); if (stat != Ok) return stat; /* simply replace region data */ if(mode == CombineModeReplace){ delete_element(®ion->node); memcpy(region, rect_region, sizeof(GpRegion)); heap_free(rect_region); return Ok; } left = heap_alloc_zero(sizeof(region_element)); if (left) { memcpy(left, ®ion->node, sizeof(region_element)); stat = clone_element(&rect_region->node, &right); if (stat == Ok) { fuse_region(region, left, right, mode); GdipDeleteRegion(rect_region); return Ok; } } else stat = OutOfMemory; heap_free(left); GdipDeleteRegion(rect_region); return stat; }
static void test_combinereplace(void) { GpStatus status; GpRegion *region, *region2; GpPath *path; GpRectF rectf; UINT needed; DWORD buf[50]; rectf.X = rectf.Y = 0.0; rectf.Width = rectf.Height = 100.0; status = GdipCreateRegionRect(&rectf, ®ion); expect(Ok, status); /* replace with the same rectangle */ status = GdipCombineRegionRect(region, &rectf,CombineModeReplace); expect(Ok, status); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); expect(36, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); expect(36, needed); expect_dword(buf, 28); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); expect_dword(buf + 3, 0); expect_dword(buf + 4, RGNDATA_RECT); /* replace with path */ status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); status = GdipAddPathEllipse(path, 0.0, 0.0, 100.0, 250.0); expect(Ok, status); status = GdipCombineRegionPath(region, path, CombineModeReplace); expect(Ok, status); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); expect(156, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); expect(156, needed); expect_dword(buf, 148); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); expect_dword(buf + 3, 0); expect_dword(buf + 4, RGNDATA_PATH); GdipDeletePath(path); /* replace with infinite rect */ status = GdipCreateRegion(®ion2); expect(Ok, status); status = GdipCombineRegionRegion(region, region2, CombineModeReplace); expect(Ok, status); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); expect(20, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); expect(20, needed); expect_dword(buf, 12); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); expect_dword(buf + 3, 0); expect_dword(buf + 4, RGNDATA_INFINITE_RECT); GdipDeleteRegion(region2); /* more complex case : replace with a combined region */ status = GdipCreateRegionRect(&rectf, ®ion2); expect(Ok, status); status = GdipCreatePath(FillModeAlternate, &path); expect(Ok, status); status = GdipAddPathEllipse(path, 0.0, 0.0, 100.0, 250.0); expect(Ok, status); status = GdipCombineRegionPath(region2, path, CombineModeUnion); expect(Ok, status); GdipDeletePath(path); status = GdipCombineRegionRegion(region, region2, CombineModeReplace); expect(Ok, status); GdipDeleteRegion(region2); status = GdipGetRegionDataSize(region, &needed); expect(Ok, status); expect(180, needed); status = GdipGetRegionData(region, (BYTE*)buf, sizeof(buf), &needed); expect(Ok, status); expect(180, needed); expect_dword(buf, 172); trace("buf[1] = %08x\n", buf[1]); expect_magic((DWORD*)(buf + 2)); expect_dword(buf + 3, 2); expect_dword(buf + 4, CombineModeUnion); GdipDeleteRegion(region); }