CXTPChartSolidSplinePolygonDeviceCommand::CXTPChartSolidSplinePolygonDeviceCommand(const CXTPChartPoints& points, const CXTPChartColor& color, BOOL bTwoSides)
{
	m_color = color;

	if (!bTwoSides)
	{
		GpPath* pGpPath = 0;
		GdipCreatePath(FillModeAlternate, &pGpPath);
		GdipStartPathFigure(pGpPath);

		int nCount = (int)points.GetSize();

		GdipAddPathLine(pGpPath, points[0].X, points[0].Y, points[1].X, points[1].Y);
		GdipAddPathCurve(pGpPath, (PointF*)points.GetData() + 1, nCount - 2);
		GdipAddPathLine(pGpPath, points[nCount - 2].X, points[nCount - 2].Y, points[nCount - 1].X, points[nCount - 1].Y);

		GdipClosePathFigures(pGpPath);

		m_pGpPath = pGpPath;
	}
	else
	{

		GpPath* pGpPath = 0;
		GdipCreatePath(FillModeAlternate, &pGpPath);
		GdipStartPathFigure(pGpPath);

		int nCount = (int)points.GetSize();

		GdipAddPathCurve(pGpPath, (PointF*)points.GetData(), nCount / 2);
		GdipAddPathLine(pGpPath, points[nCount / 2].X, points[nCount / 2].Y, points[nCount / 2 + 1].X, points[nCount / 2 + 1].Y);

		GdipAddPathCurve(pGpPath, (PointF*)points.GetData() + nCount / 2, nCount / 2);

		GdipAddPathLine(pGpPath, points[nCount - 1].X, points[nCount - 1].Y, points[0].X, points[0].Y);

		GdipClosePathFigures(pGpPath);

		m_pGpPath = pGpPath;

	}
}
CXTPChartDeviceCommand* CXTPChartAreaSeriesView::CreateDeviceCommand(CXTPChartDeviceContext* pDC)
{
	CXTPChartDeviceCommand* pSeriesCommand = new CXTPChartHitTestElementCommand(m_pSeries);
	CXTPChartDeviceCommand* pCommand = pSeriesCommand->AddChildCommand(new CXTPChartPolygonAntialiasingDeviceCommand());

	CXTPChartAreaSeriesStyle* pStyle = (CXTPChartAreaSeriesStyle*)GetStyle();

	CXTPChartAxis* pAxisY = GetAxisViewY()->GetAxis();

	CXTPChartColor clrBorder = GetBorderActualColor();

	double dZero = max(0, pAxisY->GetRange()->GetMinValue());

	int nCount = m_pPointsView->GetCount();
	if (nCount > 1)
	{
		CXTPChartPointSeriesPointView* pPointView =  (CXTPChartPointSeriesPointView*)m_pPointsView->GetAt(0);

		CXTPChartPointF pointPrev = GetScreenPoint(pPointView->GetPoint()->GetInternalArgumentValue(), pPointView->m_dInternalValue);

		CXTPChartPoints arrPoints;
		arrPoints.Add(GetScreenPoint(pPointView->GetPoint()->GetInternalArgumentValue(), dZero));

		for (int i = 1; i < nCount; i++)
		{
			pPointView =  (CXTPChartPointSeriesPointView*)m_pPointsView->GetAt(i);
			CXTPChartPointF pointNext = pPointView->GetScreenPoint();

			arrPoints.Add(pointPrev);

			pointPrev = pointNext;
		}

		arrPoints.Add(pointPrev);

		pPointView =  (CXTPChartPointSeriesPointView*)m_pPointsView->GetAt(nCount - 1);

		arrPoints.Add(GetScreenPoint(pPointView->GetPoint()->GetInternalArgumentValue(), dZero));

		pCommand->AddChildCommand(pStyle->GetFillStyle()->CreateDeviceCommand(arrPoints, GetActualColor(), GetActualColor2()));


		arrPoints.RemoveAt(0);
		arrPoints.RemoveAt(arrPoints.GetSize() - 1);

		if (pStyle->GetBorder()->IsVisible())
			pCommand->AddChildCommand(new CXTPChartSolidPolylineDeviceCommand(arrPoints, clrBorder, pStyle->GetBorder()->GetThickness()));
	}

	pCommand->AddChildCommand(CXTPChartSeriesView::CreateDeviceCommand(pDC));

	return pSeriesCommand;
}
CXTPChartClipRegionDeviceCommand::CXTPChartClipRegionDeviceCommand(const CXTPChartPoints& points)
{
	GpPath* pGpPath = NULL;
	GdipCreatePath(FillModeAlternate, &pGpPath);
	GdipAddPathPolygon(pGpPath, (GpPointF*)points.GetData(), (int)points.GetSize());

	m_pGpClip = NULL;
	GdipCreateRegionPath(pGpPath, &m_pGpClip);

	m_pGpState = NULL;
	GdipCreateRegion(&m_pGpState);

	GdipDeletePath(pGpPath);
}
CXTPChartPolygonDeviceCommand::CXTPChartPolygonDeviceCommand(const CXTPChartPoints& points)
{
	m_points.Copy(points);

	if (points.GetSize() != 0)
	{
		double xMax = points[0].X, xMin = points[0].X;
		double yMax = points[0].Y, yMin = points[0].Y;

		for (int i = 1; i < points.GetSize(); i++)
		{
			xMax = max(xMax, points[i].X);
			yMax = max(yMax, points[i].Y);
			xMin = min(xMin, points[i].X);
			yMin = min(yMin, points[i].Y);
		}

		m_bounds.X = (REAL)xMin;
		m_bounds.Y = (REAL)yMin;
		m_bounds.Width = (REAL)(xMax - xMin);
		m_bounds.Height = (REAL)(yMax - yMin);
	}
}