| Index: core/src/fpdfdoc/doc_link.cpp
 | 
| diff --git a/core/src/fpdfdoc/doc_link.cpp b/core/src/fpdfdoc/doc_link.cpp
 | 
| index 15bd14c31e8724120702df2e05dffd52751421a6..fbf18f99e5cd7791b87ec65205cd3d2618f89fef 100644
 | 
| --- a/core/src/fpdfdoc/doc_link.cpp
 | 
| +++ b/core/src/fpdfdoc/doc_link.cpp
 | 
| @@ -6,75 +6,68 @@
 | 
|  
 | 
|  #include "../../include/fpdfdoc/fpdf_doc.h"
 | 
|  
 | 
| +CPDF_LinkList::CPDF_LinkList() {
 | 
| +}
 | 
| +
 | 
|  CPDF_LinkList::~CPDF_LinkList() {
 | 
| -  FX_POSITION pos = m_PageMap.GetStartPosition();
 | 
| -  while (pos) {
 | 
| -    void* key;
 | 
| -    void* value;
 | 
| -    m_PageMap.GetNextAssoc(pos, key, value);
 | 
| -    delete (CFX_PtrArray*)value;
 | 
| -  }
 | 
|  }
 | 
| -CFX_PtrArray* CPDF_LinkList::GetPageLinks(CPDF_Page* pPage) {
 | 
| +
 | 
| +const std::vector<CPDF_Dictionary*>* CPDF_LinkList::GetPageLinks(
 | 
| +    CPDF_Page* pPage) {
 | 
|    FX_DWORD objnum = pPage->m_pFormDict->GetObjNum();
 | 
| -  if (objnum == 0) {
 | 
| -    return NULL;
 | 
| -  }
 | 
| -  CFX_PtrArray* pPageLinkList = NULL;
 | 
| -  if (!m_PageMap.Lookup((void*)(uintptr_t)objnum, (void*&)pPageLinkList)) {
 | 
| -    pPageLinkList = new CFX_PtrArray;
 | 
| -    m_PageMap.SetAt((void*)(uintptr_t)objnum, pPageLinkList);
 | 
| -    LoadPageLinks(pPage, pPageLinkList);
 | 
| -  }
 | 
| -  return pPageLinkList;
 | 
| -}
 | 
| -int CPDF_LinkList::CountLinks(CPDF_Page* pPage) {
 | 
| -  CFX_PtrArray* pPageLinkList = GetPageLinks(pPage);
 | 
| -  if (pPageLinkList == NULL) {
 | 
| -    return 0;
 | 
| -  }
 | 
| -  return pPageLinkList->GetSize();
 | 
| -}
 | 
| -CPDF_Link CPDF_LinkList::GetLink(CPDF_Page* pPage, int index) {
 | 
| -  CFX_PtrArray* pPageLinkList = GetPageLinks(pPage);
 | 
| -  if (!pPageLinkList) {
 | 
| -    return CPDF_Link();
 | 
| -  }
 | 
| -  return CPDF_Link((CPDF_Dictionary*)pPageLinkList->GetAt(index));
 | 
| +  if (objnum == 0)
 | 
| +    return nullptr;
 | 
| +
 | 
| +  auto it = m_PageMap.find(objnum);
 | 
| +  if (it != m_PageMap.end())
 | 
| +    return &it->second;
 | 
| +
 | 
| +  // std::map::operator[] forces the creation of a map entry.
 | 
| +  std::vector<CPDF_Dictionary*>& page_link_list = m_PageMap[objnum];
 | 
| +  LoadPageLinks(pPage, &page_link_list);
 | 
| +  return &page_link_list;
 | 
|  }
 | 
| +
 | 
|  CPDF_Link CPDF_LinkList::GetLinkAtPoint(CPDF_Page* pPage,
 | 
|                                          FX_FLOAT pdf_x,
 | 
| -                                        FX_FLOAT pdf_y) {
 | 
| -  CFX_PtrArray* pPageLinkList = GetPageLinks(pPage);
 | 
| -  if (!pPageLinkList) {
 | 
| +                                        FX_FLOAT pdf_y,
 | 
| +                                        int* z_order) {
 | 
| +  const std::vector<CPDF_Dictionary*>* pPageLinkList = GetPageLinks(pPage);
 | 
| +  if (!pPageLinkList)
 | 
|      return CPDF_Link();
 | 
| -  }
 | 
| -  int size = pPageLinkList->GetSize();
 | 
| -  for (int i = size - 1; i >= 0; --i) {
 | 
| -    CPDF_Link link((CPDF_Dictionary*)pPageLinkList->GetAt(i));
 | 
| +
 | 
| +  for (size_t i = pPageLinkList->size(); i > 0; --i) {
 | 
| +    size_t annot_index = i - 1;
 | 
| +    CPDF_Dictionary* pAnnot = (*pPageLinkList)[annot_index];
 | 
| +    if (!pAnnot)
 | 
| +      continue;
 | 
| +
 | 
| +    CPDF_Link link(pAnnot);
 | 
|      CPDF_Rect rect = link.GetRect();
 | 
| -    if (rect.Contains(pdf_x, pdf_y)) {
 | 
| -      return link;
 | 
| -    }
 | 
| +    if (!rect.Contains(pdf_x, pdf_y))
 | 
| +      continue;
 | 
| +
 | 
| +    if (z_order)
 | 
| +      *z_order = annot_index;
 | 
| +    return link;
 | 
|    }
 | 
|    return CPDF_Link();
 | 
|  }
 | 
| -void CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage, CFX_PtrArray* pList) {
 | 
| +
 | 
| +void CPDF_LinkList::LoadPageLinks(CPDF_Page* pPage,
 | 
| +                                  std::vector<CPDF_Dictionary*>* pList) {
 | 
|    CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
 | 
| -  if (pAnnotList == NULL) {
 | 
| +  if (!pAnnotList)
 | 
|      return;
 | 
| -  }
 | 
| -  for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i++) {
 | 
| +
 | 
| +  for (FX_DWORD i = 0; i < pAnnotList->GetCount(); ++i) {
 | 
|      CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i);
 | 
| -    if (pAnnot == NULL) {
 | 
| -      continue;
 | 
| -    }
 | 
| -    if (pAnnot->GetString("Subtype") != "Link") {
 | 
| -      continue;
 | 
| -    }
 | 
| -    pList->Add(pAnnot);
 | 
| +    bool add_link = (pAnnot && pAnnot->GetString("Subtype") == "Link");
 | 
| +    // Add non-links as nullptrs to preserve z-order.
 | 
| +    pList->push_back(add_link ? pAnnot : nullptr);
 | 
|    }
 | 
|  }
 | 
| +
 | 
|  CPDF_Rect CPDF_Link::GetRect() {
 | 
|    return m_pDict->GetRect("Rect");
 | 
|  }
 | 
| 
 |