mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Added Marker record support for Paths in svg-reader and refactoring
This commit is contained in:
@ -472,13 +472,22 @@ namespace NSCSS
|
||||
|
||||
std::wstring CColor::CutURL(const std::wstring &wsValue)
|
||||
{
|
||||
size_t unStartURL = wsValue.find(L"#");
|
||||
size_t unEndURL = wsValue.find(L')', unStartURL);
|
||||
if (wsValue.length() < 6)
|
||||
return std::wstring();
|
||||
|
||||
if (std::wstring::npos != unStartURL && std::wstring::npos != unEndURL && (2 < unEndURL - unStartURL))
|
||||
return wsValue.substr(unStartURL + 1, unEndURL - unStartURL - 1);
|
||||
size_t unBegin = wsValue.find(L"(#");
|
||||
|
||||
return std::wstring();
|
||||
if (std::wstring::npos == unBegin || unBegin < 3 || wsValue.length() - unBegin < 2)
|
||||
return std::wstring();
|
||||
|
||||
std::wstring wsCopyValue(wsValue);
|
||||
|
||||
std::transform(wsCopyValue.begin(), wsCopyValue.begin() + unBegin, wsCopyValue.begin(), std::tolower);
|
||||
|
||||
if (std::wstring::npos == wsCopyValue.find(L"url(#"))
|
||||
return std::wstring();
|
||||
|
||||
return wsCopyValue.substr(unBegin + 2, wsCopyValue.find(L')') - unBegin - 2);
|
||||
}
|
||||
|
||||
CColor::CColor()
|
||||
@ -490,12 +499,10 @@ namespace NSCSS
|
||||
if (2 > wsValue.length() || ((m_bImportant || unLevel < m_unLevel) && !bHardMode))
|
||||
return false;
|
||||
|
||||
std::wstring wsNewValue = wsValue;
|
||||
std::wstring wsNewValue(wsValue);
|
||||
|
||||
bool bImportant = CutImportant(wsNewValue);
|
||||
|
||||
std::wstring wsCopyValue{wsNewValue};
|
||||
|
||||
std::transform(wsNewValue.begin(), wsNewValue.end(), wsNewValue.begin(), std::towlower);
|
||||
|
||||
if (m_bImportant && !bImportant)
|
||||
@ -528,13 +535,6 @@ namespace NSCSS
|
||||
m_bImportant = bImportant;
|
||||
return true;
|
||||
}
|
||||
else if (5 <= wsNewValue.length() && wsNewValue.substr(0, 3) == L"url")
|
||||
{
|
||||
m_oValue.SetUrl(CutURL(wsCopyValue));
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;;
|
||||
return true;
|
||||
}
|
||||
else if (L"none" == wsNewValue)
|
||||
{
|
||||
m_oValue.SetNone();
|
||||
@ -542,26 +542,35 @@ namespace NSCSS
|
||||
m_bImportant = bImportant;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
else if (wsNewValue == L"transparent")
|
||||
{
|
||||
if (wsNewValue == L"transparent")
|
||||
{
|
||||
m_oValue.SetNone();
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;
|
||||
return true;
|
||||
}
|
||||
m_oValue.SetNone();
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::map<std::wstring, std::wstring>::const_iterator oHEX = NSConstValues::NSMaps::mColors.find(wsNewValue);
|
||||
if (oHEX != NSConstValues::NSMaps::mColors.end())
|
||||
if (5 <= wsNewValue.length())
|
||||
{
|
||||
m_oValue.SetUrl(CutURL(wsValue));
|
||||
|
||||
if (m_oValue.m_enType == ColorUrl)
|
||||
{
|
||||
m_oValue.SetHEX(oHEX->second);
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;
|
||||
m_bImportant = bImportant;;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<std::wstring, std::wstring>::const_iterator oHEX = NSConstValues::NSMaps::mColors.find(wsNewValue);
|
||||
if (oHEX != NSConstValues::NSMaps::mColors.end())
|
||||
{
|
||||
m_oValue.SetHEX(oHEX->second);
|
||||
m_unLevel = unLevel;
|
||||
m_bImportant = bImportant;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2175,7 +2184,7 @@ namespace NSCSS
|
||||
|
||||
m_pColor = new std::wstring(wsValue);
|
||||
|
||||
if (NULL == m_pColor)
|
||||
if (NULL == m_pColor || ((std::wstring*)m_pColor)->empty())
|
||||
{
|
||||
m_enType = ColorEmpty;
|
||||
return;
|
||||
|
||||
@ -78,6 +78,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
|
||||
$$METAFILE_PATH/svg/SvgObjects/CClipPath.h \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CDefs.h \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CPattern.h \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CMarker.h \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CImage.h \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CLine.h \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CRect.h \
|
||||
@ -100,6 +101,7 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
|
||||
$$METAFILE_PATH/svg/SvgObjects/CGradient.cpp \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CClipPath.cpp \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CDefs.cpp \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CMarker.cpp \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CPattern.cpp \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CImage.cpp \
|
||||
$$METAFILE_PATH/svg/SvgObjects/CLine.cpp \
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "SvgObjects/CClipPath.h"
|
||||
#include "SvgObjects/CPattern.h"
|
||||
#include "SvgObjects/CEllipse.h"
|
||||
#include "SvgObjects/CMarker.h"
|
||||
#include "SvgObjects/CCircle.h"
|
||||
#include "SvgObjects/CStyle.h"
|
||||
#include "SvgObjects/CImage.h"
|
||||
@ -61,12 +62,6 @@ namespace SVG
|
||||
if (!oXml.FromXmlString(wsContent))
|
||||
return false;
|
||||
|
||||
// TODO:: Временный вариант
|
||||
// В дальнейшем сделать либо мнетод поиска стиля и defs,
|
||||
// (проблема в том что тогда придется 2 раза запускать поиск (сначала стиля, а потом defs),
|
||||
// а лишь потом запускать само чтение)
|
||||
// либо использовать SvgCalculator при отрисовке, а не при чтении
|
||||
// (но тогда скорость самой отрисовки падает)
|
||||
ScanOther(oXml, pFile);
|
||||
|
||||
return LoadFromXmlNode(oXml, pContainer, pFile);
|
||||
@ -164,7 +159,7 @@ namespace SVG
|
||||
std::wstring wsElementName = oElement.GetName();
|
||||
|
||||
if (L"defs" == wsElementName)
|
||||
return ReadChildrens(oElement, (CGraphicsContainer*)pDefs, pFile);
|
||||
return ReadChildrens(oElement, pDefs, pFile);
|
||||
else if (L"style" == wsElementName)
|
||||
{
|
||||
pFile->AddStyles(oElement.GetText());
|
||||
@ -183,6 +178,8 @@ namespace SVG
|
||||
pDefObject = CreateAndReadChildrens<CPattern, CGraphicsContainer>(oElement, pFile);
|
||||
else if (L"clipPath" == wsElementName)
|
||||
pDefObject = CreateAndReadChildrens<CClipPath, CGraphicsContainer>(oElement, pFile);
|
||||
else if (L"marker" == wsElementName)
|
||||
pDefObject = CreateAndReadChildrens<CMarker, CGraphicsContainer>(oElement, pFile);
|
||||
|
||||
return AddObject(pDefObject, pDefs, pFile);
|
||||
}
|
||||
@ -228,7 +225,7 @@ namespace SVG
|
||||
|
||||
bool CSvgParser::IsDefs(const std::wstring &wsNodeName) const
|
||||
{
|
||||
return L"defs" == wsNodeName || L"pattern" == wsNodeName || L"clipPath" == wsNodeName || L"linearGradient" == wsNodeName || L"radialGradient" == wsNodeName;
|
||||
return L"defs" == wsNodeName || L"pattern" == wsNodeName || L"clipPath" == wsNodeName || L"linearGradient" == wsNodeName || L"radialGradient" == wsNodeName || L"marker" == wsNodeName;
|
||||
}
|
||||
|
||||
template<typename TypeContainer>
|
||||
|
||||
@ -46,7 +46,7 @@ namespace SVG
|
||||
{
|
||||
Apply(pRenderer, &pStyles->m_oTransform, oOldMatrix);
|
||||
|
||||
if (Apply(pRenderer, &pStyles->m_oStroke, true))
|
||||
if (Apply(pRenderer, &pStyles->m_oStroke))
|
||||
nTypePath += c_nStroke;
|
||||
|
||||
if (Apply(pRenderer, &pStyles->m_oFill, pDefs, true))
|
||||
|
||||
@ -67,6 +67,7 @@ namespace SVG
|
||||
friend class CDefs;
|
||||
friend class CText;
|
||||
friend class CTSpan;
|
||||
friend class CMarker;
|
||||
friend class CPattern;
|
||||
friend class CGradient;
|
||||
friend class CClipPath;
|
||||
@ -93,6 +94,7 @@ namespace SVG
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
friend class CPattern;
|
||||
friend class CMarker;
|
||||
|
||||
TRect m_oWindow;
|
||||
TRect m_oViewBox;
|
||||
|
||||
153
DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.cpp
Normal file
153
DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.cpp
Normal file
@ -0,0 +1,153 @@
|
||||
#include "CMarker.h"
|
||||
|
||||
#include "../../../graphics/pro/Graphics.h"
|
||||
#include "../SvgUtils.h"
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
CMarker::CMarker(XmlUtils::CXmlNode &oNode, CSvgGraphicsObject *pParent)
|
||||
: CDefObject(oNode, pParent), m_pImage(NULL)
|
||||
{
|
||||
m_oWindow.m_oX .SetValue(oNode.GetAttribute(L"refX"));
|
||||
m_oWindow.m_oY .SetValue(oNode.GetAttribute(L"refY"));
|
||||
|
||||
m_oWindow.m_oWidth .SetValue(oNode.GetAttribute(L"markerWidth", L"3"));
|
||||
m_oWindow.m_oHeight.SetValue(oNode.GetAttribute(L"markerHeight", L"3"));
|
||||
|
||||
const std::wstring wsViewBox = oNode.GetAttribute(L"viewBox");
|
||||
|
||||
if (!wsViewBox.empty())
|
||||
{
|
||||
std::vector<double> arValues = StrUtils::ReadDoubleValues(wsViewBox);
|
||||
if (4 == arValues.size())
|
||||
{
|
||||
m_oViewBox.m_oX = arValues[0];
|
||||
m_oViewBox.m_oY = arValues[1];
|
||||
m_oViewBox.m_oWidth = arValues[2];
|
||||
m_oViewBox.m_oHeight = arValues[3];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_oWindow.m_oWidth.Empty() && !m_oViewBox.m_oWidth.Empty())
|
||||
m_oWindow.m_oWidth = m_oViewBox.m_oWidth;
|
||||
else if (!m_oWindow.m_oWidth.Empty() && m_oViewBox.m_oWidth.Empty())
|
||||
m_oViewBox.m_oWidth = m_oWindow.m_oWidth;
|
||||
|
||||
if (m_oWindow.m_oHeight.Empty() && !m_oViewBox.m_oHeight.Empty())
|
||||
m_oWindow.m_oHeight = m_oViewBox.m_oHeight;
|
||||
else if (!m_oWindow.m_oHeight.Empty() && m_oViewBox.m_oHeight.Empty())
|
||||
m_oViewBox.m_oHeight = m_oWindow.m_oHeight;
|
||||
|
||||
const std::wstring& wsUnits = oNode.GetAttribute(L"markerUnits");
|
||||
|
||||
if (L"strokeWidth" == wsUnits)
|
||||
m_enUnits = Marker_StrokeWidth;
|
||||
else if (L"userSpaceOnUse" == wsUnits)
|
||||
m_enUnits = Marker_UserSpaceOnUse;
|
||||
}
|
||||
|
||||
CMarker::~CMarker()
|
||||
{
|
||||
if (NULL != m_pImage)
|
||||
delete m_pImage;
|
||||
}
|
||||
|
||||
void CMarker::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
{}
|
||||
|
||||
bool CMarker::Apply(IRenderer *pRenderer, const CDefs *pDefs, const TBounds &oObjectBounds)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMarker::Update(const CDefs *pDefs)
|
||||
{
|
||||
if (NULL != m_pImage || (!m_oWindow.m_oWidth.Empty() && m_oWindow.m_oWidth.Zero()) || (!m_oWindow.m_oHeight.Empty() && m_oWindow.m_oHeight.Zero()) ||
|
||||
(!m_oViewBox.m_oWidth.Empty() && m_oViewBox.m_oWidth.Zero()) || (!m_oViewBox.m_oHeight.Empty() && m_oViewBox.m_oHeight.Zero()))
|
||||
return;
|
||||
|
||||
double dWidth = m_oWindow.m_oWidth .ToDouble(NSCSS::Pixel);
|
||||
double dHeight = m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel);
|
||||
|
||||
double dVBWidth = std::min(m_oViewBox.m_oWidth .ToDouble(NSCSS::Pixel), dWidth);
|
||||
double dVBHeight = std::min(m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel), dHeight);
|
||||
|
||||
double dKoef = std::min(dWidth + dVBWidth, dHeight + dVBHeight) / 2.;
|
||||
|
||||
NSGraphics::IGraphicsRenderer* pGrRenderer = NSGraphics::Create();
|
||||
|
||||
double dMMtoPx = 96. / 25.4;
|
||||
|
||||
int nWidth = dKoef * dMMtoPx + 1;
|
||||
int nHeight = dKoef * dMMtoPx + 1;
|
||||
|
||||
if (0 == nWidth || 0 == nHeight)
|
||||
return;
|
||||
|
||||
BYTE* pBgraData = new BYTE[nWidth * nHeight * 4];
|
||||
|
||||
if (!pBgraData)
|
||||
return;
|
||||
|
||||
unsigned int alfa = 0xffffff;
|
||||
//дефолтный тон должен быть прозрачным, а не белым
|
||||
//memset(pBgraData, 0xff, nWidth * nHeight * 4);
|
||||
for (int i = 0; i < nWidth * nHeight; i++)
|
||||
((unsigned int*)pBgraData)[i] = alfa;
|
||||
|
||||
CBgraFrame oFrame;
|
||||
oFrame.put_Data(pBgraData);
|
||||
oFrame.put_Width(nWidth);
|
||||
oFrame.put_Height(nHeight);
|
||||
oFrame.put_Stride(-4 * nWidth);
|
||||
|
||||
pGrRenderer->CreateFromBgraFrame(&oFrame);
|
||||
pGrRenderer->put_Width ((dWidth + dVBWidth) / 2. * dMMtoPx);
|
||||
pGrRenderer->put_Height((dHeight + dVBHeight) / 2. * dMMtoPx);
|
||||
|
||||
pGrRenderer->SetSwapRGB(false);
|
||||
pGrRenderer->BeginCommand(c_nImageType);
|
||||
|
||||
pGrRenderer->SetTransform(dMMtoPx, 0., 0., dMMtoPx, 0., 0.);
|
||||
|
||||
for (const CSvgGraphicsObject* pObject : m_arObjects)
|
||||
pObject->Draw(pGrRenderer, pDefs);
|
||||
|
||||
pGrRenderer->EndCommand(c_nImageType);
|
||||
RELEASEINTERFACE(pGrRenderer);
|
||||
|
||||
oFrame.put_Data(NULL);
|
||||
|
||||
m_pImage = new Aggplus::CImage;
|
||||
m_pImage->Create(pBgraData, oFrame.get_Width(), oFrame.get_Height(), oFrame.get_Stride());
|
||||
}
|
||||
|
||||
void CMarker::Draw(IRenderer *pRenderer, const std::vector<Point> &arPoints) const
|
||||
{
|
||||
if (NULL == m_pImage || arPoints.empty())
|
||||
return;
|
||||
|
||||
double dWidth = m_oWindow.m_oWidth .ToDouble(NSCSS::Pixel);
|
||||
double dHeight = m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel);
|
||||
|
||||
if (dWidth > dHeight)
|
||||
dWidth = dHeight;
|
||||
else if (dHeight > dWidth)
|
||||
dHeight = dWidth;
|
||||
|
||||
double dVBWidth = m_oViewBox.m_oWidth .ToDouble(NSCSS::Pixel);
|
||||
double dVBHeight = m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel);
|
||||
|
||||
double dDeductible = std::min((dVBWidth - dWidth), (dVBHeight - dHeight)) / 2.;
|
||||
|
||||
for (const Point& oPoint : arPoints)
|
||||
{
|
||||
Point oNewPoint(oPoint);
|
||||
|
||||
oNewPoint.dX -= m_oWindow.m_oX.ToDouble(NSCSS::Pixel) - dDeductible;
|
||||
oNewPoint.dY -= m_oWindow.m_oY.ToDouble(NSCSS::Pixel) - dDeductible;
|
||||
|
||||
pRenderer->DrawImage((IGrObject*)m_pImage, oNewPoint.dX, oNewPoint.dY, dWidth, dHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.h
Normal file
37
DesktopEditor/raster/Metafile/svg/SvgObjects/CMarker.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef CMARKER_H
|
||||
#define CMARKER_H
|
||||
|
||||
#include "CDefs.h"
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
Marker_StrokeWidth,
|
||||
Marker_UserSpaceOnUse
|
||||
} MarkerUnits;
|
||||
|
||||
class CMarker : public CContainer<CSvgGraphicsObject>, public CDefObject
|
||||
{
|
||||
public:
|
||||
CMarker(XmlUtils::CXmlNode& oNode, CSvgGraphicsObject* pParent = NULL);
|
||||
virtual ~CMarker();
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;
|
||||
|
||||
bool Apply(IRenderer* pRenderer, const CDefs *pDefs, const TBounds &oObjectBounds) override;
|
||||
|
||||
void Update(const CDefs *pDefs);
|
||||
|
||||
void Draw(IRenderer* pRenderer, const std::vector<Point>& arPoints) const;
|
||||
private:
|
||||
TRect m_oWindow;
|
||||
TRect m_oViewBox;
|
||||
|
||||
MarkerUnits m_enUnits;
|
||||
|
||||
Aggplus::CImage *m_pImage;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // CMARKER_H
|
||||
@ -205,7 +205,7 @@ namespace SVG
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSvgGraphicsObject::Apply(IRenderer *pRenderer, const TSvgStyles::TSvgClip *pClip, const CDefs *pDefs) const
|
||||
bool CSvgGraphicsObject::Apply(IRenderer *pRenderer, const TClip *pClip, const CDefs *pDefs) const
|
||||
{
|
||||
if (NULL == pRenderer || NULL == pClip || NULL == pDefs)
|
||||
return false;
|
||||
|
||||
@ -16,11 +16,7 @@ namespace SVG
|
||||
SvgColor m_oFill;
|
||||
TStroke m_oStroke;
|
||||
SvgTransform m_oTransform;
|
||||
struct TSvgClip
|
||||
{
|
||||
SvgColor m_oHref;
|
||||
SvgString m_oRule;
|
||||
} m_oClip;
|
||||
TClip m_oClip;
|
||||
|
||||
TSvgStyles& operator+=(const TSvgStyles& oSvgStyles)
|
||||
{
|
||||
@ -191,7 +187,7 @@ namespace SVG
|
||||
bool Apply(IRenderer* pRenderer, const TStroke* pStroke, bool bUseDefault = false) const;
|
||||
bool Apply(IRenderer* pRenderer, const SvgColor* pFill, const CDefs *pDefs, bool bUseDefault = false) const;
|
||||
bool Apply(IRenderer* pRenderer, const SvgTransform* pTransform, Aggplus::CMatrix& oOldMatrix) const;
|
||||
bool Apply(IRenderer* pRenderer, const TSvgStyles::TSvgClip* pClip, const CDefs *pDefs) const;
|
||||
bool Apply(IRenderer* pRenderer, const TClip* pClip, const CDefs *pDefs) const;
|
||||
|
||||
bool ApplyDef(IRenderer* pRenderer, const CDefs *pDefs, const std::wstring& wsUrl) const;
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "CPath.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "CMarker.h"
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
@ -30,6 +31,15 @@ namespace SVG
|
||||
SetStroke(mAttributes, ushLevel, bHardMode);
|
||||
SetFill(mAttributes, ushLevel, bHardMode);
|
||||
SetClip(mAttributes, ushLevel, bHardMode);
|
||||
|
||||
if (mAttributes.end() != mAttributes.find(L"marker-start"))
|
||||
m_oMarkers.m_oStart.SetValue(mAttributes.at(L"marker-start"), ushLevel, bHardMode);
|
||||
|
||||
if (mAttributes.end() != mAttributes.find(L"marker-mid"))
|
||||
m_oMarkers.m_oMid.SetValue(mAttributes.at(L"marker-mid"), ushLevel, bHardMode);
|
||||
|
||||
if (mAttributes.end() != mAttributes.find(L"marker-end"))
|
||||
m_oMarkers.m_oEnd.SetValue(mAttributes.at(L"marker-end"), ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
bool CPath::Draw(IRenderer *pRenderer, const CDefs *pDefs, bool bIsClip, const TSvgStyles *pOtherStyles) const
|
||||
@ -44,6 +54,8 @@ namespace SVG
|
||||
|
||||
EndPath(pRenderer, pDefs, bIsClip, pOtherStyles);
|
||||
|
||||
DrawMarkers(pRenderer, pDefs);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -66,6 +78,52 @@ namespace SVG
|
||||
nTypePath += c_nWindingFillMode;
|
||||
}
|
||||
|
||||
bool CPath::DrawMarkers(IRenderer *pRenderer, const CDefs *pDefs) const
|
||||
{
|
||||
if (NULL == pRenderer || NULL == pDefs || m_arElements.empty())
|
||||
return false;
|
||||
|
||||
std::vector<Point> arPoints(m_arElements.size());
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < m_arElements.size(); ++unIndex)
|
||||
arPoints[unIndex] = (*m_arElements[unIndex])[0];
|
||||
|
||||
if (!m_oMarkers.m_oStart.Empty() && NSCSS::NSProperties::ColorType::ColorUrl == m_oMarkers.m_oStart.GetType())
|
||||
{
|
||||
CMarker *pStartMarker = dynamic_cast<CMarker*>(pDefs->GetDef(m_oMarkers.m_oStart.ToWString()));
|
||||
|
||||
if (NULL != pStartMarker)
|
||||
{
|
||||
pStartMarker->Update(pDefs);
|
||||
pStartMarker->Draw(pRenderer, {*arPoints.begin()});
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_oMarkers.m_oMid.Empty() && NSCSS::NSProperties::ColorType::ColorUrl == m_oMarkers.m_oMid.GetType())
|
||||
{
|
||||
CMarker *pMidMarker = dynamic_cast<CMarker*>(pDefs->GetDef(m_oMarkers.m_oMid.ToWString()));
|
||||
|
||||
if (NULL != pMidMarker)
|
||||
{
|
||||
pMidMarker->Update(pDefs);
|
||||
pMidMarker->Draw(pRenderer, std::vector<Point>(arPoints.begin() + 1, arPoints.end() - 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_oMarkers.m_oEnd.Empty() && NSCSS::NSProperties::ColorType::ColorUrl == m_oMarkers.m_oEnd.GetType())
|
||||
{
|
||||
CMarker *pEndMarker = dynamic_cast<CMarker*>(pDefs->GetDef(m_oMarkers.m_oEnd.ToWString()));
|
||||
|
||||
if (NULL != pEndMarker)
|
||||
{
|
||||
pEndMarker->Update(pDefs);
|
||||
pEndMarker->Draw(pRenderer, {*(arPoints.end() - 1)});
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TBounds CPath::GetBounds() const
|
||||
{
|
||||
TBounds oBounds{0., 0., 0., 0.}, oTempBounds;
|
||||
|
||||
@ -613,6 +613,7 @@ namespace SVG
|
||||
IPathElement* operator[](int nIndex) const;
|
||||
private:
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CDefs *pDefs, int& nTypePath, Aggplus::CMatrix& oOldMatrix) const override;
|
||||
bool DrawMarkers(IRenderer* pRenderer, const CDefs *pDefs) const;
|
||||
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
@ -622,6 +623,8 @@ namespace SVG
|
||||
void AddElements(std::vector<double>& arValues, bool bRelativeCoordinate);
|
||||
|
||||
std::vector<IPathElement*> m_arElements;
|
||||
|
||||
TMarkers m_oMarkers;
|
||||
};
|
||||
|
||||
class CMovingPath
|
||||
|
||||
@ -28,6 +28,19 @@ namespace SVG
|
||||
SvgEnum m_oLineJoin;
|
||||
};
|
||||
|
||||
struct TClip
|
||||
{
|
||||
SvgColor m_oHref;
|
||||
SvgString m_oRule;
|
||||
};
|
||||
|
||||
struct TMarkers
|
||||
{
|
||||
SvgColor m_oStart;
|
||||
SvgColor m_oMid;
|
||||
SvgColor m_oEnd;
|
||||
};
|
||||
|
||||
struct Point
|
||||
{
|
||||
double dX;
|
||||
|
||||
Reference in New Issue
Block a user