Andrew Eikum aeikum@codeweavers.com writes:
The Chrome browser print function implements their own handling for EMR_MODIFYWORLDTRANSFORM which calls ModifyWorldTransform on the HDC directly without ever calling PlayEnhMetaFileRecord. In Wine, this transformation would get discarded when the callback function returned, causing the page to be printed at the wrong scale.
Tests show that the transform is updated immediately during PlayEnhMetaFileRecord. In addition, a modified transform persists between callbacks until PlayEnhMetaFileRecord is called on a relevant type of callback, at which point the transform is reverted before playing back the record.
Signed-off-by: Andrew Eikum aeikum@codeweavers.com
v2: Get rid of win9x checks in tests, and reformat test code.
dlls/gdi32/enhmetafile.c | 41 ++++++- dlls/gdi32/tests/metafile.c | 253 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 289 insertions(+), 5 deletions(-)
This breaks the tests:
../../../tools/runtest -q -P wine -T ../../.. -M gdiplus.dll -p gdiplus_test.exe.so metafile && touch metafile.ok wine: Unhandled exception 0xc0000093 in thread a0 at address 0x7e8f10c5 (thread 00a0), starting debugger... Unhandled exception: floating point underflow in 32-bit code (0x7e8f10c7). Register dump: CS:0023 SS:002b DS:002b ES:002b FS:0063 GS:006b EIP:7e8f10c7 ESP:0033f74c EBP:0033f768 EFLAGS:00010202( R- -- I - - - ) EAX:00000001 EBX:7e99b000 ECX:7e99b000 EDX:0033f7a8 ESI:7e99b000 EDI:0033f7a8 Stack dump: 0x0033f74c: 3f000000 00000000 00000000 3f000000 0x0033f75c: 7e99b000 00140bd0 0033f7a8 0033f7d8 0x0033f76c: 7e92e9f0 0033f7a8 0033f7a8 00140bd0 0x0033f77c: 00000000 3f800000 00000000 002f003e 0x0033f78c: 3f800000 3f800000 00000000 00000000 0x0033f79c: 3f800000 00000000 00000000 3f000000 Backtrace: =>0 0x7e8f10c7 CombineTransform+0x87() in gdi32 (0x0033f768) 1 0x7e92e9f0 EMF_Update_MF_Xform+0x6f(hdc=<is not available>, info=<is not available>) [/home/julliard/wine/wine/dlls/gdi32/enhmetafile.c:545] in gdi32 (0x0033f7d8) 2 0x7e930a4e PlayEnhMetaFileRecord+0x191d(hdc=<is not available>, handletable=<is not available>, mr=<is not available>, handles=<is not available>) [/home/julliard/wine/wine/dlls/gdi32/enhmetafile.c:1276] in gdi32 (0x0033f848) 3 0x7eca4fc1 GdipPlayMetafileRecord+0x170(metafile=<is not available>, recordType=<is not available>, flags=<is not available>, dataSize=<is not available>, data=<is not available>) [/home/julliard/wine/wine/dlls/gdiplus/metafile.c:1428] in gdiplus (0x0033f8c8) 4 0x7ed3887f test_gditransform_cb+0x2e(metafile=0x13f420, record_type=EmfRecordTypeGdiComment, flags=0, dataSize=0xc, pStr=") [/home/julliard/wine/wine/dlls/gdiplus/tests/metafile.c:2278] in gdiplus_test (0x0033f928) 5 0x7ed3881c play_metafile_proc+0x25b(record_type=<couldn't compute location>, flags=<couldn't compute location>, dataSize=<couldn't compute location>, pStr=<couldn't compute location>, userdata=<couldn't compute location>) [/home/julliard/wine/wine/dlls/gdiplus/tests/metafile.c:264] in gdiplus_test (0x0033f988) 6 0x7eca3495 enum_metafile_proc+0x64(hDC=<is not available>, lpHTable=<is not available>, lpEMFR=<is not available>, nObj=<is not available>, lpData=<is not available>) [/home/julliard/wine/wine/dlls/gdiplus/metafile.c:1841] in gdiplus (0x0033f9e8) 7 0x7e931af8 EnumEnhMetaFile+0x497() in gdi32 (0x0033faf8) 8 0x7eca5e56 GdipEnumerateMetafileSrcRectDestPoints+0x505() in gdiplus (0x0033fba8) 9 0x7ed39ea4 play_metafile.constprop+0x43() in gdiplus_test (0x0033fc08) 10 0x7ed43f42 func_metafile+0x2971() [/home/julliard/wine/wine/dlls/gdiplus/tests/metafile.c:2369] in gdiplus_test (0x0033fd48) 11 0x7eced39d main+0x25c(argc=<is not available>, argv=<is not available>) [/home/julliard/wine/wine/dlls/gdiplus/tests/../../../include/wine/test.h:603] in gdiplus_test (0x0033fdf8) 12 0x7ed5947b __wine_spec_exe_entry+0x4a(peb=<couldn't compute location>) [/home/julliard/wine/wine/dlls/winecrt0/exe_entry.c:36] in gdiplus_test (0x0033fe38) 13 0x7b45e85c call_process_entry+0xb() in kernel32 (0x0033fe58) 14 0x7b45f799 start_process+0x68(entry=<couldn't compute location>) [/home/julliard/wine/wine/dlls/kernel32/process.c:1116] in kernel32 (0x0033fe98) 15 0x7bc7ea9c call_thread_func_wrapper+0xb() in ntdll (0x0033feb8) 16 0x7bc81a59 call_thread_func+0xa8(entry=0x7b45f730, arg=0x7ed59430, frame=0x33ffc8) [/home/julliard/wine/wine/dlls/ntdll/signal_i386.c:2912] in ntdll (0x0033ffa8) 17 0x7bc7ea7a call_thread_entry_point+0x11() in ntdll (0x0033ffc8) 18 0x7bc53d43 start_process+0x12(arg=0xff987f08) [/home/julliard/wine/wine/dlls/ntdll/loader.c:3083] in ntdll (0x0033ffe8) 19 0xf753b91d __x86.get_pc_thunk.di+0x2a() in libwine.so.1 (0x00000000) 20 0xf753ba80 wine_switch_to_stack+0x1f(func=0x7bc53d30, arg=0xff987f08, stack=0x340000) [/home/julliard/wine/wine/libs/wine/port.c:77] in libwine.so.1 (0xff987ed8) 21 0x7bc599fe LdrInitializeThunk+0x22d(kernel_start=<couldn't compute location>, unknown2=<couldn't compute location>, unknown3=<couldn't compute location>, unknown4=<couldn't compute location>) [/home/julliard/wine/wine/dlls/ntdll/loader.c:3144] in ntdll (0xff987f28) 22 0x7b4656ff __wine_kernel_init+0xa4e() [/home/julliard/wine/wine/dlls/kernel32/process.c:1310] in kernel32 (0xff988e18) 23 0x7bc5a853 __wine_process_init+0x152() [/home/julliard/wine/wine/dlls/ntdll/loader.c:3353] in ntdll (0xff988e88) 24 0xf7539b83 wine_init+0x2a2(argc=0x3, argv=0xff9893d4, error="", error_size=0x400) [/home/julliard/wine/wine/libs/wine/loader.c:974] in libwine.so.1 (0xff988ed8) 25 0x7c000b58 main+0x97(argc=<is not available>, argv=<is not available>) [/home/julliard/wine/wine/loader/main.c:258] in <wine-loader> (0xff989328) 26 0xf7343276 __libc_start_main+0xf5() in libc.so.6 (0x00000000) 0x7e8f10c7 CombineTransform+0x87 in gdi32: flds 0xfffffff0(%ebp)