EMFDRV_ModifyWorldTransform() does direct struct copy through pointer dereference. And, when the mode parameter is MWT_IDENTITY, the xform parameter can be NULL because it should be ignored and use the identity matrix.
Fix Tally crashing when exporting a JPEG image.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/gdi32/mapping.c | 9 +++------ dlls/gdi32/tests/metafile.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/dlls/gdi32/mapping.c b/dlls/gdi32/mapping.c index 83582846486..a0feee0abb1 100644 --- a/dlls/gdi32/mapping.c +++ b/dlls/gdi32/mapping.c @@ -276,12 +276,7 @@ BOOL CDECL nulldrv_ModifyWorldTransform( PHYSDEV dev, const XFORM *xform, DWORD switch (mode) { case MWT_IDENTITY: - 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->xformWorld2Wnd = *xform; break; case MWT_LEFTMULTIPLY: CombineTransform( &dc->xformWorld2Wnd, xform, &dc->xformWorld2Wnd ); @@ -554,10 +549,12 @@ BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom, */ BOOL WINAPI ModifyWorldTransform( HDC hdc, const XFORM *xform, DWORD mode ) { + static const XFORM identity_xform = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }; BOOL ret = FALSE; DC *dc;
if (!xform && mode != MWT_IDENTITY) return FALSE; + if (mode == MWT_IDENTITY) xform = &identity_xform; if ((dc = get_dc_ptr( hdc ))) { PHYSDEV physdev = GET_DC_PHYSDEV( dc, pModifyWorldTransform ); diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index e81cff1ae57..648e9369803 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -4158,6 +4158,18 @@ static INT CALLBACK enum_emf_WorldTransform(HDC hdc, HANDLETABLE *ht,
CombineTransform(&test_data->expected, &test_data->stored, &test_data->scale); } + else if(lpXfrm->iMode == MWT_IDENTITY) + { + /* reset to identity matrix also does discard */ + test_data->stored.eM11 = 1.0f; + test_data->stored.eM12 = 0.0f; + test_data->stored.eM21 = 0.0f; + test_data->stored.eM22 = 1.0f; + test_data->stored.eDx = 0.0f; + test_data->stored.eDy = 0.0f; + + CombineTransform(&test_data->expected, &test_data->stored, &test_data->scale); + }
/* verify it is updated immediately */ ret = GetWorldTransform(hdc, &xform); @@ -4265,6 +4277,9 @@ static void test_emf_WorldTransform(void) ret = SetWorldTransform(hdcMetafile, &xform); /* EMR_SETWORLDTRANSFORM */ ok(ret == TRUE, "SetWorldTransform failed\n");
+ ret = ModifyWorldTransform(hdcMetafile, NULL, MWT_IDENTITY); /* EMR_MODIFYWORLDTRANSFORM */ + ok(ret == TRUE, "ModifyWorldTransform failed\n"); + set_rotation_xform(&xform, M_PI / 2.f, -2, -3); ret = ModifyWorldTransform(hdcMetafile, &xform, MWT_LEFTMULTIPLY); /* EMR_MODIFYWORLDTRANSFORM */ ok(ret == TRUE, "ModifyWorldTransform failed\n");
On Tue, Mar 30, 2021 at 11:30:36AM +0800, Zhiyi Zhang wrote:
EMFDRV_ModifyWorldTransform() does direct struct copy through pointer dereference. And, when the mode parameter is MWT_IDENTITY, the xform parameter can be NULL because it should be ignored and use the identity matrix.
Fix Tally crashing when exporting a JPEG image.
It would be cleaner to fix the bug in EMFDRV_ModifyWorldTransform() itself.
Huw.