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 |