| 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> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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* DInfoDict = pDestPDFDoc->GetInfo(); |
| 58 if (!DInfoDict) | 58 if (!DInfoDict) |
| 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->SetAt("Producer", new CPDF_String(producerstr, FALSE)); | 63 DInfoDict->SetFor("Producer", new CPDF_String(producerstr, FALSE)); |
| 64 | 64 |
| 65 CFX_ByteString cbRootType = pNewRoot->GetStringBy("Type", ""); | 65 CFX_ByteString cbRootType = pNewRoot->GetStringFor("Type", ""); |
| 66 if (cbRootType.IsEmpty()) | 66 if (cbRootType.IsEmpty()) |
| 67 pNewRoot->SetAt("Type", new CPDF_Name("Catalog")); | 67 pNewRoot->SetFor("Type", new CPDF_Name("Catalog")); |
| 68 | 68 |
| 69 CPDF_Object* pElement = pNewRoot->GetObjectBy("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; | 73 pNewPages = new CPDF_Dictionary; |
| 74 uint32_t NewPagesON = pDestPDFDoc->AddIndirectObject(pNewPages); | 74 uint32_t NewPagesON = pDestPDFDoc->AddIndirectObject(pNewPages); |
| 75 pNewRoot->SetAt("Pages", new CPDF_Reference(pDestPDFDoc, NewPagesON)); | 75 pNewRoot->SetFor("Pages", new CPDF_Reference(pDestPDFDoc, NewPagesON)); |
| 76 } | 76 } |
| 77 | 77 |
| 78 CFX_ByteString cbPageType = pNewPages->GetStringBy("Type", ""); | 78 CFX_ByteString cbPageType = pNewPages->GetStringFor("Type", ""); |
| 79 if (cbPageType == "") { | 79 if (cbPageType == "") { |
| 80 pNewPages->SetAt("Type", new CPDF_Name("Pages")); | 80 pNewPages->SetFor("Type", new CPDF_Name("Pages")); |
| 81 } | 81 } |
| 82 | 82 |
| 83 CPDF_Array* pKeysArray = pNewPages->GetArrayBy("Kids"); | 83 CPDF_Array* pKeysArray = pNewPages->GetArrayFor("Kids"); |
| 84 if (!pKeysArray) { | 84 if (!pKeysArray) { |
| 85 CPDF_Array* pNewKids = new CPDF_Array; | 85 CPDF_Array* pNewKids = new CPDF_Array; |
| 86 uint32_t Kidsobjnum = pDestPDFDoc->AddIndirectObject(pNewKids); | 86 uint32_t Kidsobjnum = pDestPDFDoc->AddIndirectObject(pNewKids); |
| 87 | 87 |
| 88 pNewPages->SetAt("Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum)); | 88 pNewPages->SetFor("Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum)); |
| 89 pNewPages->SetAt("Count", new CPDF_Number(0)); | 89 pNewPages->SetFor("Count", new CPDF_Number(0)); |
| 90 } | 90 } |
| 91 | 91 |
| 92 return TRUE; | 92 return TRUE; |
| 93 } | 93 } |
| 94 | 94 |
| 95 FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, | 95 FX_BOOL CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc, |
| 96 std::vector<uint16_t>* pPageNums, | 96 std::vector<uint16_t>* pPageNums, |
| 97 CPDF_Document* pDestPDFDoc, | 97 CPDF_Document* pDestPDFDoc, |
| 98 int nIndex) { | 98 int nIndex) { |
| 99 int curpage = nIndex; | 99 int curpage = nIndex; |
| 100 std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); | 100 std::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap); |
| 101 int nSize = pdfium::CollectionSize<int>(*pPageNums); | 101 int nSize = pdfium::CollectionSize<int>(*pPageNums); |
| 102 for (int i = 0; i < nSize; ++i) { | 102 for (int i = 0; i < nSize; ++i) { |
| 103 CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); | 103 CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage); |
| 104 CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(pPageNums->at(i) - 1); | 104 CPDF_Dictionary* pSrcPageDict = pSrcPDFDoc->GetPage(pPageNums->at(i) - 1); |
| 105 if (!pSrcPageDict || !pCurPageDict) | 105 if (!pSrcPageDict || !pCurPageDict) |
| 106 return FALSE; | 106 return FALSE; |
| 107 | 107 |
| 108 // Clone the page dictionary | 108 // Clone the page dictionary |
| 109 for (const auto& it : *pSrcPageDict) { | 109 for (const auto& it : *pSrcPageDict) { |
| 110 const CFX_ByteString& cbSrcKeyStr = it.first; | 110 const CFX_ByteString& cbSrcKeyStr = it.first; |
| 111 CPDF_Object* pObj = it.second; | 111 CPDF_Object* pObj = it.second; |
| 112 if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { | 112 if (cbSrcKeyStr.Compare(("Type")) && cbSrcKeyStr.Compare(("Parent"))) { |
| 113 if (pCurPageDict->KeyExist(cbSrcKeyStr)) | 113 if (pCurPageDict->KeyExist(cbSrcKeyStr)) |
| 114 pCurPageDict->RemoveAt(cbSrcKeyStr); | 114 pCurPageDict->RemoveFor(cbSrcKeyStr); |
| 115 pCurPageDict->SetAt(cbSrcKeyStr, pObj->Clone()); | 115 pCurPageDict->SetFor(cbSrcKeyStr, pObj->Clone()); |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 // inheritable item | 119 // inheritable item |
| 120 CPDF_Object* pInheritable = nullptr; | 120 CPDF_Object* pInheritable = nullptr; |
| 121 // 1 MediaBox //required | 121 // 1 MediaBox //required |
| 122 if (!pCurPageDict->KeyExist("MediaBox")) { | 122 if (!pCurPageDict->KeyExist("MediaBox")) { |
| 123 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); | 123 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox"); |
| 124 if (!pInheritable) { | 124 if (!pInheritable) { |
| 125 // Search the "CropBox" from source page dictionary, | 125 // Search the "CropBox" from source page dictionary, |
| 126 // if not exists,we take the letter size. | 126 // if not exists,we take the letter size. |
| 127 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); | 127 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); |
| 128 if (pInheritable) { | 128 if (pInheritable) { |
| 129 pCurPageDict->SetAt("MediaBox", pInheritable->Clone()); | 129 pCurPageDict->SetFor("MediaBox", pInheritable->Clone()); |
| 130 } else { | 130 } else { |
| 131 // Make the default size to be letter size (8.5'x11') | 131 // Make the default size to be letter size (8.5'x11') |
| 132 CPDF_Array* pArray = new CPDF_Array; | 132 CPDF_Array* pArray = new CPDF_Array; |
| 133 pArray->AddNumber(0); | 133 pArray->AddNumber(0); |
| 134 pArray->AddNumber(0); | 134 pArray->AddNumber(0); |
| 135 pArray->AddNumber(612); | 135 pArray->AddNumber(612); |
| 136 pArray->AddNumber(792); | 136 pArray->AddNumber(792); |
| 137 pCurPageDict->SetAt("MediaBox", pArray); | 137 pCurPageDict->SetFor("MediaBox", pArray); |
| 138 } | 138 } |
| 139 } else { | 139 } else { |
| 140 pCurPageDict->SetAt("MediaBox", pInheritable->Clone()); | 140 pCurPageDict->SetFor("MediaBox", pInheritable->Clone()); |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 // 2 Resources //required | 143 // 2 Resources //required |
| 144 if (!pCurPageDict->KeyExist("Resources")) { | 144 if (!pCurPageDict->KeyExist("Resources")) { |
| 145 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources"); | 145 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources"); |
| 146 if (!pInheritable) | 146 if (!pInheritable) |
| 147 return FALSE; | 147 return FALSE; |
| 148 pCurPageDict->SetAt("Resources", pInheritable->Clone()); | 148 pCurPageDict->SetFor("Resources", pInheritable->Clone()); |
| 149 } | 149 } |
| 150 // 3 CropBox //Optional | 150 // 3 CropBox //Optional |
| 151 if (!pCurPageDict->KeyExist("CropBox")) { | 151 if (!pCurPageDict->KeyExist("CropBox")) { |
| 152 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); | 152 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox"); |
| 153 if (pInheritable) | 153 if (pInheritable) |
| 154 pCurPageDict->SetAt("CropBox", pInheritable->Clone()); | 154 pCurPageDict->SetFor("CropBox", pInheritable->Clone()); |
| 155 } | 155 } |
| 156 // 4 Rotate //Optional | 156 // 4 Rotate //Optional |
| 157 if (!pCurPageDict->KeyExist("Rotate")) { | 157 if (!pCurPageDict->KeyExist("Rotate")) { |
| 158 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); | 158 pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate"); |
| 159 if (pInheritable) | 159 if (pInheritable) |
| 160 pCurPageDict->SetAt("Rotate", pInheritable->Clone()); | 160 pCurPageDict->SetFor("Rotate", pInheritable->Clone()); |
| 161 } | 161 } |
| 162 | 162 |
| 163 // Update the reference | 163 // Update the reference |
| 164 uint32_t dwOldPageObj = pSrcPageDict->GetObjNum(); | 164 uint32_t dwOldPageObj = pSrcPageDict->GetObjNum(); |
| 165 uint32_t dwNewPageObj = pCurPageDict->GetObjNum(); | 165 uint32_t dwNewPageObj = pCurPageDict->GetObjNum(); |
| 166 | 166 |
| 167 (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; | 167 (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj; |
| 168 | 168 |
| 169 UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); | 169 UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get()); |
| 170 ++curpage; | 170 ++curpage; |
| 171 } | 171 } |
| 172 | 172 |
| 173 return TRUE; | 173 return TRUE; |
| 174 } | 174 } |
| 175 | 175 |
| 176 CPDF_Object* CPDF_PageOrganizer::PageDictGetInheritableTag( | 176 CPDF_Object* CPDF_PageOrganizer::PageDictGetInheritableTag( |
| 177 CPDF_Dictionary* pDict, | 177 CPDF_Dictionary* pDict, |
| 178 const CFX_ByteString& bsSrcTag) { | 178 const CFX_ByteString& bsSrcTag) { |
| 179 if (!pDict || bsSrcTag.IsEmpty()) | 179 if (!pDict || bsSrcTag.IsEmpty()) |
| 180 return nullptr; | 180 return nullptr; |
| 181 if (!pDict->KeyExist("Parent") || !pDict->KeyExist("Type")) | 181 if (!pDict->KeyExist("Parent") || !pDict->KeyExist("Type")) |
| 182 return nullptr; | 182 return nullptr; |
| 183 | 183 |
| 184 CPDF_Object* pType = pDict->GetObjectBy("Type")->GetDirect(); | 184 CPDF_Object* pType = pDict->GetObjectFor("Type")->GetDirect(); |
| 185 if (!ToName(pType)) | 185 if (!ToName(pType)) |
| 186 return nullptr; | 186 return nullptr; |
| 187 if (pType->GetString().Compare("Page")) | 187 if (pType->GetString().Compare("Page")) |
| 188 return nullptr; | 188 return nullptr; |
| 189 | 189 |
| 190 CPDF_Dictionary* pp = ToDictionary(pDict->GetObjectBy("Parent")->GetDirect()); | 190 CPDF_Dictionary* pp = |
| 191 ToDictionary(pDict->GetObjectFor("Parent")->GetDirect()); |
| 191 if (!pp) | 192 if (!pp) |
| 192 return nullptr; | 193 return nullptr; |
| 193 | 194 |
| 194 if (pDict->KeyExist(bsSrcTag)) | 195 if (pDict->KeyExist(bsSrcTag)) |
| 195 return pDict->GetObjectBy(bsSrcTag); | 196 return pDict->GetObjectFor(bsSrcTag); |
| 196 | 197 |
| 197 while (pp) { | 198 while (pp) { |
| 198 if (pp->KeyExist(bsSrcTag)) | 199 if (pp->KeyExist(bsSrcTag)) |
| 199 return pp->GetObjectBy(bsSrcTag); | 200 return pp->GetObjectFor(bsSrcTag); |
| 200 if (!pp->KeyExist("Parent")) | 201 if (!pp->KeyExist("Parent")) |
| 201 break; | 202 break; |
| 202 pp = ToDictionary(pp->GetObjectBy("Parent")->GetDirect()); | 203 pp = ToDictionary(pp->GetObjectFor("Parent")->GetDirect()); |
| 203 } | 204 } |
| 204 return nullptr; | 205 return nullptr; |
| 205 } | 206 } |
| 206 | 207 |
| 207 FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, | 208 FX_BOOL CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj, |
| 208 CPDF_Document* pDoc, | 209 CPDF_Document* pDoc, |
| 209 ObjectNumberMap* pObjNumberMap) { | 210 ObjectNumberMap* pObjNumberMap) { |
| 210 switch (pObj->GetType()) { | 211 switch (pObj->GetType()) { |
| 211 case CPDF_Object::REFERENCE: { | 212 case CPDF_Object::REFERENCE: { |
| 212 CPDF_Reference* pReference = pObj->AsReference(); | 213 CPDF_Reference* pReference = pObj->AsReference(); |
| 213 uint32_t newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference); | 214 uint32_t newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference); |
| 214 if (newobjnum == 0) | 215 if (newobjnum == 0) |
| 215 return FALSE; | 216 return FALSE; |
| 216 pReference->SetRef(pDoc, newobjnum); | 217 pReference->SetRef(pDoc, newobjnum); |
| 217 break; | 218 break; |
| 218 } | 219 } |
| 219 case CPDF_Object::DICTIONARY: { | 220 case CPDF_Object::DICTIONARY: { |
| 220 CPDF_Dictionary* pDict = pObj->AsDictionary(); | 221 CPDF_Dictionary* pDict = pObj->AsDictionary(); |
| 221 auto it = pDict->begin(); | 222 auto it = pDict->begin(); |
| 222 while (it != pDict->end()) { | 223 while (it != pDict->end()) { |
| 223 const CFX_ByteString& key = it->first; | 224 const CFX_ByteString& key = it->first; |
| 224 CPDF_Object* pNextObj = it->second; | 225 CPDF_Object* pNextObj = it->second; |
| 225 ++it; | 226 ++it; |
| 226 if (key == "Parent" || key == "Prev" || key == "First") | 227 if (key == "Parent" || key == "Prev" || key == "First") |
| 227 continue; | 228 continue; |
| 228 if (!pNextObj) | 229 if (!pNextObj) |
| 229 return FALSE; | 230 return FALSE; |
| 230 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) | 231 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) |
| 231 pDict->RemoveAt(key); | 232 pDict->RemoveFor(key); |
| 232 } | 233 } |
| 233 break; | 234 break; |
| 234 } | 235 } |
| 235 case CPDF_Object::ARRAY: { | 236 case CPDF_Object::ARRAY: { |
| 236 CPDF_Array* pArray = pObj->AsArray(); | 237 CPDF_Array* pArray = pObj->AsArray(); |
| 237 for (size_t i = 0; i < pArray->GetCount(); ++i) { | 238 for (size_t i = 0; i < pArray->GetCount(); ++i) { |
| 238 CPDF_Object* pNextObj = pArray->GetObjectAt(i); | 239 CPDF_Object* pNextObj = pArray->GetObjectAt(i); |
| 239 if (!pNextObj) | 240 if (!pNextObj) |
| 240 return FALSE; | 241 return FALSE; |
| 241 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) | 242 if (!UpdateReference(pNextObj, pDoc, pObjNumberMap)) |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 CPDF_Object* pDirect = pRef->GetDirect(); | 279 CPDF_Object* pDirect = pRef->GetDirect(); |
| 279 if (!pDirect) | 280 if (!pDirect) |
| 280 return 0; | 281 return 0; |
| 281 | 282 |
| 282 CPDF_Object* pClone = pDirect->Clone(); | 283 CPDF_Object* pClone = pDirect->Clone(); |
| 283 if (!pClone) | 284 if (!pClone) |
| 284 return 0; | 285 return 0; |
| 285 | 286 |
| 286 if (CPDF_Dictionary* pDictClone = pClone->AsDictionary()) { | 287 if (CPDF_Dictionary* pDictClone = pClone->AsDictionary()) { |
| 287 if (pDictClone->KeyExist("Type")) { | 288 if (pDictClone->KeyExist("Type")) { |
| 288 CFX_ByteString strType = pDictClone->GetStringBy("Type"); | 289 CFX_ByteString strType = pDictClone->GetStringFor("Type"); |
| 289 if (!FXSYS_stricmp(strType.c_str(), "Pages")) { | 290 if (!FXSYS_stricmp(strType.c_str(), "Pages")) { |
| 290 pDictClone->Release(); | 291 pDictClone->Release(); |
| 291 return 4; | 292 return 4; |
| 292 } | 293 } |
| 293 if (!FXSYS_stricmp(strType.c_str(), "Page")) { | 294 if (!FXSYS_stricmp(strType.c_str(), "Page")) { |
| 294 pDictClone->Release(); | 295 pDictClone->Release(); |
| 295 return 0; | 296 return 0; |
| 296 } | 297 } |
| 297 } | 298 } |
| 298 } | 299 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 FPDF_DOCUMENT src_doc) { | 388 FPDF_DOCUMENT src_doc) { |
| 388 CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc); | 389 CPDF_Document* pDstDoc = CPDFDocumentFromFPDFDocument(dest_doc); |
| 389 if (!pDstDoc) | 390 if (!pDstDoc) |
| 390 return FALSE; | 391 return FALSE; |
| 391 | 392 |
| 392 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); | 393 CPDF_Document* pSrcDoc = CPDFDocumentFromFPDFDocument(src_doc); |
| 393 if (!pSrcDoc) | 394 if (!pSrcDoc) |
| 394 return FALSE; | 395 return FALSE; |
| 395 | 396 |
| 396 CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot(); | 397 CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot(); |
| 397 pSrcDict = pSrcDict->GetDictBy("ViewerPreferences"); | 398 pSrcDict = pSrcDict->GetDictFor("ViewerPreferences"); |
| 398 if (!pSrcDict) | 399 if (!pSrcDict) |
| 399 return FALSE; | 400 return FALSE; |
| 400 | 401 |
| 401 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); | 402 CPDF_Dictionary* pDstDict = pDstDoc->GetRoot(); |
| 402 if (!pDstDict) | 403 if (!pDstDict) |
| 403 return FALSE; | 404 return FALSE; |
| 404 | 405 |
| 405 pDstDict->SetAt("ViewerPreferences", pSrcDict->CloneDirectObject()); | 406 pDstDict->SetFor("ViewerPreferences", pSrcDict->CloneDirectObject()); |
| 406 return TRUE; | 407 return TRUE; |
| 407 } | 408 } |
| OLD | NEW |