Intermediate refactoring

This commit is contained in:
Kirill Polyakov
2025-10-14 20:42:24 +03:00
parent 66d94cf00c
commit 6eeae2e804
48 changed files with 709 additions and 555 deletions

View File

@ -138,7 +138,7 @@ namespace NSCSS
bool SetValue(const std::wstring& wsValue, unsigned int unLevel = 0, bool bHardMode = true) override;
bool SetValue(const CDigit& oValue);
bool SetValue(const double& dValue, unsigned int unLevel, bool bHardMode);
bool SetValue(const double& dValue, unsigned int unLevel = 0, bool bHardMode = true);
bool Empty() const override;
bool Zero() const;

View File

@ -7,7 +7,7 @@
#define SVG_FILE_HEIGHT 150
CSvgFile::CSvgFile()
: m_oContainer(L"svg")
: m_pContainer(NULL)
{}
CSvgFile::~CSvgFile()
@ -24,7 +24,7 @@ bool CSvgFile::ReadFromBuffer(BYTE *pBuffer, unsigned int unSize)
bool CSvgFile::ReadFromWString(const std::wstring &wsContext)
{
Clear();
return m_oParser.LoadFromString(wsContext, &m_oContainer, this);
return m_oParser.LoadFromString(wsContext, m_pContainer, this);
}
bool CSvgFile::OpenFromFile(const std::wstring &wsFile)
@ -33,15 +33,15 @@ bool CSvgFile::OpenFromFile(const std::wstring &wsFile)
m_wsWorkingDirectory = NSFile::GetDirectoryName(wsFile);
return m_oParser.LoadFromFile(wsFile, &m_oContainer, this);
return m_oParser.LoadFromFile(wsFile, m_pContainer, this);
}
bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight) const
{
if (m_oContainer.Empty())
if (NULL == m_pContainer || m_pContainer->Empty())
return false;
SVG::TRect oWindow = m_oContainer.GetWindow();
SVG::TRect oWindow = m_pContainer->GetWindow();
dX = oWindow.m_oX.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
dY = oWindow.m_oY.ToDouble(NSCSS::Pixel, SVG_FILE_HEIGHT);
@ -53,8 +53,8 @@ bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight
{
if (NSCSS::Percent == oWindow.m_oWidth.GetUnitMeasure())
{
if (!m_oContainer.GetViewBox().m_oWidth.Empty() && !m_oContainer.GetViewBox().m_oWidth.Zero())
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel));
if (!m_pContainer->GetViewBox().m_oWidth.Empty() && !m_pContainer->GetViewBox().m_oWidth.Zero())
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, m_pContainer->GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel));
else
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
}
@ -62,14 +62,14 @@ bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight
dWidth = oWindow.m_oWidth.ToDouble(NSCSS::Pixel);
}
else
dWidth = m_oContainer.GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel);
dWidth = m_pContainer->GetViewBox().m_oWidth.ToDouble(NSCSS::Pixel);
if (!oWindow.m_oHeight.Empty() && !oWindow.m_oHeight.Zero())
{
if (NSCSS::Percent == oWindow.m_oHeight.GetUnitMeasure())
{
if (!m_oContainer.GetViewBox().m_oHeight.Empty() && !m_oContainer.GetViewBox().m_oHeight.Zero())
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel));
if (!m_pContainer->GetViewBox().m_oHeight.Empty() && !m_pContainer->GetViewBox().m_oHeight.Zero())
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, m_pContainer->GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel));
else
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel, SVG_FILE_WIDTH);
}
@ -77,7 +77,7 @@ bool CSvgFile::GetBounds(double &dX, double &dY, double &dWidth, double &dHeight
dHeight = oWindow.m_oHeight.ToDouble(NSCSS::Pixel);
}
else
dHeight = m_oContainer.GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel);
dHeight = m_pContainer->GetViewBox().m_oHeight.ToDouble(NSCSS::Pixel);
if (DBL_EPSILON > dWidth)
dWidth = SVG_FILE_WIDTH;
@ -160,11 +160,11 @@ void CSvgFile::AddFontFace(const SVG::TFontArguments& oArguments, const std::wst
bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, double dHeight)
{
if (NULL == pRenderer || m_oContainer.Empty())
if (NULL == pRenderer || NULL == m_pContainer || m_pContainer->Empty())
return false;
SVG::TRect oWindow = m_oContainer.GetWindow();
SVG::TRect oViewBox = m_oContainer.GetViewBox();
SVG::TRect oWindow = m_pContainer->GetWindow();
SVG::TRect oViewBox = m_pContainer->GetViewBox();
if (oWindow.m_oWidth.Empty() || oWindow.m_oWidth.Zero())
{
@ -222,7 +222,7 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d
pRenderer->SetTransform(dM11 * dMinScale, 0, 0, dM22 * dMinScale, dSkipX, dSkipY);
bool bResult = m_oContainer.Draw(pRenderer, this);
bool bResult = m_pContainer->Draw(pRenderer, this);
pRenderer->SetTransform(oldTransform[0], oldTransform[1], oldTransform[2], oldTransform[3], oldTransform[4], oldTransform[5]);
@ -231,7 +231,7 @@ bool CSvgFile::Draw(IRenderer *pRenderer, double dX, double dY, double dWidth, d
void CSvgFile::Clear()
{
m_oContainer.Clear();
RELEASEOBJECT(m_pContainer);
m_oSvgCalculator.Clear();
for (MarkedMap::reference oIter : m_mMarkedObjects)

View File

@ -44,7 +44,7 @@ class CSvgFile
void Clear();
SVG::CSvgParser m_oParser;
SVG::CGraphicsContainer m_oContainer;
SVG::CGraphicsContainer *m_pContainer;
SVG::CSvgCalculator m_oSvgCalculator;
typedef std::map<std::wstring, SVG::CObject*> MarkedMap;

View File

@ -24,6 +24,8 @@
#include "SvgObjects/CMask.h"
#include "SvgObjects/CUse.h"
#include "../../../../Common/3dParty/html/css/src/StaticFunctions.h"
namespace SVG
{
CSvgParser::CSvgParser()
@ -74,7 +76,7 @@ namespace SVG
return std::string(itEncodingValueBegin, itEncodingValueEnd);
}
bool CSvgParser::LoadFromFile(const std::wstring &wsFile, CGraphicsContainer* pContainer, CSvgFile* pFile) const
bool CSvgParser::LoadFromFile(const std::wstring &wsFile, CGraphicsContainer*& pContainer, CSvgFile* pFile) const
{
if (wsFile.empty() || NULL == pFile)
return false;
@ -109,7 +111,7 @@ namespace SVG
return bResult;
}
bool CSvgParser::LoadFromString(const std::wstring &wsContent, CGraphicsContainer* pContainer, CSvgFile* pFile) const
bool CSvgParser::LoadFromString(const std::wstring &wsContent, CGraphicsContainer*& pContainer, CSvgFile* pFile) const
{
if (wsContent.empty() || NULL == pFile)
return false;
@ -119,34 +121,22 @@ namespace SVG
return false;
ScanStyles(oReader, pFile);
oReader.MoveToStart();
if (NULL != pContainer)
pContainer->SetData(oReader);
RELEASEOBJECT(pContainer);
const CSvgCalculator *pSvgCalculator = pFile->GetSvgCalculator();
pContainer = CRenderedObject::Create<CGraphicsContainer>(oReader, pFile->GetSvgCalculator());
if (NULL != pSvgCalculator)
pSvgCalculator->SetData(pContainer);
return ReadChildrens(oElement, pContainer, pFile, pContainer);
}
bool CSvgParser::LoadFromXmlNode(XmlUtils::CXmlNode &oElement, CGraphicsContainer* pContainer, CSvgFile* pFile) const
{
if (NULL == pFile || !oElement.IsValid())
if (NULL == pContainer)
return false;
const CSvgCalculator *pSvgCalculator = pFile->GetSvgCalculator();
if (NULL != pSvgCalculator)
pSvgCalculator->SetData(pContainer);
return ReadChildrens(oElement, pContainer, pFile, pContainer);
return ReadChildrens(oReader, pContainer, pFile, pContainer);
}
bool CSvgParser::ScanStyles(CSvgReader& oReader, CSvgFile *pFile) const
{
if (oReader.IsEmptyNode() || NULL == pFile || !oReader.MoveToStart())
if (oReader.IsEmptyNode() || NULL == pFile)
return false;
const std::string sElementName = oReader.GetName();
@ -162,13 +152,13 @@ namespace SVG
if ("svg" == sElementName || "g" == sElementName || "defs" == sElementName)
{
WHILE_READ_NEXT_NODE(oReader)
{
if (ScanStyles(oReader, pFile))
bScanResult = true;
}
END_WHILE
}
oReader.MoveToStart();
return bScanResult;
}
@ -227,6 +217,21 @@ namespace SVG
}
}
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
{
@ -239,7 +244,7 @@ namespace SVG
if ("svg" == sElementName || "g" == sElementName || "a" == sElementName)
{
pObject = new CGraphicsContainer(oReader, pParent);
pObject = CRenderedObject::Create<CGraphicsContainer>(oReader, pFile->GetSvgCalculator(), pParent);
if (!ReadChildrens(oReader, (CGraphicsContainer*)pObject, pFile, (CGraphicsContainer*)pObject))
{
RELEASEOBJECT(pObject);
@ -247,41 +252,44 @@ namespace SVG
}
}
else if ("line" == sElementName)
pObject = new CLine(oReader, pParent);
pObject = CRenderedObject::Create<CLine>(oReader, pFile->GetSvgCalculator(), pParent);
else if ("rect" == sElementName)
pObject = new CRect(oReader, pParent);
pObject = CRenderedObject::Create<CRect>(oReader, pFile->GetSvgCalculator(), pParent);
else if ("circle" == sElementName)
pObject = new CCircle(oReader, pParent);
pObject = CRenderedObject::Create<CCircle>(oReader, pFile->GetSvgCalculator(), pParent);
else if ("ellipse" == sElementName)
pObject = new CEllipse(oReader, pParent);
pObject = CRenderedObject::Create<CEllipse>(oReader, pFile->GetSvgCalculator(), pParent);
else if ("path" == sElementName)
pObject = new CPath(oReader, pParent);
pObject = CRenderedObject::Create<CPath>(oReader, pFile->GetSvgCalculator(), pParent);
else if ("polyline" == sElementName)
pObject = new CPolyline(oReader, pParent);
pObject = CRenderedObject::Create<CPolyline>(oReader, pFile->GetSvgCalculator(), pParent);
else if ("polygon" == sElementName)
pObject = new CPolygon(oReader, pParent);
pObject = CRenderedObject::Create<CPolygon>(oReader, pFile->GetSvgCalculator(), pParent);
else if ("image" == sElementName)
pObject = new CImage(oReader, pParent);
pObject = CRenderedObject::Create<CImage>(oReader, pFile->GetSvgCalculator(), pParent);
else if ("use" == sElementName)
pObject = new CUse(oReader, pParent);
pObject = CRenderedObject::Create<CUse>(oReader, pFile->GetSvgCalculator(), pParent);
else if ("text" == sElementName)
{
pObject = CText::Create(oReader, pParent, m_pFontManager);
ReadChildrens(oReader, (CText*)pObject, pFile, (CText*)pObject);
pObject = ReadTextObject<CText>(oReader, pFile->GetSvgCalculator(), pParent, m_pFontManager);
// pObject = CText::Create(oReader, pParent, m_pFontManager);
// ReadChildrens(oReader, (CText*)pObject, pFile, (CText*)pObject);
}
else if ("tspan" == sElementName)
{
pObject = CTSpan::Create(oReader, pParent, m_pFontManager);
ReadChildrens(oReader, (CTSpan*)pObject, pFile, (CTSpan*)pObject);
pObject = ReadTextObject<CTSpan>(oReader, pFile->GetSvgCalculator(), pParent, m_pFontManager);
// pObject = CTSpan::Create(oReader, pParent, m_pFontManager);
// ReadChildrens(oReader, (CTSpan*)pObject, pFile, (CTSpan*)pObject);
}
else if ("textPath" == sElementName)
{
pObject = CTextPath::Create(oReader, pParent, m_pFontManager, pFile);
ReadChildrens(oReader, (CTextPath*)pObject, pFile);
pObject = ReadTextObject<CTextPath>(oReader, pFile->GetSvgCalculator(), pParent, m_pFontManager);
// pObject = CTextPath::Create(oReader, pParent, m_pFontManager);
// ReadChildrens(oReader, (CTextPath*)pObject, pFile);
}
else if ("switch" == sElementName)
{
pObject = new CSwitch(oReader, pParent);
pObject = CRenderedObject::Create<CSwitch>(oReader, pFile->GetSvgCalculator(), pParent);
ReadChildrens(oReader, (CSwitch*)pObject, pFile);
}
//defs
@ -333,7 +341,7 @@ namespace SVG
}
else if ("symbo" == sElementName)
{
pObject = new CSymbol(oReader);
pObject = CRenderedObject::Create<CSymbol>(oReader, pFile->GetSvgCalculator());
if (ReadChildrens(oReader, (CSymbol*)pObject, pFile) && MarkObject(pObject, pFile))
return true;
else
@ -349,7 +357,8 @@ namespace SVG
if ((MarkObject(pObject, pFile) && (AppliedObject == pObject->GetType() || NULL == pContainer)) ||
(RendererObject == pObject->GetType() && AddObject((ObjectType*)pObject, pContainer)))
{
UpdateStyles(pObject, pFile);
if (RendererObject != pObject->GetType())
UpdateStyles(pObject, pFile);
return true;
}
delete pObject;

View File

@ -19,8 +19,8 @@ namespace SVG
void SetFontManager(NSFonts::IFontManager* pFontManager);
bool LoadFromFile(const std::wstring& wsFile, CGraphicsContainer* pContainer, CSvgFile* pFile) const;
bool LoadFromString(const std::wstring& wsContent, CGraphicsContainer* pContainer, CSvgFile* pFile) const;
bool LoadFromFile(const std::wstring& wsFile, CGraphicsContainer*& pContainer, CSvgFile* pFile) const;
bool LoadFromString(const std::wstring& wsContent, CGraphicsContainer*& pContainer, CSvgFile* pFile) const;
template <class ObjectType>
bool ReadObject(CSvgReader& oReader, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;

View File

@ -4,20 +4,26 @@
namespace SVG
{
RENDERER_CHILDREN_CPP(Circle)
CCircle::CCircle(CSvgReader& oReader, CRenderedObject* pParent)
: CRenderedObject(oReader, pParent)
{
START_READ_ATTRIBUTES(oReader)
{
IF_ATTRIBUTE("cx")
SET_VALUE(m_oCx);
ELSE_IF_ATTRIBUTE("cy")
SET_VALUE(m_oCy);
ELSE_IF_ATTRIBUTE("r")
SET_VALUE(m_oR);
}
SetAttribute(sAttributeName, oReader);
END_READ_ATTRIBUTES(oReader)
}
void CCircle::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("cx" == sName)
m_oCx.SetValue(oReader.GetDouble());
else if ("cy" == sName)
m_oCy.SetValue(oReader.GetDouble());
else if ("r" == sName)
m_oR.SetValue(oReader.GetDouble());
else
CRenderedObject::SetAttribute(sName, oReader);
}
void CCircle::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
CRenderedObject::SetData(mAttributes, ushLevel, bHardMode);

View File

@ -7,8 +7,10 @@ namespace SVG
{
class CCircle : public CRenderedObject
{
public:
friend class CRenderedObject;
CCircle(CSvgReader& oReader, CRenderedObject* pParent = NULL);
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;

View File

@ -4,9 +4,17 @@ namespace SVG
{
CClipPath::CClipPath(CSvgReader& oReader)
: CAppliedObject(oReader), m_enUnits(ClipU_ObjectBoundingBox)
{}
void CClipPath::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if (L"userSpaceOnUse" == oReader.GetAttribute("gradientUnits"))
m_enUnits = ClipU_UserSpaceOnUse;
if ("gradientUnits" == sName)
{
if ("userSpaceOnUse" == oReader.GetTextA())
m_enUnits = ClipU_UserSpaceOnUse;
}
else
CAppliedObject::SetAttribute(sName, oReader);
}
void CClipPath::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)

View File

@ -16,6 +16,8 @@ namespace SVG
public:
CClipPath(CSvgReader& oReader);
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;
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;

View File

@ -5,9 +5,9 @@
namespace SVG
{
CGraphicsContainer::CGraphicsContainer(const std::wstring &wsName)
: CRenderedObject(NSCSS::CNode(wsName, L"", L""))
{}
// CGraphicsContainer::CGraphicsContainer(const std::wstring &wsName)
// : CRenderedObject(NSCSS::CNode(wsName, L"", L""))
// {}
CGraphicsContainer::~CGraphicsContainer()
{
@ -15,42 +15,36 @@ namespace SVG
pObject->m_pParent = NULL;
}
void CGraphicsContainer::SetData(CSvgReader& oReader)
void CGraphicsContainer::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
SetNodeData(oReader);
START_READ_ATTRIBUTES(oReader)
if ("x" == sName)
m_oWindow.m_oX.SetValue(oReader.GetDouble());
else if ("y" == sName)
m_oWindow.m_oY.SetValue(oReader.GetDouble());
else if ("width" == sName)
m_oWindow.m_oWidth.SetValue(oReader.GetDouble());
else if ("height" == sName)
m_oWindow.m_oHeight.SetValue(oReader.GetDouble());
else if ("viewBox" == sName)
{
if ("x" == sAttributeName)
m_oWindow.m_oX.SetValue(oReader.GetText());
else if ("y" == sAttributeName)
m_oWindow.m_oY.SetValue(oReader.GetText());
else if ("width" == sAttributeName)
m_oWindow.m_oWidth.SetValue(oReader.GetText(), 0, true);
else if ("height" == sAttributeName)
m_oWindow.m_oHeight.SetValue(oReader.GetText(), 0, true);
else if ("viewBox" == sAttributeName)
{
m_oViewBox = m_oWindow;
m_oViewBox = m_oWindow;
std::vector<double> arValues = StrUtils::ReadDoubleValues(oReader.GetText());
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];
}
std::vector<double> arValues = StrUtils::ReadDoubleValues(oReader.GetText());
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];
}
}
END_READ_ATTRIBUTES(oReader)
else
CRenderedObject::SetAttribute(sName, oReader);
}
CGraphicsContainer::CGraphicsContainer(CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent)
{
SetData(oReader);
}
{}
CGraphicsContainer::CGraphicsContainer(double dWidth, double dHeight, CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent), m_oWindow{0, 0, dWidth, dHeight}

View File

@ -79,14 +79,15 @@ namespace SVG
class CGraphicsContainer : public CContainer<CRenderedObject>, public CRenderedObject
{
public:
CGraphicsContainer(const std::wstring& wsName = L"GraphicsContainer");
friend class CRenderedObject;
// CGraphicsContainer(const std::wstring& wsName = L"GraphicsContainer");
CGraphicsContainer(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CGraphicsContainer(double dWidth, double dHeight, CSvgReader& oReader, CRenderedObject* pParent = NULL);
virtual ~CGraphicsContainer();
void SetData(CSvgReader& oReader);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;

View File

@ -4,21 +4,9 @@
namespace SVG
{
RENDERER_CHILDREN_CPP(Ellipse)
{
START_READ_ATTRIBUTES(oReader)
{
IF_ATTRIBUTE("cx")
SET_VALUE(m_oCx);
ELSE_IF_ATTRIBUTE("cy")
SET_VALUE(m_oCy);
ELSE_IF_ATTRIBUTE("rx")
SET_VALUE(m_oRx);
ELSE_IF_ATTRIBUTE("ry")
SET_VALUE(m_oRy);
}
END_READ_ATTRIBUTES(oReader)
}
CEllipse::CEllipse(CSvgReader& oReader, CRenderedObject* pParent)
: CRenderedObject(oReader, pParent)
{}
void CEllipse::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
@ -28,6 +16,20 @@ namespace SVG
SetFill(mAttributes, ushLevel, bHardMode);
}
void CEllipse::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("cx" == sName)
m_oCx.SetValue(oReader.GetDouble());
else if ("cy" == sName)
m_oCy.SetValue(oReader.GetDouble());
else if ("rx" == sName)
m_oRx.SetValue(oReader.GetDouble());
else if ("ry" == sName)
m_oRy.SetValue(oReader.GetDouble());
else
CRenderedObject::SetAttribute(sName, oReader);
}
bool CEllipse::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{
Aggplus::CMatrix oOldTransform;

View File

@ -1,14 +1,19 @@
#ifndef CELLIPSE_H
#define CELLIPSE_H
#include "CObjectBase.h"
namespace SVG
{
BEGIN_RENDERER_CHILDREN_H(Ellipse)
class CEllipse : public CRenderedObject
{
friend class CRenderedObject;
CEllipse(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
private:
void ApplyStyle(IRenderer* pRenderer, const TSvgStyles* pStyles, const CSvgFile *pFile, int& nTypePath, const CRenderedObject* pContexObject = NULL) const override;
@ -19,7 +24,7 @@ namespace SVG
SvgDigit m_oCy;
SvgDigit m_oRx;
SvgDigit m_oRy;
END_RENDERER_CHILDREN_H
};
}
#endif // CELLIPSE_H

View File

@ -31,19 +31,6 @@ namespace SVG
CFont::CFont(CSvgReader& oReader)
: CAppliedObject(oReader), m_pMissingGlyph(NULL)
{
START_READ_ATTRIBUTES(oReader)
{
if ("font-variant" == sAttributeName)
m_oArguments.m_wsFontVariant = oReader.GetText();
else if ("font-style" == sAttributeName)
m_oArguments.m_wsFontStyle = oReader.GetText();
else if ("font-weight" == sAttributeName)
m_oArguments.m_wsFontWidght = oReader.GetText();
else if ("horiz-adv-x" == sAttributeName)
m_oHorizAdvX.SetValue(oReader.GetText());
}
END_READ_ATTRIBUTES(oReader)
ParseGlyphs(oReader);
}
@ -55,6 +42,20 @@ namespace SVG
RELEASEOBJECT(m_pMissingGlyph);
}
void CFont::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("font-variant" == sName)
m_oArguments.m_wsFontVariant = oReader.GetText();
else if ("font-style" == sName)
m_oArguments.m_wsFontStyle = oReader.GetText();
else if ("font-weight" == sName)
m_oArguments.m_wsFontWidght = oReader.GetText();
else if ("horiz-adv-x" == sName)
m_oHorizAdvX.SetValue(oReader.GetDouble());
else
CAppliedObject::SetAttribute(sName, oReader);
}
void CFont::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
}

View File

@ -40,6 +40,8 @@ namespace SVG
CFont(CSvgReader& oReader);
~CFont();
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;
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;

View File

@ -35,20 +35,27 @@ namespace SVG
}
CGradient::CGradient(CSvgReader& oReader)
: CAppliedObject(oReader), m_enGradientUnits(GradU_ObjectBoundingBox)
: CAppliedObject(oReader), m_enGradientUnits(GradU_ObjectBoundingBox)
{}
void CGradient::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
START_READ_ATTRIBUTES(oReader)
if ("href" == sName || "xlink:href" == sName)
m_wsXlinkHref = oReader.GetText();
else if ("gradientTransform" == sName)
m_oTransform.SetMatrix(oReader.GetText(), 0, true);
else if ("gradientUnits" == sName)
{
if ("href" == sAttributeName || "xlink:href" == sAttributeName)
m_wsXlinkHref = oReader.GetText();
else if ("gradientTransform" == sAttributeName)
m_oTransform.SetMatrix(oReader.GetText(), 0, true);
else if ("gradientUnits" == sAttributeName && L"userSpaceOnUse" == oReader.GetText())
if (L"userSpaceOnUse" == oReader.GetText())
m_enGradientUnits = GradU_UserSpaceOnUse;
}
END_READ_ATTRIBUTES(oReader)
else
CAppliedObject::SetAttribute(sName, oReader);
}
void CGradient::SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode)
{}
bool CGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
{
if (NULL == pRenderer || m_arObjects.empty())
@ -118,19 +125,20 @@ namespace SVG
CLinearGradient::CLinearGradient(CSvgReader& oReader)
: CGradient(oReader)
{}
void CLinearGradient::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
START_READ_ATTRIBUTES(oReader)
{
if ("x1" == sAttributeName)
m_oX1.SetValue(oReader.GetText());
else if ("y1" == sAttributeName)
m_oY1.SetValue(oReader.GetText());
else if ("x2" == sAttributeName)
m_oX2.SetValue(oReader.GetText());
else if ("y2" == sAttributeName)
m_oY2.SetValue(oReader.GetText());
}
END_READ_ATTRIBUTES(oReader)
if ("x1" == sName)
m_oX1.SetValue(oReader.GetDouble());
else if ("y1" == sName)
m_oY1.SetValue(oReader.GetDouble());
else if ("x2" == sName)
m_oX2.SetValue(oReader.GetDouble());
else if ("y2" == sName)
m_oY2.SetValue(oReader.GetDouble());
else
CGradient::SetAttribute(sName, oReader);
}
bool CLinearGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
@ -178,17 +186,18 @@ namespace SVG
CRadialGradient::CRadialGradient(CSvgReader& oReader)
: CGradient(oReader)
{}
void CRadialGradient::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
START_READ_ATTRIBUTES(oReader)
{
if ("cx" == sAttributeName)
m_oCx.SetValue(oReader.GetText());
else if ("cy" == sAttributeName)
m_oCy.SetValue(oReader.GetText());
else if ("r" == sAttributeName)
m_oR.SetValue(oReader.GetText());
}
END_READ_ATTRIBUTES(oReader)
if ("cx" == sName)
m_oCx.SetValue(oReader.GetDouble());
else if ("cy" == sName)
m_oCy.SetValue(oReader.GetDouble());
else if ("r" == sName)
m_oR.SetValue(oReader.GetDouble());
else
CGradient::SetAttribute(sName, oReader);
}
bool CRadialGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)

View File

@ -37,16 +37,16 @@ namespace SVG
class CGradient : public CContainer<CStopElement>, public CAppliedObject
{
friend class CLinearGradient;
friend class CRadialGradient;
public:
CGradient(CSvgReader& oReader);
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;
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
void ApplyTransform(IRenderer *pRenderer, const TBounds& oBounds, double& dAngle) const;
private:
protected:
CGradient* GetRefGradient(const CSvgFile *pFile) const;
bool ApplyRefGradient(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) const;
@ -61,6 +61,8 @@ namespace SVG
public:
CLinearGradient(CSvgReader& oReader);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
private:
SvgDigit m_oX1;
@ -74,6 +76,8 @@ namespace SVG
public:
CRadialGradient(CSvgReader& oReader);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
private:
SvgDigit m_oCx;

View File

@ -8,22 +8,24 @@
namespace SVG
{
RENDERER_CHILDREN_CPP(Image)
CImage::CImage(CSvgReader& oReader, CRenderedObject* pParent)
: CRenderedObject(oReader, pParent)
{}
void CImage::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
START_READ_ATTRIBUTES(oReader)
{
IF_ATTRIBUTE("x")
SET_VALUE(m_oRect.m_oX);
ELSE_IF_ATTRIBUTE("y")
SET_VALUE(m_oRect.m_oY);
ELSE_IF_ATTRIBUTE("width")
SET_VALUE(m_oRect.m_oWidth);
ELSE_IF_ATTRIBUTE("height")
SET_VALUE(m_oRect.m_oHeight);
ELSE_IF_ATTRIBUTE2("href", "xlink:href")
SET_VALUE_STRING(m_wsHref);// TODO:: В дальнейшем возможно стоит реализовать отдельный класс CHref для всех типов ссылок
}
END_READ_ATTRIBUTES(oReader)
if ("x" == sName)
m_oRect.m_oX.SetValue(oReader.GetDouble());
else if ("y" == sName)
m_oRect.m_oY.SetValue(oReader.GetDouble());
else if ("width" == sName)
m_oRect.m_oWidth.SetValue(oReader.GetDouble());
else if ("height" == sName)
m_oRect.m_oHeight.SetValue(oReader.GetDouble());
else if ("href" == sName || "xlink:href" == sName)
m_wsHref = oReader.GetText(); // TODO:: В дальнейшем возможно стоит реализовать отдельный класс CHref для всех типов ссылок
else
CRenderedObject::SetAttribute(sName, oReader);
}
bool CImage::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const

View File

@ -5,14 +5,20 @@
namespace SVG
{
BEGIN_RENDERER_CHILDREN_H(Image)
class CImage : public CRenderedObject
{
friend class CRenderedObject;
CImage(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
private:
TBounds GetBounds() const override;
TRect m_oRect;
std::wstring m_wsHref;
END_RENDERER_CHILDREN_H
};
}
#endif // CIMAGE_H

View File

@ -2,26 +2,27 @@
namespace SVG
{
CLine::CLine(CSvgReader& oReader, CRenderedObject* pParent)
: CPath(oReader, pParent, false)
{
CLine::CLine(CSvgReader& oReader, CRenderedObject* pParent)
: CPath(oReader, pParent)
{}
void CLine::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
SvgDigit oX1;
SvgDigit oY1;
SvgDigit oX2;
SvgDigit oY2;
START_READ_ATTRIBUTES(oReader)
{
if ("x1" == sAttributeName)
oX1.SetValue(oReader.GetText());
else if ("y1" == sAttributeName)
oY1.SetValue(oReader.GetText());
else if ("x2" == sAttributeName)
oX2.SetValue(oReader.GetText());
else if ("y2" == sAttributeName)
oY2.SetValue(oReader.GetText());
}
END_READ_ATTRIBUTES(oReader)
if ("x1" == sName)
oX1.SetValue(oReader.GetText());
else if ("y1" == sName)
oY1.SetValue(oReader.GetText());
else if ("x2" == sName)
oX2.SetValue(oReader.GetText());
else if ("y2" == sName)
oY2.SetValue(oReader.GetText());
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)}));

View File

@ -7,8 +7,10 @@ namespace SVG
{
class CLine : public CPath
{
public:
friend class CRenderedObject;
CLine(CSvgReader& oReader, CRenderedObject* pParent = NULL);
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;
private:

View File

@ -1,55 +1,13 @@
#include "CMarker.h"
#include "../../../graphics/pro/Graphics.h"
#include "../SvgUtils.h"
namespace SVG
{
CMarker::CMarker(XmlUtils::CXmlNode &oNode)
: CObject(oNode), m_dAngle(0.), m_oBounds{0., 0., 0., 0.}
{
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"));
m_oViewBox = m_oWindow;
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];
}
}
const std::wstring& wsUnits = oNode.GetAttribute(L"markerUnits");
if (L"userSpaceOnUse" == wsUnits)
m_enUnits = EMarkerUnits::UserSpaceOnUse;
else
m_enUnits = EMarkerUnits::StrokeWidth;
const std::wstring& wsOrient = oNode.GetAttribute(L"orient");
if (L"auto" == wsOrient)
m_enOrient = EMarkerOrient::Auto;
else if (L"auto-start-reverse" == wsOrient)
m_enOrient = EMarkerOrient::Auto_start_reverse;
else
{
m_enOrient = EMarkerOrient::Angle;
if (!StrUtils::ReadAngle(wsOrient, m_dAngle))
StrUtils::ReadDoubleValue(wsOrient, m_dAngle);
}
}
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()
{
@ -60,6 +18,45 @@ namespace SVG
return AppliedObject;
}
void CMarker::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("refX" == sName)
m_oWindow.m_oX.SetValue(oReader.GetDouble());
else if ("refY" == sName)
m_oWindow.m_oY.SetValue(oReader.GetDouble());
else if ("markerWidth" == sName)
m_oWindow.m_oWidth.SetValue(oReader.GetDouble());
else if ("markerHeight" == sName)
m_oWindow.m_oHeight.SetValue(oReader.GetDouble());
else if ("viewBox" == sName)
{
std::vector<double> arValues = StrUtils::ReadDoubleValues(oReader.GetText());
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];
}
}
else if ("markerUnits" == sName)
{
if (L"userSpaceOnUse" == oReader.GetText())
m_enUnits = EMarkerUnits::UserSpaceOnUse;
}
else if ("orient" == sName)
{
const std::wstring& wsOrient{oReader.GetText()};
if (L"auto" == wsOrient)
m_enOrient = EMarkerOrient::Auto;
else if (L"auto-start-reverse" == wsOrient)
m_enOrient = EMarkerOrient::Auto_start_reverse;
else if (!StrUtils::ReadAngle(wsOrient, m_dAngle))
StrUtils::ReadDoubleValue(wsOrient, m_dAngle);
}
}
void CMarker::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{}

View File

@ -46,11 +46,13 @@ namespace SVG
class CMarker : public CObject, public CContainer<CRenderedObject>
{
public:
CMarker(XmlUtils::CXmlNode& oNode);
CMarker(CSvgReader& oReader);
virtual ~CMarker();
ObjectType GetType() const override;
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;
void Draw(IRenderer* pRenderer, const CSvgFile *pFile, const TMarkerExternData& oExternalData, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const;

View File

@ -2,8 +2,8 @@
namespace SVG
{
CMask::CMask(XmlUtils::CXmlNode &oNode)
: CClipPath(oNode)
CMask::CMask(CSvgReader& oReader)
: CClipPath(oReader)
{}
bool CMask::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)

View File

@ -8,7 +8,7 @@ namespace SVG
class CMask : public CClipPath
{
public:
CMask(XmlUtils::CXmlNode& oNode);
CMask(CSvgReader& oReader);
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
};

View File

@ -1,6 +1,8 @@
#include "CObjectBase.h"
#include "../CSvgFile.h"
#include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h"
namespace SVG
{
TSvgStyles &TSvgStyles::operator+=(const TSvgStyles &oSvgStyles)
@ -33,12 +35,31 @@ namespace SVG
CObject::CObject(CSvgReader& oReader)
{
SetNodeData(oReader);
m_oXmlNode.m_wsName = oReader.GetNameW();
}
CObject::CObject(const CObject& oObject)
: m_oXmlNode(oObject.m_oXmlNode), m_oTransformation(oObject.m_oTransformation)
{}
CObject::~CObject()
{}
void CObject::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("class" == sName)
{
m_oXmlNode.m_wsClass = oReader.GetText();
std::transform(m_oXmlNode.m_wsClass.begin(), m_oXmlNode.m_wsClass.end(), m_oXmlNode.m_wsClass.begin(), std::towlower);
}
else if ("id" == sName)
m_oXmlNode.m_wsId = oReader.GetText();
else if ("style" == sName)
m_oXmlNode.m_wsStyle = oReader.GetText();
else
m_oXmlNode.m_mAttributes.insert({oReader.GetNameW(), oReader.GetText()});
}
void CObject::SetData(const std::wstring wsStyles, unsigned short ushLevel, bool bHardMode)
{
if (wsStyles.empty())
@ -153,27 +174,6 @@ namespace SVG
return pDefObject->Apply(pRenderer, pFile, oBounds);
}
void CObject::SetNodeData(CSvgReader& oReader)
{
m_oXmlNode.m_wsName = oReader.GetNameW();
START_READ_ATTRIBUTES(oReader)
{
if ("class" == sAttributeName)
{
m_oXmlNode.m_wsClass = oReader.GetText();
std::transform(m_oXmlNode.m_wsClass.begin(), m_oXmlNode.m_wsClass.end(), m_oXmlNode.m_wsClass.begin(), std::towlower);
}
else if ("id" == sAttributeName)
m_oXmlNode.m_wsId = oReader.GetText();
else if ("style" == sAttributeName)
m_oXmlNode.m_wsStyle = oReader.GetText();
else
m_oXmlNode.m_mAttributes.insert({oReader.GetNameW(), oReader.GetText()});
}
END_READ_ATTRIBUTES(oReader)
}
std::wstring CObject::GetId() const
{
return m_oXmlNode.m_wsId;
@ -187,19 +187,20 @@ namespace SVG
CRenderedObject::CRenderedObject(const NSCSS::CNode &oData, CRenderedObject *pParent)
: CObject(oData), m_pParent(pParent)
{
SetDefaultStyles();
SetDefaultData();
}
CRenderedObject::CRenderedObject(CSvgReader& oReader, CRenderedObject *pParent)
: CObject(oReader), m_pParent(pParent)
{
START_READ_ATTRIBUTES(oReader)
SetAttribute(sAttributeName, oReader.GetText());
END_READ_ATTRIBUTES(oReader)
SetDefaultStyles();
SetDefaultData();
}
CRenderedObject::CRenderedObject(const CRenderedObject& oRenderedObject)
: CObject(oRenderedObject), m_oStyles(oRenderedObject.m_oStyles),
m_pParent(oRenderedObject.m_pParent)
{}
CRenderedObject::~CRenderedObject()
{}
@ -208,6 +209,11 @@ namespace SVG
return RendererObject;
}
void CRenderedObject::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
CObject::SetAttribute(sName, oReader);
}
void CRenderedObject::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
SetTransform(mAttributes, ushLevel, bHardMode);
@ -217,6 +223,11 @@ 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)
@ -227,20 +238,6 @@ namespace SVG
return arObjects;
}
void CRenderedObject::SetDefaultStyles()
{
m_oStyles.m_oStroke.m_oLineCap.SetMapping({std::make_pair(L"butt", Aggplus::LineCapFlat), std::make_pair(L"round", Aggplus::LineCapRound), std::make_pair(L"square", Aggplus::LineCapSquare)});
m_oStyles.m_oStroke.m_oLineCap = Aggplus::LineCapFlat;
m_oStyles.m_oStroke.m_oLineJoin.SetMapping({std::make_pair(L"arcs", Aggplus::LineJoinMiter), std::make_pair(L"bevel", Aggplus::LineJoinBevel), std::make_pair(L"miter", Aggplus::LineJoinMiter), std::make_pair(L"miter-clip", Aggplus::LineJoinMiterClipped), std::make_pair(L"round", Aggplus::LineJoinRound)});
m_oStyles.m_oStroke.m_oLineCap = Aggplus::LineJoinMiter;
m_oStyles.m_oStroke.m_oMiterlimit = 4.;
m_oTransformation.m_oOpacity = 1.;
m_oTransformation.m_bDraw = true;
}
void CRenderedObject::SetStroke(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
if (mAttributes.end() != mAttributes.find(L"stroke"))
@ -445,6 +442,20 @@ namespace SVG
return false;
}
void CRenderedObject::SetDefaultData()
{
m_oStyles.m_oStroke.m_oLineCap.SetMapping({std::make_pair(L"butt", Aggplus::LineCapFlat), std::make_pair(L"round", Aggplus::LineCapRound), std::make_pair(L"square", Aggplus::LineCapSquare)});
m_oStyles.m_oStroke.m_oLineCap = Aggplus::LineCapFlat;
m_oStyles.m_oStroke.m_oLineJoin.SetMapping({std::make_pair(L"arcs", Aggplus::LineJoinMiter), std::make_pair(L"bevel", Aggplus::LineJoinBevel), std::make_pair(L"miter", Aggplus::LineJoinMiter), std::make_pair(L"miter-clip", Aggplus::LineJoinMiterClipped), std::make_pair(L"round", Aggplus::LineJoinRound)});
m_oStyles.m_oStroke.m_oLineCap = Aggplus::LineJoinMiter;
m_oStyles.m_oStroke.m_oMiterlimit = 4.;
m_oTransformation.m_oOpacity = 1.;
m_oTransformation.m_bDraw = true;
}
CAppliedObject::CAppliedObject(CSvgReader& oReader)
: CObject(oReader)
{}
@ -456,4 +467,5 @@ namespace SVG
{
return AppliedObject;
}
}

View File

@ -2,12 +2,12 @@
#define COBJECTBASE_H
#include "../../../../../Common/3dParty/html/css/src/CNode.h"
#include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h"
#include "../../../../graphics/IRenderer.h"
#include "../../../../common/IGrObject.h"
#include "../SvgTypes.h"
#include "../SvgReader.h"
#include "CStyle.h"
class CSvgFile;
@ -37,17 +37,19 @@ namespace SVG
AppliedObject
};
//TODO:: хотелось бы передалать принцип чтения аргументов
class CObject : public IGrObject
{
public:
protected:
CObject(const NSCSS::CNode& oData);
CObject(CSvgReader& oReader);
CObject(const CObject& oObject);
public:
virtual ~CObject();
virtual ObjectType GetType() const = 0;
virtual void SetAttribute(const std::string& sName, CSvgReader& oReader);
void SetData(const std::wstring wsStyles, unsigned short ushLevel, bool bHardMode = false);
virtual void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) = 0;
@ -67,8 +69,6 @@ namespace SVG
bool ApplyDef(IRenderer* pRenderer, const CSvgFile *pFile, const std::wstring& wsUrl, const TBounds& oBounds) const;
void SetNodeData(CSvgReader& oReader);
friend class CRenderedObject;
friend class CAppliedObject;
@ -98,25 +98,33 @@ namespace SVG
CommandeModeMask
};
class CSvgCalculator;
class CRenderedObject : public CObject
{
public:
protected:
CRenderedObject(const NSCSS::CNode& oData, CRenderedObject* pParent = NULL);
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);
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;
std::vector<NSCSS::CNode> GetFullPath() const override;
private:
void SetDefaultStyles();
void SetStroke(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
void SetFill(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false);
@ -129,6 +137,8 @@ namespace SVG
bool ApplyFill(IRenderer* pRenderer, const SvgColor* pFill, const CSvgFile *pFile, bool bUseDefault = false, const CRenderedObject* pContextObject = NULL) const;
bool ApplyOpacity(IRenderer* pRenderer, const SvgDigit* pOpacity) const;
void SetDefaultData();
friend class CUse;
friend class CLine;
friend class CRect;
@ -149,22 +159,31 @@ namespace SVG
CRenderedObject *m_pParent;
};
#define BEGIN_RENDERER_CHILDREN_H(name)\
class C##name : public CRenderedObject\
{\
public:\
C##name(CSvgReader& oReader, CRenderedObject* pParent = NULL);
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)...);
#define END_RENDERER_CHILDREN_H };
if (NULL == pObject)
return NULL;
#define RENDERER_CHILDREN_CPP(name)\
C##name::C##name(CSvgReader& oReader, CRenderedObject* pParent)\
: CRenderedObject(oReader, pParent)
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
{
public:
protected:
CAppliedObject(CSvgReader& oReader);
public:
virtual ~CAppliedObject();
ObjectType GetType() const override;

View File

@ -445,12 +445,9 @@ namespace SVG
#define CURVESTEP 0.05
#define MINCURVESTEP 0.001
CPath::CPath(CSvgReader& oReader, CRenderedObject* pParent, bool bChechCommands)
CPath::CPath(CSvgReader& oReader, CRenderedObject* pParent)
: CRenderedObject(oReader, pParent), m_bEvenOddRule(false)
{
if (bChechCommands)
ReadFromString(oReader.GetAttribute("d"));
}
{}
CPath::~CPath()
{
@ -458,6 +455,14 @@ namespace SVG
delete pPathElement;
}
void CPath::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("d" == sName)
ReadFromString(oReader.GetText());
else
CRenderedObject::SetAttribute(sName, oReader);
}
void CPath::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
CRenderedObject::SetData(mAttributes, ushLevel, bHardMode);

View File

@ -105,10 +105,14 @@ namespace SVG
class CPath : public CRenderedObject
{
friend class CRenderedObject;
protected:
CPath(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CPath(CSvgReader& oReader, CRenderedObject* pParent = NULL, bool bChechCommands = true);
virtual ~CPath();
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;
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
@ -118,24 +122,23 @@ 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;
void SetMarker(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode);
TBounds GetBounds() const override;
const int FindIndexFirstNotEmpty(bool bReverseSearch = false) const;
void ReadFromString(const std::wstring& wsValue);
bool AddElement(IPathElement* pElement);
friend class CLine;
friend class CFont;
friend class CPolygon;
friend class CPolyline;
std::vector<IPathElement*> m_arElements;
TMarkers m_oMarkers;
bool m_bEvenOddRule;
friend class CFont;
protected:
bool AddElement(IPathElement* pElement);
void SetMarker(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode);
};
class CMovingPath

View File

@ -5,8 +5,9 @@
namespace SVG
{
CPattern::CPattern(XmlUtils::CXmlNode& oNode, NSFonts::IFontManager *pFontManager)
: CAppliedObject(oNode), m_oContainer(oNode), m_pFontManager(pFontManager), m_pImage(NULL), m_enPatternUnits(objectBoundingBox)
CPattern::CPattern(CSvgReader& oReader, NSFonts::IFontManager *pFontManager)
: CAppliedObject(oReader), m_oContainer(oReader), m_pFontManager(pFontManager),
m_pImage(NULL), m_enPatternUnits(objectBoundingBox)
{}
CPattern::~CPattern()

View File

@ -15,7 +15,7 @@ namespace SVG
class CPattern : public CAppliedObject
{
public:
CPattern(XmlUtils::CXmlNode& oNode, NSFonts::IFontManager *pFontManager = NULL);
CPattern(CSvgReader& oReader, NSFonts::IFontManager *pFontManager = NULL);
virtual ~CPattern();
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;

View File

@ -1,24 +1,38 @@
#include "CPolyline.h"
#include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h"
namespace SVG
{
CPolyline::CPolyline(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CPath(oNode, pParent, false)
CPolyline::CPolyline(CSvgReader& oReader, CRenderedObject* pParent)
: CPath(oReader, pParent)
{}
void CPolyline::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
std::vector<double> arValues = NSCSS::NS_STATIC_FUNCTIONS::ReadDoubleValues(oNode.GetAttribute(L"points"));
if ("points" == sName)
{
const std::vector<double> arValues = NSCSS::NS_STATIC_FUNCTIONS::ReadDoubleValues(oReader.GetText());
if (arValues.size() < 4)
return;
if (arValues.size() < 4)
return;
AddElement(new CMoveElement(Point{arValues[0], arValues[1]}));
AddElement(new CMoveElement(Point{arValues[0], arValues[1]}));
for (unsigned int unIndex = 2; unIndex < arValues.size(); unIndex += 2)
AddElement(new CLineElement(Point{arValues[unIndex + 0], arValues[unIndex + 1]}));
for (unsigned int unIndex = 2; unIndex < arValues.size(); unIndex += 2)
AddElement(new CLineElement(Point{arValues[unIndex + 0], arValues[unIndex + 1]}));
}
else
CRenderedObject::SetAttribute(sName, oReader);
}
CPolygon::CPolygon(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CPolyline(oNode, pParent)
CPolygon::CPolygon(CSvgReader& oReader, CRenderedObject* pParent)
: CPolyline(oReader, pParent)
{}
void CPolygon::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
CPolyline::SetAttribute(sName, oReader);
AddElement(new CCloseElement());
}
}

View File

@ -7,14 +7,19 @@ namespace SVG
{
class CPolyline : public CPath
{
friend class CRenderedObject;
protected:
CPolyline(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CPolyline(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
};
class CPolygon : public CPolyline
{
friend class CRenderedObject;
CPolygon(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CPolygon(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
};
}

View File

@ -1,20 +1,32 @@
#include "CRect.h"
#include "CStyle.h"
#include "CContainer.h"
#include "../SvgTypes.h"
namespace SVG
{
CRect::CRect(XmlUtils::CXmlNode& oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
{
m_oRect.m_oX .SetValue(oNode.GetAttribute(L"x"));
m_oRect.m_oY .SetValue(oNode.GetAttribute(L"y"));
m_oRect.m_oWidth .SetValue(oNode.GetAttribute(L"width"));
m_oRect.m_oHeight.SetValue(oNode.GetAttribute(L"height"));
CRect::CRect(CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent)
{}
m_oRx.SetValue(oNode.GetAttribute(L"rx"));
m_oRy.SetValue(oNode.GetAttribute(L"ry"));
CRect::~CRect()
{}
void CRect::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("x" == sName)
m_oRect.m_oX.SetValue(oReader.GetDouble());
else if ("y" == sName)
m_oRect.m_oY.SetValue(oReader.GetDouble());
else if ("width" == sName)
m_oRect.m_oWidth.SetValue(oReader.GetDouble());
else if ("height" == sName)
m_oRect.m_oHeight.SetValue(oReader.GetDouble());
else if ("rx" == sName)
m_oRx.SetValue(oReader.GetDouble());
else if ("ry" == sName)
m_oRy.SetValue(oReader.GetDouble());
else
CRenderedObject::SetAttribute(sName, oReader);
if (m_oRx.Empty() && !m_oRy.Empty())
m_oRx = m_oRy;
@ -22,9 +34,6 @@ namespace SVG
m_oRy = m_oRx;
}
CRect::~CRect()
{}
void CRect::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
CRenderedObject::SetData(mAttributes, ushLevel, bHardMode);

View File

@ -7,11 +7,13 @@ namespace SVG
{
class CRect : public CRenderedObject
{
friend class CRenderedObject;
CRect(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CRect(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
virtual ~CRect();
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;
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;

View File

@ -1,4 +1,5 @@
#include "CStyle.h"
#include "CObjectBase.h"
namespace SVG
{

View File

@ -3,12 +3,10 @@
#include <string>
#include "../../../../../Common/3dParty/html/css/src/CCssCalculator_Private.h"
#include "CObjectBase.h"
#include <numeric>
namespace SVG
{
class CObject;
class CSvgCalculator
{
NSCSS::CCssCalculator_Private *m_pInternal;

View File

@ -2,10 +2,9 @@
namespace SVG
{
CSwitch::CSwitch(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
{
}
CSwitch::CSwitch(CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent)
{}
bool CSwitch::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pStyles, const CRenderedObject* pContexObject) const
{

View File

@ -7,9 +7,9 @@ namespace SVG
{
class CSwitch : public CRenderedObject, public CContainer<CRenderedObject>
{
friend class CRenderedObject;
CSwitch(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CSwitch(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
TBounds GetBounds() const override;

View File

@ -2,8 +2,8 @@
namespace SVG
{
CSymbol::CSymbol(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager)
: CGraphicsContainer(oNode)
CSymbol::CSymbol(CSvgReader& oReader, CRenderedObject *pParent)
: CGraphicsContainer(oReader)
{}
bool CSymbol::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const

View File

@ -2,15 +2,14 @@
#define CSYMBOL_H
#include "CContainer.h"
#include "../../../graphics/pro/Fonts.h"
namespace SVG
{
class CSymbol : public CGraphicsContainer
{
friend class CRenderedObject;
CSymbol(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CSymbol(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager *pFontManager = NULL);
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
};
}

View File

@ -3,9 +3,11 @@
#include "../CSvgParser.h"
#include "../SvgUtils.h"
#include "../CSvgFile.h"
#include "CObjectBase.h"
#include "CContainer.h"
#include "CFont.h"
#include "CStyle.h"
#include "../../../../Common/3dParty/html/css/src/StaticFunctions.h"
#ifndef MININT8
#define MAXUINT8 ((unsigned char)~((unsigned char)0))
@ -24,79 +26,16 @@ namespace SVG
#define MIN_SCALE 0.05
#define MAX_SCALE 100
CTSpan::CTSpan(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager, bool bCheckText)
: CRenderedObject(oNode, pParent), m_pFontManager(pFontManager)
CTSpan::CTSpan(CSvgReader& oReader, CRenderedObject* pParent, NSFonts::IFontManager* pFontManager, const Point &oPosition)
: CRenderedObject(oReader, pParent), m_pFontManager(pFontManager)
{
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE,DEFAULT_TSPAN_FONT_SIZE);
m_oFont.UpdateSize(DEFAULT_TSPAN_FONT_SIZE, DEFAULT_TSPAN_FONT_SIZE);
// 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();
// std::wstring wsValue;
// if('\0' != pValue[0])
// {
// NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen(pValue), wsValue);
// m_arP.push_back(new CParaText(L"____", wsValue, 0, nCharShapeID));
// }
// }
// else if (eNodeType == XmlUtils::XmlNodeType_Element)
// {
// const std::string sChildNodeName{oReader.GetName()};
// if (GetNodeName(ENode::LineBreak, eType) == sChildNodeName)
// m_arP.push_back(new CCtrlCharacter(L" _", ECtrlCharType::LINE_BREAK));
// else if (GetNodeName(ENode::Tab, eType) == sChildNodeName)
// m_arP.push_back(new CCtrlCharacter(L" _", ECtrlCharType::TABULATION));
// else if (GetNodeName(ENode::Hyphen, eType) == sChildNodeName)
// m_arP.push_back(new CCtrlCharacter(L" _", ECtrlCharType::HARD_HYPHEN));
// else if (GetNodeName(ENode::NbSpace, eType) == sChildNodeName ||
// GetNodeName(ENode::FwSpace, eType) == sChildNodeName)
// m_arP.push_back(new CCtrlCharacter(L" _", ECtrlCharType::HARD_SPACE));
// }
// }
if (bCheckText)
m_wsText = StrUtils::TrimExtraEnding(oNode.GetText());
else
m_wsText = oNode.GetText();
m_oX.SetValue(oNode.GetAttribute(L"x"));
m_oY.SetValue(oNode.GetAttribute(L"y"));
if (NULL != pParent)
{
TBounds oBounds = pParent->GetBounds();
CTSpan *pTSpan = dynamic_cast<CTSpan*>(pParent);
if (NULL == pTSpan)
return;
m_oStyles = pTSpan->m_oStyles;
if (m_oX.Empty())
{
if (!pTSpan->m_arObjects.empty())
pTSpan = pTSpan->m_arObjects.back();
m_oX = pTSpan->m_oX.ToDouble(NSCSS::Pixel, oBounds.m_dRight - oBounds.m_dLeft) + pTSpan->GetWidth();
}
if (m_oY.Empty())
m_oY = pTSpan->m_oY;
}
m_oX = oPosition.dX;
m_oY = oPosition.dY;
}
CTSpan::CTSpan(const std::wstring &wsText, const Point &oPosition, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, bool bCheckText)
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);
@ -108,27 +47,23 @@ namespace SVG
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)
{}
CTSpan::~CTSpan()
{}
CTSpan *CTSpan::Create(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager)
void CTSpan::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
CTSpan *pTSpanParent = dynamic_cast<CTSpan*>(pParent);
if (NULL == pTSpanParent)
return NULL;
return new CTSpan(oNode, pTSpanParent, pFontManager);
}
CTSpan *CTSpan::Create(const std::wstring &wsValue, const Point& oPosition, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, bool bCheckText)
{
CTSpan *pTSpanParent = dynamic_cast<CTSpan*>(pParent);
if (NULL == pTSpanParent || wsValue.empty())
return NULL;
return new CTSpan(wsValue, oPosition, pParent, pFontManager, bCheckText);
if ("x" == sName)
m_oX.SetValue(oReader.GetDouble());
else if ("y" == sName)
m_oY.SetValue(oReader.GetDouble());
else
CRenderedObject::SetAttribute(sName, oReader);
}
void CTSpan::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
@ -182,6 +117,12 @@ namespace SVG
}
}
void CTSpan::ReadChildrens(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator)
{
// SetPositionFromParent(m_pParent);
ReadText(oReader, pSvgCalculator, true);
}
bool CTSpan::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{
if (NULL == pRenderer || (m_wsText.empty() && m_arObjects.empty()))
@ -268,34 +209,38 @@ namespace SVG
if (m_oText.Underline())
nStyle |= (1 << 2);
// Вычиления размеров текста
m_pFontManager->LoadFontByName(wsFontFamily, dFontSize, nStyle, 72., 72.);
m_pFontManager->SetCharSpacing(0);
double dKoef = 25.4 / 72.;
float fW, fUndX1, fUndY1, fUndX2, fUndY2, fUndSize;
double dFHeight = dFontSize;
NSFonts::IFontFile* pFontFile = m_pFontManager->GetFile();
if (NULL != m_pFontManager)
{
// Вычиления размеров текста
m_pFontManager->LoadFontByName(wsFontFamily, dFontSize, nStyle, 72., 72.);
m_pFontManager->SetCharSpacing(0);
if (pFontFile)
dFHeight *= pFontFile->GetHeight() / pFontFile->Units_Per_Em() * dKoef;
double dKoef = 25.4 / 72.;
float fW, fUndX1, fUndY1, fUndX2, fUndY2, fUndSize;
m_pFontManager->LoadString1(m_wsText, 0, 0);
TBBox oBox = m_pFontManager->MeasureString2();
fW = (float)dKoef * (oBox.fMaxX - oBox.fMinX);
NSFonts::IFontFile* pFontFile = m_pFontManager->GetFile();
// Просчитаем положение подчеркивания
m_pFontManager->GetUnderline(&fUndX1, &fUndY1, &fUndX2, &fUndY2, &fUndSize);
fUndX1 *= (float)dKoef;
fUndY1 *= (float)dKoef;
fUndX2 *= (float)dKoef;
fUndY2 *= (float)dKoef;
fUndSize *= (float)dKoef / 2;
if (pFontFile)
dFHeight *= pFontFile->GetHeight() / pFontFile->Units_Per_Em() * dKoef;
fUndY1 -= dFHeight / 4;
fUndY2 -= dFHeight / 4;
m_pFontManager->LoadString1(m_wsText, 0, 0);
TBBox oBox = m_pFontManager->MeasureString2();
fW = (float)dKoef * (oBox.fMaxX - oBox.fMinX);
// Просчитаем положение подчеркивания
m_pFontManager->GetUnderline(&fUndX1, &fUndY1, &fUndX2, &fUndY2, &fUndSize);
fUndX1 *= (float)dKoef;
fUndY1 *= (float)dKoef;
fUndX2 *= (float)dKoef;
fUndY2 *= (float)dKoef;
fUndSize *= (float)dKoef / 2;
fUndY1 -= dFHeight / 4;
fUndY2 -= dFHeight / 4;
}
if (L"left" == m_oText.GetAlign().ToWString())
dX += -fW;
@ -393,13 +338,64 @@ 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())
return 0.;
std::wstring wsName = DefaultFontFamily;
double dSize = m_oFont.GetSize().ToDouble(NSCSS::Pixel);
double dSize = (!m_oFont.GetSize().Zero()) ? m_oFont.GetSize().ToDouble(NSCSS::Pixel) : DEFAULT_TSPAN_FONT_SIZE;
if (!m_oFont.GetFamily().Empty())
{
@ -417,11 +413,15 @@ namespace SVG
if (m_oText.Underline())
nStyle |= (1 << 2);
m_pFontManager->LoadFontByName(wsName, dSize, nStyle, 72., 72.);
double dWidth = 0;
if (NULL != m_pFontManager)
{
m_pFontManager->LoadFontByName(wsName, dSize, nStyle, 72., 72.);
m_pFontManager->LoadString1(m_wsText, 0., 0.);
TBBox oBox = m_pFontManager->MeasureString2();
double dWidth = oBox.fMaxX - oBox.fMinX;
m_pFontManager->LoadString1(m_wsText, 0., 0.);
TBBox oBox = m_pFontManager->MeasureString2();
dWidth = oBox.fMaxX - oBox.fMinX;
}
for (const CTSpan* oTSpan : m_arObjects)
dWidth += oTSpan->GetWidth();
@ -511,6 +511,33 @@ namespace SVG
m_oY = oPosition.dY;
}
void CTSpan::SetPositionFromParent(CRenderedObject* pParent)
{
if (NULL == pParent)
return;
const TBounds oBounds{pParent->GetBounds()};
CTSpan *pTSpan = dynamic_cast<CTSpan*>(pParent);
if (NULL == pTSpan)
return;
m_oStyles = pTSpan->m_oStyles;
if (m_oX.Empty())
{
if (!pTSpan->m_arObjects.empty())
pTSpan = pTSpan->m_arObjects.back();
m_oX = pTSpan->m_oX.ToDouble(NSCSS::Pixel, oBounds.m_dRight - oBounds.m_dLeft) + pTSpan->GetWidth();
}
if (m_oY.Empty())
m_oY = pTSpan->m_oY;
}
std::vector<CTSpan> CTSpan::Split() const
{
std::vector<CTSpan> arGlyphs;
@ -527,20 +554,10 @@ namespace SVG
return arGlyphs;
}
CText::CText(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager)
: CTSpan(oNode, pParent, pFontManager)
CText::CText(CSvgReader& oReader, CRenderedObject *pParent, NSFonts::IFontManager* pFontManager)
: CTSpan(oReader, pParent, pFontManager)
{}
CText *CText::Create(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager)
{
CTSpan* pTSpan = dynamic_cast<CTSpan*>(pParent);
if (NULL != pTSpan)
return NULL;
return new CText(oNode, pParent, pFontManager);
}
bool CText::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{
if (NULL == pRenderer || NULL == pRenderer)
@ -551,20 +568,9 @@ namespace SVG
return true;
}
CTextPath::CTextPath(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, const CSvgFile* pFile)
: CText(oNode, pParent, pFontManager), m_pPath(NULL)
CTextPath::CTextPath(CSvgReader& oReader, CRenderedObject *pParent, NSFonts::IFontManager* pFontManager)
: CText(oReader, pParent, pFontManager)
{
if (NULL != pFile)
{
std::wstring wsHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href"));
size_t unPosition = wsHref.find(L'#');
if (std::wstring::npos != unPosition)
wsHref.erase(0, unPosition + 1);
m_pPath = dynamic_cast<const CPath*>(pFile->GetMarkedObject(wsHref));
}
if (NULL != pParent)
{
CTSpan *pTSpan = dynamic_cast<CTSpan*>(pParent);
@ -574,12 +580,32 @@ namespace SVG
}
}
void CTextPath::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("href" == sName || "xlink:href" == sName)
{
m_wsHref = oReader.GetText();
size_t unPosition = m_wsHref.find(L'#');
if (std::wstring::npos != unPosition)
m_wsHref.erase(0, unPosition + 1);
}
else
CText::SetAttribute(sName, oReader);
}
bool CTextPath::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const
{
if (NULL == pRenderer || CommandeModeClip == oMode || NULL == m_pPath)
if (NULL == pRenderer || CommandeModeClip == oMode || m_wsHref.empty() || NULL == pFile)
return false;
CMovingPath oMovingPath(m_pPath);
const CPath* pPath = dynamic_cast<const CPath*>(pFile->GetMarkedObject(m_wsHref));
if (NULL == pPath)
return false;
CMovingPath oMovingPath(pPath);
oMovingPath.Move(m_oX.ToDouble(NSCSS::Pixel));
@ -601,16 +627,6 @@ namespace SVG
}
CTextPath* CTextPath::Create(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent, NSFonts::IFontManager *pFontManager, const CSvgFile* pFile)
{
CTSpan *pTSpan = dynamic_cast<CText*>(pParent);
if (NULL == pTSpan)
return NULL;
return new CTextPath(oNode, pTSpan, pFontManager, pFile);
}
void CTextPath::DrawGlyph(CTSpan* pTSpan, CMovingPath &oMovingPath, IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const CRenderedObject* pContexObject) const
{
if (NULL == pTSpan)

View File

@ -12,16 +12,19 @@ namespace SVG
{
class CTSpan : public CRenderedObject, public CContainer<CTSpan>
{
public:
CTSpan(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, bool bCheckText = true);
friend class CRenderedObject;
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);
public:
virtual ~CTSpan();
static CTSpan* Create(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
static CTSpan* Create(const std::wstring& wsValue, const Point& oPosition, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, bool bCheckText = true);
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;
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
bool AddObject(CTSpan* pObject) override;
@ -35,6 +38,8 @@ namespace SVG
TBounds GetBounds() const override;
void ReadText(CSvgReader& oReader, const CSvgCalculator* pSvgCalculator, bool bCheckText);
double GetWidth() const;
void CorrectFontFamily(std::wstring& wsFontFamily) const;
@ -43,6 +48,8 @@ namespace SVG
void Normalize(IRenderer* pRenderer, double& dX, double& dY, double& dFontHeight) const;
void SetPosition(const Point& oPosition);
void SetPositionFromParent(CRenderedObject* pParent);
std::vector<CTSpan> Split() const;
NSFonts::IFontManager* m_pFontManager;
@ -61,26 +68,25 @@ namespace SVG
class CText : public CTSpan
{
friend class CRenderedObject;
protected:
CText(CSvgReader& oReader, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
public:
CText(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
static CText* Create(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
};
class CTextPath : public CText
{
friend class CRenderedObject;
CTextPath(CSvgReader& oReader, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL);
public:
CTextPath(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, const CSvgFile* pFile = NULL);
void SetAttribute(const std::string& sName, CSvgReader& oReader) override;
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;
static CTextPath* Create(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, NSFonts::IFontManager* pFontManager = NULL, const CSvgFile* pFile = NULL);
private:
void DrawGlyph(CTSpan* pTSpan, CMovingPath& oMovingPath, IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode, const CRenderedObject* pContexObject = NULL) const;
const CPath *m_pPath;
std::wstring m_wsHref;
};
}

View File

@ -3,20 +3,29 @@
namespace SVG
{
CUse::CUse(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
{
m_wsHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href"));
m_oX .SetValue(oNode.GetAttribute(L"x"));
m_oY .SetValue(oNode.GetAttribute(L"y"));
m_oWidth .SetValue(oNode.GetAttribute(L"width"));
m_oHeight.SetValue(oNode.GetAttribute(L"height"));
}
CUse::CUse(CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent)
{}
CUse::~CUse()
{}
void CUse::SetAttribute(const std::string& sName, CSvgReader& oReader)
{
if ("x" == sName)
m_oX.SetValue(oReader.GetDouble());
else if ("y" == sName)
m_oY.SetValue(oReader.GetDouble());
else if ("width" == sName)
m_oWidth.SetValue(oReader.GetDouble());
else if ("height" == sName)
m_oHeight.SetValue(oReader.GetDouble());
else if ("href" == sName || "xlink:href" == sName)
m_wsHref = oReader.GetText();
else
CRenderedObject::SetAttribute(sName, oReader);
}
void CUse::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
{
CRenderedObject::SetData(mAttributes, ushLevel, bHardMode);

View File

@ -8,10 +8,13 @@ namespace SVG
{
class CUse : public CRenderedObject
{
friend class CRenderedObject;
CUse(CSvgReader& oReader, CRenderedObject* pParent = NULL);
public:
CUse(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
virtual ~CUse();
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;
bool Draw(IRenderer* pRenderer, const CSvgFile* pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;

View File

@ -54,7 +54,10 @@ bool SVG::CSvgReader::ReadFromFile(const std::wstring& wsFilePath)
bool SVG::CSvgReader::ReadFromString(const std::wstring& wsSvg)
{
return (nullptr != m_pReader) ? m_pReader->FromString(wsSvg) : false;
if (nullptr != m_pReader && m_pReader->FromString(wsSvg))
return m_pReader->ReadNextNode();
return false;
}
// XmlUtils::CXmlLiteReader* CSvgReader::GetReader()
@ -200,7 +203,10 @@ std::wstring CSvgReader::GetAttribute(const std::string& sName)
bool CSvgReader::MoveToStart()
{
return (nullptr != m_pReader) ? m_pReader->MoveToStart() : false;
if (nullptr != m_pReader && m_pReader->MoveToStart())
return m_pReader->ReadNextNode();
return false;
}
bool CSvgReader::MoveToFirstAttribute()

View File

@ -109,13 +109,6 @@ private:
while(xml_reader.MoveToNextAttribute());\
xml_reader.MoveToElement();\
}
#define IF_ATTRIBUTE(value) if (value == ATTRIBUTE_NAME)
#define ELSE_IF_ATTRIBUTE(value) else if (value == ATTRIBUTE_NAME)
#define ELSE_IF_ATTRIBUTE2(value1, value2) else if (value1 == ATTRIBUTE_NAME || value2 == ATTRIBUTE_NAME)
#define SET_VALUE(value) value.SetValue(oReader.GetText())
#define SET_VALUE_STRING(value) value = oReader.GetText()
}
#endif // SVGREADER_H

View File

@ -5,7 +5,6 @@
#include <string>
#include <vector>
#include <regex>
#include <map>
#include <cfloat>
namespace SVG