From 4d23382c9231de31ed7facb5b92d47c2b88646a9 Mon Sep 17 00:00:00 2001 From: Green Date: Mon, 10 Mar 2025 14:21:25 +0300 Subject: [PATCH 01/15] Added a parse of the basic structure of the OFD format --- OFDFile/OFDFile.cpp | 93 +++++++++++++++++++++ OFDFile/OFDFile.pro | 35 ++++++++ OFDFile/OfdFile.h | 41 ++++++++++ OFDFile/src/Base.cpp | 134 ++++++++++++++++++++++++++++++ OFDFile/src/Base.h | 73 +++++++++++++++++ OFDFile/src/Document.cpp | 166 ++++++++++++++++++++++++++++++++++++++ OFDFile/src/Document.h | 60 ++++++++++++++ OFDFile/src/Page.cpp | 17 ++++ OFDFile/src/Page.h | 17 ++++ OFDFile/src/PublicRes.cpp | 17 ++++ OFDFile/src/PublicRes.h | 17 ++++ OFDFile/test/main.cpp | 16 ++++ OFDFile/test/test.pro | 20 +++++ 13 files changed, 706 insertions(+) create mode 100644 OFDFile/OFDFile.cpp create mode 100644 OFDFile/OFDFile.pro create mode 100644 OFDFile/OfdFile.h create mode 100644 OFDFile/src/Base.cpp create mode 100644 OFDFile/src/Base.h create mode 100644 OFDFile/src/Document.cpp create mode 100644 OFDFile/src/Document.h create mode 100644 OFDFile/src/Page.cpp create mode 100644 OFDFile/src/Page.h create mode 100644 OFDFile/src/PublicRes.cpp create mode 100644 OFDFile/src/PublicRes.h create mode 100644 OFDFile/test/main.cpp create mode 100644 OFDFile/test/test.pro diff --git a/OFDFile/OFDFile.cpp b/OFDFile/OFDFile.cpp new file mode 100644 index 0000000000..61deab990d --- /dev/null +++ b/OFDFile/OFDFile.cpp @@ -0,0 +1,93 @@ +#include "OFDFile.h" + +#include "../OfficeUtils/src/OfficeUtils.h" + +namespace OFD +{ +COfdFile::COfdFile() +{} + +COfdFile::~COfdFile() +{ + Close(); +} + +void COfdFile::Close() +{ +} + +void COfdFile::SetTempDir(const std::wstring& wsPath) +{ + m_wsTempDir = wsPath; +} + +std::wstring COfdFile::GetTempDir() const +{ + return m_wsTempDir; +} + +bool COfdFile::Read(IFolder* pFolder) +{ + if (nullptr == pFolder) + return false; + + if (!m_oBase.Read(pFolder)) + return false; + + return false; +} + +IFolder* COfdFile::CreateTempDir() const +{ + if (!NSDirectory::Exists(m_wsTempDir)) + NSDirectory::CreateDirectory(m_wsTempDir); + + int nCounter = 0; + std::wstring wsTempFolder = m_wsTempDir + L"/OFD/"; + + while (NSDirectory::Exists(wsTempFolder)) + { + wsTempFolder = m_wsTempDir + L"/OFD" + std::to_wstring(nCounter) + L'/'; + nCounter++; + } + + NSDirectory::CreateDirectory(wsTempFolder); + + return new CFolderSystem(wsTempFolder); +} + +bool COfdFile::LoadFromFile(const std::wstring& wsFilePath) +{ + Close(); + + IFolder* pFolder = CreateTempDir(); + + if (nullptr == pFolder) + return false; + + COfficeUtils oUtils(NULL); + + if (S_OK != oUtils.ExtractToDirectory(wsFilePath, pFolder->getFullFilePath(L""), NULL, 0)) + return false; + + bool bResult = Read(pFolder); + + if (!bResult) + { + pFolder->removeDirectory(L""); + delete pFolder; + } + + return false; +} + +bool COfdFile::SaveToFile(const std::wstring& wsFilePath) +{ + return false; +} + +bool COfdFile::SaveToDir(const std::wstring& wsDir) +{ + return false; +} +} diff --git a/OFDFile/OFDFile.pro b/OFDFile/OFDFile.pro new file mode 100644 index 0000000000..e0f1ead90a --- /dev/null +++ b/OFDFile/OFDFile.pro @@ -0,0 +1,35 @@ +QT -= core gui + +VERSION = 1.0.0.1 +TARGET = OFDFile +TEMPLATE = lib + +CONFIG += shared +CONFIG += plugin + +CORE_ROOT_DIR = $$PWD/.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) + +DEFINES += OFD_USE_DYNAMIC_LIBRARY + +ADD_DEPENDENCY(graphics, kernel, UnicodeConverter) + +HEADERS += \ + OFDFile.h \ + src/Base.h \ + src/Document.h \ + src/Page.h \ + src/PublicRes.h + +SOURCES += \ + OFDFile.cpp \ + src/Base.cpp \ + src/Document.cpp \ + src/Page.cpp \ + src/PublicRes.cpp + +HEADERS += $$CORE_ROOT_DIR/OOXML/Base/Unit.h +SOURCES += $$CORE_ROOT_DIR/OOXML/Base/Unit.cpp diff --git a/OFDFile/OfdFile.h b/OFDFile/OfdFile.h new file mode 100644 index 0000000000..4f3e7c0b5f --- /dev/null +++ b/OFDFile/OfdFile.h @@ -0,0 +1,41 @@ +#ifndef OFDFILE_H +#define OFDFILE_H + +#include "../OfficeUtils/src/ZipFolder.h" + +#include "src/Base.h" + +#ifndef OFD_USE_DYNAMIC_LIBRARY +#define OFD_DECL_EXPORT +#else +#include "../DesktopEditor/common/base_export.h" +#define OFD_DECL_EXPORT Q_DECL_EXPORT +#endif + +namespace OFD +{ +class OFD_DECL_EXPORT COfdFile +{ + std::wstring m_wsTempDir; + + CBase m_oBase; + + bool Read(IFolder* pFolder); + IFolder* CreateTempDir() const; +public: + COfdFile(); + ~COfdFile(); + + void Close(); + + void SetTempDir(const std::wstring& wsPath); + std::wstring GetTempDir() const; + + bool LoadFromFile(const std::wstring& wsFilePath); + + bool SaveToFile(const std::wstring& wsFilePath); + bool SaveToDir(const std::wstring& wsDir); +}; +} + +#endif // OFDFILE_H diff --git a/OFDFile/src/Base.cpp b/OFDFile/src/Base.cpp new file mode 100644 index 0000000000..c8ed20192c --- /dev/null +++ b/OFDFile/src/Base.cpp @@ -0,0 +1,134 @@ +#include "Base.h" + +namespace OFD +{ +#define IF_CHECK_NODE(node_name, varible_name)\ +if (node_name == wsNodeName)\ + varible_name = oLiteReader.GetText2() + +#define ELSE_IF_CHECK_NODE(node_name, varible_name)\ + else if (node_name == wsNodeName)\ + varible_name = oLiteReader.GetText2() + +EDocUsege GetDocUsage(const std::wstring& wsValue) +{ + if (L"EBook" == wsValue) + return EDocUsege::EBook; + else if (L"ENewsPaper" == wsValue) + return EDocUsege::ENewsPaper; + else if (L"EMagnize" == wsValue) + return EDocUsege::EMagzine; + else + return EDocUsege::Normal; +} + +CDocInfo::CDocInfo() + : m_eDocUsage(EDocUsege::Normal) +{} + +bool CDocInfo::Read(XmlUtils::CXmlLiteReader& oLiteReader) +{ + if (L"ofd:DocInfo" != oLiteReader.GetName()) + return false; + + const int nDepth = oLiteReader.GetDepth(); + + std::wstring wsNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + IF_CHECK_NODE(L"ofd:DocID", m_wsDocId); + ELSE_IF_CHECK_NODE(L"ofd:Title", m_wsTitle); + ELSE_IF_CHECK_NODE(L"ofd:Author", m_wsAuthor); + ELSE_IF_CHECK_NODE(L"ofd:Subject", m_wsSubject); + ELSE_IF_CHECK_NODE(L"ofd:Abstruct", m_wsAbstact); + ELSE_IF_CHECK_NODE(L"ofd:CreationDate", m_wsCreationDate); + ELSE_IF_CHECK_NODE(L"ofd:ModDate", m_wsModDate); + ELSE_IF_CHECK_NODE(L"ofd:Cover", m_wsCover); + ELSE_IF_CHECK_NODE(L"ofd:Creator", m_wsCreator); + ELSE_IF_CHECK_NODE(L"ofd:CreatorVersion", m_wsCreatorVersion); + else if (L"ofd:DocUsage" == wsNodeName) + m_eDocUsage = GetDocUsage(oLiteReader.GetText2()); + } + + return true; +} + +CDocBody::CDocBody() +{ + +} + +CDocBody* CDocBody::Read(XmlUtils::CXmlLiteReader& oLiteReader, IFolder* pFolder) +{ + if (L"ofd:DocBody" != oLiteReader.GetName()) + return nullptr; + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + CDocBody *pDocBody = new CDocBody(); + + if (nullptr == pDocBody) + return nullptr; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:DocInfo" == wsNodeName) + { + if (!pDocBody->m_oDocInfo.Read(oLiteReader)) + { + delete pDocBody; + return nullptr; + } + } + else if (L"ofd:DocRoot" == wsNodeName) + { + const std::wstring wsPath = NSSystemPath::ShortenPath(oLiteReader.GetText2()); + + if (!wsPath.empty() && L'.' != wsPath.front()) + pDocBody->m_oDocument.Read(pFolder->getFullFilePath(wsPath)); + } + ELSE_IF_CHECK_NODE(L"ofd:Signatures", pDocBody->m_wsSignature); + } + + return pDocBody; +} + + +CBase::CBase() +{} + +CBase::~CBase() +{ + for (CDocBody* pDocBody : m_arDocBodies) + RELEASEOBJECT(pDocBody); +} + +bool CBase::Read(IFolder* pFolder) +{ + if (nullptr == pFolder || !pFolder->existsXml(L"OFD.xml")) + return false; + + XmlUtils::CXmlLiteReader oLiteReader; + if (!oLiteReader.FromFile(pFolder->getFullFilePath(L"OFD.xml")) || !oLiteReader.ReadNextNode() || L"ofd:OFD" != oLiteReader.GetName()) + return false; + + const int nDepth = oLiteReader.GetDepth(); + + CDocBody* pDocBody = nullptr; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + pDocBody = CDocBody::Read(oLiteReader, pFolder); + if (nullptr != pDocBody) + m_arDocBodies.push_back(pDocBody); + } + + return false; +} +} diff --git a/OFDFile/src/Base.h b/OFDFile/src/Base.h new file mode 100644 index 0000000000..27a259e8fe --- /dev/null +++ b/OFDFile/src/Base.h @@ -0,0 +1,73 @@ +#ifndef BASE_H +#define BASE_H + +#include "../../OfficeUtils/src/ZipFolder.h" + +#include "Document.h" + +namespace OFD +{ +enum class EDocUsege +{ + Normal, + EBook, + ENewsPaper, + EMagzine +}; + +class CDocInfo +{ + std::wstring m_wsDocId; + std::wstring m_wsTitle; + std::wstring m_wsAuthor; + std::wstring m_wsSubject; + std::wstring m_wsAbstact; + + std::wstring m_wsCreationDate; + std::wstring m_wsModDate; + + EDocUsege m_eDocUsage; + std::wstring m_wsCover; + std::vector m_arKeywords; + + std::wstring m_wsCreator; + std::wstring m_wsCreatorVersion; + + std::vector m_arCustomData; +public: + CDocInfo(); + bool Read(XmlUtils::CXmlLiteReader& oLiteReader); +}; + +class CDocBody +{ + CDocInfo m_oDocInfo; + CDocument m_oDocument; + // std::wstring m_wsPathToDocRoot; + // std::wstring m_wsVersions; + std::wstring m_wsSignature; +public: + CDocBody(); + static CDocBody* Read(XmlUtils::CXmlLiteReader& oLiteReader, IFolder* pFolder); +}; + + +class CBase +{ + std::vector m_arDocBodies; +public: + CBase(); + ~CBase(); + + bool Read(IFolder* pFolder); + + std::wstring GetDocId() const; + std::wstring GetCreationDate() const; + std::wstring GetCreator() const; + std::wstring GetCreatorVersion() const; + + std::wstring GetpathToDocRoot() const; +}; +} + +#endif // BASE_H diff --git a/OFDFile/src/Document.cpp b/OFDFile/src/Document.cpp new file mode 100644 index 0000000000..1345d9ad60 --- /dev/null +++ b/OFDFile/src/Document.cpp @@ -0,0 +1,166 @@ +#include "Document.h" + +#include "../../DesktopEditor/common/StringExt.h" +#include "../../OOXML/Base/Unit.h" +#include + +namespace OFD +{ +#define OFD_EPSILON 0.0001 + +CPageArea::CPageArea() +{} + +bool CPageArea::Read(XmlUtils::CXmlLiteReader& oLiteReader) +{ + if (L"ofd:PageArea" != oLiteReader.GetName()) + return false; + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:PhysicalBox" == wsNodeName) + m_oPhysicalBox.Read(oLiteReader.GetText2()); + else if (L"ofd:ApplicationBox" == wsNodeName) + m_oApplicationBox.Read(oLiteReader.GetText2()); + else if (L"ofd:ContentBox" == wsNodeName) + m_oContentBox.Read(oLiteReader.GetText2()); + else if (L"ofd:BleedBox" == wsNodeName) + m_oBleedBox.Read(oLiteReader.GetText2()); + } + + return true; +} + +CCommonData::CCommonData() + : m_unMaxUnitID(0) +{} + +bool CCommonData::Read(XmlUtils::CXmlLiteReader& oLiteReader) +{ + if (L"ofd:CommonData" != oLiteReader.GetName()) + return false; + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:PageArea" == wsNodeName) + m_oPageArea.Read(oLiteReader); + else if (L"ofd:PublicRes" == wsNodeName) + { + // m_oPublicRes.Read(); + } + else if (L"ofd:MaxUnitID" == wsNodeName) + m_unMaxUnitID = XmlUtils::GetUInteger(oLiteReader.GetText2()); + // else if (L"ofd:DocumentRes" == wsNodeName) + // else if (L"ofd:TemplatePage" == wsNodeName) + // else if (L"ofd:DefaultCS" == wsNodeName) + } + + return true; +} + +CDocument::CDocument() +{} + +CDocument::~CDocument() +{ + for (std::pair oElement : m_mPages) + delete oElement.second; +} + +bool CDocument::Empty() const +{ + return m_mPages.empty(); +} + +bool CDocument::Read(const std::wstring& wsFilePath) +{ + if (wsFilePath.empty()) + return false; + + XmlUtils::CXmlLiteReader oLiteReader; + if (!oLiteReader.FromFile(wsFilePath) || !oLiteReader.ReadNextNode() || L"ofd:Document" != oLiteReader.GetName()) + return false; + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:CommonData" == wsNodeName) + m_oCommonData.Read(oLiteReader); + else if (L"ofd:Pages" == wsNodeName) + { + const int nPagesDepth = oLiteReader.GetDepth(); + + int nID = -1; + std::wstring wsBaseLoc; + + while (oLiteReader.ReadNextSiblingNode(nPagesDepth)) + { + if (L"ofd:Page" != oLiteReader.GetName() || 2 > oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) + continue; + + do + { + if (L"ID" == oLiteReader.GetName()) + nID = XmlUtils::GetUInteger(oLiteReader.GetText()); + else if (L"BaseLoc" == oLiteReader.GetName()) + wsBaseLoc = oLiteReader.GetText(); + }while (oLiteReader.MoveToNextAttribute()); + + if (wsBaseLoc.empty()) + continue; + + if (-1 == nID) + nID = m_mPages.size() + 1; + + CPage* pPage = CPage::Read(NSSystemPath::Combine(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc)); + + if (nullptr != pPage) + m_mPages.insert(std::make_pair(nID, pPage)); + + wsBaseLoc.clear(); + oLiteReader.MoveToElement(); + } + } + } + + return false; +} + +TBox::TBox() + : m_dX(0.), m_dY(0.), m_dWidth(0.), m_dHeight(0.) +{} + +bool TBox::Empty() const +{ + return m_dWidth < OFD_EPSILON || m_dHeight < OFD_EPSILON; +} + +bool TBox::Read(const std::wstring& wsValue) +{ + const std::vector arValues{NSStringExt::Split(wsValue, L' ')}; + + if (4 > arValues.size()) + return false; + + m_dX = XmlUtils::GetDouble(arValues[0]); + m_dY = XmlUtils::GetDouble(arValues[1]); + m_dWidth = XmlUtils::GetDouble(arValues[2]); + m_dHeight = XmlUtils::GetDouble(arValues[3]); + + return true; +} +} diff --git a/OFDFile/src/Document.h b/OFDFile/src/Document.h new file mode 100644 index 0000000000..578267417c --- /dev/null +++ b/OFDFile/src/Document.h @@ -0,0 +1,60 @@ +#ifndef DOCUMENT_H +#define DOCUMENT_H + +#include "Page.h" +#include "PublicRes.h" + +namespace OFD +{ +struct TBox +{ + double m_dX; + double m_dY; + double m_dWidth; + double m_dHeight; + + TBox(); + + bool Empty() const; + bool Read(const std::wstring& wsValue); +}; + +class CPageArea +{ + TBox m_oPhysicalBox; + TBox m_oApplicationBox; + TBox m_oContentBox; + TBox m_oBleedBox; +public: + CPageArea(); + + bool Read(XmlUtils::CXmlLiteReader& oLiteReader); +}; + +class CCommonData +{ + unsigned int m_unMaxUnitID; + CPageArea m_oPageArea; + CPublicRes m_oPublicRes; +public: + CCommonData(); + + bool Read(XmlUtils::CXmlLiteReader& oLiteReader); +}; + +class CDocument +{ + CCommonData m_oCommonData; + + std::map m_mPages; +public: + CDocument(); + ~CDocument(); + + bool Empty() const; + + bool Read(const std::wstring& wsFilePath); +}; +} + +#endif // DOCUMENT_H diff --git a/OFDFile/src/Page.cpp b/OFDFile/src/Page.cpp new file mode 100644 index 0000000000..c69bdf3196 --- /dev/null +++ b/OFDFile/src/Page.cpp @@ -0,0 +1,17 @@ +#include "Page.h" + +namespace OFD +{ +CPage::CPage() +{ + +} + +CPage* CPage::Read(const std::wstring& wsFilePath) +{ + if (wsFilePath.empty()) + return nullptr; + + return nullptr; +} +} diff --git a/OFDFile/src/Page.h b/OFDFile/src/Page.h new file mode 100644 index 0000000000..3340ef0cc8 --- /dev/null +++ b/OFDFile/src/Page.h @@ -0,0 +1,17 @@ +#ifndef PAGE_H +#define PAGE_H + +#include "../../OfficeUtils/src/ZipFolder.h" + +namespace OFD +{ +class CPage +{ +public: + CPage(); + + static CPage* Read(const std::wstring& wsFilePath); +}; +} + +#endif // PAGE_H diff --git a/OFDFile/src/PublicRes.cpp b/OFDFile/src/PublicRes.cpp new file mode 100644 index 0000000000..70a004cf38 --- /dev/null +++ b/OFDFile/src/PublicRes.cpp @@ -0,0 +1,17 @@ +#include "PublicRes.h" + +namespace OFD +{ +CPublicRes::CPublicRes() +{ + +} + +bool CPublicRes::Read(IFolder* pFolder) +{ + if (nullptr == pFolder) + return false; + + return false; +} +} diff --git a/OFDFile/src/PublicRes.h b/OFDFile/src/PublicRes.h new file mode 100644 index 0000000000..f9267c9818 --- /dev/null +++ b/OFDFile/src/PublicRes.h @@ -0,0 +1,17 @@ +#ifndef PUBLICRES_H +#define PUBLICRES_H + +#include "../../OfficeUtils/src/ZipFolder.h" + +namespace OFD +{ +class CPublicRes +{ +public: + CPublicRes(); + + bool Read(IFolder* pFolder); +}; +} + +#endif // PUBLICRES_H diff --git a/OFDFile/test/main.cpp b/OFDFile/test/main.cpp new file mode 100644 index 0000000000..2e2c2d6e42 --- /dev/null +++ b/OFDFile/test/main.cpp @@ -0,0 +1,16 @@ +#include "../OfdFile.h" +#include + +int main() +{ + OFD::COfdFile oOfdFile; + + oOfdFile.SetTempDir(L"temp"); + + if (oOfdFile.LoadFromFile(L"YOUR_PATH")) + std::cout << "GOOD" << std::endl; + else + std::cout << "BAD" << std::endl; + + return 0; +} diff --git a/OFDFile/test/test.pro b/OFDFile/test/test.pro new file mode 100644 index 0000000000..548db9b932 --- /dev/null +++ b/OFDFile/test/test.pro @@ -0,0 +1,20 @@ +QT -= core +QT -= gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle +TEMPLATE = app + +DEFINES += OFD_USE_DYNAMIC_LIBRARY + +SOURCES += main.cpp + +CORE_ROOT_DIR = $$PWD/../../ +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) + +ADD_DEPENDENCY(kernel, UnicodeConverter, OFDFile) + +DESTDIR = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX From 84ecffa75ed1feef8e0a9565c1c5b8f17c3e6a3b Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 11 Mar 2025 11:06:07 +0300 Subject: [PATCH 02/15] Added a parse of the basic structure and text in word format --- OFDFile/OFDFile.pro | 16 +++- OFDFile/src/Content/Content.cpp | 34 ++++++++ OFDFile/src/Content/Content.h | 19 +++++ OFDFile/src/Content/GraphicUnit.cpp | 65 +++++++++++++++ OFDFile/src/Content/GraphicUnit.h | 42 ++++++++++ OFDFile/src/Content/IPageBlock.h | 18 ++++ OFDFile/src/Content/Layer.cpp | 56 +++++++++++++ OFDFile/src/Content/Layer.h | 27 ++++++ OFDFile/src/Content/TextObject.cpp | 124 ++++++++++++++++++++++++++++ OFDFile/src/Content/TextObject.h | 46 +++++++++++ OFDFile/src/Document.cpp | 28 ------- OFDFile/src/Document.h | 15 +--- OFDFile/src/Page.cpp | 29 ++++++- OFDFile/src/Page.h | 3 +- OFDFile/src/Utils/Types.cpp | 49 +++++++++++ OFDFile/src/Utils/Types.h | 34 ++++++++ OFDFile/src/Utils/Utils.h | 49 +++++++++++ 17 files changed, 609 insertions(+), 45 deletions(-) create mode 100644 OFDFile/src/Content/Content.cpp create mode 100644 OFDFile/src/Content/Content.h create mode 100644 OFDFile/src/Content/GraphicUnit.cpp create mode 100644 OFDFile/src/Content/GraphicUnit.h create mode 100644 OFDFile/src/Content/IPageBlock.h create mode 100644 OFDFile/src/Content/Layer.cpp create mode 100644 OFDFile/src/Content/Layer.h create mode 100644 OFDFile/src/Content/TextObject.cpp create mode 100644 OFDFile/src/Content/TextObject.h create mode 100644 OFDFile/src/Utils/Types.cpp create mode 100644 OFDFile/src/Utils/Types.h create mode 100644 OFDFile/src/Utils/Utils.h diff --git a/OFDFile/OFDFile.pro b/OFDFile/OFDFile.pro index e0f1ead90a..252fe83a1e 100644 --- a/OFDFile/OFDFile.pro +++ b/OFDFile/OFDFile.pro @@ -20,16 +20,28 @@ ADD_DEPENDENCY(graphics, kernel, UnicodeConverter) HEADERS += \ OFDFile.h \ src/Base.h \ + src/Content/Content.h \ + src/Content/GraphicUnit.h \ + src/Content/IPageBlock.h \ + src/Content/Layer.h \ + src/Content/TextObject.h \ src/Document.h \ src/Page.h \ - src/PublicRes.h + src/PublicRes.h \ + src/Utils/Types.h \ + src/Utils/Utils.h SOURCES += \ OFDFile.cpp \ src/Base.cpp \ + src/Content/Content.cpp \ + src/Content/GraphicUnit.cpp \ + src/Content/Layer.cpp \ + src/Content/TextObject.cpp \ src/Document.cpp \ src/Page.cpp \ - src/PublicRes.cpp + src/PublicRes.cpp \ + src/Utils/Types.cpp HEADERS += $$CORE_ROOT_DIR/OOXML/Base/Unit.h SOURCES += $$CORE_ROOT_DIR/OOXML/Base/Unit.cpp diff --git a/OFDFile/src/Content/Content.cpp b/OFDFile/src/Content/Content.cpp new file mode 100644 index 0000000000..506adcdefc --- /dev/null +++ b/OFDFile/src/Content/Content.cpp @@ -0,0 +1,34 @@ +#include "Content.h" + +namespace OFD +{ +CContent::CContent() +{ + +} + +CContent::~CContent() +{ + for (CLayer* pLayer : m_arLayers) + delete pLayer; +} + +bool CContent::Read(XmlUtils::CXmlLiteReader& oLiteReader) +{ + if (L"ofd:Content" != oLiteReader.GetName()) + return false; + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:Layer" == wsNodeName) + m_arLayers.push_back(new CLayer(oLiteReader)); + } + + return false; +} +} diff --git a/OFDFile/src/Content/Content.h b/OFDFile/src/Content/Content.h new file mode 100644 index 0000000000..ed51011cf5 --- /dev/null +++ b/OFDFile/src/Content/Content.h @@ -0,0 +1,19 @@ +#ifndef CONTENT_H +#define CONTENT_H + +#include "Layer.h" + +namespace OFD +{ +class CContent +{ + std::vector m_arLayers; +public: + CContent(); + ~CContent(); + + bool Read(XmlUtils::CXmlLiteReader& oLiteReader); +}; +} + +#endif // CONTENT_H diff --git a/OFDFile/src/Content/GraphicUnit.cpp b/OFDFile/src/Content/GraphicUnit.cpp new file mode 100644 index 0000000000..0fd51c87ad --- /dev/null +++ b/OFDFile/src/Content/GraphicUnit.cpp @@ -0,0 +1,65 @@ +#include "GraphicUnit.h" +#include "../../../OOXML/Base/Unit.h" + +namespace OFD +{ +CGraphicUnit::CGraphicUnit(XmlUtils::CXmlLiteReader& oLiteReader) + : m_bVisible(true), m_dLineWidth(0.353), m_eCap(ECap::Butt), + m_eJoin(EJoin::Miter), m_dMiterLimit(4.234), m_dDashOffset(0.), + m_uchAlpha(255) +{ + if (0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) + return; + + std::wstring wsAttributeName; + + do + { + wsAttributeName = oLiteReader.GetName(); + + if (L"Boundary" == wsAttributeName) + m_oBoundary.Read(oLiteReader.GetText()); + else if (L"Name" == wsAttributeName) + m_wsName = oLiteReader.GetText(); + else if (L"Visible" == wsAttributeName) + m_bVisible = XmlUtils::GetBoolean(oLiteReader.GetText()); + else if (L"CTM" == wsAttributeName) + m_oCTM.Read(oLiteReader.GetText()); + else if (L"DrawParam" == wsAttributeName) + m_unDrawParam = XmlUtils::GetUInteger(oLiteReader.GetText()); + else if (L"LineWidth" == wsAttributeName) + m_dLineWidth = XmlUtils::GetDouble(oLiteReader.GetText()); + else if (L"Cap" == wsAttributeName) + { + const std::wstring wsValue{oLiteReader.GetText()}; + + if (L"Butt" == wsValue) + m_eCap = ECap::Butt; + else if (L"Round" == wsValue) + m_eCap = ECap::Round; + else if (L"Square" == wsValue) + m_eCap = ECap::Square; + } + else if (L"Join" == wsAttributeName) + { + const std::wstring wsValue{oLiteReader.GetText()}; + + if (L"Miter" == wsValue) + m_eJoin = EJoin::Miter; + else if (L"Round" == wsValue) + m_eJoin = EJoin::Round; + else if (L"Bevel" == wsValue) + m_eJoin = EJoin::Bevel; + } + else if (L"MiterLimit" == wsAttributeName) + m_dMiterLimit = XmlUtils::GetDouble(oLiteReader.GetText()); + else if (L"DashOffset" == wsAttributeName) + m_dDashOffset = XmlUtils::GetDouble(oLiteReader.GetText()); + else if (L"Alpha" == wsAttributeName) + m_uchAlpha = XmlUtils::GetUInteger(oLiteReader.GetText()); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); +} + +} diff --git a/OFDFile/src/Content/GraphicUnit.h b/OFDFile/src/Content/GraphicUnit.h new file mode 100644 index 0000000000..764ecdcac0 --- /dev/null +++ b/OFDFile/src/Content/GraphicUnit.h @@ -0,0 +1,42 @@ +#ifndef GRAPHICUNIT_H +#define GRAPHICUNIT_H + +#include "../../../DesktopEditor/xml/include/xmlutils.h" +#include "../Utils/Types.h" +#include + +namespace OFD +{ +class CGraphicUnit +{ + TBox m_oBoundary; + std::wstring m_wsName; + bool m_bVisible; + TBox m_oCTM; + unsigned int m_unDrawParam; + double m_dLineWidth; + + enum class ECap + { + Butt, + Round, + Square + } m_eCap; + + enum class EJoin + { + Miter, + Round, + Bevel + } m_eJoin; + + double m_dMiterLimit; + double m_dDashOffset; + std::vector m_arDashPattern; + unsigned char m_uchAlpha; +public: + CGraphicUnit(XmlUtils::CXmlLiteReader& oLiteReader); +}; +} + +#endif // GRAPHICUNIT_H diff --git a/OFDFile/src/Content/IPageBlock.h b/OFDFile/src/Content/IPageBlock.h new file mode 100644 index 0000000000..4769b2aa45 --- /dev/null +++ b/OFDFile/src/Content/IPageBlock.h @@ -0,0 +1,18 @@ +#ifndef IPAGEBLOCK_H +#define IPAGEBLOCK_H + +#include "../../../DesktopEditor/xml/include/xmlutils.h" + +namespace OFD +{ +class IPageBlock +{ + unsigned int m_unID; +public: + IPageBlock(){}; + virtual ~IPageBlock(){}; + virtual bool Read(XmlUtils::CXmlLiteReader& oLiteReader) = 0; +}; +} + +#endif // IPAGEBLOCK_H diff --git a/OFDFile/src/Content/Layer.cpp b/OFDFile/src/Content/Layer.cpp new file mode 100644 index 0000000000..a8aacad283 --- /dev/null +++ b/OFDFile/src/Content/Layer.cpp @@ -0,0 +1,56 @@ +#include "Layer.h" + +#include "../../../OOXML/Base/Unit.h" + +#include "TextObject.h" + +namespace OFD +{ +CLayer::CLayer(XmlUtils::CXmlLiteReader& oLiteReader) + : m_eType(EType::Body) +{ + Read(oLiteReader); +} + +CLayer::~CLayer() +{ + for (IPageBlock* pPageBlock : m_arPageBlocks) + delete pPageBlock; +} + +bool CLayer::Read(XmlUtils::CXmlLiteReader& oLiteReader) +{ + if (L"ofd:Layer" != oLiteReader.GetName()) + return false; + + if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) + { + do + { + if (L"ID" == oLiteReader.GetName()) + m_unID = XmlUtils::GetUInteger(oLiteReader.GetText()); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); + } + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + IPageBlock* pPageBlock = nullptr; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + pPageBlock = nullptr; + + if (L"ofd:TextObject" == wsNodeName) + pPageBlock = new CTextObject(oLiteReader); + + if (nullptr != pPageBlock) + m_arPageBlocks.push_back(pPageBlock); + } + + return true; +} +} diff --git a/OFDFile/src/Content/Layer.h b/OFDFile/src/Content/Layer.h new file mode 100644 index 0000000000..5e4a66a3c2 --- /dev/null +++ b/OFDFile/src/Content/Layer.h @@ -0,0 +1,27 @@ +#ifndef LAYER_H +#define LAYER_H + +#include "IPageBlock.h" + +namespace OFD +{ +class CLayer +{ + enum class EType + { + Body, + Foreground, + Background + } m_eType; + + unsigned int m_unID; + std::vector m_arPageBlocks; +public: + CLayer(XmlUtils::CXmlLiteReader& oLiteReader); + ~CLayer(); + + bool Read(XmlUtils::CXmlLiteReader& oLiteReader); +}; +} + +#endif // LAYER_H diff --git a/OFDFile/src/Content/TextObject.cpp b/OFDFile/src/Content/TextObject.cpp new file mode 100644 index 0000000000..8cc9dae630 --- /dev/null +++ b/OFDFile/src/Content/TextObject.cpp @@ -0,0 +1,124 @@ +#include "TextObject.h" + +#include "../Utils/Utils.h" + +namespace OFD +{ +CTextCode::CTextCode(XmlUtils::CXmlLiteReader& oLiteReader) +{ + if (NO_VALID_NODE(oLiteReader, L"ofd:TextCode")) + return; + + if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) + { + std::wstring wsAttributeName; + + do + { + wsAttributeName = oLiteReader.GetName(); + + if (L"X" == wsAttributeName) + m_dX = XmlUtils::GetDouble(oLiteReader.GetText()); + else if (L"Y" == wsAttributeName) + m_dY = XmlUtils::GetDouble(oLiteReader.GetText()); + else if (L"DeltaX" == wsAttributeName) + m_arDeltaX = GetDoubleValues(oLiteReader.GetText()); + else if (L"DeltaY" == wsAttributeName) + m_arDeltaY = GetDoubleValues(oLiteReader.GetText()); + } while (oLiteReader.MoveToNextAttribute()); + } + + oLiteReader.MoveToElement(); + + m_wsText = oLiteReader.GetText2(); +} + +CTextObject::CTextObject(XmlUtils::CXmlLiteReader& oLiteReader) + : CGraphicUnit(oLiteReader), + m_bStroke(false), m_bFill(false), m_dHScale(1.), + m_unReadDirection(0), m_unCharDirection(0), m_unWeight(400), + m_bItalic(false), + m_pFillColor(nullptr), m_pStrokeColor(nullptr) +{ + CTextObject::Read(oLiteReader); +} + +CTextObject::~CTextObject() +{ + if (nullptr != m_pFillColor) + delete m_pFillColor; + + if (nullptr != m_pStrokeColor) + delete m_pStrokeColor; + + for (CTextCode* pTextCode : m_arTextCodes) + delete pTextCode; +} + +bool CTextObject::Read(XmlUtils::CXmlLiteReader& oLiteReader) +{ + if (NO_VALID_NODE(oLiteReader, L"ofd:TextObject")) + return false; + + if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) + { + std::wstring wsAttributeName; + + do + { + wsAttributeName = oLiteReader.GetName(); + + if (L"Font" == wsAttributeName) + { + m_unFont = XmlUtils::GetUInteger(oLiteReader.GetText()); + } + else if (L"Size" == wsAttributeName) + m_dSize = XmlUtils::GetDouble(oLiteReader.GetText()); + else if (L"Stroke" == wsAttributeName) + m_bStroke = XmlUtils::GetBoolean(oLiteReader.GetText()); + else if (L"Fill" == wsAttributeName) + m_bFill = XmlUtils::GetBoolean(oLiteReader.GetText()); + else if (L"HScale" == wsAttributeName) + m_dHScale = XmlUtils::GetDouble(oLiteReader.GetText()); + else if (L"ReadDirection" == wsAttributeName) + m_unReadDirection = XmlUtils::GetUInteger(oLiteReader.GetText()); + else if (L"CharDirection" == wsAttributeName) + m_unCharDirection = XmlUtils::GetUInteger(oLiteReader.GetText()); + else if (L"Weight" == wsAttributeName) + m_unWeight = XmlUtils::GetUInteger(oLiteReader.GetText()); + else if (L"Italic" == wsAttributeName) + m_bItalic = XmlUtils::GetBoolean(oLiteReader.GetText()); + } while (oLiteReader.MoveToNextAttribute()); + } + + oLiteReader.MoveToElement(); + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:FillColor" == wsNodeName && m_bFill) + { + if (nullptr != m_pFillColor) + delete m_pFillColor; + + m_pFillColor = new TColor(oLiteReader); + } + else if (L"ofd:StrokeColor" == wsNodeName && m_bStroke) + { + if (nullptr != m_pStrokeColor) + delete m_pStrokeColor; + + m_pStrokeColor = new TColor(oLiteReader); + } + else if (L"ofd:TextCode" == wsNodeName) + m_arTextCodes.push_back(new CTextCode(oLiteReader)); + } + + return true; +} + +} diff --git a/OFDFile/src/Content/TextObject.h b/OFDFile/src/Content/TextObject.h new file mode 100644 index 0000000000..d748f2c96a --- /dev/null +++ b/OFDFile/src/Content/TextObject.h @@ -0,0 +1,46 @@ +#ifndef TEXTOBJECT_H +#define TEXTOBJECT_H + +#include "IPageBlock.h" +#include "GraphicUnit.h" + +namespace OFD +{ +class CTextCode +{ + double m_dX; + double m_dY; + + std::vector m_arDeltaX; + std::vector m_arDeltaY; + + std::wstring m_wsText; +public: + CTextCode(XmlUtils::CXmlLiteReader& oLiteReader); +}; + +class CTextObject : public IPageBlock, public CGraphicUnit +{ + unsigned int m_unFont; + double m_dSize; + bool m_bStroke; + bool m_bFill; + double m_dHScale; + unsigned int m_unReadDirection; + unsigned int m_unCharDirection; + unsigned int m_unWeight; + bool m_bItalic; + + TColor* m_pFillColor; + TColor* m_pStrokeColor; + + std::vector m_arTextCodes; +public: + CTextObject(XmlUtils::CXmlLiteReader& oLiteReader); + ~CTextObject(); + + virtual bool Read(XmlUtils::CXmlLiteReader& oLiteReader) override; +}; +} + +#endif // TEXTOBJECT_H diff --git a/OFDFile/src/Document.cpp b/OFDFile/src/Document.cpp index 1345d9ad60..7e39cbb447 100644 --- a/OFDFile/src/Document.cpp +++ b/OFDFile/src/Document.cpp @@ -1,13 +1,9 @@ #include "Document.h" -#include "../../DesktopEditor/common/StringExt.h" #include "../../OOXML/Base/Unit.h" -#include namespace OFD { -#define OFD_EPSILON 0.0001 - CPageArea::CPageArea() {} @@ -139,28 +135,4 @@ bool CDocument::Read(const std::wstring& wsFilePath) return false; } - -TBox::TBox() - : m_dX(0.), m_dY(0.), m_dWidth(0.), m_dHeight(0.) -{} - -bool TBox::Empty() const -{ - return m_dWidth < OFD_EPSILON || m_dHeight < OFD_EPSILON; -} - -bool TBox::Read(const std::wstring& wsValue) -{ - const std::vector arValues{NSStringExt::Split(wsValue, L' ')}; - - if (4 > arValues.size()) - return false; - - m_dX = XmlUtils::GetDouble(arValues[0]); - m_dY = XmlUtils::GetDouble(arValues[1]); - m_dWidth = XmlUtils::GetDouble(arValues[2]); - m_dHeight = XmlUtils::GetDouble(arValues[3]); - - return true; -} } diff --git a/OFDFile/src/Document.h b/OFDFile/src/Document.h index 578267417c..3171275666 100644 --- a/OFDFile/src/Document.h +++ b/OFDFile/src/Document.h @@ -4,21 +4,10 @@ #include "Page.h" #include "PublicRes.h" +#include "Utils/Types.h" + namespace OFD { -struct TBox -{ - double m_dX; - double m_dY; - double m_dWidth; - double m_dHeight; - - TBox(); - - bool Empty() const; - bool Read(const std::wstring& wsValue); -}; - class CPageArea { TBox m_oPhysicalBox; diff --git a/OFDFile/src/Page.cpp b/OFDFile/src/Page.cpp index c69bdf3196..6a66d21875 100644 --- a/OFDFile/src/Page.cpp +++ b/OFDFile/src/Page.cpp @@ -1,5 +1,9 @@ #include "Page.h" +#include +#include "../../DesktopEditor/common/File.h" +#include "../../DesktopEditor/common/Path.h" + namespace OFD { CPage::CPage() @@ -12,6 +16,29 @@ CPage* CPage::Read(const std::wstring& wsFilePath) if (wsFilePath.empty()) return nullptr; - return nullptr; + std::wstring wsNormalizedPath = wsFilePath; + + if (L"xml" != NSFile::GetFileExtention(wsNormalizedPath)) + wsNormalizedPath = NSSystemPath::Combine(wsNormalizedPath, L"Content.xml"); + + + XmlUtils::CXmlLiteReader oLiteReader; + if (!oLiteReader.FromFile(wsNormalizedPath) || !oLiteReader.ReadNextNode() || L"ofd:Page" != oLiteReader.GetName()) + return nullptr; + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + CPage *pPage = new CPage(); + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:Content" == wsNodeName) + pPage->m_oContent.Read(oLiteReader); + } + + return pPage; } } diff --git a/OFDFile/src/Page.h b/OFDFile/src/Page.h index 3340ef0cc8..f605eb9d8b 100644 --- a/OFDFile/src/Page.h +++ b/OFDFile/src/Page.h @@ -1,12 +1,13 @@ #ifndef PAGE_H #define PAGE_H -#include "../../OfficeUtils/src/ZipFolder.h" +#include "Content/Content.h" namespace OFD { class CPage { + CContent m_oContent; public: CPage(); diff --git a/OFDFile/src/Utils/Types.cpp b/OFDFile/src/Utils/Types.cpp new file mode 100644 index 0000000000..52ffb6a125 --- /dev/null +++ b/OFDFile/src/Utils/Types.cpp @@ -0,0 +1,49 @@ +#include "Types.h" + +#include +#include "../../../DesktopEditor/common/StringExt.h" +#include "../../../OOXML/Base/Unit.h" + +namespace OFD +{ +TBox::TBox() + : m_dX(0.), m_dY(0.), m_dWidth(0.), m_dHeight(0.) +{} + +bool TBox::Empty() const +{ + return m_dWidth < OFD_EPSILON || m_dHeight < OFD_EPSILON; +} + +bool TBox::Read(const std::wstring& wsValue) +{ + const std::vector arValues{NSStringExt::Split(wsValue, L' ')}; + + if (4 > arValues.size()) + return false; + + m_dX = XmlUtils::GetDouble(arValues[0]); + m_dY = XmlUtils::GetDouble(arValues[1]); + m_dWidth = XmlUtils::GetDouble(arValues[2]); + m_dHeight = XmlUtils::GetDouble(arValues[3]); + + return true; +} + + + +TColor::TColor() +{ +} + +TColor::TColor(XmlUtils::CXmlLiteReader& oLiteReader) +{ + Read(oLiteReader); +} + +bool TColor::Read(XmlUtils::CXmlLiteReader& oLiteReader) +{ + return false; +} + +} diff --git a/OFDFile/src/Utils/Types.h b/OFDFile/src/Utils/Types.h new file mode 100644 index 0000000000..9b38b1b8c7 --- /dev/null +++ b/OFDFile/src/Utils/Types.h @@ -0,0 +1,34 @@ +#ifndef TYPES_H +#define TYPES_H + +#include +#include "../../../DesktopEditor/xml/include/xmlutils.h" + + +namespace OFD +{ +#define OFD_EPSILON 0.0001 + +struct TBox +{ + double m_dX; + double m_dY; + double m_dWidth; + double m_dHeight; + + TBox(); + + bool Empty() const; + bool Read(const std::wstring& wsValue); +}; + +struct TColor +{ + TColor(); + TColor(XmlUtils::CXmlLiteReader& oLiteReader); + + bool Read(XmlUtils::CXmlLiteReader& oLiteReader); +}; +} + +#endif // TYPES_H diff --git a/OFDFile/src/Utils/Utils.h b/OFDFile/src/Utils/Utils.h new file mode 100644 index 0000000000..1b220e8724 --- /dev/null +++ b/OFDFile/src/Utils/Utils.h @@ -0,0 +1,49 @@ +#ifndef UTILS_H +#define UTILS_H + + +#include +#include +#include "../../../OOXML/Base/Unit.h" +#include "../../../DesktopEditor/common/StringExt.h" + +bool GetBoolean(const std::wstring& wsValue) +{ + return false; +} + +int GetInt(const std::wstring& wsValue) +{ + return 0; +} + +unsigned int GetUInt(const std::wstring& wsValue) +{ + return 0; +} + +double GetDouble(const std::wstring& wsValue) +{ + return 0.; +} + + + +std::vector GetDoubleValues(const std::wstring& wsValue) +{ + const std::vector arValues{NSStringExt::Split(wsValue, L' ')}; + + if(arValues.empty()) + return std::vector(); + + std::vector arDoubleValues(arValues.size()); + + for (unsigned int unIndex = 0; unIndex < arValues.size(); ++unIndex) + arDoubleValues[unIndex] = XmlUtils::GetDouble(arValues[unIndex]); + + return arDoubleValues; +} + +#define NO_VALID_NODE(lite_reader, node_name) node_name != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid() + +#endif // UTILS_H From 7252d29579400b7c97eb33b1ed79000782eeb9ea Mon Sep 17 00:00:00 2001 From: Green Date: Wed, 19 Mar 2025 15:47:49 +0300 Subject: [PATCH 03/15] Improved pars of the OFD format structure --- OFDFile/OFDFile.pro | 11 ++-- OFDFile/src/Base.cpp | 6 +- OFDFile/src/Base.h | 14 ++--- OFDFile/src/Content/Content.cpp | 6 +- OFDFile/src/Content/Content.h | 2 +- OFDFile/src/Content/GraphicUnit.cpp | 24 +++---- OFDFile/src/Content/GraphicUnit.h | 4 +- OFDFile/src/Content/IPageBlock.h | 4 +- OFDFile/src/Content/Layer.cpp | 6 +- OFDFile/src/Content/Layer.h | 4 +- OFDFile/src/Content/TextObject.cpp | 52 +++++++--------- OFDFile/src/Content/TextObject.h | 12 ++-- OFDFile/src/Document.cpp | 44 +++++++++---- OFDFile/src/Document.h | 18 +++++- OFDFile/src/Page.cpp | 3 +- OFDFile/src/Types/Color.cpp | 15 +++++ OFDFile/src/Types/Color.h | 32 ++++++++++ OFDFile/src/Utils/Types.cpp | 34 +++------- OFDFile/src/Utils/Types.h | 13 +--- OFDFile/src/Utils/Utils.h | 97 +++++++++++++++++++++-------- OFDFile/src/Utils/XmlReader.cpp | 63 +++++++++++++++++++ OFDFile/src/Utils/XmlReader.h | 25 ++++++++ 22 files changed, 337 insertions(+), 152 deletions(-) create mode 100644 OFDFile/src/Types/Color.cpp create mode 100644 OFDFile/src/Types/Color.h create mode 100644 OFDFile/src/Utils/XmlReader.cpp create mode 100644 OFDFile/src/Utils/XmlReader.h diff --git a/OFDFile/OFDFile.pro b/OFDFile/OFDFile.pro index 252fe83a1e..926731ed2a 100644 --- a/OFDFile/OFDFile.pro +++ b/OFDFile/OFDFile.pro @@ -28,8 +28,10 @@ HEADERS += \ src/Document.h \ src/Page.h \ src/PublicRes.h \ + src/Types/Color.h \ src/Utils/Types.h \ - src/Utils/Utils.h + src/Utils/Utils.h \ + src/Utils/XmlReader.h SOURCES += \ OFDFile.cpp \ @@ -41,7 +43,6 @@ SOURCES += \ src/Document.cpp \ src/Page.cpp \ src/PublicRes.cpp \ - src/Utils/Types.cpp - -HEADERS += $$CORE_ROOT_DIR/OOXML/Base/Unit.h -SOURCES += $$CORE_ROOT_DIR/OOXML/Base/Unit.cpp + src/Types/Color.cpp \ + src/Utils/Types.cpp \ + src/Utils/XmlReader.cpp diff --git a/OFDFile/src/Base.cpp b/OFDFile/src/Base.cpp index c8ed20192c..287c3722b3 100644 --- a/OFDFile/src/Base.cpp +++ b/OFDFile/src/Base.cpp @@ -26,7 +26,7 @@ CDocInfo::CDocInfo() : m_eDocUsage(EDocUsege::Normal) {} -bool CDocInfo::Read(XmlUtils::CXmlLiteReader& oLiteReader) +bool CDocInfo::Read(CXmlReader& oLiteReader) { if (L"ofd:DocInfo" != oLiteReader.GetName()) return false; @@ -61,7 +61,7 @@ CDocBody::CDocBody() } -CDocBody* CDocBody::Read(XmlUtils::CXmlLiteReader& oLiteReader, IFolder* pFolder) +CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) { if (L"ofd:DocBody" != oLiteReader.GetName()) return nullptr; @@ -114,7 +114,7 @@ bool CBase::Read(IFolder* pFolder) if (nullptr == pFolder || !pFolder->existsXml(L"OFD.xml")) return false; - XmlUtils::CXmlLiteReader oLiteReader; + CXmlReader oLiteReader; if (!oLiteReader.FromFile(pFolder->getFullFilePath(L"OFD.xml")) || !oLiteReader.ReadNextNode() || L"ofd:OFD" != oLiteReader.GetName()) return false; diff --git a/OFDFile/src/Base.h b/OFDFile/src/Base.h index 27a259e8fe..c1cddda41b 100644 --- a/OFDFile/src/Base.h +++ b/OFDFile/src/Base.h @@ -36,7 +36,7 @@ class CDocInfo std::vector m_arCustomData; public: CDocInfo(); - bool Read(XmlUtils::CXmlLiteReader& oLiteReader); + bool Read(CXmlReader& oLiteReader); }; class CDocBody @@ -48,7 +48,7 @@ class CDocBody std::wstring m_wsSignature; public: CDocBody(); - static CDocBody* Read(XmlUtils::CXmlLiteReader& oLiteReader, IFolder* pFolder); + static CDocBody* Read(CXmlReader& oLiteReader, IFolder* pFolder); }; @@ -61,12 +61,12 @@ public: bool Read(IFolder* pFolder); - std::wstring GetDocId() const; - std::wstring GetCreationDate() const; - std::wstring GetCreator() const; - std::wstring GetCreatorVersion() const; + // std::wstring GetDocId() const; + // std::wstring GetCreationDate() const; + // std::wstring GetCreator() const; + // std::wstring GetCreatorVersion() const; - std::wstring GetpathToDocRoot() const; + // std::wstring GetPathToDocRoot() const; }; } diff --git a/OFDFile/src/Content/Content.cpp b/OFDFile/src/Content/Content.cpp index 506adcdefc..76b3763ae2 100644 --- a/OFDFile/src/Content/Content.cpp +++ b/OFDFile/src/Content/Content.cpp @@ -3,9 +3,7 @@ namespace OFD { CContent::CContent() -{ - -} +{} CContent::~CContent() { @@ -13,7 +11,7 @@ CContent::~CContent() delete pLayer; } -bool CContent::Read(XmlUtils::CXmlLiteReader& oLiteReader) +bool CContent::Read(CXmlReader& oLiteReader) { if (L"ofd:Content" != oLiteReader.GetName()) return false; diff --git a/OFDFile/src/Content/Content.h b/OFDFile/src/Content/Content.h index ed51011cf5..4cec369d7d 100644 --- a/OFDFile/src/Content/Content.h +++ b/OFDFile/src/Content/Content.h @@ -12,7 +12,7 @@ public: CContent(); ~CContent(); - bool Read(XmlUtils::CXmlLiteReader& oLiteReader); + bool Read(CXmlReader& oLiteReader); }; } diff --git a/OFDFile/src/Content/GraphicUnit.cpp b/OFDFile/src/Content/GraphicUnit.cpp index 0fd51c87ad..322bf45a16 100644 --- a/OFDFile/src/Content/GraphicUnit.cpp +++ b/OFDFile/src/Content/GraphicUnit.cpp @@ -3,10 +3,10 @@ namespace OFD { -CGraphicUnit::CGraphicUnit(XmlUtils::CXmlLiteReader& oLiteReader) - : m_bVisible(true), m_dLineWidth(0.353), m_eCap(ECap::Butt), - m_eJoin(EJoin::Miter), m_dMiterLimit(4.234), m_dDashOffset(0.), - m_uchAlpha(255) +CGraphicUnit::CGraphicUnit(CXmlReader& oLiteReader) + : m_bVisible(true), m_dLineWidth(0.353), m_eCap(ECap::Butt), + m_eJoin(EJoin::Miter), m_dMiterLimit(4.234), m_dDashOffset(0.), + m_uchAlpha(255) { if (0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) return; @@ -18,17 +18,17 @@ CGraphicUnit::CGraphicUnit(XmlUtils::CXmlLiteReader& oLiteReader) wsAttributeName = oLiteReader.GetName(); if (L"Boundary" == wsAttributeName) - m_oBoundary.Read(oLiteReader.GetText()); + m_oBoundary.Read(oLiteReader.GetTextA()); else if (L"Name" == wsAttributeName) m_wsName = oLiteReader.GetText(); else if (L"Visible" == wsAttributeName) - m_bVisible = XmlUtils::GetBoolean(oLiteReader.GetText()); + m_bVisible = oLiteReader.GetBoolean(true); else if (L"CTM" == wsAttributeName) - m_oCTM.Read(oLiteReader.GetText()); + m_oCTM.Read(oLiteReader.GetTextA()); else if (L"DrawParam" == wsAttributeName) - m_unDrawParam = XmlUtils::GetUInteger(oLiteReader.GetText()); + m_unDrawParam = oLiteReader.GetUInteger(true); else if (L"LineWidth" == wsAttributeName) - m_dLineWidth = XmlUtils::GetDouble(oLiteReader.GetText()); + m_dLineWidth = oLiteReader.GetDouble(true); else if (L"Cap" == wsAttributeName) { const std::wstring wsValue{oLiteReader.GetText()}; @@ -52,11 +52,11 @@ CGraphicUnit::CGraphicUnit(XmlUtils::CXmlLiteReader& oLiteReader) m_eJoin = EJoin::Bevel; } else if (L"MiterLimit" == wsAttributeName) - m_dMiterLimit = XmlUtils::GetDouble(oLiteReader.GetText()); + m_dMiterLimit = oLiteReader.GetDouble(true); else if (L"DashOffset" == wsAttributeName) - m_dDashOffset = XmlUtils::GetDouble(oLiteReader.GetText()); + m_dDashOffset = oLiteReader.GetDouble(true); else if (L"Alpha" == wsAttributeName) - m_uchAlpha = XmlUtils::GetUInteger(oLiteReader.GetText()); + m_uchAlpha = oLiteReader.GetUInteger(true); } while (oLiteReader.MoveToNextAttribute()); oLiteReader.MoveToElement(); diff --git a/OFDFile/src/Content/GraphicUnit.h b/OFDFile/src/Content/GraphicUnit.h index 764ecdcac0..b0ae03d0b8 100644 --- a/OFDFile/src/Content/GraphicUnit.h +++ b/OFDFile/src/Content/GraphicUnit.h @@ -1,7 +1,7 @@ #ifndef GRAPHICUNIT_H #define GRAPHICUNIT_H -#include "../../../DesktopEditor/xml/include/xmlutils.h" +#include "../Utils/XmlReader.h" #include "../Utils/Types.h" #include @@ -35,7 +35,7 @@ class CGraphicUnit std::vector m_arDashPattern; unsigned char m_uchAlpha; public: - CGraphicUnit(XmlUtils::CXmlLiteReader& oLiteReader); + CGraphicUnit(CXmlReader& oLiteReader); }; } diff --git a/OFDFile/src/Content/IPageBlock.h b/OFDFile/src/Content/IPageBlock.h index 4769b2aa45..4dd7763bd8 100644 --- a/OFDFile/src/Content/IPageBlock.h +++ b/OFDFile/src/Content/IPageBlock.h @@ -1,7 +1,7 @@ #ifndef IPAGEBLOCK_H #define IPAGEBLOCK_H -#include "../../../DesktopEditor/xml/include/xmlutils.h" +#include "../Utils/XmlReader.h" namespace OFD { @@ -11,7 +11,7 @@ class IPageBlock public: IPageBlock(){}; virtual ~IPageBlock(){}; - virtual bool Read(XmlUtils::CXmlLiteReader& oLiteReader) = 0; + virtual bool Read(CXmlReader& oLiteReader) = 0; }; } diff --git a/OFDFile/src/Content/Layer.cpp b/OFDFile/src/Content/Layer.cpp index a8aacad283..1ee9e6f507 100644 --- a/OFDFile/src/Content/Layer.cpp +++ b/OFDFile/src/Content/Layer.cpp @@ -6,7 +6,7 @@ namespace OFD { -CLayer::CLayer(XmlUtils::CXmlLiteReader& oLiteReader) +CLayer::CLayer(CXmlReader& oLiteReader) : m_eType(EType::Body) { Read(oLiteReader); @@ -18,7 +18,7 @@ CLayer::~CLayer() delete pPageBlock; } -bool CLayer::Read(XmlUtils::CXmlLiteReader& oLiteReader) +bool CLayer::Read(CXmlReader& oLiteReader) { if (L"ofd:Layer" != oLiteReader.GetName()) return false; @@ -28,7 +28,7 @@ bool CLayer::Read(XmlUtils::CXmlLiteReader& oLiteReader) do { if (L"ID" == oLiteReader.GetName()) - m_unID = XmlUtils::GetUInteger(oLiteReader.GetText()); + m_unID = oLiteReader.GetUInteger(true); } while (oLiteReader.MoveToNextAttribute()); oLiteReader.MoveToElement(); diff --git a/OFDFile/src/Content/Layer.h b/OFDFile/src/Content/Layer.h index 5e4a66a3c2..2daef4f222 100644 --- a/OFDFile/src/Content/Layer.h +++ b/OFDFile/src/Content/Layer.h @@ -17,10 +17,10 @@ class CLayer unsigned int m_unID; std::vector m_arPageBlocks; public: - CLayer(XmlUtils::CXmlLiteReader& oLiteReader); + CLayer(CXmlReader& oLiteReader); ~CLayer(); - bool Read(XmlUtils::CXmlLiteReader& oLiteReader); + bool Read(CXmlReader& oLiteReader); }; } diff --git a/OFDFile/src/Content/TextObject.cpp b/OFDFile/src/Content/TextObject.cpp index 8cc9dae630..742b6d1e4e 100644 --- a/OFDFile/src/Content/TextObject.cpp +++ b/OFDFile/src/Content/TextObject.cpp @@ -1,12 +1,10 @@ #include "TextObject.h" -#include "../Utils/Utils.h" - namespace OFD { -CTextCode::CTextCode(XmlUtils::CXmlLiteReader& oLiteReader) +CTextCode::CTextCode(CXmlReader& oLiteReader) { - if (NO_VALID_NODE(oLiteReader, L"ofd:TextCode")) + if (L"ofd:TextCode" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid()) return; if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) @@ -18,13 +16,13 @@ CTextCode::CTextCode(XmlUtils::CXmlLiteReader& oLiteReader) wsAttributeName = oLiteReader.GetName(); if (L"X" == wsAttributeName) - m_dX = XmlUtils::GetDouble(oLiteReader.GetText()); + m_dX = oLiteReader.GetDouble(true); else if (L"Y" == wsAttributeName) - m_dY = XmlUtils::GetDouble(oLiteReader.GetText()); + m_dY = oLiteReader.GetDouble(true); else if (L"DeltaX" == wsAttributeName) - m_arDeltaX = GetDoubleValues(oLiteReader.GetText()); + m_arDeltaX = oLiteReader.GetArrayDoubles(true); else if (L"DeltaY" == wsAttributeName) - m_arDeltaY = GetDoubleValues(oLiteReader.GetText()); + m_arDeltaY = oLiteReader.GetArrayDoubles(true); } while (oLiteReader.MoveToNextAttribute()); } @@ -33,12 +31,12 @@ CTextCode::CTextCode(XmlUtils::CXmlLiteReader& oLiteReader) m_wsText = oLiteReader.GetText2(); } -CTextObject::CTextObject(XmlUtils::CXmlLiteReader& oLiteReader) +CTextObject::CTextObject(CXmlReader& oLiteReader) : CGraphicUnit(oLiteReader), - m_bStroke(false), m_bFill(false), m_dHScale(1.), - m_unReadDirection(0), m_unCharDirection(0), m_unWeight(400), - m_bItalic(false), - m_pFillColor(nullptr), m_pStrokeColor(nullptr) + m_bStroke(false), m_bFill(false), m_dHScale(1.), + m_unReadDirection(0), m_unCharDirection(0), m_unWeight(400), + m_bItalic(false), + m_pFillColor(nullptr), m_pStrokeColor(nullptr) { CTextObject::Read(oLiteReader); } @@ -55,9 +53,9 @@ CTextObject::~CTextObject() delete pTextCode; } -bool CTextObject::Read(XmlUtils::CXmlLiteReader& oLiteReader) +bool CTextObject::Read(CXmlReader& oLiteReader) { - if (NO_VALID_NODE(oLiteReader, L"ofd:TextObject")) + if (L"ofd:TextObject" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid()) return false; if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) @@ -69,25 +67,23 @@ bool CTextObject::Read(XmlUtils::CXmlLiteReader& oLiteReader) wsAttributeName = oLiteReader.GetName(); if (L"Font" == wsAttributeName) - { - m_unFont = XmlUtils::GetUInteger(oLiteReader.GetText()); - } + m_unFont = oLiteReader.GetUInteger(true); else if (L"Size" == wsAttributeName) - m_dSize = XmlUtils::GetDouble(oLiteReader.GetText()); + m_dSize = oLiteReader.GetDouble(true); else if (L"Stroke" == wsAttributeName) - m_bStroke = XmlUtils::GetBoolean(oLiteReader.GetText()); + m_bStroke = oLiteReader.GetBoolean(true); else if (L"Fill" == wsAttributeName) - m_bFill = XmlUtils::GetBoolean(oLiteReader.GetText()); + m_bFill = oLiteReader.GetBoolean(true); else if (L"HScale" == wsAttributeName) - m_dHScale = XmlUtils::GetDouble(oLiteReader.GetText()); + m_dHScale = oLiteReader.GetDouble(true); else if (L"ReadDirection" == wsAttributeName) - m_unReadDirection = XmlUtils::GetUInteger(oLiteReader.GetText()); + m_unReadDirection = oLiteReader.GetUInteger(true); else if (L"CharDirection" == wsAttributeName) - m_unCharDirection = XmlUtils::GetUInteger(oLiteReader.GetText()); + m_unCharDirection =oLiteReader.GetUInteger(true); else if (L"Weight" == wsAttributeName) - m_unWeight = XmlUtils::GetUInteger(oLiteReader.GetText()); + m_unWeight = oLiteReader.GetUInteger(true); else if (L"Italic" == wsAttributeName) - m_bItalic = XmlUtils::GetBoolean(oLiteReader.GetText()); + m_bItalic = oLiteReader.GetBoolean(true); } while (oLiteReader.MoveToNextAttribute()); } @@ -105,14 +101,14 @@ bool CTextObject::Read(XmlUtils::CXmlLiteReader& oLiteReader) if (nullptr != m_pFillColor) delete m_pFillColor; - m_pFillColor = new TColor(oLiteReader); + m_pFillColor = new CColor(oLiteReader); } else if (L"ofd:StrokeColor" == wsNodeName && m_bStroke) { if (nullptr != m_pStrokeColor) delete m_pStrokeColor; - m_pStrokeColor = new TColor(oLiteReader); + m_pStrokeColor = new CColor(oLiteReader); } else if (L"ofd:TextCode" == wsNodeName) m_arTextCodes.push_back(new CTextCode(oLiteReader)); diff --git a/OFDFile/src/Content/TextObject.h b/OFDFile/src/Content/TextObject.h index d748f2c96a..3a70299d1a 100644 --- a/OFDFile/src/Content/TextObject.h +++ b/OFDFile/src/Content/TextObject.h @@ -4,6 +4,8 @@ #include "IPageBlock.h" #include "GraphicUnit.h" +#include "../Types/Color.h" + namespace OFD { class CTextCode @@ -16,7 +18,7 @@ class CTextCode std::wstring m_wsText; public: - CTextCode(XmlUtils::CXmlLiteReader& oLiteReader); + CTextCode(CXmlReader& oLiteReader); }; class CTextObject : public IPageBlock, public CGraphicUnit @@ -31,15 +33,15 @@ class CTextObject : public IPageBlock, public CGraphicUnit unsigned int m_unWeight; bool m_bItalic; - TColor* m_pFillColor; - TColor* m_pStrokeColor; + CColor* m_pFillColor; + CColor* m_pStrokeColor; std::vector m_arTextCodes; public: - CTextObject(XmlUtils::CXmlLiteReader& oLiteReader); + CTextObject(CXmlReader& oLiteReader); ~CTextObject(); - virtual bool Read(XmlUtils::CXmlLiteReader& oLiteReader) override; + virtual bool Read(CXmlReader& oLiteReader) override; }; } diff --git a/OFDFile/src/Document.cpp b/OFDFile/src/Document.cpp index 7e39cbb447..7386ae0ecb 100644 --- a/OFDFile/src/Document.cpp +++ b/OFDFile/src/Document.cpp @@ -1,13 +1,11 @@ #include "Document.h" -#include "../../OOXML/Base/Unit.h" - namespace OFD { CPageArea::CPageArea() {} -bool CPageArea::Read(XmlUtils::CXmlLiteReader& oLiteReader) +bool CPageArea::Read(CXmlReader& oLiteReader) { if (L"ofd:PageArea" != oLiteReader.GetName()) return false; @@ -20,13 +18,13 @@ bool CPageArea::Read(XmlUtils::CXmlLiteReader& oLiteReader) wsNodeName = oLiteReader.GetName(); if (L"ofd:PhysicalBox" == wsNodeName) - m_oPhysicalBox.Read(oLiteReader.GetText2()); + m_oPhysicalBox.Read(oLiteReader.GetText2A()); else if (L"ofd:ApplicationBox" == wsNodeName) - m_oApplicationBox.Read(oLiteReader.GetText2()); + m_oApplicationBox.Read(oLiteReader.GetText2A()); else if (L"ofd:ContentBox" == wsNodeName) - m_oContentBox.Read(oLiteReader.GetText2()); + m_oContentBox.Read(oLiteReader.GetText2A()); else if (L"ofd:BleedBox" == wsNodeName) - m_oBleedBox.Read(oLiteReader.GetText2()); + m_oBleedBox.Read(oLiteReader.GetText2A()); } return true; @@ -36,7 +34,7 @@ CCommonData::CCommonData() : m_unMaxUnitID(0) {} -bool CCommonData::Read(XmlUtils::CXmlLiteReader& oLiteReader) +bool CCommonData::Read(CXmlReader& oLiteReader) { if (L"ofd:CommonData" != oLiteReader.GetName()) return false; @@ -55,7 +53,7 @@ bool CCommonData::Read(XmlUtils::CXmlLiteReader& oLiteReader) // m_oPublicRes.Read(); } else if (L"ofd:MaxUnitID" == wsNodeName) - m_unMaxUnitID = XmlUtils::GetUInteger(oLiteReader.GetText2()); + m_unMaxUnitID = oLiteReader.GetUInteger(); // else if (L"ofd:DocumentRes" == wsNodeName) // else if (L"ofd:TemplatePage" == wsNodeName) // else if (L"ofd:DefaultCS" == wsNodeName) @@ -64,6 +62,30 @@ bool CCommonData::Read(XmlUtils::CXmlLiteReader& oLiteReader) return true; } +CPermission::CPermission() + : m_bEdit(true), m_bAnnot(true), m_bExport(true), + m_bSignature(true), m_bWatermark(true), m_bPrintScreen(true) +{} + +bool CPermission::Read(CXmlReader& oLiteReader) +{ + if (L"ofd:Permission" != oLiteReader.GetName()) + return false; + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:Edit" == wsNodeName) + m_bEdit = oLiteReader.GetBoolean(); + } + + return true; +} + CDocument::CDocument() {} @@ -83,7 +105,7 @@ bool CDocument::Read(const std::wstring& wsFilePath) if (wsFilePath.empty()) return false; - XmlUtils::CXmlLiteReader oLiteReader; + CXmlReader oLiteReader; if (!oLiteReader.FromFile(wsFilePath) || !oLiteReader.ReadNextNode() || L"ofd:Document" != oLiteReader.GetName()) return false; @@ -111,7 +133,7 @@ bool CDocument::Read(const std::wstring& wsFilePath) do { if (L"ID" == oLiteReader.GetName()) - nID = XmlUtils::GetUInteger(oLiteReader.GetText()); + nID = oLiteReader.GetInteger(true); else if (L"BaseLoc" == oLiteReader.GetName()) wsBaseLoc = oLiteReader.GetText(); }while (oLiteReader.MoveToNextAttribute()); diff --git a/OFDFile/src/Document.h b/OFDFile/src/Document.h index 3171275666..7ae5d48531 100644 --- a/OFDFile/src/Document.h +++ b/OFDFile/src/Document.h @@ -17,7 +17,7 @@ class CPageArea public: CPageArea(); - bool Read(XmlUtils::CXmlLiteReader& oLiteReader); + bool Read(CXmlReader& oLiteReader); }; class CCommonData @@ -28,7 +28,21 @@ class CCommonData public: CCommonData(); - bool Read(XmlUtils::CXmlLiteReader& oLiteReader); + bool Read(CXmlReader& oLiteReader); +}; + +class CPermission +{ + bool m_bEdit; + bool m_bAnnot; + bool m_bExport; + bool m_bSignature; + bool m_bWatermark; + bool m_bPrintScreen; +public: + CPermission(); + + bool Read(CXmlReader& oLiteReader); }; class CDocument diff --git a/OFDFile/src/Page.cpp b/OFDFile/src/Page.cpp index 6a66d21875..153da83d28 100644 --- a/OFDFile/src/Page.cpp +++ b/OFDFile/src/Page.cpp @@ -1,6 +1,5 @@ #include "Page.h" -#include #include "../../DesktopEditor/common/File.h" #include "../../DesktopEditor/common/Path.h" @@ -22,7 +21,7 @@ CPage* CPage::Read(const std::wstring& wsFilePath) wsNormalizedPath = NSSystemPath::Combine(wsNormalizedPath, L"Content.xml"); - XmlUtils::CXmlLiteReader oLiteReader; + CXmlReader oLiteReader; if (!oLiteReader.FromFile(wsNormalizedPath) || !oLiteReader.ReadNextNode() || L"ofd:Page" != oLiteReader.GetName()) return nullptr; diff --git a/OFDFile/src/Types/Color.cpp b/OFDFile/src/Types/Color.cpp new file mode 100644 index 0000000000..33ce465754 --- /dev/null +++ b/OFDFile/src/Types/Color.cpp @@ -0,0 +1,15 @@ +#include "Color.h" + +namespace OFD +{ +CColor::CColor(CXmlReader& oXmlReader) +{ + Read(oXmlReader); +} + +bool CColor::Read(CXmlReader& oXmlReader) +{ + return false; +} + +} diff --git a/OFDFile/src/Types/Color.h b/OFDFile/src/Types/Color.h new file mode 100644 index 0000000000..79dfd9a62f --- /dev/null +++ b/OFDFile/src/Types/Color.h @@ -0,0 +1,32 @@ +#ifndef COLOR_H +#define COLOR_H + +#include "../Utils/XmlReader.h" + +namespace OFD +{ +class CColor +{ + struct TColorChannels + { + unsigned char m_chRed; + BYTE m_chGreen; + BYTE m_chBlue; + } m_oValue; + + int m_nIndex; + unsigned int m_unColorSpace; + BYTE m_chAlpha; + // Pattern + // AxialShd + // RadialShd + // GouraudShd + // LaGouraudhd +public: + CColor(CXmlReader& oXmlReader); + + bool Read(CXmlReader& oXmlReader); +}; +} + +#endif // COLOR_H diff --git a/OFDFile/src/Utils/Types.cpp b/OFDFile/src/Utils/Types.cpp index 52ffb6a125..9005ddd8ef 100644 --- a/OFDFile/src/Utils/Types.cpp +++ b/OFDFile/src/Utils/Types.cpp @@ -1,8 +1,6 @@ #include "Types.h" -#include -#include "../../../DesktopEditor/common/StringExt.h" -#include "../../../OOXML/Base/Unit.h" +#include "Utils.h" namespace OFD { @@ -15,35 +13,19 @@ bool TBox::Empty() const return m_dWidth < OFD_EPSILON || m_dHeight < OFD_EPSILON; } -bool TBox::Read(const std::wstring& wsValue) +bool TBox::Read(const std::string& sValue) { - const std::vector arValues{NSStringExt::Split(wsValue, L' ')}; + const std::vector arValues{Split(sValue, ' ')}; if (4 > arValues.size()) return false; - m_dX = XmlUtils::GetDouble(arValues[0]); - m_dY = XmlUtils::GetDouble(arValues[1]); - m_dWidth = XmlUtils::GetDouble(arValues[2]); - m_dHeight = XmlUtils::GetDouble(arValues[3]); + if (!StringToDouble(arValues[0], m_dX) || + !StringToDouble(arValues[1], m_dY) || + !StringToDouble(arValues[2], m_dWidth) || + !StringToDouble(arValues[3], m_dHeight)) + return false; return true; } - - - -TColor::TColor() -{ -} - -TColor::TColor(XmlUtils::CXmlLiteReader& oLiteReader) -{ - Read(oLiteReader); -} - -bool TColor::Read(XmlUtils::CXmlLiteReader& oLiteReader) -{ - return false; -} - } diff --git a/OFDFile/src/Utils/Types.h b/OFDFile/src/Utils/Types.h index 9b38b1b8c7..1be3d4875b 100644 --- a/OFDFile/src/Utils/Types.h +++ b/OFDFile/src/Utils/Types.h @@ -2,13 +2,10 @@ #define TYPES_H #include -#include "../../../DesktopEditor/xml/include/xmlutils.h" - namespace OFD { #define OFD_EPSILON 0.0001 - struct TBox { double m_dX; @@ -19,15 +16,7 @@ struct TBox TBox(); bool Empty() const; - bool Read(const std::wstring& wsValue); -}; - -struct TColor -{ - TColor(); - TColor(XmlUtils::CXmlLiteReader& oLiteReader); - - bool Read(XmlUtils::CXmlLiteReader& oLiteReader); + bool Read(const std::string& wsValue); }; } diff --git a/OFDFile/src/Utils/Utils.h b/OFDFile/src/Utils/Utils.h index 1b220e8724..2c885c540f 100644 --- a/OFDFile/src/Utils/Utils.h +++ b/OFDFile/src/Utils/Utils.h @@ -1,49 +1,96 @@ #ifndef UTILS_H #define UTILS_H - -#include +#include #include -#include "../../../OOXML/Base/Unit.h" -#include "../../../DesktopEditor/common/StringExt.h" +#include +#include +#include -bool GetBoolean(const std::wstring& wsValue) +namespace OFD { - return false; +inline std::vector Split(const std::string& sValue, char chDelim) +{ + if (sValue.empty()) + return std::vector(); + + std::vector arValues; + std::stringstream oStringStream(sValue); + std::string sItem; + + while (std::getline(oStringStream, sItem, chDelim)) + arValues.push_back(sItem); + + return arValues; } -int GetInt(const std::wstring& wsValue) +inline bool StringToBoolean(const std::string& sValue, bool& bValue) { - return 0; + //TODO:: скорректировать метод, если возможно чтение не стандартных значений с плавающей запятой + if (sValue.empty()) + return false; + + size_t unStart = sValue.find_first_not_of(" \t\n\r\f\v"); + + if (std::string::npos == unStart) + return false; + + size_t unEnd = sValue.find_last_not_of(" \t\n\r\f\v"); + + std::string sTrimmed = sValue.substr(unStart, unEnd - unStart + 1); + + std::transform(sTrimmed.begin(), sTrimmed.end(), sTrimmed.begin(), + [](unsigned char c){ return std::tolower(c); }); + + return "true" == sTrimmed; } -unsigned int GetUInt(const std::wstring& wsValue) +inline bool StringToInteger(const std::string& sValue, int& nValue) { - return 0; + //TODO:: скорректировать метод, если возможно чтение не стандартных значений с плавающей запятой + if (sValue.empty()) + return false; + + char* pEnd = nullptr; + + nValue = std::strtol(sValue.c_str(), &pEnd, 10); + + if (pEnd == sValue.c_str() || '\0' != *pEnd) + return false; + + return true; } -double GetDouble(const std::wstring& wsValue) +inline bool StringToUInteger(const std::string& sValue, unsigned int& unValue) { - return 0.; + //TODO:: скорректировать метод, если возможно чтение не стандартных значений с плавающей запятой + if (sValue.empty()) + return false; + + char* pEnd = nullptr; + + unValue = std::strtoul(sValue.c_str(), &pEnd, 10); + + if (pEnd == sValue.c_str() || '\0' != *pEnd) + return false; + + return true; } - - -std::vector GetDoubleValues(const std::wstring& wsValue) +inline bool StringToDouble(const std::string& sValue, double& dValue) { - const std::vector arValues{NSStringExt::Split(wsValue, L' ')}; + //TODO:: скорректировать метод, если возможно чтение не стандартных значений с плавающей запятой + if (sValue.empty()) + return false; - if(arValues.empty()) - return std::vector(); + char* pEnd = nullptr; - std::vector arDoubleValues(arValues.size()); + dValue = std::strtod(sValue.c_str(), &pEnd); - for (unsigned int unIndex = 0; unIndex < arValues.size(); ++unIndex) - arDoubleValues[unIndex] = XmlUtils::GetDouble(arValues[unIndex]); + if (pEnd == sValue.c_str() || '\0' != *pEnd) + return false; - return arDoubleValues; + return true; +} } - -#define NO_VALID_NODE(lite_reader, node_name) node_name != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid() - #endif // UTILS_H diff --git a/OFDFile/src/Utils/XmlReader.cpp b/OFDFile/src/Utils/XmlReader.cpp new file mode 100644 index 0000000000..302e8a9166 --- /dev/null +++ b/OFDFile/src/Utils/XmlReader.cpp @@ -0,0 +1,63 @@ +#include "XmlReader.h" + +#include "Utils.h" + +namespace OFD +{ +CXmlReader::CXmlReader() +{} + +std::wstring CXmlReader::GetTextValue(bool bIsAttribute) +{ + return (bIsAttribute) ? XmlUtils::CXmlLiteReader::GetText() : XmlUtils::CXmlLiteReader::GetText2(); +} + +std::string CXmlReader::GetTextValueA(bool bIsAttribute) +{ + return (bIsAttribute) ? XmlUtils::CXmlLiteReader::GetTextA() : XmlUtils::CXmlLiteReader::GetText2A(); +} + +bool CXmlReader::GetBoolean(bool bIsAttribute) +{ + bool bValue = false; + StringToBoolean(GetTextValueA(bIsAttribute), bValue); + return bValue; +} + +int CXmlReader::GetInteger(bool bIsAttribute) +{ + int nValue = 0; + StringToInteger(GetTextValueA(bIsAttribute), nValue); + return nValue; +} + +unsigned int CXmlReader::GetUInteger(bool bIsAttribute) +{ + unsigned int unValue = 0; + StringToUInteger(GetTextValueA(bIsAttribute), unValue); + return 0; +} + +double CXmlReader::GetDouble(bool bIsAttribute) +{ + double dValue = 0.; + StringToDouble(GetTextValueA(bIsAttribute), dValue); + return dValue; +} + +std::vector CXmlReader::GetArrayDoubles(bool bIsAttribute) +{ + const std::vector arValues{Split(GetTextValueA(bIsAttribute), ' ')}; + + if(arValues.empty()) + return std::vector(); + + std::vector arDoubleValues(arValues.size()); + + for (unsigned int unIndex = 0; unIndex < arValues.size(); ++unIndex) + if (!StringToDouble(arValues[unIndex], arDoubleValues[unIndex])) + return std::vector(); + + return arDoubleValues; +} +} diff --git a/OFDFile/src/Utils/XmlReader.h b/OFDFile/src/Utils/XmlReader.h new file mode 100644 index 0000000000..8642b82874 --- /dev/null +++ b/OFDFile/src/Utils/XmlReader.h @@ -0,0 +1,25 @@ +#ifndef XMLREADER_H +#define XMLREADER_H + +#include +#include +#include "../../../DesktopEditor/xml/include/xmlutils.h" + +namespace OFD +{ +class CXmlReader : public XmlUtils::CXmlLiteReader +{ + std::wstring GetTextValue(bool bIsAttribute = false); + std::string GetTextValueA(bool bIsAttribute = false); +public: + CXmlReader(); + + bool GetBoolean(bool bIsAttribute = false); + int GetInteger(bool bIsAttribute = false); + unsigned int GetUInteger(bool bIsAttribute = false); + double GetDouble(bool bIsAttribute = false); + std::vector GetArrayDoubles(bool bIsAttribute = false); +}; +} + +#endif // XMLREADER_H From 925c40aa805675c7ba4f5beb03f5b8eace51c470 Mon Sep 17 00:00:00 2001 From: Green Date: Mon, 24 Mar 2025 18:34:04 +0300 Subject: [PATCH 04/15] Added OFD rendering to the renderer --- .../graphics/pro/officedrawingfile.h | 1 + OFDFile/OFDFile.cpp | 188 +++++++----- OFDFile/OFDFile.pro | 71 +++-- OFDFile/OfdFile.h | 59 ++-- OFDFile/src/Base.cpp | 38 +++ OFDFile/src/Base.h | 16 +- OFDFile/src/Content/Content.cpp | 9 + OFDFile/src/Content/Content.h | 1 + OFDFile/src/Content/GraphicUnit.cpp | 19 +- OFDFile/src/Content/GraphicUnit.h | 7 +- OFDFile/src/Content/IPageBlock.h | 17 +- OFDFile/src/Content/Layer.cpp | 27 +- OFDFile/src/Content/Layer.h | 5 +- OFDFile/src/Content/PathObject.cpp | 284 ++++++++++++++++++ OFDFile/src/Content/PathObject.h | 118 ++++++++ OFDFile/src/Content/TextObject.cpp | 38 ++- OFDFile/src/Content/TextObject.h | 7 +- OFDFile/src/Document.cpp | 77 +++-- OFDFile/src/Document.h | 24 +- OFDFile/src/OFDFile_Private.cpp | 116 +++++++ OFDFile/src/OFDFile_Private.h | 40 +++ OFDFile/src/Page.cpp | 26 +- OFDFile/src/Page.h | 7 +- OFDFile/src/Types/Color.cpp | 42 ++- OFDFile/src/Types/Color.h | 5 +- OFDFile/src/Types/PageArea.cpp | 37 +++ OFDFile/src/Types/PageArea.h | 23 ++ OFDFile/src/Utils/Types.cpp | 23 ++ OFDFile/src/Utils/Types.h | 14 + OFDFile/src/Utils/Utils.h | 3 +- OFDFile/src/Utils/XmlReader.cpp | 2 +- OFDFile/test/main.cpp | 23 +- OFDFile/test/test.pro | 26 +- 33 files changed, 1186 insertions(+), 207 deletions(-) create mode 100644 OFDFile/src/Content/PathObject.cpp create mode 100644 OFDFile/src/Content/PathObject.h create mode 100644 OFDFile/src/OFDFile_Private.cpp create mode 100644 OFDFile/src/OFDFile_Private.h create mode 100644 OFDFile/src/Types/PageArea.cpp create mode 100644 OFDFile/src/Types/PageArea.h diff --git a/DesktopEditor/graphics/pro/officedrawingfile.h b/DesktopEditor/graphics/pro/officedrawingfile.h index 7681650e93..13f8c16601 100644 --- a/DesktopEditor/graphics/pro/officedrawingfile.h +++ b/DesktopEditor/graphics/pro/officedrawingfile.h @@ -40,6 +40,7 @@ enum OfficeDrawingFileType odftPDF = 0, odftXPS = 1, odftDJVU = 2, + odftOFD = 3, odftUndefined = 255 }; diff --git a/OFDFile/OFDFile.cpp b/OFDFile/OFDFile.cpp index 61deab990d..4a6ce144d9 100644 --- a/OFDFile/OFDFile.cpp +++ b/OFDFile/OFDFile.cpp @@ -1,93 +1,147 @@ #include "OFDFile.h" +#include "src/OFDFile_Private.h" -#include "../OfficeUtils/src/OfficeUtils.h" +#ifndef DISABLE_PDF_CONVERTATION +#include "../PdfFile/PdfFile.h" +#endif -namespace OFD -{ -COfdFile::COfdFile() +COFDFile::COFDFile(NSFonts::IApplicationFonts* pFonts) + : m_pInternal(new COFDFile_Private(pFonts)) {} -COfdFile::~COfdFile() -{ - Close(); -} - -void COfdFile::Close() -{ -} - -void COfdFile::SetTempDir(const std::wstring& wsPath) -{ - m_wsTempDir = wsPath; -} - -std::wstring COfdFile::GetTempDir() const -{ - return m_wsTempDir; -} - -bool COfdFile::Read(IFolder* pFolder) -{ - if (nullptr == pFolder) - return false; - - if (!m_oBase.Read(pFolder)) - return false; - - return false; -} - -IFolder* COfdFile::CreateTempDir() const -{ - if (!NSDirectory::Exists(m_wsTempDir)) - NSDirectory::CreateDirectory(m_wsTempDir); - - int nCounter = 0; - std::wstring wsTempFolder = m_wsTempDir + L"/OFD/"; - - while (NSDirectory::Exists(wsTempFolder)) - { - wsTempFolder = m_wsTempDir + L"/OFD" + std::to_wstring(nCounter) + L'/'; - nCounter++; - } - - NSDirectory::CreateDirectory(wsTempFolder); - - return new CFolderSystem(wsTempFolder); -} - -bool COfdFile::LoadFromFile(const std::wstring& wsFilePath) +COFDFile::~COFDFile() { Close(); - IFolder* pFolder = CreateTempDir(); + if (nullptr != m_pInternal) + delete m_pInternal; +} - if (nullptr == pFolder) +bool COFDFile::LoadFromFile(const std::wstring& file, const std::wstring& options, const std::wstring& owner_password, const std::wstring& user_password) +{ + if (nullptr == m_pInternal) return false; - COfficeUtils oUtils(NULL); + Close(); - if (S_OK != oUtils.ExtractToDirectory(wsFilePath, pFolder->getFullFilePath(L""), NULL, 0)) + return m_pInternal->LoadFromFile(file); +} + +bool COFDFile::LoadFromMemory(unsigned char* data, unsigned long length, const std::wstring& options, const std::wstring& owner_password, const std::wstring& user_password) +{ + if (nullptr == m_pInternal) return false; - bool bResult = Read(pFolder); + Close(); - if (!bResult) + return m_pInternal->LoadFromMemory(data, length); +} + +void COFDFile::Close() +{ + if (nullptr != m_pInternal) + m_pInternal->Close(); +} + +NSFonts::IApplicationFonts* COFDFile::GetFonts() +{ + return (nullptr != m_pInternal) ? m_pInternal->GetFonts() : nullptr; +} + +OfficeDrawingFileType COFDFile::GetType() +{ + return odftOFD; +} + +std::wstring COFDFile::GetTempDirectory() +{ + if (nullptr != m_pInternal) + return m_pInternal->GetTempDir(); + + return std::wstring(); +} + +void COFDFile::SetTempDirectory(const std::wstring& directory) +{ + if (nullptr != m_pInternal) + m_pInternal->SetTempDir(directory); +} + +int COFDFile::GetPagesCount() +{ + if (nullptr != m_pInternal) + return m_pInternal->GetPageCount(); + + return 0; +} + +void COFDFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) +{ + if (nullptr == m_pInternal) + return; + + m_pInternal->GetPageSize(nPageIndex, *pdWidth, *pdHeight); + + *pdDpiX = 25.4; + *pdDpiY = 25.4; +} + +void COFDFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams) +{ + if (nullptr == pRenderer || nullptr == m_pInternal) + return; + + m_pInternal->DrawPage(pRenderer, nPageIndex); +} + +#ifndef DISABLE_PDF_CONVERTATION +void COFDFile::ConvertToPdf(const std::wstring& wsDstPath) +{ + CPdfFile oPdf(GetFonts()); + oPdf.CreatePdf(); + bool bBreak = false; + + int nPagesCount = GetPagesCount(); + for (int nPageIndex = 0; nPageIndex < nPagesCount; nPageIndex++) { - pFolder->removeDirectory(L""); - delete pFolder; + oPdf.NewPage(); + oPdf.BeginCommand(c_nPageType); + + double dPageDpiX = 96., dPageDpiY = 96.; + double dWidth = 0., dHeight = 0.; + + GetPageInfo(nPageIndex, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + + dWidth *= 25.4 / dPageDpiX; + dHeight *= 25.4 / dPageDpiY; + + oPdf.put_Width(dWidth); + oPdf.put_Height(dHeight); + + DrawPageOnRenderer(&oPdf, nPageIndex, &bBreak); + + oPdf.EndCommand(c_nPageType); + +#ifdef _DEBUG + printf("page %d / %d\n", nPageIndex + 1, nPagesCount); +#endif } - return false; + oPdf.SaveToFile(wsDstPath); } -bool COfdFile::SaveToFile(const std::wstring& wsFilePath) +std::wstring COFDFile::GetInfo() { - return false; + return std::wstring(); } -bool COfdFile::SaveToDir(const std::wstring& wsDir) +unsigned char* COFDFile::GetStructure() { - return false; + return nullptr; } + +unsigned char* COFDFile::GetLinks(int nPageIndex) +{ + return nullptr; } +#endif diff --git a/OFDFile/OFDFile.pro b/OFDFile/OFDFile.pro index 926731ed2a..8463fa1893 100644 --- a/OFDFile/OFDFile.pro +++ b/OFDFile/OFDFile.pro @@ -15,34 +15,51 @@ include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) DEFINES += OFD_USE_DYNAMIC_LIBRARY -ADD_DEPENDENCY(graphics, kernel, UnicodeConverter) +ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, PdfFile) + +core_windows { +LIBS += -lgdi32 \ + -ladvapi32 \ + -luser32 \ + -lshell32 +} + +INCLUDEPATH += \ + $$CORE_ROOT_DIR/DesktopEditor/freetype-2.10.4/include \ + $$CORE_ROOT_DIR/DesktopEditor/freetype-2.10.4/include/freetype HEADERS += \ - OFDFile.h \ - src/Base.h \ - src/Content/Content.h \ - src/Content/GraphicUnit.h \ - src/Content/IPageBlock.h \ - src/Content/Layer.h \ - src/Content/TextObject.h \ - src/Document.h \ - src/Page.h \ - src/PublicRes.h \ - src/Types/Color.h \ - src/Utils/Types.h \ - src/Utils/Utils.h \ - src/Utils/XmlReader.h + OFDFile.h \ + src/Content/PathObject.h \ + src/OFDFile_Private.h \ + src/Base.h \ + src/Content/Content.h \ + src/Content/GraphicUnit.h \ + src/Content/IPageBlock.h \ + src/Content/Layer.h \ + src/Content/TextObject.h \ + src/Document.h \ + src/Page.h \ + src/PublicRes.h \ + src/Types/Color.h \ + src/Types/PageArea.h \ + src/Utils/Types.h \ + src/Utils/Utils.h \ + src/Utils/XmlReader.h SOURCES += \ - OFDFile.cpp \ - src/Base.cpp \ - src/Content/Content.cpp \ - src/Content/GraphicUnit.cpp \ - src/Content/Layer.cpp \ - src/Content/TextObject.cpp \ - src/Document.cpp \ - src/Page.cpp \ - src/PublicRes.cpp \ - src/Types/Color.cpp \ - src/Utils/Types.cpp \ - src/Utils/XmlReader.cpp + OFDFile.cpp \ + src/Content/PathObject.cpp \ + src/OFDFile_Private.cpp \ + src/Base.cpp \ + src/Content/Content.cpp \ + src/Content/GraphicUnit.cpp \ + src/Content/Layer.cpp \ + src/Content/TextObject.cpp \ + src/Document.cpp \ + src/Page.cpp \ + src/PublicRes.cpp \ + src/Types/Color.cpp \ + src/Types/PageArea.cpp \ + src/Utils/Types.cpp \ + src/Utils/XmlReader.cpp diff --git a/OFDFile/OfdFile.h b/OFDFile/OfdFile.h index 4f3e7c0b5f..63d50c5ce3 100644 --- a/OFDFile/OfdFile.h +++ b/OFDFile/OfdFile.h @@ -1,10 +1,6 @@ #ifndef OFDFILE_H #define OFDFILE_H -#include "../OfficeUtils/src/ZipFolder.h" - -#include "src/Base.h" - #ifndef OFD_USE_DYNAMIC_LIBRARY #define OFD_DECL_EXPORT #else @@ -12,30 +8,49 @@ #define OFD_DECL_EXPORT Q_DECL_EXPORT #endif -namespace OFD -{ -class OFD_DECL_EXPORT COfdFile -{ - std::wstring m_wsTempDir; +#include "../DesktopEditor/graphics/pro/officedrawingfile.h" +#include "../DesktopEditor/graphics/pro/Fonts.h" - CBase m_oBase; - - bool Read(IFolder* pFolder); - IFolder* CreateTempDir() const; +class COFDFile_Private; +class OFD_DECL_EXPORT COFDFile : public IOfficeDrawingFile +{ + COFDFile_Private* m_pInternal; public: - COfdFile(); - ~COfdFile(); + COFDFile(NSFonts::IApplicationFonts* pFonts); + virtual ~COFDFile(); - void Close(); + // Open + virtual bool LoadFromFile(const std::wstring& file, const std::wstring& options = L"", + const std::wstring& owner_password = L"", const std::wstring& user_password = L"") override; + virtual bool LoadFromMemory(unsigned char* data, unsigned long length, const std::wstring& options = L"", + const std::wstring& owner_password = L"", const std::wstring& user_password = L"") override; - void SetTempDir(const std::wstring& wsPath); - std::wstring GetTempDir() const; + // Close + virtual void Close() override; - bool LoadFromFile(const std::wstring& wsFilePath); + // Get IApplicationFonts for wrappers + virtual NSFonts::IApplicationFonts* GetFonts() override; - bool SaveToFile(const std::wstring& wsFilePath); - bool SaveToDir(const std::wstring& wsDir); + // Type + virtual OfficeDrawingFileType GetType() override; + + // Temp directory + virtual std::wstring GetTempDirectory() override; + virtual void SetTempDirectory(const std::wstring& directory) override; + + // Pages info/draw + virtual int GetPagesCount() override; + virtual void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) override; + virtual void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams = NULL) override; + + #ifndef DISABLE_PDF_CONVERTATION + void ConvertToPdf(const std::wstring& wsDstPath); + #endif + + // Common methods for viewer + virtual std::wstring GetInfo() override; + virtual unsigned char* GetStructure() override; + virtual unsigned char* GetLinks(int nPageIndex) override; }; -} #endif // OFDFILE_H diff --git a/OFDFile/src/Base.cpp b/OFDFile/src/Base.cpp index 287c3722b3..1c8c4aeb43 100644 --- a/OFDFile/src/Base.cpp +++ b/OFDFile/src/Base.cpp @@ -99,6 +99,20 @@ CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) return pDocBody; } +bool CDocBody::DrawPage(IRenderer* pRenderer, int nPageIndex) const +{ + return m_oDocument.DrawPage(pRenderer, nPageIndex); +} + +unsigned int CDocBody::GetPageCount() const +{ + return m_oDocument.GetPageCount(); +} + +bool CDocBody::GetPageSize(int nPageIndex, double& dWidth, double& dHeight) const +{ + return m_oDocument.GetPageSize(nPageIndex, dWidth, dHeight); +} CBase::CBase() {} @@ -131,4 +145,28 @@ bool CBase::Read(IFolder* pFolder) return false; } + +void CBase::DrawPage(IRenderer* pRenderer, int nPageIndex) const +{ + for (const CDocBody* pDocBody : m_arDocBodies) + if (pDocBody->DrawPage(pRenderer, nPageIndex)) + return; +} + +unsigned int CBase::GetPageCount() const +{ + unsigned int unCount = 0; + + for (const CDocBody* pDocBody : m_arDocBodies) + unCount += pDocBody->GetPageCount(); + + return unCount; +} + +void CBase::GetPageSize(int nPageIndex, double& dWidth, double& dHeight) const +{ + for (const CDocBody* pDocBody : m_arDocBodies) + if (pDocBody->GetPageSize(nPageIndex, dWidth, dHeight)) + return; +} } diff --git a/OFDFile/src/Base.h b/OFDFile/src/Base.h index c1cddda41b..78af33d98b 100644 --- a/OFDFile/src/Base.h +++ b/OFDFile/src/Base.h @@ -1,6 +1,7 @@ #ifndef BASE_H #define BASE_H +#include "../../DesktopEditor/graphics/IRenderer.h" #include "../../OfficeUtils/src/ZipFolder.h" #include "Document.h" @@ -49,8 +50,12 @@ class CDocBody public: CDocBody(); static CDocBody* Read(CXmlReader& oLiteReader, IFolder* pFolder); -}; + bool DrawPage(IRenderer* pRenderer, int nPageIndex) const; + + unsigned int GetPageCount() const; + bool GetPageSize(int nPageIndex, double& dWidth, double& dHeight) const; +}; class CBase { @@ -60,13 +65,10 @@ public: ~CBase(); bool Read(IFolder* pFolder); + void DrawPage(IRenderer* pRenderer, int nPageIndex) const; - // std::wstring GetDocId() const; - // std::wstring GetCreationDate() const; - // std::wstring GetCreator() const; - // std::wstring GetCreatorVersion() const; - - // std::wstring GetPathToDocRoot() const; + unsigned int GetPageCount() const; + void GetPageSize(int nPageIndex, double& dWidth, double& dHeight) const; }; } diff --git a/OFDFile/src/Content/Content.cpp b/OFDFile/src/Content/Content.cpp index 76b3763ae2..a87cb15859 100644 --- a/OFDFile/src/Content/Content.cpp +++ b/OFDFile/src/Content/Content.cpp @@ -29,4 +29,13 @@ bool CContent::Read(CXmlReader& oLiteReader) return false; } + +void CContent::Draw(IRenderer* pRenderer) const +{ + if (nullptr == pRenderer) + return; + + for (const CLayer* pLayer : m_arLayers) + pLayer->Draw(pRenderer); +} } diff --git a/OFDFile/src/Content/Content.h b/OFDFile/src/Content/Content.h index 4cec369d7d..efc2f5d8bf 100644 --- a/OFDFile/src/Content/Content.h +++ b/OFDFile/src/Content/Content.h @@ -13,6 +13,7 @@ public: ~CContent(); bool Read(CXmlReader& oLiteReader); + void Draw(IRenderer* pRenderer) const; }; } diff --git a/OFDFile/src/Content/GraphicUnit.cpp b/OFDFile/src/Content/GraphicUnit.cpp index 322bf45a16..1f14237c63 100644 --- a/OFDFile/src/Content/GraphicUnit.cpp +++ b/OFDFile/src/Content/GraphicUnit.cpp @@ -4,9 +4,9 @@ namespace OFD { CGraphicUnit::CGraphicUnit(CXmlReader& oLiteReader) - : m_bVisible(true), m_dLineWidth(0.353), m_eCap(ECap::Butt), - m_eJoin(EJoin::Miter), m_dMiterLimit(4.234), m_dDashOffset(0.), - m_uchAlpha(255) + : m_bVisible(true), m_unDrawParam(0), m_dLineWidth(0.353), + m_eCap(ECap::Butt), m_eJoin(EJoin::Miter), m_dMiterLimit(4.234), + m_dDashOffset(0.), m_uchAlpha(255) { if (0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) return; @@ -62,4 +62,17 @@ CGraphicUnit::CGraphicUnit(CXmlReader& oLiteReader) oLiteReader.MoveToElement(); } +void CGraphicUnit::Apply(IRenderer* pRenderer) +{ + if (nullptr == pRenderer) + return; + + //TODO:: apply boundary -> clipping -> apply CTM + // pRenderer->SetTransform(1., 0., 0., 1., m_oBoundary.m_dX, m_oBoundary.m_dY); + + //Clipping + + pRenderer->SetTransform(m_oCTM.m_dM11 * 96. / 25.4, m_oCTM.m_dM12, m_oCTM.m_dM21, m_oCTM.m_dM22 * 96. / 25.4, m_oBoundary.m_dX + m_oCTM.m_dDx, m_oBoundary.m_dY + m_oCTM.m_dDy); +} + } diff --git a/OFDFile/src/Content/GraphicUnit.h b/OFDFile/src/Content/GraphicUnit.h index b0ae03d0b8..6da3c5c2a7 100644 --- a/OFDFile/src/Content/GraphicUnit.h +++ b/OFDFile/src/Content/GraphicUnit.h @@ -3,6 +3,9 @@ #include "../Utils/XmlReader.h" #include "../Utils/Types.h" + +#include "../../../DesktopEditor/graphics/IRenderer.h" + #include namespace OFD @@ -12,7 +15,7 @@ class CGraphicUnit TBox m_oBoundary; std::wstring m_wsName; bool m_bVisible; - TBox m_oCTM; + TMatrix m_oCTM; unsigned int m_unDrawParam; double m_dLineWidth; @@ -36,6 +39,8 @@ class CGraphicUnit unsigned char m_uchAlpha; public: CGraphicUnit(CXmlReader& oLiteReader); + + void Apply(IRenderer* pRenderer); }; } diff --git a/OFDFile/src/Content/IPageBlock.h b/OFDFile/src/Content/IPageBlock.h index 4dd7763bd8..dac1bfc4b0 100644 --- a/OFDFile/src/Content/IPageBlock.h +++ b/OFDFile/src/Content/IPageBlock.h @@ -3,15 +3,30 @@ #include "../Utils/XmlReader.h" +#include "../../../DesktopEditor/graphics/IRenderer.h" + namespace OFD { class IPageBlock { unsigned int m_unID; public: - IPageBlock(){}; + IPageBlock(CXmlReader& oLiteReader) + { + if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) + { + do + { + if (L"ID" == oLiteReader.GetName()) + m_unID = oLiteReader.GetUInteger(true); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); + } + }; virtual ~IPageBlock(){}; virtual bool Read(CXmlReader& oLiteReader) = 0; + virtual void Draw(IRenderer* pRenderer) const = 0; }; } diff --git a/OFDFile/src/Content/Layer.cpp b/OFDFile/src/Content/Layer.cpp index 1ee9e6f507..0f061732a0 100644 --- a/OFDFile/src/Content/Layer.cpp +++ b/OFDFile/src/Content/Layer.cpp @@ -3,13 +3,14 @@ #include "../../../OOXML/Base/Unit.h" #include "TextObject.h" +#include "PathObject.h" namespace OFD { CLayer::CLayer(CXmlReader& oLiteReader) - : m_eType(EType::Body) + : IPageBlock(oLiteReader), m_eType(EType::Body) { - Read(oLiteReader); + CLayer::Read(oLiteReader); } CLayer::~CLayer() @@ -23,17 +24,6 @@ bool CLayer::Read(CXmlReader& oLiteReader) if (L"ofd:Layer" != oLiteReader.GetName()) return false; - if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) - { - do - { - if (L"ID" == oLiteReader.GetName()) - m_unID = oLiteReader.GetUInteger(true); - } while (oLiteReader.MoveToNextAttribute()); - - oLiteReader.MoveToElement(); - } - const int nDepth = oLiteReader.GetDepth(); std::wstring wsNodeName; @@ -46,6 +36,8 @@ bool CLayer::Read(CXmlReader& oLiteReader) if (L"ofd:TextObject" == wsNodeName) pPageBlock = new CTextObject(oLiteReader); + else if (L"ofd:PathObject" == wsNodeName) + pPageBlock = new CPathObject(oLiteReader); if (nullptr != pPageBlock) m_arPageBlocks.push_back(pPageBlock); @@ -53,4 +45,13 @@ bool CLayer::Read(CXmlReader& oLiteReader) return true; } + +void CLayer::Draw(IRenderer* pRenderer) const +{ + if (nullptr == pRenderer) + return; + + for (const IPageBlock* pPageBlock : m_arPageBlocks) + pPageBlock->Draw(pRenderer); +} } diff --git a/OFDFile/src/Content/Layer.h b/OFDFile/src/Content/Layer.h index 2daef4f222..44e075e782 100644 --- a/OFDFile/src/Content/Layer.h +++ b/OFDFile/src/Content/Layer.h @@ -5,7 +5,7 @@ namespace OFD { -class CLayer +class CLayer : public IPageBlock { enum class EType { @@ -20,7 +20,8 @@ public: CLayer(CXmlReader& oLiteReader); ~CLayer(); - bool Read(CXmlReader& oLiteReader); + bool Read(CXmlReader& oLiteReader) override; + void Draw(IRenderer* pRenderer) const override; }; } diff --git a/OFDFile/src/Content/PathObject.cpp b/OFDFile/src/Content/PathObject.cpp new file mode 100644 index 0000000000..9cd6c1eb0e --- /dev/null +++ b/OFDFile/src/Content/PathObject.cpp @@ -0,0 +1,284 @@ +#include "PathObject.h" +#include "src/Utils/Utils.h" + +namespace OFD +{ +CPathObject::CPathObject(CXmlReader& oLiteReader) + : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), + m_bStroke(true), m_bFill(true), m_eRule(ERule::NonZero), + m_pFillColor(nullptr), m_pStrokeColor(nullptr) +{ + CPathObject::Read(oLiteReader); +} + +CPathObject::~CPathObject() +{ + for (const IPathElement* pElement : m_arElements) + delete pElement; +} + +void CPathObject::AddElement(const IPathElement* pElement) +{ + if (nullptr != pElement) + m_arElements.push_back(pElement); +} + +bool CPathObject::Read(CXmlReader& oLiteReader) +{ + if (L"ofd:PathObject" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid()) + return false; + + if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) + { + std::wstring wsAttributeName; + + do + { + wsAttributeName = oLiteReader.GetName(); + + if (L"Stroke" == wsAttributeName) + m_bStroke = oLiteReader.GetBoolean(true); + else if (L"Fill" == wsAttributeName) + m_bFill = oLiteReader.GetBoolean(true); + else if (L"Rule" == wsAttributeName) + { + if (L"Even-odd" == oLiteReader.GetText()) + m_eRule = ERule::Even_Odd; + else + m_eRule = ERule::NonZero; + } + } while (oLiteReader.MoveToNextAttribute()); + } + + oLiteReader.MoveToElement(); + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:FillColor" == wsNodeName) + { + if (nullptr != m_pFillColor) + delete m_pFillColor; + + m_pFillColor = new CColor(oLiteReader); + } + else if (L"ofd:StrokeColor" == wsNodeName) + { + if (nullptr != m_pStrokeColor) + delete m_pStrokeColor; + + m_pStrokeColor = new CColor(oLiteReader); + } + else if (L"ofd:AbbreviatedData" == wsNodeName) + { + std::vector arValues{Split(oLiteReader.GetText2A(), ' ')}; + + char chElementName; + + while (!arValues.empty()) + { + if (arValues.front().length() != 1) + { + arValues.erase(arValues.begin()); + continue; + } + + chElementName = arValues[0][0]; + arValues.erase(arValues.begin()); + + switch (chElementName) + { + case 'S': + { + AddElement(CStartElement::ReadFromArray(arValues)); + break; + } + case 'M': + { + AddElement(CMoveElement::ReadFromArray(arValues)); + break; + } + case 'L': + { + AddElement(CLineElement::ReadFromArray(arValues)); + break; + } + case 'Q': + { + AddElement(CBezierCurve2Element::ReadFromArray(arValues)); + break; + } + case 'B': + { + AddElement(CBezierCurve3Element::ReadFromArray(arValues)); + break; + } + case 'A': + { + AddElement(CArcElement::ReadFromArray(arValues)); + break; + } + case 'C': + { + AddElement(CCloseElement::ReadFromArray(arValues)); + break; + } + default: + continue; + } + } + } + } + + return true; +} + +void CPathObject::Draw(IRenderer* pRenderer) const +{ + if (nullptr == pRenderer || m_arElements.empty()) + return; + + ((CGraphicUnit*)this)->Apply(pRenderer); +} + +CStartElement::CStartElement() +{} + +IPathElement* CStartElement::ReadFromArray(std::vector& arValues) +{ + if (arValues.size() < 2) + return nullptr; + + CStartElement *pElement = new CStartElement(); + + if (nullptr == pElement) + return nullptr; + + if (StringToDouble(arValues[0], pElement->m_dX) && StringToDouble(arValues[1], pElement->m_dY)) + return pElement; + + if (nullptr != pElement) + delete pElement; + + return nullptr; +} + +CMoveElement::CMoveElement() +{} + +IPathElement* CMoveElement::ReadFromArray(std::vector& arValues) +{ + if (arValues.size() < 2) + return nullptr; + + CMoveElement *pElement = new CMoveElement(); + + if (nullptr == pElement) + return nullptr; + + + if (StringToDouble(arValues[0], pElement->m_dX) && StringToDouble(arValues[1], pElement->m_dY)) + return pElement; + + delete pElement; + return nullptr; +} + +CLineElement::CLineElement() +{} + +IPathElement* CLineElement::ReadFromArray(std::vector& arValues) +{ + if (arValues.size() < 2) + return nullptr; + + CLineElement *pElement = new CLineElement(); + + if (nullptr == pElement) + return nullptr; + + if (StringToDouble(arValues[0], pElement->m_dX) && StringToDouble(arValues[1], pElement->m_dY)) + return pElement; + + delete pElement; + return nullptr; +} + +CBezierCurve2Element::CBezierCurve2Element() +{} + +IPathElement* CBezierCurve2Element::ReadFromArray(std::vector& arValues) +{ + if (arValues.size() < 4) + return nullptr; + + CBezierCurve2Element *pElement = new CBezierCurve2Element(); + + if (nullptr == pElement) + return nullptr; + + if (StringToDouble(arValues[0], pElement->m_dX1) && StringToDouble(arValues[1], pElement->m_dY1) && + StringToDouble(arValues[2], pElement->m_dX2) && StringToDouble(arValues[3], pElement->m_dY2)) + return pElement; + + delete pElement; + return nullptr; +} + +CBezierCurve3Element::CBezierCurve3Element() +{} + +IPathElement* CBezierCurve3Element::ReadFromArray(std::vector& arValues) +{ + if (arValues.size() < 4) + return nullptr; + + CBezierCurve3Element *pElement = new CBezierCurve3Element(); + + if (nullptr == pElement) + return nullptr; + + if (StringToDouble(arValues[0], pElement->m_dX1) && StringToDouble(arValues[1], pElement->m_dY1) && + StringToDouble(arValues[2], pElement->m_dX2) && StringToDouble(arValues[3], pElement->m_dY2)) + return pElement; + + delete pElement; + return nullptr; +} + +CArcElement::CArcElement() +{} + +IPathElement* CArcElement::ReadFromArray(std::vector& arValues) +{ + if (arValues.size() < 7) + return nullptr; + + CArcElement *pElement = new CArcElement(); + + if (nullptr == pElement) + return nullptr; + + if (StringToDouble(arValues[0], pElement->m_dRadiusX) && StringToDouble(arValues[1], pElement->m_dRadiusY) && + StringToDouble(arValues[2], pElement->m_dAngle) && StringToBoolean(arValues[3], pElement->m_bLarge) && + StringToBoolean(arValues[4], pElement->m_bSweep) && StringToDouble(arValues[5], pElement->m_dX) && + StringToDouble(arValues[6], pElement->m_dY)) + return pElement; + + delete pElement; + return nullptr; +} + +CCloseElement::CCloseElement() +{} + +IPathElement* CCloseElement::ReadFromArray(std::vector& arValues) +{ + return new CCloseElement(); +} + +} diff --git a/OFDFile/src/Content/PathObject.h b/OFDFile/src/Content/PathObject.h new file mode 100644 index 0000000000..4e88b26b92 --- /dev/null +++ b/OFDFile/src/Content/PathObject.h @@ -0,0 +1,118 @@ +#ifndef PATHOBJECT_H +#define PATHOBJECT_H + +#include "IPageBlock.h" +#include "GraphicUnit.h" + +#include "../Types/Color.h" + +namespace OFD +{ +class IPathElement +{ +public: + IPathElement(){}; + virtual ~IPathElement(){}; + + static IPathElement* ReadFromArray(std::vector& arValues) { return nullptr; }; +}; + +class CStartElement : public IPathElement +{ + double m_dX; + double m_dY; +public: + CStartElement(); + static IPathElement* ReadFromArray(std::vector& arValues); +}; + +class CMoveElement : public IPathElement +{ + double m_dX; + double m_dY; +public: + CMoveElement(); + static IPathElement* ReadFromArray(std::vector& arValues); +}; + +class CLineElement : public IPathElement +{ + double m_dX; + double m_dY; +public: + CLineElement(); + static IPathElement* ReadFromArray(std::vector& arValues); +}; + +class CBezierCurve2Element : public IPathElement +{ + double m_dX1; + double m_dY1; + double m_dX2; + double m_dY2; +public: + CBezierCurve2Element(); + static IPathElement* ReadFromArray(std::vector& arValues); +}; + +class CBezierCurve3Element : public IPathElement +{ + double m_dX1; + double m_dY1; + double m_dX2; + double m_dY2; + double m_dX3; + double m_dY3; +public: + CBezierCurve3Element(); + static IPathElement* ReadFromArray(std::vector& arValues); +}; + +class CArcElement : public IPathElement +{ + double m_dRadiusX; + double m_dRadiusY; + double m_dAngle; + bool m_bLarge; + bool m_bSweep; + double m_dX; + double m_dY; +public: + CArcElement(); + static IPathElement* ReadFromArray(std::vector& arValues); +}; + +class CCloseElement : public IPathElement +{ +public: + CCloseElement(); + static IPathElement* ReadFromArray(std::vector& arValues); +}; + +class CPathObject : public IPageBlock, public CGraphicUnit +{ + bool m_bStroke; + bool m_bFill; + + enum class ERule + { + NonZero, + Even_Odd + } m_eRule; + + CColor* m_pFillColor; + CColor* m_pStrokeColor; + + std::vector m_arElements; + + void AddElement(const IPathElement* pElement); +public: + CPathObject(CXmlReader& oLiteReader); + ~CPathObject(); + + bool Read(CXmlReader& oLiteReader) override; + void Draw(IRenderer* pRenderer) const override; +}; +} + +#endif // PATHOBJECT_H diff --git a/OFDFile/src/Content/TextObject.cpp b/OFDFile/src/Content/TextObject.cpp index 742b6d1e4e..7dd398f12e 100644 --- a/OFDFile/src/Content/TextObject.cpp +++ b/OFDFile/src/Content/TextObject.cpp @@ -31,8 +31,16 @@ CTextCode::CTextCode(CXmlReader& oLiteReader) m_wsText = oLiteReader.GetText2(); } +void CTextCode::Draw(IRenderer* pRenderer) const +{ + if (nullptr == pRenderer || m_wsText.empty()) + return; + + pRenderer->CommandDrawText(m_wsText, m_dX, m_dY, 0, 0); +} + CTextObject::CTextObject(CXmlReader& oLiteReader) - : CGraphicUnit(oLiteReader), + : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), m_bStroke(false), m_bFill(false), m_dHScale(1.), m_unReadDirection(0), m_unCharDirection(0), m_unWeight(400), m_bItalic(false), @@ -49,7 +57,7 @@ CTextObject::~CTextObject() if (nullptr != m_pStrokeColor) delete m_pStrokeColor; - for (CTextCode* pTextCode : m_arTextCodes) + for (const CTextCode* pTextCode : m_arTextCodes) delete pTextCode; } @@ -96,14 +104,14 @@ bool CTextObject::Read(CXmlReader& oLiteReader) { wsNodeName = oLiteReader.GetName(); - if (L"ofd:FillColor" == wsNodeName && m_bFill) + if (L"ofd:FillColor" == wsNodeName) { if (nullptr != m_pFillColor) delete m_pFillColor; m_pFillColor = new CColor(oLiteReader); } - else if (L"ofd:StrokeColor" == wsNodeName && m_bStroke) + else if (L"ofd:StrokeColor" == wsNodeName) { if (nullptr != m_pStrokeColor) delete m_pStrokeColor; @@ -117,4 +125,26 @@ bool CTextObject::Read(CXmlReader& oLiteReader) return true; } +void CTextObject::Draw(IRenderer* pRenderer) const +{ + if (nullptr == pRenderer || m_arTextCodes.empty()) + return; + + ((CGraphicUnit*)this)->Apply(pRenderer); + + if (m_bFill && nullptr != m_pFillColor) + { + pRenderer->put_BrushType(c_BrushTypeSolid); + pRenderer->put_BrushColor1(255); + pRenderer->put_BrushAlpha1(255); + } + else + pRenderer->put_BrushType(c_BrushTypeNotSet); + + pRenderer->put_FontSize(m_dSize); + + for (const CTextCode* pTextCode : m_arTextCodes) + pTextCode->Draw(pRenderer); +} + } diff --git a/OFDFile/src/Content/TextObject.h b/OFDFile/src/Content/TextObject.h index 3a70299d1a..2cf033b8e9 100644 --- a/OFDFile/src/Content/TextObject.h +++ b/OFDFile/src/Content/TextObject.h @@ -19,6 +19,8 @@ class CTextCode std::wstring m_wsText; public: CTextCode(CXmlReader& oLiteReader); + + void Draw(IRenderer* pRenderer) const; }; class CTextObject : public IPageBlock, public CGraphicUnit @@ -36,12 +38,13 @@ class CTextObject : public IPageBlock, public CGraphicUnit CColor* m_pFillColor; CColor* m_pStrokeColor; - std::vector m_arTextCodes; + std::vector m_arTextCodes; public: CTextObject(CXmlReader& oLiteReader); ~CTextObject(); - virtual bool Read(CXmlReader& oLiteReader) override; + bool Read(CXmlReader& oLiteReader) override; + void Draw(IRenderer* pRenderer) const override; }; } diff --git a/OFDFile/src/Document.cpp b/OFDFile/src/Document.cpp index 7386ae0ecb..0a83658cc3 100644 --- a/OFDFile/src/Document.cpp +++ b/OFDFile/src/Document.cpp @@ -2,34 +2,6 @@ namespace OFD { -CPageArea::CPageArea() -{} - -bool CPageArea::Read(CXmlReader& oLiteReader) -{ - if (L"ofd:PageArea" != oLiteReader.GetName()) - return false; - - const int nDepth = oLiteReader.GetDepth(); - std::wstring wsNodeName; - - while (oLiteReader.ReadNextSiblingNode(nDepth)) - { - wsNodeName = oLiteReader.GetName(); - - if (L"ofd:PhysicalBox" == wsNodeName) - m_oPhysicalBox.Read(oLiteReader.GetText2A()); - else if (L"ofd:ApplicationBox" == wsNodeName) - m_oApplicationBox.Read(oLiteReader.GetText2A()); - else if (L"ofd:ContentBox" == wsNodeName) - m_oContentBox.Read(oLiteReader.GetText2A()); - else if (L"ofd:BleedBox" == wsNodeName) - m_oBleedBox.Read(oLiteReader.GetText2A()); - } - - return true; -} - CCommonData::CCommonData() : m_unMaxUnitID(0) {} @@ -62,6 +34,17 @@ bool CCommonData::Read(CXmlReader& oLiteReader) return true; } +void CCommonData::GetPageSize(double& dWidth, double& dHeight) const +{ + TBox oPhysicalBox{m_oPageArea.GetPhysicalBox()}; + + if (oPhysicalBox.Empty()) + return; + + dWidth = oPhysicalBox.m_dWidth; + dHeight = oPhysicalBox.m_dHeight; +} + CPermission::CPermission() : m_bEdit(true), m_bAnnot(true), m_bExport(true), m_bSignature(true), m_bWatermark(true), m_bPrintScreen(true) @@ -147,14 +130,50 @@ bool CDocument::Read(const std::wstring& wsFilePath) CPage* pPage = CPage::Read(NSSystemPath::Combine(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc)); if (nullptr != pPage) - m_mPages.insert(std::make_pair(nID, pPage)); + m_mPages.insert(std::make_pair(m_mPages.size(), pPage)); wsBaseLoc.clear(); oLiteReader.MoveToElement(); } } + else if (L"ofd:Permissions" == wsNodeName) + m_oPermission.Read(oLiteReader); } return false; } + +bool CDocument::DrawPage(IRenderer* pRenderer, int nPageIndex) const +{ + if (nullptr == pRenderer) + return false; + + std::map::const_iterator itFound = m_mPages.find(nPageIndex); + + if (itFound == m_mPages.cend()) + return false; + + itFound->second->Draw(pRenderer); + + return true; +} + +unsigned int CDocument::GetPageCount() const +{ + return m_mPages.size(); +} + +bool CDocument::GetPageSize(int nPageIndex, double& dWidth, double& dHeight) const +{ + m_oCommonData.GetPageSize(dWidth, dHeight); + + std::map::const_iterator itFound = m_mPages.find(nPageIndex); + + if (itFound == m_mPages.cend()) + return false; + + itFound->second->GetPageSize(dWidth, dHeight); + + return true; +} } diff --git a/OFDFile/src/Document.h b/OFDFile/src/Document.h index 7ae5d48531..1731be60e8 100644 --- a/OFDFile/src/Document.h +++ b/OFDFile/src/Document.h @@ -4,22 +4,12 @@ #include "Page.h" #include "PublicRes.h" -#include "Utils/Types.h" +#include "Types/PageArea.h" + +#include "../../DesktopEditor/graphics/IRenderer.h" namespace OFD { -class CPageArea -{ - TBox m_oPhysicalBox; - TBox m_oApplicationBox; - TBox m_oContentBox; - TBox m_oBleedBox; -public: - CPageArea(); - - bool Read(CXmlReader& oLiteReader); -}; - class CCommonData { unsigned int m_unMaxUnitID; @@ -29,6 +19,8 @@ public: CCommonData(); bool Read(CXmlReader& oLiteReader); + + void GetPageSize(double& dWidth, double &dHeight) const; }; class CPermission @@ -48,6 +40,7 @@ public: class CDocument { CCommonData m_oCommonData; + CPermission m_oPermission; std::map m_mPages; public: @@ -57,6 +50,11 @@ public: bool Empty() const; bool Read(const std::wstring& wsFilePath); + + bool DrawPage(IRenderer* pRenderer, int nPageIndex) const; + + unsigned int GetPageCount() const; + bool GetPageSize(int nPageIndex, double& dWidth, double &dHeight) const; }; } diff --git a/OFDFile/src/OFDFile_Private.cpp b/OFDFile/src/OFDFile_Private.cpp new file mode 100644 index 0000000000..0fe6a08460 --- /dev/null +++ b/OFDFile/src/OFDFile_Private.cpp @@ -0,0 +1,116 @@ +#include "OFDFile_Private.h" + +#include "../../OfficeUtils/src/OfficeUtils.h" + +COFDFile_Private::COFDFile_Private(NSFonts::IApplicationFonts* pFonts) + : m_pAppFonts(pFonts), m_pTempFolder(nullptr) +{ + if (nullptr == pFonts) + return; + + // Создаем менеджер шрифтов с собственным кэшем + m_pFontManager = m_pAppFonts->GenerateFontManager(); + NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); + pMeasurerCache->SetStreams(m_pAppFonts->GetStreams()); + m_pFontManager->SetOwnerCache(pMeasurerCache); + pMeasurerCache->SetCacheSize(16); +} + +COFDFile_Private::~COFDFile_Private() +{ + Close(); + + if (nullptr != m_pTempFolder) + delete m_pTempFolder; + + RELEASEINTERFACE(m_pFontManager); +} + +void COFDFile_Private::Close() +{ +} + +void COFDFile_Private::SetTempDir(const std::wstring& wsPath) +{ + if (nullptr != m_pTempFolder) + delete m_pTempFolder; + + if (!NSDirectory::Exists(wsPath)) + NSDirectory::CreateDirectory(wsPath); + + int nCounter = 0; + std::wstring wsTempFolder = wsPath + L"/OFD/"; + + while (NSDirectory::Exists(wsTempFolder)) + { + wsTempFolder = wsPath + L"/OFD" + std::to_wstring(nCounter) + L'/'; + nCounter++; + } + + NSDirectory::CreateDirectory(wsTempFolder); + + m_pTempFolder = new CFolderSystem(wsTempFolder); +} + +std::wstring COFDFile_Private::GetTempDir() const +{ + return (nullptr != m_pTempFolder) ? m_pTempFolder->getFullFilePath(L"") : std::wstring(); +} + +bool COFDFile_Private::Read(IFolder* pFolder) +{ + if (nullptr == pFolder) + return false; + + if (!m_oBase.Read(pFolder)) + return false; + + return false; +} + +bool COFDFile_Private::LoadFromFile(const std::wstring& wsFilePath) +{ + if (wsFilePath.empty() || nullptr == m_pTempFolder) + return false; + + Close(); + + COfficeUtils oUtils(NULL); + + if (S_OK != oUtils.ExtractToDirectory(wsFilePath,m_pTempFolder->getFullFilePath(L""), NULL, 0)) + return false; + + return Read(m_pTempFolder); +} + +bool COFDFile_Private::LoadFromMemory(BYTE* pData, DWORD ulLength) +{ + Close(); + + if (nullptr != m_pTempFolder) + delete m_pTempFolder; + + m_pTempFolder = new CZipFolderMemory(pData, ulLength); + + return Read(m_pTempFolder); +} + +unsigned int COFDFile_Private::GetPageCount() const +{ + return m_oBase.GetPageCount(); +} + +void COFDFile_Private::GetPageSize(int nPageIndex, double& dWidth, double& dHeight) const +{ + m_oBase.GetPageSize(nPageIndex, dWidth, dHeight); +} + +void COFDFile_Private::DrawPage(IRenderer* pRenderer, int nPageIndex) +{ + m_oBase.DrawPage(pRenderer, nPageIndex); +} + +NSFonts::IApplicationFonts* COFDFile_Private::GetFonts() +{ + return m_pAppFonts; +} diff --git a/OFDFile/src/OFDFile_Private.h b/OFDFile/src/OFDFile_Private.h new file mode 100644 index 0000000000..d9b46ce4f4 --- /dev/null +++ b/OFDFile/src/OFDFile_Private.h @@ -0,0 +1,40 @@ +#ifndef OFDFILE_PRIVATE_H +#define OFDFILE_PRIVATE_H + +#include "../../OfficeUtils/src/ZipFolder.h" + +#include "../../DesktopEditor/graphics/IRenderer.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" + +#include "Base.h" + +class COFDFile_Private +{ + NSFonts::IApplicationFonts* m_pAppFonts; + NSFonts::IFontManager* m_pFontManager; + IFolder* m_pTempFolder; + + OFD::CBase m_oBase; + + bool Read(IFolder* pFolder); +public: + COFDFile_Private(NSFonts::IApplicationFonts* pFonts); + ~COFDFile_Private(); + + void Close(); + + void SetTempDir(const std::wstring& wsPath); + std::wstring GetTempDir() const; + + bool LoadFromFile(const std::wstring& wsFilePath); + bool LoadFromMemory(BYTE* pData, DWORD ulLength); + + unsigned int GetPageCount() const; + void GetPageSize(int nPageIndex, double& dWidth, double& dHeight) const; + + void DrawPage(IRenderer* pRenderer, int nPageIndex); + + NSFonts::IApplicationFonts* GetFonts(); +}; + +#endif // OFDFILE_PRIVATE_H diff --git a/OFDFile/src/Page.cpp b/OFDFile/src/Page.cpp index 153da83d28..769d9fc0e6 100644 --- a/OFDFile/src/Page.cpp +++ b/OFDFile/src/Page.cpp @@ -20,7 +20,6 @@ CPage* CPage::Read(const std::wstring& wsFilePath) if (L"xml" != NSFile::GetFileExtention(wsNormalizedPath)) wsNormalizedPath = NSSystemPath::Combine(wsNormalizedPath, L"Content.xml"); - CXmlReader oLiteReader; if (!oLiteReader.FromFile(wsNormalizedPath) || !oLiteReader.ReadNextNode() || L"ofd:Page" != oLiteReader.GetName()) return nullptr; @@ -36,8 +35,33 @@ CPage* CPage::Read(const std::wstring& wsFilePath) if (L"ofd:Content" == wsNodeName) pPage->m_oContent.Read(oLiteReader); + else if (L"ofd:Area" == wsNodeName) + pPage->m_oArea.Read(oLiteReader); } return pPage; } + +void CPage::Draw(IRenderer* pRenderer) const +{ + if (nullptr == pRenderer) + return; + + pRenderer->BeginCommand(c_nImageType); + + m_oContent.Draw(pRenderer); + + pRenderer->EndCommand(c_nImageType); +} + +void CPage::GetPageSize(double& dWidth, double& dHeight) const +{ + TBox oPhysicalBox{m_oArea.GetPhysicalBox()}; + + if (oPhysicalBox.Empty()) + return; + + dWidth = oPhysicalBox.m_dWidth * 25.4 / 96.; + dHeight = oPhysicalBox.m_dHeight * 25.4 / 96.; +} } diff --git a/OFDFile/src/Page.h b/OFDFile/src/Page.h index f605eb9d8b..6e4628e560 100644 --- a/OFDFile/src/Page.h +++ b/OFDFile/src/Page.h @@ -2,16 +2,21 @@ #define PAGE_H #include "Content/Content.h" +#include "Types/PageArea.h" namespace OFD { class CPage { - CContent m_oContent; + CPageArea m_oArea; + CContent m_oContent; public: CPage(); static CPage* Read(const std::wstring& wsFilePath); + void Draw(IRenderer* pRenderer) const; + + void GetPageSize(double& dWidth, double& dHeight) const; }; } diff --git a/OFDFile/src/Types/Color.cpp b/OFDFile/src/Types/Color.cpp index 33ce465754..3fd0bd8a4e 100644 --- a/OFDFile/src/Types/Color.cpp +++ b/OFDFile/src/Types/Color.cpp @@ -3,13 +3,53 @@ namespace OFD { CColor::CColor(CXmlReader& oXmlReader) + : m_oValue{0, 0, 0}, m_nIndex(0), m_unColorSpace(0), m_chAlpha(255) { Read(oXmlReader); } bool CColor::Read(CXmlReader& oXmlReader) { - return false; + if (0 == oXmlReader.GetAttributesCount() || !oXmlReader.MoveToFirstAttribute()) + return false; + + std::string sAttributeName; + + do + { + sAttributeName = oXmlReader.GetNameA(); + + if ("ColorSpace" == sAttributeName) + m_unColorSpace = oXmlReader.GetUInteger(true); + else if ("Value" == sAttributeName) + { + const std::vector arValues{oXmlReader.GetArrayDoubles(true)}; + + if (3 > arValues.size()) + continue; + + m_oValue.m_chRed = static_cast(arValues[0]); + m_oValue.m_chGreen = static_cast(arValues[1]); + m_oValue.m_chBlue = static_cast(arValues[2]); + } + else if ("Alpha" == sAttributeName) + m_chAlpha = oXmlReader.GetUInteger(true); + else if ("Index" == sAttributeName) + m_nIndex = oXmlReader.GetInteger(true); + } while (oXmlReader.MoveToNextAttribute()); + + oXmlReader.MoveToElement(); + + return true; } +int CColor::ToInt() const +{ + return (255 << 24) | (m_oValue.m_chRed << 16) | (m_oValue.m_chGreen << 8) | (m_oValue.m_chBlue << 0); +} + +BYTE CColor::GetAlpha() const +{ + return m_chAlpha; +} } diff --git a/OFDFile/src/Types/Color.h b/OFDFile/src/Types/Color.h index 79dfd9a62f..c2199791d4 100644 --- a/OFDFile/src/Types/Color.h +++ b/OFDFile/src/Types/Color.h @@ -9,7 +9,7 @@ class CColor { struct TColorChannels { - unsigned char m_chRed; + BYTE m_chRed; BYTE m_chGreen; BYTE m_chBlue; } m_oValue; @@ -26,6 +26,9 @@ public: CColor(CXmlReader& oXmlReader); bool Read(CXmlReader& oXmlReader); + + int ToInt() const; + BYTE GetAlpha() const; }; } diff --git a/OFDFile/src/Types/PageArea.cpp b/OFDFile/src/Types/PageArea.cpp new file mode 100644 index 0000000000..96c5f4eac3 --- /dev/null +++ b/OFDFile/src/Types/PageArea.cpp @@ -0,0 +1,37 @@ +#include "PageArea.h" + +namespace OFD +{ +CPageArea::CPageArea() +{} + +bool CPageArea::Read(CXmlReader& oLiteReader) +{ + if (L"ofd:PageArea" != oLiteReader.GetName()) + return false; + + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + + if (L"ofd:PhysicalBox" == wsNodeName) + m_oPhysicalBox.Read(oLiteReader.GetText2A()); + else if (L"ofd:ApplicationBox" == wsNodeName) + m_oApplicationBox.Read(oLiteReader.GetText2A()); + else if (L"ofd:ContentBox" == wsNodeName) + m_oContentBox.Read(oLiteReader.GetText2A()); + else if (L"ofd:BleedBox" == wsNodeName) + m_oBleedBox.Read(oLiteReader.GetText2A()); + } + + return true; +} + +TBox CPageArea::GetPhysicalBox() const +{ + return m_oPhysicalBox; +} +} diff --git a/OFDFile/src/Types/PageArea.h b/OFDFile/src/Types/PageArea.h new file mode 100644 index 0000000000..a0ec64a23e --- /dev/null +++ b/OFDFile/src/Types/PageArea.h @@ -0,0 +1,23 @@ +#ifndef PAGEAREA_H +#define PAGEAREA_H + +#include "../Utils/XmlReader.h" +#include "../Utils/Types.h" + +namespace OFD +{ +class CPageArea +{ + TBox m_oPhysicalBox; + TBox m_oApplicationBox; + TBox m_oContentBox; + TBox m_oBleedBox; +public: + CPageArea(); + + bool Read(CXmlReader& oLiteReader); + + TBox GetPhysicalBox() const; +}; +} +#endif // PAGEAREA_H diff --git a/OFDFile/src/Utils/Types.cpp b/OFDFile/src/Utils/Types.cpp index 9005ddd8ef..5d1f20c6b4 100644 --- a/OFDFile/src/Utils/Types.cpp +++ b/OFDFile/src/Utils/Types.cpp @@ -28,4 +28,27 @@ bool TBox::Read(const std::string& sValue) return true; } + +TMatrix::TMatrix() + : m_dM11(1.), m_dM12(0.), m_dM21(0.), m_dM22(1.), m_dDx(0.), m_dDy(0.) +{} + +bool TMatrix::Read(const std::string& sValue) +{ + const std::vector arValues{Split(sValue, ' ')}; + + if (6 > arValues.size()) + return false; + + if (!StringToDouble(arValues[0], m_dM11) || + !StringToDouble(arValues[1], m_dM12) || + !StringToDouble(arValues[2], m_dM21) || + !StringToDouble(arValues[3], m_dM22) || + !StringToDouble(arValues[4], m_dDx) || + !StringToDouble(arValues[5], m_dDy)) + return false; + + return true; +} + } diff --git a/OFDFile/src/Utils/Types.h b/OFDFile/src/Utils/Types.h index 1be3d4875b..c245f3476c 100644 --- a/OFDFile/src/Utils/Types.h +++ b/OFDFile/src/Utils/Types.h @@ -18,6 +18,20 @@ struct TBox bool Empty() const; bool Read(const std::string& wsValue); }; + +struct TMatrix +{ + double m_dM11; + double m_dM12; + double m_dM21; + double m_dM22; + double m_dDx; + double m_dDy; + + TMatrix(); + + bool Read(const std::string& sValue); +}; } #endif // TYPES_H diff --git a/OFDFile/src/Utils/Utils.h b/OFDFile/src/Utils/Utils.h index 2c885c540f..25b457e628 100644 --- a/OFDFile/src/Utils/Utils.h +++ b/OFDFile/src/Utils/Utils.h @@ -42,7 +42,8 @@ inline bool StringToBoolean(const std::string& sValue, bool& bValue) std::transform(sTrimmed.begin(), sTrimmed.end(), sTrimmed.begin(), [](unsigned char c){ return std::tolower(c); }); - return "true" == sTrimmed; + bValue = "true" == sTrimmed; + return true; } inline bool StringToInteger(const std::string& sValue, int& nValue) diff --git a/OFDFile/src/Utils/XmlReader.cpp b/OFDFile/src/Utils/XmlReader.cpp index 302e8a9166..5c8d860244 100644 --- a/OFDFile/src/Utils/XmlReader.cpp +++ b/OFDFile/src/Utils/XmlReader.cpp @@ -35,7 +35,7 @@ unsigned int CXmlReader::GetUInteger(bool bIsAttribute) { unsigned int unValue = 0; StringToUInteger(GetTextValueA(bIsAttribute), unValue); - return 0; + return unValue; } double CXmlReader::GetDouble(bool bIsAttribute) diff --git a/OFDFile/test/main.cpp b/OFDFile/test/main.cpp index 2e2c2d6e42..92189f10ff 100644 --- a/OFDFile/test/main.cpp +++ b/OFDFile/test/main.cpp @@ -1,16 +1,35 @@ #include "../OfdFile.h" #include +#include "../../DesktopEditor/common/Directory.h" +#include "../../DesktopEditor/common/File.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../DesktopEditor/fontengine/ApplicationFontsWorker.h" + int main() { - OFD::COfdFile oOfdFile; + // Check system fonts + CApplicationFontsWorker oWorker; + oWorker.m_sDirectory = NSFile::GetProcessDirectory() + L"/fonts_cache"; + oWorker.m_bIsNeedThumbnails = false; - oOfdFile.SetTempDir(L"temp"); + if (!NSDirectory::Exists(oWorker.m_sDirectory)) + NSDirectory::CreateDirectory(oWorker.m_sDirectory); + + NSFonts::IApplicationFonts* pFonts = oWorker.Check(); + + COFDFile oOfdFile(pFonts); + + oOfdFile.SetTempDirectory(L"temp"); if (oOfdFile.LoadFromFile(L"YOUR_PATH")) std::cout << "GOOD" << std::endl; else std::cout << "BAD" << std::endl; + oOfdFile.ConvertToRaster(0, L"result.png", 4); + + pFonts->Release(); + return 0; } diff --git a/OFDFile/test/test.pro b/OFDFile/test/test.pro index 548db9b932..0d0f676f86 100644 --- a/OFDFile/test/test.pro +++ b/OFDFile/test/test.pro @@ -2,19 +2,29 @@ QT -= core QT -= gui TARGET = test -CONFIG += console -CONFIG -= app_bundle TEMPLATE = app -DEFINES += OFD_USE_DYNAMIC_LIBRARY - -SOURCES += main.cpp - +CONFIG += console +CONFIG -= app_bundle +s CORE_ROOT_DIR = $$PWD/../../ PWD_ROOT_DIR = $$PWD include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) -ADD_DEPENDENCY(kernel, UnicodeConverter, OFDFile) +ADD_DEPENDENCY(kernel, graphics, UnicodeConverter, OFDFile) -DESTDIR = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX +win32 { +LIBS += -lgdi32 \ + -ladvapi32 \ + -luser32 \ + -lshell32 +} +linux-g++ | linux-g++-64 | linux-g++-32 { + LIBS += -lz +} + +SOURCES += main.cpp + +DESTDIR = $$PWD_ROOT_DIR/build/$$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX From 7ceefa54cb50b0310b7a83157aed87f15e72076c Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 1 Apr 2025 00:39:17 +0300 Subject: [PATCH 05/15] Improved OFD format conversion --- OFDFile/OFDFile.pro | 19 ++- OFDFile/src/Content/Content.cpp | 8 +- OFDFile/src/Content/Content.h | 4 +- OFDFile/src/Content/GraphicUnit.cpp | 9 +- OFDFile/src/Content/GraphicUnit.h | 6 +- OFDFile/src/Content/IPageBlock.h | 22 +--- OFDFile/src/Content/ImageObject.cpp | 43 +++++++ OFDFile/src/Content/ImageObject.h | 22 ++++ OFDFile/src/Content/Layer.cpp | 41 ++---- OFDFile/src/Content/Layer.h | 6 +- OFDFile/src/Content/PageBlock.cpp | 52 ++++++++ OFDFile/src/Content/PageBlock.h | 21 ++++ OFDFile/src/Content/PathObject.cpp | 136 ++++++++++++++++---- OFDFile/src/Content/PathObject.h | 15 ++- OFDFile/src/Content/TextObject.cpp | 41 +++--- OFDFile/src/Content/TextObject.h | 3 +- OFDFile/src/Document.cpp | 42 +++++-- OFDFile/src/Document.h | 11 +- OFDFile/src/IOFDElement.h | 35 ++++++ OFDFile/src/OFDFile_Private.cpp | 2 +- OFDFile/src/Page.cpp | 16 ++- OFDFile/src/Page.h | 4 +- OFDFile/src/PublicRes.cpp | 17 --- OFDFile/src/PublicRes.h | 17 --- OFDFile/src/Res.cpp | 138 +++++++++++++++++++++ OFDFile/src/Res.h | 37 ++++++ OFDFile/src/Types/Color.cpp | 48 +++++-- OFDFile/src/Types/Color.h | 10 +- OFDFile/src/Types/ColorSpace.cpp | 35 ++++++ OFDFile/src/Types/ColorSpace.h | 25 ++++ OFDFile/src/Types/CompositeGraphicUnit.cpp | 8 ++ OFDFile/src/Types/CompositeGraphicUnit.h | 15 +++ OFDFile/src/Types/DrawParam.cpp | 8 ++ OFDFile/src/Types/DrawParam.h | 14 +++ OFDFile/src/Types/Font.cpp | 37 ++++++ OFDFile/src/Types/Font.h | 25 ++++ OFDFile/src/Types/MultiMedia.cpp | 54 ++++++++ OFDFile/src/Types/MultiMedia.h | 28 +++++ OFDFile/src/Types/PageArea.cpp | 3 +- 39 files changed, 887 insertions(+), 190 deletions(-) create mode 100644 OFDFile/src/Content/ImageObject.cpp create mode 100644 OFDFile/src/Content/ImageObject.h create mode 100644 OFDFile/src/Content/PageBlock.cpp create mode 100644 OFDFile/src/Content/PageBlock.h create mode 100644 OFDFile/src/IOFDElement.h delete mode 100644 OFDFile/src/PublicRes.cpp delete mode 100644 OFDFile/src/PublicRes.h create mode 100644 OFDFile/src/Res.cpp create mode 100644 OFDFile/src/Res.h create mode 100644 OFDFile/src/Types/ColorSpace.cpp create mode 100644 OFDFile/src/Types/ColorSpace.h create mode 100644 OFDFile/src/Types/CompositeGraphicUnit.cpp create mode 100644 OFDFile/src/Types/CompositeGraphicUnit.h create mode 100644 OFDFile/src/Types/DrawParam.cpp create mode 100644 OFDFile/src/Types/DrawParam.h create mode 100644 OFDFile/src/Types/Font.cpp create mode 100644 OFDFile/src/Types/Font.h create mode 100644 OFDFile/src/Types/MultiMedia.cpp create mode 100644 OFDFile/src/Types/MultiMedia.h diff --git a/OFDFile/OFDFile.pro b/OFDFile/OFDFile.pro index 8463fa1893..0f5a5a9342 100644 --- a/OFDFile/OFDFile.pro +++ b/OFDFile/OFDFile.pro @@ -30,7 +30,10 @@ INCLUDEPATH += \ HEADERS += \ OFDFile.h \ + src/Content/ImageObject.h \ + src/Content/PageBlock.h \ src/Content/PathObject.h \ + src/IOFDElement.h \ src/OFDFile_Private.h \ src/Base.h \ src/Content/Content.h \ @@ -40,8 +43,13 @@ HEADERS += \ src/Content/TextObject.h \ src/Document.h \ src/Page.h \ - src/PublicRes.h \ + src/Res.h \ src/Types/Color.h \ + src/Types/ColorSpace.h \ + src/Types/CompositeGraphicUnit.h \ + src/Types/DrawParam.h \ + src/Types/Font.h \ + src/Types/MultiMedia.h \ src/Types/PageArea.h \ src/Utils/Types.h \ src/Utils/Utils.h \ @@ -49,6 +57,8 @@ HEADERS += \ SOURCES += \ OFDFile.cpp \ + src/Content/ImageObject.cpp \ + src/Content/PageBlock.cpp \ src/Content/PathObject.cpp \ src/OFDFile_Private.cpp \ src/Base.cpp \ @@ -58,8 +68,13 @@ SOURCES += \ src/Content/TextObject.cpp \ src/Document.cpp \ src/Page.cpp \ - src/PublicRes.cpp \ + src/Res.cpp \ src/Types/Color.cpp \ + src/Types/ColorSpace.cpp \ + src/Types/CompositeGraphicUnit.cpp \ + src/Types/DrawParam.cpp \ + src/Types/Font.cpp \ + src/Types/MultiMedia.cpp \ src/Types/PageArea.cpp \ src/Utils/Types.cpp \ src/Utils/XmlReader.cpp diff --git a/OFDFile/src/Content/Content.cpp b/OFDFile/src/Content/Content.cpp index a87cb15859..3ba8801bd7 100644 --- a/OFDFile/src/Content/Content.cpp +++ b/OFDFile/src/Content/Content.cpp @@ -11,7 +11,7 @@ CContent::~CContent() delete pLayer; } -bool CContent::Read(CXmlReader& oLiteReader) +bool CContent::Read(CXmlReader& oLiteReader, const CRes* pDocumentRes) { if (L"ofd:Content" != oLiteReader.GetName()) return false; @@ -24,18 +24,18 @@ bool CContent::Read(CXmlReader& oLiteReader) wsNodeName = oLiteReader.GetName(); if (L"ofd:Layer" == wsNodeName) - m_arLayers.push_back(new CLayer(oLiteReader)); + m_arLayers.push_back(new CLayer(oLiteReader, pDocumentRes)); } return false; } -void CContent::Draw(IRenderer* pRenderer) const +void CContent::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const { if (nullptr == pRenderer) return; for (const CLayer* pLayer : m_arLayers) - pLayer->Draw(pRenderer); + pLayer->Draw(pRenderer, pPublicRes); } } diff --git a/OFDFile/src/Content/Content.h b/OFDFile/src/Content/Content.h index efc2f5d8bf..8f52a36c82 100644 --- a/OFDFile/src/Content/Content.h +++ b/OFDFile/src/Content/Content.h @@ -12,8 +12,8 @@ public: CContent(); ~CContent(); - bool Read(CXmlReader& oLiteReader); - void Draw(IRenderer* pRenderer) const; + bool Read(CXmlReader& oLiteReader, const CRes* pDocumentRes); + void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const; }; } diff --git a/OFDFile/src/Content/GraphicUnit.cpp b/OFDFile/src/Content/GraphicUnit.cpp index 1f14237c63..6ff8188d72 100644 --- a/OFDFile/src/Content/GraphicUnit.cpp +++ b/OFDFile/src/Content/GraphicUnit.cpp @@ -62,7 +62,7 @@ CGraphicUnit::CGraphicUnit(CXmlReader& oLiteReader) oLiteReader.MoveToElement(); } -void CGraphicUnit::Apply(IRenderer* pRenderer) +void CGraphicUnit::Apply(IRenderer* pRenderer) const { if (nullptr == pRenderer) return; @@ -72,7 +72,12 @@ void CGraphicUnit::Apply(IRenderer* pRenderer) //Clipping - pRenderer->SetTransform(m_oCTM.m_dM11 * 96. / 25.4, m_oCTM.m_dM12, m_oCTM.m_dM21, m_oCTM.m_dM22 * 96. / 25.4, m_oBoundary.m_dX + m_oCTM.m_dDx, m_oBoundary.m_dY + m_oCTM.m_dDy); + pRenderer->SetTransform(m_oCTM.m_dM11, m_oCTM.m_dM12, m_oCTM.m_dM21, m_oCTM.m_dM22, m_oBoundary.m_dX + m_oCTM.m_dDx, m_oBoundary.m_dY + m_oCTM.m_dDy); +} + +TBox CGraphicUnit::GetBoundary() const +{ + return m_oBoundary; } } diff --git a/OFDFile/src/Content/GraphicUnit.h b/OFDFile/src/Content/GraphicUnit.h index 6da3c5c2a7..b2f8e4a718 100644 --- a/OFDFile/src/Content/GraphicUnit.h +++ b/OFDFile/src/Content/GraphicUnit.h @@ -37,10 +37,14 @@ class CGraphicUnit double m_dDashOffset; std::vector m_arDashPattern; unsigned char m_uchAlpha; + + friend class CPathObject; public: CGraphicUnit(CXmlReader& oLiteReader); - void Apply(IRenderer* pRenderer); + void Apply(IRenderer* pRenderer) const; + + TBox GetBoundary() const; }; } diff --git a/OFDFile/src/Content/IPageBlock.h b/OFDFile/src/Content/IPageBlock.h index dac1bfc4b0..c638da4cd4 100644 --- a/OFDFile/src/Content/IPageBlock.h +++ b/OFDFile/src/Content/IPageBlock.h @@ -1,32 +1,20 @@ #ifndef IPAGEBLOCK_H #define IPAGEBLOCK_H -#include "../Utils/XmlReader.h" +#include "../IOFDElement.h" #include "../../../DesktopEditor/graphics/IRenderer.h" +#include "../Res.h" namespace OFD { -class IPageBlock +class IPageBlock : public IOFDElement { - unsigned int m_unID; public: IPageBlock(CXmlReader& oLiteReader) - { - if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) - { - do - { - if (L"ID" == oLiteReader.GetName()) - m_unID = oLiteReader.GetUInteger(true); - } while (oLiteReader.MoveToNextAttribute()); - - oLiteReader.MoveToElement(); - } - }; + : IOFDElement(oLiteReader){}; virtual ~IPageBlock(){}; - virtual bool Read(CXmlReader& oLiteReader) = 0; - virtual void Draw(IRenderer* pRenderer) const = 0; + virtual void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const = 0; }; } diff --git a/OFDFile/src/Content/ImageObject.cpp b/OFDFile/src/Content/ImageObject.cpp new file mode 100644 index 0000000000..9f88f9c6b6 --- /dev/null +++ b/OFDFile/src/Content/ImageObject.cpp @@ -0,0 +1,43 @@ +#include "ImageObject.h" + +namespace OFD +{ +CImageObject::CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes) + : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader) +{ + if (nullptr == pDocumentRes || "ofd:ImageObject" != oLiteReader.GetNameA() || 0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) + return; + + std::string sAttributeName; + + do + { + sAttributeName = oLiteReader.GetNameA(); + + if ("ResourceID" == sAttributeName) + { + m_pMultiMedia = pDocumentRes->GetMultiMedia(oLiteReader.GetUInteger(true)); + break; + } + } while(oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); +} + +void CImageObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const +{ + if (nullptr == pRenderer || nullptr == m_pMultiMedia) + return; + + CGraphicUnit::Apply(pRenderer); + + const std::wstring wsFilePath = m_pMultiMedia->GetFilePath(); + + if (wsFilePath.empty()) + return; + + const TBox oBoundry{GetBoundary()}; + + pRenderer->DrawImageFromFile(wsFilePath, 0, 0, oBoundry.m_dWidth, oBoundry.m_dHeight); +} +} diff --git a/OFDFile/src/Content/ImageObject.h b/OFDFile/src/Content/ImageObject.h new file mode 100644 index 0000000000..5ff846ca25 --- /dev/null +++ b/OFDFile/src/Content/ImageObject.h @@ -0,0 +1,22 @@ +#ifndef IMAGEOBJECT_H +#define IMAGEOBJECT_H + +#include "IPageBlock.h" +#include "GraphicUnit.h" + +#include "../Types/MultiMedia.h" +#include "../Res.h" + +namespace OFD +{ +class CImageObject : public IPageBlock, public CGraphicUnit +{ + const CMultiMedia* m_pMultiMedia; +public: + CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes); + + void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; +}; +} + +#endif // IMAGEOBJECT_H diff --git a/OFDFile/src/Content/Layer.cpp b/OFDFile/src/Content/Layer.cpp index 0f061732a0..9103603f2c 100644 --- a/OFDFile/src/Content/Layer.cpp +++ b/OFDFile/src/Content/Layer.cpp @@ -2,15 +2,17 @@ #include "../../../OOXML/Base/Unit.h" -#include "TextObject.h" -#include "PathObject.h" +#include "PageBlock.h" namespace OFD { -CLayer::CLayer(CXmlReader& oLiteReader) +CLayer::CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes) : IPageBlock(oLiteReader), m_eType(EType::Body) { - CLayer::Read(oLiteReader); + if (L"ofd:Layer" != oLiteReader.GetName()) + return; + + CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes); } CLayer::~CLayer() @@ -19,39 +21,12 @@ CLayer::~CLayer() delete pPageBlock; } -bool CLayer::Read(CXmlReader& oLiteReader) -{ - if (L"ofd:Layer" != oLiteReader.GetName()) - return false; - - const int nDepth = oLiteReader.GetDepth(); - std::wstring wsNodeName; - - IPageBlock* pPageBlock = nullptr; - - while (oLiteReader.ReadNextSiblingNode(nDepth)) - { - wsNodeName = oLiteReader.GetName(); - pPageBlock = nullptr; - - if (L"ofd:TextObject" == wsNodeName) - pPageBlock = new CTextObject(oLiteReader); - else if (L"ofd:PathObject" == wsNodeName) - pPageBlock = new CPathObject(oLiteReader); - - if (nullptr != pPageBlock) - m_arPageBlocks.push_back(pPageBlock); - } - - return true; -} - -void CLayer::Draw(IRenderer* pRenderer) const +void CLayer::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const { if (nullptr == pRenderer) return; for (const IPageBlock* pPageBlock : m_arPageBlocks) - pPageBlock->Draw(pRenderer); + pPageBlock->Draw(pRenderer, pPublicRes); } } diff --git a/OFDFile/src/Content/Layer.h b/OFDFile/src/Content/Layer.h index 44e075e782..427525f558 100644 --- a/OFDFile/src/Content/Layer.h +++ b/OFDFile/src/Content/Layer.h @@ -2,6 +2,7 @@ #define LAYER_H #include "IPageBlock.h" +#include "../Res.h" namespace OFD { @@ -17,11 +18,10 @@ class CLayer : public IPageBlock unsigned int m_unID; std::vector m_arPageBlocks; public: - CLayer(CXmlReader& oLiteReader); + CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes); ~CLayer(); - bool Read(CXmlReader& oLiteReader) override; - void Draw(IRenderer* pRenderer) const override; + void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; }; } diff --git a/OFDFile/src/Content/PageBlock.cpp b/OFDFile/src/Content/PageBlock.cpp new file mode 100644 index 0000000000..6565b58530 --- /dev/null +++ b/OFDFile/src/Content/PageBlock.cpp @@ -0,0 +1,52 @@ +#include "PageBlock.h" + +#include "TextObject.h" +#include "PathObject.h" +#include "ImageObject.h" + +namespace OFD +{ +CPageBlock::CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes) + : IPageBlock(oLiteReader) +{ + if ("ofd:PageBlock" != oLiteReader.GetNameA() || oLiteReader.IsEmptyNode()) + return; + + CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes); +} + +void CPageBlock::ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks, const CRes* pDocumentRes) +{ + const int nDepth = oLiteReader.GetDepth(); + std::wstring wsNodeName; + + IPageBlock* pPageBlock = nullptr; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + wsNodeName = oLiteReader.GetName(); + pPageBlock = nullptr; + + if (L"ofd:TextObject" == wsNodeName) + pPageBlock = new CTextObject(oLiteReader); + else if (L"ofd:PathObject" == wsNodeName) + pPageBlock = new CPathObject(oLiteReader); + else if (L"ofd:PageBlock" == wsNodeName) + pPageBlock = new CPageBlock(oLiteReader, pDocumentRes); + else if (L"ofd:ImageObject" == wsNodeName) + pPageBlock = new CImageObject(oLiteReader, pDocumentRes); + + if (nullptr != pPageBlock) + arPageBlocks.push_back(pPageBlock); + } +} + +void CPageBlock::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const +{ + if (nullptr == pRenderer) + return; + + for (const IPageBlock* pPageBlock : m_arPageBlocks) + pPageBlock->Draw(pRenderer, pPublicRes); +} +} diff --git a/OFDFile/src/Content/PageBlock.h b/OFDFile/src/Content/PageBlock.h new file mode 100644 index 0000000000..5db7e8f4a2 --- /dev/null +++ b/OFDFile/src/Content/PageBlock.h @@ -0,0 +1,21 @@ +#ifndef PAGEBLOCK_H +#define PAGEBLOCK_H + +#include "IPageBlock.h" +#include "../Res.h" + +namespace OFD +{ +class CPageBlock : public IPageBlock +{ + std::vector m_arPageBlocks; +public: + CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes); + + static void ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks, const CRes* pDocumentRes); + + void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; +}; +} + +#endif // PAGEBLOCK_H diff --git a/OFDFile/src/Content/PathObject.cpp b/OFDFile/src/Content/PathObject.cpp index 9cd6c1eb0e..74e4a2cf36 100644 --- a/OFDFile/src/Content/PathObject.cpp +++ b/OFDFile/src/Content/PathObject.cpp @@ -7,26 +7,9 @@ CPathObject::CPathObject(CXmlReader& oLiteReader) : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), m_bStroke(true), m_bFill(true), m_eRule(ERule::NonZero), m_pFillColor(nullptr), m_pStrokeColor(nullptr) -{ - CPathObject::Read(oLiteReader); -} - -CPathObject::~CPathObject() -{ - for (const IPathElement* pElement : m_arElements) - delete pElement; -} - -void CPathObject::AddElement(const IPathElement* pElement) -{ - if (nullptr != pElement) - m_arElements.push_back(pElement); -} - -bool CPathObject::Read(CXmlReader& oLiteReader) { if (L"ofd:PathObject" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid()) - return false; + return; if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) { @@ -114,7 +97,7 @@ bool CPathObject::Read(CXmlReader& oLiteReader) } case 'B': { - AddElement(CBezierCurve3Element::ReadFromArray(arValues)); + AddElement(CBezierCurveElement::ReadFromArray(arValues)); break; } case 'A': @@ -133,16 +116,78 @@ bool CPathObject::Read(CXmlReader& oLiteReader) } } } - - return true; } -void CPathObject::Draw(IRenderer* pRenderer) const +CPathObject::~CPathObject() +{ + for (const IPathElement* pElement : m_arElements) + delete pElement; +} + +void CPathObject::AddElement(const IPathElement* pElement) +{ + if (nullptr != pElement) + m_arElements.push_back(pElement); +} + +void CPathObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const { if (nullptr == pRenderer || m_arElements.empty()) return; ((CGraphicUnit*)this)->Apply(pRenderer); + + pRenderer->BeginCommand(c_nPathType); + pRenderer->PathCommandStart(); + + for (const IPathElement* pElement : m_arElements) + pElement->Draw(pRenderer); + + int nEndType = -1; + + if (m_bStroke) + nEndType = c_nStroke; + + if (m_bFill) + { + switch (m_eRule) + { + case ERule::NonZero: + { + nEndType = (-1 == nEndType ? c_nWindingFillMode : nEndType | c_nWindingFillMode); + break; + } + case ERule::Even_Odd: + { + nEndType = (-1 == nEndType ? c_nEvenOddFillMode : nEndType | c_nEvenOddFillMode); + break; + } + } + } + + if (m_bFill && nullptr != m_pFillColor) + { + pRenderer->put_BrushType(c_BrushTypeSolid); + pRenderer->put_BrushColor1(m_pFillColor->ToInt(pPublicRes)); + pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha()); + } + else + pRenderer->put_BrushType(c_BrushTypeNotSet); + + if (m_bStroke && nullptr != m_pStrokeColor) + { + pRenderer->put_PenSize(m_dLineWidth); + pRenderer->put_PenColor(m_pStrokeColor->ToInt(pPublicRes)); + pRenderer->put_PenAlpha(m_pStrokeColor->GetAlpha()); + } + else + pRenderer->put_PenSize(0.); + + if (-1 != nEndType) + pRenderer->DrawPath(nEndType); + + pRenderer->PathCommandEnd(); + pRenderer->EndCommand(c_nPathType); } CStartElement::CStartElement() @@ -167,6 +212,12 @@ IPathElement* CStartElement::ReadFromArray(std::vector& arValues) return nullptr; } +void CStartElement::Draw(IRenderer* pRenderer) const +{ + if (nullptr != pRenderer) + pRenderer->PathCommandMoveTo(m_dX, m_dY); +} + CMoveElement::CMoveElement() {} @@ -188,6 +239,12 @@ IPathElement* CMoveElement::ReadFromArray(std::vector& arValues) return nullptr; } +void CMoveElement::Draw(IRenderer* pRenderer) const +{ + if (nullptr != pRenderer) + pRenderer->PathCommandMoveTo(m_dX, m_dY); +} + CLineElement::CLineElement() {} @@ -208,6 +265,12 @@ IPathElement* CLineElement::ReadFromArray(std::vector& arValues) return nullptr; } +void CLineElement::Draw(IRenderer* pRenderer) const +{ + if (nullptr != pRenderer) + pRenderer->PathCommandLineTo(m_dX, m_dY); +} + CBezierCurve2Element::CBezierCurve2Element() {} @@ -229,15 +292,21 @@ IPathElement* CBezierCurve2Element::ReadFromArray(std::vector& arVa return nullptr; } -CBezierCurve3Element::CBezierCurve3Element() +void CBezierCurve2Element::Draw(IRenderer* pRenderer) const +{ + // if (nullptr != pRenderer) + // pRenderer->PathCommandCurveTo() +} + +CBezierCurveElement::CBezierCurveElement() {} -IPathElement* CBezierCurve3Element::ReadFromArray(std::vector& arValues) +IPathElement* CBezierCurveElement::ReadFromArray(std::vector& arValues) { if (arValues.size() < 4) return nullptr; - CBezierCurve3Element *pElement = new CBezierCurve3Element(); + CBezierCurveElement *pElement = new CBezierCurveElement(); if (nullptr == pElement) return nullptr; @@ -250,6 +319,12 @@ IPathElement* CBezierCurve3Element::ReadFromArray(std::vector& arVa return nullptr; } +void CBezierCurveElement::Draw(IRenderer* pRenderer) const +{ + if (nullptr != pRenderer) + pRenderer->PathCommandCurveTo(m_dX1, m_dY1, m_dX2, m_dY2, m_dX3, m_dY3); +} + CArcElement::CArcElement() {} @@ -273,6 +348,12 @@ IPathElement* CArcElement::ReadFromArray(std::vector& arValues) return nullptr; } +void CArcElement::Draw(IRenderer* pRenderer) const +{ + // if (nullptr != pRenderer) + // pRenderer->PathCommandArcTo(m_dX, m_dY, m_dRadiusX * 2., m_dRadiusY * 2., ) +} + CCloseElement::CCloseElement() {} @@ -281,4 +362,9 @@ IPathElement* CCloseElement::ReadFromArray(std::vector& arValues) return new CCloseElement(); } +void CCloseElement::Draw(IRenderer* pRenderer) const +{ + if (nullptr != pRenderer) + pRenderer->PathCommandClose(); +} } diff --git a/OFDFile/src/Content/PathObject.h b/OFDFile/src/Content/PathObject.h index 4e88b26b92..0f84d0b4a6 100644 --- a/OFDFile/src/Content/PathObject.h +++ b/OFDFile/src/Content/PathObject.h @@ -15,6 +15,7 @@ public: virtual ~IPathElement(){}; static IPathElement* ReadFromArray(std::vector& arValues) { return nullptr; }; + virtual void Draw(IRenderer* pRenderer) const = 0; }; class CStartElement : public IPathElement @@ -24,6 +25,7 @@ class CStartElement : public IPathElement public: CStartElement(); static IPathElement* ReadFromArray(std::vector& arValues); + void Draw(IRenderer* pRenderer) const override; }; class CMoveElement : public IPathElement @@ -33,6 +35,7 @@ class CMoveElement : public IPathElement public: CMoveElement(); static IPathElement* ReadFromArray(std::vector& arValues); + void Draw(IRenderer* pRenderer) const override; }; class CLineElement : public IPathElement @@ -42,6 +45,7 @@ class CLineElement : public IPathElement public: CLineElement(); static IPathElement* ReadFromArray(std::vector& arValues); + void Draw(IRenderer* pRenderer) const override; }; class CBezierCurve2Element : public IPathElement @@ -53,9 +57,10 @@ class CBezierCurve2Element : public IPathElement public: CBezierCurve2Element(); static IPathElement* ReadFromArray(std::vector& arValues); + void Draw(IRenderer* pRenderer) const override; }; -class CBezierCurve3Element : public IPathElement +class CBezierCurveElement : public IPathElement { double m_dX1; double m_dY1; @@ -64,8 +69,9 @@ class CBezierCurve3Element : public IPathElement double m_dX3; double m_dY3; public: - CBezierCurve3Element(); + CBezierCurveElement(); static IPathElement* ReadFromArray(std::vector& arValues); + void Draw(IRenderer* pRenderer) const override; }; class CArcElement : public IPathElement @@ -80,6 +86,7 @@ class CArcElement : public IPathElement public: CArcElement(); static IPathElement* ReadFromArray(std::vector& arValues); + void Draw(IRenderer* pRenderer) const override; }; class CCloseElement : public IPathElement @@ -87,6 +94,7 @@ class CCloseElement : public IPathElement public: CCloseElement(); static IPathElement* ReadFromArray(std::vector& arValues); + void Draw(IRenderer* pRenderer) const override; }; class CPathObject : public IPageBlock, public CGraphicUnit @@ -110,8 +118,7 @@ public: CPathObject(CXmlReader& oLiteReader); ~CPathObject(); - bool Read(CXmlReader& oLiteReader) override; - void Draw(IRenderer* pRenderer) const override; + void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; }; } diff --git a/OFDFile/src/Content/TextObject.cpp b/OFDFile/src/Content/TextObject.cpp index 7dd398f12e..98e1484f62 100644 --- a/OFDFile/src/Content/TextObject.cpp +++ b/OFDFile/src/Content/TextObject.cpp @@ -45,26 +45,9 @@ CTextObject::CTextObject(CXmlReader& oLiteReader) m_unReadDirection(0), m_unCharDirection(0), m_unWeight(400), m_bItalic(false), m_pFillColor(nullptr), m_pStrokeColor(nullptr) -{ - CTextObject::Read(oLiteReader); -} - -CTextObject::~CTextObject() -{ - if (nullptr != m_pFillColor) - delete m_pFillColor; - - if (nullptr != m_pStrokeColor) - delete m_pStrokeColor; - - for (const CTextCode* pTextCode : m_arTextCodes) - delete pTextCode; -} - -bool CTextObject::Read(CXmlReader& oLiteReader) { if (L"ofd:TextObject" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid()) - return false; + return; if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) { @@ -121,11 +104,21 @@ bool CTextObject::Read(CXmlReader& oLiteReader) else if (L"ofd:TextCode" == wsNodeName) m_arTextCodes.push_back(new CTextCode(oLiteReader)); } - - return true; } -void CTextObject::Draw(IRenderer* pRenderer) const +CTextObject::~CTextObject() +{ + if (nullptr != m_pFillColor) + delete m_pFillColor; + + if (nullptr != m_pStrokeColor) + delete m_pStrokeColor; + + for (const CTextCode* pTextCode : m_arTextCodes) + delete pTextCode; +} + +void CTextObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const { if (nullptr == pRenderer || m_arTextCodes.empty()) return; @@ -135,13 +128,13 @@ void CTextObject::Draw(IRenderer* pRenderer) const if (m_bFill && nullptr != m_pFillColor) { pRenderer->put_BrushType(c_BrushTypeSolid); - pRenderer->put_BrushColor1(255); - pRenderer->put_BrushAlpha1(255); + pRenderer->put_BrushColor1(m_pFillColor->ToInt(pPublicRes)); + pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha()); } else pRenderer->put_BrushType(c_BrushTypeNotSet); - pRenderer->put_FontSize(m_dSize); + pRenderer->put_FontSize(m_dSize * 72. / 25.4); for (const CTextCode* pTextCode : m_arTextCodes) pTextCode->Draw(pRenderer); diff --git a/OFDFile/src/Content/TextObject.h b/OFDFile/src/Content/TextObject.h index 2cf033b8e9..9968d5f26d 100644 --- a/OFDFile/src/Content/TextObject.h +++ b/OFDFile/src/Content/TextObject.h @@ -43,8 +43,7 @@ public: CTextObject(CXmlReader& oLiteReader); ~CTextObject(); - bool Read(CXmlReader& oLiteReader) override; - void Draw(IRenderer* pRenderer) const override; + void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; }; } diff --git a/OFDFile/src/Document.cpp b/OFDFile/src/Document.cpp index 0a83658cc3..eab69c229e 100644 --- a/OFDFile/src/Document.cpp +++ b/OFDFile/src/Document.cpp @@ -3,10 +3,19 @@ namespace OFD { CCommonData::CCommonData() - : m_unMaxUnitID(0) + : m_unMaxUnitID(0), m_pPublicRes(nullptr), m_pDocumentRes(nullptr) {} -bool CCommonData::Read(CXmlReader& oLiteReader) +CCommonData::~CCommonData() +{ + if (nullptr != m_pPublicRes) + delete m_pPublicRes; + + if (nullptr != m_pDocumentRes) + delete m_pDocumentRes; +} + +bool CCommonData::Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath) { if (L"ofd:CommonData" != oLiteReader.GetName()) return false; @@ -22,11 +31,20 @@ bool CCommonData::Read(CXmlReader& oLiteReader) m_oPageArea.Read(oLiteReader); else if (L"ofd:PublicRes" == wsNodeName) { - // m_oPublicRes.Read(); + if (nullptr == m_pPublicRes) + m_pPublicRes = new CRes(); + + m_pPublicRes->Read(NSSystemPath::Combine(wsRootPath, oLiteReader.GetText2())); + } + else if (L"ofd:DocumentRes" == wsNodeName) + { + if(nullptr == m_pDocumentRes) + m_pDocumentRes = new CRes(); + + m_pDocumentRes->Read(NSSystemPath::Combine(wsRootPath, oLiteReader.GetText2())); } else if (L"ofd:MaxUnitID" == wsNodeName) m_unMaxUnitID = oLiteReader.GetUInteger(); - // else if (L"ofd:DocumentRes" == wsNodeName) // else if (L"ofd:TemplatePage" == wsNodeName) // else if (L"ofd:DefaultCS" == wsNodeName) } @@ -45,6 +63,16 @@ void CCommonData::GetPageSize(double& dWidth, double& dHeight) const dHeight = oPhysicalBox.m_dHeight; } +const CRes* CCommonData::GetPublicRes() const +{ + return m_pPublicRes; +} + +const CRes* CCommonData::GetDocumentRes() const +{ + return m_pDocumentRes; +} + CPermission::CPermission() : m_bEdit(true), m_bAnnot(true), m_bExport(true), m_bSignature(true), m_bWatermark(true), m_bPrintScreen(true) @@ -100,7 +128,7 @@ bool CDocument::Read(const std::wstring& wsFilePath) wsNodeName = oLiteReader.GetName(); if (L"ofd:CommonData" == wsNodeName) - m_oCommonData.Read(oLiteReader); + m_oCommonData.Read(oLiteReader, NSSystemPath::GetDirectoryName(wsFilePath)); else if (L"ofd:Pages" == wsNodeName) { const int nPagesDepth = oLiteReader.GetDepth(); @@ -127,7 +155,7 @@ bool CDocument::Read(const std::wstring& wsFilePath) if (-1 == nID) nID = m_mPages.size() + 1; - CPage* pPage = CPage::Read(NSSystemPath::Combine(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc)); + CPage* pPage = CPage::Read(NSSystemPath::Combine(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc), m_oCommonData.GetDocumentRes()); if (nullptr != pPage) m_mPages.insert(std::make_pair(m_mPages.size(), pPage)); @@ -153,7 +181,7 @@ bool CDocument::DrawPage(IRenderer* pRenderer, int nPageIndex) const if (itFound == m_mPages.cend()) return false; - itFound->second->Draw(pRenderer); + itFound->second->Draw(pRenderer, m_oCommonData.GetPublicRes()); return true; } diff --git a/OFDFile/src/Document.h b/OFDFile/src/Document.h index 1731be60e8..e8e62a70a7 100644 --- a/OFDFile/src/Document.h +++ b/OFDFile/src/Document.h @@ -2,7 +2,7 @@ #define DOCUMENT_H #include "Page.h" -#include "PublicRes.h" +#include "Res.h" #include "Types/PageArea.h" @@ -14,13 +14,18 @@ class CCommonData { unsigned int m_unMaxUnitID; CPageArea m_oPageArea; - CPublicRes m_oPublicRes; + CRes* m_pPublicRes; + CRes* m_pDocumentRes; public: CCommonData(); + ~CCommonData(); - bool Read(CXmlReader& oLiteReader); + bool Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath); void GetPageSize(double& dWidth, double &dHeight) const; + + const CRes* GetPublicRes() const; + const CRes* GetDocumentRes() const; }; class CPermission diff --git a/OFDFile/src/IOFDElement.h b/OFDFile/src/IOFDElement.h new file mode 100644 index 0000000000..6ea49d4662 --- /dev/null +++ b/OFDFile/src/IOFDElement.h @@ -0,0 +1,35 @@ +#ifndef IOFDELEMENT_H +#define IOFDELEMENT_H + +#include "Utils/XmlReader.h" + +namespace OFD +{ +class IOFDElement +{ + unsigned int m_unID; +public: + IOFDElement(CXmlReader& oLiteReader) + : m_unID(0) + { + if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) + { + do + { + if (L"ID" == oLiteReader.GetName()) + m_unID = oLiteReader.GetUInteger(true); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); + } + }; + virtual ~IOFDElement(){}; + + unsigned int GetID() const + { + return m_unID; + } +}; +} + +#endif // IOFDELEMENT_H diff --git a/OFDFile/src/OFDFile_Private.cpp b/OFDFile/src/OFDFile_Private.cpp index 0fe6a08460..63c7048dfc 100644 --- a/OFDFile/src/OFDFile_Private.cpp +++ b/OFDFile/src/OFDFile_Private.cpp @@ -77,7 +77,7 @@ bool COFDFile_Private::LoadFromFile(const std::wstring& wsFilePath) COfficeUtils oUtils(NULL); - if (S_OK != oUtils.ExtractToDirectory(wsFilePath,m_pTempFolder->getFullFilePath(L""), NULL, 0)) + if (S_OK != oUtils.ExtractToDirectory(wsFilePath, m_pTempFolder->getFullFilePath(L""), NULL, 0)) return false; return Read(m_pTempFolder); diff --git a/OFDFile/src/Page.cpp b/OFDFile/src/Page.cpp index 769d9fc0e6..509de27174 100644 --- a/OFDFile/src/Page.cpp +++ b/OFDFile/src/Page.cpp @@ -6,11 +6,9 @@ namespace OFD { CPage::CPage() -{ +{} -} - -CPage* CPage::Read(const std::wstring& wsFilePath) +CPage* CPage::Read(const std::wstring& wsFilePath, const CRes* pDocumentRes) { if (wsFilePath.empty()) return nullptr; @@ -34,7 +32,7 @@ CPage* CPage::Read(const std::wstring& wsFilePath) wsNodeName = oLiteReader.GetName(); if (L"ofd:Content" == wsNodeName) - pPage->m_oContent.Read(oLiteReader); + pPage->m_oContent.Read(oLiteReader, pDocumentRes); else if (L"ofd:Area" == wsNodeName) pPage->m_oArea.Read(oLiteReader); } @@ -42,14 +40,14 @@ CPage* CPage::Read(const std::wstring& wsFilePath) return pPage; } -void CPage::Draw(IRenderer* pRenderer) const +void CPage::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const { if (nullptr == pRenderer) return; pRenderer->BeginCommand(c_nImageType); - m_oContent.Draw(pRenderer); + m_oContent.Draw(pRenderer, pPublicRes); pRenderer->EndCommand(c_nImageType); } @@ -61,7 +59,7 @@ void CPage::GetPageSize(double& dWidth, double& dHeight) const if (oPhysicalBox.Empty()) return; - dWidth = oPhysicalBox.m_dWidth * 25.4 / 96.; - dHeight = oPhysicalBox.m_dHeight * 25.4 / 96.; + dWidth = oPhysicalBox.m_dWidth; + dHeight = oPhysicalBox.m_dHeight; } } diff --git a/OFDFile/src/Page.h b/OFDFile/src/Page.h index 6e4628e560..67196c5671 100644 --- a/OFDFile/src/Page.h +++ b/OFDFile/src/Page.h @@ -13,8 +13,8 @@ class CPage public: CPage(); - static CPage* Read(const std::wstring& wsFilePath); - void Draw(IRenderer* pRenderer) const; + static CPage* Read(const std::wstring& wsFilePath, const CRes* pDocumentRes); + void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const; void GetPageSize(double& dWidth, double& dHeight) const; }; diff --git a/OFDFile/src/PublicRes.cpp b/OFDFile/src/PublicRes.cpp deleted file mode 100644 index 70a004cf38..0000000000 --- a/OFDFile/src/PublicRes.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "PublicRes.h" - -namespace OFD -{ -CPublicRes::CPublicRes() -{ - -} - -bool CPublicRes::Read(IFolder* pFolder) -{ - if (nullptr == pFolder) - return false; - - return false; -} -} diff --git a/OFDFile/src/PublicRes.h b/OFDFile/src/PublicRes.h deleted file mode 100644 index f9267c9818..0000000000 --- a/OFDFile/src/PublicRes.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef PUBLICRES_H -#define PUBLICRES_H - -#include "../../OfficeUtils/src/ZipFolder.h" - -namespace OFD -{ -class CPublicRes -{ -public: - CPublicRes(); - - bool Read(IFolder* pFolder); -}; -} - -#endif // PUBLICRES_H diff --git a/OFDFile/src/Res.cpp b/OFDFile/src/Res.cpp new file mode 100644 index 0000000000..52a3736555 --- /dev/null +++ b/OFDFile/src/Res.cpp @@ -0,0 +1,138 @@ +#include "Res.h" + +namespace OFD +{ +CRes::CRes() +{} + +CRes::~CRes() +{ + #define CLEAR_VECTOR(type, arvaribles)\ + for (const std::pair& oValue : arvaribles)\ + delete oValue.second + + CLEAR_VECTOR(CColorSpace, m_mColorSpaces); + CLEAR_VECTOR(CDrawParam, m_mDrawParams); + CLEAR_VECTOR(CFont, m_mFonts); + CLEAR_VECTOR(CMultiMedia, m_mMultiMedias); + CLEAR_VECTOR(CCompositeGraphicUnit, m_mCCompositeGraphicUnits); +} + +template +inline void AddElementToMap(T* pElement, unsigned int unIndex, std::map& mElements) +{ + if (nullptr == pElement) + return; + + typename std::map::const_iterator itFound = mElements.find(unIndex); + + if (mElements.cend() != itFound) + delete itFound->second; + + mElements.insert(std::make_pair(unIndex, pElement)); +} + +bool CRes::Read(const std::wstring& wsFilePath) +{ + if (wsFilePath.empty()) + return false; + + CXmlReader oLiteReader; + if (!oLiteReader.FromFile(wsFilePath) || !oLiteReader.ReadNextNode() || L"ofd:Res" != oLiteReader.GetName() || oLiteReader.IsEmptyNode()) + return false; + + std::wstring wsRootPath; + + if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) + { + std::string sNodeName; + do + { + sNodeName = oLiteReader.GetNameA(); + + if ("BaseLoc" == sNodeName) + { + wsRootPath = NSSystemPath::Combine(NSDirectory::GetFolderPath(wsFilePath), oLiteReader.GetText()); + break; + } + } while (oLiteReader.MoveToNextAttribute()); + } + + oLiteReader.MoveToElement(); + + const int nDepth = oLiteReader.GetDepth(); + std::string sNodeName; + + #define PARSE_CONTINER(container_name, element_name, element_type, melements)\ + if (container_name == sNodeName) \ + {\ + const int nDepth = oLiteReader.GetDepth();\ + element_type* pElement = nullptr;\ + while (oLiteReader.ReadNextSiblingNode(nDepth))\ + {\ + if (element_name == oLiteReader.GetNameA())\ + {\ + pElement = new element_type(oLiteReader);\ + AddElementToMap(pElement, pElement->GetID(), melements);\ + }\ + }\ + continue;\ + } + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + sNodeName = oLiteReader.GetNameA(); + + PARSE_CONTINER("ofd:ColorSpaces", "ofd:ColorSpace", CColorSpace, m_mColorSpaces) + PARSE_CONTINER("ofd:DrawParams", "ofd:DrawParam", CDrawParam, m_mDrawParams) + PARSE_CONTINER("ofd:Fonts", "ofd:Font", CFont, m_mFonts) + PARSE_CONTINER("ofd:CompositeGraphicUnits", "ofd:CCompositeGraphicUnit", CCompositeGraphicUnit, m_mCCompositeGraphicUnits) + + if ("ofd:MultiMedias" == sNodeName) + { + const int nDepth = oLiteReader.GetDepth(); + CMultiMedia* pElement = nullptr; + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + if ("ofd:MultiMedia" == oLiteReader.GetNameA()) + { + pElement = new CMultiMedia(oLiteReader, wsRootPath); + AddElementToMap(pElement, pElement->GetID(), m_mMultiMedias); + } + } + continue; + } + } + + return true; +} + +#define RETURN_ELEMENT_FROM_MAP(element_type, mElements)\ + const std::map::const_iterator itFound = mElements.find(unId);\ + return (mElements.cend() != itFound) ? itFound->second : nullptr\ + +const CColorSpace* CRes::GetColorSpace(unsigned int unId) const +{ + RETURN_ELEMENT_FROM_MAP(CColorSpace, m_mColorSpaces); +} + +const CDrawParam* CRes::GetDrawParam(unsigned int unId) const +{ + RETURN_ELEMENT_FROM_MAP(CDrawParam, m_mDrawParams); +} + +const CFont* CRes::GetFont(unsigned int unId) const +{ + RETURN_ELEMENT_FROM_MAP(CFont, m_mFonts); +} + +const CMultiMedia* CRes::GetMultiMedia(unsigned int unId) const +{ + RETURN_ELEMENT_FROM_MAP(CMultiMedia, m_mMultiMedias); +} + +const CCompositeGraphicUnit* CRes::GetCompositeGraphicUnit(unsigned int unId) const +{ + RETURN_ELEMENT_FROM_MAP(CCompositeGraphicUnit, m_mCCompositeGraphicUnits); +} +} diff --git a/OFDFile/src/Res.h b/OFDFile/src/Res.h new file mode 100644 index 0000000000..1278942088 --- /dev/null +++ b/OFDFile/src/Res.h @@ -0,0 +1,37 @@ +#ifndef RES_H +#define RES_H + +#include + +#include "../../OfficeUtils/src/ZipFolder.h" + +#include "Types/ColorSpace.h" +#include "Types/DrawParam.h" +#include "Types/Font.h" +#include "Types/MultiMedia.h" +#include "Types/CompositeGraphicUnit.h" + +namespace OFD +{ +class CRes +{ + std::map m_mColorSpaces; + std::map m_mDrawParams; + std::map m_mFonts; + std::map m_mMultiMedias; + std::map m_mCCompositeGraphicUnits; +public: + CRes(); + ~CRes(); + + bool Read(const std::wstring& wsFilePath); + + const CColorSpace* GetColorSpace(unsigned int unId) const; + const CDrawParam* GetDrawParam(unsigned int unId) const; + const CFont* GetFont(unsigned int unId) const; + const CMultiMedia* GetMultiMedia(unsigned int unId) const; + const CCompositeGraphicUnit* GetCompositeGraphicUnit(unsigned int unId) const; +}; +} + +#endif // RES_H diff --git a/OFDFile/src/Types/Color.cpp b/OFDFile/src/Types/Color.cpp index 3fd0bd8a4e..15582d4028 100644 --- a/OFDFile/src/Types/Color.cpp +++ b/OFDFile/src/Types/Color.cpp @@ -3,7 +3,7 @@ namespace OFD { CColor::CColor(CXmlReader& oXmlReader) - : m_oValue{0, 0, 0}, m_nIndex(0), m_unColorSpace(0), m_chAlpha(255) + : m_oValues{0, 0, 0}, m_nIndex(0), m_unColorSpace(0), m_chAlpha(255) { Read(oXmlReader); } @@ -25,12 +25,13 @@ bool CColor::Read(CXmlReader& oXmlReader) { const std::vector arValues{oXmlReader.GetArrayDoubles(true)}; - if (3 > arValues.size()) + if (4 > arValues.size()) continue; - m_oValue.m_chRed = static_cast(arValues[0]); - m_oValue.m_chGreen = static_cast(arValues[1]); - m_oValue.m_chBlue = static_cast(arValues[2]); + m_oValues[0] = static_cast(arValues[0]); + m_oValues[1] = static_cast(arValues[1]); + m_oValues[2] = static_cast(arValues[2]); + m_oValues[3] = static_cast(arValues[3]); } else if ("Alpha" == sAttributeName) m_chAlpha = oXmlReader.GetUInteger(true); @@ -43,9 +44,42 @@ bool CColor::Read(CXmlReader& oXmlReader) return true; } -int CColor::ToInt() const +int CColor::ToInt(const CRes* pPublicRes) const { - return (255 << 24) | (m_oValue.m_chRed << 16) | (m_oValue.m_chGreen << 8) | (m_oValue.m_chBlue << 0); + if (nullptr != pPublicRes) + { + const CColorSpace *pColorSpace = pPublicRes->GetColorSpace(m_unColorSpace); + + if (nullptr != pColorSpace) + { + switch(pColorSpace->GetType()) + { + case CColorSpace::EType::GRAY: + return (255 << 24) | (128 << 16) | (128 << 8) | (128 << 0); + case CColorSpace::EType::RGB: + return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[1] << 8) | (m_oValues[2] << 0); + case CColorSpace::EType::CMYK: + { + const float cF = m_oValues[0] / 255.0f; + const float mF = m_oValues[1] / 255.0f; + const float yF = m_oValues[2] / 255.0f; + const float kF = m_oValues[3] / 255.0f; + + const float r = (1.0f - cF) * (1.0f - kF); + const float g = (1.0f - mF) * (1.0f - kF); + const float b = (1.0f - yF) * (1.0f - kF); + + const unsigned char rByte = static_cast(r * 255); + const unsigned char gByte = static_cast(g * 255); + const unsigned char bByte = static_cast(b * 255); + + return (rByte << 0) | (gByte << 8) | (bByte << 16); + } + } + } + } + + return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[1] << 8) | (m_oValues[2] << 0); } BYTE CColor::GetAlpha() const diff --git a/OFDFile/src/Types/Color.h b/OFDFile/src/Types/Color.h index c2199791d4..42f5f8bd90 100644 --- a/OFDFile/src/Types/Color.h +++ b/OFDFile/src/Types/Color.h @@ -2,17 +2,13 @@ #define COLOR_H #include "../Utils/XmlReader.h" +#include "../Res.h" namespace OFD { class CColor { - struct TColorChannels - { - BYTE m_chRed; - BYTE m_chGreen; - BYTE m_chBlue; - } m_oValue; + BYTE m_oValues[4]; int m_nIndex; unsigned int m_unColorSpace; @@ -27,7 +23,7 @@ public: bool Read(CXmlReader& oXmlReader); - int ToInt() const; + int ToInt(const CRes* pPublicRes) const; BYTE GetAlpha() const; }; } diff --git a/OFDFile/src/Types/ColorSpace.cpp b/OFDFile/src/Types/ColorSpace.cpp new file mode 100644 index 0000000000..3dfd6e5e45 --- /dev/null +++ b/OFDFile/src/Types/ColorSpace.cpp @@ -0,0 +1,35 @@ +#include "ColorSpace.h" + +namespace OFD +{ +CColorSpace::CColorSpace(CXmlReader& oXmlReader) + : IOFDElement(oXmlReader) +{ + if (0 != oXmlReader.GetAttributesCount() && oXmlReader.MoveToFirstAttribute()) + { + std::string sArgumentName; + do + { + sArgumentName = oXmlReader.GetNameA(); + + if ("Type" == sArgumentName) + { + const std::string sValue{oXmlReader.GetTextA()}; + + if ("Gray" == sValue) + m_eType = EType::GRAY; + else if ("RGB" == sValue) + m_eType = EType::RGB; + else if ("CMYK" == sValue) + m_eType = EType::CMYK; + } + } while (oXmlReader.MoveToNextAttribute()); + } + oXmlReader.MoveToElement(); +} + +CColorSpace::EType CColorSpace::GetType() const +{ + return m_eType; +} +} diff --git a/OFDFile/src/Types/ColorSpace.h b/OFDFile/src/Types/ColorSpace.h new file mode 100644 index 0000000000..19dceaf87d --- /dev/null +++ b/OFDFile/src/Types/ColorSpace.h @@ -0,0 +1,25 @@ +#ifndef COLORSPACE_H +#define COLORSPACE_H + +#include "../IOFDElement.h" + +namespace OFD +{ +class CColorSpace : public IOFDElement +{ +public: + CColorSpace(CXmlReader& oXmlReader); + + enum class EType + { + GRAY, + RGB, + CMYK + }; + + EType GetType() const; +private: + EType m_eType; +}; +} +#endif // COLORSPACE_H diff --git a/OFDFile/src/Types/CompositeGraphicUnit.cpp b/OFDFile/src/Types/CompositeGraphicUnit.cpp new file mode 100644 index 0000000000..5ecaa06d88 --- /dev/null +++ b/OFDFile/src/Types/CompositeGraphicUnit.cpp @@ -0,0 +1,8 @@ +#include "CompositeGraphicUnit.h" + +namespace OFD +{ +CCompositeGraphicUnit::CCompositeGraphicUnit(CXmlReader& oXmlReader) + : IOFDElement(oXmlReader) +{} +} diff --git a/OFDFile/src/Types/CompositeGraphicUnit.h b/OFDFile/src/Types/CompositeGraphicUnit.h new file mode 100644 index 0000000000..be593f293b --- /dev/null +++ b/OFDFile/src/Types/CompositeGraphicUnit.h @@ -0,0 +1,15 @@ +#ifndef COMPOSITEGRAPHICUNIT_H +#define COMPOSITEGRAPHICUNIT_H + +#include "../IOFDElement.h" + +namespace OFD +{ +class CCompositeGraphicUnit : public IOFDElement +{ +public: + CCompositeGraphicUnit(CXmlReader& oXmlReader); +}; +} + +#endif // COMPOSITEGRAPHICUNIT_H diff --git a/OFDFile/src/Types/DrawParam.cpp b/OFDFile/src/Types/DrawParam.cpp new file mode 100644 index 0000000000..c1738b429c --- /dev/null +++ b/OFDFile/src/Types/DrawParam.cpp @@ -0,0 +1,8 @@ +#include "DrawParam.h" + +namespace OFD +{ +CDrawParam::CDrawParam(CXmlReader& oXmlReader) + : IOFDElement(oXmlReader) +{} +} diff --git a/OFDFile/src/Types/DrawParam.h b/OFDFile/src/Types/DrawParam.h new file mode 100644 index 0000000000..90d8080ca1 --- /dev/null +++ b/OFDFile/src/Types/DrawParam.h @@ -0,0 +1,14 @@ +#ifndef DRAWPARAM_H +#define DRAWPARAM_H + +#include "../IOFDElement.h" + +namespace OFD +{ +class CDrawParam : public IOFDElement +{ +public: + CDrawParam(CXmlReader& oXmlReader); +}; +} +#endif // DRAWPARAM_H diff --git a/OFDFile/src/Types/Font.cpp b/OFDFile/src/Types/Font.cpp new file mode 100644 index 0000000000..7c49621e5a --- /dev/null +++ b/OFDFile/src/Types/Font.cpp @@ -0,0 +1,37 @@ +#include "Font.h" + +namespace OFD +{ +CFont::CFont(CXmlReader& oXmlReader) + : IOFDElement(oXmlReader), + m_wsCharset(L"unicode"), m_bItalic(false), m_bBold(false), + m_bSerif(false), m_bFixedWidth(false) +{ + if (0 != oXmlReader.GetAttributesCount() && oXmlReader.MoveToFirstAttribute()) + { + std::string sArgumentName; + + do + { + sArgumentName = oXmlReader.GetNameA(); + + if ("FontName" == sArgumentName) + m_wsFontName = oXmlReader.GetText(); + else if ("FamilyName" == sArgumentName) + m_wsFamilyName = oXmlReader.GetText(); + else if ("Charset" == sArgumentName) + m_wsCharset = oXmlReader.GetText(); + else if ("Italic" == sArgumentName) + m_bItalic = oXmlReader.GetBoolean(true); + else if ("Bold" == sArgumentName) + m_bBold = oXmlReader.GetBoolean(true); + else if ("Serif" == sArgumentName) + m_bSerif = oXmlReader.GetBoolean(true); + else if ("FixedWidth" == sArgumentName) + m_bFixedWidth = oXmlReader.GetBoolean(true); + } while (oXmlReader.MoveToNextAttribute()); + } + + oXmlReader.MoveToElement(); +} +} diff --git a/OFDFile/src/Types/Font.h b/OFDFile/src/Types/Font.h new file mode 100644 index 0000000000..9f58e34d84 --- /dev/null +++ b/OFDFile/src/Types/Font.h @@ -0,0 +1,25 @@ +#ifndef FONT_H +#define FONT_H + +#include "../IOFDElement.h" + +namespace OFD +{ +class CFont : public IOFDElement +{ +public: + CFont(CXmlReader& oXmlReader); +private: + std::wstring m_wsFontName; + std::wstring m_wsFamilyName; + std::wstring m_wsCharset; + bool m_bItalic; + bool m_bBold; + bool m_bSerif; + bool m_bFixedWidth; + + std::wstring m_wsFileName; +}; +} + +#endif // FONT_H diff --git a/OFDFile/src/Types/MultiMedia.cpp b/OFDFile/src/Types/MultiMedia.cpp new file mode 100644 index 0000000000..b759879c81 --- /dev/null +++ b/OFDFile/src/Types/MultiMedia.cpp @@ -0,0 +1,54 @@ +#include "MultiMedia.h" + +#include "../../../DesktopEditor/common/Path.h" + +namespace OFD +{ +CMultiMedia::CMultiMedia(CXmlReader& oXmlReader, const std::wstring& wsRootPath) + : IOFDElement(oXmlReader), m_eType(EType::Image) +{ + if (0 != oXmlReader.GetAttributesCount() && oXmlReader.MoveToFirstAttribute()) + { + std::string sArgumentName; + do + { + sArgumentName = oXmlReader.GetNameA(); + + if ("Type" == sArgumentName) + { + const std::string sValue{oXmlReader.GetTextA()}; + + if ("Image" == sValue) + m_eType = EType::Image; + else if ("Audio" == sValue) + m_eType = EType::Audio; + else if ("Video" == sValue) + m_eType = EType::Video; + } + } while (oXmlReader.MoveToNextAttribute()); + } + + oXmlReader.MoveToElement(); + + const int nDepth = oXmlReader.GetDepth(); + + while (oXmlReader.ReadNextSiblingNode(nDepth)) + { + if ("ofd:MediaFile" == oXmlReader.GetNameA()) + { + m_wsFilePath = NSSystemPath::Combine(wsRootPath, oXmlReader.GetText2()); + break; + } + } +} + +CMultiMedia::EType CMultiMedia::GetType() const +{ + return m_eType; +} + +std::wstring CMultiMedia::GetFilePath() const +{ + return m_wsFilePath; +} +} diff --git a/OFDFile/src/Types/MultiMedia.h b/OFDFile/src/Types/MultiMedia.h new file mode 100644 index 0000000000..2435a91cd4 --- /dev/null +++ b/OFDFile/src/Types/MultiMedia.h @@ -0,0 +1,28 @@ +#ifndef MULTIMEDIA_H +#define MULTIMEDIA_H + +#include "../IOFDElement.h" + +namespace OFD +{ +class CMultiMedia : public IOFDElement +{ +public: + CMultiMedia(CXmlReader& oXmlReader, const std::wstring& wsRootPath); + + enum class EType + { + Image, + Audio, + Video + }; + + EType GetType() const; + std::wstring GetFilePath() const; +private: + EType m_eType; + std::wstring m_wsFilePath; +}; +} + +#endif // MULTIMEDIA_H diff --git a/OFDFile/src/Types/PageArea.cpp b/OFDFile/src/Types/PageArea.cpp index 96c5f4eac3..2001ef6898 100644 --- a/OFDFile/src/Types/PageArea.cpp +++ b/OFDFile/src/Types/PageArea.cpp @@ -7,7 +7,8 @@ CPageArea::CPageArea() bool CPageArea::Read(CXmlReader& oLiteReader) { - if (L"ofd:PageArea" != oLiteReader.GetName()) + if (L"ofd:PageArea" != oLiteReader.GetName() && + L"ofd:Area" != oLiteReader.GetName()) return false; const int nDepth = oLiteReader.GetDepth(); From 4bd0a53c9e6c7f1fc6a9a46dfcbca690626052b6 Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 8 Apr 2025 17:43:28 +0300 Subject: [PATCH 06/15] Improved OFD format conversion --- OFDFile/OFDFile.pro | 4 + OFDFile/OfdFile.h | 2 +- OFDFile/src/Base.cpp | 8 +- OFDFile/src/Base.h | 5 +- OFDFile/src/Content/Content.cpp | 8 +- OFDFile/src/Content/Content.h | 4 +- OFDFile/src/Content/GraphicUnit.cpp | 20 ++++- OFDFile/src/Content/IPageBlock.h | 2 +- OFDFile/src/Content/ImageObject.cpp | 10 +-- OFDFile/src/Content/ImageObject.h | 2 +- OFDFile/src/Content/Layer.cpp | 8 +- OFDFile/src/Content/Layer.h | 4 +- OFDFile/src/Content/PageBlock.cpp | 16 ++-- OFDFile/src/Content/PageBlock.h | 6 +- OFDFile/src/Content/PathObject.cpp | 14 ++-- OFDFile/src/Content/PathObject.h | 4 +- OFDFile/src/Content/TextObject.cpp | 117 +++++++++++++++++++++++++--- OFDFile/src/Content/TextObject.h | 25 +++++- OFDFile/src/Document.cpp | 83 ++------------------ OFDFile/src/Document.h | 24 +----- OFDFile/src/OFDFile_Private.cpp | 2 +- OFDFile/src/Page.cpp | 44 +++++++++-- OFDFile/src/Page.h | 10 ++- OFDFile/src/Res.cpp | 48 ++++++------ OFDFile/src/Res.h | 4 +- OFDFile/src/Types/Color.cpp | 72 +++++++---------- OFDFile/src/Types/Color.h | 9 +-- OFDFile/src/Types/CommonData.cpp | 90 +++++++++++++++++++++ OFDFile/src/Types/CommonData.h | 35 +++++++++ OFDFile/src/Types/Font.cpp | 44 ++++++++++- OFDFile/src/Types/Font.h | 9 ++- OFDFile/src/Types/MultiMedia.cpp | 7 +- OFDFile/src/Types/PageArea.cpp | 3 +- OFDFile/src/Types/TemplatePage.cpp | 53 +++++++++++++ OFDFile/src/Types/TemplatePage.h | 33 ++++++++ OFDFile/src/Utils/Utils.h | 35 +++++++++ 36 files changed, 612 insertions(+), 252 deletions(-) create mode 100644 OFDFile/src/Types/CommonData.cpp create mode 100644 OFDFile/src/Types/CommonData.h create mode 100644 OFDFile/src/Types/TemplatePage.cpp create mode 100644 OFDFile/src/Types/TemplatePage.h diff --git a/OFDFile/OFDFile.pro b/OFDFile/OFDFile.pro index 0f5a5a9342..44b905d5e4 100644 --- a/OFDFile/OFDFile.pro +++ b/OFDFile/OFDFile.pro @@ -46,11 +46,13 @@ HEADERS += \ src/Res.h \ src/Types/Color.h \ src/Types/ColorSpace.h \ + src/Types/CommonData.h \ src/Types/CompositeGraphicUnit.h \ src/Types/DrawParam.h \ src/Types/Font.h \ src/Types/MultiMedia.h \ src/Types/PageArea.h \ + src/Types/TemplatePage.h \ src/Utils/Types.h \ src/Utils/Utils.h \ src/Utils/XmlReader.h @@ -71,10 +73,12 @@ SOURCES += \ src/Res.cpp \ src/Types/Color.cpp \ src/Types/ColorSpace.cpp \ + src/Types/CommonData.cpp \ src/Types/CompositeGraphicUnit.cpp \ src/Types/DrawParam.cpp \ src/Types/Font.cpp \ src/Types/MultiMedia.cpp \ src/Types/PageArea.cpp \ + src/Types/TemplatePage.cpp \ src/Utils/Types.cpp \ src/Utils/XmlReader.cpp diff --git a/OFDFile/OfdFile.h b/OFDFile/OfdFile.h index 63d50c5ce3..d94373c09d 100644 --- a/OFDFile/OfdFile.h +++ b/OFDFile/OfdFile.h @@ -26,7 +26,7 @@ public: const std::wstring& owner_password = L"", const std::wstring& user_password = L"") override; // Close - virtual void Close() override; + void Close() override; // Get IApplicationFonts for wrappers virtual NSFonts::IApplicationFonts* GetFonts() override; diff --git a/OFDFile/src/Base.cpp b/OFDFile/src/Base.cpp index 1c8c4aeb43..1439579b63 100644 --- a/OFDFile/src/Base.cpp +++ b/OFDFile/src/Base.cpp @@ -61,7 +61,7 @@ CDocBody::CDocBody() } -CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) +CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder, NSFonts::IFontManager* pFontManager) { if (L"ofd:DocBody" != oLiteReader.GetName()) return nullptr; @@ -91,7 +91,7 @@ CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) const std::wstring wsPath = NSSystemPath::ShortenPath(oLiteReader.GetText2()); if (!wsPath.empty() && L'.' != wsPath.front()) - pDocBody->m_oDocument.Read(pFolder->getFullFilePath(wsPath)); + pDocBody->m_oDocument.Read(pFolder->getFullFilePath(wsPath), pFontManager); } ELSE_IF_CHECK_NODE(L"ofd:Signatures", pDocBody->m_wsSignature); } @@ -123,7 +123,7 @@ CBase::~CBase() RELEASEOBJECT(pDocBody); } -bool CBase::Read(IFolder* pFolder) +bool CBase::Read(IFolder* pFolder, NSFonts::IFontManager* pFontManager) { if (nullptr == pFolder || !pFolder->existsXml(L"OFD.xml")) return false; @@ -138,7 +138,7 @@ bool CBase::Read(IFolder* pFolder) while (oLiteReader.ReadNextSiblingNode(nDepth)) { - pDocBody = CDocBody::Read(oLiteReader, pFolder); + pDocBody = CDocBody::Read(oLiteReader, pFolder, pFontManager); if (nullptr != pDocBody) m_arDocBodies.push_back(pDocBody); } diff --git a/OFDFile/src/Base.h b/OFDFile/src/Base.h index 78af33d98b..0c724cc753 100644 --- a/OFDFile/src/Base.h +++ b/OFDFile/src/Base.h @@ -2,6 +2,7 @@ #define BASE_H #include "../../DesktopEditor/graphics/IRenderer.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" #include "../../OfficeUtils/src/ZipFolder.h" #include "Document.h" @@ -49,7 +50,7 @@ class CDocBody std::wstring m_wsSignature; public: CDocBody(); - static CDocBody* Read(CXmlReader& oLiteReader, IFolder* pFolder); + static CDocBody* Read(CXmlReader& oLiteReader, IFolder* pFolder, NSFonts::IFontManager* pFontManager); bool DrawPage(IRenderer* pRenderer, int nPageIndex) const; @@ -64,7 +65,7 @@ public: CBase(); ~CBase(); - bool Read(IFolder* pFolder); + bool Read(IFolder* pFolder, NSFonts::IFontManager* pFontManager); void DrawPage(IRenderer* pRenderer, int nPageIndex) const; unsigned int GetPageCount() const; diff --git a/OFDFile/src/Content/Content.cpp b/OFDFile/src/Content/Content.cpp index 3ba8801bd7..dfdafda4a2 100644 --- a/OFDFile/src/Content/Content.cpp +++ b/OFDFile/src/Content/Content.cpp @@ -11,7 +11,7 @@ CContent::~CContent() delete pLayer; } -bool CContent::Read(CXmlReader& oLiteReader, const CRes* pDocumentRes) +bool CContent::Read(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) { if (L"ofd:Content" != oLiteReader.GetName()) return false; @@ -24,18 +24,18 @@ bool CContent::Read(CXmlReader& oLiteReader, const CRes* pDocumentRes) wsNodeName = oLiteReader.GetName(); if (L"ofd:Layer" == wsNodeName) - m_arLayers.push_back(new CLayer(oLiteReader, pDocumentRes)); + m_arLayers.push_back(new CLayer(oLiteReader, pDocumentRes, pPublicRes, pFontManager)); } return false; } -void CContent::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const +void CContent::Draw(IRenderer* pRenderer) const { if (nullptr == pRenderer) return; for (const CLayer* pLayer : m_arLayers) - pLayer->Draw(pRenderer, pPublicRes); + pLayer->Draw(pRenderer); } } diff --git a/OFDFile/src/Content/Content.h b/OFDFile/src/Content/Content.h index 8f52a36c82..c28897a1af 100644 --- a/OFDFile/src/Content/Content.h +++ b/OFDFile/src/Content/Content.h @@ -12,8 +12,8 @@ public: CContent(); ~CContent(); - bool Read(CXmlReader& oLiteReader, const CRes* pDocumentRes); - void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const; + bool Read(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); + void Draw(IRenderer* pRenderer) const; }; } diff --git a/OFDFile/src/Content/GraphicUnit.cpp b/OFDFile/src/Content/GraphicUnit.cpp index 6ff8188d72..c87de5a7f1 100644 --- a/OFDFile/src/Content/GraphicUnit.cpp +++ b/OFDFile/src/Content/GraphicUnit.cpp @@ -67,10 +67,24 @@ void CGraphicUnit::Apply(IRenderer* pRenderer) const if (nullptr == pRenderer) return; - //TODO:: apply boundary -> clipping -> apply CTM - // pRenderer->SetTransform(1., 0., 0., 1., m_oBoundary.m_dX, m_oBoundary.m_dY); + pRenderer->ResetTransform(); - //Clipping + // Clipping + // pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionIntersect); + + // pRenderer->BeginCommand(c_nClipType); + // pRenderer->BeginCommand(c_nPathType); + // pRenderer->PathCommandStart(); + + // pRenderer->PathCommandMoveTo(m_oBoundary.m_dX, m_oBoundary.m_dY); + // pRenderer->PathCommandLineTo(m_oBoundary.m_dX + m_oBoundary.m_dWidth, m_oBoundary.m_dY); + // pRenderer->PathCommandLineTo(m_oBoundary.m_dX + m_oBoundary.m_dWidth, m_oBoundary.m_dY + m_oBoundary.m_dHeight); + // pRenderer->PathCommandLineTo(m_oBoundary.m_dX, m_oBoundary.m_dY + m_oBoundary.m_dHeight); + // pRenderer->PathCommandLineTo(m_oBoundary.m_dX, m_oBoundary.m_dY); + + // pRenderer->EndCommand(c_nPathType); + // pRenderer->EndCommand(c_nClipType); + // pRenderer->PathCommandEnd(); pRenderer->SetTransform(m_oCTM.m_dM11, m_oCTM.m_dM12, m_oCTM.m_dM21, m_oCTM.m_dM22, m_oBoundary.m_dX + m_oCTM.m_dDx, m_oBoundary.m_dY + m_oCTM.m_dDy); } diff --git a/OFDFile/src/Content/IPageBlock.h b/OFDFile/src/Content/IPageBlock.h index c638da4cd4..ba92d558bd 100644 --- a/OFDFile/src/Content/IPageBlock.h +++ b/OFDFile/src/Content/IPageBlock.h @@ -14,7 +14,7 @@ public: IPageBlock(CXmlReader& oLiteReader) : IOFDElement(oLiteReader){}; virtual ~IPageBlock(){}; - virtual void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const = 0; + virtual void Draw(IRenderer* pRenderer) const = 0; }; } diff --git a/OFDFile/src/Content/ImageObject.cpp b/OFDFile/src/Content/ImageObject.cpp index 9f88f9c6b6..b49e8ec34d 100644 --- a/OFDFile/src/Content/ImageObject.cpp +++ b/OFDFile/src/Content/ImageObject.cpp @@ -1,9 +1,11 @@ #include "ImageObject.h" +#include "../../../DesktopEditor/graphics/Image.h" + namespace OFD { CImageObject::CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes) - : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader) + : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), m_pMultiMedia(nullptr) { if (nullptr == pDocumentRes || "ofd:ImageObject" != oLiteReader.GetNameA() || 0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) return; @@ -24,7 +26,7 @@ CImageObject::CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes) oLiteReader.MoveToElement(); } -void CImageObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const +void CImageObject::Draw(IRenderer* pRenderer) const { if (nullptr == pRenderer || nullptr == m_pMultiMedia) return; @@ -36,8 +38,6 @@ void CImageObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const if (wsFilePath.empty()) return; - const TBox oBoundry{GetBoundary()}; - - pRenderer->DrawImageFromFile(wsFilePath, 0, 0, oBoundry.m_dWidth, oBoundry.m_dHeight); + pRenderer->DrawImageFromFile(wsFilePath, 0, 0, 1, 1); } } diff --git a/OFDFile/src/Content/ImageObject.h b/OFDFile/src/Content/ImageObject.h index 5ff846ca25..06d2fd21d5 100644 --- a/OFDFile/src/Content/ImageObject.h +++ b/OFDFile/src/Content/ImageObject.h @@ -15,7 +15,7 @@ class CImageObject : public IPageBlock, public CGraphicUnit public: CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes); - void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; + void Draw(IRenderer* pRenderer) const override; }; } diff --git a/OFDFile/src/Content/Layer.cpp b/OFDFile/src/Content/Layer.cpp index 9103603f2c..027400e956 100644 --- a/OFDFile/src/Content/Layer.cpp +++ b/OFDFile/src/Content/Layer.cpp @@ -6,13 +6,13 @@ namespace OFD { -CLayer::CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes) +CLayer::CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) : IPageBlock(oLiteReader), m_eType(EType::Body) { if (L"ofd:Layer" != oLiteReader.GetName()) return; - CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes); + CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes, pPublicRes, pFontManager); } CLayer::~CLayer() @@ -21,12 +21,12 @@ CLayer::~CLayer() delete pPageBlock; } -void CLayer::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const +void CLayer::Draw(IRenderer* pRenderer) const { if (nullptr == pRenderer) return; for (const IPageBlock* pPageBlock : m_arPageBlocks) - pPageBlock->Draw(pRenderer, pPublicRes); + pPageBlock->Draw(pRenderer); } } diff --git a/OFDFile/src/Content/Layer.h b/OFDFile/src/Content/Layer.h index 427525f558..283086df0f 100644 --- a/OFDFile/src/Content/Layer.h +++ b/OFDFile/src/Content/Layer.h @@ -18,10 +18,10 @@ class CLayer : public IPageBlock unsigned int m_unID; std::vector m_arPageBlocks; public: - CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes); + CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); ~CLayer(); - void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; + void Draw(IRenderer* pRenderer) const override; }; } diff --git a/OFDFile/src/Content/PageBlock.cpp b/OFDFile/src/Content/PageBlock.cpp index 6565b58530..ae99a28474 100644 --- a/OFDFile/src/Content/PageBlock.cpp +++ b/OFDFile/src/Content/PageBlock.cpp @@ -6,16 +6,16 @@ namespace OFD { -CPageBlock::CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes) +CPageBlock::CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) : IPageBlock(oLiteReader) { if ("ofd:PageBlock" != oLiteReader.GetNameA() || oLiteReader.IsEmptyNode()) return; - CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes); + CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes, pPublicRes, pFontManager); } -void CPageBlock::ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks, const CRes* pDocumentRes) +void CPageBlock::ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) { const int nDepth = oLiteReader.GetDepth(); std::wstring wsNodeName; @@ -28,11 +28,11 @@ void CPageBlock::ReadIntoContainer(CXmlReader& oLiteReader, std::vectorDraw(pRenderer, pPublicRes); + pPageBlock->Draw(pRenderer); } } diff --git a/OFDFile/src/Content/PageBlock.h b/OFDFile/src/Content/PageBlock.h index 5db7e8f4a2..8619addaf2 100644 --- a/OFDFile/src/Content/PageBlock.h +++ b/OFDFile/src/Content/PageBlock.h @@ -10,11 +10,11 @@ class CPageBlock : public IPageBlock { std::vector m_arPageBlocks; public: - CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes); + CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); - static void ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks, const CRes* pDocumentRes); + static void ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); - void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; + void Draw(IRenderer* pRenderer) const override; }; } diff --git a/OFDFile/src/Content/PathObject.cpp b/OFDFile/src/Content/PathObject.cpp index 74e4a2cf36..c43ea03466 100644 --- a/OFDFile/src/Content/PathObject.cpp +++ b/OFDFile/src/Content/PathObject.cpp @@ -3,7 +3,7 @@ namespace OFD { -CPathObject::CPathObject(CXmlReader& oLiteReader) +CPathObject::CPathObject(CXmlReader& oLiteReader, const CRes* pPublicRes) : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), m_bStroke(true), m_bFill(true), m_eRule(ERule::NonZero), m_pFillColor(nullptr), m_pStrokeColor(nullptr) @@ -47,14 +47,14 @@ CPathObject::CPathObject(CXmlReader& oLiteReader) if (nullptr != m_pFillColor) delete m_pFillColor; - m_pFillColor = new CColor(oLiteReader); + m_pFillColor = new CColor(oLiteReader, pPublicRes); } else if (L"ofd:StrokeColor" == wsNodeName) { if (nullptr != m_pStrokeColor) delete m_pStrokeColor; - m_pStrokeColor = new CColor(oLiteReader); + m_pStrokeColor = new CColor(oLiteReader, pPublicRes); } else if (L"ofd:AbbreviatedData" == wsNodeName) { @@ -130,12 +130,12 @@ void CPathObject::AddElement(const IPathElement* pElement) m_arElements.push_back(pElement); } -void CPathObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const +void CPathObject::Draw(IRenderer* pRenderer) const { if (nullptr == pRenderer || m_arElements.empty()) return; - ((CGraphicUnit*)this)->Apply(pRenderer); + CGraphicUnit::Apply(pRenderer); pRenderer->BeginCommand(c_nPathType); pRenderer->PathCommandStart(); @@ -168,7 +168,7 @@ void CPathObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const if (m_bFill && nullptr != m_pFillColor) { pRenderer->put_BrushType(c_BrushTypeSolid); - pRenderer->put_BrushColor1(m_pFillColor->ToInt(pPublicRes)); + pRenderer->put_BrushColor1(m_pFillColor->ToInt()); pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha()); } else @@ -177,7 +177,7 @@ void CPathObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const if (m_bStroke && nullptr != m_pStrokeColor) { pRenderer->put_PenSize(m_dLineWidth); - pRenderer->put_PenColor(m_pStrokeColor->ToInt(pPublicRes)); + pRenderer->put_PenColor(m_pStrokeColor->ToInt()); pRenderer->put_PenAlpha(m_pStrokeColor->GetAlpha()); } else diff --git a/OFDFile/src/Content/PathObject.h b/OFDFile/src/Content/PathObject.h index 0f84d0b4a6..156a20606a 100644 --- a/OFDFile/src/Content/PathObject.h +++ b/OFDFile/src/Content/PathObject.h @@ -115,10 +115,10 @@ class CPathObject : public IPageBlock, public CGraphicUnit void AddElement(const IPathElement* pElement); public: - CPathObject(CXmlReader& oLiteReader); + CPathObject(CXmlReader& oLiteReader, const CRes* pPublicRes); ~CPathObject(); - void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; + void Draw(IRenderer* pRenderer) const override; }; } diff --git a/OFDFile/src/Content/TextObject.cpp b/OFDFile/src/Content/TextObject.cpp index 98e1484f62..9f20833b05 100644 --- a/OFDFile/src/Content/TextObject.cpp +++ b/OFDFile/src/Content/TextObject.cpp @@ -31,20 +31,48 @@ CTextCode::CTextCode(CXmlReader& oLiteReader) m_wsText = oLiteReader.GetText2(); } -void CTextCode::Draw(IRenderer* pRenderer) const +void CTextCode::Draw(IRenderer* pRenderer, unsigned int& unIndex, const std::vector& arCGTransforms) const { if (nullptr == pRenderer || m_wsText.empty()) return; - pRenderer->CommandDrawText(m_wsText, m_dX, m_dY, 0, 0); + double dX = m_dX, dDelta = 0; + bool bDrawed = false; + + for (unsigned int unGlyphIndex = 0; unGlyphIndex < m_wsText.length(); ++unGlyphIndex) + { + if (!arCGTransforms.empty() && false) + { + for (const TCGTransform& oCGTransform : arCGTransforms) + { + if (oCGTransform.Draw(pRenderer, unIndex, dX, m_dY)) + { + bDrawed = true; + break; + } + } + } + + if (!bDrawed) + { + pRenderer->CommandDrawTextCHAR(m_wsText[unGlyphIndex], dX, m_dY, 0, 0); + ++unIndex; + } + + if (unGlyphIndex < m_arDeltaX.size()) + dDelta = m_arDeltaX[unGlyphIndex]; + + dX += dDelta; + } } -CTextObject::CTextObject(CXmlReader& oLiteReader) +CTextObject::CTextObject(CXmlReader& oLiteReader, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), m_bStroke(false), m_bFill(false), m_dHScale(1.), m_unReadDirection(0), m_unCharDirection(0), m_unWeight(400), m_bItalic(false), - m_pFillColor(nullptr), m_pStrokeColor(nullptr) + m_pFillColor(nullptr), m_pStrokeColor(nullptr), m_pFont(nullptr), + m_pFontManager(pFontManager) { if (L"ofd:TextObject" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid()) return; @@ -58,7 +86,10 @@ CTextObject::CTextObject(CXmlReader& oLiteReader) wsAttributeName = oLiteReader.GetName(); if (L"Font" == wsAttributeName) - m_unFont = oLiteReader.GetUInteger(true); + { + if (nullptr != pPublicRes) + m_pFont = pPublicRes->GetFont(oLiteReader.GetUInteger(true)); + } else if (L"Size" == wsAttributeName) m_dSize = oLiteReader.GetDouble(true); else if (L"Stroke" == wsAttributeName) @@ -92,17 +123,19 @@ CTextObject::CTextObject(CXmlReader& oLiteReader) if (nullptr != m_pFillColor) delete m_pFillColor; - m_pFillColor = new CColor(oLiteReader); + m_pFillColor = new CColor(oLiteReader, pPublicRes); } else if (L"ofd:StrokeColor" == wsNodeName) { if (nullptr != m_pStrokeColor) delete m_pStrokeColor; - m_pStrokeColor = new CColor(oLiteReader); + m_pStrokeColor = new CColor(oLiteReader, pPublicRes); } else if (L"ofd:TextCode" == wsNodeName) m_arTextCodes.push_back(new CTextCode(oLiteReader)); + else if (L"ofd:CGTransform" == wsNodeName) + m_arCGTransforms.push_back(TCGTransform::Read(oLiteReader)); } } @@ -118,17 +151,20 @@ CTextObject::~CTextObject() delete pTextCode; } -void CTextObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const +void CTextObject::Draw(IRenderer* pRenderer) const { if (nullptr == pRenderer || m_arTextCodes.empty()) return; - ((CGraphicUnit*)this)->Apply(pRenderer); + CGraphicUnit::Apply(pRenderer); + + if (nullptr != m_pFont) + m_pFont->Apply(pRenderer, m_pFontManager, m_dSize * 72. / 25.4); if (m_bFill && nullptr != m_pFillColor) { pRenderer->put_BrushType(c_BrushTypeSolid); - pRenderer->put_BrushColor1(m_pFillColor->ToInt(pPublicRes)); + pRenderer->put_BrushColor1(m_pFillColor->ToInt()); pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha()); } else @@ -136,8 +172,67 @@ void CTextObject::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const pRenderer->put_FontSize(m_dSize * 72. / 25.4); + unsigned int unGlyphsIndex; + for (const CTextCode* pTextCode : m_arTextCodes) - pTextCode->Draw(pRenderer); + pTextCode->Draw(pRenderer, unGlyphsIndex, m_arCGTransforms); } +TCGTransform TCGTransform::Read(CXmlReader& oLiteReader) +{ + TCGTransform oCGTransform; + + if (L"ofd:CGTransform" != oLiteReader.GetName() || oLiteReader.IsEmptyElement()) + return oCGTransform; + + if (0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) + { + std::wstring wsAttributeName; + + do + { + wsAttributeName = oLiteReader.GetName(); + + if (L"CodePosition" == wsAttributeName) + oCGTransform.m_unCodePosition = oLiteReader.GetUInteger(true); + else if (L"CodeCount" == wsAttributeName) + oCGTransform.m_unCodeCount = oLiteReader.GetUInteger(true); + else if (L"GlyphCount" == wsAttributeName) + oCGTransform.m_unGlyphCount = oLiteReader.GetUInteger(true); + } while (oLiteReader.MoveToNextAttribute()); + } + + oLiteReader.MoveToElement(); + + const int nDepth = oLiteReader.GetDepth(); + unsigned int unCount = 0; + + while (oLiteReader.ReadNextSiblingNode(nDepth) && unCount < oCGTransform.m_unGlyphCount) + { + if ("ofd:Glyphs" == oLiteReader.GetNameA()) + { + oCGTransform.m_arGlyphs.push_back(oLiteReader.GetUInteger()); + ++unCount; + } + } + + return oCGTransform; +} + +bool TCGTransform::Draw(IRenderer* pRenderer, unsigned int& unIndex, double dX, double dY) const +{ + if (m_unCodePosition != unIndex || 0 == m_unCodeCount || 0 == m_unGlyphCount) + return false; + + pRenderer->put_FontStringGID(1); + + for (unsigned int unGlyphCount = 0; unGlyphCount < m_unGlyphCount; ++unGlyphCount) + pRenderer->CommandDrawTextCHAR(m_arGlyphs[unGlyphCount], dX, dY, 0, 0); + + unIndex += m_unCodeCount; + + pRenderer->put_FontStringGID(0); + + return true; +} } diff --git a/OFDFile/src/Content/TextObject.h b/OFDFile/src/Content/TextObject.h index 9968d5f26d..72320c1a21 100644 --- a/OFDFile/src/Content/TextObject.h +++ b/OFDFile/src/Content/TextObject.h @@ -8,6 +8,19 @@ namespace OFD { +struct TCGTransform +{ + unsigned int m_unCodePosition; + unsigned int m_unCodeCount; + unsigned int m_unGlyphCount; + + std::vector m_arGlyphs; + + static TCGTransform Read(CXmlReader& oLiteReader); + + bool Draw(IRenderer* pRenderer, unsigned int& unIndex, double dX, double dY) const; +}; + class CTextCode { double m_dX; @@ -20,12 +33,11 @@ class CTextCode public: CTextCode(CXmlReader& oLiteReader); - void Draw(IRenderer* pRenderer) const; + void Draw(IRenderer* pRenderer, unsigned int& unIndex, const std::vector& arCGTransforms) const; }; class CTextObject : public IPageBlock, public CGraphicUnit { - unsigned int m_unFont; double m_dSize; bool m_bStroke; bool m_bFill; @@ -38,12 +50,17 @@ class CTextObject : public IPageBlock, public CGraphicUnit CColor* m_pFillColor; CColor* m_pStrokeColor; + const CFont* m_pFont; + std::vector m_arTextCodes; + std::vector m_arCGTransforms; + + NSFonts::IFontManager* m_pFontManager; public: - CTextObject(CXmlReader& oLiteReader); + CTextObject(CXmlReader& oLiteReader, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); ~CTextObject(); - void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const override; + void Draw(IRenderer* pRenderer) const override; }; } diff --git a/OFDFile/src/Document.cpp b/OFDFile/src/Document.cpp index eab69c229e..f338e90ace 100644 --- a/OFDFile/src/Document.cpp +++ b/OFDFile/src/Document.cpp @@ -1,78 +1,11 @@ #include "Document.h" +#include "Utils/Utils.h" + +#include "../../DesktopEditor/common/Path.h" + namespace OFD { -CCommonData::CCommonData() - : m_unMaxUnitID(0), m_pPublicRes(nullptr), m_pDocumentRes(nullptr) -{} - -CCommonData::~CCommonData() -{ - if (nullptr != m_pPublicRes) - delete m_pPublicRes; - - if (nullptr != m_pDocumentRes) - delete m_pDocumentRes; -} - -bool CCommonData::Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath) -{ - if (L"ofd:CommonData" != oLiteReader.GetName()) - return false; - - const int nDepth = oLiteReader.GetDepth(); - std::wstring wsNodeName; - - while (oLiteReader.ReadNextSiblingNode(nDepth)) - { - wsNodeName = oLiteReader.GetName(); - - if (L"ofd:PageArea" == wsNodeName) - m_oPageArea.Read(oLiteReader); - else if (L"ofd:PublicRes" == wsNodeName) - { - if (nullptr == m_pPublicRes) - m_pPublicRes = new CRes(); - - m_pPublicRes->Read(NSSystemPath::Combine(wsRootPath, oLiteReader.GetText2())); - } - else if (L"ofd:DocumentRes" == wsNodeName) - { - if(nullptr == m_pDocumentRes) - m_pDocumentRes = new CRes(); - - m_pDocumentRes->Read(NSSystemPath::Combine(wsRootPath, oLiteReader.GetText2())); - } - else if (L"ofd:MaxUnitID" == wsNodeName) - m_unMaxUnitID = oLiteReader.GetUInteger(); - // else if (L"ofd:TemplatePage" == wsNodeName) - // else if (L"ofd:DefaultCS" == wsNodeName) - } - - return true; -} - -void CCommonData::GetPageSize(double& dWidth, double& dHeight) const -{ - TBox oPhysicalBox{m_oPageArea.GetPhysicalBox()}; - - if (oPhysicalBox.Empty()) - return; - - dWidth = oPhysicalBox.m_dWidth; - dHeight = oPhysicalBox.m_dHeight; -} - -const CRes* CCommonData::GetPublicRes() const -{ - return m_pPublicRes; -} - -const CRes* CCommonData::GetDocumentRes() const -{ - return m_pDocumentRes; -} - CPermission::CPermission() : m_bEdit(true), m_bAnnot(true), m_bExport(true), m_bSignature(true), m_bWatermark(true), m_bPrintScreen(true) @@ -111,7 +44,7 @@ bool CDocument::Empty() const return m_mPages.empty(); } -bool CDocument::Read(const std::wstring& wsFilePath) +bool CDocument::Read(const std::wstring& wsFilePath, NSFonts::IFontManager* pFontManager) { if (wsFilePath.empty()) return false; @@ -128,7 +61,7 @@ bool CDocument::Read(const std::wstring& wsFilePath) wsNodeName = oLiteReader.GetName(); if (L"ofd:CommonData" == wsNodeName) - m_oCommonData.Read(oLiteReader, NSSystemPath::GetDirectoryName(wsFilePath)); + m_oCommonData.Read(oLiteReader, NSSystemPath::GetDirectoryName(wsFilePath), pFontManager); else if (L"ofd:Pages" == wsNodeName) { const int nPagesDepth = oLiteReader.GetDepth(); @@ -155,7 +88,7 @@ bool CDocument::Read(const std::wstring& wsFilePath) if (-1 == nID) nID = m_mPages.size() + 1; - CPage* pPage = CPage::Read(NSSystemPath::Combine(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc), m_oCommonData.GetDocumentRes()); + CPage* pPage = CPage::Read(CombinePaths(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc), m_oCommonData, pFontManager); if (nullptr != pPage) m_mPages.insert(std::make_pair(m_mPages.size(), pPage)); @@ -181,7 +114,7 @@ bool CDocument::DrawPage(IRenderer* pRenderer, int nPageIndex) const if (itFound == m_mPages.cend()) return false; - itFound->second->Draw(pRenderer, m_oCommonData.GetPublicRes()); + itFound->second->Draw(pRenderer); return true; } diff --git a/OFDFile/src/Document.h b/OFDFile/src/Document.h index e8e62a70a7..ce495e5766 100644 --- a/OFDFile/src/Document.h +++ b/OFDFile/src/Document.h @@ -2,32 +2,12 @@ #define DOCUMENT_H #include "Page.h" -#include "Res.h" - -#include "Types/PageArea.h" #include "../../DesktopEditor/graphics/IRenderer.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" namespace OFD { -class CCommonData -{ - unsigned int m_unMaxUnitID; - CPageArea m_oPageArea; - CRes* m_pPublicRes; - CRes* m_pDocumentRes; -public: - CCommonData(); - ~CCommonData(); - - bool Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath); - - void GetPageSize(double& dWidth, double &dHeight) const; - - const CRes* GetPublicRes() const; - const CRes* GetDocumentRes() const; -}; - class CPermission { bool m_bEdit; @@ -54,7 +34,7 @@ public: bool Empty() const; - bool Read(const std::wstring& wsFilePath); + bool Read(const std::wstring& wsFilePath, NSFonts::IFontManager* pFontManager); bool DrawPage(IRenderer* pRenderer, int nPageIndex) const; diff --git a/OFDFile/src/OFDFile_Private.cpp b/OFDFile/src/OFDFile_Private.cpp index 63c7048dfc..5271a9a4aa 100644 --- a/OFDFile/src/OFDFile_Private.cpp +++ b/OFDFile/src/OFDFile_Private.cpp @@ -62,7 +62,7 @@ bool COFDFile_Private::Read(IFolder* pFolder) if (nullptr == pFolder) return false; - if (!m_oBase.Read(pFolder)) + if (!m_oBase.Read(pFolder, m_pFontManager)) return false; return false; diff --git a/OFDFile/src/Page.cpp b/OFDFile/src/Page.cpp index 509de27174..2eb793141f 100644 --- a/OFDFile/src/Page.cpp +++ b/OFDFile/src/Page.cpp @@ -1,14 +1,22 @@ #include "Page.h" +#include "Utils/Utils.h" + #include "../../DesktopEditor/common/File.h" -#include "../../DesktopEditor/common/Path.h" namespace OFD { CPage::CPage() + : m_pTemplatePage(nullptr) {} -CPage* CPage::Read(const std::wstring& wsFilePath, const CRes* pDocumentRes) +CPage::~CPage() +{ + if (nullptr != m_pTemplatePage) + delete m_pTemplatePage; +} + +CPage* CPage::Read(const std::wstring& wsFilePath, const CCommonData& oCommonData, NSFonts::IFontManager* pFontManager) { if (wsFilePath.empty()) return nullptr; @@ -16,7 +24,7 @@ CPage* CPage::Read(const std::wstring& wsFilePath, const CRes* pDocumentRes) std::wstring wsNormalizedPath = wsFilePath; if (L"xml" != NSFile::GetFileExtention(wsNormalizedPath)) - wsNormalizedPath = NSSystemPath::Combine(wsNormalizedPath, L"Content.xml"); + wsNormalizedPath = CombinePaths(wsNormalizedPath, L"Content.xml"); CXmlReader oLiteReader; if (!oLiteReader.FromFile(wsNormalizedPath) || !oLiteReader.ReadNextNode() || L"ofd:Page" != oLiteReader.GetName()) @@ -32,22 +40,46 @@ CPage* CPage::Read(const std::wstring& wsFilePath, const CRes* pDocumentRes) wsNodeName = oLiteReader.GetName(); if (L"ofd:Content" == wsNodeName) - pPage->m_oContent.Read(oLiteReader, pDocumentRes); + pPage->m_oContent.Read(oLiteReader, oCommonData.GetDocumentRes(), oCommonData.GetPublicRes(), pFontManager); else if (L"ofd:Area" == wsNodeName) pPage->m_oArea.Read(oLiteReader); + else if (L"ofd:Template" == wsNodeName && 0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) + { + EZOrder eZorder; + unsigned int unTemplateID; + + std::string sAttributeName; + + do + { + sAttributeName = oLiteReader.GetNameA(); + + if ("ZOrder" == sAttributeName) + eZorder = GetZOrderFromString(oLiteReader.GetTextA()); + else if ("TemplateID" == sAttributeName) + unTemplateID = oLiteReader.GetUInteger(true); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); + + pPage->m_pTemplatePage = oCommonData.GetTemplatePage(unTemplateID, eZorder); + } } return pPage; } -void CPage::Draw(IRenderer* pRenderer, const CRes* pPublicRes) const +void CPage::Draw(IRenderer* pRenderer) const { if (nullptr == pRenderer) return; pRenderer->BeginCommand(c_nImageType); - m_oContent.Draw(pRenderer, pPublicRes); + if (nullptr != m_pTemplatePage && EZOrder::Background == m_pTemplatePage->GetZOrder()) + m_pTemplatePage->GetPage()->Draw(pRenderer); + + m_oContent.Draw(pRenderer); pRenderer->EndCommand(c_nImageType); } diff --git a/OFDFile/src/Page.h b/OFDFile/src/Page.h index 67196c5671..6c575b20b7 100644 --- a/OFDFile/src/Page.h +++ b/OFDFile/src/Page.h @@ -2,7 +2,8 @@ #define PAGE_H #include "Content/Content.h" -#include "Types/PageArea.h" +#include "Types/CommonData.h" +#include "Types/TemplatePage.h" namespace OFD { @@ -10,11 +11,14 @@ class CPage { CPageArea m_oArea; CContent m_oContent; + + const CTemplatePage* m_pTemplatePage; public: CPage(); + ~CPage(); - static CPage* Read(const std::wstring& wsFilePath, const CRes* pDocumentRes); - void Draw(IRenderer* pRenderer, const CRes* pPublicRes) const; + static CPage* Read(const std::wstring& wsFilePath, const CCommonData& oCommonData, NSFonts::IFontManager* pFontManager); + void Draw(IRenderer* pRenderer) const; void GetPageSize(double& dWidth, double& dHeight) const; }; diff --git a/OFDFile/src/Res.cpp b/OFDFile/src/Res.cpp index 52a3736555..d1d9f39008 100644 --- a/OFDFile/src/Res.cpp +++ b/OFDFile/src/Res.cpp @@ -1,5 +1,9 @@ #include "Res.h" +#include "Utils/Utils.h" + +#include "../../DesktopEditor/common/Directory.h" + namespace OFD { CRes::CRes() @@ -52,7 +56,7 @@ bool CRes::Read(const std::wstring& wsFilePath) if ("BaseLoc" == sNodeName) { - wsRootPath = NSSystemPath::Combine(NSDirectory::GetFolderPath(wsFilePath), oLiteReader.GetText()); + wsRootPath = CombinePaths(NSDirectory::GetFolderPath(wsFilePath), oLiteReader.GetText()); break; } } while (oLiteReader.MoveToNextAttribute()); @@ -60,48 +64,42 @@ bool CRes::Read(const std::wstring& wsFilePath) oLiteReader.MoveToElement(); - const int nDepth = oLiteReader.GetDepth(); std::string sNodeName; - #define PARSE_CONTINER(container_name, element_name, element_type, melements)\ - if (container_name == sNodeName) \ + #define PARSE_CONTAINER(container_name, element_name, element_type, melements, creator)\ + if (container_name == sNodeName)\ {\ - const int nDepth = oLiteReader.GetDepth();\ + const int nChildrenDepth = oLiteReader.GetDepth();\ element_type* pElement = nullptr;\ - while (oLiteReader.ReadNextSiblingNode(nDepth))\ + while (oLiteReader.ReadNextSiblingNode(nChildrenDepth))\ {\ if (element_name == oLiteReader.GetNameA())\ {\ - pElement = new element_type(oLiteReader);\ + pElement = creator;\ AddElementToMap(pElement, pElement->GetID(), melements);\ }\ }\ continue;\ } + #define PARSE_CONTAINER_WITHOUT_PATH(container_name, element_name, element_type, melements)\ + PARSE_CONTAINER(container_name, element_name, element_type, melements, new element_type(oLiteReader)) + + #define PARSE_CONTAINER_WITH_PATH(container_name, element_name, element_type, melements)\ + PARSE_CONTAINER(container_name, element_name, element_type, melements, new element_type(oLiteReader, wsRootPath)) + + const int nDepth = oLiteReader.GetDepth(); + while (oLiteReader.ReadNextSiblingNode(nDepth)) { sNodeName = oLiteReader.GetNameA(); - PARSE_CONTINER("ofd:ColorSpaces", "ofd:ColorSpace", CColorSpace, m_mColorSpaces) - PARSE_CONTINER("ofd:DrawParams", "ofd:DrawParam", CDrawParam, m_mDrawParams) - PARSE_CONTINER("ofd:Fonts", "ofd:Font", CFont, m_mFonts) - PARSE_CONTINER("ofd:CompositeGraphicUnits", "ofd:CCompositeGraphicUnit", CCompositeGraphicUnit, m_mCCompositeGraphicUnits) + PARSE_CONTAINER_WITHOUT_PATH("ofd:ColorSpaces", "ofd:ColorSpace", CColorSpace, m_mColorSpaces) + PARSE_CONTAINER_WITHOUT_PATH("ofd:DrawParams", "ofd:DrawParam", CDrawParam, m_mDrawParams) + PARSE_CONTAINER_WITHOUT_PATH("ofd:CompositeGraphicUnits", "ofd:CCompositeGraphicUnit", CCompositeGraphicUnit, m_mCCompositeGraphicUnits) - if ("ofd:MultiMedias" == sNodeName) - { - const int nDepth = oLiteReader.GetDepth(); - CMultiMedia* pElement = nullptr; - while (oLiteReader.ReadNextSiblingNode(nDepth)) - { - if ("ofd:MultiMedia" == oLiteReader.GetNameA()) - { - pElement = new CMultiMedia(oLiteReader, wsRootPath); - AddElementToMap(pElement, pElement->GetID(), m_mMultiMedias); - } - } - continue; - } + PARSE_CONTAINER_WITH_PATH("ofd:Fonts", "ofd:Font", CFont, m_mFonts) + PARSE_CONTAINER_WITH_PATH("ofd:MultiMedias", "ofd:MultiMedia", CMultiMedia, m_mMultiMedias) } return true; diff --git a/OFDFile/src/Res.h b/OFDFile/src/Res.h index 1278942088..0efcfc91b8 100644 --- a/OFDFile/src/Res.h +++ b/OFDFile/src/Res.h @@ -3,14 +3,14 @@ #include -#include "../../OfficeUtils/src/ZipFolder.h" - #include "Types/ColorSpace.h" #include "Types/DrawParam.h" #include "Types/Font.h" #include "Types/MultiMedia.h" #include "Types/CompositeGraphicUnit.h" +#include "../../DesktopEditor/graphics/pro/Fonts.h" + namespace OFD { class CRes diff --git a/OFDFile/src/Types/Color.cpp b/OFDFile/src/Types/Color.cpp index 15582d4028..564a6543e2 100644 --- a/OFDFile/src/Types/Color.cpp +++ b/OFDFile/src/Types/Color.cpp @@ -2,16 +2,11 @@ namespace OFD { -CColor::CColor(CXmlReader& oXmlReader) - : m_oValues{0, 0, 0}, m_nIndex(0), m_unColorSpace(0), m_chAlpha(255) -{ - Read(oXmlReader); -} - -bool CColor::Read(CXmlReader& oXmlReader) +CColor::CColor(CXmlReader& oXmlReader, const CRes* pPublicRes) + : m_oValues{0, 0, 0, 0}, m_nIndex(0), m_chAlpha(255), m_pColorSpace(nullptr) { if (0 == oXmlReader.GetAttributesCount() || !oXmlReader.MoveToFirstAttribute()) - return false; + return; std::string sAttributeName; @@ -20,18 +15,16 @@ bool CColor::Read(CXmlReader& oXmlReader) sAttributeName = oXmlReader.GetNameA(); if ("ColorSpace" == sAttributeName) - m_unColorSpace = oXmlReader.GetUInteger(true); + { + if (nullptr != pPublicRes) + m_pColorSpace = pPublicRes->GetColorSpace(oXmlReader.GetUInteger(true)); + } else if ("Value" == sAttributeName) { const std::vector arValues{oXmlReader.GetArrayDoubles(true)}; - if (4 > arValues.size()) - continue; - - m_oValues[0] = static_cast(arValues[0]); - m_oValues[1] = static_cast(arValues[1]); - m_oValues[2] = static_cast(arValues[2]); - m_oValues[3] = static_cast(arValues[3]); + for (unsigned int unIndex = 0; unIndex < (std::min)((unsigned int)arValues.size(), (unsigned int)4); ++unIndex) + m_oValues[unIndex] = static_cast(arValues[unIndex]); } else if ("Alpha" == sAttributeName) m_chAlpha = oXmlReader.GetUInteger(true); @@ -40,46 +33,39 @@ bool CColor::Read(CXmlReader& oXmlReader) } while (oXmlReader.MoveToNextAttribute()); oXmlReader.MoveToElement(); - - return true; } -int CColor::ToInt(const CRes* pPublicRes) const +int CColor::ToInt() const { - if (nullptr != pPublicRes) + if (nullptr != m_pColorSpace) { - const CColorSpace *pColorSpace = pPublicRes->GetColorSpace(m_unColorSpace); - - if (nullptr != pColorSpace) + switch(m_pColorSpace->GetType()) { - switch(pColorSpace->GetType()) + case CColorSpace::EType::GRAY: + return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[0] << 8) | (m_oValues[0] << 0); + case CColorSpace::EType::RGB: + return (255 << 24) | (m_oValues[2] << 16) | (m_oValues[1] << 8) | (m_oValues[0] << 0); + case CColorSpace::EType::CMYK: { - case CColorSpace::EType::GRAY: - return (255 << 24) | (128 << 16) | (128 << 8) | (128 << 0); - case CColorSpace::EType::RGB: - return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[1] << 8) | (m_oValues[2] << 0); - case CColorSpace::EType::CMYK: - { - const float cF = m_oValues[0] / 255.0f; - const float mF = m_oValues[1] / 255.0f; - const float yF = m_oValues[2] / 255.0f; - const float kF = m_oValues[3] / 255.0f; + const float cF = m_oValues[0] / 255.0f; + const float mF = m_oValues[1] / 255.0f; + const float yF = m_oValues[2] / 255.0f; + const float kF = m_oValues[3] / 255.0f; - const float r = (1.0f - cF) * (1.0f - kF); - const float g = (1.0f - mF) * (1.0f - kF); - const float b = (1.0f - yF) * (1.0f - kF); + const float r = (1.0f - cF) * (1.0f - kF); + const float g = (1.0f - mF) * (1.0f - kF); + const float b = (1.0f - yF) * (1.0f - kF); - const unsigned char rByte = static_cast(r * 255); - const unsigned char gByte = static_cast(g * 255); - const unsigned char bByte = static_cast(b * 255); + const unsigned char rByte = static_cast(r * 255); + const unsigned char gByte = static_cast(g * 255); + const unsigned char bByte = static_cast(b * 255); - return (rByte << 0) | (gByte << 8) | (bByte << 16); - } + return (rByte << 0) | (gByte << 8) | (bByte << 16); } } } - return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[1] << 8) | (m_oValues[2] << 0); + return 0; } BYTE CColor::GetAlpha() const diff --git a/OFDFile/src/Types/Color.h b/OFDFile/src/Types/Color.h index 42f5f8bd90..9ecccc4501 100644 --- a/OFDFile/src/Types/Color.h +++ b/OFDFile/src/Types/Color.h @@ -11,19 +11,18 @@ class CColor BYTE m_oValues[4]; int m_nIndex; - unsigned int m_unColorSpace; BYTE m_chAlpha; + + const CColorSpace* m_pColorSpace; // Pattern // AxialShd // RadialShd // GouraudShd // LaGouraudhd public: - CColor(CXmlReader& oXmlReader); + CColor(CXmlReader& oXmlReader, const CRes* pPublicRes); - bool Read(CXmlReader& oXmlReader); - - int ToInt(const CRes* pPublicRes) const; + int ToInt() const; BYTE GetAlpha() const; }; } diff --git a/OFDFile/src/Types/CommonData.cpp b/OFDFile/src/Types/CommonData.cpp new file mode 100644 index 0000000000..ebcd7efb9d --- /dev/null +++ b/OFDFile/src/Types/CommonData.cpp @@ -0,0 +1,90 @@ +#include "CommonData.h" +#include "../Utils/Utils.h" + +#include "../../../DesktopEditor/common/Path.h" + +namespace OFD +{ +CCommonData::CCommonData() + : m_unMaxUnitID(0), m_pPublicRes(nullptr), m_pDocumentRes(nullptr) +{} + +CCommonData::~CCommonData() +{ + if (nullptr != m_pPublicRes) + delete m_pPublicRes; + + if (nullptr != m_pDocumentRes) + delete m_pDocumentRes; +} + +bool CCommonData::Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath, NSFonts::IFontManager* pFontManager) +{ + if ("ofd:CommonData" != oLiteReader.GetNameA()) + return false; + + const int nDepth = oLiteReader.GetDepth(); + std::string sNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + sNodeName = oLiteReader.GetNameA(); + + if ("ofd:PageArea" == sNodeName) + m_oPageArea.Read(oLiteReader); + else if ("ofd:PublicRes" == sNodeName) + { + if (nullptr == m_pPublicRes) + m_pPublicRes = new CRes(); + + m_pPublicRes->Read(CombinePaths(wsRootPath, oLiteReader.GetText2())); + } + else if ("ofd:DocumentRes" == sNodeName) + { + if(nullptr == m_pDocumentRes) + m_pDocumentRes = new CRes(); + + m_pDocumentRes->Read(CombinePaths(wsRootPath, oLiteReader.GetText2())); + } + else if ("ofd:MaxUnitID" == sNodeName) + m_unMaxUnitID = oLiteReader.GetUInteger(); + else if ("ofd:TemplatePage" == sNodeName) + AddToContainer(new const CTemplatePage(oLiteReader, *this, pFontManager), m_arTemplatePages); + // else if (L"ofd:DefaultCS" == wsNodeName) + } + + return true; +} + +void CCommonData::GetPageSize(double& dWidth, double& dHeight) const +{ + TBox oPhysicalBox{m_oPageArea.GetPhysicalBox()}; + + if (oPhysicalBox.Empty()) + return; + + dWidth = oPhysicalBox.m_dWidth; + dHeight = oPhysicalBox.m_dHeight; +} + +const CRes* CCommonData::GetPublicRes() const +{ + return m_pPublicRes; +} + +const CRes* CCommonData::GetDocumentRes() const +{ + return m_pDocumentRes; +} + +const CTemplatePage* CCommonData::GetTemplatePage(unsigned int unTemplateID, EZOrder eZOrder) const +{ + for (const CTemplatePage* pTemplatePage : m_arTemplatePages) + { + if (unTemplateID == pTemplatePage->GetID() && eZOrder == pTemplatePage->GetZOrder()) + return pTemplatePage; + } + + return nullptr; +} +} diff --git a/OFDFile/src/Types/CommonData.h b/OFDFile/src/Types/CommonData.h new file mode 100644 index 0000000000..74d48eae86 --- /dev/null +++ b/OFDFile/src/Types/CommonData.h @@ -0,0 +1,35 @@ +#ifndef COMMONDATA_H +#define COMMONDATA_H + +#include "../Res.h" +#include "PageArea.h" +#include "TemplatePage.h" + +#include "../../../DesktopEditor/graphics/pro/Fonts.h" + +namespace OFD +{ +class CCommonData +{ + unsigned int m_unMaxUnitID; + CPageArea m_oPageArea; + CRes* m_pPublicRes; + CRes* m_pDocumentRes; + + std::vector m_arTemplatePages; +public: + CCommonData(); + ~CCommonData(); + + bool Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath, NSFonts::IFontManager* pFontManager); + + void GetPageSize(double& dWidth, double &dHeight) const; + + const CRes* GetPublicRes() const; + const CRes* GetDocumentRes() const; + + const CTemplatePage* GetTemplatePage(unsigned int unTemplateID, EZOrder eZOrder) const; +}; +} + +#endif // COMMONDATA_H diff --git a/OFDFile/src/Types/Font.cpp b/OFDFile/src/Types/Font.cpp index 7c49621e5a..ce7b865804 100644 --- a/OFDFile/src/Types/Font.cpp +++ b/OFDFile/src/Types/Font.cpp @@ -1,8 +1,10 @@ #include "Font.h" +#include "../Utils/Utils.h" + namespace OFD { -CFont::CFont(CXmlReader& oXmlReader) +CFont::CFont(CXmlReader& oXmlReader, const std::wstring& wsRootPath) : IOFDElement(oXmlReader), m_wsCharset(L"unicode"), m_bItalic(false), m_bBold(false), m_bSerif(false), m_bFixedWidth(false) @@ -33,5 +35,45 @@ CFont::CFont(CXmlReader& oXmlReader) } oXmlReader.MoveToElement(); + + if (oXmlReader.IsEmptyNode()) + return; + + const int nDepth = oXmlReader.GetDepth(); + + while (oXmlReader.ReadNextSiblingNode(nDepth)) + { + if ("ofd:FontFile" == oXmlReader.GetNameA()) + { + m_wsFilePath = CombinePaths(wsRootPath, oXmlReader.GetText2()); + break; + } + } +} + +void CFont::Apply(IRenderer* pRenderer, NSFonts::IFontManager* pFontManager, const double& dFontSize) const +{ + if (nullptr == pRenderer) + return; + + int nFontStyle = 0; + + if (m_bBold) + nFontStyle |= 0x01; + if (m_bItalic) + nFontStyle |= 0x02; + + pRenderer->put_FontStyle(nFontStyle); + pRenderer->put_FontName(m_wsFontName); + + if (!m_wsFilePath.empty() && nullptr != pFontManager) + { + double dDpiX = 96, dDpiY = 96; + + pRenderer->get_DpiX(&dDpiX); + pRenderer->get_DpiY(&dDpiY); + + pFontManager->LoadFontFromFile(m_wsFilePath, 0, dFontSize, dDpiX, dDpiY); + } } } diff --git a/OFDFile/src/Types/Font.h b/OFDFile/src/Types/Font.h index 9f58e34d84..268336231e 100644 --- a/OFDFile/src/Types/Font.h +++ b/OFDFile/src/Types/Font.h @@ -3,12 +3,17 @@ #include "../IOFDElement.h" +#include "../../../DesktopEditor/graphics/IRenderer.h" +#include "../../../DesktopEditor/graphics/pro/Fonts.h" + namespace OFD { class CFont : public IOFDElement { public: - CFont(CXmlReader& oXmlReader); + CFont(CXmlReader& oXmlReader, const std::wstring& wsRootPath); + + void Apply(IRenderer* pRenderer, NSFonts::IFontManager* pFontManager, const double& dFontSize) const; private: std::wstring m_wsFontName; std::wstring m_wsFamilyName; @@ -18,7 +23,7 @@ private: bool m_bSerif; bool m_bFixedWidth; - std::wstring m_wsFileName; + std::wstring m_wsFilePath; }; } diff --git a/OFDFile/src/Types/MultiMedia.cpp b/OFDFile/src/Types/MultiMedia.cpp index b759879c81..ee48fcfd6b 100644 --- a/OFDFile/src/Types/MultiMedia.cpp +++ b/OFDFile/src/Types/MultiMedia.cpp @@ -1,6 +1,6 @@ #include "MultiMedia.h" -#include "../../../DesktopEditor/common/Path.h" +#include "../Utils/Utils.h" namespace OFD { @@ -30,13 +30,16 @@ CMultiMedia::CMultiMedia(CXmlReader& oXmlReader, const std::wstring& wsRootPath) oXmlReader.MoveToElement(); + if (oXmlReader.IsEmptyNode()) + return; + const int nDepth = oXmlReader.GetDepth(); while (oXmlReader.ReadNextSiblingNode(nDepth)) { if ("ofd:MediaFile" == oXmlReader.GetNameA()) { - m_wsFilePath = NSSystemPath::Combine(wsRootPath, oXmlReader.GetText2()); + m_wsFilePath = CombinePaths(wsRootPath, oXmlReader.GetText2()); break; } } diff --git a/OFDFile/src/Types/PageArea.cpp b/OFDFile/src/Types/PageArea.cpp index 2001ef6898..77130b614b 100644 --- a/OFDFile/src/Types/PageArea.cpp +++ b/OFDFile/src/Types/PageArea.cpp @@ -7,7 +7,8 @@ CPageArea::CPageArea() bool CPageArea::Read(CXmlReader& oLiteReader) { - if (L"ofd:PageArea" != oLiteReader.GetName() && + if (!oLiteReader.IsEmptyNode() && + L"ofd:PageArea" != oLiteReader.GetName() && L"ofd:Area" != oLiteReader.GetName()) return false; diff --git a/OFDFile/src/Types/TemplatePage.cpp b/OFDFile/src/Types/TemplatePage.cpp new file mode 100644 index 0000000000..b20a859669 --- /dev/null +++ b/OFDFile/src/Types/TemplatePage.cpp @@ -0,0 +1,53 @@ +#include "TemplatePage.h" +#include "CommonData.h" +#include "../Page.h" + +namespace OFD +{ +CTemplatePage::CTemplatePage(CXmlReader& oXmlReader, const CCommonData& oCommonData, NSFonts::IFontManager* pFontManager) + : IOFDElement(oXmlReader), m_eZOrder(EZOrder::Background), m_pPage(nullptr) +{ + if ("ofd:TemplatePage" != oXmlReader.GetNameA() || 0 == oXmlReader.GetAttributesCount() || !oXmlReader.MoveToFirstAttribute()) + return; + + std::string sAttributeName; + do + { + sAttributeName = oXmlReader.GetNameA(); + + if ("BaseLoc" == sAttributeName) + m_pPage = CPage::Read(oXmlReader.GetText2(), oCommonData, pFontManager); + else if ("ZOrder" == sAttributeName) + m_eZOrder = GetZOrderFromString(oXmlReader.GetTextA()); + } while (oXmlReader.MoveToNextAttribute()); + + oXmlReader.MoveToElement(); +} + +CTemplatePage::~CTemplatePage() +{ + if (nullptr != m_pPage) + delete m_pPage; +} + +EZOrder CTemplatePage::GetZOrder() const +{ + return m_eZOrder; +} + +const CPage* CTemplatePage::GetPage() const +{ + return m_pPage; +} + +EZOrder GetZOrderFromString(const std::string& sValue) +{ + if ("Body" == sValue) + return EZOrder::Body; + if ("Background" == sValue) + return EZOrder::Background; + + return EZOrder::Body; +} + +} diff --git a/OFDFile/src/Types/TemplatePage.h b/OFDFile/src/Types/TemplatePage.h new file mode 100644 index 0000000000..7c88be96d6 --- /dev/null +++ b/OFDFile/src/Types/TemplatePage.h @@ -0,0 +1,33 @@ +#ifndef TEMPLATEPAGE_H +#define TEMPLATEPAGE_H + +#include "../IOFDElement.h" +#include "../../../DesktopEditor/graphics/pro/Fonts.h" + +namespace OFD +{ +enum class EZOrder +{ + Body, + Background +} ; + +EZOrder GetZOrderFromString(const std::string& sValue); + +class CPage; +class CCommonData; +class CTemplatePage : public IOFDElement +{ + EZOrder m_eZOrder; + + const CPage* m_pPage; +public: + CTemplatePage(CXmlReader& oXmlReader, const CCommonData& oCommonData, NSFonts::IFontManager* pFontManager); + ~CTemplatePage(); + + EZOrder GetZOrder() const; + const CPage* GetPage() const; +}; +} + +#endif // TEMPLATEPAGE_H diff --git a/OFDFile/src/Utils/Utils.h b/OFDFile/src/Utils/Utils.h index 25b457e628..c210d01992 100644 --- a/OFDFile/src/Utils/Utils.h +++ b/OFDFile/src/Utils/Utils.h @@ -7,6 +7,8 @@ #include #include +#include "../../../DesktopEditor/common/Path.h" + namespace OFD { inline std::vector Split(const std::string& sValue, char chDelim) @@ -93,5 +95,38 @@ inline bool StringToDouble(const std::string& sValue, double& dValue) return true; } + +template +inline void AddToContainer(T* pValue, std::vector& arValues) +{ + if (nullptr != pValue) + arValues.push_back(pValue); +} + +inline std::wstring CombinePaths(const std::wstring& wsFirstPath, const std::wstring& wsSecondPath) +{ + if (wsFirstPath.empty()) + return wsSecondPath; + + if (wsSecondPath.empty()) + return wsFirstPath; + + std::wstring::const_reverse_iterator itFound = std::find_if(wsFirstPath.crbegin(), wsFirstPath.crend(), [](wchar_t wChar){ return L'/' == wChar || L'\\' == wChar; }); + + if (wsFirstPath.crend() == itFound) + return NSSystemPath::Combine(wsFirstPath, wsSecondPath); + + std::wstring wsNewSecondPath{wsSecondPath}; + + if (L'/' == wsNewSecondPath[0] || L'\\' == wsNewSecondPath[0]) + wsNewSecondPath.erase(0, 1); + + const std::wstring& wsFirstDirName = wsFirstPath.substr(itFound.base() - wsFirstPath.cbegin(), wsFirstPath.cend() - itFound.base()); + + if (wsFirstDirName == wsNewSecondPath.substr(0, wsFirstDirName.length())) + wsNewSecondPath.erase(0, wsFirstDirName.length()); + + return NSSystemPath::Combine(wsFirstPath, wsNewSecondPath); +} } #endif // UTILS_H From 87a9b92feaeac9b31fdda8e89af63acce5b384d1 Mon Sep 17 00:00:00 2001 From: Green Date: Thu, 10 Apr 2025 18:05:38 +0300 Subject: [PATCH 07/15] Improved rendering of text in OFD format and refactoring --- OFDFile/OFDFile.cpp | 2 +- OFDFile/src/Base.cpp | 8 +-- OFDFile/src/Base.h | 4 +- OFDFile/src/Content/Content.cpp | 8 +-- OFDFile/src/Content/Content.h | 5 +- OFDFile/src/Content/IPageBlock.h | 4 +- OFDFile/src/Content/ImageObject.cpp | 19 ++++--- OFDFile/src/Content/ImageObject.h | 9 ++-- OFDFile/src/Content/Layer.cpp | 8 +-- OFDFile/src/Content/Layer.h | 5 +- OFDFile/src/Content/PageBlock.cpp | 18 +++---- OFDFile/src/Content/PageBlock.h | 6 +-- OFDFile/src/Content/PathObject.cpp | 41 ++++++++++---- OFDFile/src/Content/PathObject.h | 4 +- OFDFile/src/Content/TextObject.cpp | 83 +++++++++++++++++++++-------- OFDFile/src/Content/TextObject.h | 8 ++- OFDFile/src/Document.cpp | 8 +-- OFDFile/src/Document.h | 2 +- OFDFile/src/OFDFile_Private.cpp | 2 +- OFDFile/src/Page.cpp | 33 ++++++------ OFDFile/src/Page.h | 6 +-- OFDFile/src/Types/Color.cpp | 56 +++++++++---------- OFDFile/src/Types/Color.h | 6 +-- OFDFile/src/Types/CommonData.cpp | 4 +- OFDFile/src/Types/CommonData.h | 2 +- OFDFile/src/Types/Font.cpp | 13 ++--- OFDFile/src/Types/Font.h | 3 +- OFDFile/src/Types/TemplatePage.cpp | 7 +-- OFDFile/src/Types/TemplatePage.h | 3 +- OFDFile/src/Utils/XmlReader.cpp | 5 ++ OFDFile/src/Utils/XmlReader.h | 1 + 31 files changed, 218 insertions(+), 165 deletions(-) diff --git a/OFDFile/OFDFile.cpp b/OFDFile/OFDFile.cpp index 4a6ce144d9..be4ee8ca9b 100644 --- a/OFDFile/OFDFile.cpp +++ b/OFDFile/OFDFile.cpp @@ -11,7 +11,7 @@ COFDFile::COFDFile(NSFonts::IApplicationFonts* pFonts) COFDFile::~COFDFile() { - Close(); + COFDFile::Close(); if (nullptr != m_pInternal) delete m_pInternal; diff --git a/OFDFile/src/Base.cpp b/OFDFile/src/Base.cpp index 1439579b63..1c8c4aeb43 100644 --- a/OFDFile/src/Base.cpp +++ b/OFDFile/src/Base.cpp @@ -61,7 +61,7 @@ CDocBody::CDocBody() } -CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder, NSFonts::IFontManager* pFontManager) +CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) { if (L"ofd:DocBody" != oLiteReader.GetName()) return nullptr; @@ -91,7 +91,7 @@ CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder, NSFonts::IFo const std::wstring wsPath = NSSystemPath::ShortenPath(oLiteReader.GetText2()); if (!wsPath.empty() && L'.' != wsPath.front()) - pDocBody->m_oDocument.Read(pFolder->getFullFilePath(wsPath), pFontManager); + pDocBody->m_oDocument.Read(pFolder->getFullFilePath(wsPath)); } ELSE_IF_CHECK_NODE(L"ofd:Signatures", pDocBody->m_wsSignature); } @@ -123,7 +123,7 @@ CBase::~CBase() RELEASEOBJECT(pDocBody); } -bool CBase::Read(IFolder* pFolder, NSFonts::IFontManager* pFontManager) +bool CBase::Read(IFolder* pFolder) { if (nullptr == pFolder || !pFolder->existsXml(L"OFD.xml")) return false; @@ -138,7 +138,7 @@ bool CBase::Read(IFolder* pFolder, NSFonts::IFontManager* pFontManager) while (oLiteReader.ReadNextSiblingNode(nDepth)) { - pDocBody = CDocBody::Read(oLiteReader, pFolder, pFontManager); + pDocBody = CDocBody::Read(oLiteReader, pFolder); if (nullptr != pDocBody) m_arDocBodies.push_back(pDocBody); } diff --git a/OFDFile/src/Base.h b/OFDFile/src/Base.h index 0c724cc753..2a58e03321 100644 --- a/OFDFile/src/Base.h +++ b/OFDFile/src/Base.h @@ -50,7 +50,7 @@ class CDocBody std::wstring m_wsSignature; public: CDocBody(); - static CDocBody* Read(CXmlReader& oLiteReader, IFolder* pFolder, NSFonts::IFontManager* pFontManager); + static CDocBody* Read(CXmlReader& oLiteReader, IFolder* pFolder); bool DrawPage(IRenderer* pRenderer, int nPageIndex) const; @@ -65,7 +65,7 @@ public: CBase(); ~CBase(); - bool Read(IFolder* pFolder, NSFonts::IFontManager* pFontManager); + bool Read(IFolder* pFolder); void DrawPage(IRenderer* pRenderer, int nPageIndex) const; unsigned int GetPageCount() const; diff --git a/OFDFile/src/Content/Content.cpp b/OFDFile/src/Content/Content.cpp index dfdafda4a2..6bfb81a733 100644 --- a/OFDFile/src/Content/Content.cpp +++ b/OFDFile/src/Content/Content.cpp @@ -11,7 +11,7 @@ CContent::~CContent() delete pLayer; } -bool CContent::Read(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) +bool CContent::Read(CXmlReader& oLiteReader) { if (L"ofd:Content" != oLiteReader.GetName()) return false; @@ -24,18 +24,18 @@ bool CContent::Read(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRe wsNodeName = oLiteReader.GetName(); if (L"ofd:Layer" == wsNodeName) - m_arLayers.push_back(new CLayer(oLiteReader, pDocumentRes, pPublicRes, pFontManager)); + m_arLayers.push_back(new CLayer(oLiteReader)); } return false; } -void CContent::Draw(IRenderer* pRenderer) const +void CContent::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const { if (nullptr == pRenderer) return; for (const CLayer* pLayer : m_arLayers) - pLayer->Draw(pRenderer); + pLayer->Draw(pRenderer, oCommonData); } } diff --git a/OFDFile/src/Content/Content.h b/OFDFile/src/Content/Content.h index c28897a1af..2e90d8b175 100644 --- a/OFDFile/src/Content/Content.h +++ b/OFDFile/src/Content/Content.h @@ -2,6 +2,7 @@ #define CONTENT_H #include "Layer.h" +#include "../Types/CommonData.h" namespace OFD { @@ -12,8 +13,8 @@ public: CContent(); ~CContent(); - bool Read(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); - void Draw(IRenderer* pRenderer) const; + bool Read(CXmlReader& oLiteReader); + void Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const; }; } diff --git a/OFDFile/src/Content/IPageBlock.h b/OFDFile/src/Content/IPageBlock.h index ba92d558bd..b89e62d139 100644 --- a/OFDFile/src/Content/IPageBlock.h +++ b/OFDFile/src/Content/IPageBlock.h @@ -4,7 +4,7 @@ #include "../IOFDElement.h" #include "../../../DesktopEditor/graphics/IRenderer.h" -#include "../Res.h" +#include "../Types/CommonData.h" namespace OFD { @@ -14,7 +14,7 @@ public: IPageBlock(CXmlReader& oLiteReader) : IOFDElement(oLiteReader){}; virtual ~IPageBlock(){}; - virtual void Draw(IRenderer* pRenderer) const = 0; + virtual void Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const = 0; }; } diff --git a/OFDFile/src/Content/ImageObject.cpp b/OFDFile/src/Content/ImageObject.cpp index b49e8ec34d..b9831eeabe 100644 --- a/OFDFile/src/Content/ImageObject.cpp +++ b/OFDFile/src/Content/ImageObject.cpp @@ -4,10 +4,10 @@ namespace OFD { -CImageObject::CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes) - : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), m_pMultiMedia(nullptr) +CImageObject::CImageObject(CXmlReader& oLiteReader) + : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), m_unMultiMediaID(0) { - if (nullptr == pDocumentRes || "ofd:ImageObject" != oLiteReader.GetNameA() || 0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) + if ("ofd:ImageObject" != oLiteReader.GetNameA() || 0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) return; std::string sAttributeName; @@ -18,7 +18,7 @@ CImageObject::CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes) if ("ResourceID" == sAttributeName) { - m_pMultiMedia = pDocumentRes->GetMultiMedia(oLiteReader.GetUInteger(true)); + m_unMultiMediaID = oLiteReader.GetUInteger(true); break; } } while(oLiteReader.MoveToNextAttribute()); @@ -26,14 +26,19 @@ CImageObject::CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes) oLiteReader.MoveToElement(); } -void CImageObject::Draw(IRenderer* pRenderer) const +void CImageObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const { - if (nullptr == pRenderer || nullptr == m_pMultiMedia) + if (nullptr == pRenderer || nullptr == oCommonData.GetDocumentRes()) + return; + + const CMultiMedia* pMultiMedia = oCommonData.GetDocumentRes()->GetMultiMedia(m_unMultiMediaID); + + if (nullptr == pMultiMedia) return; CGraphicUnit::Apply(pRenderer); - const std::wstring wsFilePath = m_pMultiMedia->GetFilePath(); + const std::wstring wsFilePath = pMultiMedia->GetFilePath(); if (wsFilePath.empty()) return; diff --git a/OFDFile/src/Content/ImageObject.h b/OFDFile/src/Content/ImageObject.h index 06d2fd21d5..5ea978e188 100644 --- a/OFDFile/src/Content/ImageObject.h +++ b/OFDFile/src/Content/ImageObject.h @@ -4,18 +4,15 @@ #include "IPageBlock.h" #include "GraphicUnit.h" -#include "../Types/MultiMedia.h" -#include "../Res.h" - namespace OFD { class CImageObject : public IPageBlock, public CGraphicUnit { - const CMultiMedia* m_pMultiMedia; + unsigned int m_unMultiMediaID; public: - CImageObject(CXmlReader& oLiteReader, const CRes* pDocumentRes); + CImageObject(CXmlReader& oLiteReader); - void Draw(IRenderer* pRenderer) const override; + void Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const override; }; } diff --git a/OFDFile/src/Content/Layer.cpp b/OFDFile/src/Content/Layer.cpp index 027400e956..754ca81853 100644 --- a/OFDFile/src/Content/Layer.cpp +++ b/OFDFile/src/Content/Layer.cpp @@ -6,13 +6,13 @@ namespace OFD { -CLayer::CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) +CLayer::CLayer(CXmlReader& oLiteReader) : IPageBlock(oLiteReader), m_eType(EType::Body) { if (L"ofd:Layer" != oLiteReader.GetName()) return; - CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes, pPublicRes, pFontManager); + CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks); } CLayer::~CLayer() @@ -21,12 +21,12 @@ CLayer::~CLayer() delete pPageBlock; } -void CLayer::Draw(IRenderer* pRenderer) const +void CLayer::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const { if (nullptr == pRenderer) return; for (const IPageBlock* pPageBlock : m_arPageBlocks) - pPageBlock->Draw(pRenderer); + pPageBlock->Draw(pRenderer, oCommonData); } } diff --git a/OFDFile/src/Content/Layer.h b/OFDFile/src/Content/Layer.h index 283086df0f..4b913d2d61 100644 --- a/OFDFile/src/Content/Layer.h +++ b/OFDFile/src/Content/Layer.h @@ -2,7 +2,6 @@ #define LAYER_H #include "IPageBlock.h" -#include "../Res.h" namespace OFD { @@ -18,10 +17,10 @@ class CLayer : public IPageBlock unsigned int m_unID; std::vector m_arPageBlocks; public: - CLayer(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); + CLayer(CXmlReader& oLiteReader); ~CLayer(); - void Draw(IRenderer* pRenderer) const override; + void Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const override; }; } diff --git a/OFDFile/src/Content/PageBlock.cpp b/OFDFile/src/Content/PageBlock.cpp index ae99a28474..c9daadd00f 100644 --- a/OFDFile/src/Content/PageBlock.cpp +++ b/OFDFile/src/Content/PageBlock.cpp @@ -6,16 +6,16 @@ namespace OFD { -CPageBlock::CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) +CPageBlock::CPageBlock(CXmlReader& oLiteReader) : IPageBlock(oLiteReader) { if ("ofd:PageBlock" != oLiteReader.GetNameA() || oLiteReader.IsEmptyNode()) return; - CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks, pDocumentRes, pPublicRes, pFontManager); + CPageBlock::ReadIntoContainer(oLiteReader, m_arPageBlocks); } -void CPageBlock::ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) +void CPageBlock::ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks) { const int nDepth = oLiteReader.GetDepth(); std::wstring wsNodeName; @@ -28,25 +28,25 @@ void CPageBlock::ReadIntoContainer(CXmlReader& oLiteReader, std::vectorDraw(pRenderer); + pPageBlock->Draw(pRenderer, oCommonData); } } diff --git a/OFDFile/src/Content/PageBlock.h b/OFDFile/src/Content/PageBlock.h index 8619addaf2..3a971b1e0a 100644 --- a/OFDFile/src/Content/PageBlock.h +++ b/OFDFile/src/Content/PageBlock.h @@ -10,11 +10,11 @@ class CPageBlock : public IPageBlock { std::vector m_arPageBlocks; public: - CPageBlock(CXmlReader& oLiteReader, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); + CPageBlock(CXmlReader& oLiteReader); - static void ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks, const CRes* pDocumentRes, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); + static void ReadIntoContainer(CXmlReader& oLiteReader, std::vector& arPageBlocks); - void Draw(IRenderer* pRenderer) const override; + void Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const override; }; } diff --git a/OFDFile/src/Content/PathObject.cpp b/OFDFile/src/Content/PathObject.cpp index c43ea03466..dfd96e12a2 100644 --- a/OFDFile/src/Content/PathObject.cpp +++ b/OFDFile/src/Content/PathObject.cpp @@ -3,9 +3,9 @@ namespace OFD { -CPathObject::CPathObject(CXmlReader& oLiteReader, const CRes* pPublicRes) +CPathObject::CPathObject(CXmlReader& oLiteReader) : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), - m_bStroke(true), m_bFill(true), m_eRule(ERule::NonZero), + m_bStroke(true), m_bFill(false), m_eRule(ERule::NonZero), m_pFillColor(nullptr), m_pStrokeColor(nullptr) { if (L"ofd:PathObject" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid()) @@ -47,14 +47,14 @@ CPathObject::CPathObject(CXmlReader& oLiteReader, const CRes* pPublicRes) if (nullptr != m_pFillColor) delete m_pFillColor; - m_pFillColor = new CColor(oLiteReader, pPublicRes); + m_pFillColor = new CColor(oLiteReader); } else if (L"ofd:StrokeColor" == wsNodeName) { if (nullptr != m_pStrokeColor) delete m_pStrokeColor; - m_pStrokeColor = new CColor(oLiteReader, pPublicRes); + m_pStrokeColor = new CColor(oLiteReader); } else if (L"ofd:AbbreviatedData" == wsNodeName) { @@ -130,7 +130,7 @@ void CPathObject::AddElement(const IPathElement* pElement) m_arElements.push_back(pElement); } -void CPathObject::Draw(IRenderer* pRenderer) const +void CPathObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const { if (nullptr == pRenderer || m_arElements.empty()) return; @@ -165,20 +165,39 @@ void CPathObject::Draw(IRenderer* pRenderer) const } } - if (m_bFill && nullptr != m_pFillColor) + if (m_bFill) { pRenderer->put_BrushType(c_BrushTypeSolid); - pRenderer->put_BrushColor1(m_pFillColor->ToInt()); - pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha()); + + if (nullptr != m_pFillColor) + { + pRenderer->put_BrushColor1(m_pFillColor->ToInt(oCommonData.GetPublicRes())); + pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha()); + } + else + { + pRenderer->put_BrushColor1(0); + pRenderer->put_BrushAlpha1(0xff); + } } else pRenderer->put_BrushType(c_BrushTypeNotSet); - if (m_bStroke && nullptr != m_pStrokeColor) + + if(m_bStroke) { pRenderer->put_PenSize(m_dLineWidth); - pRenderer->put_PenColor(m_pStrokeColor->ToInt()); - pRenderer->put_PenAlpha(m_pStrokeColor->GetAlpha()); + + if (nullptr != m_pStrokeColor) + { + pRenderer->put_PenColor(m_pStrokeColor->ToInt(oCommonData.GetPublicRes())); + pRenderer->put_PenAlpha(m_pStrokeColor->GetAlpha()); + } + else + { + pRenderer->put_PenColor(0); + pRenderer->put_PenAlpha(0xff); + } } else pRenderer->put_PenSize(0.); diff --git a/OFDFile/src/Content/PathObject.h b/OFDFile/src/Content/PathObject.h index 156a20606a..a4db6ff409 100644 --- a/OFDFile/src/Content/PathObject.h +++ b/OFDFile/src/Content/PathObject.h @@ -115,10 +115,10 @@ class CPathObject : public IPageBlock, public CGraphicUnit void AddElement(const IPathElement* pElement); public: - CPathObject(CXmlReader& oLiteReader, const CRes* pPublicRes); + CPathObject(CXmlReader& oLiteReader); ~CPathObject(); - void Draw(IRenderer* pRenderer) const override; + void Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const override; }; } diff --git a/OFDFile/src/Content/TextObject.cpp b/OFDFile/src/Content/TextObject.cpp index 9f20833b05..e98434ddd6 100644 --- a/OFDFile/src/Content/TextObject.cpp +++ b/OFDFile/src/Content/TextObject.cpp @@ -1,5 +1,7 @@ #include "TextObject.h" +#include "../Utils/Utils.h" + namespace OFD { CTextCode::CTextCode(CXmlReader& oLiteReader) @@ -19,10 +21,35 @@ CTextCode::CTextCode(CXmlReader& oLiteReader) m_dX = oLiteReader.GetDouble(true); else if (L"Y" == wsAttributeName) m_dY = oLiteReader.GetDouble(true); - else if (L"DeltaX" == wsAttributeName) - m_arDeltaX = oLiteReader.GetArrayDoubles(true); - else if (L"DeltaY" == wsAttributeName) - m_arDeltaY = oLiteReader.GetArrayDoubles(true); + else if (L"DeltaX" == wsAttributeName || + L"DeltaY" == wsAttributeName) + { + const std::vector arValues{oLiteReader.GetArrayStrings(true)}; + + std::vector& arDelta{L"DeltaX" == wsAttributeName ? m_arDeltaX : m_arDeltaY}; + + arDelta.reserve(arValues.size()); + double dValue = 0.; + + for (unsigned int unIndex = 0; unIndex < arValues.size(); ++unIndex) + { + if ("g" == arValues[unIndex] && unIndex + 2 < arValues.size()) + { + unsigned int unCount = 0; + + if (!StringToUInteger(arValues[unIndex + 1], unCount) || !StringToDouble(arValues[unIndex + 2], dValue)) + continue; + + unIndex += 2; + + arDelta.insert(arDelta.end(), unCount, dValue); + } + else if (StringToDouble(arValues[unIndex], dValue)) + arDelta.push_back(dValue); + else + arDelta.push_back(0.); + } + } } while (oLiteReader.MoveToNextAttribute()); } @@ -41,7 +68,7 @@ void CTextCode::Draw(IRenderer* pRenderer, unsigned int& unIndex, const std::vec for (unsigned int unGlyphIndex = 0; unGlyphIndex < m_wsText.length(); ++unGlyphIndex) { - if (!arCGTransforms.empty() && false) + if (!arCGTransforms.empty()) { for (const TCGTransform& oCGTransform : arCGTransforms) { @@ -66,13 +93,12 @@ void CTextCode::Draw(IRenderer* pRenderer, unsigned int& unIndex, const std::vec } } -CTextObject::CTextObject(CXmlReader& oLiteReader, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager) +CTextObject::CTextObject(CXmlReader& oLiteReader) : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), m_bStroke(false), m_bFill(false), m_dHScale(1.), m_unReadDirection(0), m_unCharDirection(0), m_unWeight(400), m_bItalic(false), - m_pFillColor(nullptr), m_pStrokeColor(nullptr), m_pFont(nullptr), - m_pFontManager(pFontManager) + m_pFillColor(nullptr), m_pStrokeColor(nullptr), m_unFontID(0) { if (L"ofd:TextObject" != oLiteReader.GetName() || oLiteReader.IsEmptyElement() || !oLiteReader.IsValid()) return; @@ -86,10 +112,7 @@ CTextObject::CTextObject(CXmlReader& oLiteReader, const CRes* pPublicRes, NSFont wsAttributeName = oLiteReader.GetName(); if (L"Font" == wsAttributeName) - { - if (nullptr != pPublicRes) - m_pFont = pPublicRes->GetFont(oLiteReader.GetUInteger(true)); - } + m_unFontID = oLiteReader.GetUInteger(true); else if (L"Size" == wsAttributeName) m_dSize = oLiteReader.GetDouble(true); else if (L"Stroke" == wsAttributeName) @@ -123,14 +146,14 @@ CTextObject::CTextObject(CXmlReader& oLiteReader, const CRes* pPublicRes, NSFont if (nullptr != m_pFillColor) delete m_pFillColor; - m_pFillColor = new CColor(oLiteReader, pPublicRes); + m_pFillColor = new CColor(oLiteReader); } else if (L"ofd:StrokeColor" == wsNodeName) { if (nullptr != m_pStrokeColor) delete m_pStrokeColor; - m_pStrokeColor = new CColor(oLiteReader, pPublicRes); + m_pStrokeColor = new CColor(oLiteReader); } else if (L"ofd:TextCode" == wsNodeName) m_arTextCodes.push_back(new CTextCode(oLiteReader)); @@ -151,28 +174,39 @@ CTextObject::~CTextObject() delete pTextCode; } -void CTextObject::Draw(IRenderer* pRenderer) const +void CTextObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const { if (nullptr == pRenderer || m_arTextCodes.empty()) return; CGraphicUnit::Apply(pRenderer); - if (nullptr != m_pFont) - m_pFont->Apply(pRenderer, m_pFontManager, m_dSize * 72. / 25.4); + const CFont* pFont = oCommonData.GetPublicRes()->GetFont(m_unFontID); - if (m_bFill && nullptr != m_pFillColor) + if (nullptr != pFont) + pFont->Apply(pRenderer); + + if (m_bFill) { pRenderer->put_BrushType(c_BrushTypeSolid); - pRenderer->put_BrushColor1(m_pFillColor->ToInt()); - pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha()); + + if (nullptr != m_pFillColor) + { + pRenderer->put_BrushColor1(m_pFillColor->ToInt(oCommonData.GetPublicRes())); + pRenderer->put_BrushAlpha1(m_pFillColor->GetAlpha()); + } + else + { + pRenderer->put_BrushColor1(0); + pRenderer->put_BrushAlpha1(0xff); + } } else pRenderer->put_BrushType(c_BrushTypeNotSet); pRenderer->put_FontSize(m_dSize * 72. / 25.4); - unsigned int unGlyphsIndex; + unsigned int unGlyphsIndex = 0; for (const CTextCode* pTextCode : m_arTextCodes) pTextCode->Draw(pRenderer, unGlyphsIndex, m_arCGTransforms); @@ -224,14 +258,17 @@ bool TCGTransform::Draw(IRenderer* pRenderer, unsigned int& unIndex, double dX, if (m_unCodePosition != unIndex || 0 == m_unCodeCount || 0 == m_unGlyphCount) return false; - pRenderer->put_FontStringGID(1); + int nCurrentValue; + pRenderer->get_FontStringGID(&nCurrentValue); + + pRenderer->put_FontStringGID(TRUE); for (unsigned int unGlyphCount = 0; unGlyphCount < m_unGlyphCount; ++unGlyphCount) pRenderer->CommandDrawTextCHAR(m_arGlyphs[unGlyphCount], dX, dY, 0, 0); unIndex += m_unCodeCount; - pRenderer->put_FontStringGID(0); + pRenderer->put_FontStringGID(nCurrentValue); return true; } diff --git a/OFDFile/src/Content/TextObject.h b/OFDFile/src/Content/TextObject.h index 72320c1a21..f30011c2a1 100644 --- a/OFDFile/src/Content/TextObject.h +++ b/OFDFile/src/Content/TextObject.h @@ -50,17 +50,15 @@ class CTextObject : public IPageBlock, public CGraphicUnit CColor* m_pFillColor; CColor* m_pStrokeColor; - const CFont* m_pFont; + unsigned int m_unFontID; std::vector m_arTextCodes; std::vector m_arCGTransforms; - - NSFonts::IFontManager* m_pFontManager; public: - CTextObject(CXmlReader& oLiteReader, const CRes* pPublicRes, NSFonts::IFontManager* pFontManager); + CTextObject(CXmlReader& oLiteReader); ~CTextObject(); - void Draw(IRenderer* pRenderer) const override; + void Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const override; }; } diff --git a/OFDFile/src/Document.cpp b/OFDFile/src/Document.cpp index f338e90ace..b9568a7cfc 100644 --- a/OFDFile/src/Document.cpp +++ b/OFDFile/src/Document.cpp @@ -44,7 +44,7 @@ bool CDocument::Empty() const return m_mPages.empty(); } -bool CDocument::Read(const std::wstring& wsFilePath, NSFonts::IFontManager* pFontManager) +bool CDocument::Read(const std::wstring& wsFilePath) { if (wsFilePath.empty()) return false; @@ -61,7 +61,7 @@ bool CDocument::Read(const std::wstring& wsFilePath, NSFonts::IFontManager* pFon wsNodeName = oLiteReader.GetName(); if (L"ofd:CommonData" == wsNodeName) - m_oCommonData.Read(oLiteReader, NSSystemPath::GetDirectoryName(wsFilePath), pFontManager); + m_oCommonData.Read(oLiteReader, NSSystemPath::GetDirectoryName(wsFilePath)); else if (L"ofd:Pages" == wsNodeName) { const int nPagesDepth = oLiteReader.GetDepth(); @@ -88,7 +88,7 @@ bool CDocument::Read(const std::wstring& wsFilePath, NSFonts::IFontManager* pFon if (-1 == nID) nID = m_mPages.size() + 1; - CPage* pPage = CPage::Read(CombinePaths(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc), m_oCommonData, pFontManager); + CPage* pPage = CPage::Read(CombinePaths(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc)); if (nullptr != pPage) m_mPages.insert(std::make_pair(m_mPages.size(), pPage)); @@ -114,7 +114,7 @@ bool CDocument::DrawPage(IRenderer* pRenderer, int nPageIndex) const if (itFound == m_mPages.cend()) return false; - itFound->second->Draw(pRenderer); + itFound->second->Draw(pRenderer, m_oCommonData); return true; } diff --git a/OFDFile/src/Document.h b/OFDFile/src/Document.h index ce495e5766..50bb0afc95 100644 --- a/OFDFile/src/Document.h +++ b/OFDFile/src/Document.h @@ -34,7 +34,7 @@ public: bool Empty() const; - bool Read(const std::wstring& wsFilePath, NSFonts::IFontManager* pFontManager); + bool Read(const std::wstring& wsFilePath); bool DrawPage(IRenderer* pRenderer, int nPageIndex) const; diff --git a/OFDFile/src/OFDFile_Private.cpp b/OFDFile/src/OFDFile_Private.cpp index 5271a9a4aa..63c7048dfc 100644 --- a/OFDFile/src/OFDFile_Private.cpp +++ b/OFDFile/src/OFDFile_Private.cpp @@ -62,7 +62,7 @@ bool COFDFile_Private::Read(IFolder* pFolder) if (nullptr == pFolder) return false; - if (!m_oBase.Read(pFolder, m_pFontManager)) + if (!m_oBase.Read(pFolder)) return false; return false; diff --git a/OFDFile/src/Page.cpp b/OFDFile/src/Page.cpp index 2eb793141f..a96be0ac9f 100644 --- a/OFDFile/src/Page.cpp +++ b/OFDFile/src/Page.cpp @@ -7,16 +7,13 @@ namespace OFD { CPage::CPage() - : m_pTemplatePage(nullptr) + : m_parTemplatePage{0, EZOrder::Background} {} CPage::~CPage() -{ - if (nullptr != m_pTemplatePage) - delete m_pTemplatePage; -} +{} -CPage* CPage::Read(const std::wstring& wsFilePath, const CCommonData& oCommonData, NSFonts::IFontManager* pFontManager) +CPage* CPage::Read(const std::wstring& wsFilePath) { if (wsFilePath.empty()) return nullptr; @@ -40,14 +37,11 @@ CPage* CPage::Read(const std::wstring& wsFilePath, const CCommonData& oCommonDat wsNodeName = oLiteReader.GetName(); if (L"ofd:Content" == wsNodeName) - pPage->m_oContent.Read(oLiteReader, oCommonData.GetDocumentRes(), oCommonData.GetPublicRes(), pFontManager); + pPage->m_oContent.Read(oLiteReader); else if (L"ofd:Area" == wsNodeName) pPage->m_oArea.Read(oLiteReader); else if (L"ofd:Template" == wsNodeName && 0 != oLiteReader.GetAttributesCount() && oLiteReader.MoveToFirstAttribute()) { - EZOrder eZorder; - unsigned int unTemplateID; - std::string sAttributeName; do @@ -55,31 +49,34 @@ CPage* CPage::Read(const std::wstring& wsFilePath, const CCommonData& oCommonDat sAttributeName = oLiteReader.GetNameA(); if ("ZOrder" == sAttributeName) - eZorder = GetZOrderFromString(oLiteReader.GetTextA()); + pPage->m_parTemplatePage.second = GetZOrderFromString(oLiteReader.GetTextA()); else if ("TemplateID" == sAttributeName) - unTemplateID = oLiteReader.GetUInteger(true); + pPage->m_parTemplatePage.first = oLiteReader.GetUInteger(true); } while (oLiteReader.MoveToNextAttribute()); oLiteReader.MoveToElement(); - - pPage->m_pTemplatePage = oCommonData.GetTemplatePage(unTemplateID, eZorder); } } return pPage; } -void CPage::Draw(IRenderer* pRenderer) const +void CPage::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const { if (nullptr == pRenderer) return; pRenderer->BeginCommand(c_nImageType); - if (nullptr != m_pTemplatePage && EZOrder::Background == m_pTemplatePage->GetZOrder()) - m_pTemplatePage->GetPage()->Draw(pRenderer); + if (0 != m_parTemplatePage.first) + { + const CTemplatePage *pTemplatePage = oCommonData.GetTemplatePage(m_parTemplatePage.first, m_parTemplatePage.second); - m_oContent.Draw(pRenderer); + if (nullptr != pTemplatePage && EZOrder::Background == pTemplatePage->GetZOrder() && nullptr != pTemplatePage->GetPage()) + pTemplatePage->GetPage()->Draw(pRenderer, oCommonData); + } + + m_oContent.Draw(pRenderer, oCommonData); pRenderer->EndCommand(c_nImageType); } diff --git a/OFDFile/src/Page.h b/OFDFile/src/Page.h index 6c575b20b7..c8fa772639 100644 --- a/OFDFile/src/Page.h +++ b/OFDFile/src/Page.h @@ -12,13 +12,13 @@ class CPage CPageArea m_oArea; CContent m_oContent; - const CTemplatePage* m_pTemplatePage; + std::pair m_parTemplatePage; public: CPage(); ~CPage(); - static CPage* Read(const std::wstring& wsFilePath, const CCommonData& oCommonData, NSFonts::IFontManager* pFontManager); - void Draw(IRenderer* pRenderer) const; + static CPage* Read(const std::wstring& wsFilePath); + void Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const; void GetPageSize(double& dWidth, double& dHeight) const; }; diff --git a/OFDFile/src/Types/Color.cpp b/OFDFile/src/Types/Color.cpp index 564a6543e2..d2e2c645cf 100644 --- a/OFDFile/src/Types/Color.cpp +++ b/OFDFile/src/Types/Color.cpp @@ -2,8 +2,8 @@ namespace OFD { -CColor::CColor(CXmlReader& oXmlReader, const CRes* pPublicRes) - : m_oValues{0, 0, 0, 0}, m_nIndex(0), m_chAlpha(255), m_pColorSpace(nullptr) +CColor::CColor(CXmlReader& oXmlReader) + : m_oValues{0, 0, 0, 0}, m_nIndex(0), m_chAlpha(255), m_unColodSpaceID(0) { if (0 == oXmlReader.GetAttributesCount() || !oXmlReader.MoveToFirstAttribute()) return; @@ -15,10 +15,7 @@ CColor::CColor(CXmlReader& oXmlReader, const CRes* pPublicRes) sAttributeName = oXmlReader.GetNameA(); if ("ColorSpace" == sAttributeName) - { - if (nullptr != pPublicRes) - m_pColorSpace = pPublicRes->GetColorSpace(oXmlReader.GetUInteger(true)); - } + m_unColodSpaceID = oXmlReader.GetUInteger(true); else if ("Value" == sAttributeName) { const std::vector arValues{oXmlReader.GetArrayDoubles(true)}; @@ -35,33 +32,38 @@ CColor::CColor(CXmlReader& oXmlReader, const CRes* pPublicRes) oXmlReader.MoveToElement(); } -int CColor::ToInt() const +int CColor::ToInt(const CRes* pPublicRes) const { - if (nullptr != m_pColorSpace) + if (nullptr == pPublicRes) + return 0; + + const CColorSpace* pColorSpace = pPublicRes->GetColorSpace(m_unColodSpaceID); + + if (nullptr == pColorSpace) + return 0; + + switch(pColorSpace->GetType()) { - switch(m_pColorSpace->GetType()) + case CColorSpace::EType::GRAY: + return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[0] << 8) | (m_oValues[0] << 0); + case CColorSpace::EType::RGB: + return (255 << 24) | (m_oValues[2] << 16) | (m_oValues[1] << 8) | (m_oValues[0] << 0); + case CColorSpace::EType::CMYK: { - case CColorSpace::EType::GRAY: - return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[0] << 8) | (m_oValues[0] << 0); - case CColorSpace::EType::RGB: - return (255 << 24) | (m_oValues[2] << 16) | (m_oValues[1] << 8) | (m_oValues[0] << 0); - case CColorSpace::EType::CMYK: - { - const float cF = m_oValues[0] / 255.0f; - const float mF = m_oValues[1] / 255.0f; - const float yF = m_oValues[2] / 255.0f; - const float kF = m_oValues[3] / 255.0f; + const float cF = m_oValues[0] / 255.0f; + const float mF = m_oValues[1] / 255.0f; + const float yF = m_oValues[2] / 255.0f; + const float kF = m_oValues[3] / 255.0f; - const float r = (1.0f - cF) * (1.0f - kF); - const float g = (1.0f - mF) * (1.0f - kF); - const float b = (1.0f - yF) * (1.0f - kF); + const float r = (1.0f - cF) * (1.0f - kF); + const float g = (1.0f - mF) * (1.0f - kF); + const float b = (1.0f - yF) * (1.0f - kF); - const unsigned char rByte = static_cast(r * 255); - const unsigned char gByte = static_cast(g * 255); - const unsigned char bByte = static_cast(b * 255); + const unsigned char rByte = static_cast(r * 255); + const unsigned char gByte = static_cast(g * 255); + const unsigned char bByte = static_cast(b * 255); - return (rByte << 0) | (gByte << 8) | (bByte << 16); - } + return (rByte << 0) | (gByte << 8) | (bByte << 16); } } diff --git a/OFDFile/src/Types/Color.h b/OFDFile/src/Types/Color.h index 9ecccc4501..23688225e7 100644 --- a/OFDFile/src/Types/Color.h +++ b/OFDFile/src/Types/Color.h @@ -13,16 +13,16 @@ class CColor int m_nIndex; BYTE m_chAlpha; - const CColorSpace* m_pColorSpace; + unsigned int m_unColodSpaceID; // Pattern // AxialShd // RadialShd // GouraudShd // LaGouraudhd public: - CColor(CXmlReader& oXmlReader, const CRes* pPublicRes); + CColor(CXmlReader& oXmlReader); - int ToInt() const; + int ToInt(const CRes* pPublicRes) const; BYTE GetAlpha() const; }; } diff --git a/OFDFile/src/Types/CommonData.cpp b/OFDFile/src/Types/CommonData.cpp index ebcd7efb9d..5f20c1b613 100644 --- a/OFDFile/src/Types/CommonData.cpp +++ b/OFDFile/src/Types/CommonData.cpp @@ -18,7 +18,7 @@ CCommonData::~CCommonData() delete m_pDocumentRes; } -bool CCommonData::Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath, NSFonts::IFontManager* pFontManager) +bool CCommonData::Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath) { if ("ofd:CommonData" != oLiteReader.GetNameA()) return false; @@ -49,7 +49,7 @@ bool CCommonData::Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath, else if ("ofd:MaxUnitID" == sNodeName) m_unMaxUnitID = oLiteReader.GetUInteger(); else if ("ofd:TemplatePage" == sNodeName) - AddToContainer(new const CTemplatePage(oLiteReader, *this, pFontManager), m_arTemplatePages); + AddToContainer(new const CTemplatePage(oLiteReader, wsRootPath), m_arTemplatePages); // else if (L"ofd:DefaultCS" == wsNodeName) } diff --git a/OFDFile/src/Types/CommonData.h b/OFDFile/src/Types/CommonData.h index 74d48eae86..ebecdedf78 100644 --- a/OFDFile/src/Types/CommonData.h +++ b/OFDFile/src/Types/CommonData.h @@ -21,7 +21,7 @@ public: CCommonData(); ~CCommonData(); - bool Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath, NSFonts::IFontManager* pFontManager); + bool Read(CXmlReader& oLiteReader, const std::wstring& wsRootPath); void GetPageSize(double& dWidth, double &dHeight) const; diff --git a/OFDFile/src/Types/Font.cpp b/OFDFile/src/Types/Font.cpp index ce7b865804..56cd1b2767 100644 --- a/OFDFile/src/Types/Font.cpp +++ b/OFDFile/src/Types/Font.cpp @@ -51,7 +51,7 @@ CFont::CFont(CXmlReader& oXmlReader, const std::wstring& wsRootPath) } } -void CFont::Apply(IRenderer* pRenderer, NSFonts::IFontManager* pFontManager, const double& dFontSize) const +void CFont::Apply(IRenderer* pRenderer) const { if (nullptr == pRenderer) return; @@ -66,14 +66,7 @@ void CFont::Apply(IRenderer* pRenderer, NSFonts::IFontManager* pFontManager, con pRenderer->put_FontStyle(nFontStyle); pRenderer->put_FontName(m_wsFontName); - if (!m_wsFilePath.empty() && nullptr != pFontManager) - { - double dDpiX = 96, dDpiY = 96; - - pRenderer->get_DpiX(&dDpiX); - pRenderer->get_DpiY(&dDpiY); - - pFontManager->LoadFontFromFile(m_wsFilePath, 0, dFontSize, dDpiX, dDpiY); - } + if (!m_wsFilePath.empty()) + pRenderer->put_FontPath(m_wsFilePath); } } diff --git a/OFDFile/src/Types/Font.h b/OFDFile/src/Types/Font.h index 268336231e..dc3c698ff8 100644 --- a/OFDFile/src/Types/Font.h +++ b/OFDFile/src/Types/Font.h @@ -4,7 +4,6 @@ #include "../IOFDElement.h" #include "../../../DesktopEditor/graphics/IRenderer.h" -#include "../../../DesktopEditor/graphics/pro/Fonts.h" namespace OFD { @@ -13,7 +12,7 @@ class CFont : public IOFDElement public: CFont(CXmlReader& oXmlReader, const std::wstring& wsRootPath); - void Apply(IRenderer* pRenderer, NSFonts::IFontManager* pFontManager, const double& dFontSize) const; + void Apply(IRenderer* pRenderer) const; private: std::wstring m_wsFontName; std::wstring m_wsFamilyName; diff --git a/OFDFile/src/Types/TemplatePage.cpp b/OFDFile/src/Types/TemplatePage.cpp index b20a859669..41f2f22dfb 100644 --- a/OFDFile/src/Types/TemplatePage.cpp +++ b/OFDFile/src/Types/TemplatePage.cpp @@ -1,10 +1,11 @@ #include "TemplatePage.h" -#include "CommonData.h" + #include "../Page.h" +#include "../Utils/Utils.h" namespace OFD { -CTemplatePage::CTemplatePage(CXmlReader& oXmlReader, const CCommonData& oCommonData, NSFonts::IFontManager* pFontManager) +CTemplatePage::CTemplatePage(CXmlReader& oXmlReader, const std::wstring& wsRootPath) : IOFDElement(oXmlReader), m_eZOrder(EZOrder::Background), m_pPage(nullptr) { if ("ofd:TemplatePage" != oXmlReader.GetNameA() || 0 == oXmlReader.GetAttributesCount() || !oXmlReader.MoveToFirstAttribute()) @@ -16,7 +17,7 @@ CTemplatePage::CTemplatePage(CXmlReader& oXmlReader, const CCommonData& oCommonD sAttributeName = oXmlReader.GetNameA(); if ("BaseLoc" == sAttributeName) - m_pPage = CPage::Read(oXmlReader.GetText2(), oCommonData, pFontManager); + m_pPage = CPage::Read(CombinePaths(wsRootPath, oXmlReader.GetText())); else if ("ZOrder" == sAttributeName) m_eZOrder = GetZOrderFromString(oXmlReader.GetTextA()); } while (oXmlReader.MoveToNextAttribute()); diff --git a/OFDFile/src/Types/TemplatePage.h b/OFDFile/src/Types/TemplatePage.h index 7c88be96d6..9d7e3ff796 100644 --- a/OFDFile/src/Types/TemplatePage.h +++ b/OFDFile/src/Types/TemplatePage.h @@ -15,14 +15,13 @@ enum class EZOrder EZOrder GetZOrderFromString(const std::string& sValue); class CPage; -class CCommonData; class CTemplatePage : public IOFDElement { EZOrder m_eZOrder; const CPage* m_pPage; public: - CTemplatePage(CXmlReader& oXmlReader, const CCommonData& oCommonData, NSFonts::IFontManager* pFontManager); + CTemplatePage(CXmlReader& oXmlReader, const std::wstring& wsRootPath); ~CTemplatePage(); EZOrder GetZOrder() const; diff --git a/OFDFile/src/Utils/XmlReader.cpp b/OFDFile/src/Utils/XmlReader.cpp index 5c8d860244..99ff9f924c 100644 --- a/OFDFile/src/Utils/XmlReader.cpp +++ b/OFDFile/src/Utils/XmlReader.cpp @@ -45,6 +45,11 @@ double CXmlReader::GetDouble(bool bIsAttribute) return dValue; } +std::vector CXmlReader::GetArrayStrings(bool bIsAttribute) +{ + return Split(GetTextValueA(bIsAttribute), ' '); +} + std::vector CXmlReader::GetArrayDoubles(bool bIsAttribute) { const std::vector arValues{Split(GetTextValueA(bIsAttribute), ' ')}; diff --git a/OFDFile/src/Utils/XmlReader.h b/OFDFile/src/Utils/XmlReader.h index 8642b82874..6d1e46773a 100644 --- a/OFDFile/src/Utils/XmlReader.h +++ b/OFDFile/src/Utils/XmlReader.h @@ -18,6 +18,7 @@ public: int GetInteger(bool bIsAttribute = false); unsigned int GetUInteger(bool bIsAttribute = false); double GetDouble(bool bIsAttribute = false); + std::vector GetArrayStrings(bool bIsAttribute = false); std::vector GetArrayDoubles(bool bIsAttribute = false); }; } From 6cb7e763d33b2b5de61be312860a599ac340195f Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 15 Apr 2025 19:31:32 +0300 Subject: [PATCH 08/15] Improved rendering of text in OFD format and refactoring --- OFDFile/OFDFile.pro | 2 + OFDFile/src/Base.cpp | 89 +++++++++---- OFDFile/src/Base.h | 8 +- OFDFile/src/Content/GraphicUnit.cpp | 11 +- OFDFile/src/Content/GraphicUnit.h | 2 +- OFDFile/src/Content/ImageObject.cpp | 7 +- OFDFile/src/Content/PathObject.cpp | 95 +++++++------- OFDFile/src/Content/PathObject.h | 13 +- OFDFile/src/Content/TextObject.cpp | 21 ++-- OFDFile/src/OFDFile_Private.cpp | 40 +++++- OFDFile/src/OFDFile_Private.h | 1 + OFDFile/src/Types/Color.cpp | 8 +- OFDFile/src/Types/CommonData.h | 2 - OFDFile/src/Types/Signature.cpp | 186 ++++++++++++++++++++++++++++ OFDFile/src/Types/Signature.h | 75 +++++++++++ OFDFile/src/Types/TemplatePage.h | 1 - OFDFile/src/Utils/Utils.h | 15 +++ 17 files changed, 472 insertions(+), 104 deletions(-) create mode 100644 OFDFile/src/Types/Signature.cpp create mode 100644 OFDFile/src/Types/Signature.h diff --git a/OFDFile/OFDFile.pro b/OFDFile/OFDFile.pro index 44b905d5e4..3bbb507895 100644 --- a/OFDFile/OFDFile.pro +++ b/OFDFile/OFDFile.pro @@ -52,6 +52,7 @@ HEADERS += \ src/Types/Font.h \ src/Types/MultiMedia.h \ src/Types/PageArea.h \ + src/Types/Signature.h \ src/Types/TemplatePage.h \ src/Utils/Types.h \ src/Utils/Utils.h \ @@ -79,6 +80,7 @@ SOURCES += \ src/Types/Font.cpp \ src/Types/MultiMedia.cpp \ src/Types/PageArea.cpp \ + src/Types/Signature.cpp \ src/Types/TemplatePage.cpp \ src/Utils/Types.cpp \ src/Utils/XmlReader.cpp diff --git a/OFDFile/src/Base.cpp b/OFDFile/src/Base.cpp index 1c8c4aeb43..74d33aebe7 100644 --- a/OFDFile/src/Base.cpp +++ b/OFDFile/src/Base.cpp @@ -1,14 +1,15 @@ #include "Base.h" +#include "Utils/Utils.h" namespace OFD { #define IF_CHECK_NODE(node_name, varible_name)\ -if (node_name == wsNodeName)\ +if (node_name == sNodeName)\ varible_name = oLiteReader.GetText2() #define ELSE_IF_CHECK_NODE(node_name, varible_name)\ - else if (node_name == wsNodeName)\ - varible_name = oLiteReader.GetText2() +else if (node_name == sNodeName)\ + varible_name = oLiteReader.GetText2() EDocUsege GetDocUsage(const std::wstring& wsValue) { @@ -33,32 +34,67 @@ bool CDocInfo::Read(CXmlReader& oLiteReader) const int nDepth = oLiteReader.GetDepth(); - std::wstring wsNodeName; + std::string sNodeName; while (oLiteReader.ReadNextSiblingNode(nDepth)) { - wsNodeName = oLiteReader.GetName(); + sNodeName = oLiteReader.GetNameA(); - IF_CHECK_NODE(L"ofd:DocID", m_wsDocId); - ELSE_IF_CHECK_NODE(L"ofd:Title", m_wsTitle); - ELSE_IF_CHECK_NODE(L"ofd:Author", m_wsAuthor); - ELSE_IF_CHECK_NODE(L"ofd:Subject", m_wsSubject); - ELSE_IF_CHECK_NODE(L"ofd:Abstruct", m_wsAbstact); - ELSE_IF_CHECK_NODE(L"ofd:CreationDate", m_wsCreationDate); - ELSE_IF_CHECK_NODE(L"ofd:ModDate", m_wsModDate); - ELSE_IF_CHECK_NODE(L"ofd:Cover", m_wsCover); - ELSE_IF_CHECK_NODE(L"ofd:Creator", m_wsCreator); - ELSE_IF_CHECK_NODE(L"ofd:CreatorVersion", m_wsCreatorVersion); - else if (L"ofd:DocUsage" == wsNodeName) + IF_CHECK_NODE("ofd:DocID", m_wsDocId); + ELSE_IF_CHECK_NODE("ofd:Title", m_wsTitle); + ELSE_IF_CHECK_NODE("ofd:Author", m_wsAuthor); + ELSE_IF_CHECK_NODE("ofd:Subject", m_wsSubject); + ELSE_IF_CHECK_NODE("ofd:Abstruct", m_wsAbstact); + ELSE_IF_CHECK_NODE("ofd:CreationDate", m_wsCreationDate); + ELSE_IF_CHECK_NODE("ofd:ModDate", m_wsModDate); + ELSE_IF_CHECK_NODE("ofd:Cover", m_wsCover); + ELSE_IF_CHECK_NODE("ofd:Creator", m_wsCreator); + ELSE_IF_CHECK_NODE("ofd:CreatorVersion", m_wsCreatorVersion); + else if ("ofd:DocUsage" == sNodeName) m_eDocUsage = GetDocUsage(oLiteReader.GetText2()); } return true; } -CDocBody::CDocBody() +void CDocBody::ReadSignatures(const std::wstring& wsFilePath, const std::wstring& wsRootPath) { + CXmlReader oLiteReader; + if (!oLiteReader.FromFile(CombinePaths(wsRootPath, wsFilePath)) || !oLiteReader.ReadNextNode() || L"ofd:Signatures" != oLiteReader.GetName()) + return; + const int nDepth = oLiteReader.GetDepth(); + std::string sNodeName; + unsigned int unMaxSignId = 0; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + sNodeName = oLiteReader.GetNameA(); + + if ("ofd:MaxSignId" == sNodeName) + unMaxSignId = oLiteReader.GetUInteger(); + else if ("ofd:Signature" == sNodeName) + { + if (0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) + continue; + + do + { + if ("BaseLoc" == oLiteReader.GetNameA()) + AddToContainer(CSignature::Read(oLiteReader.GetText(), wsRootPath), m_arSignatures); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); + } + } +} + +CDocBody::CDocBody() +{} + +CDocBody::~CDocBody() +{ + ClearContainer(m_arSignatures); } CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) @@ -67,7 +103,7 @@ CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) return nullptr; const int nDepth = oLiteReader.GetDepth(); - std::wstring wsNodeName; + std::string sNodeName; CDocBody *pDocBody = new CDocBody(); @@ -76,9 +112,9 @@ CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) while (oLiteReader.ReadNextSiblingNode(nDepth)) { - wsNodeName = oLiteReader.GetName(); + sNodeName = oLiteReader.GetNameA(); - if (L"ofd:DocInfo" == wsNodeName) + if ("ofd:DocInfo" == sNodeName) { if (!pDocBody->m_oDocInfo.Read(oLiteReader)) { @@ -86,14 +122,15 @@ CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) return nullptr; } } - else if (L"ofd:DocRoot" == wsNodeName) + else if ("ofd:DocRoot" == sNodeName) { const std::wstring wsPath = NSSystemPath::ShortenPath(oLiteReader.GetText2()); if (!wsPath.empty() && L'.' != wsPath.front()) pDocBody->m_oDocument.Read(pFolder->getFullFilePath(wsPath)); } - ELSE_IF_CHECK_NODE(L"ofd:Signatures", pDocBody->m_wsSignature); + else if ("ofd:Signatures" == sNodeName) + pDocBody->ReadSignatures(oLiteReader.GetText2(), pFolder->getFullFilePath(L"")); } return pDocBody; @@ -101,7 +138,13 @@ CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) bool CDocBody::DrawPage(IRenderer* pRenderer, int nPageIndex) const { - return m_oDocument.DrawPage(pRenderer, nPageIndex); + const bool bResult = m_oDocument.DrawPage(pRenderer, nPageIndex); + + for (const CSignature* pSignature : m_arSignatures) + if (pSignature->Draw(pRenderer, nPageIndex, nullptr)) + break; + + return bResult; } unsigned int CDocBody::GetPageCount() const diff --git a/OFDFile/src/Base.h b/OFDFile/src/Base.h index 2a58e03321..7f07db7884 100644 --- a/OFDFile/src/Base.h +++ b/OFDFile/src/Base.h @@ -2,10 +2,10 @@ #define BASE_H #include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" #include "../../OfficeUtils/src/ZipFolder.h" #include "Document.h" +#include "Types/Signature.h" namespace OFD { @@ -47,9 +47,13 @@ class CDocBody CDocument m_oDocument; // std::wstring m_wsPathToDocRoot; // std::wstring m_wsVersions; - std::wstring m_wsSignature; + std::vector m_arSignatures; + + void ReadSignatures(const std::wstring& wsFilePath, const std::wstring& wsRootPath); public: CDocBody(); + ~CDocBody(); + static CDocBody* Read(CXmlReader& oLiteReader, IFolder* pFolder); bool DrawPage(IRenderer* pRenderer, int nPageIndex) const; diff --git a/OFDFile/src/Content/GraphicUnit.cpp b/OFDFile/src/Content/GraphicUnit.cpp index c87de5a7f1..6285c0afbd 100644 --- a/OFDFile/src/Content/GraphicUnit.cpp +++ b/OFDFile/src/Content/GraphicUnit.cpp @@ -62,12 +62,17 @@ CGraphicUnit::CGraphicUnit(CXmlReader& oLiteReader) oLiteReader.MoveToElement(); } -void CGraphicUnit::Apply(IRenderer* pRenderer) const +void CGraphicUnit::Apply(IRenderer* pRenderer, TMatrix& oOldTransform) const { if (nullptr == pRenderer) return; - pRenderer->ResetTransform(); + pRenderer->GetTransform(&oOldTransform.m_dM11, &oOldTransform.m_dM12, &oOldTransform.m_dM21, &oOldTransform.m_dM22, &oOldTransform.m_dDx, &oOldTransform.m_dDy); + + Aggplus::CMatrix oTransform(oOldTransform.m_dM11, oOldTransform.m_dM12, oOldTransform.m_dM21, oOldTransform.m_dM22, oOldTransform.m_dDx, oOldTransform.m_dDy); + const Aggplus::CMatrix oCurrentTransform(m_oCTM.m_dM11, m_oCTM.m_dM12, m_oCTM.m_dM21, m_oCTM.m_dM22, m_oBoundary.m_dX + m_oCTM.m_dDx, m_oBoundary.m_dY + m_oCTM.m_dDy); + + oTransform.Multiply(&oCurrentTransform); // Clipping // pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionIntersect); @@ -86,7 +91,7 @@ void CGraphicUnit::Apply(IRenderer* pRenderer) const // pRenderer->EndCommand(c_nClipType); // pRenderer->PathCommandEnd(); - pRenderer->SetTransform(m_oCTM.m_dM11, m_oCTM.m_dM12, m_oCTM.m_dM21, m_oCTM.m_dM22, m_oBoundary.m_dX + m_oCTM.m_dDx, m_oBoundary.m_dY + m_oCTM.m_dDy); + pRenderer->SetTransform(oTransform.sx(), oTransform.shy(), oTransform.shx(), oTransform.sy(), oTransform.tx(), oTransform.ty()); } TBox CGraphicUnit::GetBoundary() const diff --git a/OFDFile/src/Content/GraphicUnit.h b/OFDFile/src/Content/GraphicUnit.h index b2f8e4a718..8cd10c6e5b 100644 --- a/OFDFile/src/Content/GraphicUnit.h +++ b/OFDFile/src/Content/GraphicUnit.h @@ -42,7 +42,7 @@ class CGraphicUnit public: CGraphicUnit(CXmlReader& oLiteReader); - void Apply(IRenderer* pRenderer) const; + void Apply(IRenderer* pRenderer, TMatrix& oOldTransform) const; TBox GetBoundary() const; }; diff --git a/OFDFile/src/Content/ImageObject.cpp b/OFDFile/src/Content/ImageObject.cpp index b9831eeabe..4f0d7cfec1 100644 --- a/OFDFile/src/Content/ImageObject.cpp +++ b/OFDFile/src/Content/ImageObject.cpp @@ -1,7 +1,5 @@ #include "ImageObject.h" -#include "../../../DesktopEditor/graphics/Image.h" - namespace OFD { CImageObject::CImageObject(CXmlReader& oLiteReader) @@ -36,7 +34,8 @@ void CImageObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) co if (nullptr == pMultiMedia) return; - CGraphicUnit::Apply(pRenderer); + TMatrix oOldTransform; + CGraphicUnit::Apply(pRenderer, oOldTransform); const std::wstring wsFilePath = pMultiMedia->GetFilePath(); @@ -44,5 +43,7 @@ void CImageObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) co return; pRenderer->DrawImageFromFile(wsFilePath, 0, 0, 1, 1); + + pRenderer->SetTransform(oOldTransform.m_dM11, oOldTransform.m_dM12, oOldTransform.m_dM21, oOldTransform.m_dM22, oOldTransform.m_dDx, oOldTransform.m_dDy); } } diff --git a/OFDFile/src/Content/PathObject.cpp b/OFDFile/src/Content/PathObject.cpp index dfd96e12a2..8d850b1c28 100644 --- a/OFDFile/src/Content/PathObject.cpp +++ b/OFDFile/src/Content/PathObject.cpp @@ -60,54 +60,56 @@ CPathObject::CPathObject(CXmlReader& oLiteReader) { std::vector arValues{Split(oLiteReader.GetText2A(), ' ')}; + std::vector::const_iterator itElement = arValues.cbegin(); + char chElementName; - while (!arValues.empty()) + while (arValues.cend() != itElement) { if (arValues.front().length() != 1) { - arValues.erase(arValues.begin()); + ++itElement; continue; } - chElementName = arValues[0][0]; - arValues.erase(arValues.begin()); + chElementName = (*itElement)[0]; + ++itElement; switch (chElementName) { case 'S': { - AddElement(CStartElement::ReadFromArray(arValues)); + AddElement(CStartElement::ReadFromArray(itElement, arValues.cend())); break; } case 'M': { - AddElement(CMoveElement::ReadFromArray(arValues)); + AddElement(CMoveElement::ReadFromArray(itElement, arValues.cend())); break; } case 'L': { - AddElement(CLineElement::ReadFromArray(arValues)); + AddElement(CLineElement::ReadFromArray(itElement, arValues.cend())); break; } case 'Q': { - AddElement(CBezierCurve2Element::ReadFromArray(arValues)); + AddElement(CBezierCurve2Element::ReadFromArray(itElement, arValues.cend())); break; } case 'B': { - AddElement(CBezierCurveElement::ReadFromArray(arValues)); + AddElement(CBezierCurveElement::ReadFromArray(itElement, arValues.cend())); break; } case 'A': { - AddElement(CArcElement::ReadFromArray(arValues)); + AddElement(CArcElement::ReadFromArray(itElement, arValues.cend())); break; } case 'C': { - AddElement(CCloseElement::ReadFromArray(arValues)); + AddElement(new CCloseElement()); break; } default: @@ -135,7 +137,8 @@ void CPathObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) con if (nullptr == pRenderer || m_arElements.empty()) return; - CGraphicUnit::Apply(pRenderer); + TMatrix oOldTransform; + CGraphicUnit::Apply(pRenderer, oOldTransform); pRenderer->BeginCommand(c_nPathType); pRenderer->PathCommandStart(); @@ -207,14 +210,16 @@ void CPathObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) con pRenderer->PathCommandEnd(); pRenderer->EndCommand(c_nPathType); + + pRenderer->SetTransform(oOldTransform.m_dM11, oOldTransform.m_dM12, oOldTransform.m_dM21, oOldTransform.m_dM22, oOldTransform.m_dDx, oOldTransform.m_dDy); } CStartElement::CStartElement() {} -IPathElement* CStartElement::ReadFromArray(std::vector& arValues) +IPathElement* CStartElement::ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd) { - if (arValues.size() < 2) + if (itEnd - itBegin < 2) return nullptr; CStartElement *pElement = new CStartElement(); @@ -222,12 +227,10 @@ IPathElement* CStartElement::ReadFromArray(std::vector& arValues) if (nullptr == pElement) return nullptr; - if (StringToDouble(arValues[0], pElement->m_dX) && StringToDouble(arValues[1], pElement->m_dY)) + if (StringToDouble(*itBegin++, pElement->m_dX) && StringToDouble(*itBegin++, pElement->m_dY)) return pElement; - if (nullptr != pElement) - delete pElement; - + delete pElement; return nullptr; } @@ -240,9 +243,9 @@ void CStartElement::Draw(IRenderer* pRenderer) const CMoveElement::CMoveElement() {} -IPathElement* CMoveElement::ReadFromArray(std::vector& arValues) +IPathElement* CMoveElement::ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd) { - if (arValues.size() < 2) + if (itEnd - itBegin < 2) return nullptr; CMoveElement *pElement = new CMoveElement(); @@ -250,8 +253,7 @@ IPathElement* CMoveElement::ReadFromArray(std::vector& arValues) if (nullptr == pElement) return nullptr; - - if (StringToDouble(arValues[0], pElement->m_dX) && StringToDouble(arValues[1], pElement->m_dY)) + if (StringToDouble(*itBegin++, pElement->m_dX) && StringToDouble(*itBegin++, pElement->m_dY)) return pElement; delete pElement; @@ -267,9 +269,9 @@ void CMoveElement::Draw(IRenderer* pRenderer) const CLineElement::CLineElement() {} -IPathElement* CLineElement::ReadFromArray(std::vector& arValues) +IPathElement* CLineElement::ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd) { - if (arValues.size() < 2) + if (itEnd - itBegin < 2) return nullptr; CLineElement *pElement = new CLineElement(); @@ -277,7 +279,7 @@ IPathElement* CLineElement::ReadFromArray(std::vector& arValues) if (nullptr == pElement) return nullptr; - if (StringToDouble(arValues[0], pElement->m_dX) && StringToDouble(arValues[1], pElement->m_dY)) + if (StringToDouble(*itBegin++, pElement->m_dX) && StringToDouble(*itBegin++, pElement->m_dY)) return pElement; delete pElement; @@ -293,9 +295,9 @@ void CLineElement::Draw(IRenderer* pRenderer) const CBezierCurve2Element::CBezierCurve2Element() {} -IPathElement* CBezierCurve2Element::ReadFromArray(std::vector& arValues) +IPathElement* CBezierCurve2Element::ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd) { - if (arValues.size() < 4) + if (itEnd - itBegin < 4) return nullptr; CBezierCurve2Element *pElement = new CBezierCurve2Element(); @@ -303,8 +305,8 @@ IPathElement* CBezierCurve2Element::ReadFromArray(std::vector& arVa if (nullptr == pElement) return nullptr; - if (StringToDouble(arValues[0], pElement->m_dX1) && StringToDouble(arValues[1], pElement->m_dY1) && - StringToDouble(arValues[2], pElement->m_dX2) && StringToDouble(arValues[3], pElement->m_dY2)) + if (StringToDouble(*itBegin++, pElement->m_dX1) && StringToDouble(*itBegin++, pElement->m_dY1) && + StringToDouble(*itBegin++, pElement->m_dX2) && StringToDouble(*itBegin++, pElement->m_dY2)) return pElement; delete pElement; @@ -313,16 +315,20 @@ IPathElement* CBezierCurve2Element::ReadFromArray(std::vector& arVa void CBezierCurve2Element::Draw(IRenderer* pRenderer) const { - // if (nullptr != pRenderer) - // pRenderer->PathCommandCurveTo() + if (nullptr == pRenderer) + return; + + double dX = 0, dY = 0; + pRenderer->PathCommandGetCurrentPoint(&dX, &dY); + pRenderer->PathCommandCurveTo(dX, dY, m_dX1, m_dY1, m_dX2, m_dY2); } CBezierCurveElement::CBezierCurveElement() {} -IPathElement* CBezierCurveElement::ReadFromArray(std::vector& arValues) +IPathElement* CBezierCurveElement::ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd) { - if (arValues.size() < 4) + if (itEnd - itBegin < 6) return nullptr; CBezierCurveElement *pElement = new CBezierCurveElement(); @@ -330,8 +336,9 @@ IPathElement* CBezierCurveElement::ReadFromArray(std::vector& arVal if (nullptr == pElement) return nullptr; - if (StringToDouble(arValues[0], pElement->m_dX1) && StringToDouble(arValues[1], pElement->m_dY1) && - StringToDouble(arValues[2], pElement->m_dX2) && StringToDouble(arValues[3], pElement->m_dY2)) + if (StringToDouble(*itBegin++, pElement->m_dX1) && StringToDouble(*itBegin++, pElement->m_dY1) && + StringToDouble(*itBegin++, pElement->m_dX2) && StringToDouble(*itBegin++, pElement->m_dY2) && + StringToDouble(*itBegin++, pElement->m_dX3) && StringToDouble(*itBegin++, pElement->m_dY3)) return pElement; delete pElement; @@ -347,9 +354,10 @@ void CBezierCurveElement::Draw(IRenderer* pRenderer) const CArcElement::CArcElement() {} -IPathElement* CArcElement::ReadFromArray(std::vector& arValues) +IPathElement* CArcElement::ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd) { - if (arValues.size() < 7) + + if (itEnd - itBegin < 7) return nullptr; CArcElement *pElement = new CArcElement(); @@ -357,10 +365,10 @@ IPathElement* CArcElement::ReadFromArray(std::vector& arValues) if (nullptr == pElement) return nullptr; - if (StringToDouble(arValues[0], pElement->m_dRadiusX) && StringToDouble(arValues[1], pElement->m_dRadiusY) && - StringToDouble(arValues[2], pElement->m_dAngle) && StringToBoolean(arValues[3], pElement->m_bLarge) && - StringToBoolean(arValues[4], pElement->m_bSweep) && StringToDouble(arValues[5], pElement->m_dX) && - StringToDouble(arValues[6], pElement->m_dY)) + if (StringToDouble (*itBegin++, pElement->m_dRadiusX) && StringToDouble (*itBegin++, pElement->m_dRadiusY) && + StringToDouble (*itBegin++, pElement->m_dAngle) && StringToBoolean(*itBegin++, pElement->m_bLarge) && + StringToBoolean(*itBegin++, pElement->m_bSweep) && StringToDouble (*itBegin++, pElement->m_dX) && + StringToDouble (*itBegin++, pElement->m_dY)) return pElement; delete pElement; @@ -376,11 +384,6 @@ void CArcElement::Draw(IRenderer* pRenderer) const CCloseElement::CCloseElement() {} -IPathElement* CCloseElement::ReadFromArray(std::vector& arValues) -{ - return new CCloseElement(); -} - void CCloseElement::Draw(IRenderer* pRenderer) const { if (nullptr != pRenderer) diff --git a/OFDFile/src/Content/PathObject.h b/OFDFile/src/Content/PathObject.h index a4db6ff409..4a11d9fea7 100644 --- a/OFDFile/src/Content/PathObject.h +++ b/OFDFile/src/Content/PathObject.h @@ -24,7 +24,7 @@ class CStartElement : public IPathElement double m_dY; public: CStartElement(); - static IPathElement* ReadFromArray(std::vector& arValues); + static IPathElement* ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd); void Draw(IRenderer* pRenderer) const override; }; @@ -34,7 +34,7 @@ class CMoveElement : public IPathElement double m_dY; public: CMoveElement(); - static IPathElement* ReadFromArray(std::vector& arValues); + static IPathElement* ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd); void Draw(IRenderer* pRenderer) const override; }; @@ -44,7 +44,7 @@ class CLineElement : public IPathElement double m_dY; public: CLineElement(); - static IPathElement* ReadFromArray(std::vector& arValues); + static IPathElement* ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd); void Draw(IRenderer* pRenderer) const override; }; @@ -56,7 +56,7 @@ class CBezierCurve2Element : public IPathElement double m_dY2; public: CBezierCurve2Element(); - static IPathElement* ReadFromArray(std::vector& arValues); + static IPathElement* ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd); void Draw(IRenderer* pRenderer) const override; }; @@ -70,7 +70,7 @@ class CBezierCurveElement : public IPathElement double m_dY3; public: CBezierCurveElement(); - static IPathElement* ReadFromArray(std::vector& arValues); + static IPathElement* ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd); void Draw(IRenderer* pRenderer) const override; }; @@ -85,7 +85,7 @@ class CArcElement : public IPathElement double m_dY; public: CArcElement(); - static IPathElement* ReadFromArray(std::vector& arValues); + static IPathElement* ReadFromArray(std::vector::const_iterator& itBegin, const std::vector::const_iterator& itEnd); void Draw(IRenderer* pRenderer) const override; }; @@ -93,7 +93,6 @@ class CCloseElement : public IPathElement { public: CCloseElement(); - static IPathElement* ReadFromArray(std::vector& arValues); void Draw(IRenderer* pRenderer) const override; }; diff --git a/OFDFile/src/Content/TextObject.cpp b/OFDFile/src/Content/TextObject.cpp index e98434ddd6..81397a5fbf 100644 --- a/OFDFile/src/Content/TextObject.cpp +++ b/OFDFile/src/Content/TextObject.cpp @@ -63,7 +63,7 @@ void CTextCode::Draw(IRenderer* pRenderer, unsigned int& unIndex, const std::vec if (nullptr == pRenderer || m_wsText.empty()) return; - double dX = m_dX, dDelta = 0; + double dX = m_dX, dY = m_dY, dDeltaX = 0, dDeltaY = 0; bool bDrawed = false; for (unsigned int unGlyphIndex = 0; unGlyphIndex < m_wsText.length(); ++unGlyphIndex) @@ -72,7 +72,7 @@ void CTextCode::Draw(IRenderer* pRenderer, unsigned int& unIndex, const std::vec { for (const TCGTransform& oCGTransform : arCGTransforms) { - if (oCGTransform.Draw(pRenderer, unIndex, dX, m_dY)) + if (oCGTransform.Draw(pRenderer, unIndex, dX, dY)) { bDrawed = true; break; @@ -82,20 +82,24 @@ void CTextCode::Draw(IRenderer* pRenderer, unsigned int& unIndex, const std::vec if (!bDrawed) { - pRenderer->CommandDrawTextCHAR(m_wsText[unGlyphIndex], dX, m_dY, 0, 0); + pRenderer->CommandDrawTextCHAR(m_wsText[unGlyphIndex], dX, dY, 0, 0); ++unIndex; } if (unGlyphIndex < m_arDeltaX.size()) - dDelta = m_arDeltaX[unGlyphIndex]; + dDeltaX = m_arDeltaX[unGlyphIndex]; - dX += dDelta; + if (unGlyphIndex < m_arDeltaY.size()) + dDeltaY = m_arDeltaY[unGlyphIndex]; + + dX += dDeltaX; + dY += dDeltaY; } } CTextObject::CTextObject(CXmlReader& oLiteReader) : IPageBlock(oLiteReader), CGraphicUnit(oLiteReader), - m_bStroke(false), m_bFill(false), m_dHScale(1.), + m_bStroke(false), m_bFill(true), m_dHScale(1.), m_unReadDirection(0), m_unCharDirection(0), m_unWeight(400), m_bItalic(false), m_pFillColor(nullptr), m_pStrokeColor(nullptr), m_unFontID(0) @@ -179,7 +183,8 @@ void CTextObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) con if (nullptr == pRenderer || m_arTextCodes.empty()) return; - CGraphicUnit::Apply(pRenderer); + TMatrix oOldTransform; + CGraphicUnit::Apply(pRenderer, oOldTransform); const CFont* pFont = oCommonData.GetPublicRes()->GetFont(m_unFontID); @@ -210,6 +215,8 @@ void CTextObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) con for (const CTextCode* pTextCode : m_arTextCodes) pTextCode->Draw(pRenderer, unGlyphsIndex, m_arCGTransforms); + + pRenderer->SetTransform(oOldTransform.m_dM11, oOldTransform.m_dM12, oOldTransform.m_dM21, oOldTransform.m_dM22, oOldTransform.m_dDx, oOldTransform.m_dDy); } TCGTransform TCGTransform::Read(CXmlReader& oLiteReader) diff --git a/OFDFile/src/OFDFile_Private.cpp b/OFDFile/src/OFDFile_Private.cpp index 63c7048dfc..5879594064 100644 --- a/OFDFile/src/OFDFile_Private.cpp +++ b/OFDFile/src/OFDFile_Private.cpp @@ -1,6 +1,7 @@ #include "OFDFile_Private.h" #include "../../OfficeUtils/src/OfficeUtils.h" +#include "Utils/Utils.h" COFDFile_Private::COFDFile_Private(NSFonts::IApplicationFonts* pFonts) : m_pAppFonts(pFonts), m_pTempFolder(nullptr) @@ -9,11 +10,11 @@ COFDFile_Private::COFDFile_Private(NSFonts::IApplicationFonts* pFonts) return; // Создаем менеджер шрифтов с собственным кэшем - m_pFontManager = m_pAppFonts->GenerateFontManager(); - NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); - pMeasurerCache->SetStreams(m_pAppFonts->GetStreams()); - m_pFontManager->SetOwnerCache(pMeasurerCache); - pMeasurerCache->SetCacheSize(16); + // m_pFontManager = m_pAppFonts->GenerateFontManager(); + // NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); + // pMeasurerCache->SetStreams(m_pAppFonts->GetStreams()); + // m_pFontManager->SetOwnerCache(pMeasurerCache); + // pMeasurerCache->SetCacheSize(16); } COFDFile_Private::~COFDFile_Private() @@ -23,7 +24,7 @@ COFDFile_Private::~COFDFile_Private() if (nullptr != m_pTempFolder) delete m_pTempFolder; - RELEASEINTERFACE(m_pFontManager); + // RELEASEINTERFACE(m_pFontManager); } void COFDFile_Private::Close() @@ -110,6 +111,33 @@ void COFDFile_Private::DrawPage(IRenderer* pRenderer, int nPageIndex) m_oBase.DrawPage(pRenderer, nPageIndex); } +void COFDFile_Private::DrawPage(IRenderer* pRenderer, int nPageIndex, const double& dX, const double& dY, const double& dWidth, const double& dHeight) +{ + if (nullptr == pRenderer) + return; + + double dPageWidth = 0., dPageHeight = 0.; + + GetPageSize(nPageIndex, dPageWidth, dPageHeight); + + if (OFD::IsZeroValue(dPageWidth) || OFD::IsZeroValue(dPageHeight)) + return; + + double dM11, dM12, dM21, dM22, dDx, dDy; + pRenderer->GetTransform(&dM11, &dM12, &dM21, &dM22, &dDx, &dDy); + + Aggplus::CMatrix oTransform(dM11, dM12, dM21, dM22, dDx, dDy); + + oTransform.Scale(dWidth / dPageWidth, dHeight / dPageHeight); + oTransform.Translate(dX, dY); + + pRenderer->SetTransform(oTransform.sx(), oTransform.shy(), oTransform.shx(), oTransform.sy(), oTransform.tx(), oTransform.ty()); + + m_oBase.DrawPage(pRenderer, nPageIndex); + + pRenderer->SetTransform(dM11, dM12, dM21, dM22, dDx, dDy); +} + NSFonts::IApplicationFonts* COFDFile_Private::GetFonts() { return m_pAppFonts; diff --git a/OFDFile/src/OFDFile_Private.h b/OFDFile/src/OFDFile_Private.h index d9b46ce4f4..1f7d0a79fc 100644 --- a/OFDFile/src/OFDFile_Private.h +++ b/OFDFile/src/OFDFile_Private.h @@ -33,6 +33,7 @@ public: void GetPageSize(int nPageIndex, double& dWidth, double& dHeight) const; void DrawPage(IRenderer* pRenderer, int nPageIndex); + void DrawPage(IRenderer* pRenderer, int nPageIndex, const double& dX, const double& dY, const double& dWidth, const double& dHeight); NSFonts::IApplicationFonts* GetFonts(); }; diff --git a/OFDFile/src/Types/Color.cpp b/OFDFile/src/Types/Color.cpp index d2e2c645cf..4eaf1c7f9a 100644 --- a/OFDFile/src/Types/Color.cpp +++ b/OFDFile/src/Types/Color.cpp @@ -39,10 +39,12 @@ int CColor::ToInt(const CRes* pPublicRes) const const CColorSpace* pColorSpace = pPublicRes->GetColorSpace(m_unColodSpaceID); - if (nullptr == pColorSpace) - return 0; + CColorSpace::EType eColoSpaceType{CColorSpace::EType::RGB}; - switch(pColorSpace->GetType()) + if (nullptr != pColorSpace) + eColoSpaceType = pColorSpace->GetType(); + + switch(eColoSpaceType) { case CColorSpace::EType::GRAY: return (255 << 24) | (m_oValues[0] << 16) | (m_oValues[0] << 8) | (m_oValues[0] << 0); diff --git a/OFDFile/src/Types/CommonData.h b/OFDFile/src/Types/CommonData.h index ebecdedf78..c7b88f4320 100644 --- a/OFDFile/src/Types/CommonData.h +++ b/OFDFile/src/Types/CommonData.h @@ -5,8 +5,6 @@ #include "PageArea.h" #include "TemplatePage.h" -#include "../../../DesktopEditor/graphics/pro/Fonts.h" - namespace OFD { class CCommonData diff --git a/OFDFile/src/Types/Signature.cpp b/OFDFile/src/Types/Signature.cpp new file mode 100644 index 0000000000..59573aeda8 --- /dev/null +++ b/OFDFile/src/Types/Signature.cpp @@ -0,0 +1,186 @@ +#include "Signature.h" + +#include "../Utils/Utils.h" + +#include "../OFDFile_Private.h" + +namespace OFD +{ +CSignature::CSignature() +{} + +CSignature* CSignature::Read(const std::wstring& wsFilePath, const std::wstring& wsRootPath) +{ + if (wsFilePath.empty()) + return nullptr; + + CXmlReader oLiteReader; + if (!oLiteReader.FromFile(CombinePaths(wsRootPath, wsFilePath)) || !oLiteReader.ReadNextNode() || L"ofd:Signature" != oLiteReader.GetName() || oLiteReader.IsEmptyNode()) + return nullptr; + + CSignature *pSignature = new CSignature(); + + pSignature->m_wsRootPath = wsRootPath; + + const int nDepth = oLiteReader.GetDepth(); + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + if ("ofd:SignedInfo" == oLiteReader.GetNameA()) + pSignature->m_oSignedInfo.Read(oLiteReader); + else if ("ofd:SignedValue" == oLiteReader.GetNameA()) + pSignature->m_wsSignedValue = CombinePaths(wsRootPath, oLiteReader.GetText2()); + } + + return pSignature; +} + +bool CSignature::Draw(IRenderer* pRenderer, unsigned int unPageIndex, NSFonts::IApplicationFonts* pFonts) const +{ + if (nullptr == pRenderer || m_wsSignedValue.empty() || + m_oSignedInfo.m_oStampAnnot.m_unPageRef - 1 != unPageIndex || + m_oSignedInfo.m_oStampAnnot.m_oBoundary.Empty()) + return false; + + COFDFile_Private oFile(pFonts); + oFile.SetTempDir(m_wsRootPath); + + oFile.LoadFromFile(m_wsSignedValue); + + oFile.DrawPage(pRenderer, 0, + m_oSignedInfo.m_oStampAnnot.m_oBoundary.m_dX, + m_oSignedInfo.m_oStampAnnot.m_oBoundary.m_dY, + m_oSignedInfo.m_oStampAnnot.m_oBoundary.m_dWidth, + m_oSignedInfo.m_oStampAnnot.m_oBoundary.m_dHeight); + + return false; +} + +void TProvider::Read(CXmlReader& oLiteReader) +{ + if (0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) + return; + + std::string sAttributeName; + + do + { + sAttributeName = oLiteReader.GetNameA(); + + if ("ProviderName" == sAttributeName) + m_wsProviderName = oLiteReader.GetText(); + else if ("Version" == sAttributeName) + m_wsVersion = oLiteReader.GetText(); + else if ("Company" == sAttributeName) + m_wsCompany = oLiteReader.GetText(); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); +} + +TReference* TReference::Read(CXmlReader& oLiteReader) +{ + if ("ofd:Reference" != oLiteReader.GetNameA() || oLiteReader.IsEmptyElement() || 0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) + return nullptr; + + TReference* pElement = new TReference(); + + do + { + if ("FileRef" == oLiteReader.GetNameA()) + pElement->m_wsFileRef = oLiteReader.GetText(); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); + + const int nDepth = oLiteReader.GetDepth(); + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + if ("ofd:CheckValue" == oLiteReader.GetNameA()) + { + pElement->m_wsCheckValue = oLiteReader.GetText2(); + break; + } + } + + return pElement; +} + +TReferences::~TReferences() +{ + ClearContainer(m_arValues); +} + +void TReferences::Read(CXmlReader& oLiteReader) +{ + if (oLiteReader.IsEmptyElement() || 0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) + return; + + do + { + if ("CheckMethod" == oLiteReader.GetNameA()) + m_wsCheckMethod = oLiteReader.GetText(); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); + + const int nDepth = oLiteReader.GetDepth(); + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + AddToContainer(TReference::Read(oLiteReader), m_arValues); +} + +TStampAnnot::TStampAnnot() + : m_unID(0), m_unPageRef(0) +{} + +void TStampAnnot::Read(CXmlReader& oLiteReader) +{ + if (0 == oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) + return; + + std::string sAttributeName; + + do + { + sAttributeName = oLiteReader.GetNameA(); + + if ("ID" == sAttributeName) + m_unID = oLiteReader.GetUInteger(true); + else if ("PageRef" == sAttributeName) + m_unPageRef = oLiteReader.GetUInteger(true); + else if ("Boundary" == sAttributeName) + m_oBoundary.Read(oLiteReader.GetTextA()); + } while (oLiteReader.MoveToNextAttribute()); + + oLiteReader.MoveToElement(); +} + +void TSignedInfo::Read(CXmlReader& oLiteReader) +{ + if (oLiteReader.IsEmptyNode()) + return; + + const int nDepth = oLiteReader.GetDepth(); + + std::string sNodeName; + + while (oLiteReader.ReadNextSiblingNode(nDepth)) + { + sNodeName = oLiteReader.GetNameA(); + + if ("ofd:Provider" == sNodeName) + m_oProvider.Read(oLiteReader); + else if ("ofd:SignatureMethod" == sNodeName) + m_wsSignatureMethod = oLiteReader.GetText2(); + else if ("ofd:SignatureDateTime" == sNodeName) + m_wsSignatureDateTime = oLiteReader.GetText2(); + else if ("ofd:References" == sNodeName) + m_oReferences.Read(oLiteReader); + else if ("ofd:StampAnnot" == sNodeName) + m_oStampAnnot.Read(oLiteReader); + } +} + +} diff --git a/OFDFile/src/Types/Signature.h b/OFDFile/src/Types/Signature.h new file mode 100644 index 0000000000..439d1e70c1 --- /dev/null +++ b/OFDFile/src/Types/Signature.h @@ -0,0 +1,75 @@ +#ifndef SIGNATURE_H +#define SIGNATURE_H + +#include "../../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../../DesktopEditor/graphics/IRenderer.h" +#include "../Utils/XmlReader.h" +#include "../Utils/Types.h" + +namespace OFD +{ +struct TProvider +{ + std::wstring m_wsProviderName; + std::wstring m_wsVersion; + std::wstring m_wsCompany; + + void Read(CXmlReader& oLiteReader); +}; + +struct TReference +{ + std::wstring m_wsFileRef; + std::wstring m_wsCheckValue; + + static TReference* Read(CXmlReader& oLiteReader); +}; + +struct TReferences +{ + std::wstring m_wsCheckMethod; + std::vector m_arValues; + + ~TReferences(); + + void Read(CXmlReader& oLiteReader); +}; + +struct TStampAnnot +{ + unsigned int m_unID; + unsigned int m_unPageRef; + TBox m_oBoundary; + + TStampAnnot(); + + void Read(CXmlReader& oLiteReader); +}; + +struct TSignedInfo +{ + TProvider m_oProvider; + std::wstring m_wsSignatureMethod; + std::wstring m_wsSignatureDateTime; + TReferences m_oReferences; + TStampAnnot m_oStampAnnot; + + void Read(CXmlReader& oLiteReader); +}; + +class CSignature +{ + TSignedInfo m_oSignedInfo; + std::wstring m_wsSignedValue; + + std::wstring m_wsRootPath; +public: + CSignature(); + + static CSignature* Read(const std::wstring& wsFilePath, const std::wstring& wsRootPath); + + bool Draw(IRenderer* pRenderer, unsigned int unPageIndex, NSFonts::IApplicationFonts* pFonts) const; +}; +} + +#endif // SIGNATURE_H diff --git a/OFDFile/src/Types/TemplatePage.h b/OFDFile/src/Types/TemplatePage.h index 9d7e3ff796..6b3d679614 100644 --- a/OFDFile/src/Types/TemplatePage.h +++ b/OFDFile/src/Types/TemplatePage.h @@ -2,7 +2,6 @@ #define TEMPLATEPAGE_H #include "../IOFDElement.h" -#include "../../../DesktopEditor/graphics/pro/Fonts.h" namespace OFD { diff --git a/OFDFile/src/Utils/Utils.h b/OFDFile/src/Utils/Utils.h index c210d01992..52e6070364 100644 --- a/OFDFile/src/Utils/Utils.h +++ b/OFDFile/src/Utils/Utils.h @@ -103,6 +103,16 @@ inline void AddToContainer(T* pValue, std::vector& arValues) arValues.push_back(pValue); } +template +inline void ClearContainer(std::vector& arValues) +{ + for (T* pElement : arValues) + if (nullptr != pElement) + delete pElement; + + arValues.clear(); +} + inline std::wstring CombinePaths(const std::wstring& wsFirstPath, const std::wstring& wsSecondPath) { if (wsFirstPath.empty()) @@ -128,5 +138,10 @@ inline std::wstring CombinePaths(const std::wstring& wsFirstPath, const std::wst return NSSystemPath::Combine(wsFirstPath, wsNewSecondPath); } + +inline bool IsZeroValue(const double& dValue) +{ + return DBL_EPSILON > std::abs(dValue); +} } #endif // UTILS_H From 9fe692b0488e89f23b8f6e7f9f34bcecc6232fc8 Mon Sep 17 00:00:00 2001 From: Green Date: Sat, 19 Apr 2025 16:57:31 +0300 Subject: [PATCH 09/15] Refactoring --- OFDFile/src/Base.cpp | 2 +- OFDFile/src/Content/GraphicUnit.cpp | 30 +++++++++++++++++------------ OFDFile/src/OFDFile_Private.cpp | 22 +++++++++------------ 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/OFDFile/src/Base.cpp b/OFDFile/src/Base.cpp index 74d33aebe7..88f0298c99 100644 --- a/OFDFile/src/Base.cpp +++ b/OFDFile/src/Base.cpp @@ -186,7 +186,7 @@ bool CBase::Read(IFolder* pFolder) m_arDocBodies.push_back(pDocBody); } - return false; + return !m_arDocBodies.empty(); } void CBase::DrawPage(IRenderer* pRenderer, int nPageIndex) const diff --git a/OFDFile/src/Content/GraphicUnit.cpp b/OFDFile/src/Content/GraphicUnit.cpp index 6285c0afbd..8a5c6ee85a 100644 --- a/OFDFile/src/Content/GraphicUnit.cpp +++ b/OFDFile/src/Content/GraphicUnit.cpp @@ -75,21 +75,27 @@ void CGraphicUnit::Apply(IRenderer* pRenderer, TMatrix& oOldTransform) const oTransform.Multiply(&oCurrentTransform); // Clipping - // pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionIntersect); + pRenderer->put_ClipMode(c_nClipRegionTypeWinding | c_nClipRegionIntersect); - // pRenderer->BeginCommand(c_nClipType); - // pRenderer->BeginCommand(c_nPathType); - // pRenderer->PathCommandStart(); + pRenderer->BeginCommand(c_nResetClipType); + pRenderer->EndCommand(c_nResetClipType); - // pRenderer->PathCommandMoveTo(m_oBoundary.m_dX, m_oBoundary.m_dY); - // pRenderer->PathCommandLineTo(m_oBoundary.m_dX + m_oBoundary.m_dWidth, m_oBoundary.m_dY); - // pRenderer->PathCommandLineTo(m_oBoundary.m_dX + m_oBoundary.m_dWidth, m_oBoundary.m_dY + m_oBoundary.m_dHeight); - // pRenderer->PathCommandLineTo(m_oBoundary.m_dX, m_oBoundary.m_dY + m_oBoundary.m_dHeight); - // pRenderer->PathCommandLineTo(m_oBoundary.m_dX, m_oBoundary.m_dY); + if (!m_oBoundary.Empty()) + { + pRenderer->BeginCommand(c_nClipType); + pRenderer->BeginCommand(c_nPathType); + pRenderer->PathCommandStart(); - // pRenderer->EndCommand(c_nPathType); - // pRenderer->EndCommand(c_nClipType); - // pRenderer->PathCommandEnd(); + pRenderer->PathCommandMoveTo(m_oBoundary.m_dX, m_oBoundary.m_dY); + pRenderer->PathCommandLineTo(m_oBoundary.m_dX + m_oBoundary.m_dWidth, m_oBoundary.m_dY); + pRenderer->PathCommandLineTo(m_oBoundary.m_dX + m_oBoundary.m_dWidth, m_oBoundary.m_dY + m_oBoundary.m_dHeight); + pRenderer->PathCommandLineTo(m_oBoundary.m_dX, m_oBoundary.m_dY + m_oBoundary.m_dHeight); + pRenderer->PathCommandLineTo(m_oBoundary.m_dX, m_oBoundary.m_dY); + + pRenderer->EndCommand(c_nPathType); + pRenderer->EndCommand(c_nClipType); + pRenderer->PathCommandEnd(); + } pRenderer->SetTransform(oTransform.sx(), oTransform.shy(), oTransform.shx(), oTransform.sy(), oTransform.tx(), oTransform.ty()); } diff --git a/OFDFile/src/OFDFile_Private.cpp b/OFDFile/src/OFDFile_Private.cpp index 5879594064..0e1a66bb6b 100644 --- a/OFDFile/src/OFDFile_Private.cpp +++ b/OFDFile/src/OFDFile_Private.cpp @@ -4,17 +4,17 @@ #include "Utils/Utils.h" COFDFile_Private::COFDFile_Private(NSFonts::IApplicationFonts* pFonts) - : m_pAppFonts(pFonts), m_pTempFolder(nullptr) + : m_pAppFonts(pFonts), m_pFontManager(nullptr), m_pTempFolder(nullptr) { if (nullptr == pFonts) return; // Создаем менеджер шрифтов с собственным кэшем - // m_pFontManager = m_pAppFonts->GenerateFontManager(); - // NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); - // pMeasurerCache->SetStreams(m_pAppFonts->GetStreams()); - // m_pFontManager->SetOwnerCache(pMeasurerCache); - // pMeasurerCache->SetCacheSize(16); + m_pFontManager = pFonts->GenerateFontManager(); + NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); + pMeasurerCache->SetStreams(pFonts->GetStreams()); + m_pFontManager->SetOwnerCache(pMeasurerCache); + pMeasurerCache->SetCacheSize(16); } COFDFile_Private::~COFDFile_Private() @@ -24,12 +24,11 @@ COFDFile_Private::~COFDFile_Private() if (nullptr != m_pTempFolder) delete m_pTempFolder; - // RELEASEINTERFACE(m_pFontManager); + RELEASEINTERFACE(m_pFontManager); } void COFDFile_Private::Close() -{ -} +{} void COFDFile_Private::SetTempDir(const std::wstring& wsPath) { @@ -63,10 +62,7 @@ bool COFDFile_Private::Read(IFolder* pFolder) if (nullptr == pFolder) return false; - if (!m_oBase.Read(pFolder)) - return false; - - return false; + return m_oBase.Read(pFolder); } bool COFDFile_Private::LoadFromFile(const std::wstring& wsFilePath) From c3527ad8d41816365b774ad972c4213a0595b570 Mon Sep 17 00:00:00 2001 From: Green Date: Sat, 19 Apr 2025 17:24:14 +0300 Subject: [PATCH 10/15] Added OFD format to OfficeChecker --- Common/OfficeFileFormatChecker.h | 1 + Common/OfficeFileFormatChecker2.cpp | 34 ++++++++++++++++++++++++++ Common/OfficeFileFormats.h | 1 + X2tConverter/build/Qt/X2tConverter.pri | 3 ++- X2tConverter/src/lib/pdf_image.h | 6 +++++ 5 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Common/OfficeFileFormatChecker.h b/Common/OfficeFileFormatChecker.h index 83cc47271a..29fcb2c520 100644 --- a/Common/OfficeFileFormatChecker.h +++ b/Common/OfficeFileFormatChecker.h @@ -108,4 +108,5 @@ public: bool isMobiFormatFile(unsigned char* pBuffer, int dwBytes); bool isFB2FormatFile(unsigned char* pBuffer, int dwBytes); bool isXpsFile(const std::wstring& fileName); + bool isOFDFile(const std::wstring& fileName); }; diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index e1ea7b2d88..16b8c544e5 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -786,6 +786,13 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) bufferDetect = NULL; return true; } + else if (isOFDFile(fileName)) + { + if (bufferDetect) + delete[] bufferDetect; + bufferDetect = NULL; + return true; + } else if (isMacFormatFile(fileName)) { if (bufferDetect) @@ -1527,6 +1534,8 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type) return L".djvu"; case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS: return L".xps"; + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_OFD: + return L".ofd"; case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_SVG: return L".svg"; case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_HTMLR: @@ -1701,6 +1710,8 @@ int COfficeFileFormatChecker::GetFormatByExtension(const std::wstring &sExt) return AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU; if (L".xps" == ext || L".oxps" == ext) return AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS; + if (L"ofd" == ext) + return AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_OFD; if (L".jpg" == ext || L".jpeg" == ext || L".jpe" == ext || L".jfif" == ext) return AVS_OFFICESTUDIO_FILE_IMAGE_JPG; @@ -1837,3 +1848,26 @@ bool COfficeFileFormatChecker::isXpsFile(const std::wstring &fileName) } return false; } + +bool COfficeFileFormatChecker::isOFDFile(const std::wstring& fileName) +{ + COfficeUtils OfficeUtils(NULL); + + ULONG nBufferSize = 0; + BYTE *pBuffer = NULL; + + HRESULT hresult = OfficeUtils.LoadFileFromArchive(fileName, L"OFD.xml", &pBuffer, nBufferSize); + if (hresult == S_OK && pBuffer != NULL) + { + if (19 <= nBufferSize && NULL != strstr((char *)pBuffer, "ofd:OFD")) + nFileType = AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_OFD; + + delete[] pBuffer; + pBuffer = NULL; + + if (nFileType != AVS_OFFICESTUDIO_FILE_UNKNOWN) + return true; + } + + return false; +} diff --git a/Common/OfficeFileFormats.h b/Common/OfficeFileFormats.h index fb7d280ac3..6612113c6a 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -103,6 +103,7 @@ #define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_HTMLRMenu AVS_OFFICESTUDIO_FILE_CROSSPLATFORM + 0x0007 #define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_HTMLRCanvas AVS_OFFICESTUDIO_FILE_CROSSPLATFORM + 0x0008 #define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDFA AVS_OFFICESTUDIO_FILE_CROSSPLATFORM + 0x0009 +#define AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_OFD AVS_OFFICESTUDIO_FILE_CROSSPLATFORM + 0x000a #define AVS_OFFICESTUDIO_FILE_IMAGE 0x0400 #define AVS_OFFICESTUDIO_FILE_IMAGE_JPG AVS_OFFICESTUDIO_FILE_IMAGE + 0x0001 diff --git a/X2tConverter/build/Qt/X2tConverter.pri b/X2tConverter/build/Qt/X2tConverter.pri index 685961ee4a..0cdc5af511 100644 --- a/X2tConverter/build/Qt/X2tConverter.pri +++ b/X2tConverter/build/Qt/X2tConverter.pri @@ -32,6 +32,7 @@ DEFINES += UNICODE \ DEFINES += PDFFILE_USE_DYNAMIC_LIBRARY DEFINES += XPS_USE_DYNAMIC_LIBRARY +DEFINES += OFD_USE_DYNAMIC_LIBRARY DEFINES += DJVU_USE_DYNAMIC_LIBRARY DEFINES += HTMLFILE_USE_DYNAMIC_LIBRARY DEFINES += UNICODECONVERTER_USE_DYNAMIC_LIBRARY @@ -130,7 +131,7 @@ LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib #All dynamic libs -ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network, Fb2File, PdfFile, HtmlFile2, EpubFile, XpsFile, DjVuFile, doctrenderer, DocxRenderer, IWorkFile, HWPFile) +ADD_DEPENDENCY(graphics, kernel, UnicodeConverter, kernel_network, Fb2File, PdfFile, HtmlFile2, EpubFile, XpsFile, OFDFile, DjVuFile, doctrenderer, DocxRenderer, IWorkFile, HWPFile) ##################################################### # внешнее подключение сторонних библиотек diff --git a/X2tConverter/src/lib/pdf_image.h b/X2tConverter/src/lib/pdf_image.h index 569ea9fc73..8d2d776ae5 100644 --- a/X2tConverter/src/lib/pdf_image.h +++ b/X2tConverter/src/lib/pdf_image.h @@ -38,6 +38,7 @@ #include "../../../DocxRenderer/DocxRenderer.h" #include "../../../PdfFile/PdfFile.h" #include "../../../XpsFile/XpsFile.h" +#include "../../../OFDFile/OFDFile.h" #include "../../../OfficeUtils/src/ZipFolder.h" #include "common.h" @@ -416,6 +417,8 @@ namespace NExtractTools return new CXpsFile(pFonts); case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU: return new CDjVuFile(pFonts); + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_OFD: + return new COFDFile(pFonts); default: break; } @@ -1027,6 +1030,9 @@ namespace NExtractTools case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_XPS: pReader = new CXpsFile(pApplicationFonts); break; + case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_OFD: + pReader = new COFDFile(pApplicationFonts); + break; case AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_DJVU: pReader = new CDjVuFile(pApplicationFonts); break; From 4125e698d6ae20cc1fcb0c7e45ac4ee7c670bf87 Mon Sep 17 00:00:00 2001 From: Green Date: Sun, 20 Apr 2025 02:33:48 +0300 Subject: [PATCH 11/15] Fix build --- OFDFile/{OfdFile.h => OFDFile.h} | 0 OFDFile/src/Utils/Utils.h | 1 + 2 files changed, 1 insertion(+) rename OFDFile/{OfdFile.h => OFDFile.h} (100%) diff --git a/OFDFile/OfdFile.h b/OFDFile/OFDFile.h similarity index 100% rename from OFDFile/OfdFile.h rename to OFDFile/OFDFile.h diff --git a/OFDFile/src/Utils/Utils.h b/OFDFile/src/Utils/Utils.h index 52e6070364..ac277b8598 100644 --- a/OFDFile/src/Utils/Utils.h +++ b/OFDFile/src/Utils/Utils.h @@ -6,6 +6,7 @@ #include #include #include +#include #include "../../../DesktopEditor/common/Path.h" From 5a8bd3f8ce60cd7eebf56239904d12cea2d32f7b Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 21 Apr 2025 17:17:30 +0300 Subject: [PATCH 12/15] DrawTextToRenderer for Unicode --- PdfFile/PdfWriter.cpp | 8 +++++--- PdfFile/PdfWriter.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 69df9405ea..e5ade8761e 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -655,6 +655,8 @@ HRESULT CPdfWriter::CommandDrawTextCHAR(const LONG& lUnicode, const double& dX, unsigned int unUnicode = lUnicode; unsigned char* pCodes = EncodeString(&unUnicode, 1); + if (!pCodes) + return DrawTextToRenderer(NULL, 0, dX, dY, NSStringExt::CConverter::GetUnicodeFromUTF32(&unUnicode, 1)) ? S_OK : S_FALSE; return DrawText(pCodes, 2, dX, dY, UnicodePUA(unUnicode) ? NSStringExt::CConverter::GetUtf8FromUTF32(&unUnicode, 1) : "") ? S_OK : S_FALSE; } HRESULT CPdfWriter::CommandDrawText(const std::wstring& wsUnicodeText, const double& dX, const double& dY, const double& dW, const double& dH) @@ -674,7 +676,7 @@ HRESULT CPdfWriter::CommandDrawText(const std::wstring& wsUnicodeText, const dou delete[] pUnicodes; if (!pCodes) - return S_FALSE; + return DrawTextToRenderer(NULL, 0, dX, dY, wsUnicodeText) ? S_OK : S_FALSE; // Специальный случай для текста из Djvu, нам не нужно, чтобы он рисовался if (L"" == m_oFont.GetPath() && L"DjvuEmptyFont" == m_oFont.GetName()) @@ -3112,14 +3114,14 @@ bool CPdfWriter::DrawText(unsigned char* pCodes, const unsigned int& unLen, cons return true; } -bool CPdfWriter::DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY) +bool CPdfWriter::DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY, const std::wstring& wsUnicodeText) { // TODO pdf позволяет создание своего шрифта, но не следует это использовать для воссоздания шрифта запрещенного для редактирования или встраивания Aggplus::CGraphicsPathSimpleConverter simplifier; simplifier.SetRenderer(m_pRenderer); m_pFontManager->LoadFontByName(m_oFont.GetName(), m_oFont.GetSize(), (int)m_oFont.GetStyle(), 72.0, 72.0); PathCommandEnd(); - if (simplifier.PathCommandText2(L"", (const int*)unGid, unLen, m_pFontManager, dX, dY, 0, 0)) + if (simplifier.PathCommandText2(wsUnicodeText, (const int*)unGid, unLen, m_pFontManager, dX, dY, 0, 0)) { DrawPath(NULL, L"", c_nWindingFillMode); PathCommandEnd(); diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 98f4ba015a..3ca2de790d 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -226,7 +226,7 @@ private: PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, BYTE nAlpha); PdfWriter::CImageDict* DrawImage(Aggplus::CImage* pImage, const double& dX, const double& dY, const double& dW, const double& dH, const BYTE& nAlpha); bool DrawText(unsigned char* pCodes, const unsigned int& unLen, const double& dX, const double& dY, const std::string& sPUA); - bool DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY); + bool DrawTextToRenderer(const unsigned int* unGid, const unsigned int& unLen, const double& dX, const double& dY, const std::wstring& wsUnicodeText = L""); bool PathCommandDrawText(unsigned int* pUnicodes, unsigned int unLen, const double& dX, const double& dY, const unsigned int* pGids = NULL); int IsEmbeddedBase14(const std::wstring& wsFontName); bool GetBaseFont14(const std::wstring& wsFontName, int nBase14); From 91dc5b8582c0ec748b461a0cbfd6392b9f8ed26e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 21 Apr 2025 18:18:18 +0300 Subject: [PATCH 13/15] Fix null EncodeGID --- PdfFile/PdfWriter.cpp | 11 +++++++++++ PdfFile/SrcWriter/FontCidTT.cpp | 9 +++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index e5ade8761e..020f5905b4 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -3719,6 +3719,11 @@ unsigned char* CPdfWriter::EncodeString(const unsigned int *pUnicodes, const uns ushCode = m_pFont->EncodeGID(pGIDs[unIndex], &pUnicodes[unIndex], 1); else ushCode = m_pFont->EncodeUnicode(pUnicodes[unIndex]); + if (ushCode == 0) + { + RELEASEARRAYOBJECTS(pCodes); + return NULL; + } pCodes[2 * unIndex + 0] = (ushCode >> 8) & 0xFF; pCodes[2 * unIndex + 1] = ushCode & 0xFF; @@ -3758,6 +3763,12 @@ unsigned char* CPdfWriter::EncodeGID(const unsigned int& unGID, const unsigned i return NULL; unsigned short ushCode = m_pFont->EncodeGID(unGID, pUnicodes, unUnicodesCount); + if (ushCode == 0) + { + RELEASEARRAYOBJECTS(pCodes); + return NULL; + } + pCodes[0] = (ushCode >> 8) & 0xFF; pCodes[1] = ushCode & 0xFF; return pCodes; diff --git a/PdfFile/SrcWriter/FontCidTT.cpp b/PdfFile/SrcWriter/FontCidTT.cpp index 22411d6cc8..d19a1b962b 100644 --- a/PdfFile/SrcWriter/FontCidTT.cpp +++ b/PdfFile/SrcWriter/FontCidTT.cpp @@ -339,9 +339,12 @@ namespace PdfWriter } memset((void *)pGlyphs, 0x00, m_nGlyphsCount * sizeof(unsigned char)); - for (auto oIt : m_mGlyphs) + if (m_nGlyphsCount >= m_mGlyphs.size()) { - pGlyphs[oIt.first] = 1; + for (auto oIt : m_mGlyphs) + { + pGlyphs[oIt.first] = 1; + } } *ppCodeToGid = pCodeToGID; @@ -539,6 +542,8 @@ namespace PdfWriter { m_vWidths.push_back(0); m_vGlypWidths.push_back(0); + m_vCodeToGid.back() = 0; + return 0; } return ushCode; From ab62a3ebcf72ae1527ae75da467e914273a1d262 Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 22 Apr 2025 11:19:43 +0300 Subject: [PATCH 14/15] Improved work with text when converting OFD format --- OFDFile/src/Content/TextObject.cpp | 25 ++++++++++--------------- OFDFile/src/Content/TextObject.h | 2 +- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/OFDFile/src/Content/TextObject.cpp b/OFDFile/src/Content/TextObject.cpp index 81397a5fbf..1239bedb67 100644 --- a/OFDFile/src/Content/TextObject.cpp +++ b/OFDFile/src/Content/TextObject.cpp @@ -72,7 +72,7 @@ void CTextCode::Draw(IRenderer* pRenderer, unsigned int& unIndex, const std::vec { for (const TCGTransform& oCGTransform : arCGTransforms) { - if (oCGTransform.Draw(pRenderer, unIndex, dX, dY)) + if (oCGTransform.Draw(pRenderer, m_wsText[unGlyphIndex], unIndex, dX, dY)) { bDrawed = true; break; @@ -183,13 +183,15 @@ void CTextObject::Draw(IRenderer* pRenderer, const CCommonData& oCommonData) con if (nullptr == pRenderer || m_arTextCodes.empty()) return; - TMatrix oOldTransform; - CGraphicUnit::Apply(pRenderer, oOldTransform); - const CFont* pFont = oCommonData.GetPublicRes()->GetFont(m_unFontID); - if (nullptr != pFont) - pFont->Apply(pRenderer); + if (nullptr == pFont) + return; + + pFont->Apply(pRenderer); + + TMatrix oOldTransform; + CGraphicUnit::Apply(pRenderer, oOldTransform); if (m_bFill) { @@ -260,23 +262,16 @@ TCGTransform TCGTransform::Read(CXmlReader& oLiteReader) return oCGTransform; } -bool TCGTransform::Draw(IRenderer* pRenderer, unsigned int& unIndex, double dX, double dY) const +bool TCGTransform::Draw(IRenderer* pRenderer, const LONG& lUnicode, unsigned int& unIndex, double dX, double dY) const { if (m_unCodePosition != unIndex || 0 == m_unCodeCount || 0 == m_unGlyphCount) return false; - int nCurrentValue; - pRenderer->get_FontStringGID(&nCurrentValue); - - pRenderer->put_FontStringGID(TRUE); - for (unsigned int unGlyphCount = 0; unGlyphCount < m_unGlyphCount; ++unGlyphCount) - pRenderer->CommandDrawTextCHAR(m_arGlyphs[unGlyphCount], dX, dY, 0, 0); + pRenderer->CommandDrawTextExCHAR(lUnicode, m_arGlyphs[unGlyphCount], dX, dY, 0, 0); unIndex += m_unCodeCount; - pRenderer->put_FontStringGID(nCurrentValue); - return true; } } diff --git a/OFDFile/src/Content/TextObject.h b/OFDFile/src/Content/TextObject.h index f30011c2a1..1b01d57d42 100644 --- a/OFDFile/src/Content/TextObject.h +++ b/OFDFile/src/Content/TextObject.h @@ -18,7 +18,7 @@ struct TCGTransform static TCGTransform Read(CXmlReader& oLiteReader); - bool Draw(IRenderer* pRenderer, unsigned int& unIndex, double dX, double dY) const; + bool Draw(IRenderer* pRenderer, const LONG& lUnicode, unsigned int& unIndex, double dX, double dY) const; }; class CTextCode From c66cb32ddeac8e396986bbff3db9e6516c297e07 Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 22 Apr 2025 13:29:16 +0300 Subject: [PATCH 15/15] Added a restriction on the scope of files in OFD format. --- OFDFile/src/Base.cpp | 18 ++++++++---------- OFDFile/src/Base.h | 3 +-- OFDFile/src/Document.cpp | 12 +++++++----- OFDFile/src/Document.h | 4 ++-- OFDFile/src/Page.cpp | 6 +++--- OFDFile/src/Page.h | 2 +- OFDFile/src/Res.cpp | 14 ++++++++------ OFDFile/src/Res.h | 4 ++-- OFDFile/src/Types/CommonData.cpp | 6 ++---- OFDFile/src/Types/Font.cpp | 6 +++++- OFDFile/src/Types/MultiMedia.cpp | 6 +++++- OFDFile/src/Types/Signature.cpp | 10 +++++----- OFDFile/src/Types/Signature.h | 5 ++++- OFDFile/src/Types/TemplatePage.cpp | 3 +-- OFDFile/src/Utils/Utils.h | 26 ++++++++++++++++++++++++++ 15 files changed, 80 insertions(+), 45 deletions(-) diff --git a/OFDFile/src/Base.cpp b/OFDFile/src/Base.cpp index 88f0298c99..59404d12d4 100644 --- a/OFDFile/src/Base.cpp +++ b/OFDFile/src/Base.cpp @@ -57,10 +57,13 @@ bool CDocInfo::Read(CXmlReader& oLiteReader) return true; } -void CDocBody::ReadSignatures(const std::wstring& wsFilePath, const std::wstring& wsRootPath) +void CDocBody::ReadSignatures(const std::wstring& wsFilePath, IFolder* pFolder) { + if (wsFilePath.empty() || !CanUseThisPath(wsFilePath, pFolder->getFullFilePath(L""))) + return; + CXmlReader oLiteReader; - if (!oLiteReader.FromFile(CombinePaths(wsRootPath, wsFilePath)) || !oLiteReader.ReadNextNode() || L"ofd:Signatures" != oLiteReader.GetName()) + if (!oLiteReader.FromFile(CombinePaths(pFolder->getFullFilePath(L""), wsFilePath)) || !oLiteReader.ReadNextNode() || L"ofd:Signatures" != oLiteReader.GetName()) return; const int nDepth = oLiteReader.GetDepth(); @@ -81,7 +84,7 @@ void CDocBody::ReadSignatures(const std::wstring& wsFilePath, const std::wstring do { if ("BaseLoc" == oLiteReader.GetNameA()) - AddToContainer(CSignature::Read(oLiteReader.GetText(), wsRootPath), m_arSignatures); + AddToContainer(CSignature::Read(oLiteReader.GetText(), pFolder), m_arSignatures); } while (oLiteReader.MoveToNextAttribute()); oLiteReader.MoveToElement(); @@ -123,14 +126,9 @@ CDocBody* CDocBody::Read(CXmlReader& oLiteReader, IFolder* pFolder) } } else if ("ofd:DocRoot" == sNodeName) - { - const std::wstring wsPath = NSSystemPath::ShortenPath(oLiteReader.GetText2()); - - if (!wsPath.empty() && L'.' != wsPath.front()) - pDocBody->m_oDocument.Read(pFolder->getFullFilePath(wsPath)); - } + pDocBody->m_oDocument.Read(oLiteReader.GetText2(), pFolder); else if ("ofd:Signatures" == sNodeName) - pDocBody->ReadSignatures(oLiteReader.GetText2(), pFolder->getFullFilePath(L"")); + pDocBody->ReadSignatures(oLiteReader.GetText2(), pFolder); } return pDocBody; diff --git a/OFDFile/src/Base.h b/OFDFile/src/Base.h index 7f07db7884..a10c281b3b 100644 --- a/OFDFile/src/Base.h +++ b/OFDFile/src/Base.h @@ -45,11 +45,10 @@ class CDocBody { CDocInfo m_oDocInfo; CDocument m_oDocument; - // std::wstring m_wsPathToDocRoot; // std::wstring m_wsVersions; std::vector m_arSignatures; - void ReadSignatures(const std::wstring& wsFilePath, const std::wstring& wsRootPath); + void ReadSignatures(const std::wstring& wsFilePath, IFolder* pFolder); public: CDocBody(); ~CDocBody(); diff --git a/OFDFile/src/Document.cpp b/OFDFile/src/Document.cpp index b9568a7cfc..272bcbce7f 100644 --- a/OFDFile/src/Document.cpp +++ b/OFDFile/src/Document.cpp @@ -44,15 +44,16 @@ bool CDocument::Empty() const return m_mPages.empty(); } -bool CDocument::Read(const std::wstring& wsFilePath) +bool CDocument::Read(const std::wstring& wsFilePath, IFolder* pFolder) { - if (wsFilePath.empty()) + if (wsFilePath.empty() || !CanUseThisPath(wsFilePath, pFolder->getFullFilePath(L""))) return false; CXmlReader oLiteReader; - if (!oLiteReader.FromFile(wsFilePath) || !oLiteReader.ReadNextNode() || L"ofd:Document" != oLiteReader.GetName()) + if (!oLiteReader.FromFile(pFolder->getFullFilePath(wsFilePath)) || !oLiteReader.ReadNextNode() || L"ofd:Document" != oLiteReader.GetName()) return false; + const std::wstring wsCoreDirectory{pFolder->getFullFilePath(NSSystemPath::GetDirectoryName(wsFilePath))}; const int nDepth = oLiteReader.GetDepth(); std::wstring wsNodeName; @@ -61,7 +62,7 @@ bool CDocument::Read(const std::wstring& wsFilePath) wsNodeName = oLiteReader.GetName(); if (L"ofd:CommonData" == wsNodeName) - m_oCommonData.Read(oLiteReader, NSSystemPath::GetDirectoryName(wsFilePath)); + m_oCommonData.Read(oLiteReader, wsCoreDirectory); else if (L"ofd:Pages" == wsNodeName) { const int nPagesDepth = oLiteReader.GetDepth(); @@ -69,6 +70,7 @@ bool CDocument::Read(const std::wstring& wsFilePath) int nID = -1; std::wstring wsBaseLoc; + while (oLiteReader.ReadNextSiblingNode(nPagesDepth)) { if (L"ofd:Page" != oLiteReader.GetName() || 2 > oLiteReader.GetAttributesCount() || !oLiteReader.MoveToFirstAttribute()) @@ -88,7 +90,7 @@ bool CDocument::Read(const std::wstring& wsFilePath) if (-1 == nID) nID = m_mPages.size() + 1; - CPage* pPage = CPage::Read(CombinePaths(NSSystemPath::GetDirectoryName(wsFilePath), wsBaseLoc)); + CPage* pPage = CPage::Read(wsBaseLoc, wsCoreDirectory); if (nullptr != pPage) m_mPages.insert(std::make_pair(m_mPages.size(), pPage)); diff --git a/OFDFile/src/Document.h b/OFDFile/src/Document.h index 50bb0afc95..ee7f265c77 100644 --- a/OFDFile/src/Document.h +++ b/OFDFile/src/Document.h @@ -4,7 +4,7 @@ #include "Page.h" #include "../../DesktopEditor/graphics/IRenderer.h" -#include "../../DesktopEditor/graphics/pro/Fonts.h" +#include "../../OfficeUtils/src/ZipFolder.h" namespace OFD { @@ -34,7 +34,7 @@ public: bool Empty() const; - bool Read(const std::wstring& wsFilePath); + bool Read(const std::wstring& wsFilePath, IFolder* pFolder); bool DrawPage(IRenderer* pRenderer, int nPageIndex) const; diff --git a/OFDFile/src/Page.cpp b/OFDFile/src/Page.cpp index a96be0ac9f..34a47a28c4 100644 --- a/OFDFile/src/Page.cpp +++ b/OFDFile/src/Page.cpp @@ -13,12 +13,12 @@ CPage::CPage() CPage::~CPage() {} -CPage* CPage::Read(const std::wstring& wsFilePath) +CPage* CPage::Read(const std::wstring& wsFilePath, const std::wstring& wsRootPath) { - if (wsFilePath.empty()) + if (wsFilePath.empty() || !CanUseThisPath(wsFilePath, wsRootPath)) return nullptr; - std::wstring wsNormalizedPath = wsFilePath; + std::wstring wsNormalizedPath = CombinePaths(wsRootPath, wsFilePath); if (L"xml" != NSFile::GetFileExtention(wsNormalizedPath)) wsNormalizedPath = CombinePaths(wsNormalizedPath, L"Content.xml"); diff --git a/OFDFile/src/Page.h b/OFDFile/src/Page.h index c8fa772639..09d16e5130 100644 --- a/OFDFile/src/Page.h +++ b/OFDFile/src/Page.h @@ -17,7 +17,7 @@ public: CPage(); ~CPage(); - static CPage* Read(const std::wstring& wsFilePath); + static CPage* Read(const std::wstring& wsFilePath, const std::wstring& wsRootPath); void Draw(IRenderer* pRenderer, const CCommonData& oCommonData) const; void GetPageSize(double& dWidth, double& dHeight) const; diff --git a/OFDFile/src/Res.cpp b/OFDFile/src/Res.cpp index d1d9f39008..6ad11a11a9 100644 --- a/OFDFile/src/Res.cpp +++ b/OFDFile/src/Res.cpp @@ -36,16 +36,18 @@ inline void AddElementToMap(T* pElement, unsigned int unIndex, std::mapRead(CombinePaths(wsRootPath, oLiteReader.GetText2())); + m_pPublicRes->Read(oLiteReader.GetText2(), wsRootPath); } else if ("ofd:DocumentRes" == sNodeName) { if(nullptr == m_pDocumentRes) m_pDocumentRes = new CRes(); - m_pDocumentRes->Read(CombinePaths(wsRootPath, oLiteReader.GetText2())); + m_pDocumentRes->Read(oLiteReader.GetText2(), wsRootPath); } else if ("ofd:MaxUnitID" == sNodeName) m_unMaxUnitID = oLiteReader.GetUInteger(); diff --git a/OFDFile/src/Types/Font.cpp b/OFDFile/src/Types/Font.cpp index 56cd1b2767..a596884160 100644 --- a/OFDFile/src/Types/Font.cpp +++ b/OFDFile/src/Types/Font.cpp @@ -45,7 +45,11 @@ CFont::CFont(CXmlReader& oXmlReader, const std::wstring& wsRootPath) { if ("ofd:FontFile" == oXmlReader.GetNameA()) { - m_wsFilePath = CombinePaths(wsRootPath, oXmlReader.GetText2()); + const std::wstring wsPath{oXmlReader.GetText2()}; + + if (CanUseThisPath(wsPath, wsRootPath)) + m_wsFilePath = CombinePaths(wsRootPath, wsPath); + break; } } diff --git a/OFDFile/src/Types/MultiMedia.cpp b/OFDFile/src/Types/MultiMedia.cpp index ee48fcfd6b..a3cd0ffb04 100644 --- a/OFDFile/src/Types/MultiMedia.cpp +++ b/OFDFile/src/Types/MultiMedia.cpp @@ -39,7 +39,11 @@ CMultiMedia::CMultiMedia(CXmlReader& oXmlReader, const std::wstring& wsRootPath) { if ("ofd:MediaFile" == oXmlReader.GetNameA()) { - m_wsFilePath = CombinePaths(wsRootPath, oXmlReader.GetText2()); + const std::wstring wsPath{oXmlReader.GetText2()}; + + if (CanUseThisPath(wsPath, wsRootPath)) + m_wsFilePath = CombinePaths(wsRootPath, wsPath); + break; } } diff --git a/OFDFile/src/Types/Signature.cpp b/OFDFile/src/Types/Signature.cpp index 59573aeda8..bc82a71427 100644 --- a/OFDFile/src/Types/Signature.cpp +++ b/OFDFile/src/Types/Signature.cpp @@ -9,18 +9,18 @@ namespace OFD CSignature::CSignature() {} -CSignature* CSignature::Read(const std::wstring& wsFilePath, const std::wstring& wsRootPath) +CSignature* CSignature::Read(const std::wstring& wsFilePath, IFolder* pFolder) { - if (wsFilePath.empty()) + if (wsFilePath.empty() || !CanUseThisPath(wsFilePath, pFolder->getFullFilePath(L""))) return nullptr; CXmlReader oLiteReader; - if (!oLiteReader.FromFile(CombinePaths(wsRootPath, wsFilePath)) || !oLiteReader.ReadNextNode() || L"ofd:Signature" != oLiteReader.GetName() || oLiteReader.IsEmptyNode()) + if (!oLiteReader.FromFile(CombinePaths(pFolder->getFullFilePath(L""), wsFilePath)) || !oLiteReader.ReadNextNode() || L"ofd:Signature" != oLiteReader.GetName() || oLiteReader.IsEmptyNode()) return nullptr; CSignature *pSignature = new CSignature(); - pSignature->m_wsRootPath = wsRootPath; + pSignature->m_wsRootPath = pFolder->getFullFilePath(L""); const int nDepth = oLiteReader.GetDepth(); @@ -29,7 +29,7 @@ CSignature* CSignature::Read(const std::wstring& wsFilePath, const std::wstring& if ("ofd:SignedInfo" == oLiteReader.GetNameA()) pSignature->m_oSignedInfo.Read(oLiteReader); else if ("ofd:SignedValue" == oLiteReader.GetNameA()) - pSignature->m_wsSignedValue = CombinePaths(wsRootPath, oLiteReader.GetText2()); + pSignature->m_wsSignedValue = CombinePaths(pSignature->m_wsRootPath, oLiteReader.GetText2()); } return pSignature; diff --git a/OFDFile/src/Types/Signature.h b/OFDFile/src/Types/Signature.h index 439d1e70c1..d2184637c1 100644 --- a/OFDFile/src/Types/Signature.h +++ b/OFDFile/src/Types/Signature.h @@ -3,6 +3,9 @@ #include "../../../DesktopEditor/graphics/pro/Fonts.h" #include "../../../DesktopEditor/graphics/IRenderer.h" + +#include "../../../OfficeUtils/src/ZipFolder.h" + #include "../Utils/XmlReader.h" #include "../Utils/Types.h" @@ -66,7 +69,7 @@ class CSignature public: CSignature(); - static CSignature* Read(const std::wstring& wsFilePath, const std::wstring& wsRootPath); + static CSignature* Read(const std::wstring& wsFilePath, IFolder* pFolder); bool Draw(IRenderer* pRenderer, unsigned int unPageIndex, NSFonts::IApplicationFonts* pFonts) const; }; diff --git a/OFDFile/src/Types/TemplatePage.cpp b/OFDFile/src/Types/TemplatePage.cpp index 41f2f22dfb..4821a10d5f 100644 --- a/OFDFile/src/Types/TemplatePage.cpp +++ b/OFDFile/src/Types/TemplatePage.cpp @@ -1,7 +1,6 @@ #include "TemplatePage.h" #include "../Page.h" -#include "../Utils/Utils.h" namespace OFD { @@ -17,7 +16,7 @@ CTemplatePage::CTemplatePage(CXmlReader& oXmlReader, const std::wstring& wsRootP sAttributeName = oXmlReader.GetNameA(); if ("BaseLoc" == sAttributeName) - m_pPage = CPage::Read(CombinePaths(wsRootPath, oXmlReader.GetText())); + m_pPage = CPage::Read(oXmlReader.GetText(), wsRootPath); else if ("ZOrder" == sAttributeName) m_eZOrder = GetZOrderFromString(oXmlReader.GetTextA()); } while (oXmlReader.MoveToNextAttribute()); diff --git a/OFDFile/src/Utils/Utils.h b/OFDFile/src/Utils/Utils.h index ac277b8598..096f878d9b 100644 --- a/OFDFile/src/Utils/Utils.h +++ b/OFDFile/src/Utils/Utils.h @@ -9,6 +9,9 @@ #include #include "../../../DesktopEditor/common/Path.h" +#include "../../../DesktopEditor/common/ProcessEnv.h" + +#include namespace OFD { @@ -140,6 +143,29 @@ inline std::wstring CombinePaths(const std::wstring& wsFirstPath, const std::wst return NSSystemPath::Combine(wsFirstPath, wsNewSecondPath); } +inline bool GetStatusUsingExternalLocalFiles() +{ + return false; + + if (NSProcessEnv::IsPresent(NSProcessEnv::Converter::gc_allowPrivateIP)) + return NSProcessEnv::GetBoolValue(NSProcessEnv::Converter::gc_allowPrivateIP); + + return true; +} + +inline bool CanUseThisPath(const std::wstring& wsPath, const std::wstring& wsRootPath) +{ + if (GetStatusUsingExternalLocalFiles()) + return true; + + const std::wstring wsFullPath = NSSystemPath::ShortenPath(NSSystemPath::Combine(wsRootPath, wsPath)); + + if (!wsRootPath.empty()) + return boost::starts_with(wsFullPath, wsRootPath); + + return !boost::starts_with(wsFullPath, L"../"); +} + inline bool IsZeroValue(const double& dValue) { return DBL_EPSILON > std::abs(dValue);