| 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 |