From 925c40aa805675c7ba4f5beb03f5b8eace51c470 Mon Sep 17 00:00:00 2001 From: Green Date: Mon, 24 Mar 2025 18:34:04 +0300 Subject: [PATCH] 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