actually add the patches

This commit is contained in:
Zebediah Figura
2019-02-16 08:36:04 -06:00
parent 4d363d04f9
commit b080509a3b
5 changed files with 593 additions and 0 deletions

View File

@@ -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

View 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

View 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