mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
Intermediate refactoring
This commit is contained in:
@ -3,11 +3,13 @@
|
||||
#include "SvgObjects/CContainer.h"
|
||||
#include "SvgObjects/CFont.h"
|
||||
|
||||
#include "CSvgParser.h"
|
||||
|
||||
#define SVG_FILE_WIDTH 300
|
||||
#define SVG_FILE_HEIGHT 150
|
||||
|
||||
CSvgFile::CSvgFile()
|
||||
: m_pContainer(NULL)
|
||||
: m_pContainer(NULL), m_pFontManager(NULL)
|
||||
{}
|
||||
|
||||
CSvgFile::~CSvgFile()
|
||||
@ -24,7 +26,10 @@ bool CSvgFile::ReadFromBuffer(BYTE *pBuffer, unsigned int unSize)
|
||||
bool CSvgFile::ReadFromWString(const std::wstring &wsContext)
|
||||
{
|
||||
Clear();
|
||||
return m_oParser.LoadFromString(wsContext, m_pContainer, this);
|
||||
|
||||
SVG::CSvgParser oSvgParser(m_pFontManager);
|
||||
|
||||
return oSvgParser.LoadFromString(wsContext, m_pContainer, this);
|
||||
}
|
||||
|
||||
bool CSvgFile::OpenFromFile(const std::wstring &wsFile)
|
||||
@ -33,7 +38,9 @@ bool CSvgFile::OpenFromFile(const std::wstring &wsFile)
|
||||
|
||||
m_wsWorkingDirectory = NSFile::GetDirectoryName(wsFile);
|
||||
|
||||
return m_oParser.LoadFromFile(wsFile, m_pContainer, this);
|
||||
SVG::CSvgParser oSvgParser(m_pFontManager);
|
||||
|
||||
return oSvgParser.LoadFromFile(wsFile, m_pContainer, this);
|
||||
}
|
||||
|
||||
bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight) const
|
||||
@ -94,7 +101,7 @@ const SVG::CSvgCalculator *CSvgFile::GetSvgCalculator() const
|
||||
|
||||
void CSvgFile::SetFontManager(NSFonts::IFontManager *pFontManager)
|
||||
{
|
||||
m_oParser.SetFontManager(pFontManager);
|
||||
m_pFontManager = pFontManager;
|
||||
}
|
||||
|
||||
void CSvgFile::SetWorkingDirectory(const std::wstring &wsWorkingDirectory)
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
#include "../../../graphics/IRenderer.h"
|
||||
#include "../../../graphics/pro/Fonts.h"
|
||||
|
||||
#include "CSvgParser.h"
|
||||
#include "SvgObjects/CStyle.h"
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
struct TFontArguments;
|
||||
class CFont;
|
||||
class CGraphicsContainer;
|
||||
}
|
||||
|
||||
class CSvgFile
|
||||
@ -43,9 +43,9 @@ class CSvgFile
|
||||
private:
|
||||
void Clear();
|
||||
|
||||
SVG::CSvgParser m_oParser;
|
||||
SVG::CGraphicsContainer *m_pContainer;
|
||||
SVG::CSvgCalculator m_oSvgCalculator;
|
||||
NSFonts::IFontManager *m_pFontManager;
|
||||
|
||||
typedef std::map<std::wstring, SVG::CObject*> MarkedMap;
|
||||
|
||||
|
||||
@ -28,14 +28,12 @@
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
CSvgParser::CSvgParser()
|
||||
: m_pFontManager(NULL)
|
||||
{
|
||||
}
|
||||
CSvgParser::CSvgParser(NSFonts::IFontManager* pFontManager)
|
||||
: m_pFontManager(pFontManager)
|
||||
{}
|
||||
|
||||
CSvgParser::~CSvgParser()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void CSvgParser::SetFontManager(NSFonts::IFontManager *pFontManager)
|
||||
{
|
||||
@ -104,11 +102,7 @@ namespace SVG
|
||||
else
|
||||
return false;
|
||||
|
||||
XmlUtils::IXmlDOMDocument::DisableOutput();
|
||||
bool bResult = LoadFromString(wsContent, pContainer, pFile);
|
||||
XmlUtils::IXmlDOMDocument::EnableOutput();
|
||||
|
||||
return bResult;
|
||||
return LoadFromString(wsContent, pContainer, pFile);
|
||||
}
|
||||
|
||||
bool CSvgParser::LoadFromString(const std::wstring &wsContent, CGraphicsContainer*& pContainer, CSvgFile* pFile) const
|
||||
@ -125,12 +119,11 @@ namespace SVG
|
||||
|
||||
RELEASEOBJECT(pContainer);
|
||||
|
||||
pContainer = CRenderedObject::Create<CGraphicsContainer>(oReader, pFile->GetSvgCalculator());
|
||||
pContainer = CObject::Create<CGraphicsContainer>(oReader, pFile);
|
||||
|
||||
if (NULL == pContainer)
|
||||
return false;
|
||||
|
||||
|
||||
return ReadChildrens(oReader, pContainer, pFile, pContainer);
|
||||
}
|
||||
|
||||
@ -216,22 +209,6 @@ namespace SVG
|
||||
oSearchStart = oMatch.suffix().first;
|
||||
}
|
||||
}
|
||||
|
||||
template <class TextType>
|
||||
TextType* ReadTextObject(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator, CRenderedObject *pParent, NSFonts::IFontManager* pFontManager)
|
||||
{
|
||||
//1 - создаем родительский объект
|
||||
//2 - парсим аргументы
|
||||
//3 - SetData
|
||||
//4 - чтение дочерних (текста и внутри)
|
||||
|
||||
TextType *pText = CRenderedObject::Create<TextType>(oReader, pSvgCalculator, pParent, pFontManager);
|
||||
if (NULL == pText)
|
||||
return NULL;
|
||||
|
||||
return pText;
|
||||
}
|
||||
|
||||
template <class ObjectType>
|
||||
bool CSvgParser::ReadObject(CSvgReader& oReader, CContainer<ObjectType> *pContainer, CSvgFile *pFile, CRenderedObject *pParent) const
|
||||
{
|
||||
@ -244,7 +221,7 @@ namespace SVG
|
||||
|
||||
if ("svg" == sElementName || "g" == sElementName || "a" == sElementName)
|
||||
{
|
||||
pObject = CRenderedObject::Create<CGraphicsContainer>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CGraphicsContainer>(oReader, pFile, pParent);
|
||||
if (!ReadChildrens(oReader, (CGraphicsContainer*)pObject, pFile, (CGraphicsContainer*)pObject))
|
||||
{
|
||||
RELEASEOBJECT(pObject);
|
||||
@ -252,138 +229,83 @@ namespace SVG
|
||||
}
|
||||
}
|
||||
else if ("line" == sElementName)
|
||||
pObject = CRenderedObject::Create<CLine>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CLine>(oReader, pFile, pParent);
|
||||
else if ("rect" == sElementName)
|
||||
pObject = CRenderedObject::Create<CRect>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CRect>(oReader, pFile, pParent);
|
||||
else if ("circle" == sElementName)
|
||||
pObject = CRenderedObject::Create<CCircle>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CCircle>(oReader, pFile, pParent);
|
||||
else if ("ellipse" == sElementName)
|
||||
pObject = CRenderedObject::Create<CEllipse>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CEllipse>(oReader, pFile, pParent);
|
||||
else if ("path" == sElementName)
|
||||
pObject = CRenderedObject::Create<CPath>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CPath>(oReader, pFile, pParent);
|
||||
else if ("polyline" == sElementName)
|
||||
pObject = CRenderedObject::Create<CPolyline>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CPolyline>(oReader, pFile, pParent);
|
||||
else if ("polygon" == sElementName)
|
||||
pObject = CRenderedObject::Create<CPolygon>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CPolygon>(oReader, pFile, pParent);
|
||||
else if ("image" == sElementName)
|
||||
pObject = CRenderedObject::Create<CImage>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CImage>(oReader, pFile, pParent);
|
||||
else if ("use" == sElementName)
|
||||
pObject = CRenderedObject::Create<CUse>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CUse>(oReader, pFile, pParent);
|
||||
else if ("text" == sElementName)
|
||||
{
|
||||
pObject = ReadTextObject<CText>(oReader, pFile->GetSvgCalculator(), pParent, m_pFontManager);
|
||||
// pObject = CText::Create(oReader, pParent, m_pFontManager);
|
||||
// ReadChildrens(oReader, (CText*)pObject, pFile, (CText*)pObject);
|
||||
}
|
||||
pObject = CObject::Create<CText>(oReader, pFile, pParent, m_pFontManager);
|
||||
else if ("tspan" == sElementName)
|
||||
{
|
||||
pObject = ReadTextObject<CTSpan>(oReader, pFile->GetSvgCalculator(), pParent, m_pFontManager);
|
||||
// pObject = CTSpan::Create(oReader, pParent, m_pFontManager);
|
||||
// ReadChildrens(oReader, (CTSpan*)pObject, pFile, (CTSpan*)pObject);
|
||||
}
|
||||
pObject = CObject::Create<CTSpan>(oReader, pFile, pParent, m_pFontManager);
|
||||
else if ("textPath" == sElementName)
|
||||
{
|
||||
pObject = ReadTextObject<CTextPath>(oReader, pFile->GetSvgCalculator(), pParent, m_pFontManager);
|
||||
// pObject = CTextPath::Create(oReader, pParent, m_pFontManager);
|
||||
// ReadChildrens(oReader, (CTextPath*)pObject, pFile);
|
||||
}
|
||||
pObject = CObject::Create<CTextPath>(oReader, pFile, pParent, m_pFontManager);
|
||||
else if ("switch" == sElementName)
|
||||
{
|
||||
pObject = CRenderedObject::Create<CSwitch>(oReader, pFile->GetSvgCalculator(), pParent);
|
||||
pObject = CObject::Create<CSwitch>(oReader, pFile, pParent);
|
||||
ReadChildrens(oReader, (CSwitch*)pObject, pFile);
|
||||
}
|
||||
//defs
|
||||
else if ("defs" == sElementName)
|
||||
return ReadChildrens<CRenderedObject>(oReader, NULL, pFile);
|
||||
else if("linearGradient" == sElementName)
|
||||
{
|
||||
pObject = new CLinearGradient(oReader);
|
||||
ReadChildrens(oReader, (CLinearGradient*)pObject, pFile);
|
||||
}
|
||||
pObject = CObject::Create<CLinearGradient>(oReader, pFile);
|
||||
else if ("radialGradient" == sElementName)
|
||||
{
|
||||
pObject = new CRadialGradient(oReader);
|
||||
ReadChildrens(oReader, (CRadialGradient*)pObject, pFile);
|
||||
}
|
||||
else if ("stop" == sElementName)
|
||||
{
|
||||
CStopElement *pStopElement = new CStopElement(oReader);
|
||||
if (AddObject((ObjectType*)pStopElement, pContainer))
|
||||
{
|
||||
UpdateStyles(pStopElement, pFile);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
RELEASEOBJECT(pStopElement);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
pObject = CObject::Create<CRadialGradient>(oReader, pFile);
|
||||
else if ("pattern" == sElementName)
|
||||
{
|
||||
pObject = new CPattern(oReader, m_pFontManager);
|
||||
pObject = CObject::Create<CPattern>(oReader, pFile);
|
||||
ReadChildrens(oReader, (CGraphicsContainer*)(&((CPattern*)pObject)->GetContainer()), pFile);
|
||||
}
|
||||
else if ("clipPath" == sElementName)
|
||||
{
|
||||
pObject = new CClipPath(oReader);
|
||||
pObject = CObject::Create<CClipPath>(oReader, pFile);
|
||||
ReadChildrens(oReader, (CGraphicsContainer*)(&((CClipPath*)pObject)->GetContainer()), pFile);
|
||||
}
|
||||
else if ("marker" == sElementName)
|
||||
{
|
||||
pObject = new CMarker(oReader);
|
||||
pObject = CObject::Create<CMarker>(oReader, pFile);
|
||||
ReadChildrens(oReader, (CMarker*)pObject, pFile);
|
||||
}
|
||||
else if ("mask" == sElementName)
|
||||
{
|
||||
pObject = new CMask(oReader);
|
||||
pObject = CObject::Create<CMask>(oReader, pFile);
|
||||
ReadChildrens(oReader, (CGraphicsContainer*)(&((CMask*)pObject)->GetContainer()), pFile);
|
||||
}
|
||||
else if ("symbo" == sElementName)
|
||||
else if ("symbol" == sElementName)
|
||||
{
|
||||
pObject = CRenderedObject::Create<CSymbol>(oReader, pFile->GetSvgCalculator());
|
||||
if (ReadChildrens(oReader, (CSymbol*)pObject, pFile) && MarkObject(pObject, pFile))
|
||||
pObject = CObject::Create<CSymbol>(oReader, pFile);
|
||||
if (ReadChildrens(oReader, (CSymbol*)pObject, pFile))
|
||||
return true;
|
||||
else
|
||||
RELEASEOBJECT(pObject);
|
||||
}
|
||||
else if ("font" == sElementName)
|
||||
{
|
||||
pObject = new CFont(oReader);
|
||||
pObject = CObject::Create<CFont>(oReader, pFile);
|
||||
}
|
||||
|
||||
if (NULL != pObject)
|
||||
{
|
||||
if ((MarkObject(pObject, pFile) && (AppliedObject == pObject->GetType() || NULL == pContainer)) ||
|
||||
(RendererObject == pObject->GetType() && AddObject((ObjectType*)pObject, pContainer)))
|
||||
{
|
||||
if (RendererObject != pObject->GetType())
|
||||
UpdateStyles(pObject, pFile);
|
||||
return true;
|
||||
}
|
||||
delete pObject;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSvgParser::UpdateStyles(CObject *pObject, CSvgFile *pFile) const
|
||||
{
|
||||
if (NULL == pObject || NULL == pFile)
|
||||
return;
|
||||
|
||||
const CSvgCalculator *pSvgCalculator = pFile->GetSvgCalculator();
|
||||
|
||||
if (NULL != pSvgCalculator)
|
||||
pSvgCalculator->SetData(pObject);
|
||||
}
|
||||
|
||||
bool CSvgParser::MarkObject(CObject *pObject, CSvgFile *pFile) const
|
||||
{
|
||||
if (NULL == pObject || NULL == pFile)
|
||||
if (NULL == pObject)
|
||||
return false;
|
||||
|
||||
return pFile->MarkObject(pObject);
|
||||
if ((RendererObject == pObject->GetType() && AddObject((ObjectType*)pObject, pContainer)) ||
|
||||
AppliedObject == pObject->GetType())
|
||||
return true;
|
||||
|
||||
RELEASEOBJECT(pObject);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class ObjectType>
|
||||
|
||||
@ -14,7 +14,7 @@ namespace SVG
|
||||
class CSvgParser
|
||||
{
|
||||
public:
|
||||
CSvgParser();
|
||||
CSvgParser(NSFonts::IFontManager* pFontManager = NULL);
|
||||
~CSvgParser();
|
||||
|
||||
void SetFontManager(NSFonts::IFontManager* pFontManager);
|
||||
@ -31,8 +31,6 @@ namespace SVG
|
||||
bool ScanStyles(CSvgReader& oReader, CSvgFile* pFile) const;
|
||||
void ParseStyles(const std::wstring& wsStyles, CSvgFile *pFile) const;
|
||||
|
||||
void UpdateStyles(CObject* pObject, CSvgFile* pFile) const;
|
||||
bool MarkObject(CObject* pObject, CSvgFile* pFile) const;
|
||||
template <class ObjectType>
|
||||
bool AddObject(ObjectType* pObject, CContainer<ObjectType>* pContainer) const;
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ namespace SVG
|
||||
{
|
||||
class CCircle : public CRenderedObject
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CCircle(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
@ -31,7 +31,7 @@ namespace SVG
|
||||
|
||||
ApplyClip(pRenderer, &m_oTransformation.m_oClip, pFile, oObjectBounds);
|
||||
|
||||
for (const CRenderedObject* pObject : m_oContainer.m_arObjects)
|
||||
for (const CRenderedObject* pObject : m_oContainer)
|
||||
pObject->Draw(pRenderer, pFile, CommandeModeClip);
|
||||
|
||||
return true;
|
||||
|
||||
@ -13,9 +13,9 @@ namespace SVG
|
||||
|
||||
class CClipPath : public CAppliedObject
|
||||
{
|
||||
public:
|
||||
friend class CObject;
|
||||
CClipPath(CSvgReader& oReader);
|
||||
|
||||
public:
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;
|
||||
|
||||
@ -5,15 +5,9 @@
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
// CGraphicsContainer::CGraphicsContainer(const std::wstring &wsName)
|
||||
// : CRenderedObject(NSCSS::CNode(wsName, L"", L""))
|
||||
// {}
|
||||
|
||||
CGraphicsContainer::~CGraphicsContainer()
|
||||
{
|
||||
for (CRenderedObject* pObject : m_arObjects)
|
||||
pObject->m_pParent = NULL;
|
||||
}
|
||||
CGraphicsContainer::CGraphicsContainer(CSvgReader& oReader, CRenderedObject *pParent)
|
||||
: CRenderedObject(oReader, pParent)
|
||||
{}
|
||||
|
||||
void CGraphicsContainer::SetAttribute(const std::string& sName, CSvgReader& oReader)
|
||||
{
|
||||
@ -27,9 +21,7 @@ namespace SVG
|
||||
m_oWindow.m_oHeight.SetValue(oReader.GetDouble());
|
||||
else if ("viewBox" == sName)
|
||||
{
|
||||
m_oViewBox = m_oWindow;
|
||||
|
||||
std::vector<double> arValues = StrUtils::ReadDoubleValues(oReader.GetText());
|
||||
const std::vector<double> arValues{StrUtils::ReadDoubleValues(oReader.GetText())};
|
||||
if (4 == arValues.size())
|
||||
{
|
||||
m_oViewBox.m_oX = arValues[0];
|
||||
@ -42,14 +34,6 @@ namespace SVG
|
||||
CRenderedObject::SetAttribute(sName, oReader);
|
||||
}
|
||||
|
||||
CGraphicsContainer::CGraphicsContainer(CSvgReader& oReader, CRenderedObject *pParent)
|
||||
: CRenderedObject(oReader, pParent)
|
||||
{}
|
||||
|
||||
CGraphicsContainer::CGraphicsContainer(double dWidth, double dHeight, CSvgReader& oReader, CRenderedObject *pParent)
|
||||
: CRenderedObject(oReader, pParent), m_oWindow{0, 0, dWidth, dHeight}
|
||||
{}
|
||||
|
||||
bool CGraphicsContainer::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
{
|
||||
Aggplus::CMatrix oOldTransform;
|
||||
@ -72,6 +56,9 @@ namespace SVG
|
||||
|
||||
TRect CGraphicsContainer::GetViewBox() const
|
||||
{
|
||||
if (m_oViewBox.m_oWidth.Empty() || m_oViewBox.m_oHeight.Empty())
|
||||
return m_oWindow;
|
||||
|
||||
return m_oViewBox;
|
||||
}
|
||||
|
||||
|
||||
@ -12,8 +12,9 @@ namespace SVG
|
||||
template<typename TypeObject>
|
||||
class CContainer
|
||||
{
|
||||
using const_iterator = typename std::vector<TypeObject*>::const_iterator;
|
||||
public:
|
||||
CContainer(){}
|
||||
CContainer() = default;
|
||||
virtual ~CContainer()
|
||||
{
|
||||
Clear();
|
||||
@ -61,31 +62,26 @@ namespace SVG
|
||||
|
||||
return NULL;
|
||||
}
|
||||
private:
|
||||
std::vector<TypeObject*> m_arObjects;
|
||||
|
||||
friend class CText;
|
||||
friend class CMask;
|
||||
friend class CTSpan;
|
||||
friend class CMarker;
|
||||
friend class CSwitch;
|
||||
friend class CPattern;
|
||||
friend class CGradient;
|
||||
friend class CClipPath;
|
||||
friend class CTextPath;
|
||||
friend class CLinearGradient;
|
||||
friend class CGraphicsContainer;
|
||||
const_iterator begin() const
|
||||
{
|
||||
return m_arObjects.cbegin();
|
||||
}
|
||||
|
||||
const_iterator end() const
|
||||
{
|
||||
return m_arObjects.cend();
|
||||
}
|
||||
protected:
|
||||
std::vector<TypeObject*> m_arObjects;
|
||||
};
|
||||
|
||||
class CGraphicsContainer : public CContainer<CRenderedObject>, public CRenderedObject
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
// CGraphicsContainer(const std::wstring& wsName = L"GraphicsContainer");
|
||||
friend class CObject;
|
||||
CGraphicsContainer(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
CGraphicsContainer(double dWidth, double dHeight, CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
|
||||
virtual ~CGraphicsContainer();
|
||||
virtual ~CGraphicsContainer() = default;
|
||||
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ namespace SVG
|
||||
{
|
||||
class CEllipse : public CRenderedObject
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CEllipse(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
|
||||
@ -36,8 +36,9 @@ namespace SVG
|
||||
|
||||
class CFont : public CAppliedObject
|
||||
{
|
||||
public:
|
||||
friend class CObject;
|
||||
CFont(CSvgReader& oReader);
|
||||
public:
|
||||
~CFont();
|
||||
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
@ -56,6 +56,25 @@ namespace SVG
|
||||
void CGradient::SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
{}
|
||||
|
||||
void CGradient::ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile)
|
||||
{
|
||||
if (NULL == pSvgFile || NULL == pSvgFile->GetSvgCalculator())
|
||||
return;
|
||||
|
||||
WHILE_READ_NEXT_NODE_WITH_ONE_NAME(oReader, "stop")
|
||||
{
|
||||
CStopElement *pStopElement = new CStopElement(oReader);
|
||||
|
||||
if (NULL == pStopElement)
|
||||
continue;
|
||||
|
||||
pSvgFile->GetSvgCalculator()->SetData(pStopElement);
|
||||
|
||||
AddObject(pStopElement);
|
||||
}
|
||||
END_WHILE
|
||||
}
|
||||
|
||||
bool CGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
|
||||
{
|
||||
if (NULL == pRenderer || m_arObjects.empty())
|
||||
|
||||
@ -37,13 +37,15 @@ namespace SVG
|
||||
|
||||
class CGradient : public CContainer<CStopElement>, public CAppliedObject
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
CGradient(CSvgReader& oReader);
|
||||
|
||||
public:
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
|
||||
void ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile) override;
|
||||
|
||||
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
|
||||
void ApplyTransform(IRenderer *pRenderer, const TBounds& oBounds, double& dAngle) const;
|
||||
protected:
|
||||
@ -58,9 +60,9 @@ namespace SVG
|
||||
|
||||
class CLinearGradient : public CGradient
|
||||
{
|
||||
public:
|
||||
friend class CObject;
|
||||
CLinearGradient(CSvgReader& oReader);
|
||||
|
||||
public:
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
|
||||
@ -73,9 +75,9 @@ namespace SVG
|
||||
|
||||
class CRadialGradient : public CGradient
|
||||
{
|
||||
public:
|
||||
friend class CObject;
|
||||
CRadialGradient(CSvgReader& oReader);
|
||||
|
||||
public:
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
#include "../../../BgraFrame.h"
|
||||
#include "../../../../common/Path.h"
|
||||
#include "../../../../common/ProcessEnv.h"
|
||||
#include "../../../../common/Base64.h"
|
||||
#include "../../../../Common/File.h"
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
|
||||
@ -7,7 +7,7 @@ namespace SVG
|
||||
{
|
||||
class CImage : public CRenderedObject
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CImage(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
@ -4,28 +4,44 @@ namespace SVG
|
||||
{
|
||||
CLine::CLine(CSvgReader& oReader, CRenderedObject* pParent)
|
||||
: CPath(oReader, pParent)
|
||||
{}
|
||||
{
|
||||
AddElement(new CMoveElement(Point{0, 0}));
|
||||
AddElement(new CLineElement(Point{0, 0}));
|
||||
}
|
||||
|
||||
void CLine::SetAttribute(const std::string& sName, CSvgReader& oReader)
|
||||
{
|
||||
SvgDigit oX1;
|
||||
SvgDigit oY1;
|
||||
SvgDigit oX2;
|
||||
SvgDigit oY2;
|
||||
|
||||
//TODO:: не нравится, подумать как можно сделать иначе
|
||||
if ("x1" == sName)
|
||||
oX1.SetValue(oReader.GetText());
|
||||
{
|
||||
CMoveElement* pMoveElement{dynamic_cast<CMoveElement*>(operator[](0))};
|
||||
|
||||
if (NULL != pMoveElement)
|
||||
pMoveElement->m_oPoint.dX = oReader.GetDouble();
|
||||
}
|
||||
else if ("y1" == sName)
|
||||
oY1.SetValue(oReader.GetText());
|
||||
{
|
||||
CMoveElement* pMoveElement{dynamic_cast<CMoveElement*>(operator[](0))};
|
||||
|
||||
if (NULL != pMoveElement)
|
||||
pMoveElement->m_oPoint.dY = oReader.GetDouble();
|
||||
}
|
||||
else if ("x2" == sName)
|
||||
oX2.SetValue(oReader.GetText());
|
||||
{
|
||||
CLineElement* pLineElement{dynamic_cast<CLineElement*>(operator[](1))};
|
||||
|
||||
if (NULL != pLineElement)
|
||||
pLineElement->m_oPoint.dX = oReader.GetDouble();
|
||||
}
|
||||
else if ("y2" == sName)
|
||||
oY2.SetValue(oReader.GetText());
|
||||
{
|
||||
CLineElement* pLineElement{dynamic_cast<CLineElement*>(operator[](1))};
|
||||
|
||||
if (NULL != pLineElement)
|
||||
pLineElement->m_oPoint.dY = oReader.GetDouble();
|
||||
}
|
||||
else
|
||||
CRenderedObject::SetAttribute(sName, oReader);
|
||||
|
||||
AddElement(new CMoveElement(Point{oX1.ToDouble(NSCSS::Pixel), oY1.ToDouble(NSCSS::Pixel)}));
|
||||
AddElement(new CLineElement(Point{oX2.ToDouble(NSCSS::Pixel), oY2.ToDouble(NSCSS::Pixel)}));
|
||||
}
|
||||
|
||||
void CLine::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
|
||||
@ -7,7 +7,7 @@ namespace SVG
|
||||
{
|
||||
class CLine : public CPath
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CLine(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
@ -7,10 +7,9 @@ namespace SVG
|
||||
CMarker::CMarker(CSvgReader& oReader)
|
||||
: CObject(oReader), m_enUnits{EMarkerUnits::StrokeWidth}, m_enOrient{EMarkerOrient::Angle},
|
||||
m_dAngle(0.), m_oBounds{0., 0., 0., 0.}
|
||||
{}
|
||||
|
||||
CMarker::~CMarker()
|
||||
{
|
||||
m_oWindow.m_oWidth.SetValue(3);
|
||||
m_oWindow.m_oHeight.SetValue(3);
|
||||
}
|
||||
|
||||
ObjectType CMarker::GetType() const
|
||||
@ -30,7 +29,7 @@ namespace SVG
|
||||
m_oWindow.m_oHeight.SetValue(oReader.GetDouble());
|
||||
else if ("viewBox" == sName)
|
||||
{
|
||||
std::vector<double> arValues = StrUtils::ReadDoubleValues(oReader.GetText());
|
||||
const std::vector<double> arValues{StrUtils::ReadDoubleValues(oReader.GetText())};
|
||||
if (4 == arValues.size())
|
||||
{
|
||||
m_oViewBox.m_oX = arValues[0];
|
||||
@ -55,6 +54,8 @@ namespace SVG
|
||||
else if (!StrUtils::ReadAngle(wsOrient, m_dAngle))
|
||||
StrUtils::ReadDoubleValue(wsOrient, m_dAngle);
|
||||
}
|
||||
else
|
||||
CObject::SetAttribute(sName, oReader);
|
||||
}
|
||||
|
||||
void CMarker::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
@ -65,7 +66,11 @@ namespace SVG
|
||||
if (NULL == oExternalData.m_pPoints || oExternalData.m_pPoints->empty() || m_arObjects.empty() || (EMarkerUnits::StrokeWidth == m_enUnits && Equals(0., oExternalData.m_dStroke)))
|
||||
return;
|
||||
|
||||
const double dMaxScale = ((EMarkerUnits::StrokeWidth == m_enUnits) ? oExternalData.m_dStroke : 1.) * std::max((m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oWidth.ToDouble(NSCSS::Pixel)), (m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel)));
|
||||
const double dMaxScale = ((EMarkerUnits::StrokeWidth == m_enUnits) ? oExternalData.m_dStroke : 1.) *
|
||||
((!m_oViewBox.m_oWidth.Empty() && !m_oViewBox.m_oHeight.Empty()) ?
|
||||
std::max((m_oWindow.m_oWidth.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oWidth.ToDouble(NSCSS::Pixel)),
|
||||
(m_oWindow.m_oHeight.ToDouble(NSCSS::Pixel) / m_oViewBox.m_oHeight.ToDouble(NSCSS::Pixel))) :
|
||||
1.);
|
||||
|
||||
double dM11, dM12, dM21, dM22, dDx, dDy;
|
||||
pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy);
|
||||
|
||||
@ -45,9 +45,10 @@ namespace SVG
|
||||
|
||||
class CMarker : public CObject, public CContainer<CRenderedObject>
|
||||
{
|
||||
public:
|
||||
friend class CObject;
|
||||
CMarker(CSvgReader& oReader);
|
||||
virtual ~CMarker();
|
||||
public:
|
||||
virtual ~CMarker() = default;
|
||||
|
||||
ObjectType GetType() const override;
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ namespace SVG
|
||||
pRenderer->BeginCommand(c_nMaskType);
|
||||
pRenderer->PathCommandStart();
|
||||
|
||||
for (const CRenderedObject* pObject : m_oContainer.m_arObjects)
|
||||
for (const CRenderedObject* pObject : m_oContainer)
|
||||
pObject->Draw(pRenderer, pFile, CommandeModeMask);
|
||||
|
||||
pRenderer->EndCommand(c_nMaskType);
|
||||
|
||||
@ -7,9 +7,9 @@ namespace SVG
|
||||
{
|
||||
class CMask : public CClipPath
|
||||
{
|
||||
public:
|
||||
friend class CObject;
|
||||
CMask(CSvgReader& oReader);
|
||||
|
||||
public:
|
||||
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
|
||||
};
|
||||
}
|
||||
|
||||
@ -42,9 +42,6 @@ namespace SVG
|
||||
: m_oXmlNode(oObject.m_oXmlNode), m_oTransformation(oObject.m_oTransformation)
|
||||
{}
|
||||
|
||||
CObject::~CObject()
|
||||
{}
|
||||
|
||||
void CObject::SetAttribute(const std::string& sName, CSvgReader& oReader)
|
||||
{
|
||||
if ("class" == sName)
|
||||
@ -68,6 +65,11 @@ namespace SVG
|
||||
SetData(NSCSS::NS_STATIC_FUNCTIONS::GetRules(wsStyles), ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
void CObject::ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile)
|
||||
{
|
||||
//TODO:: реализовано в классах там, где нужно
|
||||
}
|
||||
|
||||
void CObject::SetTransform(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
|
||||
{
|
||||
if (mAttributes.end() != mAttributes.find(L"transform"))
|
||||
@ -201,9 +203,6 @@ namespace SVG
|
||||
m_pParent(oRenderedObject.m_pParent)
|
||||
{}
|
||||
|
||||
CRenderedObject::~CRenderedObject()
|
||||
{}
|
||||
|
||||
ObjectType CRenderedObject::GetType() const
|
||||
{
|
||||
return RendererObject;
|
||||
@ -223,11 +222,6 @@ namespace SVG
|
||||
SetMask (mAttributes, ushLevel, bHardMode);
|
||||
}
|
||||
|
||||
void CRenderedObject::ReadChildrens(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator)
|
||||
{
|
||||
//TODO:: реализовано в классах там, где нужно
|
||||
}
|
||||
|
||||
std::vector<NSCSS::CNode> CRenderedObject::GetFullPath() const
|
||||
{
|
||||
if (NULL == m_pParent)
|
||||
@ -460,9 +454,6 @@ namespace SVG
|
||||
: CObject(oReader)
|
||||
{}
|
||||
|
||||
CAppliedObject::~CAppliedObject()
|
||||
{}
|
||||
|
||||
ObjectType CAppliedObject::GetType() const
|
||||
{
|
||||
return AppliedObject;
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#include "../SvgReader.h"
|
||||
#include "CStyle.h"
|
||||
|
||||
class CSvgFile;
|
||||
#include "../CSvgFile.h"
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
@ -44,7 +44,7 @@ namespace SVG
|
||||
CObject(CSvgReader& oReader);
|
||||
CObject(const CObject& oObject);
|
||||
public:
|
||||
virtual ~CObject();
|
||||
virtual ~CObject() = default;
|
||||
|
||||
virtual ObjectType GetType() const = 0;
|
||||
|
||||
@ -54,6 +54,10 @@ namespace SVG
|
||||
|
||||
virtual void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) = 0;
|
||||
|
||||
template <class T, typename... Args>
|
||||
static T* Create(CSvgReader& oReader, CSvgFile* pSvgFile, Args&&... args);
|
||||
virtual void ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile);
|
||||
|
||||
void SetTransform(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
|
||||
void SetClip(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
|
||||
void SetMask(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
|
||||
@ -62,35 +66,48 @@ namespace SVG
|
||||
|
||||
std::wstring GetId() const;
|
||||
virtual std::vector<NSCSS::CNode> GetFullPath() const;
|
||||
private:
|
||||
protected:
|
||||
bool ApplyTransform(IRenderer* pRenderer, const SvgTransform* pTransform, Aggplus::CMatrix& oOldMatrix) const;
|
||||
bool ApplyClip(IRenderer* pRenderer, const TClip* pClip, const CSvgFile *pFile, const TBounds& oBounds) const;
|
||||
bool ApplyMask(IRenderer* pRenderer, const SvgColor* pMask, const CSvgFile *pFile, const TBounds& oBounds) const;
|
||||
|
||||
bool ApplyDef(IRenderer* pRenderer, const CSvgFile *pFile, const std::wstring& wsUrl, const TBounds& oBounds) const;
|
||||
|
||||
friend class CRenderedObject;
|
||||
friend class CAppliedObject;
|
||||
|
||||
friend class CUse;
|
||||
friend class CLine;
|
||||
friend class CRect;
|
||||
friend class CPath;
|
||||
friend class CText;
|
||||
friend class CTSpan;
|
||||
friend class CImage;
|
||||
friend class CCircle;
|
||||
friend class CPolygon;
|
||||
friend class CEllipse;
|
||||
friend class CPolyline;
|
||||
friend class CGraphicsContainer;
|
||||
|
||||
friend class CClipPath;
|
||||
|
||||
NSCSS::CNode m_oXmlNode;
|
||||
TSvgTransformation m_oTransformation;
|
||||
};
|
||||
|
||||
template<class T, typename... Args>
|
||||
inline T* CObject::Create(CSvgReader& oReader, CSvgFile* pSvgFile, Args&&... args)
|
||||
{
|
||||
T* pObject = new T(oReader, std::forward<Args>(args)...);
|
||||
|
||||
if (NULL == pObject)
|
||||
return NULL;
|
||||
|
||||
START_READ_ATTRIBUTES(oReader)
|
||||
pObject->SetAttribute(sAttributeName, oReader);
|
||||
END_READ_ATTRIBUTES(oReader)
|
||||
|
||||
if (NULL == pSvgFile)
|
||||
return pObject;
|
||||
|
||||
if (!pSvgFile->MarkObject(pObject) && AppliedObject == pObject->GetType())
|
||||
{
|
||||
delete pObject;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const CSvgCalculator* pSvgCalculator{pSvgFile->GetSvgCalculator()};
|
||||
|
||||
if (NULL != pSvgCalculator)
|
||||
pSvgCalculator->SetData(pObject);
|
||||
|
||||
pObject->ReadChildrens(oReader, pSvgFile);
|
||||
|
||||
return pObject;
|
||||
}
|
||||
|
||||
enum CommandeMode
|
||||
{
|
||||
CommandeModeDraw,
|
||||
@ -107,18 +124,13 @@ namespace SVG
|
||||
CRenderedObject(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
CRenderedObject(const CRenderedObject& oRenderedObject);
|
||||
public:
|
||||
virtual ~CRenderedObject();
|
||||
|
||||
template <class T, typename... Args>
|
||||
static T* Create(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator, CRenderedObject* pParent = NULL, Args&&... args);
|
||||
virtual ~CRenderedObject() = default;
|
||||
|
||||
ObjectType GetType() const override;
|
||||
|
||||
virtual void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
virtual void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
|
||||
virtual void ReadChildrens(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator);
|
||||
|
||||
virtual bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContextObject = NULL) const = 0;
|
||||
|
||||
virtual TBounds GetBounds() const = 0;
|
||||
@ -159,32 +171,12 @@ namespace SVG
|
||||
CRenderedObject *m_pParent;
|
||||
};
|
||||
|
||||
template<class T, typename... Args>
|
||||
inline T* CRenderedObject::Create(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator, CRenderedObject* pParent, Args&&... args)
|
||||
{
|
||||
T* pObject = new T(oReader, pParent, std::forward<Args>(args)...);
|
||||
|
||||
if (NULL == pObject)
|
||||
return NULL;
|
||||
|
||||
START_READ_ATTRIBUTES(oReader)
|
||||
pObject->SetAttribute(sAttributeName, oReader);
|
||||
END_READ_ATTRIBUTES(oReader)
|
||||
|
||||
if (NULL != pSvgCalculator)
|
||||
pSvgCalculator->SetData(pObject);
|
||||
|
||||
pObject->ReadChildrens(oReader, pSvgCalculator);
|
||||
|
||||
return pObject;
|
||||
}
|
||||
|
||||
class CAppliedObject : public CObject
|
||||
{
|
||||
protected:
|
||||
CAppliedObject(CSvgReader& oReader);
|
||||
public:
|
||||
virtual ~CAppliedObject();
|
||||
virtual ~CAppliedObject() = default;
|
||||
|
||||
ObjectType GetType() const override;
|
||||
|
||||
|
||||
@ -8,49 +8,46 @@
|
||||
|
||||
namespace SVG
|
||||
{
|
||||
IPathElement::~IPathElement()
|
||||
{
|
||||
}
|
||||
|
||||
#define ISPATHCOMMAND(wchar) L'M' == wchar || L'm' == wchar || L'Z' == wchar || L'z' == wchar || L'L' == wchar || L'l' == wchar || L'H' == wchar || L'h' == wchar || L'V' == wchar || L'v' == wchar || L'C' == wchar || L'c' == wchar || L'S' == wchar || L's' == wchar || L'Q' == wchar || L'q' == wchar || L'T' == wchar || L't' == wchar || L'A' == wchar || L'a' == wchar
|
||||
// IpathElement
|
||||
TBounds IPathElement::GetBounds() const
|
||||
{
|
||||
TBounds oBounds{DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX};
|
||||
|
||||
for (const Point& oPoint : m_arPoints)
|
||||
Point IPathElement::GetFirstPoint() const
|
||||
{
|
||||
switch (GetType())
|
||||
{
|
||||
oBounds.m_dLeft = std::min(oBounds.m_dLeft, oPoint.dX);
|
||||
oBounds.m_dTop = std::min(oBounds.m_dTop, oPoint.dY);
|
||||
oBounds.m_dRight = std::max(oBounds.m_dRight, oPoint.dX);
|
||||
oBounds.m_dBottom = std::max(oBounds.m_dBottom, oPoint.dY);
|
||||
case Move: return ((CMoveElement*)this)->m_oPoint;
|
||||
case Line: return ((CLineElement*)this)->m_oPoint;
|
||||
case CBezier:
|
||||
case SBezier:
|
||||
case QBezier:
|
||||
case TBezier:
|
||||
case Arc: return ((CCBezierElement*)this)->m_oPoint1;
|
||||
case Close: return Point{0., 0.};
|
||||
}
|
||||
|
||||
return oBounds;
|
||||
return Point{0., 0.};
|
||||
}
|
||||
|
||||
UINT IPathElement::GetPointCount() const
|
||||
Point IPathElement::GetLastPoint() const
|
||||
{
|
||||
return m_arPoints.size();
|
||||
}
|
||||
switch (GetType())
|
||||
{
|
||||
case Move: return ((CMoveElement*)this)->m_oPoint;
|
||||
case Line: return ((CLineElement*)this)->m_oPoint;
|
||||
case CBezier:
|
||||
case SBezier:
|
||||
case QBezier:
|
||||
case TBezier:
|
||||
case Arc: return ((CCBezierElement*)this)->m_oPointE;
|
||||
case Close: return Point{0., 0.};
|
||||
}
|
||||
|
||||
Point IPathElement::operator[](int nIndex) const
|
||||
{
|
||||
if (m_arPoints.empty() || (nIndex > 0 && nIndex >= m_arPoints.size()) || (nIndex < 0 && -nIndex > m_arPoints.size()))
|
||||
return Point{0., 0.};
|
||||
|
||||
return m_arPoints[(nIndex >= 0) ? nIndex : m_arPoints.size() + nIndex];
|
||||
return Point{0., 0.};
|
||||
}
|
||||
|
||||
//CMoveElement
|
||||
CMoveElement::CMoveElement(const Point &oPoint)
|
||||
{
|
||||
m_arPoints.push_back(oPoint);
|
||||
}
|
||||
|
||||
CMoveElement::~CMoveElement()
|
||||
{
|
||||
}
|
||||
: m_oPoint(oPoint)
|
||||
{}
|
||||
|
||||
EPathElement CMoveElement::GetType() const
|
||||
{
|
||||
@ -65,7 +62,7 @@ namespace SVG
|
||||
Point oTranslatePoint{0., 0.};
|
||||
|
||||
if (bRelativeCoordinate && NULL != pPrevElement)
|
||||
oTranslatePoint = (*pPrevElement)[-1];
|
||||
oTranslatePoint = pPrevElement->GetLastPoint();
|
||||
|
||||
CMoveElement *pMoveElement = new CMoveElement(Point{arValues[0], arValues[1]} + oTranslatePoint);
|
||||
|
||||
@ -76,19 +73,18 @@ namespace SVG
|
||||
|
||||
void CMoveElement::Draw(IRenderer *pRenderer) const
|
||||
{
|
||||
if (m_arPoints.empty())
|
||||
return;
|
||||
if (NULL != pRenderer)
|
||||
pRenderer->PathCommandMoveTo(m_oPoint.dX, m_oPoint.dY);
|
||||
}
|
||||
|
||||
pRenderer->PathCommandMoveTo(m_arPoints[0].dX, m_arPoints[0].dY);
|
||||
TBounds CMoveElement::GetBounds() const
|
||||
{
|
||||
return TBounds{m_oPoint.dX, m_oPoint.dY, 1, 1};
|
||||
}
|
||||
|
||||
//CLineElement
|
||||
CLineElement::CLineElement(const Point &oPoint)
|
||||
{
|
||||
m_arPoints.push_back(oPoint);
|
||||
}
|
||||
|
||||
CLineElement::~CLineElement()
|
||||
: m_oPoint(oPoint)
|
||||
{}
|
||||
|
||||
EPathElement CLineElement::GetType() const
|
||||
@ -104,7 +100,7 @@ namespace SVG
|
||||
Point oTranslatePoint{0., 0.};
|
||||
|
||||
if (bRelativeCoordinate && NULL != pPrevElement)
|
||||
oTranslatePoint = (*pPrevElement)[-1];
|
||||
oTranslatePoint = pPrevElement->GetLastPoint();
|
||||
|
||||
CLineElement *pLineElement = new CLineElement(Point{arValues[0], arValues[1]} + oTranslatePoint);
|
||||
|
||||
@ -121,7 +117,7 @@ namespace SVG
|
||||
Point oTranslatePoint{0., 0.};
|
||||
|
||||
if (NULL != pPrevElement)
|
||||
oTranslatePoint = (*pPrevElement)[-1];
|
||||
oTranslatePoint = pPrevElement->GetLastPoint();
|
||||
|
||||
CLineElement *pLineElement = new CLineElement(Point{oTranslatePoint.dX, arValues[0] + ((bRelativeCoordinate) ? oTranslatePoint.dY : 0)});
|
||||
|
||||
@ -138,7 +134,7 @@ namespace SVG
|
||||
Point oTranslatePoint{0., 0.};
|
||||
|
||||
if (NULL != pPrevElement)
|
||||
oTranslatePoint = (*pPrevElement)[-1];
|
||||
oTranslatePoint = pPrevElement->GetLastPoint();
|
||||
|
||||
CLineElement *pLineElement = new CLineElement(Point{arValues[0] + ((bRelativeCoordinate) ? oTranslatePoint.dX : 0), oTranslatePoint.dY});
|
||||
|
||||
@ -149,23 +145,19 @@ namespace SVG
|
||||
|
||||
void CLineElement::Draw(IRenderer *pRenderer) const
|
||||
{
|
||||
if (m_arPoints.empty())
|
||||
return;
|
||||
if (NULL != pRenderer)
|
||||
pRenderer->PathCommandLineTo(m_oPoint.dX, m_oPoint.dY);
|
||||
}
|
||||
|
||||
pRenderer->PathCommandLineTo(m_arPoints[0].dX, m_arPoints[0].dY);
|
||||
TBounds CLineElement::GetBounds() const
|
||||
{
|
||||
return TBounds{m_oPoint.dX, m_oPoint.dY, 1, 1};
|
||||
}
|
||||
|
||||
//CCurveBezierElement
|
||||
CCBezierElement::CCBezierElement(const Point &oPoint1, const Point &oPoint2, const Point &oPointE, EPathElement enType)
|
||||
: m_enType(enType)
|
||||
{
|
||||
m_arPoints.push_back(oPoint1);
|
||||
m_arPoints.push_back(oPoint2);
|
||||
m_arPoints.push_back(oPointE);
|
||||
}
|
||||
CCBezierElement::~CCBezierElement()
|
||||
{
|
||||
}
|
||||
: m_oPoint1(oPoint1), m_oPoint2(oPoint2), m_oPointE(oPointE), m_enType(enType)
|
||||
{}
|
||||
|
||||
EPathElement CCBezierElement::GetType() const
|
||||
{
|
||||
@ -180,11 +172,11 @@ namespace SVG
|
||||
Point oTranslatePoint{0., 0.};
|
||||
|
||||
if (bRelativeCoordinate && NULL != pPrevElement)
|
||||
oTranslatePoint = (*pPrevElement)[-1];
|
||||
oTranslatePoint = pPrevElement->GetLastPoint();
|
||||
|
||||
CCBezierElement *pCBezierElement = new CCBezierElement(Point{arValues[0], arValues[1]} + oTranslatePoint,
|
||||
Point{arValues[2], arValues[3]} + oTranslatePoint,
|
||||
Point{arValues[4], arValues[5]} + oTranslatePoint);
|
||||
Point{arValues[2], arValues[3]} + oTranslatePoint,
|
||||
Point{arValues[4], arValues[5]} + oTranslatePoint);
|
||||
|
||||
arValues.erase(arValues.begin(), arValues.begin() + 6);
|
||||
|
||||
@ -200,14 +192,19 @@ namespace SVG
|
||||
|
||||
if (NULL != pPrevElement)
|
||||
{
|
||||
oFirstPoint = (*pPrevElement)[-1];
|
||||
oFirstPoint = pPrevElement->GetLastPoint();
|
||||
if (bRelativeCoordinate)
|
||||
oTranslatePoint = oFirstPoint;
|
||||
}
|
||||
|
||||
if (EPathElement::SBezier == pPrevElement->GetType() ||
|
||||
EPathElement::CBezier == pPrevElement->GetType())
|
||||
oFirstPoint += oFirstPoint - (*pPrevElement)[-2];
|
||||
{
|
||||
CCBezierElement *pBezierElement{dynamic_cast<CCBezierElement*>(pPrevElement)};
|
||||
|
||||
if (NULL != pBezierElement)
|
||||
oFirstPoint += oFirstPoint - pBezierElement->m_oPoint2;
|
||||
}
|
||||
|
||||
CCBezierElement *pCBezierElement = new CCBezierElement(oFirstPoint,
|
||||
Point{arValues[0], arValues[1]} + oTranslatePoint,
|
||||
@ -228,7 +225,7 @@ namespace SVG
|
||||
|
||||
if (NULL != pPrevElement)
|
||||
{
|
||||
oLastPoint = (*pPrevElement)[-1];
|
||||
oLastPoint = pPrevElement->GetLastPoint();
|
||||
if (bRelativeCoordinate)
|
||||
oTranslatePoint = oLastPoint;
|
||||
}
|
||||
@ -240,6 +237,14 @@ namespace SVG
|
||||
return pCBezierElement;
|
||||
}
|
||||
|
||||
bool ItBezierType(EPathElement eType)
|
||||
{
|
||||
return EPathElement::CBezier == eType ||
|
||||
EPathElement::SBezier == eType ||
|
||||
EPathElement::QBezier == eType ||
|
||||
EPathElement::TBezier == eType;
|
||||
}
|
||||
|
||||
IPathElement *CCBezierElement::CreateFromTArray(std::vector<double> &arValues, bool bRelativeCoordinate, IPathElement *pPrevElement)
|
||||
{
|
||||
if (arValues.size() < 2)
|
||||
@ -247,10 +252,29 @@ namespace SVG
|
||||
|
||||
Point oFirstPoint{0., 0.}, oSecondPoint{0., 0.}, oTranslatePoint{0., 0.};
|
||||
|
||||
if (EPathElement::SBezier == pPrevElement->GetType() ||
|
||||
EPathElement::CBezier == pPrevElement->GetType())
|
||||
{
|
||||
CCBezierElement *pBezierElement{dynamic_cast<CCBezierElement*>(pPrevElement)};
|
||||
|
||||
if (NULL != pBezierElement)
|
||||
oFirstPoint += oFirstPoint - pBezierElement->m_oPoint2;
|
||||
}
|
||||
|
||||
if (NULL != pPrevElement)
|
||||
{
|
||||
oFirstPoint = (*pPrevElement)[-1];
|
||||
oSecondPoint = (*pPrevElement)[-2];
|
||||
oFirstPoint = pPrevElement->GetLastPoint();
|
||||
|
||||
if (ItBezierType(pPrevElement->GetType()))
|
||||
{
|
||||
CCBezierElement *pBezierElement{dynamic_cast<CCBezierElement*>(pPrevElement)};
|
||||
|
||||
if (NULL != pBezierElement)
|
||||
oSecondPoint = pBezierElement->m_oPoint2;
|
||||
}
|
||||
else
|
||||
oSecondPoint = oFirstPoint;
|
||||
|
||||
if (bRelativeCoordinate)
|
||||
oTranslatePoint = oFirstPoint;
|
||||
}
|
||||
@ -282,9 +306,9 @@ namespace SVG
|
||||
Point oTranslatePoint{0., 0.};
|
||||
|
||||
if (bRelativeCoordinate && NULL != pPrevElement)
|
||||
oTranslatePoint = (*pPrevElement)[-1];
|
||||
oTranslatePoint = pPrevElement->GetLastPoint();
|
||||
|
||||
Point oSrartPoint{(*pPrevElement)[-1]};
|
||||
Point oSrartPoint{pPrevElement->GetLastPoint()};
|
||||
Point oSecondPoint{arValues[5] + oTranslatePoint.dX, arValues[6] + oTranslatePoint.dY};
|
||||
|
||||
if (oSrartPoint == oSecondPoint)
|
||||
@ -361,12 +385,26 @@ namespace SVG
|
||||
|
||||
void CCBezierElement::Draw(IRenderer *pRenderer) const
|
||||
{
|
||||
if (3 != m_arPoints.size())
|
||||
return;
|
||||
pRenderer->PathCommandCurveTo(m_oPoint1.dX, m_oPoint1.dY,
|
||||
m_oPoint2.dX, m_oPoint2.dY,
|
||||
m_oPointE.dX, m_oPointE.dY);
|
||||
}
|
||||
|
||||
pRenderer->PathCommandCurveTo(m_arPoints[0].dX, m_arPoints[0].dY,
|
||||
m_arPoints[1].dX, m_arPoints[1].dY,
|
||||
m_arPoints[2].dX, m_arPoints[2].dY);
|
||||
#define CHECK_BOUNDS(bounds, point)\
|
||||
bounds.m_dLeft = std::min(oBounds.m_dLeft, point.dX);\
|
||||
bounds.m_dTop = std::min(oBounds.m_dTop, point.dY);\
|
||||
bounds.m_dRight = std::max(oBounds.m_dRight, point.dX);\
|
||||
bounds.m_dBottom = std::max(oBounds.m_dBottom, point.dY)
|
||||
|
||||
TBounds CCBezierElement::GetBounds() const
|
||||
{
|
||||
TBounds oBounds{DBL_MAX, DBL_MAX, -DBL_MAX, -DBL_MAX};
|
||||
|
||||
CHECK_BOUNDS(oBounds, m_oPoint1);
|
||||
CHECK_BOUNDS(oBounds, m_oPoint2);
|
||||
CHECK_BOUNDS(oBounds, m_oPointE);
|
||||
|
||||
return oBounds;
|
||||
}
|
||||
|
||||
inline double ClampSinCos(const double& d)
|
||||
@ -422,13 +460,6 @@ namespace SVG
|
||||
}
|
||||
|
||||
//CCloseElement
|
||||
CCloseElement::CCloseElement()
|
||||
{}
|
||||
|
||||
CCloseElement::~CCloseElement()
|
||||
{
|
||||
}
|
||||
|
||||
EPathElement CCloseElement::GetType() const
|
||||
{
|
||||
return EPathElement::Close;
|
||||
@ -439,6 +470,11 @@ namespace SVG
|
||||
pRenderer->PathCommandClose();
|
||||
}
|
||||
|
||||
TBounds CCloseElement::GetBounds() const
|
||||
{
|
||||
return TBounds{0., 0., 0., 0.};
|
||||
}
|
||||
|
||||
#define LASTELEMENT(array) (array.empty()) ? NULL : array.back()
|
||||
#define RANGEALIGMENT(value, left, rigth) if (value < left) value = left; else if (value > rigth) value = rigth;
|
||||
#define EPSILON 0.05
|
||||
@ -546,17 +582,22 @@ namespace SVG
|
||||
{
|
||||
const IPathElement* pFirstElement{m_arElements[unIndex]};
|
||||
|
||||
(*oExternalData.m_pPoints)[0].m_oPoint = (*pFirstElement)[0];
|
||||
(*oExternalData.m_pPoints)[0].m_oPoint = pFirstElement->GetFirstPoint();
|
||||
|
||||
if (pStartMarker->NeedExternalAngle())
|
||||
{
|
||||
Point oCurent{(*pFirstElement)[0]};
|
||||
Point oCurent{pFirstElement->GetFirstPoint()};
|
||||
Point oNext;
|
||||
|
||||
if (pFirstElement->GetPointCount() > 1)
|
||||
oNext = (*pFirstElement)[1];
|
||||
if (ItBezierType(pFirstElement->GetType()))
|
||||
{
|
||||
const CCBezierElement* pBezierElement{dynamic_cast<const CCBezierElement*>(pFirstElement)};
|
||||
|
||||
if (NULL != pBezierElement)
|
||||
oNext = pBezierElement->m_oPoint2;
|
||||
}
|
||||
else if (unIndex < m_arElements.size() - 1 && EPathElement::Close != m_arElements[unIndex + 1]->GetType() && EPathElement::Move != m_arElements[unIndex + 1]->GetType())
|
||||
oNext = (*m_arElements[unIndex + 1])[0];
|
||||
oNext = m_arElements[unIndex + 1]->GetFirstPoint();
|
||||
|
||||
(*oExternalData.m_pPoints)[0].m_dAngle = CALCULATE_ANGLE(oCurent, oNext);
|
||||
|
||||
@ -582,12 +623,12 @@ namespace SVG
|
||||
for (unsigned int unIndex = 1; unIndex < m_arElements.size() - 1; ++unIndex)
|
||||
{
|
||||
if (EPathElement::Close != m_arElements[unIndex]->GetType())
|
||||
(*oExternalData.m_pPoints)[unIndex - 1].m_oPoint = (*m_arElements[unIndex])[-1];
|
||||
(*oExternalData.m_pPoints)[unIndex - 1].m_oPoint = m_arElements[unIndex]->GetLastPoint();
|
||||
|
||||
if (pMidMarker->NeedExternalAngle())
|
||||
{
|
||||
const Point oCurrent{(*m_arElements[unIndex])[0]};
|
||||
const Point oPrev{(*m_arElements[unIndex + 1])[-1]};
|
||||
const Point oCurrent{m_arElements[unIndex]->GetFirstPoint()};
|
||||
const Point oPrev{m_arElements[unIndex + 1]->GetLastPoint()};
|
||||
|
||||
(*oExternalData.m_pPoints)[unIndex - 1].m_dAngle = CALCULATE_ANGLE(oCurrent, oPrev);
|
||||
}
|
||||
@ -613,17 +654,22 @@ namespace SVG
|
||||
{
|
||||
const IPathElement* pLastElement{m_arElements[unIndex]};
|
||||
|
||||
(*oExternalData.m_pPoints)[0].m_oPoint = (*pLastElement)[-1];
|
||||
(*oExternalData.m_pPoints)[0].m_oPoint = pLastElement->GetLastPoint();
|
||||
|
||||
if (pEndMarker->NeedExternalAngle())
|
||||
{
|
||||
Point oCurent{(*pLastElement)[-1]};
|
||||
Point oCurent{pLastElement->GetLastPoint()};
|
||||
Point oPrev;
|
||||
|
||||
if (pLastElement->GetPointCount() > 1)
|
||||
oPrev = (*pLastElement)[-2];
|
||||
else if (unIndex > 0 && EPathElement::Close != m_arElements[unIndex - 1]->GetType() && EPathElement::Move != m_arElements[unIndex - 1]->GetType())
|
||||
oPrev = (*m_arElements[unIndex - 1])[0];
|
||||
if (ItBezierType(pLastElement->GetType()))
|
||||
{
|
||||
const CCBezierElement* pBezierElement{dynamic_cast<const CCBezierElement*>(pLastElement)};
|
||||
|
||||
if (NULL != pBezierElement)
|
||||
oPrev = pBezierElement->m_oPoint2;
|
||||
}
|
||||
else if (unIndex > 0 && EPathElement::Close != m_arElements[unIndex - 1]->GetType())
|
||||
oPrev = m_arElements[unIndex - 1]->GetFirstPoint();
|
||||
|
||||
(*oExternalData.m_pPoints)[0].m_dAngle = CALCULATE_ANGLE(oPrev, oCurent);
|
||||
}
|
||||
@ -706,7 +752,7 @@ namespace SVG
|
||||
if (NULL == pMoveElement)
|
||||
return;
|
||||
|
||||
AddElement(new CCloseElement);
|
||||
AddElement(new CCloseElement());
|
||||
oSecondPos = ++oFirstPos;
|
||||
continue;
|
||||
}
|
||||
@ -846,13 +892,13 @@ namespace SVG
|
||||
case EPathElement::Move:
|
||||
case EPathElement::Close:
|
||||
{
|
||||
m_oPosition = m_oLastPoint = (*m_pCurrentElement)[0];
|
||||
m_oPosition = m_oLastPoint = m_pCurrentElement->GetFirstPoint();
|
||||
m_pCurrentElement = (*m_pPath)[m_unIndexElement++];
|
||||
return Move(dX);
|
||||
}
|
||||
case EPathElement::Line:
|
||||
{
|
||||
Point oPoint{(*m_pCurrentElement)[0]};
|
||||
Point oPoint{m_pCurrentElement->GetFirstPoint()};
|
||||
|
||||
double dDx = oPoint.dX - m_oPosition.dX;
|
||||
double dDy = oPoint.dY - m_oPosition.dY;
|
||||
@ -879,6 +925,11 @@ namespace SVG
|
||||
case EPathElement::QBezier:
|
||||
case EPathElement::TBezier:
|
||||
{
|
||||
const CCBezierElement* pBezierElement{dynamic_cast<const CCBezierElement*>(m_pCurrentElement)};
|
||||
|
||||
if (NULL == pBezierElement)
|
||||
return false;
|
||||
|
||||
Point oCurvePoint{0., 0.};
|
||||
double dPrevValue = dX;
|
||||
|
||||
@ -902,8 +953,8 @@ namespace SVG
|
||||
|
||||
RANGEALIGMENT(m_dCurveIndex, 0., 1.);
|
||||
|
||||
oCurvePoint.dX = std::pow((1. - m_dCurveIndex), 3) * m_oLastPoint.dX + 3 * std::pow((1. - m_dCurveIndex), 2) * m_dCurveIndex * (*m_pCurrentElement)[0].dX + 3 * (1. - m_dCurveIndex)* std::pow(m_dCurveIndex, 2) * (*m_pCurrentElement)[1].dX + std::pow(m_dCurveIndex, 3) * (*m_pCurrentElement)[2].dX;
|
||||
oCurvePoint.dY = std::pow((1. - m_dCurveIndex), 3) * m_oLastPoint.dY + 3 * std::pow((1. - m_dCurveIndex), 2) * m_dCurveIndex * (*m_pCurrentElement)[0].dY + 3 * (1. - m_dCurveIndex)* std::pow(m_dCurveIndex, 2) * (*m_pCurrentElement)[1].dY + std::pow(m_dCurveIndex, 3) * (*m_pCurrentElement)[2].dY;
|
||||
oCurvePoint.dX = std::pow((1. - m_dCurveIndex), 3) * m_oLastPoint.dX + 3 * std::pow((1. - m_dCurveIndex), 2) * m_dCurveIndex * pBezierElement->m_oPoint1.dX + 3 * (1. - m_dCurveIndex)* std::pow(m_dCurveIndex, 2) * pBezierElement->m_oPoint2.dX + std::pow(m_dCurveIndex, 3) * pBezierElement->m_oPointE.dX;
|
||||
oCurvePoint.dY = std::pow((1. - m_dCurveIndex), 3) * m_oLastPoint.dY + 3 * std::pow((1. - m_dCurveIndex), 2) * m_dCurveIndex * pBezierElement->m_oPoint1.dY + 3 * (1. - m_dCurveIndex)* std::pow(m_dCurveIndex, 2) * pBezierElement->m_oPoint2.dY + std::pow(m_dCurveIndex, 3) * pBezierElement->m_oPointE.dY;
|
||||
|
||||
dPrevValue = dX;
|
||||
|
||||
@ -912,7 +963,7 @@ namespace SVG
|
||||
|
||||
m_dCurveStep = CURVESTEP;
|
||||
|
||||
return NextMove(dX, (*m_pCurrentElement)[-1]);
|
||||
return NextMove(dX, m_pCurrentElement->GetLastPoint());
|
||||
}
|
||||
default: return false;
|
||||
}
|
||||
@ -927,7 +978,7 @@ namespace SVG
|
||||
|
||||
m_unIndexElement = 0;
|
||||
m_pCurrentElement = (*m_pPath)[m_unIndexElement++];
|
||||
m_oPosition = m_oLastPoint = (*m_pCurrentElement)[0];
|
||||
m_oPosition = m_oLastPoint = m_pCurrentElement->GetFirstPoint();
|
||||
m_dAngle = m_dCurveIndex = 0.;
|
||||
m_dCurveStep = CURVESTEP;
|
||||
}
|
||||
|
||||
@ -30,57 +30,55 @@ namespace SVG
|
||||
class IPathElement
|
||||
{
|
||||
public:
|
||||
virtual ~IPathElement();
|
||||
virtual ~IPathElement() = default;
|
||||
virtual EPathElement GetType() const = 0;
|
||||
virtual void Draw(IRenderer* pRenderer) const = 0;
|
||||
virtual TBounds GetBounds() const = 0;
|
||||
|
||||
TBounds GetBounds() const;
|
||||
UINT GetPointCount() const;
|
||||
virtual Point operator[](int nIndex) const;
|
||||
|
||||
private:
|
||||
friend class CMoveElement;
|
||||
friend class CLineElement;
|
||||
friend class CVLineElement;
|
||||
friend class CHLineElement;
|
||||
friend class CCBezierElement;
|
||||
friend class CSBezierElement;
|
||||
friend class CQBezierElement;
|
||||
friend class CTBezierElement;
|
||||
friend class CArcElement;
|
||||
friend class CCloseElement;
|
||||
friend class CMovingPath;
|
||||
|
||||
std::vector<Point> m_arPoints;
|
||||
Point GetFirstPoint() const;
|
||||
Point GetLastPoint() const;
|
||||
};
|
||||
|
||||
class CMoveElement : public IPathElement
|
||||
{
|
||||
public:
|
||||
CMoveElement(const Point& oPoint);
|
||||
virtual ~CMoveElement();
|
||||
virtual ~CMoveElement() = default;
|
||||
EPathElement GetType() const override;
|
||||
static CMoveElement* CreateFromArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
|
||||
void Draw(IRenderer* pRenderer) const override;
|
||||
TBounds GetBounds() const override;
|
||||
private:
|
||||
Point m_oPoint;
|
||||
|
||||
friend class IPathElement;
|
||||
friend class CLine;
|
||||
};
|
||||
|
||||
class CLineElement : public IPathElement
|
||||
{
|
||||
public:
|
||||
CLineElement(const Point& oPoint);
|
||||
virtual ~CLineElement();
|
||||
virtual ~CLineElement() = default;
|
||||
EPathElement GetType() const override;
|
||||
static CLineElement* CreateFromArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
|
||||
static CLineElement* CreateFromVArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
|
||||
static CLineElement* CreateFromHArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
|
||||
void Draw(IRenderer* pRenderer) const override;
|
||||
TBounds GetBounds() const override;
|
||||
Point GetPoint() const;
|
||||
private:
|
||||
Point m_oPoint;
|
||||
|
||||
friend class IPathElement;
|
||||
friend class CLine;
|
||||
};
|
||||
|
||||
class CCBezierElement : public IPathElement
|
||||
{
|
||||
public:
|
||||
CCBezierElement(const Point& oPoint1, const Point& oPoint2, const Point& oPointE, EPathElement enType = CBezier);
|
||||
virtual ~CCBezierElement();
|
||||
virtual ~CCBezierElement() = default;
|
||||
EPathElement GetType() const override;
|
||||
static IPathElement* CreateFromArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
|
||||
static IPathElement* CreateFromSArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
|
||||
@ -88,24 +86,33 @@ namespace SVG
|
||||
static IPathElement* CreateFromTArray(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
|
||||
static std::vector<IPathElement*> CreateFromArc(std::vector<double>& arValues, bool bRelativeCoordinate, IPathElement* pPrevElement = NULL);
|
||||
void Draw(IRenderer* pRenderer) const override;
|
||||
TBounds GetBounds() const override;
|
||||
private:
|
||||
static void CalculateArcData(const Point& oFirst, const Point& oSecond, Point& oRadius, Point& oCenter, double dAngle, bool bLargeArc, bool bSweep, double& dStartAngle, double& dSweep);
|
||||
|
||||
Point m_oPoint1;
|
||||
Point m_oPoint2;
|
||||
Point m_oPointE;
|
||||
EPathElement m_enType;
|
||||
|
||||
friend class IPathElement;
|
||||
friend class CMovingPath;
|
||||
friend class CPath;
|
||||
};
|
||||
|
||||
class CCloseElement : public IPathElement
|
||||
{
|
||||
public:
|
||||
CCloseElement();
|
||||
virtual ~CCloseElement();
|
||||
CCloseElement() = default;
|
||||
virtual ~CCloseElement() = default;
|
||||
EPathElement GetType() const override;
|
||||
void Draw(IRenderer* pRenderer) const override;
|
||||
TBounds GetBounds() const override;
|
||||
};
|
||||
|
||||
class CPath : public CRenderedObject
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
protected:
|
||||
CPath(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
@ -122,7 +129,6 @@ namespace SVG
|
||||
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
|
||||
bool DrawMarkers(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
|
||||
|
||||
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
const int FindIndexFirstNotEmpty(bool bReverseSearch = false) const;
|
||||
|
||||
@ -14,8 +14,9 @@ namespace SVG
|
||||
|
||||
class CPattern : public CAppliedObject
|
||||
{
|
||||
public:
|
||||
friend class CObject;
|
||||
CPattern(CSvgReader& oReader, NSFonts::IFontManager *pFontManager = NULL);
|
||||
public:
|
||||
virtual ~CPattern();
|
||||
|
||||
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;
|
||||
|
||||
@ -7,7 +7,7 @@ namespace SVG
|
||||
{
|
||||
class CPolyline : public CPath
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
protected:
|
||||
CPolyline(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
@ -16,7 +16,7 @@ namespace SVG
|
||||
|
||||
class CPolygon : public CPolyline
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CPolygon(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
@ -7,7 +7,7 @@ namespace SVG
|
||||
{
|
||||
class CRect : public CRenderedObject
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CRect(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
virtual ~CRect();
|
||||
|
||||
@ -7,7 +7,7 @@ namespace SVG
|
||||
{
|
||||
class CSwitch : public CRenderedObject, public CContainer<CRenderedObject>
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CSwitch(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
|
||||
|
||||
@ -7,7 +7,7 @@ namespace SVG
|
||||
{
|
||||
class CSymbol : public CGraphicsContainer
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CSymbol(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
|
||||
|
||||
@ -27,31 +27,26 @@ namespace SVG
|
||||
#define MAX_SCALE 100
|
||||
|
||||
CTSpan::CTSpan(CSvgReader& oReader, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager, const Point &oPosition)
|
||||
: CRenderedObject(oReader, pParent), m_pFontManager(pFontManager)
|
||||
: CRenderedObject(oReader, pParent), m_pFontManager(pFontManager),
|
||||
m_oX(oPosition.dX), m_oY(oPosition.dY)
|
||||
{
|
||||
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE);
|
||||
|
||||
m_oX = oPosition.dX;
|
||||
m_oY = oPosition.dY;
|
||||
}
|
||||
|
||||
CTSpan::CTSpan(const std::wstring &wsText, const Point &oPosition, CRenderedObject *pParent, NSFonts::IFontManager* pFontManager, bool bCheckText)
|
||||
: CRenderedObject(NSCSS::CNode(L"tspan", L"", L""), pParent), m_pFontManager(pFontManager), m_wsText(wsText)
|
||||
{
|
||||
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE);
|
||||
|
||||
if (bCheckText)
|
||||
m_wsText = StrUtils::TrimExtraEnding(m_wsText);
|
||||
|
||||
m_oX = oPosition.dX;
|
||||
m_oY = oPosition.dY;
|
||||
}
|
||||
|
||||
CTSpan::CTSpan(const CTSpan& oTSpan, double dX, const std::wstring& wsText)
|
||||
: CRenderedObject(oTSpan), m_pFontManager(oTSpan.m_pFontManager),
|
||||
m_oX(dX), m_oY(oTSpan.m_oY), m_wsText(wsText),
|
||||
m_oFont(oTSpan.m_oFont), m_oText(oTSpan.m_oText)
|
||||
{}
|
||||
{
|
||||
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE);
|
||||
}
|
||||
|
||||
CTSpan::CTSpan(wchar_t wChar, const Point& oPosition, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager)
|
||||
: CRenderedObject(NSCSS::CNode(L"tspan", L"", L""), pParent), m_pFontManager(pFontManager),
|
||||
m_oX(oPosition.dX), m_oY(oPosition.dY)
|
||||
{
|
||||
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE);
|
||||
}
|
||||
|
||||
CTSpan::~CTSpan()
|
||||
{}
|
||||
@ -117,10 +112,55 @@ namespace SVG
|
||||
}
|
||||
}
|
||||
|
||||
void CTSpan::ReadChildrens(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator)
|
||||
void CTSpan::ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile)
|
||||
{
|
||||
// SetPositionFromParent(m_pParent);
|
||||
ReadText(oReader, pSvgCalculator, true);
|
||||
const int nDepth = oReader.GetDepth();
|
||||
XmlUtils::XmlNodeType eNodeType = XmlUtils::XmlNodeType_EndElement;
|
||||
while (oReader.Read(eNodeType) && oReader.GetDepth() >= nDepth && XmlUtils::XmlNodeType_EndElement != eNodeType)
|
||||
{
|
||||
if (eNodeType == XmlUtils::XmlNodeType_Text ||
|
||||
eNodeType == XmlUtils::XmlNodeType_Whitespace ||
|
||||
eNodeType == XmlUtils::XmlNodeType_SIGNIFICANT_WHITESPACE ||
|
||||
eNodeType == XmlUtils::XmlNodeType_CDATA)
|
||||
{
|
||||
const char* pValue = oReader.GetTextChar();
|
||||
|
||||
if('\0' != pValue[0])
|
||||
{
|
||||
bool bFoundedSymbol = false;
|
||||
const char* pCheckValue = pValue;
|
||||
while ('\0' != *pCheckValue)
|
||||
{
|
||||
if (isprint(*pCheckValue++))
|
||||
{
|
||||
bFoundedSymbol = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFoundedSymbol)
|
||||
continue;
|
||||
|
||||
if (m_wsText.empty())
|
||||
{
|
||||
NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen(pValue), m_wsText);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::wstring wsValue;
|
||||
NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen(pValue), wsValue);
|
||||
|
||||
AddObject(new CTSpan(*this, GetBounds().m_dRight, wsValue));
|
||||
}
|
||||
}
|
||||
else if (eNodeType == XmlUtils::XmlNodeType_Element && "tspan" == oReader.GetName())
|
||||
{
|
||||
const TBounds oBounds{GetBounds()};
|
||||
const Point oPoint{oBounds.m_dRight, oBounds.m_dTop};
|
||||
|
||||
AddObject(CRenderedObject::Create<CTSpan>(oReader, pSvgFile, this, m_pFontManager, oPoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CTSpan::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
|
||||
@ -338,57 +378,6 @@ namespace SVG
|
||||
return oBounds;
|
||||
}
|
||||
|
||||
void CTSpan::ReadText(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator, bool bCheckText)
|
||||
{
|
||||
const int nDepth = oReader.GetDepth();
|
||||
XmlUtils::XmlNodeType eNodeType = XmlUtils::XmlNodeType_EndElement;
|
||||
while (oReader.Read(eNodeType) && oReader.GetDepth() >= nDepth && XmlUtils::XmlNodeType_EndElement != eNodeType)
|
||||
{
|
||||
if (eNodeType == XmlUtils::XmlNodeType_Text ||
|
||||
eNodeType == XmlUtils::XmlNodeType_Whitespace ||
|
||||
eNodeType == XmlUtils::XmlNodeType_SIGNIFICANT_WHITESPACE ||
|
||||
eNodeType == XmlUtils::XmlNodeType_CDATA)
|
||||
{
|
||||
const char* pValue = oReader.GetTextChar();
|
||||
|
||||
if('\0' != pValue[0])
|
||||
{
|
||||
bool bFoundedSymbol = false;
|
||||
const char* pCheckValue = pValue;
|
||||
while ('\0' != *pCheckValue)
|
||||
{
|
||||
if (isprint(*pCheckValue++))
|
||||
{
|
||||
bFoundedSymbol = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFoundedSymbol)
|
||||
continue;
|
||||
|
||||
if (m_wsText.empty())
|
||||
{
|
||||
NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen(pValue), m_wsText);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::wstring wsValue;
|
||||
NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen(pValue), wsValue);
|
||||
|
||||
AddObject(new CTSpan(*this, GetBounds().m_dRight, wsValue));
|
||||
}
|
||||
}
|
||||
else if (eNodeType == XmlUtils::XmlNodeType_Element && "tspan" == oReader.GetName())
|
||||
{
|
||||
const TBounds oBounds{GetBounds()};
|
||||
const Point oPoint{oBounds.m_dRight, oBounds.m_dTop};
|
||||
|
||||
AddObject(CRenderedObject::Create<CTSpan>(oReader, pSvgCalculator, this, m_pFontManager, oPoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double CTSpan::GetWidth() const
|
||||
{
|
||||
if (m_wsText.empty() && m_arObjects.empty())
|
||||
@ -547,7 +536,7 @@ namespace SVG
|
||||
|
||||
for (unsigned int unIndex = 0; unIndex < m_wsText.length(); ++unIndex)
|
||||
{
|
||||
arGlyphs.push_back(CTSpan(std::wstring(1, m_wsText[unIndex]), oPosition, m_pParent, m_pFontManager, false));
|
||||
arGlyphs.push_back(CTSpan(m_wsText[unIndex], oPosition, m_pParent, m_pFontManager));
|
||||
oPosition.dX += arGlyphs[unIndex].GetWidth();
|
||||
}
|
||||
|
||||
|
||||
@ -12,18 +12,18 @@ namespace SVG
|
||||
{
|
||||
class CTSpan : public CRenderedObject, public CContainer<CTSpan>
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
protected:
|
||||
CTSpan(CSvgReader& oReader, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, const Point& oPosition = {});
|
||||
CTSpan(const std::wstring& wsText, const Point& oPosition, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, bool bCheckText = true);
|
||||
CTSpan(const CTSpan& oTSpan, double dX, const std::wstring& wsText);
|
||||
CTSpan(wchar_t wChar, const Point& oPosition, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
|
||||
public:
|
||||
virtual ~CTSpan();
|
||||
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
|
||||
|
||||
void ReadChildrens(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator) override;
|
||||
void ReadChildrens(CSvgReader& oReader, CSvgFile* pSvgFile) override;
|
||||
|
||||
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
|
||||
|
||||
@ -38,8 +38,6 @@ namespace SVG
|
||||
|
||||
TBounds GetBounds() const override;
|
||||
|
||||
void ReadText(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator, bool bCheckText);
|
||||
|
||||
double GetWidth() const;
|
||||
void CorrectFontFamily(std::wstring& wsFontFamily) const;
|
||||
|
||||
@ -68,7 +66,7 @@ namespace SVG
|
||||
|
||||
class CText : public CTSpan
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
protected:
|
||||
CText(CSvgReader& oReader, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
|
||||
public:
|
||||
@ -77,7 +75,7 @@ namespace SVG
|
||||
|
||||
class CTextPath : public CText
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CTextPath(CSvgReader& oReader, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
|
||||
public:
|
||||
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
|
||||
|
||||
@ -8,7 +8,7 @@ namespace SVG
|
||||
{
|
||||
class CUse : public CRenderedObject
|
||||
{
|
||||
friend class CRenderedObject;
|
||||
friend class CObject;
|
||||
CUse(CSvgReader& oReader, CRenderedObject* pParent = NULL);
|
||||
public:
|
||||
virtual ~CUse();
|
||||
|
||||
Reference in New Issue
Block a user