From cbf76e656042e3d9778ccc114983ab6a3c19ff92 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Wed, 28 Mar 2018 21:00:35 +0000 Subject: Rename CBA_AnnotIterator to CPDFSDK_AnnotIterator This CL renames CBA_AnnotIterator to CPDFSDK_AnnotIterator. This iterator does not seem to be restricted to just BAAnnot entries, so rename to the more general name. Change-Id: I735dc37cd5417a2b544882db515dbef4d4dbae67 Reviewed-on: https://pdfium-review.googlesource.com/29430 Commit-Queue: dsinclair Reviewed-by: Henrique Nakashima --- BUILD.gn | 6 +- fpdfsdk/cba_annotiterator.cpp | 176 ------------------------- fpdfsdk/cba_annotiterator.h | 46 ------- fpdfsdk/cba_annotiterator_embeddertest.cpp | 126 ------------------ fpdfsdk/cpdfsdk_annothandlermgr.cpp | 9 +- fpdfsdk/cpdfsdk_annotiterator.cpp | 176 +++++++++++++++++++++++++ fpdfsdk/cpdfsdk_annotiterator.h | 46 +++++++ fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp | 126 ++++++++++++++++++ fpdfsdk/cpdfsdk_interform.cpp | 4 +- fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp | 6 +- fpdfsdk/pwl/cpwl_edit_embeddertest.cpp | 6 +- 11 files changed, 364 insertions(+), 363 deletions(-) delete mode 100644 fpdfsdk/cba_annotiterator.cpp delete mode 100644 fpdfsdk/cba_annotiterator.h delete mode 100644 fpdfsdk/cba_annotiterator_embeddertest.cpp create mode 100644 fpdfsdk/cpdfsdk_annotiterator.cpp create mode 100644 fpdfsdk/cpdfsdk_annotiterator.h create mode 100644 fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp diff --git a/BUILD.gn b/BUILD.gn index c6aee5c645..1cb7046c25 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -103,8 +103,6 @@ config("xfa_warnings") { jumbo_static_library("pdfium") { sources = [ - "fpdfsdk/cba_annotiterator.cpp", - "fpdfsdk/cba_annotiterator.h", "fpdfsdk/cfx_systemhandler.cpp", "fpdfsdk/cfx_systemhandler.h", "fpdfsdk/cpdfsdk_actionhandler.cpp", @@ -115,6 +113,8 @@ jumbo_static_library("pdfium") { "fpdfsdk/cpdfsdk_annothandlermgr.h", "fpdfsdk/cpdfsdk_annotiteration.cpp", "fpdfsdk/cpdfsdk_annotiteration.h", + "fpdfsdk/cpdfsdk_annotiterator.cpp", + "fpdfsdk/cpdfsdk_annotiterator.h", "fpdfsdk/cpdfsdk_baannot.cpp", "fpdfsdk/cpdfsdk_baannot.h", "fpdfsdk/cpdfsdk_baannothandler.cpp", @@ -2989,7 +2989,7 @@ test("pdfium_embeddertests") { "core/fpdfapi/render/fpdf_render_pattern_embeddertest.cpp", "core/fxcodec/codec/fx_codec_embeddertest.cpp", "core/fxge/fx_ge_text_embeddertest.cpp", - "fpdfsdk/cba_annotiterator_embeddertest.cpp", + "fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp", "fpdfsdk/fpdf_annot_embeddertest.cpp", "fpdfsdk/fpdf_attachment_embeddertest.cpp", "fpdfsdk/fpdf_dataavail_embeddertest.cpp", diff --git a/fpdfsdk/cba_annotiterator.cpp b/fpdfsdk/cba_annotiterator.cpp deleted file mode 100644 index d1c9599cf6..0000000000 --- a/fpdfsdk/cba_annotiterator.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include "fpdfsdk/cba_annotiterator.h" - -#include - -#include "core/fpdfapi/page/cpdf_page.h" -#include "fpdfsdk/cpdfsdk_annot.h" -#include "fpdfsdk/cpdfsdk_pageview.h" - -namespace { - -CFX_FloatRect GetAnnotRect(const CPDFSDK_Annot* pAnnot) { - return pAnnot->GetPDFAnnot()->GetRect(); -} - -bool CompareByLeftAscending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) { - return GetAnnotRect(p1).left < GetAnnotRect(p2).left; -} - -bool CompareByTopDescending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) { - return GetAnnotRect(p1).top > GetAnnotRect(p2).top; -} - -} // namespace - -CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, - CPDF_Annot::Subtype nAnnotSubtype) - : m_eTabOrder(STRUCTURE), - m_pPageView(pPageView), - m_nAnnotSubtype(nAnnotSubtype) { - CPDF_Page* pPDFPage = m_pPageView->GetPDFPage(); - ByteString sTabs = pPDFPage->m_pFormDict->GetStringFor("Tabs"); - if (sTabs == "R") - m_eTabOrder = ROW; - else if (sTabs == "C") - m_eTabOrder = COLUMN; - - GenerateResults(); -} - -CBA_AnnotIterator::~CBA_AnnotIterator() {} - -CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() { - return m_Annots.empty() ? nullptr : m_Annots.front(); -} - -CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() { - return m_Annots.empty() ? nullptr : m_Annots.back(); -} - -CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) { - auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); - if (iter == m_Annots.end()) - return nullptr; - ++iter; - if (iter == m_Annots.end()) - iter = m_Annots.begin(); - return *iter; -} - -CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) { - auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); - if (iter == m_Annots.end()) - return nullptr; - if (iter == m_Annots.begin()) - iter = m_Annots.end(); - return *(--iter); -} - -void CBA_AnnotIterator::CollectAnnots(std::vector* pArray) { - for (auto* pAnnot : m_pPageView->GetAnnotList()) { - if (pAnnot->GetAnnotSubtype() == m_nAnnotSubtype && - !pAnnot->IsSignatureWidget()) { - pArray->push_back(pAnnot); - } - } -} - -CFX_FloatRect CBA_AnnotIterator::AddToAnnotsList( - std::vector* sa, - size_t idx) { - CPDFSDK_Annot* pLeftTopAnnot = sa->at(idx); - CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot); - m_Annots.push_back(pLeftTopAnnot); - sa->erase(sa->begin() + idx); - return rcLeftTop; -} - -void CBA_AnnotIterator::AddSelectedToAnnots(std::vector* sa, - std::vector* aSelect) { - for (size_t i = 0; i < aSelect->size(); ++i) - m_Annots.push_back(sa->at(aSelect->at(i))); - - for (int i = aSelect->size() - 1; i >= 0; --i) - sa->erase(sa->begin() + aSelect->at(i)); -} - -void CBA_AnnotIterator::GenerateResults() { - switch (m_eTabOrder) { - case STRUCTURE: - CollectAnnots(&m_Annots); - break; - - case ROW: { - std::vector sa; - CollectAnnots(&sa); - std::sort(sa.begin(), sa.end(), CompareByLeftAscending); - - while (!sa.empty()) { - int nLeftTopIndex = -1; - float fTop = 0.0f; - for (int i = sa.size() - 1; i >= 0; i--) { - CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); - if (rcAnnot.top > fTop) { - nLeftTopIndex = i; - fTop = rcAnnot.top; - } - } - if (nLeftTopIndex < 0) - continue; - - CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex); - - std::vector aSelect; - for (size_t i = 0; i < sa.size(); ++i) { - CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); - float fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f; - if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top) - aSelect.push_back(i); - } - AddSelectedToAnnots(&sa, &aSelect); - } - break; - } - - case COLUMN: { - std::vector sa; - CollectAnnots(&sa); - std::sort(sa.begin(), sa.end(), CompareByTopDescending); - - while (!sa.empty()) { - int nLeftTopIndex = -1; - float fLeft = -1.0f; - for (int i = sa.size() - 1; i >= 0; --i) { - CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); - if (fLeft < 0) { - nLeftTopIndex = 0; - fLeft = rcAnnot.left; - } else if (rcAnnot.left < fLeft) { - nLeftTopIndex = i; - fLeft = rcAnnot.left; - } - } - if (nLeftTopIndex < 0) - continue; - - CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex); - - std::vector aSelect; - for (size_t i = 0; i < sa.size(); ++i) { - CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); - float fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f; - if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right) - aSelect.push_back(i); - } - AddSelectedToAnnots(&sa, &aSelect); - } - break; - } - } -} diff --git a/fpdfsdk/cba_annotiterator.h b/fpdfsdk/cba_annotiterator.h deleted file mode 100644 index 8f9768d1e2..0000000000 --- a/fpdfsdk/cba_annotiterator.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#ifndef FPDFSDK_CBA_ANNOTITERATOR_H_ -#define FPDFSDK_CBA_ANNOTITERATOR_H_ - -#include - -#include "core/fpdfdoc/cpdf_annot.h" -#include "core/fxcrt/fx_coordinates.h" -#include "core/fxcrt/fx_string.h" -#include "core/fxcrt/unowned_ptr.h" - -class CPDFSDK_Annot; -class CPDFSDK_PageView; - -class CBA_AnnotIterator { - public: - enum TabOrder { STRUCTURE = 0, ROW, COLUMN }; - - CBA_AnnotIterator(CPDFSDK_PageView* pPageView, - CPDF_Annot::Subtype nAnnotSubtype); - ~CBA_AnnotIterator(); - - CPDFSDK_Annot* GetFirstAnnot(); - CPDFSDK_Annot* GetLastAnnot(); - CPDFSDK_Annot* GetNextAnnot(CPDFSDK_Annot* pAnnot); - CPDFSDK_Annot* GetPrevAnnot(CPDFSDK_Annot* pAnnot); - - private: - void GenerateResults(); - void CollectAnnots(std::vector* pArray); - CFX_FloatRect AddToAnnotsList(std::vector* sa, size_t idx); - void AddSelectedToAnnots(std::vector* sa, - std::vector* aSelect); - - TabOrder m_eTabOrder; - UnownedPtr m_pPageView; - CPDF_Annot::Subtype m_nAnnotSubtype; - std::vector m_Annots; -}; - -#endif // FPDFSDK_CBA_ANNOTITERATOR_H_ diff --git a/fpdfsdk/cba_annotiterator_embeddertest.cpp b/fpdfsdk/cba_annotiterator_embeddertest.cpp deleted file mode 100644 index 6198ee1eb4..0000000000 --- a/fpdfsdk/cba_annotiterator_embeddertest.cpp +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "fpdfsdk/cba_annotiterator.h" -#include "fpdfsdk/cpdfsdk_annot.h" -#include "fpdfsdk/cpdfsdk_formfillenvironment.h" -#include "fpdfsdk/cpdfsdk_helpers.h" -#include "testing/embedder_test.h" -#include "testing/embedder_test_mock_delegate.h" -#include "testing/embedder_test_timer_handling_delegate.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -void CheckRect(const CFX_FloatRect& actual, const CFX_FloatRect& expected) { - EXPECT_EQ(expected.left, actual.left); - EXPECT_EQ(expected.bottom, actual.bottom); - EXPECT_EQ(expected.right, actual.right); - EXPECT_EQ(expected.top, actual.top); -} - -} // namespace - -class CBA_AnnotIteratorTest : public EmbedderTest {}; - -TEST_F(CBA_AnnotIteratorTest, CBA_AnnotIterator) { - EXPECT_TRUE(OpenDocument("annotiter.pdf")); - FPDF_PAGE page0 = LoadPage(0); - FPDF_PAGE page1 = LoadPage(1); - FPDF_PAGE page2 = LoadPage(2); - ASSERT_TRUE(page0); - ASSERT_TRUE(page1); - ASSERT_TRUE(page2); - - CFX_FloatRect LeftBottom(200, 200, 220, 220); - CFX_FloatRect RightBottom(400, 201, 420, 221); - CFX_FloatRect LeftTop(201, 400, 221, 420); - CFX_FloatRect RightTop(401, 401, 421, 421); - - CPDFSDK_FormFillEnvironment* pFormFillEnv = - static_cast(form_handle()); - - { - // Page 0 specifies "row order". - CBA_AnnotIterator iter(pFormFillEnv->GetPageView(0), - CPDF_Annot::Subtype::WIDGET); - CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot(); - CheckRect(pAnnot->GetRect(), RightTop); - pAnnot = iter.GetNextAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), LeftTop); - pAnnot = iter.GetNextAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), RightBottom); - pAnnot = iter.GetNextAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), LeftBottom); - pAnnot = iter.GetNextAnnot(pAnnot); - EXPECT_EQ(iter.GetFirstAnnot(), pAnnot); - - pAnnot = iter.GetLastAnnot(); - CheckRect(pAnnot->GetRect(), LeftBottom); - pAnnot = iter.GetPrevAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), RightBottom); - pAnnot = iter.GetPrevAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), LeftTop); - pAnnot = iter.GetPrevAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), RightTop); - pAnnot = iter.GetPrevAnnot(pAnnot); - EXPECT_EQ(iter.GetLastAnnot(), pAnnot); - } - { - // Page 1 specifies "column order" - CBA_AnnotIterator iter(pFormFillEnv->GetPageView(1), - CPDF_Annot::Subtype::WIDGET); - CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot(); - CheckRect(pAnnot->GetRect(), RightTop); - pAnnot = iter.GetNextAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), RightBottom); - pAnnot = iter.GetNextAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), LeftTop); - pAnnot = iter.GetNextAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), LeftBottom); - pAnnot = iter.GetNextAnnot(pAnnot); - EXPECT_EQ(iter.GetFirstAnnot(), pAnnot); - - pAnnot = iter.GetLastAnnot(); - CheckRect(pAnnot->GetRect(), LeftBottom); - pAnnot = iter.GetPrevAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), LeftTop); - pAnnot = iter.GetPrevAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), RightBottom); - pAnnot = iter.GetPrevAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), RightTop); - pAnnot = iter.GetPrevAnnot(pAnnot); - EXPECT_EQ(iter.GetLastAnnot(), pAnnot); - } - { - // Page 2 specifies "struct order" - CBA_AnnotIterator iter(pFormFillEnv->GetPageView(2), - CPDF_Annot::Subtype::WIDGET); - CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot(); - CheckRect(pAnnot->GetRect(), LeftBottom); - pAnnot = iter.GetNextAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), RightTop); - pAnnot = iter.GetNextAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), LeftTop); - pAnnot = iter.GetNextAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), RightBottom); - pAnnot = iter.GetNextAnnot(pAnnot); - EXPECT_EQ(iter.GetFirstAnnot(), pAnnot); - - pAnnot = iter.GetLastAnnot(); - CheckRect(pAnnot->GetRect(), RightBottom); - pAnnot = iter.GetPrevAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), LeftTop); - pAnnot = iter.GetPrevAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), RightTop); - pAnnot = iter.GetPrevAnnot(pAnnot); - CheckRect(pAnnot->GetRect(), LeftBottom); - pAnnot = iter.GetPrevAnnot(pAnnot); - EXPECT_EQ(iter.GetLastAnnot(), pAnnot); - } - UnloadPage(page2); - UnloadPage(page1); - UnloadPage(page0); -} diff --git a/fpdfsdk/cpdfsdk_annothandlermgr.cpp b/fpdfsdk/cpdfsdk_annothandlermgr.cpp index 2966b4d19b..e0405e84f9 100644 --- a/fpdfsdk/cpdfsdk_annothandlermgr.cpp +++ b/fpdfsdk/cpdfsdk_annothandlermgr.cpp @@ -9,8 +9,8 @@ #include "core/fpdfapi/parser/cpdf_number.h" #include "core/fpdfapi/parser/cpdf_string.h" #include "core/fpdfdoc/cpdf_annot.h" -#include "fpdfsdk/cba_annotiterator.h" #include "fpdfsdk/cpdfsdk_annot.h" +#include "fpdfsdk/cpdfsdk_annotiterator.h" #include "fpdfsdk/cpdfsdk_baannot.h" #include "fpdfsdk/cpdfsdk_baannothandler.h" #include "fpdfsdk/cpdfsdk_datetime.h" @@ -292,8 +292,8 @@ CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot, if (!pPage) return nullptr; if (pPage->GetPDFPage()) { // for pdf annots. - CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), - pSDKAnnot->GetAnnotSubtype()); + CPDFSDK_AnnotIterator ai(pSDKAnnot->GetPageView(), + pSDKAnnot->GetAnnotSubtype()); CPDFSDK_Annot* pNext = bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot); return pNext; @@ -315,7 +315,8 @@ CPDFSDK_Annot* CPDFSDK_AnnotHandlerMgr::GetNextAnnot(CPDFSDK_Annot* pSDKAnnot, return pPageView->GetAnnotByXFAWidget(hNextFocus); #else // PDF_ENABLE_XFA - CBA_AnnotIterator ai(pSDKAnnot->GetPageView(), CPDF_Annot::Subtype::WIDGET); + CPDFSDK_AnnotIterator ai(pSDKAnnot->GetPageView(), + CPDF_Annot::Subtype::WIDGET); return bNext ? ai.GetNextAnnot(pSDKAnnot) : ai.GetPrevAnnot(pSDKAnnot); #endif // PDF_ENABLE_XFA } diff --git a/fpdfsdk/cpdfsdk_annotiterator.cpp b/fpdfsdk/cpdfsdk_annotiterator.cpp new file mode 100644 index 0000000000..1c168454fe --- /dev/null +++ b/fpdfsdk/cpdfsdk_annotiterator.cpp @@ -0,0 +1,176 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "fpdfsdk/cpdfsdk_annotiterator.h" + +#include + +#include "core/fpdfapi/page/cpdf_page.h" +#include "fpdfsdk/cpdfsdk_annot.h" +#include "fpdfsdk/cpdfsdk_pageview.h" + +namespace { + +CFX_FloatRect GetAnnotRect(const CPDFSDK_Annot* pAnnot) { + return pAnnot->GetPDFAnnot()->GetRect(); +} + +bool CompareByLeftAscending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) { + return GetAnnotRect(p1).left < GetAnnotRect(p2).left; +} + +bool CompareByTopDescending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) { + return GetAnnotRect(p1).top > GetAnnotRect(p2).top; +} + +} // namespace + +CPDFSDK_AnnotIterator::CPDFSDK_AnnotIterator(CPDFSDK_PageView* pPageView, + CPDF_Annot::Subtype nAnnotSubtype) + : m_eTabOrder(STRUCTURE), + m_pPageView(pPageView), + m_nAnnotSubtype(nAnnotSubtype) { + CPDF_Page* pPDFPage = m_pPageView->GetPDFPage(); + ByteString sTabs = pPDFPage->m_pFormDict->GetStringFor("Tabs"); + if (sTabs == "R") + m_eTabOrder = ROW; + else if (sTabs == "C") + m_eTabOrder = COLUMN; + + GenerateResults(); +} + +CPDFSDK_AnnotIterator::~CPDFSDK_AnnotIterator() {} + +CPDFSDK_Annot* CPDFSDK_AnnotIterator::GetFirstAnnot() { + return m_Annots.empty() ? nullptr : m_Annots.front(); +} + +CPDFSDK_Annot* CPDFSDK_AnnotIterator::GetLastAnnot() { + return m_Annots.empty() ? nullptr : m_Annots.back(); +} + +CPDFSDK_Annot* CPDFSDK_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) { + auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); + if (iter == m_Annots.end()) + return nullptr; + ++iter; + if (iter == m_Annots.end()) + iter = m_Annots.begin(); + return *iter; +} + +CPDFSDK_Annot* CPDFSDK_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) { + auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); + if (iter == m_Annots.end()) + return nullptr; + if (iter == m_Annots.begin()) + iter = m_Annots.end(); + return *(--iter); +} + +void CPDFSDK_AnnotIterator::CollectAnnots(std::vector* pArray) { + for (auto* pAnnot : m_pPageView->GetAnnotList()) { + if (pAnnot->GetAnnotSubtype() == m_nAnnotSubtype && + !pAnnot->IsSignatureWidget()) { + pArray->push_back(pAnnot); + } + } +} + +CFX_FloatRect CPDFSDK_AnnotIterator::AddToAnnotsList( + std::vector* sa, + size_t idx) { + CPDFSDK_Annot* pLeftTopAnnot = sa->at(idx); + CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot); + m_Annots.push_back(pLeftTopAnnot); + sa->erase(sa->begin() + idx); + return rcLeftTop; +} + +void CPDFSDK_AnnotIterator::AddSelectedToAnnots(std::vector* sa, + std::vector* aSelect) { + for (size_t i = 0; i < aSelect->size(); ++i) + m_Annots.push_back(sa->at(aSelect->at(i))); + + for (int i = aSelect->size() - 1; i >= 0; --i) + sa->erase(sa->begin() + aSelect->at(i)); +} + +void CPDFSDK_AnnotIterator::GenerateResults() { + switch (m_eTabOrder) { + case STRUCTURE: + CollectAnnots(&m_Annots); + break; + + case ROW: { + std::vector sa; + CollectAnnots(&sa); + std::sort(sa.begin(), sa.end(), CompareByLeftAscending); + + while (!sa.empty()) { + int nLeftTopIndex = -1; + float fTop = 0.0f; + for (int i = sa.size() - 1; i >= 0; i--) { + CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); + if (rcAnnot.top > fTop) { + nLeftTopIndex = i; + fTop = rcAnnot.top; + } + } + if (nLeftTopIndex < 0) + continue; + + CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex); + + std::vector aSelect; + for (size_t i = 0; i < sa.size(); ++i) { + CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); + float fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f; + if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top) + aSelect.push_back(i); + } + AddSelectedToAnnots(&sa, &aSelect); + } + break; + } + + case COLUMN: { + std::vector sa; + CollectAnnots(&sa); + std::sort(sa.begin(), sa.end(), CompareByTopDescending); + + while (!sa.empty()) { + int nLeftTopIndex = -1; + float fLeft = -1.0f; + for (int i = sa.size() - 1; i >= 0; --i) { + CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); + if (fLeft < 0) { + nLeftTopIndex = 0; + fLeft = rcAnnot.left; + } else if (rcAnnot.left < fLeft) { + nLeftTopIndex = i; + fLeft = rcAnnot.left; + } + } + if (nLeftTopIndex < 0) + continue; + + CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex); + + std::vector aSelect; + for (size_t i = 0; i < sa.size(); ++i) { + CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); + float fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f; + if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right) + aSelect.push_back(i); + } + AddSelectedToAnnots(&sa, &aSelect); + } + break; + } + } +} diff --git a/fpdfsdk/cpdfsdk_annotiterator.h b/fpdfsdk/cpdfsdk_annotiterator.h new file mode 100644 index 0000000000..723550edc5 --- /dev/null +++ b/fpdfsdk/cpdfsdk_annotiterator.h @@ -0,0 +1,46 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#ifndef FPDFSDK_CPDFSDK_ANNOTITERATOR_H_ +#define FPDFSDK_CPDFSDK_ANNOTITERATOR_H_ + +#include + +#include "core/fpdfdoc/cpdf_annot.h" +#include "core/fxcrt/fx_coordinates.h" +#include "core/fxcrt/fx_string.h" +#include "core/fxcrt/unowned_ptr.h" + +class CPDFSDK_Annot; +class CPDFSDK_PageView; + +class CPDFSDK_AnnotIterator { + public: + enum TabOrder { STRUCTURE = 0, ROW, COLUMN }; + + CPDFSDK_AnnotIterator(CPDFSDK_PageView* pPageView, + CPDF_Annot::Subtype nAnnotSubtype); + ~CPDFSDK_AnnotIterator(); + + CPDFSDK_Annot* GetFirstAnnot(); + CPDFSDK_Annot* GetLastAnnot(); + CPDFSDK_Annot* GetNextAnnot(CPDFSDK_Annot* pAnnot); + CPDFSDK_Annot* GetPrevAnnot(CPDFSDK_Annot* pAnnot); + + private: + void GenerateResults(); + void CollectAnnots(std::vector* pArray); + CFX_FloatRect AddToAnnotsList(std::vector* sa, size_t idx); + void AddSelectedToAnnots(std::vector* sa, + std::vector* aSelect); + + TabOrder m_eTabOrder; + UnownedPtr m_pPageView; + CPDF_Annot::Subtype m_nAnnotSubtype; + std::vector m_Annots; +}; + +#endif // FPDFSDK_CPDFSDK_ANNOTITERATOR_H_ diff --git a/fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp b/fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp new file mode 100644 index 0000000000..879a365ae8 --- /dev/null +++ b/fpdfsdk/cpdfsdk_annotiterator_embeddertest.cpp @@ -0,0 +1,126 @@ +// Copyright 2016 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "fpdfsdk/cpdfsdk_annot.h" +#include "fpdfsdk/cpdfsdk_annotiterator.h" +#include "fpdfsdk/cpdfsdk_formfillenvironment.h" +#include "fpdfsdk/cpdfsdk_helpers.h" +#include "testing/embedder_test.h" +#include "testing/embedder_test_mock_delegate.h" +#include "testing/embedder_test_timer_handling_delegate.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +void CheckRect(const CFX_FloatRect& actual, const CFX_FloatRect& expected) { + EXPECT_EQ(expected.left, actual.left); + EXPECT_EQ(expected.bottom, actual.bottom); + EXPECT_EQ(expected.right, actual.right); + EXPECT_EQ(expected.top, actual.top); +} + +} // namespace + +class CPDFSDK_AnnotIteratorTest : public EmbedderTest {}; + +TEST_F(CPDFSDK_AnnotIteratorTest, CPDFSDK_AnnotIterator) { + EXPECT_TRUE(OpenDocument("annotiter.pdf")); + FPDF_PAGE page0 = LoadPage(0); + FPDF_PAGE page1 = LoadPage(1); + FPDF_PAGE page2 = LoadPage(2); + ASSERT_TRUE(page0); + ASSERT_TRUE(page1); + ASSERT_TRUE(page2); + + CFX_FloatRect LeftBottom(200, 200, 220, 220); + CFX_FloatRect RightBottom(400, 201, 420, 221); + CFX_FloatRect LeftTop(201, 400, 221, 420); + CFX_FloatRect RightTop(401, 401, 421, 421); + + CPDFSDK_FormFillEnvironment* pFormFillEnv = + static_cast(form_handle()); + + { + // Page 0 specifies "row order". + CPDFSDK_AnnotIterator iter(pFormFillEnv->GetPageView(0), + CPDF_Annot::Subtype::WIDGET); + CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot(); + CheckRect(pAnnot->GetRect(), RightTop); + pAnnot = iter.GetNextAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), LeftTop); + pAnnot = iter.GetNextAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), RightBottom); + pAnnot = iter.GetNextAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), LeftBottom); + pAnnot = iter.GetNextAnnot(pAnnot); + EXPECT_EQ(iter.GetFirstAnnot(), pAnnot); + + pAnnot = iter.GetLastAnnot(); + CheckRect(pAnnot->GetRect(), LeftBottom); + pAnnot = iter.GetPrevAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), RightBottom); + pAnnot = iter.GetPrevAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), LeftTop); + pAnnot = iter.GetPrevAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), RightTop); + pAnnot = iter.GetPrevAnnot(pAnnot); + EXPECT_EQ(iter.GetLastAnnot(), pAnnot); + } + { + // Page 1 specifies "column order" + CPDFSDK_AnnotIterator iter(pFormFillEnv->GetPageView(1), + CPDF_Annot::Subtype::WIDGET); + CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot(); + CheckRect(pAnnot->GetRect(), RightTop); + pAnnot = iter.GetNextAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), RightBottom); + pAnnot = iter.GetNextAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), LeftTop); + pAnnot = iter.GetNextAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), LeftBottom); + pAnnot = iter.GetNextAnnot(pAnnot); + EXPECT_EQ(iter.GetFirstAnnot(), pAnnot); + + pAnnot = iter.GetLastAnnot(); + CheckRect(pAnnot->GetRect(), LeftBottom); + pAnnot = iter.GetPrevAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), LeftTop); + pAnnot = iter.GetPrevAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), RightBottom); + pAnnot = iter.GetPrevAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), RightTop); + pAnnot = iter.GetPrevAnnot(pAnnot); + EXPECT_EQ(iter.GetLastAnnot(), pAnnot); + } + { + // Page 2 specifies "struct order" + CPDFSDK_AnnotIterator iter(pFormFillEnv->GetPageView(2), + CPDF_Annot::Subtype::WIDGET); + CPDFSDK_Annot* pAnnot = iter.GetFirstAnnot(); + CheckRect(pAnnot->GetRect(), LeftBottom); + pAnnot = iter.GetNextAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), RightTop); + pAnnot = iter.GetNextAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), LeftTop); + pAnnot = iter.GetNextAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), RightBottom); + pAnnot = iter.GetNextAnnot(pAnnot); + EXPECT_EQ(iter.GetFirstAnnot(), pAnnot); + + pAnnot = iter.GetLastAnnot(); + CheckRect(pAnnot->GetRect(), RightBottom); + pAnnot = iter.GetPrevAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), LeftTop); + pAnnot = iter.GetPrevAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), RightTop); + pAnnot = iter.GetPrevAnnot(pAnnot); + CheckRect(pAnnot->GetRect(), LeftBottom); + pAnnot = iter.GetPrevAnnot(pAnnot); + EXPECT_EQ(iter.GetLastAnnot(), pAnnot); + } + UnloadPage(page2); + UnloadPage(page1); + UnloadPage(page0); +} diff --git a/fpdfsdk/cpdfsdk_interform.cpp b/fpdfsdk/cpdfsdk_interform.cpp index 22d1a47e33..6d3e9cd848 100644 --- a/fpdfsdk/cpdfsdk_interform.cpp +++ b/fpdfsdk/cpdfsdk_interform.cpp @@ -21,9 +21,9 @@ #include "core/fpdfdoc/cpdf_interform.h" #include "core/fxge/cfx_graphstatedata.h" #include "core/fxge/cfx_pathdata.h" -#include "fpdfsdk/cba_annotiterator.h" #include "fpdfsdk/cpdfsdk_actionhandler.h" #include "fpdfsdk/cpdfsdk_annot.h" +#include "fpdfsdk/cpdfsdk_annotiterator.h" #include "fpdfsdk/cpdfsdk_formfillenvironment.h" #include "fpdfsdk/cpdfsdk_helpers.h" #include "fpdfsdk/cpdfsdk_pageview.h" @@ -106,7 +106,7 @@ bool CPDFSDK_InterForm::HighlightWidgets() { CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget, bool bNext) const { - auto pIterator = pdfium::MakeUnique( + auto pIterator = pdfium::MakeUnique( pWidget->GetPageView(), CPDF_Annot::Subtype::WIDGET); if (bNext) diff --git a/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp b/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp index 9fd8eec173..e4b329e61e 100644 --- a/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp +++ b/fpdfsdk/pwl/cpwl_combo_box_embeddertest.cpp @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fpdfsdk/cba_annotiterator.h" #include "fpdfsdk/cpdfsdk_annot.h" +#include "fpdfsdk/cpdfsdk_annotiterator.h" #include "fpdfsdk/cpdfsdk_formfillenvironment.h" #include "fpdfsdk/formfiller/cffl_formfiller.h" #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h" @@ -30,8 +30,8 @@ class CPWLComboBoxEditEmbeddertest : public EmbedderTest { ASSERT_TRUE(m_page); m_pFormFillEnv = static_cast(form_handle()); - CBA_AnnotIterator iter(m_pFormFillEnv->GetPageView(0), - CPDF_Annot::Subtype::WIDGET); + CPDFSDK_AnnotIterator iter(m_pFormFillEnv->GetPageView(0), + CPDF_Annot::Subtype::WIDGET); // User editable combobox. m_pAnnotEditable = iter.GetFirstAnnot(); diff --git a/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp b/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp index b3f0d5dc0e..43d06d3d2a 100644 --- a/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp +++ b/fpdfsdk/pwl/cpwl_edit_embeddertest.cpp @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "fpdfsdk/cba_annotiterator.h" #include "fpdfsdk/cpdfsdk_annot.h" +#include "fpdfsdk/cpdfsdk_annotiterator.h" #include "fpdfsdk/cpdfsdk_formfillenvironment.h" #include "fpdfsdk/formfiller/cffl_formfiller.h" #include "fpdfsdk/formfiller/cffl_interactiveformfiller.h" @@ -29,8 +29,8 @@ class CPWLEditEmbeddertest : public EmbedderTest { ASSERT_TRUE(m_page); m_pFormFillEnv = static_cast(form_handle()); - CBA_AnnotIterator iter(m_pFormFillEnv->GetPageView(0), - CPDF_Annot::Subtype::WIDGET); + CPDFSDK_AnnotIterator iter(m_pFormFillEnv->GetPageView(0), + CPDF_Annot::Subtype::WIDGET); // Normal text field. m_pAnnot = iter.GetFirstAnnot(); ASSERT_TRUE(m_pAnnot); -- cgit v1.2.3