| 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 | 
|---|