gdi32: Fix PathToRegion and SelectClipPath behavior with an empty path.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-06-16 00:37:01 +09:00
parent bc44b3f60d
commit 7373a7c71d
2 changed files with 13 additions and 34 deletions

View File

@ -374,9 +374,9 @@ static HRGN PATH_PathToRegion(const struct gdi_path *pPath, INT nPolyFillMode)
INT *pNumPointsInStroke; INT *pNumPointsInStroke;
HRGN hrgn; HRGN hrgn;
if (!(rgn_path = PATH_FlattenPath( pPath ))) return 0; if (!pPath->count) return 0;
/* FIXME: What happens when number of points is zero? */ if (!(rgn_path = PATH_FlattenPath( pPath ))) return 0;
/* First pass: Find out how many strokes there are in the path */ /* First pass: Find out how many strokes there are in the path */
/* FIXME: We could eliminate this with some bookkeeping in GdiPath */ /* FIXME: We could eliminate this with some bookkeeping in GdiPath */
@ -636,30 +636,20 @@ INT WINAPI GetPath(HDC hdc, LPPOINT pPoints, LPBYTE pTypes, INT nSize)
/*********************************************************************** /***********************************************************************
* PathToRegion (GDI32.@) * PathToRegion (GDI32.@)
*
* FIXME
* Check that SetLastError is being called correctly
*
* The documentation does not state this explicitly, but a test under Windows
* shows that the region which is returned should be in device coordinates.
*/ */
HRGN WINAPI PathToRegion(HDC hdc) HRGN WINAPI PathToRegion(HDC hdc)
{ {
HRGN hrgnRval = 0; HRGN hrgnRval = 0;
DC *dc = get_dc_ptr( hdc ); DC *dc = get_dc_ptr( hdc );
/* Get pointer to path */
if(!dc) return 0; if(!dc) return 0;
if (!dc->path) SetLastError(ERROR_CAN_NOT_COMPLETE); if (!dc->path) SetLastError(ERROR_CAN_NOT_COMPLETE);
else else
{ {
if ((hrgnRval = PATH_PathToRegion(dc->path, GetPolyFillMode(hdc)))) hrgnRval = PATH_PathToRegion(dc->path, GetPolyFillMode(hdc));
{ free_gdi_path( dc->path );
/* FIXME: Should we empty the path even if conversion failed? */ dc->path = NULL;
free_gdi_path( dc->path );
dc->path = NULL;
}
} }
release_dc_ptr( dc ); release_dc_ptr( dc );
return hrgnRval; return hrgnRval;
@ -674,6 +664,7 @@ static BOOL PATH_FillPath( HDC hdc, const struct gdi_path *pPath )
HRGN hrgn; HRGN hrgn;
/* Construct a region from the path and fill it */ /* Construct a region from the path and fill it */
if (!pPath->count) return TRUE;
if ((hrgn = PATH_PathToRegion(pPath, GetPolyFillMode(hdc)))) if ((hrgn = PATH_PathToRegion(pPath, GetPolyFillMode(hdc))))
{ {
/* Since PaintRgn interprets the region as being in logical coordinates /* Since PaintRgn interprets the region as being in logical coordinates
@ -752,8 +743,6 @@ BOOL WINAPI FillPath(HDC hdc)
/*********************************************************************** /***********************************************************************
* SelectClipPath (GDI32.@) * SelectClipPath (GDI32.@)
* FIXME
* Check that SetLastError is being called correctly
*/ */
BOOL WINAPI SelectClipPath(HDC hdc, INT iMode) BOOL WINAPI SelectClipPath(HDC hdc, INT iMode)
{ {
@ -2116,24 +2105,14 @@ BOOL nulldrv_CloseFigure( PHYSDEV dev )
BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode ) BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode )
{ {
BOOL ret; BOOL ret = FALSE;
HRGN hrgn; HRGN hrgn = PathToRegion( dev->hdc );
DC *dc = get_nulldrv_dc( dev );
if (!dc->path) if (hrgn)
{ {
SetLastError( ERROR_CAN_NOT_COMPLETE ); ret = ExtSelectClipRgn( dev->hdc, hrgn, mode ) != ERROR;
return FALSE; DeleteObject( hrgn );
} }
if (!(hrgn = PATH_PathToRegion( dc->path, GetPolyFillMode(dev->hdc)))) return FALSE;
ret = ExtSelectClipRgn( dev->hdc, hrgn, mode ) != ERROR;
if (ret)
{
free_gdi_path( dc->path );
dc->path = NULL;
}
/* FIXME: Should this function delete the path even if it failed? */
DeleteObject( hrgn );
return ret; return ret;
} }

View File

@ -266,7 +266,7 @@ static void test_path_state(void)
EndPath( hdc ); EndPath( hdc );
SetLastError( 0xdeadbeef ); SetLastError( 0xdeadbeef );
ret = SelectClipPath( hdc, RGN_OR ); ret = SelectClipPath( hdc, RGN_OR );
todo_wine ok( !ret, "SelectClipPath succeeded on empty path\n" ); ok( !ret, "SelectClipPath succeeded on empty path\n" );
ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" ); ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" );
@ -282,7 +282,7 @@ static void test_path_state(void)
EndPath( hdc ); EndPath( hdc );
SetLastError( 0xdeadbeef ); SetLastError( 0xdeadbeef );
rgn = PathToRegion( hdc ); rgn = PathToRegion( hdc );
todo_wine ok( !rgn, "PathToRegion succeeded on empty path\n" ); ok( !rgn, "PathToRegion succeeded on empty path\n" );
ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() ); ok( GetLastError() == 0xdeadbeef, "wrong error %u\n", GetLastError() );
DeleteObject( rgn ); DeleteObject( rgn );
ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" ); ok( GetPath( hdc, NULL, NULL, 0 ) == -1, "path not deleted\n" );