1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "../../../include/fpdfapi/fpdf_parser.h" 8 #include "../../../include/fpdfapi/fpdf_module.h" 9 extern FX_LPVOID PDFPreviewInitCache(CPDF_Document* pDoc); 10 extern void PDFPreviewClearCache(FX_LPVOID pCache); 11 CPDF_Document::CPDF_Document(IPDF_DocParser* pParser) : CPDF_IndirectObjects(pParser) 12 { 13 ASSERT(pParser != NULL); 14 m_pRootDict = NULL; 15 m_pInfoDict = NULL; 16 m_bLinearized = FALSE; 17 m_dwFirstPageNo = 0; 18 m_dwFirstPageObjNum = 0; 19 m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); 20 m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); 21 } 22 CPDF_DocPageData* CPDF_Document::GetValidatePageData() 23 { 24 if (m_pDocPage) { 25 return m_pDocPage; 26 } 27 m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); 28 return m_pDocPage; 29 } 30 CPDF_DocRenderData* CPDF_Document::GetValidateRenderData() 31 { 32 if (m_pDocRender) { 33 return m_pDocRender; 34 } 35 m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); 36 return m_pDocRender; 37 } 38 void CPDF_Document::LoadDoc() 39 { 40 m_LastObjNum = m_pParser->GetLastObjNum(); 41 CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum()); 42 if (pRootObj == NULL) { 43 return; 44 } 45 m_pRootDict = pRootObj->GetDict(); 46 if (m_pRootDict == NULL) { 47 return; 48 } 49 CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum()); 50 if (pInfoObj) { 51 m_pInfoDict = pInfoObj->GetDict(); 52 } 53 CPDF_Array* pIDArray = m_pParser->GetIDArray(); 54 if (pIDArray) { 55 m_ID1 = pIDArray->GetString(0); 56 m_ID2 = pIDArray->GetString(1); 57 } 58 m_PageList.SetSize(_GetPageCount()); 59 } 60 void CPDF_Document::LoadAsynDoc(CPDF_Dictionary *pLinearized) 61 { 62 m_bLinearized = TRUE; 63 m_LastObjNum = m_pParser->GetLastObjNum(); 64 m_pRootDict = GetIndirectObject(m_pParser->GetRootObjNum())->GetDict(); 65 if (m_pRootDict == NULL) { 66 return; 67 } 68 m_pInfoDict = GetIndirectObject(m_pParser->GetInfoObjNum())->GetDict(); 69 CPDF_Array* pIDArray = m_pParser->GetIDArray(); 70 if (pIDArray) { 71 m_ID1 = pIDArray->GetString(0); 72 m_ID2 = pIDArray->GetString(1); 73 } 74 FX_DWORD dwPageCount = 0; 75 CPDF_Object *pCount = pLinearized->GetElement(FX_BSTRC("N")); 76 if (pCount && pCount->GetType() == PDFOBJ_NUMBER) { 77 dwPageCount = pCount->GetInteger(); 78 } 79 m_PageList.SetSize(dwPageCount); 80 CPDF_Object *pNo = pLinearized->GetElement(FX_BSTRC("P")); 81 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { 82 m_dwFirstPageNo = pNo->GetInteger(); 83 } 84 CPDF_Object *pObjNum = pLinearized->GetElement(FX_BSTRC("O")); 85 if (pObjNum && pObjNum->GetType() == PDFOBJ_NUMBER) { 86 m_dwFirstPageObjNum = pObjNum->GetInteger(); 87 } 88 } 89 void CPDF_Document::LoadPages() 90 { 91 m_PageList.SetSize(_GetPageCount()); 92 } 93 extern void FPDF_TTFaceMapper_ReleaseDoc(CPDF_Document*); 94 CPDF_Document::~CPDF_Document() 95 { 96 if (m_pDocRender) { 97 CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender); 98 } 99 if (m_pDocPage) { 100 CPDF_ModuleMgr::Get()->GetPageModule()->ReleaseDoc(this); 101 CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this); 102 } 103 } 104 #define FX_MAX_PAGE_LEVEL 1024 105 CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, int iPage, int nPagesToGo, int level) 106 { 107 CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); 108 if (pKidList == NULL) { 109 if (nPagesToGo == 0) { 110 return pPages; 111 } 112 return NULL; 113 } 114 if (level >= FX_MAX_PAGE_LEVEL) { 115 return NULL; 116 } 117 int nKids = pKidList->GetCount(); 118 for (int i = 0; i < nKids; i ++) { 119 CPDF_Dictionary* pKid = pKidList->GetDict(i); 120 if (pKid == NULL) { 121 nPagesToGo --; 122 continue; 123 } 124 if (pKid == pPages) { 125 continue; 126 } 127 if (!pKid->KeyExist(FX_BSTRC("Kids"))) { 128 if (nPagesToGo == 0) { 129 return pKid; 130 } 131 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); 132 nPagesToGo --; 133 } else { 134 int nPages = pKid->GetInteger(FX_BSTRC("Count")); 135 if (nPagesToGo < nPages) { 136 return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1); 137 } 138 nPagesToGo -= nPages; 139 } 140 } 141 return NULL; 142 } 143 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) 144 { 145 if (iPage < 0 || iPage >= m_PageList.GetSize()) { 146 return NULL; 147 } 148 if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) { 149 CPDF_Object* pObj = GetIndirectObject(m_dwFirstPageObjNum); 150 if (pObj && pObj->GetType() == PDFOBJ_DICTIONARY) { 151 return (CPDF_Dictionary*)pObj; 152 } 153 } 154 int objnum = m_PageList.GetAt(iPage); 155 if (objnum) { 156 CPDF_Object* pObj = GetIndirectObject(objnum); 157 ASSERT(pObj->GetType() == PDFOBJ_DICTIONARY); 158 return (CPDF_Dictionary*)pObj; 159 } 160 CPDF_Dictionary* pRoot = GetRoot(); 161 if (pRoot == NULL) { 162 return NULL; 163 } 164 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); 165 if (pPages == NULL) { 166 return NULL; 167 } 168 CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0); 169 if (pPage == NULL) { 170 return NULL; 171 } 172 m_PageList.SetAt(iPage, pPage->GetObjNum()); 173 return pPage; 174 } 175 int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, FX_DWORD& skip_count, FX_DWORD objnum, int& index, int level) 176 { 177 if (pNode->KeyExist(FX_BSTRC("Kids"))) { 178 CPDF_Array* pKidList = pNode->GetArray(FX_BSTRC("Kids")); 179 if (pKidList == NULL) { 180 return -1; 181 } 182 if (level >= FX_MAX_PAGE_LEVEL) { 183 return -1; 184 } 185 FX_DWORD count = pNode->GetInteger(FX_BSTRC("Count")); 186 if (count <= skip_count) { 187 skip_count -= count; 188 index += count; 189 return -1; 190 } 191 if (count && count == pKidList->GetCount()) { 192 for (FX_DWORD i = 0; i < count; i ++) { 193 CPDF_Reference* pKid = (CPDF_Reference*)pKidList->GetElement(i); 194 if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { 195 if (pKid->GetRefObjNum() == objnum) { 196 m_PageList.SetAt(index + i, objnum); 197 return index + i; 198 } 199 } 200 } 201 } 202 for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) { 203 CPDF_Dictionary* pKid = pKidList->GetDict(i); 204 if (pKid == NULL) { 205 continue; 206 } 207 if (pKid == pNode) { 208 continue; 209 } 210 int found_index = _FindPageIndex(pKid, skip_count, objnum, index, level + 1); 211 if (found_index >= 0) { 212 return found_index; 213 } 214 } 215 } else { 216 if (objnum == pNode->GetObjNum()) { 217 return index; 218 } 219 if (skip_count) { 220 skip_count--; 221 } 222 index ++; 223 } 224 return -1; 225 } 226 int CPDF_Document::GetPageIndex(FX_DWORD objnum) 227 { 228 FX_DWORD nPages = m_PageList.GetSize(); 229 FX_DWORD skip_count = 0; 230 FX_BOOL bSkipped = FALSE; 231 for (FX_DWORD i = 0; i < nPages; i ++) { 232 FX_DWORD objnum1 = m_PageList.GetAt(i); 233 if (objnum1 == objnum) { 234 return i; 235 } 236 if (!bSkipped && objnum1 == 0) { 237 skip_count = i; 238 bSkipped = TRUE; 239 } 240 } 241 CPDF_Dictionary* pRoot = GetRoot(); 242 if (pRoot == NULL) { 243 return -1; 244 } 245 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); 246 if (pPages == NULL) { 247 return -1; 248 } 249 int index = 0; 250 return _FindPageIndex(pPages, skip_count, objnum, index); 251 } 252 int CPDF_Document::GetPageCount() const 253 { 254 return m_PageList.GetSize(); 255 } 256 static int _CountPages(CPDF_Dictionary* pPages, int level) 257 { 258 if (level > 128) { 259 return 0; 260 } 261 int count = pPages->GetInteger(FX_BSTRC("Count")); 262 if (count > 0 && count < FPDF_PAGE_MAX_NUM) { 263 return count; 264 } 265 CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); 266 if (pKidList == NULL) { 267 return 0; 268 } 269 count = 0; 270 for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) { 271 CPDF_Dictionary* pKid = pKidList->GetDict(i); 272 if (pKid == NULL) { 273 continue; 274 } 275 if (!pKid->KeyExist(FX_BSTRC("Kids"))) { 276 count ++; 277 } else { 278 count += _CountPages(pKid, level + 1); 279 } 280 } 281 pPages->SetAtInteger(FX_BSTRC("Count"), count); 282 return count; 283 } 284 int CPDF_Document::_GetPageCount() const 285 { 286 CPDF_Dictionary* pRoot = GetRoot(); 287 if (pRoot == NULL) { 288 return 0; 289 } 290 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); 291 if (pPages == NULL) { 292 return 0; 293 } 294 if (!pPages->KeyExist(FX_BSTRC("Kids"))) { 295 return 1; 296 } 297 return _CountPages(pPages, 0); 298 } 299 static FX_BOOL _EnumPages(CPDF_Dictionary* pPages, IPDF_EnumPageHandler* pHandler) 300 { 301 CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); 302 if (pKidList == NULL) { 303 return pHandler->EnumPage(pPages); 304 } 305 for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) { 306 CPDF_Dictionary* pKid = pKidList->GetDict(i); 307 if (pKid == NULL) { 308 continue; 309 } 310 if (!pKid->KeyExist(FX_BSTRC("Kids"))) { 311 if (!pHandler->EnumPage(pKid)) { 312 return FALSE; 313 } 314 } else { 315 return _EnumPages(pKid, pHandler); 316 } 317 } 318 return TRUE; 319 } 320 void CPDF_Document::EnumPages(IPDF_EnumPageHandler* pHandler) 321 { 322 CPDF_Dictionary* pRoot = GetRoot(); 323 if (pRoot == NULL) { 324 return; 325 } 326 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); 327 if (pPages == NULL) { 328 return; 329 } 330 _EnumPages(pPages, pHandler); 331 } 332 FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum, CPDF_Dictionary* pThisPageDict) 333 { 334 for (int i = 0; i < m_PageList.GetSize(); i ++) { 335 CPDF_Dictionary* pPageDict = GetPage(i); 336 if (pPageDict == pThisPageDict) { 337 continue; 338 } 339 CPDF_Object* pContents = pPageDict->GetElement(FX_BSTRC("Contents")); 340 if (pContents == NULL) { 341 continue; 342 } 343 if (pContents->GetDirectType() == PDFOBJ_ARRAY) { 344 CPDF_Array* pArray = (CPDF_Array*)pContents->GetDirect(); 345 for (FX_DWORD j = 0; j < pArray->GetCount(); j ++) { 346 CPDF_Reference* pRef = (CPDF_Reference*)pArray->GetElement(j); 347 if (pRef->GetRefObjNum() == objnum) { 348 return TRUE; 349 } 350 } 351 } else if (pContents->GetObjNum() == objnum) { 352 return TRUE; 353 } 354 } 355 return FALSE; 356 } 357 FX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const 358 { 359 if (m_pParser == NULL) { 360 return (FX_DWORD) - 1; 361 } 362 return m_pParser->GetPermissions(bCheckRevision); 363 } 364 FX_BOOL CPDF_Document::IsOwner() const 365 { 366 if (m_pParser == NULL) { 367 return TRUE; 368 } 369 return m_pParser->IsOwner(); 370 } 371 FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const 372 { 373 { 374 CPDF_Object* pObj; 375 if (m_IndirectObjs.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, (FX_LPVOID&)pObj)) { 376 bForm = pObj->GetType() == PDFOBJ_STREAM && 377 ((CPDF_Stream*)pObj)->GetDict()->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Form"); 378 return TRUE; 379 } 380 } 381 if (m_pParser == NULL) { 382 bForm = FALSE; 383 return TRUE; 384 } 385 return m_pParser->IsFormStream(objnum, bForm); 386 } 387 void CPDF_Document::ClearPageData() 388 { 389 if (m_pDocPage) { 390 CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this); 391 } 392 } 393 void CPDF_Document::ClearRenderData() 394 { 395 if (m_pDocRender) { 396 CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender); 397 } 398 } 399