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

Side by Side Diff: core/src/fpdfapi/fpdf_parser/fpdf_parser_document.cpp

Issue 1780503002: Split off CPDF_Document into its own .cpp/.h files. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Nits. Created 4 years, 9 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
OLDNEW
(Empty)
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 "core/include/fpdfapi/fpdf_parser.h"
8
9 #include <set>
10
11 #include "core/include/fpdfapi/fpdf_module.h"
12 #include "third_party/base/stl_util.h"
13
14 namespace {
15
16 int CountPages(CPDF_Dictionary* pPages,
17 std::set<CPDF_Dictionary*>* visited_pages) {
18 int count = pPages->GetIntegerBy("Count");
19 if (count > 0 && count < FPDF_PAGE_MAX_NUM) {
20 return count;
21 }
22 CPDF_Array* pKidList = pPages->GetArrayBy("Kids");
23 if (!pKidList) {
24 return 0;
25 }
26 count = 0;
27 for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) {
28 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
29 if (!pKid || pdfium::ContainsKey(*visited_pages, pKid)) {
30 continue;
31 }
32 if (pKid->KeyExist("Kids")) {
33 // Use |visited_pages| to help detect circular references of pages.
34 ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages, pKid);
35 count += CountPages(pKid, visited_pages);
36 } else {
37 // This page is a leaf node.
38 count++;
39 }
40 }
41 pPages->SetAtInteger("Count", count);
42 return count;
43 }
44
45 } // namespace
46
47 CPDF_Document::CPDF_Document(CPDF_Parser* pParser)
48 : CPDF_IndirectObjectHolder(pParser) {
49 ASSERT(pParser);
50 m_pRootDict = NULL;
51 m_pInfoDict = NULL;
52 m_bLinearized = FALSE;
53 m_dwFirstPageNo = 0;
54 m_dwFirstPageObjNum = 0;
55 m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this);
56 m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this);
57 }
58 CPDF_DocPageData* CPDF_Document::GetValidatePageData() {
59 if (m_pDocPage) {
60 return m_pDocPage;
61 }
62 m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this);
63 return m_pDocPage;
64 }
65 CPDF_DocRenderData* CPDF_Document::GetValidateRenderData() {
66 if (m_pDocRender) {
67 return m_pDocRender;
68 }
69 m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this);
70 return m_pDocRender;
71 }
72 void CPDF_Document::LoadDoc() {
73 m_LastObjNum = m_pParser->GetLastObjNum();
74 CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum());
75 if (!pRootObj) {
76 return;
77 }
78 m_pRootDict = pRootObj->GetDict();
79 if (!m_pRootDict) {
80 return;
81 }
82 CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum());
83 if (pInfoObj) {
84 m_pInfoDict = pInfoObj->GetDict();
85 }
86 CPDF_Array* pIDArray = m_pParser->GetIDArray();
87 if (pIDArray) {
88 m_ID1 = pIDArray->GetStringAt(0);
89 m_ID2 = pIDArray->GetStringAt(1);
90 }
91 m_PageList.SetSize(RetrievePageCount());
92 }
93 void CPDF_Document::LoadAsynDoc(CPDF_Dictionary* pLinearized) {
94 m_bLinearized = TRUE;
95 m_LastObjNum = m_pParser->GetLastObjNum();
96 CPDF_Object* pIndirectObj = GetIndirectObject(m_pParser->GetRootObjNum());
97 m_pRootDict = pIndirectObj ? pIndirectObj->GetDict() : nullptr;
98 if (!m_pRootDict) {
99 return;
100 }
101 pIndirectObj = GetIndirectObject(m_pParser->GetInfoObjNum());
102 m_pInfoDict = pIndirectObj ? pIndirectObj->GetDict() : nullptr;
103 CPDF_Array* pIDArray = m_pParser->GetIDArray();
104 if (pIDArray) {
105 m_ID1 = pIDArray->GetStringAt(0);
106 m_ID2 = pIDArray->GetStringAt(1);
107 }
108 FX_DWORD dwPageCount = 0;
109 CPDF_Object* pCount = pLinearized->GetElement("N");
110 if (ToNumber(pCount))
111 dwPageCount = pCount->GetInteger();
112
113 m_PageList.SetSize(dwPageCount);
114 CPDF_Object* pNo = pLinearized->GetElement("P");
115 if (ToNumber(pNo))
116 m_dwFirstPageNo = pNo->GetInteger();
117
118 CPDF_Object* pObjNum = pLinearized->GetElement("O");
119 if (ToNumber(pObjNum))
120 m_dwFirstPageObjNum = pObjNum->GetInteger();
121 }
122 void CPDF_Document::LoadPages() {
123 m_PageList.SetSize(RetrievePageCount());
124 }
125 CPDF_Document::~CPDF_Document() {
126 if (m_pDocPage) {
127 CPDF_ModuleMgr::Get()->GetPageModule()->ReleaseDoc(this);
128 CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this);
129 }
130 if (m_pDocRender) {
131 CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender);
132 }
133 }
134 #define FX_MAX_PAGE_LEVEL 1024
135 CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages,
136 int iPage,
137 int nPagesToGo,
138 int level) {
139 CPDF_Array* pKidList = pPages->GetArrayBy("Kids");
140 if (!pKidList) {
141 if (nPagesToGo == 0) {
142 return pPages;
143 }
144 return NULL;
145 }
146 if (level >= FX_MAX_PAGE_LEVEL) {
147 return NULL;
148 }
149 int nKids = pKidList->GetCount();
150 for (int i = 0; i < nKids; i++) {
151 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
152 if (!pKid) {
153 nPagesToGo--;
154 continue;
155 }
156 if (pKid == pPages) {
157 continue;
158 }
159 if (!pKid->KeyExist("Kids")) {
160 if (nPagesToGo == 0) {
161 return pKid;
162 }
163 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum());
164 nPagesToGo--;
165 } else {
166 int nPages = pKid->GetIntegerBy("Count");
167 if (nPagesToGo < nPages) {
168 return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1);
169 }
170 nPagesToGo -= nPages;
171 }
172 }
173 return NULL;
174 }
175
176 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) {
177 if (iPage < 0 || iPage >= m_PageList.GetSize())
178 return nullptr;
179
180 if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) {
181 if (CPDF_Dictionary* pDict =
182 ToDictionary(GetIndirectObject(m_dwFirstPageObjNum))) {
183 return pDict;
184 }
185 }
186
187 int objnum = m_PageList.GetAt(iPage);
188 if (objnum) {
189 if (CPDF_Dictionary* pDict = ToDictionary(GetIndirectObject(objnum)))
190 return pDict;
191 }
192
193 CPDF_Dictionary* pRoot = GetRoot();
194 if (!pRoot)
195 return nullptr;
196
197 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages");
198 if (!pPages)
199 return nullptr;
200
201 CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0);
202 if (!pPage)
203 return nullptr;
204
205 m_PageList.SetAt(iPage, pPage->GetObjNum());
206 return pPage;
207 }
208
209 int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode,
210 FX_DWORD& skip_count,
211 FX_DWORD objnum,
212 int& index,
213 int level) {
214 if (pNode->KeyExist("Kids")) {
215 CPDF_Array* pKidList = pNode->GetArrayBy("Kids");
216 if (!pKidList) {
217 return -1;
218 }
219 if (level >= FX_MAX_PAGE_LEVEL) {
220 return -1;
221 }
222 FX_DWORD count = pNode->GetIntegerBy("Count");
223 if (count <= skip_count) {
224 skip_count -= count;
225 index += count;
226 return -1;
227 }
228 if (count && count == pKidList->GetCount()) {
229 for (FX_DWORD i = 0; i < count; i++) {
230 if (CPDF_Reference* pKid = ToReference(pKidList->GetElement(i))) {
231 if (pKid->GetRefObjNum() == objnum) {
232 m_PageList.SetAt(index + i, objnum);
233 return index + i;
234 }
235 }
236 }
237 }
238 for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) {
239 CPDF_Dictionary* pKid = pKidList->GetDictAt(i);
240 if (!pKid) {
241 continue;
242 }
243 if (pKid == pNode) {
244 continue;
245 }
246 int found_index =
247 _FindPageIndex(pKid, skip_count, objnum, index, level + 1);
248 if (found_index >= 0) {
249 return found_index;
250 }
251 }
252 } else {
253 if (objnum == pNode->GetObjNum()) {
254 return index;
255 }
256 if (skip_count) {
257 skip_count--;
258 }
259 index++;
260 }
261 return -1;
262 }
263 int CPDF_Document::GetPageIndex(FX_DWORD objnum) {
264 FX_DWORD nPages = m_PageList.GetSize();
265 FX_DWORD skip_count = 0;
266 FX_BOOL bSkipped = FALSE;
267 for (FX_DWORD i = 0; i < nPages; i++) {
268 FX_DWORD objnum1 = m_PageList.GetAt(i);
269 if (objnum1 == objnum) {
270 return i;
271 }
272 if (!bSkipped && objnum1 == 0) {
273 skip_count = i;
274 bSkipped = TRUE;
275 }
276 }
277 CPDF_Dictionary* pRoot = GetRoot();
278 if (!pRoot) {
279 return -1;
280 }
281 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages");
282 if (!pPages) {
283 return -1;
284 }
285 int index = 0;
286 return _FindPageIndex(pPages, skip_count, objnum, index);
287 }
288 int CPDF_Document::GetPageCount() const {
289 return m_PageList.GetSize();
290 }
291
292 int CPDF_Document::RetrievePageCount() const {
293 CPDF_Dictionary* pRoot = GetRoot();
294 if (!pRoot) {
295 return 0;
296 }
297 CPDF_Dictionary* pPages = pRoot->GetDictBy("Pages");
298 if (!pPages) {
299 return 0;
300 }
301 if (!pPages->KeyExist("Kids")) {
302 return 1;
303 }
304 std::set<CPDF_Dictionary*> visited_pages;
305 visited_pages.insert(pPages);
306 return CountPages(pPages, &visited_pages);
307 }
308
309 FX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const {
310 if (!m_pParser) {
311 return (FX_DWORD)-1;
312 }
313 return m_pParser->GetPermissions(bCheckRevision);
314 }
315
316 FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const {
317 auto it = m_IndirectObjs.find(objnum);
318 if (it != m_IndirectObjs.end()) {
319 CPDF_Stream* pStream = it->second->AsStream();
320 bForm = pStream && pStream->GetDict()->GetStringBy("Subtype") == "Form";
321 return TRUE;
322 }
323 if (!m_pParser) {
324 bForm = FALSE;
325 return TRUE;
326 }
327 return m_pParser->IsFormStream(objnum, bForm);
328 }
329
330 void CPDF_Document::ClearPageData() {
331 if (m_pDocPage)
332 CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this);
333 }
334
335 void CPDF_Document::ClearRenderData() {
336 if (m_pDocRender)
337 CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender);
338 }
OLDNEW
« no previous file with comments | « core/src/fpdfapi/fpdf_parser/cpdf_document.cpp ('k') | core/src/fpdfapi/fpdf_parser/fpdf_parser_parser.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698