From d4663668b827a7095090969811ac6b5aaee9cca4 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Sun, 11 Oct 1998 18:47:02 +0000 Subject: [PATCH] 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. --- graphics/path.c | 14 +---- graphics/x11drv/bitblt.c | 2 - graphics/x11drv/clipping.c | 4 +- graphics/x11drv/graphics.c | 19 ++++--- graphics/x11drv/text.c | 13 ++--- if1632/gdi.spec | 2 +- include/dc.h | 2 + include/windows.h | 1 + objects/clipping.c | 109 ++++++++++++++++++++++++----------- objects/dc.c | 25 +++++++- objects/dcvalues.c | 7 +-- windows/dce.c | 42 ++++++++++---- windows/painting.c | 4 +- windows/scroll.c | 114 +++++++++++-------------------------- 14 files changed, 188 insertions(+), 170 deletions(-) diff --git a/graphics/path.c b/graphics/path.c index bd5dffdef8c..23698d32454 100644 --- a/graphics/path.c +++ b/graphics/path.c @@ -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 */ diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c index 87ddb157d3e..fc146d768f1 100644 --- a/graphics/x11drv/bitblt.c +++ b/graphics/x11drv/bitblt.c @@ -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 */ diff --git a/graphics/x11drv/clipping.c b/graphics/x11drv/clipping.c index bf5f880399e..60f931907f9 100644 --- a/graphics/x11drv/clipping.c +++ b/graphics/x11drv/clipping.c @@ -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 ); diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c index b4b70d5367b..750c757841a 100644 --- a/graphics/x11drv/graphics.c +++ b/graphics/x11drv/graphics.c @@ -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 ); } diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c index 0b93e1060b3..068b4ccce8a 100644 --- a/graphics/x11drv/text.c +++ b/graphics/x11drv/text.c @@ -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; } diff --git a/if1632/gdi.spec b/if1632/gdi.spec index b200bda68ab..14fdda16e4b 100644 --- a/if1632/gdi.spec +++ b/if1632/gdi.spec @@ -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 diff --git a/include/dc.h b/include/dc.h index f94e0a2db43..74eadcdeb9e 100644 --- a/include/dc.h +++ b/include/dc.h @@ -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 */ diff --git a/include/windows.h b/include/windows.h index 2a23cc1e658..0bc876cc741 100644 --- a/include/windows.h +++ b/include/windows.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) diff --git a/objects/clipping.c b/objects/clipping.c index 3f3ad300ddc..1d874101d99 100644 --- a/objects/clipping.c +++ b/objects/clipping.c @@ -60,27 +60,7 @@ INT16 WINAPI SelectClipRgn16( HDC16 hdc, HRGN16 hrgn ) */ INT32 WINAPI SelectClipRgn32( HDC32 hdc, HRGN32 hrgn ) { - INT32 retval; - 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; + return ExtSelectClipRgn( hdc, hrgn, RGN_COPY ); } /****************************************************************************** @@ -88,9 +68,44 @@ INT32 WINAPI SelectClipRgn32( HDC32 hdc, HRGN32 hrgn ) */ INT32 WINAPI ExtSelectClipRgn( HDC32 hdc, HRGN32 hrgn, INT32 fnMode ) { - if (fnMode != RGN_COPY) - FIXME(clipping, "Unimplemented mode: %d\n", fnMode); - return SelectClipRgn32( hdc, hrgn ); + INT32 retval; + DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ); + 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; 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; diff --git a/objects/dc.c b/objects/dc.c index a7874751f40..230f50291c5 100644 --- a/objects/dc.c +++ b/objects/dc.c @@ -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 */ +} + diff --git a/objects/dcvalues.c b/objects/dcvalues.c index df7de094cff..3abf31a1615 100644 --- a/objects/dcvalues.c +++ b/objects/dcvalues.c @@ -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 */ - diff --git a/windows/dce.c b/windows/dce.c index 25145c8d627..fbb8e09a387 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -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 ); } diff --git a/windows/painting.c b/windows/painting.c index c97dad1598b..9ddd9f1cdbc 100644 --- a/windows/painting.c +++ b/windows/painting.c @@ -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; diff --git a/windows/scroll.c b/windows/scroll.c index d8b06b3bba2..b67d00ae423 100644 --- a/windows/scroll.c +++ b/windows/scroll.c @@ -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); + + SaveVisRgn( hdc ); + 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 */ @@ -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; + 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; /* 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 ); + if( rcUpdate ) GetRgnBox32( hrgnUpdate, rcUpdate ); - 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 ); + 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 ); }