new PdfReader and PdfWriter for PdfFile

This commit is contained in:
Kulikova Svetlana
2022-11-02 17:50:50 +03:00
parent c2f6f2d1b5
commit e27a20f9ae
12 changed files with 6026 additions and 32 deletions

View File

@ -1,6 +1,38 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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-12 Ernesta Birznieka-Upisha
* 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 "PdfFile.h"
#include "../PdfWriter/PdfRenderer.h"
#include "../PdfReader/PdfReader.h"
#include "Src/PdfWriter.h"
#include "Src/OnlineOfficeBinToPdf.h"
#include "Src/PdfReader.h"
#include "../PdfReader/Src/Adaptors.h"
#include "../DesktopEditor/common/File.h"
@ -127,11 +159,12 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary,
class CPdfFile_Private
{
public:
CPdfRenderer* pWriter;
CPdfWriter* pWriter;
PdfReader::CPdfReader* pReader;
std::wstring wsSrcFile;
std::wstring wsPassword;
bool bEdit;
bool bEditPage;
void GetPageTree(XRef* xref, Object* pPagesRefObj)
{
@ -206,9 +239,11 @@ CPdfFile::CPdfFile(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA)
{
m_pInternal = new CPdfFile_Private();
m_pInternal->pWriter = new CPdfRenderer (pAppFonts, isPDFA);
m_pInternal->pWriter = new CPdfWriter(pAppFonts, isPDFA);
m_pInternal->pReader = new PdfReader::CPdfReader(pAppFonts);
m_pInternal->wsPassword = L"";
m_pInternal->bEdit = false;
m_pInternal->bEditPage = false;
}
// nMode = 1/2/3, 01 - reader, 10 - writer, 11 - editer
CPdfFile::CPdfFile(NSFonts::IApplicationFonts* pAppFonts, int nMode, bool isPDFA)
@ -218,8 +253,10 @@ CPdfFile::CPdfFile(NSFonts::IApplicationFonts* pAppFonts, int nMode, bool isPDFA
if (nMode & 1)
m_pInternal->pReader = new PdfReader::CPdfReader(pAppFonts);
if (nMode & 2)
m_pInternal->pWriter = new CPdfRenderer (pAppFonts, isPDFA);
m_pInternal->pWriter = new CPdfWriter(pAppFonts, isPDFA);
m_pInternal->wsPassword = L"";
m_pInternal->bEdit = false;
m_pInternal->bEditPage = false;
}
CPdfFile::~CPdfFile()
{
@ -401,7 +438,7 @@ bool CPdfFile::EditPdf(const std::wstring& wsDstFile)
if (bRes)
{
m_pInternal->GetPageTree(xref, &pagesRefObj);
m_pInternal->pWriter->EditPdf();
m_pInternal->bEdit = true;
}
pagesRefObj.free();
return bRes;
@ -410,7 +447,7 @@ bool CPdfFile::EditClose()
{
PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument();
PdfWriter::CDocument* pDoc = m_pInternal->pWriter->GetPDFDocument();
if (!pPDFDocument || !pDoc)
if (!pPDFDocument || !pDoc || !m_pInternal->bEdit)
return false;
XRef* xref = pPDFDocument->getXRef();
@ -499,13 +536,15 @@ bool CPdfFile::EditClose()
}
}
m_pInternal->bEdit = false;
m_pInternal->bEditPage = false;
return bRes;
}
bool CPdfFile::EditPage(int nPageIndex)
{
PDFDoc* pPDFDocument = m_pInternal->pReader->GetPDFDocument();
PdfWriter::CDocument* pDoc = m_pInternal->pWriter->GetPDFDocument();
if (!pPDFDocument || !pDoc)
if (!pPDFDocument || !pDoc || !m_pInternal->bEdit)
return false;
XRef* xref = pPDFDocument->getXRef();
@ -557,6 +596,7 @@ bool CPdfFile::EditPage(int nPageIndex)
pNewPage->Fix();
pageObj.free();
m_pInternal->bEditPage = true;
if (m_pInternal->pWriter->EditPage(pNewPage) && pDoc->EditPage(pXref, pNewPage))
return true;
@ -565,10 +605,14 @@ bool CPdfFile::EditPage(int nPageIndex)
}
bool CPdfFile::DeletePage(int nPageIndex)
{
if (!m_pInternal->bEdit)
return false;
return m_pInternal->pWriter->DeletePage(nPageIndex);
}
bool CPdfFile::AddPage(int nPageIndex)
{
if (!m_pInternal->bEdit)
return false;
bool bRes = m_pInternal->pWriter->AddPage(nPageIndex);
if (bRes)
{
@ -581,15 +625,20 @@ bool CPdfFile::AddPage(int nPageIndex)
m_pInternal->pWriter->put_Width(dWidth);
m_pInternal->pWriter->put_Height(dHeight);
m_pInternal->bEditPage = true;
}
return bRes;
}
void CPdfFile::Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate)
{
if (!m_pInternal->bEdit)
return;
m_pInternal->pWriter->Sign(dX, dY, dW, dH, wsPicturePath, pCertificate);
}
void CPdfFile::PageRotate(int nRotate)
{
if (!m_pInternal->bEdit)
return;
m_pInternal->pWriter->PageRotate(nRotate);
}
@ -642,7 +691,7 @@ void CPdfFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, do
}
void CPdfFile::DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak)
{
m_pInternal->pReader->DrawPageOnRenderer((pRenderer == this ? m_pInternal->pWriter : pRenderer), nPageIndex, pBreak);
m_pInternal->pReader->DrawPageOnRenderer(this, nPageIndex, pBreak);
}
std::wstring CPdfFile::GetInfo()
{
@ -679,11 +728,17 @@ void CPdfFile::SetTempFolder(const std::wstring& wsPath)
}
HRESULT CPdfFile::OnlineWordToPdf(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams)
{
return m_pInternal->pWriter->OnlineWordToPdf(wsSrcFile, wsDstFile, pParams);
if (!NSOnlineOfficeBinToPdf::ConvertBinToPdf(this, wsSrcFile, wsDstFile, false, pParams))
return S_FALSE;
return S_OK;
}
HRESULT CPdfFile::OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams)
{
return m_pInternal->pWriter->OnlineWordToPdfFromBinary(wsSrcFile, wsDstFile, pParams);
if (!NSOnlineOfficeBinToPdf::ConvertBinToPdf(this, wsSrcFile, wsDstFile, true, pParams))
return S_FALSE;
return S_OK;
}
HRESULT CPdfFile::DrawImageWith1bppMask(IGrObject* pImage, NSImages::CPixJbig2* pMaskBuffer, const unsigned int& unMaskWidth, const unsigned int& unMaskHeight, const double& dX, const double& dY, const double& dW, const double& dH)
{
@ -701,7 +756,10 @@ HRESULT CPdfFile::SetRadialGradient(const double& dX1, const double& dY1, const
{
return m_pInternal->pWriter->SetRadialGradient(dX1, dY1, dR1, dX2, dY2, dR2);
}
NSFonts::IApplicationFonts* CPdfFile::GetApplicationFonts()
{
return m_pInternal->pWriter->GetApplicationFonts();
}
HRESULT CPdfFile::get_Type(LONG* lType)
{
@ -709,6 +767,8 @@ HRESULT CPdfFile::get_Type(LONG* lType)
}
HRESULT CPdfFile::NewPage()
{
if (m_pInternal->bEdit)
return S_FALSE;
return m_pInternal->pWriter->NewPage();
}
HRESULT CPdfFile::get_Height(double* dHeight)
@ -717,6 +777,8 @@ HRESULT CPdfFile::get_Height(double* dHeight)
}
HRESULT CPdfFile::put_Height(const double& dHeight)
{
if (m_pInternal->bEdit && m_pInternal->bEditPage)
return S_OK;
return m_pInternal->pWriter->put_Height(dHeight);
}
HRESULT CPdfFile::get_Width(double* dWidth)
@ -725,6 +787,8 @@ HRESULT CPdfFile::get_Width(double* dWidth)
}
HRESULT CPdfFile::put_Width(const double& dWidth)
{
if (m_pInternal->bEdit && m_pInternal->bEditPage)
return S_OK;
return m_pInternal->pWriter->put_Width(dWidth);
}
HRESULT CPdfFile::get_DpiX(double* dDpiX)

View File

@ -1,3 +1,34 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
#ifndef _PDF_FILE_H
#define _PDF_FILE_H
@ -8,11 +39,9 @@
#define PDFFILE_DECL_EXPORT Q_DECL_EXPORT
#endif
#include "../DesktopEditor/graphics/pro/officedrawingfile.h"
#include "../DesktopEditor/graphics/IRenderer.h"
#include "../DesktopEditor/graphics/pro/Fonts.h"
#include "../DesktopEditor/graphics/pro/Image.h"
#include "../DesktopEditor/graphics/pro/officedrawingfile.h"
#include "../DesktopEditor/xmlsec/src/include/Certificate.h"
class CPdfFile_Private;
@ -108,7 +137,7 @@ public:
HRESULT DrawImage1bpp(NSImages::CPixJbig2* pImageBuffer, const unsigned int& unWidth, const unsigned int& unHeight, const double& dX, const double& dY, const double& dW, const double& dH);
HRESULT SetLinearGradient(const double& dX1, const double& dY1, const double& dX2, const double& dY2);
HRESULT SetRadialGradient(const double& dX1, const double& dY1, const double& dR1, const double& dX2, const double& dY2, const double& dR2);
NSFonts::IApplicationFonts* GetApplicationFonts();
//----------------------------------------------------------------------------------------
// Тип рендерера

View File

@ -56,15 +56,13 @@ SOURCES -= \
SOURCES += \
$$PDFREADER_ROOT_DIR/Src/RendererOutputDev.cpp \
$$PDFREADER_ROOT_DIR/Src/Adaptors.cpp \
$$PDFREADER_ROOT_DIR/Src/GfxClip.cpp \
$$PDFREADER_ROOT_DIR/PdfReader.cpp
$$PDFREADER_ROOT_DIR/Src/GfxClip.cpp
HEADERS += \
$$PDFREADER_ROOT_DIR/Src/RendererOutputDev.h \
$$PDFREADER_ROOT_DIR/Src/Adaptors.h \
$$PDFREADER_ROOT_DIR/Src/MemoryUtils.h \
$$PDFREADER_ROOT_DIR/Src/GfxClip.h \
$$PDFREADER_ROOT_DIR/PdfReader.h
$$PDFREADER_ROOT_DIR/Src/GfxClip.h
# Base fonts
HEADERS += \
@ -165,8 +163,6 @@ HEADERS += \
$$PDFWRITER_ROOT_DIR/Src/Streams.h \
$$PDFWRITER_ROOT_DIR/Src/Types.h \
$$PDFWRITER_ROOT_DIR/Src/Utils.h \
$$PDFWRITER_ROOT_DIR/OnlineOfficeBinToPdf.h \
$$PDFWRITER_ROOT_DIR/PdfRenderer.h \
$$PDFWRITER_ROOT_DIR/Src/Metadata.h \
$$PDFWRITER_ROOT_DIR/Src/ICCProfile.h
@ -195,11 +191,16 @@ SOURCES += \
$$PDFWRITER_ROOT_DIR/Src/Shading.cpp \
$$PDFWRITER_ROOT_DIR/Src/Streams.cpp \
$$PDFWRITER_ROOT_DIR/Src/Utils.cpp \
$$PDFWRITER_ROOT_DIR/Src/Metadata.cpp \
$$PDFWRITER_ROOT_DIR/OnlineOfficeBinToPdf.cpp \
$$PDFWRITER_ROOT_DIR/PdfRenderer.cpp
$$PDFWRITER_ROOT_DIR/Src/Metadata.cpp
# PdfFile
HEADERS += PdfFile.h
SOURCES += PdfFile.cpp
HEADERS += PdfFile.h \
Src/PdfWriter.h \
Src/PdfReader.h \
Src/OnlineOfficeBinToPdf.h
SOURCES += PdfFile.cpp \
Src/PdfWriter.cpp \
Src/PdfReader.cpp \
Src/OnlineOfficeBinToPdf.cpp

View File

@ -0,0 +1,148 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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-12 Ernesta Birznieka-Upisha
* 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 "OnlineOfficeBinToPdf.h"
#include "../../DesktopEditor/common/File.h"
#include "../../DesktopEditor/common/Directory.h"
#include "../../DesktopEditor/common/Base64.h"
#include "../../DesktopEditor/graphics/MetafileToRenderer.h"
namespace NSOnlineOfficeBinToPdf
{
class CMetafileToRenderterPDF : public IMetafileToRenderter
{
public:
CMetafileToRenderterPDF(IRenderer* pRenderer) : IMetafileToRenderter(pRenderer)
{
}
public:
virtual void SetLinearGradiant(const double& x0, const double& y0, const double& x1, const double& y1)
{
((CPdfFile*)m_pRenderer)->SetLinearGradient(x0, y0, x1, y1);
}
virtual void SetRadialGradiant(const double& dX0, const double& dY0, const double& dR0, const double& dX1, const double& dY1, const double& dR1)
{
((CPdfFile*)m_pRenderer)->SetRadialGradient(dX0, dY0, dR0, dX1, dY1, dR1);
}
};
static bool ConvertBufferToPdf(CPdfFile* pPdf, BYTE* pBuffer, LONG lBufferLen, CConvertFromBinParams* pParams)
{
CMetafileToRenderterPDF oCorrector(pPdf);
oCorrector.SetTempDirectory(pPdf->GetTempDirectory());
if (pParams)
{
oCorrector.SetMediaDirectory(pParams->m_sMediaDirectory);
oCorrector.SetInternalMediaDirectory(pParams->m_sInternalMediaDirectory);
oCorrector.SetThemesDirectory(pParams->m_sThemesDirectory);
if (pParams->m_bIsUsePicker)
oCorrector.InitPicker(pPdf->GetApplicationFonts());
}
NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(pBuffer, lBufferLen, &oCorrector);
return true;
}
bool ConvertBinToPdf(CPdfFile* pPdf, const std::wstring& wsSrcFile, const std::wstring& wsDstFile, bool bBinary, CConvertFromBinParams* pParams)
{
NSFile::CFileBinary oFile;
if (!oFile.OpenFile(wsSrcFile))
return false;
DWORD dwFileSize = oFile.GetFileSize();
BYTE* pFileContent = new BYTE[dwFileSize];
if (!pFileContent)
{
oFile.CloseFile();
return false;
}
DWORD dwReaded;
oFile.ReadFile(pFileContent, dwFileSize, dwReaded);
oFile.CloseFile();
bool bIsNeedDestroy = (NULL == pParams) ? true : false;
if (bIsNeedDestroy)
pParams = new CConvertFromBinParams();
if (pParams->m_sMediaDirectory.empty())
pParams->m_sMediaDirectory = NSFile::GetDirectoryName(wsSrcFile);
if (bBinary)
{
ConvertBufferToPdf(pPdf, pFileContent, dwFileSize, pParams);
}
else
{
int nBufferLen = NSBase64::Base64DecodeGetRequiredLength(dwFileSize);
BYTE* pBuffer = new BYTE[nBufferLen];
if (!pBuffer)
{
RELEASEARRAYOBJECTS(pFileContent);
if (bIsNeedDestroy)
RELEASEOBJECT(pParams);
return false;
}
if (NSBase64::Base64Decode((const char*)pFileContent, dwFileSize, pBuffer, &nBufferLen))
{
ConvertBufferToPdf(pPdf, pBuffer, nBufferLen, pParams);
}
else
{
RELEASEARRAYOBJECTS(pBuffer);
RELEASEARRAYOBJECTS(pFileContent);
if (bIsNeedDestroy)
RELEASEOBJECT(pParams);
return false;
}
RELEASEARRAYOBJECTS(pBuffer);
}
RELEASEARRAYOBJECTS(pFileContent);
if (bIsNeedDestroy)
RELEASEOBJECT(pParams);
if (!wsDstFile.empty())
{
if (0 != pPdf->SaveToFile(wsDstFile))
return false;
}
return true;
}
}

View File

@ -0,0 +1,44 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
#ifndef _PDF_WRITER_ONLINEOFFICEBINTOPDF_H
#define _PDF_WRITER_ONLINEOFFICEBINTOPDF_H
#include <string>
#include "../PdfFile.h"
namespace NSOnlineOfficeBinToPdf
{
bool ConvertBinToPdf(CPdfFile* pPdf, const std::wstring& wsSrcFile, const std::wstring& wsDstFile, bool bBinary, CConvertFromBinParams* pParams);
}
#endif // _PDF_WRITER_ONLINEOFFICEBINTOPDF_H

787
PdfFile/Src/PdfReader.cpp Normal file
View File

@ -0,0 +1,787 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
#define errMemory 12
#include "../../DesktopEditor/graphics/pro/Graphics.h"
#include "PdfReader.h"
#include "../../PdfReader/Src/Adaptors.h"
#include "../../PdfReader/lib/xpdf/ErrorCodes.h"
#include "../../Common/OfficeDefines.h"
#include "../../DesktopEditor/raster/BgraFrame.h"
#include "../../DesktopEditor/graphics/IRenderer.h"
#include "../../DesktopEditor/common/Directory.h"
#include "../../DesktopEditor/common/StringExt.h"
#include "../../DesktopEditor/common/Path.h"
#include "../../PdfWriter/PdfRenderer.h"
#include "../../PdfReader/lib/xpdf/PDFDoc.h"
#include "../../PdfReader/lib/xpdf/GlobalParams.h"
#include "../../PdfReader/lib/xpdf/ErrorCodes.h"
#include "../../PdfReader/lib/xpdf/ImageOutputDev.h"
#include "../../PdfReader/lib/xpdf/TextString.h"
#include "../../PdfReader/lib/xpdf/SecurityHandler.h"
#include "../../PdfReader/lib/xpdf/Lexer.h"
#include "../../PdfReader/lib/xpdf/Parser.h"
#include "../../PdfReader/lib/xpdf/AcroForm.h"
#include "../../PdfReader/Src/RendererOutputDev.h"
#include "../../PdfReader/Src/Adaptors.h"
#ifdef BUILDING_WASM_MODULE
#include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h"
#include "../../PdfReader/lib/xpdf/Outline.h"
#include "../../PdfReader/lib/xpdf/Link.h"
#include "../../PdfReader/lib/xpdf/TextOutputDev.h"
#include "../../PdfReader/lib/goo/GList.h"
#include <vector>
#endif
namespace PdfReader
{
class CPdfReader_Private
{
public:
PDFDoc* m_pPDFDocument;
std::wstring m_wsTempFolder;
std::wstring m_wsCMapFolder;
std::wstring m_wsSrcPath;
NSFonts::IApplicationFonts* m_pAppFonts;
NSFonts::IFontManager* m_pFontManager;
CFontList* m_pFontList;
DWORD m_nFileLength;
};
CPdfReader::CPdfReader(NSFonts::IApplicationFonts* pAppFonts)
{
m_pInternal = new CPdfReader_Private();
m_pInternal->m_wsTempFolder = L"";
m_pInternal->m_wsCMapFolder = L"";
m_pInternal->m_wsSrcPath = L"";
m_pInternal->m_pPDFDocument = NULL;
m_pInternal->m_pFontManager = NULL;
m_pInternal->m_nFileLength = 0;
globalParams = new GlobalParamsAdaptor(NULL);
#ifndef _DEBUG
globalParams->setErrQuiet(gTrue);
#endif
m_pInternal->m_pFontList = new CFontList();
m_pInternal->m_pAppFonts = pAppFonts;
// Создаем менеджер шрифтов с собственным кэшем
m_pInternal->m_pFontManager = pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
pMeasurerCache->SetStreams(pAppFonts->GetStreams());
m_pInternal->m_pFontManager->SetOwnerCache(pMeasurerCache);
pMeasurerCache->SetCacheSize(1);
((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pInternal->m_pFontManager);
#ifndef BUILDING_WASM_MODULE
globalParams->setupBaseFonts(NULL);
#endif
#ifdef CMAP_USE_MEMORY
SetCMapMemory();
#endif
m_eError = errNone;
}
CPdfReader::~CPdfReader()
{
if (m_pInternal->m_pFontList)
{
m_pInternal->m_pFontList->Clear();
delete m_pInternal->m_pFontList;
}
m_pInternal->m_wsCMapFolder = L"";
if (!m_pInternal->m_wsTempFolder.empty())
{
NSDirectory::DeleteDirectory(m_pInternal->m_wsTempFolder);
m_pInternal->m_wsTempFolder = L"";
}
RELEASEOBJECT((m_pInternal->m_pPDFDocument));
RELEASEOBJECT((globalParams));
RELEASEINTERFACE((m_pInternal->m_pFontManager));
}
bool CPdfReader::LoadFromFile(const std::wstring& wsSrcPath, const std::wstring& wsOptions,
const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword)
{
// TODO: Сейчас при загрузке каждой новой картинки мы пересоздаем
// FontManager, потому что сейчас в нем кэш без ограничения.
//------------------------------------------------------
RELEASEINTERFACE((m_pInternal->m_pFontManager));
m_pInternal->m_pFontManager = m_pInternal->m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
pMeasurerCache->SetStreams(m_pInternal->m_pAppFonts->GetStreams());
m_pInternal->m_pFontManager->SetOwnerCache(pMeasurerCache);
pMeasurerCache->SetCacheSize(1);
((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pInternal->m_pFontManager);
//------------------------------------------------------
if (m_pInternal->m_pPDFDocument)
delete m_pInternal->m_pPDFDocument;
if (GetTempDirectory() == L"")
{
SetTempDirectory(NSDirectory::GetTempPath());
}
m_eError = errNone;
GString* owner_pswd = NSStrings::CreateString(wsOwnerPassword);
GString* user_pswd = NSStrings::CreateString(wsUserPassword);
// конвертим путь в utf8 - под виндой они сконвертят в юникод, а на остальных - так и надо
m_pInternal->m_wsSrcPath = wsSrcPath;
std::string sPathUtf8 = U_TO_UTF8(wsSrcPath);
m_pInternal->m_pPDFDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd);
delete owner_pswd;
delete user_pswd;
NSFile::CFileBinary oFile;
if (oFile.OpenFile(wsSrcPath))
{
m_pInternal->m_nFileLength = oFile.GetFileSize();
oFile.CloseFile();
}
if (m_pInternal->m_pPDFDocument)
m_eError = m_pInternal->m_pPDFDocument->getErrorCode();
else
m_eError = errMemory;
if (!m_pInternal->m_pPDFDocument || !m_pInternal->m_pPDFDocument->isOk())
{
RELEASEOBJECT(m_pInternal->m_pPDFDocument);
return false;
}
m_pInternal->m_pFontList->Clear();
return true;
}
bool CPdfReader::LoadFromMemory(BYTE* data, DWORD length, const std::wstring& options,
const std::wstring& owner_password, const std::wstring& user_password)
{
// TODO: Сейчас при загрузке каждой новой картинки мы пересоздаем
// FontManager, потому что сейчас в нем кэш без ограничения.
//------------------------------------------------------
RELEASEINTERFACE((m_pInternal->m_pFontManager));
m_pInternal->m_pFontManager = m_pInternal->m_pAppFonts->GenerateFontManager();
NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create();
pMeasurerCache->SetStreams(m_pInternal->m_pAppFonts->GetStreams());
m_pInternal->m_pFontManager->SetOwnerCache(pMeasurerCache);
pMeasurerCache->SetCacheSize(1);
((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pInternal->m_pFontManager);
//------------------------------------------------------
RELEASEOBJECT(m_pInternal->m_pPDFDocument);
m_eError = errNone;
GString* owner_pswd = NSStrings::CreateString(owner_password);
GString* user_pswd = NSStrings::CreateString(user_password);
Object obj;
obj.initNull();
// будет освобожден в деструкторе PDFDoc
BaseStream *str = new MemStream((char*)data, 0, length, &obj);
m_pInternal->m_pPDFDocument = new PDFDoc(str, owner_pswd, user_pswd);
m_pInternal->m_nFileLength = length;
delete owner_pswd;
delete user_pswd;
m_eError = m_pInternal->m_pPDFDocument ? m_pInternal->m_pPDFDocument->getErrorCode() : errMemory;
if (!m_pInternal->m_pPDFDocument || !m_pInternal->m_pPDFDocument->isOk())
{
RELEASEOBJECT(m_pInternal->m_pPDFDocument);
return false;
}
m_pInternal->m_pFontList->Clear();
return true;
}
void CPdfReader::Close()
{
RELEASEOBJECT((m_pInternal->m_pPDFDocument));
}
NSFonts::IApplicationFonts* CPdfReader::GetFonts()
{
return m_pInternal->m_pAppFonts;
}
int CPdfReader::GetError()
{
if (!m_pInternal->m_pPDFDocument)
return m_eError;
if (m_pInternal->m_pPDFDocument->isOk())
return 0;
return m_pInternal->m_pPDFDocument->getErrorCode();
}
int CPdfReader::GetPagesCount()
{
if (!m_pInternal->m_pPDFDocument)
return 0;
return m_pInternal->m_pPDFDocument->getNumPages();
}
double CPdfReader::GetVersion()
{
if (!m_pInternal->m_pPDFDocument)
return 0;
return m_pInternal->m_pPDFDocument->getPDFVersion();
}
int CPdfReader::GetPermissions()
{
if (!m_pInternal->m_pPDFDocument)
return 0;
int nPermissions = 0;
if (m_pInternal->m_pPDFDocument->okToPrint())
nPermissions += PERMISSION_PRINT;
if (m_pInternal->m_pPDFDocument->okToCopy())
nPermissions += PERMISSION_COPY;
if (m_pInternal->m_pPDFDocument->okToChange())
nPermissions += PERMISSION_CHANGE;
return nPermissions;
}
std::wstring CPdfReader::GetPageLabel(int nPageIndex)
{
if (!m_pInternal->m_pPDFDocument)
return std::wstring();
// todo label
// StringExt* seLabel = m_pInternal->m_pPDFDocument->GetPageLabels()->GetLabel(nPageIndex);
// if (seLabel)
// {
// std::wstring wsResult(seLabel->GetWString());
// delete seLabel;
// return wsResult;
// }
return std::wstring();
}
bool CPdfReader::ExtractAllImages(const wchar_t* wsDstPath, const wchar_t* wsPrefix)
{
std::wstring sDstPath(wsDstPath);
if (sDstPath.empty())
return false;
// check last symbol (directory)
wchar_t nLastSymbol = sDstPath[sDstPath.length() - 1];
if ('\\' != nLastSymbol && '/' != nLastSymbol)
sDstPath += '/';
// prefix for each file
if (NULL != wsPrefix)
sDstPath += std::wstring(wsPrefix);
std::string sDstPathA = U_TO_UTF8(sDstPath);
ImageOutputDev *pOutputDev = new ImageOutputDev((char*)sDstPathA.c_str(), true, false, false);
if (!pOutputDev)
return false;
int nPagesCount = GetPagesCount();
for (int nIndex = 1; nIndex <= nPagesCount; nIndex++)
{
m_pInternal->m_pPDFDocument->displayPage(pOutputDev, nIndex, 72, 72, 0, false, false, false);
}
delete pOutputDev;
return true;
}
void CPdfReader::GetPageInfo(int _nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY)
{
int nPageIndex = _nPageIndex + 1;
if (!m_pInternal->m_pPDFDocument)
return;
const double c_dInch = 25.399; // Миллиметров в дюйме
const double c_dXResolution = 154.0;
const double c_dYResolution = 154.0;
double dKoefX = c_dInch / c_dXResolution;
double dKoefY = c_dInch / c_dYResolution;
int nRotate = m_pInternal->m_pPDFDocument->getPageRotate(nPageIndex);
while (nRotate >= 360)
nRotate -= 360;
while (nRotate < 0)
nRotate += 360;
if (0 != nRotate && 180 != nRotate)
{
*pdHeight = m_pInternal->m_pPDFDocument->getPageCropWidth(nPageIndex);
*pdWidth = m_pInternal->m_pPDFDocument->getPageCropHeight(nPageIndex);
}
else
{
*pdWidth = m_pInternal->m_pPDFDocument->getPageCropWidth(nPageIndex);
*pdHeight = m_pInternal->m_pPDFDocument->getPageCropHeight(nPageIndex);
}
*pdDpiX = 72;
*pdDpiY = 72;
}
void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* pbBreak)
{
int nPageIndex = _nPageIndex + 1;
if (m_pInternal->m_pPDFDocument && pRenderer)
{
RendererOutputDev oRendererOut(pRenderer, m_pInternal->m_pFontManager, m_pInternal->m_pFontList);
oRendererOut.NewPDF(m_pInternal->m_pPDFDocument->getXRef());
oRendererOut.SetBreak(pbBreak);
m_pInternal->m_pPDFDocument->displayPage(&oRendererOut, nPageIndex, 72.0, 72.0, 0, false, true, false);
}
}
int CPdfReader::GetImagesCount()
{
// ImageOutputDev *pOutputDev = new ImageOutputDev(NULL, true, true, false);
// if (!pOutputDev)
// return 0;
//
// for (int nIndex = 1; nIndex <= m_pInternal->m_pPDFDocument->GetPagesCount(); nIndex++)
// {
// m_pInternal->m_pPDFDocument->displayPage(pOutputDev, nIndex, 72, 72, 0, false, false, false);
// }
//
// return pOutputDev->
return 0;
}
void CPdfReader::SetTempDirectory(const std::wstring& wsTempFolder)
{
if (!m_pInternal->m_wsTempFolder.empty())
{
NSDirectory::DeleteDirectory(m_pInternal->m_wsTempFolder);
m_pInternal->m_wsTempFolder = wsTempFolder;
}
if (!wsTempFolder.empty())
{
std::wstring wsFolderName = std::wstring(wsTempFolder) + L"//pdftemp";
std::wstring wsFolder = wsFolderName;
int nCounter = 0;
while (NSDirectory::Exists(wsFolder))
{
nCounter++;
wsFolder = wsFolderName + L"_" + std::to_wstring(nCounter);
}
NSDirectory::CreateDirectory(wsFolder);
m_pInternal->m_wsTempFolder = wsFolder;
}
else
m_pInternal->m_wsTempFolder = L"";
if (globalParams)
((GlobalParamsAdaptor*)globalParams)->SetTempFolder(m_pInternal->m_wsTempFolder.c_str());
}
std::wstring CPdfReader::GetTempDirectory()
{
return m_pInternal->m_wsTempFolder;
}
void CPdfReader::SetCMapFolder(const wchar_t* wsCMapFolder)
{
m_pInternal->m_wsCMapFolder = std::wstring(wsCMapFolder);
if (globalParams)
((GlobalParamsAdaptor*)globalParams)->SetCMapFolder(m_pInternal->m_wsCMapFolder.c_str());
}
void CPdfReader::SetCMapMemory()
{
if (globalParams)
((GlobalParamsAdaptor*)globalParams)->SetCMapMemory();
}
NSFonts::IFontManager* CPdfReader::GetFontManager()
{
return m_pInternal->m_pFontManager;
}
std::wstring CPdfReader::ToXml(const std::wstring& wsFilePath, bool isPrintStream)
{
XMLConverter oConverter(m_pInternal->m_pPDFDocument->getXRef(), isPrintStream);
std::wstring wsXml = oConverter.GetXml();
if (wsFilePath != L"")
{
NSFile::CFileBinary oFile;
if (!oFile.CreateFileW(wsFilePath))
return wsXml;
oFile.WriteStringUTF8(wsXml);
oFile.CloseFile();
}
return wsXml;
}
PDFDoc* CPdfReader::GetPDFDocument()
{
return m_pInternal->m_pPDFDocument;
}
void CPdfReader::ChangeLength(DWORD nLength)
{
m_pInternal->m_nFileLength = nLength;
}
#define DICT_LOOKUP(sName, wsName) \
if (info.dictLookup(sName, &obj1)->isString())\
{\
TextString* s = new TextString(obj1.getString());\
sRes += L"\"";\
sRes += wsName;\
sRes += L"\":\"";\
std::wstring sValue = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());\
NSStringExt::Replace(sValue, L"\"", L"\\\"");\
sRes += sValue;\
sRes += L"\",";\
delete s;\
}\
#define DICT_LOOKUP_DATE(sName, wsName) \
if (info.dictLookup(sName, &obj1)->isString())\
{\
char* str = obj1.getString()->getCString();\
if (str)\
{\
TextString* s = new TextString(obj1.getString());\
std::wstring sNoDate = NSStringExt::CConverter::GetUnicodeFromUTF32(s->getUnicode(), s->getLength());\
if (sNoDate.length() > 16)\
{\
std::wstring sDate = sNoDate.substr(2, 4) + L'-' + sNoDate.substr(6, 2) + L'-' + sNoDate.substr(8, 2) + L'T' +\
sNoDate.substr(10, 2) + L':' + sNoDate.substr(12, 2) + L':' + sNoDate.substr(14, 2);\
if (sNoDate.length() > 21)\
sDate += (L".000" + sNoDate.substr(16, 3) + L':' + sNoDate.substr(20, 2));\
else\
sDate += L"Z";\
NSStringExt::Replace(sDate, L"\"", L"\\\"");\
sRes += L"\"";\
sRes += wsName;\
sRes += L"\":\"";\
sRes += sDate;\
sRes += L"\",";\
}\
delete s;\
}\
}\
std::wstring CPdfReader::GetInfo()
{
if (!m_pInternal->m_pPDFDocument)
return NULL;
XRef* xref = m_pInternal->m_pPDFDocument->getXRef();
BaseStream* str = m_pInternal->m_pPDFDocument->getBaseStream();
if (!xref || !str)
return NULL;
std::wstring sRes = L"{";
Object info, obj1;
m_pInternal->m_pPDFDocument->getDocInfo(&info);
if (info.isDict())
{
DICT_LOOKUP("Title", L"Title");
DICT_LOOKUP("Author", L"Author");
DICT_LOOKUP("Subject", L"Subject");
DICT_LOOKUP("Keywords", L"Keywords");
DICT_LOOKUP("Creator", L"Creator");
DICT_LOOKUP("Producer", L"Producer");
DICT_LOOKUP_DATE("CreationDate", L"CreationDate");
DICT_LOOKUP_DATE("ModDate", L"ModDate");
}
info.free();
obj1.free();
std::wstring version = std::to_wstring(GetVersion());
std::wstring::size_type posDot = version.find('.');
if (posDot != std::wstring::npos)
version = version.substr(0, posDot + 2);
sRes += L"\"Version\":";
sRes += version;
double nW = 0;
double nH = 0;
double nDpi = 0;
GetPageInfo(0, &nW, &nH, &nDpi, &nDpi);
sRes += L",\"PageWidth\":";
sRes += std::to_wstring((int)(nW * 100));
sRes += L",\"PageHeight\":";
sRes += std::to_wstring((int)(nH * 100));
sRes += L",\"NumberOfPages\":";
sRes += std::to_wstring(GetPagesCount());
sRes += L",\"FastWebView\":";
Object obj2, obj3, obj4, obj5, obj6;
bool bLinearized = false;
obj1.initNull();
Parser* parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), gTrue);
parser->getObj(&obj1);
parser->getObj(&obj2);
parser->getObj(&obj3);
parser->getObj(&obj4);
if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && obj4.isDict())
{
obj4.dictLookup("Linearized", &obj5);
obj4.dictLookup("L", &obj6);
if (obj5.isNum() && obj5.getNum() > 0 && obj6.isNum())
{
unsigned long size = obj6.getNum();
bLinearized = size == m_pInternal->m_nFileLength;
}
obj6.free();
obj5.free();
}
obj4.free();
obj3.free();
obj2.free();
obj1.free();
delete parser;
sRes += bLinearized ? L"true" : L"false";
sRes += L",\"Tagged\":";
bool bTagged = false;
Object catDict, markInfoObj;
if (xref->getCatalog(&catDict) && catDict.isDict() && catDict.dictLookup("MarkInfo", &markInfoObj) && markInfoObj.isDict())
{
Object marked, suspects;
if (markInfoObj.dictLookup("Marked", &marked) && marked.isBool() && marked.getBool())
{
bTagged = true;
// If Suspects is true, the document may not completely conform to Tagged PDF conventions.
if (markInfoObj.dictLookup("Suspects", &suspects) && suspects.isBool() && suspects.getBool())
bTagged = false;
}
marked.free();
suspects.free();
}
markInfoObj.free();
catDict.free();
sRes += bTagged ? L"true" : L"false";
sRes += L"}";
return sRes;
}
#ifdef BUILDING_WASM_MODULE
void getBookmars(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, int level)
{
int nLengthTitle = pOutlineItem->getTitleLength();
Unicode* pTitle = pOutlineItem->getTitle();
std::string sTitle = NSStringExt::CConverter::GetUtf8FromUTF32(pTitle, nLengthTitle);
LinkAction* pLinkAction = pOutlineItem->getAction();
if (!pLinkAction)
return;
LinkActionKind kind = pLinkAction->getKind();
if (kind != actionGoTo)
return;
GString* str = ((LinkGoTo*)pLinkAction)->getNamedDest();
LinkDest* pLinkDest = str ? pdfDoc->findDest(str) : ((LinkGoTo*)pLinkAction)->getDest();
if (!pLinkDest)
return;
int pg;
if (pLinkDest->isPageRef())
{
Ref pageRef = pLinkDest->getPageRef();
pg = pdfDoc->findPage(pageRef.num, pageRef.gen);
}
else
pg = pLinkDest->getPageNum();
if (pg == 0)
pg = 1;
double dy = 0;
double dTop = pLinkDest->getTop();
double dHeight = pdfDoc->getPageCropHeight(pg);
if (dTop > 0 && dTop < dHeight)
dy = dHeight - dTop;
if (str)
RELEASEOBJECT(pLinkDest);
out.AddInt(pg - 1);
out.AddInt(level);
out.AddDouble(dy);
out.WriteString((BYTE*)sTitle.c_str(), sTitle.length());
pOutlineItem->open();
GList* pList = pOutlineItem->getKids();
if (!pList)
return;
int num = pList->getLength();
for (int i = 0; i < num; i++)
{
OutlineItem* pOutlineItemKid = (OutlineItem*)pList->get(i);
if (!pOutlineItemKid)
continue;
getBookmars(pdfDoc, pOutlineItemKid, out, level + 1);
}
pOutlineItem->close();
}
BYTE* CPdfReader::GetStructure()
{
if (!m_pInternal->m_pPDFDocument)
return NULL;
Outline* pOutline = m_pInternal->m_pPDFDocument->getOutline();
if (!pOutline)
return NULL;
GList* pList = pOutline->getItems();
if (!pList)
return NULL;
NSWasm::CData oRes;
oRes.SkipLen();
int num = pList->getLength();
for (int i = 0; i < num; i++)
{
OutlineItem* pOutlineItem = (OutlineItem*)pList->get(i);
if (pOutlineItem)
getBookmars(m_pInternal->m_pPDFDocument, pOutlineItem, oRes, 1);
}
oRes.WriteLen();
BYTE* bRes = oRes.GetBuffer();
oRes.ClearWithoutAttack();
return bRes;
}
BYTE* CPdfReader::GetLinks(int nPageIndex)
{
if (!m_pInternal->m_pPDFDocument)
return NULL;
nPageIndex++;
NSWasm::CPageLink oLinks;
double height = m_pInternal->m_pPDFDocument->getPageCropHeight(nPageIndex);
// Гиперссылка
Links* pLinks = m_pInternal->m_pPDFDocument->getLinks(nPageIndex);
if (!pLinks)
return NULL;
int num = pLinks->getNumLinks();
for (int i = 0; i < num; i++)
{
Link* pLink = pLinks->getLink(i);
if (!pLink)
continue;
GString* str = NULL;
double x1 = 0.0, y1 = 0.0, x2 = 0.0, y2 = 0.0, dy = 0.0;
pLink->getRect(&x1, &y1, &x2, &y2);
y1 = height - y1;
y2 = height - y2;
LinkAction* pLinkAction = pLink->getAction();
if (!pLinkAction)
continue;
LinkActionKind kind = pLinkAction->getKind();
if (kind == actionGoTo)
{
str = ((LinkGoTo*)pLinkAction)->getNamedDest();
LinkDest* pLinkDest = str ? m_pInternal->m_pPDFDocument->findDest(str) : ((LinkGoTo*)pLinkAction)->getDest()->copy();
if (pLinkDest)
{
int pg;
if (pLinkDest->isPageRef())
{
Ref pageRef = pLinkDest->getPageRef();
pg = m_pInternal->m_pPDFDocument->findPage(pageRef.num, pageRef.gen);
}
else
pg = pLinkDest->getPageNum();
std::string sLink = "#" + std::to_string(pg - 1);
str = new GString(sLink.c_str());
dy = m_pInternal->m_pPDFDocument->getPageCropHeight(pg) - pLinkDest->getTop();
}
RELEASEOBJECT(pLinkDest);
}
else if (kind == actionURI)
str = ((LinkURI*)pLinkAction)->getURI()->copy();
oLinks.m_arLinks.push_back({str ? std::string(str->getCString(), str->getLength()) : "", dy, x1, y2, x2 - x1, y1 - y2});
RELEASEOBJECT(str);
}
RELEASEOBJECT(pLinks);
// Текст-ссылка
TextOutputControl textOutControl;
textOutControl.mode = textOutReadingOrder;
TextOutputDev* pTextOut = new TextOutputDev(NULL, &textOutControl, gFalse);
m_pInternal->m_pPDFDocument->displayPage(pTextOut, nPageIndex, 72, 72, 0, gFalse, gTrue, gFalse);
m_pInternal->m_pPDFDocument->processLinks(pTextOut, nPageIndex);
TextWordList* pWordList = pTextOut->makeWordList();
for (int i = 0; i < pWordList->getLength(); i++)
{
TextWord* pWord = pWordList->get(i);
if (!pWord)
continue;
GString* sLink = pWord->getText();
if (!sLink)
continue;
std::string link(sLink->getCString(), sLink->getLength());
size_t find = link.find("http://");
if (find == std::string::npos)
find = link.find("https://");
if (find == std::string::npos)
find = link.find("www.");
if (find != std::string::npos)
{
link.erase(0, find);
double x1, y1, x2, y2;
pWord->getBBox(&x1, &y1, &x2, &y2);
oLinks.m_arLinks.push_back({link, 0, x1, y1, x2 - x1, y2 - y1});
}
}
RELEASEOBJECT(pTextOut);
return oLinks.Serialize();
}
#endif
}

109
PdfFile/Src/PdfReader.h Normal file
View File

@ -0,0 +1,109 @@
/*
* (c) Copyright Ascensio System SIA 2010-2019
*
* 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-12 Ernesta Birznieka-Upisha
* 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
*
*/
#ifndef _PDF_READER_H
#define _PDF_READER_H
#include "../../DesktopEditor/graphics/pro/Fonts.h"
#include "../../DesktopEditor/graphics/IRenderer.h"
class PDFDoc;
namespace PdfReader
{
typedef enum
{
errorNone = 0, // Нет ошибок
errorOpenFile = 1, // Ошибка при открытии PDF файла
errorBadCatalog = 2, // couldn't read the page catalog
errorDamaged = 3, // PDF файл был поврежден и его невозможно восстановить
errorEncrypted = 4, // Файл зашифрован, авторизация не пройдена
errorHighlightFile = 5, // nonexistent or invalid highlight file
errorBadPrinter = 6, // плохой принтер
errorPrinting = 7, // ошибка во время печати
errorPermission = 8, // Ошибка связанная с ограничениями наложенными на файл
errorBadPageNum = 9, // Неверное количество страниц
errorFileIO = 10, // Ошибка при чтении/записи
errorMemory = 11 // Memory exceed
} EError;
class CPdfReader_Private;
class CPdfReader
{
public:
CPdfReader(NSFonts::IApplicationFonts* fonts);
~CPdfReader();
bool LoadFromFile(const std::wstring& file, const std::wstring& options = L"",
const std::wstring& owner_password = L"", const std::wstring& user_password = L"");
bool LoadFromMemory(BYTE* data, DWORD length, const std::wstring& options = L"",
const std::wstring& owner_password = L"", const std::wstring& user_password = L"");
void Close();
NSFonts::IApplicationFonts* GetFonts();
std::wstring GetTempDirectory();
void SetTempDirectory(const std::wstring& directory);
int GetPagesCount();
void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY);
void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak);
std::wstring GetInfo();
int GetError();
double GetVersion();
int GetPermissions();
std::wstring GetPageLabel(int nPageIndex);
bool ExtractAllImages(const wchar_t* wsDstPath, const wchar_t* wsPrefix = 0);
int GetImagesCount();
void SetCMapFolder(const wchar_t* wsCMapFolder);
void SetCMapMemory();
NSFonts::IFontManager* GetFontManager();
std::wstring ToXml(const std::wstring& wsXmlPath, bool isPrintStreams = false);
PDFDoc* GetPDFDocument();
void ChangeLength(DWORD nLength);
#ifdef BUILDING_WASM_MODULE
BYTE* GetStructure();
BYTE* GetLinks(int nPageIndex);
#endif
private:
CPdfReader_Private* m_pInternal;
int m_eError;
};
}
#endif // _PDF_READER_H

2933
PdfFile/Src/PdfWriter.cpp Normal file

File diff suppressed because it is too large Load Diff

1864
PdfFile/Src/PdfWriter.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -80,7 +80,7 @@ int main()
return 0;
}
if (true)
if (false)
{
double dPageDpiX, dPageDpiY, dWidth, dHeight;
pdfFile.GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY);