Files
core/DesktopEditor/raster/Metafile/Common/CPathConverter.cpp
2022-03-01 22:04:47 +03:00

171 lines
7.7 KiB
C++

#include "CPathConverter.h"
namespace MetaFile
{
CPathConverter::CPathConverter()
{}
CPathConverter::~CPathConverter()
{}
void CPathConverter::GetUpdatedPath(CEmfPath &oNewPath, CEmfPath &oLineCapPath, const CEmfPath &oPath, const CEmfPlusPen &oPen)
{
TEmfPlusPointF oLastPoint(0, 0);
for (const CEmfPathCommandBase* pCommand : oPath.m_pCommands)
{
switch (pCommand->GetType())
{
case EMF_PATHCOMMAND_UNKNOWN: break;
case EMF_PATHCOMMAND_MOVETO:
{
CEmfPathMoveTo *pCommandMoveTo = (CEmfPathMoveTo*)pCommand;
oNewPath.MoveTo(pCommandMoveTo->x, pCommandMoveTo->y);
oLastPoint.X = pCommandMoveTo->x;
oLastPoint.Y = pCommandMoveTo->y;
break;
}
case EMF_PATHCOMMAND_LINETO:
{
CEmfPathLineTo *pCommandLineTo = (CEmfPathLineTo*)pCommand;
double dAngle = -90 + (atan((pCommandLineTo->y - oLastPoint.Y) /
(pCommandLineTo->x - oLastPoint.X)) * 180 / 3.14);
if (AddLineStartCap(oLineCapPath, oPen, oLastPoint.X, oLastPoint.Y, dAngle + 180))
oNewPath.MoveTo(oLastPoint.X, oLastPoint.Y);
oLastPoint.X = pCommandLineTo->x;
oLastPoint.Y = pCommandLineTo->y;
AddLineEndCap(oLineCapPath, oPen, oLastPoint.X, oLastPoint.Y, dAngle);
oNewPath.LineTo(oLastPoint.X, oLastPoint.Y);
break;
}
case EMF_PATHCOMMAND_CURVETO:
{
CEmfPathCurveTo *pCommandCurveTo = (CEmfPathCurveTo*)pCommand;
oNewPath.CurveTo(pCommandCurveTo->x1, pCommandCurveTo->y1,
pCommandCurveTo->x2, pCommandCurveTo->y2,
pCommandCurveTo->xE, pCommandCurveTo->yE);
break;
}
case EMF_PATHCOMMAND_ARCTO:
{
CEmfPathArcTo *pCommandArcTo = (CEmfPathArcTo*)pCommand;
oNewPath.ArcTo(pCommandArcTo->left, pCommandArcTo->top,
pCommandArcTo->right, pCommandArcTo->bottom,
pCommandArcTo->start, pCommandArcTo->sweep);
break;
}
case EMF_PATHCOMMAND_CLOSE:
{
oNewPath.Close();
break;
}
}
}
}
bool CPathConverter::AddLineStartCap(CEmfPath &oPath, const CEmfPlusPen &oPen, double& dX, double& dY, double dAngle)
{
if (NULL != oPen.LineStartCapData)
{
if (CustomLineCapDataTypeDefault == oPen.LineStartCapData->GetType() && NULL != ((TEmfPlusCustomLineCapData*)oPen.LineStartCapData)->pPath)
{
return AddLineCap(oPath, ((TEmfPlusCustomLineCapData*)oPen.LineStartCapData)->pPath, dX, dY, dAngle, oPen.Width);
}
}
return false;
}
bool CPathConverter::AddLineEndCap(CEmfPath &oPath, const CEmfPlusPen &oPen, double &dX, double &dY, double dAngle)
{
if (NULL != oPen.LineEndCapData)
{
if (CustomLineCapDataTypeDefault == oPen.LineEndCapData->GetType() && NULL != ((TEmfPlusCustomLineCapData*)oPen.LineEndCapData)->pPath)
{
return AddLineCap(oPath, ((TEmfPlusCustomLineCapData*)oPen.LineEndCapData)->pPath, dX, dY, dAngle, oPen.Width);
}
}
return false;
}
bool CPathConverter::AddLineCap(CEmfPath &oPath, const CEmfPath &oLineCapPath, double &dX, double &dY, double dAngle, double dPenWidth)
{
double dNewX = 0;
double dNewY = 0;
double dSin = sin(dAngle * 3.14 / 180);
double dCos = cos(dAngle * 3.14 / 180);
for (const CEmfPathCommandBase* pCommand : oLineCapPath.m_pCommands)
{
switch (pCommand->GetType())
{
case EMF_PATHCOMMAND_UNKNOWN: break;
case EMF_PATHCOMMAND_MOVETO:
{
CEmfPathMoveTo *pCommandMoveTo = (CEmfPathMoveTo*)pCommand;
double dTempX = pCommandMoveTo->x * dPenWidth * dCos - pCommandMoveTo->y * dPenWidth * dSin;
double dTempY = pCommandMoveTo->x * dPenWidth * dSin + pCommandMoveTo->y * dPenWidth * dCos;
dNewX += dTempX;
dNewY += dTempY;
oPath.MoveTo(dX + dTempX, dY + dTempY);
break;
}
case EMF_PATHCOMMAND_LINETO:
{
CEmfPathLineTo *pCommandLineTo = (CEmfPathLineTo*)pCommand;
double dTempX = pCommandLineTo->x * dPenWidth * dCos - pCommandLineTo->y * dPenWidth * dSin;
double dTempY = pCommandLineTo->x * dPenWidth * dSin + pCommandLineTo->y * dPenWidth * dCos;
dNewX += dTempX;
dNewY += dTempY;
oPath.LineTo(dX + dTempX, dY + dTempY);
break;
}
case EMF_PATHCOMMAND_CURVETO:
{
break;
}
case EMF_PATHCOMMAND_ARCTO:
{
break;
}
case EMF_PATHCOMMAND_CLOSE:
{
oPath.Close();
break;
}
}
}
if (oPath.m_pCommands.size() > 1)
{
dX = dX + dNewX / (oPath.m_pCommands.size() - 1);
dY = dY + dNewY / (oPath.m_pCommands.size() - 1);
return true;
}
return false;
}
}