Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 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 #include "core/fpdfapi/parser/cpdf_document.h" | 5 #include "core/fpdfapi/parser/cpdf_document.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "core/fpdfapi/cpdf_modulemgr.h" | 9 #include "core/fpdfapi/cpdf_modulemgr.h" |
| 10 #include "core/fpdfapi/parser/cpdf_array.h" | 10 #include "core/fpdfapi/parser/cpdf_array.h" |
| 11 #include "core/fpdfapi/parser/cpdf_boolean.h" | |
| 11 #include "core/fpdfapi/parser/cpdf_dictionary.h" | 12 #include "core/fpdfapi/parser/cpdf_dictionary.h" |
| 12 #include "core/fpdfapi/parser/cpdf_linearized_header.h" | 13 #include "core/fpdfapi/parser/cpdf_linearized_header.h" |
| 14 #include "core/fpdfapi/parser/cpdf_number.h" | |
| 13 #include "core/fpdfapi/parser/cpdf_parser.h" | 15 #include "core/fpdfapi/parser/cpdf_parser.h" |
| 14 #include "core/fpdfapi/parser/cpdf_reference.h" | 16 #include "core/fpdfapi/parser/cpdf_reference.h" |
| 17 #include "core/fpdfapi/parser/cpdf_string.h" | |
| 15 #include "core/fxcrt/fx_memory.h" | 18 #include "core/fxcrt/fx_memory.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 17 #include "third_party/base/ptr_util.h" | 20 #include "third_party/base/ptr_util.h" |
| 18 | 21 |
| 19 namespace { | 22 namespace { |
| 20 | 23 |
| 21 CPDF_Dictionary* CreatePageTreeNode(std::unique_ptr<CPDF_Array> kids, | 24 CPDF_Dictionary* CreatePageTreeNode(std::unique_ptr<CPDF_Array> kids, |
| 22 CPDF_Document* pDoc, | 25 CPDF_Document* pDoc, |
| 23 int count) { | 26 int count) { |
| 24 CPDF_Array* pUnowned = pDoc->AddIndirectObject(std::move(kids))->AsArray(); | 27 CPDF_Array* pUnowned = pDoc->AddIndirectObject(std::move(kids))->AsArray(); |
| 25 CPDF_Dictionary* pageNode = pDoc->NewIndirect<CPDF_Dictionary>(); | 28 CPDF_Dictionary* pageNode = pDoc->NewIndirect<CPDF_Dictionary>(); |
| 26 pageNode->SetStringFor("Type", "Pages"); | 29 pageNode->SetNewFor<CPDF_String>("Type", "Pages", false); |
| 27 pageNode->SetReferenceFor("Kids", pDoc, pUnowned); | 30 pageNode->SetNewFor<CPDF_Reference>("Kids", pDoc, pUnowned->GetObjNum()); |
| 28 pageNode->SetIntegerFor("Count", count); | 31 pageNode->SetNewFor<CPDF_Number>("Count", count); |
| 29 for (size_t i = 0; i < pUnowned->GetCount(); i++) | 32 for (size_t i = 0; i < pUnowned->GetCount(); i++) { |
| 30 pUnowned->GetDictAt(i)->SetReferenceFor("Parent", pDoc, pageNode); | 33 pUnowned->GetDictAt(i)->SetNewFor<CPDF_Reference>("Parent", pDoc, |
| 34 pageNode->GetObjNum()); | |
| 35 } | |
| 31 return pageNode; | 36 return pageNode; |
| 32 } | 37 } |
| 33 | 38 |
| 34 std::unique_ptr<CPDF_Dictionary> CreateNumberedPage(size_t number) { | 39 std::unique_ptr<CPDF_Dictionary> CreateNumberedPage(size_t number) { |
| 35 auto page = pdfium::MakeUnique<CPDF_Dictionary>(); | 40 auto page = pdfium::MakeUnique<CPDF_Dictionary>(); |
| 36 page->SetStringFor("Type", "Page"); | 41 page->SetNewFor<CPDF_String>("Type", "Page", false); |
| 37 page->SetIntegerFor("PageNumbering", number); | 42 page->SetNewFor<CPDF_Number>("PageNumbering", static_cast<int>(number)); |
|
Lei Zhang
2016/11/18 23:28:35
Maybe just pass in an int instead?
| |
| 38 return page; | 43 return page; |
| 39 } | 44 } |
| 40 | 45 |
| 41 class CPDF_TestDocumentForPages : public CPDF_Document { | 46 class CPDF_TestDocumentForPages : public CPDF_Document { |
| 42 public: | 47 public: |
| 43 CPDF_TestDocumentForPages() : CPDF_Document(nullptr) { | 48 CPDF_TestDocumentForPages() : CPDF_Document(nullptr) { |
| 44 // Set up test | 49 // Set up test |
| 45 auto zeroToTwo = pdfium::MakeUnique<CPDF_Array>(); | 50 auto zeroToTwo = pdfium::MakeUnique<CPDF_Array>(); |
| 46 zeroToTwo->AddNew<CPDF_Reference>( | 51 zeroToTwo->AddNew<CPDF_Reference>( |
| 47 this, AddIndirectObject(CreateNumberedPage(0))->GetObjNum()); | 52 this, AddIndirectObject(CreateNumberedPage(0))->GetObjNum()); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 72 CPDF_Dictionary* branch4 = CreatePageTreeNode(std::move(justSix), this, 1); | 77 CPDF_Dictionary* branch4 = CreatePageTreeNode(std::move(justSix), this, 1); |
| 73 | 78 |
| 74 auto allPages = pdfium::MakeUnique<CPDF_Array>(); | 79 auto allPages = pdfium::MakeUnique<CPDF_Array>(); |
| 75 allPages->AddNew<CPDF_Reference>(this, branch2->GetObjNum()); | 80 allPages->AddNew<CPDF_Reference>(this, branch2->GetObjNum()); |
| 76 allPages->AddNew<CPDF_Reference>(this, branch3->GetObjNum()); | 81 allPages->AddNew<CPDF_Reference>(this, branch3->GetObjNum()); |
| 77 allPages->AddNew<CPDF_Reference>(this, branch4->GetObjNum()); | 82 allPages->AddNew<CPDF_Reference>(this, branch4->GetObjNum()); |
| 78 CPDF_Dictionary* pagesDict = | 83 CPDF_Dictionary* pagesDict = |
| 79 CreatePageTreeNode(std::move(allPages), this, 7); | 84 CreatePageTreeNode(std::move(allPages), this, 7); |
| 80 | 85 |
| 81 m_pOwnedRootDict = pdfium::MakeUnique<CPDF_Dictionary>(); | 86 m_pOwnedRootDict = pdfium::MakeUnique<CPDF_Dictionary>(); |
| 82 m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict); | 87 m_pOwnedRootDict->SetNewFor<CPDF_Reference>("Pages", this, |
| 88 pagesDict->GetObjNum()); | |
| 83 m_pRootDict = m_pOwnedRootDict.get(); | 89 m_pRootDict = m_pOwnedRootDict.get(); |
| 84 m_PageList.SetSize(7); | 90 m_PageList.SetSize(7); |
| 85 } | 91 } |
| 86 | 92 |
| 87 private: | 93 private: |
| 88 std::unique_ptr<CPDF_Dictionary> m_pOwnedRootDict; | 94 std::unique_ptr<CPDF_Dictionary> m_pOwnedRootDict; |
| 89 }; | 95 }; |
| 90 | 96 |
| 91 class CPDF_TestDocumentWithPageWithoutPageNum : public CPDF_Document { | 97 class CPDF_TestDocumentWithPageWithoutPageNum : public CPDF_Document { |
| 92 public: | 98 public: |
| 93 CPDF_TestDocumentWithPageWithoutPageNum() : CPDF_Document(nullptr) { | 99 CPDF_TestDocumentWithPageWithoutPageNum() : CPDF_Document(nullptr) { |
| 94 // Set up test | 100 // Set up test |
| 95 auto allPages = pdfium::MakeUnique<CPDF_Array>(); | 101 auto allPages = pdfium::MakeUnique<CPDF_Array>(); |
| 96 allPages->AddNew<CPDF_Reference>( | 102 allPages->AddNew<CPDF_Reference>( |
| 97 this, AddIndirectObject(CreateNumberedPage(0))->GetObjNum()); | 103 this, AddIndirectObject(CreateNumberedPage(0))->GetObjNum()); |
| 98 allPages->AddNew<CPDF_Reference>( | 104 allPages->AddNew<CPDF_Reference>( |
| 99 this, AddIndirectObject(CreateNumberedPage(1))->GetObjNum()); | 105 this, AddIndirectObject(CreateNumberedPage(1))->GetObjNum()); |
| 100 // Page without pageNum. | 106 // Page without pageNum. |
| 101 allPages->Add(CreateNumberedPage(2)); | 107 allPages->Add(CreateNumberedPage(2)); |
| 102 CPDF_Dictionary* pagesDict = | 108 CPDF_Dictionary* pagesDict = |
| 103 CreatePageTreeNode(std::move(allPages), this, 3); | 109 CreatePageTreeNode(std::move(allPages), this, 3); |
| 104 m_pOwnedRootDict.reset(new CPDF_Dictionary()); | 110 m_pOwnedRootDict.reset(new CPDF_Dictionary()); |
| 105 m_pOwnedRootDict->SetReferenceFor("Pages", this, pagesDict->GetObjNum()); | 111 m_pOwnedRootDict->SetNewFor<CPDF_Reference>("Pages", this, |
| 112 pagesDict->GetObjNum()); | |
| 106 m_pRootDict = m_pOwnedRootDict.get(); | 113 m_pRootDict = m_pOwnedRootDict.get(); |
| 107 m_PageList.SetSize(3); | 114 m_PageList.SetSize(3); |
| 108 } | 115 } |
| 109 | 116 |
| 110 private: | 117 private: |
| 111 std::unique_ptr<CPDF_Dictionary> m_pOwnedRootDict; | 118 std::unique_ptr<CPDF_Dictionary> m_pOwnedRootDict; |
| 112 }; | 119 }; |
| 113 | 120 |
| 114 class TestLinearized : public CPDF_LinearizedHeader { | 121 class TestLinearized : public CPDF_LinearizedHeader { |
| 115 public: | 122 public: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 ASSERT_TRUE(page->KeyExist("PageNumbering")); | 194 ASSERT_TRUE(page->KeyExist("PageNumbering")); |
| 188 EXPECT_EQ(6, page->GetIntegerFor("PageNumbering")); | 195 EXPECT_EQ(6, page->GetIntegerFor("PageNumbering")); |
| 189 } | 196 } |
| 190 | 197 |
| 191 TEST_F(cpdf_document_test, UseCachedPageObjNumIfHaveNotPagesDict) { | 198 TEST_F(cpdf_document_test, UseCachedPageObjNumIfHaveNotPagesDict) { |
| 192 // ObjNum can be added in CPDF_DataAvail::IsPageAvail, and PagesDict | 199 // ObjNum can be added in CPDF_DataAvail::IsPageAvail, and PagesDict |
| 193 // can be not exists in this case. | 200 // can be not exists in this case. |
| 194 // (case, when hint table is used to page check in CPDF_DataAvail). | 201 // (case, when hint table is used to page check in CPDF_DataAvail). |
| 195 CPDF_Document document(pdfium::MakeUnique<CPDF_Parser>()); | 202 CPDF_Document document(pdfium::MakeUnique<CPDF_Parser>()); |
| 196 auto dict = pdfium::MakeUnique<CPDF_Dictionary>(); | 203 auto dict = pdfium::MakeUnique<CPDF_Dictionary>(); |
| 197 dict->SetBooleanFor("Linearized", true); | 204 dict->SetNewFor<CPDF_Boolean>("Linearized", true); |
| 198 const int page_count = 100; | 205 const int page_count = 100; |
| 199 dict->SetIntegerFor("N", page_count); | 206 dict->SetNewFor<CPDF_Number>("N", page_count); |
| 200 TestLinearized linearized(dict.get()); | 207 TestLinearized linearized(dict.get()); |
| 201 document.LoadLinearizedDoc(&linearized); | 208 document.LoadLinearizedDoc(&linearized); |
| 202 ASSERT_EQ(page_count, document.GetPageCount()); | 209 ASSERT_EQ(page_count, document.GetPageCount()); |
| 203 CPDF_Object* page_stub = document.NewIndirect<CPDF_Dictionary>(); | 210 CPDF_Object* page_stub = document.NewIndirect<CPDF_Dictionary>(); |
| 204 const uint32_t obj_num = page_stub->GetObjNum(); | 211 const uint32_t obj_num = page_stub->GetObjNum(); |
| 205 const int test_page_num = 33; | 212 const int test_page_num = 33; |
| 206 | 213 |
| 207 EXPECT_FALSE(document.IsPageLoaded(test_page_num)); | 214 EXPECT_FALSE(document.IsPageLoaded(test_page_num)); |
| 208 EXPECT_EQ(nullptr, document.GetPage(test_page_num)); | 215 EXPECT_EQ(nullptr, document.GetPage(test_page_num)); |
| 209 | 216 |
| 210 document.SetPageObjNum(test_page_num, obj_num); | 217 document.SetPageObjNum(test_page_num, obj_num); |
| 211 EXPECT_TRUE(document.IsPageLoaded(test_page_num)); | 218 EXPECT_TRUE(document.IsPageLoaded(test_page_num)); |
| 212 EXPECT_EQ(page_stub, document.GetPage(test_page_num)); | 219 EXPECT_EQ(page_stub, document.GetPage(test_page_num)); |
| 213 } | 220 } |
| OLD | NEW |