gdi32: Handle EMFs directly in arc functions.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-07-20 09:19:24 +02:00 committed by Alexandre Julliard
parent b825727d1d
commit b9f773ded1
4 changed files with 83 additions and 74 deletions

View file

@ -612,32 +612,6 @@ static BOOL CDECL emfpathdrv_AngleArc( PHYSDEV dev, INT x, INT y, DWORD radius,
next->funcs->pAngleArc( next, x, y, radius, start, sweep ));
}
/***********************************************************************
* emfpathdrv_Arc
*/
static BOOL CDECL emfpathdrv_Arc( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArc );
return (emfdev->funcs->pArc( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
next->funcs->pArc( next, left, top, right, bottom, xstart, ystart, xend, yend ));
}
/***********************************************************************
* emfpathdrv_ArcTo
*/
static BOOL CDECL emfpathdrv_ArcTo( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pArcTo );
return (emfdev->funcs->pArcTo( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
next->funcs->pArcTo( next, left, top, right, bottom, xstart, ystart, xend, yend ));
}
/***********************************************************************
* emfpathdrv_BeginPath
*/
@ -649,19 +623,6 @@ static BOOL CDECL emfpathdrv_BeginPath( PHYSDEV dev )
return (emfdev->funcs->pBeginPath( emfdev ) && next->funcs->pBeginPath( next ));
}
/***********************************************************************
* emfpathdrv_Chord
*/
static BOOL CDECL emfpathdrv_Chord( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pChord );
return (emfdev->funcs->pChord( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
next->funcs->pChord( next, left, top, right, bottom, xstart, ystart, xend, yend ));
}
/***********************************************************************
* emfpathdrv_CloseFigure
*/
@ -734,19 +695,6 @@ static BOOL CDECL emfpathdrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
next->funcs->pExtTextOut( next, x, y, flags, rect, str, count, dx ));
}
/***********************************************************************
* emfpathdrv_Pie
*/
static BOOL CDECL emfpathdrv_Pie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
PHYSDEV emfdev = get_emfdev( dev );
PHYSDEV next = GET_NEXT_PHYSDEV( dev, pPie );
return (emfdev->funcs->pPie( emfdev, left, top, right, bottom, xstart, ystart, xend, yend ) &&
next->funcs->pPie( next, left, top, right, bottom, xstart, ystart, xend, yend ));
}
/***********************************************************************
* emfpathdrv_PolyBezier
*/
@ -875,11 +823,11 @@ static const struct gdi_dc_funcs emfpath_driver =
emfpathdrv_AbortPath, /* pAbortPath */
NULL, /* pAlphaBlend */
emfpathdrv_AngleArc, /* pAngleArc */
emfpathdrv_Arc, /* pArc */
emfpathdrv_ArcTo, /* pArcTo */
NULL, /* pArc */
NULL, /* pArcTo */
emfpathdrv_BeginPath, /* pBeginPath */
NULL, /* pBlendImage */
emfpathdrv_Chord, /* pChord */
NULL, /* pChord */
emfpathdrv_CloseFigure, /* pCloseFigure */
NULL, /* pCreateCompatibleDC */
emfpathdrv_CreateDC, /* pCreateDC */
@ -939,7 +887,7 @@ static const struct gdi_dc_funcs emfpath_driver =
NULL, /* pOffsetWindowOrg */
NULL, /* pPaintRgn */
NULL, /* pPatBlt */
emfpathdrv_Pie, /* pPie */
NULL, /* pPie */
emfpathdrv_PolyBezier, /* pPolyBezier */
emfpathdrv_PolyBezierTo, /* pPolyBezierTo */
emfpathdrv_PolyDraw, /* pPolyDraw */

View file

@ -168,14 +168,46 @@ BOOL CDECL EMFDRV_LineTo( PHYSDEV dev, INT x, INT y )
return TRUE;
}
/***********************************************************************
* EMFDC_ArcChordPie
*/
BOOL EMFDC_ArcChordPie( DC_ATTR *dc_attr, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend, DWORD type )
{
EMFDRV_PDEVICE *emf = dc_attr->emf;
EMRARC emr;
INT temp;
if (left == right || top == bottom) return FALSE;
if (left > right) { temp = left; left = right; right = temp; }
if (top > bottom) { temp = top; top = bottom; bottom = temp; }
if (dc_attr->graphics_mode == GM_COMPATIBLE)
{
right--;
bottom--;
}
emr.emr.iType = type;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
emr.rclBox.right = right;
emr.rclBox.bottom = bottom;
emr.ptlStart.x = xstart;
emr.ptlStart.y = ystart;
emr.ptlEnd.x = xend;
emr.ptlEnd.y = yend;
return EMFDRV_WriteRecord( &emf->dev, &emr.emr );
}
/***********************************************************************
* EMFDRV_ArcChordPie
*/
static BOOL
EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend, DWORD iType )
static BOOL EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend, DWORD type )
{
EMFDRV_PDEVICE *physDev = get_emf_physdev( dev );
DC *dc = get_physdev_dc( dev );
INT temp, xCentre, yCentre, i;
double angleStart, angleEnd;
@ -188,12 +220,13 @@ EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
if(left > right) {temp = left; left = right; right = temp;}
if(top > bottom) {temp = top; top = bottom; bottom = temp;}
if(dc->attr->graphics_mode == GM_COMPATIBLE) {
if (dc->attr->graphics_mode == GM_COMPATIBLE)
{
right--;
bottom--;
}
emr.emr.iType = iType;
emr.emr.iType = type;
emr.emr.nSize = sizeof(emr);
emr.rclBox.left = left;
emr.rclBox.top = top;
@ -260,13 +293,14 @@ EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
}
/* If we're drawing a pie then make sure we include the centre */
if(iType == EMR_PIE) {
if (type == EMR_PIE)
{
if(bounds.left > xCentre) bounds.left = xCentre;
else if(bounds.right < xCentre) bounds.right = xCentre;
if(bounds.top > yCentre) bounds.top = yCentre;
else if(bounds.bottom < yCentre) bounds.bottom = yCentre;
}
if (iType == EMR_ARCTO)
else if (type == EMR_ARCTO)
{
POINT pt;
pt = dc->attr->cur_pos;
@ -275,14 +309,10 @@ EMFDRV_ArcChordPie( PHYSDEV dev, INT left, INT top, INT right, INT bottom,
bounds.right = max( bounds.right, pt.x );
bounds.bottom = max( bounds.bottom, pt.y );
}
if(!EMFDRV_WriteRecord( dev, &emr.emr ))
return FALSE;
if(!physDev->path)
EMFDRV_UpdateBBox( dev, &bounds );
return TRUE;
}
/***********************************************************************
* EMFDRV_Arc
*/

View file

@ -52,6 +52,9 @@ extern BOOL METADC_Pie( HDC hdc, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend ) DECLSPEC_HIDDEN;
/* enhanced metafiles */
extern BOOL EMFDC_ArcChordPie( DC_ATTR *dc_attr, INT left, INT top, INT right,
INT bottom, INT xstart, INT ystart, INT xend,
INT yend, DWORD type ) DECLSPEC_HIDDEN;
extern BOOL EMFDC_LineTo( DC_ATTR *dc_attr, INT x, INT y ) DECLSPEC_HIDDEN;
extern BOOL EMFDC_MoveTo( DC_ATTR *dc_attr, INT x, INT y ) DECLSPEC_HIDDEN;

View file

@ -84,6 +84,8 @@ BOOL WINAPI MoveToEx( HDC hdc, INT x, INT y, POINT *pt )
BOOL WINAPI Arc( HDC hdc, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
DC_ATTR *dc_attr;
TRACE( "%p, (%d, %d)-(%d, %d), (%d, %d), (%d, %d)\n", hdc, left, top,
right, bottom, xstart, ystart, xend, yend );
@ -91,6 +93,11 @@ BOOL WINAPI Arc( HDC hdc, INT left, INT top, INT right, INT bottom,
return METADC_Arc( hdc, left, top, right, bottom,
xstart, ystart, xend, yend );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom,
xstart, ystart, xend, yend, EMR_ARC ))
return FALSE;
return NtGdiArcInternal( NtGdiArc, hdc, left, top, right, bottom,
xstart, ystart, xend, yend );
}
@ -101,9 +108,16 @@ BOOL WINAPI Arc( HDC hdc, INT left, INT top, INT right, INT bottom,
BOOL WINAPI ArcTo( HDC hdc, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
DC_ATTR *dc_attr;
TRACE( "%p, (%d, %d)-(%d, %d), (%d, %d), (%d, %d)\n", hdc, left, top,
right, bottom, xstart, ystart, xend, yend );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom,
xstart, ystart, xend, yend, EMR_ARCTO ))
return FALSE;
return NtGdiArcInternal( NtGdiArcTo, hdc, left, top, right, bottom,
xstart, ystart, xend, yend );
}
@ -114,6 +128,8 @@ BOOL WINAPI ArcTo( HDC hdc, INT left, INT top, INT right, INT bottom,
BOOL WINAPI Chord( HDC hdc, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
DC_ATTR *dc_attr;
TRACE( "%p, (%d, %d)-(%d, %d), (%d, %d), (%d, %d)\n", hdc, left, top,
right, bottom, xstart, ystart, xend, yend );
@ -121,6 +137,11 @@ BOOL WINAPI Chord( HDC hdc, INT left, INT top, INT right, INT bottom,
return METADC_Chord( hdc, left, top, right, bottom,
xstart, ystart, xend, yend );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom,
xstart, ystart, xend, yend, EMR_CHORD ))
return FALSE;
return NtGdiArcInternal( NtGdiChord, hdc, left, top, right, bottom,
xstart, ystart, xend, yend );
}
@ -131,6 +152,8 @@ BOOL WINAPI Chord( HDC hdc, INT left, INT top, INT right, INT bottom,
BOOL WINAPI Pie( HDC hdc, INT left, INT top, INT right, INT bottom,
INT xstart, INT ystart, INT xend, INT yend )
{
DC_ATTR *dc_attr;
TRACE( "%p, (%d, %d)-(%d, %d), (%d, %d), (%d, %d)\n", hdc, left, top,
right, bottom, xstart, ystart, xend, yend );
@ -138,6 +161,11 @@ BOOL WINAPI Pie( HDC hdc, INT left, INT top, INT right, INT bottom,
return METADC_Pie( hdc, left, top, right, bottom,
xstart, ystart, xend, yend );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE;
if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom,
xstart, ystart, xend, yend, EMR_PIE ))
return FALSE;
return NtGdiArcInternal( NtGdiPie, hdc, left, top, right, bottom,
xstart, ystart, xend, yend );
}