| 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 "core/include/fpdfapi/fpdf_module.h" |    7 #include "core/include/fpdfapi/fpdf_module.h" | 
|    8 #include "core/include/fpdfapi/fpdf_parser.h" |    8 #include "core/include/fpdfapi/fpdf_parser.h" | 
|    9  |    9  | 
|   10 CPDF_Document::CPDF_Document(CPDF_Parser* pParser) |   10 CPDF_Document::CPDF_Document(CPDF_Parser* pParser) | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|   28 CPDF_DocRenderData* CPDF_Document::GetValidateRenderData() { |   28 CPDF_DocRenderData* CPDF_Document::GetValidateRenderData() { | 
|   29   if (m_pDocRender) { |   29   if (m_pDocRender) { | 
|   30     return m_pDocRender; |   30     return m_pDocRender; | 
|   31   } |   31   } | 
|   32   m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); |   32   m_pDocRender = CPDF_ModuleMgr::Get()->GetRenderModule()->CreateDocData(this); | 
|   33   return m_pDocRender; |   33   return m_pDocRender; | 
|   34 } |   34 } | 
|   35 void CPDF_Document::LoadDoc() { |   35 void CPDF_Document::LoadDoc() { | 
|   36   m_LastObjNum = m_pParser->GetLastObjNum(); |   36   m_LastObjNum = m_pParser->GetLastObjNum(); | 
|   37   CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum()); |   37   CPDF_Object* pRootObj = GetIndirectObject(m_pParser->GetRootObjNum()); | 
|   38   if (pRootObj == NULL) { |   38   if (!pRootObj) { | 
|   39     return; |   39     return; | 
|   40   } |   40   } | 
|   41   m_pRootDict = pRootObj->GetDict(); |   41   m_pRootDict = pRootObj->GetDict(); | 
|   42   if (m_pRootDict == NULL) { |   42   if (!m_pRootDict) { | 
|   43     return; |   43     return; | 
|   44   } |   44   } | 
|   45   CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum()); |   45   CPDF_Object* pInfoObj = GetIndirectObject(m_pParser->GetInfoObjNum()); | 
|   46   if (pInfoObj) { |   46   if (pInfoObj) { | 
|   47     m_pInfoDict = pInfoObj->GetDict(); |   47     m_pInfoDict = pInfoObj->GetDict(); | 
|   48   } |   48   } | 
|   49   CPDF_Array* pIDArray = m_pParser->GetIDArray(); |   49   CPDF_Array* pIDArray = m_pParser->GetIDArray(); | 
|   50   if (pIDArray) { |   50   if (pIDArray) { | 
|   51     m_ID1 = pIDArray->GetString(0); |   51     m_ID1 = pIDArray->GetString(0); | 
|   52     m_ID2 = pIDArray->GetString(1); |   52     m_ID2 = pIDArray->GetString(1); | 
|   53   } |   53   } | 
|   54   m_PageList.SetSize(_GetPageCount()); |   54   m_PageList.SetSize(_GetPageCount()); | 
|   55 } |   55 } | 
|   56 void CPDF_Document::LoadAsynDoc(CPDF_Dictionary* pLinearized) { |   56 void CPDF_Document::LoadAsynDoc(CPDF_Dictionary* pLinearized) { | 
|   57   m_bLinearized = TRUE; |   57   m_bLinearized = TRUE; | 
|   58   m_LastObjNum = m_pParser->GetLastObjNum(); |   58   m_LastObjNum = m_pParser->GetLastObjNum(); | 
|   59   CPDF_Object* indirectObj = GetIndirectObject(m_pParser->GetRootObjNum()); |   59   CPDF_Object* indirectObj = GetIndirectObject(m_pParser->GetRootObjNum()); | 
|   60   m_pRootDict = indirectObj ? indirectObj->GetDict() : NULL; |   60   m_pRootDict = indirectObj ? indirectObj->GetDict() : NULL; | 
|   61   if (m_pRootDict == NULL) { |   61   if (!m_pRootDict) { | 
|   62     return; |   62     return; | 
|   63   } |   63   } | 
|   64   indirectObj = GetIndirectObject(m_pParser->GetInfoObjNum()); |   64   indirectObj = GetIndirectObject(m_pParser->GetInfoObjNum()); | 
|   65   m_pInfoDict = indirectObj ? indirectObj->GetDict() : NULL; |   65   m_pInfoDict = indirectObj ? indirectObj->GetDict() : NULL; | 
|   66   CPDF_Array* pIDArray = m_pParser->GetIDArray(); |   66   CPDF_Array* pIDArray = m_pParser->GetIDArray(); | 
|   67   if (pIDArray) { |   67   if (pIDArray) { | 
|   68     m_ID1 = pIDArray->GetString(0); |   68     m_ID1 = pIDArray->GetString(0); | 
|   69     m_ID2 = pIDArray->GetString(1); |   69     m_ID2 = pIDArray->GetString(1); | 
|   70   } |   70   } | 
|   71   FX_DWORD dwPageCount = 0; |   71   FX_DWORD dwPageCount = 0; | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|   93   if (m_pDocRender) { |   93   if (m_pDocRender) { | 
|   94     CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender); |   94     CPDF_ModuleMgr::Get()->GetRenderModule()->DestroyDocData(m_pDocRender); | 
|   95   } |   95   } | 
|   96 } |   96 } | 
|   97 #define FX_MAX_PAGE_LEVEL 1024 |   97 #define FX_MAX_PAGE_LEVEL 1024 | 
|   98 CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, |   98 CPDF_Dictionary* CPDF_Document::_FindPDFPage(CPDF_Dictionary* pPages, | 
|   99                                              int iPage, |   99                                              int iPage, | 
|  100                                              int nPagesToGo, |  100                                              int nPagesToGo, | 
|  101                                              int level) { |  101                                              int level) { | 
|  102   CPDF_Array* pKidList = pPages->GetArray("Kids"); |  102   CPDF_Array* pKidList = pPages->GetArray("Kids"); | 
|  103   if (pKidList == NULL) { |  103   if (!pKidList) { | 
|  104     if (nPagesToGo == 0) { |  104     if (nPagesToGo == 0) { | 
|  105       return pPages; |  105       return pPages; | 
|  106     } |  106     } | 
|  107     return NULL; |  107     return NULL; | 
|  108   } |  108   } | 
|  109   if (level >= FX_MAX_PAGE_LEVEL) { |  109   if (level >= FX_MAX_PAGE_LEVEL) { | 
|  110     return NULL; |  110     return NULL; | 
|  111   } |  111   } | 
|  112   int nKids = pKidList->GetCount(); |  112   int nKids = pKidList->GetCount(); | 
|  113   for (int i = 0; i < nKids; i++) { |  113   for (int i = 0; i < nKids; i++) { | 
|  114     CPDF_Dictionary* pKid = pKidList->GetDict(i); |  114     CPDF_Dictionary* pKid = pKidList->GetDict(i); | 
|  115     if (pKid == NULL) { |  115     if (!pKid) { | 
|  116       nPagesToGo--; |  116       nPagesToGo--; | 
|  117       continue; |  117       continue; | 
|  118     } |  118     } | 
|  119     if (pKid == pPages) { |  119     if (pKid == pPages) { | 
|  120       continue; |  120       continue; | 
|  121     } |  121     } | 
|  122     if (!pKid->KeyExist("Kids")) { |  122     if (!pKid->KeyExist("Kids")) { | 
|  123       if (nPagesToGo == 0) { |  123       if (nPagesToGo == 0) { | 
|  124         return pKid; |  124         return pKid; | 
|  125       } |  125       } | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  168   return pPage; |  168   return pPage; | 
|  169 } |  169 } | 
|  170  |  170  | 
|  171 int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, |  171 int CPDF_Document::_FindPageIndex(CPDF_Dictionary* pNode, | 
|  172                                   FX_DWORD& skip_count, |  172                                   FX_DWORD& skip_count, | 
|  173                                   FX_DWORD objnum, |  173                                   FX_DWORD objnum, | 
|  174                                   int& index, |  174                                   int& index, | 
|  175                                   int level) { |  175                                   int level) { | 
|  176   if (pNode->KeyExist("Kids")) { |  176   if (pNode->KeyExist("Kids")) { | 
|  177     CPDF_Array* pKidList = pNode->GetArray("Kids"); |  177     CPDF_Array* pKidList = pNode->GetArray("Kids"); | 
|  178     if (pKidList == NULL) { |  178     if (!pKidList) { | 
|  179       return -1; |  179       return -1; | 
|  180     } |  180     } | 
|  181     if (level >= FX_MAX_PAGE_LEVEL) { |  181     if (level >= FX_MAX_PAGE_LEVEL) { | 
|  182       return -1; |  182       return -1; | 
|  183     } |  183     } | 
|  184     FX_DWORD count = pNode->GetInteger("Count"); |  184     FX_DWORD count = pNode->GetInteger("Count"); | 
|  185     if (count <= skip_count) { |  185     if (count <= skip_count) { | 
|  186       skip_count -= count; |  186       skip_count -= count; | 
|  187       index += count; |  187       index += count; | 
|  188       return -1; |  188       return -1; | 
|  189     } |  189     } | 
|  190     if (count && count == pKidList->GetCount()) { |  190     if (count && count == pKidList->GetCount()) { | 
|  191       for (FX_DWORD i = 0; i < count; i++) { |  191       for (FX_DWORD i = 0; i < count; i++) { | 
|  192         if (CPDF_Reference* pKid = ToReference(pKidList->GetElement(i))) { |  192         if (CPDF_Reference* pKid = ToReference(pKidList->GetElement(i))) { | 
|  193           if (pKid->GetRefObjNum() == objnum) { |  193           if (pKid->GetRefObjNum() == objnum) { | 
|  194             m_PageList.SetAt(index + i, objnum); |  194             m_PageList.SetAt(index + i, objnum); | 
|  195             return index + i; |  195             return index + i; | 
|  196           } |  196           } | 
|  197         } |  197         } | 
|  198       } |  198       } | 
|  199     } |  199     } | 
|  200     for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) { |  200     for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) { | 
|  201       CPDF_Dictionary* pKid = pKidList->GetDict(i); |  201       CPDF_Dictionary* pKid = pKidList->GetDict(i); | 
|  202       if (pKid == NULL) { |  202       if (!pKid) { | 
|  203         continue; |  203         continue; | 
|  204       } |  204       } | 
|  205       if (pKid == pNode) { |  205       if (pKid == pNode) { | 
|  206         continue; |  206         continue; | 
|  207       } |  207       } | 
|  208       int found_index = |  208       int found_index = | 
|  209           _FindPageIndex(pKid, skip_count, objnum, index, level + 1); |  209           _FindPageIndex(pKid, skip_count, objnum, index, level + 1); | 
|  210       if (found_index >= 0) { |  210       if (found_index >= 0) { | 
|  211         return found_index; |  211         return found_index; | 
|  212       } |  212       } | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
|  230     FX_DWORD objnum1 = m_PageList.GetAt(i); |  230     FX_DWORD objnum1 = m_PageList.GetAt(i); | 
|  231     if (objnum1 == objnum) { |  231     if (objnum1 == objnum) { | 
|  232       return i; |  232       return i; | 
|  233     } |  233     } | 
|  234     if (!bSkipped && objnum1 == 0) { |  234     if (!bSkipped && objnum1 == 0) { | 
|  235       skip_count = i; |  235       skip_count = i; | 
|  236       bSkipped = TRUE; |  236       bSkipped = TRUE; | 
|  237     } |  237     } | 
|  238   } |  238   } | 
|  239   CPDF_Dictionary* pRoot = GetRoot(); |  239   CPDF_Dictionary* pRoot = GetRoot(); | 
|  240   if (pRoot == NULL) { |  240   if (!pRoot) { | 
|  241     return -1; |  241     return -1; | 
|  242   } |  242   } | 
|  243   CPDF_Dictionary* pPages = pRoot->GetDict("Pages"); |  243   CPDF_Dictionary* pPages = pRoot->GetDict("Pages"); | 
|  244   if (pPages == NULL) { |  244   if (!pPages) { | 
|  245     return -1; |  245     return -1; | 
|  246   } |  246   } | 
|  247   int index = 0; |  247   int index = 0; | 
|  248   return _FindPageIndex(pPages, skip_count, objnum, index); |  248   return _FindPageIndex(pPages, skip_count, objnum, index); | 
|  249 } |  249 } | 
|  250 int CPDF_Document::GetPageCount() const { |  250 int CPDF_Document::GetPageCount() const { | 
|  251   return m_PageList.GetSize(); |  251   return m_PageList.GetSize(); | 
|  252 } |  252 } | 
|  253 static int _CountPages(CPDF_Dictionary* pPages, int level) { |  253 static int _CountPages(CPDF_Dictionary* pPages, int level) { | 
|  254   if (level > 128) { |  254   if (level > 128) { | 
|  255     return 0; |  255     return 0; | 
|  256   } |  256   } | 
|  257   int count = pPages->GetInteger("Count"); |  257   int count = pPages->GetInteger("Count"); | 
|  258   if (count > 0 && count < FPDF_PAGE_MAX_NUM) { |  258   if (count > 0 && count < FPDF_PAGE_MAX_NUM) { | 
|  259     return count; |  259     return count; | 
|  260   } |  260   } | 
|  261   CPDF_Array* pKidList = pPages->GetArray("Kids"); |  261   CPDF_Array* pKidList = pPages->GetArray("Kids"); | 
|  262   if (pKidList == NULL) { |  262   if (!pKidList) { | 
|  263     return 0; |  263     return 0; | 
|  264   } |  264   } | 
|  265   count = 0; |  265   count = 0; | 
|  266   for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) { |  266   for (FX_DWORD i = 0; i < pKidList->GetCount(); i++) { | 
|  267     CPDF_Dictionary* pKid = pKidList->GetDict(i); |  267     CPDF_Dictionary* pKid = pKidList->GetDict(i); | 
|  268     if (pKid == NULL) { |  268     if (!pKid) { | 
|  269       continue; |  269       continue; | 
|  270     } |  270     } | 
|  271     if (!pKid->KeyExist("Kids")) { |  271     if (!pKid->KeyExist("Kids")) { | 
|  272       count++; |  272       count++; | 
|  273     } else { |  273     } else { | 
|  274       count += _CountPages(pKid, level + 1); |  274       count += _CountPages(pKid, level + 1); | 
|  275     } |  275     } | 
|  276   } |  276   } | 
|  277   pPages->SetAtInteger("Count", count); |  277   pPages->SetAtInteger("Count", count); | 
|  278   return count; |  278   return count; | 
|  279 } |  279 } | 
|  280 int CPDF_Document::_GetPageCount() const { |  280 int CPDF_Document::_GetPageCount() const { | 
|  281   CPDF_Dictionary* pRoot = GetRoot(); |  281   CPDF_Dictionary* pRoot = GetRoot(); | 
|  282   if (pRoot == NULL) { |  282   if (!pRoot) { | 
|  283     return 0; |  283     return 0; | 
|  284   } |  284   } | 
|  285   CPDF_Dictionary* pPages = pRoot->GetDict("Pages"); |  285   CPDF_Dictionary* pPages = pRoot->GetDict("Pages"); | 
|  286   if (pPages == NULL) { |  286   if (!pPages) { | 
|  287     return 0; |  287     return 0; | 
|  288   } |  288   } | 
|  289   if (!pPages->KeyExist("Kids")) { |  289   if (!pPages->KeyExist("Kids")) { | 
|  290     return 1; |  290     return 1; | 
|  291   } |  291   } | 
|  292   return _CountPages(pPages, 0); |  292   return _CountPages(pPages, 0); | 
|  293 } |  293 } | 
|  294 FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum, |  294 FX_BOOL CPDF_Document::IsContentUsedElsewhere(FX_DWORD objnum, | 
|  295                                               CPDF_Dictionary* pThisPageDict) { |  295                                               CPDF_Dictionary* pThisPageDict) { | 
|  296   for (int i = 0; i < m_PageList.GetSize(); i++) { |  296   for (int i = 0; i < m_PageList.GetSize(); i++) { | 
|  297     CPDF_Dictionary* pPageDict = GetPage(i); |  297     CPDF_Dictionary* pPageDict = GetPage(i); | 
|  298     if (pPageDict == pThisPageDict) { |  298     if (pPageDict == pThisPageDict) { | 
|  299       continue; |  299       continue; | 
|  300     } |  300     } | 
|  301     CPDF_Object* pContents = |  301     CPDF_Object* pContents = | 
|  302         pPageDict ? pPageDict->GetElement("Contents") : NULL; |  302         pPageDict ? pPageDict->GetElement("Contents") : NULL; | 
|  303     if (pContents == NULL) { |  303     if (!pContents) { | 
|  304       continue; |  304       continue; | 
|  305     } |  305     } | 
|  306     if (pContents->GetDirectType() == PDFOBJ_ARRAY) { |  306     if (pContents->GetDirectType() == PDFOBJ_ARRAY) { | 
|  307       CPDF_Array* pArray = pContents->GetDirect()->AsArray(); |  307       CPDF_Array* pArray = pContents->GetDirect()->AsArray(); | 
|  308       for (FX_DWORD j = 0; j < pArray->GetCount(); j++) { |  308       for (FX_DWORD j = 0; j < pArray->GetCount(); j++) { | 
|  309         CPDF_Reference* pRef = ToReference(pArray->GetElement(j)); |  309         CPDF_Reference* pRef = ToReference(pArray->GetElement(j)); | 
|  310         if (pRef && pRef->GetRefObjNum() == objnum) |  310         if (pRef && pRef->GetRefObjNum() == objnum) | 
|  311           return TRUE; |  311           return TRUE; | 
|  312       } |  312       } | 
|  313     } else if (pContents->GetObjNum() == objnum) { |  313     } else if (pContents->GetObjNum() == objnum) { | 
|  314       return TRUE; |  314       return TRUE; | 
|  315     } |  315     } | 
|  316   } |  316   } | 
|  317   return FALSE; |  317   return FALSE; | 
|  318 } |  318 } | 
|  319 FX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const { |  319 FX_DWORD CPDF_Document::GetUserPermissions(FX_BOOL bCheckRevision) const { | 
|  320   if (m_pParser == NULL) { |  320   if (!m_pParser) { | 
|  321     return (FX_DWORD)-1; |  321     return (FX_DWORD)-1; | 
|  322   } |  322   } | 
|  323   return m_pParser->GetPermissions(bCheckRevision); |  323   return m_pParser->GetPermissions(bCheckRevision); | 
|  324 } |  324 } | 
|  325 FX_BOOL CPDF_Document::IsOwner() const { |  325 FX_BOOL CPDF_Document::IsOwner() const { | 
|  326   if (m_pParser == NULL) { |  326   return !m_pParser || m_pParser->IsOwner(); | 
|  327     return TRUE; |  | 
|  328   } |  | 
|  329   return m_pParser->IsOwner(); |  | 
|  330 } |  327 } | 
|  331 FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const { |  328 FX_BOOL CPDF_Document::IsFormStream(FX_DWORD objnum, FX_BOOL& bForm) const { | 
|  332   { |  329   { | 
|  333     CPDF_Object* pObj; |  330     CPDF_Object* pObj; | 
|  334     if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, (void*&)pObj)) { |  331     if (m_IndirectObjs.Lookup((void*)(uintptr_t)objnum, (void*&)pObj)) { | 
|  335       CPDF_Stream* pStream = pObj->AsStream(); |  332       CPDF_Stream* pStream = pObj->AsStream(); | 
|  336       bForm = pStream && pStream->GetDict()->GetString("Subtype") == "Form"; |  333       bForm = pStream && pStream->GetDict()->GetString("Subtype") == "Form"; | 
|  337       return TRUE; |  334       return TRUE; | 
|  338     } |  335     } | 
|  339   } |  336   } | 
|  340   if (m_pParser == NULL) { |  337   if (!m_pParser) { | 
|  341     bForm = FALSE; |  338     bForm = FALSE; | 
|  342     return TRUE; |  339     return TRUE; | 
|  343   } |  340   } | 
|  344   return m_pParser->IsFormStream(objnum, bForm); |  341   return m_pParser->IsFormStream(objnum, bForm); | 
|  345 } |  342 } | 
|  346 void CPDF_Document::ClearPageData() { |  343 void CPDF_Document::ClearPageData() { | 
|  347   if (m_pDocPage) { |  344   if (m_pDocPage) { | 
|  348     CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this); |  345     CPDF_ModuleMgr::Get()->GetPageModule()->ClearDoc(this); | 
|  349   } |  346   } | 
|  350 } |  347 } | 
|  351 void CPDF_Document::ClearRenderData() { |  348 void CPDF_Document::ClearRenderData() { | 
|  352   if (m_pDocRender) { |  349   if (m_pDocRender) { | 
|  353     CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender); |  350     CPDF_ModuleMgr::Get()->GetRenderModule()->ClearDocData(m_pDocRender); | 
|  354   } |  351   } | 
|  355 } |  352 } | 
| OLD | NEW |