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.top = 0;
|
||||||
dc->vis_rect.right = bitmap->bitmap.bmWidth;
|
dc->vis_rect.right = bitmap->bitmap.bmWidth;
|
||||||
dc->vis_rect.bottom = bitmap->bitmap.bmHeight;
|
dc->vis_rect.bottom = bitmap->bitmap.bmHeight;
|
||||||
SetRectRgn( dc->hVisRgn, 0, 0, bitmap->bitmap.bmWidth, bitmap->bitmap.bmHeight);
|
|
||||||
GDI_ReleaseObj( handle );
|
GDI_ReleaseObj( handle );
|
||||||
DC_InitDC( dc );
|
DC_InitDC( dc );
|
||||||
GDI_dec_ref_count( ret );
|
GDI_dec_ref_count( ret );
|
||||||
|
|
|
@ -29,6 +29,16 @@
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(clipping);
|
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
|
* get_clip_rect
|
||||||
*
|
*
|
||||||
|
@ -77,6 +87,7 @@ BOOL clip_visrect( DC *dc, RECT *dst, const RECT *src )
|
||||||
void CLIPPING_UpdateGCRegion( DC * dc )
|
void CLIPPING_UpdateGCRegion( DC * dc )
|
||||||
{
|
{
|
||||||
HRGN clip_rgn;
|
HRGN clip_rgn;
|
||||||
|
RECT visrect;
|
||||||
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDeviceClipping );
|
PHYSDEV physdev = GET_DC_PHYSDEV( dc, pSetDeviceClipping );
|
||||||
|
|
||||||
/* update the intersection of meta and clip regions */
|
/* update the intersection of meta and clip regions */
|
||||||
|
@ -91,11 +102,17 @@ void CLIPPING_UpdateGCRegion( DC * dc )
|
||||||
dc->hMetaClipRgn = 0;
|
dc->hMetaClipRgn = 0;
|
||||||
}
|
}
|
||||||
clip_rgn = get_clip_region( dc );
|
clip_rgn = get_clip_region( dc );
|
||||||
if (clip_rgn || dc->hVisRgn)
|
if (dc->hVisRgn)
|
||||||
{
|
{
|
||||||
if (!dc->region) dc->region = CreateRectRgn( 0, 0, 0, 0 );
|
if (!dc->region) dc->region = CreateRectRgn( 0, 0, 0, 0 );
|
||||||
CombineRgn( dc->region, dc->hVisRgn, clip_rgn, clip_rgn ? RGN_AND : RGN_COPY );
|
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
|
else
|
||||||
{
|
{
|
||||||
if (dc->region) DeleteObject( dc->region );
|
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 */
|
/* map region to DC coordinates */
|
||||||
OffsetRgn( hrgn, -vis_rect->left, -vis_rect->top );
|
OffsetRgn( hrgn, -vis_rect->left, -vis_rect->top );
|
||||||
|
|
||||||
DeleteObject( dc->hVisRgn );
|
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
||||||
dc->dirty = 0;
|
dc->dirty = 0;
|
||||||
dc->vis_rect = *vis_rect;
|
dc->vis_rect = *vis_rect;
|
||||||
dc->hVisRgn = hrgn;
|
dc->hVisRgn = hrgn;
|
||||||
|
@ -476,7 +493,8 @@ INT WINAPI GetMetaRgn( HDC hdc, HRGN hRgn )
|
||||||
*/
|
*/
|
||||||
INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
|
INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
|
||||||
{
|
{
|
||||||
HRGN rgn;
|
INT ret = 1;
|
||||||
|
RECT visrect;
|
||||||
DC *dc = get_dc_ptr( hDC );
|
DC *dc = get_dc_ptr( hDC );
|
||||||
|
|
||||||
if (!dc) return -1;
|
if (!dc) return -1;
|
||||||
|
@ -484,33 +502,37 @@ INT WINAPI GetRandomRgn(HDC hDC, HRGN hRgn, INT iCode)
|
||||||
switch (iCode)
|
switch (iCode)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
rgn = dc->hClipRgn;
|
if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY );
|
||||||
|
else ret = 0;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
rgn = dc->hMetaRgn;
|
if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY );
|
||||||
|
else ret = 0;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
rgn = dc->hMetaClipRgn;
|
if (dc->hMetaClipRgn) CombineRgn( hRgn, dc->hMetaClipRgn, 0, RGN_COPY );
|
||||||
if(!rgn) rgn = dc->hClipRgn;
|
else if (dc->hClipRgn) CombineRgn( hRgn, dc->hClipRgn, 0, RGN_COPY );
|
||||||
if(!rgn) rgn = dc->hMetaRgn;
|
else if (dc->hMetaRgn) CombineRgn( hRgn, dc->hMetaRgn, 0, RGN_COPY );
|
||||||
|
else ret = 0;
|
||||||
break;
|
break;
|
||||||
case SYSRGN: /* == 4 */
|
case SYSRGN: /* == 4 */
|
||||||
update_dc( dc );
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN("Unknown code %d\n", iCode);
|
WARN("Unknown code %d\n", iCode);
|
||||||
release_dc_ptr( dc );
|
ret = -1;
|
||||||
return -1;
|
break;
|
||||||
}
|
}
|
||||||
if (rgn) CombineRgn( hRgn, rgn, 0, RGN_COPY );
|
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
|
return ret;
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -585,11 +585,10 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output,
|
||||||
ERR( "no driver found for %s\n", debugstr_w(buf) );
|
ERR( "no driver found for %s\n", debugstr_w(buf) );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!(dc = alloc_dc_ptr( OBJ_DC ))) goto error;
|
if (!(dc = alloc_dc_ptr( OBJ_DC ))) return 0;
|
||||||
hdc = dc->hSelf;
|
hdc = dc->hSelf;
|
||||||
|
|
||||||
dc->hBitmap = GDI_inc_ref_count( GetStockObject( DEFAULT_BITMAP ));
|
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",
|
TRACE("(driver=%s, device=%s, output=%s): returning %p\n",
|
||||||
debugstr_w(driver), debugstr_w(device), debugstr_w(output), dc->hSelf );
|
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 ))
|
if (!funcs->pCreateDC( &dc->physDev, buf, device, output, initData ))
|
||||||
{
|
{
|
||||||
WARN("creation aborted by device\n" );
|
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.top = 0;
|
||||||
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
|
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
|
||||||
dc->vis_rect.bottom = GetDeviceCaps( hdc, DESKTOPVERTRES );
|
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 );
|
DC_InitDC( dc );
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
return hdc;
|
return hdc;
|
||||||
|
|
||||||
error:
|
|
||||||
if (dc) free_dc_ptr( dc );
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -698,7 +693,7 @@ HDC WINAPI CreateCompatibleDC( HDC hdc )
|
||||||
release_dc_ptr( origDC );
|
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 );
|
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.top = 0;
|
||||||
dc->vis_rect.right = 1;
|
dc->vis_rect.right = 1;
|
||||||
dc->vis_rect.bottom = 1;
|
dc->vis_rect.bottom = 1;
|
||||||
if (!(dc->hVisRgn = CreateRectRgn( 0, 0, 1, 1 ))) goto error; /* default bitmap is 1x1 */
|
|
||||||
|
|
||||||
ret = dc->hSelf;
|
ret = dc->hSelf;
|
||||||
|
|
||||||
if (!funcs->pCreateCompatibleDC( physDev, &dc->physDev ))
|
if (!funcs->pCreateCompatibleDC( physDev, &dc->physDev ))
|
||||||
{
|
{
|
||||||
WARN("creation aborted by device\n");
|
WARN("creation aborted by device\n");
|
||||||
goto error;
|
free_dc_ptr( dc );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
DC_InitDC( dc );
|
DC_InitDC( dc );
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
return ret;
|
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.top = 0;
|
||||||
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
|
dc->vis_rect.right = GetDeviceCaps( hdc, DESKTOPHORZRES );
|
||||||
dc->vis_rect.bottom = GetDeviceCaps( hdc, DESKTOPVERTRES );
|
dc->vis_rect.bottom = GetDeviceCaps( hdc, DESKTOPVERTRES );
|
||||||
SetRectRgn( dc->hVisRgn, dc->vis_rect.left, dc->vis_rect.top,
|
if (dc->hVisRgn) DeleteObject( dc->hVisRgn );
|
||||||
dc->vis_rect.right, dc->vis_rect.bottom );
|
dc->hVisRgn = 0;
|
||||||
CLIPPING_UpdateGCRegion( dc );
|
CLIPPING_UpdateGCRegion( dc );
|
||||||
}
|
}
|
||||||
release_dc_ptr( dc );
|
release_dc_ptr( dc );
|
||||||
|
|
Loading…
Reference in New Issue