OLD | NEW |
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 "../../../include/fpdfapi/fpdf_parser.h" | 7 #include "../../../include/fpdfapi/fpdf_parser.h" |
8 #include "../../../include/fpdfapi/fpdf_module.h" | 8 #include "../../../include/fpdfapi/fpdf_module.h" |
9 | 9 |
10 CPDF_Document::CPDF_Document(CPDF_Parser* pParser) : CPDF_IndirectObjects(pParse
r) | 10 CPDF_Document::CPDF_Document(CPDF_Parser* pParser) |
11 { | 11 : CPDF_IndirectObjects(pParser) { |
12 ASSERT(pParser != NULL); | 12 ASSERT(pParser != NULL); |
13 m_pRootDict = NULL; | 13 m_pRootDict = NULL; |
14 m_pInfoDict = NULL; | 14 m_pInfoDict = NULL; |
15 m_bLinearized = FALSE; | 15 m_bLinearized = FALSE; |
16 m_dwFirstPageNo = 0; | 16 m_dwFirstPageNo = 0; |
17 m_dwFirstPageObjNum = 0; | 17 m_dwFirstPageObjNum = 0; |
18 m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); | 18 m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); |
19 m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this)
; | 19 m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); |
20 } | 20 } |
21 CPDF_DocPageData* CPDF_Document::GetValidatePageData() | 21 CPDF_DocPageData* CPDF_Document::GetValidatePageData() { |
22 { | 22 if (m_pDocPage) { |
23 if (m_pDocPage) { | |
24 return m_pDocPage; | |
25 } | |
26 m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); | |
27 return m_pDocPage; | 23 return m_pDocPage; |
28 } | 24 } |
29 CPDF_DocRenderData* CPDF_Document::GetValidateRenderData() | 25 m_pDocPage = CPDF_ModuleMgr::Get()->GetPageModule()->CreateDocData(this); |
30 { | 26 return m_pDocPage; |
31 if (m_pDocRender) { | 27 } |
32 return m_pDocRender; | 28 CPDF_DocRenderData* CPDF_Document::GetValidateRenderData() { |
33 } | 29 if (m_pDocRender) { |
34 m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this)
; | |
35 return m_pDocRender; | 30 return m_pDocRender; |
36 } | 31 } |
37 void CPDF_Document::LoadDoc() | 32 m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); |
38 { | 33 return m_pDocRender; |
39 m_LastObjNum = m_pParser->GetLastObjNum(); | 34 } |
40 CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum()); | 35 void CPDF_Document::LoadDoc() { |
41 if (pRootObj == NULL) { | 36 m_LastObjNum = m_pParser->GetLastObjNum(); |
42 return; | 37 CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum()); |
43 } | 38 if (pRootObj == NULL) { |
44 m_pRootDict = pRootObj->GetDict(); | 39 return; |
45 if (m_pRootDict == NULL) { | 40 } |
46 return; | 41 m_pRootDict = pRootObj->GetDict(); |
47 } | 42 if (m_pRootDict == NULL) { |
48 CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum()); | 43 return; |
49 if (pInfoObj) { | 44 } |
50 m_pInfoDict = pInfoObj->GetDict(); | 45 CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum()); |
51 } | 46 if (pInfoObj) { |
52 CPDF_Array* pIDArray = m_pParser->GetIDArray(); | 47 m_pInfoDict = pInfoObj->GetDict(); |
53 if (pIDArray) { | 48 } |
54 m_ID1 = pIDArray->GetString(0); | 49 CPDF_Array* pIDArray = m_pParser->GetIDArray(); |
55 m_ID2 = pIDArray->GetString(1); | 50 if (pIDArray) { |
56 } | 51 m_ID1 = pIDArray->GetString(0); |
57 m_PageList.SetSize(_GetPageCount()); | 52 m_ID2 = pIDArray->GetString(1); |
58 } | 53 } |
59 void CPDF_Document::LoadAsynDoc(CPDF_Dictionary *pLinearized) | 54 m_PageList.SetSize(_GetPageCount()); |
60 { | 55 } |
61 m_bLinearized = TRUE; | 56 void CPDF_Document::LoadAsynDoc(CPDF_Dictionary* pLinearized) { |
62 m_LastObjNum = m_pParser->GetLastObjNum(); | 57 m_bLinearized = TRUE; |
63 CPDF_Object* indirectObj = GetIndirectObject(m_pParser->GetRootObjNum()); | 58 m_LastObjNum = m_pParser->GetLastObjNum(); |
64 m_pRootDict = indirectObj ? indirectObj->GetDict() : NULL; | 59 CPDF_Object* indirectObj = GetIndirectObject(m_pParser->GetRootObjNum()); |
65 if (m_pRootDict == NULL) { | 60 m_pRootDict = indirectObj ? indirectObj->GetDict() : NULL; |
66 return; | 61 if (m_pRootDict == NULL) { |
67 } | 62 return; |
68 indirectObj = GetIndirectObject(m_pParser->GetInfoObjNum()); | 63 } |
69 m_pInfoDict = indirectObj ? indirectObj->GetDict() : NULL; | 64 indirectObj = GetIndirectObject(m_pParser->GetInfoObjNum()); |
70 CPDF_Array* pIDArray = m_pParser->GetIDArray(); | 65 m_pInfoDict = indirectObj ? indirectObj->GetDict() : NULL; |
71 if (pIDArray) { | 66 CPDF_Array* pIDArray = m_pParser->GetIDArray(); |
72 m_ID1 = pIDArray->GetString(0); | 67 if (pIDArray) { |
73 m_ID2 = pIDArray->GetString(1); | 68 m_ID1 = pIDArray->GetString(0); |
74 } | 69 m_ID2 = pIDArray->GetString(1); |
75 FX_DWORD dwPageCount = 0; | 70 } |
76 CPDF_Object *pCount = pLinearized->GetElement(FX_BSTRC("N")); | 71 FX_DWORD dwPageCount = 0; |
77 if (pCount && pCount->GetType() == PDFOBJ_NUMBER) { | 72 CPDF_Object* pCount = pLinearized->GetElement(FX_BSTRC("N")); |
78 dwPageCount = pCount->GetInteger(); | 73 if (pCount && pCount->GetType() == PDFOBJ_NUMBER) { |
79 } | 74 dwPageCount = pCount->GetInteger(); |
80 m_PageList.SetSize(dwPageCount); | 75 } |
81 CPDF_Object *pNo = pLinearized->GetElement(FX_BSTRC("P")); | 76 m_PageList.SetSize(dwPageCount); |
82 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { | 77 CPDF_Object* pNo = pLinearized->GetElement(FX_BSTRC("P")); |
83 m_dwFirstPageNo = pNo->GetInteger(); | 78 if (pNo && pNo->GetType() == PDFOBJ_NUMBER) { |
84 } | 79 m_dwFirstPageNo = pNo->GetInteger(); |
85 CPDF_Object *pObjNum = pLinearized->GetElement(FX_BSTRC("O")); | 80 } |
86 if (pObjNum && pObjNum->GetType() == PDFOBJ_NUMBER) { | 81 CPDF_Object* pObjNum = pLinearized->GetElement(FX_BSTRC("O")); |
87 m_dwFirstPageObjNum = pObjNum->GetInteger(); | 82 if (pObjNum && pObjNum->GetType() == PDFOBJ_NUMBER) { |
88 } | 83 m_dwFirstPageObjNum = pObjNum->GetInteger(); |
89 } | 84 } |
90 void CPDF_Document::LoadPages() | 85 } |
91 { | 86 void CPDF_Document::LoadPages() { |
92 m_PageList.SetSize(_GetPageCount()); | 87 m_PageList.SetSize(_GetPageCount()); |
93 } | 88 } |
94 extern void FPDF_TTFaceMapper_ReleaseDoc(CPDF_Document*); | 89 extern void FPDF_TTFaceMapper_ReleaseDoc(CPDF_Document*); |
95 CPDF_Document::~CPDF_Document() | 90 CPDF_Document::~CPDF_Document() { |
96 { | 91 if (m_pDocPage) { |
97 if (m_pDocPage) { | 92 CPDF_ModuleMgr::Get()->GetPageModule()->ReleaseDoc(this); |
98 CPDF_ModuleMgr::Get()->GetPageModule()->ReleaseDoc(this); | 93 CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this); |
99 CPDF_ModuleMgr::Get()->GetPageModule()->ClearStockFont(this); | 94 } |
100 } | 95 if (m_pDocRender) { |
101 if (m_pDocRender) { | 96 CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender); |
102 CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender); | 97 } |
103 } | 98 } |
104 } | 99 #define FX_MAX_PAGE_LEVEL 1024 |
105 #define»» FX_MAX_PAGE_LEVEL» » » 1024 | 100 CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, |
106 CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, int iPage,
int nPagesToGo, int level) | 101 int iPage, |
107 { | 102 int nPagesToGo, |
108 CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); | 103 int level) { |
| 104 CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); |
| 105 if (pKidList == NULL) { |
| 106 if (nPagesToGo == 0) { |
| 107 return pPages; |
| 108 } |
| 109 return NULL; |
| 110 } |
| 111 if (level >= FX_MAX_PAGE_LEVEL) { |
| 112 return NULL; |
| 113 } |
| 114 int nKids = pKidList->GetCount(); |
| 115 for (int i = 0; i < nKids; i++) { |
| 116 CPDF_Dictionary* pKid = pKidList->GetDict(i); |
| 117 if (pKid == NULL) { |
| 118 nPagesToGo--; |
| 119 continue; |
| 120 } |
| 121 if (pKid == pPages) { |
| 122 continue; |
| 123 } |
| 124 if (!pKid->KeyExist(FX_BSTRC("Kids"))) { |
| 125 if (nPagesToGo == 0) { |
| 126 return pKid; |
| 127 } |
| 128 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); |
| 129 nPagesToGo--; |
| 130 } else { |
| 131 int nPages = pKid->GetInteger(FX_BSTRC("Count")); |
| 132 if (nPagesToGo < nPages) { |
| 133 return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1); |
| 134 } |
| 135 nPagesToGo -= nPages; |
| 136 } |
| 137 } |
| 138 return NULL; |
| 139 } |
| 140 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) { |
| 141 if (iPage < 0 || iPage >= m_PageList.GetSize()) { |
| 142 return NULL; |
| 143 } |
| 144 if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) { |
| 145 CPDF_Object* pObj = GetIndirectObject(m_dwFirstPageObjNum); |
| 146 if (pObj && pObj->GetType() == PDFOBJ_DICTIONARY) { |
| 147 return (CPDF_Dictionary*)pObj; |
| 148 } |
| 149 } |
| 150 int objnum = m_PageList.GetAt(iPage); |
| 151 if (objnum) { |
| 152 CPDF_Object* pObj = GetIndirectObject(objnum); |
| 153 ASSERT(pObj->GetType() == PDFOBJ_DICTIONARY); |
| 154 return (CPDF_Dictionary*)pObj; |
| 155 } |
| 156 CPDF_Dictionary* pRoot = GetRoot(); |
| 157 if (pRoot == NULL) { |
| 158 return NULL; |
| 159 } |
| 160 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); |
| 161 if (pPages == NULL) { |
| 162 return NULL; |
| 163 } |
| 164 CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0); |
| 165 if (pPage == NULL) { |
| 166 return NULL; |
| 167 } |
| 168 m_PageList.SetAt(iPage, pPage->GetObjNum()); |
| 169 return pPage; |
| 170 } |
| 171 int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, |
| 172 FX_DWORD& skip_count, |
| 173 FX_DWORD objnum, |
| 174 int& index, |
| 175 int level) { |
| 176 if (pNode->KeyExist(FX_BSTRC("Kids"))) { |
| 177 CPDF_Array* pKidList = pNode->GetArray(FX_BSTRC("Kids")); |
109 if (pKidList == NULL) { | 178 if (pKidList == NULL) { |
110 if (nPagesToGo == 0) { | 179 return -1; |
111 return pPages; | 180 } |
| 181 if (level >= FX_MAX_PAGE_LEVEL) { |
| 182 return -1; |
| 183 } |
| 184 FX_DWORD count = pNode->GetInteger(FX_BSTRC("Count")); |
| 185 if (count <= skip_count) { |
| 186 skip_count -= count; |
| 187 index += count; |
| 188 return -1; |
| 189 } |
| 190 if (count && count == pKidList->GetCount()) { |
| 191 for (FX_DWORD i = 0; i < count; i++) { |
| 192 CPDF_Object* pKid = pKidList->GetElement(i); |
| 193 if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { |
| 194 if (((CPDF_Reference*)pKid)->GetRefObjNum() == objnum) { |
| 195 m_PageList.SetAt(index + i, objnum); |
| 196 return index + i; |
| 197 } |
112 } | 198 } |
113 return NULL; | 199 } |
114 } | 200 } |
115 if (level >= FX_MAX_PAGE_LEVEL) { | 201 for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) { |
116 return NULL; | 202 CPDF_Dictionary* pKid = pKidList->GetDict(i); |
117 } | 203 if (pKid == NULL) { |
118 int nKids = pKidList->GetCount(); | 204 continue; |
119 for (int i = 0; i < nKids; i ++) { | 205 } |
120 CPDF_Dictionary* pKid = pKidList->GetDict(i); | 206 if (pKid == pNode) { |
121 if (pKid == NULL) { | 207 continue; |
122 nPagesToGo --; | 208 } |
123 continue; | 209 int found_index = |
| 210 _FindPageIndex(pKid, skip_count, objnum, index, level + 1); |
| 211 if (found_index >= 0) { |
| 212 return found_index; |
| 213 } |
| 214 } |
| 215 } else { |
| 216 if (objnum == pNode->GetObjNum()) { |
| 217 return index; |
| 218 } |
| 219 if (skip_count) { |
| 220 skip_count--; |
| 221 } |
| 222 index++; |
| 223 } |
| 224 return -1; |
| 225 } |
| 226 int CPDF_Document::GetPageIndex(FX_DWORD objnum) { |
| 227 FX_DWORD nPages = m_PageList.GetSize(); |
| 228 FX_DWORD skip_count = 0; |
| 229 FX_BOOL bSkipped = FALSE; |
| 230 for (FX_DWORD i = 0; i < nPages; i++) { |
| 231 FX_DWORD objnum1 = m_PageList.GetAt(i); |
| 232 if (objnum1 == objnum) { |
| 233 return i; |
| 234 } |
| 235 if (!bSkipped && objnum1 == 0) { |
| 236 skip_count = i; |
| 237 bSkipped = TRUE; |
| 238 } |
| 239 } |
| 240 CPDF_Dictionary* pRoot = GetRoot(); |
| 241 if (pRoot == NULL) { |
| 242 return -1; |
| 243 } |
| 244 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); |
| 245 if (pPages == NULL) { |
| 246 return -1; |
| 247 } |
| 248 int index = 0; |
| 249 return _FindPageIndex(pPages, skip_count, objnum, index); |
| 250 } |
| 251 int CPDF_Document::GetPageCount() const { |
| 252 return m_PageList.GetSize(); |
| 253 } |
| 254 static int _CountPages(CPDF_Dictionary* pPages, int level) { |
| 255 if (level > 128) { |
| 256 return 0; |
| 257 } |
| 258 int count = pPages->GetInteger(FX_BSTRC("Count")); |
| 259 if (count > 0 && count < FPDF_PAGE_MAX_NUM) { |
| 260 return count; |
| 261 } |
| 262 CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); |
| 263 if (pKidList == NULL) { |
| 264 return 0; |
| 265 } |
| 266 count = 0; |
| 267 for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) { |
| 268 CPDF_Dictionary* pKid = pKidList->GetDict(i); |
| 269 if (pKid == NULL) { |
| 270 continue; |
| 271 } |
| 272 if (!pKid->KeyExist(FX_BSTRC("Kids"))) { |
| 273 count++; |
| 274 } else { |
| 275 count += _CountPages(pKid, level + 1); |
| 276 } |
| 277 } |
| 278 pPages->SetAtInteger(FX_BSTRC("Count"), count); |
| 279 return count; |
| 280 } |
| 281 int CPDF_Document::_GetPageCount() const { |
| 282 CPDF_Dictionary* pRoot = GetRoot(); |
| 283 if (pRoot == NULL) { |
| 284 return 0; |
| 285 } |
| 286 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); |
| 287 if (pPages == NULL) { |
| 288 return 0; |
| 289 } |
| 290 if (!pPages->KeyExist(FX_BSTRC("Kids"))) { |
| 291 return 1; |
| 292 } |
| 293 return _CountPages(pPages, 0); |
| 294 } |
| 295 FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum, |
| 296 CPDF_Dictionary* pThisPageDict) { |
| 297 for (int i = 0; i < m_PageList.GetSize(); i++) { |
| 298 CPDF_Dictionary* pPageDict = GetPage(i); |
| 299 if (pPageDict == pThisPageDict) { |
| 300 continue; |
| 301 } |
| 302 CPDF_Object* pContents = |
| 303 pPageDict ? pPageDict->GetElement(FX_BSTRC("Contents")) : NULL; |
| 304 if (pContents == NULL) { |
| 305 continue; |
| 306 } |
| 307 if (pContents->GetDirectType() == PDFOBJ_ARRAY) { |
| 308 CPDF_Array* pArray = (CPDF_Array*)pContents->GetDirect(); |
| 309 for (FX_DWORD j = 0; j < pArray->GetCount(); j++) { |
| 310 CPDF_Object* pRef = pArray->GetElement(j); |
| 311 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { |
| 312 continue; |
124 } | 313 } |
125 if (pKid == pPages) { | 314 if (((CPDF_Reference*)pRef)->GetRefObjNum() == objnum) { |
126 continue; | 315 return TRUE; |
127 } | 316 } |
128 if (!pKid->KeyExist(FX_BSTRC("Kids"))) { | 317 } |
129 if (nPagesToGo == 0) { | 318 } else if (pContents->GetObjNum() == objnum) { |
130 return pKid; | 319 return TRUE; |
131 } | 320 } |
132 m_PageList.SetAt(iPage - nPagesToGo, pKid->GetObjNum()); | 321 } |
133 nPagesToGo --; | 322 return FALSE; |
134 } else { | 323 } |
135 int nPages = pKid->GetInteger(FX_BSTRC("Count")); | 324 FX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const { |
136 if (nPagesToGo < nPages) { | 325 if (m_pParser == NULL) { |
137 return _FindPDFPage(pKid, iPage, nPagesToGo, level + 1); | 326 return (FX_DWORD)-1; |
138 } | 327 } |
139 nPagesToGo -= nPages; | 328 return m_pParser->GetPermissions(bCheckRevision); |
140 } | 329 } |
141 } | 330 FX_BOOL CPDF_Document::IsOwner() const { |
142 return NULL; | 331 if (m_pParser == NULL) { |
143 } | 332 return TRUE; |
144 CPDF_Dictionary* CPDF_Document::GetPage(int iPage) | 333 } |
145 { | 334 return m_pParser->IsOwner(); |
146 if (iPage < 0 || iPage >= m_PageList.GetSize()) { | 335 } |
147 return NULL; | 336 FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const { |
148 } | 337 { |
149 if (m_bLinearized && (iPage == (int)m_dwFirstPageNo)) { | 338 CPDF_Object* pObj; |
150 CPDF_Object* pObj = GetIndirectObject(m_dwFirstPageObjNum); | 339 if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, (void*&)pObj)) { |
151 if (pObj && pObj->GetType() == PDFOBJ_DICTIONARY) { | 340 bForm = pObj->GetType() == PDFOBJ_STREAM && |
152 return (CPDF_Dictionary*)pObj; | 341 ((CPDF_Stream*)pObj)->GetDict()->GetString(FX_BSTRC("Subtype")) == |
153 } | 342 FX_BSTRC("Form"); |
154 } | 343 return TRUE; |
155 int objnum = m_PageList.GetAt(iPage); | 344 } |
156 if (objnum) { | 345 } |
157 CPDF_Object* pObj = GetIndirectObject(objnum); | 346 if (m_pParser == NULL) { |
158 ASSERT(pObj->GetType() == PDFOBJ_DICTIONARY); | 347 bForm = FALSE; |
159 return (CPDF_Dictionary*)pObj; | 348 return TRUE; |
160 } | 349 } |
161 CPDF_Dictionary* pRoot = GetRoot(); | 350 return m_pParser->IsFormStream(objnum, bForm); |
162 if (pRoot == NULL) { | 351 } |
163 return NULL; | 352 void CPDF_Document::ClearPageData() { |
164 } | 353 if (m_pDocPage) { |
165 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); | 354 CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this); |
166 if (pPages == NULL) { | 355 } |
167 return NULL; | 356 } |
168 } | 357 void CPDF_Document::ClearRenderData() { |
169 CPDF_Dictionary* pPage = _FindPDFPage(pPages, iPage, iPage, 0); | 358 if (m_pDocRender) { |
170 if (pPage == NULL) { | 359 CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender); |
171 return NULL; | 360 } |
172 } | 361 } |
173 m_PageList.SetAt(iPage, pPage->GetObjNum()); | |
174 return pPage; | |
175 } | |
176 int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, FX_DWORD& skip_count,
FX_DWORD objnum, int& index, int level) | |
177 { | |
178 if (pNode->KeyExist(FX_BSTRC("Kids"))) { | |
179 CPDF_Array* pKidList = pNode->GetArray(FX_BSTRC("Kids")); | |
180 if (pKidList == NULL) { | |
181 return -1; | |
182 } | |
183 if (level >= FX_MAX_PAGE_LEVEL) { | |
184 return -1; | |
185 } | |
186 FX_DWORD count = pNode->GetInteger(FX_BSTRC("Count")); | |
187 if (count <= skip_count) { | |
188 skip_count -= count; | |
189 index += count; | |
190 return -1; | |
191 } | |
192 if (count && count == pKidList->GetCount()) { | |
193 for (FX_DWORD i = 0; i < count; i ++) { | |
194 CPDF_Object* pKid = pKidList->GetElement(i); | |
195 if (pKid && pKid->GetType() == PDFOBJ_REFERENCE) { | |
196 if (((CPDF_Reference*) pKid)->GetRefObjNum() == objnum) { | |
197 m_PageList.SetAt(index + i, objnum); | |
198 return index + i; | |
199 } | |
200 } | |
201 } | |
202 } | |
203 for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) { | |
204 CPDF_Dictionary* pKid = pKidList->GetDict(i); | |
205 if (pKid == NULL) { | |
206 continue; | |
207 } | |
208 if (pKid == pNode) { | |
209 continue; | |
210 } | |
211 int found_index = _FindPageIndex(pKid, skip_count, objnum, index, le
vel + 1); | |
212 if (found_index >= 0) { | |
213 return found_index; | |
214 } | |
215 } | |
216 } else { | |
217 if (objnum == pNode->GetObjNum()) { | |
218 return index; | |
219 } | |
220 if (skip_count) { | |
221 skip_count--; | |
222 } | |
223 index ++; | |
224 } | |
225 return -1; | |
226 } | |
227 int CPDF_Document::GetPageIndex(FX_DWORD objnum) | |
228 { | |
229 FX_DWORD nPages = m_PageList.GetSize(); | |
230 FX_DWORD skip_count = 0; | |
231 FX_BOOL bSkipped = FALSE; | |
232 for (FX_DWORD i = 0; i < nPages; i ++) { | |
233 FX_DWORD objnum1 = m_PageList.GetAt(i); | |
234 if (objnum1 == objnum) { | |
235 return i; | |
236 } | |
237 if (!bSkipped && objnum1 == 0) { | |
238 skip_count = i; | |
239 bSkipped = TRUE; | |
240 } | |
241 } | |
242 CPDF_Dictionary* pRoot = GetRoot(); | |
243 if (pRoot == NULL) { | |
244 return -1; | |
245 } | |
246 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); | |
247 if (pPages == NULL) { | |
248 return -1; | |
249 } | |
250 int index = 0; | |
251 return _FindPageIndex(pPages, skip_count, objnum, index); | |
252 } | |
253 int CPDF_Document::GetPageCount() const | |
254 { | |
255 return m_PageList.GetSize(); | |
256 } | |
257 static int _CountPages(CPDF_Dictionary* pPages, int level) | |
258 { | |
259 if (level > 128) { | |
260 return 0; | |
261 } | |
262 int count = pPages->GetInteger(FX_BSTRC("Count")); | |
263 if (count > 0 && count < FPDF_PAGE_MAX_NUM) { | |
264 return count; | |
265 } | |
266 CPDF_Array* pKidList = pPages->GetArray(FX_BSTRC("Kids")); | |
267 if (pKidList == NULL) { | |
268 return 0; | |
269 } | |
270 count = 0; | |
271 for (FX_DWORD i = 0; i < pKidList->GetCount(); i ++) { | |
272 CPDF_Dictionary* pKid = pKidList->GetDict(i); | |
273 if (pKid == NULL) { | |
274 continue; | |
275 } | |
276 if (!pKid->KeyExist(FX_BSTRC("Kids"))) { | |
277 count ++; | |
278 } else { | |
279 count += _CountPages(pKid, level + 1); | |
280 } | |
281 } | |
282 pPages->SetAtInteger(FX_BSTRC("Count"), count); | |
283 return count; | |
284 } | |
285 int CPDF_Document::_GetPageCount() const | |
286 { | |
287 CPDF_Dictionary* pRoot = GetRoot(); | |
288 if (pRoot == NULL) { | |
289 return 0; | |
290 } | |
291 CPDF_Dictionary* pPages = pRoot->GetDict(FX_BSTRC("Pages")); | |
292 if (pPages == NULL) { | |
293 return 0; | |
294 } | |
295 if (!pPages->KeyExist(FX_BSTRC("Kids"))) { | |
296 return 1; | |
297 } | |
298 return _CountPages(pPages, 0); | |
299 } | |
300 FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum, CPDF_Dictionary*
pThisPageDict) | |
301 { | |
302 for (int i = 0; i < m_PageList.GetSize(); i ++) { | |
303 CPDF_Dictionary* pPageDict = GetPage(i); | |
304 if (pPageDict == pThisPageDict) { | |
305 continue; | |
306 } | |
307 CPDF_Object* pContents = pPageDict ? pPageDict->GetElement(FX_BSTRC("Con
tents")) : NULL; | |
308 if (pContents == NULL) { | |
309 continue; | |
310 } | |
311 if (pContents->GetDirectType() == PDFOBJ_ARRAY) { | |
312 CPDF_Array* pArray = (CPDF_Array*)pContents->GetDirect(); | |
313 for (FX_DWORD j = 0; j < pArray->GetCount(); j ++) { | |
314 CPDF_Object* pRef = pArray->GetElement(j); | |
315 if (pRef == NULL || pRef->GetType() != PDFOBJ_REFERENCE) { | |
316 continue; | |
317 } | |
318 if (((CPDF_Reference*) pRef)->GetRefObjNum() == objnum) { | |
319 return TRUE; | |
320 } | |
321 } | |
322 } else if (pContents->GetObjNum() == objnum) { | |
323 return TRUE; | |
324 } | |
325 } | |
326 return FALSE; | |
327 } | |
328 FX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const | |
329 { | |
330 if (m_pParser == NULL) { | |
331 return (FX_DWORD) - 1; | |
332 } | |
333 return m_pParser->GetPermissions(bCheckRevision); | |
334 } | |
335 FX_BOOL CPDF_Document::IsOwner() const | |
336 { | |
337 if (m_pParser == NULL) { | |
338 return TRUE; | |
339 } | |
340 return m_pParser->IsOwner(); | |
341 } | |
342 FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const | |
343 { | |
344 { | |
345 CPDF_Object* pObj; | |
346 if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, (void*&)pObj)) { | |
347 bForm = pObj->GetType() == PDFOBJ_STREAM && | |
348 ((CPDF_Stream*)pObj)->GetDict()->GetString(FX_BSTRC("Subtype
")) == FX_BSTRC("Form"); | |
349 return TRUE; | |
350 } | |
351 } | |
352 if (m_pParser == NULL) { | |
353 bForm = FALSE; | |
354 return TRUE; | |
355 } | |
356 return m_pParser->IsFormStream(objnum, bForm); | |
357 } | |
358 void CPDF_Document::ClearPageData() | |
359 { | |
360 if (m_pDocPage) { | |
361 CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this); | |
362 } | |
363 } | |
364 void CPDF_Document::ClearRenderData() | |
365 { | |
366 if (m_pDocRender) { | |
367 CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender); | |
368 } | |
369 } | |
OLD | NEW |