winex11: Implement FillPath, StrokeAndFillPath and StrokePath.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2016-06-16 14:15:05 +09:00
parent b5cf73edd9
commit 10b526733f
3 changed files with 107 additions and 3 deletions

View File

@ -1227,6 +1227,107 @@ BOOL X11DRV_PolyPolyline( PHYSDEV dev, const POINT* pt, const DWORD* counts, DWO
return TRUE;
}
/* helper for path stroking and filling functions */
static BOOL x11drv_stroke_and_fill_path( PHYSDEV dev, BOOL stroke, BOOL fill )
{
X11DRV_PDEVICE *physDev = get_x11drv_dev( dev );
POINT *points;
BYTE *flags;
BOOL ret = FALSE;
XPoint *xpoints;
int i, j, size;
FlattenPath( dev->hdc );
if ((size = GetPath( dev->hdc, NULL, NULL, 0 )) == -1) return FALSE;
if (!size)
{
AbortPath( dev->hdc );
return TRUE;
}
xpoints = HeapAlloc( GetProcessHeap(), 0, (size + 1) * sizeof(*xpoints) );
points = HeapAlloc( GetProcessHeap(), 0, size * sizeof(*points) );
flags = HeapAlloc( GetProcessHeap(), 0, size * sizeof(*flags) );
if (!points || !flags || !xpoints) goto done;
if (GetPath( dev->hdc, points, flags, size ) == -1) goto done;
LPtoDP( dev->hdc, points, size );
if (fill && X11DRV_SetupGCForBrush( physDev ))
{
XRectangle *rect;
HRGN hrgn = PathToRegion( dev->hdc );
RGNDATA *data = X11DRV_GetRegionData( hrgn, 0 );
DeleteObject( hrgn );
if (!data) goto done;
rect = (XRectangle *)data->Buffer;
for (i = 0; i < data->rdh.nCount; i++)
{
rect[i].x += physDev->dc_rect.left;
rect[i].y += physDev->dc_rect.top;
}
XFillRectangles( gdi_display, physDev->drawable, physDev->gc, rect, data->rdh.nCount );
HeapFree( GetProcessHeap(), 0, data );
}
if (stroke && X11DRV_SetupGCForPen ( physDev ))
{
for (i = j = 0; i < size; i++, j++)
{
if (flags[i] == PT_MOVETO)
{
if (j > 1)
{
if (fill || (flags[i - 1] & PT_CLOSEFIGURE)) xpoints[j++] = xpoints[0];
XDrawLines( gdi_display, physDev->drawable, physDev->gc, xpoints, j, CoordModeOrigin );
}
j = 0;
}
xpoints[j].x = physDev->dc_rect.left + points[i].x;
xpoints[j].y = physDev->dc_rect.top + points[i].y;
}
if (j > 1)
{
if (fill || (flags[i - 1] & PT_CLOSEFIGURE)) xpoints[j++] = xpoints[0];
XDrawLines( gdi_display, physDev->drawable, physDev->gc, xpoints, j, CoordModeOrigin );
}
}
add_pen_device_bounds( physDev, points, size );
AbortPath( dev->hdc );
ret = TRUE;
done:
HeapFree( GetProcessHeap(), 0, xpoints );
HeapFree( GetProcessHeap(), 0, points );
HeapFree( GetProcessHeap(), 0, flags );
return ret;
}
/**********************************************************************
* X11DRV_FillPath
*/
BOOL X11DRV_FillPath( PHYSDEV dev )
{
return x11drv_stroke_and_fill_path( dev, FALSE, TRUE );
}
/**********************************************************************
* X11DRV_StrokeAndFillPath
*/
BOOL X11DRV_StrokeAndFillPath( PHYSDEV dev )
{
return x11drv_stroke_and_fill_path( dev, TRUE, TRUE );
}
/**********************************************************************
* X11DRV_StrokePath
*/
BOOL X11DRV_StrokePath( PHYSDEV dev )
{
return x11drv_stroke_and_fill_path( dev, TRUE, FALSE );
}
/**********************************************************************
* X11DRV_InternalFloodFill

View File

@ -494,7 +494,7 @@ static const struct gdi_dc_funcs x11drv_funcs =
X11DRV_ExtFloodFill, /* pExtFloodFill */
NULL, /* pExtSelectClipRgn */
NULL, /* pExtTextOut */
NULL, /* pFillPath */
X11DRV_FillPath, /* pFillPath */
NULL, /* pFillRgn */
NULL, /* pFlattenPath */
NULL, /* pFontIsLinked */
@ -589,8 +589,8 @@ static const struct gdi_dc_funcs x11drv_funcs =
NULL, /* pStartPage */
X11DRV_StretchBlt, /* pStretchBlt */
NULL, /* pStretchDIBits */
NULL, /* pStrokeAndFillPath */
NULL, /* pStrokePath */
X11DRV_StrokeAndFillPath, /* pStrokeAndFillPath */
X11DRV_StrokePath, /* pStrokePath */
X11DRV_UnrealizePalette, /* pUnrealizePalette */
NULL, /* pWidenPath */
X11DRV_wine_get_wgl_driver, /* wine_get_wgl_driver */

View File

@ -150,6 +150,7 @@ extern BOOL X11DRV_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
extern BOOL X11DRV_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT bottom ) DECLSPEC_HIDDEN;
extern INT X11DRV_EnumICMProfiles( PHYSDEV dev, ICMENUMPROCW proc, LPARAM lparam ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT fillType ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_GetDeviceGammaRamp( PHYSDEV dev, LPVOID ramp ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_GetICMProfile( PHYSDEV dev, LPDWORD size, LPWSTR filename ) DECLSPEC_HIDDEN;
extern DWORD X11DRV_GetImage( PHYSDEV dev, BITMAPINFO *info,
@ -183,6 +184,8 @@ extern BOOL X11DRV_SetDeviceGammaRamp( PHYSDEV dev, LPVOID ramp ) DECLSPEC_HIDDE
extern COLORREF X11DRV_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
PHYSDEV src_dev, struct bitblt_coords *src, DWORD rop ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_StrokeAndFillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_StrokePath( PHYSDEV dev ) DECLSPEC_HIDDEN;
extern BOOL X11DRV_UnrealizePalette( HPALETTE hpal ) DECLSPEC_HIDDEN;
/* X11 driver internal functions */