14d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Copyright 2016 PDFium Authors. All rights reserved. 24d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Use of this source code is governed by a BSD-style license that can be 34d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// found in the LICENSE file. 44d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 54d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 64d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 74d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "fpdfsdk/cba_annotiterator.h" 84d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 94d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include <algorithm> 104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fpdfapi/page/cpdf_page.h" 124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "fpdfsdk/cpdfsdk_annot.h" 134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "fpdfsdk/cpdfsdk_pageview.h" 144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannnamespace { 164d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFX_FloatRect GetAnnotRect(const CPDFSDK_Annot* pAnnot) { 184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return pAnnot->GetPDFAnnot()->GetRect(); 194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CompareByLeftAscending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) { 224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return GetAnnotRect(p1).left < GetAnnotRect(p2).left; 234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannbool CompareByTopDescending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) { 264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return GetAnnotRect(p1).top > GetAnnotRect(p2).top; 274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} // namespace 304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, 324d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CPDF_Annot::Subtype nAnnotSubtype) 334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann : m_eTabOrder(STRUCTURE), 344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_pPageView(pPageView), 354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_nAnnotSubtype(nAnnotSubtype) { 364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CPDF_Page* pPDFPage = m_pPageView->GetPDFPage(); 37d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann ByteString sTabs = pPDFPage->m_pFormDict->GetStringFor("Tabs"); 384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (sTabs == "R") 394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_eTabOrder = ROW; 404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann else if (sTabs == "C") 414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_eTabOrder = COLUMN; 424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann GenerateResults(); 444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCBA_AnnotIterator::~CBA_AnnotIterator() {} 474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 484d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() { 494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return m_Annots.empty() ? nullptr : m_Annots.front(); 504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() { 534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return m_Annots.empty() ? nullptr : m_Annots.back(); 544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) { 574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); 584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (iter == m_Annots.end()) 594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann ++iter; 614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (iter == m_Annots.end()) 624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann iter = m_Annots.begin(); 634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return *iter; 644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) { 674d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); 684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (iter == m_Annots.end()) 694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return nullptr; 704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (iter == m_Annots.begin()) 714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann iter = m_Annots.end(); 724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return *(--iter); 734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBA_AnnotIterator::CollectAnnots(std::vector<CPDFSDK_Annot*>* pArray) { 76d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann for (auto* pAnnot : m_pPageView->GetAnnotList()) { 774d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (pAnnot->GetAnnotSubtype() == m_nAnnotSubtype && 784d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann !pAnnot->IsSignatureWidget()) { 794d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann pArray->push_back(pAnnot); 804d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 814d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 824d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 834d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 844d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. MoltmannCFX_FloatRect CBA_AnnotIterator::AddToAnnotsList( 854d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<CPDFSDK_Annot*>* sa, 864d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann size_t idx) { 874d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CPDFSDK_Annot* pLeftTopAnnot = sa->at(idx); 884d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot); 894d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_Annots.push_back(pLeftTopAnnot); 904d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sa->erase(sa->begin() + idx); 914d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann return rcLeftTop; 924d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 934d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 944d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBA_AnnotIterator::AddSelectedToAnnots(std::vector<CPDFSDK_Annot*>* sa, 954d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<size_t>* aSelect) { 964d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (size_t i = 0; i < aSelect->size(); ++i) 974d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann m_Annots.push_back(sa->at(aSelect->at(i))); 984d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 994d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int i = aSelect->size() - 1; i >= 0; --i) 1004d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann sa->erase(sa->begin() + aSelect->at(i)); 1014d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 1024d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1034d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmannvoid CBA_AnnotIterator::GenerateResults() { 1044d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann switch (m_eTabOrder) { 1054d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case STRUCTURE: 1064d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CollectAnnots(&m_Annots); 1074d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 1084d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1094d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case ROW: { 1104d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<CPDFSDK_Annot*> sa; 1114d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CollectAnnots(&sa); 1124d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::sort(sa.begin(), sa.end(), CompareByLeftAscending); 1134d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1144d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (!sa.empty()) { 1154d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int nLeftTopIndex = -1; 116d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float fTop = 0.0f; 1174d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int i = sa.size() - 1; i >= 0; i--) { 1184d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); 1194d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (rcAnnot.top > fTop) { 1204d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann nLeftTopIndex = i; 1214d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann fTop = rcAnnot.top; 1224d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1244d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (nLeftTopIndex < 0) 1254d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann continue; 1264d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1274d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex); 1284d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1294d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<size_t> aSelect; 1304d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (size_t i = 0; i < sa.size(); ++i) { 1314d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); 132d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f; 1334d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top) 1344d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann aSelect.push_back(i); 1354d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1364d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann AddSelectedToAnnots(&sa, &aSelect); 1374d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1384d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 1394d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1404d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1414d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann case COLUMN: { 1424d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<CPDFSDK_Annot*> sa; 1434d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CollectAnnots(&sa); 1444d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::sort(sa.begin(), sa.end(), CompareByTopDescending); 1454d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1464d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann while (!sa.empty()) { 1474d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann int nLeftTopIndex = -1; 148d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float fLeft = -1.0f; 1494d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (int i = sa.size() - 1; i >= 0; --i) { 1504d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); 1514d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (fLeft < 0) { 1524d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann nLeftTopIndex = 0; 1534d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann fLeft = rcAnnot.left; 1544d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } else if (rcAnnot.left < fLeft) { 1554d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann nLeftTopIndex = i; 1564d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann fLeft = rcAnnot.left; 1574d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1584d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1594d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (nLeftTopIndex < 0) 1604d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann continue; 1614d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1624d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex); 1634d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann 1644d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann std::vector<size_t> aSelect; 1654d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann for (size_t i = 0; i < sa.size(); ++i) { 1664d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); 167d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann float fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f; 1684d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right) 1694d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann aSelect.push_back(i); 1704d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1714d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann AddSelectedToAnnots(&sa, &aSelect); 1724d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1734d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann break; 1744d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1754d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann } 1764d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann} 177