Chromium Code Reviews| 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 <map> | 9 #include <map> |
| 10 #include <memory> | 10 #include <memory> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "core/fpdfapi/parser/cpdf_array.h" | 13 #include "core/fpdfapi/parser/cpdf_array.h" |
| 14 #include "core/fpdfapi/parser/cpdf_document.h" | 14 #include "core/fpdfapi/parser/cpdf_document.h" |
| 15 #include "core/fpdfapi/parser/cpdf_name.h" | 15 #include "core/fpdfapi/parser/cpdf_name.h" |
| 16 #include "core/fpdfapi/parser/cpdf_number.h" | 16 #include "core/fpdfapi/parser/cpdf_number.h" |
| 17 #include "core/fpdfapi/parser/cpdf_reference.h" | 17 #include "core/fpdfapi/parser/cpdf_reference.h" |
| 18 #include "core/fpdfapi/parser/cpdf_stream.h" | 18 #include "core/fpdfapi/parser/cpdf_stream.h" |
| 19 #include "core/fpdfapi/parser/cpdf_string.h" | 19 #include "core/fpdfapi/parser/cpdf_string.h" |
| 20 #include "fpdfsdk/fsdk_define.h" | 20 #include "fpdfsdk/fsdk_define.h" |
| 21 #include "third_party/base/stl_util.h" | 21 #include "third_party/base/stl_util.h" |
|
Tom Sepez
2016/11/14 17:31:35
nit: include ptr_util.h
Lei Zhang
2016/11/14 19:57:01
Done.
| |
| 22 | 22 |
| 23 class CPDF_PageOrganizer { | 23 class CPDF_PageOrganizer { |
| 24 public: | 24 public: |
| 25 using ObjectNumberMap = std::map<uint32_t, uint32_t>; | 25 using ObjectNumberMap = std::map<uint32_t, uint32_t>; |
| 26 CPDF_PageOrganizer(); | 26 CPDF_PageOrganizer(); |
| 27 ~CPDF_PageOrganizer(); | 27 ~CPDF_PageOrganizer(); |
| 28 | 28 |
| 29 bool PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc); | 29 bool PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc); |
| 30 bool ExportPage(CPDF_Document* pSrcPDFDoc, | 30 bool ExportPage(CPDF_Document* pDestPDFDoc, |
| 31 std::vector<uint16_t>* pPageNums, | 31 CPDF_Document* pSrcPDFDoc, |
| 32 CPDF_Document* pDestPDFDoc, | 32 const std::vector<uint16_t>& pageNums, |
| 33 int nIndex); | 33 int nIndex); |
| 34 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict, | 34 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict, |
| 35 const CFX_ByteString& bsSrctag); | 35 const CFX_ByteString& bsSrctag); |
| 36 bool UpdateReference(CPDF_Object* pObj, | 36 bool UpdateReference(CPDF_Object* pObj, |
| 37 CPDF_Document* pDoc, | 37 CPDF_Document* pDoc, |
| 38 ObjectNumberMap* pObjNumberMap); | 38 ObjectNumberMap* pObjNumberMap); |
| 39 uint32_t GetNewObjId(CPDF_Document* pDoc, | 39 uint32_t GetNewObjId(CPDF_Document* pDoc, |
| 40 ObjectNumberMap* pObjNumberMap, | 40 ObjectNumberMap* pObjNumberMap, |
| 41 CPDF_Reference* pRef); | 41 CPDF_Reference* pRef); |
| 42 }; | 42 }; |
| 43 | 43 |
| 44 CPDF_PageOrganizer::CPDF_PageOrganizer() {} | 44 CPDF_PageOrganizer::CPDF_PageOrganizer() {} |
| 45 | 45 |
| 46 CPDF_PageOrganizer::~CPDF_PageOrganizer() {} | 46 CPDF_PageOrganizer::~CPDF_PageOrganizer() {} |
| 47 | 47 |
| 48 bool CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc, | 48 bool CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc, |
| 49 CPDF_Document* pSrcPDFDoc) { | 49 CPDF_Document* pSrcPDFDoc) { |
| 50 if (!pDestPDFDoc || !pSrcPDFDoc) | 50 if (!pDestPDFDoc || !pSrcPDFDoc) |
| 51 return false; | 51 return false; |
| 52 | 52 |
| 53 CPDF_Dictionary* pNewRoot = pDestPDFDoc->GetRoot(); | 53 CPDF_Dictionary* pNewRoot = pDestPDFDoc->GetRoot(); |
| 54 if (!pNewRoot) | 54 if (!pNewRoot) |
| 55 return false; | 55 return false; |
| 56 | 56 |
| 57 CPDF_Dictionary* DInfoDict = pDestPDFDoc->GetInfo(); | 57 CPDF_Dictionary* pDocInfoDict = pDestPDFDoc->GetInfo(); |
| 58 if (!DInfoDict) | 58 if (!pDocInfoDict) |
| 59 return false; | 59 return false; |
| 60 | 60 |
| 61 CFX_ByteString producerstr; | 61 CFX_ByteString producerstr; |
| 62 producerstr.Format("PDFium"); | 62 producerstr.Format("PDFium"); |
| 63 DInfoDict->SetFor("Producer", new CPDF_String(producerstr, false)); | 63 pDocInfoDict->SetFor("Producer", new CPDF_String(producerstr, false)); |
| 64 | 64 |
| 65 CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", ""); | 65 CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", ""); |
| 66 if (cbRootType.IsEmpty()) | 66 if (cbRootType.IsEmpty()) |
| 67 pNewRoot->SetFor("Type", new CPDF_Name("Catalog")); | 67 pNewRoot->SetFor("Type", new CPDF_Name("Catalog")); |
| 68 | 68 |
| 69 CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages"); | 69 CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages"); |
| 70 CPDF_Dictionary* pNewPages = | 70 CPDF_Dictionary* pNewPages = |
| 71 pElement ? ToDictionary(pElement->GetDirect()) : nullptr; | 71 pElement ? ToDictionary(pElement->GetDirect()) : nullptr; |
| 72 if (!pNewPages) { | 72 if (!pNewPages) { |
| 73 pNewPages = new CPDF_Dictionary(pDestPDFDoc->GetByteStringPool()); | 73 pNewPages = new CPDF_Dictionary(pDestPDFDoc->GetByteStringPool()); |
| 74 pNewRoot->SetReferenceFor("Pages", pDestPDFDoc, | 74 pNewRoot->SetReferenceFor("Pages", pDestPDFDoc, |
| 75 pDestPDFDoc->AddIndirectObject(pNewPages)); | 75 pDestPDFDoc->AddIndirectObject(pNewPages)); |
| 76 } | 76 } |
| 77 | 77 |
| 78 CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", ""); | 78 CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", ""); |
| 79 if (cbPageType == "") { | 79 if (cbPageType.IsEmpty()) |
| 80 pNewPages->SetFor("Type", new CPDF_Name("Pages")); | 80 pNewPages->SetFor("Type", new CPDF_Name("Pages")); |
| 81 } | |
| 82 | 81 |
| 83 if (!pNewPages->GetArrayFor("Kids")) { | 82 if (!pNewPages->GetArrayFor("Kids")) { |
| 84 pNewPages->SetIntegerFor("Count", 0); | 83 pNewPages->SetIntegerFor("Count", 0); |
| 85 pNewPages->SetReferenceFor("Kids", pDestPDFDoc, | 84 pNewPages->SetReferenceFor("Kids", pDestPDFDoc, |
| 86 pDestPDFDoc->AddIndirectObject(new CPDF_Array)); | 85 pDestPDFDoc->AddIndirectObject(new CPDF_Array)); |
| 87 } | 86 } |
| 88 | 87 |
| 89 return true; | 88 return true; |
| 90 } | 89 } |
| 91 | 90 |
| 92 bool CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, | 91 bool CPDF_PageOrganizer::ExportPage(CPDF_Document* pDestPDFDoc, |
| 93 std::vector<uint16_t>* pPageNums, | 92 CPDF_Document* pSrcPDFDoc, |
| 94 CPDF_Document* pDestPDFDoc, | 93 const std::vector<uint16_t>& pageNums, |
| 95 int nIndex) { | 94 int nIndex) { |
| 96 int curpage = nIndex; | 95 int curpage = nIndex; |
| 97 std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); | 96 auto pObjNumberMap = pdfium::MakeUnique<ObjectNumberMap>(); |
| 98 int nSize = pdfium::CollectionSize<int>(*pPageNums); | 97 int nSize = pdfium::CollectionSize<int>(pageNums); |
| 99 for (int i = 0; i < nSize; ++i) { | 98 for (int i = 0; i < nSize; ++i) { |
| 100 CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); | 99 CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); |
| 101 CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(pPageNums->at(i) - 1); | 100 CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(pageNums[i] - 1); |
| 102 if (!pSrcPageDict || !pCurPageDict) | 101 if (!pSrcPageDict || !pCurPageDict) |
| 103 return false; | 102 return false; |
| 104 | 103 |
| 105 // Clone the page dictionary | 104 // Clone the page dictionary |
| 106 for (const auto& it : *pSrcPageDict) { | 105 for (const auto& it : *pSrcPageDict) { |
| 107 const CFX_ByteString& cbSrcKeyStr = it.first; | 106 const CFX_ByteString& cbSrcKeyStr = it.first; |
| 108 CPDF_Object* pObj = it.second; | 107 CPDF_Object* pObj = it.second; |
| 109 if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { | 108 if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { |
|
Tom Sepez
2016/11/14 17:31:35
nit: overparenthesized, also how about
if (cbSrc
Lei Zhang
2016/11/14 19:57:01
Done.
| |
| 110 if (pCurPageDict->KeyExist(cbSrcKeyStr)) | 109 if (pCurPageDict->KeyExist(cbSrcKeyStr)) |
|
Tom Sepez
2016/11/14 17:31:35
No need to remove as dicts clean themselves.
Wond
Lei Zhang
2016/11/14 19:57:01
Done.
| |
| 111 pCurPageDict->RemoveFor(cbSrcKeyStr); | 110 pCurPageDict->RemoveFor(cbSrcKeyStr); |
| 112 pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone().release()); | 111 pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone().release()); |
| 113 } | 112 } |
| 114 } | 113 } |
| 115 | 114 |
| 116 // inheritable item | 115 // inheritable item |
| 117 CPDF_Object* pInheritable = nullptr; | 116 // 1 MediaBox - required |
| 118 // 1 MediaBox //required | |
| 119 if (!pCurPageDict->KeyExist("MediaBox")) { | 117 if (!pCurPageDict->KeyExist("MediaBox")) { |
| 120 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); | 118 CPDF_Object* pInheritable = |
| 121 if (!pInheritable) { | 119 PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); |
| 122 // Search the "CropBox" from source page dictionary, | 120 if (pInheritable) { |
| 123 // if not exists,we take the letter size. | 121 pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release()); |
| 122 } else { | |
| 123 // Search for "CropBox" in the source page dictionary, | |
| 124 // if it does not exists, use the default letter size. | |
| 124 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); | 125 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); |
| 125 if (pInheritable) { | 126 if (pInheritable) { |
| 126 pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release()); | 127 pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release()); |
| 127 } else { | 128 } else { |
| 128 // Make the default size to be letter size (8.5'x11') | 129 // Make the default size to be letter size (8.5'x11') |
| 129 CPDF_Array* pArray = new CPDF_Array; | 130 CPDF_Array* pArray = new CPDF_Array; |
| 130 pArray->AddNumber(0); | 131 pArray->AddNumber(0); |
| 131 pArray->AddNumber(0); | 132 pArray->AddNumber(0); |
| 132 pArray->AddNumber(612); | 133 pArray->AddNumber(612); |
| 133 pArray->AddNumber(792); | 134 pArray->AddNumber(792); |
| 134 pCurPageDict->SetFor("MediaBox", pArray); | 135 pCurPageDict->SetFor("MediaBox", pArray); |
| 135 } | 136 } |
| 136 } else { | |
| 137 pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release()); | |
| 138 } | 137 } |
| 139 } | 138 } |
| 140 // 2 Resources //required | 139 // 2 Resources - required |
| 141 if (!pCurPageDict->KeyExist("Resources")) { | 140 if (!pCurPageDict->KeyExist("Resources")) { |
| 142 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources"); | 141 CPDF_Object* pInheritable = |
|
Tom Sepez
2016/11/14 17:31:35
Helper method?
Lei Zhang
2016/11/14 19:57:01
Done.
| |
| 142 PageDictGetInheritableTag(pSrcPageDict, "Resources"); | |
| 143 if (!pInheritable) | 143 if (!pInheritable) |
| 144 return false; | 144 return false; |
| 145 pCurPageDict->SetFor("Resources", pInheritable->Clone().release()); | 145 pCurPageDict->SetFor("Resources", pInheritable->Clone().release()); |
| 146 } | 146 } |
| 147 // 3 CropBox //Optional | 147 // 3 CropBox - optional |
| 148 if (!pCurPageDict->KeyExist("CropBox")) { | 148 if (!pCurPageDict->KeyExist("CropBox")) { |
| 149 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); | 149 CPDF_Object* pInheritable = |
| 150 PageDictGetInheritableTag(pSrcPageDict, "CropBox"); | |
| 150 if (pInheritable) | 151 if (pInheritable) |
| 151 pCurPageDict->SetFor("CropBox", pInheritable->Clone().release()); | 152 pCurPageDict->SetFor("CropBox", pInheritable->Clone().release()); |
| 152 } | 153 } |
| 153 // 4 Rotate //Optional | 154 // 4 Rotate - optional |
| 154 if (!pCurPageDict->KeyExist("Rotate")) { | 155 if (!pCurPageDict->KeyExist("Rotate")) { |
| 155 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); | 156 CPDF_Object* pInheritable = |
| 157 PageDictGetInheritableTag(pSrcPageDict, "Rotate"); | |
| 156 if (pInheritable) | 158 if (pInheritable) |
| 157 pCurPageDict->SetFor("Rotate", pInheritable->Clone().release()); | 159 pCurPageDict->SetFor("Rotate", pInheritable->Clone().release()); |
| 158 } | 160 } |
| 159 | 161 |
| 160 // Update the reference | 162 // Update the reference |
| 161 uint32_t dwOldPageObj = pSrcPageDict->GetObjNum(); | 163 uint32_t dwOldPageObj = pSrcPageDict->GetObjNum(); |
| 162 uint32_t dwNewPageObj = pCurPageDict->GetObjNum(); | 164 uint32_t dwNewPageObj = pCurPageDict->GetObjNum(); |
| 163 (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; | 165 (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; |
| 164 UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); | 166 UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); |
| 165 ++curpage; | 167 ++curpage; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 if (!pNextObj) | 237 if (!pNextObj) |
| 236 return false; | 238 return false; |
| 237 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) | 239 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) |
| 238 return false; | 240 return false; |
| 239 } | 241 } |
| 240 break; | 242 break; |
| 241 } | 243 } |
| 242 case CPDF_Object::STREAM: { | 244 case CPDF_Object::STREAM: { |
| 243 CPDF_Stream* pStream = pObj->AsStream(); | 245 CPDF_Stream* pStream = pObj->AsStream(); |
| 244 CPDF_Dictionary* pDict = pStream->GetDict(); | 246 CPDF_Dictionary* pDict = pStream->GetDict(); |
| 245 if (pDict) { | 247 if (!pDict) |
| 246 if (!UpdateReference(pDict, pDoc, pObjNumberMap)) | |
| 247 return false; | |
| 248 } else { | |
| 249 return false; | 248 return false; |
| 250 } | 249 if (!UpdateReference(pDict, pDoc, pObjNumberMap)) |
| 250 return false; | |
| 251 break; | 251 break; |
| 252 } | 252 } |
| 253 default: | 253 default: |
| 254 break; | 254 break; |
| 255 } | 255 } |
| 256 | 256 |
| 257 return true; | 257 return true; |
| 258 } | 258 } |
| 259 | 259 |
| 260 uint32_t CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc, | 260 uint32_t CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc, |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 287 } | 287 } |
| 288 dwNewObjNum = pDoc->AddIndirectObject(pClone.get()); | 288 dwNewObjNum = pDoc->AddIndirectObject(pClone.get()); |
| 289 (*pObjNumberMap)[dwObjnum] = dwNewObjNum; | 289 (*pObjNumberMap)[dwObjnum] = dwNewObjNum; |
| 290 if (!UpdateReference(pClone.get(), pDoc, pObjNumberMap)) | 290 if (!UpdateReference(pClone.get(), pDoc, pObjNumberMap)) |
| 291 return 0; | 291 return 0; |
| 292 | 292 |
| 293 pClone.release(); // TODO(tsepez): figure out ownership. | 293 pClone.release(); // TODO(tsepez): figure out ownership. |
| 294 return dwNewObjNum; | 294 return dwNewObjNum; |
| 295 } | 295 } |
| 296 | 296 |
| 297 FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring, | 297 FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring, |
|
Tom Sepez
2016/11/14 17:31:35
nit: bool ?
Lei Zhang
2016/11/14 19:57:01
Done.
| |
| 298 std::vector<uint16_t>* pageArray, | 298 std::vector<uint16_t>* pageArray, |
| 299 int nCount) { | 299 int nCount) { |
| 300 if (rangstring.GetLength() != 0) { | 300 if (rangstring.IsEmpty()) |
| 301 rangstring.Remove(' '); | 301 return true; |
| 302 int nLength = rangstring.GetLength(); | 302 |
| 303 CFX_ByteString cbCompareString("0123456789-,"); | 303 rangstring.Remove(' '); |
| 304 for (int i = 0; i < nLength; ++i) { | 304 int nLength = rangstring.GetLength(); |
| 305 if (cbCompareString.Find(rangstring[i]) == -1) | 305 CFX_ByteString cbCompareString("0123456789-,"); |
| 306 for (int i = 0; i < nLength; ++i) { | |
| 307 if (cbCompareString.Find(rangstring[i]) == -1) | |
| 308 return false; | |
| 309 } | |
| 310 | |
| 311 CFX_ByteString cbMidRange; | |
| 312 int nStringFrom = 0; | |
| 313 int nStringTo = 0; | |
| 314 while (nStringTo < nLength) { | |
| 315 nStringTo = rangstring.Find(',', nStringFrom); | |
| 316 if (nStringTo == -1) | |
| 317 nStringTo = nLength; | |
| 318 cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom); | |
| 319 int nMid = cbMidRange.Find('-'); | |
| 320 if (nMid == -1) { | |
| 321 long lPageNum = atol(cbMidRange.c_str()); | |
| 322 if (lPageNum <= 0 || lPageNum > nCount) | |
| 306 return false; | 323 return false; |
| 324 pageArray->push_back((uint16_t)lPageNum); | |
| 325 } else { | |
| 326 int nStartPageNum = atol(cbMidRange.Mid(0, nMid).c_str()); | |
| 327 if (nStartPageNum == 0) | |
| 328 return false; | |
| 329 | |
| 330 ++nMid; | |
| 331 int nEnd = cbMidRange.GetLength() - nMid; | |
| 332 if (nEnd == 0) | |
| 333 return false; | |
| 334 | |
| 335 int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd).c_str()); | |
| 336 if (nStartPageNum < 0 || nStartPageNum > nEndPageNum || | |
| 337 nEndPageNum > nCount) { | |
| 338 return false; | |
| 339 } | |
| 340 for (int i = nStartPageNum; i <= nEndPageNum; ++i) { | |
| 341 pageArray->push_back(i); | |
| 342 } | |
| 307 } | 343 } |
| 308 CFX_ByteString cbMidRange; | 344 nStringFrom = nStringTo + 1; |
| 309 int nStringFrom = 0; | |
| 310 int nStringTo = 0; | |
| 311 while (nStringTo < nLength) { | |
| 312 nStringTo = rangstring.Find(',', nStringFrom); | |
| 313 if (nStringTo == -1) | |
| 314 nStringTo = nLength; | |
| 315 cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom); | |
| 316 int nMid = cbMidRange.Find('-'); | |
| 317 if (nMid == -1) { | |
| 318 long lPageNum = atol(cbMidRange.c_str()); | |
| 319 if (lPageNum <= 0 || lPageNum > nCount) | |
| 320 return false; | |
| 321 pageArray->push_back((uint16_t)lPageNum); | |
| 322 } else { | |
| 323 int nStartPageNum = atol(cbMidRange.Mid(0, nMid).c_str()); | |
| 324 if (nStartPageNum == 0) | |
| 325 return false; | |
| 326 | |
| 327 ++nMid; | |
| 328 int nEnd = cbMidRange.GetLength() - nMid; | |
| 329 if (nEnd == 0) | |
| 330 return false; | |
| 331 | |
| 332 int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd).c_str()); | |
| 333 if (nStartPageNum < 0 || nStartPageNum > nEndPageNum || | |
| 334 nEndPageNum > nCount) { | |
| 335 return false; | |
| 336 } | |
| 337 for (int i = nStartPageNum; i <= nEndPageNum; ++i) { | |
| 338 pageArray->push_back(i); | |
| 339 } | |
| 340 } | |
| 341 nStringFrom = nStringTo + 1; | |
| 342 } | |
| 343 } | 345 } |
| 344 return true; | 346 return true; |
| 345 } | 347 } |
| 346 | 348 |
| 347 DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc, | 349 DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc, |
| 348 FPDF_DOCUMENT src_doc, | 350 FPDF_DOCUMENT src_doc, |
| 349 FPDF_BYTESTRING pagerange, | 351 FPDF_BYTESTRING pagerange, |
| 350 int index) { | 352 int index) { |
| 351 CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc); | 353 CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc); |
| 352 if (!dest_doc) | 354 if (!dest_doc) |
| 353 return false; | 355 return false; |
| 354 | 356 |
| 355 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); | 357 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); |
| 356 if (!pSrcDoc) | 358 if (!pSrcDoc) |
| 357 return false; | 359 return false; |
| 358 | 360 |
| 359 std::vector<uint16_t> pageArray; | 361 std::vector<uint16_t> pageArray; |
| 360 int nCount = pSrcDoc->GetPageCount(); | 362 int nCount = pSrcDoc->GetPageCount(); |
| 361 if (pagerange) { | 363 if (pagerange) { |
| 362 if (!ParserPageRangeString(pagerange, &pageArray, nCount)) | 364 if (!ParserPageRangeString(pagerange, &pageArray, nCount)) |
| 363 return false; | 365 return false; |
| 364 } else { | 366 } else { |
| 365 for (int i = 1; i <= nCount; ++i) { | 367 for (int i = 1; i <= nCount; ++i) { |
| 366 pageArray.push_back(i); | 368 pageArray.push_back(i); |
| 367 } | 369 } |
| 368 } | 370 } |
| 369 | 371 |
| 370 CPDF_PageOrganizer pageOrg; | 372 CPDF_PageOrganizer pageOrg; |
| 371 pageOrg.PDFDocInit(pDestDoc, pSrcDoc); | 373 pageOrg.PDFDocInit(pDestDoc, pSrcDoc); |
| 372 return pageOrg.ExportPage(pSrcDoc, &pageArray, pDestDoc, index); | 374 return pageOrg.ExportPage(pDestDoc, pSrcDoc, pageArray, index); |
| 373 } | 375 } |
| 374 | 376 |
| 375 DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, | 377 DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, |
| 376 FPDF_DOCUMENT src_doc) { | 378 FPDF_DOCUMENT src_doc) { |
| 377 CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc); | 379 CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc); |
| 378 if (!pDstDoc) | 380 if (!pDstDoc) |
| 379 return false; | 381 return false; |
| 380 | 382 |
| 381 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); | 383 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); |
| 382 if (!pSrcDoc) | 384 if (!pSrcDoc) |
| 383 return false; | 385 return false; |
| 384 | 386 |
| 385 CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot(); | 387 CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot(); |
| 386 pSrcDict = pSrcDict->GetDictFor("ViewerPreferences"); | 388 pSrcDict = pSrcDict->GetDictFor("ViewerPreferences"); |
| 387 if (!pSrcDict) | 389 if (!pSrcDict) |
| 388 return false; | 390 return false; |
| 389 | 391 |
| 390 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); | 392 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); |
| 391 if (!pDstDict) | 393 if (!pDstDict) |
| 392 return false; | 394 return false; |
| 393 | 395 |
| 394 pDstDict->SetFor("ViewerPreferences", | 396 pDstDict->SetFor("ViewerPreferences", |
| 395 pSrcDict->CloneDirectObject().release()); | 397 pSrcDict->CloneDirectObject().release()); |
| 396 return true; | 398 return true; |
| 397 } | 399 } |
| OLD | NEW |