mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
Merge pull request 'Feature pdf print' (#590) from feature/pdf-print into release/v9.3.0
Reviewed-on: https://git.onlyoffice.com/ONLYOFFICE/core/pulls/590
This commit is contained in:
@ -54,6 +54,7 @@
|
||||
#include "SrcWriter/Outline.h"
|
||||
#include "SrcWriter/GState.h"
|
||||
#include "SrcWriter/RedactOutputDev.h"
|
||||
#include "SrcWriter/Image.h"
|
||||
|
||||
#define AddToObject(oVal)\
|
||||
{\
|
||||
@ -2908,6 +2909,387 @@ bool CPdfEditor::MergePages(const std::wstring& wsPath)
|
||||
|
||||
return bRes;
|
||||
}
|
||||
bool CPdfEditor::PrintPages(const std::vector<bool>& arrPages, int nFlag)
|
||||
{
|
||||
if (m_nMode != Mode::Unknown)
|
||||
return false;
|
||||
|
||||
PdfWriter::CDocument* pDoc = m_pWriter->GetDocument();
|
||||
PdfWriter::CPageTree* pPageTree = pDoc->GetPageTree();
|
||||
m_mObjManager.SetDoc(pDoc);
|
||||
|
||||
for (int i = 0; i < arrPages.size(); ++i)
|
||||
{
|
||||
if (!arrPages[i])
|
||||
continue;
|
||||
|
||||
PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc);
|
||||
pDoc->AddObject(pPage);
|
||||
pPageTree->AddPage(pPage);
|
||||
pDoc->AddEditPage(pPage, i);
|
||||
|
||||
PDFDoc* pPDFDocument = NULL;
|
||||
PdfReader::CPdfFontList* pFontList = NULL;
|
||||
int nStartRefID = 0;
|
||||
int nPageIndex = m_pReader->GetPageIndex(i, &pPDFDocument, &pFontList, &nStartRefID);
|
||||
|
||||
Catalog* pCatalog = pPDFDocument->getCatalog();
|
||||
XRef* xref = pPDFDocument->getXRef();
|
||||
Ref* pPageRef = pCatalog->getPageRef(nPageIndex);
|
||||
Object pageRefObj, pageObj;
|
||||
pageRefObj.initRef(pPageRef->num, pPageRef->gen);
|
||||
if (!pageRefObj.fetch(xref, &pageObj)->isDict())
|
||||
{
|
||||
pageObj.free(); pageRefObj.free();
|
||||
continue;
|
||||
}
|
||||
m_mObjManager.AddObj(pPageRef->num + nStartRefID, pPage);
|
||||
pageRefObj.free();
|
||||
|
||||
bool bResources = false, bMediaBox = false, bCropBox = false, bRotate = false;
|
||||
for (int nIndex = 0; nIndex < pageObj.dictGetLength(); ++nIndex)
|
||||
{
|
||||
Object oTemp;
|
||||
char* chKey = pageObj.dictGetKey(nIndex);
|
||||
if (strcmp("Resources", chKey) == 0)
|
||||
{
|
||||
bResources = true;
|
||||
Ref oResourcesRef = { -1, -1 };
|
||||
if (pageObj.dictGetValNF(nIndex, &oTemp)->isRef())
|
||||
oResourcesRef = oTemp.getRef();
|
||||
oTemp.free();
|
||||
|
||||
PdfWriter::CObjectBase* pObj = oResourcesRef.num > 0 ? m_mObjManager.GetObj(oResourcesRef.num + nStartRefID) : NULL;
|
||||
if (pObj)
|
||||
{
|
||||
pPage->Add(chKey, pObj);
|
||||
m_mObjManager.IncRefCount(oResourcesRef.num + nStartRefID);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pageObj.dictGetVal(nIndex, &oTemp)->isDict())
|
||||
{
|
||||
PdfWriter::CResourcesDict* pDict = pDoc->CreateResourcesDict(oResourcesRef.num < 0, false);
|
||||
if (oResourcesRef.num > 0)
|
||||
m_mObjManager.AddObj(oResourcesRef.num + nStartRefID, pDict);
|
||||
pPage->Add(chKey, pDict);
|
||||
for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex)
|
||||
{
|
||||
Object oRes;
|
||||
char* chKey2 = oTemp.dictGetKey(nIndex);
|
||||
oTemp.dictGetValNF(nIndex, &oRes);
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oRes, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
pDict->Add(chKey2, pBase);
|
||||
oRes.free();
|
||||
}
|
||||
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
oTemp.free();
|
||||
pageObj.dictGetValNF(nIndex, &oTemp);
|
||||
}
|
||||
}
|
||||
else if (strcmp("Parent", chKey) == 0)
|
||||
{
|
||||
// Поля родителей страниц переносятся к самим страницам
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else if (strcmp("MediaBox", chKey) == 0)
|
||||
{
|
||||
bMediaBox = true;
|
||||
pageObj.dictGetValNF(nIndex, &oTemp);
|
||||
}
|
||||
else if (strcmp("CropBox", chKey) == 0)
|
||||
{
|
||||
bCropBox = true;
|
||||
pageObj.dictGetValNF(nIndex, &oTemp);
|
||||
}
|
||||
else if (strcmp("Rotate", chKey) == 0)
|
||||
{
|
||||
bRotate = true;
|
||||
pageObj.dictGetValNF(nIndex, &oTemp);
|
||||
}
|
||||
else if (nFlag != 3 && strcmp("Contents", chKey) == 0)
|
||||
{
|
||||
pageObj.dictGetValNF(nIndex, &oTemp);
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID, 0, false);
|
||||
pPage->Add(chKey, pBase);
|
||||
continue;
|
||||
}
|
||||
else if (strcmp("Annots", chKey) == 0)
|
||||
{
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else
|
||||
pageObj.dictGetValNF(nIndex, &oTemp);
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
pPage->Add(chKey, pBase);
|
||||
oTemp.free();
|
||||
}
|
||||
if (!bResources || !bMediaBox || !bCropBox || !bRotate)
|
||||
{
|
||||
Page* pOPage = pCatalog->getPage(nPageIndex);
|
||||
if (!bMediaBox)
|
||||
{
|
||||
PDFRectangle* pRect = pOPage->getMediaBox();
|
||||
pPage->Add("MediaBox", PdfWriter::CArrayObject::CreateBox(pRect->x1, pRect->y1, pRect->x2, pRect->y2));
|
||||
}
|
||||
if (!bCropBox && pOPage->isCropped())
|
||||
{
|
||||
PDFRectangle* pRect = pOPage->getCropBox();
|
||||
pPage->Add("CropBox", PdfWriter::CArrayObject::CreateBox(pRect->x1, pRect->y1, pRect->x2, pRect->y2));
|
||||
}
|
||||
if (!bRotate)
|
||||
pPage->Add("Rotate", pOPage->getRotate());
|
||||
if (!bResources)
|
||||
{
|
||||
Dict* pResources = pOPage->getResourceDict();
|
||||
PdfWriter::CResourcesDict* pDict = pDoc->CreateResourcesDict(true, false);
|
||||
pPage->Add("Resources", pDict);
|
||||
for (int nIndex = 0; nIndex < pResources->getLength(); ++nIndex)
|
||||
{
|
||||
Object oRes;
|
||||
char* chKey2 = pResources->getKey(nIndex);
|
||||
pResources->getValNF(nIndex, &oRes);
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oRes, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
pDict->Add(chKey2, pBase);
|
||||
oRes.free();
|
||||
}
|
||||
}
|
||||
}
|
||||
pPage->Fix();
|
||||
pDoc->FixEditPage(pPage);
|
||||
|
||||
if (nFlag == 0)
|
||||
{
|
||||
pageObj.free();
|
||||
continue;
|
||||
}
|
||||
|
||||
double dCTM[6] = { 1, 0, 0, 1, 0, 0 };
|
||||
double dInvMatrix[6] = { 1, 0, 0, 1, 0, 0 };
|
||||
GetCTM(xref, &pageObj, dCTM);
|
||||
|
||||
double det = dCTM[0] * dCTM[3] - dCTM[1] * dCTM[2];
|
||||
if (fabs(det) > 1e-10)
|
||||
{
|
||||
double invDet = 1.0 / det;
|
||||
dInvMatrix[0] = dCTM[3] * invDet;
|
||||
dInvMatrix[1] = -dCTM[1] * invDet;
|
||||
dInvMatrix[2] = -dCTM[2] * invDet;
|
||||
dInvMatrix[3] = dCTM[0] * invDet;
|
||||
dInvMatrix[4] = (dCTM[2] * dCTM[5] - dCTM[3] * dCTM[4]) * invDet;
|
||||
dInvMatrix[5] = (dCTM[1] * dCTM[4] - dCTM[0] * dCTM[5]) * invDet;
|
||||
}
|
||||
|
||||
PdfWriter::CStream* pStream = pPage->GetStream();
|
||||
pStream->WriteReal(dInvMatrix[0]);
|
||||
pStream->WriteChar(' ');
|
||||
pStream->WriteReal(dInvMatrix[1]);
|
||||
pStream->WriteChar(' ');
|
||||
pStream->WriteReal(dInvMatrix[2]);
|
||||
pStream->WriteChar(' ');
|
||||
pStream->WriteReal(dInvMatrix[3]);
|
||||
pStream->WriteChar(' ');
|
||||
pStream->WriteReal(dInvMatrix[4]);
|
||||
pStream->WriteChar(' ');
|
||||
pStream->WriteReal(dInvMatrix[5]);
|
||||
pStream->WriteStr(" cm\012");
|
||||
|
||||
pPage->SetStrokeColor(0, 0, 0);
|
||||
pPage->SetFillColor(0, 0, 0);
|
||||
pPage->SetExtGrState(pDoc->GetExtGState(255, 255));
|
||||
pPage->BeginText();
|
||||
pPage->SetCharSpace(0);
|
||||
pPage->SetTextRenderingMode(PdfWriter::textrenderingmode_Fill);
|
||||
pPage->SetHorizontalScaling(100);
|
||||
pPage->EndText();
|
||||
|
||||
Object oAnnots;
|
||||
if (!pageObj.dictLookup("Annots", &oAnnots)->isArray())
|
||||
{
|
||||
pageObj.free();
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < oAnnots.arrayGetLength(); ++i)
|
||||
{
|
||||
Object oAnnot, oType, oObj;
|
||||
if (!oAnnots.arrayGet(i, &oAnnot)->isDict() || !oAnnot.dictLookup("Subtype", &oType)->isName() || !oAnnot.dictLookup("F", &oObj)->isInt())
|
||||
{
|
||||
oAnnot.free(); oType.free(); oObj.free();
|
||||
continue;
|
||||
}
|
||||
|
||||
int nFlags = oObj.getInt();
|
||||
oObj.free();
|
||||
// if Invisible || Hidden || !Print
|
||||
if ((nFlags & (1 << 0)) || (nFlags & (1 << 1)) || !(nFlags & (1 << 2)))
|
||||
{
|
||||
oAnnot.free(); oType.free();
|
||||
continue;
|
||||
}
|
||||
|
||||
char* sType = oType.getName();
|
||||
if ((nFlag == 1 && (strcmp(sType, "StrikeOut") || strcmp(sType, "FreeText") || strcmp(sType, "Underline") || strcmp(sType, "Square") || strcmp(sType, "Circle") || strcmp(sType, "Polygon")
|
||||
|| strcmp(sType, "PolyLine") || strcmp(sType, "Highlight") || strcmp(sType, "Line") || strcmp(sType, "Squiggly") || strcmp(sType, "Text") || strcmp(sType, "Caret") || strcmp(sType, "Ink")
|
||||
|| strcmp(sType, "FileAttachment") || strcmp(sType, "Sound") || strcmp(sType, "Redact"))) || (nFlag == 2 && strcmp(sType, "Stamp")) || (nFlag == 3 && strcmp(sType, "Widget")))
|
||||
{
|
||||
oType.free(); oAnnot.free();
|
||||
continue;
|
||||
}
|
||||
oType.free();
|
||||
|
||||
PdfWriter::CXObject* pForm = pDoc->CreateForm();
|
||||
pPage->GrSave();
|
||||
pPage->ExecuteXObject(pForm);
|
||||
pPage->GrRestore();
|
||||
|
||||
// TODO Нужно ли генерировать внешний вид тем у кого его нет
|
||||
Object oAP, oAPN;
|
||||
if (!oAnnot.dictLookup("AP", &oAP)->isDict() || !oAP.dictLookup("N", &oAPN)->isStream())
|
||||
{
|
||||
oAnnot.free(); oAP.free(); oAPN.free();
|
||||
continue;
|
||||
}
|
||||
oAP.free();
|
||||
|
||||
Object oTemp;
|
||||
double m[6] = { 1, 0, 0, 1, 0, 0 }, bbox[4] = { 0, 0, 0, 0 }, rect[4] = { 0, 0, 0, 0 };
|
||||
if (oAnnot.dictLookup("Rect", &oTemp)->isArray() && oTemp.arrayGetLength() == 4)
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
oTemp.arrayGet(j, &oObj);
|
||||
rect[j] = oObj.isNum() ? oObj.getNum() : 0;
|
||||
oObj.free();
|
||||
}
|
||||
|
||||
if (rect[0] > rect[2])
|
||||
std::swap(rect[0], rect[2]);
|
||||
if (rect[1] > rect[3])
|
||||
std::swap(rect[1], rect[3]);
|
||||
}
|
||||
oTemp.free();
|
||||
|
||||
Dict* pODict = oAPN.streamGetDict();
|
||||
for (int nIndex = 0; nIndex < pODict->getLength(); ++nIndex)
|
||||
{
|
||||
char* chKey = pODict->getKey(nIndex);
|
||||
if (strcmp("Length", chKey) == 0)
|
||||
{
|
||||
oTemp.free();
|
||||
continue;
|
||||
}
|
||||
else if (strcmp("BBox", chKey) == 0 && pODict->getVal(nIndex, &oTemp)->isArray() && oTemp.arrayGetLength() == 4)
|
||||
{
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
oTemp.arrayGet(j, &oObj);
|
||||
bbox[j] = oObj.isNum() ? oObj.getNum() : 0;
|
||||
oObj.free();
|
||||
}
|
||||
|
||||
if (bbox[0] > bbox[2])
|
||||
std::swap(bbox[0], bbox[2]);
|
||||
if (bbox[1] > bbox[3])
|
||||
std::swap(bbox[1], bbox[3]);
|
||||
}
|
||||
else if (strcmp("Matrix", chKey) == 0 && pODict->getVal(nIndex, &oTemp)->isArray() && oTemp.arrayGetLength() == 6)
|
||||
{
|
||||
for (int j = 0; j < 6; ++j)
|
||||
{
|
||||
oTemp.arrayGet(j, &oObj);
|
||||
m[j] = oObj.getNum();
|
||||
oObj.free();
|
||||
}
|
||||
}
|
||||
oTemp.free();
|
||||
pODict->getValNF(nIndex, &oTemp);
|
||||
PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID);
|
||||
pForm->Add(chKey, pBase);
|
||||
oTemp.free();
|
||||
}
|
||||
|
||||
double formXMin, formYMin, formXMax, formYMax, x, y, sx, sy;
|
||||
x = bbox[0] * m[0] + bbox[1] * m[2] + m[4];
|
||||
y = bbox[0] * m[1] + bbox[1] * m[3] + m[5];
|
||||
formXMin = formXMax = x;
|
||||
formYMin = formYMax = y;
|
||||
x = bbox[0] * m[0] + bbox[3] * m[2] + m[4];
|
||||
y = bbox[0] * m[1] + bbox[3] * m[3] + m[5];
|
||||
if (x < formXMin)
|
||||
formXMin = x;
|
||||
else if (x > formXMax)
|
||||
formXMax = x;
|
||||
if (y < formYMin)
|
||||
formYMin = y;
|
||||
else if (y > formYMax)
|
||||
formYMax = y;
|
||||
x = bbox[2] * m[0] + bbox[1] * m[2] + m[4];
|
||||
y = bbox[2] * m[1] + bbox[1] * m[3] + m[5];
|
||||
if (x < formXMin)
|
||||
formXMin = x;
|
||||
else if (x > formXMax)
|
||||
formXMax = x;
|
||||
if (y < formYMin)
|
||||
formYMin = y;
|
||||
else if (y > formYMax)
|
||||
formYMax = y;
|
||||
x = bbox[2] * m[0] + bbox[3] * m[2] + m[4];
|
||||
y = bbox[2] * m[1] + bbox[3] * m[3] + m[5];
|
||||
if (x < formXMin)
|
||||
formXMin = x;
|
||||
else if (x > formXMax)
|
||||
formXMax = x;
|
||||
if (y < formYMin)
|
||||
formYMin = y;
|
||||
else if (y > formYMax)
|
||||
formYMax = y;
|
||||
|
||||
if (formXMin == formXMax)
|
||||
sx = 1;
|
||||
else
|
||||
sx = (rect[2] - rect[0]) / (formXMax - formXMin);
|
||||
if (formYMin == formYMax)
|
||||
sy = 1;
|
||||
else
|
||||
sy = (rect[3] - rect[1]) / (formYMax - formYMin);
|
||||
double tx = -formXMin * sx + rect[0];
|
||||
double ty = -formYMin * sy + rect[1];
|
||||
|
||||
m[0] *= sx;
|
||||
m[1] *= sy;
|
||||
m[2] *= sx;
|
||||
m[3] *= sy;
|
||||
m[4] = m[4] * sx + tx;
|
||||
m[5] = m[5] * sy + ty;
|
||||
|
||||
pForm->Add("Matrix", PdfWriter::CArrayObject::CreateMatrix(m));
|
||||
|
||||
PdfWriter::CStream* pStream = pForm->GetStream();
|
||||
Stream* pOStream = oAPN.getStream()->getUndecodedStream();
|
||||
pOStream->reset();
|
||||
int nChar = pOStream->getChar();
|
||||
while (nChar != EOF)
|
||||
{
|
||||
pStream->WriteChar(nChar);
|
||||
nChar = pOStream->getChar();
|
||||
}
|
||||
|
||||
oAPN.free(); oAnnot.free();
|
||||
}
|
||||
oAnnots.free();
|
||||
|
||||
pageObj.free();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool CPdfEditor::DeletePage(int nPageIndex)
|
||||
{
|
||||
if (m_nMode == Mode::Unknown && !IncrementalUpdates())
|
||||
|
||||
@ -107,6 +107,8 @@ public:
|
||||
void AfterSplitPages();
|
||||
bool MergePages(const std::wstring& wsPath);
|
||||
|
||||
bool PrintPages(const std::vector<bool>& arrPages, int nFlag);
|
||||
|
||||
private:
|
||||
bool IncrementalUpdates();
|
||||
void NewFrom();
|
||||
|
||||
@ -151,6 +151,29 @@ bool CPdfFile::MergePages(const std::wstring& wsPath, int nMaxID, const std::wst
|
||||
return m_pInternal->pEditor->MergePages(wsPath);
|
||||
return false;
|
||||
}
|
||||
bool CPdfFile::PrintPages(const std::vector<bool>& arrPages, int nFlag)
|
||||
{
|
||||
if (!m_pInternal->pReader)
|
||||
return false;
|
||||
|
||||
m_pInternal->pReader->CleanUp();
|
||||
|
||||
RELEASEOBJECT(m_pInternal->pWriter);
|
||||
m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this, true, m_pInternal->wsTempFolder);
|
||||
|
||||
RELEASEOBJECT(m_pInternal->pEditor);
|
||||
m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, L"", m_pInternal->pReader, m_pInternal->pWriter);
|
||||
if (m_pInternal->pEditor->GetError())
|
||||
{
|
||||
RELEASEOBJECT(m_pInternal->pEditor);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bRes = m_pInternal->pEditor->PrintPages(arrPages, nFlag);
|
||||
|
||||
RELEASEOBJECT(m_pInternal->pEditor);
|
||||
return bRes;
|
||||
}
|
||||
bool CPdfFile::MovePage(int nPageIndex, int nPos)
|
||||
{
|
||||
if (!m_pInternal->pEditor)
|
||||
|
||||
@ -99,6 +99,7 @@ public:
|
||||
bool AddPage (int nPageIndex);
|
||||
bool MovePage (int nPageIndex, int nPos);
|
||||
bool MergePages(const std::wstring& wsPath, int nMaxID = 0, const std::wstring& wsPrefixForm = L"");
|
||||
bool PrintPages(const std::vector<bool>& arrPages, int nFlag);
|
||||
HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L"");
|
||||
|
||||
// --- READER ---
|
||||
|
||||
@ -469,6 +469,21 @@ namespace PdfWriter
|
||||
|
||||
return pArray;
|
||||
}
|
||||
CArrayObject* CArrayObject::CreateMatrix(double* m)
|
||||
{
|
||||
CArrayObject* pArray = new CArrayObject();
|
||||
if (!pArray)
|
||||
return NULL;
|
||||
|
||||
pArray->Add(m[0]);
|
||||
pArray->Add(m[1]);
|
||||
pArray->Add(m[2]);
|
||||
pArray->Add(m[3]);
|
||||
pArray->Add(m[4]);
|
||||
pArray->Add(m[5]);
|
||||
|
||||
return pArray;
|
||||
}
|
||||
CObjectBase* CArrayObject::Copy(CObjectBase* pOut) const
|
||||
{
|
||||
CArrayObject* pArray = pOut && pOut->GetType() == object_type_ARRAY ? (CArrayObject*)pOut : new CArrayObject();
|
||||
|
||||
@ -434,6 +434,7 @@ namespace PdfWriter
|
||||
}
|
||||
static CArrayObject* CreateBox(const TBox& oBox);
|
||||
static CArrayObject* CreateBox(double dL, double dB, double dR, double dT);
|
||||
static CArrayObject* CreateMatrix(double* m);
|
||||
virtual CObjectBase* Copy(CObjectBase* pOut = NULL) const;
|
||||
void FromXml(const std::wstring& sXml);
|
||||
|
||||
|
||||
@ -235,6 +235,8 @@ namespace PdfWriter
|
||||
{
|
||||
m_pPages->Add(pObj);
|
||||
(*m_pCount)++;
|
||||
if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGE)
|
||||
((CPage*)pObj)->Add("Parent", this);
|
||||
}
|
||||
CObjectBase* CPageTree::GetObj(int nPageIndex)
|
||||
{
|
||||
@ -259,8 +261,6 @@ namespace PdfWriter
|
||||
if (nPageIndex >= m_pCount->Get())
|
||||
{
|
||||
AddPage(pPage);
|
||||
if (pPage->GetType() == object_type_DICT && ((CDictObject*)pPage)->GetDictType() == dict_type_PAGE)
|
||||
((CPage*)pPage)->Add("Parent", this);
|
||||
return true;
|
||||
}
|
||||
int nI = 0;
|
||||
|
||||
@ -494,7 +494,7 @@ TEST_F(CPdfFileTest, EditPdf)
|
||||
|
||||
TEST_F(CPdfFileTest, EditPdfFromBase64)
|
||||
{
|
||||
//GTEST_SKIP();
|
||||
GTEST_SKIP();
|
||||
|
||||
NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage());
|
||||
|
||||
@ -590,6 +590,23 @@ TEST_F(CPdfFileTest, EditPdfSign)
|
||||
RELEASEOBJECT(pCertificate);
|
||||
}
|
||||
|
||||
TEST_F(CPdfFileTest, PrintPdf)
|
||||
{
|
||||
//GTEST_SKIP();
|
||||
|
||||
LoadFromFile();
|
||||
|
||||
int nPages = pdfFile->GetPagesCount();
|
||||
std::vector<bool> arrPages;
|
||||
for (int i = 0; i < nPages; ++i)
|
||||
arrPages.push_back(true);
|
||||
|
||||
ASSERT_TRUE(pdfFile->PrintPages(arrPages, 1));
|
||||
|
||||
pdfFile->SaveToFile(wsDstFile);
|
||||
pdfFile->Close();
|
||||
}
|
||||
|
||||
TEST_F(CPdfFileTest, ChangePasswordToEmpty)
|
||||
{
|
||||
GTEST_SKIP();
|
||||
|
||||
@ -295,29 +295,65 @@ namespace NExtractTools
|
||||
}
|
||||
|
||||
// from crossplatform (pdf)
|
||||
std::string checkPrintPages(InputParams ¶ms)
|
||||
std::string checkPrintPages(InputParams ¶ms, int &nType)
|
||||
{
|
||||
if (NULL == params.m_sJsonParams)
|
||||
return "";
|
||||
|
||||
std::wstring sPages;
|
||||
std::wstring::size_type posPrintPages = params.m_sJsonParams->find(L"\"printPages\":\"");
|
||||
if (std::wstring::npos != posPrintPages)
|
||||
{
|
||||
posPrintPages += 14;
|
||||
std::wstring::size_type posPrintPages2 = params.m_sJsonParams->find(L"\"", posPrintPages);
|
||||
if (std::wstring::npos == posPrintPages2)
|
||||
return "";
|
||||
|
||||
sPages = params.m_sJsonParams->substr(posPrintPages, posPrintPages2 - posPrintPages);
|
||||
}
|
||||
|
||||
std::wstring::size_type posNativeOptions = params.m_sJsonParams->find(L"\"nativeOptions\"");
|
||||
if (std::wstring::npos == posNativeOptions)
|
||||
return "";
|
||||
if (sPages.empty() && std::wstring::npos != posNativeOptions)
|
||||
{
|
||||
std::wstring::size_type posNativePages = params.m_sJsonParams->find(L"\"pages\":\"", posNativeOptions);
|
||||
if (std::wstring::npos == posNativePages)
|
||||
return "";
|
||||
|
||||
std::wstring::size_type posNativePages = params.m_sJsonParams->find(L"\"pages\":\"", posNativeOptions);
|
||||
if (std::wstring::npos == posNativePages)
|
||||
return "";
|
||||
posNativePages += 9;
|
||||
std::wstring::size_type posNativePages2 = params.m_sJsonParams->find(L"\"", posNativePages);
|
||||
if (std::wstring::npos == posNativePages2)
|
||||
return "";
|
||||
|
||||
posNativePages += 9;
|
||||
std::wstring::size_type posNativePages2 = params.m_sJsonParams->find(L"\"", posNativePages);
|
||||
if (std::wstring::npos == posNativePages2)
|
||||
return "";
|
||||
sPages = params.m_sJsonParams->substr(posNativePages, posNativePages2 - posNativePages);
|
||||
}
|
||||
|
||||
std::wstring::size_type posLayout = params.m_sJsonParams->find(L"\"pdfLayout\":{");
|
||||
if (std::wstring::npos != posLayout)
|
||||
{
|
||||
std::wstring::size_type posContent = params.m_sJsonParams->find(L"\"content\":\"", posLayout);
|
||||
if (std::wstring::npos != posContent)
|
||||
{
|
||||
posContent += 11;
|
||||
std::wstring::size_type posContent2 = params.m_sJsonParams->find(L"\"", posContent);
|
||||
if (std::wstring::npos == posContent2)
|
||||
return "";
|
||||
|
||||
std::wstring sType = params.m_sJsonParams->substr(posContent, posContent2 - posContent);
|
||||
if (sType == L"doc")
|
||||
nType = 0;
|
||||
else if (sType == L"docAndMarkups")
|
||||
nType = 1;
|
||||
else if (sType == L"docAndStamps")
|
||||
nType = 2;
|
||||
else if (sType == L"formsOnly")
|
||||
nType = 3;
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring sPages = params.m_sJsonParams->substr(posNativePages, posNativePages2 - posNativePages);
|
||||
if (L"all" == sPages)
|
||||
return "";
|
||||
|
||||
if (L"current" == sPages)
|
||||
if (L"current" == sPages && std::wstring::npos != posNativeOptions)
|
||||
{
|
||||
std::wstring::size_type posCurrentPage = params.m_sJsonParams->find(L"\"currentPage\":", posNativeOptions);
|
||||
if (std::wstring::npos == posCurrentPage)
|
||||
@ -347,6 +383,9 @@ namespace NExtractTools
|
||||
|
||||
std::vector<bool> getPrintPages(const std::string &sPages, int nPagesCount)
|
||||
{
|
||||
if (sPages.empty())
|
||||
return std::vector<bool>(nPagesCount, true);
|
||||
|
||||
const char *buffer = sPages.c_str();
|
||||
|
||||
size_t nCur = 0;
|
||||
@ -831,14 +870,15 @@ namespace NExtractTools
|
||||
|
||||
if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo)
|
||||
{
|
||||
std::string sPages = checkPrintPages(params);
|
||||
int nType = -1;
|
||||
std::string sPages = checkPrintPages(params, nType);
|
||||
|
||||
if (nFormatFrom == nFormatTo && !params.getIsPDFA())
|
||||
{
|
||||
if (!sPages.empty())
|
||||
if (!sPages.empty() || nType != -1)
|
||||
{
|
||||
std::wstring sCurrentTmp = L"";
|
||||
sCurrentTmp =NSFile::CFileBinary::CreateTempFileWithUniqueName(convertParams.m_sTempDir, L"PDF_");
|
||||
sCurrentTmp = NSFile::CFileBinary::CreateTempFileWithUniqueName(convertParams.m_sTempDir, L"PDF_");
|
||||
if (NSFile::CFileBinary::Exists(sCurrentTmp))
|
||||
NSFile::CFileBinary::Remove(sCurrentTmp);
|
||||
|
||||
@ -846,17 +886,14 @@ namespace NExtractTools
|
||||
oPdfPages.SetTempDirectory(convertParams.m_sTempDir);
|
||||
|
||||
std::wstring sPassword = params.getPassword();
|
||||
if (oPdfPages.LoadFromFile(sFrom.c_str(), L"", sPassword, sPassword) && oPdfPages.EditPdf(sCurrentTmp))
|
||||
if (oPdfPages.LoadFromFile(sFrom.c_str(), L"", sPassword, sPassword))
|
||||
{
|
||||
int nPagesCount = oPdfPages.GetPagesCount();
|
||||
std::vector<bool> arPages = getPrintPages(convertParams.m_sPrintPages, nPagesCount);
|
||||
std::vector<bool> arPages = getPrintPages(sPages, nPagesCount);
|
||||
|
||||
for (int i = 0; i < nPagesCount; ++i)
|
||||
{
|
||||
if (!arPages[i])
|
||||
oPdfPages.DeletePage(i);
|
||||
}
|
||||
oPdfPages.PrintPages(arPages, nType);
|
||||
|
||||
oPdfPages.SaveToFile(sCurrentTmp);
|
||||
oPdfPages.Close();
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user