Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Side by Side Diff: xfa/src/fee/fde_txtedtbuf.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/src/fee/fde_txtedtbuf.h ('k') | xfa/src/fee/fde_txtedtengine.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2014 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 "xfa/src/fee/fde_txtedtbuf.h"
8
9 #include <algorithm>
10
11 #include "xfa/src/fee/ifde_txtedtbuf.h"
12 #include "xfa/src/fee/ifde_txtedtengine.h"
13
14 #define FDE_DEFCHUNKCOUNT 2
15 #define FDE_TXTEDT_FORMATBLOCK_BGN 0xFFF9
16 #define FDE_TXTEDT_FORMATBLOCK_END 0xFFFB
17 #define FDE_TXTEDT_ZEROWIDTHSPACE 0x200B
18
19 CFDE_TxtEdtBufIter::CFDE_TxtEdtBufIter(CFDE_TxtEdtBuf* pBuf, FX_WCHAR wcAlias)
20 : m_pBuf(pBuf),
21 m_nCurChunk(0),
22 m_nCurIndex(0),
23 m_nIndex(0),
24 m_Alias(wcAlias) {
25 FXSYS_assert(m_pBuf);
26 }
27 CFDE_TxtEdtBufIter::~CFDE_TxtEdtBufIter() {}
28 void CFDE_TxtEdtBufIter::Release() {
29 delete this;
30 }
31 FX_BOOL CFDE_TxtEdtBufIter::Next(FX_BOOL bPrev) {
32 if (bPrev) {
33 if (m_nIndex == 0) {
34 return FALSE;
35 }
36 FXSYS_assert(m_nCurChunk < m_pBuf->m_Chunks.GetSize());
37 CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER lpChunk = NULL;
38 if (m_nCurIndex > 0) {
39 m_nCurIndex--;
40 } else {
41 while (m_nCurChunk > 0) {
42 --m_nCurChunk;
43 lpChunk =
44 (CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk];
45 if (lpChunk->nUsed > 0) {
46 m_nCurIndex = lpChunk->nUsed - 1;
47 break;
48 }
49 }
50 }
51 FXSYS_assert(m_nCurChunk >= 0);
52 m_nIndex--;
53 return TRUE;
54 } else {
55 if (m_nIndex >= (m_pBuf->m_nTotal - 1)) {
56 return FALSE;
57 }
58 FXSYS_assert(m_nCurChunk < m_pBuf->m_Chunks.GetSize());
59 CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER lpChunk =
60 (CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk];
61 if (lpChunk->nUsed != (m_nCurIndex + 1)) {
62 m_nCurIndex++;
63 } else {
64 int32_t nEnd = m_pBuf->m_Chunks.GetSize() - 1;
65 while (m_nCurChunk < nEnd) {
66 m_nCurChunk++;
67 CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER lpChunkTemp =
68 (CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk];
69 if (lpChunkTemp->nUsed > 0) {
70 m_nCurIndex = 0;
71 break;
72 }
73 }
74 }
75 m_nIndex++;
76 return TRUE;
77 }
78 }
79 void CFDE_TxtEdtBufIter::SetAt(int32_t nIndex) {
80 FXSYS_assert(nIndex >= 0 && nIndex < m_pBuf->m_nTotal);
81 CFDE_TxtEdtBuf::FDE_CHUNKPLACE cp;
82 m_pBuf->Index2CP(nIndex, cp);
83 m_nIndex = nIndex;
84 m_nCurChunk = cp.nChunkIndex;
85 m_nCurIndex = cp.nCharIndex;
86 }
87 int32_t CFDE_TxtEdtBufIter::GetAt() const {
88 return m_nIndex;
89 }
90 FX_WCHAR CFDE_TxtEdtBufIter::GetChar() {
91 FXSYS_assert(m_nIndex >= 0 && m_nIndex < m_pBuf->m_nTotal);
92 if (m_Alias == 0 || m_nIndex == (m_pBuf->m_nTotal - 1)) {
93 return ((CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk])
94 ->wChars[m_nCurIndex];
95 }
96 return m_Alias;
97 }
98 FX_BOOL CFDE_TxtEdtBufIter::IsEOF(FX_BOOL bTail) const {
99 return bTail ? m_nIndex == (m_pBuf->GetTextLength() - 2) : m_nIndex == 0;
100 }
101 IFX_CharIter* CFDE_TxtEdtBufIter::Clone() {
102 CFDE_TxtEdtBufIter* pIter = new CFDE_TxtEdtBufIter(m_pBuf);
103 pIter->m_nCurChunk = m_nCurChunk;
104 pIter->m_nCurIndex = m_nCurIndex;
105 pIter->m_nIndex = m_nIndex;
106 pIter->m_Alias = m_Alias;
107 return pIter;
108 }
109 CFDE_TxtEdtBuf::CFDE_TxtEdtBuf(int32_t nDefChunkSize)
110 : m_nChunkSize(nDefChunkSize),
111 m_nTotal(0),
112 m_bChanged(FALSE),
113 m_pAllocator(NULL) {
114 FXSYS_assert(m_nChunkSize);
115 ResetChunkBuffer(FDE_DEFCHUNKCOUNT, m_nChunkSize);
116 }
117 void CFDE_TxtEdtBuf::Release() {
118 delete this;
119 }
120 CFDE_TxtEdtBuf::~CFDE_TxtEdtBuf() {
121 Clear(TRUE);
122 m_pAllocator->Release();
123 m_Chunks.RemoveAll();
124 }
125 FX_BOOL CFDE_TxtEdtBuf::SetChunkSize(int32_t nChunkSize) {
126 FXSYS_assert(nChunkSize);
127 ResetChunkBuffer(FDE_DEFCHUNKCOUNT, nChunkSize);
128 return TRUE;
129 }
130 int32_t CFDE_TxtEdtBuf::GetChunkSize() const {
131 return m_nChunkSize;
132 }
133 int32_t CFDE_TxtEdtBuf::GetTextLength() const {
134 return m_nTotal;
135 }
136 void CFDE_TxtEdtBuf::SetText(const CFX_WideString& wsText) {
137 FXSYS_assert(!wsText.IsEmpty());
138 Clear(FALSE);
139 int32_t nTextLength = wsText.GetLength();
140 int32_t nNeedCount =
141 ((nTextLength - 1) / m_nChunkSize + 1) - m_Chunks.GetSize();
142 int32_t i = 0;
143 for (i = 0; i < nNeedCount; i++) {
144 FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(
145 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR));
146 lpChunk->nUsed = 0;
147 m_Chunks.Add(lpChunk);
148 }
149 int32_t nTotalCount = m_Chunks.GetSize();
150 const FX_WCHAR* lpSrcBuf = wsText.c_str();
151 int32_t nLeave = nTextLength;
152 int32_t nCopyedLength = m_nChunkSize;
153 for (i = 0; i < nTotalCount && nLeave > 0; i++) {
154 if (nLeave < nCopyedLength) {
155 nCopyedLength = nLeave;
156 }
157 FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[i];
158 FXSYS_memcpy(lpChunk->wChars, lpSrcBuf, nCopyedLength * sizeof(FX_WCHAR));
159 nLeave -= nCopyedLength;
160 lpSrcBuf += nCopyedLength;
161 lpChunk->nUsed = nCopyedLength;
162 }
163 m_nTotal = nTextLength;
164 m_bChanged = TRUE;
165 }
166 void CFDE_TxtEdtBuf::GetText(CFX_WideString& wsText) const {
167 GetRange(wsText, 0, m_nTotal);
168 }
169 FX_WCHAR CFDE_TxtEdtBuf::GetCharByIndex(int32_t nIndex) const {
170 FXSYS_assert(nIndex >= 0 && nIndex < GetTextLength());
171 FDE_LPCHUNKHEADER pChunkHeader = NULL;
172 int32_t nTotal = 0;
173 int32_t nCount = m_Chunks.GetSize();
174 int32_t i = 0;
175 for (i = 0; i < nCount; i++) {
176 pChunkHeader = (FDE_LPCHUNKHEADER)m_Chunks[i];
177 nTotal += pChunkHeader->nUsed;
178 if (nTotal > nIndex) {
179 break;
180 }
181 }
182 FXSYS_assert(pChunkHeader);
183 return pChunkHeader->wChars[pChunkHeader->nUsed - (nTotal - nIndex)];
184 }
185 void CFDE_TxtEdtBuf::GetRange(CFX_WideString& wsText,
186 int32_t nBegin,
187 int32_t nLength) const {
188 FDE_CHUNKPLACE cp;
189 Index2CP(nBegin, cp);
190 int32_t nLeave = nLength;
191 int32_t nCount = m_Chunks.GetSize();
192 FX_WCHAR* lpDstBuf = wsText.GetBuffer(nLength);
193 int32_t nChunkIndex = cp.nChunkIndex;
194 FDE_LPCHUNKHEADER lpChunkHeader = (FDE_LPCHUNKHEADER)m_Chunks[nChunkIndex];
195 int32_t nCopyLength = lpChunkHeader->nUsed - cp.nCharIndex;
196 FX_WCHAR* lpSrcBuf = lpChunkHeader->wChars + cp.nCharIndex;
197 while (nLeave > 0) {
198 if (nLeave <= nCopyLength) {
199 nCopyLength = nLeave;
200 }
201 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nCopyLength * sizeof(FX_WCHAR));
202 nChunkIndex++;
203 if (nChunkIndex >= nCount) {
204 break;
205 }
206 lpChunkHeader = (FDE_LPCHUNKHEADER)m_Chunks[nChunkIndex];
207 lpSrcBuf = lpChunkHeader->wChars;
208 nLeave -= nCopyLength;
209 lpDstBuf += nCopyLength;
210 nCopyLength = lpChunkHeader->nUsed;
211 }
212 wsText.ReleaseBuffer();
213 }
214 void CFDE_TxtEdtBuf::Insert(int32_t nPos,
215 const FX_WCHAR* lpText,
216 int32_t nLength) {
217 FXSYS_assert(nPos >= 0 && nPos <= m_nTotal);
218 FDE_CHUNKPLACE cp;
219 Index2CP(nPos, cp);
220 int32_t nLengthTemp = nLength;
221 if (cp.nCharIndex != 0) {
222 FDE_LPCHUNKHEADER lpNewChunk = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(
223 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR));
224 FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cp.nChunkIndex];
225 int32_t nCopy = lpChunk->nUsed - cp.nCharIndex;
226 FXSYS_memcpy(lpNewChunk->wChars, lpChunk->wChars + cp.nCharIndex,
227 nCopy * sizeof(FX_WCHAR));
228 lpChunk->nUsed -= nCopy;
229 cp.nChunkIndex++;
230 m_Chunks.InsertAt(cp.nChunkIndex, lpNewChunk);
231 lpNewChunk->nUsed = nCopy;
232 cp.nCharIndex = 0;
233 }
234 if (cp.nChunkIndex != 0) {
235 FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cp.nChunkIndex - 1];
236 if (lpChunk->nUsed != m_nChunkSize) {
237 cp.nChunkIndex--;
238 int32_t nFree = m_nChunkSize - lpChunk->nUsed;
239 int32_t nCopy = std::min(nLengthTemp, nFree);
240 FXSYS_memcpy(lpChunk->wChars + lpChunk->nUsed, lpText,
241 nCopy * sizeof(FX_WCHAR));
242 lpText += nCopy;
243 nLengthTemp -= nCopy;
244 lpChunk->nUsed += nCopy;
245 cp.nChunkIndex++;
246 }
247 }
248 while (nLengthTemp > 0) {
249 FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(
250 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR));
251 FXSYS_assert(lpChunk);
252 int32_t nCopy = std::min(nLengthTemp, m_nChunkSize);
253 FXSYS_memcpy(lpChunk->wChars, lpText, nCopy * sizeof(FX_WCHAR));
254 lpText += nCopy;
255 nLengthTemp -= nCopy;
256 lpChunk->nUsed = nCopy;
257 m_Chunks.InsertAt(cp.nChunkIndex, lpChunk);
258 cp.nChunkIndex++;
259 }
260 m_nTotal += nLength;
261 m_bChanged = TRUE;
262 }
263 void CFDE_TxtEdtBuf::Delete(int32_t nIndex, int32_t nLength) {
264 FXSYS_assert(nLength > 0 && nIndex >= 0 && nIndex + nLength <= m_nTotal);
265 FDE_CHUNKPLACE cpEnd;
266 Index2CP(nIndex + nLength - 1, cpEnd);
267 m_nTotal -= nLength;
268 FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cpEnd.nChunkIndex];
269 int32_t nFirstPart = cpEnd.nCharIndex + 1;
270 int32_t nMovePart = lpChunk->nUsed - nFirstPart;
271 if (nMovePart != 0) {
272 int32_t nDelete = std::min(nFirstPart, nLength);
273 FXSYS_memmove(lpChunk->wChars + nFirstPart - nDelete,
274 lpChunk->wChars + nFirstPart, nMovePart * sizeof(FX_WCHAR));
275 lpChunk->nUsed -= nDelete;
276 nLength -= nDelete;
277 cpEnd.nChunkIndex--;
278 }
279 while (nLength > 0) {
280 lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cpEnd.nChunkIndex];
281 int32_t nDeleted = std::min(lpChunk->nUsed, nLength);
282 lpChunk->nUsed -= nDeleted;
283 if (lpChunk->nUsed == 0) {
284 m_pAllocator->Free(lpChunk);
285 m_Chunks.RemoveAt(cpEnd.nChunkIndex);
286 lpChunk = NULL;
287 }
288 nLength -= nDeleted;
289 cpEnd.nChunkIndex--;
290 }
291 m_bChanged = TRUE;
292 }
293 void CFDE_TxtEdtBuf::Clear(FX_BOOL bRelease) {
294 int32_t i = 0;
295 int32_t nCount = m_Chunks.GetSize();
296 if (bRelease) {
297 while (i < nCount) {
298 m_pAllocator->Free(m_Chunks[i++]);
299 }
300 m_Chunks.RemoveAll();
301 } else {
302 while (i < nCount) {
303 ((FDE_LPCHUNKHEADER)m_Chunks[i++])->nUsed = 0;
304 }
305 }
306 m_nTotal = 0;
307 m_bChanged = TRUE;
308 }
309 FX_BOOL CFDE_TxtEdtBuf::Optimize(IFX_Pause* pPause) {
310 if (m_bChanged == FALSE) {
311 return TRUE;
312 }
313 if (m_nTotal == 0) {
314 return TRUE;
315 }
316 int32_t nCount = m_Chunks.GetSize();
317 if (nCount == 0) {
318 return TRUE;
319 }
320 int32_t i = 0;
321 for (; i < nCount; i++) {
322 FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[i];
323 if (lpChunk->nUsed == 0) {
324 m_pAllocator->Free(lpChunk);
325 m_Chunks.RemoveAt(i);
326 --i;
327 --nCount;
328 }
329 }
330 if (pPause != NULL && pPause->NeedToPauseNow()) {
331 return FALSE;
332 }
333 FDE_LPCHUNKHEADER lpPreChunk = (FDE_LPCHUNKHEADER)m_Chunks[0];
334 FDE_LPCHUNKHEADER lpCurChunk = NULL;
335 for (i = 1; i < nCount; i++) {
336 lpCurChunk = (FDE_LPCHUNKHEADER)m_Chunks[i];
337 if (lpPreChunk->nUsed + lpCurChunk->nUsed <= m_nChunkSize) {
338 FXSYS_memcpy(lpPreChunk->wChars + lpPreChunk->nUsed, lpCurChunk->wChars,
339 lpCurChunk->nUsed * sizeof(FX_WCHAR));
340 lpPreChunk->nUsed += lpCurChunk->nUsed;
341 m_pAllocator->Free(lpCurChunk);
342 m_Chunks.RemoveAt(i);
343 --i;
344 --nCount;
345 } else {
346 lpPreChunk = lpCurChunk;
347 }
348 if (pPause != NULL && pPause->NeedToPauseNow()) {
349 return FALSE;
350 }
351 }
352 m_bChanged = FALSE;
353 return TRUE;
354 }
355 void CFDE_TxtEdtBuf::ResetChunkBuffer(int32_t nDefChunkCount,
356 int32_t nChunkSize) {
357 FXSYS_assert(nChunkSize);
358 FXSYS_assert(nDefChunkCount);
359 if (m_pAllocator) {
360 m_pAllocator->Release();
361 m_pAllocator = NULL;
362 }
363 m_Chunks.RemoveAll();
364 m_nChunkSize = nChunkSize;
365 int32_t nChunkLength =
366 sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR);
367 m_pAllocator =
368 FX_CreateAllocator(FX_ALLOCTYPE_Fixed, nDefChunkCount, nChunkLength);
369 FXSYS_assert(m_pAllocator);
370 FDE_LPCHUNKHEADER lpChunkHeader =
371 (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(nChunkLength);
372 FXSYS_assert(lpChunkHeader);
373 lpChunkHeader->nUsed = 0;
374 m_Chunks.Add(lpChunkHeader);
375 m_nTotal = 0;
376 }
377 int32_t CFDE_TxtEdtBuf::CP2Index(const FDE_CHUNKPLACE& cp) const {
378 int32_t nTotal = cp.nCharIndex;
379 int32_t i = 0;
380 for (i = 0; i < cp.nChunkIndex; i++) {
381 nTotal += ((FDE_LPCHUNKHEADER)m_Chunks[i])->nUsed;
382 }
383 return nTotal;
384 }
385 void CFDE_TxtEdtBuf::Index2CP(int32_t nIndex, FDE_CHUNKPLACE& cp) const {
386 FXSYS_assert(nIndex <= GetTextLength());
387 if (nIndex == m_nTotal) {
388 cp.nChunkIndex = m_Chunks.GetSize() - 1;
389 cp.nCharIndex = ((FDE_LPCHUNKHEADER)m_Chunks[cp.nChunkIndex])->nUsed;
390 return;
391 }
392 int32_t i = 0;
393 int32_t nTotal = 0;
394 int32_t nCount = m_Chunks.GetSize();
395 for (; i < nCount; i++) {
396 nTotal += ((FDE_LPCHUNKHEADER)m_Chunks[i])->nUsed;
397 if (nTotal > nIndex) {
398 break;
399 }
400 }
401 cp.nChunkIndex = i;
402 cp.nCharIndex = ((FDE_LPCHUNKHEADER)m_Chunks[i])->nUsed - (nTotal - nIndex);
403 }
OLDNEW
« no previous file with comments | « xfa/src/fee/fde_txtedtbuf.h ('k') | xfa/src/fee/fde_txtedtengine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698