| 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 |