diff --git a/XpsFile/XpsFile.cpp b/XpsFile/XpsFile.cpp index 2feb542103..0143c2ad82 100644 --- a/XpsFile/XpsFile.cpp +++ b/XpsFile/XpsFile.cpp @@ -1,11 +1,12 @@ #include "XpsFile.h" -#include "XpsLib/Folder.h" +#include "XpsLib/Document.h" #include "../DesktopEditor/common/File.h" #include "../DesktopEditor/common/Directory.h" #include "../DesktopEditor/fontengine/FontManager.h" #include "../DesktopEditor/fontengine/ApplicationFonts.h" #include "../DesktopEditor/graphics/GraphicsRenderer.h" +#include "../PdfWriter/PdfRenderer.h" #include "../ASCOfficeUtils/ASCOfficeUtilsLib/OfficeUtils.h" @@ -13,11 +14,6 @@ using namespace XPS; CXpsFile::CXpsFile(CApplicationFonts* pAppFonts) { - std::wstring wsTemp = NSFile::CFileBinary::GetTempPath(); - wsTemp += L"/XPS/"; - m_wsTempDirectory = wsTemp; - NSDirectory::CreateDirectory(m_wsTempDirectory); - m_pAppFonts = pAppFonts; // Создаем менеджер шрифтов с собственным кэшем @@ -25,23 +21,35 @@ CXpsFile::CXpsFile(CApplicationFonts* pAppFonts) CFontsCache* pMeasurerCache = new CFontsCache(); pMeasurerCache->SetStreams(pAppFonts->GetStreams()); m_pFontManager->SetOwnerCache(pMeasurerCache); + + m_wsTempFolder = L""; + SetTempFolder(NSFile::CFileBinary::GetTempPath()); } CXpsFile::~CXpsFile() { + if (L"" != m_wsTempFolder) + NSDirectory::DeleteDirectory(m_wsTempFolder); + Close(); - NSDirectory::DeleteDirectory(m_wsTempDirectory); RELEASEINTERFACE(m_pFontManager); } -std::wstring CXpsFile::GetTempDirectory() const +std::wstring CXpsFile::GetTempFolder() const { - return m_wsTempDirectory; + return m_wsTempFolder; } -void CXpsFile::SetTempDirectory(const std::wstring& wsDirectory) +void CXpsFile::SetTempFolder(const std::wstring& wsPath) { - NSDirectory::DeleteDirectory(m_wsTempDirectory); - m_wsTempDirectory = wsDirectory; - m_wsTempDirectory += L"/XPS/"; - NSDirectory::CreateDirectory(m_wsTempDirectory); + if (L"" != m_wsTempFolder) + NSDirectory::DeleteDirectory(m_wsTempFolder); + + int nCounter = 0; + m_wsTempFolder = wsPath + L"\\XPS\\"; + while (NSDirectory::Exists(m_wsTempFolder)) + { + m_wsTempFolder = wsPath + L"\\XPS" + std::to_wstring(nCounter) + L"\\"; + nCounter++; + } + NSDirectory::CreateDirectory(m_wsTempFolder); } bool CXpsFile::LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXmlOptions) { @@ -49,52 +57,52 @@ bool CXpsFile::LoadFromFile(const std::wstring& wsSrcFileName, const std // Распаковываем Zip-архив в темповую папку COfficeUtils oUtils(NULL); - if (S_OK != oUtils.ExtractToDirectory(wsSrcFileName, m_wsTempDirectory, NULL, 0)) + if (S_OK != oUtils.ExtractToDirectory(wsSrcFileName, m_wsTempFolder, NULL, 0)) return false; - m_pFolder = new XPS::Folder(m_pFontManager); - if (!m_pFolder) + m_pDocument = new XPS::CDocument(m_pFontManager); + if (!m_pDocument) return false; - std::wstring wsPath = m_wsTempDirectory + L"/"; - m_pFolder->ReadFromPath(wsPath); + std::wstring wsPath = m_wsTempFolder + L"/"; + m_pDocument->ReadFromPath(wsPath); return true; } void CXpsFile::Close() { - if (m_pFolder) + if (m_pDocument) { - m_pFolder->Close(); - delete m_pFolder; - m_pFolder = NULL; + m_pDocument->Close(); + delete m_pDocument; + m_pDocument = NULL; } } int CXpsFile::GetPagesCount() { - if (!m_pFolder) + if (!m_pDocument) return 0; - return m_pFolder->GetPageCount(); + return m_pDocument->GetPageCount(); } void CXpsFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) { int nW = 0, nH = 0; - if (m_pFolder) - m_pFolder->GetPageSize(nPageIndex, nW, nH); + if (m_pDocument) + m_pDocument->GetPageSize(nPageIndex, nW, nH); *pdWidth = nW * 25.4 / 96; *pdHeight = nH * 25.4 / 96; - *pdDpiX = 96; - *pdDpiY = 96; + *pdDpiX = 25.4; + *pdDpiY = 25.4; } void CXpsFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak) { - if (!m_pFolder) + if (!m_pDocument) return; - m_pFolder->DrawPage(nPageIndex, pRenderer, pBreak); + m_pDocument->DrawPage(nPageIndex, pRenderer, pBreak); } void CXpsFile::ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType) { @@ -134,4 +142,36 @@ void CXpsFile::ConvertToRaster(int nPageIndex, const std::wstring& wsDst oFrame.SaveFile(wsDstPath, nImageType); RELEASEINTERFACE(pFontManager); +} +void CXpsFile::ConvertToPdf(const std::wstring& wsPath) +{ + CPdfRenderer oPdf(m_pAppFonts); + bool bBreak = false; + + int nPagesCount = GetPagesCount(); + for (int nPageIndex = 0; nPageIndex < nPagesCount; nPageIndex++) + { + oPdf.NewPage(); + oPdf.BeginCommand(c_nPageType); + + double dPageDpiX, dPageDpiY; + double dWidth, dHeight; + 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 + } + + oPdf.SaveToFile(wsPath); } \ No newline at end of file diff --git a/XpsFile/XpsFile.h b/XpsFile/XpsFile.h index 7fd0fd2a93..92d7bc84e5 100644 --- a/XpsFile/XpsFile.h +++ b/XpsFile/XpsFile.h @@ -5,7 +5,7 @@ namespace XPS { - class Folder; + class CDocument; } class IRenderer; @@ -20,19 +20,20 @@ public: bool LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXmlOptions = L""); void Close(); - std::wstring GetTempDirectory() const; - void SetTempDirectory(const std::wstring& wsPath); + std::wstring GetTempFolder() const; + void SetTempFolder(const std::wstring& wsPath); int GetPagesCount(); void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); void ConvertToRaster(int nPageIndex, const std::wstring& wsDstPath, int nImageType); + void ConvertToPdf(const std::wstring& wsDstPath); private: CApplicationFonts* m_pAppFonts; CFontManager* m_pFontManager; - std::wstring m_wsTempDirectory; - XPS::Folder* m_pFolder; + std::wstring m_wsTempFolder; + XPS::CDocument* m_pDocument; }; #endif // _XPS_FILE_H \ No newline at end of file diff --git a/XpsFile/XpsFile.sln b/XpsFile/XpsFile.sln index 78eba9ab5b..0e50814551 100644 --- a/XpsFile/XpsFile.sln +++ b/XpsFile/XpsFile.sln @@ -42,7 +42,8 @@ Global {84BACD6F-275B-4C60-AC5A-F541919728C5}.Release|Mixed Platforms.Build.0 = Release|Win32 {84BACD6F-275B-4C60-AC5A-F541919728C5}.Release|Win32.ActiveCfg = Release|Win32 {84BACD6F-275B-4C60-AC5A-F541919728C5}.Release|Win32.Build.0 = Release|Win32 - {84BACD6F-275B-4C60-AC5A-F541919728C5}.Release|x64.ActiveCfg = Release|Win32 + {84BACD6F-275B-4C60-AC5A-F541919728C5}.Release|x64.ActiveCfg = Release|x64 + {84BACD6F-275B-4C60-AC5A-F541919728C5}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/XpsFile/XpsFile.vcxproj b/XpsFile/XpsFile.vcxproj index 5cbf3d9f24..0c393c8f55 100644 --- a/XpsFile/XpsFile.vcxproj +++ b/XpsFile/XpsFile.vcxproj @@ -123,8 +123,9 @@ MaxSpeed true true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS;UNICODE;_UNICODE;_USE_LIBXML2_READER_;LIBXML_READER_ENABLED;%(PreprocessorDefinitions) true + D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\Common\DocxFormat\Source\XML\libxml2\XML\include;D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\freetype-2.5.2\include;D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\agg-2.4\include;%(AdditionalIncludeDirectories) Windows @@ -139,14 +140,14 @@ - + - + diff --git a/XpsFile/XpsFileTest/XpsFileTest.cpp b/XpsFile/XpsFileTest/XpsFileTest.cpp index 8625c09af7..50e9abbb86 100644 --- a/XpsFile/XpsFileTest/XpsFileTest.cpp +++ b/XpsFile/XpsFileTest/XpsFileTest.cpp @@ -12,6 +12,8 @@ #include "../../DesktopEditor/common/String.h" #include "../../DesktopEditor/fontengine/ApplicationFonts.h" +#include + std::vector GetAllFilesInFolder(std::wstring wsFolder, std::wstring wsExt) { std::vector vwsNames; @@ -35,9 +37,13 @@ std::vector GetAllFilesInFolder(std::wstring wsFolder, std::wstrin } return vwsNames; } -void ConvertFolder(CXpsFile& oReader, std::wstring wsFolderPath) +void ConvertFolderToRaster(const std::wstring& wsFolderPath) { - oReader.Close(); + CApplicationFonts oFonts; + oFonts.Initialize(); + + CXpsFile oReader(&oFonts); + oReader.SetTempFolder(L"D:/Test Files/Temp/"); std::vector vFiles = GetAllFilesInFolder(wsFolderPath, L"xps"); for (int nIndex = 0; nIndex < vFiles.size(); nIndex++) @@ -63,14 +69,39 @@ void ConvertFolder(CXpsFile& oReader, std::wstring wsFolderPath) } } } - - -void main() +void ConvertFolderToPdf(const std::wstring& wsFolderPath) { CApplicationFonts oFonts; oFonts.Initialize(); - CXpsFile oFile(&oFonts); - oFile.SetTempDirectory(L"D:/Test Files/Temp/"); - ConvertFolder(oFile, L"D:/Test Files//"); + CXpsFile oReader(&oFonts); + oReader.SetTempFolder(L"D:/Test Files/Temp/"); + + std::vector vFiles = GetAllFilesInFolder(wsFolderPath, L"xps"); + for (int nIndex = 0; nIndex < vFiles.size(); nIndex++) + { + std::wstring wsFilePath = wsFolderPath; + wsFilePath.append(vFiles.at(nIndex)); + std::wstring wsFilePathName = (wsFilePath.substr(0, wsFilePath.size() - 4)); + if (oReader.LoadFromFile(wsFilePath.c_str())) + { + printf("%d of %d %S\n", nIndex + 1, vFiles.size(), vFiles.at(nIndex).c_str()); + std::wstring wsDstFilePath = wsFilePathName + L".pdf"; + oReader.ConvertToPdf(wsDstFilePath); + oReader.Close(); + } + else + { + printf("%d of %d %S error\n", nIndex, vFiles.size(), vFiles.at(nIndex).c_str()); + } + } +} + +void main() +{ + //ConvertFolderToRaster(L"D:/Test Files//Xps//"); + ConvertFolderToPdf(L"D:/Test Files//Xps//"); + + char q; + std::cin >> q; } diff --git a/XpsFile/XpsFileTest/XpsFileTest.vcxproj b/XpsFile/XpsFileTest/XpsFileTest.vcxproj index ac904640d8..5a1cf8c5d0 100644 --- a/XpsFile/XpsFileTest/XpsFileTest.vcxproj +++ b/XpsFile/XpsFileTest/XpsFileTest.vcxproj @@ -129,8 +129,9 @@ MaxSpeed true true - WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + WIN32;NDEBUG;_CONSOLE;_LIB;_CRT_SECURE_NO_WARNINGS;UNICODE;_UNICODE;_USE_LIBXML2_READER_;LIBXML_READER_ENABLED;%(PreprocessorDefinitions) true + D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\freetype-2.5.2\include;D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\DesktopEditor\agg-2.4\include;D:\Subversion\AVS\Sources\TeamlabOffice\trunk\ServerComponents\Common\DocxFormat\Source\XML\libxml2\XML\include Console @@ -149,12 +150,15 @@ NotUsing + NotUsing NotUsing + NotUsing NotUsing + NotUsing Create diff --git a/XpsFile/XpsFileTest/stdafx.h b/XpsFile/XpsFileTest/stdafx.h index 1a93b2b803..c53a10048d 100644 --- a/XpsFile/XpsFileTest/stdafx.h +++ b/XpsFile/XpsFileTest/stdafx.h @@ -10,13 +10,17 @@ #include #ifdef _DEBUG +#pragma comment(lib, "../x64/Debug/XpsFile.lib") #pragma comment(lib, "../../Common/DocxFormat/Source/XML/libxml2/win_build/x64/Debug/libxml2.lib") #pragma comment(lib, "../../ASCOfficeUtils/ASCOfficeUtilsLib/Win/x64/Debug/ASCOfficeUtilsLib.lib") -#pragma comment(lib, "../x64/Debug/XpsFile.lib") #pragma comment(lib, "../../DesktopEditor/Qt_build/graphics/project/debug/graphics.lib") +#pragma comment(lib, "../../PdfWriter/x64/Debug/PdfWriter.lib") #else #pragma comment(lib, "../x64/Release/XpsFile.lib") +#pragma comment(lib, "../../Common/DocxFormat/Source/XML/libxml2/win_build/x64/Release/libxml2.lib") +#pragma comment(lib, "../../ASCOfficeUtils/ASCOfficeUtilsLib/Win/x64/Release/ASCOfficeUtilsLib.lib") #pragma comment(lib, "../../DesktopEditor/Qt_build/graphics/project/release/graphics.lib") +#pragma comment(lib, "../../PdfWriter/x64/Release/PdfWriter.lib") #endif diff --git a/XpsFile/XpsLib/Document.cpp b/XpsFile/XpsLib/Document.cpp new file mode 100644 index 0000000000..9f9f660357 --- /dev/null +++ b/XpsFile/XpsLib/Document.cpp @@ -0,0 +1,253 @@ +#include "Document.h" +#include "../../Common/DocxFormat/Source/XML/xmlutils.h" + +namespace XPS +{ + CDocument::CDocument(CFontManager* pFontManager) + { + m_pFontManager = pFontManager; + m_mPages.clear(); + } + CDocument::~CDocument() + { + Close(); + } + bool CDocument::ReadFromPath(const std::wstring& wsPath) + { + Close(); + + m_wsPath = wsPath; + + XmlUtils::CXmlLiteReader oReader; + + std::wstring wsRelsPath = NormalizePath(wsPath + L"_rels/.rels"); + + clock_t oBeginTime = clock(); + + if (!oReader.FromFile(wsRelsPath)) + return false; + + clock_t oEndTime = clock(); + double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + printf("%S %fseconds\n", wsRelsPath.c_str(), dElapsedSecs); + + if (!oReader.ReadNextNode()) + return false; + + std::wstring wsName = oReader.GetName(); + if (L"Relationships" != wsName) + return false; + + std::wstring wsFile; + while (oReader.ReadNextNode()) + { + wsName = oReader.GetName(); + if (L"Relationship" == wsName) + { + std::wstring wsAttr; + ReadAttribute(oReader, L"Type", wsAttr); + + if (L"http://schemas.microsoft.com/xps/2005/06/fixedrepresentation" == wsAttr) + { + ReadAttribute(oReader, L"Target", wsFile); + break; + } + } + } + + if (wsFile.empty()) + return false; + + oReader.Clear(); + + oBeginTime = clock(); + + if (!oReader.FromFile(wsPath + wsFile)) + return false; + + oEndTime = clock(); + dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + printf("%S %fseconds\n", (wsPath + wsFile).c_str(), dElapsedSecs); + + if (!oReader.ReadNextNode()) + return false; + + wsName = oReader.GetName(); + if (L"FixedDocumentSequence" != wsName) + return false; + + wsFile.clear(); + while (oReader.ReadNextNode()) + { + wsName = oReader.GetName(); + if (L"DocumentReference" == wsName) + { + ReadAttribute(oReader, L"Source", wsFile); + break; + } + } + + if (wsFile.empty()) + return false; + + oReader.Clear(); + + oBeginTime = clock(); + + if (!oReader.FromFile(m_wsPath + wsFile)) + return false; + + oEndTime = clock(); + dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + printf("%S %fseconds\n", (m_wsPath + wsFile).c_str(), dElapsedSecs); + + if (!oReader.ReadNextNode()) + return false; + + wsName = oReader.GetName(); + if (L"FixedDocument" != wsName) + return false; + + std::wstring wsFilePath = GetPath(m_wsPath + wsFile); + std::wstring wsPagePath; + std::wstring wsSource; + + int nIndex = 0; + while (oReader.ReadNextNode()) + { + wsName = oReader.GetName(); + + if (L"PageContent" == wsName) + { + ReadAttribute(oReader, L"Source", wsSource); + if ('/' == wsSource[0]) + wsPagePath = m_wsPath + wsSource; + else + wsPagePath = wsFilePath + wsSource; + + m_mPages.insert(std::pair(nIndex++, new XPS::Page(wsPagePath, wsPath, &m_oFontList, m_pFontManager, this))); + } + + } + + return true; + + //Close(); + + //m_wsPath = wsPath; + + //XmlUtils::CXmlNode oNode; + //XmlUtils::CXmlNodes arrNodes; + //XmlUtils::CXmlNode oSubnode; + // + //std::wstring wsRelsPath = NormalizePath(wsPath + L"_rels/.rels"); + + //clock_t oBeginTime = clock(); + + //if (!oNode.FromXmlFile(wsRelsPath.c_str())) + // return false; + + //clock_t oEndTime = clock(); + //double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + //printf("%S %fseconds\n", wsRelsPath.c_str(), dElapsedSecs); + + //// Checking root node + //if (L"Relationships" != oNode.GetName()) + // return false; + + //if (!oNode.GetNodes(L"Relationship", arrNodes)) + // return false; + + //std::wstring wsFile; + //for (int nIndex = 0, nCount = arrNodes.GetCount(); nIndex < nCount; nIndex++) + //{ + // arrNodes.GetAt(nIndex, oNode); + + // if (L"http://schemas.microsoft.com/xps/2005/06/fixedrepresentation" == oNode.GetAttribute(L"Type")) + // { + // wsFile = oNode.GetAttribute(L"Target"); + // break; + // } + + // if (nIndex == nCount - 1) + // return false; + //} + + //oBeginTime = clock(); + + //if (!oNode.FromXmlFile((wsPath + wsFile).c_str())) + // return false; + + //oEndTime = clock(); + //dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + //printf("%S %fseconds\n", (wsPath + wsFile).c_str(), dElapsedSecs); + + //// Checking root node + //if (L"FixedDocumentSequence" != oNode.GetName()) + // return false; + + //if (!oNode.GetNode(L"DocumentReference", oSubnode)) + // return false; + + //wsFile = oSubnode.GetAttribute(L"Source"); + + //oBeginTime = clock(); + + //if (!oNode.FromXmlFile((m_wsPath + wsFile).c_str())) + // return false; + + //oEndTime = clock(); + //dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + //printf("%S %fseconds\n", (m_wsPath + wsFile).c_str(), dElapsedSecs); + + //if (L"FixedDocument" != oNode.GetName()) + // return false; + + //if (!oNode.GetNodes(L"PageContent", arrNodes)) + // return false; + + //std::wstring wsFilePath = GetPath(m_wsPath + wsFile); + //std::wstring wsPagePath; + //std::wstring wsSource; + + //for (int nIndex = 0, nCount = arrNodes.GetCount(); nIndex < nCount; nIndex++) + //{ + // arrNodes.GetAt(nIndex, oNode); + // wsSource = oNode.GetAttribute(L"Source"); + // if('/' == wsSource[0]) + // wsPagePath = m_wsPath + wsSource; + // else + // wsPagePath = wsFilePath + wsSource; + + // m_mPages.insert(std::pair(nIndex, new XPS::Page(wsPagePath, wsPath, &m_oFontList, m_pFontManager))); + //} + + //return true; + } + int CDocument::GetPageCount()const + { + return (int)m_mPages.size(); + } + void CDocument::GetPageSize(int nPageIndex, int& nW, int& nH) + { + std::map::const_iterator oIter = m_mPages.find(nPageIndex); + if (oIter != m_mPages.end()) + oIter->second->GetSize(nW, nH); + } + void CDocument::DrawPage(int nPageIndex, IRenderer* pRenderer, bool* pbBreak) + { + std::map::const_iterator oIter = m_mPages.find(nPageIndex); + if (oIter != m_mPages.end()) + oIter->second->Draw(pRenderer, pbBreak); + } + void CDocument::Close() + { + for (std::map::iterator oIter = m_mPages.begin(); oIter != m_mPages.end(); oIter++) + { + if (oIter->second) + delete oIter->second; + } + m_mPages.clear(); + m_oFontList.Clear(); + } +} \ No newline at end of file diff --git a/XpsFile/XpsLib/Folder.h b/XpsFile/XpsLib/Document.h similarity index 77% rename from XpsFile/XpsLib/Folder.h rename to XpsFile/XpsLib/Document.h index 332ac7d2e6..c9841449a4 100644 --- a/XpsFile/XpsLib/Folder.h +++ b/XpsFile/XpsLib/Document.h @@ -1,5 +1,5 @@ -#ifndef _XPS_XPSLIB_FOLDER_H -#define _XPS_XPSLIB_FOLDER_H +#ifndef _XPS_XPSLIB_DOCUMENT_H +#define _XPS_XPSLIB_DOCUMENT_H #include "FontList.h" #include "Page.h" @@ -15,11 +15,11 @@ namespace XPS { - class Folder + class CDocument { public: - Folder(CFontManager* pFontManager); - ~Folder(); + CDocument(CFontManager* pFontManager); + ~CDocument(); bool ReadFromPath(const std::wstring& wsPath); int GetPageCount() const; @@ -36,4 +36,4 @@ namespace XPS }; } -#endif //_XPS_XPSLIB_FOLDER_H \ No newline at end of file +#endif //_XPS_XPSLIB_DOCUMENT_H \ No newline at end of file diff --git a/XpsFile/XpsLib/Folder.cpp b/XpsFile/XpsLib/Folder.cpp deleted file mode 100644 index c5bc12a05f..0000000000 --- a/XpsFile/XpsLib/Folder.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "Folder.h" -#include "../../Common/DocxFormat/Source/XML/xmlutils.h" - -namespace XPS -{ - Folder::Folder(CFontManager* pFontManager) - { - m_pFontManager = pFontManager; - m_mPages.clear(); - } - Folder::~Folder() - { - Close(); - } - bool Folder::ReadFromPath(const std::wstring& wsPath) - { - Close(); - - m_wsPath = wsPath; - - XmlUtils::CXmlNode oNode; - XmlUtils::CXmlNodes arrNodes; - XmlUtils::CXmlNode oSubnode; - - std::wstring wsRelsPath = NormalizePath(wsPath + L"_rels/.rels"); - if (!oNode.FromXmlFile(wsRelsPath.c_str())) - return false; - - // Checking root node - if (L"Relationships" != oNode.GetName()) - return false; - - if (!oNode.GetNodes(L"Relationship", arrNodes)) - return false; - - std::wstring wsFile; - for (int nIndex = 0, nCount = arrNodes.GetCount(); nIndex < nCount; nIndex++) - { - arrNodes.GetAt(nIndex, oNode); - - if (L"http://schemas.microsoft.com/xps/2005/06/fixedrepresentation" == oNode.GetAttribute(L"Type")) - { - wsFile = oNode.GetAttribute(L"Target"); - break; - } - - if (nIndex == nCount - 1) - return false; - } - - if (!oNode.FromXmlFile((wsPath + wsFile).c_str())) - return false;; - - // Checking root node - if (L"FixedDocumentSequence" != oNode.GetName()) - return false; - - if (!oNode.GetNode(L"DocumentReference", oSubnode)) - return false; - - wsFile = oSubnode.GetAttribute(L"Source"); - - if (!oNode.FromXmlFile((m_wsPath + wsFile).c_str())) - return false; - - if (L"FixedDocument" != oNode.GetName()) - return false; - - if (!oNode.GetNodes(L"PageContent", arrNodes)) - return false; - - std::wstring wsFilePath = GetPath(m_wsPath + wsFile); - std::wstring wsPagePath; - std::wstring wsSource; - - for (int nIndex = 0, nCount = arrNodes.GetCount(); nIndex < nCount; nIndex++) - { - arrNodes.GetAt(nIndex, oNode); - wsSource = oNode.GetAttribute(L"Source"); - if('/' == wsSource[0]) - wsPagePath = m_wsPath + wsSource; - else - wsPagePath = wsFilePath + wsSource; - - m_mPages.insert(std::pair(nIndex, new XPS::Page(wsPagePath, wsPath, &m_oFontList, m_pFontManager))); - } - - return true; - } - int Folder::GetPageCount()const - { - return (int)m_mPages.size(); - } - void Folder::GetPageSize(int nPageIndex, int& nW, int& nH) - { - std::map::const_iterator oIter = m_mPages.find(nPageIndex); - if (oIter != m_mPages.end()) - oIter->second->GetSize(nW, nH); - } - void Folder::DrawPage(int nPageIndex, IRenderer* pRenderer, bool* pbBreak) - { - std::map::const_iterator oIter = m_mPages.find(nPageIndex); - if (oIter != m_mPages.end()) - oIter->second->Draw(pRenderer, pbBreak); - } - void Folder::Close() - { - for (std::map::iterator oIter = m_mPages.begin(); oIter != m_mPages.end(); oIter++) - { - if (oIter->second) - delete oIter->second; - } - m_mPages.clear(); - m_oFontList.Clear(); - } -} \ No newline at end of file diff --git a/XpsFile/XpsLib/Page.cpp b/XpsFile/XpsLib/Page.cpp index 68fe20efc1..d1c0f86ac5 100644 --- a/XpsFile/XpsLib/Page.cpp +++ b/XpsFile/XpsLib/Page.cpp @@ -2,6 +2,9 @@ #include #include "../../DesktopEditor/common/String.h" #include "../../DesktopEditor/graphics/structures.h" +#include "Document.h" + +#include #ifndef M_PI #define M_PI 3.14159265358979323846 @@ -150,36 +153,80 @@ namespace XPS dCpY = GetDouble(arrElements[nPos + 2]); nPos += 4; } - Page::Page(const std::wstring& wsPagePath, const std::wstring& wsRootPath, CFontList* pFontList, CFontManager* pFontManager) + Page::Page(const std::wstring& wsPagePath, const std::wstring& wsRootPath, CFontList* pFontList, CFontManager* pFontManager, CDocument* pDocument) { m_wsPagePath = wsPagePath; m_wsRootPath = wsRootPath; m_pFontList = pFontList; m_pFontManager = pFontManager; + m_pDocument = pDocument; } Page::~Page() { } void Page::GetSize(int& nW, int& nH) const { - XmlUtils::CXmlNode oNode; + XmlUtils::CXmlLiteReader oReader; + clock_t oBeginTime = clock(); - if (!oNode.FromXmlFile(m_wsPagePath.c_str())) + if (!oReader.FromFile(m_wsPagePath)) return; - if (L"FixedPage" != oNode.GetName()) + clock_t oEndTime = clock(); + double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + printf("%S %fseconds\n", m_wsPagePath.c_str(), dElapsedSecs); + + if (!oReader.ReadNextNode()) return; - - nW = XmlUtils::GetInteger(oNode.GetAttribute(L"Width")); - nH = XmlUtils::GetInteger(oNode.GetAttribute(L"Height")); + + std::wstring wsName = oReader.GetName(); + if (L"FixedPage" != wsName) + return; + + ReadAttribute(oReader, L"Width", wsName); + nW = XmlUtils::GetInteger(wsName.c_str()); + + ReadAttribute(oReader, L"Height", wsName); + nH = XmlUtils::GetInteger(wsName.c_str()); } void Page::Draw(IRenderer* pRenderer, bool* pbBreak) { - XmlUtils::CXmlNode oNode; + XmlUtils::CXmlLiteReader oReader; + + clock_t oBeginTime = clock(); + + if (!oReader.FromFile(m_wsPagePath.c_str())) + return; + + clock_t oEndTime = clock(); + double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + printf("%S %fseconds\n", m_wsPagePath.c_str(), dElapsedSecs); + + if (!oReader.ReadNextNode()) + return; + + std::wstring wsNodeName = oReader.GetName(); + if (L"FixedPage" != wsNodeName) + return; + + CContextState oState; + DrawCanvas(oReader, pRenderer, &oState, pbBreak); + + + + + /*XmlUtils::CXmlNode oNode; + + + clock_t oBeginTime = clock(); if (!oNode.FromXmlFile(m_wsPagePath.c_str())) return; + clock_t oEndTime = clock(); + double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + printf("%S %fseconds\n", m_wsPagePath.c_str(), dElapsedSecs); + if (L"FixedPage" != oNode.GetName()) return; @@ -197,7 +244,15 @@ namespace XPS std::wstring wsPath = m_wsRootPath + wsXmlSource; XmlUtils::CXmlNode oNodeSource; + + clock_t oBeginTime = clock(); + oNodeSource.FromXmlFile(wsPath.c_str()); + + clock_t oEndTime = clock(); + double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + printf("%S %fseconds\n", wsPath.c_str(), dElapsedSecs); + if (oNodeSource.IsValid()) { XmlUtils::CXmlNodes arrNodes; @@ -238,7 +293,171 @@ namespace XPS } DrawCanvas(oNode, pRenderer, &oState, pbBreak); - return; + return;*/ + } + void Page::DrawCanvas(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState, bool* pbBreak) + { + std::wstring wsClip; + ReadAttribute(oReader, L"Clip", wsClip); + bool bClip = false; + if (L"" != wsClip) + { + std::wstring wsValue = pState->GetFigure(wsClip); + if (L"" != wsValue) + wsClip = wsValue; + + bClip = true; + pRenderer->PathCommandStart(); + pRenderer->BeginCommand(c_nClipType); + pRenderer->put_ClipMode(0); + pRenderer->BeginCommand(c_nPathType); + + VmlToRenderer(wsClip, pRenderer); + + pRenderer->EndCommand(c_nPathType); + pRenderer->EndCommand(c_nClipType); + pRenderer->PathCommandEnd(); + } + + std::wstring wsTransform; + ReadAttribute(oReader, L"RenderTransform", wsTransform); + bool bTransform = false; + if (L"" != wsTransform) + { + bTransform = true; + TransformToRenderer(wsTransform, pRenderer, pState); + } + + if (oReader.IsEmptyNode()) + return; + + std::wstring wsNodeName; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + wsNodeName = oReader.GetName(); + wsNodeName = RemoveNamespace(wsNodeName); + + if (L"FixedPage.Resources" == wsNodeName) + { + ReadPageResources(oReader, pRenderer, pState); + } + else if (L"Glyphs" == wsNodeName) + { + DrawGlyph(oReader, pRenderer, pState); + } + else if (L"Canvas" == wsNodeName) + { + DrawCanvas(oReader, pRenderer, pState, pbBreak); + } + else if (L"Canvas.RenderTransform" == wsNodeName) + { + if (!bTransform) + { + CanvasTransform(oReader, pRenderer, pState); + bTransform = true; + } + } + else if (L"Path" == wsNodeName) + { + DrawPath(oReader, pRenderer, pState); + } + + if (NULL != pbBreak && *pbBreak) + return; + } + + if (bClip) + { + pRenderer->BeginCommand(c_nResetClipType); + pRenderer->EndCommand(c_nResetClipType); + } + + if (bTransform) + ResetTransform(pRenderer, pState); + } + void Page::ReadPageResources(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState) + { + if (oReader.IsEmptyNode()) + return; + + std::wstring wsNodeName; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + wsNodeName = oReader.GetName(); + if (L"ResourceDictionary" == wsNodeName) + { + std::wstring wsSource; + ReadAttribute(oReader, L"Source", wsSource); + if (!wsSource.empty()) + { + std::wstring wsPath = m_wsRootPath + wsSource; + + XmlUtils::CXmlLiteReader oSourceReader; + + clock_t oBeginTime = clock(); + + if (!oSourceReader.FromFile(wsPath)) + return; + + std::wstring wsNodeText; + while (oSourceReader.ReadNextNode()) + { + wsNodeName = oSourceReader.GetName(); + if (L"PathGeometry" == wsNodeName) + { + std::wstring wsKey, wsValue; + + if (oSourceReader.MoveToFirstAttribute()) + { + std::wstring wsAttrName = oSourceReader.GetName(); + while (!wsAttrName.empty()) + { + if (L"x:Key" == wsAttrName) + wsKey = oSourceReader.GetText(); + else if (L"Figures" == wsAttrName) + wsValue = oSourceReader.GetText(); + + if (!oSourceReader.MoveToNextAttribute()) + break; + + wsAttrName = oSourceReader.GetName(); + } + + oSourceReader.MoveToElement(); + } + + wsKey = L"{StaticResource " + wsKey + L"}"; + pState->AddFigure(wsKey, wsValue); + } + } + + clock_t oEndTime = clock(); + double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC; + printf("%S %fseconds\n", wsPath.c_str(), dElapsedSecs); + } + else + { + if (oReader.IsEmptyNode()) + return; + + int nPathDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nPathDepth)) + { + wsNodeName = oReader.GetName(); + if (L"PathGeometry" == wsNodeName) + { + std::wstring wsKey, wsValue; + ReadAttribute(oReader, L"x:Key", wsKey); + ReadAttribute(oReader, L"Figures", wsValue); + wsKey = L"{StaticResource " + wsKey + L"}"; + pState->AddFigure(wsKey, wsValue); + } + } + } + } + } } void Page::DrawCanvas(XmlUtils::CXmlNode& oCanvasNode, IRenderer* pRenderer, CContextState* pState, bool* pbBreak) { @@ -280,6 +499,7 @@ namespace XPS arrNodes.GetAt(nIndex, oNode); wsNodeName = oNode.GetName(); wsNodeName = RemoveNamespace(wsNodeName); + if (L"Glyphs" == wsNodeName) DrawGlyph(oNode, pRenderer, pState); else if (L"Canvas" == wsNodeName) @@ -320,7 +540,7 @@ namespace XPS bool bPrevCommandIsCurve = false; PrepareVmlString(wsString); - std::vector arrElements = NSString::Split(wsString, L" ,"); + std::vector arrElements = NSString::Split(wsString, L" ,", false); int nElementsCount = (int)arrElements.size(); for (int nPos = 0; nPos < nElementsCount; nPos++) @@ -555,6 +775,141 @@ namespace XPS if (bTransform) ResetTransform(pRenderer, pState); } + void Page::DrawGlyph(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState) + { + int nBgr = 0, nAlpha = 255; + double dFontSize = 10.0; + bool bTransform = false; + int nTextLen = 0; + std::wstring wsText; + double dX = 0; + double dY = 0; + std::wstring wsFontPath; + std::wstring wsIndicies; + if (oReader.MoveToFirstAttribute()) + { + std::wstring wsAttrName = oReader.GetName(); + while (!wsAttrName.empty()) + { + if (L"FontUri" == wsAttrName) + { + wsFontPath = oReader.GetText(); + std::wstring wsFontName = GetFileName(wsFontPath); + wsFontPath = m_wsRootPath + L"/" + wsFontPath; + std::wstring wsExt = GetFileExtension(wsFontPath); + NSString::ToLower(wsExt); + if (L"odttf" == wsExt) + { + NSString::ToLower(wsFontName); + m_pFontList->Check(wsFontName, wsFontPath); + } + wsFontPath = NormalizePath(wsFontPath); + pRenderer->put_FontPath(wsFontPath); + } + else if (L"Fill" == wsAttrName) + { + int nBgr, nAlpha; + std::wstring wsFontColor = oReader.GetText(); + ReadAttribute(oReader, L"Fill", wsFontColor); + GetBgra(wsFontColor, nBgr, nAlpha); + } + else if (L"StyleSimulations" == wsAttrName) + { + std::wstring wsFontStyle = oReader.GetText(); + if (L"ItalicSimulation" == wsFontStyle) + pRenderer->put_FontStyle(0x02); + else if (L"BoldSimulation" == wsFontStyle) + pRenderer->put_FontStyle(0x01); + else if (L"BoldItalicSimulation" == wsFontStyle) + pRenderer->put_FontStyle(0x03); + } + else if (L"FontRenderingEmSize" == wsAttrName) + { + std::wstring wsFontSize = oReader.GetText(); + dFontSize = GetDouble(wsFontSize); + } + else if (L"RenderTransform" == wsAttrName) + { + std::wstring wsTransform = oReader.GetText(); + if (!wsTransform.empty()) + { + TransformToRenderer(wsTransform, pRenderer, pState); + bTransform = true; + + if (dFontSize < 5) + { + double dDet = pState->NormalizeTransform(); + dFontSize *= dDet; + pState->SetTransformToRenderer(pRenderer); + } + } + } + else if (L"UnicodeString" == wsAttrName) + { + wsText = oReader.GetText(); + nTextLen = wsText.length(); + } + else if (L"OriginX" == wsAttrName) + { + std::wstring wsTextX = oReader.GetText(); + dX = GetDouble(wsTextX); + } + else if (L"OriginY" == wsAttrName) + { + std::wstring wsTextY = oReader.GetText(); + dY = GetDouble(wsTextY); + } + else if (L"Indices" == wsAttrName) + { + wsIndicies = oReader.GetText(); + } + + if (!oReader.MoveToNextAttribute()) + break; + + wsAttrName = oReader.GetName(); + } + } + oReader.MoveToElement(); + + pRenderer->put_BrushColor1(nBgr & 0x00FFFFFF); + pRenderer->put_BrushAlpha1(nAlpha); + pRenderer->put_BrushType(c_BrushTypeSolid); + pRenderer->put_FontSize(dFontSize * 0.75); + + std::wstring wsChar = wsText.substr(0, 1); + std::vector> arrElements = Split(wsIndicies, L';', L','); + + m_pFontManager->LoadFontFromFile(wsFontPath, 0, (float)(dFontSize * 0.75), 96, 96); + for (int nIndex = 0; nIndex < nTextLen - 1; nIndex++) + { + if (nIndex >= arrElements.size()) + arrElements.push_back(std::vector()); + + pRenderer->CommandDrawText(wsChar, xpsUnitToMM(dX), xpsUnitToMM(dY), 0, 0, 0); + + if (arrElements.at(nIndex).size() >= 2) + { + dX += GetDouble(arrElements.at(nIndex).at(1)) * dFontSize / 100.0; + } + else + { + m_pFontManager->LoadString1(wsChar, 0, 0); + TBBox oBox = m_pFontManager->MeasureString2(); + dX += (oBox.fMaxX - oBox.fMinX); + } + + wsChar = wsText.substr(nIndex + 1, 1); + } + + if (nTextLen > 0) + { + pRenderer->CommandDrawText(wsChar, xpsUnitToMM(dX), xpsUnitToMM(dY), 0, 0, 0); + } + + if (bTransform) + ResetTransform(pRenderer, pState); + } void Page::CanvasTransform(XmlUtils::CXmlNode& oRootNode, IRenderer* pRenderer, CContextState* pState) { XmlUtils::CXmlNode oTransformNode; @@ -562,6 +917,24 @@ namespace XPS std::wstring wsMatrix = oTransformNode.GetAttribute(L"Matrix"); TransformToRenderer(wsMatrix, pRenderer, pState); } + void Page::CanvasTransform(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState) + { + std::wstring wsNodeName; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + wsNodeName = oReader.GetName(); + wsNodeName = RemoveNamespace(wsNodeName); + + if (L"MatrixTransform" == wsNodeName) + { + std::wstring wsMatrix; + ReadAttribute(oReader, L"Matrix", wsMatrix); + TransformToRenderer(wsMatrix, pRenderer, pState); + break; + } + } + } void Page::DrawPath(XmlUtils::CXmlNode& oRootNode, IRenderer* pRenderer, CContextState* pState) { bool bTransform = false; @@ -636,6 +1009,121 @@ namespace XPS if (bTransform) ResetTransform(pRenderer, pState); } + void Page::DrawPath(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState) + { + bool bTransform = false; + bool bFillSetted = false; + double dPenSize = 1.0; + std::wstring wsData; + bool bStroke = false; + if (oReader.MoveToFirstAttribute()) + { + std::wstring wsAttrName = oReader.GetName(); + while (!wsAttrName.empty()) + { + if (L"RenderTransform" == wsAttrName) + { + std::wstring wsTransform = oReader.GetText(); + if (!wsTransform.empty()) + { + TransformToRenderer(wsTransform, pRenderer, pState); + bTransform = true; + } + } + else if (L"Stroke" == wsAttrName) + { + int nStrokeAlpha = 255, nStrokeBgr = 0; + std::wstring wsStrokeColor = oReader.GetText(); + GetBgra(wsStrokeColor, nStrokeBgr, nStrokeAlpha); + pRenderer->put_PenColor(nStrokeBgr & 0x00FFFFFF); + pRenderer->put_PenAlpha(nStrokeAlpha); + bStroke = true; + } + else if (L"StrokeThickness" == wsAttrName) + { + std::wstring wsPenSize = oReader.GetText(); + dPenSize = GetDouble(wsPenSize); + } + else if (L"Fill" == wsAttrName) + { + bFillSetted = true; + std::wstring wsFill = oReader.GetText(); + int nFillBgra, nFillAlpha; + GetBgra(wsFill, nFillBgra, nFillAlpha); + pRenderer->put_BrushType(c_BrushTypeSolid); + pRenderer->put_BrushColor1(nFillBgra & 0x00FFFFFF); + pRenderer->put_BrushAlpha1(nFillAlpha); + } + else if (L"Data" == wsAttrName) + { + wsData = oReader.GetText(); + } + + if (!oReader.MoveToNextAttribute()) + break; + + wsAttrName = oReader.GetName(); + } + } + oReader.MoveToElement(); + + pRenderer->put_PenSize(xpsUnitToMM(dPenSize)); + + bool bFill = bFillSetted; + if (!bFillSetted) + { + if (!oReader.IsEmptyNode()) + { + std::wstring wsNodeName; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + wsNodeName = oReader.GetName(); + wsNodeName = RemoveNamespace(wsNodeName); + + if (L"Path.Fill" == wsNodeName) + { + bFill = FillToRenderer(oReader, pRenderer); + } + } + } + } + + if (L"" == wsData) + ReadPathData(oReader, wsData); + + if (L'{' == wsData[0]) + { + std::wstring wsValue = pState->GetFigure(wsData); + if (L"" != wsValue) + wsData = wsValue; + else + { + if (bTransform) + ResetTransform(pRenderer, pState); + + return; + } + } + + pRenderer->BeginCommand(c_nPathType); + pRenderer->PathCommandStart(); + + bool bWindingFillMode = false; + if (L'{' != wsData[0]) + bWindingFillMode = VmlToRenderer(wsData, pRenderer); + + int nMode = bStroke ? c_nStroke : 0; + if (bFill) + nMode |= (bWindingFillMode ? c_nWindingFillMode : c_nEvenOddFillMode); + + pRenderer->DrawPath(nMode); + pRenderer->EndCommand(c_nPathType); + pRenderer->PathCommandEnd(); + + if (bTransform) + ResetTransform(pRenderer, pState); + } void Page::FillToRenderer(XmlUtils::CXmlNode& oRootNode, IRenderer* pRenderer) { XmlUtils::CXmlNode oBrushNode; @@ -660,6 +1148,41 @@ namespace XPS pRenderer->put_BrushAlpha2(0); } } + bool Page::FillToRenderer(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer) + { + if (!oReader.IsEmptyNode()) + { + std::wstring wsNodeName; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + wsNodeName = oReader.GetName(); + wsNodeName = RemoveNamespace(wsNodeName); + + if (L"SolidColorBrush" == wsNodeName) + { + int nBgr, nAlpha; + std::wstring wsColor; + ReadAttribute(oReader, L"Color", wsColor); + GetBgra(wsColor, nBgr, nAlpha); + pRenderer->put_BrushType(c_BrushTypeSolid); + pRenderer->put_BrushColor1(nBgr & 0x00FFFFFF); + pRenderer->put_BrushAlpha1(nAlpha); + return true; + } + else if (L"ImageBrush" == wsNodeName) + { + std::wstring wsImageSource; + ReadAttribute(oReader, L"ImageSource", wsImageSource); + pRenderer->put_BrushType(c_BrushTypeTexture); + pRenderer->put_BrushTexturePath(m_wsRootPath + wsImageSource); + return true; + } + } + } + + return false; + } void Page::GetDataFromNode(std::wstring& wsString, XmlUtils::CXmlNode& oNode) { wsString = L""; @@ -736,4 +1259,135 @@ namespace XPS wsString += L" Z "; } } + void Page::ReadPathData(XmlUtils::CXmlLiteReader& oReader, std::wstring& wsData) + { + wsData = L""; + + if (oReader.IsEmptyNode()) + return; + + std::wstring wsNodeName; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + wsNodeName = oReader.GetName(); + if (L"Path.Data" == wsNodeName) + { + if (!oReader.IsEmptyNode()) + { + int nDataDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + wsNodeName = oReader.GetName(); + if (L"PathGeometry" == wsNodeName) + { + return ReadPathGeometry(oReader, wsData); + } + } + } + } + } + } + void Page::ReadPathGeometry(XmlUtils::CXmlLiteReader& oReader, std::wstring& wsData) + { + if (oReader.IsEmptyNode()) + return; + + std::wstring wsFillMode; + ReadAttribute(oReader, L"FillRule", wsFillMode); + + if (L"EvenOdd" == wsFillMode) + wsData += L"F 0 "; + else + wsData += L"F 1 "; + + std::wstring wsNodeName; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + wsNodeName = oReader.GetName(); + if (L"PathFigure" == wsNodeName) + { + ReadPathFigure(oReader, wsData); + } + } + } + void Page::ReadPathFigure(XmlUtils::CXmlLiteReader& oReader, std::wstring& wsData) + { + if (oReader.IsEmptyNode()) + return; + + std::wstring wsStartPoint; + ReadAttribute(oReader, L"StartPoint", wsStartPoint); + wsData += L" M " + wsStartPoint; + + std::wstring wsNodeName; + std::wstring wsText; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + wsNodeName = oReader.GetName(); + wsText.empty(); + if (L"PolyLineSegment" == wsNodeName) + { + ReadAttribute(oReader, L"Points", wsText); + wsData += L" L " + wsText; + } + else if (L"PolyBezierSegment" == wsNodeName) + { + ReadAttribute(oReader, L"Points", wsText); + wsData += L" C " + wsText; + } + else if (L"PolyQuadraticBezierSegment" == wsNodeName) + { + ReadAttribute(oReader, L"Points", wsText); + wsData += L" Q " + wsText; + } + else if (L"ArcSegment" == wsNodeName) + { + std::wstring wsSize, wsRotationAngle, wsIsLargeArc, wsSweepDirection, wsPoint; + if (oReader.MoveToFirstAttribute()) + { + std::wstring wsAttrName = oReader.GetName(); + while (!wsAttrName.empty()) + { + if (L"Size" == wsAttrName) + wsSize = oReader.GetText(); + else if (L"RotationAngle" == wsAttrName) + wsRotationAngle = oReader.GetText(); + else if (L"IsLargeArc" == wsAttrName) + wsIsLargeArc = oReader.GetText(); + else if (L"SweepDirection" == wsAttrName) + wsSweepDirection = oReader.GetText(); + else if (L"Point" == wsAttrName) + wsPoint = oReader.GetText(); + + if (!oReader.MoveToNextAttribute()) + break; + + wsAttrName = oReader.GetName(); + } + oReader.MoveToElement(); + } + + wsData += L" A " + wsSize + L" " + wsRotationAngle + L" "; + if (GetBool(wsIsLargeArc)) + wsData += L"1 "; + else + wsData += L"0 "; + + if (L"Counterclockwise" == wsSweepDirection) + wsData += L"0 "; + else + wsData += L"1 "; + + wsData += wsPoint; + } + } + + std::wstring wsClosed; + ReadAttribute(oReader, L"IsClosed", wsClosed); + if (GetBool(wsClosed)) + wsData += L" Z "; + } } \ No newline at end of file diff --git a/XpsFile/XpsLib/Page.h b/XpsFile/XpsLib/Page.h index eafba20053..655229a9d9 100644 --- a/XpsFile/XpsLib/Page.h +++ b/XpsFile/XpsLib/Page.h @@ -11,10 +11,12 @@ namespace XPS { + class CDocument; + class Page { public: - Page(const std::wstring& wsFile, const std::wstring& Path, CFontList* pFontList, CFontManager* pFontManager); + Page(const std::wstring& wsFile, const std::wstring& Path, CFontList* pFontList, CFontManager* pFontManager, CDocument* pDocument); ~Page(); void GetSize(int& nW, int& nH) const; @@ -22,14 +24,24 @@ namespace XPS private: + void DrawCanvas(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState, bool* pbBreak); + void ReadPageResources(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState); + void DrawGlyph(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState); + void CanvasTransform(XmlUtils::CXmlLiteReader& oRNode, IRenderer* pRenderer, CContextState* pState); + void DrawPath(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState); + bool FillToRenderer(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer); + void ReadPathData(XmlUtils::CXmlLiteReader& oReader, std::wstring& wsData); + void ReadPathGeometry(XmlUtils::CXmlLiteReader& oReader, std::wstring& wsData); + void ReadPathFigure(XmlUtils::CXmlLiteReader& oReader, std::wstring& wsData); + void DrawCanvas(XmlUtils::CXmlNode& oNode, IRenderer* pRenderer, CContextState* pState, bool* pbBreak); void DrawGlyph(XmlUtils::CXmlNode& oNode, IRenderer* pRenderer, CContextState* pState); void DrawPath(XmlUtils::CXmlNode& oNode, IRenderer* pRenderer, CContextState* pState); void CanvasTransform(XmlUtils::CXmlNode& oNode, IRenderer* pRenderer, CContextState* pState); void FillToRenderer(XmlUtils::CXmlNode& oNode, IRenderer* pRenderer); + void GetDataFromNode(std::wstring& wsString, XmlUtils::CXmlNode& oNode); bool VmlToRenderer(std::wstring& wsValue, IRenderer* pRenderer); - void GetDataFromNode(std::wstring& wsString, XmlUtils::CXmlNode& oNode); void TransformToRenderer(const std::wstring& wsString, IRenderer* pRenderer, CContextState* pState); void ResetTransform(IRenderer* pRenderer, CContextState* pState); @@ -41,6 +53,7 @@ namespace XPS std::wstring m_wsRootPath; CFontList* m_pFontList; CFontManager* m_pFontManager; + CDocument* m_pDocument; }; } diff --git a/XpsFile/XpsLib/Utils.cpp b/XpsFile/XpsLib/Utils.cpp index 9d98f6dff9..986d5a7e51 100644 --- a/XpsFile/XpsLib/Utils.cpp +++ b/XpsFile/XpsLib/Utils.cpp @@ -1,6 +1,7 @@ #include "Utils.h" #include "../../DesktopEditor/common/String.h" #include "../../DesktopEditor/common/Types.h" +#include "../../Common/DocxFormat/Source/XML/xmlutils.h" namespace XPS { @@ -149,4 +150,29 @@ namespace XPS } return arrResult; } + void ReadAttribute(XmlUtils::CXmlLiteReader& oReader, const wchar_t* wsAttrName, std::wstring& wsAttr) + { + if (oReader.GetAttributesCount() <= 0) + return; + + if (!oReader.MoveToFirstAttribute()) + return; + + std::wstring wsName = oReader.GetName(); + + while (!wsName.empty()) + { + if (wsAttrName == wsName) + { + wsAttr = oReader.GetText(); + break; + } + if (!oReader.MoveToNextAttribute()) + break; + + wsName = oReader.GetName(); + } + + oReader.MoveToElement(); + } } \ No newline at end of file diff --git a/XpsFile/XpsLib/Utils.h b/XpsFile/XpsLib/Utils.h index 3cdaa067cf..ebc5de2a7e 100644 --- a/XpsFile/XpsLib/Utils.h +++ b/XpsFile/XpsLib/Utils.h @@ -4,6 +4,11 @@ #include #include +namespace XmlUtils +{ + class CXmlLiteReader; +} + namespace XPS { bool IsAlpha(wchar_t wChar); @@ -19,6 +24,8 @@ namespace XPS std::wstring RemoveNamespace(const std::wstring& wsString); std::vector> Split(const std::wstring& wsString, wchar_t wDelim1, wchar_t wDelim2); + + void ReadAttribute(XmlUtils::CXmlLiteReader& oReader, const wchar_t* wsAttrName, std::wstring& wsAttr); } #endif // _XPS_XPSLIB_UTILS_H \ No newline at end of file