{
double angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
/* Initialize angleEndQuadrant to silence gcc's warning */doublex, y;
FLOAT_POINT corners[2], pointStart, pointEnd;
POINT centre, pointCurPos;
BOOLstart, end, Ret = TRUE;
INTtemp;
BOOL clockwise;
PPATH pPath;
/* FIXME: This function should check for all possible error returns *//* FIXME: Do we have to respect newStroke? */ASSERT ( dc );
pPath = PATH_LockPath( dc->dclevel.hPath );
if (!pPath) returnFALSE;
clockwise = ((dc->dclevel.flPath & DCPATH_CLOCKWISE) != 0);
/* Check that path is open */if ( pPath->state != PATH_Open )
{
Ret = FALSE;
goto ArcExit;
}
/* Check for zero height / width *//* FIXME: Only in GM_COMPATIBLE? */if ( x1==x2 || y1==y2 )
{
Ret = TRUE;
goto ArcExit;
}
/* Convert points to device coordinates */
corners[0].x=(FLOAT)x1;
corners[0].y=(FLOAT)y1;
corners[1].x=(FLOAT)x2;
corners[1].y=(FLOAT)y2;
pointStart.x=(FLOAT)xStart;
pointStart.y=(FLOAT)yStart;
pointEnd.x=(FLOAT)xEnd;
pointEnd.y=(FLOAT)yEnd;
INTERNAL_LPTODP_FLOAT(dc, corners);
INTERNAL_LPTODP_FLOAT(dc, corners+1);
INTERNAL_LPTODP_FLOAT(dc, &pointStart);
INTERNAL_LPTODP_FLOAT(dc, &pointEnd);
/* Make sure first corner is top left and second corner is bottom right */if ( corners[0].x > corners[1].x )
{
temp=corners[0].x;
corners[0].x=corners[1].x;
corners[1].x=temp;
}
if ( corners[0].y > corners[1].y )
{
temp=corners[0].y;
corners[0].y=corners[1].y;
corners[1].y=temp;
}
/* Compute start and end angle */PATH_NormalizePoint(corners, &pointStart, &x, &y);
angleStart=atan2(y, x);
PATH_NormalizePoint(corners, &pointEnd, &x, &y);
angleEnd=atan2(y, x);
/* Make sure the end angle is "on the right side" of the start angle */if ( clockwise )
{
if ( angleEnd <= angleStart )
{
angleEnd+=2*M_PI;
ASSERT(angleEnd>=angleStart);
}
}
else
{
if(angleEnd>=angleStart)
{
angleEnd-=2*M_PI;
ASSERT(angleEnd<=angleStart);
}
}
/* In GM_COMPATIBLE, don't include bottom and right edges */if (dc->pdcattr->iGraphicsMode == GM_COMPATIBLE )
{
corners[1].x--;
corners[1].y--;
}
/* arcto: Add a PT_MOVETO only if this is the first entry in a stroke */if(lines==GdiTypeArcTo && pPath->newStroke) // -1
{
pPath->newStroke=FALSE;
IntGetCurrentPositionEx ( dc, &pointCurPos );
CoordLPtoDP(dc, &pointCurPos);
if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO))
{
Ret = FALSE;
goto ArcExit;
}
}
/* Add the arc to the path with one Bezier spline per quadrant that the * arc spans */
start=TRUE;
end=FALSE;
do
{
/* Determine the start and end angles for this quadrant */if(start)
{
angleStartQuadrant=angleStart;
if ( clockwise )
angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2;
else
angleEndQuadrant=(ceil(angleStart/M_PI_2)-1.0)*M_PI_2;
}
else
{
angleStartQuadrant=angleEndQuadrant;
if ( clockwise )
angleEndQuadrant+=M_PI_2;
else
angleEndQuadrant-=M_PI_2;
}
/* Have we reached the last part of the arc? */if ( (clockwise && angleEnd<angleEndQuadrant)
|| (!clockwise && angleEnd>angleEndQuadrant)
)
{
/* Adjust the end angle for this quadrant */
angleEndQuadrant = angleEnd;
end = TRUE;
}
/* Add the Bezier spline to the path */PATH_DoArcPart ( pPath, corners, angleStartQuadrant, angleEndQuadrant,
start ? (lines==GdiTypeArcTo ? PT_LINETO : PT_MOVETO) : FALSE ); // -1
start = FALSE;
} while(!end);
/* chord: close figure. pie: add line and close figure */if (lines==GdiTypeChord) // 1
{
IntGdiCloseFigure(pPath);
}
elseif (lines==GdiTypePie) // 2
{
centre.x = (corners[0].x+corners[1].x)/2;
centre.y = (corners[0].y+corners[1].y)/2;
if(!PATH_AddEntry(pPath, ¢re, PT_LINETO | PT_CLOSEFIGURE))
Ret = FALSE;
}
ArcExit:
PATH_UnlockPath( pPath );
return Ret;
}
Generated on Sat May 26 2012 06:10:00 for ReactOS by
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.