gdi32: Add support for clipping source coordinates to the DC device rectangle.
This commit is contained in:
parent
d2581e6229
commit
41e5bc06d8
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue