Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: fpdfsdk/fpdfppo.cpp

Issue 2493283003: Fix nits in CPDF_PageOrganizer. (Closed)
Patch Set: Shuffle code, address nits Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ptr_util.h"
21 #include "third_party/base/stl_util.h" 22 #include "third_party/base/stl_util.h"
22 23
24 namespace {
25
26 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict,
27 const CFX_ByteString& bsSrcTag) {
28 if (!pDict || bsSrcTag.IsEmpty())
29 return nullptr;
30 if (!pDict->KeyExist("Parent") || !pDict->KeyExist("Type"))
31 return nullptr;
32
33 CPDF_Object* pType = pDict->GetObjectFor("Type")->GetDirect();
34 if (!ToName(pType))
35 return nullptr;
36 if (pType->GetString().Compare("Page"))
37 return nullptr;
38
39 CPDF_Dictionary* pp =
40 ToDictionary(pDict->GetObjectFor("Parent")->GetDirect());
41 if (!pp)
42 return nullptr;
43
44 if (pDict->KeyExist(bsSrcTag))
45 return pDict->GetObjectFor(bsSrcTag);
46
47 while (pp) {
48 if (pp->KeyExist(bsSrcTag))
49 return pp->GetObjectFor(bsSrcTag);
50 if (!pp->KeyExist("Parent"))
51 break;
52 pp = ToDictionary(pp->GetObjectFor("Parent")->GetDirect());
53 }
54 return nullptr;
55 }
56
57 bool CopyInheritable(CPDF_Dictionary* pCurPageDict,
58 CPDF_Dictionary* pSrcPageDict,
59 const CFX_ByteString& key) {
60 if (pCurPageDict->KeyExist(key))
61 return true;
62
63 CPDF_Object* pInheritable = PageDictGetInheritableTag(pSrcPageDict, key);
64 if (!pInheritable)
65 return false;
66
67 pCurPageDict->SetFor(key, pInheritable->Clone().release());
68 return true;
69 }
70
71 bool ParserPageRangeString(CFX_ByteString rangstring,
72 std::vector<uint16_t>* pageArray,
73 int nCount) {
74 if (rangstring.IsEmpty())
75 return true;
76
77 rangstring.Remove(' ');
78 int nLength = rangstring.GetLength();
79 CFX_ByteString cbCompareString("0123456789-,");
80 for (int i = 0; i < nLength; ++i) {
81 if (cbCompareString.Find(rangstring[i]) == -1)
82 return false;
83 }
84
85 CFX_ByteString cbMidRange;
86 int nStringFrom = 0;
87 int nStringTo = 0;
88 while (nStringTo < nLength) {
89 nStringTo = rangstring.Find(',', nStringFrom);
90 if (nStringTo == -1)
91 nStringTo = nLength;
92 cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom);
93 int nMid = cbMidRange.Find('-');
94 if (nMid == -1) {
95 long lPageNum = atol(cbMidRange.c_str());
96 if (lPageNum <= 0 || lPageNum > nCount)
97 return false;
98 pageArray->push_back((uint16_t)lPageNum);
99 } else {
100 int nStartPageNum = atol(cbMidRange.Mid(0, nMid).c_str());
101 if (nStartPageNum == 0)
102 return false;
103
104 ++nMid;
105 int nEnd = cbMidRange.GetLength() - nMid;
106 if (nEnd == 0)
107 return false;
108
109 int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd).c_str());
110 if (nStartPageNum < 0 || nStartPageNum > nEndPageNum ||
111 nEndPageNum > nCount) {
112 return false;
113 }
114 for (int i = nStartPageNum; i <= nEndPageNum; ++i) {
115 pageArray->push_back(i);
116 }
117 }
118 nStringFrom = nStringTo + 1;
119 }
120 return true;
121 }
122
123 } // namespace
124
23 class CPDF_PageOrganizer { 125 class CPDF_PageOrganizer {
24 public: 126 public:
25 using ObjectNumberMap = std::map<uint32_t, uint32_t>; 127 CPDF_PageOrganizer(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc);
26 CPDF_PageOrganizer();
27 ~CPDF_PageOrganizer(); 128 ~CPDF_PageOrganizer();
28 129
29 bool PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc); 130 bool PDFDocInit();
30 bool ExportPage(CPDF_Document* pSrcPDFDoc, 131 bool ExportPage(const std::vector<uint16_t>& pageNums, int nIndex);
31 std::vector<uint16_t>* pPageNums, 132
32 CPDF_Document* pDestPDFDoc, 133 private:
33 int nIndex); 134 using ObjectNumberMap = std::map<uint32_t, uint32_t>;
34 CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict, 135
35 const CFX_ByteString& bsSrctag); 136 bool UpdateReference(CPDF_Object* pObj, ObjectNumberMap* pObjNumberMap);
36 bool UpdateReference(CPDF_Object* pObj, 137 uint32_t GetNewObjId(ObjectNumberMap* pObjNumberMap, CPDF_Reference* pRef);
37 CPDF_Document* pDoc, 138
38 ObjectNumberMap* pObjNumberMap); 139 CPDF_Document* m_pDestPDFDoc;
39 uint32_t GetNewObjId(CPDF_Document* pDoc, 140 CPDF_Document* m_pSrcPDFDoc;
40 ObjectNumberMap* pObjNumberMap,
41 CPDF_Reference* pRef);
42 }; 141 };
43 142
44 CPDF_PageOrganizer::CPDF_PageOrganizer() {} 143 CPDF_PageOrganizer::CPDF_PageOrganizer(CPDF_Document* pDestPDFDoc,
144 CPDF_Document* pSrcPDFDoc)
145 : m_pDestPDFDoc(pDestPDFDoc), m_pSrcPDFDoc(pSrcPDFDoc) {}
45 146
46 CPDF_PageOrganizer::~CPDF_PageOrganizer() {} 147 CPDF_PageOrganizer::~CPDF_PageOrganizer() {}
47 148
48 bool CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc, 149 bool CPDF_PageOrganizer::PDFDocInit() {
49 CPDF_Document* pSrcPDFDoc) { 150 ASSERT(m_pDestPDFDoc);
50 if (!pDestPDFDoc || !pSrcPDFDoc) 151 ASSERT(m_pSrcPDFDoc);
51 return false;
52 152
53 CPDF_Dictionary* pNewRoot = pDestPDFDoc->GetRoot(); 153 CPDF_Dictionary* pNewRoot = m_pDestPDFDoc->GetRoot();
54 if (!pNewRoot) 154 if (!pNewRoot)
55 return false; 155 return false;
56 156
57 CPDF_Dictionary* DInfoDict = pDestPDFDoc->GetInfo(); 157 CPDF_Dictionary* pDocInfoDict = m_pDestPDFDoc->GetInfo();
58 if (!DInfoDict) 158 if (!pDocInfoDict)
59 return false; 159 return false;
60 160
61 CFX_ByteString producerstr; 161 CFX_ByteString producerstr;
62 producerstr.Format("PDFium"); 162 producerstr.Format("PDFium");
63 DInfoDict->SetFor("Producer", new CPDF_String(producerstr, false)); 163 pDocInfoDict->SetFor("Producer", new CPDF_String(producerstr, false));
64 164
65 CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", ""); 165 CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", "");
66 if (cbRootType.IsEmpty()) 166 if (cbRootType.IsEmpty())
67 pNewRoot->SetFor("Type", new CPDF_Name("Catalog")); 167 pNewRoot->SetFor("Type", new CPDF_Name("Catalog"));
68 168
69 CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages"); 169 CPDF_Object* pElement = pNewRoot->GetObjectFor("Pages");
70 CPDF_Dictionary* pNewPages = 170 CPDF_Dictionary* pNewPages =
71 pElement ? ToDictionary(pElement->GetDirect()) : nullptr; 171 pElement ? ToDictionary(pElement->GetDirect()) : nullptr;
72 if (!pNewPages) { 172 if (!pNewPages) {
73 pNewPages = new CPDF_Dictionary(pDestPDFDoc->GetByteStringPool()); 173 pNewPages = new CPDF_Dictionary(m_pDestPDFDoc->GetByteStringPool());
74 pNewRoot->SetReferenceFor("Pages", pDestPDFDoc, 174 pNewRoot->SetReferenceFor("Pages", m_pDestPDFDoc,
75 pDestPDFDoc->AddIndirectObject(pNewPages)); 175 m_pDestPDFDoc->AddIndirectObject(pNewPages));
76 } 176 }
77 177
78 CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", ""); 178 CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", "");
79 if (cbPageType == "") { 179 if (cbPageType.IsEmpty())
80 pNewPages->SetFor("Type", new CPDF_Name("Pages")); 180 pNewPages->SetFor("Type", new CPDF_Name("Pages"));
81 }
82 181
83 if (!pNewPages->GetArrayFor("Kids")) { 182 if (!pNewPages->GetArrayFor("Kids")) {
84 pNewPages->SetIntegerFor("Count", 0); 183 pNewPages->SetIntegerFor("Count", 0);
85 pNewPages->SetReferenceFor("Kids", pDestPDFDoc, 184 pNewPages->SetReferenceFor(
86 pDestPDFDoc->AddIndirectObject(new CPDF_Array)); 185 "Kids", m_pDestPDFDoc,
186 m_pDestPDFDoc->AddIndirectObject(new CPDF_Array));
87 } 187 }
88 188
89 return true; 189 return true;
90 } 190 }
91 191
92 bool CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, 192 bool CPDF_PageOrganizer::ExportPage(const std::vector<uint16_t>& pageNums,
93 std::vector<uint16_t>* pPageNums,
94 CPDF_Document* pDestPDFDoc,
95 int nIndex) { 193 int nIndex) {
96 int curpage = nIndex; 194 int curpage = nIndex;
97 std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); 195 auto pObjNumberMap = pdfium::MakeUnique<ObjectNumberMap>();
98 int nSize = pdfium::CollectionSize<int>(*pPageNums); 196 int nSize = pdfium::CollectionSize<int>(pageNums);
99 for (int i = 0; i < nSize; ++i) { 197 for (int i = 0; i < nSize; ++i) {
100 CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); 198 CPDF_Dictionary* pCurPageDict = m_pDestPDFDoc->CreateNewPage(curpage);
101 CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(pPageNums->at(i) - 1); 199 CPDF_Dictionary* pSrcPageDict = m_pSrcPDFDoc->GetPage(pageNums[i] - 1);
102 if (!pSrcPageDict || !pCurPageDict) 200 if (!pSrcPageDict || !pCurPageDict)
103 return false; 201 return false;
104 202
105 // Clone the page dictionary 203 // Clone the page dictionary
106 for (const auto& it : *pSrcPageDict) { 204 for (const auto& it : *pSrcPageDict) {
107 const CFX_ByteString& cbSrcKeyStr = it.first; 205 const CFX_ByteString& cbSrcKeyStr = it.first;
108 CPDF_Object* pObj = it.second; 206 CPDF_Object* pObj = it.second;
109 if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { 207 if (cbSrcKeyStr == "Type" || cbSrcKeyStr == "Parent")
110 if (pCurPageDict->KeyExist(cbSrcKeyStr)) 208 continue;
111 pCurPageDict->RemoveFor(cbSrcKeyStr); 209
112 pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone().release()); 210 pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone().release());
211 }
212
213 // inheritable item
214 // 1 MediaBox - required
215 if (!CopyInheritable(pCurPageDict, pSrcPageDict, "MediaBox")) {
216 // Search for "CropBox" in the source page dictionary,
217 // if it does not exists, use the default letter size.
218 CPDF_Object* pInheritable =
219 PageDictGetInheritableTag(pSrcPageDict, "CropBox");
220 if (pInheritable) {
221 pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release());
222 } else {
223 // Make the default size to be letter size (8.5'x11')
224 CPDF_Array* pArray = new CPDF_Array;
225 pArray->AddNumber(0);
226 pArray->AddNumber(0);
227 pArray->AddNumber(612);
228 pArray->AddNumber(792);
229 pCurPageDict->SetFor("MediaBox", pArray);
113 } 230 }
114 } 231 }
115 232
116 // inheritable item 233 // 2 Resources - required
117 CPDF_Object* pInheritable = nullptr; 234 if (!CopyInheritable(pCurPageDict, pSrcPageDict, "Resources"))
118 // 1 MediaBox //required 235 return false;
119 if (!pCurPageDict->KeyExist("MediaBox")) { 236
120 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); 237 // 3 CropBox - optional
121 if (!pInheritable) { 238 CopyInheritable(pCurPageDict, pSrcPageDict, "CropBox");
122 // Search the "CropBox" from source page dictionary, 239 // 4 Rotate - optional
123 // if not exists,we take the letter size. 240 CopyInheritable(pCurPageDict, pSrcPageDict, "Rotate");
124 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox");
125 if (pInheritable) {
126 pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release());
127 } else {
128 // Make the default size to be letter size (8.5'x11')
129 CPDF_Array* pArray = new CPDF_Array;
130 pArray->AddNumber(0);
131 pArray->AddNumber(0);
132 pArray->AddNumber(612);
133 pArray->AddNumber(792);
134 pCurPageDict->SetFor("MediaBox", pArray);
135 }
136 } else {
137 pCurPageDict->SetFor("MediaBox", pInheritable->Clone().release());
138 }
139 }
140 // 2 Resources //required
141 if (!pCurPageDict->KeyExist("Resources")) {
142 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources");
143 if (!pInheritable)
144 return false;
145 pCurPageDict->SetFor("Resources", pInheritable->Clone().release());
146 }
147 // 3 CropBox //Optional
148 if (!pCurPageDict->KeyExist("CropBox")) {
149 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox");
150 if (pInheritable)
151 pCurPageDict->SetFor("CropBox", pInheritable->Clone().release());
152 }
153 // 4 Rotate //Optional
154 if (!pCurPageDict->KeyExist("Rotate")) {
155 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate");
156 if (pInheritable)
157 pCurPageDict->SetFor("Rotate", pInheritable->Clone().release());
158 }
159 241
160 // Update the reference 242 // Update the reference
161 uint32_t dwOldPageObj = pSrcPageDict->GetObjNum(); 243 uint32_t dwOldPageObj = pSrcPageDict->GetObjNum();
162 uint32_t dwNewPageObj = pCurPageDict->GetObjNum(); 244 uint32_t dwNewPageObj = pCurPageDict->GetObjNum();
163 (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; 245 (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj;
164 UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); 246 UpdateReference(pCurPageDict, pObjNumberMap.get());
165 ++curpage; 247 ++curpage;
166 } 248 }
167 249
168 return true; 250 return true;
169 } 251 }
170 252
171 CPDF_Object* CPDF_PageOrganizer::PageDictGetInheritableTag(
172 CPDF_Dictionary* pDict,
173 const CFX_ByteString& bsSrcTag) {
174 if (!pDict || bsSrcTag.IsEmpty())
175 return nullptr;
176 if (!pDict->KeyExist("Parent") || !pDict->KeyExist("Type"))
177 return nullptr;
178
179 CPDF_Object* pType = pDict->GetObjectFor("Type")->GetDirect();
180 if (!ToName(pType))
181 return nullptr;
182 if (pType->GetString().Compare("Page"))
183 return nullptr;
184
185 CPDF_Dictionary* pp =
186 ToDictionary(pDict->GetObjectFor("Parent")->GetDirect());
187 if (!pp)
188 return nullptr;
189
190 if (pDict->KeyExist(bsSrcTag))
191 return pDict->GetObjectFor(bsSrcTag);
192
193 while (pp) {
194 if (pp->KeyExist(bsSrcTag))
195 return pp->GetObjectFor(bsSrcTag);
196 if (!pp->KeyExist("Parent"))
197 break;
198 pp = ToDictionary(pp->GetObjectFor("Parent")->GetDirect());
199 }
200 return nullptr;
201 }
202
203 bool CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, 253 bool CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj,
204 CPDF_Document* pDoc,
205 ObjectNumberMap* pObjNumberMap) { 254 ObjectNumberMap* pObjNumberMap) {
206 switch (pObj->GetType()) { 255 switch (pObj->GetType()) {
207 case CPDF_Object::REFERENCE: { 256 case CPDF_Object::REFERENCE: {
208 CPDF_Reference* pReference = pObj->AsReference(); 257 CPDF_Reference* pReference = pObj->AsReference();
209 uint32_t newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference); 258 uint32_t newobjnum = GetNewObjId(pObjNumberMap, pReference);
210 if (newobjnum == 0) 259 if (newobjnum == 0)
211 return false; 260 return false;
212 pReference->SetRef(pDoc, newobjnum); 261 pReference->SetRef(m_pDestPDFDoc, newobjnum);
213 break; 262 break;
214 } 263 }
215 case CPDF_Object::DICTIONARY: { 264 case CPDF_Object::DICTIONARY: {
216 CPDF_Dictionary* pDict = pObj->AsDictionary(); 265 CPDF_Dictionary* pDict = pObj->AsDictionary();
217 auto it = pDict->begin(); 266 auto it = pDict->begin();
218 while (it != pDict->end()) { 267 while (it != pDict->end()) {
219 const CFX_ByteString& key = it->first; 268 const CFX_ByteString& key = it->first;
220 CPDF_Object* pNextObj = it->second; 269 CPDF_Object* pNextObj = it->second;
221 ++it; 270 ++it;
222 if (key == "Parent" || key == "Prev" || key == "First") 271 if (key == "Parent" || key == "Prev" || key == "First")
223 continue; 272 continue;
224 if (!pNextObj) 273 if (!pNextObj)
225 return false; 274 return false;
226 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) 275 if (!UpdateReference(pNextObj, pObjNumberMap))
227 pDict->RemoveFor(key); 276 pDict->RemoveFor(key);
228 } 277 }
229 break; 278 break;
230 } 279 }
231 case CPDF_Object::ARRAY: { 280 case CPDF_Object::ARRAY: {
232 CPDF_Array* pArray = pObj->AsArray(); 281 CPDF_Array* pArray = pObj->AsArray();
233 for (size_t i = 0; i < pArray->GetCount(); ++i) { 282 for (size_t i = 0; i < pArray->GetCount(); ++i) {
234 CPDF_Object* pNextObj = pArray->GetObjectAt(i); 283 CPDF_Object* pNextObj = pArray->GetObjectAt(i);
235 if (!pNextObj) 284 if (!pNextObj)
236 return false; 285 return false;
237 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) 286 if (!UpdateReference(pNextObj, pObjNumberMap))
238 return false; 287 return false;
239 } 288 }
240 break; 289 break;
241 } 290 }
242 case CPDF_Object::STREAM: { 291 case CPDF_Object::STREAM: {
243 CPDF_Stream* pStream = pObj->AsStream(); 292 CPDF_Stream* pStream = pObj->AsStream();
244 CPDF_Dictionary* pDict = pStream->GetDict(); 293 CPDF_Dictionary* pDict = pStream->GetDict();
245 if (pDict) { 294 if (!pDict)
246 if (!UpdateReference(pDict, pDoc, pObjNumberMap))
247 return false;
248 } else {
249 return false; 295 return false;
250 } 296 if (!UpdateReference(pDict, pObjNumberMap))
297 return false;
251 break; 298 break;
252 } 299 }
253 default: 300 default:
254 break; 301 break;
255 } 302 }
256 303
257 return true; 304 return true;
258 } 305 }
259 306
260 uint32_t CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc, 307 uint32_t CPDF_PageOrganizer::GetNewObjId(ObjectNumberMap* pObjNumberMap,
261 ObjectNumberMap* pObjNumberMap,
262 CPDF_Reference* pRef) { 308 CPDF_Reference* pRef) {
263 if (!pRef) 309 if (!pRef)
264 return 0; 310 return 0;
265 311
266 uint32_t dwObjnum = pRef->GetRefObjNum(); 312 uint32_t dwObjnum = pRef->GetRefObjNum();
267 uint32_t dwNewObjNum = 0; 313 uint32_t dwNewObjNum = 0;
268 const auto it = pObjNumberMap->find(dwObjnum); 314 const auto it = pObjNumberMap->find(dwObjnum);
269 if (it != pObjNumberMap->end()) 315 if (it != pObjNumberMap->end())
270 dwNewObjNum = it->second; 316 dwNewObjNum = it->second;
271 if (dwNewObjNum) 317 if (dwNewObjNum)
272 return dwNewObjNum; 318 return dwNewObjNum;
273 319
274 CPDF_Object* pDirect = pRef->GetDirect(); 320 CPDF_Object* pDirect = pRef->GetDirect();
275 if (!pDirect) 321 if (!pDirect)
276 return 0; 322 return 0;
277 323
278 std::unique_ptr<CPDF_Object> pClone = pDirect->Clone(); 324 std::unique_ptr<CPDF_Object> pClone = pDirect->Clone();
279 if (CPDF_Dictionary* pDictClone = pClone->AsDictionary()) { 325 if (CPDF_Dictionary* pDictClone = pClone->AsDictionary()) {
280 if (pDictClone->KeyExist("Type")) { 326 if (pDictClone->KeyExist("Type")) {
281 CFX_ByteString strType = pDictClone->GetStringFor("Type"); 327 CFX_ByteString strType = pDictClone->GetStringFor("Type");
282 if (!FXSYS_stricmp(strType.c_str(), "Pages")) 328 if (!FXSYS_stricmp(strType.c_str(), "Pages"))
283 return 4; 329 return 4;
284 if (!FXSYS_stricmp(strType.c_str(), "Page")) 330 if (!FXSYS_stricmp(strType.c_str(), "Page"))
285 return 0; 331 return 0;
286 } 332 }
287 } 333 }
288 CPDF_Object* pUnownedClone = pClone.get(); 334 CPDF_Object* pUnownedClone = pClone.get();
289 dwNewObjNum = pDoc->AddIndirectObject(pClone.release()); 335 dwNewObjNum = m_pDestPDFDoc->AddIndirectObject(pClone.release());
290 (*pObjNumberMap)[dwObjnum] = dwNewObjNum; 336 (*pObjNumberMap)[dwObjnum] = dwNewObjNum;
291 if (!UpdateReference(pUnownedClone, pDoc, pObjNumberMap)) 337 if (!UpdateReference(pUnownedClone, pObjNumberMap))
292 return 0; 338 return 0;
293 339
294 return dwNewObjNum; 340 return dwNewObjNum;
295 } 341 }
296 342
297 FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring,
298 std::vector<uint16_t>* pageArray,
299 int nCount) {
300 if (rangstring.GetLength() != 0) {
301 rangstring.Remove(' ');
302 int nLength = rangstring.GetLength();
303 CFX_ByteString cbCompareString("0123456789-,");
304 for (int i = 0; i < nLength; ++i) {
305 if (cbCompareString.Find(rangstring[i]) == -1)
306 return false;
307 }
308 CFX_ByteString cbMidRange;
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 }
344 return true;
345 }
346
347 DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc, 343 DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc,
348 FPDF_DOCUMENT src_doc, 344 FPDF_DOCUMENT src_doc,
349 FPDF_BYTESTRING pagerange, 345 FPDF_BYTESTRING pagerange,
350 int index) { 346 int index) {
351 CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc); 347 CPDF_Document* pDestDoc = CPDFDocumentFromFPDFDocument(dest_doc);
352 if (!dest_doc) 348 if (!dest_doc)
353 return false; 349 return false;
354 350
355 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); 351 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc);
356 if (!pSrcDoc) 352 if (!pSrcDoc)
357 return false; 353 return false;
358 354
359 std::vector<uint16_t> pageArray; 355 std::vector<uint16_t> pageArray;
360 int nCount = pSrcDoc->GetPageCount(); 356 int nCount = pSrcDoc->GetPageCount();
361 if (pagerange) { 357 if (pagerange) {
362 if (!ParserPageRangeString(pagerange, &pageArray, nCount)) 358 if (!ParserPageRangeString(pagerange, &pageArray, nCount))
363 return false; 359 return false;
364 } else { 360 } else {
365 for (int i = 1; i <= nCount; ++i) { 361 for (int i = 1; i <= nCount; ++i) {
366 pageArray.push_back(i); 362 pageArray.push_back(i);
367 } 363 }
368 } 364 }
369 365
370 CPDF_PageOrganizer pageOrg; 366 CPDF_PageOrganizer pageOrg(pDestDoc, pSrcDoc);
371 pageOrg.PDFDocInit(pDestDoc, pSrcDoc); 367 if (!pageOrg.PDFDocInit())
372 return pageOrg.ExportPage(pSrcDoc, &pageArray, pDestDoc, index); 368 return false;
Tom Sepez 2016/11/14 21:27:36 nit: or just return pageOrg.PDFDocInit() && pageOr
Lei Zhang 2016/11/14 21:37:14 Done.
369 return pageOrg.ExportPage(pageArray, index);
373 } 370 }
374 371
375 DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc, 372 DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc,
376 FPDF_DOCUMENT src_doc) { 373 FPDF_DOCUMENT src_doc) {
377 CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc); 374 CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc);
378 if (!pDstDoc) 375 if (!pDstDoc)
379 return false; 376 return false;
380 377
381 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); 378 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc);
382 if (!pSrcDoc) 379 if (!pSrcDoc)
383 return false; 380 return false;
384 381
385 CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot(); 382 CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot();
386 pSrcDict = pSrcDict->GetDictFor("ViewerPreferences"); 383 pSrcDict = pSrcDict->GetDictFor("ViewerPreferences");
387 if (!pSrcDict) 384 if (!pSrcDict)
388 return false; 385 return false;
389 386
390 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); 387 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot();
391 if (!pDstDict) 388 if (!pDstDict)
392 return false; 389 return false;
393 390
394 pDstDict->SetFor("ViewerPreferences", 391 pDstDict->SetFor("ViewerPreferences",
395 pSrcDict->CloneDirectObject().release()); 392 pSrcDict->CloneDirectObject().release());
396 return true; 393 return true;
397 } 394 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698