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

Side by Side Diff: core/fpdfapi/parser/cpdf_document.cpp

Issue 2414423002: Traverse PDF page tree only once in CPDF_Document (Closed)
Patch Set: Created 4 years, 2 months 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 | « core/fpdfapi/parser/cpdf_document.h ('k') | 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 "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
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
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
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_
OLDNEW
« no previous file with comments | « core/fpdfapi/parser/cpdf_document.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698