diff --git a/patches/ddraw-version-check/0001-ddraw-Return-correct-devices-based-off-requested-Dir.patch b/patches/ddraw-version-check/0001-ddraw-Return-correct-devices-based-off-requested-Dir.patch new file mode 100644 index 00000000..6b4a9a9e --- /dev/null +++ b/patches/ddraw-version-check/0001-ddraw-Return-correct-devices-based-off-requested-Dir.patch @@ -0,0 +1,345 @@ +From 88412e5d16a242a1d0fed2db46ffd7ad7eb87ca8 Mon Sep 17 00:00:00 2001 +From: David Adam +Date: Fri, 8 Feb 2019 18:48:33 -1000 +Subject: [PATCH] ddraw: Return correct devices based off requested DirectX + version. + +--- + dlls/ddraw/ddraw.c | 230 +++++++++++++++++++++++++-------------------- + 1 file changed, 129 insertions(+), 101 deletions(-) + +diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c +index 8a1d0a4f..274a0907 100644 +--- a/dlls/ddraw/ddraw.c ++++ b/dlls/ddraw/ddraw.c +@@ -47,37 +47,80 @@ static const DDDEVICEIDENTIFIER2 deviceidentifier = + 0 + }; + ++#define D3D_VERSION(x) (1 << (x)) ++ + static struct enum_device_entry + { +- char interface_name[100]; ++ unsigned int version_mask; ++ /* Some games (Motoracer 2 demo) have the bad idea to modify the device ++ * name/description strings. Let's put the strings in sufficiently sized ++ * arrays in static-lifetime writable memory. */ ++ char device_desc[100]; + char device_name[100]; + const GUID *device_guid; + DWORD remove_caps; +-} device_list7[] = ++} device_list[] = + { +- /* T&L HAL device */ ++ /* Ramp Emulation (D3D 1&2 only) */ + { +- "WINE Direct3D7 Hardware Transform and Lighting acceleration using WineD3D", +- "Wine D3D7 T&L HAL", +- &IID_IDirect3DTnLHalDevice, ++ D3D_VERSION(1)|D3D_VERSION(2), ++ "WineD3D Ramp Software Emulation", ++ "Ramp Emulation", ++ &IID_IDirect3DRampDevice, + 0, + }, + +- /* HAL device */ ++ /* RGB Emulation (D3D 1-7) */ + { +- "WINE Direct3D7 Hardware acceleration using WineD3D", ++ D3D_VERSION(1)|D3D_VERSION(2)|D3D_VERSION(3)|D3D_VERSION(7), ++ "WineD3D RGB Software Emulation", ++ "RGB Emulation", ++ &IID_IDirect3DRGBDevice, ++ D3DDEVCAPS_HWTRANSFORMANDLIGHT, ++ }, ++ ++ /* Direct3D HAL (D3D 1-7) */ ++ { ++ D3D_VERSION(1)|D3D_VERSION(2)|D3D_VERSION(3)|D3D_VERSION(7), ++ "WineD3D Hardware Acceleration", + "Direct3D HAL", + &IID_IDirect3DHALDevice, + 0, + }, + +- /* RGB device */ ++ /* MMX Emulation (D3D2 only) */ + { +- "WINE Direct3D7 RGB Software Emulation using WineD3D", +- "Wine D3D7 RGB", +- &IID_IDirect3DRGBDevice, +- D3DDEVCAPS_HWTRANSFORMANDLIGHT, ++ D3D_VERSION(2), ++ "WineD3D MMX Software Emulation", ++ "MMX Emulation", ++ &IID_IDirect3DMMXDevice, ++ 0, ++ }, ++ ++ /* Direct3D T&L HAL (D3D7 only) */ ++ { ++ D3D_VERSION(7), ++ "WineD3D Hardware Transform and Lighting Acceleration", ++ "Direct3D T&L HAL", ++ &IID_IDirect3DTnLHalDevice, ++ 0, + }, ++ ++ /* In the future, we may wish to add the "Reference Rasterizer" and ++ * "Null device", which are only available in DX6-8 and must be explicitly ++ * enabled by the registry values: ++ * * EnumReference ++ * * EnumNullDevice, ++ * which are DWORD values which must be created under ++ * HKLM\Software\Microsoft\Direct3D\Drivers and set to any nonzero value. ++ * (Refer to enablerefrast.reg/disablerefrast.reg in the DX6/7 SDKs and ++ * KB249579 for more information.) ++ * ++ * DirectX 9.0 and higher appear to no longer recognize these settings, ++ * so apparently these devices were removed starting with DX9. ++ * ++ * Some games (AvP, Motoracer 2) break if these devices are enumerated. ++ */ + }; + + static void STDMETHODCALLTYPE ddraw_null_wined3d_object_destroyed(void *parent) {} +@@ -1396,15 +1439,6 @@ HRESULT ddraw_get_d3dcaps(const struct ddraw *ddraw, D3DDEVICEDESC7 *caps) + D3DPTADDRESSCAPS_WRAP | D3DPTADDRESSCAPS_MIRROR | D3DPTADDRESSCAPS_CLAMP | + D3DPTADDRESSCAPS_BORDER | D3DPTADDRESSCAPS_INDEPENDENTUV); + +- if (!(caps->dpcLineCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2)) +- { +- /* DirectX7 always has the np2 flag set, no matter what the card +- * supports. Some old games (Rollcage) check the caps incorrectly. +- * If wined3d supports nonpow2 textures it also has np2 conditional +- * support. */ +- caps->dpcLineCaps.dwTextureCaps |= D3DPTEXTURECAPS_POW2 | D3DPTEXTURECAPS_NONPOW2CONDITIONAL; +- } +- + /* Fill the missing members, and do some fixup */ + caps->dpcLineCaps.dwSize = sizeof(caps->dpcLineCaps); + caps->dpcLineCaps.dwTextureBlendCaps = D3DPTBLENDCAPS_ADD +@@ -1547,6 +1581,8 @@ static HRESULT WINAPI ddraw7_GetCaps(IDirectDraw7 *iface, DDCAPS *DriverCaps, DD + + IDirect3D7_EnumZBufferFormats(&ddraw->IDirect3D7_iface, &IID_IDirect3DHALDevice, enum_zbuffer, &caps); + ++ caps.ddsOldCaps.dwCaps = caps.ddsCaps.dwCaps; ++ + if(DriverCaps) + { + DD_STRUCT_COPY_BYSIZE(DriverCaps, &caps); +@@ -3669,8 +3705,7 @@ static HRESULT WINAPI ddraw1_DuplicateSurface(IDirectDraw *iface, IDirectDrawSur + /***************************************************************************** + * IDirect3D7::EnumDevices + * +- * The EnumDevices method for IDirect3D7. It enumerates all supported +- * D3D7 devices. Currently the T&L, HAL and RGB devices are enumerated. ++ * The EnumDevices method for IDirect3D7. It enumerates all D3D7 devices. + * + * Params: + * callback: Function to call for each enumerated device +@@ -3703,14 +3738,14 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + + dev_caps = device_desc7.dwDevCaps; + +- for (i = 0; i < ARRAY_SIZE(device_list7); i++) ++ for (i = 0; i < ARRAY_SIZE(device_list); i++) + { + HRESULT ret; + +- device_desc7.deviceGUID = *device_list7[i].device_guid; +- device_desc7.dwDevCaps = dev_caps & ~device_list7[i].remove_caps; ++ device_desc7.deviceGUID = *device_list[i].device_guid; ++ device_desc7.dwDevCaps = dev_caps & ~device_list[i].remove_caps; + +- ret = callback(device_list7[i].interface_name, device_list7[i].device_name, &device_desc7, context); ++ ret = callback(device_list[i].device_name, device_list[i].device_name, &device_desc7, context); + if (ret != DDENUMRET_OK) + { + TRACE("Application cancelled the enumeration.\n"); +@@ -3726,11 +3761,21 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + return D3D_OK; + } + ++static void clear_device_desc(D3DDEVICEDESC *device_desc) ++{ ++ memset(device_desc, 0, sizeof(*device_desc)); ++ device_desc->dwSize = sizeof(*device_desc); ++ device_desc->dtcTransformCaps.dwSize = sizeof(device_desc->dtcTransformCaps); ++ device_desc->dlcLightingCaps.dwSize = sizeof(device_desc->dlcLightingCaps); ++ device_desc->dpcLineCaps.dwSize = sizeof(device_desc->dpcLineCaps); ++ device_desc->dpcTriCaps.dwSize = sizeof(device_desc->dpcTriCaps); ++} ++ + /***************************************************************************** + * IDirect3D3::EnumDevices + * +- * Enumerates all supported Direct3DDevice interfaces. This is the +- * implementation for Direct3D 1 to Direc3D 3, Version 7 has its own. ++ * Enumerates all Direct3DDevice interfaces. This is the implementation for ++ * Direct3D 1 to Direct3D 3; Version 7 has its own. + * + * Versions 1, 2 and 3 + * +@@ -3745,18 +3790,18 @@ static HRESULT WINAPI d3d7_EnumDevices(IDirect3D7 *iface, LPD3DENUMDEVICESCALLBA + *****************************************************************************/ + static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBACK callback, void *context) + { +- static CHAR wined3d_description[] = "Wine D3DDevice using WineD3D and OpenGL"; +- ++/* Size of D3DDEVICEDESC in Direct3D 1-3 */ ++enum { ++ D3D1_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMinTextureWidth), /* 172 */ ++ D3D2_DESC_SIZE = FIELD_OFFSET(D3DDEVICEDESC, dwMaxTextureRepeat), /* 204 */ ++ D3D3_DESC_SIZE = sizeof(D3DDEVICEDESC) /* 252 */ ++}; + struct ddraw *ddraw = impl_from_IDirect3D3(iface); +- D3DDEVICEDESC device_desc1, hal_desc, hel_desc; ++ DWORD desc_size; ++ D3DDEVICEDESC device_desc1, empty_desc1, hal_desc, hel_desc; + D3DDEVICEDESC7 device_desc7; + HRESULT hr; +- +- /* Some games (Motoracer 2 demo) have the bad idea to modify the device +- * name string. Let's put the string in a sufficiently sized array in +- * writable memory. */ +- char device_name[50]; +- strcpy(device_name,"Direct3D HEL"); ++ size_t i; + + TRACE("iface %p, callback %p, context %p.\n", iface, callback, context); + +@@ -3765,52 +3810,58 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA + + wined3d_mutex_lock(); + ++ switch (ddraw->d3dversion) ++ { ++ case 1: desc_size = D3D1_DESC_SIZE; break; ++ case 2: desc_size = D3D2_DESC_SIZE; break; ++ default: desc_size = D3D3_DESC_SIZE; break; ++ } ++ + if (FAILED(hr = ddraw_get_d3dcaps(ddraw, &device_desc7))) + { + wined3d_mutex_unlock(); + return hr; + } ++ + ddraw_d3dcaps1_from_7(&device_desc1, &device_desc7); ++ device_desc1.dwSize = desc_size; + +- /* Do I have to enumerate the reference id? Note from old d3d7: +- * "It seems that enumerating the reference IID on Direct3D 1 games +- * (AvP / Motoracer2) breaks them". So do not enumerate this iid in V1 +- * +- * There's a registry key HKLM\Software\Microsoft\Direct3D\Drivers, +- * EnumReference which enables / disables enumerating the reference +- * rasterizer. It's a DWORD, 0 means disabled, 2 means enabled. The +- * enablerefrast.reg and disablerefrast.reg files in the DirectX 7.0 sdk +- * demo directory suggest this. +- * +- * Some games(GTA 2) seem to use the second enumerated device, so I have +- * to enumerate at least 2 devices. So enumerate the reference device to +- * have 2 devices. +- * +- * Other games (Rollcage) tell emulation and hal device apart by certain +- * flags. Rollcage expects D3DPTEXTURECAPS_POW2 to be set (yeah, it is a +- * limitation flag), and it refuses all devices that have the perspective +- * flag set. This way it refuses the emulation device, and HAL devices +- * never have POW2 unset in d3d7 on windows. */ +- if (ddraw->d3dversion != 1) +- { +- static CHAR reference_description[] = "RGB Direct3D emulation"; +- +- TRACE("Enumerating WineD3D D3DDevice interface.\n"); +- hal_desc = device_desc1; +- hel_desc = device_desc1; +- /* The rgb device has the pow2 flag set in the hel caps, but not in the hal caps. */ +- hal_desc.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 +- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); +- hal_desc.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 +- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); +- /* RGB, RAMP and MMX devices have a HAL dcmColorModel of 0 */ +- hal_desc.dcmColorModel = 0; +- /* RGB, RAMP and MMX devices cannot report HAL hardware flags */ +- hal_desc.dwFlags = 0; +- +- hr = callback((GUID *)&IID_IDirect3DRGBDevice, reference_description, +- device_name, &hal_desc, &hel_desc, context); +- if (hr != D3DENUMRET_OK) ++ clear_device_desc(&empty_desc1); ++ empty_desc1.dwSize = desc_size; ++ ++ for (i = 0; i < ARRAY_SIZE(device_list); i++) ++ { ++ if (!(device_list[i].version_mask & D3D_VERSION(ddraw->d3dversion))) ++ continue; ++ ++ if (IsEqualGUID(&IID_IDirect3DHALDevice, device_list[i].device_guid)) ++ { ++ hal_desc = device_desc1; ++ ++ /* The HAL device's hel_desc is almost empty -- but not completely */ ++ hel_desc = empty_desc1; ++ hel_desc.dwFlags = D3DDD_COLORMODEL | D3DDD_DEVCAPS | D3DDD_TRANSFORMCAPS ++ | D3DDD_LIGHTINGCAPS | D3DDD_BCLIPPING; ++ hel_desc.dcmColorModel = 0; ++ hel_desc.dwDevCaps = D3DDEVCAPS_FLOATTLVERTEX; ++ hel_desc.dtcTransformCaps.dwCaps = hal_desc.dtcTransformCaps.dwCaps; ++ hel_desc.dlcLightingCaps = hal_desc.dlcLightingCaps; ++ hel_desc.bClipping = hal_desc.bClipping; ++ hel_desc.dwMaxVertexCount = hal_desc.dwMaxVertexCount; ++ } ++ else ++ { ++ hal_desc = empty_desc1; ++ ++ hel_desc = device_desc1; ++ /* Ramp device supports grayscale only */ ++ if (IsEqualGUID(&IID_IDirect3DRampDevice, device_list[i].device_guid)) ++ hel_desc.dcmColorModel = D3DCOLOR_MONO; ++ } ++ ++ hr = callback((GUID *)device_list[i].device_guid, device_list[i].device_desc, ++ device_list[i].device_name, &hal_desc, &hel_desc, context); ++ if (hr != DDENUMRET_OK) + { + TRACE("Application cancelled the enumeration.\n"); + wined3d_mutex_unlock(); +@@ -3818,29 +3869,6 @@ static HRESULT WINAPI d3d3_EnumDevices(IDirect3D3 *iface, LPD3DENUMDEVICESCALLBA + } + } + +- strcpy(device_name,"Direct3D HAL"); +- +- TRACE("Enumerating HAL Direct3D device.\n"); +- hal_desc = device_desc1; +- hel_desc = device_desc1; +- +- /* The hal device does not have the pow2 flag set in hel, but in hal. */ +- hel_desc.dpcLineCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 +- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); +- hel_desc.dpcTriCaps.dwTextureCaps &= ~(D3DPTEXTURECAPS_POW2 +- | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PERSPECTIVE); +- /* HAL devices have a HEL dcmColorModel of 0 */ +- hel_desc.dcmColorModel = 0; +- +- hr = callback((GUID *)&IID_IDirect3DHALDevice, wined3d_description, +- device_name, &hal_desc, &hel_desc, context); +- if (hr != D3DENUMRET_OK) +- { +- TRACE("Application cancelled the enumeration.\n"); +- wined3d_mutex_unlock(); +- return D3D_OK; +- } +- + TRACE("End of enumeration.\n"); + + wined3d_mutex_unlock(); +-- +2.20.1 + diff --git a/patches/ddraw-version-check/definition b/patches/ddraw-version-check/definition new file mode 100644 index 00000000..5d587c2b --- /dev/null +++ b/patches/ddraw-version-check/definition @@ -0,0 +1,10 @@ +# Games from code comments +# Rollcage +# GTA 2 +# Motoracer 2 demo +# Games that require testing from the bug report. +# Resident Evil +# Carmageddon 2 demo +# The Sims Online +Fixes: [19153] https://bugs.winehq.org/show_bug.cgi?id=19153 +Depends: ddraw-Device_Caps diff --git a/patches/gdi32-rotation/0001-gdi32-fix-for-rotated-Arc-ArcTo-Chord-and-Pie-drawin.patch b/patches/gdi32-rotation/0001-gdi32-fix-for-rotated-Arc-ArcTo-Chord-and-Pie-drawin.patch new file mode 100644 index 00000000..a1f56edf --- /dev/null +++ b/patches/gdi32-rotation/0001-gdi32-fix-for-rotated-Arc-ArcTo-Chord-and-Pie-drawin.patch @@ -0,0 +1,132 @@ +From 8a91b7a88d96f735f7236afeed90c376a18f0eea Mon Sep 17 00:00:00 2001 +From: Daniel Wendt +Date: Fri, 15 Nov 2013 12:52:37 +0100 +Subject: [PATCH] gdi32: fix for rotated Arc, ArcTo, Chord and Pie drawing + problem + +Wine-Bug: http://bugs.winehq.org/show_bug.cgi?id=34579 +--- + dlls/gdi32/dibdrv/graphics.c | 80 ++++++++++++++++++++++++++++++++++++++++++++ + dlls/gdi32/gdi_private.h | 3 ++ + 2 files changed, 83 insertions(+) + +diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c +index 7d71fbb..d269cc1 100644 +--- a/dlls/gdi32/dibdrv/graphics.c ++++ b/dlls/gdi32/dibdrv/graphics.c +@@ -313,6 +313,60 @@ static int get_arc_points( int arc_dir, const RECT *rect, POINT start, POINT end + return pos - count; + } + ++/* ++ Check if matrix has uniform scale and shear and contains a rotation. ++*/ ++BOOL xform_has_rotate_and_uniform_scale_and_shear( const XFORM *xform ) ++{ ++ return xform->eM21 != 0 && xform->eM11 == xform->eM22 && -xform->eM21 == xform->eM12; ++} ++ ++/* ++ Decompose rotation and translation from matrix xform. ++ ++ If parameter rotation_and_translation is != NULL, save rotation and translation into it. ++ ++ Note: The current implementation only works on matrixes with uniform scale and shear, ++ which has to be checked by a call to xform_has_rotate_and_uniform_scale_and_shear(). ++ Hints how to get unique values for non-uniform matrixes are welcome. ++*/ ++BOOL xform_decompose_rotation_and_translation( XFORM *xform, XFORM *rotation_and_translation ) ++{ ++ XFORM inverse_matrix_scale; ++ XFORM origin_matrix = *xform; ++ double determinant = 0; ++ ++ /* xform = xfrom-transposed * xform */ ++ xform->eM11 = sqrt( xform->eM11 * xform->eM11 + xform->eM21 * xform->eM21 ); ++ xform->eM22 = sqrt( xform->eM12 * xform->eM12 + xform->eM22 * xform->eM22 ); ++ xform->eM12 = 0; ++ xform->eM21 = 0; ++ xform->eDx = 0; ++ xform->eDy = 0; ++ ++ if ( rotation_and_translation == NULL ) ++ return TRUE; ++ ++ if ( xform->eM11 == 0 || xform->eM22 == 0 ) ++ return FALSE; ++ ++ determinant = xform->eM11 * xform->eM22; ++ ++ inverse_matrix_scale.eM11 = xform->eM22 / determinant; ++ inverse_matrix_scale.eM12 = 0; ++ inverse_matrix_scale.eM21 = 0; ++ inverse_matrix_scale.eM22 = xform->eM11 / determinant; ++ ++ /* calculate the rotation matrix */ ++ rotation_and_translation->eM11 = inverse_matrix_scale.eM11 * origin_matrix.eM11; ++ rotation_and_translation->eM12 = inverse_matrix_scale.eM11 * origin_matrix.eM12; ++ rotation_and_translation->eM21 = inverse_matrix_scale.eM22 * origin_matrix.eM12 * -1; ++ rotation_and_translation->eM22 = inverse_matrix_scale.eM22 * origin_matrix.eM22; ++ rotation_and_translation->eDx = origin_matrix.eDx; ++ rotation_and_translation->eDy = origin_matrix.eDy; ++ return TRUE; ++} ++ + /* backend for arc functions; extra_lines is -1 for ArcTo, 0 for Arc, 1 for Chord, 2 for Pie */ + static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom, + INT start_x, INT start_y, INT end_x, INT end_y, INT extra_lines ) +@@ -325,6 +379,22 @@ static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom, + BOOL ret = TRUE; + HRGN outline = 0, interior = 0; + ++ BOOL exclude_rotation = FALSE; ++ XFORM old; ++ XFORM rotation_and_translation; ++ if (GetGraphicsMode( pdev->dev.hdc ) == GM_ADVANCED) ++ { ++ XFORM xf; ++ GetWorldTransform( pdev->dev.hdc, &old ); ++ xf = old; ++ if (xform_has_rotate_and_uniform_scale_and_shear( &xf ) && ++ xform_decompose_rotation_and_translation( &xf, &rotation_and_translation )) ++ { ++ SetWorldTransform( pdev->dev.hdc, &xf ); ++ exclude_rotation = TRUE; ++ } ++ } ++ + if (!get_pen_device_rect( dc, pdev, &rect, left, top, right, bottom )) return TRUE; + + width = rect.right - rect.left; +@@ -358,6 +428,16 @@ static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom, + points[count].y = rect.top + height / 2; + count++; + } ++ ++ if (exclude_rotation == TRUE) ++ { ++ SetWorldTransform( pdev->dev.hdc, &rotation_and_translation ); ++ /* apply rotation and translation to calculated points */ ++ LPtoDP( dev->hdc, points, count ); ++ /* restore origin matrix */ ++ SetWorldTransform( pdev->dev.hdc, &old ); ++ } ++ + if (count < 2) + { + HeapFree( GetProcessHeap(), 0, points ); +diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h +index 920cd1e..4949187 100644 +--- a/dlls/gdi32/gdi_private.h ++++ b/dlls/gdi32/gdi_private.h +@@ -608,4 +608,7 @@ extern void free_heap_bits( struct gdi_image_bits *bits ) DECLSPEC_HIDDEN; + + extern HMODULE gdi32_module DECLSPEC_HIDDEN; + ++BOOL xform_has_rotate_and_uniform_scale_and_shear( const XFORM *xform ) DECLSPEC_HIDDEN; ++BOOL xform_decompose_rotation_and_translation( XFORM *xform, XFORM *rotation_and_translation ) DECLSPEC_HIDDEN; ++ + #endif /* __WINE_GDI_PRIVATE_H */ +-- +1.9.1 + diff --git a/patches/gdi32-rotation/0002-gdi32-fix-for-rotated-ellipse.patch b/patches/gdi32-rotation/0002-gdi32-fix-for-rotated-ellipse.patch new file mode 100644 index 00000000..5efc3d2e --- /dev/null +++ b/patches/gdi32-rotation/0002-gdi32-fix-for-rotated-ellipse.patch @@ -0,0 +1,104 @@ +From b278711b2c76680e6e26a114f74d7f7c26ff6328 Mon Sep 17 00:00:00 2001 +From: Daniel Wendt +Date: Tue, 10 Dec 2013 14:55:32 +0100 +Subject: [PATCH] gdi32: fix for rotated ellipse + +Bug: http://bugs.winehq.org/show_bug.cgi?id=35331 +--- + dlls/gdi32/dibdrv/graphics.c | 60 +++++++++++++++++++++++++++++++------------- + 1 file changed, 42 insertions(+), 18 deletions(-) + +diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c +index d269cc1..447aab5 100644 +--- a/dlls/gdi32/dibdrv/graphics.c ++++ b/dlls/gdi32/dibdrv/graphics.c +@@ -1555,6 +1555,23 @@ BOOL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom, + BOOL ret = TRUE; + HRGN outline = 0, interior = 0; + ++ BOOL exclude_rotation_translation = FALSE; ++ XFORM old; ++ XFORM rotation_and_translation; ++ ++ if (GetGraphicsMode( pdev->dev.hdc ) == GM_ADVANCED) ++ { ++ XFORM xf; ++ GetWorldTransform( pdev->dev.hdc, &old ); ++ xf = old; ++ if (xform_has_rotate_and_uniform_scale_and_shear( &xf ) && ++ xform_decompose_rotation_and_translation( &xf, &rotation_and_translation )) ++ { ++ SetWorldTransform( pdev->dev.hdc, &xf ); ++ exclude_rotation_translation = TRUE; ++ } ++ } ++ + if (!get_pen_device_rect( dc, pdev, &rect, left, top, right, bottom )) return TRUE; + + pt[0].x = pt[0].y = 0; +@@ -1575,23 +1592,6 @@ BOOL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom, + return FALSE; + } + +- if (pdev->brush.style != BS_NULL && +- !(interior = CreateRoundRectRgn( rect.left, rect.top, rect.right + 1, rect.bottom + 1, +- ellipse_width, ellipse_height ))) +- { +- HeapFree( GetProcessHeap(), 0, points ); +- if (outline) DeleteObject( outline ); +- return FALSE; +- } +- +- /* if not using a region, paint the interior first so the outline can overlap it */ +- if (interior && !outline) +- { +- ret = brush_region( pdev, interior ); +- DeleteObject( interior ); +- interior = 0; +- } +- + count = ellipse_first_quadrant( ellipse_width, ellipse_height, points ); + + if (dc->ArcDirection == AD_CLOCKWISE) +@@ -1635,13 +1635,37 @@ BOOL dibdrv_RoundRect( PHYSDEV dev, INT left, INT top, INT right, INT bottom, + } + count = end + 1; + ++ if (exclude_rotation_translation == TRUE) ++ { ++ SetWorldTransform( pdev->dev.hdc, &rotation_and_translation ); ++ /* apply rotation and translation to calculated points */ ++ LPtoDP( dev->hdc, points, count ); ++ /* restore origin matrix */ ++ SetWorldTransform( pdev->dev.hdc, &old ); ++ } ++ ++ if (pdev->brush.style != BS_NULL && ++ !(interior = CreatePolygonRgn(points, count, ALTERNATE))) ++ { ++ HeapFree( GetProcessHeap(), 0, points ); ++ if (outline) DeleteObject( outline ); ++ return FALSE; ++ } ++ ++ /* if not using a region, paint the interior first so the outline can overlap it */ ++ if (interior && !outline) ++ { ++ ret = brush_region( pdev, interior ); ++ DeleteObject( interior ); ++ interior = 0; ++ } ++ + reset_dash_origin( pdev ); + pdev->pen_lines( pdev, count, points, TRUE, outline ); + add_pen_lines_bounds( pdev, count, points, outline ); + + if (interior) + { +- CombineRgn( interior, interior, outline, RGN_DIFF ); + ret = brush_region( pdev, interior ); + DeleteObject( interior ); + } +-- +1.9.1 + diff --git a/patches/gdi32-rotation/definition b/patches/gdi32-rotation/definition new file mode 100644 index 00000000..cad5066b --- /dev/null +++ b/patches/gdi32-rotation/definition @@ -0,0 +1,2 @@ +Fixes: [34579] gdi32: fix for rotated Arc, ArcTo, Chord and Pie drawing problem +Fixes: [35331] gdi32: fix for rotated ellipse