Commit 2201d088 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Only store the path in the DC when it's closed.

Open paths are stored only in the path physdev.
parent a218e068
...@@ -150,6 +150,7 @@ typedef struct tagDC ...@@ -150,6 +150,7 @@ typedef struct tagDC
} DC; } DC;
/* DC flags */ /* DC flags */
#define DC_PATH_OPEN 0x0001 /* DC path is open (only set on saved DCs) */
#define DC_BOUNDS_ENABLE 0x0008 /* Bounding rectangle tracking is enabled */ #define DC_BOUNDS_ENABLE 0x0008 /* Bounding rectangle tracking is enabled */
/* Certain functions will do no further processing if the driver returns this. /* Certain functions will do no further processing if the driver returns this.
......
...@@ -108,11 +108,21 @@ static inline struct path_physdev *get_path_physdev( PHYSDEV dev ) ...@@ -108,11 +108,21 @@ static inline struct path_physdev *get_path_physdev( PHYSDEV dev )
return (struct path_physdev *)dev; return (struct path_physdev *)dev;
} }
static inline void pop_path_driver( DC *dc ) static inline void pop_path_driver( DC *dc, struct path_physdev *physdev )
{ {
PHYSDEV dev = pop_dc_driver( &dc->physDev ); PHYSDEV *dev = &dc->physDev;
assert( dev->funcs == &path_driver ); while (*dev != &physdev->dev) dev = &(*dev)->next;
HeapFree( GetProcessHeap(), 0, dev ); *dev = physdev->dev.next;
HeapFree( GetProcessHeap(), 0, physdev );
}
static inline struct path_physdev *find_path_physdev( DC *dc )
{
PHYSDEV dev;
for (dev = dc->physDev; dev->funcs != &null_driver; dev = dev->next)
if (dev->funcs == &path_driver) return get_path_physdev( dev );
return NULL;
} }
void free_gdi_path( struct gdi_path *path ) void free_gdi_path( struct gdi_path *path )
...@@ -614,44 +624,39 @@ BOOL WINAPI CloseFigure(HDC hdc) ...@@ -614,44 +624,39 @@ BOOL WINAPI CloseFigure(HDC hdc)
/*********************************************************************** /***********************************************************************
* GetPath (GDI32.@) * GetPath (GDI32.@)
*/ */
INT WINAPI GetPath(HDC hdc, LPPOINT pPoints, LPBYTE pTypes, INT WINAPI GetPath(HDC hdc, LPPOINT pPoints, LPBYTE pTypes, INT nSize)
INT nSize)
{ {
INT ret = -1; INT ret = -1;
GdiPath *pPath;
DC *dc = get_dc_ptr( hdc ); DC *dc = get_dc_ptr( hdc );
if(!dc) return -1; if(!dc) return -1;
pPath = dc->path; if (!dc->path)
/* Check that path is closed */
if(!pPath || pPath->state != PATH_Closed)
{ {
SetLastError(ERROR_CAN_NOT_COMPLETE); SetLastError(ERROR_CAN_NOT_COMPLETE);
goto done; goto done;
} }
if(nSize==0) if(nSize==0)
ret = pPath->numEntriesUsed; ret = dc->path->numEntriesUsed;
else if(nSize<pPath->numEntriesUsed) else if(nSize<dc->path->numEntriesUsed)
{ {
SetLastError(ERROR_INVALID_PARAMETER); SetLastError(ERROR_INVALID_PARAMETER);
goto done; goto done;
} }
else else
{ {
memcpy(pPoints, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); memcpy(pPoints, dc->path->pPoints, sizeof(POINT)*dc->path->numEntriesUsed);
memcpy(pTypes, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); memcpy(pTypes, dc->path->pFlags, sizeof(BYTE)*dc->path->numEntriesUsed);
/* Convert the points to logical coordinates */ /* Convert the points to logical coordinates */
if(!DPtoLP(hdc, pPoints, pPath->numEntriesUsed)) if(!DPtoLP(hdc, pPoints, dc->path->numEntriesUsed))
{ {
/* FIXME: Is this the correct value? */ /* FIXME: Is this the correct value? */
SetLastError(ERROR_CAN_NOT_COMPLETE); SetLastError(ERROR_CAN_NOT_COMPLETE);
goto done; goto done;
} }
else ret = pPath->numEntriesUsed; else ret = dc->path->numEntriesUsed;
} }
done: done:
release_dc_ptr( dc ); release_dc_ptr( dc );
...@@ -676,8 +681,7 @@ HRGN WINAPI PathToRegion(HDC hdc) ...@@ -676,8 +681,7 @@ HRGN WINAPI PathToRegion(HDC hdc)
/* Get pointer to path */ /* Get pointer to path */
if(!dc) return 0; if(!dc) return 0;
/* Check that path is closed */ if (!dc->path) SetLastError(ERROR_CAN_NOT_COMPLETE);
if (!dc->path || dc->path->state != PATH_Closed) SetLastError(ERROR_CAN_NOT_COMPLETE);
else else
{ {
if ((hrgnRval = PATH_PathToRegion(dc->path, GetPolyFillMode(hdc)))) if ((hrgnRval = PATH_PathToRegion(dc->path, GetPolyFillMode(hdc))))
...@@ -811,12 +815,12 @@ static BOOL pathdrv_BeginPath( PHYSDEV dev ) ...@@ -811,12 +815,12 @@ static BOOL pathdrv_BeginPath( PHYSDEV dev )
*/ */
static BOOL pathdrv_AbortPath( PHYSDEV dev ) static BOOL pathdrv_AbortPath( PHYSDEV dev )
{ {
struct path_physdev *physdev = get_path_physdev( dev );
DC *dc = get_dc_ptr( dev->hdc ); DC *dc = get_dc_ptr( dev->hdc );
if (!dc) return FALSE; if (!dc) return FALSE;
free_gdi_path( dc->path ); free_gdi_path( physdev->path );
dc->path = NULL; pop_path_driver( dc, physdev );
pop_path_driver( dc );
release_dc_ptr( dc ); release_dc_ptr( dc );
return TRUE; return TRUE;
} }
...@@ -827,11 +831,13 @@ static BOOL pathdrv_AbortPath( PHYSDEV dev ) ...@@ -827,11 +831,13 @@ static BOOL pathdrv_AbortPath( PHYSDEV dev )
*/ */
static BOOL pathdrv_EndPath( PHYSDEV dev ) static BOOL pathdrv_EndPath( PHYSDEV dev )
{ {
struct path_physdev *physdev = get_path_physdev( dev );
DC *dc = get_dc_ptr( dev->hdc ); DC *dc = get_dc_ptr( dev->hdc );
if (!dc) return FALSE; if (!dc) return FALSE;
dc->path = physdev->path;
dc->path->state = PATH_Closed; dc->path->state = PATH_Closed;
pop_path_driver( dc ); pop_path_driver( dc, physdev );
release_dc_ptr( dc ); release_dc_ptr( dc );
return TRUE; return TRUE;
} }
...@@ -866,30 +872,43 @@ static BOOL pathdrv_DeleteDC( PHYSDEV dev ) ...@@ -866,30 +872,43 @@ static BOOL pathdrv_DeleteDC( PHYSDEV dev )
BOOL PATH_SavePath( DC *dst, DC *src ) BOOL PATH_SavePath( DC *dst, DC *src )
{ {
struct path_physdev *physdev;
if (src->path) if (src->path)
{ {
if (!(dst->path = copy_gdi_path( src->path ))) return FALSE; if (!(dst->path = copy_gdi_path( src->path ))) return FALSE;
} }
else if ((physdev = find_path_physdev( src )))
{
if (!(dst->path = copy_gdi_path( physdev->path ))) return FALSE;
dst->flags |= DC_PATH_OPEN;
}
else dst->path = NULL; else dst->path = NULL;
return TRUE; return TRUE;
} }
BOOL PATH_RestorePath( DC *dst, DC *src ) BOOL PATH_RestorePath( DC *dst, DC *src )
{ {
struct path_physdev *physdev; struct path_physdev *physdev = find_path_physdev( dst );
if (src->path && src->path->state == PATH_Open) if (src->path && (src->flags & DC_PATH_OPEN))
{ {
if (!dst->path || dst->path->state != PATH_Open) if (!physdev)
{ {
if (!path_driver.pCreateDC( &dst->physDev, NULL, NULL, NULL, NULL )) return FALSE; if (!path_driver.pCreateDC( &dst->physDev, NULL, NULL, NULL, NULL )) return FALSE;
physdev = get_path_physdev( dst->physDev );
} }
physdev = get_path_physdev( dst->physDev ); else free_gdi_path( physdev->path );
assert( physdev->dev.funcs == &path_driver );
physdev->path = src->path; physdev->path = src->path;
src->flags &= ~DC_PATH_OPEN;
src->path = NULL;
}
else if (physdev)
{
free_gdi_path( physdev->path );
pop_path_driver( dst, physdev );
} }
else if (dst->path && dst->path->state == PATH_Open) pop_path_driver( dst );
if (dst->path) free_gdi_path( dst->path ); if (dst->path) free_gdi_path( dst->path );
dst->path = src->path; dst->path = src->path;
src->path = NULL; src->path = NULL;
...@@ -2106,7 +2125,7 @@ BOOL nulldrv_BeginPath( PHYSDEV dev ) ...@@ -2106,7 +2125,7 @@ BOOL nulldrv_BeginPath( PHYSDEV dev )
physdev = get_path_physdev( dc->physDev ); physdev = get_path_physdev( dc->physDev );
physdev->path = path; physdev->path = path;
if (dc->path) free_gdi_path( dc->path ); if (dc->path) free_gdi_path( dc->path );
dc->path = path; dc->path = NULL;
return TRUE; return TRUE;
} }
...@@ -2137,7 +2156,7 @@ BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode ) ...@@ -2137,7 +2156,7 @@ BOOL nulldrv_SelectClipPath( PHYSDEV dev, INT mode )
HRGN hrgn; HRGN hrgn;
DC *dc = get_nulldrv_dc( dev ); DC *dc = get_nulldrv_dc( dev );
if (!dc->path || dc->path->state != PATH_Closed) if (!dc->path)
{ {
SetLastError( ERROR_CAN_NOT_COMPLETE ); SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE; return FALSE;
...@@ -2158,7 +2177,7 @@ BOOL nulldrv_FillPath( PHYSDEV dev ) ...@@ -2158,7 +2177,7 @@ BOOL nulldrv_FillPath( PHYSDEV dev )
{ {
DC *dc = get_nulldrv_dc( dev ); DC *dc = get_nulldrv_dc( dev );
if (!dc->path || dc->path->state != PATH_Closed) if (!dc->path)
{ {
SetLastError( ERROR_CAN_NOT_COMPLETE ); SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE; return FALSE;
...@@ -2174,7 +2193,7 @@ BOOL nulldrv_StrokeAndFillPath( PHYSDEV dev ) ...@@ -2174,7 +2193,7 @@ BOOL nulldrv_StrokeAndFillPath( PHYSDEV dev )
{ {
DC *dc = get_nulldrv_dc( dev ); DC *dc = get_nulldrv_dc( dev );
if (!dc->path || dc->path->state != PATH_Closed) if (!dc->path)
{ {
SetLastError( ERROR_CAN_NOT_COMPLETE ); SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE; return FALSE;
...@@ -2190,7 +2209,7 @@ BOOL nulldrv_StrokePath( PHYSDEV dev ) ...@@ -2190,7 +2209,7 @@ BOOL nulldrv_StrokePath( PHYSDEV dev )
{ {
DC *dc = get_nulldrv_dc( dev ); DC *dc = get_nulldrv_dc( dev );
if (!dc->path || dc->path->state != PATH_Closed) if (!dc->path)
{ {
SetLastError( ERROR_CAN_NOT_COMPLETE ); SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE; return FALSE;
...@@ -2206,7 +2225,7 @@ BOOL nulldrv_FlattenPath( PHYSDEV dev ) ...@@ -2206,7 +2225,7 @@ BOOL nulldrv_FlattenPath( PHYSDEV dev )
DC *dc = get_nulldrv_dc( dev ); DC *dc = get_nulldrv_dc( dev );
struct gdi_path *path; struct gdi_path *path;
if (!dc->path || dc->path->state != PATH_Closed) if (!dc->path)
{ {
SetLastError( ERROR_CAN_NOT_COMPLETE ); SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE; return FALSE;
...@@ -2222,7 +2241,7 @@ BOOL nulldrv_WidenPath( PHYSDEV dev ) ...@@ -2222,7 +2241,7 @@ BOOL nulldrv_WidenPath( PHYSDEV dev )
DC *dc = get_nulldrv_dc( dev ); DC *dc = get_nulldrv_dc( dev );
struct gdi_path *path; struct gdi_path *path;
if (!dc->path || dc->path->state != PATH_Closed) if (!dc->path)
{ {
SetLastError( ERROR_CAN_NOT_COMPLETE ); SetLastError( ERROR_CAN_NOT_COMPLETE );
return FALSE; return FALSE;
......
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