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