Changed DC members w.hVisRgn, w.hClipRgn, amd w.hGCClipRgn to

coordinates relative to the device, not the DC origin. This is
necessary to correctly implement GetClipRgn16 and InquireVisRgn.
SelectVisRgn also expects region in device-relative coordinates.
Adapted the rest of Wine to this coordinate change.
Implemented ExtSelectClipRgn.
This commit is contained in:
Ulrich Weigand 1998-10-11 18:47:02 +00:00 committed by Alexandre Julliard
parent 832e498565
commit d4663668b8
14 changed files with 188 additions and 170 deletions

View File

@ -424,7 +424,7 @@ BOOL32 WINAPI FillPath32(HDC32 hdc)
BOOL32 WINAPI SelectClipPath32(HDC32 hdc, INT32 iMode) BOOL32 WINAPI SelectClipPath32(HDC32 hdc, INT32 iMode)
{ {
GdiPath *pPath; GdiPath *pPath;
HRGN32 hrgnPath, hrgnClip; HRGN32 hrgnPath;
BOOL32 success; BOOL32 success;
/* Get pointer to path */ /* Get pointer to path */
@ -444,17 +444,7 @@ BOOL32 WINAPI SelectClipPath32(HDC32 hdc, INT32 iMode)
/* Construct a region from the path */ /* Construct a region from the path */
if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgnPath)) if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgnPath))
{ {
hrgnClip=CreateRectRgn32(0, 0, 0, 0); success = ExtSelectClipRgn( hdc, hrgnPath, iMode ) != ERROR;
if(hrgnClip==(HRGN32)0)
success=FALSE;
else
{
success=(GetClipRgn32(hdc, hrgnClip)!=-1) &&
(CombineRgn32(hrgnClip, hrgnClip, hrgnPath, iMode)!=ERROR) &&
(SelectClipRgn32(hdc, hrgnClip)!=ERROR);
DeleteObject32(hrgnClip);
}
DeleteObject32(hrgnPath); DeleteObject32(hrgnPath);
/* Empty the path */ /* Empty the path */

View File

@ -1035,7 +1035,6 @@ static BOOL32 BITBLT_GetVisRectangles( DC *dcDst, INT32 xDst, INT32 yDst,
if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right ); if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right );
if (heightDst < 0) SWAP_INT32( &rect.top, &rect.bottom ); if (heightDst < 0) SWAP_INT32( &rect.top, &rect.bottom );
GetRgnBox32( dcDst->w.hGCClipRgn, &clipRect ); GetRgnBox32( dcDst->w.hGCClipRgn, &clipRect );
OffsetRect32( &clipRect, dcDst->w.DCOrgX, dcDst->w.DCOrgY );
if (!IntersectRect32( visRectDst, &rect, &clipRect )) return FALSE; if (!IntersectRect32( visRectDst, &rect, &clipRect )) return FALSE;
/* Get the source visible rectangle */ /* Get the source visible rectangle */
@ -1046,7 +1045,6 @@ static BOOL32 BITBLT_GetVisRectangles( DC *dcDst, INT32 xDst, INT32 yDst,
if (heightSrc < 0) SWAP_INT32( &rect.top, &rect.bottom ); if (heightSrc < 0) SWAP_INT32( &rect.top, &rect.bottom );
/* Apparently the clip region is only for output, so use hVisRgn here */ /* Apparently the clip region is only for output, so use hVisRgn here */
GetRgnBox32( dcSrc->w.hVisRgn, &clipRect ); GetRgnBox32( dcSrc->w.hVisRgn, &clipRect );
OffsetRect32( &clipRect, dcSrc->w.DCOrgX, dcSrc->w.DCOrgY );
if (!IntersectRect32( visRectSrc, &rect, &clipRect )) return FALSE; if (!IntersectRect32( visRectSrc, &rect, &clipRect )) return FALSE;
/* Intersect the rectangles */ /* Intersect the rectangles */

View File

@ -54,8 +54,8 @@ void X11DRV_SetDeviceClipping( DC * dc )
else else
pXrect = NULL; pXrect = NULL;
TSXSetClipRectangles( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY, TSXSetClipRectangles( display, dc->u.x.gc, 0, 0,
pXrect, obj->rgn->numRects, YXBanded ); pXrect, obj->rgn->numRects, YXBanded );
if(pXrect) if(pXrect)
HeapFree( GetProcessHeap(), 0, pXrect ); HeapFree( GetProcessHeap(), 0, pXrect );

View File

@ -619,7 +619,8 @@ X11DRV_PaintRgn( DC *dc, HRGN32 hrgn )
if (!(tmpVisRgn = CreateRectRgn32( 0, 0, 0, 0 ))) return FALSE; if (!(tmpVisRgn = CreateRectRgn32( 0, 0, 0, 0 ))) return FALSE;
/* Transform region into device co-ords */ /* Transform region into device co-ords */
if (!REGION_LPTODP( hdc, tmpVisRgn, hrgn )) { if ( !REGION_LPTODP( hdc, tmpVisRgn, hrgn )
|| OffsetRgn32( tmpVisRgn, dc->w.DCOrgX, dc->w.DCOrgY ) == ERROR) {
DeleteObject32( tmpVisRgn ); DeleteObject32( tmpVisRgn );
return FALSE; return FALSE;
} }
@ -638,8 +639,8 @@ X11DRV_PaintRgn( DC *dc, HRGN32 hrgn )
GetRgnBox32( dc->w.hGCClipRgn, &box ); GetRgnBox32( dc->w.hGCClipRgn, &box );
if (DC_SetupGCForBrush( dc )) if (DC_SetupGCForBrush( dc ))
TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc, TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top, box.left, box.top,
box.right-box.left, box.bottom-box.top ); box.right-box.left, box.bottom-box.top );
/* Restore the visible region */ /* Restore the visible region */
@ -876,8 +877,8 @@ static BOOL32 X11DRV_DoFloodFill( const struct FloodFill_params *params )
if (GetRgnBox32( dc->w.hGCClipRgn, &rect ) == ERROR) return FALSE; if (GetRgnBox32( dc->w.hGCClipRgn, &rect ) == ERROR) return FALSE;
if (!(image = XGetImage( display, dc->u.x.drawable, if (!(image = XGetImage( display, dc->u.x.drawable,
dc->w.DCOrgX + rect.left, rect.left,
dc->w.DCOrgY + rect.top, rect.top,
rect.right - rect.left, rect.right - rect.left,
rect.bottom - rect.top, rect.bottom - rect.top,
AllPlanes, ZPixmap ))) return FALSE; AllPlanes, ZPixmap ))) return FALSE;
@ -887,10 +888,10 @@ static BOOL32 X11DRV_DoFloodFill( const struct FloodFill_params *params )
/* ROP mode is always GXcopy for flood-fill */ /* ROP mode is always GXcopy for flood-fill */
XSetFunction( display, dc->u.x.gc, GXcopy ); XSetFunction( display, dc->u.x.gc, GXcopy );
X11DRV_InternalFloodFill(image, dc, X11DRV_InternalFloodFill(image, dc,
XLPTODP(dc,params->x) - rect.left, XLPTODP(dc,params->x) + dc->w.DCOrgX - rect.left,
YLPTODP(dc,params->y) - rect.top, YLPTODP(dc,params->y) + dc->w.DCOrgY - rect.top,
dc->w.DCOrgX + rect.left, rect.left,
dc->w.DCOrgY + rect.top, rect.top,
COLOR_ToPhysical( dc, params->color ), COLOR_ToPhysical( dc, params->color ),
params->fillType ); params->fillType );
} }

View File

@ -28,7 +28,6 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
const RECT32 *lprect, LPCSTR str, UINT32 count, const RECT32 *lprect, LPCSTR str, UINT32 count,
const INT32 *lpDx ) const INT32 *lpDx )
{ {
HRGN32 hRgnClip = 0;
int i; int i;
fontObject* pfo; fontObject* pfo;
INT32 width, ascent, descent, xwidth, ywidth; INT32 width, ascent, descent, xwidth, ywidth;
@ -176,9 +175,9 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED)
{ {
hRgnClip = dc->w.hClipRgn; SaveVisRgn( dc->hSelf );
CLIPPING_IntersectClipRect( dc, rect.left, rect.top, rect.right, CLIPPING_IntersectVisRect( dc, rect.left, rect.top, rect.right,
rect.bottom, CLIP_INTERSECT|CLIP_KEEPRGN ); rect.bottom, FALSE );
} }
/* Draw the text background if necessary */ /* Draw the text background if necessary */
@ -331,10 +330,8 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
} }
if (flags & ETO_CLIPPED) if (flags & ETO_CLIPPED)
{ RestoreVisRgn( dc->hSelf );
SelectClipRgn32( dc->hSelf, hRgnClip );
DeleteObject32( hRgnClip );
}
return TRUE; return TRUE;
} }

View File

@ -160,7 +160,7 @@ file gdi.exe
190 pascal16 SetDCHook(word segptr long) THUNK_SetDCHook 190 pascal16 SetDCHook(word segptr long) THUNK_SetDCHook
191 pascal GetDCHook(word ptr) THUNK_GetDCHook 191 pascal GetDCHook(word ptr) THUNK_GetDCHook
192 pascal16 SetHookFlags(word word) SetHookFlags 192 pascal16 SetHookFlags(word word) SetHookFlags
193 stub SetBoundsRect 193 pascal16 SetBoundsRect(word ptr word) SetBoundsRect16
194 pascal16 GetBoundsRect(word ptr word) GetBoundsRect16 194 pascal16 GetBoundsRect(word ptr word) GetBoundsRect16
195 stub SelectBitmap 195 stub SelectBitmap
196 pascal16 SetMetaFileBitsBetter(word) SetMetaFileBitsBetter 196 pascal16 SetMetaFileBitsBetter(word) SetMetaFileBitsBetter

View File

@ -28,6 +28,8 @@ extern const int DC_XROPfunction[];
/* objects/clipping.c */ /* objects/clipping.c */
INT32 CLIPPING_IntersectClipRect( DC * dc, INT32 left, INT32 top, INT32 CLIPPING_IntersectClipRect( DC * dc, INT32 left, INT32 top,
INT32 right, INT32 bottom, UINT32 flags ); INT32 right, INT32 bottom, UINT32 flags );
INT32 CLIPPING_IntersectVisRect( DC * dc, INT32 left, INT32 top,
INT32 right, INT32 bottom, BOOL32 exclude );
extern void CLIPPING_UpdateGCRegion( DC * dc ); extern void CLIPPING_UpdateGCRegion( DC * dc );
#endif /* __WINE_DC_H */ #endif /* __WINE_DC_H */

View File

@ -6584,6 +6584,7 @@ BOOL32 WINAPI EnumTimeFormats32W(TIMEFMT_ENUMPROC32W lpTimeFmtEnumProc, LCI
VOID WINAPI ExitProcess(DWORD); VOID WINAPI ExitProcess(DWORD);
VOID WINAPI ExitThread(DWORD); VOID WINAPI ExitThread(DWORD);
BOOL32 WINAPI ExitWindowsEx(UINT32,DWORD); BOOL32 WINAPI ExitWindowsEx(UINT32,DWORD);
INT32 WINAPI ExtSelectClipRgn(HDC32,HRGN32,INT32);
DWORD WINAPI ExpandEnvironmentStrings32A(LPCSTR,LPSTR,DWORD); DWORD WINAPI ExpandEnvironmentStrings32A(LPCSTR,LPSTR,DWORD);
DWORD WINAPI ExpandEnvironmentStrings32W(LPCWSTR,LPWSTR,DWORD); DWORD WINAPI ExpandEnvironmentStrings32W(LPCWSTR,LPWSTR,DWORD);
#define ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings) #define ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings)

View File

@ -60,27 +60,7 @@ INT16 WINAPI SelectClipRgn16( HDC16 hdc, HRGN16 hrgn )
*/ */
INT32 WINAPI SelectClipRgn32( HDC32 hdc, HRGN32 hrgn ) INT32 WINAPI SelectClipRgn32( HDC32 hdc, HRGN32 hrgn )
{ {
INT32 retval; return ExtSelectClipRgn( hdc, hrgn, RGN_COPY );
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return ERROR;
TRACE(clipping, "%04x %04x\n", hdc, hrgn );
if (hrgn)
{
if (!dc->w.hClipRgn) dc->w.hClipRgn = CreateRectRgn32(0,0,0,0);
retval = CombineRgn32( dc->w.hClipRgn, hrgn, 0, RGN_COPY );
}
else
{
if (dc->w.hClipRgn) DeleteObject16( dc->w.hClipRgn );
dc->w.hClipRgn = 0;
retval = SIMPLEREGION; /* Clip region == whole DC */
}
CLIPPING_UpdateGCRegion( dc );
GDI_HEAP_UNLOCK( hdc );
return retval;
} }
/****************************************************************************** /******************************************************************************
@ -88,9 +68,44 @@ INT32 WINAPI SelectClipRgn32( HDC32 hdc, HRGN32 hrgn )
*/ */
INT32 WINAPI ExtSelectClipRgn( HDC32 hdc, HRGN32 hrgn, INT32 fnMode ) INT32 WINAPI ExtSelectClipRgn( HDC32 hdc, HRGN32 hrgn, INT32 fnMode )
{ {
if (fnMode != RGN_COPY) INT32 retval;
FIXME(clipping, "Unimplemented mode: %d\n", fnMode); DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
return SelectClipRgn32( hdc, hrgn ); if (!dc) return ERROR;
TRACE( clipping, "%04x %04x %d\n", hdc, hrgn, fnMode );
if (!hrgn)
{
if (fnMode == RGN_COPY)
{
if (dc->w.hClipRgn) DeleteObject16( dc->w.hClipRgn );
dc->w.hClipRgn = 0;
retval = SIMPLEREGION; /* Clip region == whole DC */
}
else
{
FIXME(clipping, "Unimplemented: hrgn NULL in mode: %d\n", fnMode);
return ERROR;
}
}
else
{
if (!dc->w.hClipRgn)
{
RECT32 rect;
GetRgnBox32( dc->w.hVisRgn, &rect );
dc->w.hClipRgn = CreateRectRgnIndirect32( &rect );
}
OffsetRgn32( dc->w.hClipRgn, -dc->w.DCOrgX, -dc->w.DCOrgY );
retval = CombineRgn32( dc->w.hClipRgn, dc->w.hClipRgn, hrgn, fnMode );
OffsetRgn32( dc->w.hClipRgn, dc->w.DCOrgX, dc->w.DCOrgY );
}
CLIPPING_UpdateGCRegion( dc );
GDI_HEAP_UNLOCK( hdc );
return retval;
} }
/*********************************************************************** /***********************************************************************
@ -180,6 +195,11 @@ INT32 CLIPPING_IntersectClipRect( DC * dc, INT32 left, INT32 top,
HRGN32 newRgn; HRGN32 newRgn;
INT32 ret; INT32 ret;
left += dc->w.DCOrgX;
right += dc->w.DCOrgX;
top += dc->w.DCOrgY;
bottom += dc->w.DCOrgY;
if (!(newRgn = CreateRectRgn32( left, top, right, bottom ))) return ERROR; if (!(newRgn = CreateRectRgn32( left, top, right, bottom ))) return ERROR;
if (!dc->w.hClipRgn) if (!dc->w.hClipRgn)
{ {
@ -293,19 +313,21 @@ INT32 WINAPI IntersectClipRect32( HDC32 hdc, INT32 left, INT32 top,
/*********************************************************************** /***********************************************************************
* CLIPPING_IntersectVisRect * CLIPPING_IntersectVisRect
* *
* Helper function for {Intersect,Exclude}VisRect * Helper function for {Intersect,Exclude}VisRect, can be called from
* elsewhere (like ExtTextOut()) to skip redundant metafile update and
* coordinate conversion.
*/ */
static INT32 CLIPPING_IntersectVisRect( DC * dc, INT32 left, INT32 top, INT32 CLIPPING_IntersectVisRect( DC * dc, INT32 left, INT32 top,
INT32 right, INT32 bottom, INT32 right, INT32 bottom,
BOOL32 exclude ) BOOL32 exclude )
{ {
HRGN32 tempRgn, newRgn; HRGN32 tempRgn, newRgn;
INT32 ret; INT32 ret;
left = XLPTODP( dc, left ); left += dc->w.DCOrgX;
right = XLPTODP( dc, right ); right += dc->w.DCOrgX;
top = YLPTODP( dc, top ); top += dc->w.DCOrgY;
bottom = YLPTODP( dc, bottom ); bottom += dc->w.DCOrgY;
if (!(newRgn = CreateRectRgn32( 0, 0, 0, 0 ))) return ERROR; if (!(newRgn = CreateRectRgn32( 0, 0, 0, 0 ))) return ERROR;
if (!(tempRgn = CreateRectRgn32( left, top, right, bottom ))) if (!(tempRgn = CreateRectRgn32( left, top, right, bottom )))
@ -340,6 +362,12 @@ INT16 WINAPI ExcludeVisRect( HDC16 hdc, INT16 left, INT16 top,
{ {
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return ERROR; if (!dc) return ERROR;
left = XLPTODP( dc, left );
right = XLPTODP( dc, right );
top = YLPTODP( dc, top );
bottom = YLPTODP( dc, bottom );
TRACE(clipping, "%04x %dx%d,%dx%d\n", TRACE(clipping, "%04x %dx%d,%dx%d\n",
hdc, left, top, right, bottom ); hdc, left, top, right, bottom );
@ -355,6 +383,12 @@ INT16 WINAPI IntersectVisRect( HDC16 hdc, INT16 left, INT16 top,
{ {
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return ERROR; if (!dc) return ERROR;
left = XLPTODP( dc, left );
right = XLPTODP( dc, right );
top = YLPTODP( dc, top );
bottom = YLPTODP( dc, bottom );
TRACE(clipping, "%04x %dx%d,%dx%d\n", TRACE(clipping, "%04x %dx%d,%dx%d\n",
hdc, left, top, right, bottom ); hdc, left, top, right, bottom );
@ -385,7 +419,8 @@ BOOL32 WINAPI PtVisible32( HDC32 hdc, INT32 x, INT32 y )
if( dc->w.flags & DC_DIRTY ) UPDATE_DIRTY_DC(dc); if( dc->w.flags & DC_DIRTY ) UPDATE_DIRTY_DC(dc);
dc->w.flags &= ~DC_DIRTY; dc->w.flags &= ~DC_DIRTY;
return PtInRegion32( dc->w.hGCClipRgn, XLPTODP(dc,x), YLPTODP(dc,y) ); return PtInRegion32( dc->w.hGCClipRgn, XLPTODP(dc,x) + dc->w.DCOrgX,
YLPTODP(dc,y) + dc->w.DCOrgY );
} }
@ -403,6 +438,7 @@ BOOL16 WINAPI RectVisible16( HDC16 hdc, LPRECT16 rect )
/* copy rectangle to avoid overwriting by LPtoDP */ /* copy rectangle to avoid overwriting by LPtoDP */
tmpRect = *rect; tmpRect = *rect;
LPtoDP16( hdc, (LPPOINT16)&tmpRect, 2 ); LPtoDP16( hdc, (LPPOINT16)&tmpRect, 2 );
OffsetRect16( &tmpRect, dc->w.DCOrgX, dc->w.DCOrgY );
return RectInRegion16( dc->w.hGCClipRgn, &tmpRect ); return RectInRegion16( dc->w.hGCClipRgn, &tmpRect );
} }
@ -427,6 +463,7 @@ INT16 WINAPI GetClipBox16( HDC16 hdc, LPRECT16 rect )
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return ERROR; if (!dc) return ERROR;
ret = GetRgnBox16( dc->w.hGCClipRgn, rect ); ret = GetRgnBox16( dc->w.hGCClipRgn, rect );
OffsetRect16( rect, -dc->w.DCOrgX, -dc->w.DCOrgY );
DPtoLP16( hdc, (LPPOINT16)rect, 2 ); DPtoLP16( hdc, (LPPOINT16)rect, 2 );
return ret; return ret;
} }
@ -441,6 +478,7 @@ INT32 WINAPI GetClipBox32( HDC32 hdc, LPRECT32 rect )
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return ERROR; if (!dc) return ERROR;
ret = GetRgnBox32( dc->w.hGCClipRgn, rect ); ret = GetRgnBox32( dc->w.hGCClipRgn, rect );
OffsetRect32( rect, -dc->w.DCOrgX, -dc->w.DCOrgY );
DPtoLP32( hdc, (LPPOINT32)rect, 2 ); DPtoLP32( hdc, (LPPOINT32)rect, 2 );
return ret; return ret;
} }
@ -456,10 +494,13 @@ INT32 WINAPI GetClipRgn32( HDC32 hdc, HRGN32 hRgn )
if( dc->w.hClipRgn ) if( dc->w.hClipRgn )
{ {
/* this assumes that dc->w.hClipRgn is in coordinates /* this assumes that dc->w.hClipRgn is in coordinates
relative to the DC origin (not device) */ relative to the device (not DC origin) */
if( CombineRgn32(hRgn, dc->w.hClipRgn, 0, RGN_COPY) != ERROR ) if( CombineRgn32(hRgn, dc->w.hClipRgn, 0, RGN_COPY) != ERROR )
{
OffsetRgn32( hRgn, -dc->w.DCOrgX, -dc->w.DCOrgY );
return 1; return 1;
}
} }
else return 0; else return 0;
return -1; return -1;

View File

@ -546,8 +546,11 @@ HDC16 WINAPI GetDCState( HDC16 hdc )
newdc->w.breakRem = dc->w.breakRem; newdc->w.breakRem = dc->w.breakRem;
newdc->w.MapMode = dc->w.MapMode; newdc->w.MapMode = dc->w.MapMode;
newdc->w.GraphicsMode = dc->w.GraphicsMode; newdc->w.GraphicsMode = dc->w.GraphicsMode;
#if 0
/* Apparently, the DC origin is not changed by [GS]etDCState */
newdc->w.DCOrgX = dc->w.DCOrgX; newdc->w.DCOrgX = dc->w.DCOrgX;
newdc->w.DCOrgY = dc->w.DCOrgY; newdc->w.DCOrgY = dc->w.DCOrgY;
#endif
newdc->w.CursPosX = dc->w.CursPosX; newdc->w.CursPosX = dc->w.CursPosX;
newdc->w.CursPosY = dc->w.CursPosY; newdc->w.CursPosY = dc->w.CursPosY;
newdc->w.ArcDirection = dc->w.ArcDirection; newdc->w.ArcDirection = dc->w.ArcDirection;
@ -627,8 +630,11 @@ void WINAPI SetDCState( HDC16 hdc, HDC16 hdcs )
dc->w.breakRem = dcs->w.breakRem; dc->w.breakRem = dcs->w.breakRem;
dc->w.MapMode = dcs->w.MapMode; dc->w.MapMode = dcs->w.MapMode;
dc->w.GraphicsMode = dcs->w.GraphicsMode; dc->w.GraphicsMode = dcs->w.GraphicsMode;
#if 0
/* Apparently, the DC origin is not changed by [GS]etDCState */
dc->w.DCOrgX = dcs->w.DCOrgX; dc->w.DCOrgX = dcs->w.DCOrgX;
dc->w.DCOrgY = dcs->w.DCOrgY; dc->w.DCOrgY = dcs->w.DCOrgY;
#endif
dc->w.CursPosX = dcs->w.CursPosX; dc->w.CursPosX = dcs->w.CursPosX;
dc->w.CursPosY = dcs->w.CursPosY; dc->w.CursPosY = dcs->w.CursPosY;
dc->w.ArcDirection = dcs->w.ArcDirection; dc->w.ArcDirection = dcs->w.ArcDirection;
@ -647,7 +653,15 @@ void WINAPI SetDCState( HDC16 hdc, HDC16 hdcs )
dc->vportExtY = dcs->vportExtY; dc->vportExtY = dcs->vportExtY;
if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel; if (!(dc->w.flags & DC_MEMORY)) dc->w.bitsPerPixel = dcs->w.bitsPerPixel;
SelectClipRgn32( hdc, dcs->w.hClipRgn );
if (dcs->w.hClipRgn)
{
if (!dc->w.hClipRgn) dc->w.hClipRgn = CreateRectRgn32( 0, 0, 0, 0 );
CombineRgn32( dc->w.hClipRgn, dcs->w.hClipRgn, 0, RGN_COPY );
CLIPPING_UpdateGCRegion( dc );
}
else
dc->w.hClipRgn = 0;
SelectObject32( hdc, dcs->w.hBitmap ); SelectObject32( hdc, dcs->w.hBitmap );
SelectObject32( hdc, dcs->w.hBrush ); SelectObject32( hdc, dcs->w.hBrush );
@ -1516,3 +1530,12 @@ UINT16 WINAPI GetBoundsRect16(HDC16 hdc, LPRECT16 rect, UINT16 flags)
return DCB_RESET; /* bounding rectangle always empty */ return DCB_RESET; /* bounding rectangle always empty */
} }
/***********************************************************************
* SetBoundsRect16 (GDI.193)
*/
UINT16 WINAPI SetBoundsRect16(HDC16 hdc, LPRECT16 rect, UINT16 flags)
{
FIXME(dc, "(): stub\n");
return DCB_DISABLE; /* bounding rectangle always empty */
}

View File

@ -129,6 +129,7 @@ DC_GET_X_Y( DWORD, GetViewportOrg, vportOrgX, vportOrgY ) /* GDI.95 */
DC_GET_X_Y( DWORD, GetWindowExt, wndExtX, wndExtY ) /* GDI.96 */ DC_GET_X_Y( DWORD, GetWindowExt, wndExtX, wndExtY ) /* GDI.96 */
DC_GET_X_Y( DWORD, GetWindowOrg, wndOrgX, wndOrgY ) /* GDI.97 */ DC_GET_X_Y( DWORD, GetWindowOrg, wndOrgX, wndOrgY ) /* GDI.97 */
DC_GET_VAL_16( HRGN16, InquireVisRgn, w.hVisRgn ) /* GDI.131 */ DC_GET_VAL_16( HRGN16, InquireVisRgn, w.hVisRgn ) /* GDI.131 */
DC_GET_VAL_16( HRGN16, GetClipRgn16, w.hClipRgn ) /* GDI.173 */
DC_GET_X_Y( DWORD, GetBrushOrg, w.brushOrgX, w.brushOrgY ) /* GDI.149 */ DC_GET_X_Y( DWORD, GetBrushOrg, w.brushOrgX, w.brushOrgY ) /* GDI.149 */
DC_GET_VAL_16( UINT16, GetTextAlign16, w.textAlign ) /* GDI.345 */ DC_GET_VAL_16( UINT16, GetTextAlign16, w.textAlign ) /* GDI.345 */
DC_GET_VAL_32( UINT32, GetTextAlign32, w.textAlign ) /* GDI32.224 */ DC_GET_VAL_32( UINT32, GetTextAlign32, w.textAlign ) /* GDI32.224 */
@ -140,9 +141,3 @@ DC_GET_VAL_EX( GetViewportExtEx, vportExtX, vportExtY ) /* GDI.472 GDI32.239 */
DC_GET_VAL_EX( GetViewportOrgEx, vportOrgX, vportOrgY ) /* GDI.473 GDI32.240 */ DC_GET_VAL_EX( GetViewportOrgEx, vportOrgX, vportOrgY ) /* GDI.473 GDI32.240 */
DC_GET_VAL_EX( GetWindowExtEx, wndExtX, wndExtY ) /* GDI.474 GDI32.242 */ DC_GET_VAL_EX( GetWindowExtEx, wndExtX, wndExtY ) /* GDI.474 GDI32.242 */
DC_GET_VAL_EX( GetWindowOrgEx, wndOrgX, wndOrgY ) /* GDI.475 GDI32.243 */ DC_GET_VAL_EX( GetWindowOrgEx, wndOrgX, wndOrgY ) /* GDI.475 GDI32.243 */
/* this one is wrong - Windows returns region that
is relative to the device and not to the DC origin */
DC_GET_VAL_16( HRGN16, GetClipRgn16, w.hClipRgn ) /* GDI.173 */

View File

@ -497,6 +497,22 @@ HRGN32 DCE_GetVisRgn( HWND32 hwnd, WORD flags )
return hrgnVis; return hrgnVis;
} }
/***********************************************************************
* DCE_OffsetVisRgn
*
* Change region from DC-origin relative coordinates to screen coords.
*/
static void DCE_OffsetVisRgn( HDC32 hDC, HRGN32 hVisRgn )
{
DC *dc;
if (!(dc = (DC *) GDI_GetObjPtr( hDC, DC_MAGIC ))) return;
OffsetRgn32( hVisRgn, dc->w.DCOrgX, dc->w.DCOrgY );
GDI_HEAP_UNLOCK( hDC );
}
/*********************************************************************** /***********************************************************************
* DCE_SetDrawable * DCE_SetDrawable
@ -535,6 +551,7 @@ static void DCE_SetDrawable( WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOri
dc->w.DCOrgY -= wndPtr->rectWindow.top; dc->w.DCOrgY -= wndPtr->rectWindow.top;
dc->u.x.drawable = wndPtr->window; dc->u.x.drawable = wndPtr->window;
#if 0
/* This is needed when we reuse a cached DC because /* This is needed when we reuse a cached DC because
* SetDCState() called by ReleaseDC() screws up DC * SetDCState() called by ReleaseDC() screws up DC
* origins for child windows. * origins for child windows.
@ -542,6 +559,7 @@ static void DCE_SetDrawable( WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOri
if( bSetClipOrigin ) if( bSetClipOrigin )
TSXSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY ); TSXSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY );
#endif
} }
} }
/*********************************************************************** /***********************************************************************
@ -552,9 +570,7 @@ static void DCE_SetDrawable( WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOri
*/ */
INT16 DCE_ExcludeRgn( HDC32 hDC, WND* wnd, HRGN32 hRgn ) INT16 DCE_ExcludeRgn( HDC32 hDC, WND* wnd, HRGN32 hRgn )
{ {
INT16 ret;
POINT32 pt = {0, 0}; POINT32 pt = {0, 0};
HRGN32 hRgnClip = GetClipRgn16( hDC );
DCE *dce = firstDCE; DCE *dce = firstDCE;
while (dce && (dce->hDC != hDC)) dce = dce->next; while (dce && (dce->hDC != hDC)) dce = dce->next;
@ -570,14 +586,8 @@ INT16 DCE_ExcludeRgn( HDC32 hDC, WND* wnd, HRGN32 hRgn )
} }
else return ERROR; else return ERROR;
OffsetRgn32(hRgn, pt.x, pt.y); OffsetRgn32(hRgn, pt.x, pt.y);
if( hRgnClip ) ret = CombineRgn32( hRgnClip, hRgnClip, hRgn, RGN_DIFF );
else return ExtSelectClipRgn( hDC, hRgn, RGN_DIFF );
{
hRgnClip = InquireVisRgn( hDC );
ret = CombineRgn32( hRgn, hRgnClip, hRgn, RGN_DIFF );
SelectClipRgn32( hDC, hRgn );
}
return ret;
} }
/*********************************************************************** /***********************************************************************
@ -755,6 +765,7 @@ HDC32 WINAPI GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags )
else else
OffsetRgn32( hrgnVisible, -wndPtr->rectClient.left, OffsetRgn32( hrgnVisible, -wndPtr->rectClient.left,
-wndPtr->rectClient.top ); -wndPtr->rectClient.top );
DCE_OffsetVisRgn( hdc, hrgnVisible );
} }
else else
hrgnVisible = CreateRectRgn32( 0, 0, 0, 0 ); hrgnVisible = CreateRectRgn32( 0, 0, 0, 0 );
@ -764,7 +775,11 @@ HDC32 WINAPI GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags )
(rootWindow == DefaultRootWindow(display))) (rootWindow == DefaultRootWindow(display)))
hrgnVisible = CreateRectRgn32( 0, 0, SYSMETRICS_CXSCREEN, hrgnVisible = CreateRectRgn32( 0, 0, SYSMETRICS_CXSCREEN,
SYSMETRICS_CYSCREEN ); SYSMETRICS_CYSCREEN );
else hrgnVisible = DCE_GetVisRgn( hwnd, flags ); else
{
hrgnVisible = DCE_GetVisRgn( hwnd, flags );
DCE_OffsetVisRgn( hdc, hrgnVisible );
}
dc->w.flags &= ~DC_DIRTY; dc->w.flags &= ~DC_DIRTY;
dce->DCXflags &= ~DCX_DCEDIRTY; dce->DCXflags &= ~DCX_DCEDIRTY;
@ -785,7 +800,9 @@ HDC32 WINAPI GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags )
TRACE(dc, "\tsaved VisRgn, clipRgn = %04x\n", hrgnClip); TRACE(dc, "\tsaved VisRgn, clipRgn = %04x\n", hrgnClip);
SaveVisRgn( hdc ); SaveVisRgn( hdc );
CombineRgn32( hrgnVisible, InquireVisRgn( hdc ), hrgnClip, CombineRgn32( hrgnVisible, hrgnClip, 0, RGN_COPY );
DCE_OffsetVisRgn( hdc, hrgnVisible );
CombineRgn32( hrgnVisible, InquireVisRgn( hdc ), hrgnVisible,
(flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF ); (flags & DCX_INTERSECTRGN) ? RGN_AND : RGN_DIFF );
SelectVisRgn( hdc, hrgnVisible ); SelectVisRgn( hdc, hrgnVisible );
} }
@ -919,6 +936,7 @@ BOOL16 WINAPI DCHook( HDC16 hDC, WORD code, DWORD data, LPARAM lParam )
(dce->DCXflags & DCX_EXCLUDERGN)? RGN_DIFF:RGN_AND); (dce->DCXflags & DCX_EXCLUDERGN)? RGN_DIFF:RGN_AND);
} }
dce->DCXflags &= ~DCX_DCEDIRTY; dce->DCXflags &= ~DCX_DCEDIRTY;
DCE_OffsetVisRgn( hDC, hVisRgn );
SelectVisRgn(hDC, hVisRgn); SelectVisRgn(hDC, hVisRgn);
DeleteObject32( hVisRgn ); DeleteObject32( hVisRgn );
} }

View File

@ -138,13 +138,11 @@ HDC16 WINAPI BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps )
return 0; return 0;
} }
GetRgnBox16( InquireVisRgn(lps->hdc), &lps->rcPaint ); GetClipBox16( lps->hdc, &lps->rcPaint );
TRACE(win,"box = (%i,%i - %i,%i)\n", lps->rcPaint.left, lps->rcPaint.top, TRACE(win,"box = (%i,%i - %i,%i)\n", lps->rcPaint.left, lps->rcPaint.top,
lps->rcPaint.right, lps->rcPaint.bottom ); lps->rcPaint.right, lps->rcPaint.bottom );
DPtoLP16( lps->hdc, (LPPOINT16)&lps->rcPaint, 2 );
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND) if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
{ {
wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND; wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;

View File

@ -147,9 +147,7 @@ BOOL32 WINAPI ScrollDC32( HDC32 hdc, INT32 dx, INT32 dy, const RECT32 *rc,
const RECT32 *prLClip, HRGN32 hrgnUpdate, const RECT32 *prLClip, HRGN32 hrgnUpdate,
LPRECT32 rcUpdate ) LPRECT32 rcUpdate )
{ {
RECT32 rDClip, rLClip; RECT32 rClip;
HRGN32 hrgnClip = 0;
HRGN32 hrgnScrollClip = 0;
POINT32 src, dest; POINT32 src, dest;
INT32 ldx, ldy; INT32 ldx, ldy;
DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC); DC *dc = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
@ -171,49 +169,23 @@ BOOL32 WINAPI ScrollDC32( HDC32 hdc, INT32 dx, INT32 dy, const RECT32 *rc,
/* compute device clipping region */ /* compute device clipping region */
if ( rc ) if ( rc )
{ rClip = *rc;
rLClip = *rc;
rDClip.left = XLPTODP(dc, rc->left); rDClip.right = XLPTODP(dc, rc->right);
rDClip.top = YLPTODP(dc, rc->top); rDClip.bottom = YLPTODP(dc, rc->bottom);
}
else /* maybe we should just return FALSE? */ else /* maybe we should just return FALSE? */
{ GetClipBox32( hdc, &rClip );
GetClipBox32( hdc, &rDClip );
rLClip.left = XDPTOLP(dc, rDClip.left); rLClip.right = XDPTOLP(dc, rDClip.right);
rLClip.top = YDPTOLP(dc, rDClip.top); rLClip.bottom = YDPTOLP(dc, rDClip.bottom);
}
if (prLClip) if (prLClip)
{ IntersectRect32(&rClip,&rClip,prLClip);
RECT32 r;
r.left = XLPTODP(dc, prLClip->left); r.right = XLPTODP(dc, prLClip->right); if( rClip.left >= rClip.right || rClip.top >= rClip.bottom )
r.top = YLPTODP(dc, prLClip->top); r.bottom = YLPTODP(dc, prLClip->bottom);
IntersectRect32(&rLClip,&rLClip,prLClip);
IntersectRect32(&rDClip,&rDClip,&r);
}
if( rDClip.left >= rDClip.right || rDClip.top >= rDClip.bottom )
{ {
GDI_HEAP_UNLOCK( hdc ); GDI_HEAP_UNLOCK( hdc );
return FALSE; return FALSE;
} }
hrgnClip = GetClipRgn16(hdc); SaveVisRgn( hdc );
hrgnScrollClip = CreateRectRgnIndirect32(&rDClip); IntersectVisRect( hdc, rClip.left, rClip.top,
rClip.right, rClip.bottom );
if( hrgnClip )
{
/* change device clipping region directly */
CombineRgn32( hrgnScrollClip, hrgnClip, 0, RGN_COPY );
SetRectRgn32( hrgnClip, rDClip.left, rDClip.top,
rDClip.right, rDClip.bottom );
CLIPPING_UpdateGCRegion( dc );
}
else
SelectClipRgn32( hdc, hrgnScrollClip );
/* translate coordinates */ /* translate coordinates */
@ -221,22 +193,22 @@ BOOL32 WINAPI ScrollDC32( HDC32 hdc, INT32 dx, INT32 dy, const RECT32 *rc,
ldy = dy * dc->wndExtY / dc->vportExtY; ldy = dy * dc->wndExtY / dc->vportExtY;
if (dx > 0) if (dx > 0)
dest.x = (src.x = rLClip.left) + ldx; dest.x = (src.x = rClip.left) + ldx;
else else
src.x = (dest.x = rLClip.left) - ldx; src.x = (dest.x = rClip.left) - ldx;
if (dy > 0) if (dy > 0)
dest.y = (src.y = rLClip.top) + ldy; dest.y = (src.y = rClip.top) + ldy;
else else
src.y = (dest.y = rLClip.top) - ldy; src.y = (dest.y = rClip.top) - ldy;
/* copy bits */ /* copy bits */
if( rDClip.right - rDClip.left > dx && if( rClip.right - rClip.left > ldx &&
rDClip.bottom - rDClip.top > dy ) rClip.bottom - rClip.top > ldy )
{ {
ldx = rLClip.right - rLClip.left - ldx; ldx = rClip.right - rClip.left - ldx;
ldy = rLClip.bottom - rLClip.top - ldy; ldy = rClip.bottom - rClip.top - ldy;
if (!BitBlt32( hdc, dest.x, dest.y, ldx, ldy, if (!BitBlt32( hdc, dest.x, dest.y, ldx, ldy,
hdc, src.x, src.y, SRCCOPY)) hdc, src.x, src.y, SRCCOPY))
@ -248,52 +220,32 @@ BOOL32 WINAPI ScrollDC32( HDC32 hdc, INT32 dx, INT32 dy, const RECT32 *rc,
/* restore clipping region */ /* restore clipping region */
if( hrgnClip ) RestoreVisRgn( hdc );
{
CombineRgn32( hrgnClip, hrgnScrollClip, 0, RGN_COPY );
CLIPPING_UpdateGCRegion( dc );
SetRectRgn32( hrgnScrollClip, rDClip.left, rDClip.top,
rDClip.right, rDClip.bottom );
}
else
SelectClipRgn32( hdc, 0 );
/* compute update areas */ /* compute update areas */
if (hrgnUpdate || rcUpdate) if ( (hrgnUpdate || rcUpdate) && dc->w.hVisRgn )
{ {
HRGN32 hrgn = (hrgnUpdate) ? hrgnUpdate : CreateRectRgn32( 0,0,0,0 ); HRGN32 hrgn = (hrgnUpdate) ? hrgnUpdate : CreateRectRgn32( 0,0,0,0 );
HRGN32 hrgnClip;
if( dc->w.hVisRgn ) LPtoDP32( hdc, (LPPOINT32)&rClip, 2 );
{ OffsetRect32( &rClip, dc->w.DCOrgX, dc->w.DCOrgY );
CombineRgn32( hrgn, dc->w.hVisRgn, hrgnScrollClip, RGN_AND ); hrgnClip = CreateRectRgnIndirect32( &rClip );
OffsetRgn32( hrgn, dx, dy );
CombineRgn32( hrgn, dc->w.hVisRgn, hrgn, RGN_DIFF ); CombineRgn32( hrgn, dc->w.hVisRgn, hrgnClip, RGN_AND );
CombineRgn32( hrgn, hrgn, hrgnScrollClip, RGN_AND ); OffsetRgn32( hrgn, dx, dy );
} CombineRgn32( hrgn, dc->w.hVisRgn, hrgn, RGN_DIFF );
else CombineRgn32( hrgn, hrgn, hrgnClip, RGN_AND );
{ OffsetRgn32( hrgn, -dc->w.DCOrgX, -dc->w.DCOrgY );
RECT32 rect;
rect = rDClip; /* vertical band */ if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate );
if (dx > 0) rect.right = rect.left + dx;
else if (dx < 0) rect.left = rect.right + dx;
else SetRectEmpty32( &rect );
SetRectRgn32( hrgn, rect.left, rect.top, rect.right, rect.bottom );
rect = rDClip; /* horizontal band */
if (dy > 0) rect.bottom = rect.top + dy;
else if (dy < 0) rect.top = rect.bottom + dy;
else SetRectEmpty32( &rect );
REGION_UnionRectWithRgn( hrgn, &rect );
}
if (rcUpdate) GetRgnBox32( hrgn, rcUpdate );
if (!hrgnUpdate) DeleteObject32( hrgn ); if (!hrgnUpdate) DeleteObject32( hrgn );
DeleteObject32( hrgnClip );
} }
DeleteObject32( hrgnScrollClip );
GDI_HEAP_UNLOCK( hdc ); GDI_HEAP_UNLOCK( hdc );
return TRUE; return TRUE;
} }
@ -415,10 +367,12 @@ rect?rect->left:0, rect?rect->top:0, rect ?rect->right:0, rect ?rect->bottom:0,
if( dc->w.hVisRgn && bUpdate ) if( dc->w.hVisRgn && bUpdate )
{ {
OffsetRgn32( hrgnClip, dc->w.DCOrgX, dc->w.DCOrgY );
CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnClip, RGN_AND ); CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnClip, RGN_AND );
OffsetRgn32( hrgnUpdate, dx, dy ); OffsetRgn32( hrgnUpdate, dx, dy );
CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnUpdate, RGN_DIFF ); CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnUpdate, RGN_DIFF );
CombineRgn32( hrgnUpdate, hrgnUpdate, hrgnClip, RGN_AND ); CombineRgn32( hrgnUpdate, hrgnUpdate, hrgnClip, RGN_AND );
OffsetRgn32( hrgnUpdate, -dc->w.DCOrgX, -dc->w.DCOrgY );
if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate ); if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate );
} }