Commit 3ebc7158 authored by Zhiyi Zhang's avatar Zhiyi Zhang Committed by Alexandre Julliard

gdi32: Reselect font and pen when changing world transforms for enhanced metafiles.

Reselect font and pen into enhanced metafile device contexts after world transform is changed so that content can be drawn using the correct size. Also modifying the world transform for enhanced metafiles doesn't generate EMR_SELECTOBJECT records according to winedump outputs. Fix an issue that Tally may produce a print preview with a too large font or with a black side bar. Signed-off-by: 's avatarZhiyi Zhang <zzhang@codeweavers.com> Signed-off-by: 's avatarHuw Davies <huw@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 1543be81
...@@ -364,7 +364,7 @@ void DC_UpdateXforms( DC *dc ) ...@@ -364,7 +364,7 @@ void DC_UpdateXforms( DC *dc )
/* Reselect the font and pen back into the dc so that the size /* Reselect the font and pen back into the dc so that the size
gets updated. */ gets updated. */
if (linear_xform_cmp( &oldworld2vport, &dc->xformWorld2Vport ) && if (linear_xform_cmp( &oldworld2vport, &dc->xformWorld2Vport ) &&
!GdiIsMetaFileDC(dc->hSelf)) GetObjectType( dc->hSelf ) != OBJ_METADC)
{ {
SelectObject(dc->hSelf, dc->hFont); SelectObject(dc->hSelf, dc->hFont);
SelectObject(dc->hSelf, dc->hPen); SelectObject(dc->hSelf, dc->hPen);
......
...@@ -235,19 +235,27 @@ INT CDECL EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode ) ...@@ -235,19 +235,27 @@ INT CDECL EMFDRV_ExtSelectClipRgn( PHYSDEV dev, HRGN hrgn, INT mode )
INT CDECL EMFDRV_SetMapMode( PHYSDEV dev, INT mode ) INT CDECL EMFDRV_SetMapMode( PHYSDEV dev, INT mode )
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETMAPMODE emr; EMRSETMAPMODE emr;
INT ret;
emr.emr.iType = EMR_SETMAPMODE; emr.emr.iType = EMR_SETMAPMODE;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
emr.iMode = mode; emr.iMode = mode;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return 0;
return next->funcs->pSetMapMode( next, mode ); physDev->modifying_transform++;
ret = next->funcs->pSetMapMode( next, mode );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) BOOL CDECL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportExtEx );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETVIEWPORTEXTEX emr; EMRSETVIEWPORTEXTEX emr;
BOOL ret;
emr.emr.iType = EMR_SETVIEWPORTEXTEX; emr.emr.iType = EMR_SETVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
...@@ -255,13 +263,18 @@ BOOL CDECL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) ...@@ -255,13 +263,18 @@ BOOL CDECL EMFDRV_SetViewportExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
emr.szlExtent.cy = cy; emr.szlExtent.cy = cy;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetViewportExtEx( next, cx, cy, size ); physDev->modifying_transform++;
ret = next->funcs->pSetViewportExtEx( next, cx, cy, size );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) BOOL CDECL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowExtEx );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWINDOWEXTEX emr; EMRSETWINDOWEXTEX emr;
BOOL ret;
emr.emr.iType = EMR_SETWINDOWEXTEX; emr.emr.iType = EMR_SETWINDOWEXTEX;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
...@@ -269,13 +282,18 @@ BOOL CDECL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size ) ...@@ -269,13 +282,18 @@ BOOL CDECL EMFDRV_SetWindowExtEx( PHYSDEV dev, INT cx, INT cy, SIZE *size )
emr.szlExtent.cy = cy; emr.szlExtent.cy = cy;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetWindowExtEx( next, cx, cy, size ); physDev->modifying_transform++;
ret = next->funcs->pSetWindowExtEx( next, cx, cy, size );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) BOOL CDECL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetViewportOrgEx );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETVIEWPORTORGEX emr; EMRSETVIEWPORTORGEX emr;
BOOL ret;
emr.emr.iType = EMR_SETVIEWPORTORGEX; emr.emr.iType = EMR_SETVIEWPORTORGEX;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
...@@ -283,13 +301,18 @@ BOOL CDECL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) ...@@ -283,13 +301,18 @@ BOOL CDECL EMFDRV_SetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = y; emr.ptlOrigin.y = y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetViewportOrgEx( next, x, y, pt ); physDev->modifying_transform++;
ret = next->funcs->pSetViewportOrgEx( next, x, y, pt );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) BOOL CDECL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWindowOrgEx );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWINDOWORGEX emr; EMRSETWINDOWORGEX emr;
BOOL ret;
emr.emr.iType = EMR_SETWINDOWORGEX; emr.emr.iType = EMR_SETWINDOWORGEX;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
...@@ -297,13 +320,18 @@ BOOL CDECL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) ...@@ -297,13 +320,18 @@ BOOL CDECL EMFDRV_SetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = y; emr.ptlOrigin.y = y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetWindowOrgEx( next, x, y, pt ); physDev->modifying_transform++;
ret = next->funcs->pSetWindowOrgEx( next, x, y, pt );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) BOOL CDECL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pScaleViewportExtEx );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSCALEVIEWPORTEXTEX emr; EMRSCALEVIEWPORTEXTEX emr;
BOOL ret;
emr.emr.iType = EMR_SCALEVIEWPORTEXTEX; emr.emr.iType = EMR_SCALEVIEWPORTEXTEX;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
...@@ -313,7 +341,10 @@ BOOL CDECL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNu ...@@ -313,7 +341,10 @@ BOOL CDECL EMFDRV_ScaleViewportExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNu
emr.yDenom = yDenom; emr.yDenom = yDenom;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size ); physDev->modifying_transform++;
ret = next->funcs->pScaleViewportExtEx( next, xNum, xDenom, yNum, yDenom, size );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size ) BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, INT yDenom, SIZE *size )
...@@ -335,32 +366,44 @@ BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum, ...@@ -335,32 +366,44 @@ BOOL CDECL EMFDRV_ScaleWindowExtEx( PHYSDEV dev, INT xNum, INT xDenom, INT yNum,
DWORD CDECL EMFDRV_SetLayout( PHYSDEV dev, DWORD layout ) DWORD CDECL EMFDRV_SetLayout( PHYSDEV dev, DWORD layout )
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetMapMode );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETLAYOUT emr; EMRSETLAYOUT emr;
DWORD ret;
emr.emr.iType = EMR_SETLAYOUT; emr.emr.iType = EMR_SETLAYOUT;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
emr.iMode = layout; emr.iMode = layout;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return GDI_ERROR; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return GDI_ERROR;
return next->funcs->pSetLayout( next, layout ); physDev->modifying_transform++;
ret = next->funcs->pSetLayout( next, layout );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform) BOOL CDECL EMFDRV_SetWorldTransform( PHYSDEV dev, const XFORM *xform)
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pSetWorldTransform );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWORLDTRANSFORM emr; EMRSETWORLDTRANSFORM emr;
BOOL ret;
emr.emr.iType = EMR_SETWORLDTRANSFORM; emr.emr.iType = EMR_SETWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
emr.xform = *xform; emr.xform = *xform;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pSetWorldTransform( next, xform ); physDev->modifying_transform++;
ret = next->funcs->pSetWorldTransform( next, xform );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode) BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD mode)
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pModifyWorldTransform );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRMODIFYWORLDTRANSFORM emr; EMRMODIFYWORLDTRANSFORM emr;
BOOL ret;
emr.emr.iType = EMR_MODIFYWORLDTRANSFORM; emr.emr.iType = EMR_MODIFYWORLDTRANSFORM;
emr.emr.nSize = sizeof(emr); emr.emr.nSize = sizeof(emr);
...@@ -380,14 +423,19 @@ BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD m ...@@ -380,14 +423,19 @@ BOOL CDECL EMFDRV_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD m
emr.iMode = mode; emr.iMode = mode;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pModifyWorldTransform( next, xform, mode ); physDev->modifying_transform++;
ret = next->funcs->pModifyWorldTransform( next, xform, mode );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) BOOL CDECL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetViewportOrgEx );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETVIEWPORTORGEX emr; EMRSETVIEWPORTORGEX emr;
POINT prev; POINT prev;
BOOL ret;
GetViewportOrgEx( dev->hdc, &prev ); GetViewportOrgEx( dev->hdc, &prev );
...@@ -397,14 +445,19 @@ BOOL CDECL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) ...@@ -397,14 +445,19 @@ BOOL CDECL EMFDRV_OffsetViewportOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = prev.y + y; emr.ptlOrigin.y = prev.y + y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pOffsetViewportOrgEx( next, x, y, pt ); physDev->modifying_transform++;
ret = next->funcs->pOffsetViewportOrgEx( next, x, y, pt );
physDev->modifying_transform--;
return ret;
} }
BOOL CDECL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) BOOL CDECL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
{ {
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pOffsetWindowOrgEx );
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
EMRSETWINDOWORGEX emr; EMRSETWINDOWORGEX emr;
POINT prev; POINT prev;
BOOL ret;
GetWindowOrgEx( dev->hdc, &prev ); GetWindowOrgEx( dev->hdc, &prev );
...@@ -414,7 +467,10 @@ BOOL CDECL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt ) ...@@ -414,7 +467,10 @@ BOOL CDECL EMFDRV_OffsetWindowOrgEx( PHYSDEV dev, INT x, INT y, POINT *pt )
emr.ptlOrigin.y = prev.y + y; emr.ptlOrigin.y = prev.y + y;
if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE; if (!EMFDRV_WriteRecord( dev, &emr.emr )) return FALSE;
return next->funcs->pOffsetWindowOrgEx( next, x, y, pt ); physDev->modifying_transform++;
ret = next->funcs->pOffsetWindowOrgEx( next, x, y, pt );
physDev->modifying_transform--;
return ret;
} }
DWORD CDECL EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags ) DWORD CDECL EMFDRV_SetMapperFlags( PHYSDEV dev, DWORD flags )
......
...@@ -41,6 +41,7 @@ typedef struct ...@@ -41,6 +41,7 @@ typedef struct
HBRUSH dc_brush; HBRUSH dc_brush;
HPEN dc_pen; HPEN dc_pen;
INT restoring; /* RestoreDC counter */ INT restoring; /* RestoreDC counter */
INT modifying_transform;/* Counter for functions that can change world transform */
BOOL path; BOOL path;
INT dev_caps[COLORMGMTCAPS + 1]; INT dev_caps[COLORMGMTCAPS + 1];
} EMFDRV_PDEVICE; } EMFDRV_PDEVICE;
......
...@@ -372,6 +372,7 @@ HDC WINAPI CreateEnhMetaFileW( ...@@ -372,6 +372,7 @@ HDC WINAPI CreateEnhMetaFileW(
physDev->dc_brush = 0; physDev->dc_brush = 0;
physDev->dc_pen = 0; physDev->dc_pen = 0;
physDev->restoring = 0; physDev->restoring = 0;
physDev->modifying_transform = 0;
physDev->path = FALSE; physDev->path = FALSE;
if (hdc) /* if no ref, use current display */ if (hdc) /* if no ref, use current display */
......
...@@ -285,6 +285,7 @@ HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags ) ...@@ -285,6 +285,7 @@ HFONT CDECL EMFDRV_SelectFont( PHYSDEV dev, HFONT hFont, UINT *aa_flags )
int i; int i;
if (physDev->restoring) goto done; /* don't output SelectObject records during RestoreDC */ if (physDev->restoring) goto done; /* don't output SelectObject records during RestoreDC */
if (physDev->modifying_transform) goto done; /* don't output SelectObject records when modifying the world transform */
/* If the object is a stock font object, do not need to create it. /* If the object is a stock font object, do not need to create it.
* See definitions in wingdi.h for range of stock fonts. * See definitions in wingdi.h for range of stock fonts.
...@@ -370,6 +371,7 @@ HPEN CDECL EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen, const struct brush_pattern * ...@@ -370,6 +371,7 @@ HPEN CDECL EMFDRV_SelectPen(PHYSDEV dev, HPEN hPen, const struct brush_pattern *
int i; int i;
if (physDev->restoring) return hPen; /* don't output SelectObject records during RestoreDC */ if (physDev->restoring) return hPen; /* don't output SelectObject records during RestoreDC */
if (physDev->modifying_transform) return hPen; /* don't output SelectObject records when modifying the world transform */
/* If the object is a stock pen object, do not need to create it. /* If the object is a stock pen object, do not need to create it.
* See definitions in wingdi.h for range of stock pens. * See definitions in wingdi.h for range of stock pens.
......
...@@ -5060,7 +5060,6 @@ static void test_emf_text_extents(void) ...@@ -5060,7 +5060,6 @@ static void test_emf_text_extents(void)
ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError()); ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
ret = GetTextExtentPoint32W(emf_dc, L"W", 1, &size2); ret = GetTextExtentPoint32W(emf_dc, L"W", 1, &size2);
ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError()); ok(ret, "GetTextExtentPoint32W failed, error %d\n", GetLastError());
todo_wine
ok(size2.cx == size.cx && size2.cy == size.cy, "Expected size %dx%d, got %dx%d\n", ok(size2.cx == size.cx && size2.cy == size.cy, "Expected size %dx%d, got %dx%d\n",
size.cx, size.cy, size2.cx, size2.cy); size.cx, size.cy, size2.cx, size2.cy);
......
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