| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "public/fpdf_ppo.h" | 7 #include "public/fpdf_ppo.h" |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 | 10 |
| 11 #include "fpdfsdk/include/fsdk_define.h" | 11 #include "fpdfsdk/include/fsdk_define.h" |
| 12 #include "third_party/base/stl_util.h" |
| 12 | 13 |
| 13 class CPDF_PageOrganizer { | 14 class CPDF_PageOrganizer { |
| 14 public: | 15 public: |
| 15 using ObjectNumberMap = std::map<FX_DWORD, FX_DWORD>; | 16 using ObjectNumberMap = std::map<FX_DWORD, FX_DWORD>; |
| 16 CPDF_PageOrganizer(); | 17 CPDF_PageOrganizer(); |
| 17 ~CPDF_PageOrganizer(); | 18 ~CPDF_PageOrganizer(); |
| 18 | 19 |
| 19 FX_BOOL PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc); | 20 FX_BOOL PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc); |
| 20 FX_BOOL ExportPage(CPDF_Document* pSrcPDFDoc, | 21 FX_BOOL ExportPage(CPDF_Document* pSrcPDFDoc, |
| 21 CFX_WordArray* nPageNum, | 22 std::vector<FX_WORD>* pPageNums, |
| 22 CPDF_Document* pDestPDFDoc, | 23 CPDF_Document* pDestPDFDoc, |
| 23 int nIndex); | 24 int nIndex); |
| 24 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict, | 25 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict, |
| 25 CFX_ByteString nSrctag); | 26 CFX_ByteString nSrctag); |
| 26 FX_BOOL UpdateReference(CPDF_Object* pObj, | 27 FX_BOOL UpdateReference(CPDF_Object* pObj, |
| 27 CPDF_Document* pDoc, | 28 CPDF_Document* pDoc, |
| 28 ObjectNumberMap* pObjNumberMap); | 29 ObjectNumberMap* pObjNumberMap); |
| 29 FX_DWORD GetNewObjId(CPDF_Document* pDoc, | 30 FX_DWORD GetNewObjId(CPDF_Document* pDoc, |
| 30 ObjectNumberMap* pObjNumberMap, | 31 ObjectNumberMap* pObjNumberMap, |
| 31 CPDF_Reference* pRef); | 32 CPDF_Reference* pRef); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 Kidsobjnum = pDestPDFDoc->AddIndirectObject(pNewKids); | 81 Kidsobjnum = pDestPDFDoc->AddIndirectObject(pNewKids); |
| 81 | 82 |
| 82 pNewPages->SetAt("Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum)); | 83 pNewPages->SetAt("Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum)); |
| 83 pNewPages->SetAt("Count", new CPDF_Number(0)); | 84 pNewPages->SetAt("Count", new CPDF_Number(0)); |
| 84 } | 85 } |
| 85 | 86 |
| 86 return TRUE; | 87 return TRUE; |
| 87 } | 88 } |
| 88 | 89 |
| 89 FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, | 90 FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, |
| 90 CFX_WordArray* nPageNum, | 91 std::vector<FX_WORD>* pPageNums, |
| 91 CPDF_Document* pDestPDFDoc, | 92 CPDF_Document* pDestPDFDoc, |
| 92 int nIndex) { | 93 int nIndex) { |
| 93 int curpage = nIndex; | 94 int curpage = nIndex; |
| 94 | |
| 95 std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); | 95 std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); |
| 96 | 96 int nSize = pdfium::CollectionSize<int>(*pPageNums); |
| 97 for (int i = 0; i < nPageNum->GetSize(); ++i) { | 97 for (int i = 0; i < nSize; ++i) { |
| 98 CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); | 98 CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); |
| 99 CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(nPageNum->GetAt(i) - 1); | 99 CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(pPageNums->at(i) - 1); |
| 100 if (!pSrcPageDict || !pCurPageDict) | 100 if (!pSrcPageDict || !pCurPageDict) |
| 101 return FALSE; | 101 return FALSE; |
| 102 | 102 |
| 103 // Clone the page dictionary | 103 // Clone the page dictionary |
| 104 for (const auto& it : *pSrcPageDict) { | 104 for (const auto& it : *pSrcPageDict) { |
| 105 const CFX_ByteString& cbSrcKeyStr = it.first; | 105 const CFX_ByteString& cbSrcKeyStr = it.first; |
| 106 CPDF_Object* pObj = it.second; | 106 CPDF_Object* pObj = it.second; |
| 107 if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { | 107 if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { |
| 108 if (pCurPageDict->KeyExist(cbSrcKeyStr)) | 108 if (pCurPageDict->KeyExist(cbSrcKeyStr)) |
| 109 pCurPageDict->RemoveAt(cbSrcKeyStr); | 109 pCurPageDict->RemoveAt(cbSrcKeyStr); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 dwNewObjNum = pDoc->AddIndirectObject(pClone); | 299 dwNewObjNum = pDoc->AddIndirectObject(pClone); |
| 300 (*pObjNumberMap)[dwObjnum] = dwNewObjNum; | 300 (*pObjNumberMap)[dwObjnum] = dwNewObjNum; |
| 301 if (!UpdateReference(pClone, pDoc, pObjNumberMap)) { | 301 if (!UpdateReference(pClone, pDoc, pObjNumberMap)) { |
| 302 pClone->Release(); | 302 pClone->Release(); |
| 303 return 0; | 303 return 0; |
| 304 } | 304 } |
| 305 return dwNewObjNum; | 305 return dwNewObjNum; |
| 306 } | 306 } |
| 307 | 307 |
| 308 FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring, | 308 FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring, |
| 309 CFX_WordArray* pageArray, | 309 std::vector<FX_WORD>* pageArray, |
| 310 int nCount) { | 310 int nCount) { |
| 311 if (rangstring.GetLength() != 0) { | 311 if (rangstring.GetLength() != 0) { |
| 312 rangstring.Remove(' '); | 312 rangstring.Remove(' '); |
| 313 int nLength = rangstring.GetLength(); | 313 int nLength = rangstring.GetLength(); |
| 314 CFX_ByteString cbCompareString("0123456789-,"); | 314 CFX_ByteString cbCompareString("0123456789-,"); |
| 315 for (int i = 0; i < nLength; ++i) { | 315 for (int i = 0; i < nLength; ++i) { |
| 316 if (cbCompareString.Find(rangstring[i]) == -1) | 316 if (cbCompareString.Find(rangstring[i]) == -1) |
| 317 return FALSE; | 317 return FALSE; |
| 318 } | 318 } |
| 319 CFX_ByteString cbMidRange; | 319 CFX_ByteString cbMidRange; |
| 320 int nStringFrom = 0; | 320 int nStringFrom = 0; |
| 321 int nStringTo = 0; | 321 int nStringTo = 0; |
| 322 while (nStringTo < nLength) { | 322 while (nStringTo < nLength) { |
| 323 nStringTo = rangstring.Find(',', nStringFrom); | 323 nStringTo = rangstring.Find(',', nStringFrom); |
| 324 if (nStringTo == -1) | 324 if (nStringTo == -1) |
| 325 nStringTo = nLength; | 325 nStringTo = nLength; |
| 326 cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom); | 326 cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom); |
| 327 int nMid = cbMidRange.Find('-'); | 327 int nMid = cbMidRange.Find('-'); |
| 328 if (nMid == -1) { | 328 if (nMid == -1) { |
| 329 long lPageNum = atol(cbMidRange); | 329 long lPageNum = atol(cbMidRange); |
| 330 if (lPageNum <= 0 || lPageNum > nCount) | 330 if (lPageNum <= 0 || lPageNum > nCount) |
| 331 return FALSE; | 331 return FALSE; |
| 332 pageArray->Add((FX_WORD)lPageNum); | 332 pageArray->push_back((FX_WORD)lPageNum); |
| 333 } else { | 333 } else { |
| 334 int nStartPageNum = atol(cbMidRange.Mid(0, nMid)); | 334 int nStartPageNum = atol(cbMidRange.Mid(0, nMid)); |
| 335 if (nStartPageNum == 0) | 335 if (nStartPageNum == 0) |
| 336 return FALSE; | 336 return FALSE; |
| 337 | 337 |
| 338 ++nMid; | 338 ++nMid; |
| 339 int nEnd = cbMidRange.GetLength() - nMid; | 339 int nEnd = cbMidRange.GetLength() - nMid; |
| 340 if (nEnd == 0) | 340 if (nEnd == 0) |
| 341 return FALSE; | 341 return FALSE; |
| 342 | 342 |
| 343 int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd)); | 343 int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd)); |
| 344 if (nStartPageNum < 0 || nStartPageNum > nEndPageNum || | 344 if (nStartPageNum < 0 || nStartPageNum > nEndPageNum || |
| 345 nEndPageNum > nCount) { | 345 nEndPageNum > nCount) { |
| 346 return FALSE; | 346 return FALSE; |
| 347 } | 347 } |
| 348 for (int i = nStartPageNum; i <= nEndPageNum; ++i) { | 348 for (int i = nStartPageNum; i <= nEndPageNum; ++i) { |
| 349 pageArray->Add(i); | 349 pageArray->push_back(i); |
| 350 } | 350 } |
| 351 } | 351 } |
| 352 nStringFrom = nStringTo + 1; | 352 nStringFrom = nStringTo + 1; |
| 353 } | 353 } |
| 354 } | 354 } |
| 355 return TRUE; | 355 return TRUE; |
| 356 } | 356 } |
| 357 | 357 |
| 358 DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc, | 358 DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc, |
| 359 FPDF_DOCUMENT src_doc, | 359 FPDF_DOCUMENT src_doc, |
| 360 FPDF_BYTESTRING pagerange, | 360 FPDF_BYTESTRING pagerange, |
| 361 int index) { | 361 int index) { |
| 362 CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc); | 362 CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc); |
| 363 if (!dest_doc) | 363 if (!dest_doc) |
| 364 return FALSE; | 364 return FALSE; |
| 365 | 365 |
| 366 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); | 366 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); |
| 367 if (!pSrcDoc) | 367 if (!pSrcDoc) |
| 368 return FALSE; | 368 return FALSE; |
| 369 | 369 |
| 370 CFX_WordArray pageArray; | 370 std::vector<FX_WORD> pageArray; |
| 371 int nCount = pSrcDoc->GetPageCount(); | 371 int nCount = pSrcDoc->GetPageCount(); |
| 372 if (pagerange) { | 372 if (pagerange) { |
| 373 if (!ParserPageRangeString(pagerange, &pageArray, nCount)) | 373 if (!ParserPageRangeString(pagerange, &pageArray, nCount)) |
| 374 return FALSE; | 374 return FALSE; |
| 375 } else { | 375 } else { |
| 376 for (int i = 1; i <= nCount; ++i) { | 376 for (int i = 1; i <= nCount; ++i) { |
| 377 pageArray.Add(i); | 377 pageArray.push_back(i); |
| 378 } | 378 } |
| 379 } | 379 } |
| 380 | 380 |
| 381 CPDF_PageOrganizer pageOrg; | 381 CPDF_PageOrganizer pageOrg; |
| 382 pageOrg.PDFDocInit(pDestDoc, pSrcDoc); | 382 pageOrg.PDFDocInit(pDestDoc, pSrcDoc); |
| 383 return pageOrg.ExportPage(pSrcDoc, &pageArray, pDestDoc, index); | 383 return pageOrg.ExportPage(pSrcDoc, &pageArray, pDestDoc, index); |
| 384 } | 384 } |
| 385 | 385 |
| 386 DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, | 386 DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, |
| 387 FPDF_DOCUMENT src_doc) { | 387 FPDF_DOCUMENT src_doc) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 398 if (!pSrcDict) | 398 if (!pSrcDict) |
| 399 return FALSE; | 399 return FALSE; |
| 400 | 400 |
| 401 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); | 401 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); |
| 402 if (!pDstDict) | 402 if (!pDstDict) |
| 403 return FALSE; | 403 return FALSE; |
| 404 | 404 |
| 405 pDstDict->SetAt("ViewerPreferences", pSrcDict->Clone(TRUE)); | 405 pDstDict->SetAt("ViewerPreferences", pSrcDict->Clone(TRUE)); |
| 406 return TRUE; | 406 return TRUE; |
| 407 } | 407 } |
| OLD | NEW |