Alexandre Julliard : gdi32: Add support for clipping source coordinates to the DC device rectangle.
Alexandre Julliard
julliard at winehq.org
Tue May 1 13:12:13 CDT 2012
Module: wine
Branch: master
Commit: 41e5bc06d8928d6d9b56b8910164683cf66b4cd8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=41e5bc06d8928d6d9b56b8910164683cf66b4cd8
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Apr 30 21:17:00 2012 +0200
gdi32: Add support for clipping source coordinates to the DC device rectangle.
---
dlls/gdi32/bitblt.c | 14 +++--------
dlls/gdi32/bitmap.c | 1 +
dlls/gdi32/clipping.c | 55 +++++++++++++++++++++++++++------------------
dlls/gdi32/dc.c | 1 +
dlls/gdi32/dib.c | 1 +
dlls/gdi32/gdi_private.h | 2 +
6 files changed, 42 insertions(+), 32 deletions(-)
diff --git a/dlls/gdi32/bitblt.c b/dlls/gdi32/bitblt.c
index a97231c..6b99e43 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 cee9204..68e9c9a 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 c413e1a..1cb420c 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 );
}
/***********************************************************************
@@ -64,6 +61,20 @@ static inline RECT get_clip_rect( DC * dc, int left, int top, int right, int bot
}
/***********************************************************************
+ * 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
*
* Clip a rectangle to the DC visible rect.
@@ -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 33c1033..95dd3e2 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 d8d283e..f7e08a5 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 20b522d..2589238 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;
More information about the wine-cvs
mailing list