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

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

Issue 1778633003: Collapse xfa/src/fee directories (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: 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/src/fee/fde_txtedtengine.h ('k') | xfa/src/fee/src/fee/fde_txtedtpage.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/src/fee/fde_txtedtengine.h"
8
9 #include <algorithm>
10
11 #include "xfa/src/fee/include/ifde_txtedtbuf.h"
12 #include "xfa/src/fee/include/ifde_txtedtengine.h"
13 #include "xfa/src/fee/include/ifde_txtedtpage.h"
14 #include "xfa/src/fee/src/fee/fde_txtedtbuf.h"
15 #include "xfa/src/fee/src/fee/fde_txtedtparag.h"
16 #include "xfa/src/fdp/include/fde_tto.h"
17
18 #define FDE_PAGEWIDTH_MAX 0xFFFF
19 #define FDE_TXTPLATESIZE (1024 * 12)
20 #define FDE_UNICODE_PARAGRAPH_SPERATOR (0x2029)
21 #define FDE_TXTEDT_DORECORD_INS 0
22 #define FDE_TXTEDT_DORECORD_DEL 1
23
24 IFDE_TxtEdtEngine* IFDE_TxtEdtEngine::Create() {
25 return new CFDE_TxtEdtEngine();
26 }
27 CFDE_TxtEdtEngine::CFDE_TxtEdtEngine()
28 : m_pTextBreak(nullptr),
29 m_nPageLineCount(20),
30 m_nLineCount(0),
31 m_nAnchorPos(-1),
32 m_nLayoutPos(0),
33 m_fCaretPosReserve(0.0),
34 m_nCaret(0),
35 m_bBefore(TRUE),
36 m_nCaretPage(0),
37 m_dwFindFlags(0),
38 m_bLock(FALSE),
39 m_nLimit(0),
40 m_wcAliasChar(L'*'),
41 m_nFirstLineEnd(FDE_TXTEDIT_LINEEND_Auto),
42 m_bAutoLineEnd(TRUE),
43 m_wLineEnd(FDE_UNICODE_PARAGRAPH_SPERATOR) {
44 FXSYS_memset(&m_rtCaret, 0, sizeof(CFX_RectF));
45 m_pTxtBuf = new CFDE_TxtEdtBuf();
46 m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto);
47 }
48 CFDE_TxtEdtEngine::~CFDE_TxtEdtEngine() {
49 if (m_pTxtBuf) {
50 m_pTxtBuf->Release();
51 m_pTxtBuf = NULL;
52 }
53 if (m_pTextBreak) {
54 m_pTextBreak->Release();
55 m_pTextBreak = NULL;
56 }
57 RemoveAllParags();
58 RemoveAllPages();
59 m_Param.pEventSink = NULL;
60 ClearSelection();
61 }
62 void CFDE_TxtEdtEngine::Release() {
63 delete this;
64 }
65 void CFDE_TxtEdtEngine::SetEditParams(const FDE_TXTEDTPARAMS& params) {
66 if (m_pTextBreak == NULL) {
67 m_pTextBreak = IFX_TxtBreak::Create(FX_TXTBREAKPOLICY_None);
68 }
69 FXSYS_memcpy(&m_Param, &params, sizeof(FDE_TXTEDTPARAMS));
70 m_wLineEnd = params.wLineBreakChar;
71 m_bAutoLineEnd = (m_Param.nLineEnd == FDE_TXTEDIT_LINEEND_Auto);
72 UpdateTxtBreak();
73 }
74 const FDE_TXTEDTPARAMS* CFDE_TxtEdtEngine::GetEditParams() const {
75 return &m_Param;
76 }
77 int32_t CFDE_TxtEdtEngine::CountPages() const {
78 if (m_nLineCount == 0) {
79 return 0;
80 }
81 return ((m_nLineCount - 1) / m_nPageLineCount) + 1;
82 }
83 IFDE_TxtEdtPage* CFDE_TxtEdtEngine::GetPage(int32_t nIndex) {
84 if (m_PagePtrArray.GetSize() <= nIndex) {
85 return NULL;
86 }
87 return (IFDE_TxtEdtPage*)m_PagePtrArray[nIndex];
88 }
89 FX_BOOL CFDE_TxtEdtEngine::SetBufChunkSize(int32_t nChunkSize) {
90 return m_pTxtBuf->SetChunkSize(nChunkSize);
91 }
92 void CFDE_TxtEdtEngine::SetTextByStream(IFX_Stream* pStream) {
93 ResetEngine();
94 int32_t nIndex = 0;
95 if (pStream != NULL && pStream->GetLength()) {
96 int32_t nStreamLength = pStream->GetLength();
97 FX_BOOL bValid = TRUE;
98 if (m_nLimit > 0 && nStreamLength > m_nLimit) {
99 bValid = FALSE;
100 }
101 FX_BOOL bPreIsCR = FALSE;
102 if (bValid) {
103 uint8_t bom[4];
104 int32_t nPos = pStream->GetBOM(bom);
105 pStream->Seek(FX_STREAMSEEK_Begin, nPos);
106 int32_t nPlateSize = std::min(nStreamLength, m_pTxtBuf->GetChunkSize());
107 FX_WCHAR* lpwstr = FX_Alloc(FX_WCHAR, nPlateSize);
108 FX_BOOL bEos = false;
109 while (!bEos) {
110 int32_t nRead = pStream->ReadString(lpwstr, nPlateSize, bEos);
111 bPreIsCR = ReplaceParagEnd(lpwstr, nRead, bPreIsCR);
112 m_pTxtBuf->Insert(nIndex, lpwstr, nRead);
113 nIndex += nRead;
114 }
115 FX_Free(lpwstr);
116 }
117 }
118 m_pTxtBuf->Insert(nIndex, &m_wLineEnd, 1);
119 RebuildParagraphs();
120 }
121 void CFDE_TxtEdtEngine::SetText(const CFX_WideString& wsText) {
122 ResetEngine();
123 int32_t nLength = wsText.GetLength();
124 if (nLength > 0) {
125 CFX_WideString wsTemp;
126 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nLength);
127 FXSYS_memcpy(lpBuffer, wsText.c_str(), nLength * sizeof(FX_WCHAR));
128 ReplaceParagEnd(lpBuffer, nLength, FALSE);
129 wsTemp.ReleaseBuffer(nLength);
130 if (m_nLimit > 0 && nLength > m_nLimit) {
131 wsTemp.Delete(m_nLimit, nLength - m_nLimit);
132 nLength = m_nLimit;
133 }
134 m_pTxtBuf->SetText(wsTemp);
135 }
136 m_pTxtBuf->Insert(nLength, &m_wLineEnd, 1);
137 RebuildParagraphs();
138 }
139 int32_t CFDE_TxtEdtEngine::GetTextLength() const {
140 return GetTextBufLength();
141 }
142 void CFDE_TxtEdtEngine::GetText(CFX_WideString& wsText,
143 int32_t nStart,
144 int32_t nCount) {
145 int32_t nTextBufLength = GetTextBufLength();
146 if (nCount == -1) {
147 nCount = nTextBufLength - nStart;
148 }
149 m_pTxtBuf->GetRange(wsText, nStart, nCount);
150 RecoverParagEnd(wsText);
151 }
152
153 void CFDE_TxtEdtEngine::ClearText() {
154 DeleteRange(0, -1);
155 }
156 int32_t CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret) const {
157 rtCaret = m_rtCaret;
158 return m_nCaret;
159 }
160 int32_t CFDE_TxtEdtEngine::GetCaretPos() const {
161 if (IsLocked()) {
162 return 0;
163 }
164 return m_nCaret + (m_bBefore ? 0 : 1);
165 }
166 int32_t CFDE_TxtEdtEngine::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
167 if (IsLocked()) {
168 return 0;
169 }
170 FXSYS_assert(nIndex >= 0 && nIndex <= GetTextBufLength());
171 if (m_PagePtrArray.GetSize() <= m_nCaretPage) {
172 return 0;
173 }
174 m_bBefore = bBefore;
175 m_nCaret = nIndex;
176 MovePage2Char(m_nCaret);
177 GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore);
178 if (!m_bBefore) {
179 m_nCaret++;
180 m_bBefore = TRUE;
181 }
182 m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical)
183 ? m_rtCaret.top
184 : m_rtCaret.left;
185 m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0);
186 m_nAnchorPos = -1;
187 return m_nCaret;
188 }
189 int32_t CFDE_TxtEdtEngine::MoveCaretPos(FDE_TXTEDTMOVECARET eMoveCaret,
190 FX_BOOL bShift,
191 FX_BOOL bCtrl) {
192 if (IsLocked()) {
193 return 0;
194 }
195 if (m_PagePtrArray.GetSize() <= m_nCaretPage) {
196 return 0;
197 }
198 FX_BOOL bSelChange = FALSE;
199 if (IsSelect()) {
200 ClearSelection();
201 bSelChange = TRUE;
202 }
203 if (bShift) {
204 if (m_nAnchorPos == -1) {
205 m_nAnchorPos = m_nCaret;
206 }
207 } else {
208 m_nAnchorPos = -1;
209 }
210 FX_BOOL bVertical = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical;
211 switch (eMoveCaret) {
212 case MC_Left: {
213 if (bVertical) {
214 CFX_PointF ptCaret;
215 if (MoveUp(ptCaret)) {
216 UpdateCaretIndex(ptCaret);
217 }
218 } else {
219 FX_BOOL bBefore = TRUE;
220 int32_t nIndex = MoveBackward(bBefore);
221 if (nIndex >= 0) {
222 UpdateCaretRect(nIndex, bBefore);
223 }
224 }
225 } break;
226 case MC_Right: {
227 if (bVertical) {
228 CFX_PointF ptCaret;
229 if (MoveDown(ptCaret)) {
230 UpdateCaretIndex(ptCaret);
231 }
232 } else {
233 FX_BOOL bBefore = TRUE;
234 int32_t nIndex = MoveForward(bBefore);
235 if (nIndex >= 0) {
236 UpdateCaretRect(nIndex, bBefore);
237 }
238 }
239 } break;
240 case MC_Up: {
241 if (bVertical) {
242 FX_BOOL bBefore = TRUE;
243 int32_t nIndex = MoveBackward(bBefore);
244 if (nIndex >= 0) {
245 UpdateCaretRect(nIndex, bBefore);
246 }
247 } else {
248 CFX_PointF ptCaret;
249 if (MoveUp(ptCaret)) {
250 UpdateCaretIndex(ptCaret);
251 }
252 }
253 } break;
254 case MC_Down: {
255 if (bVertical) {
256 FX_BOOL bBefore = TRUE;
257 int32_t nIndex = MoveForward(bBefore);
258 if (nIndex >= 0) {
259 UpdateCaretRect(nIndex, bBefore);
260 }
261 } else {
262 CFX_PointF ptCaret;
263 if (MoveDown(ptCaret)) {
264 UpdateCaretIndex(ptCaret);
265 }
266 }
267 } break;
268 case MC_WordBackward:
269 break;
270 case MC_WordForward:
271 break;
272 case MC_LineStart:
273 MoveLineStart();
274 break;
275 case MC_LineEnd:
276 MoveLineEnd();
277 break;
278 case MC_ParagStart:
279 MoveParagStart();
280 break;
281 case MC_ParagEnd:
282 MoveParagEnd();
283 break;
284 case MC_PageDown:
285 break;
286 case MC_PageUp:
287 break;
288 case MC_Home:
289 MoveHome();
290 break;
291 case MC_End:
292 MoveEnd();
293 break;
294 default:
295 break;
296 }
297 if (bShift && m_nAnchorPos != -1 && (m_nAnchorPos != m_nCaret)) {
298 AddSelRange(std::min(m_nAnchorPos, m_nCaret),
299 FXSYS_abs(m_nAnchorPos - m_nCaret));
300 m_Param.pEventSink->On_SelChanged(this);
301 }
302 if (bSelChange) {
303 m_Param.pEventSink->On_SelChanged(this);
304 }
305 return m_nCaret;
306 }
307 void CFDE_TxtEdtEngine::Lock() {
308 m_bLock = TRUE;
309 }
310 void CFDE_TxtEdtEngine::Unlock() {
311 m_bLock = FALSE;
312 }
313 FX_BOOL CFDE_TxtEdtEngine::IsLocked() const {
314 return m_bLock;
315 }
316 int32_t CFDE_TxtEdtEngine::Insert(int32_t nStart,
317 const FX_WCHAR* lpText,
318 int32_t nLength) {
319 if (IsLocked()) {
320 return FDE_TXTEDT_MODIFY_RET_F_Locked;
321 }
322 CFX_WideString wsTemp;
323 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nLength);
324 FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR));
325 ReplaceParagEnd(lpBuffer, nLength, FALSE);
326 wsTemp.ReleaseBuffer(nLength);
327 FX_BOOL bPart = FALSE;
328 if (m_nLimit > 0) {
329 int32_t nTotalLength = GetTextBufLength();
330 int32_t nCount = m_SelRangePtrArr.GetSize();
331 for (int32_t i = 0; i < nCount; i++) {
332 FDE_LPTXTEDTSELRANGE lpSelRange = m_SelRangePtrArr.GetAt(i);
333 nTotalLength -= lpSelRange->nCount;
334 }
335 int32_t nExpectLength = nTotalLength + nLength;
336 if (nTotalLength == m_nLimit) {
337 return FDE_TXTEDT_MODIFY_RET_F_Full;
338 }
339 if (nExpectLength > m_nLimit) {
340 nLength -= (nExpectLength - m_nLimit);
341 bPart = TRUE;
342 }
343 }
344 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) ||
345 (m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz)) {
346 int32_t nTemp = nLength;
347 if (m_Param.dwMode & FDE_TEXTEDITMODE_Password) {
348 CFX_WideString wsText;
349 while (nLength > 0) {
350 GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength);
351 int32_t nTotal = wsText.GetLength();
352 FX_WCHAR* lpBuf = wsText.GetBuffer(nTotal);
353 for (int32_t i = 0; i < nTotal; i++) {
354 lpBuf[i] = m_wcAliasChar;
355 }
356 wsText.ReleaseBuffer(nTotal);
357 if (IsFitArea(wsText)) {
358 break;
359 }
360 nLength--;
361 }
362 } else {
363 CFX_WideString wsText;
364 while (nLength > 0) {
365 GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength);
366 if (IsFitArea(wsText)) {
367 break;
368 }
369 nLength--;
370 }
371 }
372 if (nLength == 0) {
373 return FDE_TXTEDT_MODIFY_RET_F_Full;
374 }
375 if (nLength < nTemp) {
376 bPart = TRUE;
377 }
378 }
379 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
380 CFX_WideString wsText;
381 GetPreInsertText(wsText, m_nCaret, lpBuffer, nLength);
382 if (!m_Param.pEventSink->On_Validate(this, wsText)) {
383 return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
384 }
385 }
386 if (IsSelect()) {
387 DeleteSelect();
388 }
389 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
390 IFDE_TxtEdtDoRecord* pRecord =
391 new CFDE_TxtEdtDoRecord_Insert(this, m_nCaret, lpBuffer, nLength);
392 CFX_ByteString bsDoRecord;
393 pRecord->Serialize(bsDoRecord);
394 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
395 pRecord->Release();
396 }
397 GetText(m_ChangeInfo.wsPrevText, 0);
398 Inner_Insert(m_nCaret, lpBuffer, nLength);
399 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
400 m_ChangeInfo.wsInsert = CFX_WideString(lpBuffer, nLength);
401 nStart = m_nCaret;
402 nStart += nLength;
403 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1);
404 FX_BOOL bBefore = TRUE;
405 if (wChar != L'\n' && wChar != L'\r') {
406 nStart--;
407 bBefore = FALSE;
408 }
409 SetCaretPos(nStart, bBefore);
410 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
411 return bPart ? FDE_TXTEDT_MODIFY_RET_S_Part : FDE_TXTEDT_MODIFY_RET_S_Normal;
412 }
413 int32_t CFDE_TxtEdtEngine::Delete(int32_t nStart, FX_BOOL bBackspace) {
414 if (IsLocked()) {
415 return FDE_TXTEDT_MODIFY_RET_F_Locked;
416 }
417 if (IsSelect()) {
418 DeleteSelect();
419 return FDE_TXTEDT_MODIFY_RET_S_Normal;
420 }
421
422 int32_t nCount = 1;
423 if (bBackspace) {
424 if (nStart == 0) {
425 return FDE_TXTEDT_MODIFY_RET_F_Boundary;
426 }
427 if (nStart > 2 && m_pTxtBuf->GetCharByIndex(nStart - 1) == L'\n' &&
428 m_pTxtBuf->GetCharByIndex(nStart - 2) == L'\r') {
429 nStart--;
430 nCount++;
431 }
432 nStart--;
433 } else {
434 if (nStart == GetTextBufLength()) {
435 return FDE_TXTEDT_MODIFY_RET_F_Full;
436 }
437 if ((nStart + 1 < GetTextBufLength()) &&
438 (m_pTxtBuf->GetCharByIndex(nStart) == L'\r') &&
439 (m_pTxtBuf->GetCharByIndex(nStart + 1) == L'\n')) {
440 nCount++;
441 }
442 }
443 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
444 CFX_WideString wsText;
445 GetPreDeleteText(wsText, nStart, nCount);
446 if (!m_Param.pEventSink->On_Validate(this, wsText)) {
447 return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
448 }
449 }
450 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
451 CFX_WideString wsRange;
452 m_pTxtBuf->GetRange(wsRange, nStart, nCount);
453 IFDE_TxtEdtDoRecord* pRecord =
454 new CFDE_TxtEdtDoRecord_DeleteRange(this, nStart, m_nCaret, wsRange);
455 CFX_ByteString bsDoRecord;
456 pRecord->Serialize(bsDoRecord);
457 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
458 pRecord->Release();
459 }
460 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete;
461 GetText(m_ChangeInfo.wsDelete, nStart, nCount);
462 Inner_DeleteRange(nStart, nCount);
463 SetCaretPos(nStart + ((!bBackspace && nStart > 0) ? -1 : 0),
464 (bBackspace || nStart == 0));
465 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
466 return FDE_TXTEDT_MODIFY_RET_S_Normal;
467 }
468 int32_t CFDE_TxtEdtEngine::DeleteRange(int32_t nStart, int32_t nCount) {
469 if (IsLocked()) {
470 return FDE_TXTEDT_MODIFY_RET_F_Locked;
471 }
472 if (nCount == -1) {
473 nCount = GetTextBufLength();
474 }
475 if (nCount == 0) {
476 return FDE_TXTEDT_MODIFY_RET_S_Normal;
477 }
478 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
479 CFX_WideString wsText;
480 GetPreDeleteText(wsText, nStart, nCount);
481 if (!m_Param.pEventSink->On_Validate(this, wsText)) {
482 return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
483 }
484 }
485 DeleteRange_DoRecord(nStart, nCount);
486 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
487 SetCaretPos(nStart, TRUE);
488 return FDE_TXTEDT_MODIFY_RET_S_Normal;
489 }
490 int32_t CFDE_TxtEdtEngine::Replace(int32_t nStart,
491 int32_t nLength,
492 const CFX_WideString& wsReplace) {
493 if (IsLocked()) {
494 return FDE_TXTEDT_MODIFY_RET_F_Locked;
495 }
496 if (nStart < 0 || (nStart + nLength > GetTextBufLength())) {
497 return FDE_TXTEDT_MODIFY_RET_F_Boundary;
498 }
499 if (m_Param.dwMode & FDE_TEXTEDITMODE_Validate) {
500 CFX_WideString wsText;
501 GetPreReplaceText(wsText, nStart, nLength, wsReplace.c_str(),
502 wsReplace.GetLength());
503 if (!m_Param.pEventSink->On_Validate(this, wsText)) {
504 return FDE_TXTEDT_MODIFY_RET_F_Invalidate;
505 }
506 }
507 if (IsSelect()) {
508 ClearSelection();
509 }
510 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Replace;
511 GetText(m_ChangeInfo.wsDelete, nStart, nLength);
512 if (nLength > 0) {
513 Inner_DeleteRange(nStart, nLength);
514 }
515 int32_t nTextLength = wsReplace.GetLength();
516 if (nTextLength > 0) {
517 Inner_Insert(nStart, wsReplace.c_str(), nTextLength);
518 }
519 m_ChangeInfo.wsInsert = CFX_WideString(wsReplace.c_str(), nTextLength);
520 nStart += nTextLength;
521 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nStart - 1);
522 FX_BOOL bBefore = TRUE;
523 if (wChar != L'\n' && wChar != L'\r') {
524 nStart--;
525 bBefore = FALSE;
526 }
527 SetCaretPos(nStart, bBefore);
528 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
529 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
530 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
531 return FDE_TXTEDT_MODIFY_RET_S_Normal;
532 }
533 void CFDE_TxtEdtEngine::SetLimit(int32_t nLimit) {
534 m_nLimit = nLimit;
535 }
536 void CFDE_TxtEdtEngine::SetAliasChar(FX_WCHAR wcAlias) {
537 m_wcAliasChar = wcAlias;
538 }
539
540 void CFDE_TxtEdtEngine::RemoveSelRange(int32_t nStart, int32_t nCount) {
541 FDE_LPTXTEDTSELRANGE lpTemp = NULL;
542 int32_t nRangeCount = m_SelRangePtrArr.GetSize();
543 int32_t i = 0;
544 for (i = 0; i < nRangeCount; i++) {
545 lpTemp = m_SelRangePtrArr[i];
546 if (lpTemp->nStart == nStart && lpTemp->nCount == nCount) {
547 delete lpTemp;
548 m_SelRangePtrArr.RemoveAt(i);
549 return;
550 }
551 }
552 }
553
554 void CFDE_TxtEdtEngine::AddSelRange(int32_t nStart, int32_t nCount) {
555 if (nCount == -1) {
556 nCount = GetTextLength() - nStart;
557 }
558 int32_t nSize = m_SelRangePtrArr.GetSize();
559 if (nSize <= 0) {
560 FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE;
561 lpSelRange->nStart = nStart;
562 lpSelRange->nCount = nCount;
563 m_SelRangePtrArr.Add(lpSelRange);
564 m_Param.pEventSink->On_SelChanged(this);
565 return;
566 }
567 FDE_LPTXTEDTSELRANGE lpTemp = NULL;
568 lpTemp = m_SelRangePtrArr[nSize - 1];
569 if (nStart >= lpTemp->nStart + lpTemp->nCount) {
570 FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE;
571 lpSelRange->nStart = nStart;
572 lpSelRange->nCount = nCount;
573 m_SelRangePtrArr.Add(lpSelRange);
574 m_Param.pEventSink->On_SelChanged(this);
575 return;
576 }
577 int32_t nEnd = nStart + nCount - 1;
578 FX_BOOL bBegin = FALSE;
579 int32_t nRangeBgn = 0;
580 int32_t nRangeCnt = 0;
581 for (int32_t i = 0; i < nSize; i++) {
582 lpTemp = m_SelRangePtrArr[i];
583 int32_t nTempBgn = lpTemp->nStart;
584 int32_t nTempEnd = nTempBgn + lpTemp->nCount - 1;
585 if (bBegin) {
586 if (nEnd < nTempBgn) {
587 break;
588 } else if (nStart >= nTempBgn && nStart <= nTempEnd) {
589 nRangeCnt++;
590 break;
591 }
592 nRangeCnt++;
593 } else {
594 if (nStart <= nTempEnd) {
595 nRangeBgn = i;
596 if (nEnd < nTempBgn) {
597 break;
598 }
599 nRangeCnt = 1;
600 bBegin = TRUE;
601 }
602 }
603 }
604 if (nRangeCnt == 0) {
605 FDE_LPTXTEDTSELRANGE lpSelRange = new FDE_TXTEDTSELRANGE;
606 lpSelRange->nStart = nStart;
607 lpSelRange->nCount = nCount;
608 m_SelRangePtrArr.InsertAt(nRangeBgn, lpSelRange);
609 } else {
610 lpTemp = m_SelRangePtrArr[nRangeBgn];
611 lpTemp->nStart = nStart;
612 lpTemp->nCount = nCount;
613 nRangeCnt--;
614 nRangeBgn++;
615 while (nRangeCnt--) {
616 delete m_SelRangePtrArr[nRangeBgn];
617 m_SelRangePtrArr.RemoveAt(nRangeBgn);
618 }
619 }
620 m_Param.pEventSink->On_SelChanged(this);
621 }
622
623 int32_t CFDE_TxtEdtEngine::CountSelRanges() {
624 return m_SelRangePtrArr.GetSize();
625 }
626 int32_t CFDE_TxtEdtEngine::GetSelRange(int32_t nIndex, int32_t& nStart) {
627 nStart = m_SelRangePtrArr[nIndex]->nStart;
628 return m_SelRangePtrArr[nIndex]->nCount;
629 }
630 void CFDE_TxtEdtEngine::ClearSelection() {
631 int32_t nCount = m_SelRangePtrArr.GetSize();
632 FDE_LPTXTEDTSELRANGE lpRange = NULL;
633 int32_t i = 0;
634 for (i = 0; i < nCount; i++) {
635 lpRange = m_SelRangePtrArr[i];
636 if (lpRange != NULL) {
637 delete lpRange;
638 lpRange = NULL;
639 }
640 }
641 m_SelRangePtrArr.RemoveAll();
642 if (nCount && m_Param.pEventSink) {
643 m_Param.pEventSink->On_SelChanged(this);
644 }
645 }
646 FX_BOOL CFDE_TxtEdtEngine::Redo(const CFX_ByteStringC& bsRedo) {
647 if (IsLocked()) {
648 return FALSE;
649 }
650 if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) {
651 return FALSE;
652 }
653 IFDE_TxtEdtDoRecord* pDoRecord = IFDE_TxtEdtDoRecord::Create(bsRedo);
654 FXSYS_assert(pDoRecord);
655 if (pDoRecord == NULL) {
656 return FALSE;
657 }
658 FX_BOOL bOK = pDoRecord->Redo();
659 pDoRecord->Release();
660 return bOK;
661 }
662 FX_BOOL CFDE_TxtEdtEngine::Undo(const CFX_ByteStringC& bsUndo) {
663 if (IsLocked()) {
664 return FALSE;
665 }
666 if (m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo) {
667 return FALSE;
668 }
669 IFDE_TxtEdtDoRecord* pDoRecord = IFDE_TxtEdtDoRecord::Create(bsUndo);
670 FXSYS_assert(pDoRecord);
671 if (pDoRecord == NULL) {
672 return FALSE;
673 }
674 FX_BOOL bOK = pDoRecord->Undo();
675 pDoRecord->Release();
676 return bOK;
677 }
678 int32_t CFDE_TxtEdtEngine::StartLayout() {
679 Lock();
680 RemoveAllPages();
681 m_nLayoutPos = 0;
682 m_nLineCount = 0;
683 return 0;
684 }
685 int32_t CFDE_TxtEdtEngine::DoLayout(IFX_Pause* pPause) {
686 int32_t nCount = m_ParagPtrArray.GetSize();
687 CFDE_TxtEdtParag* pParag = NULL;
688 int32_t nLineCount = 0;
689 for (; m_nLayoutPos < nCount; m_nLayoutPos++) {
690 pParag = m_ParagPtrArray[m_nLayoutPos];
691 pParag->CalcLines();
692 nLineCount += pParag->m_nLineCount;
693 if ((pPause != NULL) && (nLineCount > m_nPageLineCount) &&
694 pPause->NeedToPauseNow()) {
695 m_nLineCount += nLineCount;
696 return (++m_nLayoutPos * 100) / nCount;
697 }
698 }
699 m_nLineCount += nLineCount;
700 return 100;
701 }
702 void CFDE_TxtEdtEngine::EndLayout() {
703 UpdatePages();
704 int32_t nLength = GetTextLength();
705 if (m_nCaret > nLength) {
706 m_nCaret = nLength;
707 }
708 int32_t nIndex = m_nCaret;
709 if (!m_bBefore) {
710 nIndex--;
711 }
712 m_rtCaret.Set(0, 0, 1, m_Param.fFontSize);
713 Unlock();
714 }
715 FX_BOOL CFDE_TxtEdtEngine::Optimize(IFX_Pause* pPause) {
716 return m_pTxtBuf->Optimize(pPause);
717 }
718 IFDE_TxtEdtBuf* CFDE_TxtEdtEngine::GetTextBuf() const {
719 return (IFDE_TxtEdtBuf*)m_pTxtBuf;
720 }
721 int32_t CFDE_TxtEdtEngine::GetTextBufLength() const {
722 return m_pTxtBuf->GetTextLength() - 1;
723 }
724 IFX_TxtBreak* CFDE_TxtEdtEngine::GetTextBreak() const {
725 return m_pTextBreak;
726 }
727 int32_t CFDE_TxtEdtEngine::GetLineCount() const {
728 return m_nLineCount;
729 }
730 int32_t CFDE_TxtEdtEngine::GetPageLineCount() const {
731 return m_nPageLineCount;
732 }
733 int32_t CFDE_TxtEdtEngine::CountParags() const {
734 return m_ParagPtrArray.GetSize();
735 }
736 IFDE_TxtEdtParag* CFDE_TxtEdtEngine::GetParag(int32_t nParagIndex) const {
737 return m_ParagPtrArray[nParagIndex];
738 }
739 IFX_CharIter* CFDE_TxtEdtEngine::CreateCharIter() {
740 if (!m_pTxtBuf) {
741 return NULL;
742 }
743 return new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf);
744 }
745 int32_t CFDE_TxtEdtEngine::Line2Parag(int32_t nStartParag,
746 int32_t nStartLineofParag,
747 int32_t nLineIndex,
748 int32_t& nStartLine) const {
749 int32_t nLineTotal = nStartLineofParag;
750 int32_t nCount = m_ParagPtrArray.GetSize();
751 CFDE_TxtEdtParag* pParag = NULL;
752 int32_t i = nStartParag;
753 for (; i < nCount; i++) {
754 pParag = m_ParagPtrArray[i];
755 nLineTotal += pParag->m_nLineCount;
756 if (nLineTotal > nLineIndex) {
757 break;
758 }
759 }
760 nStartLine = nLineTotal - pParag->m_nLineCount;
761 return i;
762 }
763 void CFDE_TxtEdtEngine::GetPreDeleteText(CFX_WideString& wsText,
764 int32_t nIndex,
765 int32_t nLength) {
766 GetText(wsText, 0, GetTextBufLength());
767 wsText.Delete(nIndex, nLength);
768 }
769 void CFDE_TxtEdtEngine::GetPreInsertText(CFX_WideString& wsText,
770 int32_t nIndex,
771 const FX_WCHAR* lpText,
772 int32_t nLength) {
773 GetText(wsText, 0, GetTextBufLength());
774 int32_t nSelIndex = 0;
775 int32_t nSelLength = 0;
776 int32_t nSelCount = CountSelRanges();
777 while (nSelCount--) {
778 nSelLength = GetSelRange(nSelCount, nSelIndex);
779 wsText.Delete(nSelIndex, nSelLength);
780 nIndex = nSelIndex;
781 }
782 CFX_WideString wsTemp;
783 int32_t nOldLength = wsText.GetLength();
784 const FX_WCHAR* pOldBuffer = wsText.c_str();
785 FX_WCHAR* lpBuffer = wsTemp.GetBuffer(nOldLength + nLength);
786 FXSYS_memcpy(lpBuffer, pOldBuffer, (nIndex) * sizeof(FX_WCHAR));
787 FXSYS_memcpy(lpBuffer + nIndex, lpText, nLength * sizeof(FX_WCHAR));
788 FXSYS_memcpy(lpBuffer + nIndex + nLength, pOldBuffer + nIndex,
789 (nOldLength - nIndex) * sizeof(FX_WCHAR));
790 wsTemp.ReleaseBuffer(nOldLength + nLength);
791 wsText = wsTemp;
792 }
793 void CFDE_TxtEdtEngine::GetPreReplaceText(CFX_WideString& wsText,
794 int32_t nIndex,
795 int32_t nOriginLength,
796 const FX_WCHAR* lpText,
797 int32_t nLength) {
798 GetText(wsText, 0, GetTextBufLength());
799 int32_t nSelIndex = 0;
800 int32_t nSelLength = 0;
801 int32_t nSelCount = CountSelRanges();
802 while (nSelCount--) {
803 nSelLength = GetSelRange(nSelCount, nSelIndex);
804 wsText.Delete(nSelIndex, nSelLength);
805 }
806 wsText.Delete(nIndex, nOriginLength);
807 int32_t i = 0;
808 for (i = 0; i < nLength; i++) {
809 wsText.Insert(nIndex++, lpText[i]);
810 }
811 }
812 void CFDE_TxtEdtEngine::Inner_Insert(int32_t nStart,
813 const FX_WCHAR* lpText,
814 int32_t nLength) {
815 FXSYS_assert(nLength > 0);
816 FDE_TXTEDTPARAGPOS ParagPos;
817 TextPos2ParagPos(nStart, ParagPos);
818 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
819 int32_t nParagCount = m_ParagPtrArray.GetSize();
820 int32_t i = 0;
821 for (i = ParagPos.nParagIndex + 1; i < nParagCount; i++) {
822 m_ParagPtrArray[i]->m_nCharStart += nLength;
823 }
824 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
825 int32_t nReserveLineCount = pParag->m_nLineCount;
826 int32_t nReserveCharStart = pParag->m_nCharStart;
827 int32_t nLeavePart = ParagPos.nCharIndex;
828 int32_t nCutPart = pParag->m_nCharCount - ParagPos.nCharIndex;
829 int32_t nTextStart = 0;
830 FX_WCHAR wCurChar = L' ';
831 const FX_WCHAR* lpPos = lpText;
832 FX_BOOL bFirst = TRUE;
833 int32_t nParagIndex = ParagPos.nParagIndex;
834 for (i = 0; i < nLength; i++, lpPos++) {
835 wCurChar = *lpPos;
836 if (wCurChar == m_wLineEnd) {
837 if (bFirst) {
838 pParag->m_nCharCount = nLeavePart + (i - nTextStart + 1);
839 pParag->m_nLineCount = -1;
840 nReserveCharStart += pParag->m_nCharCount;
841 bFirst = FALSE;
842 } else {
843 pParag = new CFDE_TxtEdtParag(this);
844 pParag->m_nLineCount = -1;
845 pParag->m_nCharCount = i - nTextStart + 1;
846 pParag->m_nCharStart = nReserveCharStart;
847 m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
848 nReserveCharStart += pParag->m_nCharCount;
849 }
850 nTextStart = i + 1;
851 }
852 }
853 if (bFirst) {
854 pParag->m_nCharCount += nLength;
855 pParag->m_nLineCount = -1;
856 bFirst = FALSE;
857 } else {
858 pParag = new CFDE_TxtEdtParag(this);
859 pParag->m_nLineCount = -1;
860 pParag->m_nCharCount = nLength - nTextStart + nCutPart;
861 pParag->m_nCharStart = nReserveCharStart;
862 m_ParagPtrArray.InsertAt(++nParagIndex, pParag);
863 }
864 m_pTxtBuf->Insert(nStart, lpText, nLength);
865 int32_t nTotalLineCount = 0;
866 for (i = ParagPos.nParagIndex; i <= nParagIndex; i++) {
867 pParag = m_ParagPtrArray[i];
868 pParag->CalcLines();
869 nTotalLineCount += pParag->m_nLineCount;
870 }
871 m_nLineCount += nTotalLineCount - nReserveLineCount;
872 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
873 UpdatePages();
874 }
875
876 void CFDE_TxtEdtEngine::Inner_DeleteRange(int32_t nStart, int32_t nCount) {
877 if (nCount == -1) {
878 nCount = m_pTxtBuf->GetTextLength() - nStart;
879 }
880 int32_t nEnd = nStart + nCount - 1;
881 FXSYS_assert(nStart >= 0 && nEnd < m_pTxtBuf->GetTextLength());
882 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
883 FDE_TXTEDTPARAGPOS ParagPosBgn, ParagPosEnd;
884 TextPos2ParagPos(nStart, ParagPosBgn);
885 TextPos2ParagPos(nEnd, ParagPosEnd);
886 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPosEnd.nParagIndex];
887 FX_BOOL bLastParag = FALSE;
888 if (ParagPosEnd.nCharIndex == pParag->m_nCharCount - 1) {
889 if (ParagPosEnd.nParagIndex < m_ParagPtrArray.GetSize() - 1) {
890 ParagPosEnd.nParagIndex++;
891 } else {
892 bLastParag = TRUE;
893 }
894 }
895 int32_t nTotalLineCount = 0;
896 int32_t nTotalCharCount = 0;
897 int32_t i = 0;
898 for (i = ParagPosBgn.nParagIndex; i <= ParagPosEnd.nParagIndex; i++) {
899 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[i];
900 pParag->CalcLines();
901 nTotalLineCount += pParag->m_nLineCount;
902 nTotalCharCount += pParag->m_nCharCount;
903 }
904 m_pTxtBuf->Delete(nStart, nCount);
905 int32_t nNextParagIndex = (ParagPosBgn.nCharIndex == 0 && bLastParag)
906 ? ParagPosBgn.nParagIndex
907 : (ParagPosBgn.nParagIndex + 1);
908 for (i = nNextParagIndex; i <= ParagPosEnd.nParagIndex; i++) {
909 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[nNextParagIndex];
910 delete pParag;
911 m_ParagPtrArray.RemoveAt(nNextParagIndex);
912 }
913 if (!(bLastParag && ParagPosBgn.nCharIndex == 0)) {
914 pParag = m_ParagPtrArray[ParagPosBgn.nParagIndex];
915 pParag->m_nCharCount = nTotalCharCount - nCount;
916 pParag->CalcLines();
917 nTotalLineCount -= pParag->m_nLineCount;
918 }
919 int32_t nParagCount = m_ParagPtrArray.GetSize();
920 for (i = nNextParagIndex; i < nParagCount; i++) {
921 m_ParagPtrArray[i]->m_nCharStart -= nCount;
922 }
923 m_nLineCount -= nTotalLineCount;
924 UpdatePages();
925 int32_t nPageCount = CountPages();
926 if (m_nCaretPage >= nPageCount) {
927 m_nCaretPage = nPageCount - 1;
928 }
929 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
930 }
931 void CFDE_TxtEdtEngine::DeleteRange_DoRecord(int32_t nStart,
932 int32_t nCount,
933 FX_BOOL bSel) {
934 FXSYS_assert(nStart >= 0);
935 if (nCount == -1) {
936 nCount = GetTextLength() - nStart;
937 }
938 FXSYS_assert((nStart + nCount) <= m_pTxtBuf->GetTextLength());
939
940 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_NoRedoUndo)) {
941 CFX_WideString wsRange;
942 m_pTxtBuf->GetRange(wsRange, nStart, nCount);
943 IFDE_TxtEdtDoRecord* pRecord = new CFDE_TxtEdtDoRecord_DeleteRange(
944 this, nStart, m_nCaret, wsRange, bSel);
945 CFX_ByteString bsDoRecord;
946 pRecord->Serialize(bsDoRecord);
947 m_Param.pEventSink->On_AddDoRecord(this, bsDoRecord);
948 pRecord->Release();
949 }
950 m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete;
951 GetText(m_ChangeInfo.wsDelete, nStart, nCount);
952 Inner_DeleteRange(nStart, nCount);
953 }
954 void CFDE_TxtEdtEngine::ResetEngine() {
955 RemoveAllPages();
956 RemoveAllParags();
957 ClearSelection();
958 m_nCaret = 0;
959 m_pTxtBuf->Clear(FALSE);
960 m_nCaret = 0;
961 }
962 void CFDE_TxtEdtEngine::RebuildParagraphs() {
963 RemoveAllParags();
964 FX_WCHAR wChar = L' ';
965 int32_t nParagStart = 0;
966 int32_t nIndex = 0;
967 IFX_CharIter* pIter = new CFDE_TxtEdtBufIter((CFDE_TxtEdtBuf*)m_pTxtBuf);
968 pIter->SetAt(0);
969 do {
970 wChar = pIter->GetChar();
971 nIndex = pIter->GetAt();
972 if (wChar == m_wLineEnd) {
973 CFDE_TxtEdtParag* pParag = new CFDE_TxtEdtParag(this);
974 pParag->m_nCharStart = nParagStart;
975 pParag->m_nCharCount = nIndex - nParagStart + 1;
976 pParag->m_nLineCount = -1;
977 m_ParagPtrArray.Add(pParag);
978 nParagStart = nIndex + 1;
979 }
980 } while (pIter->Next());
981 pIter->Release();
982 }
983 void CFDE_TxtEdtEngine::RemoveAllParags() {
984 int32_t nCount = m_ParagPtrArray.GetSize();
985 int32_t i = 0;
986 for (i = 0; i < nCount; i++) {
987 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[i];
988 if (pParag) {
989 delete pParag;
990 }
991 }
992 m_ParagPtrArray.RemoveAll();
993 }
994 void CFDE_TxtEdtEngine::RemoveAllPages() {
995 int32_t nCount = m_PagePtrArray.GetSize();
996 int32_t i = 0;
997 for (i = 0; i < nCount; i++) {
998 IFDE_TxtEdtPage* pPage = m_PagePtrArray[i];
999 if (pPage) {
1000 pPage->Release();
1001 }
1002 }
1003 m_PagePtrArray.RemoveAll();
1004 }
1005 void CFDE_TxtEdtEngine::UpdateParags() {
1006 int32_t nCount = m_ParagPtrArray.GetSize();
1007 if (nCount == 0) {
1008 return;
1009 }
1010 CFDE_TxtEdtParag* pParag = NULL;
1011 int32_t nLineCount = 0;
1012 int32_t i = 0;
1013 for (i = 0; i < nCount; i++) {
1014 pParag = m_ParagPtrArray[i];
1015 if (pParag->m_nLineCount == -1) {
1016 pParag->CalcLines();
1017 }
1018 nLineCount += pParag->m_nLineCount;
1019 }
1020 m_nLineCount = nLineCount;
1021 }
1022 void CFDE_TxtEdtEngine::UpdatePages() {
1023 if (m_nLineCount == 0) {
1024 return;
1025 }
1026 int32_t nPageCount = (m_nLineCount - 1) / (m_nPageLineCount) + 1;
1027 int32_t nSize = m_PagePtrArray.GetSize();
1028 if (nSize == nPageCount) {
1029 return;
1030 }
1031 if (nSize > nPageCount) {
1032 IFDE_TxtEdtPage* pPage = NULL;
1033 int32_t i = 0;
1034 for (i = nSize - 1; i >= nPageCount; i--) {
1035 pPage = m_PagePtrArray[i];
1036 if (pPage) {
1037 pPage->Release();
1038 }
1039 m_PagePtrArray.RemoveAt(i);
1040 }
1041 m_Param.pEventSink->On_PageCountChanged(this);
1042 return;
1043 }
1044 if (nSize < nPageCount) {
1045 IFDE_TxtEdtPage* pPage = NULL;
1046 int32_t i = 0;
1047 for (i = nSize; i < nPageCount; i++) {
1048 pPage = IFDE_TxtEdtPage::Create(this, i);
1049 m_PagePtrArray.Add(pPage);
1050 }
1051 m_Param.pEventSink->On_PageCountChanged(this);
1052 return;
1053 }
1054 }
1055 void CFDE_TxtEdtEngine::UpdateTxtBreak() {
1056 FX_DWORD dwStyle = m_pTextBreak->GetLayoutStyles();
1057 if (m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines) {
1058 dwStyle &= ~FX_TXTLAYOUTSTYLE_SingleLine;
1059 } else {
1060 dwStyle |= FX_TXTLAYOUTSTYLE_SingleLine;
1061 }
1062 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
1063 dwStyle |= FX_TXTLAYOUTSTYLE_VerticalLayout;
1064 } else {
1065 dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalLayout;
1066 }
1067 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve) {
1068 dwStyle |= FX_TXTLAYOUTSTYLE_ReverseLine;
1069 } else {
1070 dwStyle &= ~FX_TXTLAYOUTSTYLE_ReverseLine;
1071 }
1072 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_RTL) {
1073 dwStyle |= FX_TXTLAYOUTSTYLE_RTLReadingOrder;
1074 } else {
1075 dwStyle &= ~FX_TXTLAYOUTSTYLE_RTLReadingOrder;
1076 }
1077 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) {
1078 dwStyle |= FX_TXTLAYOUTSTYLE_CombText;
1079 } else {
1080 dwStyle &= ~FX_TXTLAYOUTSTYLE_CombText;
1081 }
1082 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CharVertial) {
1083 dwStyle |= FX_TXTLAYOUTSTYLE_VerticalChars;
1084 } else {
1085 dwStyle &= ~FX_TXTLAYOUTSTYLE_VerticalChars;
1086 }
1087 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ExpandTab) {
1088 dwStyle |= FX_TXTLAYOUTSTYLE_ExpandTab;
1089 } else {
1090 dwStyle &= ~FX_TXTLAYOUTSTYLE_ExpandTab;
1091 }
1092 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicContext) {
1093 dwStyle |= FX_TXTLAYOUTSTYLE_ArabicContext;
1094 } else {
1095 dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicContext;
1096 }
1097 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_ArabicShapes) {
1098 dwStyle |= FX_TXTLAYOUTSTYLE_ArabicShapes;
1099 } else {
1100 dwStyle &= ~FX_TXTLAYOUTSTYLE_ArabicShapes;
1101 }
1102 m_pTextBreak->SetLayoutStyles(dwStyle);
1103 FX_DWORD dwAligment = 0;
1104 if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Justified) {
1105 dwAligment |= FX_TXTLINEALIGNMENT_Justified;
1106 } else if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Distributed) {
1107 dwAligment |= FX_TXTLINEALIGNMENT_Distributed;
1108 }
1109 if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Center) {
1110 dwAligment |= FX_TXTLINEALIGNMENT_Center;
1111 } else if (m_Param.dwAlignment & FDE_TEXTEDITALIGN_Right) {
1112 dwAligment |= FX_TXTLINEALIGNMENT_Right;
1113 }
1114 m_pTextBreak->SetAlignment(dwAligment);
1115 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
1116 if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) {
1117 m_pTextBreak->SetLineWidth(m_Param.fPlateHeight);
1118 } else {
1119 m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX);
1120 }
1121 } else {
1122 if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) {
1123 m_pTextBreak->SetLineWidth(m_Param.fPlateWidth);
1124 } else {
1125 m_pTextBreak->SetLineWidth(FDE_PAGEWIDTH_MAX);
1126 }
1127 }
1128 m_nPageLineCount = m_Param.nLineCount;
1129 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) {
1130 FX_FLOAT fCombWidth =
1131 m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical
1132 ? m_Param.fPlateHeight
1133 : m_Param.fPlateWidth;
1134 if (m_nLimit > 0) {
1135 fCombWidth /= m_nLimit;
1136 }
1137 m_pTextBreak->SetCombWidth(fCombWidth);
1138 }
1139 m_pTextBreak->SetFont(m_Param.pFont);
1140 m_pTextBreak->SetFontSize(m_Param.fFontSize);
1141 m_pTextBreak->SetTabWidth(m_Param.fTabWidth, m_Param.bTabEquidistant);
1142 m_pTextBreak->SetDefaultChar(m_Param.wDefChar);
1143 m_pTextBreak->SetParagraphBreakChar(m_Param.wLineBreakChar);
1144 m_pTextBreak->SetCharRotation(m_Param.nCharRotation);
1145 m_pTextBreak->SetLineBreakTolerance(m_Param.fFontSize * 0.2f);
1146 m_pTextBreak->SetHorizontalScale(m_Param.nHorzScale);
1147 m_pTextBreak->SetCharSpace(m_Param.fCharSpace);
1148 }
1149 FX_BOOL CFDE_TxtEdtEngine::ReplaceParagEnd(FX_WCHAR*& lpText,
1150 int32_t& nLength,
1151 FX_BOOL bPreIsCR) {
1152 for (int32_t i = 0; i < nLength; i++) {
1153 FX_WCHAR wc = lpText[i];
1154 switch (wc) {
1155 case L'\r': {
1156 lpText[i] = m_wLineEnd;
1157 bPreIsCR = TRUE;
1158 } break;
1159 case L'\n': {
1160 if (bPreIsCR == TRUE) {
1161 int32_t nNext = i + 1;
1162 if (nNext < nLength) {
1163 FXSYS_memmove(lpText + i, lpText + nNext,
1164 (nLength - nNext) * sizeof(FX_WCHAR));
1165 }
1166 i--;
1167 nLength--;
1168 bPreIsCR = FALSE;
1169 if (m_bAutoLineEnd) {
1170 m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CRLF;
1171 m_bAutoLineEnd = FALSE;
1172 }
1173 } else {
1174 lpText[i] = m_wLineEnd;
1175 if (m_bAutoLineEnd) {
1176 m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_LF;
1177 m_bAutoLineEnd = FALSE;
1178 }
1179 }
1180 } break;
1181 default: {
1182 if (bPreIsCR && m_bAutoLineEnd) {
1183 m_nFirstLineEnd = FDE_TXTEDIT_LINEEND_CR;
1184 m_bAutoLineEnd = FALSE;
1185 }
1186 bPreIsCR = FALSE;
1187 } break;
1188 }
1189 }
1190 return bPreIsCR;
1191 }
1192 void CFDE_TxtEdtEngine::RecoverParagEnd(CFX_WideString& wsText) {
1193 FX_WCHAR wc = (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CR) ? L'\n' : L'\r';
1194 if (m_nFirstLineEnd == FDE_TXTEDIT_LINEEND_CRLF) {
1195 CFX_ArrayTemplate<int32_t> PosArr;
1196 int32_t nLength = wsText.GetLength();
1197 int32_t i = 0;
1198 FX_WCHAR* lpPos = (FX_WCHAR*)(const FX_WCHAR*)wsText;
1199 for (i = 0; i < nLength; i++, lpPos++) {
1200 if (*lpPos == m_wLineEnd) {
1201 *lpPos = wc;
1202 PosArr.Add(i);
1203 }
1204 }
1205 const FX_WCHAR* lpSrcBuf = wsText.c_str();
1206 CFX_WideString wsTemp;
1207 int32_t nCount = PosArr.GetSize();
1208 FX_WCHAR* lpDstBuf = wsTemp.GetBuffer(nLength + nCount);
1209 int32_t nDstPos = 0;
1210 int32_t nSrcPos = 0;
1211 for (i = 0; i < nCount; i++) {
1212 int32_t nPos = PosArr[i];
1213 int32_t nCopyLen = nPos - nSrcPos + 1;
1214 FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos,
1215 nCopyLen * sizeof(FX_WCHAR));
1216 nDstPos += nCopyLen;
1217 nSrcPos += nCopyLen;
1218 lpDstBuf[nDstPos] = L'\n';
1219 nDstPos++;
1220 }
1221 if (nSrcPos < nLength) {
1222 FXSYS_memcpy(lpDstBuf + nDstPos, lpSrcBuf + nSrcPos,
1223 (nLength - nSrcPos) * sizeof(FX_WCHAR));
1224 }
1225 wsTemp.ReleaseBuffer(nLength + nCount);
1226 wsText = wsTemp;
1227 } else {
1228 int32_t nLength = wsText.GetLength();
1229 FX_WCHAR* lpBuf = (FX_WCHAR*)(const FX_WCHAR*)wsText;
1230 for (int32_t i = 0; i < nLength; i++, lpBuf++) {
1231 if (*lpBuf == m_wLineEnd) {
1232 *lpBuf = wc;
1233 }
1234 }
1235 }
1236 }
1237 int32_t CFDE_TxtEdtEngine::MovePage2Char(int32_t nIndex) {
1238 FXSYS_assert(nIndex >= 0);
1239 FXSYS_assert(nIndex <= m_pTxtBuf->GetTextLength());
1240 if (m_nCaretPage >= 0) {
1241 IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage];
1242 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
1243 int32_t nPageCharStart = pPage->GetCharStart();
1244 int32_t nPageCharCount = pPage->GetCharCount();
1245 if (nIndex >= nPageCharStart && nIndex < nPageCharStart + nPageCharCount) {
1246 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
1247 return m_nCaretPage;
1248 }
1249 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
1250 }
1251 CFDE_TxtEdtParag* pParag = NULL;
1252 int32_t nLineCount = 0;
1253 int32_t nParagCount = m_ParagPtrArray.GetSize();
1254 int32_t i = 0;
1255 for (i = 0; i < nParagCount; i++) {
1256 pParag = m_ParagPtrArray[i];
1257 if (pParag->m_nCharStart <= nIndex &&
1258 nIndex < (pParag->m_nCharStart + pParag->m_nCharCount)) {
1259 break;
1260 }
1261 nLineCount += pParag->m_nLineCount;
1262 }
1263 pParag->LoadParag();
1264 int32_t nLineStart = -1;
1265 int32_t nLineCharCount = -1;
1266 for (i = 0; i < pParag->m_nLineCount; i++) {
1267 pParag->GetLineRange(i, nLineStart, nLineCharCount);
1268 if (nLineStart <= nIndex && nIndex < (nLineStart + nLineCharCount)) {
1269 break;
1270 }
1271 }
1272 FXSYS_assert(i < pParag->m_nLineCount);
1273 nLineCount += (i + 1);
1274 m_nCaretPage = (nLineCount - 1) / m_nPageLineCount + 1 - 1;
1275 m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
1276 pParag->UnloadParag();
1277 return m_nCaretPage;
1278 }
1279 void CFDE_TxtEdtEngine::TextPos2ParagPos(int32_t nIndex,
1280 FDE_TXTEDTPARAGPOS& ParagPos) const {
1281 FXSYS_assert(nIndex >= 0 && nIndex < m_pTxtBuf->GetTextLength());
1282 int32_t nCount = m_ParagPtrArray.GetSize();
1283 int32_t nBgn = 0;
1284 int32_t nMid = 0;
1285 int32_t nEnd = nCount - 1;
1286 while (nEnd > nBgn) {
1287 nMid = (nBgn + nEnd) / 2;
1288 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[nMid];
1289 if (nIndex < pParag->m_nCharStart) {
1290 nEnd = nMid - 1;
1291 } else if (nIndex >= (pParag->m_nCharStart + pParag->m_nCharCount)) {
1292 nBgn = nMid + 1;
1293 } else {
1294 break;
1295 }
1296 }
1297 if (nBgn == nEnd) {
1298 nMid = nBgn;
1299 }
1300 FXSYS_assert(nIndex >= m_ParagPtrArray[nMid]->m_nCharStart &&
1301 (nIndex < m_ParagPtrArray[nMid]->m_nCharStart +
1302 m_ParagPtrArray[nMid]->m_nCharCount));
1303 ParagPos.nParagIndex = nMid;
1304 ParagPos.nCharIndex = nIndex - m_ParagPtrArray[nMid]->m_nCharStart;
1305 }
1306 int32_t CFDE_TxtEdtEngine::MoveForward(FX_BOOL& bBefore) {
1307 if (m_nCaret == m_pTxtBuf->GetTextLength() - 1) {
1308 return -1;
1309 }
1310 int32_t nCaret = m_nCaret;
1311 if ((nCaret + 1 < m_pTxtBuf->GetTextLength()) &&
1312 (m_pTxtBuf->GetCharByIndex(nCaret) == L'\r') &&
1313 (m_pTxtBuf->GetCharByIndex(nCaret + 1) == L'\n')) {
1314 nCaret++;
1315 }
1316 nCaret++;
1317 bBefore = TRUE;
1318 return nCaret;
1319 }
1320 int32_t CFDE_TxtEdtEngine::MoveBackward(FX_BOOL& bBefore) {
1321 if (m_nCaret == 0) {
1322 return FALSE;
1323 }
1324 int32_t nCaret = m_nCaret;
1325 if (nCaret > 2 && m_pTxtBuf->GetCharByIndex(nCaret - 1) == L'\n' &&
1326 m_pTxtBuf->GetCharByIndex(nCaret - 2) == L'\r') {
1327 nCaret--;
1328 }
1329 nCaret--;
1330 bBefore = TRUE;
1331 return nCaret;
1332 }
1333 FX_BOOL CFDE_TxtEdtEngine::MoveUp(CFX_PointF& ptCaret) {
1334 IFDE_TxtEdtPage* pPage = GetPage(m_nCaretPage);
1335 const CFX_RectF& rtContent = pPage->GetContentsBox();
1336 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
1337 ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 - m_Param.fLineSpace;
1338 ptCaret.y = m_fCaretPosReserve;
1339 FX_BOOL bLineReserve =
1340 m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve;
1341 if (ptCaret.x < rtContent.left) {
1342 if (bLineReserve) {
1343 if (m_nCaretPage == CountPages() - 1) {
1344 return FALSE;
1345 }
1346 } else {
1347 if (m_nCaretPage == 0) {
1348 return FALSE;
1349 }
1350 }
1351 if (bLineReserve) {
1352 m_nCaretPage++;
1353 } else {
1354 m_nCaretPage--;
1355 }
1356 m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
1357 ptCaret.x -= rtContent.left;
1358 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage);
1359 ptCaret.x += pCurPage->GetContentsBox().right();
1360 }
1361 } else {
1362 ptCaret.x = m_fCaretPosReserve;
1363 ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 - m_Param.fLineSpace;
1364 if (ptCaret.y < rtContent.top) {
1365 if (m_nCaretPage == 0) {
1366 return FALSE;
1367 }
1368 ptCaret.y -= rtContent.top;
1369 m_nCaretPage--;
1370 m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
1371 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage);
1372 ptCaret.y += pCurPage->GetContentsBox().bottom();
1373 }
1374 }
1375 return TRUE;
1376 }
1377 FX_BOOL CFDE_TxtEdtEngine::MoveDown(CFX_PointF& ptCaret) {
1378 IFDE_TxtEdtPage* pPage = GetPage(m_nCaretPage);
1379 const CFX_RectF& rtContent = pPage->GetContentsBox();
1380 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
1381 ptCaret.x = m_rtCaret.left + m_rtCaret.width / 2 + m_Param.fLineSpace;
1382 ptCaret.y = m_fCaretPosReserve;
1383 if (ptCaret.x >= rtContent.right()) {
1384 FX_BOOL bLineReserve =
1385 m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_LineReserve;
1386 if (bLineReserve) {
1387 if (m_nCaretPage == 0) {
1388 return FALSE;
1389 }
1390 } else {
1391 if (m_nCaretPage == CountPages() - 1) {
1392 return FALSE;
1393 }
1394 }
1395 if (bLineReserve) {
1396 m_nCaretPage--;
1397 } else {
1398 m_nCaretPage++;
1399 }
1400 m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
1401 ptCaret.x -= rtContent.right();
1402 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage);
1403 ptCaret.x += pCurPage->GetContentsBox().left;
1404 }
1405 } else {
1406 ptCaret.x = m_fCaretPosReserve;
1407 ptCaret.y = m_rtCaret.top + m_rtCaret.height / 2 + m_Param.fLineSpace;
1408 if (ptCaret.y >= rtContent.bottom()) {
1409 if (m_nCaretPage == CountPages() - 1) {
1410 return FALSE;
1411 }
1412 ptCaret.y -= rtContent.bottom();
1413 m_nCaretPage++;
1414 m_Param.pEventSink->On_PageChange(this, m_nCaretPage);
1415 IFDE_TxtEdtPage* pCurPage = GetPage(m_nCaretPage);
1416 ptCaret.y += pCurPage->GetContentsBox().top;
1417 }
1418 }
1419 return TRUE;
1420 }
1421 FX_BOOL CFDE_TxtEdtEngine::MoveLineStart() {
1422 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
1423 FDE_TXTEDTPARAGPOS ParagPos;
1424 TextPos2ParagPos(nIndex, ParagPos);
1425 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
1426 pParag->LoadParag();
1427 int32_t nLineCount = pParag->m_nLineCount;
1428 int32_t i = 0;
1429 int32_t nStart = 0;
1430 int32_t nCount = 0;
1431 for (; i < nLineCount; i++) {
1432 pParag->GetLineRange(i, nStart, nCount);
1433 if (nIndex >= nStart && nIndex < nStart + nCount) {
1434 break;
1435 }
1436 }
1437 UpdateCaretRect(nStart, TRUE);
1438 pParag->UnloadParag();
1439 return TRUE;
1440 }
1441 FX_BOOL CFDE_TxtEdtEngine::MoveLineEnd() {
1442 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
1443 FDE_TXTEDTPARAGPOS ParagPos;
1444 TextPos2ParagPos(nIndex, ParagPos);
1445 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
1446 pParag->LoadParag();
1447 int32_t nLineCount = pParag->m_nLineCount;
1448 int32_t i = 0;
1449 int32_t nStart = 0;
1450 int32_t nCount = 0;
1451 for (; i < nLineCount; i++) {
1452 pParag->GetLineRange(i, nStart, nCount);
1453 if (nIndex >= nStart && nIndex < nStart + nCount) {
1454 break;
1455 }
1456 }
1457 nIndex = nStart + nCount - 1;
1458 FXSYS_assert(nIndex <= GetTextBufLength());
1459 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex);
1460 FX_BOOL bBefore = FALSE;
1461 if (nIndex <= GetTextBufLength()) {
1462 if (wChar == L'\r') {
1463 bBefore = TRUE;
1464 } else if (wChar == L'\n' && nIndex > nStart) {
1465 bBefore = TRUE;
1466 nIndex--;
1467 wChar = m_pTxtBuf->GetCharByIndex(nIndex);
1468 if (wChar != L'\r') {
1469 nIndex++;
1470 }
1471 }
1472 }
1473 UpdateCaretRect(nIndex, bBefore);
1474 pParag->UnloadParag();
1475 return TRUE;
1476 }
1477 FX_BOOL CFDE_TxtEdtEngine::MoveParagStart() {
1478 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
1479 FDE_TXTEDTPARAGPOS ParagPos;
1480 TextPos2ParagPos(nIndex, ParagPos);
1481 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
1482 UpdateCaretRect(pParag->m_nCharStart, TRUE);
1483 return TRUE;
1484 }
1485 FX_BOOL CFDE_TxtEdtEngine::MoveParagEnd() {
1486 int32_t nIndex = m_bBefore ? m_nCaret : m_nCaret - 1;
1487 FDE_TXTEDTPARAGPOS ParagPos;
1488 TextPos2ParagPos(nIndex, ParagPos);
1489 CFDE_TxtEdtParag* pParag = m_ParagPtrArray[ParagPos.nParagIndex];
1490 nIndex = pParag->m_nCharStart + pParag->m_nCharCount - 1;
1491 FX_WCHAR wChar = m_pTxtBuf->GetCharByIndex(nIndex);
1492 if (wChar == L'\n' && nIndex > 0) {
1493 nIndex--;
1494 wChar = m_pTxtBuf->GetCharByIndex(nIndex);
1495 if (wChar != L'\r') {
1496 nIndex++;
1497 }
1498 }
1499 UpdateCaretRect(nIndex, TRUE);
1500 return TRUE;
1501 }
1502 FX_BOOL CFDE_TxtEdtEngine::MoveHome() {
1503 UpdateCaretRect(0, TRUE);
1504 return TRUE;
1505 }
1506 FX_BOOL CFDE_TxtEdtEngine::MoveEnd() {
1507 UpdateCaretRect(GetTextBufLength(), TRUE);
1508 return TRUE;
1509 }
1510
1511 FX_BOOL CFDE_TxtEdtEngine::IsFitArea(CFX_WideString& wsText) {
1512 IFDE_TextOut* pTextOut = IFDE_TextOut::Create();
1513 pTextOut->SetLineSpace(m_Param.fLineSpace);
1514 pTextOut->SetFont(m_Param.pFont);
1515 pTextOut->SetFontSize(m_Param.fFontSize);
1516 CFX_RectF rcText;
1517 FXSYS_memset(&rcText, 0, sizeof(rcText));
1518 FX_DWORD dwStyle = 0;
1519 if (!(m_Param.dwMode & FDE_TEXTEDITMODE_MultiLines)) {
1520 dwStyle |= FDE_TTOSTYLE_SingleLine;
1521 }
1522 if (m_Param.dwMode & FDE_TEXTEDITMODE_AutoLineWrap) {
1523 dwStyle |= FDE_TTOSTYLE_LineWrap;
1524 rcText.width = m_Param.fPlateWidth;
1525 } else {
1526 rcText.width = 65535;
1527 }
1528 pTextOut->SetStyles(dwStyle);
1529 wsText += L"\n";
1530 pTextOut->CalcLogicSize(wsText, wsText.GetLength(), rcText);
1531 pTextOut->Release();
1532 wsText.Delete(wsText.GetLength() - 1);
1533 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Horz) &&
1534 (rcText.width > m_Param.fPlateWidth)) {
1535 return FALSE;
1536 }
1537 if ((m_Param.dwMode & FDE_TEXTEDITMODE_LimitArea_Vert) &&
1538 (rcText.height > m_Param.fLineSpace * m_Param.nLineCount)) {
1539 return FALSE;
1540 }
1541 return TRUE;
1542 }
1543 void CFDE_TxtEdtEngine::UpdateCaretRect(int32_t nIndex, FX_BOOL bBefore) {
1544 MovePage2Char(nIndex);
1545 GetCaretRect(m_rtCaret, m_nCaretPage, nIndex, bBefore);
1546 m_nCaret = nIndex;
1547 m_bBefore = bBefore;
1548 if (!m_bBefore) {
1549 m_nCaret++;
1550 m_bBefore = TRUE;
1551 }
1552 m_fCaretPosReserve = (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical)
1553 ? m_rtCaret.top
1554 : m_rtCaret.left;
1555 m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage, 0);
1556 }
1557 void CFDE_TxtEdtEngine::GetCaretRect(CFX_RectF& rtCaret,
1558 int32_t nPageIndex,
1559 int32_t nCaret,
1560 FX_BOOL bBefore) {
1561 IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage];
1562 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
1563 FX_BOOL bCombText = m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText;
1564 int32_t nIndexInpage = nCaret - pPage->GetCharStart();
1565 if (bBefore && bCombText && nIndexInpage > 0) {
1566 nIndexInpage--;
1567 bBefore = FALSE;
1568 }
1569 int32_t nBIDILevel = pPage->GetCharRect(nIndexInpage, rtCaret, bCombText);
1570 if (m_Param.dwLayoutStyles & FDE_TEXTEDITLAYOUT_DocVertical) {
1571 if ((!FX_IsOdd(nBIDILevel) && !bBefore) ||
1572 (FX_IsOdd(nBIDILevel) && bBefore)) {
1573 rtCaret.Offset(0, rtCaret.height - 1.0f);
1574 }
1575 if (rtCaret.height == 0 && rtCaret.top > 1.0f) {
1576 rtCaret.top -= 1.0f;
1577 }
1578 rtCaret.height = 1.0f;
1579 } else {
1580 if ((!FX_IsOdd(nBIDILevel) && !bBefore) ||
1581 (FX_IsOdd(nBIDILevel) && bBefore)) {
1582 rtCaret.Offset(rtCaret.width - 1.0f, 0);
1583 }
1584 if (rtCaret.width == 0 && rtCaret.left > 1.0f) {
1585 rtCaret.left -= 1.0f;
1586 }
1587 rtCaret.width = 1.0f;
1588 }
1589 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
1590 }
1591 void CFDE_TxtEdtEngine::UpdateCaretIndex(const CFX_PointF& ptCaret) {
1592 IFDE_TxtEdtPage* pPage = m_PagePtrArray[m_nCaretPage];
1593 m_Param.pEventSink->On_PageLoad(this, m_nCaretPage, 0);
1594 m_nCaret = pPage->GetCharIndex(ptCaret, m_bBefore);
1595 GetCaretRect(m_rtCaret, m_nCaretPage, m_nCaret, m_bBefore);
1596 if (!m_bBefore) {
1597 m_nCaret++;
1598 m_bBefore = TRUE;
1599 }
1600 m_Param.pEventSink->On_CaretChanged(this, m_nCaretPage);
1601 m_Param.pEventSink->On_PageUnload(this, m_nCaretPage, 0);
1602 }
1603 FX_BOOL CFDE_TxtEdtEngine::IsSelect() {
1604 return m_SelRangePtrArr.GetSize() > 0;
1605 }
1606 void CFDE_TxtEdtEngine::DeleteSelect() {
1607 int32_t nCountRange = CountSelRanges();
1608 if (nCountRange > 0) {
1609 int32_t nSelStart;
1610 int32_t nSelCount;
1611 while (nCountRange > 0) {
1612 nSelCount = GetSelRange(--nCountRange, nSelStart);
1613 FDE_LPTXTEDTSELRANGE lpTemp = m_SelRangePtrArr[nCountRange];
1614 delete lpTemp;
1615 m_SelRangePtrArr.RemoveAt(nCountRange);
1616 DeleteRange_DoRecord(nSelStart, nSelCount, TRUE);
1617 }
1618 ClearSelection();
1619 m_Param.pEventSink->On_TextChanged(this, m_ChangeInfo);
1620 m_Param.pEventSink->On_SelChanged(this);
1621 SetCaretPos(nSelStart, TRUE);
1622 return;
1623 }
1624 }
1625 IFDE_TxtEdtDoRecord* IFDE_TxtEdtDoRecord::Create(
1626 const CFX_ByteStringC& bsDoRecord) {
1627 const FX_CHAR* lpBuf = bsDoRecord.GetCStr();
1628 int32_t nType = *((int32_t*)lpBuf);
1629 switch (nType) {
1630 case FDE_TXTEDT_DORECORD_INS:
1631 return new CFDE_TxtEdtDoRecord_Insert(bsDoRecord);
1632 case FDE_TXTEDT_DORECORD_DEL:
1633 return new CFDE_TxtEdtDoRecord_DeleteRange(bsDoRecord);
1634 default:
1635 break;
1636 }
1637 return NULL;
1638 }
1639 CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert(
1640 const CFX_ByteStringC& bsDoRecord) {
1641 Deserialize(bsDoRecord);
1642 }
1643 CFDE_TxtEdtDoRecord_Insert::CFDE_TxtEdtDoRecord_Insert(
1644 CFDE_TxtEdtEngine* pEngine,
1645 int32_t nCaret,
1646 const FX_WCHAR* lpText,
1647 int32_t nLength)
1648 : m_pEngine(pEngine), m_nCaret(nCaret) {
1649 FXSYS_assert(pEngine);
1650 FX_WCHAR* lpBuffer = m_wsInsert.GetBuffer(nLength);
1651 FXSYS_memcpy(lpBuffer, lpText, nLength * sizeof(FX_WCHAR));
1652 m_wsInsert.ReleaseBuffer();
1653 }
1654 CFDE_TxtEdtDoRecord_Insert::~CFDE_TxtEdtDoRecord_Insert() {}
1655 void CFDE_TxtEdtDoRecord_Insert::Release() {
1656 delete this;
1657 }
1658 FX_BOOL CFDE_TxtEdtDoRecord_Insert::Undo() {
1659 if (m_pEngine->IsSelect()) {
1660 m_pEngine->ClearSelection();
1661 }
1662 m_pEngine->Inner_DeleteRange(m_nCaret, m_wsInsert.GetLength());
1663 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
1664 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Delete;
1665 m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert;
1666 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
1667 m_pEngine->SetCaretPos(m_nCaret, TRUE);
1668 return TRUE;
1669 }
1670 FX_BOOL CFDE_TxtEdtDoRecord_Insert::Redo() {
1671 m_pEngine->Inner_Insert(m_nCaret, m_wsInsert.c_str(), m_wsInsert.GetLength());
1672 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
1673 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
1674 m_pEngine->m_ChangeInfo.wsDelete = m_wsInsert;
1675 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
1676 m_pEngine->SetCaretPos(m_nCaret, FALSE);
1677 return TRUE;
1678 }
1679 void CFDE_TxtEdtDoRecord_Insert::Serialize(CFX_ByteString& bsDoRecord) const {
1680 CFX_ArchiveSaver ArchiveSaver;
1681 ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_INS);
1682 ArchiveSaver << (int32_t)(uintptr_t)m_pEngine;
1683 ArchiveSaver << m_nCaret;
1684 ArchiveSaver << m_wsInsert;
1685 int32_t nLength = ArchiveSaver.GetLength();
1686 const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer();
1687 FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength);
1688 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
1689 bsDoRecord.ReleaseBuffer(nLength);
1690 }
1691 void CFDE_TxtEdtDoRecord_Insert::Deserialize(
1692 const CFX_ByteStringC& bsDoRecord) {
1693 CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(),
1694 bsDoRecord.GetLength());
1695 int32_t nType = 0;
1696 ArchiveLoader >> nType;
1697 FXSYS_assert(nType == FDE_TXTEDT_DORECORD_INS);
1698 int32_t nEngine = 0;
1699 ArchiveLoader >> nEngine;
1700 m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine;
1701 ArchiveLoader >> m_nCaret;
1702 ArchiveLoader >> m_wsInsert;
1703 }
1704 CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange(
1705 const CFX_ByteStringC& bsDoRecord) {
1706 Deserialize(bsDoRecord);
1707 }
1708 CFDE_TxtEdtDoRecord_DeleteRange::CFDE_TxtEdtDoRecord_DeleteRange(
1709 CFDE_TxtEdtEngine* pEngine,
1710 int32_t nIndex,
1711 int32_t nCaret,
1712 const CFX_WideString& wsRange,
1713 FX_BOOL bSel)
1714 : m_pEngine(pEngine),
1715 m_bSel(bSel),
1716 m_nIndex(nIndex),
1717 m_nCaret(nCaret),
1718 m_wsRange(wsRange) {
1719 FXSYS_assert(pEngine);
1720 }
1721 CFDE_TxtEdtDoRecord_DeleteRange::~CFDE_TxtEdtDoRecord_DeleteRange() {}
1722 void CFDE_TxtEdtDoRecord_DeleteRange::Release() {
1723 delete this;
1724 }
1725 FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Undo() {
1726 if (m_pEngine->IsSelect()) {
1727 m_pEngine->ClearSelection();
1728 }
1729 m_pEngine->Inner_Insert(m_nIndex, m_wsRange.c_str(), m_wsRange.GetLength());
1730 if (m_bSel) {
1731 m_pEngine->AddSelRange(m_nIndex, m_wsRange.GetLength());
1732 }
1733 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
1734 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
1735 m_pEngine->m_ChangeInfo.wsDelete = m_wsRange;
1736 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
1737 m_pEngine->SetCaretPos(m_nCaret, TRUE);
1738 return TRUE;
1739 }
1740 FX_BOOL CFDE_TxtEdtDoRecord_DeleteRange::Redo() {
1741 m_pEngine->Inner_DeleteRange(m_nIndex, m_wsRange.GetLength());
1742 if (m_bSel) {
1743 m_pEngine->RemoveSelRange(m_nIndex, m_wsRange.GetLength());
1744 }
1745 FDE_TXTEDTPARAMS& Param = m_pEngine->m_Param;
1746 m_pEngine->m_ChangeInfo.nChangeType = FDE_TXTEDT_TEXTCHANGE_TYPE_Insert;
1747 m_pEngine->m_ChangeInfo.wsDelete = m_wsRange;
1748 Param.pEventSink->On_TextChanged(m_pEngine, m_pEngine->m_ChangeInfo);
1749 m_pEngine->SetCaretPos(m_nIndex, TRUE);
1750 return TRUE;
1751 }
1752 void CFDE_TxtEdtDoRecord_DeleteRange::Serialize(
1753 CFX_ByteString& bsDoRecord) const {
1754 CFX_ArchiveSaver ArchiveSaver;
1755 ArchiveSaver << int32_t(FDE_TXTEDT_DORECORD_DEL);
1756 ArchiveSaver << (int32_t)(uintptr_t)m_pEngine;
1757 ArchiveSaver << (int32_t)m_bSel;
1758 ArchiveSaver << m_nIndex;
1759 ArchiveSaver << m_nCaret;
1760 ArchiveSaver << m_wsRange;
1761 int32_t nLength = ArchiveSaver.GetLength();
1762 const uint8_t* lpSrcBuf = ArchiveSaver.GetBuffer();
1763 FX_CHAR* lpDstBuf = bsDoRecord.GetBuffer(nLength);
1764 FXSYS_memcpy(lpDstBuf, lpSrcBuf, nLength);
1765 bsDoRecord.ReleaseBuffer(nLength);
1766 }
1767 void CFDE_TxtEdtDoRecord_DeleteRange::Deserialize(
1768 const CFX_ByteStringC& bsDoRecord) {
1769 CFX_ArchiveLoader ArchiveLoader((const uint8_t*)bsDoRecord.GetCStr(),
1770 bsDoRecord.GetLength());
1771 int32_t nType = 0;
1772 ArchiveLoader >> nType;
1773 FXSYS_assert(nType == FDE_TXTEDT_DORECORD_DEL);
1774 int32_t nEngine = 0;
1775 ArchiveLoader >> nEngine;
1776 m_pEngine = (CFDE_TxtEdtEngine*)(uintptr_t)nEngine;
1777 int32_t iSel = 0;
1778 ArchiveLoader >> iSel;
1779 m_bSel = !!iSel;
1780 ArchiveLoader >> m_nIndex;
1781 ArchiveLoader >> m_nCaret;
1782 ArchiveLoader >> m_wsRange;
1783 }
OLDNEW
« no previous file with comments | « xfa/src/fee/src/fee/fde_txtedtengine.h ('k') | xfa/src/fee/src/fee/fde_txtedtpage.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698