Commit d4663668 authored by Ulrich Weigand's avatar Ulrich Weigand Committed by Alexandre Julliard

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.
parent 832e4985
......@@ -424,7 +424,7 @@ BOOL32 WINAPI FillPath32(HDC32 hdc)
BOOL32 WINAPI SelectClipPath32(HDC32 hdc, INT32 iMode)
{
GdiPath *pPath;
HRGN32 hrgnPath, hrgnClip;
HRGN32 hrgnPath;
BOOL32 success;
/* Get pointer to path */
......@@ -444,17 +444,7 @@ BOOL32 WINAPI SelectClipPath32(HDC32 hdc, INT32 iMode)
/* Construct a region from the path */
if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgnPath))
{
hrgnClip=CreateRectRgn32(0, 0, 0, 0);
if(hrgnClip==(HRGN32)0)
success=FALSE;
else
{
success=(GetClipRgn32(hdc, hrgnClip)!=-1) &&
(CombineRgn32(hrgnClip, hrgnClip, hrgnPath, iMode)!=ERROR) &&
(SelectClipRgn32(hdc, hrgnClip)!=ERROR);
DeleteObject32(hrgnClip);
}
success = ExtSelectClipRgn( hdc, hrgnPath, iMode ) != ERROR;
DeleteObject32(hrgnPath);
/* Empty the path */
......
......@@ -1035,7 +1035,6 @@ static BOOL32 BITBLT_GetVisRectangles( DC *dcDst, INT32 xDst, INT32 yDst,
if (widthDst < 0) SWAP_INT32( &rect.left, &rect.right );
if (heightDst < 0) SWAP_INT32( &rect.top, &rect.bottom );
GetRgnBox32( dcDst->w.hGCClipRgn, &clipRect );
OffsetRect32( &clipRect, dcDst->w.DCOrgX, dcDst->w.DCOrgY );
if (!IntersectRect32( visRectDst, &rect, &clipRect )) return FALSE;
/* 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 );
/* Apparently the clip region is only for output, so use hVisRgn here */
GetRgnBox32( dcSrc->w.hVisRgn, &clipRect );
OffsetRect32( &clipRect, dcSrc->w.DCOrgX, dcSrc->w.DCOrgY );
if (!IntersectRect32( visRectSrc, &rect, &clipRect )) return FALSE;
/* Intersect the rectangles */
......
......@@ -54,8 +54,8 @@ void X11DRV_SetDeviceClipping( DC * dc )
else
pXrect = NULL;
TSXSetClipRectangles( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY,
pXrect, obj->rgn->numRects, YXBanded );
TSXSetClipRectangles( display, dc->u.x.gc, 0, 0,
pXrect, obj->rgn->numRects, YXBanded );
if(pXrect)
HeapFree( GetProcessHeap(), 0, pXrect );
......
......@@ -619,7 +619,8 @@ X11DRV_PaintRgn( DC *dc, HRGN32 hrgn )
if (!(tmpVisRgn = CreateRectRgn32( 0, 0, 0, 0 ))) return FALSE;
/* 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 );
return FALSE;
}
......@@ -638,8 +639,8 @@ X11DRV_PaintRgn( DC *dc, HRGN32 hrgn )
GetRgnBox32( dc->w.hGCClipRgn, &box );
if (DC_SetupGCForBrush( dc ))
TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top,
box.right-box.left, box.bottom-box.top );
box.left, box.top,
box.right-box.left, box.bottom-box.top );
/* 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 (!(image = XGetImage( display, dc->u.x.drawable,
dc->w.DCOrgX + rect.left,
dc->w.DCOrgY + rect.top,
rect.left,
rect.top,
rect.right - rect.left,
rect.bottom - rect.top,
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 */
XSetFunction( display, dc->u.x.gc, GXcopy );
X11DRV_InternalFloodFill(image, dc,
XLPTODP(dc,params->x) - rect.left,
YLPTODP(dc,params->y) - rect.top,
dc->w.DCOrgX + rect.left,
dc->w.DCOrgY + rect.top,
XLPTODP(dc,params->x) + dc->w.DCOrgX - rect.left,
YLPTODP(dc,params->y) + dc->w.DCOrgY - rect.top,
rect.left,
rect.top,
COLOR_ToPhysical( dc, params->color ),
params->fillType );
}
......
......@@ -28,7 +28,6 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
const RECT32 *lprect, LPCSTR str, UINT32 count,
const INT32 *lpDx )
{
HRGN32 hRgnClip = 0;
int i;
fontObject* pfo;
INT32 width, ascent, descent, xwidth, ywidth;
......@@ -176,9 +175,9 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
if (flags & ETO_CLIPPED)
{
hRgnClip = dc->w.hClipRgn;
CLIPPING_IntersectClipRect( dc, rect.left, rect.top, rect.right,
rect.bottom, CLIP_INTERSECT|CLIP_KEEPRGN );
SaveVisRgn( dc->hSelf );
CLIPPING_IntersectVisRect( dc, rect.left, rect.top, rect.right,
rect.bottom, FALSE );
}
/* Draw the text background if necessary */
......@@ -331,10 +330,8 @@ X11DRV_ExtTextOut( DC *dc, INT32 x, INT32 y, UINT32 flags,
}
if (flags & ETO_CLIPPED)
{
SelectClipRgn32( dc->hSelf, hRgnClip );
DeleteObject32( hRgnClip );
}
RestoreVisRgn( dc->hSelf );
return TRUE;
}
......@@ -160,7 +160,7 @@ file gdi.exe
190 pascal16 SetDCHook(word segptr long) THUNK_SetDCHook
191 pascal GetDCHook(word ptr) THUNK_GetDCHook
192 pascal16 SetHookFlags(word word) SetHookFlags
193 stub SetBoundsRect
193 pascal16 SetBoundsRect(word ptr word) SetBoundsRect16
194 pascal16 GetBoundsRect(word ptr word) GetBoundsRect16
195 stub SelectBitmap
196 pascal16 SetMetaFileBitsBetter(word) SetMetaFileBitsBetter
......
......@@ -28,6 +28,8 @@ extern const int DC_XROPfunction[];
/* objects/clipping.c */
INT32 CLIPPING_IntersectClipRect( DC * dc, INT32 left, INT32 top,
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 );
#endif /* __WINE_DC_H */
......@@ -6584,6 +6584,7 @@ BOOL32 WINAPI EnumTimeFormats32W(TIMEFMT_ENUMPROC32W lpTimeFmtEnumProc, LCI
VOID WINAPI ExitProcess(DWORD);
VOID WINAPI ExitThread(DWORD);
BOOL32 WINAPI ExitWindowsEx(UINT32,DWORD);
INT32 WINAPI ExtSelectClipRgn(HDC32,HRGN32,INT32);
DWORD WINAPI ExpandEnvironmentStrings32A(LPCSTR,LPSTR,DWORD);
DWORD WINAPI ExpandEnvironmentStrings32W(LPCWSTR,LPWSTR,DWORD);
#define ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings)
......
......@@ -60,39 +60,54 @@ INT16 WINAPI SelectClipRgn16( HDC16 hdc, HRGN16 hrgn )
*/
INT32 WINAPI SelectClipRgn32( HDC32 hdc, HRGN32 hrgn )
{
return ExtSelectClipRgn( hdc, hrgn, RGN_COPY );
}
/******************************************************************************
* ExtSelectClipRgn [GDI32.97]
*/
INT32 WINAPI ExtSelectClipRgn( HDC32 hdc, HRGN32 hrgn, INT32 fnMode )
{
INT32 retval;
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return ERROR;
TRACE(clipping, "%04x %04x\n", hdc, hrgn );
TRACE( clipping, "%04x %04x %d\n", hdc, hrgn, fnMode );
if (hrgn)
if (!hrgn)
{
if (!dc->w.hClipRgn) dc->w.hClipRgn = CreateRectRgn32(0,0,0,0);
retval = CombineRgn32( dc->w.hClipRgn, hrgn, 0, RGN_COPY );
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
else
{
if (dc->w.hClipRgn) DeleteObject16( dc->w.hClipRgn );
dc->w.hClipRgn = 0;
retval = SIMPLEREGION; /* Clip region == whole DC */
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;
}
/******************************************************************************
* ExtSelectClipRgn [GDI32.97]
*/
INT32 WINAPI ExtSelectClipRgn( HDC32 hdc, HRGN32 hrgn, INT32 fnMode )
{
if (fnMode != RGN_COPY)
FIXME(clipping, "Unimplemented mode: %d\n", fnMode);
return SelectClipRgn32( hdc, hrgn );
}
/***********************************************************************
* SelectVisRgn (GDI.105)
*/
......@@ -180,6 +195,11 @@ INT32 CLIPPING_IntersectClipRect( DC * dc, INT32 left, INT32 top,
HRGN32 newRgn;
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 (!dc->w.hClipRgn)
{
......@@ -293,19 +313,21 @@ INT32 WINAPI IntersectClipRect32( HDC32 hdc, INT32 left, INT32 top,
/***********************************************************************
* 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 right, INT32 bottom,
BOOL32 exclude )
INT32 CLIPPING_IntersectVisRect( DC * dc, INT32 left, INT32 top,
INT32 right, INT32 bottom,
BOOL32 exclude )
{
HRGN32 tempRgn, newRgn;
INT32 ret;
left = XLPTODP( dc, left );
right = XLPTODP( dc, right );
top = YLPTODP( dc, top );
bottom = YLPTODP( dc, bottom );
left += dc->w.DCOrgX;
right += dc->w.DCOrgX;
top += dc->w.DCOrgY;
bottom += dc->w.DCOrgY;
if (!(newRgn = CreateRectRgn32( 0, 0, 0, 0 ))) return ERROR;
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 );
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",
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 );
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",
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);
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 */
tmpRect = *rect;
LPtoDP16( hdc, (LPPOINT16)&tmpRect, 2 );
OffsetRect16( &tmpRect, dc->w.DCOrgX, dc->w.DCOrgY );
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 );
if (!dc) return ERROR;
ret = GetRgnBox16( dc->w.hGCClipRgn, rect );
OffsetRect16( rect, -dc->w.DCOrgX, -dc->w.DCOrgY );
DPtoLP16( hdc, (LPPOINT16)rect, 2 );
return ret;
}
......@@ -441,6 +478,7 @@ INT32 WINAPI GetClipBox32( HDC32 hdc, LPRECT32 rect )
DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
if (!dc) return ERROR;
ret = GetRgnBox32( dc->w.hGCClipRgn, rect );
OffsetRect32( rect, -dc->w.DCOrgX, -dc->w.DCOrgY );
DPtoLP32( hdc, (LPPOINT32)rect, 2 );
return ret;
}
......@@ -456,10 +494,13 @@ INT32 WINAPI GetClipRgn32( HDC32 hdc, HRGN32 hRgn )
if( dc->w.hClipRgn )
{
/* 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 )
{
OffsetRgn32( hRgn, -dc->w.DCOrgX, -dc->w.DCOrgY );
return 1;
}
}
else return 0;
return -1;
......
......@@ -546,8 +546,11 @@ HDC16 WINAPI GetDCState( HDC16 hdc )
newdc->w.breakRem = dc->w.breakRem;
newdc->w.MapMode = dc->w.MapMode;
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.DCOrgY = dc->w.DCOrgY;
#endif
newdc->w.CursPosX = dc->w.CursPosX;
newdc->w.CursPosY = dc->w.CursPosY;
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.MapMode = dcs->w.MapMode;
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.DCOrgY = dcs->w.DCOrgY;
#endif
dc->w.CursPosX = dcs->w.CursPosX;
dc->w.CursPosY = dcs->w.CursPosY;
dc->w.ArcDirection = dcs->w.ArcDirection;
......@@ -647,7 +653,15 @@ void WINAPI SetDCState( HDC16 hdc, HDC16 hdcs )
dc->vportExtY = dcs->vportExtY;
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.hBrush );
......@@ -1516,3 +1530,12 @@ UINT16 WINAPI GetBoundsRect16(HDC16 hdc, LPRECT16 rect, UINT16 flags)
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 */
}
......@@ -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, GetWindowOrg, wndOrgX, wndOrgY ) /* GDI.97 */
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_VAL_16( UINT16, GetTextAlign16, w.textAlign ) /* GDI.345 */
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( GetWindowExtEx, wndExtX, wndExtY ) /* GDI.474 GDI32.242 */
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 */
......@@ -497,6 +497,22 @@ HRGN32 DCE_GetVisRgn( HWND32 hwnd, WORD flags )
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
......@@ -535,6 +551,7 @@ static void DCE_SetDrawable( WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOri
dc->w.DCOrgY -= wndPtr->rectWindow.top;
dc->u.x.drawable = wndPtr->window;
#if 0
/* This is needed when we reuse a cached DC because
* SetDCState() called by ReleaseDC() screws up DC
* origins for child windows.
......@@ -542,6 +559,7 @@ static void DCE_SetDrawable( WND *wndPtr, DC *dc, WORD flags, BOOL32 bSetClipOri
if( bSetClipOrigin )
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 ret;
POINT32 pt = {0, 0};
HRGN32 hRgnClip = GetClipRgn16( hDC );
DCE *dce = firstDCE;
while (dce && (dce->hDC != hDC)) dce = dce->next;
......@@ -570,14 +586,8 @@ INT16 DCE_ExcludeRgn( HDC32 hDC, WND* wnd, HRGN32 hRgn )
}
else return ERROR;
OffsetRgn32(hRgn, pt.x, pt.y);
if( hRgnClip ) ret = CombineRgn32( hRgnClip, hRgnClip, hRgn, RGN_DIFF );
else
{
hRgnClip = InquireVisRgn( hDC );
ret = CombineRgn32( hRgn, hRgnClip, hRgn, RGN_DIFF );
SelectClipRgn32( hDC, hRgn );
}
return ret;
return ExtSelectClipRgn( hDC, hRgn, RGN_DIFF );
}
/***********************************************************************
......@@ -755,6 +765,7 @@ HDC32 WINAPI GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags )
else
OffsetRgn32( hrgnVisible, -wndPtr->rectClient.left,
-wndPtr->rectClient.top );
DCE_OffsetVisRgn( hdc, hrgnVisible );
}
else
hrgnVisible = CreateRectRgn32( 0, 0, 0, 0 );
......@@ -764,7 +775,11 @@ HDC32 WINAPI GetDCEx32( HWND32 hwnd, HRGN32 hrgnClip, DWORD flags )
(rootWindow == DefaultRootWindow(display)))
hrgnVisible = CreateRectRgn32( 0, 0, SYSMETRICS_CXSCREEN,
SYSMETRICS_CYSCREEN );
else hrgnVisible = DCE_GetVisRgn( hwnd, flags );
else
{
hrgnVisible = DCE_GetVisRgn( hwnd, flags );
DCE_OffsetVisRgn( hdc, hrgnVisible );
}
dc->w.flags &= ~DC_DIRTY;
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);
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 );
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_DCEDIRTY;
DCE_OffsetVisRgn( hDC, hVisRgn );
SelectVisRgn(hDC, hVisRgn);
DeleteObject32( hVisRgn );
}
......
......@@ -138,13 +138,11 @@ HDC16 WINAPI BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps )
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,
lps->rcPaint.right, lps->rcPaint.bottom );
DPtoLP16( lps->hdc, (LPPOINT16)&lps->rcPaint, 2 );
if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
{
wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
......
......@@ -147,9 +147,7 @@ BOOL32 WINAPI ScrollDC32( HDC32 hdc, INT32 dx, INT32 dy, const RECT32 *rc,
const RECT32 *prLClip, HRGN32 hrgnUpdate,
LPRECT32 rcUpdate )
{
RECT32 rDClip, rLClip;
HRGN32 hrgnClip = 0;
HRGN32 hrgnScrollClip = 0;
RECT32 rClip;
POINT32 src, dest;
INT32 ldx, ldy;
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 */
if ( 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);
}
rClip = *rc;
else /* maybe we should just return FALSE? */
{
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);
}
GetClipBox32( hdc, &rClip );
if (prLClip)
{
RECT32 r;
IntersectRect32(&rClip,&rClip,prLClip);
r.left = XLPTODP(dc, prLClip->left); r.right = XLPTODP(dc, prLClip->right);
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 )
if( rClip.left >= rClip.right || rClip.top >= rClip.bottom )
{
GDI_HEAP_UNLOCK( hdc );
return FALSE;
}
hrgnClip = GetClipRgn16(hdc);
hrgnScrollClip = CreateRectRgnIndirect32(&rDClip);
if( hrgnClip )
{
/* change device clipping region directly */
SaveVisRgn( hdc );
IntersectVisRect( hdc, rClip.left, rClip.top,
rClip.right, rClip.bottom );
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 */
......@@ -221,22 +193,22 @@ BOOL32 WINAPI ScrollDC32( HDC32 hdc, INT32 dx, INT32 dy, const RECT32 *rc,
ldy = dy * dc->wndExtY / dc->vportExtY;
if (dx > 0)
dest.x = (src.x = rLClip.left) + ldx;
dest.x = (src.x = rClip.left) + ldx;
else
src.x = (dest.x = rLClip.left) - ldx;
src.x = (dest.x = rClip.left) - ldx;
if (dy > 0)
dest.y = (src.y = rLClip.top) + ldy;
dest.y = (src.y = rClip.top) + ldy;
else
src.y = (dest.y = rLClip.top) - ldy;
src.y = (dest.y = rClip.top) - ldy;
/* copy bits */
if( rDClip.right - rDClip.left > dx &&
rDClip.bottom - rDClip.top > dy )
if( rClip.right - rClip.left > ldx &&
rClip.bottom - rClip.top > ldy )
{
ldx = rLClip.right - rLClip.left - ldx;
ldy = rLClip.bottom - rLClip.top - ldy;
ldx = rClip.right - rClip.left - ldx;
ldy = rClip.bottom - rClip.top - ldy;
if (!BitBlt32( hdc, dest.x, dest.y, ldx, ldy,
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 */
if( hrgnClip )
{
CombineRgn32( hrgnClip, hrgnScrollClip, 0, RGN_COPY );
CLIPPING_UpdateGCRegion( dc );
SetRectRgn32( hrgnScrollClip, rDClip.left, rDClip.top,
rDClip.right, rDClip.bottom );
}
else
SelectClipRgn32( hdc, 0 );
RestoreVisRgn( hdc );
/* compute update areas */
if (hrgnUpdate || rcUpdate)
if ( (hrgnUpdate || rcUpdate) && dc->w.hVisRgn )
{
HRGN32 hrgn = (hrgnUpdate) ? hrgnUpdate : CreateRectRgn32( 0,0,0,0 );
HRGN32 hrgnClip;
if( dc->w.hVisRgn )
{
CombineRgn32( hrgn, dc->w.hVisRgn, hrgnScrollClip, RGN_AND );
OffsetRgn32( hrgn, dx, dy );
CombineRgn32( hrgn, dc->w.hVisRgn, hrgn, RGN_DIFF );
CombineRgn32( hrgn, hrgn, hrgnScrollClip, RGN_AND );
}
else
{
RECT32 rect;
rect = rDClip; /* vertical band */
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 );
LPtoDP32( hdc, (LPPOINT32)&rClip, 2 );
OffsetRect32( &rClip, dc->w.DCOrgX, dc->w.DCOrgY );
hrgnClip = CreateRectRgnIndirect32( &rClip );
CombineRgn32( hrgn, dc->w.hVisRgn, hrgnClip, RGN_AND );
OffsetRgn32( hrgn, dx, dy );
CombineRgn32( hrgn, dc->w.hVisRgn, hrgn, RGN_DIFF );
CombineRgn32( hrgn, hrgn, hrgnClip, RGN_AND );
OffsetRgn32( hrgn, -dc->w.DCOrgX, -dc->w.DCOrgY );
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( hrgnUpdate, rcUpdate );
if (rcUpdate) GetRgnBox32( hrgn, rcUpdate );
if (!hrgnUpdate) DeleteObject32( hrgn );
DeleteObject32( hrgnClip );
}
DeleteObject32( hrgnScrollClip );
GDI_HEAP_UNLOCK( hdc );
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 )
{
OffsetRgn32( hrgnClip, dc->w.DCOrgX, dc->w.DCOrgY );
CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnClip, RGN_AND );
OffsetRgn32( hrgnUpdate, dx, dy );
CombineRgn32( hrgnUpdate, dc->w.hVisRgn, hrgnUpdate, RGN_DIFF );
CombineRgn32( hrgnUpdate, hrgnUpdate, hrgnClip, RGN_AND );
OffsetRgn32( hrgnUpdate, -dc->w.DCOrgX, -dc->w.DCOrgY );
if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate );
}
......
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