Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 PDFium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| 6 | |
| 7 #include "core/fpdfdoc/csection.h" | |
| 8 | |
| 9 #include <algorithm> | |
| 10 | |
| 11 #include "core/fpdfdoc/cpvt_wordinfo.h" | |
| 12 #include "core/fpdfdoc/ctypeset.h" | |
| 13 #include "third_party/base/stl_util.h" | |
| 14 | |
| 15 CSection::CSection(CPDF_VariableText* pVT) : m_pVT(pVT) {} | |
| 16 | |
| 17 CSection::~CSection() { | |
| 18 ResetAll(); | |
| 19 } | |
| 20 | |
| 21 void CSection::ResetAll() { | |
|
dsinclair
2016/05/16 14:12:27
nit: Just Reset()?
| |
| 22 ResetWordArray(); | |
| 23 ResetLineArray(); | |
| 24 } | |
| 25 | |
| 26 void CSection::ResetLineArray() { | |
|
dsinclair
2016/05/16 14:12:27
nit: ResetLines(), Array is an implmentation detai
| |
| 27 m_LineArray.RemoveAll(); | |
| 28 } | |
| 29 | |
| 30 void CSection::ResetWordArray() { | |
|
dsinclair
2016/05/16 14:12:27
ditto
| |
| 31 m_WordArray.clear(); | |
| 32 } | |
| 33 | |
| 34 void CSection::ResetLinePlace() { | |
| 35 for (int32_t i = 0, sz = m_LineArray.GetSize(); i < sz; i++) { | |
| 36 if (CLine* pLine = m_LineArray.GetAt(i)) { | |
| 37 pLine->LinePlace = CPVT_WordPlace(SecPlace.nSecIndex, i, -1); | |
| 38 } | |
| 39 } | |
| 40 } | |
| 41 | |
| 42 CPVT_WordPlace CSection::AddWord(const CPVT_WordPlace& place, | |
| 43 const CPVT_WordInfo& wordinfo) { | |
| 44 std::unique_ptr<CPVT_WordInfo> pWord(new CPVT_WordInfo(wordinfo)); | |
| 45 int32_t nSize = GetNumberOfWords(); | |
| 46 int32_t nWordIndex = std::max(std::min(place.nWordIndex, nSize), 0); | |
| 47 if (nWordIndex == nSize) | |
| 48 m_WordArray.push_back(std::move(pWord)); | |
| 49 else | |
| 50 m_WordArray.insert(m_WordArray.begin() + nWordIndex, std::move(pWord)); | |
| 51 return place; | |
| 52 } | |
| 53 | |
| 54 CPVT_WordPlace CSection::AddLine(const CPVT_LineInfo& lineinfo) { | |
| 55 return CPVT_WordPlace(SecPlace.nSecIndex, m_LineArray.Add(lineinfo), -1); | |
| 56 } | |
| 57 | |
| 58 CPVT_FloatRect CSection::Rearrange() { | |
| 59 if (m_pVT->m_nCharArray > 0) | |
| 60 return CTypeset(this).CharArray(); | |
| 61 return CTypeset(this).Typeset(); | |
| 62 } | |
| 63 | |
| 64 CFX_PointF CSection::GetSectionSize(FX_FLOAT fFontSize) { | |
| 65 return CTypeset(this).GetEditSize(fFontSize); | |
| 66 } | |
| 67 | |
| 68 CPVT_WordPlace CSection::GetBeginWordPlace() const { | |
| 69 if (CLine* pLine = m_LineArray.GetAt(0)) | |
| 70 return pLine->GetBeginWordPlace(); | |
| 71 return SecPlace; | |
| 72 } | |
| 73 | |
| 74 CPVT_WordPlace CSection::GetEndWordPlace() const { | |
| 75 if (CLine* pLine = m_LineArray.GetAt(m_LineArray.GetSize() - 1)) | |
| 76 return pLine->GetEndWordPlace(); | |
| 77 return SecPlace; | |
| 78 } | |
| 79 | |
| 80 CPVT_WordPlace CSection::GetPrevWordPlace(const CPVT_WordPlace& place) const { | |
| 81 if (place.nLineIndex < 0) | |
| 82 return GetBeginWordPlace(); | |
| 83 | |
| 84 if (place.nLineIndex >= m_LineArray.GetSize()) | |
| 85 return GetEndWordPlace(); | |
| 86 | |
| 87 if (CLine* pLine = m_LineArray.GetAt(place.nLineIndex)) { | |
| 88 if (place.nWordIndex == pLine->m_LineInfo.nBeginWordIndex) | |
| 89 return CPVT_WordPlace(place.nSecIndex, place.nLineIndex, -1); | |
| 90 | |
| 91 if (place.nWordIndex >= pLine->m_LineInfo.nBeginWordIndex) | |
| 92 return pLine->GetPrevWordPlace(place); | |
| 93 | |
| 94 if (CLine* pPrevLine = m_LineArray.GetAt(place.nLineIndex - 1)) | |
| 95 return pPrevLine->GetEndWordPlace(); | |
| 96 } | |
| 97 return place; | |
| 98 } | |
| 99 | |
| 100 CPVT_WordPlace CSection::GetNextWordPlace(const CPVT_WordPlace& place) const { | |
| 101 if (place.nLineIndex < 0) | |
| 102 return GetBeginWordPlace(); | |
| 103 | |
| 104 if (place.nLineIndex >= m_LineArray.GetSize()) | |
| 105 return GetEndWordPlace(); | |
| 106 | |
| 107 if (CLine* pLine = m_LineArray.GetAt(place.nLineIndex)) { | |
| 108 if (place.nWordIndex < pLine->m_LineInfo.nEndWordIndex) | |
| 109 return pLine->GetNextWordPlace(place); | |
| 110 | |
| 111 if (CLine* pNextLine = m_LineArray.GetAt(place.nLineIndex + 1)) | |
| 112 return pNextLine->GetBeginWordPlace(); | |
| 113 } | |
| 114 return place; | |
| 115 } | |
| 116 | |
| 117 void CSection::UpdateWordPlace(CPVT_WordPlace& place) const { | |
| 118 int32_t nLeft = 0; | |
| 119 int32_t nRight = m_LineArray.GetSize() - 1; | |
| 120 int32_t nMid = (nLeft + nRight) / 2; | |
| 121 while (nLeft <= nRight) { | |
| 122 CLine* pLine = m_LineArray.GetAt(nMid); | |
| 123 if (!pLine) | |
| 124 return; | |
| 125 | |
| 126 if (place.nWordIndex == pLine->m_LineInfo.nBeginWordIndex) { | |
| 127 place.nLineIndex = nMid; | |
| 128 return; | |
| 129 } | |
| 130 | |
| 131 if (place.nWordIndex < pLine->m_LineInfo.nBeginWordIndex) | |
| 132 nRight = nMid - 1; | |
| 133 else | |
| 134 nLeft = nMid + 1; | |
| 135 nMid = (nLeft + nRight) / 2; | |
| 136 } | |
| 137 } | |
| 138 | |
| 139 CPVT_WordPlace CSection::SearchWordPlace(const CFX_FloatPoint& point) const { | |
| 140 CPVT_WordPlace place = GetBeginWordPlace(); | |
| 141 FX_BOOL bUp = TRUE; | |
| 142 FX_BOOL bDown = TRUE; | |
| 143 int32_t nLeft = 0; | |
| 144 int32_t nRight = m_LineArray.GetSize() - 1; | |
| 145 int32_t nMid = m_LineArray.GetSize() / 2; | |
| 146 FX_FLOAT fTop = 0; | |
| 147 FX_FLOAT fBottom = 0; | |
| 148 while (nLeft <= nRight) { | |
| 149 if (CLine* pLine = m_LineArray.GetAt(nMid)) { | |
| 150 fTop = pLine->m_LineInfo.fLineY - pLine->m_LineInfo.fLineAscent - | |
| 151 m_pVT->GetLineLeading(m_SecInfo); | |
| 152 fBottom = pLine->m_LineInfo.fLineY - pLine->m_LineInfo.fLineDescent; | |
| 153 if (IsFloatBigger(point.y, fTop)) | |
| 154 bUp = FALSE; | |
| 155 | |
| 156 if (IsFloatSmaller(point.y, fBottom)) | |
| 157 bDown = FALSE; | |
| 158 | |
| 159 if (IsFloatSmaller(point.y, fTop)) { | |
| 160 nRight = nMid - 1; | |
| 161 nMid = (nLeft + nRight) / 2; | |
| 162 continue; | |
| 163 } | |
| 164 if (IsFloatBigger(point.y, fBottom)) { | |
| 165 nLeft = nMid + 1; | |
| 166 nMid = (nLeft + nRight) / 2; | |
| 167 continue; | |
| 168 } | |
| 169 | |
| 170 place = SearchWordPlace( | |
| 171 point.x, | |
| 172 CPVT_WordRange(pLine->GetNextWordPlace(pLine->GetBeginWordPlace()), | |
| 173 pLine->GetEndWordPlace())); | |
| 174 place.nLineIndex = nMid; | |
| 175 return place; | |
| 176 } | |
| 177 } | |
| 178 if (bUp) | |
| 179 place = GetBeginWordPlace(); | |
| 180 if (bDown) | |
| 181 place = GetEndWordPlace(); | |
| 182 return place; | |
| 183 } | |
| 184 | |
| 185 CPVT_WordPlace CSection::SearchWordPlace( | |
| 186 FX_FLOAT fx, | |
| 187 const CPVT_WordPlace& lineplace) const { | |
| 188 CLine* pLine = m_LineArray.GetAt(lineplace.nLineIndex); | |
| 189 if (!pLine) | |
| 190 return GetBeginWordPlace(); | |
| 191 return SearchWordPlace( | |
| 192 fx - m_SecInfo.rcSection.left, | |
| 193 CPVT_WordRange(pLine->GetNextWordPlace(pLine->GetBeginWordPlace()), | |
| 194 pLine->GetEndWordPlace())); | |
| 195 } | |
| 196 | |
| 197 CPVT_WordPlace CSection::SearchWordPlace(FX_FLOAT fx, | |
| 198 const CPVT_WordRange& range) const { | |
| 199 CPVT_WordPlace wordplace = range.BeginPos; | |
| 200 wordplace.nWordIndex = -1; | |
| 201 if (!m_pVT) | |
| 202 return wordplace; | |
| 203 | |
| 204 int32_t nLeft = range.BeginPos.nWordIndex; | |
| 205 int32_t nRight = range.EndPos.nWordIndex + 1; | |
| 206 int32_t nMid = (nLeft + nRight) / 2; | |
| 207 while (nLeft < nRight) { | |
| 208 if (nMid == nLeft) | |
| 209 break; | |
| 210 | |
| 211 if (nMid == nRight) { | |
| 212 nMid--; | |
| 213 break; | |
| 214 } | |
| 215 | |
| 216 const CPVT_WordInfo* pWord = GetWord(nMid); | |
| 217 if (!pWord) | |
| 218 break; | |
| 219 | |
| 220 if (fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * VARIABLETEXT_HALF) | |
| 221 nLeft = nMid; | |
| 222 else | |
| 223 nRight = nMid; | |
| 224 nMid = (nLeft + nRight) / 2; | |
| 225 } | |
| 226 const CPVT_WordInfo* pWord = GetWord(nMid); | |
| 227 if (pWord && | |
| 228 fx > pWord->fWordX + m_pVT->GetWordWidth(*pWord) * VARIABLETEXT_HALF) { | |
| 229 wordplace.nWordIndex = nMid; | |
| 230 } | |
| 231 return wordplace; | |
| 232 } | |
| 233 | |
| 234 void CSection::ClearLeftWords(int32_t nWordIndex) { | |
| 235 if (IsWordArrayEmpty()) | |
| 236 return; | |
| 237 | |
| 238 m_WordArray.erase(m_WordArray.begin(), m_WordArray.begin() + nWordIndex + 1); | |
| 239 } | |
| 240 | |
| 241 void CSection::ClearRightWords(int32_t nWordIndex) { | |
| 242 if (IsWordArrayEmpty()) | |
| 243 return; | |
| 244 | |
| 245 m_WordArray.erase(m_WordArray.begin() + nWordIndex, m_WordArray.end()); | |
| 246 } | |
| 247 | |
| 248 void CSection::ClearMidWords(int32_t nBeginIndex, int32_t nEndIndex) { | |
| 249 if (IsWordArrayEmpty()) | |
| 250 return; | |
| 251 | |
| 252 m_WordArray.erase(m_WordArray.begin() + nBeginIndex + 1, | |
| 253 m_WordArray.begin() + nEndIndex + 1); | |
| 254 } | |
| 255 | |
| 256 void CSection::ClearWords(const CPVT_WordRange& PlaceRange) { | |
| 257 CPVT_WordPlace SecBeginPos = GetBeginWordPlace(); | |
| 258 CPVT_WordPlace SecEndPos = GetEndWordPlace(); | |
| 259 if (PlaceRange.BeginPos.WordCmp(SecBeginPos) >= 0) { | |
| 260 if (PlaceRange.EndPos.WordCmp(SecEndPos) <= 0) { | |
| 261 ClearMidWords(PlaceRange.BeginPos.nWordIndex, | |
| 262 PlaceRange.EndPos.nWordIndex); | |
| 263 } else { | |
| 264 ClearRightWords(PlaceRange.BeginPos.nWordIndex); | |
| 265 } | |
| 266 } else if (PlaceRange.EndPos.WordCmp(SecEndPos) <= 0) { | |
| 267 ClearLeftWords(PlaceRange.EndPos.nWordIndex); | |
| 268 } else { | |
| 269 ResetWordArray(); | |
| 270 } | |
| 271 } | |
| 272 | |
| 273 void CSection::ClearWord(const CPVT_WordPlace& place) { | |
| 274 m_WordArray.erase(m_WordArray.begin() + place.nWordIndex); | |
| 275 } | |
| 276 | |
| 277 bool CSection::IsWordArrayEmpty() const { | |
| 278 return m_WordArray.empty(); | |
| 279 } | |
| 280 | |
| 281 int32_t CSection::GetNumberOfWords() const { | |
| 282 return pdfium::CollectionSize<int32_t>(m_WordArray); | |
| 283 } | |
| 284 | |
| 285 const CPVT_WordInfo* CSection::GetWord(int32_t index) const { | |
| 286 if (index < 0 || index >= GetNumberOfWords()) | |
| 287 return nullptr; | |
| 288 return m_WordArray[index].get(); | |
| 289 } | |
| 290 | |
| 291 CPVT_WordInfo* CSection::GetWord(int32_t index) { | |
| 292 if (index < 0 || index >= GetNumberOfWords()) | |
| 293 return nullptr; | |
| 294 return m_WordArray[index].get(); | |
| 295 } | |
| OLD | NEW |