gdi32: Implement FillPath, StrokeAndFillPath and StrokePath in the DIB driver.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3054c0fd1b
commit
b5cf73edd9
|
@ -424,7 +424,7 @@ const struct gdi_dc_funcs dib_driver =
|
||||||
dibdrv_ExtFloodFill, /* pExtFloodFill */
|
dibdrv_ExtFloodFill, /* pExtFloodFill */
|
||||||
NULL, /* pExtSelectClipRgn */
|
NULL, /* pExtSelectClipRgn */
|
||||||
dibdrv_ExtTextOut, /* pExtTextOut */
|
dibdrv_ExtTextOut, /* pExtTextOut */
|
||||||
NULL, /* pFillPath */
|
dibdrv_FillPath, /* pFillPath */
|
||||||
NULL, /* pFillRgn */
|
NULL, /* pFillRgn */
|
||||||
NULL, /* pFlattenPath */
|
NULL, /* pFlattenPath */
|
||||||
NULL, /* pFontIsLinked */
|
NULL, /* pFontIsLinked */
|
||||||
|
@ -519,8 +519,8 @@ const struct gdi_dc_funcs dib_driver =
|
||||||
NULL, /* pStartPage */
|
NULL, /* pStartPage */
|
||||||
dibdrv_StretchBlt, /* pStretchBlt */
|
dibdrv_StretchBlt, /* pStretchBlt */
|
||||||
NULL, /* pStretchDIBits */
|
NULL, /* pStretchDIBits */
|
||||||
NULL, /* pStrokeAndFillPath */
|
dibdrv_StrokeAndFillPath, /* pStrokeAndFillPath */
|
||||||
NULL, /* pStrokePath */
|
dibdrv_StrokePath, /* pStrokePath */
|
||||||
NULL, /* pUnrealizePalette */
|
NULL, /* pUnrealizePalette */
|
||||||
NULL, /* pWidenPath */
|
NULL, /* pWidenPath */
|
||||||
dibdrv_wine_get_wgl_driver, /* wine_get_wgl_driver */
|
dibdrv_wine_get_wgl_driver, /* wine_get_wgl_driver */
|
||||||
|
|
|
@ -120,6 +120,7 @@ extern BOOL dibdrv_Ellipse( PHYSDEV dev, INT left, INT top, INT right, INT b
|
||||||
extern BOOL dibdrv_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT type ) DECLSPEC_HIDDEN;
|
extern BOOL dibdrv_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT type ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL dibdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
extern BOOL dibdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
|
||||||
const RECT *rect, LPCWSTR str, UINT count, const INT *dx ) DECLSPEC_HIDDEN;
|
const RECT *rect, LPCWSTR str, UINT count, const INT *dx ) DECLSPEC_HIDDEN;
|
||||||
|
extern BOOL dibdrv_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||||
extern DWORD dibdrv_GetImage( PHYSDEV dev, BITMAPINFO *info, struct gdi_image_bits *bits,
|
extern DWORD dibdrv_GetImage( PHYSDEV dev, BITMAPINFO *info, struct gdi_image_bits *bits,
|
||||||
struct bitblt_coords *src ) DECLSPEC_HIDDEN;
|
struct bitblt_coords *src ) DECLSPEC_HIDDEN;
|
||||||
extern COLORREF dibdrv_GetNearestColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
|
extern COLORREF dibdrv_GetNearestColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HIDDEN;
|
||||||
|
@ -150,6 +151,8 @@ extern COLORREF dibdrv_SetDCPenColor( PHYSDEV dev, COLORREF color ) DECLSPEC_HID
|
||||||
extern COLORREF dibdrv_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) DECLSPEC_HIDDEN;
|
extern COLORREF dibdrv_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL dibdrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
extern BOOL dibdrv_StretchBlt( PHYSDEV dst_dev, struct bitblt_coords *dst,
|
||||||
PHYSDEV src_dev, struct bitblt_coords *src, DWORD rop ) DECLSPEC_HIDDEN;
|
PHYSDEV src_dev, struct bitblt_coords *src, DWORD rop ) DECLSPEC_HIDDEN;
|
||||||
|
extern BOOL dibdrv_StrokeAndFillPath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||||
|
extern BOOL dibdrv_StrokePath( PHYSDEV dev ) DECLSPEC_HIDDEN;
|
||||||
extern struct opengl_funcs *dibdrv_wine_get_wgl_driver( PHYSDEV dev, UINT version ) DECLSPEC_HIDDEN;
|
extern struct opengl_funcs *dibdrv_wine_get_wgl_driver( PHYSDEV dev, UINT version ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
static inline dibdrv_physdev *get_dibdrv_pdev( PHYSDEV dev )
|
static inline dibdrv_physdev *get_dibdrv_pdev( PHYSDEV dev )
|
||||||
|
|
|
@ -402,6 +402,73 @@ static BOOL draw_arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* helper for path stroking and filling functions */
|
||||||
|
static BOOL stroke_and_fill_path( dibdrv_physdev *dev, BOOL stroke, BOOL fill )
|
||||||
|
{
|
||||||
|
POINT *points;
|
||||||
|
BYTE *types;
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
HRGN outline = 0, interior = 0;
|
||||||
|
int i, pos, total;
|
||||||
|
|
||||||
|
if (dev->brush.style == BS_NULL) fill = FALSE;
|
||||||
|
|
||||||
|
total = get_gdi_flat_path( dev->dev.hdc, &points, &types, fill ? &interior : NULL );
|
||||||
|
if (total == -1) return FALSE;
|
||||||
|
if (!total) goto done;
|
||||||
|
|
||||||
|
if (stroke && dev->pen_uses_region) outline = CreateRectRgn( 0, 0, 0, 0 );
|
||||||
|
|
||||||
|
/* if not using a region, paint the interior first so the outline can overlap it */
|
||||||
|
if (interior && !outline)
|
||||||
|
{
|
||||||
|
ret = brush_region( dev, interior );
|
||||||
|
DeleteObject( interior );
|
||||||
|
interior = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stroke)
|
||||||
|
{
|
||||||
|
pos = 0;
|
||||||
|
for (i = 1; i < total; i++)
|
||||||
|
{
|
||||||
|
if (types[i] != PT_MOVETO) continue;
|
||||||
|
if (i > pos + 1)
|
||||||
|
{
|
||||||
|
reset_dash_origin( dev );
|
||||||
|
dev->pen_lines( dev, i - pos, points + pos,
|
||||||
|
fill || types[i - 1] & PT_CLOSEFIGURE, outline );
|
||||||
|
}
|
||||||
|
pos = i;
|
||||||
|
}
|
||||||
|
if (i > pos + 1)
|
||||||
|
{
|
||||||
|
reset_dash_origin( dev );
|
||||||
|
dev->pen_lines( dev, i - pos, points + pos,
|
||||||
|
fill || types[i - 1] & PT_CLOSEFIGURE, outline );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add_pen_lines_bounds( dev, total, points, outline );
|
||||||
|
|
||||||
|
if (interior)
|
||||||
|
{
|
||||||
|
CombineRgn( interior, interior, outline, RGN_DIFF );
|
||||||
|
ret = brush_region( dev, interior );
|
||||||
|
DeleteObject( interior );
|
||||||
|
}
|
||||||
|
if (outline)
|
||||||
|
{
|
||||||
|
if (ret) ret = pen_region( dev, outline );
|
||||||
|
DeleteObject( outline );
|
||||||
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
|
HeapFree( GetProcessHeap(), 0, points );
|
||||||
|
HeapFree( GetProcessHeap(), 0, types );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Intensities of the 17 glyph levels when drawn with text component of 0xff on a
|
/* Intensities of the 17 glyph levels when drawn with text component of 0xff on a
|
||||||
black bkgnd. [A log-log plot of these data gives: y = 77.05 * x^0.4315]. */
|
black bkgnd. [A log-log plot of these data gives: y = 77.05 * x^0.4315]. */
|
||||||
static const BYTE ramp[17] =
|
static const BYTE ramp[17] =
|
||||||
|
@ -999,6 +1066,16 @@ BOOL dibdrv_ExtFloodFill( PHYSDEV dev, INT x, INT y, COLORREF color, UINT type )
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* dibdrv_FillPath
|
||||||
|
*/
|
||||||
|
BOOL dibdrv_FillPath( PHYSDEV dev )
|
||||||
|
{
|
||||||
|
dibdrv_physdev *pdev = get_dibdrv_pdev( dev );
|
||||||
|
|
||||||
|
return stroke_and_fill_path( pdev, FALSE, TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* dibdrv_GetNearestColor
|
* dibdrv_GetNearestColor
|
||||||
*/
|
*/
|
||||||
|
@ -1499,3 +1576,23 @@ COLORREF dibdrv_SetPixel( PHYSDEV dev, INT x, INT y, COLORREF color )
|
||||||
free_clipped_rects( &clipped_rects );
|
free_clipped_rects( &clipped_rects );
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* dibdrv_StrokeAndFillPath
|
||||||
|
*/
|
||||||
|
BOOL dibdrv_StrokeAndFillPath( PHYSDEV dev )
|
||||||
|
{
|
||||||
|
dibdrv_physdev *pdev = get_dibdrv_pdev( dev );
|
||||||
|
|
||||||
|
return stroke_and_fill_path( pdev, TRUE, TRUE );
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* dibdrv_StrokePath
|
||||||
|
*/
|
||||||
|
BOOL dibdrv_StrokePath( PHYSDEV dev )
|
||||||
|
{
|
||||||
|
dibdrv_physdev *pdev = get_dibdrv_pdev( dev );
|
||||||
|
|
||||||
|
return stroke_and_fill_path( pdev, TRUE, FALSE );
|
||||||
|
}
|
||||||
|
|
|
@ -335,6 +335,7 @@ typedef struct
|
||||||
/* path.c */
|
/* path.c */
|
||||||
|
|
||||||
extern void free_gdi_path( struct gdi_path *path ) DECLSPEC_HIDDEN;
|
extern void free_gdi_path( struct gdi_path *path ) DECLSPEC_HIDDEN;
|
||||||
|
extern int get_gdi_flat_path( HDC hdc, POINT **points, BYTE **flags, HRGN *rgn ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL PATH_SavePath( DC *dst, DC *src ) DECLSPEC_HIDDEN;
|
extern BOOL PATH_SavePath( DC *dst, DC *src ) DECLSPEC_HIDDEN;
|
||||||
extern BOOL PATH_RestorePath( DC *dst, DC *src ) DECLSPEC_HIDDEN;
|
extern BOOL PATH_RestorePath( DC *dst, DC *src ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -273,6 +273,32 @@ static BOOL start_new_stroke( struct path_physdev *physdev )
|
||||||
return add_log_points( physdev, &pos, 1, PT_MOVETO ) != NULL;
|
return add_log_points( physdev, &pos, 1, PT_MOVETO ) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* convert a (flattened) path to a region */
|
||||||
|
static HRGN path_to_region( const struct gdi_path *path, int mode )
|
||||||
|
{
|
||||||
|
int i, pos, polygons, *counts;
|
||||||
|
HRGN hrgn;
|
||||||
|
|
||||||
|
if (!path->count) return 0;
|
||||||
|
|
||||||
|
if (!(counts = HeapAlloc( GetProcessHeap(), 0, (path->count / 2) * sizeof(*counts) ))) return 0;
|
||||||
|
|
||||||
|
pos = polygons = 0;
|
||||||
|
assert( path->flags[0] == PT_MOVETO );
|
||||||
|
for (i = 1; i < path->count; i++)
|
||||||
|
{
|
||||||
|
if (path->flags[i] != PT_MOVETO) continue;
|
||||||
|
counts[polygons++] = i - pos;
|
||||||
|
pos = i;
|
||||||
|
}
|
||||||
|
if (i > pos + 1) counts[polygons++] = i - pos;
|
||||||
|
|
||||||
|
assert( polygons <= path->count / 2 );
|
||||||
|
hrgn = CreatePolyPolygonRgn( path->points, counts, polygons, mode );
|
||||||
|
HeapFree( GetProcessHeap(), 0, counts );
|
||||||
|
return hrgn;
|
||||||
|
}
|
||||||
|
|
||||||
/* PATH_CheckCorners
|
/* PATH_CheckCorners
|
||||||
*
|
*
|
||||||
* Helper function for RoundRect() and Rectangle()
|
* Helper function for RoundRect() and Rectangle()
|
||||||
|
@ -505,6 +531,37 @@ static BOOL PATH_DoArcPart(struct gdi_path *pPath, FLOAT_POINT corners[],
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* retrieve a flattened path in device coordinates, and optionally its region */
|
||||||
|
/* the DC path is deleted; the returned data must be freed by caller */
|
||||||
|
/* helper for stroke_and_fill_path in the DIB driver */
|
||||||
|
int get_gdi_flat_path( HDC hdc, POINT **points, BYTE **flags, HRGN *rgn )
|
||||||
|
{
|
||||||
|
DC *dc = get_dc_ptr( hdc );
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!dc) return -1;
|
||||||
|
|
||||||
|
if (dc->path)
|
||||||
|
{
|
||||||
|
struct gdi_path *path = PATH_FlattenPath( dc->path );
|
||||||
|
|
||||||
|
free_gdi_path( dc->path );
|
||||||
|
dc->path = NULL;
|
||||||
|
if (path)
|
||||||
|
{
|
||||||
|
ret = path->count;
|
||||||
|
*points = path->points;
|
||||||
|
*flags = path->flags;
|
||||||
|
if (rgn) *rgn = path_to_region( path, GetPolyFillMode( hdc ));
|
||||||
|
HeapFree( GetProcessHeap(), 0, path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else SetLastError( ERROR_CAN_NOT_COMPLETE );
|
||||||
|
|
||||||
|
release_dc_ptr( dc );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* BeginPath (GDI32.@)
|
* BeginPath (GDI32.@)
|
||||||
|
|
Loading…
Reference in New Issue