gdi32: Add a DC hook flag to reset the DC state.

This commit is contained in:
Alexandre Julliard 2012-10-24 18:24:03 +02:00
parent 77c1856d43
commit 4396a79ede
4 changed files with 94 additions and 48 deletions

View File

@ -70,6 +70,56 @@ static inline DC *get_dc_obj( HDC hdc )
}
/***********************************************************************
* set_initial_dc_state
*/
static void set_initial_dc_state( DC *dc )
{
dc->wndOrgX = 0;
dc->wndOrgY = 0;
dc->wndExtX = 1;
dc->wndExtY = 1;
dc->vportOrgX = 0;
dc->vportOrgY = 0;
dc->vportExtX = 1;
dc->vportExtY = 1;
dc->miterLimit = 10.0f; /* 10.0 is the default, from MSDN */
dc->layout = 0;
dc->font_code_page = CP_ACP;
dc->ROPmode = R2_COPYPEN;
dc->polyFillMode = ALTERNATE;
dc->stretchBltMode = BLACKONWHITE;
dc->relAbsMode = ABSOLUTE;
dc->backgroundMode = OPAQUE;
dc->backgroundColor = RGB( 255, 255, 255 );
dc->dcBrushColor = RGB( 255, 255, 255 );
dc->dcPenColor = RGB( 0, 0, 0 );
dc->textColor = RGB( 0, 0, 0 );
dc->brushOrgX = 0;
dc->brushOrgY = 0;
dc->mapperFlags = 0;
dc->textAlign = TA_LEFT | TA_TOP | TA_NOUPDATECP;
dc->charExtra = 0;
dc->breakExtra = 0;
dc->breakRem = 0;
dc->MapMode = MM_TEXT;
dc->GraphicsMode = GM_COMPATIBLE;
dc->CursPosX = 0;
dc->CursPosY = 0;
dc->ArcDirection = AD_COUNTERCLOCKWISE;
dc->xformWorld2Wnd.eM11 = 1.0f;
dc->xformWorld2Wnd.eM12 = 0.0f;
dc->xformWorld2Wnd.eM21 = 0.0f;
dc->xformWorld2Wnd.eM22 = 1.0f;
dc->xformWorld2Wnd.eDx = 0.0f;
dc->xformWorld2Wnd.eDy = 0.0f;
dc->xformWorld2Vport = dc->xformWorld2Wnd;
dc->xformVport2World = dc->xformWorld2Wnd;
dc->vport2WorldValid = TRUE;
reset_bounds( &dc->bounds );
}
/***********************************************************************
* alloc_dc_ptr
*/
@ -84,40 +134,12 @@ DC *alloc_dc_ptr( WORD magic )
dc->module = gdi32_module;
dc->thread = GetCurrentThreadId();
dc->refcount = 1;
dc->wndExtX = 1;
dc->wndExtY = 1;
dc->vportExtX = 1;
dc->vportExtY = 1;
dc->miterLimit = 10.0f; /* 10.0 is the default, from MSDN */
dc->hPen = GDI_inc_ref_count( GetStockObject( BLACK_PEN ));
dc->hBrush = GDI_inc_ref_count( GetStockObject( WHITE_BRUSH ));
dc->hFont = GDI_inc_ref_count( GetStockObject( SYSTEM_FONT ));
dc->hPalette = GetStockObject( DEFAULT_PALETTE );
dc->font_code_page = CP_ACP;
dc->ROPmode = R2_COPYPEN;
dc->polyFillMode = ALTERNATE;
dc->stretchBltMode = BLACKONWHITE;
dc->relAbsMode = ABSOLUTE;
dc->backgroundMode = OPAQUE;
dc->backgroundColor = RGB( 255, 255, 255 );
dc->dcBrushColor = RGB( 255, 255, 255 );
dc->dcPenColor = RGB( 0, 0, 0 );
dc->textColor = RGB( 0, 0, 0 );
dc->textAlign = TA_LEFT | TA_TOP | TA_NOUPDATECP;
dc->MapMode = MM_TEXT;
dc->GraphicsMode = GM_COMPATIBLE;
dc->ArcDirection = AD_COUNTERCLOCKWISE;
dc->xformWorld2Wnd.eM11 = 1.0f;
dc->xformWorld2Wnd.eM12 = 0.0f;
dc->xformWorld2Wnd.eM21 = 0.0f;
dc->xformWorld2Wnd.eM22 = 1.0f;
dc->xformWorld2Wnd.eDx = 0.0f;
dc->xformWorld2Wnd.eDy = 0.0f;
dc->xformWorld2Vport = dc->xformWorld2Wnd;
dc->xformVport2World = dc->xformWorld2Wnd;
dc->vport2WorldValid = TRUE;
reset_bounds( &dc->bounds );
set_initial_dc_state( dc );
if (!(dc->hSelf = alloc_gdi_handle( dc, magic, &dc_funcs )))
{
@ -519,6 +541,44 @@ BOOL nulldrv_RestoreDC( PHYSDEV dev, INT level )
}
/***********************************************************************
* reset_dc_state
*/
static BOOL reset_dc_state( HDC hdc )
{
DC *dc, *dcs, *next;
if (!(dc = get_dc_ptr( hdc ))) return FALSE;
set_initial_dc_state( dc );
SetBkColor( hdc, RGB( 255, 255, 255 ));
SetTextColor( hdc, RGB( 0, 0, 0 ));
SelectObject( hdc, GetStockObject( WHITE_BRUSH ));
SelectObject( hdc, GetStockObject( SYSTEM_FONT ));
SelectObject( hdc, GetStockObject( BLACK_PEN ));
SetVirtualResolution( hdc, 0, 0, 0, 0 );
GDISelectPalette( hdc, GetStockObject( DEFAULT_PALETTE ), FALSE );
SetBoundsRect( hdc, NULL, DCB_DISABLE );
AbortPath( hdc );
if (dc->hClipRgn) DeleteObject( dc->hClipRgn );
if (dc->hMetaRgn) DeleteObject( dc->hMetaRgn );
dc->hClipRgn = 0;
dc->hMetaRgn = 0;
update_dc_clipping( dc );
for (dcs = dc->saved_dc; dcs; dcs = next)
{
next = dcs->saved_dc;
free_dc_state( dcs );
}
dc->saved_dc = NULL;
dc->saveLevel = 0;
release_dc_ptr( dc );
return TRUE;
}
/***********************************************************************
* SaveDC (GDI32.@)
*/
@ -1217,8 +1277,6 @@ WORD WINAPI SetHookFlags( HDC hdc, WORD flags )
if (!dc) return 0;
/* "Undocumented Windows" info is slightly confusing. */
TRACE("hDC %p, flags %04x\n",hdc,flags);
if (flags & DCHF_INVALIDATEVISRGN)
@ -1227,6 +1285,8 @@ WORD WINAPI SetHookFlags( HDC hdc, WORD flags )
ret = InterlockedExchange( &dc->dirty, 0 );
GDI_ReleaseObj( hdc );
if (flags & DCHF_RESETDC) ret = reset_dc_state( hdc );
return ret;
}

View File

@ -124,10 +124,7 @@ static void test_savedc_2(void)
rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
ret = SaveDC(hdc);
todo_wine
{
ok(ret == 1, "ret = %d\n", ret);
}
ret = IntersectClipRect(hdc, 0, 0, 50, 50);
if (ret == COMPLEXREGION)

View File

@ -177,16 +177,6 @@ static void update_visible_region( struct dce *dce )
}
/***********************************************************************
* reset_dce_attrs
*/
static void reset_dce_attrs( struct dce *dce )
{
RestoreDC( dce->hdc, 1 ); /* initial save level is always 1 */
SaveDC( dce->hdc ); /* save the state again for next time */
}
/***********************************************************************
* release_dce
*/
@ -235,8 +225,6 @@ static struct dce *alloc_dce(void)
HeapFree( GetProcessHeap(), 0, dce );
return 0;
}
SaveDC( dce->hdc );
dce->hwnd = 0;
dce->clip_rgn = 0;
dce->flags = 0;
@ -352,7 +340,7 @@ void free_dce( struct dce *dce, HWND hwnd )
if (!--dce->count)
{
/* turn it into a cache entry */
reset_dce_attrs( dce );
SetHookFlags( dce->hdc, DCHF_RESETDC );
release_dce( dce );
dce->flags |= DCX_CACHE;
}
@ -470,7 +458,7 @@ static INT release_dc( HWND hwnd, HDC hdc, BOOL end_paint )
dce = (struct dce *)GetDCHook( hdc, NULL );
if (dce && dce->count)
{
if (!(dce->flags & DCX_NORESETATTRS)) reset_dce_attrs( dce );
if (!(dce->flags & DCX_NORESETATTRS)) SetHookFlags( dce->hdc, DCHF_RESETDC );
if (end_paint || (dce->flags & DCX_CACHE)) delete_clip_rgn( dce );
if (dce->flags & DCX_CACHE) dce->count = 0;
ret = TRUE;

View File

@ -265,6 +265,7 @@ static inline ULONG window_surface_release( struct window_surface *surface )
#define DCHC_DELETEDC 0x0002
#define DCHF_INVALIDATEVISRGN 0x0001
#define DCHF_VALIDATEVISRGN 0x0002
#define DCHF_RESETDC 0x0004 /* Wine extension */
typedef BOOL (CALLBACK *DCHOOKPROC)(HDC,WORD,DWORD_PTR,LPARAM);