| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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/include/cpdf_link.h" | |
| 8 | |
| 9 #include <vector> | |
| 10 | |
| 11 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h" | |
| 12 #include "core/fpdfapi/fpdf_parser/include/cpdf_array.h" | |
| 13 #include "core/fpdfdoc/include/cpdf_linklist.h" | |
| 14 #include "core/fpdfdoc/include/cpdf_nametree.h" | |
| 15 | |
| 16 CPDF_LinkList::CPDF_LinkList() {} | |
| 17 | |
| 18 CPDF_LinkList::~CPDF_LinkList() {} | |
| 19 | |
| 20 const std::vector<CPDF_Dictionary*>* CPDF_LinkList::GetPageLinks( | |
| 21 CPDF_Page* pPage) { | |
| 22 uint32_t objnum = pPage->m_pFormDict->GetObjNum(); | |
| 23 if (objnum == 0) | |
| 24 return nullptr; | |
| 25 | |
| 26 auto it = m_PageMap.find(objnum); | |
| 27 if (it != m_PageMap.end()) | |
| 28 return &it->second; | |
| 29 | |
| 30 // std::map::operator[] forces the creation of a map entry. | |
| 31 std::vector<CPDF_Dictionary*>& page_link_list = m_PageMap[objnum]; | |
| 32 LoadPageLinks(pPage, &page_link_list); | |
| 33 return &page_link_list; | |
| 34 } | |
| 35 | |
| 36 CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, | |
| 37 FX_FLOAT pdf_x, | |
| 38 FX_FLOAT pdf_y, | |
| 39 int* z_order) { | |
| 40 const std::vector<CPDF_Dictionary*>* pPageLinkList = GetPageLinks(pPage); | |
| 41 if (!pPageLinkList) | |
| 42 return CPDF_Link(); | |
| 43 | |
| 44 for (size_t i = pPageLinkList->size(); i > 0; --i) { | |
| 45 size_t annot_index = i - 1; | |
| 46 CPDF_Dictionary* pAnnot = (*pPageLinkList)[annot_index]; | |
| 47 if (!pAnnot) | |
| 48 continue; | |
| 49 | |
| 50 CPDF_Link link(pAnnot); | |
| 51 CFX_FloatRect rect = link.GetRect(); | |
| 52 if (!rect.Contains(pdf_x, pdf_y)) | |
| 53 continue; | |
| 54 | |
| 55 if (z_order) | |
| 56 *z_order = annot_index; | |
| 57 return link; | |
| 58 } | |
| 59 return CPDF_Link(); | |
| 60 } | |
| 61 | |
| 62 void CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage, | |
| 63 std::vector<CPDF_Dictionary*>* pList) { | |
| 64 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArrayBy("Annots"); | |
| 65 if (!pAnnotList) | |
| 66 return; | |
| 67 | |
| 68 for (size_t i = 0; i < pAnnotList->GetCount(); ++i) { | |
| 69 CPDF_Dictionary* pAnnot = pAnnotList->GetDictAt(i); | |
| 70 bool add_link = (pAnnot && pAnnot->GetStringBy("Subtype") == "Link"); | |
| 71 // Add non-links as nullptrs to preserve z-order. | |
| 72 pList->push_back(add_link ? pAnnot : nullptr); | |
| 73 } | |
| 74 } | |
| 75 | |
| 76 CFX_FloatRect CPDF_Link::GetRect() { | |
| 77 return m_pDict->GetRectBy("Rect"); | |
| 78 } | |
| 79 CPDF_Dest CPDF_Link::GetDest(CPDF_Document* pDoc) { | |
| 80 CPDF_Object* pDest = m_pDict->GetDirectObjectBy("Dest"); | |
| 81 if (!pDest) | |
| 82 return CPDF_Dest(); | |
| 83 | |
| 84 if (pDest->IsString() || pDest->IsName()) { | |
| 85 CPDF_NameTree name_tree(pDoc, "Dests"); | |
| 86 return CPDF_Dest(name_tree.LookupNamedDest(pDoc, pDest->GetString())); | |
| 87 } | |
| 88 if (CPDF_Array* pArray = pDest->AsArray()) | |
| 89 return CPDF_Dest(pArray); | |
| 90 return CPDF_Dest(); | |
| 91 } | |
| 92 CPDF_Action CPDF_Link::GetAction() { | |
| 93 return CPDF_Action(m_pDict->GetDictBy("A")); | |
| 94 } | |
| OLD | NEW |