1 // Copyright 2016 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/fpdfdoc/cpdf_linklist.h" 8 9 #include "core/fpdfapi/page/cpdf_page.h" 10 #include "core/fpdfapi/parser/cpdf_array.h" 11 CPDF_LinkList()12CPDF_LinkList::CPDF_LinkList() {} 13 ~CPDF_LinkList()14CPDF_LinkList::~CPDF_LinkList() {} 15 GetPageLinks(CPDF_Page * pPage)16const std::vector<CPDF_Dictionary*>* CPDF_LinkList::GetPageLinks( 17 CPDF_Page* pPage) { 18 uint32_t objnum = pPage->m_pFormDict->GetObjNum(); 19 if (objnum == 0) 20 return nullptr; 21 22 auto it = m_PageMap.find(objnum); 23 if (it != m_PageMap.end()) 24 return &it->second; 25 26 // std::map::operator[] forces the creation of a map entry. 27 std::vector<CPDF_Dictionary*>& page_link_list = m_PageMap[objnum]; 28 LoadPageLinks(pPage, &page_link_list); 29 return &page_link_list; 30 } 31 GetLinkAtPoint(CPDF_Page * pPage,const CFX_PointF & point,int * z_order)32CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, 33 const CFX_PointF& point, 34 int* z_order) { 35 const std::vector<CPDF_Dictionary*>* pPageLinkList = GetPageLinks(pPage); 36 if (!pPageLinkList) 37 return CPDF_Link(); 38 39 for (size_t i = pPageLinkList->size(); i > 0; --i) { 40 size_t annot_index = i - 1; 41 CPDF_Dictionary* pAnnot = (*pPageLinkList)[annot_index]; 42 if (!pAnnot) 43 continue; 44 45 CPDF_Link link(pAnnot); 46 if (!link.GetRect().Contains(point)) 47 continue; 48 49 if (z_order) 50 *z_order = annot_index; 51 return link; 52 } 53 return CPDF_Link(); 54 } 55 LoadPageLinks(CPDF_Page * pPage,std::vector<CPDF_Dictionary * > * pList)56void CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage, 57 std::vector<CPDF_Dictionary*>* pList) { 58 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArrayFor("Annots"); 59 if (!pAnnotList) 60 return; 61 62 for (size_t i = 0; i < pAnnotList->GetCount(); ++i) { 63 CPDF_Dictionary* pAnnot = pAnnotList->GetDictAt(i); 64 bool add_link = (pAnnot && pAnnot->GetStringFor("Subtype") == "Link"); 65 // Add non-links as nullptrs to preserve z-order. 66 pList->push_back(add_link ? pAnnot : nullptr); 67 } 68 } 69