Intermediate refactoring

This commit is contained in:
Kirill Polyakov
2025-10-09 18:59:40 +03:00
parent d0f1691a5e
commit 66d94cf00c
27 changed files with 836 additions and 282 deletions

View File

@ -18,6 +18,7 @@ namespace NSCSS
std::wstring m_wsId; // Id тэга
std::wstring m_wsStyle; // Стиль тэга
std::map<std::wstring, std::wstring> m_mAttributes; // Остальные аттрибуты тэга
//TODO:: возможно использование std::wstring излишне
#ifdef CSS_CALCULATOR_WITH_XHTML
CCompiledStyle *m_pCompiledStyle;

View File

@ -121,7 +121,8 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
$$METAFILE_PATH/svg/SvgObjects/CFont.h \
$$METAFILE_PATH/svg/SvgObjects/CStyle.h \
$$METAFILE_PATH/svg/SvgObjects/CObjectBase.h \
$$METAFILE_PATH/svg/SvgUtils.h
$$METAFILE_PATH/svg/SvgUtils.h \
$$METAFILE_PATH/svg/SvgReader.h
SOURCES += \
$$METAFILE_PATH/svg/CSvgFile.cpp \
@ -145,7 +146,8 @@ METAFILE_PATH = $$PWD/../../raster/Metafile
$$METAFILE_PATH/svg/SvgObjects/CPolyline.cpp \
$$METAFILE_PATH/svg/SvgObjects/CFont.cpp \
$$METAFILE_PATH/svg/SvgObjects/CObjectBase.cpp \
$$METAFILE_PATH/svg/SvgObjects/CStyle.cpp
$$METAFILE_PATH/svg/SvgObjects/CStyle.cpp \
$$METAFILE_PATH/svg/SvgReader.cpp
CONFIG += css_calculator_without_xhtml

View File

@ -109,21 +109,26 @@ namespace SVG
return bResult;
}
bool CSvgParser::LoadFromString(const std::wstring &wsContentent, CGraphicsContainer* pContainer, CSvgFile* pFile) const
bool CSvgParser::LoadFromString(const std::wstring &wsContent, CGraphicsContainer* pContainer, CSvgFile* pFile) const
{
if (wsContentent.empty() || NULL == pFile)
if (wsContent.empty() || NULL == pFile)
return false;
XmlUtils::CXmlNode oXml;
if (!oXml.FromXmlString(wsContentent))
CSvgReader oReader;
if (!oReader.ReadFromString(wsContent))
return false;
ScanStyles(oXml, pFile);
ScanStyles(oReader, pFile);
if (NULL != pContainer)
pContainer->SetData(oXml);
pContainer->SetData(oReader);
return LoadFromXmlNode(oXml, pContainer, pFile);
const CSvgCalculator *pSvgCalculator = 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
@ -139,34 +144,31 @@ namespace SVG
return ReadChildrens(oElement, pContainer, pFile, pContainer);
}
bool CSvgParser::ScanStyles(XmlUtils::CXmlNode &oElement, CSvgFile *pFile) const
bool CSvgParser::ScanStyles(CSvgReader& oReader, CSvgFile *pFile) const
{
if (!oElement.IsValid() || NULL == pFile)
if (oReader.IsEmptyNode() || NULL == pFile || !oReader.MoveToStart())
return false;
std::wstring wsElementName = oElement.GetName();
const std::string sElementName = oReader.GetName();
if (L"style" == wsElementName)
if ("style" == sElementName)
{
ParseStyles(oElement.GetText(), pFile);
ParseStyles(oReader.GetText(), pFile);
return true;
}
bool bScanResult = false;
if (L"svg" == wsElementName || L"g" == wsElementName || L"defs" == wsElementName)
if ("svg" == sElementName || "g" == sElementName || "defs" == sElementName)
{
std::vector<XmlUtils::CXmlNode> arChilds;
oElement.GetChilds(arChilds);
for (XmlUtils::CXmlNode& oChild : arChilds)
{
if (ScanStyles(oChild, pFile))
WHILE_READ_NEXT_NODE(oReader)
if (ScanStyles(oReader, pFile))
bScanResult = true;
}
END_WHILE
}
oReader.MoveToStart();
return bScanResult;
}
@ -226,78 +228,78 @@ namespace SVG
}
template <class ObjectType>
bool CSvgParser::ReadObject(XmlUtils::CXmlNode &oElement, CContainer<ObjectType> *pContainer, CSvgFile *pFile, CRenderedObject *pParent) const
bool CSvgParser::ReadObject(CSvgReader& oReader, CContainer<ObjectType> *pContainer, CSvgFile *pFile, CRenderedObject *pParent) const
{
if (!oElement.IsValid() || NULL == pFile)
if (NULL == pFile)
return false;
std::wstring wsElementName = oElement.GetName();
const std::string sElementName = oReader.GetName();
CObject *pObject = NULL;
if (L"svg" == wsElementName || L"g" == wsElementName || L"a" == wsElementName)
if ("svg" == sElementName || "g" == sElementName || "a" == sElementName)
{
pObject = new CGraphicsContainer(oElement, pParent);
if (!ReadChildrens(oElement, (CGraphicsContainer*)pObject, pFile, (CGraphicsContainer*)pObject))
pObject = new CGraphicsContainer(oReader, pParent);
if (!ReadChildrens(oReader, (CGraphicsContainer*)pObject, pFile, (CGraphicsContainer*)pObject))
{
RELEASEOBJECT(pObject);
return false;
}
}
else if (L"line" == wsElementName)
pObject = new CLine(oElement, pParent);
else if (L"rect" == wsElementName)
pObject = new CRect(oElement, pParent);
else if (L"circle" == wsElementName)
pObject = new CCircle(oElement, pParent);
else if (L"ellipse" == wsElementName)
pObject = new CEllipse(oElement, pParent);
else if (L"path" == wsElementName)
pObject = new CPath(oElement, pParent);
else if (L"polyline" == wsElementName)
pObject = new CPolyline(oElement, pParent);
else if (L"polygon" == wsElementName)
pObject = new CPolygon(oElement, pParent);
else if (L"image" == wsElementName)
pObject = new CImage(oElement, pParent);
else if (L"use" == wsElementName)
pObject = new CUse(oElement, pParent);
else if (L"text" == wsElementName)
else if ("line" == sElementName)
pObject = new CLine(oReader, pParent);
else if ("rect" == sElementName)
pObject = new CRect(oReader, pParent);
else if ("circle" == sElementName)
pObject = new CCircle(oReader, pParent);
else if ("ellipse" == sElementName)
pObject = new CEllipse(oReader, pParent);
else if ("path" == sElementName)
pObject = new CPath(oReader, pParent);
else if ("polyline" == sElementName)
pObject = new CPolyline(oReader, pParent);
else if ("polygon" == sElementName)
pObject = new CPolygon(oReader, pParent);
else if ("image" == sElementName)
pObject = new CImage(oReader, pParent);
else if ("use" == sElementName)
pObject = new CUse(oReader, pParent);
else if ("text" == sElementName)
{
pObject = CText::Create(oElement, pParent, m_pFontManager);
ReadChildrens(oElement, (CText*)pObject, pFile, (CText*)pObject);
pObject = CText::Create(oReader, pParent, m_pFontManager);
ReadChildrens(oReader, (CText*)pObject, pFile, (CText*)pObject);
}
else if (L"tspan" == wsElementName)
else if ("tspan" == sElementName)
{
pObject = CTSpan::Create(oElement, pParent, m_pFontManager);
ReadChildrens(oElement, (CTSpan*)pObject, pFile, (CTSpan*)pObject);
pObject = CTSpan::Create(oReader, pParent, m_pFontManager);
ReadChildrens(oReader, (CTSpan*)pObject, pFile, (CTSpan*)pObject);
}
else if (L"textPath" == wsElementName)
else if ("textPath" == sElementName)
{
pObject = CTextPath::Create(oElement, pParent, m_pFontManager, pFile);
ReadChildrens(oElement, (CTextPath*)pObject, pFile);
pObject = CTextPath::Create(oReader, pParent, m_pFontManager, pFile);
ReadChildrens(oReader, (CTextPath*)pObject, pFile);
}
else if (L"switch" == wsElementName)
else if ("switch" == sElementName)
{
pObject = new CSwitch(oElement, pParent);
ReadChildrens(oElement, (CSwitch*)pObject, pFile);
pObject = new CSwitch(oReader, pParent);
ReadChildrens(oReader, (CSwitch*)pObject, pFile);
}
//defs
else if (L"defs" == wsElementName)
return ReadChildrens<CRenderedObject>(oElement, NULL, pFile);
else if(L"linearGradient" == wsElementName)
else if ("defs" == sElementName)
return ReadChildrens<CRenderedObject>(oReader, NULL, pFile);
else if("linearGradient" == sElementName)
{
pObject = new CLinearGradient(oElement);
ReadChildrens(oElement, (CLinearGradient*)pObject, pFile);
pObject = new CLinearGradient(oReader);
ReadChildrens(oReader, (CLinearGradient*)pObject, pFile);
}
else if (L"radialGradient" == wsElementName)
else if ("radialGradient" == sElementName)
{
pObject = new CRadialGradient(oElement);
ReadChildrens(oElement, (CRadialGradient*)pObject, pFile);
pObject = new CRadialGradient(oReader);
ReadChildrens(oReader, (CRadialGradient*)pObject, pFile);
}
else if (L"stop" == wsElementName)
else if ("stop" == sElementName)
{
CStopElement *pStopElement = new CStopElement(oElement);
CStopElement *pStopElement = new CStopElement(oReader);
if (AddObject((ObjectType*)pStopElement, pContainer))
{
UpdateStyles(pStopElement, pFile);
@ -309,37 +311,37 @@ namespace SVG
return false;
}
}
else if (L"pattern" == wsElementName)
else if ("pattern" == sElementName)
{
pObject = new CPattern(oElement, m_pFontManager);
ReadChildrens(oElement, (CGraphicsContainer*)(&((CPattern*)pObject)->GetContainer()), pFile);
pObject = new CPattern(oReader, m_pFontManager);
ReadChildrens(oReader, (CGraphicsContainer*)(&((CPattern*)pObject)->GetContainer()), pFile);
}
else if (L"clipPath" == wsElementName)
else if ("clipPath" == sElementName)
{
pObject = new CClipPath(oElement);
ReadChildrens(oElement, (CGraphicsContainer*)(&((CClipPath*)pObject)->GetContainer()), pFile);
pObject = new CClipPath(oReader);
ReadChildrens(oReader, (CGraphicsContainer*)(&((CClipPath*)pObject)->GetContainer()), pFile);
}
else if (L"marker" == wsElementName)
else if ("marker" == sElementName)
{
pObject = new CMarker(oElement);
ReadChildrens(oElement, (CMarker*)pObject, pFile);
pObject = new CMarker(oReader);
ReadChildrens(oReader, (CMarker*)pObject, pFile);
}
else if (L"mask" == wsElementName)
else if ("mask" == sElementName)
{
pObject = new CMask(oElement);
ReadChildrens(oElement, (CGraphicsContainer*)(&((CMask*)pObject)->GetContainer()), pFile);
pObject = new CMask(oReader);
ReadChildrens(oReader, (CGraphicsContainer*)(&((CMask*)pObject)->GetContainer()), pFile);
}
else if (L"symbol" == wsElementName)
else if ("symbo" == sElementName)
{
pObject = new CSymbol(oElement);
if (ReadChildrens(oElement, (CSymbol*)pObject, pFile) && MarkObject(pObject, pFile))
pObject = new CSymbol(oReader);
if (ReadChildrens(oReader, (CSymbol*)pObject, pFile) && MarkObject(pObject, pFile))
return true;
else
RELEASEOBJECT(pObject);
}
else if (L"font" == wsElementName)
else if ("font" == sElementName)
{
pObject = new CFont(oElement);
pObject = new CFont(oReader);
}
if (NULL != pObject)
@ -382,18 +384,15 @@ namespace SVG
}
template <class ObjectType>
bool CSvgParser::ReadChildrens(XmlUtils::CXmlNode &oElement, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject *pParent) const
bool CSvgParser::ReadChildrens(CSvgReader& oReader, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject *pParent) const
{
std::vector<XmlUtils::CXmlNode> arChilds;
bool bResult = false;
oElement.GetChilds(arChilds);
WHILE_READ_NEXT_NODE(oReader)
if (ReadObject(oReader, pContainer, pFile, pParent))
bResult = true;
END_WHILE
if (arChilds.empty())
return false;
for (XmlUtils::CXmlNode& oChild : arChilds)
ReadObject(oChild, pContainer, pFile, pParent);
return true;
return bResult;
}
}

View File

@ -3,9 +3,9 @@
#include "../../../common/Directory.h"
#include "../../../graphics/pro/Fonts.h"
#include "../../../xml/include/xmlutils.h"
#include "SvgObjects/CContainer.h"
#include "SvgReader.h"
class CSvgFile;
@ -20,16 +20,15 @@ namespace SVG
void SetFontManager(NSFonts::IFontManager* pFontManager);
bool LoadFromFile(const std::wstring& wsFile, CGraphicsContainer* pContainer, CSvgFile* pFile) const;
bool LoadFromString(const std::wstring& wsContentent, CGraphicsContainer* pContainer, CSvgFile* pFile) const;
bool LoadFromXmlNode(XmlUtils::CXmlNode& oElement, CGraphicsContainer* pContainer, CSvgFile* pFile) const;
bool LoadFromString(const std::wstring& wsContent, CGraphicsContainer* pContainer, CSvgFile* pFile) const;
template <class ObjectType>
bool ReadObject(XmlUtils::CXmlNode& oElement, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;
bool ReadObject(CSvgReader& oReader, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;
private:
template <class ObjectType>
bool ReadChildrens(XmlUtils::CXmlNode& oElement, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;
bool ReadChildrens(CSvgReader& oReader, CContainer<ObjectType>* pContainer, CSvgFile* pFile, CRenderedObject* pParent = NULL) const;
bool ScanStyles(XmlUtils::CXmlNode& oElement, CSvgFile* pFile) const;
bool ScanStyles(CSvgReader& oReader, CSvgFile* pFile) const;
void ParseStyles(const std::wstring& wsStyles, CSvgFile *pFile) const;
void UpdateStyles(CObject* pObject, CSvgFile* pFile) const;

View File

@ -1,16 +1,21 @@
#include "CCircle.h"
#include "CContainer.h"
#include "CStyle.h"
namespace SVG
{
CCircle::CCircle(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CRenderedObject(oNode, pParent)
RENDERER_CHILDREN_CPP(Circle)
{
m_oCx.SetValue(oNode.GetAttribute(L"cx"));
m_oCy.SetValue(oNode.GetAttribute(L"cy"));
m_oR .SetValue(oNode.GetAttribute(L"r"));
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);
}
END_READ_ATTRIBUTES(oReader)
}
void CCircle::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)

View File

@ -8,7 +8,7 @@ namespace SVG
class CCircle : public CRenderedObject
{
public:
CCircle(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
CCircle(CSvgReader& oReader, CRenderedObject* pParent = NULL);
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;

View File

@ -2,13 +2,11 @@
namespace SVG
{
CClipPath::CClipPath(XmlUtils::CXmlNode &oNode)
: CAppliedObject(oNode)
CClipPath::CClipPath(CSvgReader& oReader)
: CAppliedObject(oReader), m_enUnits(ClipU_ObjectBoundingBox)
{
if (L"userSpaceOnUse" == oNode.GetAttribute(L"gradientUnits"))
if (L"userSpaceOnUse" == oReader.GetAttribute("gradientUnits"))
m_enUnits = ClipU_UserSpaceOnUse;
else
m_enUnits = ClipU_ObjectBoundingBox;
}
void CClipPath::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)

View File

@ -14,7 +14,7 @@ namespace SVG
class CClipPath : public CAppliedObject
{
public:
CClipPath(XmlUtils::CXmlNode& oNode);
CClipPath(CSvgReader& oReader);
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;

View File

@ -15,40 +15,45 @@ namespace SVG
pObject->m_pParent = NULL;
}
void CGraphicsContainer::SetData(XmlUtils::CXmlNode &oNode)
void CGraphicsContainer::SetData(CSvgReader& oReader)
{
SetNodeData(oNode);
SetNodeData(oReader);
m_oWindow.m_oX .SetValue(oNode.GetAttribute(L"x"));
m_oWindow.m_oY .SetValue(oNode.GetAttribute(L"y"));
m_oWindow.m_oWidth .SetValue(oNode.GetAttribute(L"width"), 0, true);
m_oWindow.m_oHeight.SetValue(oNode.GetAttribute(L"height"), 0, true);
const std::wstring wsViewBox = oNode.GetAttribute(L"viewBox");
if (!wsViewBox.empty())
START_READ_ATTRIBUTES(oReader)
{
std::vector<double> arValues = StrUtils::ReadDoubleValues(wsViewBox);
if (4 == arValues.size())
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_oX = arValues[0];
m_oViewBox.m_oY = arValues[1];
m_oViewBox.m_oWidth = arValues[2];
m_oViewBox.m_oHeight = arValues[3];
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];
}
}
}
else
m_oViewBox = m_oWindow;
END_READ_ATTRIBUTES(oReader)
}
CGraphicsContainer::CGraphicsContainer(XmlUtils::CXmlNode& oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
CGraphicsContainer::CGraphicsContainer(CSvgReader& oReader, CRenderedObject *pParent)
: CRenderedObject(oReader, pParent)
{
SetData(oNode);
SetData(oReader);
}
CGraphicsContainer::CGraphicsContainer(double dWidth, double dHeight, XmlUtils::CXmlNode& oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent), m_oWindow{0, 0, dWidth, dHeight}
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

View File

@ -81,12 +81,12 @@ namespace SVG
{
public:
CGraphicsContainer(const std::wstring& wsName = L"GraphicsContainer");
CGraphicsContainer(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
CGraphicsContainer(double dWidth, double dHeight, XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
CGraphicsContainer(CSvgReader& oReader, CRenderedObject* pParent = NULL);
CGraphicsContainer(double dWidth, double dHeight, CSvgReader& oReader, CRenderedObject* pParent = NULL);
virtual ~CGraphicsContainer();
void SetData(XmlUtils::CXmlNode& oNode);
void SetData(CSvgReader& oReader);
bool Draw(IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pOtherStyles = NULL, const CRenderedObject* pContexObject = NULL) const override;

View File

@ -1,17 +1,23 @@
#include "CEllipse.h"
#include "CStyle.h"
#include "CContainer.h"
namespace SVG
{
CEllipse::CEllipse(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent)
: CRenderedObject(oNode, pParent)
RENDERER_CHILDREN_CPP(Ellipse)
{
m_oCx.SetValue(oNode.GetAttribute(L"cx"));
m_oCy.SetValue(oNode.GetAttribute(L"cy"));
m_oRx.SetValue(oNode.GetAttribute(L"rx"));
m_oRy.SetValue(oNode.GetAttribute(L"ry"));
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)
}
void CEllipse::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)

View File

@ -6,11 +6,7 @@
namespace SVG
{
class CEllipse : public CRenderedObject
{
public:
CEllipse(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
BEGIN_RENDERER_CHILDREN_H(Ellipse)
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;
@ -23,7 +19,7 @@ namespace SVG
SvgDigit m_oCy;
SvgDigit m_oRx;
SvgDigit m_oRy;
};
END_RENDERER_CHILDREN_H
}
#endif // CELLIPSE_H

View File

@ -2,15 +2,22 @@
namespace SVG
{
CGlyph::CGlyph(XmlUtils::CXmlNode &oNode)
: CPath(oNode)
CGlyph::CGlyph(CSvgReader& oReader)
: CPath(oReader)
{
std::wstring wsUnicode(oNode.GetAttribute(L"unicode"));
START_READ_ATTRIBUTES(oReader)
{
if ("unicode" == sAttributeName)
{
const std::wstring wsUnicode{oReader.GetText()};
if (!wsUnicode.empty())
m_wchUnicode = wsUnicode[0];
m_oHorizAdvX.SetValue(oNode.GetAttributeOrValue(L"horiz-adv-x"));
if (!wsUnicode.empty())
m_wchUnicode = wsUnicode[0];
}
else if ("horiz-adv-x" == sAttributeName)
m_oHorizAdvX.SetValue(oReader.GetText());
}
END_READ_ATTRIBUTES(oReader)
}
wchar_t CGlyph::GetUnicode() const
@ -18,21 +25,26 @@ namespace SVG
return m_wchUnicode;
}
CFontFace::CFontFace(XmlUtils::CXmlNode &oNode)
CFontFace::CFontFace(CSvgReader& oReader)
{}
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)
CFont::CFont(XmlUtils::CXmlNode &oNode)
: CAppliedObject(oNode), m_pMissingGlyph(NULL)
{
ParseGlyphs(oNode);
m_oArguments.m_wsFontVariant = oNode.GetAttribute(L"font-variant");
m_oArguments.m_wsFontStyle = oNode.GetAttribute(L"font-style");
m_oArguments.m_wsFontWidght = oNode.GetAttribute(L"font-weight");
m_oHorizAdvX.SetValue(oNode.GetAttributeOrValue(L"horiz-adv-x"));
ParseGlyphs(oReader);
}
CFont::~CFont()
@ -115,18 +127,13 @@ namespace SVG
return true;
}
void CFont::ParseGlyphs(XmlUtils::CXmlNode &oNode)
void CFont::ParseGlyphs(CSvgReader& oReader)
{
std::vector<XmlUtils::CXmlNode> arChilds;
if (!oNode.GetChilds(arChilds) || arChilds.empty())
return;
for (XmlUtils::CXmlNode& oChild : arChilds)
WHILE_READ_NEXT_NODE_WITH_NAME(oReader)
{
if (L"glyph" == oChild.GetName())
if ("glyph" == sNodeName)
{
CGlyph *pGlyph = new CGlyph(oChild);
CGlyph *pGlyph = new CGlyph(oReader);
if (NULL == pGlyph)
continue;
@ -136,22 +143,17 @@ namespace SVG
else
delete pGlyph;
}
else if (L"missing-glyph" == oChild.GetName())
else if ("missing-glyph" == sNodeName)
{
std::vector<XmlUtils::CXmlNode> arMissingGlyphChilds;
if (!oChild.GetChilds(arMissingGlyphChilds) || arMissingGlyphChilds.empty())
continue;
for (XmlUtils::CXmlNode& oChildMissingGlyph : arMissingGlyphChilds)
WHILE_READ_NEXT_NODE_WITH_DEPTH_ONE_NAME(oReader, Child, "path")
{
if (L"path" == oChildMissingGlyph.GetName())
{
m_pMissingGlyph = new CPath(oChildMissingGlyph);
if (NULL != m_pMissingGlyph)
break;
}
m_pMissingGlyph = new CPath(oReader);
if (NULL != m_pMissingGlyph)
break;
}
END_WHILE
}
}
END_WHILE
}
}

View File

@ -8,7 +8,7 @@ namespace SVG
class CGlyph : public CPath
{
public:
CGlyph(XmlUtils::CXmlNode& oNode);
CGlyph(CSvgReader& oReader);
wchar_t GetUnicode() const;
private:
@ -21,7 +21,7 @@ namespace SVG
class CFontFace
{
public:
CFontFace(XmlUtils::CXmlNode& oNode);
CFontFace(CSvgReader& oReader);
private:
std::wstring m_wsSrcFaceName;
};
@ -37,7 +37,7 @@ namespace SVG
class CFont : public CAppliedObject
{
public:
CFont(XmlUtils::CXmlNode& oNode);
CFont(CSvgReader& oReader);
~CFont();
void SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode) override;
@ -45,7 +45,7 @@ namespace SVG
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
bool Draw(const std::wstring& wsText, const double& dX, const double& dY, const double& dFontHeight, IRenderer* pRenderer, const CSvgFile *pFile, CommandeMode oMode = CommandeModeDraw, const TSvgStyles* pStyles = NULL, const CRenderedObject* pContexObject = NULL) const;
private:
void ParseGlyphs(XmlUtils::CXmlNode& oNode);
void ParseGlyphs(CSvgReader& oReader);
TFontArguments m_oArguments;

View File

@ -3,8 +3,8 @@
namespace SVG
{
CStopElement::CStopElement(XmlUtils::CXmlNode& oNode)
: CObject(oNode)
CStopElement::CStopElement(CSvgReader& oReader)
: CObject(oReader)
{}
ObjectType CStopElement::GetType() const
@ -34,20 +34,19 @@ namespace SVG
m_oColor.SetOpacity(mAttributes.at(L"stop-opacity"));
}
CGradient::CGradient(XmlUtils::CXmlNode &oNode)
: CAppliedObject(oNode)
{
m_wsXlinkHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href"));
m_oTransform.SetMatrix(oNode.GetAttribute(L"gradientTransform"), 0, true);
if (L"userSpaceOnUse" == oNode.GetAttribute(L"gradientUnits"))
m_enGradientUnits = GradU_UserSpaceOnUse;
else
m_enGradientUnits = GradU_ObjectBoundingBox;
}
void CGradient::SetData(const std::map<std::wstring, std::wstring> &mAttributes, unsigned short ushLevel, bool bHardMode)
CGradient::CGradient(CSvgReader& oReader)
: CAppliedObject(oReader), m_enGradientUnits(GradU_ObjectBoundingBox)
{
START_READ_ATTRIBUTES(oReader)
{
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())
m_enGradientUnits = GradU_UserSpaceOnUse;
}
END_READ_ATTRIBUTES(oReader)
}
bool CGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
@ -117,13 +116,21 @@ namespace SVG
return pRefGradient->Apply(pRenderer, pFile, oObjectBounds);
}
CLinearGradient::CLinearGradient(XmlUtils::CXmlNode& oNode)
: CGradient(oNode)
CLinearGradient::CLinearGradient(CSvgReader& oReader)
: CGradient(oReader)
{
m_oX1.SetValue(oNode.GetAttribute(L"x1"));
m_oY1.SetValue(oNode.GetAttribute(L"y1"));
m_oX2.SetValue(oNode.GetAttribute(L"x2"));
m_oY2.SetValue(oNode.GetAttribute(L"y2"));
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)
}
bool CLinearGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)
@ -169,12 +176,19 @@ namespace SVG
return true;
}
CRadialGradient::CRadialGradient(XmlUtils::CXmlNode& oNode)
: CGradient(oNode)
CRadialGradient::CRadialGradient(CSvgReader& oReader)
: CGradient(oReader)
{
m_oCx.SetValue(oNode.GetAttribute(L"cx"));
m_oCy.SetValue(oNode.GetAttribute(L"cy"));
m_oR.SetValue(oNode.GetAttribute(L"r"));
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)
}
bool CRadialGradient::Apply(IRenderer *pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds)

View File

@ -22,7 +22,7 @@ namespace SVG
class CStopElement : public CObject
{
public:
CStopElement(XmlUtils::CXmlNode& oNode);
CStopElement(CSvgReader& oReader);
ObjectType GetType() const override;
@ -40,7 +40,7 @@ namespace SVG
friend class CLinearGradient;
friend class CRadialGradient;
public:
CGradient(XmlUtils::CXmlNode& oNode);
CGradient(CSvgReader& oReader);
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
@ -59,7 +59,7 @@ namespace SVG
class CLinearGradient : public CGradient
{
public:
CLinearGradient(XmlUtils::CXmlNode& oNode);
CLinearGradient(CSvgReader& oReader);
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
private:
@ -72,7 +72,7 @@ namespace SVG
class CRadialGradient : public CGradient
{
public:
CRadialGradient(XmlUtils::CXmlNode& oNode);
CRadialGradient(CSvgReader& oReader);
bool Apply(IRenderer* pRenderer, const CSvgFile *pFile, const TBounds &oObjectBounds) override;
private:

View File

@ -8,15 +8,22 @@
namespace SVG
{
CImage::CImage(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CRenderedObject(oNode, pParent)
RENDERER_CHILDREN_CPP(Image)
{
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"));
m_wsHref = oNode.GetAttribute(L"href", oNode.GetAttribute(L"xlink:href")); // TODO:: В дальнейшем возможно стоит реализовать отдельный класс CHref для всех типов ссылок
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)
}
bool CImage::Draw(IRenderer *pRenderer, const CSvgFile *pFile, CommandeMode oMode, const TSvgStyles *pOtherStyles, const CRenderedObject* pContexObject) const

View File

@ -5,18 +5,14 @@
namespace SVG
{
class CImage : public CRenderedObject
{
public:
CImage(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
BEGIN_RENDERER_CHILDREN_H(Image)
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,18 +2,26 @@
namespace SVG
{
CLine::CLine(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent)
: CPath(oNode, pParent, false)
CLine::CLine(CSvgReader& oReader, CRenderedObject* pParent)
: CPath(oReader, pParent, false)
{
SvgDigit oX1;
SvgDigit oY1;
SvgDigit oX2;
SvgDigit oY2;
oX1.SetValue(oNode.GetAttribute(L"x1"));
oY1.SetValue(oNode.GetAttribute(L"y1"));
oX2.SetValue(oNode.GetAttribute(L"x2"));
oY2.SetValue(oNode.GetAttribute(L"y2"));
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)
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

@ -8,7 +8,7 @@ namespace SVG
class CLine : public CPath
{
public:
CLine(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
CLine(CSvgReader& oReader, CRenderedObject* pParent = NULL);
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;
private:

View File

@ -31,9 +31,9 @@ namespace SVG
: m_oXmlNode(oData)
{}
CObject::CObject(XmlUtils::CXmlNode &oNode)
CObject::CObject(CSvgReader& oReader)
{
SetNodeData(oNode);
SetNodeData(oReader);
}
CObject::~CObject()
@ -153,31 +153,25 @@ namespace SVG
return pDefObject->Apply(pRenderer, pFile, oBounds);
}
void CObject::SetNodeData(XmlUtils::CXmlNode &oNode)
void CObject::SetNodeData(CSvgReader& oReader)
{
if (!oNode.IsValid())
return;
m_oXmlNode.m_wsName = oReader.GetNameW();
std::vector<std::wstring> arProperties, arValues;
oNode.GetAllAttributes(arProperties, arValues);
m_oXmlNode.m_wsName = oNode.GetName();
for (unsigned int unIndex = 0; unIndex < arProperties.size(); ++unIndex)
START_READ_ATTRIBUTES(oReader)
{
if (L"class" == arProperties[unIndex])
if ("class" == sAttributeName)
{
m_oXmlNode.m_wsClass = arValues[unIndex];
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 (L"id" == arProperties[unIndex])
m_oXmlNode.m_wsId = arValues[unIndex];
else if (L"style" == arProperties[unIndex])
m_oXmlNode.m_wsStyle = arValues[unIndex];
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({arProperties[unIndex], arValues[unIndex]});
m_oXmlNode.m_mAttributes.insert({oReader.GetNameW(), oReader.GetText()});
}
END_READ_ATTRIBUTES(oReader)
}
std::wstring CObject::GetId() const
@ -196,9 +190,13 @@ namespace SVG
SetDefaultStyles();
}
CRenderedObject::CRenderedObject(XmlUtils::CXmlNode &oNode, CRenderedObject *pParent)
: CObject(oNode), m_pParent(pParent)
CRenderedObject::CRenderedObject(CSvgReader& oReader, CRenderedObject *pParent)
: CObject(oReader), m_pParent(pParent)
{
START_READ_ATTRIBUTES(oReader)
SetAttribute(sAttributeName, oReader.GetText());
END_READ_ATTRIBUTES(oReader)
SetDefaultStyles();
}
@ -447,8 +445,8 @@ namespace SVG
return false;
}
CAppliedObject::CAppliedObject(XmlUtils::CXmlNode &oNode)
: CObject(oNode)
CAppliedObject::CAppliedObject(CSvgReader& oReader)
: CObject(oReader)
{}
CAppliedObject::~CAppliedObject()

View File

@ -3,10 +3,11 @@
#include "../../../../../Common/3dParty/html/css/src/CNode.h"
#include "../../../../../Common/3dParty/html/css/src/StaticFunctions.h"
#include "../../../../xml/include/xmlutils.h"
#include "../../../../graphics/IRenderer.h"
#include "../../../../common/IGrObject.h"
#include "../SvgTypes.h"
#include "../SvgReader.h"
class CSvgFile;
@ -36,11 +37,13 @@ namespace SVG
AppliedObject
};
//TODO:: хотелось бы передалать принцип чтения аргументов
class CObject : public IGrObject
{
public:
CObject(const NSCSS::CNode& oData);
CObject(XmlUtils::CXmlNode& oNode);
CObject(CSvgReader& oReader);
virtual ~CObject();
virtual ObjectType GetType() const = 0;
@ -64,7 +67,7 @@ namespace SVG
bool ApplyDef(IRenderer* pRenderer, const CSvgFile *pFile, const std::wstring& wsUrl, const TBounds& oBounds) const;
void SetNodeData(XmlUtils::CXmlNode& oNode);
void SetNodeData(CSvgReader& oReader);
friend class CRenderedObject;
friend class CAppliedObject;
@ -99,7 +102,7 @@ namespace SVG
{
public:
CRenderedObject(const NSCSS::CNode& oData, CRenderedObject* pParent = NULL);
CRenderedObject(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL);
CRenderedObject(CSvgReader& oReader, CRenderedObject* pParent = NULL);
virtual ~CRenderedObject();
ObjectType GetType() const override;
@ -146,10 +149,22 @@ namespace SVG
CRenderedObject *m_pParent;
};
#define BEGIN_RENDERER_CHILDREN_H(name)\
class C##name : public CRenderedObject\
{\
public:\
C##name(CSvgReader& oReader, CRenderedObject* pParent = NULL);
#define END_RENDERER_CHILDREN_H };
#define RENDERER_CHILDREN_CPP(name)\
C##name::C##name(CSvgReader& oReader, CRenderedObject* pParent)\
: CRenderedObject(oReader, pParent)
class CAppliedObject : public CObject
{
public:
CAppliedObject(XmlUtils::CXmlNode& oNode);
CAppliedObject(CSvgReader& oReader);
virtual ~CAppliedObject();
ObjectType GetType() const override;

View File

@ -445,11 +445,11 @@ namespace SVG
#define CURVESTEP 0.05
#define MINCURVESTEP 0.001
CPath::CPath(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent, bool bChechCommands)
: CRenderedObject(oNode, pParent), m_bEvenOddRule(false)
CPath::CPath(CSvgReader& oReader, CRenderedObject* pParent, bool bChechCommands)
: CRenderedObject(oReader, pParent), m_bEvenOddRule(false)
{
if (bChechCommands)
ReadFromString(oNode.GetAttribute(L"d"));
ReadFromString(oReader.GetAttribute("d"));
}
CPath::~CPath()

View File

@ -106,7 +106,7 @@ namespace SVG
class CPath : public CRenderedObject
{
public:
CPath(XmlUtils::CXmlNode& oNode, CRenderedObject* pParent = NULL, bool bChechCommands = true);
CPath(CSvgReader& oReader, CRenderedObject* pParent = NULL, bool bChechCommands = true);
virtual ~CPath();
void SetData(const std::map<std::wstring, std::wstring>& mAttributes, unsigned short ushLevel, bool bHardMode = false) override;

View File

@ -29,6 +29,41 @@ namespace SVG
{
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

View File

@ -0,0 +1,347 @@
#include "SvgReader.h"
#include <cmath>
#include <cctype>
namespace SVG
{
int ConvertHexToInt(const std::string& sValue, const int& _default)
{
if (sValue.empty() || "none" == sValue)
return _default;
std::string::const_iterator itStart = sValue.cbegin();
if ('#' == *itStart)
++itStart;
if (sValue.cend() - itStart != 6)
return _default;
itStart = sValue.cend() - 6;
int nResult = 0;
while (itStart != sValue.cend())
{
if ('0' <= *itStart && *itStart <= '9')
nResult = (nResult << 4) | (*itStart++ - '0');
else if ('A' <= *itStart && *itStart <= 'F')
nResult = (nResult << 4) | (*itStart++ - 'A' + 10);
else if ('a' <= *itStart && *itStart <= 'f')
nResult = (nResult << 4) | (*itStart++ - 'a' + 10);
else
return _default;
}
return nResult;
}
CSvgReader::CSvgReader()
: m_pReader(new XmlUtils::CXmlLiteReader), m_bParseAttribute(false)
{}
CSvgReader::~CSvgReader()
{
if (nullptr != m_pReader)
delete m_pReader;
}
bool SVG::CSvgReader::ReadFromFile(const std::wstring& wsFilePath)
{
return (nullptr != m_pReader) ? m_pReader->FromFile(wsFilePath) : false;
}
bool SVG::CSvgReader::ReadFromString(const std::wstring& wsSvg)
{
return (nullptr != m_pReader) ? m_pReader->FromString(wsSvg) : false;
}
// XmlUtils::CXmlLiteReader* CSvgReader::GetReader()
// {
// return m_pReader;
// }
unsigned int CSvgReader::GetDepth()
{
return (nullptr != m_pReader) ? m_pReader->GetDepth() : 0;
}
bool CSvgReader::IsEmptyNode()
{
return (nullptr != m_pReader) ? m_pReader->IsEmptyNode() : true;
}
bool CSvgReader::GetBool()
{
return "1" == GetTextAValue(*this) || "true" == GetTextAValue(*this);
}
int StringToInt(const std::string& sValue, const int& _default)
{
std::string::const_iterator itPos{sValue.cbegin()};
while (std::isspace(*itPos))
++itPos;
if (sValue.cend() == itPos)
return _default;
while (sValue.cend() != itPos && !std::isdigit(*itPos))
++itPos;
if (sValue.cend() == itPos)
return _default;
int nResult = 0;
while (itPos != sValue.cend() && std::isdigit(*itPos))
{
nResult = nResult * 10 + (*itPos - '0');
++itPos;
}
return ((nResult & 0xFF) << 16) | (((nResult >> 8) & 0xFF) << 8) | ((nResult >> 16) & 0xFF);
}
int CSvgReader::GetColor(const int& nDefault)
{
const std::string sValue{GetTextAValue(*this)};
if (sValue.empty())
return nDefault;
if ('#' == sValue[0])
return ConvertHexToInt(sValue, nDefault);
return StringToInt(sValue, nDefault);
}
int CSvgReader::GetInt()
{
return GetIntValue(*this);
}
double CSvgReader::GetDouble()
{
return GetDoubleValue(*this);
}
std::string CSvgReader::GetTextA()
{
if (nullptr == m_pReader)
return std::string();
return (m_bParseAttribute) ? m_pReader->GetTextA() : m_pReader->GetText2A();
}
std::wstring CSvgReader::GetText()
{
if (nullptr == m_pReader)
return std::wstring();
return (m_bParseAttribute) ? m_pReader->GetText() : m_pReader->GetText2();
}
const char* CSvgReader::GetTextChar()
{
if (nullptr == m_pReader)
return "";
return m_pReader->GetTextChar();
}
template<typename T>
T CSvgReader::GetAttribute(const std::string& sName, T _default, T (*GetValue)(CSvgReader&))
{
if (!MoveToFirstAttribute())
return _default;
T oValue = _default;
do
{
if (sName == m_pReader->GetNameA())
{
oValue = GetValue(*this);
break;
}
}while(m_pReader->MoveToNextAttribute());
MoveToElement();
return oValue;
}
int CSvgReader::GetAttributeInt(const std::string& sName, int nDefault)
{
return GetAttribute<int>(sName, nDefault, &GetIntValue);
}
bool CSvgReader::GetAttributeBool(const std::string& sName)
{
return GetAttribute<bool>(sName, false, &GetBoolValue);
}
double CSvgReader::GetAttributeDouble(const std::string& sName)
{
return GetAttribute<double>(sName, 0., &GetDoubleValue);
}
std::string CSvgReader::GetAttributeA(const std::string& sName)
{
return GetAttribute<std::string>(sName, "", &GetTextAValue);
}
std::wstring CSvgReader::GetAttribute(const std::string& sName)
{
return GetAttribute<std::wstring>(sName, L"", &GetTextValue);
}
bool CSvgReader::MoveToStart()
{
return (nullptr != m_pReader) ? m_pReader->MoveToStart() : false;
}
bool CSvgReader::MoveToFirstAttribute()
{
if (nullptr == m_pReader || !m_pReader->MoveToFirstAttribute())
return false;
m_bParseAttribute = true;
return true;
}
bool CSvgReader::MoveToNextAttribute()
{
return (nullptr != m_pReader) ? m_pReader->MoveToNextAttribute() : false;
}
bool CSvgReader::MoveToElement()
{
if (nullptr == m_pReader || !m_pReader->MoveToElement())
return false;
m_bParseAttribute = false;
return true;
}
std::string CSvgReader::GetName()
{
return (nullptr != m_pReader) ? m_pReader->GetNameA() : std::string();
}
std::wstring CSvgReader::GetNameW()
{
return (nullptr != m_pReader) ? m_pReader->GetName() : std::wstring();
}
bool CSvgReader::ReadNextSiblingNode(unsigned int unDepth)
{
return (nullptr != m_pReader) ? m_pReader->ReadNextSiblingNode(unDepth) : false;
}
bool CSvgReader::ReadNextNode()
{
return (nullptr != m_pReader) ? m_pReader->ReadNextNode() : false;
}
bool CSvgReader::Read(XmlUtils::XmlNodeType& eNodeType)
{
return (nullptr != m_pReader) ? m_pReader->Read(eNodeType) : false;
}
int CSvgReader::GetIntValue(CSvgReader& oXmlReader)
{
return std::atoi(oXmlReader.GetTextA().c_str());
}
bool CSvgReader::GetBoolValue(CSvgReader& oXmlReader)
{
return "1" == oXmlReader.GetTextA();
}
double CSvgReader::GetDoubleValue(CSvgReader& oXmlReader)
{
const std::string sValue{oXmlReader.GetTextA()};
const char* pCur = sValue.c_str();
while (std::isspace(*pCur))
++pCur;
if (!pCur)
return 0.;
bool bNegative = false;
while ('-' == *pCur || '+' == *pCur)
{
if ('-' == *pCur)
bNegative = !bNegative;
++pCur;
}
if (!pCur)
return 0.;
double dResult = 0.;
while (std::isdigit(*pCur))
dResult = dResult * 10. + (*pCur++ - '0');
if (',' == *pCur || '.' == *pCur)
{
++pCur;
double dFraction = 0.0;
double dDivisor = 1.0;
while (std::isdigit(*pCur))
{
dFraction = dFraction * 10. + (*pCur++ - '0');
dDivisor *= 10;
}
dResult += dFraction / dDivisor;
}
if ('e' == *pCur || 'E' == *pCur)
{
++pCur;
bool bExpNegative = false;
while ('-' == *pCur || '+' == *pCur)
{
if ('-' == *pCur)
bExpNegative = !bExpNegative;
++pCur;
}
int nExponent = 0;
while (std::isdigit(*pCur))
nExponent = nExponent * 10 + (*pCur++ - '0');
if (bExpNegative)
nExponent = -nExponent;
dResult *= std::pow(10., nExponent);
}
return bNegative ? -dResult : dResult;
}
std::string CSvgReader::GetTextAValue(CSvgReader& oXmlReader)
{
return oXmlReader.GetTextA();
}
std::wstring CSvgReader::GetTextValue(CSvgReader& oXmlReader)
{
return oXmlReader.GetText();
}
}

View File

@ -0,0 +1,121 @@
#ifndef SVGREADER_H
#define SVGREADER_H
#include "../../../xml/include/xmlutils.h"
namespace SVG
{
class CSvgReader
{
XmlUtils::CXmlLiteReader *m_pReader;
bool m_bParseAttribute;
public:
CSvgReader();
~CSvgReader();
// XmlUtils::CXmlLiteReader* GetReader();
bool ReadFromFile(const std::wstring& wsFilePath);
bool ReadFromString(const std::wstring& wsSvg);
unsigned int GetDepth();
bool IsEmptyNode();
bool GetBool();
int GetColor(const int& nDefault = 0x000000);
int GetInt();
double GetDouble();
std::string GetTextA();
std::wstring GetText();
const char* GetTextChar();
int GetAttributeInt(const std::string& sName, int nDefault = 0);
bool GetAttributeBool(const std::string& sName);
double GetAttributeDouble(const std::string& sName);
std::string GetAttributeA(const std::string& sName);
std::wstring GetAttribute(const std::string& sName);
bool MoveToStart();
bool MoveToFirstAttribute();
bool MoveToNextAttribute();
bool MoveToElement();
std::string GetName();
std::wstring GetNameW();
bool ReadNextSiblingNode(unsigned int unDepth);
bool ReadNextNode();
bool Read(XmlUtils::XmlNodeType& eNodeType);
private:
static int GetIntValue(CSvgReader& oXmlReader);
static bool GetBoolValue(CSvgReader& oXmlReader);
static double GetDoubleValue(CSvgReader& oXmlReader);
static std::string GetTextAValue(CSvgReader& oXmlReader);
static std::wstring GetTextValue(CSvgReader& oXmlReader);
template<typename T>
T GetAttribute(const std::string& sName, T _default, T (*GetValue)(CSvgReader& oXmlReader));
};
#define WHILE_READ_NEXT_NODE_WITH_DEPTH(xml_reader, name_depth)\
if (!xml_reader.IsEmptyNode())\
{\
const int n##name_depth = xml_reader.GetDepth();\
while (xml_reader.ReadNextSiblingNode(n##name_depth))\
{
#define WHILE_READ_NEXT_NODE_WITH_DEPTH_AND_NAME(xml_reader, name_depth)\
if (!xml_reader.IsEmptyNode())\
{\
const int n##name_depth##Depth = xml_reader.GetDepth();\
std::string sNode##name_depth##Name;\
while (xml_reader.ReadNextSiblingNode(n##name_depth##Depth))\
{\
sNode##name_depth##Name = xml_reader.GetName();
#define WHILE_READ_NEXT_NODE(xml_reader) WHILE_READ_NEXT_NODE_WITH_DEPTH(xml_reader, Depth)
#define WHILE_READ_NEXT_NODE_WITH_NAME(xml_reader)\
if (!xml_reader.IsEmptyNode())\
{\
const int nDepth = xml_reader.GetDepth();\
std::string sNodeName;\
while (xml_reader.ReadNextSiblingNode(nDepth))\
{\
sNodeName = xml_reader.GetName();
#define WHILE_READ_NEXT_NODE_WITH_DEPTH_ONE_NAME(xml_reader, name_depth, node_name)\
WHILE_READ_NEXT_NODE_WITH_DEPTH(xml_reader, name_depth)\
if (node_name != xml_reader.GetName())\
continue;
#define WHILE_READ_NEXT_NODE_WITH_ONE_NAME(xml_reader, node_name) WHILE_READ_NEXT_NODE_WITH_DEPTH_ONE_NAME(xml_reader, Depth, node_name)
#define END_WHILE } }
#define ATTRIBUTE_NAME sAttributeName
#define START_READ_ATTRIBUTES(xml_reader)\
if (xml_reader.MoveToFirstAttribute())\
{\
std::string ATTRIBUTE_NAME;\
do\
{\
ATTRIBUTE_NAME = xml_reader.GetName();
#define END_READ_ATTRIBUTES(xml_reader)\
}\
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