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 |