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 "core/fpdfapi/parser/cpdf_document.h" | 7 #include "core/fpdfapi/parser/cpdf_document.h" |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <set> | 10 #include <set> |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
407 } | 407 } |
408 | 408 |
409 } // namespace | 409 } // namespace |
410 | 410 |
411 CPDF_Document::CPDF_Document(std::unique_ptr<CPDF_Parser> pParser) | 411 CPDF_Document::CPDF_Document(std::unique_ptr<CPDF_Parser> pParser) |
412 : CPDF_IndirectObjectHolder(), | 412 : CPDF_IndirectObjectHolder(), |
413 m_pParser(std::move(pParser)), | 413 m_pParser(std::move(pParser)), |
414 m_pRootDict(nullptr), | 414 m_pRootDict(nullptr), |
415 m_pInfoDict(nullptr), | 415 m_pInfoDict(nullptr), |
416 m_bLinearized(false), | 416 m_bLinearized(false), |
417 m_bPagesTraversed(false), | |
417 m_iFirstPageNo(0), | 418 m_iFirstPageNo(0), |
418 m_dwFirstPageObjNum(0), | 419 m_dwFirstPageObjNum(0), |
419 m_pDocPage(new CPDF_DocPageData(this)), | 420 m_pDocPage(new CPDF_DocPageData(this)), |
420 m_pDocRender(new CPDF_DocRenderData(this)), | 421 m_pDocRender(new CPDF_DocRenderData(this)), |
421 m_pByteStringPool(pdfium::MakeUnique<CFX_ByteStringPool>()) { | 422 m_pByteStringPool(pdfium::MakeUnique<CFX_ByteStringPool>()) { |
422 if (pParser) | 423 if (pParser) |
423 SetLastObjNum(m_pParser->GetLastObjNum()); | 424 SetLastObjNum(m_pParser->GetLastObjNum()); |
424 } | 425 } |
425 | 426 |
426 CPDF_Document::~CPDF_Document() { | 427 CPDF_Document::~CPDF_Document() { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 | 471 |
471 CPDF_Object* pObjNum = pLinearizationParams->GetObjectFor("O"); | 472 CPDF_Object* pObjNum = pLinearizationParams->GetObjectFor("O"); |
472 if (ToNumber(pObjNum)) | 473 if (ToNumber(pObjNum)) |
473 m_dwFirstPageObjNum = pObjNum->GetInteger(); | 474 m_dwFirstPageObjNum = pObjNum->GetInteger(); |
474 } | 475 } |
475 | 476 |
476 void CPDF_Document::LoadPages() { | 477 void CPDF_Document::LoadPages() { |
477 m_PageList.SetSize(RetrievePageCount()); | 478 m_PageList.SetSize(RetrievePageCount()); |
478 } | 479 } |
479 | 480 |
480 CPDF_Dictionary* CPDF_Document::FindPDFPage(CPDF_Dictionary* pPages, | 481 void CPDF_Document::TraversePDFPages(CPDF_Dictionary* pPages, |
481 int iPage, | 482 int iPage, |
482 int nPagesToGo, | 483 int level) { |
483 int level) { | 484 if (iPage >= m_PageList.GetSize()) |
485 return; | |
484 CPDF_Array* pKidList = pPages->GetArrayFor("Kids"); | 486 CPDF_Array* pKidList = pPages->GetArrayFor("Kids"); |
485 if (!pKidList) | 487 if (!pKidList) { |
486 return nPagesToGo == 0 ? pPages : nullptr; | 488 m_PageList.SetAt(iPage, pPages->GetObjNum()); |
489 return; | |
490 } | |
487 | 491 |
488 if (level >= FX_MAX_PAGE_LEVEL) | 492 if (level >= FX_MAX_PAGE_LEVEL) |
489 return nullptr; | 493 return; |
490 | 494 |
491 for (size_t i = 0; i < pKidList->GetCount(); i++) { | 495 for (size_t i = 0; i < pKidList->GetCount(); i++) { |
492 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); | 496 CPDF_Dictionary* pKid = pKidList->GetDictAt(i); |
493 if (!pKid) { | 497 if (!pKid) { |
494 nPagesToGo--; | 498 iPage++; |
495 continue; | 499 continue; |
496 } | 500 } |
497 if (pKid == pPages) | 501 if (pKid == pPages) |
498 continue; | 502 continue; |
499 if (!pKid->KeyExist("Kids")) { | 503 if (!pKid->KeyExist("Kids")) { |
500 if (nPagesToGo == 0) | 504 m_PageList.SetAt(iPage, pKid->GetObjNum()); |
501 return pKid; | 505 iPage++; |
502 | |
503 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); | |
504 nPagesToGo--; | |
505 } else { | 506 } else { |
506 int nPages = pKid->GetIntegerFor("Count"); | 507 int nPages = pKid->GetIntegerFor("Count"); |
Tom Sepez
2016/10/14 19:01:16
I think we have to deal with the situation where C
npm
2016/10/14 19:31:25
Well, it is not clear to me how we should behave i
dsinclair
2016/10/17 13:26:37
Should we increase iPage by the min(count, sizeof
npm
2016/10/17 21:10:23
We were not doing this before. I think this might
| |
507 if (nPagesToGo < nPages) | 508 TraversePDFPages(pKid, iPage, level + 1); |
508 return FindPDFPage(pKid, iPage, nPagesToGo, level + 1); | 509 iPage += nPages; |
509 | |
510 nPagesToGo -= nPages; | |
511 } | 510 } |
512 } | 511 } |
513 return nullptr; | |
514 } | 512 } |
515 | 513 |
516 CPDF_Dictionary* CPDF_Document::GetPagesDict() const { | 514 CPDF_Dictionary* CPDF_Document::GetPagesDict() const { |
517 CPDF_Dictionary* pRoot = GetRoot(); | 515 CPDF_Dictionary* pRoot = GetRoot(); |
518 return pRoot ? pRoot->GetDictFor("Pages") : nullptr; | 516 return pRoot ? pRoot->GetDictFor("Pages") : nullptr; |
519 } | 517 } |
520 | 518 |
521 bool CPDF_Document::IsPageLoaded(int iPage) const { | 519 bool CPDF_Document::IsPageLoaded(int iPage) const { |
522 return !!m_PageList.GetAt(iPage); | 520 return !!m_PageList.GetAt(iPage); |
523 } | 521 } |
524 | 522 |
525 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { | 523 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { |
526 if (iPage < 0 || iPage >= m_PageList.GetSize()) | 524 if (iPage < 0 || iPage >= m_PageList.GetSize()) |
527 return nullptr; | 525 return nullptr; |
528 | 526 |
529 if (m_bLinearized && (iPage == m_iFirstPageNo)) { | 527 if (m_bLinearized && (iPage == m_iFirstPageNo)) { |
530 if (CPDF_Dictionary* pDict = | 528 if (CPDF_Dictionary* pDict = |
531 ToDictionary(GetOrParseIndirectObject(m_dwFirstPageObjNum))) { | 529 ToDictionary(GetOrParseIndirectObject(m_dwFirstPageObjNum))) { |
532 return pDict; | 530 return pDict; |
533 } | 531 } |
534 } | 532 } |
535 | 533 |
534 if (!m_bPagesTraversed) { | |
535 CPDF_Dictionary* pPages = GetPagesDict(); | |
536 if (!pPages) | |
537 return nullptr; | |
538 | |
539 TraversePDFPages(pPages, 0, 0); | |
dsinclair
2016/10/17 13:26:37
This may have to do more work then needed in some
npm
2016/10/17 21:10:23
Changed to traverse only until needed.
| |
540 m_bPagesTraversed = true; | |
541 } | |
536 int objnum = m_PageList.GetAt(iPage); | 542 int objnum = m_PageList.GetAt(iPage); |
537 if (objnum) { | 543 if (objnum) { |
538 if (CPDF_Dictionary* pDict = ToDictionary(GetOrParseIndirectObject(objnum))) | 544 if (CPDF_Dictionary* pDict = ToDictionary(GetOrParseIndirectObject(objnum))) |
539 return pDict; | 545 return pDict; |
540 } | 546 } |
541 | 547 return nullptr; |
542 CPDF_Dictionary* pPages = GetPagesDict(); | |
543 if (!pPages) | |
544 return nullptr; | |
545 | |
546 CPDF_Dictionary* pPage = FindPDFPage(pPages, iPage, iPage, 0); | |
547 if (!pPage) | |
548 return nullptr; | |
549 | |
550 m_PageList.SetAt(iPage, pPage->GetObjNum()); | |
551 return pPage; | |
552 } | 548 } |
553 | 549 |
554 void CPDF_Document::SetPageObjNum(int iPage, uint32_t objNum) { | 550 void CPDF_Document::SetPageObjNum(int iPage, uint32_t objNum) { |
555 m_PageList.SetAt(iPage, objNum); | 551 m_PageList.SetAt(iPage, objNum); |
556 } | 552 } |
557 | 553 |
558 int CPDF_Document::FindPageIndex(CPDF_Dictionary* pNode, | 554 int CPDF_Document::FindPageIndex(CPDF_Dictionary* pNode, |
559 uint32_t& skip_count, | 555 uint32_t& skip_count, |
560 uint32_t objnum, | 556 uint32_t objnum, |
561 int& index, | 557 int& index, |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1013 pBBox, pLogFont->lfWeight / 5); | 1009 pBBox, pLogFont->lfWeight / 5); |
1014 pFontDesc->SetIntegerFor("CapHeight", capheight); | 1010 pFontDesc->SetIntegerFor("CapHeight", capheight); |
1015 pFontDict->SetReferenceFor("FontDescriptor", this, | 1011 pFontDict->SetReferenceFor("FontDescriptor", this, |
1016 AddIndirectObject(pFontDesc)); | 1012 AddIndirectObject(pFontDesc)); |
1017 hFont = SelectObject(hDC, hFont); | 1013 hFont = SelectObject(hDC, hFont); |
1018 DeleteObject(hFont); | 1014 DeleteObject(hFont); |
1019 DeleteDC(hDC); | 1015 DeleteDC(hDC); |
1020 return LoadFont(pBaseDict); | 1016 return LoadFont(pBaseDict); |
1021 } | 1017 } |
1022 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ | 1018 #endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ |
OLD | NEW |