| OLD | NEW | 
|   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  |   8  | 
 |   9 CPDF_LinkList::CPDF_LinkList() { | 
 |  10 } | 
 |  11  | 
|   9 CPDF_LinkList::~CPDF_LinkList() { |  12 CPDF_LinkList::~CPDF_LinkList() { | 
|  10   FX_POSITION pos = m_PageMap.GetStartPosition(); |  | 
|  11   while (pos) { |  | 
|  12     void* key; |  | 
|  13     void* value; |  | 
|  14     m_PageMap.GetNextAssoc(pos, key, value); |  | 
|  15     delete (CFX_PtrArray*)value; |  | 
|  16   } |  | 
|  17 } |  13 } | 
|  18 CFX_PtrArray* CPDF_LinkList::GetPageLinks(CPDF_Page* pPage) { |  14  | 
 |  15 const std::vector<CPDF_Dictionary*>* CPDF_LinkList::GetPageLinks( | 
 |  16     CPDF_Page* pPage) { | 
|  19   FX_DWORD objnum = pPage->m_pFormDict->GetObjNum(); |  17   FX_DWORD objnum = pPage->m_pFormDict->GetObjNum(); | 
|  20   if (objnum == 0) { |  18   if (objnum == 0) | 
|  21     return NULL; |  19     return nullptr; | 
|  22   } |  20  | 
|  23   CFX_PtrArray* pPageLinkList = NULL; |  21   auto it = m_PageMap.find(objnum); | 
|  24   if (!m_PageMap.Lookup((void*)(uintptr_t)objnum, (void*&)pPageLinkList)) { |  22   if (it != m_PageMap.end()) | 
|  25     pPageLinkList = new CFX_PtrArray; |  23     return &it->second; | 
|  26     m_PageMap.SetAt((void*)(uintptr_t)objnum, pPageLinkList); |  24  | 
|  27     LoadPageLinks(pPage, pPageLinkList); |  25   // std::map::operator[] forces the creation of a map entry. | 
|  28   } |  26   std::vector<CPDF_Dictionary*>& page_link_list = m_PageMap[objnum]; | 
|  29   return pPageLinkList; |  27   LoadPageLinks(pPage, &page_link_list); | 
 |  28   return &page_link_list; | 
|  30 } |  29 } | 
|  31 int CPDF_LinkList::CountLinks(CPDF_Page* pPage) { |  30  | 
|  32   CFX_PtrArray* pPageLinkList = GetPageLinks(pPage); |  | 
|  33   if (pPageLinkList == NULL) { |  | 
|  34     return 0; |  | 
|  35   } |  | 
|  36   return pPageLinkList->GetSize(); |  | 
|  37 } |  | 
|  38 CPDF_Link CPDF_LinkList::GetLink(CPDF_Page* pPage, int index) { |  | 
|  39   CFX_PtrArray* pPageLinkList = GetPageLinks(pPage); |  | 
|  40   if (!pPageLinkList) { |  | 
|  41     return CPDF_Link(); |  | 
|  42   } |  | 
|  43   return CPDF_Link((CPDF_Dictionary*)pPageLinkList->GetAt(index)); |  | 
|  44 } |  | 
|  45 CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, |  31 CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage, | 
|  46                                         FX_FLOAT pdf_x, |  32                                         FX_FLOAT pdf_x, | 
|  47                                         FX_FLOAT pdf_y) { |  33                                         FX_FLOAT pdf_y, | 
|  48   CFX_PtrArray* pPageLinkList = GetPageLinks(pPage); |  34                                         int* z_order) { | 
|  49   if (!pPageLinkList) { |  35   const std::vector<CPDF_Dictionary*>* pPageLinkList = GetPageLinks(pPage); | 
 |  36   if (!pPageLinkList) | 
|  50     return CPDF_Link(); |  37     return CPDF_Link(); | 
|  51   } |  38  | 
|  52   int size = pPageLinkList->GetSize(); |  39   for (size_t i = pPageLinkList->size(); i > 0; --i) { | 
|  53   for (int i = size - 1; i >= 0; --i) { |  40     size_t annot_index = i - 1; | 
|  54     CPDF_Link link((CPDF_Dictionary*)pPageLinkList->GetAt(i)); |  41     CPDF_Dictionary* pAnnot = (*pPageLinkList)[annot_index]; | 
 |  42     if (!pAnnot) | 
 |  43       continue; | 
 |  44  | 
 |  45     CPDF_Link link(pAnnot); | 
|  55     CPDF_Rect rect = link.GetRect(); |  46     CPDF_Rect rect = link.GetRect(); | 
|  56     if (rect.Contains(pdf_x, pdf_y)) { |  47     if (!rect.Contains(pdf_x, pdf_y)) | 
|  57       return link; |  48       continue; | 
|  58     } |  49  | 
 |  50     if (z_order) | 
 |  51       *z_order = annot_index; | 
 |  52     return link; | 
|  59   } |  53   } | 
|  60   return CPDF_Link(); |  54   return CPDF_Link(); | 
|  61 } |  55 } | 
|  62 void CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage, CFX_PtrArray* pList) { |  56  | 
 |  57 void CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage, | 
 |  58                                   std::vector<CPDF_Dictionary*>* pList) { | 
|  63   CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); |  59   CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); | 
|  64   if (pAnnotList == NULL) { |  60   if (!pAnnotList) | 
|  65     return; |  61     return; | 
|  66   } |  62  | 
|  67   for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i++) { |  63   for (FX_DWORD i = 0; i < pAnnotList->GetCount(); ++i) { | 
|  68     CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i); |  64     CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i); | 
|  69     if (pAnnot == NULL) { |  65     bool add_link = (pAnnot && pAnnot->GetString("Subtype") == "Link"); | 
|  70       continue; |  66     // Add non-links as nullptrs to preserve z-order. | 
|  71     } |  67     pList->push_back(add_link ? pAnnot : nullptr); | 
|  72     if (pAnnot->GetString("Subtype") != "Link") { |  | 
|  73       continue; |  | 
|  74     } |  | 
|  75     pList->Add(pAnnot); |  | 
|  76   } |  68   } | 
|  77 } |  69 } | 
 |  70  | 
|  78 CPDF_Rect CPDF_Link::GetRect() { |  71 CPDF_Rect CPDF_Link::GetRect() { | 
|  79   return m_pDict->GetRect("Rect"); |  72   return m_pDict->GetRect("Rect"); | 
|  80 } |  73 } | 
|  81 CPDF_Dest CPDF_Link::GetDest(CPDF_Document* pDoc) { |  74 CPDF_Dest CPDF_Link::GetDest(CPDF_Document* pDoc) { | 
|  82   CPDF_Object* pDest = m_pDict->GetElementValue("Dest"); |  75   CPDF_Object* pDest = m_pDict->GetElementValue("Dest"); | 
|  83   if (pDest == NULL) { |  76   if (pDest == NULL) { | 
|  84     return CPDF_Dest(); |  77     return CPDF_Dest(); | 
|  85   } |  78   } | 
|  86   if (pDest->GetType() == PDFOBJ_STRING || pDest->GetType() == PDFOBJ_NAME) { |  79   if (pDest->GetType() == PDFOBJ_STRING || pDest->GetType() == PDFOBJ_NAME) { | 
|  87     CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests")); |  80     CPDF_NameTree name_tree(pDoc, FX_BSTRC("Dests")); | 
|  88     CFX_ByteStringC name = pDest->GetString(); |  81     CFX_ByteStringC name = pDest->GetString(); | 
|  89     return CPDF_Dest(name_tree.LookupNamedDest(pDoc, name)); |  82     return CPDF_Dest(name_tree.LookupNamedDest(pDoc, name)); | 
|  90   } |  83   } | 
|  91   if (pDest->GetType() == PDFOBJ_ARRAY) { |  84   if (pDest->GetType() == PDFOBJ_ARRAY) { | 
|  92     return CPDF_Dest((CPDF_Array*)pDest); |  85     return CPDF_Dest((CPDF_Array*)pDest); | 
|  93   } |  86   } | 
|  94   return CPDF_Dest(); |  87   return CPDF_Dest(); | 
|  95 } |  88 } | 
|  96 CPDF_Action CPDF_Link::GetAction() { |  89 CPDF_Action CPDF_Link::GetAction() { | 
|  97   return CPDF_Action(m_pDict->GetDict("A")); |  90   return CPDF_Action(m_pDict->GetDict("A")); | 
|  98 } |  91 } | 
| OLD | NEW |