Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(248)

Side by Side Diff: core/src/fpdfdoc/doc_link.cpp

Issue 958423005: Handle overlapping links and widgets. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/src/fpdfdoc/doc_form.cpp ('k') | fpdfsdk/src/fpdfdoc.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "../../include/fpdfdoc/fpdf_doc.h" 7 #include "../../include/fpdfdoc/fpdf_doc.h"
8 #include "../../src/fxcrt/fx_safe_types.h" 8 #include "../../src/fxcrt/fx_safe_types.h"
9 9
10 CPDF_LinkList::CPDF_LinkList()
11 {
12 }
10 CPDF_LinkList::~CPDF_LinkList() 13 CPDF_LinkList::~CPDF_LinkList()
11 { 14 {
12 FX_POSITION pos = m_PageMap.GetStartPosition(); 15 FX_POSITION pos = m_PageMap.GetStartPosition();
13 while (pos) { 16 while (pos) {
14 FX_LPVOID key, value; 17 FX_LPVOID key, value;
15 m_PageMap.GetNextAssoc(pos, key, value); 18 m_PageMap.GetNextAssoc(pos, key, value);
16 delete (CFX_PtrArray*)value; 19 delete (CFX_PtrArray*)value;
17 } 20 }
18 } 21 }
19 CFX_PtrArray* CPDF_LinkList::GetPageLinks(CPDF_Page* pPage) 22 CFX_PtrArray* CPDF_LinkList::GetPageLinks(CPDF_Page* pPage)
20 { 23 {
21 FX_DWORD objnum = pPage->m_pFormDict->GetObjNum(); 24 FX_DWORD objnum = pPage->m_pFormDict->GetObjNum();
22 if (objnum == 0) { 25 if (objnum == 0) {
23 return NULL; 26 return NULL;
24 } 27 }
25 CFX_PtrArray* pPageLinkList = NULL; 28 CFX_PtrArray* pPageLinkList = NULL;
26 if (!m_PageMap.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, (FX_LPVOID&)pPageLinkLi st)) { 29 if (!m_PageMap.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, (FX_LPVOID&)pPageLinkLi st)) {
27 pPageLinkList = FX_NEW CFX_PtrArray; 30 pPageLinkList = FX_NEW CFX_PtrArray;
28 if (pPageLinkList == NULL) { 31 if (pPageLinkList == NULL) {
29 return NULL; 32 return NULL;
30 } 33 }
31 m_PageMap.SetAt((FX_LPVOID)(FX_UINTPTR)objnum, pPageLinkList); 34 m_PageMap.SetAt((FX_LPVOID)(FX_UINTPTR)objnum, pPageLinkList);
32 LoadPageLinks(pPage, pPageLinkList); 35 LoadPageLinks(pPage, pPageLinkList);
33 } 36 }
34 return pPageLinkList; 37 return pPageLinkList;
35 } 38 }
36 int CPDF_LinkList::CountLinks(CPDF_Page* pPage) 39 FX_BOOL CPDF_LinkList::IsLink(CPDF_Dictionary* pAnnot)
37 { 40 {
38 CFX_PtrArray* pPageLinkList = GetPageLinks(pPage); 41 return pAnnot->GetString("Subtype") == "Link";
39 if (pPageLinkList == NULL) {
40 return 0;
41 }
42 return pPageLinkList->GetSize();
43 } 42 }
44 CPDF_Link CPDF_LinkList::GetLink(CPDF_Page* pPage, int index) 43 FX_BOOL CPDF_LinkList::IsWidget(CPDF_Dictionary* pAnnot)
45 { 44 {
46 CFX_PtrArray* pPageLinkList = GetPageLinks(pPage); 45 return pAnnot->GetString("Subtype") == "Widget";
47 if (pPageLinkList == NULL) { 46 }
48 return NULL; 47 CPDF_Rect CPDF_LinkList::GetWidgetRect(CPDF_Dictionary* pWidget)
49 } 48 {
50 return (CPDF_Dictionary*)pPageLinkList->GetAt(index); 49 return pWidget->GetRect("Rect");
51 } 50 }
52 CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, FX_FLOAT pdf_x, FX_FLO AT pdf_y) 51 CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, FX_FLOAT pdf_x, FX_FLO AT pdf_y)
53 { 52 {
54 CFX_PtrArray* pPageLinkList = GetPageLinks(pPage); 53 CFX_PtrArray* pPageLinkList = GetPageLinks(pPage);
55 if (pPageLinkList == NULL) { 54 if (pPageLinkList == NULL) {
56 return NULL; 55 return NULL;
57 } 56 }
58 int size = pPageLinkList->GetSize(); 57 int size = pPageLinkList->GetSize();
59 for (int i = size - 1; i >= 0; --i) { 58 for (int i = size - 1; i >= 0; --i) {
60 CPDF_Link Link = (CPDF_Dictionary*)pPageLinkList->GetAt(i); 59 CPDF_Dictionary* pAnnot = (CPDF_Dictionary*)pPageLinkList->GetAt(i);
61 CPDF_Rect rect = Link.GetRect(); 60 if (IsLink(pAnnot)) {
62 if (rect.Contains(pdf_x, pdf_y)) { 61 CPDF_Link link(pAnnot);
63 return Link; 62 CPDF_Rect rect = link.GetRect();
63 if (rect.Contains(pdf_x, pdf_y)) {
64 return link;
65 }
66 } else if (IsWidget(pAnnot)) {
67 CPDF_Rect rect = GetWidgetRect(pAnnot);
68 if (rect.Contains(pdf_x, pdf_y)) {
69 return NULL;
70 }
64 } 71 }
65 } 72 }
66 return NULL; 73 return NULL;
67 } 74 }
68 void CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage, CFX_PtrArray* pList) 75 void CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage, CFX_PtrArray* pList)
69 { 76 {
70 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); 77 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
71 if (pAnnotList == NULL) { 78 if (pAnnotList == NULL) {
72 return; 79 return;
73 } 80 }
74 for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i ++) { 81 for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i ++) {
75 CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i); 82 CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i);
76 if (pAnnot == NULL) { 83 if (pAnnot == NULL) {
77 continue; 84 continue;
78 } 85 }
79 if (pAnnot->GetString("Subtype") != "Link") { 86 if (IsLink(pAnnot) || IsWidget(pAnnot)) {
80 continue; 87 pList->Add(pAnnot);
81 } 88 }
82 pList->Add(pAnnot);
83 } 89 }
84 } 90 }
85 CPDF_Rect CPDF_Link::GetRect() 91 CPDF_Rect CPDF_Link::GetRect()
86 { 92 {
87 return m_pDict->GetRect("Rect"); 93 return m_pDict->GetRect("Rect");
88 } 94 }
89 CPDF_Dest CPDF_Link::GetDest(CPDF_Document* pDoc) 95 CPDF_Dest CPDF_Link::GetDest(CPDF_Document* pDoc)
90 { 96 {
91 CPDF_Object* pDest = m_pDict->GetElementValue("Dest"); 97 CPDF_Object* pDest = m_pDict->GetElementValue("Dest");
92 if (pDest == NULL) { 98 if (pDest == NULL) {
93 return NULL; 99 return NULL;
94 } 100 }
95 if (pDest->GetType() == PDFOBJ_STRING || pDest->GetType() == PDFOBJ_NAME) { 101 if (pDest->GetType() == PDFOBJ_STRING || pDest->GetType() == PDFOBJ_NAME) {
96 CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests")); 102 CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests"));
97 CFX_ByteStringC name = pDest->GetString(); 103 CFX_ByteStringC name = pDest->GetString();
98 return name_tree.LookupNamedDest(pDoc, name); 104 return name_tree.LookupNamedDest(pDoc, name);
99 } else if (pDest->GetType() == PDFOBJ_ARRAY) { 105 } else if (pDest->GetType() == PDFOBJ_ARRAY) {
100 return (CPDF_Array*)pDest; 106 return (CPDF_Array*)pDest;
101 } 107 }
102 return NULL; 108 return NULL;
103 } 109 }
104 CPDF_Action CPDF_Link::GetAction() 110 CPDF_Action CPDF_Link::GetAction()
105 { 111 {
106 return m_pDict->GetDict("A"); 112 return m_pDict->GetDict("A");
107 } 113 }
OLDNEW
« no previous file with comments | « core/src/fpdfdoc/doc_form.cpp ('k') | fpdfsdk/src/fpdfdoc.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698