void CFDE_Path::AddCurve(const CFX_PointsF& points, FX_BOOL bClosed, FX_FLOAT fTension) { int32_t iLast = points.GetUpperBound(); if (iLast < 1) return; CFX_PointsF tangents; GetCurveTangents(points, tangents, bClosed, fTension); const CFX_PointF* pPoints = points.GetData(); CFX_PointF* pTangents = tangents.GetData(); MoveTo(pPoints[0]); for (int32_t i = 0; i < iLast; ++i) { BezierTo(CFX_PointF(pPoints[i].x + pTangents[i].x, pPoints[i].y + pTangents[i].y), CFX_PointF(pPoints[i + 1].x - pTangents[i + 1].x, pPoints[i + 1].y - pTangents[i + 1].y), CFX_PointF(pPoints[i + 1].x, pPoints[i + 1].y)); } if (bClosed) { BezierTo(CFX_PointF(pPoints[iLast].x + pTangents[iLast].x, pPoints[iLast].y + pTangents[iLast].y), CFX_PointF(pPoints[0].x - pTangents[0].x, pPoints[0].y - pTangents[0].y), CFX_PointF(pPoints[0].x, pPoints[0].y)); CloseFigure(); } }
void CFDE_Path::AddBezier(const CFX_PointsF& points) { if (points.GetSize() != 4) return; const CFX_PointF* p = points.GetData(); MoveTo(p[0]); BezierTo(p[1], p[2], p[3]); }
void CFDE_Path::AddLines(const CFX_PointsF& points) { int32_t iCount = points.GetSize(); if (iCount < 2) return; const CFX_PointF* p = points.GetData(); const CFX_PointF* pEnd = p + iCount; MoveTo(p[0]); for (++p; p < pEnd; ++p) LineTo(*p); }
void CFDE_Path::AddBeziers(const CFX_PointsF& points) { int32_t iCount = points.GetSize(); if (iCount < 4) return; const CFX_PointF* p = points.GetData(); const CFX_PointF* pEnd = p + iCount; MoveTo(p[0]); for (++p; p <= pEnd - 3; p += 3) BezierTo(p[0], p[1], p[2]); }
void CFDE_Path::AddPolygon(const CFX_PointsF& points) { int32_t iCount = points.GetSize(); if (iCount < 2) return; AddLines(points); const CFX_PointF* p = points.GetData(); if (FXSYS_fabs(p[0].x - p[iCount - 1].x) < 0.01f || FXSYS_fabs(p[0].y - p[iCount - 1].y) < 0.01f) { LineTo(p[0]); } CloseFigure(); }
FX_BOOL CFDE_GdiDevice::FillPolygon(IFDE_Brush* pBrush, const CFX_PointsF& points, const CFX_Matrix* pMatrix) { Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush); if (pGdiBrush == NULL) { return FALSE; } ApplyMatrix(pMatrix); Gdiplus::Status ret = m_pGraphics->FillPolygon( pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize()); RestoreMatrix(pMatrix); ReleaseGdiBrush(pGdiBrush); return ret == Gdiplus::Ok; }
FX_BOOL CFDE_GdiDevice::DrawCurve(IFDE_Pen* pPen, FX_FLOAT fPenWidth, const CFX_PointsF& points, FX_BOOL bClosed, FX_FLOAT fTension, const CFX_Matrix* pMatrix) { Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth); if (pGdiPen == NULL) { return FALSE; } ApplyMatrix(pMatrix); Gdiplus::Status ret = bClosed ? m_pGraphics->DrawClosedCurve( pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize(), fTension) : m_pGraphics->DrawCurve(pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize(), fTension); RestoreMatrix(pMatrix); ReleaseGdiPen(pGdiPen); return ret == Gdiplus::Ok; }
void CFDE_Path::GetCurveTangents(const CFX_PointsF& points, CFX_PointsF& tangents, FX_BOOL bClosed, FX_FLOAT fTension) const { int32_t iCount = points.GetSize(); tangents.SetSize(iCount); if (iCount < 3) return; FX_FLOAT fCoefficient = fTension / 3.0f; const CFX_PointF* pPoints = points.GetData(); CFX_PointF* pTangents = tangents.GetData(); for (int32_t i = 0; i < iCount; ++i) { int32_t r = i + 1; int32_t s = i - 1; if (r >= iCount) r = bClosed ? (r - iCount) : (iCount - 1); if (s < 0) s = bClosed ? (s + iCount) : 0; pTangents[i].x += (fCoefficient * (pPoints[r].x - pPoints[s].x)); pTangents[i].y += (fCoefficient * (pPoints[r].y - pPoints[s].y)); } }
FX_BOOL CFDE_GdiDevice::DrawLines(IFDE_Pen* pPen, FX_FLOAT fPenWidth, const CFX_PointsF& points, const CFX_Matrix* pMatrix) { Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth); if (pGdiPen == NULL) { return FALSE; } ApplyMatrix(pMatrix); Gdiplus::Status ret = m_pGraphics->DrawLines( pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize()); ApplyMatrix(pMatrix); ReleaseGdiPen(pGdiPen); return ret == Gdiplus::Ok; }
FX_BOOL CFDE_GdiDevice::FillClosedCurve(IFDE_Brush* pBrush, const CFX_PointsF& points, FX_FLOAT fTension, const CFX_Matrix* pMatrix) { Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush); if (pGdiBrush == NULL) { return FALSE; } ApplyMatrix(pMatrix); Gdiplus::Status ret = m_pGraphics->FillClosedCurve( pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize(), Gdiplus::FillModeAlternate, fTension); RestoreMatrix(pMatrix); ReleaseGdiBrush(pGdiBrush); return ret == Gdiplus::Ok; }