Files
Yajbir Singh f1b860b25c
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

232 lines
6.7 KiB
C++

/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "XpsFile.h"
#include "XpsLib/Document.h"
#include "../DesktopEditor/common/File.h"
#include "../DesktopEditor/common/Directory.h"
#include "../DesktopEditor/graphics/pro/Graphics.h"
#include "../DesktopEditor/raster/BgraFrame.h"
#ifndef DISABLE_PDF_CONVERTATION
#include "../PdfFile/PdfFile.h"
#endif
#include "../OfficeUtils/src/OfficeUtils.h"
#include "../OfficeUtils/src/ZipFolder.h"
using namespace XPS;
class CXpsFile_Private
{
public:
NSFonts::IApplicationFonts* m_pAppFonts;
NSFonts::IFontManager* m_pFontManager;
IFolder* m_wsTempFolder;
XPS::CDocument* m_pDocument;
public:
CXpsFile_Private(NSFonts::IApplicationFonts* pAppFonts)
{
m_pDocument = NULL;
m_pAppFonts = pAppFonts;
// Создаем менеджер шрифтов с собственным кэшем
m_pFontManager = pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
pMeasurerCache->SetStreams(pAppFonts->GetStreams());
m_pFontManager->SetOwnerCache(pMeasurerCache);
pMeasurerCache->SetCacheSize(16);
m_wsTempFolder = NULL;
}
~CXpsFile_Private()
{
}
};
CXpsFile::CXpsFile(NSFonts::IApplicationFonts* pAppFonts)
{
m_pInternal = new CXpsFile_Private(pAppFonts);
}
CXpsFile::~CXpsFile()
{
Close();
RELEASEOBJECT(m_pInternal->m_wsTempFolder);
RELEASEINTERFACE((m_pInternal->m_pFontManager));
}
std::wstring CXpsFile::GetTempDirectory()
{
return m_pInternal->m_wsTempFolder->getFullFilePath(L"");
}
void CXpsFile::SetTempDirectory(const std::wstring& wsPath)
{
RELEASEOBJECT(m_pInternal->m_wsTempFolder);
int nCounter = 0;
std::wstring wsTempFolder = wsPath + L"/XPS/";
while (NSDirectory::Exists(wsTempFolder))
{
wsTempFolder = wsPath + L"/XPS" + std::to_wstring(nCounter) + L"/";
nCounter++;
}
NSDirectory::CreateDirectory(wsTempFolder);
m_pInternal->m_wsTempFolder = new CFolderSystem(wsTempFolder);
}
bool CXpsFile::LoadFromFile(const std::wstring& wsSrcFileName, const std::wstring& wsXmlOptions,
const std::wstring& owner_password, const std::wstring& user_password)
{
Close();
// Распаковываем Zip-архив в темповую папку
COfficeUtils oUtils(NULL);
if (S_OK != oUtils.ExtractToDirectory(wsSrcFileName, m_pInternal->m_wsTempFolder->getFullFilePath(L""), NULL, 0))
return false;
m_pInternal->m_pDocument = new XPS::CDocument(m_pInternal->m_pFontManager);
if (!m_pInternal->m_pDocument)
return false;
m_pInternal->m_pDocument->Read(m_pInternal->m_wsTempFolder);
return true;
}
bool CXpsFile::LoadFromMemory(BYTE* data, DWORD length, const std::wstring& options,
const std::wstring& owner_password, const std::wstring& user_password)
{
Close();
m_pInternal->m_wsTempFolder = new CZipFolderMemory(data, length);
m_pInternal->m_pDocument = new XPS::CDocument(m_pInternal->m_pFontManager);
if (!m_pInternal->m_pDocument)
return false;
m_pInternal->m_pDocument->Read(m_pInternal->m_wsTempFolder);
return true;
}
void CXpsFile::Close()
{
if (m_pInternal->m_pDocument)
{
m_pInternal->m_pDocument->Close();
delete m_pInternal->m_pDocument;
m_pInternal->m_pDocument = NULL;
m_pInternal->m_wsTempFolder = NULL;
}
}
NSFonts::IApplicationFonts* CXpsFile::GetFonts()
{
return m_pInternal->m_pAppFonts;
}
OfficeDrawingFileType CXpsFile::GetType()
{
return odftXPS;
}
int CXpsFile::GetPagesCount()
{
if (!m_pInternal->m_pDocument)
return 0;
return m_pInternal->m_pDocument->GetPageCount();
}
void CXpsFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY)
{
int nW = 0, nH = 0;
if (m_pInternal->m_pDocument)
m_pInternal->m_pDocument->GetPageSize(nPageIndex, nW, nH);
*pdWidth = nW * 25.4 / 96;
*pdHeight = nH * 25.4 / 96;
*pdDpiX = 25.4;
*pdDpiY = 25.4;
}
void CXpsFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak, COfficeDrawingPageParams* pParams)
{
if (!m_pInternal->m_pDocument)
return;
m_pInternal->m_pDocument->DrawPage(nPageIndex, pRenderer, pBreak);
}
std::wstring CXpsFile::GetInfo()
{
return m_pInternal->m_pDocument->GetInfo();
}
#ifndef DISABLE_PDF_CONVERTATION
void CXpsFile::ConvertToPdf(const std::wstring& wsPath)
{
CPdfFile oPdf(m_pInternal->m_pAppFonts);
oPdf.CreatePdf();
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);
}
#endif
BYTE* CXpsFile::GetStructure()
{
return m_pInternal->m_pDocument->GetStructure();
}
BYTE* CXpsFile::GetLinks (int nPageIndex)
{
return m_pInternal->m_pDocument->GetPageLinks(nPageIndex);
}