forked from Mirrors/wine-wine
gdi32: Store a pointer to the path in the DC and make the path structure opaque.
parent
ddc9860a42
commit
a214a3c3da
|
@ -110,6 +110,7 @@ DC *alloc_dc_ptr( WORD magic )
|
||||||
dc->hDevice = 0;
|
dc->hDevice = 0;
|
||||||
dc->hPalette = GetStockObject( DEFAULT_PALETTE );
|
dc->hPalette = GetStockObject( DEFAULT_PALETTE );
|
||||||
dc->gdiFont = 0;
|
dc->gdiFont = 0;
|
||||||
|
dc->path = NULL;
|
||||||
dc->font_code_page = CP_ACP;
|
dc->font_code_page = CP_ACP;
|
||||||
dc->ROPmode = R2_COPYPEN;
|
dc->ROPmode = R2_COPYPEN;
|
||||||
dc->polyFillMode = ALTERNATE;
|
dc->polyFillMode = ALTERNATE;
|
||||||
|
@ -146,7 +147,6 @@ DC *alloc_dc_ptr( WORD magic )
|
||||||
dc->BoundsRect.top = 0;
|
dc->BoundsRect.top = 0;
|
||||||
dc->BoundsRect.right = 0;
|
dc->BoundsRect.right = 0;
|
||||||
dc->BoundsRect.bottom = 0;
|
dc->BoundsRect.bottom = 0;
|
||||||
PATH_InitGdiPath(&dc->path);
|
|
||||||
|
|
||||||
if (!(dc->hSelf = alloc_gdi_handle( &dc->header, magic, &dc_funcs )))
|
if (!(dc->hSelf = alloc_gdi_handle( &dc->header, magic, &dc_funcs )))
|
||||||
{
|
{
|
||||||
|
@ -174,7 +174,7 @@ static void free_dc_state( DC *dc )
|
||||||
if (dc->hMetaRgn) DeleteObject( dc->hMetaRgn );
|
if (dc->hMetaRgn) DeleteObject( dc->hMetaRgn );
|
||||||
if (dc->hMetaClipRgn) DeleteObject( dc->hMetaClipRgn );
|
if (dc->hMetaClipRgn) DeleteObject( dc->hMetaClipRgn );
|
||||||
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
||||||
PATH_DestroyGdiPath( &dc->path );
|
if (dc->path) free_gdi_path( dc->path );
|
||||||
HeapFree( GetProcessHeap(), 0, dc );
|
HeapFree( GetProcessHeap(), 0, dc );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,27 +72,6 @@ typedef struct tagGDIOBJHDR
|
||||||
struct hdc_list *hdcs;
|
struct hdc_list *hdcs;
|
||||||
} GDIOBJHDR;
|
} GDIOBJHDR;
|
||||||
|
|
||||||
/* It should not be necessary to access the contents of the GdiPath
|
|
||||||
* structure directly; if you find that the exported functions don't
|
|
||||||
* allow you to do what you want, then please place a new exported
|
|
||||||
* function that does this job in path.c.
|
|
||||||
*/
|
|
||||||
typedef enum tagGdiPathState
|
|
||||||
{
|
|
||||||
PATH_Null,
|
|
||||||
PATH_Open,
|
|
||||||
PATH_Closed
|
|
||||||
} GdiPathState;
|
|
||||||
|
|
||||||
typedef struct gdi_path
|
|
||||||
{
|
|
||||||
GdiPathState state;
|
|
||||||
POINT *pPoints;
|
|
||||||
BYTE *pFlags;
|
|
||||||
int numEntriesUsed, numEntriesAllocated;
|
|
||||||
BOOL newStroke;
|
|
||||||
} GdiPath;
|
|
||||||
|
|
||||||
typedef struct tagGdiFont GdiFont;
|
typedef struct tagGdiFont GdiFont;
|
||||||
|
|
||||||
typedef struct tagDC
|
typedef struct tagDC
|
||||||
|
@ -137,7 +116,7 @@ typedef struct tagDC
|
||||||
HPALETTE hPalette;
|
HPALETTE hPalette;
|
||||||
|
|
||||||
GdiFont *gdiFont;
|
GdiFont *gdiFont;
|
||||||
GdiPath path;
|
struct gdi_path *path;
|
||||||
|
|
||||||
UINT font_code_page;
|
UINT font_code_page;
|
||||||
WORD ROPmode;
|
WORD ROPmode;
|
||||||
|
@ -320,8 +299,7 @@ extern METAHEADER *MF_CreateMetaHeaderDisk(METAHEADER *mr, LPCVOID filename, BOO
|
||||||
|
|
||||||
/* path.c */
|
/* path.c */
|
||||||
|
|
||||||
extern void PATH_InitGdiPath(GdiPath *pPath) DECLSPEC_HIDDEN;
|
extern void free_gdi_path( struct gdi_path *path ) DECLSPEC_HIDDEN;
|
||||||
extern void PATH_DestroyGdiPath(GdiPath *pPath) DECLSPEC_HIDDEN;
|
|
||||||
extern BOOL PATH_SavePath( DC *dst, DC *src ) DECLSPEC_HIDDEN;
|
extern BOOL PATH_SavePath( DC *dst, DC *src ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL PATH_RestorePath( DC *dst, DC *src ) DECLSPEC_HIDDEN;
|
extern BOOL PATH_RestorePath( DC *dst, DC *src ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -81,11 +81,26 @@ typedef struct tagFLOAT_POINT
|
||||||
double x, y;
|
double x, y;
|
||||||
} FLOAT_POINT;
|
} FLOAT_POINT;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PATH_Null,
|
||||||
|
PATH_Open,
|
||||||
|
PATH_Closed
|
||||||
|
} GdiPathState;
|
||||||
|
|
||||||
|
typedef struct gdi_path
|
||||||
|
{
|
||||||
|
GdiPathState state;
|
||||||
|
POINT *pPoints;
|
||||||
|
BYTE *pFlags;
|
||||||
|
int numEntriesUsed, numEntriesAllocated;
|
||||||
|
BOOL newStroke;
|
||||||
|
} GdiPath;
|
||||||
|
|
||||||
struct path_physdev
|
struct path_physdev
|
||||||
{
|
{
|
||||||
struct gdi_physdev dev;
|
struct gdi_physdev dev;
|
||||||
GdiPath *path;
|
struct gdi_path *path;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct path_physdev *get_path_physdev( PHYSDEV dev )
|
static inline struct path_physdev *get_path_physdev( PHYSDEV dev )
|
||||||
|
@ -100,7 +115,7 @@ static inline void pop_path_driver( DC *dc )
|
||||||
HeapFree( GetProcessHeap(), 0, dev );
|
HeapFree( GetProcessHeap(), 0, dev );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_gdi_path( struct gdi_path *path )
|
void free_gdi_path( struct gdi_path *path )
|
||||||
{
|
{
|
||||||
HeapFree( GetProcessHeap(), 0, path->pPoints );
|
HeapFree( GetProcessHeap(), 0, path->pPoints );
|
||||||
HeapFree( GetProcessHeap(), 0, path->pFlags );
|
HeapFree( GetProcessHeap(), 0, path->pFlags );
|
||||||
|
@ -131,6 +146,31 @@ static struct gdi_path *alloc_gdi_path(void)
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct gdi_path *copy_gdi_path( const struct gdi_path *src_path )
|
||||||
|
{
|
||||||
|
struct gdi_path *path = HeapAlloc( GetProcessHeap(), 0, sizeof(*path) );
|
||||||
|
|
||||||
|
if (!path)
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
path->state = src_path->state;
|
||||||
|
path->numEntriesUsed = path->numEntriesAllocated = src_path->numEntriesUsed;
|
||||||
|
path->newStroke = src_path->newStroke;
|
||||||
|
path->pPoints = HeapAlloc( GetProcessHeap(), 0, path->numEntriesUsed * sizeof(*path->pPoints) );
|
||||||
|
path->pFlags = HeapAlloc( GetProcessHeap(), 0, path->numEntriesUsed * sizeof(*path->pFlags) );
|
||||||
|
if (!path->pPoints || !path->pFlags)
|
||||||
|
{
|
||||||
|
free_gdi_path( path );
|
||||||
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memcpy( path->pPoints, src_path->pPoints, path->numEntriesUsed * sizeof(*path->pPoints) );
|
||||||
|
memcpy( path->pFlags, src_path->pFlags, path->numEntriesUsed * sizeof(*path->pFlags) );
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
/* Performs a world-to-viewport transformation on the specified point (which
|
/* Performs a world-to-viewport transformation on the specified point (which
|
||||||
* is in floating point format).
|
* is in floating point format).
|
||||||
*/
|
*/
|
||||||
|
@ -156,16 +196,6 @@ static inline INT int_from_fixed(FIXED f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* PATH_EmptyPath
|
|
||||||
*
|
|
||||||
* Removes all entries from the path and sets the path state to PATH_Null.
|
|
||||||
*/
|
|
||||||
static void PATH_EmptyPath(GdiPath *pPath)
|
|
||||||
{
|
|
||||||
pPath->state=PATH_Null;
|
|
||||||
pPath->numEntriesUsed=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PATH_ReserveEntries
|
/* PATH_ReserveEntries
|
||||||
*
|
*
|
||||||
* Ensures that at least "numEntries" entries (for points and flags) have
|
* Ensures that at least "numEntries" entries (for points and flags) have
|
||||||
|
@ -262,35 +292,6 @@ static BOOL start_new_stroke( struct path_physdev *physdev )
|
||||||
return add_log_points( physdev, &pos, 1, PT_MOVETO ) != NULL;
|
return add_log_points( physdev, &pos, 1, PT_MOVETO ) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PATH_AssignGdiPath
|
|
||||||
*
|
|
||||||
* Copies the GdiPath structure "pPathSrc" to "pPathDest". A deep copy is
|
|
||||||
* performed, i.e. the contents of the pPoints and pFlags arrays are copied,
|
|
||||||
* not just the pointers. Since this means that the arrays in pPathDest may
|
|
||||||
* need to be resized, pPathDest should have been initialized using
|
|
||||||
* PATH_InitGdiPath (in C++, this function would be an assignment operator,
|
|
||||||
* not a copy constructor).
|
|
||||||
* Returns TRUE if successful, else FALSE.
|
|
||||||
*/
|
|
||||||
static BOOL PATH_AssignGdiPath(GdiPath *pPathDest, const GdiPath *pPathSrc)
|
|
||||||
{
|
|
||||||
/* Make sure destination arrays are big enough */
|
|
||||||
if(!PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Perform the copy operation */
|
|
||||||
memcpy(pPathDest->pPoints, pPathSrc->pPoints,
|
|
||||||
sizeof(POINT)*pPathSrc->numEntriesUsed);
|
|
||||||
memcpy(pPathDest->pFlags, pPathSrc->pFlags,
|
|
||||||
sizeof(BYTE)*pPathSrc->numEntriesUsed);
|
|
||||||
|
|
||||||
pPathDest->state=pPathSrc->state;
|
|
||||||
pPathDest->numEntriesUsed=pPathSrc->numEntriesUsed;
|
|
||||||
pPathDest->newStroke=pPathSrc->newStroke;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PATH_CheckCorners
|
/* PATH_CheckCorners
|
||||||
*
|
*
|
||||||
* Helper function for RoundRect() and Rectangle()
|
* Helper function for RoundRect() and Rectangle()
|
||||||
|
@ -622,10 +623,10 @@ INT WINAPI GetPath(HDC hdc, LPPOINT pPoints, LPBYTE pTypes,
|
||||||
|
|
||||||
if(!dc) return -1;
|
if(!dc) return -1;
|
||||||
|
|
||||||
pPath = &dc->path;
|
pPath = dc->path;
|
||||||
|
|
||||||
/* Check that path is closed */
|
/* Check that path is closed */
|
||||||
if(pPath->state!=PATH_Closed)
|
if(!pPath || pPath->state != PATH_Closed)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_CAN_NOT_COMPLETE);
|
SetLastError(ERROR_CAN_NOT_COMPLETE);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -669,22 +670,22 @@ INT WINAPI GetPath(HDC hdc, LPPOINT pPoints, LPBYTE pTypes,
|
||||||
*/
|
*/
|
||||||
HRGN WINAPI PathToRegion(HDC hdc)
|
HRGN WINAPI PathToRegion(HDC hdc)
|
||||||
{
|
{
|
||||||
GdiPath *pPath;
|
|
||||||
HRGN hrgnRval = 0;
|
HRGN hrgnRval = 0;
|
||||||
DC *dc = get_dc_ptr( hdc );
|
DC *dc = get_dc_ptr( hdc );
|
||||||
|
|
||||||
/* Get pointer to path */
|
/* Get pointer to path */
|
||||||
if(!dc) return 0;
|
if(!dc) return 0;
|
||||||
|
|
||||||
pPath = &dc->path;
|
|
||||||
|
|
||||||
/* Check that path is closed */
|
/* Check that path is closed */
|
||||||
if(pPath->state!=PATH_Closed) SetLastError(ERROR_CAN_NOT_COMPLETE);
|
if (!dc->path || dc->path->state != PATH_Closed) SetLastError(ERROR_CAN_NOT_COMPLETE);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* FIXME: Should we empty the path even if conversion failed? */
|
if ((hrgnRval = PATH_PathToRegion(dc->path, GetPolyFillMode(hdc))))
|
||||||
hrgnRval = PATH_PathToRegion(pPath, GetPolyFillMode(hdc));
|
{
|
||||||
if (hrgnRval) PATH_EmptyPath(pPath);
|
/* FIXME: Should we empty the path even if conversion failed? */
|
||||||
|
free_gdi_path( dc->path );
|
||||||
|
dc->path = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
return hrgnRval;
|
return hrgnRval;
|
||||||
|
@ -813,7 +814,8 @@ static BOOL pathdrv_AbortPath( PHYSDEV dev )
|
||||||
DC *dc = get_dc_ptr( dev->hdc );
|
DC *dc = get_dc_ptr( dev->hdc );
|
||||||
|
|
||||||
if (!dc) return FALSE;
|
if (!dc) return FALSE;
|
||||||
PATH_EmptyPath( &dc->path );
|
free_gdi_path( dc->path );
|
||||||
|
dc->path = NULL;
|
||||||
pop_path_driver( dc );
|
pop_path_driver( dc );
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -828,7 +830,7 @@ static BOOL pathdrv_EndPath( 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.state = PATH_Closed;
|
dc->path->state = PATH_Closed;
|
||||||
pop_path_driver( dc );
|
pop_path_driver( dc );
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -846,7 +848,6 @@ static BOOL pathdrv_CreateDC( PHYSDEV *dev, LPCWSTR driver, LPCWSTR device,
|
||||||
|
|
||||||
if (!physdev) return FALSE;
|
if (!physdev) return FALSE;
|
||||||
dc = get_dc_ptr( (*dev)->hdc );
|
dc = get_dc_ptr( (*dev)->hdc );
|
||||||
physdev->path = &dc->path;
|
|
||||||
push_dc_driver( dev, &physdev->dev, &path_driver );
|
push_dc_driver( dev, &physdev->dev, &path_driver );
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -863,56 +864,36 @@ static BOOL pathdrv_DeleteDC( PHYSDEV dev )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* PATH_InitGdiPath
|
|
||||||
*
|
|
||||||
* Initializes the GdiPath structure.
|
|
||||||
*/
|
|
||||||
void PATH_InitGdiPath(GdiPath *pPath)
|
|
||||||
{
|
|
||||||
assert(pPath!=NULL);
|
|
||||||
|
|
||||||
pPath->state=PATH_Null;
|
|
||||||
pPath->pPoints=NULL;
|
|
||||||
pPath->pFlags=NULL;
|
|
||||||
pPath->numEntriesUsed=0;
|
|
||||||
pPath->numEntriesAllocated=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PATH_DestroyGdiPath
|
|
||||||
*
|
|
||||||
* Destroys a GdiPath structure (frees the memory in the arrays).
|
|
||||||
*/
|
|
||||||
void PATH_DestroyGdiPath(GdiPath *pPath)
|
|
||||||
{
|
|
||||||
assert(pPath!=NULL);
|
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, pPath->pPoints );
|
|
||||||
HeapFree( GetProcessHeap(), 0, pPath->pFlags );
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL PATH_SavePath( DC *dst, DC *src )
|
BOOL PATH_SavePath( DC *dst, DC *src )
|
||||||
{
|
{
|
||||||
PATH_InitGdiPath( &dst->path );
|
if (src->path)
|
||||||
return PATH_AssignGdiPath( &dst->path, &src->path );
|
{
|
||||||
|
if (!(dst->path = copy_gdi_path( src->path ))) return FALSE;
|
||||||
|
}
|
||||||
|
else dst->path = NULL;
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL PATH_RestorePath( DC *dst, DC *src )
|
BOOL PATH_RestorePath( DC *dst, DC *src )
|
||||||
{
|
{
|
||||||
BOOL ret;
|
struct path_physdev *physdev;
|
||||||
|
|
||||||
if (src->path.state == PATH_Open && dst->path.state != PATH_Open)
|
if (src->path && src->path->state == PATH_Open)
|
||||||
{
|
{
|
||||||
if (!path_driver.pCreateDC( &dst->physDev, NULL, NULL, NULL, NULL )) return FALSE;
|
if (!dst->path || dst->path->state != PATH_Open)
|
||||||
ret = PATH_AssignGdiPath( &dst->path, &src->path );
|
{
|
||||||
if (!ret) pop_path_driver( dst );
|
if (!path_driver.pCreateDC( &dst->physDev, NULL, NULL, NULL, NULL )) return FALSE;
|
||||||
|
}
|
||||||
|
physdev = get_path_physdev( dst->physDev );
|
||||||
|
assert( physdev->dev.funcs == &path_driver );
|
||||||
|
physdev->path = src->path;
|
||||||
}
|
}
|
||||||
else if (src->path.state != PATH_Open && dst->path.state == PATH_Open)
|
else if (dst->path && dst->path->state == PATH_Open) pop_path_driver( dst );
|
||||||
{
|
|
||||||
ret = PATH_AssignGdiPath( &dst->path, &src->path );
|
if (dst->path) free_gdi_path( dst->path );
|
||||||
if (ret) pop_path_driver( dst );
|
dst->path = src->path;
|
||||||
}
|
src->path = NULL;
|
||||||
else ret = PATH_AssignGdiPath( &dst->path, &src->path );
|
return TRUE;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1797,7 +1778,7 @@ static struct gdi_path *PATH_WidenPath(DC *dc)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(flat_path = PATH_FlattenPath( &dc->path ))) return NULL;
|
if (!(flat_path = PATH_FlattenPath( dc->path ))) return NULL;
|
||||||
|
|
||||||
penWidthIn = penWidth / 2;
|
penWidthIn = penWidth / 2;
|
||||||
penWidthOut = penWidth / 2;
|
penWidthOut = penWidth / 2;
|
||||||
|
@ -2113,11 +2094,19 @@ BOOL WINAPI WidenPath(HDC hdc)
|
||||||
BOOL nulldrv_BeginPath( PHYSDEV dev )
|
BOOL nulldrv_BeginPath( PHYSDEV dev )
|
||||||
{
|
{
|
||||||
DC *dc = get_nulldrv_dc( dev );
|
DC *dc = get_nulldrv_dc( dev );
|
||||||
|
struct path_physdev *physdev;
|
||||||
|
struct gdi_path *path = alloc_gdi_path();
|
||||||
|
|
||||||
if (!path_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL )) return FALSE;
|
if (!path) return FALSE;
|
||||||
PATH_EmptyPath(&dc->path);
|
if (!path_driver.pCreateDC( &dc->physDev, NULL, NULL, NULL, NULL ))
|
||||||
dc->path.newStroke = TRUE;
|
{
|
||||||
dc->path.state = PATH_Open;
|
free_gdi_path( path );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
physdev = get_path_physdev( dc->physDev );
|
||||||
|
physdev->path = path;
|
||||||
|
if (dc->path) free_gdi_path( dc->path );
|
||||||
|
dc->path = path;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2131,7 +2120,8 @@ BOOL nulldrv_AbortPath( PHYSDEV dev )
|
||||||
{
|
{
|
||||||
DC *dc = get_nulldrv_dc( dev );
|
DC *dc = get_nulldrv_dc( dev );
|
||||||
|
|
||||||
PATH_EmptyPath( &dc->path );
|
if (dc->path) free_gdi_path( dc->path );
|
||||||
|
dc->path = NULL;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2147,14 +2137,18 @@ 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.state != PATH_Closed)
|
if (!dc->path || dc->path->state != PATH_Closed)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!(hrgn = PATH_PathToRegion( &dc->path, GetPolyFillMode(dev->hdc)))) return FALSE;
|
if (!(hrgn = PATH_PathToRegion( dc->path, GetPolyFillMode(dev->hdc)))) return FALSE;
|
||||||
ret = ExtSelectClipRgn( dev->hdc, hrgn, mode ) != ERROR;
|
ret = ExtSelectClipRgn( dev->hdc, hrgn, mode ) != ERROR;
|
||||||
if (ret) PATH_EmptyPath( &dc->path );
|
if (ret)
|
||||||
|
{
|
||||||
|
free_gdi_path( dc->path );
|
||||||
|
dc->path = NULL;
|
||||||
|
}
|
||||||
/* FIXME: Should this function delete the path even if it failed? */
|
/* FIXME: Should this function delete the path even if it failed? */
|
||||||
DeleteObject( hrgn );
|
DeleteObject( hrgn );
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -2164,14 +2158,15 @@ BOOL nulldrv_FillPath( PHYSDEV dev )
|
||||||
{
|
{
|
||||||
DC *dc = get_nulldrv_dc( dev );
|
DC *dc = get_nulldrv_dc( dev );
|
||||||
|
|
||||||
if (dc->path.state != PATH_Closed)
|
if (!dc->path || dc->path->state != PATH_Closed)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!PATH_FillPath( dev->hdc, &dc->path )) return FALSE;
|
if (!PATH_FillPath( dev->hdc, dc->path )) return FALSE;
|
||||||
/* FIXME: Should the path be emptied even if conversion failed? */
|
/* FIXME: Should the path be emptied even if conversion failed? */
|
||||||
PATH_EmptyPath( &dc->path );
|
free_gdi_path( dc->path );
|
||||||
|
dc->path = NULL;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2179,14 +2174,15 @@ BOOL nulldrv_StrokeAndFillPath( PHYSDEV dev )
|
||||||
{
|
{
|
||||||
DC *dc = get_nulldrv_dc( dev );
|
DC *dc = get_nulldrv_dc( dev );
|
||||||
|
|
||||||
if (dc->path.state != PATH_Closed)
|
if (!dc->path || dc->path->state != PATH_Closed)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!PATH_FillPath( dev->hdc, &dc->path )) return FALSE;
|
if (!PATH_FillPath( dev->hdc, dc->path )) return FALSE;
|
||||||
if (!PATH_StrokePath( dev->hdc, &dc->path )) return FALSE;
|
if (!PATH_StrokePath( dev->hdc, dc->path )) return FALSE;
|
||||||
PATH_EmptyPath( &dc->path );
|
free_gdi_path( dc->path );
|
||||||
|
dc->path = NULL;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2194,13 +2190,14 @@ BOOL nulldrv_StrokePath( PHYSDEV dev )
|
||||||
{
|
{
|
||||||
DC *dc = get_nulldrv_dc( dev );
|
DC *dc = get_nulldrv_dc( dev );
|
||||||
|
|
||||||
if (dc->path.state != PATH_Closed)
|
if (!dc->path || dc->path->state != PATH_Closed)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!PATH_StrokePath( dev->hdc, &dc->path )) return FALSE;
|
if (!PATH_StrokePath( dev->hdc, dc->path )) return FALSE;
|
||||||
PATH_EmptyPath( &dc->path );
|
free_gdi_path( dc->path );
|
||||||
|
dc->path = NULL;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2209,14 +2206,14 @@ 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.state != PATH_Closed)
|
if (!dc->path || dc->path->state != PATH_Closed)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!(path = PATH_FlattenPath( &dc->path ))) return FALSE;
|
if (!(path = PATH_FlattenPath( dc->path ))) return FALSE;
|
||||||
PATH_AssignGdiPath( &dc->path, path );
|
free_gdi_path( dc->path );
|
||||||
free_gdi_path( path );
|
dc->path = path;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2225,14 +2222,14 @@ 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.state != PATH_Closed)
|
if (!dc->path || dc->path->state != PATH_Closed)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
SetLastError( ERROR_CAN_NOT_COMPLETE );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (!(path = PATH_WidenPath( dc ))) return FALSE;
|
if (!(path = PATH_WidenPath( dc ))) return FALSE;
|
||||||
PATH_AssignGdiPath( &dc->path, path );
|
free_gdi_path( dc->path );
|
||||||
free_gdi_path( path );
|
dc->path = path;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue