diff --git a/dlls/gdi32/dibdrv/dc.c b/dlls/gdi32/dibdrv/dc.c index 7001b464611..6ce2212f3a5 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 ba8c0a4da34..1f158db094a 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 4fb112620c1..81d1d1bd423 100644 --- a/dlls/gdi32/dibdrv/graphics.c +++ b/dlls/gdi32/dibdrv/graphics.c @@ -519,6 +519,64 @@ BOOL dibdrv_PaintRgn( PHYSDEV dev, HRGN rgn ) return TRUE; } +/*********************************************************************** + * 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 */ @@ -570,6 +628,16 @@ BOOL dibdrv_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWO return ret; } +/*********************************************************************** + * 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 */