diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c index a97231c69bc..6b99e4385e7 100644 --- a/dlls/gdi32/bitblt.c +++ b/dlls/gdi32/bitblt.c @@ -146,13 +146,7 @@ static BOOL get_vis_rectangles( DC *dc_dst, struct bitblt_coords *dst, } get_bounding_rect( &rect, src->x, src->y, src->width, src->height ); - /* source is not clipped */ - if (dc_src->header.type == OBJ_MEMDC) - intersect_rect( &src->visrect, &rect, &dc_src->vis_rect ); - else - src->visrect = rect; /* FIXME: clip to device size */ - - if (is_rect_empty( &src->visrect )) return FALSE; + if (!clip_device_rect( dc_src, &src->visrect, &rect )) return FALSE; if (is_rect_empty( &dst->visrect )) return FALSE; return intersect_vis_rectangles( dst, src ); @@ -932,9 +926,9 @@ BOOL WINAPI GdiAlphaBlend(HDC hdcDst, int xDst, int yDst, int widthDst, int heig if (src.x < 0 || src.y < 0 || src.width < 0 || src.height < 0 || src.log_width < 0 || src.log_height < 0 || - (dcSrc->header.type == OBJ_MEMDC && - (src.width > dcSrc->vis_rect.right - dcSrc->vis_rect.left - src.x || - src.height > dcSrc->vis_rect.bottom - dcSrc->vis_rect.top - src.y))) + (!is_rect_empty( &dcSrc->device_rect ) && + (src.width > dcSrc->device_rect.right - dcSrc->vis_rect.left - src.x || + src.height > dcSrc->device_rect.bottom - dcSrc->vis_rect.top - src.y))) { WARN( "Invalid src coords: (%d,%d), size %dx%d\n", src.x, src.y, src.width, src.height ); SetLastError( ERROR_INVALID_PARAMETER ); diff --git a/dlls/gdi32/bitmap.c b/dlls/gdi32/bitmap.c index cee92048490..68e9c9adf1d 100644 --- a/dlls/gdi32/bitmap.c +++ b/dlls/gdi32/bitmap.c @@ -609,6 +609,7 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc ) dc->vis_rect.top = 0; dc->vis_rect.right = bitmap->dib.dsBm.bmWidth; dc->vis_rect.bottom = bitmap->dib.dsBm.bmHeight; + dc->device_rect = dc->vis_rect; GDI_ReleaseObj( handle ); DC_InitDC( dc ); GDI_dec_ref_count( ret ); diff --git a/dlls/gdi32/clipping.c b/dlls/gdi32/clipping.c index c413e1a8306..1cb420c4944 100644 --- a/dlls/gdi32/clipping.c +++ b/dlls/gdi32/clipping.c @@ -29,15 +29,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(clipping); -/* return the DC visible rectangle if not empty */ -static inline BOOL get_dc_visrect( DC *dc, RECT *rect ) +/* return the DC device rectangle if not empty */ +static inline BOOL get_dc_device_rect( DC *dc, RECT *rect ) { - if (dc->header.type != OBJ_MEMDC) return FALSE; - rect->left = 0; - rect->top = 0; - rect->right = dc->vis_rect.right - dc->vis_rect.left; - rect->bottom = dc->vis_rect.bottom - dc->vis_rect.top; - return TRUE; + *rect = dc->device_rect; + offset_rect( rect, -dc->vis_rect.left, -dc->vis_rect.top ); + return !is_rect_empty( rect ); } /*********************************************************************** @@ -63,6 +60,20 @@ static inline RECT get_clip_rect( DC * dc, int left, int top, int right, int bot return rect; } +/*********************************************************************** + * clip_device_rect + * + * Clip a rectangle to the whole DC surface. + */ +BOOL clip_device_rect( DC *dc, RECT *dst, const RECT *src ) +{ + RECT clip; + + if (get_dc_device_rect( dc, &clip )) return intersect_rect( dst, src, &clip ); + *dst = *src; + return TRUE; +} + /*********************************************************************** * clip_visrect * @@ -72,11 +83,9 @@ BOOL clip_visrect( DC *dc, RECT *dst, const RECT *src ) { RECT clip; - if (get_dc_visrect( dc, &clip )) intersect_rect( dst, src, &clip ); - else *dst = *src; - - if (GetRgnBox( get_dc_region(dc), &clip )) intersect_rect( dst, dst, &clip ); - return !is_rect_empty( dst ); + if (!clip_device_rect( dc, dst, src )) return FALSE; + if (GetRgnBox( get_dc_region(dc), &clip )) return intersect_rect( dst, dst, &clip ); + return TRUE; } /*********************************************************************** @@ -117,7 +126,7 @@ static inline void create_default_clip_region( DC * dc ) { RECT rect; - if (!get_dc_visrect( dc, &rect )) + if (!get_dc_device_rect( dc, &rect )) { rect.left = 0; rect.top = 0; @@ -361,7 +370,7 @@ BOOL WINAPI PtVisible( HDC hdc, INT x, INT y ) pt.y = y; LPtoDP( hdc, &pt, 1 ); update_dc( dc ); - ret = (!get_dc_visrect( dc, &visrect ) || + ret = (!get_dc_device_rect( dc, &visrect ) || (pt.x >= visrect.left && pt.x < visrect.right && pt.y >= visrect.top && pt.y < visrect.bottom)); if (ret && get_dc_region( dc )) ret = PtInRegion( get_dc_region( dc ), pt.x, pt.y ); @@ -385,7 +394,7 @@ BOOL WINAPI RectVisible( HDC hdc, const RECT* rect ) LPtoDP( hdc, (POINT *)&tmpRect, 2 ); update_dc( dc ); - ret = (!get_dc_visrect( dc, &visrect ) || intersect_rect( &visrect, &visrect, &tmpRect )); + ret = (!get_dc_device_rect( dc, &visrect ) || intersect_rect( &visrect, &visrect, &tmpRect )); if (ret && get_dc_region( dc )) ret = RectInRegion( get_dc_region( dc ), &tmpRect ); release_dc_ptr( dc ); return ret; @@ -406,7 +415,7 @@ INT WINAPI GetClipBox( HDC hdc, LPRECT rect ) if (get_dc_region( dc )) { ret = GetRgnBox( get_dc_region( dc ), rect ); - if (get_dc_visrect( dc, &visrect ) && !intersect_rect( rect, rect, &visrect )) + if (get_dc_device_rect( dc, &visrect ) && !intersect_rect( rect, rect, &visrect )) ret = NULLREGION; } else @@ -492,7 +501,6 @@ INT WINAPI GetMetaRgn( HDC hdc, HRGN hRgn ) INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode) { INT ret = 1; - RECT visrect; DC *dc = get_dc_ptr( hDC ); if (!dc) return -1; @@ -516,13 +524,16 @@ INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode) case SYSRGN: /* == 4 */ update_dc( dc ); if (dc->hVisRgn) + { CombineRgn( hRgn, dc->hVisRgn, 0, RGN_COPY ); - else if (get_dc_visrect( dc, &visrect )) - SetRectRgn( hRgn, visrect.left, visrect.top, visrect.right, visrect.bottom ); + /* On Windows NT/2000, the SYSRGN returned is in screen coordinates */ + if (!(GetVersion() & 0x80000000)) OffsetRgn( hRgn, dc->vis_rect.left, dc->vis_rect.top ); + } + else if (!is_rect_empty( &dc->device_rect )) + SetRectRgn( hRgn, dc->device_rect.left, dc->device_rect.top, + dc->device_rect.right, dc->device_rect.bottom ); else ret = 0; - /* On Windows NT/2000, the SYSRGN returned is in screen coordinates */ - if (ret && !(GetVersion() & 0x80000000)) OffsetRgn( hRgn, dc->vis_rect.left, dc->vis_rect.top ); break; default: WARN("Unknown code %d\n", iCode); diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 33c1033bbe8..95dd3e2f9b5 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -698,6 +698,7 @@ HDC WINAPI CreateCompatibleDC( HDC hdc ) dc->vis_rect.top = 0; dc->vis_rect.right = 1; dc->vis_rect.bottom = 1; + dc->device_rect = dc->vis_rect; ret = dc->hSelf; diff --git a/dlls/gdi32/dib.c b/dlls/gdi32/dib.c index d8d283e1823..f7e08a53fbb 100644 --- a/dlls/gdi32/dib.c +++ b/dlls/gdi32/dib.c @@ -1624,6 +1624,7 @@ static HGDIOBJ DIB_SelectObject( HGDIOBJ handle, HDC hdc ) dc->vis_rect.top = 0; dc->vis_rect.right = bitmap->dib.dsBm.bmWidth; dc->vis_rect.bottom = bitmap->dib.dsBm.bmHeight; + dc->device_rect = dc->vis_rect; GDI_ReleaseObj( handle ); DC_InitDC( dc ); GDI_dec_ref_count( ret ); diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 20b522da8cd..2589238e6d7 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -104,6 +104,7 @@ typedef struct tagDC SIZE virtual_res; /* Initially HORZRES,VERTRES. Changed by SetVirtualResolution */ SIZE virtual_size; /* Initially HORZSIZE,VERTSIZE. Changed by SetVirtualResolution */ RECT vis_rect; /* visible rectangle in screen coords */ + RECT device_rect; /* rectangle for the whole device */ FLOAT miterLimit; int flags; @@ -217,6 +218,7 @@ extern void free_brush_pattern( struct brush_pattern *pattern ) DECLSPEC_HIDDEN; extern BOOL get_brush_bitmap_info( HBRUSH handle, BITMAPINFO *info, void **bits, UINT *usage ) DECLSPEC_HIDDEN; /* clipping.c */ +extern BOOL clip_device_rect( DC *dc, RECT *dst, const RECT *src ) DECLSPEC_HIDDEN; extern BOOL clip_visrect( DC *dc, RECT *dst, const RECT *src ) DECLSPEC_HIDDEN; extern void update_dc_clipping( DC * dc ) DECLSPEC_HIDDEN;