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 "../include/fpdfxfa/fpdfxfa_doc.h" | 9 #include "../include/fpdfxfa/fpdfxfa_doc.h" |
10 #include "fpdfsdk/include/fsdk_define.h" | 10 #include "fpdfsdk/include/fsdk_define.h" |
| 11 #include "third_party/base/nonstd_unique_ptr.h" |
11 | 12 |
12 class CPDF_PageOrganizer { | 13 class CPDF_PageOrganizer { |
13 public: | 14 public: |
| 15 using ObjectNumberMap = std::map<FX_DWORD, FX_DWORD>; |
14 CPDF_PageOrganizer(); | 16 CPDF_PageOrganizer(); |
15 ~CPDF_PageOrganizer(); | 17 ~CPDF_PageOrganizer(); |
16 | 18 |
17 public: | |
18 FX_BOOL PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc); | 19 FX_BOOL PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc); |
19 FX_BOOL ExportPage(CPDF_Document* pSrcPDFDoc, | 20 FX_BOOL ExportPage(CPDF_Document* pSrcPDFDoc, |
20 CFX_WordArray* nPageNum, | 21 CFX_WordArray* nPageNum, |
21 CPDF_Document* pDestPDFDoc, | 22 CPDF_Document* pDestPDFDoc, |
22 int nIndex); | 23 int nIndex); |
23 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict, | 24 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict, |
24 CFX_ByteString nSrctag); | 25 CFX_ByteString nSrctag); |
25 FX_BOOL UpdateReference(CPDF_Object* pObj, | 26 FX_BOOL UpdateReference(CPDF_Object* pObj, |
26 CPDF_Document* pDoc, | 27 CPDF_Document* pDoc, |
27 CFX_MapPtrToPtr* pMapPtrToPtr); | 28 ObjectNumberMap* pObjNumberMap); |
28 int GetNewObjId(CPDF_Document* pDoc, | 29 FX_DWORD GetNewObjId(CPDF_Document* pDoc, |
29 CFX_MapPtrToPtr* pMapPtrToPtr, | 30 ObjectNumberMap* pObjNumberMap, |
30 CPDF_Reference* pRef); | 31 CPDF_Reference* pRef); |
31 }; | 32 }; |
32 | 33 |
33 CPDF_PageOrganizer::CPDF_PageOrganizer() {} | 34 CPDF_PageOrganizer::CPDF_PageOrganizer() {} |
34 | 35 |
35 CPDF_PageOrganizer::~CPDF_PageOrganizer() {} | 36 CPDF_PageOrganizer::~CPDF_PageOrganizer() {} |
36 | 37 |
37 FX_BOOL CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc, | 38 FX_BOOL CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc, |
38 CPDF_Document* pSrcPDFDoc) { | 39 CPDF_Document* pSrcPDFDoc) { |
39 if (!pDestPDFDoc || !pSrcPDFDoc) | 40 if (!pDestPDFDoc || !pSrcPDFDoc) |
40 return false; | 41 return FALSE; |
41 | 42 |
42 CPDF_Dictionary* pNewRoot = pDestPDFDoc->GetRoot(); | 43 CPDF_Dictionary* pNewRoot = pDestPDFDoc->GetRoot(); |
43 if (!pNewRoot) | 44 if (!pNewRoot) |
44 return FALSE; | 45 return FALSE; |
45 | 46 |
46 // Set the document information//////////////////////////////////////////// | 47 // Set the document information//////////////////////////////////////////// |
47 | 48 |
48 CPDF_Dictionary* DInfoDict = pDestPDFDoc->GetInfo(); | 49 CPDF_Dictionary* DInfoDict = pDestPDFDoc->GetInfo(); |
49 | |
50 if (!DInfoDict) | 50 if (!DInfoDict) |
51 return FALSE; | 51 return FALSE; |
52 | 52 |
53 CFX_ByteString producerstr; | 53 CFX_ByteString producerstr; |
54 producerstr.Format("PDFium"); | 54 producerstr.Format("PDFium"); |
55 DInfoDict->SetAt("Producer", new CPDF_String(producerstr)); | 55 DInfoDict->SetAt("Producer", new CPDF_String(producerstr)); |
56 | 56 |
57 // Set type//////////////////////////////////////////////////////////////// | 57 // Set type//////////////////////////////////////////////////////////////// |
58 CFX_ByteString cbRootType = pNewRoot->GetString("Type", ""); | 58 CFX_ByteString cbRootType = pNewRoot->GetString("Type", ""); |
59 if (cbRootType.Equal("")) { | 59 if (cbRootType.Equal("")) { |
60 pNewRoot->SetAt("Type", new CPDF_Name("Catalog")); | 60 pNewRoot->SetAt("Type", new CPDF_Name("Catalog")); |
61 } | 61 } |
62 | 62 |
63 CPDF_Dictionary* pNewPages = ToDictionary( | 63 CPDF_Object* pElement = pNewRoot->GetElement("Pages"); |
64 pNewRoot->GetElement("Pages") ? pNewRoot->GetElement("Pages")->GetDirect() | 64 CPDF_Dictionary* pNewPages = |
65 : nullptr); | 65 pElement ? ToDictionary(pElement->GetDirect()) : nullptr; |
66 | |
67 if (!pNewPages) { | 66 if (!pNewPages) { |
68 pNewPages = new CPDF_Dictionary; | 67 pNewPages = new CPDF_Dictionary; |
69 FX_DWORD NewPagesON = pDestPDFDoc->AddIndirectObject(pNewPages); | 68 FX_DWORD NewPagesON = pDestPDFDoc->AddIndirectObject(pNewPages); |
70 pNewRoot->SetAt("Pages", new CPDF_Reference(pDestPDFDoc, NewPagesON)); | 69 pNewRoot->SetAt("Pages", new CPDF_Reference(pDestPDFDoc, NewPagesON)); |
71 } | 70 } |
72 | 71 |
73 CFX_ByteString cbPageType = pNewPages->GetString("Type", ""); | 72 CFX_ByteString cbPageType = pNewPages->GetString("Type", ""); |
74 if (cbPageType.Equal("")) { | 73 if (cbPageType.Equal("")) { |
75 pNewPages->SetAt("Type", new CPDF_Name("Pages")); | 74 pNewPages->SetAt("Type", new CPDF_Name("Pages")); |
76 } | 75 } |
77 | 76 |
78 CPDF_Array* pKeysArray = pNewPages->GetArray("Kids"); | 77 CPDF_Array* pKeysArray = pNewPages->GetArray("Kids"); |
79 if (pKeysArray == NULL) { | 78 if (!pKeysArray) { |
80 CPDF_Array* pNewKids = new CPDF_Array; | 79 CPDF_Array* pNewKids = new CPDF_Array; |
81 FX_DWORD Kidsobjnum = -1; | 80 FX_DWORD Kidsobjnum = -1; |
82 Kidsobjnum = | 81 Kidsobjnum = pDestPDFDoc->AddIndirectObject(pNewKids); |
83 pDestPDFDoc->AddIndirectObject(pNewKids); //, Kidsobjnum, Kidsgennum); | |
84 | 82 |
85 pNewPages->SetAt( | 83 pNewPages->SetAt("Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum)); |
86 "Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum)); //, Kidsgennum)); | |
87 pNewPages->SetAt("Count", new CPDF_Number(0)); | 84 pNewPages->SetAt("Count", new CPDF_Number(0)); |
88 } | 85 } |
89 | 86 |
90 return true; | 87 return TRUE; |
91 } | 88 } |
92 | 89 |
93 FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, | 90 FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, |
94 CFX_WordArray* nPageNum, | 91 CFX_WordArray* nPageNum, |
95 CPDF_Document* pDestPDFDoc, | 92 CPDF_Document* pDestPDFDoc, |
96 int nIndex) { | 93 int nIndex) { |
97 int curpage = nIndex; | 94 int curpage = nIndex; |
98 | 95 |
99 CFX_MapPtrToPtr* pMapPtrToPtr = new CFX_MapPtrToPtr; | 96 nonstd::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); |
100 pMapPtrToPtr->InitHashTable(1001); | |
101 | 97 |
102 for (int i = 0; i < nPageNum->GetSize(); i++) { | 98 for (int i = 0; i < nPageNum->GetSize(); ++i) { |
103 CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); | 99 CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); |
104 CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(nPageNum->GetAt(i) - 1); | 100 CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(nPageNum->GetAt(i) - 1); |
105 if (!pSrcPageDict || !pCurPageDict) { | 101 if (!pSrcPageDict || !pCurPageDict) |
106 delete pMapPtrToPtr; | |
107 return FALSE; | 102 return FALSE; |
108 } | |
109 | 103 |
110 // Clone the page dictionary/////////// | 104 // Clone the page dictionary/////////// |
111 FX_POSITION SrcPos = pSrcPageDict->GetStartPos(); | 105 FX_POSITION SrcPos = pSrcPageDict->GetStartPos(); |
112 while (SrcPos) { | 106 while (SrcPos) { |
113 CFX_ByteString cbSrcKeyStr; | 107 CFX_ByteString cbSrcKeyStr; |
114 CPDF_Object* pObj = pSrcPageDict->GetNextElement(SrcPos, cbSrcKeyStr); | 108 CPDF_Object* pObj = pSrcPageDict->GetNextElement(SrcPos, cbSrcKeyStr); |
115 if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { | 109 if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { |
116 if (pCurPageDict->KeyExist(cbSrcKeyStr)) | 110 if (pCurPageDict->KeyExist(cbSrcKeyStr)) |
117 pCurPageDict->RemoveAt(cbSrcKeyStr); | 111 pCurPageDict->RemoveAt(cbSrcKeyStr); |
118 pCurPageDict->SetAt(cbSrcKeyStr, pObj->Clone()); | 112 pCurPageDict->SetAt(cbSrcKeyStr, pObj->Clone()); |
119 } | 113 } |
120 } | 114 } |
121 | 115 |
122 // inheritable item/////////////////////// | 116 // inheritable item/////////////////////// |
123 CPDF_Object* pInheritable = NULL; | 117 CPDF_Object* pInheritable = nullptr; |
124 // 1 MediaBox //required | 118 // 1 MediaBox //required |
125 if (!pCurPageDict->KeyExist("MediaBox")) { | 119 if (!pCurPageDict->KeyExist("MediaBox")) { |
126 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); | 120 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); |
127 if (!pInheritable) { | 121 if (!pInheritable) { |
128 // Search the "CropBox" from source page dictionary, if not exists,we | 122 // Search the "CropBox" from source page dictionary, |
129 // take the letter size. | 123 // if not exists,we take the letter size. |
130 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); | 124 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); |
131 if (pInheritable) | 125 if (pInheritable) { |
132 pCurPageDict->SetAt("MediaBox", pInheritable->Clone()); | 126 pCurPageDict->SetAt("MediaBox", pInheritable->Clone()); |
133 else { | 127 } else { |
134 // Make the default size to be letter size (8.5'x11') | 128 // Make the default size to be letter size (8.5'x11') |
135 CPDF_Array* pArray = new CPDF_Array; | 129 CPDF_Array* pArray = new CPDF_Array; |
136 pArray->AddNumber(0); | 130 pArray->AddNumber(0); |
137 pArray->AddNumber(0); | 131 pArray->AddNumber(0); |
138 pArray->AddNumber(612); | 132 pArray->AddNumber(612); |
139 pArray->AddNumber(792); | 133 pArray->AddNumber(792); |
140 pCurPageDict->SetAt("MediaBox", pArray); | 134 pCurPageDict->SetAt("MediaBox", pArray); |
141 } | 135 } |
142 } else | 136 } else { |
143 pCurPageDict->SetAt("MediaBox", pInheritable->Clone()); | 137 pCurPageDict->SetAt("MediaBox", pInheritable->Clone()); |
| 138 } |
144 } | 139 } |
145 // 2 Resources //required | 140 // 2 Resources //required |
146 if (!pCurPageDict->KeyExist("Resources")) { | 141 if (!pCurPageDict->KeyExist("Resources")) { |
147 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources"); | 142 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources"); |
148 if (!pInheritable) { | 143 if (!pInheritable) |
149 delete pMapPtrToPtr; | |
150 return FALSE; | 144 return FALSE; |
151 } | |
152 pCurPageDict->SetAt("Resources", pInheritable->Clone()); | 145 pCurPageDict->SetAt("Resources", pInheritable->Clone()); |
153 } | 146 } |
154 // 3 CropBox //Optional | 147 // 3 CropBox //Optional |
155 if (!pCurPageDict->KeyExist("CropBox")) { | 148 if (!pCurPageDict->KeyExist("CropBox")) { |
156 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); | 149 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); |
157 if (pInheritable) | 150 if (pInheritable) |
158 pCurPageDict->SetAt("CropBox", pInheritable->Clone()); | 151 pCurPageDict->SetAt("CropBox", pInheritable->Clone()); |
159 } | 152 } |
160 // 4 Rotate //Optional | 153 // 4 Rotate //Optional |
161 if (!pCurPageDict->KeyExist("Rotate")) { | 154 if (!pCurPageDict->KeyExist("Rotate")) { |
162 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); | 155 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); |
163 if (pInheritable) | 156 if (pInheritable) |
164 pCurPageDict->SetAt("Rotate", pInheritable->Clone()); | 157 pCurPageDict->SetAt("Rotate", pInheritable->Clone()); |
165 } | 158 } |
166 | 159 |
167 ///////////////////////////////////////////// | 160 ///////////////////////////////////////////// |
168 // Update the reference | 161 // Update the reference |
169 FX_DWORD dwOldPageObj = pSrcPageDict->GetObjNum(); | 162 FX_DWORD dwOldPageObj = pSrcPageDict->GetObjNum(); |
170 FX_DWORD dwNewPageObj = pCurPageDict->GetObjNum(); | 163 FX_DWORD dwNewPageObj = pCurPageDict->GetObjNum(); |
171 | 164 |
172 pMapPtrToPtr->SetAt((void*)(uintptr_t)dwOldPageObj, | 165 (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; |
173 (void*)(uintptr_t)dwNewPageObj); | |
174 | 166 |
175 UpdateReference(pCurPageDict, pDestPDFDoc, pMapPtrToPtr); | 167 UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); |
176 curpage++; | 168 ++curpage; |
177 } | 169 } |
178 | 170 |
179 delete pMapPtrToPtr; | |
180 return TRUE; | 171 return TRUE; |
181 } | 172 } |
182 | 173 |
183 CPDF_Object* CPDF_PageOrganizer::PageDictGetInheritableTag( | 174 CPDF_Object* CPDF_PageOrganizer::PageDictGetInheritableTag( |
184 CPDF_Dictionary* pDict, | 175 CPDF_Dictionary* pDict, |
185 CFX_ByteString nSrctag) { | 176 CFX_ByteString nSrctag) { |
186 if (!pDict || !pDict->KeyExist("Type") || nSrctag.IsEmpty()) | 177 if (!pDict || nSrctag.IsEmpty()) |
187 return NULL; | 178 return nullptr; |
| 179 if (!pDict->KeyExist("Parent") || !pDict->KeyExist("Type")) |
| 180 return nullptr; |
188 | 181 |
189 CPDF_Object* pType = pDict->GetElement("Type")->GetDirect(); | 182 CPDF_Object* pType = pDict->GetElement("Type")->GetDirect(); |
190 if (!ToName(pType)) | 183 if (!ToName(pType)) |
191 return nullptr; | 184 return nullptr; |
192 if (pType->GetString().Compare("Page")) | 185 if (pType->GetString().Compare("Page")) |
193 return NULL; | 186 return nullptr; |
194 if (!pDict->KeyExist("Parent")) | |
195 return NULL; | |
196 | 187 |
197 CPDF_Dictionary* pp = ToDictionary(pDict->GetElement("Parent")->GetDirect()); | 188 CPDF_Dictionary* pp = ToDictionary(pDict->GetElement("Parent")->GetDirect()); |
198 if (!pp) | 189 if (!pp) |
199 return nullptr; | 190 return nullptr; |
200 | 191 |
201 if (pDict->KeyExist((const char*)nSrctag)) | 192 if (pDict->KeyExist((const char*)nSrctag)) |
202 return pDict->GetElement((const char*)nSrctag); | 193 return pDict->GetElement((const char*)nSrctag); |
203 | 194 |
204 while (pp) { | 195 while (pp) { |
205 if (pp->KeyExist((const char*)nSrctag)) | 196 if (pp->KeyExist((const char*)nSrctag)) |
206 return pp->GetElement((const char*)nSrctag); | 197 return pp->GetElement((const char*)nSrctag); |
207 if (!pp->KeyExist("Parent")) { | 198 if (!pp->KeyExist("Parent")) |
208 break; | 199 break; |
209 } | |
210 pp = ToDictionary(pp->GetElement("Parent")->GetDirect()); | 200 pp = ToDictionary(pp->GetElement("Parent")->GetDirect()); |
211 } | 201 } |
212 return nullptr; | 202 return nullptr; |
213 } | 203 } |
214 | 204 |
215 FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, | 205 FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, |
216 CPDF_Document* pDoc, | 206 CPDF_Document* pDoc, |
217 CFX_MapPtrToPtr* pMapPtrToPtr) { | 207 ObjectNumberMap* pObjNumberMap) { |
218 switch (pObj->GetType()) { | 208 switch (pObj->GetType()) { |
219 case PDFOBJ_REFERENCE: { | 209 case PDFOBJ_REFERENCE: { |
220 CPDF_Reference* pReference = pObj->AsReference(); | 210 CPDF_Reference* pReference = pObj->AsReference(); |
221 int newobjnum = GetNewObjId(pDoc, pMapPtrToPtr, pReference); | 211 FX_DWORD newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference); |
222 if (newobjnum == 0) | 212 if (newobjnum == 0) |
223 return FALSE; | 213 return FALSE; |
224 pReference->SetRef(pDoc, newobjnum); | 214 pReference->SetRef(pDoc, newobjnum); |
225 break; | 215 break; |
226 } | 216 } |
227 case PDFOBJ_DICTIONARY: { | 217 case PDFOBJ_DICTIONARY: { |
228 CPDF_Dictionary* pDict = pObj->AsDictionary(); | 218 CPDF_Dictionary* pDict = pObj->AsDictionary(); |
229 | 219 |
230 FX_POSITION pos = pDict->GetStartPos(); | 220 FX_POSITION pos = pDict->GetStartPos(); |
231 while (pos) { | 221 while (pos) { |
232 CFX_ByteString key(""); | 222 CFX_ByteString key(""); |
233 CPDF_Object* pNextObj = pDict->GetNextElement(pos, key); | 223 CPDF_Object* pNextObj = pDict->GetNextElement(pos, key); |
234 if (!FXSYS_strcmp(key, "Parent") || !FXSYS_strcmp(key, "Prev") || | 224 if (!FXSYS_strcmp(key, "Parent") || !FXSYS_strcmp(key, "Prev") || |
235 !FXSYS_strcmp(key, "First")) | 225 !FXSYS_strcmp(key, "First")) { |
236 continue; | 226 continue; |
| 227 } |
237 if (pNextObj) { | 228 if (pNextObj) { |
238 if (!UpdateReference(pNextObj, pDoc, pMapPtrToPtr)) | 229 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) |
239 pDict->RemoveAt(key); | 230 pDict->RemoveAt(key); |
240 } else | 231 } else { |
241 return FALSE; | 232 return FALSE; |
| 233 } |
242 } | 234 } |
243 break; | 235 break; |
244 } | 236 } |
245 case PDFOBJ_ARRAY: { | 237 case PDFOBJ_ARRAY: { |
246 CPDF_Array* pArray = pObj->AsArray(); | 238 CPDF_Array* pArray = pObj->AsArray(); |
247 FX_DWORD count = pArray->GetCount(); | 239 FX_DWORD count = pArray->GetCount(); |
248 for (FX_DWORD i = 0; i < count; i++) { | 240 for (FX_DWORD i = 0; i < count; ++i) { |
249 CPDF_Object* pNextObj = pArray->GetElement(i); | 241 CPDF_Object* pNextObj = pArray->GetElement(i); |
250 if (pNextObj) { | 242 if (!pNextObj) |
251 if (!UpdateReference(pNextObj, pDoc, pMapPtrToPtr)) | 243 return FALSE; |
252 return FALSE; | 244 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) |
253 } else | |
254 return FALSE; | 245 return FALSE; |
255 } | 246 } |
256 break; | 247 break; |
257 } | 248 } |
258 case PDFOBJ_STREAM: { | 249 case PDFOBJ_STREAM: { |
259 CPDF_Stream* pStream = pObj->AsStream(); | 250 CPDF_Stream* pStream = pObj->AsStream(); |
260 CPDF_Dictionary* pDict = pStream->GetDict(); | 251 CPDF_Dictionary* pDict = pStream->GetDict(); |
261 if (pDict) { | 252 if (pDict) { |
262 if (!UpdateReference(pDict, pDoc, pMapPtrToPtr)) | 253 if (!UpdateReference(pDict, pDoc, pObjNumberMap)) |
263 return FALSE; | 254 return FALSE; |
264 } else | 255 } else { |
265 return FALSE; | 256 return FALSE; |
| 257 } |
266 break; | 258 break; |
267 } | 259 } |
268 default: | 260 default: |
269 break; | 261 break; |
270 } | 262 } |
271 | 263 |
272 return TRUE; | 264 return TRUE; |
273 } | 265 } |
274 | 266 |
275 int CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc, | 267 FX_DWORD CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc, |
276 CFX_MapPtrToPtr* pMapPtrToPtr, | 268 ObjectNumberMap* pObjNumberMap, |
277 CPDF_Reference* pRef) { | 269 CPDF_Reference* pRef) { |
278 if (!pRef) | 270 if (!pRef) |
279 return 0; | 271 return 0; |
280 | 272 |
281 size_t dwObjnum = pRef->GetRefObjNum(); | 273 FX_DWORD dwObjnum = pRef->GetRefObjNum(); |
282 size_t dwNewObjNum = 0; | 274 FX_DWORD dwNewObjNum = 0; |
283 | 275 const auto it = pObjNumberMap->find(dwObjnum); |
284 pMapPtrToPtr->Lookup((void*)dwObjnum, (void*&)dwNewObjNum); | 276 if (it != pObjNumberMap->end()) |
285 if (dwNewObjNum) { | 277 dwNewObjNum = it->second; |
286 return (int)dwNewObjNum; | 278 if (dwNewObjNum) |
287 } | 279 return dwNewObjNum; |
288 | 280 |
289 CPDF_Object* pDirect = pRef->GetDirect(); | 281 CPDF_Object* pDirect = pRef->GetDirect(); |
290 if (!pDirect) { | 282 if (!pDirect) |
291 return 0; | 283 return 0; |
292 } | |
293 | 284 |
294 CPDF_Object* pClone = pDirect->Clone(); | 285 CPDF_Object* pClone = pDirect->Clone(); |
295 if (!pClone) { | 286 if (!pClone) |
296 return 0; | 287 return 0; |
297 } | |
298 | 288 |
299 if (CPDF_Dictionary* pDictClone = pClone->AsDictionary()) { | 289 if (CPDF_Dictionary* pDictClone = pClone->AsDictionary()) { |
300 if (pDictClone->KeyExist("Type")) { | 290 if (pDictClone->KeyExist("Type")) { |
301 CFX_ByteString strType = pDictClone->GetString("Type"); | 291 CFX_ByteString strType = pDictClone->GetString("Type"); |
302 if (!FXSYS_stricmp(strType, "Pages")) { | 292 if (!FXSYS_stricmp(strType, "Pages")) { |
303 pDictClone->Release(); | 293 pDictClone->Release(); |
304 return 4; | 294 return 4; |
305 } else if (!FXSYS_stricmp(strType, "Page")) { | 295 } |
| 296 if (!FXSYS_stricmp(strType, "Page")) { |
306 pDictClone->Release(); | 297 pDictClone->Release(); |
307 return 0; | 298 return 0; |
308 } | 299 } |
309 } | 300 } |
310 } | 301 } |
311 | |
312 dwNewObjNum = pDoc->AddIndirectObject(pClone); | 302 dwNewObjNum = pDoc->AddIndirectObject(pClone); |
313 pMapPtrToPtr->SetAt((void*)dwObjnum, (void*)dwNewObjNum); | 303 (*pObjNumberMap)[dwObjnum] = dwNewObjNum; |
314 if (!UpdateReference(pClone, pDoc, pMapPtrToPtr)) { | 304 if (!UpdateReference(pClone, pDoc, pObjNumberMap)) { |
315 pClone->Release(); | 305 pClone->Release(); |
316 return 0; | 306 return 0; |
317 } | 307 } |
318 | 308 return dwNewObjNum; |
319 return (int)dwNewObjNum; | |
320 } | 309 } |
321 | 310 |
322 FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring, | 311 FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring, |
323 CFX_WordArray* pageArray, | 312 CFX_WordArray* pageArray, |
324 int nCount) { | 313 int nCount) { |
325 if (rangstring.GetLength() != 0) { | 314 if (rangstring.GetLength() != 0) { |
326 rangstring.Remove(' '); | 315 rangstring.Remove(' '); |
327 int nLength = rangstring.GetLength(); | 316 int nLength = rangstring.GetLength(); |
328 CFX_ByteString cbCompareString("0123456789-,"); | 317 CFX_ByteString cbCompareString("0123456789-,"); |
329 for (int i = 0; i < nLength; i++) { | 318 for (int i = 0; i < nLength; ++i) { |
330 if (cbCompareString.Find(rangstring[i]) == -1) | 319 if (cbCompareString.Find(rangstring[i]) == -1) |
331 return FALSE; | 320 return FALSE; |
332 } | 321 } |
333 CFX_ByteString cbMidRange; | 322 CFX_ByteString cbMidRange; |
334 int nStringFrom = 0; | 323 int nStringFrom = 0; |
335 int nStringTo = 0; | 324 int nStringTo = 0; |
336 while (nStringTo < nLength) { | 325 while (nStringTo < nLength) { |
337 nStringTo = rangstring.Find(',', nStringFrom); | 326 nStringTo = rangstring.Find(',', nStringFrom); |
338 if (nStringTo == -1) { | 327 if (nStringTo == -1) |
339 nStringTo = nLength; | 328 nStringTo = nLength; |
340 } | |
341 cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom); | 329 cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom); |
342 | |
343 int nMid = cbMidRange.Find('-'); | 330 int nMid = cbMidRange.Find('-'); |
344 if (nMid == -1) { | 331 if (nMid == -1) { |
345 long lPageNum = atol(cbMidRange); | 332 long lPageNum = atol(cbMidRange); |
346 if (lPageNum <= 0 || lPageNum > nCount) | 333 if (lPageNum <= 0 || lPageNum > nCount) |
347 return FALSE; | 334 return FALSE; |
348 | |
349 pageArray->Add((FX_WORD)lPageNum); | 335 pageArray->Add((FX_WORD)lPageNum); |
350 } else { | 336 } else { |
351 int nStartPageNum = atol(cbMidRange.Mid(0, nMid)); | 337 int nStartPageNum = atol(cbMidRange.Mid(0, nMid)); |
352 if (nStartPageNum == 0) | 338 if (nStartPageNum == 0) |
353 return FALSE; | 339 return FALSE; |
354 | 340 |
355 nMid = nMid + 1; | 341 ++nMid; |
356 int nEnd = cbMidRange.GetLength() - nMid; | 342 int nEnd = cbMidRange.GetLength() - nMid; |
357 if (nEnd == 0) | 343 if (nEnd == 0) |
358 return FALSE; | 344 return FALSE; |
359 | 345 |
360 int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd)); | 346 int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd)); |
361 if (nStartPageNum < 0 || nStartPageNum > nEndPageNum || | 347 if (nStartPageNum < 0 || nStartPageNum > nEndPageNum || |
362 nEndPageNum > nCount) | 348 nEndPageNum > nCount) { |
363 return FALSE; | 349 return FALSE; |
364 | 350 } |
365 for (int nIndex = nStartPageNum; nIndex <= nEndPageNum; ++nIndex) | 351 for (int i = nStartPageNum; i <= nEndPageNum; ++i) { |
366 pageArray->Add(nIndex); | 352 pageArray->Add(i); |
| 353 } |
367 } | 354 } |
368 nStringFrom = nStringTo + 1; | 355 nStringFrom = nStringTo + 1; |
369 } | 356 } |
370 } | 357 } |
371 return TRUE; | 358 return TRUE; |
372 } | 359 } |
373 | 360 |
374 DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc, | 361 DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc, |
375 FPDF_DOCUMENT src_doc, | 362 FPDF_DOCUMENT src_doc, |
376 FPDF_BYTESTRING pagerange, | 363 FPDF_BYTESTRING pagerange, |
377 int index) { | 364 int index) { |
378 CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc); | 365 CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc); |
379 if (!dest_doc) | 366 if (!dest_doc) |
380 return FALSE; | 367 return FALSE; |
381 | 368 |
382 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); | 369 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); |
383 if (!pSrcDoc) | 370 if (!pSrcDoc) |
384 return FALSE; | 371 return FALSE; |
| 372 |
385 CFX_WordArray pageArray; | 373 CFX_WordArray pageArray; |
386 int nCount = pSrcDoc->GetPageCount(); | 374 int nCount = pSrcDoc->GetPageCount(); |
387 if (pagerange) { | 375 if (pagerange) { |
388 if (ParserPageRangeString(pagerange, &pageArray, nCount) == FALSE) | 376 if (!ParserPageRangeString(pagerange, &pageArray, nCount)) |
389 return FALSE; | 377 return FALSE; |
390 } else { | 378 } else { |
391 for (int i = 1; i <= nCount; i++) { | 379 for (int i = 1; i <= nCount; ++i) { |
392 pageArray.Add(i); | 380 pageArray.Add(i); |
393 } | 381 } |
394 } | 382 } |
395 | 383 |
396 CPDF_PageOrganizer pageOrg; | 384 CPDF_PageOrganizer pageOrg; |
397 pageOrg.PDFDocInit(pDestDoc, pSrcDoc); | 385 pageOrg.PDFDocInit(pDestDoc, pSrcDoc); |
398 return pageOrg.ExportPage(pSrcDoc, &pageArray, pDestDoc, index); | 386 return pageOrg.ExportPage(pSrcDoc, &pageArray, pDestDoc, index); |
399 } | 387 } |
400 | 388 |
401 DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, | 389 DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, |
(...skipping 11 matching lines...) Expand all Loading... |
413 if (!pSrcDict) | 401 if (!pSrcDict) |
414 return FALSE; | 402 return FALSE; |
415 | 403 |
416 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); | 404 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); |
417 if (!pDstDict) | 405 if (!pDstDict) |
418 return FALSE; | 406 return FALSE; |
419 | 407 |
420 pDstDict->SetAt(FX_BSTRC("ViewerPreferences"), pSrcDict->Clone(TRUE)); | 408 pDstDict->SetAt(FX_BSTRC("ViewerPreferences"), pSrcDict->Clone(TRUE)); |
421 return TRUE; | 409 return TRUE; |
422 } | 410 } |
OLD | NEW |