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 "../../include/fxedit/fxet_stub.h"
8 #include "../../include/fxedit/fxet_edit.h"
9 
10 #define FX_EDIT_UNDO_MAXITEM				10000
11 
12 /* ---------------------------- CFX_Edit_Iterator ---------------------------- */
13 
CFX_Edit_Iterator(CFX_Edit * pEdit,IPDF_VariableText_Iterator * pVTIterator)14 CFX_Edit_Iterator::CFX_Edit_Iterator(CFX_Edit * pEdit,IPDF_VariableText_Iterator * pVTIterator) :
15 	m_pEdit(pEdit),
16 	m_pVTIterator(pVTIterator)
17 {
18 }
19 
~CFX_Edit_Iterator()20 CFX_Edit_Iterator::~CFX_Edit_Iterator()
21 {
22 }
23 
NextWord()24 FX_BOOL	CFX_Edit_Iterator::NextWord()
25 {
26 	ASSERT(m_pVTIterator != NULL);
27 
28 	return m_pVTIterator->NextWord();
29 }
30 
NextLine()31 FX_BOOL CFX_Edit_Iterator::NextLine()
32 {
33 	ASSERT(m_pVTIterator != NULL);
34 
35 	return m_pVTIterator->NextLine();
36 }
37 
NextSection()38 FX_BOOL CFX_Edit_Iterator::NextSection()
39 {
40 	ASSERT(m_pVTIterator != NULL);
41 
42 	return m_pVTIterator->NextSection();
43 }
44 
PrevWord()45 FX_BOOL	CFX_Edit_Iterator::PrevWord()
46 {
47 	ASSERT(m_pVTIterator != NULL);
48 
49 	return m_pVTIterator->PrevWord();
50 }
51 
PrevLine()52 FX_BOOL	CFX_Edit_Iterator::PrevLine()
53 {
54 	ASSERT(m_pVTIterator != NULL);
55 
56 	return m_pVTIterator->PrevLine();
57 }
58 
PrevSection()59 FX_BOOL	CFX_Edit_Iterator::PrevSection()
60 {
61 	ASSERT(m_pVTIterator != NULL);
62 
63 	return m_pVTIterator->PrevSection();
64 }
65 
GetWord(CPVT_Word & word) const66 FX_BOOL CFX_Edit_Iterator::GetWord(CPVT_Word & word) const
67 {
68 	ASSERT(m_pEdit != NULL);
69 	ASSERT(m_pVTIterator != NULL);
70 
71 	if (m_pVTIterator->GetWord(word))
72 	{
73 		word.ptWord = m_pEdit->VTToEdit(word.ptWord);
74 		return TRUE;
75 	}
76 
77 	return FALSE;
78 }
79 
GetLine(CPVT_Line & line) const80 FX_BOOL CFX_Edit_Iterator::GetLine(CPVT_Line & line) const
81 {
82 	ASSERT(m_pEdit != NULL);
83 	ASSERT(m_pVTIterator != NULL);
84 
85 	if (m_pVTIterator->GetLine(line))
86 	{
87 		line.ptLine = m_pEdit->VTToEdit(line.ptLine);
88 		return TRUE;
89 	}
90 
91 	return FALSE;
92 }
93 
GetSection(CPVT_Section & section) const94 FX_BOOL CFX_Edit_Iterator::GetSection(CPVT_Section & section) const
95 {
96 	ASSERT(m_pEdit != NULL);
97 	ASSERT(m_pVTIterator != NULL);
98 
99 	if (m_pVTIterator->GetSection(section))
100 	{
101 		section.rcSection = m_pEdit->VTToEdit(section.rcSection);
102 		return TRUE;
103 	}
104 
105 	return FALSE;
106 }
107 
SetAt(FX_INT32 nWordIndex)108 void CFX_Edit_Iterator::SetAt(FX_INT32 nWordIndex)
109 {
110 	ASSERT(m_pVTIterator != NULL);
111 
112 	m_pVTIterator->SetAt(nWordIndex);
113 }
114 
SetAt(const CPVT_WordPlace & place)115 void CFX_Edit_Iterator::SetAt(const CPVT_WordPlace & place)
116 {
117 	ASSERT(m_pVTIterator != NULL);
118 
119 	m_pVTIterator->SetAt(place);
120 }
121 
GetAt() const122 const CPVT_WordPlace & CFX_Edit_Iterator::GetAt() const
123 {
124 	ASSERT(m_pVTIterator != NULL);
125 
126 	return m_pVTIterator->GetAt();
127 }
128 
GetEdit() const129 IFX_Edit* CFX_Edit_Iterator::GetEdit() const
130 {
131 	return m_pEdit;
132 }
133 
134 /* --------------------------- CFX_Edit_Provider ------------------------------- */
135 
CFX_Edit_Provider(IFX_Edit_FontMap * pFontMap)136 CFX_Edit_Provider::CFX_Edit_Provider(IFX_Edit_FontMap * pFontMap) : m_pFontMap(pFontMap)
137 {
138 	ASSERT(m_pFontMap != NULL);
139 }
140 
~CFX_Edit_Provider()141 CFX_Edit_Provider::~CFX_Edit_Provider()
142 {
143 }
144 
GetFontMap()145 IFX_Edit_FontMap* CFX_Edit_Provider::GetFontMap()
146 {
147 	return m_pFontMap;
148 }
149 
GetCharWidth(FX_INT32 nFontIndex,FX_WORD word,FX_INT32 nWordStyle)150 FX_INT32 CFX_Edit_Provider::GetCharWidth(FX_INT32 nFontIndex, FX_WORD word, FX_INT32 nWordStyle)
151 {
152 	if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
153 	{
154 		FX_DWORD charcode = word;
155 
156 		if (pPDFFont->IsUnicodeCompatible())
157 			charcode = pPDFFont->CharCodeFromUnicode(word);
158 		else
159 			charcode = m_pFontMap->CharCodeFromUnicode(nFontIndex, word);
160 
161 		if (charcode != -1)
162 			return pPDFFont->GetCharWidthF(charcode);
163 	}
164 
165 	return 0;
166 }
167 
GetTypeAscent(FX_INT32 nFontIndex)168 FX_INT32 CFX_Edit_Provider::GetTypeAscent(FX_INT32 nFontIndex)
169 {
170 	if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
171 		return pPDFFont->GetTypeAscent();
172 
173 	return 0;
174 }
175 
GetTypeDescent(FX_INT32 nFontIndex)176 FX_INT32 CFX_Edit_Provider::GetTypeDescent(FX_INT32 nFontIndex)
177 {
178 	if (CPDF_Font* pPDFFont = m_pFontMap->GetPDFFont(nFontIndex))
179 		return pPDFFont->GetTypeDescent();
180 
181 	return 0;
182 }
183 
GetWordFontIndex(FX_WORD word,FX_INT32 charset,FX_INT32 nFontIndex)184 FX_INT32 CFX_Edit_Provider::GetWordFontIndex(FX_WORD word, FX_INT32 charset, FX_INT32 nFontIndex)
185 {
186 	return m_pFontMap->GetWordFontIndex(word,charset,nFontIndex);
187 }
188 
GetDefaultFontIndex()189 FX_INT32 CFX_Edit_Provider::GetDefaultFontIndex()
190 {
191 	return 0;
192 }
193 
IsLatinWord(FX_WORD word)194 FX_BOOL	CFX_Edit_Provider::IsLatinWord(FX_WORD word)
195 {
196 	return FX_EDIT_ISLATINWORD(word);
197 }
198 
199 /* --------------------------------- CFX_Edit_Refresh --------------------------------- */
200 
CFX_Edit_Refresh()201 CFX_Edit_Refresh::CFX_Edit_Refresh()
202 {
203 }
204 
~CFX_Edit_Refresh()205 CFX_Edit_Refresh::~CFX_Edit_Refresh()
206 {
207 }
208 
BeginRefresh()209 void CFX_Edit_Refresh::BeginRefresh()
210 {
211 	m_RefreshRects.Empty();
212 	m_OldLineRects = m_NewLineRects;
213 }
214 
Push(const CPVT_WordRange & linerange,const CPDF_Rect & rect)215 void CFX_Edit_Refresh::Push(const CPVT_WordRange & linerange,const CPDF_Rect & rect)
216 {
217 	m_NewLineRects.Add(linerange,rect);
218 }
219 
NoAnalyse()220 void CFX_Edit_Refresh::NoAnalyse()
221 {
222 	{
223 		for (FX_INT32 i = 0, sz = m_OldLineRects.GetSize(); i < sz; i++)
224 			if (CFX_Edit_LineRect * pOldRect = m_OldLineRects.GetAt(i))
225 				m_RefreshRects.Add(pOldRect->m_rcLine);
226 	}
227 
228 	{
229 		for (FX_INT32 i = 0, sz = m_NewLineRects.GetSize(); i < sz; i++)
230 			if (CFX_Edit_LineRect * pNewRect = m_NewLineRects.GetAt(i))
231 				m_RefreshRects.Add(pNewRect->m_rcLine);
232 	}
233 }
234 
Analyse(FX_INT32 nAlignment)235 void CFX_Edit_Refresh::Analyse(FX_INT32 nAlignment)
236 {
237 	FX_BOOL bLineTopChanged = FALSE;
238 	CPDF_Rect rcResult;
239 	FX_FLOAT fWidthDiff;
240 
241 	FX_INT32 szMax = FX_EDIT_MAX(m_OldLineRects.GetSize(),m_NewLineRects.GetSize());
242 	FX_INT32 i = 0;
243 
244 	while (i < szMax)
245 	{
246 		CFX_Edit_LineRect * pOldRect = m_OldLineRects.GetAt(i);
247 		CFX_Edit_LineRect * pNewRect = m_NewLineRects.GetAt(i);
248 
249 		if (pOldRect)
250 		{
251 			if (pNewRect)
252 			{
253 				if (bLineTopChanged)
254 				{
255 					rcResult = pOldRect->m_rcLine;
256 					rcResult.Union(pNewRect->m_rcLine);
257 					m_RefreshRects.Add(rcResult);
258 				}
259 				else
260 				{
261 					if (*pNewRect != *pOldRect)
262 					{
263 						if (!pNewRect->IsSameTop(*pOldRect) || !pNewRect->IsSameHeight(*pOldRect))
264 						{
265 							bLineTopChanged = TRUE;
266 							continue;
267 						}
268 
269 						if (nAlignment == 0)
270 						{
271 							if (pNewRect->m_wrLine.BeginPos != pOldRect->m_wrLine.BeginPos)
272 							{
273 								rcResult = pOldRect->m_rcLine;
274 								rcResult.Union(pNewRect->m_rcLine);
275 								m_RefreshRects.Add(rcResult);
276 							}
277 							else
278 							{
279 								if (!pNewRect->IsSameLeft(*pOldRect))
280 								{
281 									rcResult = pOldRect->m_rcLine;
282 									rcResult.Union(pNewRect->m_rcLine);
283 								}
284 								else
285 								{
286 									fWidthDiff = pNewRect->m_rcLine.Width() - pOldRect->m_rcLine.Width();
287 									rcResult = pNewRect->m_rcLine;
288 									if (fWidthDiff > 0.0f)
289 										rcResult.left = rcResult.right - fWidthDiff;
290 									else
291 									{
292 										rcResult.left = rcResult.right;
293 										rcResult.right += (-fWidthDiff);
294 									}
295 								}
296 								m_RefreshRects.Add(rcResult);
297 							}
298 						}
299 						else
300 						{
301 							rcResult = pOldRect->m_rcLine;
302 							rcResult.Union(pNewRect->m_rcLine);
303 							m_RefreshRects.Add(rcResult);
304 						}
305 					}
306 					else
307 					{
308 						//don't need to do anything
309 					}
310 				}
311 			}
312 			else
313 			{
314 				m_RefreshRects.Add(pOldRect->m_rcLine);
315 			}
316 		}
317 		else
318 		{
319 			if (pNewRect)
320 			{
321 				m_RefreshRects.Add(pNewRect->m_rcLine);
322 			}
323 			else
324 			{
325 				//error
326 			}
327 		}
328 		i++;
329 	}
330 }
331 
AddRefresh(const CPDF_Rect & rect)332 void CFX_Edit_Refresh::AddRefresh(const CPDF_Rect & rect)
333 {
334 	m_RefreshRects.Add(rect);
335 }
336 
GetRefreshRects() const337 const CFX_Edit_RectArray * CFX_Edit_Refresh::GetRefreshRects() const
338 {
339 	return &m_RefreshRects;
340 }
341 
EndRefresh()342 void CFX_Edit_Refresh::EndRefresh()
343 {
344 	m_RefreshRects.Empty();
345 }
346 
347 /* ------------------------------------- CFX_Edit_Undo ------------------------------------- */
348 
CFX_Edit_Undo(FX_INT32 nBufsize)349 CFX_Edit_Undo::CFX_Edit_Undo(FX_INT32 nBufsize) : m_nCurUndoPos(0),
350 	m_nBufSize(nBufsize),
351 	m_bModified(FALSE),
352 	m_bVirgin(TRUE),
353 	m_bWorking(FALSE)
354 {
355 }
356 
~CFX_Edit_Undo()357 CFX_Edit_Undo::~CFX_Edit_Undo()
358 {
359 	Reset();
360 }
361 
CanUndo() const362 FX_BOOL CFX_Edit_Undo::CanUndo() const
363 {
364 	return m_nCurUndoPos > 0;
365 }
366 
Undo()367 void CFX_Edit_Undo::Undo()
368 {
369 	m_bWorking = TRUE;
370 
371 	if (m_nCurUndoPos > 0)
372 	{
373 		IFX_Edit_UndoItem * pItem = m_UndoItemStack.GetAt(m_nCurUndoPos-1);
374 		ASSERT(pItem != NULL);
375 
376 		pItem->Undo();
377 
378 		m_nCurUndoPos--;
379 		m_bModified = (m_nCurUndoPos != 0);
380 	}
381 
382 	m_bWorking = FALSE;
383 }
384 
CanRedo() const385 FX_BOOL	CFX_Edit_Undo::CanRedo() const
386 {
387 	return m_nCurUndoPos < m_UndoItemStack.GetSize();
388 }
389 
Redo()390 void CFX_Edit_Undo::Redo()
391 {
392 	m_bWorking = TRUE;
393 
394 	FX_INT32 nStackSize = m_UndoItemStack.GetSize();
395 
396 	if (m_nCurUndoPos < nStackSize)
397 	{
398 		IFX_Edit_UndoItem * pItem = m_UndoItemStack.GetAt(m_nCurUndoPos);
399 		ASSERT(pItem != NULL);
400 
401 		pItem->Redo();
402 
403 		m_nCurUndoPos++;
404 		m_bModified = (m_nCurUndoPos != 0);
405 	}
406 
407 	m_bWorking = FALSE;
408 }
409 
IsWorking() const410 FX_BOOL	CFX_Edit_Undo::IsWorking() const
411 {
412 	return m_bWorking;
413 }
414 
AddItem(IFX_Edit_UndoItem * pItem)415 void CFX_Edit_Undo::AddItem(IFX_Edit_UndoItem* pItem)
416 {
417 	ASSERT(!m_bWorking);
418 	ASSERT(pItem != NULL);
419 	ASSERT(m_nBufSize > 1);
420 
421 	if (m_nCurUndoPos < m_UndoItemStack.GetSize())
422 		RemoveTails();
423 
424 	if (m_UndoItemStack.GetSize() >= m_nBufSize)
425 	{
426 		RemoveHeads();
427 		m_bVirgin = FALSE;
428 	}
429 
430 	m_UndoItemStack.Add(pItem);
431 	m_nCurUndoPos = m_UndoItemStack.GetSize();
432 
433 	m_bModified = (m_nCurUndoPos != 0);
434 }
435 
IsModified() const436 FX_BOOL	CFX_Edit_Undo::IsModified() const
437 {
438 	if (m_bVirgin)
439 		return m_bModified;
440 	else
441 		return TRUE;
442 }
443 
GetItem(FX_INT32 nIndex)444 IFX_Edit_UndoItem* CFX_Edit_Undo::GetItem(FX_INT32 nIndex)
445 {
446 	if (nIndex>=0 && nIndex < m_UndoItemStack.GetSize())
447 		return m_UndoItemStack.GetAt(nIndex);
448 
449 	return NULL;
450 }
451 
RemoveHeads()452 void CFX_Edit_Undo::RemoveHeads()
453 {
454 	ASSERT(m_UndoItemStack.GetSize() > 1);
455 
456 	delete m_UndoItemStack.GetAt(0);
457 	m_UndoItemStack.RemoveAt(0);
458 }
459 
RemoveTails()460 void CFX_Edit_Undo::RemoveTails()
461 {
462 	for (FX_INT32 i = m_UndoItemStack.GetSize()-1; i >= m_nCurUndoPos; i--)
463 	{
464 		delete m_UndoItemStack.GetAt(i);
465 		m_UndoItemStack.RemoveAt(i);
466 	}
467 }
468 
Reset()469 void CFX_Edit_Undo::Reset()
470 {
471 	for (FX_INT32 i=0, sz=m_UndoItemStack.GetSize(); i < sz; i++)
472 	{
473 		delete m_UndoItemStack.GetAt(i);
474 	}
475 	m_nCurUndoPos = 0;
476 	m_UndoItemStack.RemoveAll();
477 }
478 
479 /* -------------------------------- CFX_Edit_GroupUndoItem -------------------------------- */
480 
CFX_Edit_GroupUndoItem(const CFX_WideString & sTitle)481 CFX_Edit_GroupUndoItem::CFX_Edit_GroupUndoItem(const CFX_WideString& sTitle) : m_sTitle(sTitle)
482 {
483 }
484 
~CFX_Edit_GroupUndoItem()485 CFX_Edit_GroupUndoItem::~CFX_Edit_GroupUndoItem()
486 {
487 	for (int i=0,sz=m_Items.GetSize(); i<sz; i++)
488 	{
489 		delete m_Items[i];
490 	}
491 
492 	m_Items.RemoveAll();
493 }
494 
AddUndoItem(CFX_Edit_UndoItem * pUndoItem)495 void CFX_Edit_GroupUndoItem::AddUndoItem(CFX_Edit_UndoItem* pUndoItem)
496 {
497 	ASSERT(pUndoItem != NULL);
498 
499 	pUndoItem->SetFirst(FALSE);
500 	pUndoItem->SetLast(FALSE);
501 
502 	m_Items.Add(pUndoItem);
503 
504 	if (m_sTitle.IsEmpty())
505 		m_sTitle = pUndoItem->GetUndoTitle();
506 }
507 
UpdateItems()508 void CFX_Edit_GroupUndoItem::UpdateItems()
509 {
510 	if (m_Items.GetSize() > 0)
511 	{
512 		CFX_Edit_UndoItem* pFirstItem = m_Items[0];
513 		ASSERT(pFirstItem != NULL);
514 		pFirstItem->SetFirst(TRUE);
515 
516 		CFX_Edit_UndoItem* pLastItem = m_Items[m_Items.GetSize() - 1];
517 		ASSERT(pLastItem != NULL);
518 		pLastItem->SetLast(TRUE);
519 	}
520 }
521 
Undo()522 void CFX_Edit_GroupUndoItem::Undo()
523 {
524 	for (int i=m_Items.GetSize()-1; i>=0; i--)
525 	{
526 		CFX_Edit_UndoItem* pUndoItem = m_Items[i];
527 		ASSERT(pUndoItem != NULL);
528 
529 		pUndoItem->Undo();
530 	}
531 }
532 
Redo()533 void CFX_Edit_GroupUndoItem::Redo()
534 {
535 	for (int i=0,sz=m_Items.GetSize(); i<sz; i++)
536 	{
537 		CFX_Edit_UndoItem* pUndoItem = m_Items[i];
538 		ASSERT(pUndoItem != NULL);
539 
540 		pUndoItem->Redo();
541 	}
542 }
543 
GetUndoTitle()544 CFX_WideString CFX_Edit_GroupUndoItem::GetUndoTitle()
545 {
546 	return m_sTitle;
547 }
548 
549 /* ------------------------------------- CFX_Edit_UndoItem derived classes ------------------------------------- */
550 
CFXEU_InsertWord(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,FX_WORD word,FX_INT32 charset,const CPVT_WordProps * pWordProps)551 CFXEU_InsertWord::CFXEU_InsertWord(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
552 								 FX_WORD word, FX_INT32 charset, const CPVT_WordProps * pWordProps)
553 	: m_pEdit(pEdit), m_wpOld(wpOldPlace), m_wpNew(wpNewPlace), m_Word(word), m_nCharset(charset), m_WordProps()
554 {
555 	if (pWordProps)
556 		m_WordProps = *pWordProps;
557 }
558 
~CFXEU_InsertWord()559 CFXEU_InsertWord::~CFXEU_InsertWord()
560 {
561 }
562 
Redo()563 void CFXEU_InsertWord::Redo()
564 {
565 	if (m_pEdit)
566 	{
567 		m_pEdit->SelectNone();
568 		m_pEdit->SetCaret(m_wpOld);
569 		m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,TRUE);
570 	}
571 }
572 
Undo()573 void CFXEU_InsertWord::Undo()
574 {
575 	if (m_pEdit)
576 	{
577 		m_pEdit->SelectNone();
578 		m_pEdit->SetCaret(m_wpNew);
579 		m_pEdit->Backspace(FALSE,TRUE);
580 	}
581 }
582 
583 /* -------------------------------------------------------------------------- */
584 
CFXEU_InsertReturn(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)585 CFXEU_InsertReturn::CFXEU_InsertReturn(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
586 			 const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps) :
587 			m_pEdit(pEdit),
588 			m_wpOld(wpOldPlace),
589 			m_wpNew(wpNewPlace),
590 			m_SecProps(),
591 			m_WordProps()
592 {
593 	if (pSecProps)
594 		m_SecProps = *pSecProps;
595 	if (pWordProps)
596 		m_WordProps = *pWordProps;
597 }
598 
~CFXEU_InsertReturn()599 CFXEU_InsertReturn::~CFXEU_InsertReturn()
600 {
601 }
602 
Redo()603 void CFXEU_InsertReturn::Redo()
604 {
605 	if (m_pEdit)
606 	{
607 		m_pEdit->SelectNone();
608 		m_pEdit->SetCaret(m_wpOld);
609 		m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,TRUE);
610 	}
611 }
612 
Undo()613 void CFXEU_InsertReturn::Undo()
614 {
615 	if (m_pEdit)
616 	{
617 		m_pEdit->SelectNone();
618 		m_pEdit->SetCaret(m_wpNew);
619 		m_pEdit->Backspace(FALSE,TRUE);
620 	}
621 }
622 
623 /* -------------------------------------------------------------------------- */
624 //CFXEU_Backspace
625 
CFXEU_Backspace(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,FX_WORD word,FX_INT32 charset,const CPVT_SecProps & SecProps,const CPVT_WordProps & WordProps)626 CFXEU_Backspace::CFXEU_Backspace(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
627 							   FX_WORD word, FX_INT32 charset,
628 							   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps) :
629 			m_pEdit(pEdit),
630 			m_wpOld(wpOldPlace),
631 			m_wpNew(wpNewPlace),
632 			m_Word(word),
633 			m_nCharset(charset),
634 			m_SecProps(SecProps),
635 			m_WordProps(WordProps)
636 {
637 }
638 
~CFXEU_Backspace()639 CFXEU_Backspace::~CFXEU_Backspace()
640 {
641 }
642 
Redo()643 void CFXEU_Backspace::Redo()
644 {
645 	if (m_pEdit)
646 	{
647 		m_pEdit->SelectNone();
648 		m_pEdit->SetCaret(m_wpOld);
649 		m_pEdit->Backspace(FALSE,TRUE);
650 	}
651 }
652 
Undo()653 void CFXEU_Backspace::Undo()
654 {
655 	if (m_pEdit)
656 	{
657 		m_pEdit->SelectNone();
658 		m_pEdit->SetCaret(m_wpNew);
659 		if (m_wpNew.SecCmp(m_wpOld) != 0)
660 		{
661 			m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,TRUE);
662 		}
663 		else
664 		{
665 			m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,TRUE);
666 		}
667 	}
668 }
669 
670 /* -------------------------------------------------------------------------- */
671 //CFXEU_Delete
672 
CFXEU_Delete(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,FX_WORD word,FX_INT32 charset,const CPVT_SecProps & SecProps,const CPVT_WordProps & WordProps,FX_BOOL bSecEnd)673 CFXEU_Delete::CFXEU_Delete(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
674 							   FX_WORD word, FX_INT32 charset,
675 							   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps, FX_BOOL bSecEnd) :
676 			m_pEdit(pEdit),
677 			m_wpOld(wpOldPlace),
678 			m_wpNew(wpNewPlace),
679 			m_Word(word),
680 			m_nCharset(charset),
681 			m_SecProps(SecProps),
682 			m_WordProps(WordProps),
683 			m_bSecEnd(bSecEnd)
684 {
685 }
686 
~CFXEU_Delete()687 CFXEU_Delete::~CFXEU_Delete()
688 {
689 }
690 
Redo()691 void CFXEU_Delete::Redo()
692 {
693 	if (m_pEdit)
694 	{
695 		m_pEdit->SelectNone();
696 		m_pEdit->SetCaret(m_wpOld);
697 		m_pEdit->Delete(FALSE,TRUE);
698 	}
699 }
700 
Undo()701 void CFXEU_Delete::Undo()
702 {
703 	if (m_pEdit)
704 	{
705 		m_pEdit->SelectNone();
706 		m_pEdit->SetCaret(m_wpNew);
707 		if (m_bSecEnd)
708 		{
709 			m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,TRUE);
710 		}
711 		else
712 		{
713 			m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,TRUE);
714 		}
715 	}
716 }
717 
718 /* -------------------------------------------------------------------------- */
719 //CFXEU_Clear
720 
CFXEU_Clear(CFX_Edit * pEdit,const CPVT_WordRange & wrSel,const CFX_WideString & swText)721 CFXEU_Clear::CFXEU_Clear(CFX_Edit * pEdit,  const CPVT_WordRange & wrSel, const CFX_WideString & swText) :
722 			m_pEdit(pEdit),
723 			m_wrSel(wrSel),
724 			m_swText(swText)
725 {
726 }
727 
~CFXEU_Clear()728 CFXEU_Clear::~CFXEU_Clear()
729 {
730 }
731 
Redo()732 void CFXEU_Clear::Redo()
733 {
734 	if (m_pEdit)
735 	{
736 		m_pEdit->SelectNone();
737 		m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
738 		m_pEdit->Clear(FALSE,TRUE);
739 	}
740 }
741 
Undo()742 void CFXEU_Clear::Undo()
743 {
744 	if (m_pEdit)
745 	{
746 		m_pEdit->SelectNone();
747 		m_pEdit->SetCaret(m_wrSel.BeginPos);
748 		m_pEdit->InsertText(m_swText.c_str(), DEFAULT_CHARSET, NULL, NULL, FALSE, TRUE);
749 		m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
750 	}
751 }
752 
753 /* -------------------------------------------------------------------------- */
754 //CFXEU_ClearRich
755 
CFXEU_ClearRich(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,const CPVT_WordRange & wrSel,FX_WORD word,FX_INT32 charset,const CPVT_SecProps & SecProps,const CPVT_WordProps & WordProps)756 CFXEU_ClearRich::CFXEU_ClearRich(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
757 							   const CPVT_WordRange & wrSel, FX_WORD word, FX_INT32 charset,
758 							   const CPVT_SecProps & SecProps, const CPVT_WordProps & WordProps) :
759 			m_pEdit(pEdit),
760 			m_wpOld(wpOldPlace),
761 			m_wpNew(wpNewPlace),
762 			m_wrSel(wrSel),
763 			m_Word(word),
764 			m_nCharset(charset),
765 			m_SecProps(SecProps),
766 			m_WordProps(WordProps)
767 {
768 }
769 
~CFXEU_ClearRich()770 CFXEU_ClearRich::~CFXEU_ClearRich()
771 {
772 }
773 
Redo()774 void CFXEU_ClearRich::Redo()
775 {
776 	if (m_pEdit && IsLast())
777 	{
778 		m_pEdit->SelectNone();
779 		m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
780 		m_pEdit->Clear(FALSE,TRUE);
781 	}
782 }
783 
Undo()784 void CFXEU_ClearRich::Undo()
785 {
786 	if (m_pEdit)
787 	{
788 		m_pEdit->SelectNone();
789 		m_pEdit->SetCaret(m_wpOld);
790 		if (m_wpNew.SecCmp(m_wpOld) != 0)
791 		{
792 			m_pEdit->InsertReturn(&m_SecProps,&m_WordProps,FALSE,FALSE);
793 		}
794 		else
795 		{
796 			m_pEdit->InsertWord(m_Word,m_nCharset,&m_WordProps,FALSE,FALSE);
797 		}
798 
799 		if (IsFirst())
800 		{
801 			m_pEdit->PaintInsertText(m_wrSel.BeginPos,m_wrSel.EndPos);
802 			m_pEdit->SetSel(m_wrSel.BeginPos,m_wrSel.EndPos);
803 		}
804 	}
805 }
806 /* -------------------------------------------------------------------------- */
807 //CFXEU_InsertText
808 
CFXEU_InsertText(CFX_Edit * pEdit,const CPVT_WordPlace & wpOldPlace,const CPVT_WordPlace & wpNewPlace,const CFX_WideString & swText,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)809 CFXEU_InsertText::CFXEU_InsertText(CFX_Edit * pEdit, const CPVT_WordPlace & wpOldPlace, const CPVT_WordPlace & wpNewPlace,
810 							   const CFX_WideString & swText, FX_INT32 charset,
811 							   const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps) :
812 			m_pEdit(pEdit),
813 			m_wpOld(wpOldPlace),
814 			m_wpNew(wpNewPlace),
815 			m_swText(swText),
816 			m_nCharset(charset),
817 			m_SecProps(),
818 			m_WordProps()
819 {
820 	if (pSecProps)
821 		m_SecProps = *pSecProps;
822 	if (pWordProps)
823 		m_WordProps = *pWordProps;
824 }
825 
~CFXEU_InsertText()826 CFXEU_InsertText::~CFXEU_InsertText()
827 {
828 }
829 
Redo()830 void CFXEU_InsertText::Redo()
831 {
832 	if (m_pEdit && IsLast())
833 	{
834 		m_pEdit->SelectNone();
835 		m_pEdit->SetCaret(m_wpOld);
836 		m_pEdit->InsertText(m_swText.c_str(), m_nCharset, &m_SecProps, &m_WordProps, FALSE, TRUE);
837 	}
838 }
839 
Undo()840 void CFXEU_InsertText::Undo()
841 {
842 	if (m_pEdit)
843 	{
844 		m_pEdit->SelectNone();
845 		m_pEdit->SetSel(m_wpOld,m_wpNew);
846 		m_pEdit->Clear(FALSE,TRUE);
847 	}
848 }
849 
850 /* -------------------------------------------------------------------------- */
851 
CFXEU_SetSecProps(CFX_Edit * pEdit,const CPVT_WordPlace & place,EDIT_PROPS_E ep,const CPVT_SecProps & oldsecprops,const CPVT_WordProps & oldwordprops,const CPVT_SecProps & newsecprops,const CPVT_WordProps & newwordprops,const CPVT_WordRange & range)852 CFXEU_SetSecProps::CFXEU_SetSecProps(CFX_Edit * pEdit, const CPVT_WordPlace & place, EDIT_PROPS_E ep,
853 		const CPVT_SecProps & oldsecprops, const CPVT_WordProps & oldwordprops,
854 		const CPVT_SecProps & newsecprops, const CPVT_WordProps & newwordprops, const CPVT_WordRange & range)
855 		: m_pEdit(pEdit),
856 		m_wpPlace(place),
857 		m_wrPlace(range),
858 		m_eProps(ep),
859 		m_OldSecProps(oldsecprops),
860 		m_NewSecProps(newsecprops),
861 		m_OldWordProps(oldwordprops),
862 		m_NewWordProps(newwordprops)
863 {
864 }
865 
~CFXEU_SetSecProps()866 CFXEU_SetSecProps::~CFXEU_SetSecProps()
867 {
868 }
869 
Redo()870 void CFXEU_SetSecProps::Redo()
871 {
872 	if (m_pEdit)
873 	{
874 		m_pEdit->SetSecProps(m_eProps,m_wpPlace,&m_NewSecProps,&m_NewWordProps,m_wrPlace,FALSE);
875 		if (IsLast())
876 		{
877 			m_pEdit->SelectNone();
878 			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
879 			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
880 		}
881 	}
882 }
883 
Undo()884 void CFXEU_SetSecProps::Undo()
885 {
886 	if (m_pEdit)
887 	{
888 		m_pEdit->SetSecProps(m_eProps,m_wpPlace,&m_OldSecProps,&m_OldWordProps,m_wrPlace,FALSE);
889 		if (IsFirst())
890 		{
891 			m_pEdit->SelectNone();
892 			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
893 			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
894 		}
895 	}
896 }
897 
898 /* -------------------------------------------------------------------------- */
899 
CFXEU_SetWordProps(CFX_Edit * pEdit,const CPVT_WordPlace & place,EDIT_PROPS_E ep,const CPVT_WordProps & oldprops,const CPVT_WordProps & newprops,const CPVT_WordRange & range)900 CFXEU_SetWordProps::CFXEU_SetWordProps(CFX_Edit * pEdit, const CPVT_WordPlace & place, EDIT_PROPS_E ep,
901 		const CPVT_WordProps & oldprops, const CPVT_WordProps & newprops, const CPVT_WordRange & range)
902 		: m_pEdit(pEdit),
903 		m_wpPlace(place),
904 		m_wrPlace(range),
905 		m_eProps(ep),
906 		m_OldWordProps(oldprops),
907 		m_NewWordProps(newprops)
908 {
909 }
910 
~CFXEU_SetWordProps()911 CFXEU_SetWordProps::~CFXEU_SetWordProps()
912 {
913 }
914 
Redo()915 void CFXEU_SetWordProps::Redo()
916 {
917 	if (m_pEdit)
918 	{
919 		m_pEdit->SetWordProps(m_eProps,m_wpPlace,&m_NewWordProps,m_wrPlace,FALSE);
920 		if (IsLast())
921 		{
922 			m_pEdit->SelectNone();
923 			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
924 			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
925 		}
926 	}
927 }
928 
Undo()929 void CFXEU_SetWordProps::Undo()
930 {
931 	if (m_pEdit)
932 	{
933 		m_pEdit->SetWordProps(m_eProps,m_wpPlace,&m_OldWordProps,m_wrPlace,FALSE);
934 		if (IsFirst())
935 		{
936 			m_pEdit->SelectNone();
937 			m_pEdit->PaintSetProps(m_eProps,m_wrPlace);
938 			m_pEdit->SetSel(m_wrPlace.BeginPos,m_wrPlace.EndPos);
939 		}
940 	}
941 }
942 
943 /* ------------------------------------- CFX_Edit ------------------------------------- */
944 
CFX_Edit(IPDF_VariableText * pVT)945 CFX_Edit::CFX_Edit(IPDF_VariableText * pVT) :
946 	m_pVT(pVT),
947 	m_pNotify(NULL),
948 	m_pOprNotify(NULL),
949 	m_pVTProvide(NULL),
950 	m_wpCaret(-1,-1,-1),
951 	m_wpOldCaret(-1,-1,-1),
952 	m_SelState(),
953 	m_ptScrollPos(0,0),
954 	m_ptRefreshScrollPos(0,0),
955 	m_bEnableScroll(FALSE),
956 	m_pIterator(NULL),
957 	m_ptCaret(0.0f,0.0f),
958 	m_Undo(FX_EDIT_UNDO_MAXITEM),
959 	m_nAlignment(0),
960 	m_bNotifyFlag(FALSE),
961 	m_bEnableOverflow(FALSE),
962 	m_bEnableRefresh(TRUE),
963 	m_rcOldContent(0.0f,0.0f,0.0f,0.0f),
964 	m_bEnableUndo(TRUE),
965 	m_bNotify(TRUE),
966 	m_bOprNotify(FALSE),
967 	m_pGroupUndoItem(NULL)
968 {
969 	ASSERT(pVT != NULL);
970 }
971 
~CFX_Edit()972 CFX_Edit::~CFX_Edit()
973 {
974 	if (m_pVTProvide)
975 	{
976 		delete m_pVTProvide;
977 		m_pVTProvide = NULL;
978 	}
979 
980 	if (m_pIterator)
981 	{
982 		delete m_pIterator;
983 		m_pIterator = NULL;
984 	}
985 
986 	ASSERT(m_pGroupUndoItem == NULL);
987 }
988 
989 // public methods
990 
Initialize()991 void CFX_Edit::Initialize()
992 {
993 	m_pVT->Initialize();
994 	SetCaret(m_pVT->GetBeginWordPlace());
995 	SetCaretOrigin();
996 }
997 
SetFontMap(IFX_Edit_FontMap * pFontMap)998 void CFX_Edit::SetFontMap(IFX_Edit_FontMap * pFontMap)
999 {
1000 	if (m_pVTProvide)
1001 		delete m_pVTProvide;
1002 
1003 	m_pVT->SetProvider(m_pVTProvide = new CFX_Edit_Provider(pFontMap));
1004 }
1005 
SetVTProvider(IPDF_VariableText_Provider * pProvider)1006 void CFX_Edit::SetVTProvider(IPDF_VariableText_Provider* pProvider)
1007 {
1008 	m_pVT->SetProvider(pProvider);
1009 }
1010 
SetNotify(IFX_Edit_Notify * pNotify)1011 void CFX_Edit::SetNotify(IFX_Edit_Notify* pNotify)
1012 {
1013 	m_pNotify = pNotify;
1014 }
1015 
SetOprNotify(IFX_Edit_OprNotify * pOprNotify)1016 void CFX_Edit::SetOprNotify(IFX_Edit_OprNotify* pOprNotify)
1017 {
1018 	m_pOprNotify = pOprNotify;
1019 }
1020 
GetIterator()1021 IFX_Edit_Iterator * CFX_Edit::GetIterator()
1022 {
1023 	if (!m_pIterator)
1024 		m_pIterator = new CFX_Edit_Iterator(this,m_pVT->GetIterator());
1025 
1026 	return m_pIterator;
1027 }
1028 
GetVariableText()1029 IPDF_VariableText *	CFX_Edit::GetVariableText()
1030 {
1031 	return m_pVT;
1032 }
1033 
GetFontMap()1034 IFX_Edit_FontMap* CFX_Edit::GetFontMap()
1035 {
1036 	if (m_pVTProvide)
1037 		return m_pVTProvide->GetFontMap();
1038 
1039 	return NULL;
1040 }
1041 
SetPlateRect(const CPDF_Rect & rect,FX_BOOL bPaint)1042 void CFX_Edit::SetPlateRect(const CPDF_Rect & rect, FX_BOOL bPaint/* = TRUE*/)
1043 {
1044 	m_pVT->SetPlateRect(rect);
1045 	m_ptScrollPos = CPDF_Point(rect.left,rect.top);
1046 	if (bPaint) Paint();
1047 }
1048 
SetAlignmentH(FX_INT32 nFormat,FX_BOOL bPaint)1049 void CFX_Edit::SetAlignmentH(FX_INT32 nFormat/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1050 {
1051 	m_pVT->SetAlignment(nFormat);
1052 	if (bPaint) Paint();
1053 }
1054 
SetAlignmentV(FX_INT32 nFormat,FX_BOOL bPaint)1055 void CFX_Edit::SetAlignmentV(FX_INT32 nFormat/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1056 {
1057 	m_nAlignment = nFormat;
1058 	if (bPaint) Paint();
1059 }
1060 
SetPasswordChar(FX_WORD wSubWord,FX_BOOL bPaint)1061 void CFX_Edit::SetPasswordChar(FX_WORD wSubWord/* ='*' */, FX_BOOL bPaint/* = TRUE*/)
1062 {
1063 	m_pVT->SetPasswordChar(wSubWord);
1064 	if (bPaint) Paint();
1065 }
1066 
SetLimitChar(FX_INT32 nLimitChar,FX_BOOL bPaint)1067 void CFX_Edit::SetLimitChar(FX_INT32 nLimitChar/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1068 {
1069 	m_pVT->SetLimitChar(nLimitChar);
1070 	if (bPaint) Paint();
1071 }
1072 
SetCharArray(FX_INT32 nCharArray,FX_BOOL bPaint)1073 void CFX_Edit::SetCharArray(FX_INT32 nCharArray/* =0 */, FX_BOOL bPaint/* = TRUE*/)
1074 {
1075 	m_pVT->SetCharArray(nCharArray);
1076 	if (bPaint) Paint();
1077 }
1078 
SetCharSpace(FX_FLOAT fCharSpace,FX_BOOL bPaint)1079 void CFX_Edit::SetCharSpace(FX_FLOAT fCharSpace/* =0.0f */, FX_BOOL bPaint/* = TRUE*/)
1080 {
1081 	m_pVT->SetCharSpace(fCharSpace);
1082 	if (bPaint) Paint();
1083 }
1084 
SetHorzScale(FX_INT32 nHorzScale,FX_BOOL bPaint)1085 void CFX_Edit::SetHorzScale(FX_INT32 nHorzScale/* =100 */, FX_BOOL bPaint/* = TRUE*/)
1086 {
1087 	m_pVT->SetHorzScale(nHorzScale);
1088 	if (bPaint) Paint();
1089 }
1090 
SetMultiLine(FX_BOOL bMultiLine,FX_BOOL bPaint)1091 void CFX_Edit::SetMultiLine(FX_BOOL bMultiLine/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1092 {
1093 	m_pVT->SetMultiLine(bMultiLine);
1094 	if (bPaint) Paint();
1095 }
1096 
SetAutoReturn(FX_BOOL bAuto,FX_BOOL bPaint)1097 void CFX_Edit::SetAutoReturn(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1098 {
1099 	m_pVT->SetAutoReturn(bAuto);
1100 	if (bPaint) Paint();
1101 }
1102 
SetLineLeading(FX_FLOAT fLineLeading,FX_BOOL bPaint)1103 void CFX_Edit::SetLineLeading(FX_FLOAT fLineLeading/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1104 {
1105 	m_pVT->SetLineLeading(fLineLeading);
1106 	if (bPaint) Paint();
1107 }
1108 
SetAutoFontSize(FX_BOOL bAuto,FX_BOOL bPaint)1109 void CFX_Edit::SetAutoFontSize(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1110 {
1111 	m_pVT->SetAutoFontSize(bAuto);
1112 	if (bPaint) Paint();
1113 }
1114 
SetFontSize(FX_FLOAT fFontSize,FX_BOOL bPaint)1115 void CFX_Edit::SetFontSize(FX_FLOAT fFontSize, FX_BOOL bPaint/* = TRUE*/)
1116 {
1117 	m_pVT->SetFontSize(fFontSize);
1118 	if (bPaint) Paint();
1119 }
1120 
SetAutoScroll(FX_BOOL bAuto,FX_BOOL bPaint)1121 void CFX_Edit::SetAutoScroll(FX_BOOL bAuto/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1122 {
1123 	m_bEnableScroll = bAuto;
1124 	if (bPaint) Paint();
1125 }
1126 
SetTextOverflow(FX_BOOL bAllowed,FX_BOOL bPaint)1127 void CFX_Edit::SetTextOverflow(FX_BOOL bAllowed /*= FALSE*/, FX_BOOL bPaint/* = TRUE*/)
1128 {
1129 	m_bEnableOverflow = bAllowed;
1130 	if (bPaint) Paint();
1131 }
1132 
SetSel(FX_INT32 nStartChar,FX_INT32 nEndChar)1133 void CFX_Edit::SetSel(FX_INT32 nStartChar,FX_INT32 nEndChar)
1134 {
1135 	if (m_pVT->IsValid())
1136 	{
1137 		if (nStartChar == 0 && nEndChar < 0)
1138 		{
1139 			SelectAll();
1140 		}
1141 		else if (nStartChar < 0)
1142 		{
1143 			this->SelectNone();
1144 		}
1145 		else
1146 		{
1147 			if (nStartChar < nEndChar)
1148 			{
1149 				SetSel(m_pVT->WordIndexToWordPlace(nStartChar),m_pVT->WordIndexToWordPlace(nEndChar));
1150 			}
1151 			else
1152 			{
1153 				SetSel(m_pVT->WordIndexToWordPlace(nEndChar),m_pVT->WordIndexToWordPlace(nStartChar));
1154 			}
1155 		}
1156 	}
1157 }
1158 
SetSel(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)1159 void CFX_Edit::SetSel(const CPVT_WordPlace & begin,const CPVT_WordPlace & end)
1160 {
1161 	if (m_pVT->IsValid())
1162 	{
1163 		SelectNone();
1164 
1165 		m_SelState.Set(begin,end);
1166 
1167 		SetCaret(m_SelState.EndPos);
1168 
1169 		if (m_SelState.IsExist())
1170 		{
1171 			ScrollToCaret();
1172 			CPVT_WordRange wr(m_SelState.BeginPos,m_SelState.EndPos);
1173 			Refresh(RP_OPTIONAL,&wr);
1174 			SetCaretInfo();
1175 		}
1176 		else
1177 		{
1178 			ScrollToCaret();
1179 			SetCaretInfo();
1180 		}
1181 	}
1182 }
1183 
GetSel(FX_INT32 & nStartChar,FX_INT32 & nEndChar) const1184 void CFX_Edit::GetSel(FX_INT32 & nStartChar, FX_INT32 & nEndChar) const
1185 {
1186 	nStartChar = -1;
1187 	nEndChar = -1;
1188 
1189 	if (m_pVT->IsValid())
1190 	{
1191 		if (m_SelState.IsExist())
1192 		{
1193 			if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
1194 			{
1195 				nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
1196 				nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
1197 			}
1198 			else
1199 			{
1200 				nStartChar = m_pVT->WordPlaceToWordIndex(m_SelState.EndPos);
1201 				nEndChar = m_pVT->WordPlaceToWordIndex(m_SelState.BeginPos);
1202 			}
1203 		}
1204 		else
1205 		{
1206 			nStartChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
1207 			nEndChar = m_pVT->WordPlaceToWordIndex(m_wpCaret);
1208 		}
1209 	}
1210 }
1211 
GetCaret() const1212 FX_INT32 CFX_Edit::GetCaret() const
1213 {
1214 	if (m_pVT->IsValid())
1215 		return m_pVT->WordPlaceToWordIndex(m_wpCaret);
1216 
1217 	return -1;
1218 }
1219 
GetCaretWordPlace() const1220 CPVT_WordPlace CFX_Edit::GetCaretWordPlace() const
1221 {
1222 	return m_wpCaret;
1223 }
1224 
GetText() const1225 CFX_WideString CFX_Edit::GetText() const
1226 {
1227 	CFX_WideString swRet;
1228 
1229 	if (m_pVT->IsValid())
1230 	{
1231 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1232 		{
1233 			FX_BOOL bRich = m_pVT->IsRichText();
1234 
1235 			pIterator->SetAt(0);
1236 
1237 			CPVT_Word wordinfo;
1238 			CPVT_WordPlace oldplace = pIterator->GetAt();
1239 			while (pIterator->NextWord())
1240 			{
1241 				CPVT_WordPlace place = pIterator->GetAt();
1242 
1243 				if (pIterator->GetWord(wordinfo))
1244 				{
1245 					if (bRich)
1246 					{
1247 						swRet += wordinfo.Word;
1248 					}
1249 					else
1250 					{
1251 						swRet += wordinfo.Word;
1252 					}
1253 				}
1254 
1255 				if (oldplace.SecCmp(place) != 0)
1256 				{
1257 					swRet += 0x0D;
1258 					swRet += 0x0A;
1259 				}
1260 
1261 				oldplace = place;
1262 			}
1263 		}
1264 	}
1265 
1266 	return swRet;
1267 }
1268 
GetRangeText(const CPVT_WordRange & range) const1269 CFX_WideString CFX_Edit::GetRangeText(const CPVT_WordRange & range) const
1270 {
1271 	CFX_WideString swRet;
1272 
1273 	if (m_pVT->IsValid())
1274 	{
1275 		FX_BOOL bRich = m_pVT->IsRichText();
1276 
1277 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1278 		{
1279 			CPVT_WordRange wrTemp = range;
1280 			m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1281 			m_pVT->UpdateWordPlace(wrTemp.EndPos);
1282 			pIterator->SetAt(wrTemp.BeginPos);
1283 
1284 			CPVT_Word wordinfo;
1285 			CPVT_WordPlace oldplace = wrTemp.BeginPos;
1286 			while (pIterator->NextWord())
1287 			{
1288 				CPVT_WordPlace place = pIterator->GetAt();
1289 				if (place.WordCmp(wrTemp.EndPos) > 0)break;
1290 
1291 				if (pIterator->GetWord(wordinfo))
1292 				{
1293 					if (bRich)
1294 					{
1295 						swRet += wordinfo.Word;
1296 					}
1297 					else
1298 					{
1299 						swRet += wordinfo.Word;
1300 					}
1301 				}
1302 
1303 				if (oldplace.SecCmp(place) != 0)
1304 				{
1305 					swRet += 0x0D;
1306 					swRet += 0x0A;
1307 				}
1308 
1309 				oldplace = place;
1310 			}
1311 		}
1312 	}
1313 
1314 	return swRet;
1315 }
1316 
GetSelText() const1317 CFX_WideString CFX_Edit::GetSelText() const
1318 {
1319 	return GetRangeText(m_SelState.ConvertToWordRange());
1320 }
1321 
GetTotalWords() const1322 FX_INT32 CFX_Edit::GetTotalWords() const
1323 {
1324 	return m_pVT->GetTotalWords();
1325 }
1326 
GetTotalLines() const1327 FX_INT32 CFX_Edit::GetTotalLines() const
1328 {
1329 	FX_INT32 nLines = 0;
1330 
1331 	if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1332 	{
1333 		pIterator->SetAt(0);
1334 		while (pIterator->NextLine())
1335 			nLines++;
1336 	}
1337 
1338 	return nLines+1;
1339 }
1340 
GetSelectWordRange() const1341 CPVT_WordRange CFX_Edit::GetSelectWordRange() const
1342 {
1343 	return m_SelState.ConvertToWordRange();
1344 }
1345 
CombineWordRange(const CPVT_WordRange & wr1,const CPVT_WordRange & wr2)1346 CPVT_WordRange CFX_Edit::CombineWordRange(const CPVT_WordRange & wr1, const CPVT_WordRange & wr2)
1347 {
1348 	CPVT_WordRange wrRet;
1349 
1350 	if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0)
1351 	{
1352 		wrRet.BeginPos = wr1.BeginPos;
1353 	}
1354 	else
1355 	{
1356 		wrRet.BeginPos = wr2.BeginPos;
1357 	}
1358 
1359 	if (wr1.EndPos.WordCmp(wr2.EndPos) < 0)
1360 	{
1361 		wrRet.EndPos = wr2.EndPos;
1362 	}
1363 	else
1364 	{
1365 		wrRet.EndPos = wr1.EndPos;
1366 	}
1367 
1368 	return wrRet;
1369 }
1370 
IsRichText() const1371 FX_BOOL	CFX_Edit::IsRichText() const
1372 {
1373 	return m_pVT->IsRichText();
1374 }
1375 
SetRichText(FX_BOOL bRichText,FX_BOOL bPaint)1376 void CFX_Edit::SetRichText(FX_BOOL bRichText/* =TRUE */, FX_BOOL bPaint/* = TRUE*/)
1377 {
1378 	m_pVT->SetRichText(bRichText);
1379 	if (bPaint) Paint();
1380 }
1381 
SetRichFontIndex(FX_INT32 nFontIndex)1382 FX_BOOL CFX_Edit::SetRichFontIndex(FX_INT32 nFontIndex)
1383 {
1384 	CPVT_WordProps WordProps;
1385 	WordProps.nFontIndex = nFontIndex;
1386 	return SetRichTextProps(EP_FONTINDEX,NULL,&WordProps);
1387 }
1388 
SetRichFontSize(FX_FLOAT fFontSize)1389 FX_BOOL CFX_Edit::SetRichFontSize(FX_FLOAT fFontSize)
1390 {
1391 	CPVT_WordProps WordProps;
1392 	WordProps.fFontSize = fFontSize;
1393 	return SetRichTextProps(EP_FONTSIZE,NULL,&WordProps);
1394 }
1395 
SetRichTextColor(FX_COLORREF dwColor)1396 FX_BOOL CFX_Edit::SetRichTextColor(FX_COLORREF dwColor)
1397 {
1398 	CPVT_WordProps WordProps;
1399 	WordProps.dwWordColor = dwColor;
1400 	return SetRichTextProps(EP_WORDCOLOR,NULL,&WordProps);
1401 }
1402 
SetRichTextScript(FX_INT32 nScriptType)1403 FX_BOOL CFX_Edit::SetRichTextScript(FX_INT32 nScriptType)
1404 {
1405 	CPVT_WordProps WordProps;
1406 	WordProps.nScriptType = nScriptType;
1407 	return SetRichTextProps(EP_SCRIPTTYPE,NULL,&WordProps);
1408 }
1409 
SetRichTextBold(FX_BOOL bBold)1410 FX_BOOL CFX_Edit::SetRichTextBold(FX_BOOL bBold)
1411 {
1412 	CPVT_WordProps WordProps;
1413 	if (bBold)
1414 		WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
1415 	return SetRichTextProps(EP_BOLD,NULL,&WordProps);
1416 }
1417 
SetRichTextItalic(FX_BOOL bItalic)1418 FX_BOOL CFX_Edit::SetRichTextItalic(FX_BOOL bItalic)
1419 {
1420 	CPVT_WordProps WordProps;
1421 	if (bItalic)
1422 		WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
1423 	return SetRichTextProps(EP_ITALIC,NULL,&WordProps);
1424 }
1425 
SetRichTextUnderline(FX_BOOL bUnderline)1426 FX_BOOL CFX_Edit::SetRichTextUnderline(FX_BOOL bUnderline)
1427 {
1428 	CPVT_WordProps WordProps;
1429 	if (bUnderline)
1430 		WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
1431 	return SetRichTextProps(EP_UNDERLINE,NULL,&WordProps);
1432 }
1433 
SetRichTextCrossout(FX_BOOL bCrossout)1434 FX_BOOL CFX_Edit::SetRichTextCrossout(FX_BOOL bCrossout)
1435 {
1436 	CPVT_WordProps WordProps;
1437 	if (bCrossout)
1438 		WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
1439 	return SetRichTextProps(EP_CROSSOUT,NULL,&WordProps);
1440 }
1441 
SetRichTextCharSpace(FX_FLOAT fCharSpace)1442 FX_BOOL CFX_Edit::SetRichTextCharSpace(FX_FLOAT fCharSpace)
1443 {
1444 	CPVT_WordProps WordProps;
1445 	WordProps.fCharSpace = fCharSpace;
1446 	return SetRichTextProps(EP_CHARSPACE,NULL,&WordProps);
1447 }
1448 
SetRichTextHorzScale(FX_INT32 nHorzScale)1449 FX_BOOL CFX_Edit::SetRichTextHorzScale(FX_INT32 nHorzScale /*= 100*/)
1450 {
1451 	CPVT_WordProps WordProps;
1452 	WordProps.nHorzScale = nHorzScale;
1453 	return SetRichTextProps(EP_HORZSCALE,NULL,&WordProps);
1454 }
1455 
SetRichTextLineLeading(FX_FLOAT fLineLeading)1456 FX_BOOL CFX_Edit::SetRichTextLineLeading(FX_FLOAT fLineLeading)
1457 {
1458 	CPVT_SecProps SecProps;
1459 	SecProps.fLineLeading = fLineLeading;
1460 	return SetRichTextProps(EP_LINELEADING,&SecProps,NULL);
1461 }
1462 
SetRichTextLineIndent(FX_FLOAT fLineIndent)1463 FX_BOOL CFX_Edit::SetRichTextLineIndent(FX_FLOAT fLineIndent)
1464 {
1465 	CPVT_SecProps SecProps;
1466 	SecProps.fLineIndent = fLineIndent;
1467 	return SetRichTextProps(EP_LINEINDENT,&SecProps,NULL);
1468 }
1469 
SetRichTextAlignment(FX_INT32 nAlignment)1470 FX_BOOL	CFX_Edit::SetRichTextAlignment(FX_INT32 nAlignment)
1471 {
1472 	CPVT_SecProps SecProps;
1473 	SecProps.nAlignment = nAlignment;
1474 	return SetRichTextProps(EP_ALIGNMENT,&SecProps,NULL);
1475 }
1476 
SetRichTextProps(EDIT_PROPS_E eProps,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)1477 FX_BOOL CFX_Edit::SetRichTextProps(EDIT_PROPS_E eProps, const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps)
1478 {
1479 	FX_BOOL bSet = FALSE;
1480 	FX_BOOL bSet1,bSet2;
1481 	if (m_pVT->IsValid() && m_pVT->IsRichText())
1482 	{
1483 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1484 		{
1485 			CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
1486 
1487 			m_pVT->UpdateWordPlace(wrTemp.BeginPos);
1488 			m_pVT->UpdateWordPlace(wrTemp.EndPos);
1489 			pIterator->SetAt(wrTemp.BeginPos);
1490 
1491 			BeginGroupUndo(L"");;
1492 
1493 			bSet = SetSecProps(eProps,wrTemp.BeginPos,pSecProps,pWordProps,wrTemp,TRUE);
1494 
1495 			while (pIterator->NextWord())
1496 			{
1497 				CPVT_WordPlace place = pIterator->GetAt();
1498 				if (place.WordCmp(wrTemp.EndPos) > 0) break;
1499 				bSet1 = SetSecProps(eProps,place,pSecProps,pWordProps,wrTemp,TRUE);
1500 				bSet2 = SetWordProps(eProps,place,pWordProps,wrTemp,TRUE);
1501 
1502 				if (!bSet)
1503 					bSet = (bSet1 || bSet2);
1504 			}
1505 
1506 			EndGroupUndo();
1507 
1508 			if (bSet)
1509 			{
1510 				PaintSetProps(eProps,wrTemp);
1511 			}
1512 		}
1513 	}
1514 
1515 	return bSet;
1516 }
1517 
PaintSetProps(EDIT_PROPS_E eProps,const CPVT_WordRange & wr)1518 void CFX_Edit::PaintSetProps(EDIT_PROPS_E eProps, const CPVT_WordRange & wr)
1519 {
1520 	switch(eProps)
1521 	{
1522 	case EP_LINELEADING:
1523 	case EP_LINEINDENT:
1524 	case EP_ALIGNMENT:
1525 		RearrangePart(wr);
1526 		ScrollToCaret();
1527 		Refresh(RP_ANALYSE);
1528 		SetCaretOrigin();
1529 		SetCaretInfo();
1530 		break;
1531 	case EP_WORDCOLOR:
1532 	case EP_UNDERLINE:
1533 	case EP_CROSSOUT:
1534 		Refresh(RP_OPTIONAL,&wr);
1535 		break;
1536 	case EP_FONTINDEX:
1537 	case EP_FONTSIZE:
1538 	case EP_SCRIPTTYPE:
1539 	case EP_CHARSPACE:
1540 	case EP_HORZSCALE:
1541 	case EP_BOLD:
1542 	case EP_ITALIC:
1543 		RearrangePart(wr);
1544 		ScrollToCaret();
1545 
1546 		CPVT_WordRange wrRefresh(m_pVT->GetSectionBeginPlace(wr.BeginPos),
1547 			m_pVT->GetSectionEndPlace(wr.EndPos));
1548 		Refresh(RP_ANALYSE,&wrRefresh);
1549 
1550 		SetCaretOrigin();
1551 		SetCaretInfo();
1552 		break;
1553 	}
1554 }
1555 
SetSecProps(EDIT_PROPS_E eProps,const CPVT_WordPlace & place,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,const CPVT_WordRange & wr,FX_BOOL bAddUndo)1556 FX_BOOL CFX_Edit::SetSecProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
1557 							   const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps,
1558 							   const CPVT_WordRange & wr, FX_BOOL bAddUndo)
1559 {
1560 	if (m_pVT->IsValid() && m_pVT->IsRichText())
1561 	{
1562 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1563 		{
1564 			FX_BOOL bSet = FALSE;
1565 			CPVT_Section secinfo;
1566 			CPVT_Section OldSecinfo;
1567 
1568 			CPVT_WordPlace oldplace = pIterator->GetAt();
1569 
1570 			if (eProps == EP_LINELEADING || eProps == EP_LINEINDENT || eProps == EP_ALIGNMENT)
1571 			{
1572 				if (pSecProps)
1573 				{
1574 					pIterator->SetAt(place);
1575 					if (pIterator->GetSection(secinfo))
1576 					{
1577 						if (bAddUndo) OldSecinfo = secinfo;
1578 
1579 						switch(eProps)
1580 						{
1581 						case EP_LINELEADING:
1582 							if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineLeading,pSecProps->fLineLeading))
1583 							{
1584 								secinfo.SecProps.fLineLeading = pSecProps->fLineLeading;
1585 								bSet = TRUE;
1586 							}
1587 							break;
1588 						case EP_LINEINDENT:
1589 							if (!FX_EDIT_IsFloatEqual(secinfo.SecProps.fLineIndent,pSecProps->fLineIndent))
1590 							{
1591 								secinfo.SecProps.fLineIndent = pSecProps->fLineIndent;
1592 								bSet = TRUE;
1593 							}
1594 							break;
1595 						case EP_ALIGNMENT:
1596 							if (secinfo.SecProps.nAlignment != pSecProps->nAlignment)
1597 							{
1598 								secinfo.SecProps.nAlignment = pSecProps->nAlignment;
1599 								bSet = TRUE;
1600 							}
1601 							break;
1602 						default:
1603 							break;
1604 						}
1605 					}
1606 				}
1607 			}
1608 			else
1609 			{
1610 				if (pWordProps && place == m_pVT->GetSectionBeginPlace(place))
1611 				{
1612 					pIterator->SetAt(place);
1613 					if (pIterator->GetSection(secinfo))
1614 					{
1615 						if (bAddUndo) OldSecinfo = secinfo;
1616 
1617 						switch(eProps)
1618 						{
1619 						case EP_FONTINDEX:
1620 							if (secinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
1621 							{
1622 								secinfo.WordProps.nFontIndex = pWordProps->nFontIndex;
1623 								bSet = TRUE;
1624 							}
1625 							break;
1626 						case EP_FONTSIZE:
1627 							if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fFontSize,pWordProps->fFontSize))
1628 							{
1629 								secinfo.WordProps.fFontSize = pWordProps->fFontSize;
1630 								bSet = TRUE;
1631 							}
1632 							break;
1633 						case EP_WORDCOLOR:
1634 							if (secinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
1635 							{
1636 								secinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
1637 								bSet = TRUE;
1638 							}
1639 							break;
1640 						case EP_SCRIPTTYPE:
1641 							if (secinfo.WordProps.nScriptType != pWordProps->nScriptType)
1642 							{
1643 								secinfo.WordProps.nScriptType = pWordProps->nScriptType;
1644 								bSet = TRUE;
1645 							}
1646 							break;
1647 						case EP_CHARSPACE:
1648 							if (!FX_EDIT_IsFloatEqual(secinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
1649 							{
1650 								secinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
1651 								bSet = TRUE;
1652 							}
1653 							break;
1654 						case EP_HORZSCALE:
1655 							if (secinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
1656 							{
1657 								secinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
1658 								bSet = TRUE;
1659 							}
1660 							break;
1661 						case EP_UNDERLINE:
1662 							if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
1663 							{
1664 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
1665 								{
1666 									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
1667 									bSet = TRUE;
1668 								}
1669 							}
1670 							else
1671 							{
1672 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
1673 								{
1674 									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
1675 									bSet = TRUE;
1676 								}
1677 							}
1678 							break;
1679 						case EP_CROSSOUT:
1680 							if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
1681 							{
1682 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
1683 								{
1684 									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
1685 									bSet = TRUE;
1686 								}
1687 							}
1688 							else
1689 							{
1690 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
1691 								{
1692 									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
1693 									bSet = TRUE;
1694 								}
1695 							}
1696 							break;
1697 						case EP_BOLD:
1698 							if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
1699 							{
1700 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
1701 								{
1702 									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
1703 									bSet = TRUE;
1704 								}
1705 							}
1706 							else
1707 							{
1708 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
1709 								{
1710 									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
1711 									bSet = TRUE;
1712 								}
1713 							}
1714 							break;
1715 						case EP_ITALIC:
1716 							if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
1717 							{
1718 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
1719 								{
1720 									secinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
1721 									bSet = TRUE;
1722 								}
1723 							}
1724 							else
1725 							{
1726 								if ((secinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
1727 								{
1728 									secinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
1729 									bSet = TRUE;
1730 								}
1731 							}
1732 							break;
1733 						default:
1734 							break;
1735 						}
1736 					}
1737 				}
1738 			}
1739 
1740 			if (bSet)
1741 			{
1742 				pIterator->SetSection(secinfo);
1743 
1744 				if (bAddUndo && m_bEnableUndo)
1745 				{
1746 					AddEditUndoItem(new CFXEU_SetSecProps
1747 						(this,place,eProps,OldSecinfo.SecProps,OldSecinfo.WordProps,secinfo.SecProps,secinfo.WordProps,wr));
1748 				}
1749 			}
1750 
1751 			pIterator->SetAt(oldplace);
1752 
1753 			return bSet;
1754 		}
1755 	}
1756 
1757 	return FALSE;
1758 }
1759 
SetWordProps(EDIT_PROPS_E eProps,const CPVT_WordPlace & place,const CPVT_WordProps * pWordProps,const CPVT_WordRange & wr,FX_BOOL bAddUndo)1760 FX_BOOL CFX_Edit::SetWordProps(EDIT_PROPS_E eProps, const CPVT_WordPlace & place,
1761 								const CPVT_WordProps * pWordProps, const CPVT_WordRange & wr, FX_BOOL bAddUndo)
1762 {
1763 	if (m_pVT->IsValid() && m_pVT->IsRichText())
1764 	{
1765 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
1766 		{
1767 			FX_BOOL bSet = FALSE;
1768 			CPVT_Word wordinfo;
1769 			CPVT_Word OldWordinfo;
1770 
1771 			CPVT_WordPlace oldplace = pIterator->GetAt();
1772 
1773 			if (pWordProps)
1774 			{
1775 				pIterator->SetAt(place);
1776 				if (pIterator->GetWord(wordinfo))
1777 				{
1778 					if (bAddUndo) OldWordinfo = wordinfo;
1779 
1780 					switch(eProps)
1781 					{
1782 					case EP_FONTINDEX:
1783 						if (wordinfo.WordProps.nFontIndex != pWordProps->nFontIndex)
1784 						{
1785 							if (IFX_Edit_FontMap* pFontMap = this->GetFontMap())
1786 							{
1787 								wordinfo.WordProps.nFontIndex = pFontMap->GetWordFontIndex(wordinfo.Word,wordinfo.nCharset,pWordProps->nFontIndex);
1788 							}
1789 							bSet = TRUE;
1790 						}
1791 						break;
1792 					case EP_FONTSIZE:
1793 						if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fFontSize,pWordProps->fFontSize))
1794 						{
1795 							wordinfo.WordProps.fFontSize = pWordProps->fFontSize;
1796 							bSet = TRUE;
1797 						}
1798 						break;
1799 					case EP_WORDCOLOR:
1800 						if (wordinfo.WordProps.dwWordColor != pWordProps->dwWordColor)
1801 						{
1802 							wordinfo.WordProps.dwWordColor = pWordProps->dwWordColor;
1803 							bSet = TRUE;
1804 						}
1805 						break;
1806 					case EP_SCRIPTTYPE:
1807 						if (wordinfo.WordProps.nScriptType != pWordProps->nScriptType)
1808 						{
1809 							wordinfo.WordProps.nScriptType = pWordProps->nScriptType;
1810 							bSet = TRUE;
1811 						}
1812 						break;
1813 					case EP_CHARSPACE:
1814 						if (!FX_EDIT_IsFloatEqual(wordinfo.WordProps.fCharSpace,pWordProps->fCharSpace))
1815 						{
1816 							wordinfo.WordProps.fCharSpace = pWordProps->fCharSpace;
1817 							bSet = TRUE;
1818 						}
1819 						break;
1820 					case EP_HORZSCALE:
1821 						if (wordinfo.WordProps.nHorzScale != pWordProps->nHorzScale)
1822 						{
1823 							wordinfo.WordProps.nHorzScale = pWordProps->nHorzScale;
1824 							bSet = TRUE;
1825 						}
1826 						break;
1827 					case EP_UNDERLINE:
1828 						if (pWordProps->nWordStyle & PVTWORD_STYLE_UNDERLINE)
1829 						{
1830 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) == 0)
1831 							{
1832 								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_UNDERLINE;
1833 								bSet = TRUE;
1834 							}
1835 						}
1836 						else
1837 						{
1838 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_UNDERLINE) != 0)
1839 							{
1840 								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_UNDERLINE;
1841 								bSet = TRUE;
1842 							}
1843 						}
1844 						break;
1845 					case EP_CROSSOUT:
1846 						if (pWordProps->nWordStyle & PVTWORD_STYLE_CROSSOUT)
1847 						{
1848 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) == 0)
1849 							{
1850 								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_CROSSOUT;
1851 								bSet = TRUE;
1852 							}
1853 						}
1854 						else
1855 						{
1856 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_CROSSOUT) != 0)
1857 							{
1858 								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_CROSSOUT;
1859 								bSet = TRUE;
1860 							}
1861 						}
1862 						break;
1863 					case EP_BOLD:
1864 						if (pWordProps->nWordStyle & PVTWORD_STYLE_BOLD)
1865 						{
1866 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) == 0)
1867 							{
1868 								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_BOLD;
1869 								bSet = TRUE;
1870 							}
1871 						}
1872 						else
1873 						{
1874 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_BOLD) != 0)
1875 							{
1876 								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_BOLD;
1877 								bSet = TRUE;
1878 							}
1879 						}
1880 						break;
1881 					case EP_ITALIC:
1882 						if (pWordProps->nWordStyle & PVTWORD_STYLE_ITALIC)
1883 						{
1884 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) == 0)
1885 							{
1886 								wordinfo.WordProps.nWordStyle |= PVTWORD_STYLE_ITALIC;
1887 								bSet = TRUE;
1888 							}
1889 						}
1890 						else
1891 						{
1892 							if ((wordinfo.WordProps.nWordStyle & PVTWORD_STYLE_ITALIC) != 0)
1893 							{
1894 								wordinfo.WordProps.nWordStyle &= ~PVTWORD_STYLE_ITALIC;
1895 								bSet = TRUE;
1896 							}
1897 						}
1898 						break;
1899 					default:
1900 						break;
1901 					}
1902 				}
1903 			}
1904 
1905 			if (bSet)
1906 			{
1907 				pIterator->SetWord(wordinfo);
1908 
1909 				if (bAddUndo && m_bEnableUndo)
1910 				{
1911 					AddEditUndoItem(new CFXEU_SetWordProps
1912 						(this,place,eProps,OldWordinfo.WordProps,wordinfo.WordProps,wr));
1913 				}
1914 			}
1915 
1916 			pIterator->SetAt(oldplace);
1917 			return bSet;
1918 		}
1919 	}
1920 
1921 	return FALSE;
1922 }
1923 
SetText(FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)1924 void CFX_Edit::SetText(FX_LPCWSTR text,FX_INT32 charset /*= DEFAULT_CHARSET*/,
1925 						const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
1926 {
1927 	SetText(text,charset,pSecProps,pWordProps,TRUE,TRUE);
1928 }
1929 
InsertWord(FX_WORD word,FX_INT32 charset,const CPVT_WordProps * pWordProps)1930 FX_BOOL CFX_Edit::InsertWord(FX_WORD word, FX_INT32 charset /*= DEFAULT_CHARSET*/, const CPVT_WordProps * pWordProps /*= NULL*/)
1931 {
1932 	return InsertWord(word,charset,pWordProps,TRUE,TRUE);
1933 }
1934 
InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)1935 FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
1936 {
1937 	return InsertReturn(pSecProps,pWordProps,TRUE,TRUE);
1938 }
1939 
Backspace()1940 FX_BOOL CFX_Edit::Backspace()
1941 {
1942 	return Backspace(TRUE,TRUE);
1943 }
1944 
Delete()1945 FX_BOOL CFX_Edit::Delete()
1946 {
1947 	return Delete(TRUE,TRUE);
1948 }
1949 
Clear()1950 FX_BOOL CFX_Edit::Clear()
1951 {
1952 	return Clear(TRUE,TRUE);
1953 }
1954 
InsertText(FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)1955 FX_BOOL CFX_Edit::InsertText(FX_LPCWSTR text, FX_INT32 charset /*= DEFAULT_CHARSET*/,
1956 								const CPVT_SecProps * pSecProps /*= NULL*/,const CPVT_WordProps * pWordProps /*= NULL*/)
1957 {
1958 	return InsertText(text,charset,pSecProps,pWordProps,TRUE,TRUE);
1959 }
1960 
GetFontSize() const1961 FX_FLOAT CFX_Edit::GetFontSize() const
1962 {
1963 	return m_pVT->GetFontSize();
1964 }
1965 
GetPasswordChar() const1966 FX_WORD CFX_Edit::GetPasswordChar() const
1967 {
1968 	return m_pVT->GetPasswordChar();
1969 }
1970 
GetCharArray() const1971 FX_INT32 CFX_Edit::GetCharArray() const
1972 {
1973 	return m_pVT->GetCharArray();
1974 }
1975 
GetPlateRect() const1976 CPDF_Rect CFX_Edit::GetPlateRect() const
1977 {
1978 	return m_pVT->GetPlateRect();
1979 }
1980 
GetContentRect() const1981 CPDF_Rect CFX_Edit::GetContentRect() const
1982 {
1983 	return VTToEdit(m_pVT->GetContentRect());
1984 }
1985 
GetHorzScale() const1986 FX_INT32 CFX_Edit::GetHorzScale() const
1987 {
1988 	return m_pVT->GetHorzScale();
1989 }
1990 
GetCharSpace() const1991 FX_FLOAT CFX_Edit::GetCharSpace() const
1992 {
1993 	return m_pVT->GetCharSpace();
1994 }
1995 
1996 // inner methods
1997 
GetWholeWordRange() const1998 CPVT_WordRange CFX_Edit::GetWholeWordRange() const
1999 {
2000 	if (m_pVT->IsValid())
2001 		return CPVT_WordRange(m_pVT->GetBeginWordPlace(),m_pVT->GetEndWordPlace());
2002 
2003 	return CPVT_WordRange();
2004 }
2005 
GetVisibleWordRange() const2006 CPVT_WordRange CFX_Edit::GetVisibleWordRange() const
2007 {
2008 	if (m_bEnableOverflow) return GetWholeWordRange();
2009 
2010 	if (m_pVT->IsValid())
2011 	{
2012 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2013 
2014 		CPVT_WordPlace place1 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.left,rcPlate.top)));
2015 		CPVT_WordPlace place2 = m_pVT->SearchWordPlace(EditToVT(CPDF_Point(rcPlate.right,rcPlate.bottom)));
2016 
2017 		return CPVT_WordRange(place1,place2);
2018 	}
2019 
2020 	return CPVT_WordRange();
2021 }
2022 
SearchWordPlace(const CPDF_Point & point) const2023 CPVT_WordPlace CFX_Edit::SearchWordPlace(const CPDF_Point& point) const
2024 {
2025 	if (m_pVT->IsValid())
2026 	{
2027 		return m_pVT->SearchWordPlace(EditToVT(point));
2028 	}
2029 
2030 	return CPVT_WordPlace();
2031 }
2032 
Paint()2033 void CFX_Edit::Paint()
2034 {
2035 	if (m_pVT->IsValid())
2036 	{
2037 		RearrangeAll();
2038 		ScrollToCaret();
2039 		Refresh(RP_NOANALYSE);
2040 		SetCaretOrigin();
2041 		SetCaretInfo();
2042 	}
2043 }
2044 
RearrangeAll()2045 void CFX_Edit::RearrangeAll()
2046 {
2047 	if (m_pVT->IsValid())
2048 	{
2049 		m_pVT->UpdateWordPlace(m_wpCaret);
2050 		m_pVT->RearrangeAll();
2051 		m_pVT->UpdateWordPlace(m_wpCaret);
2052 		SetScrollInfo();
2053 		SetContentChanged();
2054 	}
2055 }
2056 
RearrangePart(const CPVT_WordRange & range)2057 void CFX_Edit::RearrangePart(const CPVT_WordRange & range)
2058 {
2059 	if (m_pVT->IsValid())
2060 	{
2061 		m_pVT->UpdateWordPlace(m_wpCaret);
2062 		m_pVT->RearrangePart(range);
2063 		m_pVT->UpdateWordPlace(m_wpCaret);
2064 		SetScrollInfo();
2065 		SetContentChanged();
2066 	}
2067 }
2068 
SetContentChanged()2069 void CFX_Edit::SetContentChanged()
2070 {
2071 	if (m_bNotify && m_pNotify)
2072 	{
2073 		CPDF_Rect rcContent = m_pVT->GetContentRect();
2074 		if (rcContent.Width() != m_rcOldContent.Width() ||
2075 			rcContent.Height() != m_rcOldContent.Height())
2076 		{
2077 			if (!m_bNotifyFlag)
2078 			{
2079 				m_bNotifyFlag = TRUE;
2080 				m_pNotify->IOnContentChange(rcContent);
2081 				m_bNotifyFlag = FALSE;
2082 			}
2083 			m_rcOldContent = rcContent;
2084 		}
2085 	}
2086 }
2087 
SelectAll()2088 void CFX_Edit::SelectAll()
2089 {
2090 	if (m_pVT->IsValid())
2091 	{
2092 		m_SelState = GetWholeWordRange();
2093 		SetCaret(m_SelState.EndPos);
2094 
2095 		ScrollToCaret();
2096 		CPVT_WordRange wrVisible = GetVisibleWordRange();
2097 		Refresh(RP_OPTIONAL,&wrVisible);
2098 		SetCaretInfo();
2099 	}
2100 }
2101 
SelectNone()2102 void CFX_Edit::SelectNone()
2103 {
2104 	if (m_pVT->IsValid())
2105 	{
2106 		if (m_SelState.IsExist())
2107 		{
2108 			CPVT_WordRange wrTemp = m_SelState.ConvertToWordRange();
2109 			m_SelState.Default();
2110 			Refresh(RP_OPTIONAL,&wrTemp);
2111 		}
2112 	}
2113 }
2114 
IsSelected() const2115 FX_BOOL	CFX_Edit::IsSelected() const
2116 {
2117 	return m_SelState.IsExist();
2118 }
2119 
VTToEdit(const CPDF_Point & point) const2120 CPDF_Point CFX_Edit::VTToEdit(const CPDF_Point & point) const
2121 {
2122 	CPDF_Rect rcContent = m_pVT->GetContentRect();
2123 	CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2124 
2125 	FX_FLOAT fPadding = 0.0f;
2126 
2127 	switch (m_nAlignment)
2128 	{
2129 	case 0:
2130 		fPadding = 0.0f;
2131 		break;
2132 	case 1:
2133 		fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
2134 		break;
2135 	case 2:
2136 		fPadding = rcPlate.Height() - rcContent.Height();
2137 		break;
2138 	}
2139 
2140 	return CPDF_Point(point.x - (m_ptScrollPos.x - rcPlate.left),
2141 		point.y - (m_ptScrollPos.y + fPadding - rcPlate.top));
2142 }
2143 
EditToVT(const CPDF_Point & point) const2144 CPDF_Point CFX_Edit::EditToVT(const CPDF_Point & point) const
2145 {
2146 	CPDF_Rect rcContent = m_pVT->GetContentRect();
2147 	CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2148 
2149 	FX_FLOAT fPadding = 0.0f;
2150 
2151 	switch (m_nAlignment)
2152 	{
2153 	case 0:
2154 		fPadding = 0.0f;
2155 		break;
2156 	case 1:
2157 		fPadding = (rcPlate.Height() - rcContent.Height()) * 0.5f;
2158 		break;
2159 	case 2:
2160 		fPadding = rcPlate.Height() - rcContent.Height();
2161 		break;
2162 	}
2163 
2164 	return CPDF_Point(point.x + (m_ptScrollPos.x - rcPlate.left),
2165 		point.y + (m_ptScrollPos.y + fPadding - rcPlate.top));
2166 }
2167 
VTToEdit(const CPDF_Rect & rect) const2168 CPDF_Rect CFX_Edit::VTToEdit(const CPDF_Rect & rect) const
2169 {
2170 	CPDF_Point ptLeftBottom = VTToEdit(CPDF_Point(rect.left,rect.bottom));
2171 	CPDF_Point ptRightTop = VTToEdit(CPDF_Point(rect.right,rect.top));
2172 
2173 	return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
2174 }
2175 
EditToVT(const CPDF_Rect & rect) const2176 CPDF_Rect CFX_Edit::EditToVT(const CPDF_Rect & rect) const
2177 {
2178 	CPDF_Point ptLeftBottom = EditToVT(CPDF_Point(rect.left,rect.bottom));
2179 	CPDF_Point ptRightTop = EditToVT(CPDF_Point(rect.right,rect.top));
2180 
2181 	return CPDF_Rect(ptLeftBottom.x,ptLeftBottom.y,ptRightTop.x,ptRightTop.y);
2182 }
2183 
SetScrollInfo()2184 void CFX_Edit::SetScrollInfo()
2185 {
2186 	if (m_bNotify && m_pNotify)
2187 	{
2188 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2189 		CPDF_Rect rcContent = m_pVT->GetContentRect();
2190 
2191 		if (!m_bNotifyFlag)
2192 		{
2193 			m_bNotifyFlag = TRUE;
2194 			m_pNotify->IOnSetScrollInfoX(rcPlate.left, rcPlate.right,
2195 								rcContent.left, rcContent.right, rcPlate.Width() / 3, rcPlate.Width());
2196 
2197 			m_pNotify->IOnSetScrollInfoY(rcPlate.bottom, rcPlate.top,
2198 					rcContent.bottom, rcContent.top, rcPlate.Height() / 3, rcPlate.Height());
2199 			m_bNotifyFlag = FALSE;
2200 		}
2201 	}
2202 }
2203 
SetScrollPosX(FX_FLOAT fx)2204 void CFX_Edit::SetScrollPosX(FX_FLOAT fx)
2205 {
2206 	if (!m_bEnableScroll) return;
2207 
2208 	if (m_pVT->IsValid())
2209 	{
2210 		if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.x,fx))
2211 		{
2212 			m_ptScrollPos.x = fx;
2213 			Refresh(RP_NOANALYSE);
2214 
2215 			if (m_bNotify && m_pNotify)
2216 			{
2217 				if (!m_bNotifyFlag)
2218 				{
2219 					m_bNotifyFlag = TRUE;
2220 					m_pNotify->IOnSetScrollPosX(fx);
2221 					m_bNotifyFlag = FALSE;
2222 				}
2223 			}
2224 		}
2225 	}
2226 }
2227 
SetScrollPosY(FX_FLOAT fy)2228 void CFX_Edit::SetScrollPosY(FX_FLOAT fy)
2229 {
2230 	if (!m_bEnableScroll) return;
2231 
2232 	if (m_pVT->IsValid())
2233 	{
2234 		if (!FX_EDIT_IsFloatEqual(m_ptScrollPos.y,fy))
2235 		{
2236 			m_ptScrollPos.y = fy;
2237 			Refresh(RP_NOANALYSE);
2238 
2239 			if (m_bNotify && m_pNotify)
2240 			{
2241 				if (!m_bNotifyFlag)
2242 				{
2243 					m_bNotifyFlag = TRUE;
2244 					m_pNotify->IOnSetScrollPosY(fy);
2245 					m_bNotifyFlag = FALSE;
2246 				}
2247 			}
2248 		}
2249 	}
2250 }
2251 
SetScrollPos(const CPDF_Point & point)2252 void CFX_Edit::SetScrollPos(const CPDF_Point & point)
2253 {
2254 	SetScrollPosX(point.x);
2255 	SetScrollPosY(point.y);
2256 	SetScrollLimit();
2257 	SetCaretInfo();
2258 }
2259 
GetScrollPos() const2260 CPDF_Point CFX_Edit::GetScrollPos() const
2261 {
2262 	return m_ptScrollPos;
2263 }
2264 
SetScrollLimit()2265 void CFX_Edit::SetScrollLimit()
2266 {
2267 	if (m_pVT->IsValid())
2268 	{
2269 		CPDF_Rect rcContent = m_pVT->GetContentRect();
2270 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2271 
2272 		if (rcPlate.Width() > rcContent.Width())
2273 		{
2274 			SetScrollPosX(rcPlate.left);
2275 		}
2276 		else
2277 		{
2278 			if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.x, rcContent.left))
2279 			{
2280 				SetScrollPosX(rcContent.left);
2281 			}
2282 			else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.x, rcContent.right - rcPlate.Width()))
2283 			{
2284 				SetScrollPosX(rcContent.right - rcPlate.Width());
2285 			}
2286 		}
2287 
2288 		if (rcPlate.Height() > rcContent.Height())
2289 		{
2290 			SetScrollPosY(rcPlate.top);
2291 		}
2292 		else
2293 		{
2294 			if (FX_EDIT_IsFloatSmaller(m_ptScrollPos.y, rcContent.bottom + rcPlate.Height()))
2295 			{
2296 				SetScrollPosY(rcContent.bottom + rcPlate.Height());
2297 			}
2298 			else if (FX_EDIT_IsFloatBigger(m_ptScrollPos.y, rcContent.top))
2299 			{
2300 				SetScrollPosY(rcContent.top);
2301 			}
2302 		}
2303 	}
2304 }
2305 
ScrollToCaret()2306 void CFX_Edit::ScrollToCaret()
2307 {
2308 	SetScrollLimit();
2309 
2310 	if (m_pVT->IsValid())
2311 	{
2312 		CPDF_Point ptHead(0,0);
2313 		CPDF_Point ptFoot(0,0);
2314 
2315 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2316 		{
2317 			pIterator->SetAt(m_wpCaret);
2318 
2319 			CPVT_Word word;
2320 			CPVT_Line line;
2321 			if (pIterator->GetWord(word))
2322 			{
2323 				ptHead.x = word.ptWord.x + word.fWidth;
2324 				ptHead.y = word.ptWord.y + word.fAscent;
2325 				ptFoot.x = word.ptWord.x + word.fWidth;
2326 				ptFoot.y = word.ptWord.y + word.fDescent;
2327 			}
2328 			else if (pIterator->GetLine(line))
2329 			{
2330 				ptHead.x = line.ptLine.x;
2331 				ptHead.y = line.ptLine.y + line.fLineAscent;
2332 				ptFoot.x = line.ptLine.x;
2333 				ptFoot.y = line.ptLine.y + line.fLineDescent;
2334 			}
2335 		}
2336 
2337 		CPDF_Point ptHeadEdit = VTToEdit(ptHead);
2338 		CPDF_Point ptFootEdit = VTToEdit(ptFoot);
2339 
2340 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
2341 
2342 		if (!FX_EDIT_IsFloatEqual(rcPlate.left,rcPlate.right))
2343 		{
2344 			if (FX_EDIT_IsFloatSmaller(ptHeadEdit.x, rcPlate.left) ||
2345 				FX_EDIT_IsFloatEqual(ptHeadEdit.x, rcPlate.left))
2346 			{
2347 				SetScrollPosX(ptHead.x);
2348 			}
2349 			else if (FX_EDIT_IsFloatBigger(ptHeadEdit.x, rcPlate.right))
2350 			{
2351 				SetScrollPosX(ptHead.x - rcPlate.Width());
2352 			}
2353 		}
2354 
2355 		if (!FX_EDIT_IsFloatEqual(rcPlate.top,rcPlate.bottom))
2356 		{
2357 			if (FX_EDIT_IsFloatSmaller(ptFootEdit.y, rcPlate.bottom) ||
2358 				FX_EDIT_IsFloatEqual(ptFootEdit.y, rcPlate.bottom))
2359 			{
2360 				if (FX_EDIT_IsFloatSmaller(ptHeadEdit.y, rcPlate.top))
2361 				{
2362 					SetScrollPosY(ptFoot.y + rcPlate.Height());
2363 				}
2364 			}
2365 			else if (FX_EDIT_IsFloatBigger(ptHeadEdit.y, rcPlate.top))
2366 			{
2367 				if (FX_EDIT_IsFloatBigger(ptFootEdit.y, rcPlate.bottom))
2368 				{
2369 					SetScrollPosY(ptHead.y);
2370 				}
2371 			}
2372 		}
2373 	}
2374 }
2375 
Refresh(REFRESH_PLAN_E ePlan,const CPVT_WordRange * pRange1,const CPVT_WordRange * pRange2)2376 void CFX_Edit::Refresh(REFRESH_PLAN_E ePlan,const CPVT_WordRange * pRange1,const CPVT_WordRange * pRange2)
2377 {
2378 	if (m_bEnableRefresh && m_pVT->IsValid())
2379 	{
2380 		m_Refresh.BeginRefresh();
2381 		RefreshPushLineRects(GetVisibleWordRange());
2382 
2383 // 		if (!FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.x,m_ptScrollPos.x) ||
2384 // 			!FX_EDIT_IsFloatEqual(m_ptRefreshScrollPos.y,m_ptScrollPos.y))
2385 // 		{
2386 			m_Refresh.NoAnalyse();
2387 			m_ptRefreshScrollPos = m_ptScrollPos;
2388 // 		}
2389 // 		else
2390 // 		{
2391 // 			switch (ePlan)
2392 // 			{
2393 // 			case RP_ANALYSE:
2394 // 				m_Refresh.Analyse(m_pVT->GetAlignment());
2395 //
2396 // 				if (pRange1) RefreshPushRandomRects(*pRange1);
2397 // 				if (pRange2) RefreshPushRandomRects(*pRange2);
2398 // 				break;
2399 // 			case RP_NOANALYSE:
2400 // 				m_Refresh.NoAnalyse();
2401 // 				break;
2402 // 			case RP_OPTIONAL:
2403 // 				if (pRange1) RefreshPushRandomRects(*pRange1);
2404 // 				if (pRange2) RefreshPushRandomRects(*pRange2);
2405 // 				break;
2406 // 			}
2407 // 		}
2408 
2409 		if (m_bNotify && m_pNotify)
2410 		{
2411 			if (!m_bNotifyFlag)
2412 			{
2413 				m_bNotifyFlag = TRUE;
2414 				if (const CFX_Edit_RectArray * pRects = m_Refresh.GetRefreshRects())
2415 				{
2416 					for (FX_INT32 i = 0, sz = pRects->GetSize(); i < sz; i++)
2417 						m_pNotify->IOnInvalidateRect(pRects->GetAt(i));
2418 				}
2419 				m_bNotifyFlag = FALSE;
2420 			}
2421 		}
2422 
2423 		m_Refresh.EndRefresh();
2424 	}
2425 }
2426 
RefreshPushLineRects(const CPVT_WordRange & wr)2427 void CFX_Edit::RefreshPushLineRects(const CPVT_WordRange & wr)
2428 {
2429 	if (m_pVT->IsValid())
2430 	{
2431 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2432 		{
2433 			CPVT_WordPlace wpBegin = wr.BeginPos;
2434 			m_pVT->UpdateWordPlace(wpBegin);
2435 			CPVT_WordPlace wpEnd = wr.EndPos;
2436 			m_pVT->UpdateWordPlace(wpEnd);
2437 			pIterator->SetAt(wpBegin);
2438 
2439 			CPVT_Line lineinfo;
2440 			do
2441 			{
2442 				if (!pIterator->GetLine(lineinfo))break;
2443 				if (lineinfo.lineplace.LineCmp(wpEnd) > 0)break;
2444 
2445 				CPDF_Rect rcLine(lineinfo.ptLine.x,
2446 									lineinfo.ptLine.y + lineinfo.fLineDescent,
2447 									lineinfo.ptLine.x + lineinfo.fLineWidth,
2448 									lineinfo.ptLine.y + lineinfo.fLineAscent);
2449 
2450 				m_Refresh.Push(CPVT_WordRange(lineinfo.lineplace,lineinfo.lineEnd),VTToEdit(rcLine));
2451 
2452 			}while (pIterator->NextLine());
2453 		}
2454 	}
2455 }
2456 
RefreshPushRandomRects(const CPVT_WordRange & wr)2457 void CFX_Edit::RefreshPushRandomRects(const CPVT_WordRange & wr)
2458 {
2459 	if (m_pVT->IsValid())
2460 	{
2461 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2462 		{
2463 			CPVT_WordRange wrTemp = wr;
2464 
2465 			m_pVT->UpdateWordPlace(wrTemp.BeginPos);
2466 			m_pVT->UpdateWordPlace(wrTemp.EndPos);
2467 			pIterator->SetAt(wrTemp.BeginPos);
2468 
2469 			CPVT_Word wordinfo;
2470 			CPVT_Line lineinfo;
2471 			CPVT_WordPlace place;
2472 
2473 			while (pIterator->NextWord())
2474 			{
2475 				place = pIterator->GetAt();
2476 				if (place.WordCmp(wrTemp.EndPos) > 0) break;
2477 
2478 				pIterator->GetWord(wordinfo);
2479 				pIterator->GetLine(lineinfo);
2480 
2481 				if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
2482 				{
2483 					CPDF_Rect rcWord(wordinfo.ptWord.x,
2484 										lineinfo.ptLine.y + lineinfo.fLineDescent,
2485 										wordinfo.ptWord.x + wordinfo.fWidth,
2486 										lineinfo.ptLine.y + lineinfo.fLineAscent);
2487 
2488 					m_Refresh.AddRefresh(VTToEdit(rcWord));
2489 				}
2490 				else
2491 				{
2492 					CPDF_Rect rcLine(lineinfo.ptLine.x,
2493 										lineinfo.ptLine.y + lineinfo.fLineDescent,
2494 										lineinfo.ptLine.x + lineinfo.fLineWidth,
2495 										lineinfo.ptLine.y + lineinfo.fLineAscent);
2496 
2497 					m_Refresh.AddRefresh(VTToEdit(rcLine));
2498 
2499 					pIterator->NextLine();
2500 				}
2501 			}
2502 		}
2503 	}
2504 }
2505 
RefreshWordRange(const CPVT_WordRange & wr)2506 void CFX_Edit::RefreshWordRange(const CPVT_WordRange& wr)
2507 {
2508 	if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2509 	{
2510 		CPVT_WordRange wrTemp = wr;
2511 
2512 		m_pVT->UpdateWordPlace(wrTemp.BeginPos);
2513 		m_pVT->UpdateWordPlace(wrTemp.EndPos);
2514 		pIterator->SetAt(wrTemp.BeginPos);
2515 
2516 		CPVT_Word wordinfo;
2517 		CPVT_Line lineinfo;
2518 		CPVT_WordPlace place;
2519 
2520 		while (pIterator->NextWord())
2521 		{
2522 			place = pIterator->GetAt();
2523 			if (place.WordCmp(wrTemp.EndPos) > 0) break;
2524 
2525 			pIterator->GetWord(wordinfo);
2526 			pIterator->GetLine(lineinfo);
2527 
2528 			if (place.LineCmp(wrTemp.BeginPos) == 0 || place.LineCmp(wrTemp.EndPos) == 0)
2529 			{
2530 				CPDF_Rect rcWord(wordinfo.ptWord.x,
2531 									lineinfo.ptLine.y + lineinfo.fLineDescent,
2532 									wordinfo.ptWord.x + wordinfo.fWidth,
2533 									lineinfo.ptLine.y + lineinfo.fLineAscent);
2534 
2535 				if (m_bNotify && m_pNotify)
2536 				{
2537 					if (!m_bNotifyFlag)
2538 					{
2539 						m_bNotifyFlag = TRUE;
2540 						CPDF_Rect rcRefresh = VTToEdit(rcWord);
2541 						m_pNotify->IOnInvalidateRect(&rcRefresh);
2542 						m_bNotifyFlag = FALSE;
2543 					}
2544 				}
2545 			}
2546 			else
2547 			{
2548 				CPDF_Rect rcLine(lineinfo.ptLine.x,
2549 									lineinfo.ptLine.y + lineinfo.fLineDescent,
2550 									lineinfo.ptLine.x + lineinfo.fLineWidth,
2551 									lineinfo.ptLine.y + lineinfo.fLineAscent);
2552 
2553 				if (m_bNotify && m_pNotify)
2554 				{
2555 					if (!m_bNotifyFlag)
2556 					{
2557 						m_bNotifyFlag = TRUE;
2558 						CPDF_Rect rcRefresh = VTToEdit(rcLine);
2559 						m_pNotify->IOnInvalidateRect(&rcRefresh);
2560 						m_bNotifyFlag = FALSE;
2561 					}
2562 				}
2563 
2564 				pIterator->NextLine();
2565 			}
2566 		}
2567 	}
2568 }
2569 
SetCaret(const CPVT_WordPlace & place)2570 void CFX_Edit::SetCaret(const CPVT_WordPlace & place)
2571 {
2572 	m_wpOldCaret = m_wpCaret;
2573 	m_wpCaret = place;
2574 }
2575 
SetCaretInfo()2576 void CFX_Edit::SetCaretInfo()
2577 {
2578 	if (m_bNotify && m_pNotify)
2579 	{
2580 		if (!m_bNotifyFlag)
2581 		{
2582 			CPDF_Point ptHead(0.0f,0.0f),ptFoot(0.0f,0.0f);
2583 
2584 			if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2585 			{
2586 				pIterator->SetAt(m_wpCaret);
2587 				CPVT_Word word;
2588 				CPVT_Line line;
2589 				if (pIterator->GetWord(word))
2590 				{
2591 					ptHead.x = word.ptWord.x + word.fWidth;
2592 					ptHead.y = word.ptWord.y + word.fAscent;
2593 					ptFoot.x = word.ptWord.x + word.fWidth;
2594 					ptFoot.y = word.ptWord.y + word.fDescent;
2595 				}
2596 				else if (pIterator->GetLine(line))
2597 				{
2598 					ptHead.x = line.ptLine.x;
2599 					ptHead.y = line.ptLine.y + line.fLineAscent;
2600 					ptFoot.x = line.ptLine.x;
2601 					ptFoot.y = line.ptLine.y + line.fLineDescent;
2602 				}
2603 			}
2604 
2605 			m_bNotifyFlag = TRUE;
2606 			m_pNotify->IOnSetCaret(!m_SelState.IsExist(),VTToEdit(ptHead),VTToEdit(ptFoot), m_wpCaret);
2607 			m_bNotifyFlag = FALSE;
2608 		}
2609 	}
2610 
2611 	SetCaretChange();
2612 }
2613 
SetCaretChange()2614 void CFX_Edit::SetCaretChange()
2615 {
2616 	if (this->m_wpCaret == this->m_wpOldCaret) return;
2617 
2618 	if (m_bNotify && m_pVT->IsRichText() && m_pNotify)
2619 	{
2620 		CPVT_SecProps SecProps;
2621 		CPVT_WordProps WordProps;
2622 
2623 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
2624 		{
2625 			pIterator->SetAt(m_wpCaret);
2626 			CPVT_Word word;
2627 			CPVT_Section section;
2628 
2629 			if (pIterator->GetSection(section))
2630 			{
2631 				SecProps = section.SecProps;
2632 				WordProps = section.WordProps;
2633 			}
2634 
2635 			if (pIterator->GetWord(word))
2636 			{
2637 				WordProps = word.WordProps;
2638 			}
2639 		}
2640 
2641 		if (!m_bNotifyFlag)
2642 		{
2643 			m_bNotifyFlag = TRUE;
2644 			m_pNotify->IOnCaretChange(SecProps,WordProps);
2645 			m_bNotifyFlag = FALSE;
2646 		}
2647 	}
2648 }
2649 
SetCaret(FX_INT32 nPos)2650 void CFX_Edit::SetCaret(FX_INT32 nPos)
2651 {
2652 	if (m_pVT->IsValid())
2653 	{
2654 		SelectNone();
2655 		SetCaret(m_pVT->WordIndexToWordPlace(nPos));
2656 		m_SelState.Set(m_wpCaret,m_wpCaret);
2657 
2658 		ScrollToCaret();
2659 		SetCaretOrigin();
2660 		SetCaretInfo();
2661 	}
2662 }
2663 
OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)2664 void CFX_Edit::OnMouseDown(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
2665 {
2666 	if (m_pVT->IsValid())
2667 	{
2668 		SelectNone();
2669 		SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
2670 		m_SelState.Set(m_wpCaret,m_wpCaret);
2671 
2672 		ScrollToCaret();
2673 		SetCaretOrigin();
2674 		SetCaretInfo();
2675 	}
2676 }
2677 
OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)2678 void CFX_Edit::OnMouseMove(const CPDF_Point & point,FX_BOOL bShift,FX_BOOL bCtrl)
2679 {
2680 	if (m_pVT->IsValid())
2681 	{
2682 		SetCaret(m_pVT->SearchWordPlace(EditToVT(point)));
2683 
2684 		if (m_wpCaret != m_wpOldCaret)
2685 		{
2686 			m_SelState.SetEndPos(m_wpCaret);
2687 
2688 			ScrollToCaret();
2689 			CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2690 			Refresh(RP_OPTIONAL,&wr);
2691 			SetCaretOrigin();
2692 			SetCaretInfo();
2693 		}
2694 	}
2695 }
2696 
OnVK_UP(FX_BOOL bShift,FX_BOOL bCtrl)2697 void CFX_Edit::OnVK_UP(FX_BOOL bShift,FX_BOOL bCtrl)
2698 {
2699 	if (m_pVT->IsValid())
2700 	{
2701 		SetCaret(m_pVT->GetUpWordPlace(m_wpCaret,m_ptCaret));
2702 
2703 		if (bShift)
2704 		{
2705 			if (m_SelState.IsExist())
2706 				m_SelState.SetEndPos(m_wpCaret);
2707 			else
2708 				m_SelState.Set(m_wpOldCaret,m_wpCaret);
2709 
2710 			if (m_wpOldCaret != m_wpCaret)
2711 			{
2712 				ScrollToCaret();
2713 				CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
2714 				Refresh(RP_OPTIONAL, &wr);
2715 				SetCaretInfo();
2716 			}
2717 		}
2718 		else
2719 		{
2720 			SelectNone();
2721 
2722 			ScrollToCaret();
2723 			SetCaretInfo();
2724 		}
2725 	}
2726 }
2727 
OnVK_DOWN(FX_BOOL bShift,FX_BOOL bCtrl)2728 void CFX_Edit::OnVK_DOWN(FX_BOOL bShift,FX_BOOL bCtrl)
2729 {
2730 	if (m_pVT->IsValid())
2731 	{
2732 		SetCaret(m_pVT->GetDownWordPlace(m_wpCaret,m_ptCaret));
2733 
2734 		if (bShift)
2735 		{
2736 			if (m_SelState.IsExist())
2737 				m_SelState.SetEndPos(m_wpCaret);
2738 			else
2739 				m_SelState.Set(m_wpOldCaret,m_wpCaret);
2740 
2741 			if (m_wpOldCaret != m_wpCaret)
2742 			{
2743 				ScrollToCaret();
2744 				CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2745 				Refresh(RP_OPTIONAL, &wr);
2746 				SetCaretInfo();
2747 			}
2748 		}
2749 		else
2750 		{
2751 			SelectNone();
2752 
2753 			ScrollToCaret();
2754 			SetCaretInfo();
2755 		}
2756 	}
2757 }
2758 
OnVK_LEFT(FX_BOOL bShift,FX_BOOL bCtrl)2759 void CFX_Edit::OnVK_LEFT(FX_BOOL bShift,FX_BOOL bCtrl)
2760 {
2761 	if (m_pVT->IsValid())
2762 	{
2763 		if (bShift)
2764 		{
2765 			if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
2766 				m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
2767 				SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2768 
2769 			SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2770 
2771 			if (m_SelState.IsExist())
2772 				m_SelState.SetEndPos(m_wpCaret);
2773 			else
2774 				m_SelState.Set(m_wpOldCaret, m_wpCaret);
2775 
2776 			if (m_wpOldCaret != m_wpCaret)
2777 			{
2778 				ScrollToCaret();
2779 				CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2780 				Refresh(RP_OPTIONAL,&wr);
2781 				SetCaretInfo();
2782 			}
2783 		}
2784 		else
2785 		{
2786 			if (m_SelState.IsExist())
2787 			{
2788 				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
2789 					SetCaret(m_SelState.BeginPos);
2790 				else
2791 					SetCaret(m_SelState.EndPos);
2792 
2793 				SelectNone();
2794 				ScrollToCaret();
2795 				SetCaretInfo();
2796 			}
2797 			else
2798 			{
2799 				if (m_wpCaret == m_pVT->GetLineBeginPlace(m_wpCaret) &&
2800 					m_wpCaret != m_pVT->GetSectionBeginPlace(m_wpCaret))
2801 					SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2802 
2803 				SetCaret(m_pVT->GetPrevWordPlace(m_wpCaret));
2804 
2805 				ScrollToCaret();
2806 				SetCaretOrigin();
2807 				SetCaretInfo();
2808 			}
2809 		}
2810 	}
2811 }
2812 
OnVK_RIGHT(FX_BOOL bShift,FX_BOOL bCtrl)2813 void CFX_Edit::OnVK_RIGHT(FX_BOOL bShift,FX_BOOL bCtrl)
2814 {
2815 	if (m_pVT->IsValid())
2816 	{
2817 		if (bShift)
2818 		{
2819 			SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2820 
2821 			if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
2822 				m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
2823 				SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2824 
2825 			if (m_SelState.IsExist())
2826 				m_SelState.SetEndPos(m_wpCaret);
2827 			else
2828 				m_SelState.Set(m_wpOldCaret,m_wpCaret);
2829 
2830 			if (m_wpOldCaret != m_wpCaret)
2831 			{
2832 				ScrollToCaret();
2833 				CPVT_WordRange wr(m_wpOldCaret,m_wpCaret);
2834 				Refresh(RP_OPTIONAL,&wr);
2835 				SetCaretInfo();
2836 			}
2837 		}
2838 		else
2839 		{
2840 			if (m_SelState.IsExist())
2841 			{
2842 				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
2843 					SetCaret(m_SelState.BeginPos);
2844 				else
2845 					SetCaret(m_SelState.EndPos);
2846 
2847 				SelectNone();
2848 				ScrollToCaret();
2849 				SetCaretInfo();
2850 			}
2851 			else
2852 			{
2853 				SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2854 
2855 				if (m_wpCaret == m_pVT->GetLineEndPlace(m_wpCaret) &&
2856 					m_wpCaret != m_pVT->GetSectionEndPlace(m_wpCaret))
2857 					SetCaret(m_pVT->GetNextWordPlace(m_wpCaret));
2858 
2859 				ScrollToCaret();
2860 				SetCaretOrigin();
2861 				SetCaretInfo();
2862 			}
2863 		}
2864 	}
2865 }
2866 
OnVK_HOME(FX_BOOL bShift,FX_BOOL bCtrl)2867 void CFX_Edit::OnVK_HOME(FX_BOOL bShift,FX_BOOL bCtrl)
2868 {
2869 	if (m_pVT->IsValid())
2870 	{
2871 		if (bShift)
2872 		{
2873 			if (bCtrl)
2874 				SetCaret(m_pVT->GetBeginWordPlace());
2875 			else
2876 				SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
2877 
2878 			if (m_SelState.IsExist())
2879 				m_SelState.SetEndPos(m_wpCaret);
2880 			else
2881 				m_SelState.Set(m_wpOldCaret,m_wpCaret);
2882 
2883 			ScrollToCaret();
2884 			CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
2885 			Refresh(RP_OPTIONAL, &wr);
2886 			SetCaretInfo();
2887 		}
2888 		else
2889 		{
2890 			if (m_SelState.IsExist())
2891 			{
2892 				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)<0)
2893 					SetCaret(m_SelState.BeginPos);
2894 				else
2895 					SetCaret(m_SelState.EndPos);
2896 
2897 				SelectNone();
2898 				ScrollToCaret();
2899 				SetCaretInfo();
2900 			}
2901 			else
2902 			{
2903 				if (bCtrl)
2904 					SetCaret(m_pVT->GetBeginWordPlace());
2905 				else
2906 					SetCaret(m_pVT->GetLineBeginPlace(m_wpCaret));
2907 
2908 				ScrollToCaret();
2909 				SetCaretOrigin();
2910 				SetCaretInfo();
2911 			}
2912 		}
2913 	}
2914 }
2915 
OnVK_END(FX_BOOL bShift,FX_BOOL bCtrl)2916 void CFX_Edit::OnVK_END(FX_BOOL bShift,FX_BOOL bCtrl)
2917 {
2918 	if (m_pVT->IsValid())
2919 	{
2920 		if (bShift)
2921 		{
2922 			if (bCtrl)
2923 				SetCaret(m_pVT->GetEndWordPlace());
2924 			else
2925 				SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
2926 
2927 			if (m_SelState.IsExist())
2928 				m_SelState.SetEndPos(m_wpCaret);
2929 			else
2930 				m_SelState.Set(m_wpOldCaret, m_wpCaret);
2931 
2932 			ScrollToCaret();
2933 			CPVT_WordRange wr(m_wpOldCaret, m_wpCaret);
2934 			Refresh(RP_OPTIONAL, &wr);
2935 			SetCaretInfo();
2936 		}
2937 		else
2938 		{
2939 			if (m_SelState.IsExist())
2940 			{
2941 				if (m_SelState.BeginPos.WordCmp(m_SelState.EndPos)>0)
2942 					SetCaret(m_SelState.BeginPos);
2943 				else
2944 					SetCaret(m_SelState.EndPos);
2945 
2946 				SelectNone();
2947 				ScrollToCaret();
2948 				SetCaretInfo();
2949 			}
2950 			else
2951 			{
2952 				if (bCtrl)
2953 					SetCaret(m_pVT->GetEndWordPlace());
2954 				else
2955 					SetCaret(m_pVT->GetLineEndPlace(m_wpCaret));
2956 
2957 				ScrollToCaret();
2958 				SetCaretOrigin();
2959 				SetCaretInfo();
2960 			}
2961 		}
2962 	}
2963 }
2964 
SetText(FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo,FX_BOOL bPaint)2965 void CFX_Edit::SetText(FX_LPCWSTR text,FX_INT32 charset,
2966 						const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
2967 {
2968 	Empty();
2969 	DoInsertText(CPVT_WordPlace(0,0,-1), text, charset, pSecProps, pWordProps);
2970 	if (bPaint) Paint();
2971 	if (m_bOprNotify && m_pOprNotify)
2972 		m_pOprNotify->OnSetText(m_wpCaret, m_wpOldCaret);
2973 	//if (bAddUndo)
2974 }
2975 
InsertWord(FX_WORD word,FX_INT32 charset,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo,FX_BOOL bPaint)2976 FX_BOOL CFX_Edit::InsertWord(FX_WORD word, FX_INT32 charset, const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
2977 {
2978 	if (IsTextOverflow()) return FALSE;
2979 
2980 	if (m_pVT->IsValid())
2981 	{
2982 		m_pVT->UpdateWordPlace(m_wpCaret);
2983 
2984 		SetCaret(m_pVT->InsertWord(m_wpCaret,word,GetCharSetFromUnicode(word, charset),pWordProps));
2985 		m_SelState.Set(m_wpCaret,m_wpCaret);
2986 
2987 		if (m_wpCaret != m_wpOldCaret)
2988 		{
2989 			if (bAddUndo && m_bEnableUndo)
2990 			{
2991 				AddEditUndoItem(new CFXEU_InsertWord(this,m_wpOldCaret,m_wpCaret,word,charset,pWordProps));
2992 			}
2993 
2994 			if (bPaint)
2995 				PaintInsertText(m_wpOldCaret, m_wpCaret);
2996 
2997 			if (m_bOprNotify && m_pOprNotify)
2998 				m_pOprNotify->OnInsertWord(m_wpCaret, m_wpOldCaret);
2999 
3000 			return TRUE;
3001 		}
3002 	}
3003 
3004 	return FALSE;
3005 }
3006 
InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo,FX_BOOL bPaint)3007 FX_BOOL CFX_Edit::InsertReturn(const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,
3008 							   FX_BOOL bAddUndo, FX_BOOL bPaint)
3009 {
3010 	if (IsTextOverflow()) return FALSE;
3011 
3012 	if (m_pVT->IsValid())
3013 	{
3014 		m_pVT->UpdateWordPlace(m_wpCaret);
3015 		SetCaret(m_pVT->InsertSection(m_wpCaret,pSecProps,pWordProps));
3016 		m_SelState.Set(m_wpCaret,m_wpCaret);
3017 
3018 		if (m_wpCaret != m_wpOldCaret)
3019 		{
3020 			if (bAddUndo && m_bEnableUndo)
3021 			{
3022 				AddEditUndoItem(new CFXEU_InsertReturn(this,m_wpOldCaret,m_wpCaret,pSecProps,pWordProps));
3023 			}
3024 
3025 			if (bPaint)
3026 			{
3027 				RearrangePart(CPVT_WordRange(m_wpOldCaret, m_wpCaret));
3028 				ScrollToCaret();
3029 				CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
3030 				Refresh(RP_ANALYSE, &wr);
3031 				SetCaretOrigin();
3032 				SetCaretInfo();
3033 			}
3034 
3035 			if (m_bOprNotify && m_pOprNotify)
3036 				m_pOprNotify->OnInsertReturn(m_wpCaret, m_wpOldCaret);
3037 
3038 			return TRUE;
3039 		}
3040 	}
3041 
3042 	return FALSE;
3043 }
3044 
Backspace(FX_BOOL bAddUndo,FX_BOOL bPaint)3045 FX_BOOL CFX_Edit::Backspace(FX_BOOL bAddUndo, FX_BOOL bPaint)
3046 {
3047 	if (m_pVT->IsValid())
3048 	{
3049 		if (m_wpCaret == m_pVT->GetBeginWordPlace()) return FALSE;
3050 
3051 		CPVT_Section section;
3052 		CPVT_Word word;
3053 
3054 		if (bAddUndo)
3055 		{
3056 			if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
3057 			{
3058 				pIterator->SetAt(m_wpCaret);
3059 				pIterator->GetSection(section);
3060 				pIterator->GetWord(word);
3061 			}
3062 		}
3063 
3064 		m_pVT->UpdateWordPlace(m_wpCaret);
3065 		SetCaret(m_pVT->BackSpaceWord(m_wpCaret));
3066 		m_SelState.Set(m_wpCaret,m_wpCaret);
3067 
3068 		if (m_wpCaret != m_wpOldCaret)
3069 		{
3070 			if (bAddUndo && m_bEnableUndo)
3071 			{
3072 				if (m_wpCaret.SecCmp(m_wpOldCaret) != 0)
3073 					AddEditUndoItem(new CFXEU_Backspace(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
3074 						section.SecProps,section.WordProps));
3075 				else
3076 					AddEditUndoItem(new CFXEU_Backspace(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
3077 						section.SecProps,word.WordProps));
3078 			}
3079 
3080 			if (bPaint)
3081 			{
3082 				RearrangePart(CPVT_WordRange(m_wpCaret,m_wpOldCaret));
3083 				ScrollToCaret();
3084 
3085 				CPVT_WordRange wr;
3086 				if (m_wpCaret.SecCmp(m_wpOldCaret) !=0)
3087 					wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),GetVisibleWordRange().EndPos);
3088 				else if (m_wpCaret.LineCmp(m_wpOldCaret) !=0)
3089 					wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
3090 				else
3091 					wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
3092 
3093 				Refresh(RP_ANALYSE, &wr);
3094 
3095 				SetCaretOrigin();
3096 				SetCaretInfo();
3097 			}
3098 
3099 			if (m_bOprNotify && m_pOprNotify)
3100 				m_pOprNotify->OnBackSpace(m_wpCaret, m_wpOldCaret);
3101 
3102 			return TRUE;
3103 		}
3104 	}
3105 
3106 	return FALSE;
3107 }
3108 
Delete(FX_BOOL bAddUndo,FX_BOOL bPaint)3109 FX_BOOL CFX_Edit::Delete(FX_BOOL bAddUndo, FX_BOOL bPaint)
3110 {
3111 	if (m_pVT->IsValid())
3112 	{
3113 		if (m_wpCaret == m_pVT->GetEndWordPlace()) return FALSE;
3114 
3115 		CPVT_Section section;
3116 		CPVT_Word word;
3117 
3118 		if (bAddUndo)
3119 		{
3120 			if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
3121 			{
3122 				pIterator->SetAt(m_pVT->GetNextWordPlace(m_wpCaret));
3123 				pIterator->GetSection(section);
3124 				pIterator->GetWord(word);
3125 			}
3126 		}
3127 
3128 		m_pVT->UpdateWordPlace(m_wpCaret);
3129 		FX_BOOL bSecEnd = (m_wpCaret == m_pVT->GetSectionEndPlace(m_wpCaret));
3130 
3131 		SetCaret(m_pVT->DeleteWord(m_wpCaret));
3132 		m_SelState.Set(m_wpCaret,m_wpCaret);
3133 
3134 		if (bAddUndo && m_bEnableUndo)
3135 		{
3136 			if (bSecEnd)
3137 				AddEditUndoItem(new CFXEU_Delete(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
3138 					section.SecProps,section.WordProps,bSecEnd));
3139 			else
3140 				AddEditUndoItem(new CFXEU_Delete(this,m_wpOldCaret,m_wpCaret,word.Word,word.nCharset,
3141 					section.SecProps,word.WordProps,bSecEnd));
3142 		}
3143 
3144 		if (bPaint)
3145 		{
3146 			RearrangePart(CPVT_WordRange(m_wpOldCaret,m_wpCaret));
3147 			ScrollToCaret();
3148 
3149 			CPVT_WordRange wr;
3150 			if (bSecEnd)
3151 				wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),GetVisibleWordRange().EndPos);
3152 			else if (m_wpCaret.LineCmp(m_wpOldCaret) !=0)
3153 				wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(m_wpCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
3154 			else
3155 				wr = CPVT_WordRange(m_pVT->GetPrevWordPlace(m_wpOldCaret),m_pVT->GetSectionEndPlace(m_wpCaret));
3156 
3157 			Refresh(RP_ANALYSE, &wr);
3158 
3159 			SetCaretOrigin();
3160 			SetCaretInfo();
3161 		}
3162 
3163 		if (m_bOprNotify && m_pOprNotify)
3164 			m_pOprNotify->OnDelete(m_wpCaret, m_wpOldCaret);
3165 
3166 		return TRUE;
3167 	}
3168 
3169 	return FALSE;
3170 }
3171 
Empty()3172 FX_BOOL	CFX_Edit::Empty()
3173 {
3174 	if (m_pVT->IsValid())
3175 	{
3176 		m_pVT->DeleteWords(GetWholeWordRange());
3177 		SetCaret(m_pVT->GetBeginWordPlace());
3178 
3179 		return TRUE;
3180 	}
3181 
3182 	return FALSE;
3183 }
3184 
Clear(FX_BOOL bAddUndo,FX_BOOL bPaint)3185 FX_BOOL CFX_Edit::Clear(FX_BOOL bAddUndo, FX_BOOL bPaint)
3186 {
3187 	if (m_pVT->IsValid())
3188 	{
3189 		if (m_SelState.IsExist())
3190 		{
3191 			CPVT_WordRange range = m_SelState.ConvertToWordRange();
3192 
3193 			if (bAddUndo && m_bEnableUndo)
3194 			{
3195 				if (m_pVT->IsRichText())
3196 				{
3197 					BeginGroupUndo(L"");
3198 
3199 					if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
3200 					{
3201 						pIterator->SetAt(range.EndPos);
3202 
3203 						CPVT_Word wordinfo;
3204 						CPVT_Section secinfo;
3205 						do
3206 						{
3207 							CPVT_WordPlace place = pIterator->GetAt();
3208 							if (place.WordCmp(range.BeginPos) <= 0)break;
3209 
3210 							CPVT_WordPlace oldplace = m_pVT->GetPrevWordPlace(place);
3211 
3212 							if (oldplace.SecCmp(place) != 0)
3213 							{
3214 								if (pIterator->GetSection(secinfo))
3215 								{
3216 									AddEditUndoItem(new CFXEU_ClearRich(this,oldplace,place,range,wordinfo.Word,
3217 										wordinfo.nCharset,secinfo.SecProps,secinfo.WordProps));
3218 								}
3219 							}
3220 							else
3221 							{
3222 								if (pIterator->GetWord(wordinfo))
3223 								{
3224 									oldplace = m_pVT->AjustLineHeader(oldplace,TRUE);
3225 									place = m_pVT->AjustLineHeader(place,TRUE);
3226 
3227 									AddEditUndoItem(new CFXEU_ClearRich(this,oldplace,place,range,wordinfo.Word,
3228 										wordinfo.nCharset,secinfo.SecProps,wordinfo.WordProps));
3229 								}
3230 							}
3231 						}while (pIterator->PrevWord());
3232 					}
3233 					EndGroupUndo();
3234 				}
3235 				else
3236 				{
3237 					AddEditUndoItem(new CFXEU_Clear(this,range,GetSelText()));
3238 				}
3239 			}
3240 
3241 			SelectNone();
3242 			SetCaret(m_pVT->DeleteWords(range));
3243 			m_SelState.Set(m_wpCaret,m_wpCaret);
3244 
3245 			if (bPaint)
3246 			{
3247 				RearrangePart(range);
3248 				ScrollToCaret();
3249 
3250 				CPVT_WordRange wr(m_wpOldCaret, GetVisibleWordRange().EndPos);
3251 				Refresh(RP_ANALYSE, &wr);
3252 
3253 				SetCaretOrigin();
3254 				SetCaretInfo();
3255 			}
3256 
3257 			if (m_bOprNotify && m_pOprNotify)
3258 				m_pOprNotify->OnClear(m_wpCaret, m_wpOldCaret);
3259 
3260 			return TRUE;
3261 		}
3262 	}
3263 
3264 	return FALSE;
3265 }
3266 
InsertText(FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps,FX_BOOL bAddUndo,FX_BOOL bPaint)3267 FX_BOOL CFX_Edit::InsertText(FX_LPCWSTR text, FX_INT32 charset,
3268 					const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps, FX_BOOL bAddUndo, FX_BOOL bPaint)
3269 {
3270 	if (IsTextOverflow()) return FALSE;
3271 
3272 	m_pVT->UpdateWordPlace(m_wpCaret);
3273 	SetCaret(DoInsertText(m_wpCaret, text, charset, pSecProps, pWordProps));
3274 	m_SelState.Set(m_wpCaret,m_wpCaret);
3275 
3276 	if (m_wpCaret != m_wpOldCaret)
3277 	{
3278 		if (bAddUndo && m_bEnableUndo)
3279 		{
3280 			AddEditUndoItem(new CFXEU_InsertText(this,m_wpOldCaret,m_wpCaret,text,charset,pSecProps,pWordProps));
3281 		}
3282 
3283 		if (bPaint)
3284 			PaintInsertText(m_wpOldCaret, m_wpCaret);
3285 
3286 		if (m_bOprNotify && m_pOprNotify)
3287 			m_pOprNotify->OnInsertText(m_wpCaret, m_wpOldCaret);
3288 
3289 		return TRUE;
3290 	}
3291 	return FALSE;
3292 }
3293 
PaintInsertText(const CPVT_WordPlace & wpOld,const CPVT_WordPlace & wpNew)3294 void CFX_Edit::PaintInsertText(const CPVT_WordPlace & wpOld, const CPVT_WordPlace & wpNew)
3295 {
3296 	if (m_pVT->IsValid())
3297 	{
3298 		RearrangePart(CPVT_WordRange(wpOld,wpNew));
3299 		ScrollToCaret();
3300 
3301 		CPVT_WordRange wr;
3302 		if (m_wpCaret.LineCmp(wpOld) !=0)
3303 			wr = CPVT_WordRange(m_pVT->GetLineBeginPlace(wpOld),m_pVT->GetSectionEndPlace(wpNew));
3304 		else
3305 			wr = CPVT_WordRange(wpOld,m_pVT->GetSectionEndPlace(wpNew));
3306 		Refresh(RP_ANALYSE, &wr);
3307 		SetCaretOrigin();
3308 		SetCaretInfo();
3309 	}
3310 }
3311 
Redo()3312 FX_BOOL CFX_Edit::Redo()
3313 {
3314 	if (m_bEnableUndo)
3315 	{
3316 		if (m_Undo.CanRedo())
3317 		{
3318 			m_Undo.Redo();
3319 			return TRUE;
3320 		}
3321 	}
3322 
3323 	return FALSE;
3324 }
3325 
Undo()3326 FX_BOOL CFX_Edit::Undo()
3327 {
3328 	if (m_bEnableUndo)
3329 	{
3330 		if (m_Undo.CanUndo())
3331 		{
3332 			m_Undo.Undo();
3333 			return TRUE;
3334 		}
3335 	}
3336 
3337 	return FALSE;
3338 }
3339 
SetCaretOrigin()3340 void CFX_Edit::SetCaretOrigin()
3341 {
3342 	if (m_pVT->IsValid())
3343 	{
3344 		if (IPDF_VariableText_Iterator * pIterator = m_pVT->GetIterator())
3345 		{
3346 			pIterator->SetAt(m_wpCaret);
3347 			CPVT_Word word;
3348 			CPVT_Line line;
3349 			if (pIterator->GetWord(word))
3350 			{
3351 				m_ptCaret.x = word.ptWord.x + word.fWidth;
3352 				m_ptCaret.y = word.ptWord.y;
3353 			}
3354 			else if (pIterator->GetLine(line))
3355 			{
3356 				m_ptCaret.x = line.ptLine.x;
3357 				m_ptCaret.y = line.ptLine.y;
3358 			}
3359 		}
3360 	}
3361 }
3362 
WordPlaceToWordIndex(const CPVT_WordPlace & place) const3363 FX_INT32 CFX_Edit::WordPlaceToWordIndex(const CPVT_WordPlace & place) const
3364 {
3365 	if (m_pVT->IsValid())
3366 		return m_pVT->WordPlaceToWordIndex(place);
3367 
3368 	return -1;
3369 }
3370 
WordIndexToWordPlace(FX_INT32 index) const3371 CPVT_WordPlace CFX_Edit::WordIndexToWordPlace(FX_INT32 index) const
3372 {
3373 	if (m_pVT->IsValid())
3374 		return m_pVT->WordIndexToWordPlace(index);
3375 
3376 	return CPVT_WordPlace();
3377 }
3378 
IsTextFull() const3379 FX_BOOL	CFX_Edit::IsTextFull() const
3380 {
3381 	FX_INT32 nTotalWords = m_pVT->GetTotalWords();
3382 	FX_INT32 nLimitChar = m_pVT->GetLimitChar();
3383 	FX_INT32 nCharArray = m_pVT->GetCharArray();
3384 
3385 	return IsTextOverflow() || (nLimitChar>0 && nTotalWords >= nLimitChar)
3386 		|| (nCharArray>0 && nTotalWords >= nCharArray);
3387 }
3388 
IsTextOverflow() const3389 FX_BOOL	CFX_Edit::IsTextOverflow() const
3390 {
3391 	if (!m_bEnableScroll && !m_bEnableOverflow)
3392 	{
3393 		CPDF_Rect rcPlate = m_pVT->GetPlateRect();
3394 		CPDF_Rect rcContent = m_pVT->GetContentRect();
3395 
3396 		if (m_pVT->IsMultiLine() && GetTotalLines() > 1)
3397 		{
3398 			if (FX_EDIT_IsFloatBigger(rcContent.Height(),rcPlate.Height())) return TRUE;
3399 		}
3400 
3401 		if (FX_EDIT_IsFloatBigger(rcContent.Width(),rcPlate.Width())) return TRUE;
3402 	}
3403 
3404 	return FALSE;
3405 }
3406 
GetLineBeginPlace(const CPVT_WordPlace & place) const3407 CPVT_WordPlace CFX_Edit::GetLineBeginPlace(const CPVT_WordPlace & place) const
3408 {
3409 	return m_pVT->GetLineBeginPlace(place);
3410 }
3411 
GetLineEndPlace(const CPVT_WordPlace & place) const3412 CPVT_WordPlace CFX_Edit::GetLineEndPlace(const CPVT_WordPlace & place) const
3413 {
3414 	return m_pVT->GetLineEndPlace(place);
3415 }
3416 
GetSectionBeginPlace(const CPVT_WordPlace & place) const3417 CPVT_WordPlace CFX_Edit::GetSectionBeginPlace(const CPVT_WordPlace & place) const
3418 {
3419 	return m_pVT->GetSectionBeginPlace(place);
3420 }
3421 
GetSectionEndPlace(const CPVT_WordPlace & place) const3422 CPVT_WordPlace CFX_Edit::GetSectionEndPlace(const CPVT_WordPlace & place) const
3423 {
3424 	return m_pVT->GetSectionEndPlace(place);
3425 }
3426 
CanUndo() const3427 FX_BOOL	CFX_Edit::CanUndo() const
3428 {
3429 	if (m_bEnableUndo)
3430 	{
3431 		return m_Undo.CanUndo();
3432 	}
3433 
3434 	return FALSE;
3435 }
3436 
CanRedo() const3437 FX_BOOL	CFX_Edit::CanRedo() const
3438 {
3439 	if (m_bEnableUndo)
3440 	{
3441 		return m_Undo.CanRedo();
3442 	}
3443 
3444 	return FALSE;
3445 }
3446 
IsModified() const3447 FX_BOOL	CFX_Edit::IsModified() const
3448 {
3449 	if (m_bEnableUndo)
3450 	{
3451 		return m_Undo.IsModified();
3452 	}
3453 
3454 	return FALSE;
3455 }
3456 
EnableRefresh(FX_BOOL bRefresh)3457 void CFX_Edit::EnableRefresh(FX_BOOL bRefresh)
3458 {
3459 	m_bEnableRefresh = bRefresh;
3460 }
3461 
EnableUndo(FX_BOOL bUndo)3462 void CFX_Edit::EnableUndo(FX_BOOL bUndo)
3463 {
3464 	this->m_bEnableUndo = bUndo;
3465 }
3466 
EnableNotify(FX_BOOL bNotify)3467 void CFX_Edit::EnableNotify(FX_BOOL bNotify)
3468 {
3469 	this->m_bNotify = bNotify;
3470 }
3471 
EnableOprNotify(FX_BOOL bNotify)3472 void CFX_Edit::EnableOprNotify(FX_BOOL bNotify)
3473 {
3474 	this->m_bOprNotify = bNotify;
3475 }
3476 
GetLineTop(const CPVT_WordPlace & place) const3477 FX_FLOAT CFX_Edit::GetLineTop(const CPVT_WordPlace& place) const
3478 {
3479 	if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator())
3480 	{
3481 		CPVT_WordPlace wpOld = pIterator->GetAt();
3482 
3483 		pIterator->SetAt(place);
3484 		CPVT_Line line;
3485 		pIterator->GetLine(line);
3486 
3487 		pIterator->SetAt(wpOld);
3488 
3489 		return line.ptLine.y + line.fLineAscent;
3490 	}
3491 
3492 	return 0.0f;
3493 }
3494 
GetLineBottom(const CPVT_WordPlace & place) const3495 FX_FLOAT CFX_Edit::GetLineBottom(const CPVT_WordPlace& place) const
3496 {
3497 	if (IPDF_VariableText_Iterator* pIterator = m_pVT->GetIterator())
3498 	{
3499 		CPVT_WordPlace wpOld = pIterator->GetAt();
3500 
3501 		pIterator->SetAt(place);
3502 		CPVT_Line line;
3503 		pIterator->GetLine(line);
3504 
3505 		pIterator->SetAt(wpOld);
3506 
3507 		return line.ptLine.y + line.fLineDescent;
3508 	}
3509 
3510 	return 0.0f;
3511 }
3512 
DoInsertText(const CPVT_WordPlace & place,FX_LPCWSTR text,FX_INT32 charset,const CPVT_SecProps * pSecProps,const CPVT_WordProps * pWordProps)3513 CPVT_WordPlace CFX_Edit::DoInsertText(const CPVT_WordPlace& place, FX_LPCWSTR text, FX_INT32 charset,
3514 									  const CPVT_SecProps * pSecProps, const CPVT_WordProps * pWordProps)
3515 {
3516 	CPVT_WordPlace wp = place;
3517 
3518 	if (m_pVT->IsValid())
3519 	{
3520 		CFX_WideString sText = text;
3521 
3522 		for (FX_INT32 i = 0, sz = sText.GetLength(); i < sz; i++)
3523 		{
3524 			FX_WORD word = sText[i];
3525 			switch (word)
3526 			{
3527 			case 0x0D:
3528 				wp = m_pVT->InsertSection(wp,pSecProps,pWordProps);
3529 				if (sText[i+1] == 0x0A)
3530 					i++;
3531 				break;
3532 			case 0x0A:
3533 				wp = m_pVT->InsertSection(wp,pSecProps,pWordProps);
3534 				if (sText[i+1] == 0x0D)
3535 					i++;
3536 				break;
3537 			case 0x09:
3538 				word = 0x20;
3539 			default:
3540 				wp = m_pVT->InsertWord(wp,word,GetCharSetFromUnicode(word, charset),pWordProps);
3541 				break;
3542 			}
3543 		}
3544 	}
3545 
3546 	return wp;
3547 }
3548 
GetCharSetFromUnicode(FX_WORD word,FX_INT32 nOldCharset)3549 FX_INT32 CFX_Edit::GetCharSetFromUnicode(FX_WORD word, FX_INT32 nOldCharset)
3550 {
3551 	if (IFX_Edit_FontMap* pFontMap = this->GetFontMap())
3552 		return pFontMap->CharSetFromUnicode(word, nOldCharset);
3553 	else
3554 		return nOldCharset;
3555 }
3556 
BeginGroupUndo(const CFX_WideString & sTitle)3557 void CFX_Edit::BeginGroupUndo(const CFX_WideString& sTitle)
3558 {
3559 	ASSERT(m_pGroupUndoItem == NULL);
3560 
3561 	m_pGroupUndoItem = new CFX_Edit_GroupUndoItem(sTitle);
3562 }
3563 
EndGroupUndo()3564 void CFX_Edit::EndGroupUndo()
3565 {
3566 	ASSERT(m_pGroupUndoItem != NULL);
3567 
3568 	m_pGroupUndoItem->UpdateItems();
3569 	m_Undo.AddItem(m_pGroupUndoItem);
3570 	if (m_bOprNotify && m_pOprNotify)
3571 		m_pOprNotify->OnAddUndo(m_pGroupUndoItem);
3572 	m_pGroupUndoItem = NULL;
3573 }
3574 
AddEditUndoItem(CFX_Edit_UndoItem * pEditUndoItem)3575 void CFX_Edit::AddEditUndoItem(CFX_Edit_UndoItem* pEditUndoItem)
3576 {
3577 	if (m_pGroupUndoItem)
3578 		m_pGroupUndoItem->AddUndoItem(pEditUndoItem);
3579 	else
3580 	{
3581 		m_Undo.AddItem(pEditUndoItem);
3582 		if (m_bOprNotify && m_pOprNotify)
3583 			m_pOprNotify->OnAddUndo(pEditUndoItem);
3584 	}
3585 }
3586 
AddUndoItem(IFX_Edit_UndoItem * pUndoItem)3587 void CFX_Edit::AddUndoItem(IFX_Edit_UndoItem* pUndoItem)
3588 {
3589 	m_Undo.AddItem(pUndoItem);
3590 	if (m_bOprNotify && m_pOprNotify)
3591 		m_pOprNotify->OnAddUndo(pUndoItem);
3592 }
3593 
3594