mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
actually add the patches
This commit is contained in:
parent
4d363d04f9
commit
b080509a3b
@ -0,0 +1,345 @@
|
||||
From 88412e5d16a242a1d0fed2db46ffd7ad7eb87ca8 Mon Sep 17 00:00:00 2001
|
||||
From: David Adam <david.adam.cnrs@gmail.com>
|
||||
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
|
||||
|
10
patches/ddraw-version-check/definition
Normal file
10
patches/ddraw-version-check/definition
Normal file
@ -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
|
@ -0,0 +1,132 @@
|
||||
From 8a91b7a88d96f735f7236afeed90c376a18f0eea Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Wendt <daniel.wendt@linux.com>
|
||||
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
|
||||
|
104
patches/gdi32-rotation/0002-gdi32-fix-for-rotated-ellipse.patch
Normal file
104
patches/gdi32-rotation/0002-gdi32-fix-for-rotated-ellipse.patch
Normal file
@ -0,0 +1,104 @@
|
||||
From b278711b2c76680e6e26a114f74d7f7c26ff6328 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Wendt <daniel.wendt@linux.com>
|
||||
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
|
||||
|
2
patches/gdi32-rotation/definition
Normal file
2
patches/gdi32-rotation/definition
Normal file
@ -0,0 +1,2 @@
|
||||
Fixes: [34579] gdi32: fix for rotated Arc, ArcTo, Chord and Pie drawing problem
|
||||
Fixes: [35331] gdi32: fix for rotated ellipse
|
Loading…
Reference in New Issue
Block a user