OLD | NEW |
1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 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 "fpdfsdk/cba_annotiterator.h" | 7 #include "fpdfsdk/cba_annotiterator.h" |
8 | 8 |
9 #include "core/fpdfapi/page/cpdf_page.h" | 9 #include "core/fpdfapi/page/cpdf_page.h" |
10 #include "fpdfsdk/cpdfsdk_annot.h" | 10 #include "fpdfsdk/cpdfsdk_annot.h" |
11 #include "fpdfsdk/cpdfsdk_pageview.h" | 11 #include "fpdfsdk/cpdfsdk_pageview.h" |
12 | 12 |
13 // static | 13 namespace { |
14 bool CBA_AnnotIterator::CompareByLeftAscending(const CPDFSDK_Annot* p1, | 14 |
15 const CPDFSDK_Annot* p2) { | 15 CFX_FloatRect GetAnnotRect(const CPDFSDK_Annot* pAnnot) { |
| 16 return pAnnot->GetPDFAnnot()->GetRect(); |
| 17 } |
| 18 |
| 19 bool CompareByLeftAscending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) { |
16 return GetAnnotRect(p1).left < GetAnnotRect(p2).left; | 20 return GetAnnotRect(p1).left < GetAnnotRect(p2).left; |
17 } | 21 } |
18 | 22 |
19 // static | 23 bool CompareByTopDescending(const CPDFSDK_Annot* p1, const CPDFSDK_Annot* p2) { |
20 bool CBA_AnnotIterator::CompareByTopDescending(const CPDFSDK_Annot* p1, | |
21 const CPDFSDK_Annot* p2) { | |
22 return GetAnnotRect(p1).top > GetAnnotRect(p2).top; | 24 return GetAnnotRect(p1).top > GetAnnotRect(p2).top; |
23 } | 25 } |
24 | 26 |
| 27 } // namespace |
| 28 |
25 CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, | 29 CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, |
26 CPDF_Annot::Subtype nAnnotSubtype) | 30 CPDF_Annot::Subtype nAnnotSubtype) |
27 : m_eTabOrder(STRUCTURE), | 31 : m_eTabOrder(STRUCTURE), |
28 m_pPageView(pPageView), | 32 m_pPageView(pPageView), |
29 m_nAnnotSubtype(nAnnotSubtype) { | 33 m_nAnnotSubtype(nAnnotSubtype) { |
30 CPDF_Page* pPDFPage = m_pPageView->GetPDFPage(); | 34 CPDF_Page* pPDFPage = m_pPageView->GetPDFPage(); |
31 CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringFor("Tabs"); | 35 CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringFor("Tabs"); |
32 if (sTabs == "R") | 36 if (sTabs == "R") |
33 m_eTabOrder = ROW; | 37 m_eTabOrder = ROW; |
34 else if (sTabs == "C") | 38 else if (sTabs == "C") |
(...skipping 24 matching lines...) Expand all Loading... |
59 | 63 |
60 CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) { | 64 CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) { |
61 auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); | 65 auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); |
62 if (iter == m_Annots.end()) | 66 if (iter == m_Annots.end()) |
63 return nullptr; | 67 return nullptr; |
64 if (iter == m_Annots.begin()) | 68 if (iter == m_Annots.begin()) |
65 iter = m_Annots.end(); | 69 iter = m_Annots.end(); |
66 return *(--iter); | 70 return *(--iter); |
67 } | 71 } |
68 | 72 |
| 73 void CBA_AnnotIterator::CollectAnnots(std::vector<CPDFSDK_Annot*>* pArray) { |
| 74 for (auto pAnnot : m_pPageView->GetAnnotList()) { |
| 75 if (pAnnot->GetAnnotSubtype() == m_nAnnotSubtype && |
| 76 !pAnnot->IsSignatureWidget()) { |
| 77 pArray->push_back(pAnnot); |
| 78 } |
| 79 } |
| 80 } |
| 81 |
| 82 CFX_FloatRect CBA_AnnotIterator::AddToAnnotsList( |
| 83 std::vector<CPDFSDK_Annot*>* sa, |
| 84 size_t idx) { |
| 85 CPDFSDK_Annot* pLeftTopAnnot = sa->at(idx); |
| 86 CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot); |
| 87 m_Annots.push_back(pLeftTopAnnot); |
| 88 sa->erase(sa->begin() + idx); |
| 89 return rcLeftTop; |
| 90 } |
| 91 |
| 92 void CBA_AnnotIterator::AddSelectedToAnnots(std::vector<CPDFSDK_Annot*>* sa, |
| 93 std::vector<size_t>* aSelect) { |
| 94 for (size_t i = 0; i < aSelect->size(); ++i) |
| 95 m_Annots.push_back(sa->at(aSelect->at(i))); |
| 96 |
| 97 for (int i = aSelect->size() - 1; i >= 0; --i) |
| 98 sa->erase(sa->begin() + aSelect->at(i)); |
| 99 } |
| 100 |
69 void CBA_AnnotIterator::GenerateResults() { | 101 void CBA_AnnotIterator::GenerateResults() { |
70 switch (m_eTabOrder) { | 102 switch (m_eTabOrder) { |
71 case STRUCTURE: { | 103 case STRUCTURE: |
72 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { | 104 CollectAnnots(&m_Annots); |
73 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); | |
74 if (pAnnot->GetAnnotSubtype() == m_nAnnotSubtype && | |
75 !pAnnot->IsSignatureWidget()) | |
76 m_Annots.push_back(pAnnot); | |
77 } | |
78 break; | 105 break; |
79 } | 106 |
80 case ROW: { | 107 case ROW: { |
81 std::vector<CPDFSDK_Annot*> sa; | 108 std::vector<CPDFSDK_Annot*> sa; |
82 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { | 109 CollectAnnots(&sa); |
83 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); | 110 std::sort(sa.begin(), sa.end(), CompareByLeftAscending); |
84 if (pAnnot->GetAnnotSubtype() == m_nAnnotSubtype && | |
85 !pAnnot->IsSignatureWidget()) | |
86 sa.push_back(pAnnot); | |
87 } | |
88 | 111 |
89 std::sort(sa.begin(), sa.end(), CompareByLeftAscending); | |
90 while (!sa.empty()) { | 112 while (!sa.empty()) { |
91 int nLeftTopIndex = -1; | 113 int nLeftTopIndex = -1; |
92 FX_FLOAT fTop = 0.0f; | 114 FX_FLOAT fTop = 0.0f; |
93 for (int i = sa.size() - 1; i >= 0; i--) { | 115 for (int i = sa.size() - 1; i >= 0; i--) { |
94 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); | 116 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); |
95 if (rcAnnot.top > fTop) { | 117 if (rcAnnot.top > fTop) { |
96 nLeftTopIndex = i; | 118 nLeftTopIndex = i; |
97 fTop = rcAnnot.top; | 119 fTop = rcAnnot.top; |
98 } | 120 } |
99 } | 121 } |
100 if (nLeftTopIndex >= 0) { | 122 if (nLeftTopIndex < 0) |
101 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex]; | 123 continue; |
102 CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot); | |
103 m_Annots.push_back(pLeftTopAnnot); | |
104 sa.erase(sa.begin() + nLeftTopIndex); | |
105 | 124 |
106 std::vector<int> aSelect; | 125 CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex); |
107 for (size_t i = 0; i < sa.size(); ++i) { | |
108 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); | |
109 FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f; | |
110 if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top) | |
111 aSelect.push_back(i); | |
112 } | |
113 for (size_t i = 0; i < aSelect.size(); ++i) | |
114 m_Annots.push_back(sa[aSelect[i]]); | |
115 | 126 |
116 for (int i = aSelect.size() - 1; i >= 0; --i) | 127 std::vector<size_t> aSelect; |
117 sa.erase(sa.begin() + aSelect[i]); | 128 for (size_t i = 0; i < sa.size(); ++i) { |
| 129 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); |
| 130 FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f; |
| 131 if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top) |
| 132 aSelect.push_back(i); |
118 } | 133 } |
| 134 AddSelectedToAnnots(&sa, &aSelect); |
119 } | 135 } |
120 break; | 136 break; |
121 } | 137 } |
| 138 |
122 case COLUMN: { | 139 case COLUMN: { |
123 std::vector<CPDFSDK_Annot*> sa; | 140 std::vector<CPDFSDK_Annot*> sa; |
124 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { | 141 CollectAnnots(&sa); |
125 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); | 142 std::sort(sa.begin(), sa.end(), CompareByTopDescending); |
126 if (pAnnot->GetAnnotSubtype() == m_nAnnotSubtype && | |
127 !pAnnot->IsSignatureWidget()) | |
128 sa.push_back(pAnnot); | |
129 } | |
130 | 143 |
131 std::sort(sa.begin(), sa.end(), CompareByTopDescending); | |
132 while (!sa.empty()) { | 144 while (!sa.empty()) { |
133 int nLeftTopIndex = -1; | 145 int nLeftTopIndex = -1; |
134 FX_FLOAT fLeft = -1.0f; | 146 FX_FLOAT fLeft = -1.0f; |
135 for (int i = sa.size() - 1; i >= 0; --i) { | 147 for (int i = sa.size() - 1; i >= 0; --i) { |
136 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); | 148 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); |
137 if (fLeft < 0) { | 149 if (fLeft < 0) { |
138 nLeftTopIndex = 0; | 150 nLeftTopIndex = 0; |
139 fLeft = rcAnnot.left; | 151 fLeft = rcAnnot.left; |
140 } else if (rcAnnot.left < fLeft) { | 152 } else if (rcAnnot.left < fLeft) { |
141 nLeftTopIndex = i; | 153 nLeftTopIndex = i; |
142 fLeft = rcAnnot.left; | 154 fLeft = rcAnnot.left; |
143 } | 155 } |
144 } | 156 } |
| 157 if (nLeftTopIndex < 0) |
| 158 continue; |
145 | 159 |
146 if (nLeftTopIndex >= 0) { | 160 CFX_FloatRect rcLeftTop = AddToAnnotsList(&sa, nLeftTopIndex); |
147 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex]; | |
148 CFX_FloatRect rcLeftTop = GetAnnotRect(pLeftTopAnnot); | |
149 m_Annots.push_back(pLeftTopAnnot); | |
150 sa.erase(sa.begin() + nLeftTopIndex); | |
151 | 161 |
152 std::vector<int> aSelect; | 162 std::vector<size_t> aSelect; |
153 for (size_t i = 0; i < sa.size(); ++i) { | 163 for (size_t i = 0; i < sa.size(); ++i) { |
154 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); | 164 CFX_FloatRect rcAnnot = GetAnnotRect(sa[i]); |
155 FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f; | 165 FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f; |
156 if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right) | 166 if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right) |
157 aSelect.push_back(i); | 167 aSelect.push_back(i); |
158 } | |
159 for (size_t i = 0; i < aSelect.size(); ++i) | |
160 m_Annots.push_back(sa[aSelect[i]]); | |
161 | |
162 for (int i = aSelect.size() - 1; i >= 0; --i) | |
163 sa.erase(sa.begin() + aSelect[i]); | |
164 } | 168 } |
| 169 AddSelectedToAnnots(&sa, &aSelect); |
165 } | 170 } |
166 break; | 171 break; |
167 } | 172 } |
168 } | 173 } |
169 } | 174 } |
170 | |
171 CFX_FloatRect CBA_AnnotIterator::GetAnnotRect(const CPDFSDK_Annot* pAnnot) { | |
172 return pAnnot->GetPDFAnnot()->GetRect(); | |
173 } | |
OLD | NEW |