wineps: Implement the additional clipping in PutImage.

This commit is contained in:
Alexandre Julliard 2011-07-21 19:46:28 +02:00
parent 316372a21f
commit 0f9ee1b68f
3 changed files with 49 additions and 61 deletions

View File

@ -308,6 +308,7 @@ DWORD PSDRV_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info,
PSDRV_SetClip(dev); PSDRV_SetClip(dev);
PSDRV_WriteGSave(dev); PSDRV_WriteGSave(dev);
if (clip) PSDRV_AddClip( dev, clip );
PSDRV_WriteImageBits( dev, info, dst_x, dst_y, dst_width, dst_height, PSDRV_WriteImageBits( dev, info, dst_x, dst_y, dst_width, dst_height,
width, height, dst_bits.ptr, size ); width, height, dst_bits.ptr, size );
PSDRV_WriteGRestore(dev); PSDRV_WriteGRestore(dev);

View File

@ -24,6 +24,47 @@
WINE_DEFAULT_DEBUG_CHANNEL(psdrv); WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
/***********************************************************************
* PSDRV_AddClip
*/
void PSDRV_AddClip( PHYSDEV dev, HRGN hrgn )
{
CHAR szArrayName[] = "clippath";
RECT *rect;
RGNDATA *data;
DWORD i, size = GetRegionData(hrgn, 0, NULL);
if (!size) return;
if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
GetRegionData( hrgn, size, data );
rect = (RECT *)data->Buffer;
switch (data->rdh.nCount)
{
case 0:
/* set an empty clip path. */
PSDRV_WriteRectClip(dev, 0, 0, 0, 0);
break;
case 1:
/* optimize when it is a simple region */
PSDRV_WriteRectClip(dev, rect->left, rect->top,
rect->right - rect->left, rect->bottom - rect->top);
break;
default:
PSDRV_WriteArrayDef(dev, szArrayName, data->rdh.nCount * 4);
for (i = 0; i < data->rdh.nCount; i++, rect++)
{
PSDRV_WriteArrayPut(dev, szArrayName, i * 4, rect->left);
PSDRV_WriteArrayPut(dev, szArrayName, i * 4 + 1, rect->top);
PSDRV_WriteArrayPut(dev, szArrayName, i * 4 + 2, rect->right - rect->left);
PSDRV_WriteArrayPut(dev, szArrayName, i * 4 + 3, rect->bottom - rect->top);
}
PSDRV_WriteRectClip2(dev, szArrayName);
break;
}
HeapFree( GetProcessHeap(), 0, data );
}
/*********************************************************************** /***********************************************************************
* PSDRV_SetClip * PSDRV_SetClip
* *
@ -38,76 +79,21 @@ WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
void PSDRV_SetClip( PHYSDEV dev ) void PSDRV_SetClip( PHYSDEV dev )
{ {
PSDRV_PDEVICE *physDev = get_psdrv_dev( dev ); PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
CHAR szArrayName[] = "clippath"; HRGN hrgn;
DWORD size;
RGNDATA *rgndata = NULL;
HRGN hrgn = CreateRectRgn(0,0,0,0);
BOOL empty;
TRACE("hdc=%p\n", dev->hdc); TRACE("hdc=%p\n", dev->hdc);
if(physDev->pathdepth) { if(physDev->pathdepth) {
TRACE("inside a path, so not clipping\n"); TRACE("inside a path, so not clipping\n");
goto end; return;
} }
empty = !GetClipRgn(dev->hdc, hrgn); hrgn = CreateRectRgn(0,0,0,0);
if (GetClipRgn(dev->hdc, hrgn))
if(!empty) { {
size = GetRegionData(hrgn, 0, NULL);
if(!size) {
ERR("Invalid region\n");
goto end;
}
rgndata = HeapAlloc( GetProcessHeap(), 0, size );
if(!rgndata) {
ERR("Can't allocate buffer\n");
goto end;
}
GetRegionData(hrgn, size, rgndata);
PSDRV_WriteGSave(dev); PSDRV_WriteGSave(dev);
PSDRV_AddClip( dev, hrgn );
/* check for NULL region */
if (rgndata->rdh.nCount == 0)
{
/* set an empty clip path. */
PSDRV_WriteRectClip(dev, 0, 0, 0, 0);
}
/* optimize when it is a simple region */
else if (rgndata->rdh.nCount == 1)
{
RECT *pRect = (RECT *)rgndata->Buffer;
PSDRV_WriteRectClip(dev, pRect->left, pRect->top,
pRect->right - pRect->left,
pRect->bottom - pRect->top);
}
else
{
UINT i;
RECT *pRect = (RECT *)rgndata->Buffer;
PSDRV_WriteArrayDef(dev, szArrayName, rgndata->rdh.nCount * 4);
for (i = 0; i < rgndata->rdh.nCount; i++, pRect++)
{
PSDRV_WriteArrayPut(dev, szArrayName, i * 4,
pRect->left);
PSDRV_WriteArrayPut(dev, szArrayName, i * 4 + 1,
pRect->top);
PSDRV_WriteArrayPut(dev, szArrayName, i * 4 + 2,
pRect->right - pRect->left);
PSDRV_WriteArrayPut(dev, szArrayName, i * 4 + 3,
pRect->bottom - pRect->top);
}
PSDRV_WriteRectClip2(dev, szArrayName);
}
} }
end:
HeapFree( GetProcessHeap(), 0, rgndata );
DeleteObject(hrgn); DeleteObject(hrgn);
} }

View File

@ -480,6 +480,7 @@ extern BOOL PSDRV_Brush(PHYSDEV dev, BOOL EO) DECLSPEC_HIDDEN;
extern BOOL PSDRV_SetFont( PHYSDEV dev ) DECLSPEC_HIDDEN; extern BOOL PSDRV_SetFont( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL PSDRV_SetPen( PHYSDEV dev ) DECLSPEC_HIDDEN; extern BOOL PSDRV_SetPen( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern void PSDRV_AddClip( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
extern void PSDRV_SetClip( PHYSDEV dev ) DECLSPEC_HIDDEN; extern void PSDRV_SetClip( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern void PSDRV_ResetClip( PHYSDEV dev ) DECLSPEC_HIDDEN; extern void PSDRV_ResetClip( PHYSDEV dev ) DECLSPEC_HIDDEN;