Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
fpdf_doc_unittest.cpp
Go to the documentation of this file.
1// Copyright 2016 The PDFium Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "public/fpdf_doc.h"
6
7#include <memory>
8#include <vector>
9
10#include "core/fpdfapi/page/test_with_page_module.h"
11#include "core/fpdfapi/parser/cpdf_array.h"
12#include "core/fpdfapi/parser/cpdf_dictionary.h"
13#include "core/fpdfapi/parser/cpdf_document.h"
14#include "core/fpdfapi/parser/cpdf_name.h"
15#include "core/fpdfapi/parser/cpdf_null.h"
16#include "core/fpdfapi/parser/cpdf_number.h"
17#include "core/fpdfapi/parser/cpdf_parser.h"
18#include "core/fpdfapi/parser/cpdf_reference.h"
19#include "core/fpdfapi/parser/cpdf_string.h"
20#include "core/fpdfapi/parser/cpdf_test_document.h"
21#include "core/fpdfdoc/cpdf_dest.h"
22#include "fpdfsdk/cpdfsdk_helpers.h"
23#include "public/cpp/fpdf_scopers.h"
24#include "testing/fx_string_testhelpers.h"
25#include "testing/gtest/include/gtest/gtest.h"
26
28 public:
29 struct DictObjInfo {
30 uint32_t num;
31 RetainPtr<CPDF_Dictionary> obj;
32 };
33
34 void SetUp() override {
36 auto pTestDoc = std::make_unique<CPDF_TestDocument>();
37 m_pIndirectObjs = pTestDoc.get();
38 m_pRootObj = m_pIndirectObjs->NewIndirect<CPDF_Dictionary>();
39 pTestDoc->SetRoot(m_pRootObj);
40 m_pDoc.reset(FPDFDocumentFromCPDFDocument(pTestDoc.release()));
41 }
42
44 m_pRootObj = nullptr;
45 m_pIndirectObjs = nullptr;
46 m_pDoc.reset();
48 }
49
51 std::vector<DictObjInfo> info;
52 for (int i = 0; i < num; ++i) {
53 auto obj = m_pIndirectObjs->NewIndirect<CPDF_Dictionary>();
54 info.push_back({obj->GetObjNum(), obj});
55 }
56 return info;
57 }
58
59 protected:
62 RetainPtr<CPDF_Dictionary> m_pRootObj;
63};
64
66 {
67 // No bookmark information.
68 ScopedFPDFWideString title = GetFPDFWideString(L"");
69 EXPECT_FALSE(FPDFBookmark_Find(m_pDoc.get(), title.get()));
70
71 title = GetFPDFWideString(L"Preface");
72 EXPECT_FALSE(FPDFBookmark_Find(m_pDoc.get(), title.get()));
73 }
74 {
75 // Empty bookmark tree.
76 m_pRootObj->SetNewFor<CPDF_Dictionary>("Outlines");
77 ScopedFPDFWideString title = GetFPDFWideString(L"");
78 EXPECT_FALSE(FPDFBookmark_Find(m_pDoc.get(), title.get()));
79
80 title = GetFPDFWideString(L"Preface");
81 EXPECT_FALSE(FPDFBookmark_Find(m_pDoc.get(), title.get()));
82 }
83 {
84 // Check on a regular bookmark tree.
85 auto bookmarks = CreateDictObjs(3);
86
87 bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1");
88 bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
89 bookmarks[0].num);
90 bookmarks[1].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
91 bookmarks[2].num);
92
93 bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2");
94 bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
95 bookmarks[0].num);
96 bookmarks[2].obj->SetNewFor<CPDF_Reference>("Prev", m_pIndirectObjs,
97 bookmarks[1].num);
98
99 bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines");
100 bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2);
101 bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
102 bookmarks[1].num);
103 bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs,
104 bookmarks[2].num);
105
106 m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs,
107 bookmarks[0].num);
108
109 // Title with no match.
110 ScopedFPDFWideString title = GetFPDFWideString(L"Chapter 3");
111 EXPECT_FALSE(FPDFBookmark_Find(m_pDoc.get(), title.get()));
112
113 // Title with partial match only.
114 title = GetFPDFWideString(L"Chapter");
115 EXPECT_FALSE(FPDFBookmark_Find(m_pDoc.get(), title.get()));
116
117 // Title with a match.
118 title = GetFPDFWideString(L"Chapter 2");
119 EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[2].obj.Get()),
120 FPDFBookmark_Find(m_pDoc.get(), title.get()));
121
122 // Title match is case insensitive.
123 title = GetFPDFWideString(L"cHaPter 2");
124 EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[2].obj.Get()),
125 FPDFBookmark_Find(m_pDoc.get(), title.get()));
126 }
127 {
128 // Circular bookmarks in depth.
129 auto bookmarks = CreateDictObjs(3);
130
131 bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1");
132 bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
133 bookmarks[0].num);
134 bookmarks[1].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
135 bookmarks[2].num);
136
137 bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2");
138 bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
139 bookmarks[1].num);
140 bookmarks[2].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
141 bookmarks[1].num);
142
143 bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines");
144 bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2);
145 bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
146 bookmarks[1].num);
147 bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs,
148 bookmarks[2].num);
149
150 m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs,
151 bookmarks[0].num);
152
153 // Title with no match.
154 ScopedFPDFWideString title = GetFPDFWideString(L"Chapter 3");
155 EXPECT_FALSE(FPDFBookmark_Find(m_pDoc.get(), title.get()));
156
157 // Title with a match.
158 title = GetFPDFWideString(L"Chapter 2");
159 EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[2].obj.Get()),
160 FPDFBookmark_Find(m_pDoc.get(), title.get()));
161 }
162 {
163 // Circular bookmarks in breadth.
164 auto bookmarks = CreateDictObjs(4);
165
166 bookmarks[1].obj->SetNewFor<CPDF_String>("Title", L"Chapter 1");
167 bookmarks[1].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
168 bookmarks[0].num);
169 bookmarks[1].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
170 bookmarks[2].num);
171
172 bookmarks[2].obj->SetNewFor<CPDF_String>("Title", L"Chapter 2");
173 bookmarks[2].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
174 bookmarks[0].num);
175 bookmarks[2].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
176 bookmarks[3].num);
177
178 bookmarks[3].obj->SetNewFor<CPDF_String>("Title", L"Chapter 3");
179 bookmarks[3].obj->SetNewFor<CPDF_Reference>("Parent", m_pIndirectObjs,
180 bookmarks[0].num);
181 bookmarks[3].obj->SetNewFor<CPDF_Reference>("Next", m_pIndirectObjs,
182 bookmarks[1].num);
183
184 bookmarks[0].obj->SetNewFor<CPDF_Name>("Type", "Outlines");
185 bookmarks[0].obj->SetNewFor<CPDF_Number>("Count", 2);
186 bookmarks[0].obj->SetNewFor<CPDF_Reference>("First", m_pIndirectObjs,
187 bookmarks[1].num);
188 bookmarks[0].obj->SetNewFor<CPDF_Reference>("Last", m_pIndirectObjs,
189 bookmarks[2].num);
190
191 m_pRootObj->SetNewFor<CPDF_Reference>("Outlines", m_pIndirectObjs,
192 bookmarks[0].num);
193
194 // Title with no match.
195 ScopedFPDFWideString title = GetFPDFWideString(L"Chapter 8");
196 EXPECT_FALSE(FPDFBookmark_Find(m_pDoc.get(), title.get()));
197
198 // Title with a match.
199 title = GetFPDFWideString(L"Chapter 3");
200 EXPECT_EQ(FPDFBookmarkFromCPDFDictionary(bookmarks[3].obj.Get()),
201 FPDFBookmark_Find(m_pDoc.get(), title.get()));
202 }
203}
204
206 auto array = pdfium::MakeRetain<CPDF_Array>();
207 array->AppendNew<CPDF_Number>(0); // Page Index.
208 array->AppendNew<CPDF_Name>("XYZ");
209 array->AppendNew<CPDF_Number>(4); // X
210 array->AppendNew<CPDF_Number>(5); // Y
211 array->AppendNew<CPDF_Number>(6); // Zoom.
212
213 FPDF_BOOL hasX;
214 FPDF_BOOL hasY;
215 FPDF_BOOL hasZoom;
216 FS_FLOAT x;
217 FS_FLOAT y;
218 FS_FLOAT zoom;
219
220 EXPECT_TRUE(FPDFDest_GetLocationInPage(FPDFDestFromCPDFArray(array.Get()),
221 &hasX, &hasY, &hasZoom, &x, &y,
222 &zoom));
223 EXPECT_TRUE(hasX);
224 EXPECT_TRUE(hasY);
225 EXPECT_TRUE(hasZoom);
226 EXPECT_EQ(4, x);
227 EXPECT_EQ(5, y);
228 EXPECT_EQ(6, zoom);
229
230 array->SetNewAt<CPDF_Null>(2);
231 array->SetNewAt<CPDF_Null>(3);
232 array->SetNewAt<CPDF_Null>(4);
233 EXPECT_TRUE(FPDFDest_GetLocationInPage(FPDFDestFromCPDFArray(array.Get()),
234 &hasX, &hasY, &hasZoom, &x, &y,
235 &zoom));
236 EXPECT_FALSE(hasX);
237 EXPECT_FALSE(hasY);
238 EXPECT_FALSE(hasZoom);
239
240 array = pdfium::MakeRetain<CPDF_Array>();
241 EXPECT_FALSE(FPDFDest_GetLocationInPage(FPDFDestFromCPDFArray(array.Get()),
242 &hasX, &hasY, &hasZoom, &x, &y,
243 &zoom));
244}
std::vector< DictObjInfo > CreateDictObjs(int num)
void TearDown() override
UnownedPtr< CPDF_IndirectObjectHolder > m_pIndirectObjs
ScopedFPDFDocument m_pDoc
RetainPtr< CPDF_Dictionary > m_pRootObj
void SetUp() override
TEST_F(PDFDocTest, FindBookmark)
RetainPtr< CPDF_Dictionary > obj