gdi32: Only create the DC visible region when necessary.
Most DCs can simply use the visible rectangle instead.
This commit is contained in:
parent
1f15ffa1e6
commit
ddfe35867d
|
@ -639,7 +639,6 @@ static HGDIOBJ BITMAP_SelectObject( HGDIOBJ handle, HDC hdc )
|
|||
dc->vis_rect.top = 0;
|
||||
dc->vis_rect.right = bitmap->bitmap.bmWidth;
|
||||
dc->vis_rect.bottom = bitmap->bitmap.bmHeight;
|
||||
SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
|
||||
GDI_ReleaseObj( handle );
|
||||
DC_InitDC( dc );
|
||||
GDI_dec_ref_count( ret );
|
||||
|
|
|
@ -29,6 +29,16 @@
|
|||
WINE_DEFAULT_DEBUG_CHANNEL(clipping);
|
||||
|
||||
|
||||
/* return the DC visible rectangle if not empty */
|
||||
static inline BOOL get_dc_visrect( DC *dc, RECT *rect )
|
||||
{
|
||||
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 !is_rect_empty( rect );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_clip_rect
|
||||
*
|
||||
|
@ -77,6 +87,7 @@ BOOL clip_visrect( DC *dc, RECT *dst, const RECT *src )
|
|||
void CLIPPING_UpdateGCRegion( DC * dc )
|
||||
{
|
||||
HRGN clip_rgn;
|
||||
RECT visrect;
|
||||
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDeviceClipping );
|
||||
|
||||
/* update the intersection of meta and clip regions */
|
||||
|
@ -91,11 +102,17 @@ void CLIPPING_UpdateGCRegion( DC * dc )
|
|||
dc->hMetaClipRgn = 0;
|
||||
}
|
||||
clip_rgn = get_clip_region( dc );
|
||||
if (clip_rgn || dc->hVisRgn)
|
||||
if (dc->hVisRgn)
|
||||
{
|
||||
if (!dc->region) dc->region = CreateRectRgn( 0, 0, 0, 0 );
|
||||
CombineRgn( dc->region, dc->hVisRgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
|
||||
}
|
||||
else if (get_dc_visrect( dc, &visrect ))
|
||||
{
|
||||
if (!dc->region) dc->region = CreateRectRgn( 0, 0, 0, 0 );
|
||||
SetRectRgn( dc->region, visrect.left, visrect.top, visrect.right, visrect.bottom );
|
||||
if (clip_rgn) CombineRgn( dc->region, dc->region, clip_rgn, RGN_AND );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dc->region) DeleteObject( dc->region );
|
||||
|
@ -272,7 +289,7 @@ void CDECL __wine_set_visible_region( HDC hdc, HRGN hrgn, const RECT *vis_rect )
|
|||
/* map region to DC coordinates */
|
||||
OffsetRgn( hrgn, -vis_rect->left, -vis_rect->top );
|
||||
|
||||
DeleteObject( dc->hVisRgn );
|
||||
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
||||
dc->dirty = 0;
|
||||
dc->vis_rect = *vis_rect;
|
||||
dc->hVisRgn = hrgn;
|
||||
|
@ -476,7 +493,8 @@ INT WINAPI GetMetaRgn( HDC hdc, HRGN hRgn )
|
|||
*/
|
||||
INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
|
||||
{
|
||||
HRGN rgn;
|
||||
INT ret = 1;
|
||||
RECT visrect;
|
||||
DC *dc = get_dc_ptr( hDC );
|
||||
|
||||
if (!dc) return -1;
|
||||
|
@ -484,33 +502,37 @@ INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
|
|||
switch (iCode)
|
||||
{
|
||||
case 1:
|
||||
rgn = dc->hClipRgn;
|
||||
if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY );
|
||||
else ret = 0;
|
||||
break;
|
||||
case 2:
|
||||
rgn = dc->hMetaRgn;
|
||||
if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY );
|
||||
else ret = 0;
|
||||
break;
|
||||
case 3:
|
||||
rgn = dc->hMetaClipRgn;
|
||||
if(!rgn) rgn = dc->hClipRgn;
|
||||
if(!rgn) rgn = dc->hMetaRgn;
|
||||
if (dc->hMetaClipRgn) CombineRgn( hRgn, dc->hMetaClipRgn, 0, RGN_COPY );
|
||||
else if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY );
|
||||
else if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY );
|
||||
else ret = 0;
|
||||
break;
|
||||
case SYSRGN: /* == 4 */
|
||||
update_dc( dc );
|
||||
rgn = dc->hVisRgn;
|
||||
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 );
|
||||
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);
|
||||
release_dc_ptr( dc );
|
||||
return -1;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
if (rgn) CombineRgn( hRgn, rgn, 0, RGN_COPY );
|
||||
release_dc_ptr( dc );
|
||||
|
||||
/* On Windows NT/2000, the SYSRGN returned is in screen coordinates */
|
||||
if (iCode == SYSRGN && !(GetVersion() & 0x80000000))
|
||||
OffsetRgn( hRgn, dc->vis_rect.left, dc->vis_rect.top );
|
||||
|
||||
return (rgn != 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -585,11 +585,10 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
|
|||
ERR( "no driver found for %s\n", debugstr_w(buf) );
|
||||
return 0;
|
||||
}
|
||||
if (!(dc = alloc_dc_ptr( OBJ_DC ))) goto error;
|
||||
if (!(dc = alloc_dc_ptr( OBJ_DC ))) return 0;
|
||||
hdc = dc->hSelf;
|
||||
|
||||
dc->hBitmap = GDI_inc_ref_count( GetStockObject( DEFAULT_BITMAP ));
|
||||
if (!(dc->hVisRgn = CreateRectRgn( 0, 0, 1, 1 ))) goto error;
|
||||
|
||||
TRACE("(driver=%s, device=%s, output=%s): returning %p\n",
|
||||
debugstr_w(driver), debugstr_w(device), debugstr_w(output), dc->hSelf );
|
||||
|
@ -599,7 +598,8 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
|
|||
if (!funcs->pCreateDC( &dc->physDev, buf, device, output, initData ))
|
||||
{
|
||||
WARN("creation aborted by device\n" );
|
||||
goto error;
|
||||
free_dc_ptr( dc );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,15 +607,10 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
|
|||
dc->vis_rect.top = 0;
|
||||
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
|
||||
dc->vis_rect.bottom = GetDeviceCaps( hdc, DESKTOPVERTRES );
|
||||
SetRectRgn(dc->hVisRgn, dc->vis_rect.left, dc->vis_rect.top, dc->vis_rect.right, dc->vis_rect.bottom);
|
||||
|
||||
DC_InitDC( dc );
|
||||
release_dc_ptr( dc );
|
||||
return hdc;
|
||||
|
||||
error:
|
||||
if (dc) free_dc_ptr( dc );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -698,7 +693,7 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
|
|||
release_dc_ptr( origDC );
|
||||
}
|
||||
|
||||
if (!(dc = alloc_dc_ptr( OBJ_MEMDC ))) goto error;
|
||||
if (!(dc = alloc_dc_ptr( OBJ_MEMDC ))) return 0;
|
||||
|
||||
TRACE("(%p): returning %p\n", hdc, dc->hSelf );
|
||||
|
||||
|
@ -707,22 +702,18 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
|
|||
dc->vis_rect.top = 0;
|
||||
dc->vis_rect.right = 1;
|
||||
dc->vis_rect.bottom = 1;
|
||||
if (!(dc->hVisRgn = CreateRectRgn( 0, 0, 1, 1 ))) goto error; /* default bitmap is 1x1 */
|
||||
|
||||
ret = dc->hSelf;
|
||||
|
||||
if (!funcs->pCreateCompatibleDC( physDev, &dc->physDev ))
|
||||
{
|
||||
WARN("creation aborted by device\n");
|
||||
goto error;
|
||||
free_dc_ptr( dc );
|
||||
return 0;
|
||||
}
|
||||
DC_InitDC( dc );
|
||||
release_dc_ptr( dc );
|
||||
return ret;
|
||||
|
||||
error:
|
||||
if (dc) free_dc_ptr( dc );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -790,8 +781,8 @@ HDC WINAPI ResetDCW( HDC hdc, const DEVMODEW *devmode )
|
|||
dc->vis_rect.top = 0;
|
||||
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
|
||||
dc->vis_rect.bottom = GetDeviceCaps( hdc, DESKTOPVERTRES );
|
||||
SetRectRgn( dc->hVisRgn, dc->vis_rect.left, dc->vis_rect.top,
|
||||
dc->vis_rect.right, dc->vis_rect.bottom );
|
||||
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
||||
dc->hVisRgn = 0;
|
||||
CLIPPING_UpdateGCRegion( dc );
|
||||
}
|
||||
release_dc_ptr( dc );
|
||||
|
|
Loading…
Reference in New Issue