Alexandre Julliard : gdi32: Implement PolyPolygon in the DIB driver.

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


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Dec 29 09:57:58 2011 +0100

gdi32: Implement PolyPolygon in the DIB driver.

---

 dlls/gdi32/dibdrv/dc.c       |    4 +-
 dlls/gdi32/dibdrv/dibdrv.h   |    2 +
 dlls/gdi32/dibdrv/graphics.c |   68 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c
index 7001b46..6ce2212 100644
--- a/dlls/gdi32/dibdrv/dc.c
+++ b/dlls/gdi32/dibdrv/dc.c
@@ -474,9 +474,9 @@ const struct gdi_dc_funcs dib_driver =
     NULL,                               /* pPolyBezier */
     NULL,                               /* pPolyBezierTo */
     NULL,                               /* pPolyDraw */
-    NULL,                               /* pPolyPolygon */
+    dibdrv_PolyPolygon,                 /* pPolyPolygon */
     dibdrv_PolyPolyline,                /* pPolyPolyline */
-    NULL,                               /* pPolygon */
+    dibdrv_Polygon,                     /* pPolygon */
     dibdrv_Polyline,                    /* pPolyline */
     NULL,                               /* pPolylineTo */
     dibdrv_PutImage,                    /* pPutImage */
diff --git a/dlls/gdi32/dibdrv/dibdrv.h b/dlls/gdi32/dibdrv/dibdrv.h
index ba8c0a4..1f158db 100644
--- a/dlls/gdi32/dibdrv/dibdrv.h
+++ b/dlls/gdi32/dibdrv/dibdrv.h
@@ -122,8 +122,10 @@ extern COLORREF dibdrv_GetPixel( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
 extern BOOL     dibdrv_LineTo( PHYSDEV dev, INT x, INT y ) DECLSPEC_HIDDEN;
 extern BOOL     dibdrv_PatBlt( PHYSDEV dev, struct bitblt_coords *dst, DWORD rop ) DECLSPEC_HIDDEN;
 extern BOOL     dibdrv_PaintRgn( PHYSDEV dev, HRGN hrgn ) DECLSPEC_HIDDEN;
+extern BOOL     dibdrv_PolyPolygon( PHYSDEV dev, const POINT *pt, const INT *counts, DWORD polygons ) DECLSPEC_HIDDEN;
 extern BOOL     dibdrv_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts,
                                      DWORD polylines ) DECLSPEC_HIDDEN;
+extern BOOL     dibdrv_Polygon( PHYSDEV dev, const POINT *pt, INT count ) DECLSPEC_HIDDEN;
 extern BOOL     dibdrv_Polyline( PHYSDEV dev, const POINT* pt, INT count ) DECLSPEC_HIDDEN;
 extern DWORD    dibdrv_PutImage( PHYSDEV dev, HBITMAP hbitmap, HRGN clip, BITMAPINFO *info,
                                  const struct gdi_image_bits *bits, struct bitblt_coords *src,
diff --git a/dlls/gdi32/dibdrv/graphics.c b/dlls/gdi32/dibdrv/graphics.c
index 4fb1126..81d1d1b 100644
--- a/dlls/gdi32/dibdrv/graphics.c
+++ b/dlls/gdi32/dibdrv/graphics.c
@@ -520,6 +520,64 @@ BOOL dibdrv_PaintRgn( PHYSDEV dev, HRGN rgn )
 }
 
 /***********************************************************************
+ *           dibdrv_PolyPolygon
+ */
+BOOL dibdrv_PolyPolygon( PHYSDEV dev, const POINT *pt, const INT *counts, DWORD polygons )
+{
+    dibdrv_physdev *pdev = get_dibdrv_pdev(dev);
+    PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolygon );
+    DWORD total, i, pos;
+    BOOL ret = FALSE;
+    POINT *points;
+    INT rop = GetROP2( dev->hdc );
+    HRGN outline = 0, interior;
+
+    if (defer_pen( pdev )) return next->funcs->pPolyPolygon( next, pt, counts, polygons );
+
+    for (i = total = 0; i < polygons; i++)
+    {
+        if (counts[i] < 2) return FALSE;
+        total += counts[i];
+    }
+
+    points = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*pt) );
+    if (!points) return FALSE;
+    memcpy( points, pt, total * sizeof(*pt) );
+    LPtoDP( dev->hdc, points, total );
+
+    if (!(interior = CreatePolyPolygonRgn( points, counts, polygons, GetPolyFillMode( dev->hdc ))))
+    {
+        HeapFree( GetProcessHeap(), 0, points );
+        return FALSE;
+    }
+
+    if (pdev->clip) CombineRgn( interior, interior, pdev->clip, RGN_AND );
+
+    /* if not using a region, paint the interior first so the outline can overlap it */
+    if (!pdev->pen_uses_region || !(outline = CreateRectRgn( 0, 0, 0, 0 )))
+        ret = brush_rect( pdev, NULL, interior, rop );
+
+    for (i = pos = 0; i < polygons; i++)
+    {
+        reset_dash_origin( pdev );
+        pdev->pen_lines( pdev, counts[i], points + pos, TRUE, outline );
+        pos += counts[i];
+    }
+
+    if (outline)
+    {
+        if (pdev->clip) CombineRgn( outline, outline, pdev->clip, RGN_AND );
+        CombineRgn( interior, interior, outline, RGN_DIFF );
+        ret = pen_rect( pdev, NULL, outline, rop ) && brush_rect( pdev, NULL, interior, rop );
+        DeleteObject( outline );
+    }
+
+    DeleteObject( interior );
+    HeapFree( GetProcessHeap(), 0, points );
+    return ret;
+}
+
+/***********************************************************************
  *           dibdrv_PolyPolyline
  */
 BOOL dibdrv_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWORD polylines )
@@ -571,6 +629,16 @@ BOOL dibdrv_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWO
 }
 
 /***********************************************************************
+ *           dibdrv_Polygon
+ */
+BOOL dibdrv_Polygon( PHYSDEV dev, const POINT *pt, INT count )
+{
+    INT counts[1] = { count };
+
+    return dibdrv_PolyPolygon( dev, pt, counts, 1 );
+}
+
+/***********************************************************************
  *           dibdrv_Polyline
  */
 BOOL dibdrv_Polyline( PHYSDEV dev, const POINT* pt, INT count )




More information about the wine-cvs mailing list