Commit eceed527 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Completely implement RestoreDC in the driver, having it call restore_dc_state if necessary.

parent e2f888a6
......@@ -455,6 +455,11 @@ BOOL restore_dc_state( HDC hdc, INT level )
/* find the state level to restore */
if (abs(level) > dc->saveLevel || level == 0)
{
release_dc_ptr( dc );
return FALSE;
}
if (level < 0) level = dc->saveLevel + level + 1;
first_dcs = dc->saved_dc;
for (hdcs = first_dcs, save_level = dc->saveLevel; save_level > level; save_level--)
......@@ -602,23 +607,11 @@ BOOL WINAPI RestoreDC( HDC hdc, INT level )
if (!(dc = get_dc_ptr( hdc ))) return FALSE;
update_dc( dc );
if(abs(level) > dc->saveLevel || level == 0)
{
release_dc_ptr( dc );
return FALSE;
}
if(dc->funcs->pRestoreDC)
{
success = dc->funcs->pRestoreDC( dc->physDev, level );
if(level < 0) level = dc->saveLevel + level + 1;
if(success)
dc->saveLevel = level - 1;
release_dc_ptr( dc );
return success;
}
else
success = restore_dc_state( hdc, level );
success = restore_dc_state( hdc, level );
release_dc_ptr( dc );
return success;
}
......
......@@ -43,6 +43,7 @@ BOOL CDECL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
EMFDRV_PDEVICE* physDev = (EMFDRV_PDEVICE*)dev;
DC *dc = get_dc_ptr( physDev->hdc );
EMRRESTOREDC emr;
BOOL ret;
emr.emr.iType = EMR_RESTOREDC;
emr.emr.nSize = sizeof(emr);
......@@ -51,11 +52,14 @@ BOOL CDECL EMFDRV_RestoreDC( PHYSDEV dev, INT level )
emr.iRelative = level;
else
emr.iRelative = level - dc->saveLevel - 1;
release_dc_ptr( dc );
EMFDRV_WriteRecord( dev, &emr.emr );
physDev->restoring++;
ret = restore_dc_state( physDev->hdc, level );
physDev->restoring--;
release_dc_ptr( dc );
return TRUE;
if (ret) EMFDRV_WriteRecord( dev, &emr.emr );
return ret;
}
UINT CDECL EMFDRV_SetTextAlign( PHYSDEV dev, UINT align )
......
......@@ -46,6 +46,7 @@ typedef struct
INT technology;
INT planes;
INT numcolors;
INT restoring; /* RestoreDC counter */
} EMFDRV_PDEVICE;
......
......@@ -684,6 +684,9 @@ COLORREF CDECL
EMFDRV_SetBkColor( PHYSDEV dev, COLORREF color )
{
EMRSETBKCOLOR emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
if (physDev->restoring) return color; /* don't output records during RestoreDC */
emr.emr.iType = EMR_SETBKCOLOR;
emr.emr.nSize = sizeof(emr);
......@@ -700,6 +703,9 @@ COLORREF CDECL
EMFDRV_SetTextColor( PHYSDEV dev, COLORREF color )
{
EMRSETTEXTCOLOR emr;
EMFDRV_PDEVICE *physDev = (EMFDRV_PDEVICE *)dev;
if (physDev->restoring) return color; /* don't output records during RestoreDC */
emr.emr.iType = EMR_SETTEXTCOLOR;
emr.emr.nSize = sizeof(emr);
......
......@@ -356,6 +356,7 @@ HDC WINAPI CreateEnhMetaFileW(
physDev->technology = GetDeviceCaps(hRefDC, TECHNOLOGY);
physDev->planes = GetDeviceCaps(hRefDC, PLANES);
physDev->numcolors = GetDeviceCaps(hRefDC, NUMCOLORS);
physDev->restoring = 0;
physDev->emh->iType = EMR_HEADER;
physDev->emh->nSize = size;
......
......@@ -280,6 +280,8 @@ HBRUSH CDECL EMFDRV_SelectBrush(PHYSDEV dev, HBRUSH hBrush )
DWORD index;
int i;
if (physDev->restoring) return hBrush; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock brush object, do not need to create it.
* See definitions in wingdi.h for range of stock brushes.
* We do however have to handle setting the higher order bit to
......@@ -357,6 +359,8 @@ HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, HANDLE gdiFont )
DWORD index;
int i;
if (physDev->restoring) return 0; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock font object, do not need to create it.
* See definitions in wingdi.h for range of stock fonts.
* We do however have to handle setting the higher order bit to
......@@ -436,6 +440,8 @@ HPEN CDECL EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen )
DWORD index;
int i;
if (physDev->restoring) return hPen; /* don't output SelectObject records during RestoreDC */
/* If the object is a stock pen object, do not need to create it.
* See definitions in wingdi.h for range of stock pens.
* We do however have to handle setting the higher order bit to
......@@ -501,6 +507,8 @@ HPALETTE CDECL EMFDRV_SelectPalette( PHYSDEV dev, HPALETTE hPal, BOOL force )
EMRSELECTPALETTE emr;
DWORD index;
if (physDev->restoring) return hPal; /* don't output SelectObject records during RestoreDC */
if (hPal == GetStockObject( DEFAULT_PALETTE ))
{
index = DEFAULT_PALETTE | 0x80000000;
......
......@@ -27,7 +27,6 @@ INT CDECL MFDRV_SaveDC( PHYSDEV dev )
BOOL CDECL MFDRV_RestoreDC( PHYSDEV dev, INT level )
{
if(level != -1) return FALSE;
return MFDRV_MetaParam1( dev, META_RESTOREDC, level );
}
......
......@@ -571,24 +571,24 @@ static void test_SaveDC(void)
ok(ret, "ret = %d\n", ret);
ret = GetViewportOrgEx(hdcMetafile, &pt);
todo_wine ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
ret = GetViewportExtEx(hdcMetafile, &size);
todo_wine ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
todo_wine ok( GetPolyFillMode( hdcMetafile ) == ALTERNATE, "PolyFillMode not restored\n" );
todo_wine ok( GetBkColor( hdcMetafile ) == 0, "Background color not restored\n" );
ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
ok( GetPolyFillMode( hdcMetafile ) == ALTERNATE, "PolyFillMode not restored\n" );
ok( GetBkColor( hdcMetafile ) == 0, "Background color not restored\n" );
ret = SaveDC(hdcMetafile);
ok(ret == 3, "ret = %d\n", ret);
ret = GetViewportOrgEx(hdcMetafile, &pt);
todo_wine ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
ok(pt.x == 20,"Expecting ViewportOrg x of 20, got %i\n",pt.x);
ret = GetViewportExtEx(hdcMetafile, &size);
todo_wine ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
ok(size.cx == 300,"Expecting ViewportExt cx of 300, got %i\n",size.cx);
ret = RestoreDC(hdcMetafile, 1);
ok(ret, "ret = %d\n", ret);
ret = GetViewportOrgEx(hdcMetafile, &pt);
todo_wine ok(pt.x == 0,"Expecting ViewportOrg x of 0, got %i\n",pt.x);
ok(pt.x == 0,"Expecting ViewportOrg x of 0, got %i\n",pt.x);
ret = GetViewportExtEx(hdcMetafile, &size);
todo_wine ok(size.cx == 120,"Expecting ViewportExt cx of 120, got %i\n",size.cx);
ok(size.cx == 120,"Expecting ViewportExt cx of 120, got %i\n",size.cx);
SetWindowOrgEx(hdcMetafile, -4, -4, NULL);
SetViewportOrgEx(hdcMetafile, 40, 40, NULL);
......@@ -640,8 +640,8 @@ static void test_SaveDC(void)
ok(size.cx == 50,"Expecting ViewportExt cx of 50, got %i\n",size.cx);
hFontCheck = SelectObject(hdcMetafile, hFontOld);
todo_wine ok(hFontOld == hFontCheck && hFontCheck != hFont && hFontCheck != hFont2,
"Font not reverted with DC Restore\n");
ok(hFontOld == hFontCheck && hFontCheck != hFont && hFontCheck != hFont2,
"Font not reverted with DC Restore\n");
ret = RestoreDC(hdcMetafile, -20);
ok(!ret, "ret = %d\n", ret);
......@@ -736,13 +736,13 @@ static void test_mf_SaveDC(void)
SetPixelV(hdcMetafile, 50, 50, 0);
ret = RestoreDC(hdcMetafile, -1);
todo_wine ok(ret, "ret = %d\n", ret);
ok(ret, "ret = %d\n", ret);
ret = SaveDC(hdcMetafile);
ok(ret == 1, "ret = %d\n", ret);
ret = RestoreDC(hdcMetafile, 1);
todo_wine ok(ret, "ret = %d\n", ret);
ok(ret, "ret = %d\n", ret);
SetWindowOrgEx(hdcMetafile, -4, -4, NULL);
SetViewportOrgEx(hdcMetafile, 40, 40, NULL);
......@@ -779,18 +779,18 @@ static void test_mf_SaveDC(void)
SetPixelV(hdcMetafile, 50, 50, 0);
ret = RestoreDC(hdcMetafile, 1);
todo_wine ok(ret, "ret = %d\n", ret);
ok(ret, "ret = %d\n", ret);
hFontCheck = SelectObject(hdcMetafile, hFontOld);
ok(hFontOld != hFontCheck && hFontCheck == hFont2, "Font incorrectly reverted with DC Restore\n");
/* restore level is ignored */
ret = RestoreDC(hdcMetafile, -20);
todo_wine ok(ret, "ret = %d\n", ret);
ok(ret, "ret = %d\n", ret);
ret = RestoreDC(hdcMetafile, 20);
todo_wine ok(ret, "ret = %d\n", ret);
ok(ret, "ret = %d\n", ret);
ret = RestoreDC(hdcMetafile, 0);
todo_wine ok(ret, "ret = %d\n", ret);
ok(ret, "ret = %d\n", ret);
hMetafile = CloseMetaFile(hdcMetafile);
ok(hMetafile != 0, "CloseEnhMetaFile error %d\n", GetLastError());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment