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

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

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

Powered by Google App Engine
This is Rietveld 408576698