diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 5a06fc3f08..52b2897e35 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -650,6 +650,7 @@ void GetCTM(XRef* pXref, Object* oPage, double* dCTM) CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter) { m_wsSrcFile = _wsSrcFile; + m_wsDstFile = _wsDstFile; m_wsPassword = _wsPassword; m_pReader = _pReader; m_pWriter = _pWriter; @@ -665,7 +666,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } // Если результат редактирования будет сохранен в тот же файл, что открыт для чтения, то файл необходимо сделать редактируемым - std::string sPathUtf8New = U_TO_UTF8(_wsDstFile); + std::string sPathUtf8New = U_TO_UTF8(m_wsDstFile); std::string sPathUtf8Old = U_TO_UTF8(m_wsSrcFile); if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) { @@ -680,15 +681,15 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa return; } } - else + else if (!m_wsDstFile.empty()) { - if (!NSFile::CFileBinary::Copy(m_wsSrcFile, _wsDstFile)) + if (!NSFile::CFileBinary::Copy(m_wsSrcFile, m_wsDstFile)) { m_nError = 2; return; } NSFile::CFileBinary oFile; - if (!oFile.OpenFile(_wsDstFile, true)) + if (!oFile.OpenFile(m_wsDstFile, true)) { m_nError = 2; return; @@ -890,7 +891,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } // Применение редактирования для writer - bool bRes = pDoc->EditPdf(_wsDstFile, xref->getLastXRefPos(), xref->getNumObjects() + 1, pXref, pCatalog, pEncryptDict, nFormField); + bool bRes = pDoc->EditPdf(xref->getLastXRefPos(), xref->getNumObjects() + 1, pXref, pCatalog, pEncryptDict, nFormField); if (bRes) { // Воспроизведение дерева страниц во writer @@ -903,7 +904,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa if (!bRes) m_nError = 5; // Ошибка применения редактирования } -CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, const int* arrPageIndex, unsigned int unLength) +CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter) { m_pReader = _pReader; m_pWriter = _pWriter; @@ -925,39 +926,16 @@ CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, const int* ar m_nError = 1; return; } - - // Страницы должны быть созданы заранее для ссылки - Catalog* pCatalog = pPDFDocument->getCatalog(); - for (int i = 0; i < unLength; ++i) - { - Ref* pPageRef = pCatalog->getPageRef(arrPageIndex[i] + 1); - if (pPageRef->num == 0) - { - m_nError = 3; - return; - } - - PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); - pDoc->AddObject(pPage); - pDoc->AddPage(pPage); - - // Получение объекта страницы - Object pageRefObj, pageObj; - pageRefObj.initRef(pPageRef->num, pPageRef->gen); - if (!pageRefObj.fetch(xref, &pageObj)->isDict()) - { - pageObj.free(); - pageRefObj.free(); - m_nError = 3; - return; - } - m_mSplitUniqueRef[pPageRef->num] = pPage; - pageRefObj.free(); - } +} +int CPdfEditor::Close(const std::wstring& wsPath) +{ + m_wsDstFile = wsPath; + Close(); + return 0; } void CPdfEditor::Close() { - if (m_nMode != 0) + if (m_nMode != 0 || m_wsDstFile.empty()) return; PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -1024,14 +1002,13 @@ void CPdfEditor::Close() } info.free(); - if (!m_pWriter->EditClose() || !pDoc->AddToFile(pXref, pTrailer, pInfoXref, pInfoDict)) + if (!m_pWriter->EditClose() || !pDoc->AddToFile(m_wsDstFile, pXref, pTrailer, pInfoXref, pInfoDict)) { RELEASEOBJECT(pXref); return; } - std::wstring wsPath = pDoc->GetEditPdfPath(); - std::string sPathUtf8New = U_TO_UTF8(wsPath); + std::string sPathUtf8New = U_TO_UTF8(m_wsDstFile); std::string sPathUtf8Old = U_TO_UTF8(m_wsSrcFile); if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) { @@ -1305,6 +1282,127 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) RELEASEOBJECT(pXref); return false; } +bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) +{ + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + + // Страницы должны быть созданы заранее для ссылки + Catalog* pCatalog = pPDFDocument->getCatalog(); + for (int i = 0; i < unLength; ++i) + { + Ref* pPageRef = pCatalog->getPageRef(arrPageIndex[i] + 1); + if (pPageRef->num == 0) + { + m_nError = 3; + return false; + } + + PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); + pDoc->AddObject(pPage); + pDoc->AddPage(pPage); + + // Получение объекта страницы + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef->num, pPageRef->gen); + if (!pageRefObj.fetch(xref, &pageObj)->isDict()) + { + pageObj.free(); + pageRefObj.free(); + m_nError = 3; + return false; + } + m_mSplitUniqueRef[pPageRef->num] = pPage; + pageRefObj.free(); + } + bool bRes = true; + for (unsigned int i = 0; i < unLength; ++i) + bRes &= SplitPage(arrPageIndex[i]); + if (!bRes) + return false; + + Object oCatalog; + if (!xref->getCatalog(&oCatalog)->isDict()) + { + oCatalog.free(); + return false; + } + + Object oAcroForm; + if (oCatalog.dictLookupNF("AcroForm", &oAcroForm)->isRef() || oAcroForm.isDict()) + { + PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); + if (oAcroForm.isRef()) + { + pDoc->AddObject(pAcroForm); + oAcroForm.free(); + if (!oCatalog.dictLookup("AcroForm", &oAcroForm)->isDict()) + { + oAcroForm.free(); oCatalog.free(); + return false; + } + } + pDoc->SetAcroForm(pAcroForm); + + for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = oAcroForm.dictGetKey(nIndex); + if (strcmp("Fields", chKey) == 0) + { + Ref oFieldsRef = { -1, -1 }; + if (oAcroForm.dictGetValNF(nIndex, &oTemp)->isRef()) + oFieldsRef = oTemp.getRef(); + oTemp.free(); + + std::map::iterator it = m_mSplitUniqueRef.find(oFieldsRef.num); + if (oFieldsRef.num > 0 && it != m_mSplitUniqueRef.end()) + { + pAcroForm->Add(chKey, it->second); + continue; + } + + if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + if (oFieldsRef.num > 0) + { + pDoc->AddObject(pArray); + m_mSplitUniqueRef[oFieldsRef.num] = pArray; + } + pAcroForm->Add(chKey, pArray); + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oRes; + if (oTemp.arrayGetNF(nIndex, &oRes)->isRef()) + { + it = m_mSplitUniqueRef.find(oRes.getRefNum()); + if (it != m_mSplitUniqueRef.end()) + pArray->Add(it->second); + } + oRes.free(); + } + oTemp.free(); + continue; + } + else + { + oTemp.free(); + oAcroForm.dictGetValNF(nIndex, &oTemp); + } + } + else + oAcroForm.dictGetValNF(nIndex, &oTemp); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); + pAcroForm->Add(chKey, pBase); + oTemp.free(); + } + } + oAcroForm.free(); oCatalog.free(); + + return bRes; +} bool CPdfEditor::SplitPage(int nPageIndex) { PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); @@ -1394,91 +1492,6 @@ bool CPdfEditor::SplitPage(int nPageIndex) return true; } -void CPdfEditor::SplitEnd() -{ - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); - XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - - Object oCatalog; - if (!xref->getCatalog(&oCatalog)->isDict()) - { - oCatalog.free(); - return; - } - - Object oAcroForm; - if (oCatalog.dictLookupNF("AcroForm", &oAcroForm)->isRef() || oAcroForm.isDict()) - { - PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); - if (oAcroForm.isRef()) - { - pDoc->AddObject(pAcroForm); - oAcroForm.free(); - if (!oCatalog.dictLookup("AcroForm", &oAcroForm)->isDict()) - { - oAcroForm.free(); oCatalog.free(); - return; - } - } - pDoc->SetAcroForm(pAcroForm); - - for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex) - { - Object oTemp; - char* chKey = oAcroForm.dictGetKey(nIndex); - if (strcmp("Fields", chKey) == 0) - { - Ref oFieldsRef = { -1, -1 }; - if (oAcroForm.dictGetValNF(nIndex, &oTemp)->isRef()) - oFieldsRef = oTemp.getRef(); - oTemp.free(); - - std::map::iterator it = m_mSplitUniqueRef.find(oFieldsRef.num); - if (oFieldsRef.num > 0 && it != m_mSplitUniqueRef.end()) - { - pAcroForm->Add(chKey, it->second); - continue; - } - - if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) - { - PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); - if (oFieldsRef.num > 0) - { - pDoc->AddObject(pArray); - m_mSplitUniqueRef[oFieldsRef.num] = pArray; - } - pAcroForm->Add(chKey, pArray); - for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) - { - Object oRes; - if (oTemp.arrayGetNF(nIndex, &oRes)->isRef()) - { - it = m_mSplitUniqueRef.find(oRes.getRefNum()); - if (it != m_mSplitUniqueRef.end()) - pArray->Add(it->second); - } - oRes.free(); - } - oTemp.free(); - continue; - } - else - { - oTemp.free(); - oAcroForm.dictGetValNF(nIndex, &oTemp); - } - } - else - oAcroForm.dictGetValNF(nIndex, &oTemp); - PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); - pAcroForm->Add(chKey, pBase); - oTemp.free(); - } - } - oAcroForm.free(); oCatalog.free(); -} bool CPdfEditor::DeletePage(int nPageIndex) { return m_pWriter->GetDocument()->DeletePage(nPageIndex); diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index a2318c95b0..a3a776fd19 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -41,13 +41,12 @@ class CPdfEditor { public: CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter); - CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, const int* arrPageIndex, unsigned int unLength); + CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter); int GetError(); void Close(); + int Close(const std::wstring& wsPath); bool EditPage(int nPageIndex, bool bSet = true); - bool SplitPage(int nPageIndex); - void SplitEnd(); bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); bool EditAnnot(int nPageIndex, int nID); @@ -62,10 +61,14 @@ public: void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); + bool SplitPage(int nPageIndex); + bool SplitPages(const int* arrPageIndex, unsigned int unLength); + private: void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); std::wstring m_wsSrcFile; + std::wstring m_wsDstFile; std::wstring m_wsPassword; std::map m_mFonts; std::map m_mSplitUniqueRef; // map уникальных объектов для Split diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 59523c7cd4..ccd0b2731b 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -165,10 +165,6 @@ bool CPdfFile::AddPage(int nPageIndex) return false; return m_pInternal->pEditor->AddPage(nPageIndex); } -bool CPdfFile::SplitPages(const std::vector& arrPageIndex) -{ - return SplitPages(arrPageIndex.data(), arrPageIndex.size()); -} bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) { if (!m_pInternal->pEditor) @@ -179,15 +175,46 @@ bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) if (!m_pInternal->pWriter) m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); - m_pInternal->pEditor = new CPdfEditor(m_pInternal->pReader, m_pInternal->pWriter, arrPageIndex, unLength); + m_pInternal->pEditor = new CPdfEditor(m_pInternal->pReader, m_pInternal->pWriter); if (m_pInternal->pEditor->GetError() != 0) return false; } - bool bRes = true; - for (unsigned int i = 0; i < unLength; ++i) - bRes &= m_pInternal->pEditor->SplitPage(arrPageIndex[i]); - if (bRes) - m_pInternal->pEditor->SplitEnd(); + return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); +} +bool CPdfFile::MergePages(CPdfFile* pMergeFile, const int* arrPageIndex, unsigned int unLength, int nMergePos) +{ + if (!pMergeFile || !pMergeFile->m_pInternal || !pMergeFile->m_pInternal->pReader) + return false; + + if (!m_pInternal->pEditor) + { + if (!m_pInternal->pReader) + return false; + + if (!m_pInternal->pWriter) + m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); + + m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, m_pInternal->pReader, L"", m_pInternal->pWriter); + if (m_pInternal->pEditor->GetError() != 0) + return false; + } + + // TODO + return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); +} +bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength, int nMergePos) +{ + CPdfFile* pMergeFile = new CPdfFile(m_pInternal->pAppFonts); + pMergeFile->SetTempDirectory(m_pInternal->wsTempFolder); + + if (!pMergeFile->LoadFromFile(wsPath, L"", wsPassword, wsPassword)) + { + RELEASEOBJECT(pMergeFile); + return false; + } + + bool bRes = MergePages(pMergeFile, arrPageIndex, unLength, nMergePos); + RELEASEOBJECT(pMergeFile); return bRes; } HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) @@ -503,6 +530,8 @@ int CPdfFile::SaveToFile(const std::wstring& wsPath) { if (!m_pInternal->pWriter) return 1; + if (m_pInternal->pEditor) + return m_pInternal->pEditor->Close(wsPath); return m_pInternal->pWriter->SaveToFile(wsPath); } void CPdfFile::SetPassword(const std::wstring& wsPassword) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 7a03e0190b..2a0283a0be 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -94,11 +94,12 @@ public: // Переходит в режим редактирования. Pdf уже должен быть открыт на чтение - LoadFromFile/LoadFromMemory bool EditPdf(const std::wstring& wsDstFile = L""); // Манипуляции со страницами возможны в режиме редактирования - bool EditPage (int nPageIndex); - bool DeletePage (int nPageIndex); - bool AddPage (int nPageIndex); - bool SplitPages (const std::vector& arrPageIndex); - bool SplitPages (const int* arrPageIndex, unsigned int unLength); + bool EditPage (int nPageIndex); + bool DeletePage(int nPageIndex); + bool AddPage (int nPageIndex); + bool SplitPages(const int* arrPageIndex, unsigned int unLength); + bool MergePages(CPdfFile* pMergeFile, const int* arrPageIndex = NULL, unsigned int unLength = 0, int nMergePos = -1); + bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0, int nMergePos = -1); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 5a3e62bafc..2e7f0e4658 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -203,8 +203,6 @@ namespace PdfWriter m_pFieldsResources = NULL; memset((void*)m_sTTFontTag, 0x00, 8); m_pDefaultCheckBoxFont = NULL; - m_wsDocumentID = L""; - m_wsFilePath = L""; m_vExtGrStates.clear(); m_vStrokeAlpha.clear(); @@ -1402,7 +1400,7 @@ namespace PdfWriter return true; } - bool CDocument::EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField) + bool CDocument::EditPdf(int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField) { if (!pXref || !pCatalog) return false; @@ -1435,7 +1433,6 @@ namespace PdfWriter } m_unFormFields = nFormField; - m_wsFilePath = wsPath; return true; } bool CDocument::EditResources(CXref* pXref, CResourcesDict* pResources) @@ -1610,16 +1607,16 @@ namespace PdfWriter } return false; } - bool CDocument::AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo) + bool CDocument::AddToFile(const std::wstring& wsPath, CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo) { - if (!pTrailer || m_wsFilePath.empty()) + if (!pTrailer || wsPath.empty()) return false; CFileStream* pStream = new CFileStream(); if (!pStream) return false; - if (!pStream->OpenFile(m_wsFilePath, false)) + if (!pStream->OpenFile(wsPath, false)) { RELEASEOBJECT(pStream); return false; @@ -1708,7 +1705,7 @@ namespace PdfWriter RELEASEOBJECT(pStream); unsigned int nSizeXRef = m_pXref->GetSizeXRef(); m_pXref = m_pLastXref; - Sign(m_wsFilePath, nSizeXRef, bNeedStreamXRef); + Sign(wsPath, nSizeXRef, bNeedStreamXRef); RELEASEOBJECT(m_pEncryptDict); return true; diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index e449be6eb1..931830540c 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -190,16 +190,15 @@ namespace PdfWriter void SetCurImage(CImageDict* pImage) { m_pCurImage = pImage; } bool CreatePageTree(CXref* pXref, CPageTree* pPageTree); - bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); + bool EditPdf(int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); bool EditResources(CXref* pXref, CResourcesDict* pResources); std::pair GetPageRef(int nPageIndex); bool EditPage(CXref* pXref, CPage* pPage, int nPageIndex); CPage* AddPage(int nPageIndex); bool DeletePage(int nPageIndex); - bool AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); + bool AddToFile(const std::wstring& wsPath, CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); void AddObject(CObjectBase* pObj); void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert); - std::wstring GetEditPdfPath() { return m_wsFilePath; } bool EditAnnot (CXref* pXref, CAnnotation* pAnnot, int nID); bool EditParent(CXref* pXref, CDictObject* pParent, int nID); bool DeleteAnnot(int nObjNum, int nObjGen); @@ -309,7 +308,6 @@ namespace PdfWriter FT_Library m_pFreeTypeLibrary; bool m_bPDFAConformance; std::wstring m_wsDocumentID; - std::wstring m_wsFilePath; CDictObject* m_pAcroForm; CResourcesDict* m_pFieldsResources; std::vector m_vRadioGroups; diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 407fad324a..dbd83c86f3 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -356,14 +356,21 @@ TEST_F(CPdfFileTest, SplitPdf) LoadFromFile(); - pdfFile->SplitPages({2, 5, 6, 7}); + std::vector arrPages = { 0, 1, 2, 3 }; + pdfFile->SplitPages(arrPages.empty() ? NULL : arrPages.data(), arrPages.size()); pdfFile->SaveToFile(wsDstFile); } TEST_F(CPdfFileTest, MergePdf) { - GTEST_SKIP(); + //GTEST_SKIP(); + + LoadFromFile(); + + pdfFile->MergePages(wsSrcFile); + + pdfFile->SaveToFile(wsDstFile); } TEST_F(CPdfFileTest, CopyAnotherPdf)