Alexandre Julliard : gdi32: Use a region to render geometric and wide pens in PolyPolyline.

Alexandre Julliard julliard at winehq.org
Thu Dec 29 12:15:44 CST 2011


Module: wine
Branch: master
Commit: 64ed56366c6ac64c8d5a1e818b0480ff533ef5b2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=64ed56366c6ac64c8d5a1e818b0480ff533ef5b2

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Dec 28 13:52:58 2011 +0100

gdi32: Use a region to render geometric and wide pens in PolyPolyline.

---

 dlls/gdi32/dibdrv/dibdrv.h   |    2 +-
 dlls/gdi32/dibdrv/graphics.c |   45 ++++++++++++++++++++++++-----------------
 dlls/gdi32/dibdrv/objects.c  |    2 +
 3 files changed, 29 insertions(+), 20 deletions(-)

diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index fa8d445..ba8c0a4 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -84,7 +84,7 @@ typedef struct dibdrv_physdev
     /* pen */
     COLORREF pen_colorref;
     DWORD pen_style, pen_endcap, pen_join;
-    BOOL pen_is_ext;
+    BOOL pen_uses_region, pen_is_ext;
     int pen_width;
     dash_pattern pen_pattern;
     dash_pos dash_pos;
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
index e8b45a1..d43b30b 100644
--- a/dlls/gdi32/dibdrv/graphics.c
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -517,14 +517,27 @@ BOOL dibdrv_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWO
     PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolyline );
     DWORD max_points = 0, i;
     POINT *points;
+    BOOL ret = TRUE;
+    INT rop = GetROP2( dev->hdc );
+    HRGN outline = 0;
 
     if (defer_pen( pdev )) return next->funcs->pPolyPolyline( next, pt, counts, polylines );
 
-    for (i = 0; i < polylines; i++) max_points = max( counts[i], max_points );
+    for (i = 0; i < polylines; i++)
+    {
+        if (counts[i] < 2) return FALSE;
+        max_points = max( counts[i], max_points );
+    }
 
     points = HeapAlloc( GetProcessHeap(), 0, max_points * sizeof(*pt) );
     if (!points) return FALSE;
 
+    if (pdev->pen_uses_region && !(outline = CreateRectRgn( 0, 0, 0, 0 )))
+    {
+        HeapFree( GetProcessHeap(), 0, points );
+        return FALSE;
+    }
+
     for (i = 0; i < polylines; i++)
     {
         memcpy( points, pt, counts[i] * sizeof(*pt) );
@@ -532,11 +545,18 @@ BOOL dibdrv_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWO
         LPtoDP( dev->hdc, points, counts[i] );
 
         reset_dash_origin( pdev );
-        pdev->pen_lines( pdev, counts[i], points, FALSE, 0 );
+        pdev->pen_lines( pdev, counts[i], points, FALSE, outline );
+    }
+
+    if (outline)
+    {
+        if (pdev->clip) CombineRgn( outline, outline, pdev->clip, RGN_AND );
+        ret = pen_rect( pdev, NULL, outline, rop );
+        DeleteObject( outline );
     }
 
     HeapFree( GetProcessHeap(), 0, points );
-    return TRUE;
+    return ret;
 }
 
 /***********************************************************************
@@ -544,23 +564,10 @@ BOOL dibdrv_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWO
  */
 BOOL dibdrv_Polyline( PHYSDEV dev, const POINT* pt, INT count )
 {
-    dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
-    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyline );
-    POINT *points;
-
-    if (defer_pen( pdev )) return next->funcs->pPolyline( next, pt, count );
-
-    points = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pt) );
-    if (!points) return FALSE;
+    DWORD counts[1] = { count };
 
-    memcpy( points, pt, count * sizeof(*pt) );
-    LPtoDP( dev->hdc, points, count );
-
-    reset_dash_origin( pdev );
-    pdev->pen_lines( pdev, count, points, FALSE, 0 );
-
-    HeapFree( GetProcessHeap(), 0, points );
-    return TRUE;
+    if (count < 0) return FALSE;
+    return dibdrv_PolyPolyline( dev, pt, counts, 1 );
 }
 
 /***********************************************************************
diff --git a/dlls/gdi32/dibdrv/objects.c b/dlls/gdi32/dibdrv/objects.c
index dd7ddb7..197b220 100644
--- a/dlls/gdi32/dibdrv/objects.c
+++ b/dlls/gdi32/dibdrv/objects.c
@@ -1615,6 +1615,7 @@ HPEN dibdrv_SelectPen( PHYSDEV dev, HPEN hpen )
         break;
 
     case PS_NULL:
+        pdev->pen_width = 0;
         pdev->pen_lines = null_pen_lines;
         pdev->defer &= ~DEFER_PEN;
         break;
@@ -1637,6 +1638,7 @@ HPEN dibdrv_SelectPen( PHYSDEV dev, HPEN hpen )
         break;
     }
 
+    pdev->pen_uses_region = (logpen.lopnStyle & PS_GEOMETRIC || pdev->pen_width > 1);
     pdev->pen_is_ext = (elp != NULL);
     HeapFree( GetProcessHeap(), 0, elp );
 




More information about the wine-cvs mailing list