1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved. 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file. 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/fpdfdoc/fpdf_doc.h" 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_LinkList::~CPDF_LinkList() 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_POSITION pos = m_PageMap.GetStartPosition(); 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while (pos) { 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_LPVOID key, value; 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_PageMap.GetNextAssoc(pos, key, value); 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delete (CFX_PtrArray*)value; 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_PtrArray* CPDF_LinkList::GetPageLinks(CPDF_Page* pPage) 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_DWORD objnum = pPage->m_pFormDict->GetObjNum(); 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (objnum == 0) { 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_PtrArray* pPageLinkList = NULL; 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (!m_PageMap.Lookup((FX_LPVOID)(FX_UINTPTR)objnum, (FX_LPVOID&)pPageLinkList)) { 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pPageLinkList = FX_NEW CFX_PtrArray; 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pPageLinkList == NULL) { 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_PageMap.SetAt((FX_LPVOID)(FX_UINTPTR)objnum, pPageLinkList); 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov LoadPageLinks(pPage, pPageLinkList); 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pPageLinkList; 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_LinkList::CountLinks(CPDF_Page* pPage) 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_PtrArray* pPageLinkList = GetPageLinks(pPage); 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pPageLinkList == NULL) { 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return pPageLinkList->GetSize(); 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Link CPDF_LinkList::GetLink(CPDF_Page* pPage, int index) 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_PtrArray* pPageLinkList = GetPageLinks(pPage); 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pPageLinkList == NULL) { 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (CPDF_Dictionary*)pPageLinkList->GetAt(index); 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, FX_FLOAT pdf_x, FX_FLOAT pdf_y) 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_PtrArray* pPageLinkList = GetPageLinks(pPage); 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pPageLinkList == NULL) { 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int size = pPageLinkList->GetSize(); 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (int i = 0; i < size; i ++) { 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Link Link = (CPDF_Dictionary*)pPageLinkList->GetAt(i); 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Rect rect = Link.GetRect(); 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (rect.Contains(pdf_x, pdf_y)) { 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Link; 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage, CFX_PtrArray* pList) 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pAnnotList == NULL) { 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i ++) { 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i); 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pAnnot == NULL) { 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pAnnot->GetString("Subtype") != "Link") { 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pList->Add(pAnnot); 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Rect CPDF_Link::GetRect() 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return m_pDict->GetRect("Rect"); 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Dest CPDF_Link::GetDest(CPDF_Document* pDoc) 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_Object* pDest = m_pDict->GetElementValue("Dest"); 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pDest == NULL) { 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if (pDest->GetType() == PDFOBJ_STRING || pDest->GetType() == PDFOBJ_NAME) { 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests")); 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov CFX_ByteStringC name = pDest->GetString(); 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return name_tree.LookupNamedDest(pDoc, name); 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else if (pDest->GetType() == PDFOBJ_ARRAY) { 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (CPDF_Array*)pDest; 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return NULL; 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Action CPDF_Link::GetAction() 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return m_pDict->GetDict("A"); 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 106