| 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/fpdf_parser/include/cpdf_array.h" | 13 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" |
| 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" | 14 #include "core/fpdfapi/fpdf_parser/include/cpdf_document.h" |
| 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" | 15 #include "core/fpdfapi/fpdf_parser/include/cpdf_name.h" |
| 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" | 16 #include "core/fpdfapi/fpdf_parser/include/cpdf_number.h" |
| 17 #include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h" | 17 #include "core/fpdfapi/fpdf_parser/include/cpdf_reference.h" |
| 18 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" | 18 #include "core/fpdfapi/fpdf_parser/include/cpdf_stream.h" |
| 19 #include "core/fpdfapi/fpdf_parser/include/cpdf_string.h" | 19 #include "core/fpdfapi/fpdf_parser/include/cpdf_string.h" |
| 20 #include "fpdfsdk/include/fsdk_define.h" | 20 #include "fpdfsdk/include/fsdk_define.h" |
| 21 #include "third_party/base/stl_util.h" | 21 #include "third_party/base/stl_util.h" |
| 22 | 22 |
| 23 class CPDF_PageOrganizer { | 23 class CPDF_PageOrganizer { |
| 24 public: | 24 public: |
| 25 using ObjectNumberMap = std::map<FX_DWORD, FX_DWORD>; | 25 using ObjectNumberMap = std::map<uint32_t, uint32_t>; |
| 26 CPDF_PageOrganizer(); | 26 CPDF_PageOrganizer(); |
| 27 ~CPDF_PageOrganizer(); | 27 ~CPDF_PageOrganizer(); |
| 28 | 28 |
| 29 FX_BOOL PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc); | 29 FX_BOOL PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc); |
| 30 FX_BOOL ExportPage(CPDF_Document* pSrcPDFDoc, | 30 FX_BOOL ExportPage(CPDF_Document* pSrcPDFDoc, |
| 31 std::vector<uint16_t>* pPageNums, | 31 std::vector<uint16_t>* pPageNums, |
| 32 CPDF_Document* pDestPDFDoc, | 32 CPDF_Document* pDestPDFDoc, |
| 33 int nIndex); | 33 int nIndex); |
| 34 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict, | 34 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict, |
| 35 CFX_ByteString nSrctag); | 35 CFX_ByteString nSrctag); |
| 36 FX_BOOL UpdateReference(CPDF_Object* pObj, | 36 FX_BOOL UpdateReference(CPDF_Object* pObj, |
| 37 CPDF_Document* pDoc, | 37 CPDF_Document* pDoc, |
| 38 ObjectNumberMap* pObjNumberMap); | 38 ObjectNumberMap* pObjNumberMap); |
| 39 FX_DWORD 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 FX_BOOL CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc, | 48 FX_BOOL CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc, |
| 49 CPDF_Document* pSrcPDFDoc) { | 49 CPDF_Document* pSrcPDFDoc) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 67 CFX_ByteString cbRootType = pNewRoot->GetStringBy("Type", ""); | 67 CFX_ByteString cbRootType = pNewRoot->GetStringBy("Type", ""); |
| 68 if (cbRootType.Equal("")) { | 68 if (cbRootType.Equal("")) { |
| 69 pNewRoot->SetAt("Type", new CPDF_Name("Catalog")); | 69 pNewRoot->SetAt("Type", new CPDF_Name("Catalog")); |
| 70 } | 70 } |
| 71 | 71 |
| 72 CPDF_Object* pElement = pNewRoot->GetElement("Pages"); | 72 CPDF_Object* pElement = pNewRoot->GetElement("Pages"); |
| 73 CPDF_Dictionary* pNewPages = | 73 CPDF_Dictionary* pNewPages = |
| 74 pElement ? ToDictionary(pElement->GetDirect()) : nullptr; | 74 pElement ? ToDictionary(pElement->GetDirect()) : nullptr; |
| 75 if (!pNewPages) { | 75 if (!pNewPages) { |
| 76 pNewPages = new CPDF_Dictionary; | 76 pNewPages = new CPDF_Dictionary; |
| 77 FX_DWORD NewPagesON = pDestPDFDoc->AddIndirectObject(pNewPages); | 77 uint32_t NewPagesON = pDestPDFDoc->AddIndirectObject(pNewPages); |
| 78 pNewRoot->SetAt("Pages", new CPDF_Reference(pDestPDFDoc, NewPagesON)); | 78 pNewRoot->SetAt("Pages", new CPDF_Reference(pDestPDFDoc, NewPagesON)); |
| 79 } | 79 } |
| 80 | 80 |
| 81 CFX_ByteString cbPageType = pNewPages->GetStringBy("Type", ""); | 81 CFX_ByteString cbPageType = pNewPages->GetStringBy("Type", ""); |
| 82 if (cbPageType.Equal("")) { | 82 if (cbPageType.Equal("")) { |
| 83 pNewPages->SetAt("Type", new CPDF_Name("Pages")); | 83 pNewPages->SetAt("Type", new CPDF_Name("Pages")); |
| 84 } | 84 } |
| 85 | 85 |
| 86 CPDF_Array* pKeysArray = pNewPages->GetArrayBy("Kids"); | 86 CPDF_Array* pKeysArray = pNewPages->GetArrayBy("Kids"); |
| 87 if (!pKeysArray) { | 87 if (!pKeysArray) { |
| 88 CPDF_Array* pNewKids = new CPDF_Array; | 88 CPDF_Array* pNewKids = new CPDF_Array; |
| 89 FX_DWORD Kidsobjnum = pDestPDFDoc->AddIndirectObject(pNewKids); | 89 uint32_t Kidsobjnum = pDestPDFDoc->AddIndirectObject(pNewKids); |
| 90 | 90 |
| 91 pNewPages->SetAt("Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum)); | 91 pNewPages->SetAt("Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum)); |
| 92 pNewPages->SetAt("Count", new CPDF_Number(0)); | 92 pNewPages->SetAt("Count", new CPDF_Number(0)); |
| 93 } | 93 } |
| 94 | 94 |
| 95 return TRUE; | 95 return TRUE; |
| 96 } | 96 } |
| 97 | 97 |
| 98 FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, | 98 FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, |
| 99 std::vector<uint16_t>* pPageNums, | 99 std::vector<uint16_t>* pPageNums, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 pCurPageDict->SetAt("CropBox", pInheritable->Clone()); | 157 pCurPageDict->SetAt("CropBox", pInheritable->Clone()); |
| 158 } | 158 } |
| 159 // 4 Rotate //Optional | 159 // 4 Rotate //Optional |
| 160 if (!pCurPageDict->KeyExist("Rotate")) { | 160 if (!pCurPageDict->KeyExist("Rotate")) { |
| 161 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); | 161 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); |
| 162 if (pInheritable) | 162 if (pInheritable) |
| 163 pCurPageDict->SetAt("Rotate", pInheritable->Clone()); | 163 pCurPageDict->SetAt("Rotate", pInheritable->Clone()); |
| 164 } | 164 } |
| 165 | 165 |
| 166 // Update the reference | 166 // Update the reference |
| 167 FX_DWORD dwOldPageObj = pSrcPageDict->GetObjNum(); | 167 uint32_t dwOldPageObj = pSrcPageDict->GetObjNum(); |
| 168 FX_DWORD dwNewPageObj = pCurPageDict->GetObjNum(); | 168 uint32_t dwNewPageObj = pCurPageDict->GetObjNum(); |
| 169 | 169 |
| 170 (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; | 170 (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; |
| 171 | 171 |
| 172 UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); | 172 UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); |
| 173 ++curpage; | 173 ++curpage; |
| 174 } | 174 } |
| 175 | 175 |
| 176 return TRUE; | 176 return TRUE; |
| 177 } | 177 } |
| 178 | 178 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 206 } | 206 } |
| 207 return nullptr; | 207 return nullptr; |
| 208 } | 208 } |
| 209 | 209 |
| 210 FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, | 210 FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, |
| 211 CPDF_Document* pDoc, | 211 CPDF_Document* pDoc, |
| 212 ObjectNumberMap* pObjNumberMap) { | 212 ObjectNumberMap* pObjNumberMap) { |
| 213 switch (pObj->GetType()) { | 213 switch (pObj->GetType()) { |
| 214 case CPDF_Object::REFERENCE: { | 214 case CPDF_Object::REFERENCE: { |
| 215 CPDF_Reference* pReference = pObj->AsReference(); | 215 CPDF_Reference* pReference = pObj->AsReference(); |
| 216 FX_DWORD newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference); | 216 uint32_t newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference); |
| 217 if (newobjnum == 0) | 217 if (newobjnum == 0) |
| 218 return FALSE; | 218 return FALSE; |
| 219 pReference->SetRef(pDoc, newobjnum); | 219 pReference->SetRef(pDoc, newobjnum); |
| 220 break; | 220 break; |
| 221 } | 221 } |
| 222 case CPDF_Object::DICTIONARY: { | 222 case CPDF_Object::DICTIONARY: { |
| 223 CPDF_Dictionary* pDict = pObj->AsDictionary(); | 223 CPDF_Dictionary* pDict = pObj->AsDictionary(); |
| 224 auto it = pDict->begin(); | 224 auto it = pDict->begin(); |
| 225 while (it != pDict->end()) { | 225 while (it != pDict->end()) { |
| 226 const CFX_ByteString& key = it->first; | 226 const CFX_ByteString& key = it->first; |
| 227 CPDF_Object* pNextObj = it->second; | 227 CPDF_Object* pNextObj = it->second; |
| 228 ++it; | 228 ++it; |
| 229 if (!FXSYS_strcmp(key, "Parent") || !FXSYS_strcmp(key, "Prev") || | 229 if (!FXSYS_strcmp(key, "Parent") || !FXSYS_strcmp(key, "Prev") || |
| 230 !FXSYS_strcmp(key, "First")) { | 230 !FXSYS_strcmp(key, "First")) { |
| 231 continue; | 231 continue; |
| 232 } | 232 } |
| 233 if (pNextObj) { | 233 if (pNextObj) { |
| 234 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) | 234 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) |
| 235 pDict->RemoveAt(key); | 235 pDict->RemoveAt(key); |
| 236 } else { | 236 } else { |
| 237 return FALSE; | 237 return FALSE; |
| 238 } | 238 } |
| 239 } | 239 } |
| 240 break; | 240 break; |
| 241 } | 241 } |
| 242 case CPDF_Object::ARRAY: { | 242 case CPDF_Object::ARRAY: { |
| 243 CPDF_Array* pArray = pObj->AsArray(); | 243 CPDF_Array* pArray = pObj->AsArray(); |
| 244 FX_DWORD count = pArray->GetCount(); | 244 uint32_t count = pArray->GetCount(); |
| 245 for (FX_DWORD i = 0; i < count; ++i) { | 245 for (uint32_t i = 0; i < count; ++i) { |
| 246 CPDF_Object* pNextObj = pArray->GetElement(i); | 246 CPDF_Object* pNextObj = pArray->GetElement(i); |
| 247 if (!pNextObj) | 247 if (!pNextObj) |
| 248 return FALSE; | 248 return FALSE; |
| 249 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) | 249 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) |
| 250 return FALSE; | 250 return FALSE; |
| 251 } | 251 } |
| 252 break; | 252 break; |
| 253 } | 253 } |
| 254 case CPDF_Object::STREAM: { | 254 case CPDF_Object::STREAM: { |
| 255 CPDF_Stream* pStream = pObj->AsStream(); | 255 CPDF_Stream* pStream = pObj->AsStream(); |
| 256 CPDF_Dictionary* pDict = pStream->GetDict(); | 256 CPDF_Dictionary* pDict = pStream->GetDict(); |
| 257 if (pDict) { | 257 if (pDict) { |
| 258 if (!UpdateReference(pDict, pDoc, pObjNumberMap)) | 258 if (!UpdateReference(pDict, pDoc, pObjNumberMap)) |
| 259 return FALSE; | 259 return FALSE; |
| 260 } else { | 260 } else { |
| 261 return FALSE; | 261 return FALSE; |
| 262 } | 262 } |
| 263 break; | 263 break; |
| 264 } | 264 } |
| 265 default: | 265 default: |
| 266 break; | 266 break; |
| 267 } | 267 } |
| 268 | 268 |
| 269 return TRUE; | 269 return TRUE; |
| 270 } | 270 } |
| 271 | 271 |
| 272 FX_DWORD CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc, | 272 uint32_t CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc, |
| 273 ObjectNumberMap* pObjNumberMap, | 273 ObjectNumberMap* pObjNumberMap, |
| 274 CPDF_Reference* pRef) { | 274 CPDF_Reference* pRef) { |
| 275 if (!pRef) | 275 if (!pRef) |
| 276 return 0; | 276 return 0; |
| 277 | 277 |
| 278 FX_DWORD dwObjnum = pRef->GetRefObjNum(); | 278 uint32_t dwObjnum = pRef->GetRefObjNum(); |
| 279 FX_DWORD dwNewObjNum = 0; | 279 uint32_t dwNewObjNum = 0; |
| 280 const auto it = pObjNumberMap->find(dwObjnum); | 280 const auto it = pObjNumberMap->find(dwObjnum); |
| 281 if (it != pObjNumberMap->end()) | 281 if (it != pObjNumberMap->end()) |
| 282 dwNewObjNum = it->second; | 282 dwNewObjNum = it->second; |
| 283 if (dwNewObjNum) | 283 if (dwNewObjNum) |
| 284 return dwNewObjNum; | 284 return dwNewObjNum; |
| 285 | 285 |
| 286 CPDF_Object* pDirect = pRef->GetDirect(); | 286 CPDF_Object* pDirect = pRef->GetDirect(); |
| 287 if (!pDirect) | 287 if (!pDirect) |
| 288 return 0; | 288 return 0; |
| 289 | 289 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 if (!pSrcDict) | 406 if (!pSrcDict) |
| 407 return FALSE; | 407 return FALSE; |
| 408 | 408 |
| 409 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); | 409 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); |
| 410 if (!pDstDict) | 410 if (!pDstDict) |
| 411 return FALSE; | 411 return FALSE; |
| 412 | 412 |
| 413 pDstDict->SetAt("ViewerPreferences", pSrcDict->Clone(TRUE)); | 413 pDstDict->SetAt("ViewerPreferences", pSrcDict->Clone(TRUE)); |
| 414 return TRUE; | 414 return TRUE; |
| 415 } | 415 } |
| OLD | NEW |