gdiplus: Implement GdipRegionGetHRgn for paths.

This commit is contained in:
Vincent Povirk 2008-11-24 15:01:47 -06:00 committed by Alexandre Julliard
parent 4f8751a5db
commit 08aa0cac74
4 changed files with 86 additions and 1 deletions

View File

@ -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 GpStatus trace_path(GpGraphics *graphics, GpPath *path);
typedef struct region_element region_element;
extern inline void delete_element(region_element *element);

View File

@ -715,6 +715,17 @@ end:
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)
{
TRACE("(%p, %p)\n", hdc, graphics);

View File

@ -768,6 +768,49 @@ GpStatus WINGDIPAPI GdipGetRegionDataSize(GpRegion *region, UINT *needed)
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)
{
switch (element->type)
@ -778,6 +821,8 @@ static GpStatus get_region_hrgn(struct region_element *element, GpGraphics *grap
case RegionDataEmptyRect:
*hrgn = CreateRectRgn(0, 0, 0, 0);
return *hrgn ? Ok : OutOfMemory;
case RegionDataPath:
return get_path_hrgn(element->elementdata.pathdata.path, graphics, hrgn);
default:
FIXME("GdipGetRegionHRgn unimplemented for region type=%x\n", element->type);
*hrgn = NULL;

View File

@ -797,11 +797,14 @@ todo_wine{
static void test_gethrgn(void)
{
GpStatus status;
GpRegion *region;
GpRegion *region, *region2;
GpPath *path;
GpGraphics *graphics;
HRGN hrgn;
HDC hdc=GetDC(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);
ok(status == Ok, "status %08x\n", status);
@ -831,8 +834,32 @@ static void test_gethrgn(void)
verify_region(hrgn, &empty_rect);
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);
ok(status == Ok, "status %08x\n", status);
status = GdipDeleteRegion(region2);
ok(status == Ok, "status %08x\n", status);
status = GdipDeleteGraphics(graphics);
ok(status == Ok, "status %08x\n", status);
ReleaseDC(0, hdc);