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

This commit is contained in:
Alexandre Julliard 2011-12-28 13:52:58 +01:00
parent 9ee690c984
commit 64ed56366c
3 changed files with 29 additions and 20 deletions

View File

@ -84,7 +84,7 @@ typedef struct dibdrv_physdev
/* pen */ /* pen */
COLORREF pen_colorref; COLORREF pen_colorref;
DWORD pen_style, pen_endcap, pen_join; DWORD pen_style, pen_endcap, pen_join;
BOOL pen_is_ext; BOOL pen_uses_region, pen_is_ext;
int pen_width; int pen_width;
dash_pattern pen_pattern; dash_pattern pen_pattern;
dash_pos dash_pos; dash_pos dash_pos;

View File

@ -517,14 +517,27 @@ BOOL dibdrv_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWO
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolyline ); PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyPolyline );
DWORD max_points = 0, i; DWORD max_points = 0, i;
POINT *points; 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 ); 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) ); points = HeapAlloc( GetProcessHeap(), 0, max_points * sizeof(*pt) );
if (!points) return FALSE; 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++) for (i = 0; i < polylines; i++)
{ {
memcpy( points, pt, counts[i] * sizeof(*pt) ); 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] ); LPtoDP( dev->hdc, points, counts[i] );
reset_dash_origin( pdev ); 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 ); 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 ) BOOL dibdrv_Polyline( PHYSDEV dev, const POINT* pt, INT count )
{ {
dibdrv_physdev *pdev = get_dibdrv_pdev(dev); DWORD counts[1] = { count };
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPolyline );
POINT *points;
if (defer_pen( pdev )) return next->funcs->pPolyline( next, pt, count ); if (count < 0) return FALSE;
return dibdrv_PolyPolyline( dev, pt, counts, 1 );
points = HeapAlloc( GetProcessHeap(), 0, count * sizeof(*pt) );
if (!points) return FALSE;
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;
} }
/*********************************************************************** /***********************************************************************

View File

@ -1615,6 +1615,7 @@ HPEN dibdrv_SelectPen( PHYSDEV dev, HPEN hpen )
break; break;
case PS_NULL: case PS_NULL:
pdev->pen_width = 0;
pdev->pen_lines = null_pen_lines; pdev->pen_lines = null_pen_lines;
pdev->defer &= ~DEFER_PEN; pdev->defer &= ~DEFER_PEN;
break; break;
@ -1637,6 +1638,7 @@ HPEN dibdrv_SelectPen( PHYSDEV dev, HPEN hpen )
break; break;
} }
pdev->pen_uses_region = (logpen.lopnStyle & PS_GEOMETRIC || pdev->pen_width > 1);
pdev->pen_is_ext = (elp != NULL); pdev->pen_is_ext = (elp != NULL);
HeapFree( GetProcessHeap(), 0, elp ); HeapFree( GetProcessHeap(), 0, elp );