Commit 08aa0cac authored by Vincent Povirk's avatar Vincent Povirk Committed by Alexandre Julliard

gdiplus: Implement GdipRegionGetHRgn for paths.

parent 4f8751a5
...@@ -54,6 +54,8 @@ extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj, ...@@ -54,6 +54,8 @@ extern void calc_curve_bezier_endp(REAL xend, REAL yend, REAL xadj, REAL yadj,
extern BOOL lengthen_path(GpPath *path, INT len); extern BOOL lengthen_path(GpPath *path, INT len);
extern GpStatus trace_path(GpGraphics *graphics, GpPath *path);
typedef struct region_element region_element; typedef struct region_element region_element;
extern inline void delete_element(region_element *element); extern inline void delete_element(region_element *element);
......
...@@ -715,6 +715,17 @@ end: ...@@ -715,6 +715,17 @@ end:
return status; return status;
} }
GpStatus trace_path(GpGraphics *graphics, GpPath *path)
{
GpStatus result;
BeginPath(graphics->hdc);
result = draw_poly(graphics, NULL, path->pathdata.Points,
path->pathdata.Types, path->pathdata.Count, FALSE);
EndPath(graphics->hdc);
return result;
}
GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics) GpStatus WINGDIPAPI GdipCreateFromHDC(HDC hdc, GpGraphics **graphics)
{ {
TRACE("(%p, %p)\n", hdc, graphics); TRACE("(%p, %p)\n", hdc, graphics);
......
...@@ -768,6 +768,49 @@ GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed) ...@@ -768,6 +768,49 @@ GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
return Ok; return Ok;
} }
static GpStatus get_path_hrgn(GpPath *path, GpGraphics *graphics, HRGN *hrgn)
{
HDC new_hdc=NULL;
GpStatus stat;
INT save_state;
if (!graphics)
{
new_hdc = GetDC(0);
if (!new_hdc)
return OutOfMemory;
stat = GdipCreateFromHDC(new_hdc, &graphics);
if (stat != Ok)
{
ReleaseDC(0, new_hdc);
return stat;
}
}
save_state = SaveDC(graphics->hdc);
EndPath(graphics->hdc);
SetPolyFillMode(graphics->hdc, (path->fill == FillModeAlternate ? ALTERNATE
: WINDING));
stat = trace_path(graphics, path);
if (stat == Ok)
{
*hrgn = PathToRegion(graphics->hdc);
stat = *hrgn ? Ok : OutOfMemory;
}
RestoreDC(graphics->hdc, save_state);
if (new_hdc)
{
ReleaseDC(0, new_hdc);
GdipDeleteGraphics(graphics);
}
return stat;
}
static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *graphics, HRGN *hrgn) static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *graphics, HRGN *hrgn)
{ {
switch (element->type) switch (element->type)
...@@ -778,6 +821,8 @@ static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *grap ...@@ -778,6 +821,8 @@ static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *grap
case RegionDataEmptyRect: case RegionDataEmptyRect:
*hrgn = CreateRectRgn(0, 0, 0, 0); *hrgn = CreateRectRgn(0, 0, 0, 0);
return *hrgn ? Ok : OutOfMemory; return *hrgn ? Ok : OutOfMemory;
case RegionDataPath:
return get_path_hrgn(element->elementdata.pathdata.path, graphics, hrgn);
default: default:
FIXME("GdipGetRegionHRgn unimplemented for region type=%x\n", element->type); FIXME("GdipGetRegionHRgn unimplemented for region type=%x\n", element->type);
*hrgn = NULL; *hrgn = NULL;
......
...@@ -797,11 +797,14 @@ todo_wine{ ...@@ -797,11 +797,14 @@ todo_wine{
static void test_gethrgn(void) static void test_gethrgn(void)
{ {
GpStatus status; GpStatus status;
GpRegion *region; GpRegion *region, *region2;
GpPath *path;
GpGraphics *graphics; GpGraphics *graphics;
HRGN hrgn; HRGN hrgn;
HDC hdc=GetDC(0); HDC hdc=GetDC(0);
static const RECT empty_rect = {0,0,0,0}; static const RECT empty_rect = {0,0,0,0};
static const RECT test_rect = {10, 11, 20, 21};
static const RECT scaled_rect = {20, 22, 40, 42};
status = GdipCreateFromHDC(hdc, &graphics); status = GdipCreateFromHDC(hdc, &graphics);
ok(status == Ok, "status %08x\n", status); ok(status == Ok, "status %08x\n", status);
...@@ -831,8 +834,32 @@ static void test_gethrgn(void) ...@@ -831,8 +834,32 @@ static void test_gethrgn(void)
verify_region(hrgn, &empty_rect); verify_region(hrgn, &empty_rect);
DeleteObject(hrgn); DeleteObject(hrgn);
status = GdipCreatePath(FillModeAlternate, &path);
ok(status == Ok, "status %08x\n", status);
status = GdipAddPathRectangle(path, 10.0, 11.0, 10.0, 10.0);
ok(status == Ok, "status %08x\n", status);
status = GdipCreateRegionPath(path, &region2);
ok(status == Ok, "status %08x\n", status);
status = GdipGetRegionHRgn(region2, NULL, &hrgn);
ok(status == Ok, "status %08x\n", status);
verify_region(hrgn, &test_rect);
DeleteObject(hrgn);
/* resulting HRGN is in device coordinates */
status = GdipScaleWorldTransform(graphics, 2.0, 2.0, MatrixOrderPrepend);
ok(status == Ok, "status %08x\n", status);
status = GdipGetRegionHRgn(region2, graphics, &hrgn);
ok(status == Ok, "status %08x\n", status);
verify_region(hrgn, &scaled_rect);
DeleteObject(hrgn);
status = GdipDeletePath(path);
ok(status == Ok, "status %08x\n", status);
status = GdipDeleteRegion(region); status = GdipDeleteRegion(region);
ok(status == Ok, "status %08x\n", status); ok(status == Ok, "status %08x\n", status);
status = GdipDeleteRegion(region2);
ok(status == Ok, "status %08x\n", status);
status = GdipDeleteGraphics(graphics); status = GdipDeleteGraphics(graphics);
ok(status == Ok, "status %08x\n", status); ok(status == Ok, "status %08x\n", status);
ReleaseDC(0, hdc); ReleaseDC(0, hdc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment