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 "fpdfsdk/include/fsdk_baseform.h" | 7 #include "fpdfsdk/include/fsdk_baseform.h" |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 | 10 |
(...skipping 2061 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2072 if (nFieldType < 0 || nFieldType > kNumFieldTypes) | 2072 if (nFieldType < 0 || nFieldType > kNumFieldTypes) |
2073 return FXSYS_RGB(255, 255, 255); | 2073 return FXSYS_RGB(255, 255, 255); |
2074 if (nFieldType == 0) | 2074 if (nFieldType == 0) |
2075 return m_aHighlightColor[0]; | 2075 return m_aHighlightColor[0]; |
2076 return m_aHighlightColor[nFieldType - 1]; | 2076 return m_aHighlightColor[nFieldType - 1]; |
2077 } | 2077 } |
2078 | 2078 |
2079 CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, | 2079 CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, |
2080 const CFX_ByteString& sType, | 2080 const CFX_ByteString& sType, |
2081 const CFX_ByteString& sSubType) | 2081 const CFX_ByteString& sSubType) |
2082 : m_pPageView(pPageView), | 2082 : m_eTabOrder(STRUCTURE), |
2083 m_pPageView(pPageView), | |
2083 m_sType(sType), | 2084 m_sType(sType), |
2084 m_sSubType(sSubType), | 2085 m_sSubType(sSubType) { |
2085 m_nTabs(BAI_STRUCTURE) { | |
2086 CPDF_Page* pPDFPage = m_pPageView->GetPDFPage(); | 2086 CPDF_Page* pPDFPage = m_pPageView->GetPDFPage(); |
2087 CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringBy("Tabs"); | 2087 CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetStringBy("Tabs"); |
2088 | 2088 if (sTabs == "R") |
2089 if (sTabs == "R") { | 2089 m_eTabOrder = ROW; |
2090 m_nTabs = BAI_ROW; | 2090 else if (sTabs == "C") |
2091 } else if (sTabs == "C") { | 2091 m_eTabOrder = COLUMN; |
2092 m_nTabs = BAI_COLUMN; | |
2093 } else { | |
2094 m_nTabs = BAI_STRUCTURE; | |
2095 } | |
2096 | 2092 |
2097 GenerateResults(); | 2093 GenerateResults(); |
2098 } | 2094 } |
2099 | 2095 |
2100 CBA_AnnotIterator::~CBA_AnnotIterator() { | 2096 CBA_AnnotIterator::~CBA_AnnotIterator() { |
2101 m_Annots.RemoveAll(); | |
2102 } | 2097 } |
2103 | 2098 |
2104 CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() { | 2099 CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot() { |
2105 if (m_Annots.GetSize() > 0) | 2100 return m_Annots.empty() ? nullptr : m_Annots.front(); |
2106 return m_Annots[0]; | |
2107 | |
2108 return NULL; | |
2109 } | 2101 } |
2110 | 2102 |
2111 CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() { | 2103 CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot() { |
2112 if (m_Annots.GetSize() > 0) | 2104 return m_Annots.empty() ? nullptr : m_Annots.back(); |
2113 return m_Annots[m_Annots.GetSize() - 1]; | |
2114 | |
2115 return NULL; | |
2116 } | 2105 } |
2117 | 2106 |
2118 CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) { | 2107 CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot) { |
2119 for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) { | 2108 auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); |
Lei Zhang
2016/02/01 19:12:55
IYWU paranoia: #include <algorithm>
Tom Sepez
2016/02/01 20:14:22
Done.
| |
2120 if (m_Annots[i] == pAnnot) | 2109 if (iter == m_Annots.end()) |
2121 return (i + 1 < sz) ? m_Annots[i + 1] : m_Annots[0]; | 2110 return nullptr; |
2122 } | 2111 ++iter; |
2123 return NULL; | 2112 if (iter == m_Annots.end()) |
2113 iter = m_Annots.begin(); | |
2114 return *iter; | |
2124 } | 2115 } |
2125 | 2116 |
2126 CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) { | 2117 CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot) { |
2127 for (int i = 0, sz = m_Annots.GetSize(); i < sz; ++i) { | 2118 auto iter = std::find(m_Annots.begin(), m_Annots.end(), pAnnot); |
2128 if (m_Annots[i] == pAnnot) | 2119 if (iter == m_Annots.end()) |
2129 return (i - 1 >= 0) ? m_Annots[i - 1] : m_Annots[sz - 1]; | 2120 return nullptr; |
2130 } | 2121 if (iter == m_Annots.begin()) |
2131 return NULL; | 2122 iter = m_Annots.end(); |
2123 return *(--iter); | |
2132 } | 2124 } |
2133 | 2125 |
2134 int CBA_AnnotIterator::CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) { | 2126 // static |
2135 ASSERT(p1); | 2127 bool CBA_AnnotIterator::CompareByLeftAscending(const CPDFSDK_Annot* p1, |
2136 ASSERT(p2); | 2128 const CPDFSDK_Annot* p2) { |
2137 | 2129 return GetAnnotRect(p1).left < GetAnnotRect(p2).left; |
2138 CPDF_Rect rcAnnot1 = GetAnnotRect(p1); | |
2139 CPDF_Rect rcAnnot2 = GetAnnotRect(p2); | |
2140 | |
2141 if (rcAnnot1.left < rcAnnot2.left) | |
2142 return -1; | |
2143 if (rcAnnot1.left > rcAnnot2.left) | |
2144 return 1; | |
2145 return 0; | |
2146 } | 2130 } |
2147 | 2131 |
2148 int CBA_AnnotIterator::CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2) { | 2132 // static |
2149 ASSERT(p1); | 2133 bool CBA_AnnotIterator::CompareByTopDescending(const CPDFSDK_Annot* p1, |
2150 ASSERT(p2); | 2134 const CPDFSDK_Annot* p2) { |
2151 | 2135 return GetAnnotRect(p1).top > GetAnnotRect(p2).top; |
2152 CPDF_Rect rcAnnot1 = GetAnnotRect(p1); | |
2153 CPDF_Rect rcAnnot2 = GetAnnotRect(p2); | |
2154 | |
2155 if (rcAnnot1.top < rcAnnot2.top) | |
2156 return -1; | |
2157 if (rcAnnot1.top > rcAnnot2.top) | |
2158 return 1; | |
2159 return 0; | |
2160 } | 2136 } |
2161 | 2137 |
2162 void CBA_AnnotIterator::GenerateResults() { | 2138 void CBA_AnnotIterator::GenerateResults() { |
2163 switch (m_nTabs) { | 2139 switch (m_eTabOrder) { |
2164 case BAI_STRUCTURE: { | 2140 case STRUCTURE: { |
2165 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { | 2141 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { |
2166 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); | 2142 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); |
2167 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) | 2143 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) |
2168 m_Annots.Add(pAnnot); | 2144 m_Annots.push_back(pAnnot); |
2169 } | 2145 } |
2170 break; | 2146 } break; |
2171 } | 2147 case ROW: { |
2172 case BAI_ROW: { | 2148 std::vector<CPDFSDK_Annot*> sa; |
2173 CPDFSDK_SortAnnots sa; | |
2174 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { | 2149 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { |
2175 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); | 2150 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); |
2176 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) | 2151 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) |
2177 sa.Add(pAnnot); | 2152 sa.push_back(pAnnot); |
2178 } | 2153 } |
2154 if (sa.empty()) | |
Lei Zhang
2016/02/01 19:12:55
We can probably just omit this?
Tom Sepez
2016/02/01 20:14:22
Done.
| |
2155 break; | |
2179 | 2156 |
2180 if (sa.GetSize() > 0) | 2157 std::sort(sa.begin(), sa.end(), CompareByLeftAscending); |
2181 sa.Sort(CBA_AnnotIterator::CompareByLeft); | 2158 while (!sa.empty()) { |
2182 | |
2183 while (sa.GetSize() > 0) { | |
2184 int nLeftTopIndex = -1; | 2159 int nLeftTopIndex = -1; |
2185 FX_FLOAT fTop = 0.0f; | 2160 FX_FLOAT fTop = 0.0f; |
2186 | 2161 for (int i = sa.size() - 1; i >= 0; i--) { |
Lei Zhang
2016/02/01 19:12:55
for (auto it = sa.rbegin(); it != sa.rend(); ++it)
Tom Sepez
2016/02/01 20:14:22
Meh, I think both of those are more complicated to
Lei Zhang
2016/02/01 21:18:15
I was thinking of avoiding int vs size_t, but it l
| |
2187 for (int i = sa.GetSize() - 1; i >= 0; i--) { | 2162 CPDF_Rect rcAnnot = GetAnnotRect(sa[i]); |
2188 CPDFSDK_Annot* pAnnot = sa.GetAt(i); | |
2189 ASSERT(pAnnot); | |
2190 | |
2191 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot); | |
2192 | |
2193 if (rcAnnot.top > fTop) { | 2163 if (rcAnnot.top > fTop) { |
2194 nLeftTopIndex = i; | 2164 nLeftTopIndex = i; |
2195 fTop = rcAnnot.top; | 2165 fTop = rcAnnot.top; |
2196 } | 2166 } |
2197 } | 2167 } |
2168 if (nLeftTopIndex >= 0) { | |
2169 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex]; | |
2170 CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot); | |
2171 m_Annots.push_back(pLeftTopAnnot); | |
2172 sa.erase(sa.begin() + nLeftTopIndex); | |
2198 | 2173 |
2199 if (nLeftTopIndex >= 0) { | 2174 std::vector<int> aSelect; |
2200 CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex); | 2175 for (int i = 0; i < sa.size(); ++i) { |
Lei Zhang
2016/02/01 19:12:55
As is, shadow variable |i| here and in the for loo
Tom Sepez
2016/02/01 20:14:22
Done.
Tom Sepez
2016/02/01 20:14:22
Huh? Aren't yhe other |i|s are already out of sco
Lei Zhang
2016/02/01 21:18:15
n/m, I read the diff wrong somewhere.
| |
2201 ASSERT(pLeftTopAnnot); | 2176 CPDF_Rect rcAnnot = GetAnnotRect(sa[i]); |
2202 | |
2203 CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot); | |
2204 | |
2205 m_Annots.Add(pLeftTopAnnot); | |
2206 sa.RemoveAt(nLeftTopIndex); | |
2207 | |
2208 CFX_ArrayTemplate<int> aSelect; | |
2209 | |
2210 for (int i = 0, sz = sa.GetSize(); i < sz; ++i) { | |
2211 CPDFSDK_Annot* pAnnot = sa.GetAt(i); | |
2212 ASSERT(pAnnot); | |
2213 | |
2214 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot); | |
2215 FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f; | 2177 FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f; |
2216 if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top) | 2178 if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top) |
2217 aSelect.Add(i); | 2179 aSelect.push_back(i); |
2218 } | 2180 } |
2181 for (int i = 0; i < aSelect.size(); ++i) | |
2182 m_Annots.push_back(sa[aSelect[i]]); | |
2219 | 2183 |
2220 for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i) | 2184 for (int i = aSelect.size() - 1; i >= 0; --i) |
2221 m_Annots.Add(sa[aSelect[i]]); | 2185 sa.erase(sa.begin() + aSelect[i]); |
2222 | |
2223 for (int i = aSelect.GetSize() - 1; i >= 0; --i) | |
2224 sa.RemoveAt(aSelect[i]); | |
2225 | |
2226 aSelect.RemoveAll(); | |
2227 } | 2186 } |
2228 } | 2187 } |
2229 sa.RemoveAll(); | 2188 } break; |
2230 break; | 2189 case COLUMN: { |
2231 } | 2190 std::vector<CPDFSDK_Annot*> sa; |
2232 case BAI_COLUMN: { | |
2233 CPDFSDK_SortAnnots sa; | |
2234 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { | 2191 for (size_t i = 0; i < m_pPageView->CountAnnots(); ++i) { |
2235 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); | 2192 CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i); |
2236 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) | 2193 if (pAnnot->GetType() == m_sType && pAnnot->GetSubType() == m_sSubType) |
2237 sa.Add(pAnnot); | 2194 sa.push_back(pAnnot); |
2238 } | 2195 } |
2196 if (sa.empty()) | |
2197 break; | |
2239 | 2198 |
2240 if (sa.GetSize() > 0) | 2199 std::sort(sa.begin(), sa.end(), CompareByTopDescending); |
2241 sa.Sort(CBA_AnnotIterator::CompareByTop, FALSE); | 2200 while (!sa.empty()) { |
2242 | |
2243 while (sa.GetSize() > 0) { | |
2244 int nLeftTopIndex = -1; | 2201 int nLeftTopIndex = -1; |
2245 FX_FLOAT fLeft = -1.0f; | 2202 FX_FLOAT fLeft = -1.0f; |
2246 | 2203 for (int i = sa.size() - 1; i >= 0; --i) { |
2247 for (int i = sa.GetSize() - 1; i >= 0; --i) { | 2204 CPDF_Rect rcAnnot = GetAnnotRect(sa[i]); |
2248 CPDFSDK_Annot* pAnnot = sa.GetAt(i); | |
2249 ASSERT(pAnnot); | |
2250 | |
2251 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot); | |
2252 | |
2253 if (fLeft < 0) { | 2205 if (fLeft < 0) { |
2254 nLeftTopIndex = 0; | 2206 nLeftTopIndex = 0; |
2255 fLeft = rcAnnot.left; | 2207 fLeft = rcAnnot.left; |
2256 } else if (rcAnnot.left < fLeft) { | 2208 } else if (rcAnnot.left < fLeft) { |
2257 nLeftTopIndex = i; | 2209 nLeftTopIndex = i; |
2258 fLeft = rcAnnot.left; | 2210 fLeft = rcAnnot.left; |
2259 } | 2211 } |
2260 } | 2212 } |
2261 | 2213 |
2262 if (nLeftTopIndex >= 0) { | 2214 if (nLeftTopIndex >= 0) { |
2263 CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex); | 2215 CPDFSDK_Annot* pLeftTopAnnot = sa[nLeftTopIndex]; |
2264 ASSERT(pLeftTopAnnot); | 2216 CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot); |
2217 m_Annots.push_back(pLeftTopAnnot); | |
2218 sa.erase(sa.begin() + nLeftTopIndex); | |
2265 | 2219 |
2266 CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot); | 2220 std::vector<int> aSelect; |
2267 | 2221 for (int i = 0; i < sa.size(); ++i) { |
2268 m_Annots.Add(pLeftTopAnnot); | 2222 CPDF_Rect rcAnnot = GetAnnotRect(sa[i]); |
2269 sa.RemoveAt(nLeftTopIndex); | |
2270 | |
2271 CFX_ArrayTemplate<int> aSelect; | |
2272 for (int i = 0, sz = sa.GetSize(); i < sz; ++i) { | |
2273 CPDFSDK_Annot* pAnnot = sa.GetAt(i); | |
2274 ASSERT(pAnnot); | |
2275 | |
2276 CPDF_Rect rcAnnot = GetAnnotRect(pAnnot); | |
2277 FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f; | 2223 FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f; |
2278 if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right) | 2224 if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right) |
2279 aSelect.Add(i); | 2225 aSelect.push_back(i); |
2280 } | 2226 } |
2227 for (int i = 0; i < aSelect.size(); ++i) | |
2228 m_Annots.push_back(sa[aSelect[i]]); | |
2281 | 2229 |
2282 for (int i = 0, sz = aSelect.GetSize(); i < sz; ++i) | 2230 for (int i = aSelect.size() - 1; i >= 0; --i) |
2283 m_Annots.Add(sa[aSelect[i]]); | 2231 sa.erase(sa.begin() + aSelect[i]); |
2284 | |
2285 for (int i = aSelect.GetSize() - 1; i >= 0; --i) | |
2286 sa.RemoveAt(aSelect[i]); | |
2287 | |
2288 aSelect.RemoveAll(); | |
2289 } | 2232 } |
2290 } | 2233 } |
2291 sa.RemoveAll(); | |
2292 break; | 2234 break; |
2293 } | 2235 } |
2294 } | 2236 } |
2295 } | 2237 } |
2296 | 2238 |
2297 CPDF_Rect CBA_AnnotIterator::GetAnnotRect(CPDFSDK_Annot* pAnnot) { | 2239 CPDF_Rect CBA_AnnotIterator::GetAnnotRect(const CPDFSDK_Annot* pAnnot) { |
2298 CPDF_Rect rcAnnot; | 2240 CPDF_Rect rcAnnot; |
2299 pAnnot->GetPDFAnnot()->GetRect(rcAnnot); | 2241 pAnnot->GetPDFAnnot()->GetRect(rcAnnot); |
2300 return rcAnnot; | 2242 return rcAnnot; |
2301 } | 2243 } |
OLD | NEW |