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/pdfwindow/PDFWindow.h"
8#include "../../include/pdfwindow/PWL_Wnd.h"
9#include "../../include/pdfwindow/PWL_EditCtrl.h"
10#include "../../include/pdfwindow/PWL_Edit.h"
11#include "../../include/pdfwindow/PWL_ScrollBar.h"
12#include "../../include/pdfwindow/PWL_Utils.h"
13#include "../../include/pdfwindow/PWL_Caret.h"
14#include "../../include/pdfwindow/PWL_FontMap.h"
15
16/* ---------------------------- CPWL_Edit ------------------------------ */
17
18CPWL_Edit::CPWL_Edit() : m_pFillerNotify(NULL),
19	m_pSpellCheck(NULL),
20	m_bFocus(FALSE)
21{
22	m_pFormFiller = NULL;
23}
24
25CPWL_Edit::~CPWL_Edit()
26{
27	ASSERT(m_bFocus == FALSE);
28}
29
30CFX_ByteString CPWL_Edit::GetClassName() const
31{
32	return PWL_CLASSNAME_EDIT;
33}
34
35void CPWL_Edit::OnDestroy()
36{
37}
38
39void CPWL_Edit::SetText(FX_LPCWSTR csText)
40{
41	CFX_WideString swText = csText;
42
43	if (HasFlag(PES_RICH))
44	{
45		CFX_ByteString sValue = CFX_ByteString::FromUnicode(swText);
46
47		if (CXML_Element * pXML = CXML_Element::Parse((FX_LPCSTR)sValue,sValue.GetLength()))
48		{
49			FX_INT32 nCount = pXML->CountChildren();
50			FX_BOOL bFirst = TRUE;
51
52			swText.Empty();
53
54			for (FX_INT32 i=0; i<nCount; i++)
55			{
56				if (CXML_Element * pSubElement = pXML->GetElement(i))
57				{
58					CFX_ByteString tag=pSubElement->GetTagName();
59		   			if (tag.EqualNoCase("p"))
60					{
61						int nChild = pSubElement->CountChildren();
62						CFX_WideString swSection;
63						for(FX_INT32 j=0; j<nChild; j++)
64						{
65							swSection += pSubElement->GetContent(j);
66						}
67
68						if (bFirst)bFirst = FALSE;
69						else
70							swText += FWL_VKEY_Return;
71						swText += swSection;
72					}
73				}
74			}
75
76			delete pXML;
77		}
78	}
79
80	m_pEdit->SetText(swText);
81}
82
83void CPWL_Edit::RePosChildWnd()
84{
85	if (CPWL_ScrollBar * pVSB = this->GetVScrollBar())
86	{
87		//if (pVSB->IsVisible())
88		{
89			CPDF_Rect rcWindow = m_rcOldWindow;
90			CPDF_Rect rcVScroll = CPDF_Rect(rcWindow.right,
91								rcWindow.bottom,
92								rcWindow.right + PWL_SCROLLBAR_WIDTH,
93								rcWindow.top);
94			pVSB->Move(rcVScroll, TRUE, FALSE);
95		}
96	}
97
98	if (m_pEditCaret && !HasFlag(PES_TEXTOVERFLOW))
99		m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(GetClientRect(),1.0f)); //+1 for caret beside border
100
101	CPWL_EditCtrl::RePosChildWnd();
102}
103
104CPDF_Rect CPWL_Edit::GetClientRect() const
105{
106	CPDF_Rect rcClient = CPWL_Utils::DeflateRect(GetWindowRect(),(FX_FLOAT)(GetBorderWidth()+GetInnerBorderWidth()));
107
108	if (CPWL_ScrollBar * pVSB = this->GetVScrollBar())
109	{
110		if (pVSB->IsVisible())
111		{
112			rcClient.right -= PWL_SCROLLBAR_WIDTH;
113		}
114	}
115
116	return rcClient;
117}
118
119void CPWL_Edit::SetAlignFormatH(PWL_EDIT_ALIGNFORMAT_H nFormat, FX_BOOL bPaint/* = TRUE*/)
120{
121	m_pEdit->SetAlignmentH((FX_INT32)nFormat, bPaint);
122}
123
124void CPWL_Edit::SetAlignFormatV(PWL_EDIT_ALIGNFORMAT_V nFormat, FX_BOOL bPaint/* = TRUE*/)
125{
126	m_pEdit->SetAlignmentV((FX_INT32)nFormat, bPaint);
127}
128
129FX_BOOL	CPWL_Edit::CanSelectAll() const
130{
131	return  GetSelectWordRange() != m_pEdit->GetWholeWordRange();
132}
133
134FX_BOOL	CPWL_Edit::CanClear() const
135{
136	return !IsReadOnly() && m_pEdit->IsSelected();
137}
138
139FX_BOOL	CPWL_Edit::CanCopy() const
140{
141	return 	!HasFlag(PES_PASSWORD) && !HasFlag(PES_NOREAD) && m_pEdit->IsSelected();
142}
143
144FX_BOOL	CPWL_Edit::CanCut() const
145{
146	return 	CanCopy() && !IsReadOnly();
147}
148
149FX_BOOL	CPWL_Edit::CanPaste() const
150{
151	if (IsReadOnly()) return FALSE;
152
153	CFX_WideString swClipboard;
154	if (IFX_SystemHandler* pSH = GetSystemHandler())
155		swClipboard = pSH->GetClipboardText(GetAttachedHWnd());
156
157	return !swClipboard.IsEmpty();
158}
159
160void CPWL_Edit::CopyText()
161{
162	if (!CanCopy()) return;
163
164	CFX_WideString str = m_pEdit->GetSelText();
165
166	if (IFX_SystemHandler* pSH = GetSystemHandler())
167		pSH->SetClipboardText(GetAttachedHWnd(), str);
168}
169
170void CPWL_Edit::PasteText()
171{
172	if (!CanPaste()) return;
173
174	CFX_WideString swClipboard;
175	if (IFX_SystemHandler* pSH = GetSystemHandler())
176		swClipboard = pSH->GetClipboardText(GetAttachedHWnd());
177
178	if (m_pFillerNotify)
179	{
180		FX_BOOL bRC = TRUE;
181		FX_BOOL bExit = FALSE;
182		CFX_WideString strChangeEx;
183		int nSelStart = 0;
184		int nSelEnd = 0;
185		GetSel(nSelStart, nSelEnd);
186		m_pFillerNotify->OnBeforeKeyStroke(TRUE, GetAttachedData(), 0 , swClipboard, strChangeEx, nSelStart, nSelEnd, TRUE, bRC, bExit, 0);
187		if (!bRC) return;
188		if (bExit) return;
189	}
190
191	if (swClipboard.GetLength() > 0)
192	{
193		Clear();
194		InsertText(swClipboard);
195	}
196
197	if (m_pFillerNotify)
198	{
199		FX_BOOL bExit = FALSE;
200		m_pFillerNotify->OnAfterKeyStroke(TRUE, GetAttachedData(), bExit,0);
201		if (bExit) return;
202	}
203}
204
205void CPWL_Edit::CutText()
206{
207	if (!CanCut()) return;
208
209	CFX_WideString str = m_pEdit->GetSelText();
210
211	if (IFX_SystemHandler* pSH = GetSystemHandler())
212		pSH->SetClipboardText(GetAttachedHWnd(), str);
213
214	m_pEdit->Clear();
215}
216
217void CPWL_Edit::OnCreated()
218{
219	CPWL_EditCtrl::OnCreated();
220
221	if (CPWL_ScrollBar * pScroll = GetVScrollBar())
222	{
223		pScroll->RemoveFlag(PWS_AUTOTRANSPARENT);
224		pScroll->SetTransparency(255);
225	}
226
227	SetParamByFlag();
228
229	m_rcOldWindow = GetWindowRect();
230
231	m_pEdit->SetOprNotify(this);
232	m_pEdit->EnableOprNotify(TRUE);
233}
234
235void CPWL_Edit::SetParamByFlag()
236{
237	if (HasFlag(PES_RIGHT))
238	{
239		m_pEdit->SetAlignmentH(2, FALSE);
240	}
241	else if (HasFlag(PES_MIDDLE))
242	{
243		m_pEdit->SetAlignmentH(1, FALSE);
244	}
245	else
246	{
247		m_pEdit->SetAlignmentH(0, FALSE);
248	}
249
250	if (HasFlag(PES_BOTTOM))
251	{
252		m_pEdit->SetAlignmentV(2, FALSE);
253	}
254	else if (HasFlag(PES_CENTER))
255	{
256		m_pEdit->SetAlignmentV(1, FALSE);
257	}
258	else
259	{
260		m_pEdit->SetAlignmentV(0, FALSE);
261	}
262
263	if (HasFlag(PES_PASSWORD))
264	{
265		m_pEdit->SetPasswordChar('*', FALSE);
266	}
267
268	m_pEdit->SetMultiLine(HasFlag(PES_MULTILINE), FALSE);
269	m_pEdit->SetAutoReturn(HasFlag(PES_AUTORETURN), FALSE);
270	m_pEdit->SetAutoFontSize(HasFlag(PWS_AUTOFONTSIZE), FALSE);
271	m_pEdit->SetAutoScroll(HasFlag(PES_AUTOSCROLL), FALSE);
272	m_pEdit->EnableUndo(HasFlag(PES_UNDO));
273
274	if (HasFlag(PES_TEXTOVERFLOW))
275	{
276		SetClipRect(CPDF_Rect(0.0f,0.0f,0.0f,0.0f));
277		m_pEdit->SetTextOverflow(TRUE, FALSE);
278	}
279	else
280	{
281		if (m_pEditCaret)
282		{
283			m_pEditCaret->SetClipRect(CPWL_Utils::InflateRect(GetClientRect(),1.0f)); //+1 for caret beside border
284		}
285	}
286
287	if (HasFlag(PES_SPELLCHECK))
288	{
289		m_pSpellCheck = GetCreationParam().pSpellCheck;
290	}
291}
292
293void CPWL_Edit::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)
294{
295	CPWL_Wnd::GetThisAppearanceStream(sAppStream);
296
297	CPDF_Rect rcClient = GetClientRect();
298	CFX_ByteTextBuf sLine;
299
300	FX_INT32 nCharArray = m_pEdit->GetCharArray();
301
302	if (nCharArray > 0)
303	{
304		switch (GetBorderStyle())
305		{
306		case PBS_SOLID:
307			{
308				sLine << "q\n" << GetBorderWidth() << " w\n"
309					<< CPWL_Utils::GetColorAppStream(GetBorderColor(),FALSE) << " 2 J 0 j\n";
310
311				for (FX_INT32 i=1;i<nCharArray;i++)
312				{
313					sLine << rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*i << " "
314						<< rcClient.bottom << " m\n"
315						<< rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*i << " "
316						<< rcClient.top << " l S\n";
317				}
318
319				sLine << "Q\n";
320			}
321			break;
322		case PBS_DASH:
323			{
324				sLine << "q\n" << GetBorderWidth() << " w\n"
325					<< CPWL_Utils::GetColorAppStream(GetBorderColor(),FALSE) << " 2 J 0 j\n"
326					<< "[" << GetBorderDash().nDash << " "
327					<< GetBorderDash().nGap << "] "
328					<< GetBorderDash().nPhase << " d\n";
329
330				for (FX_INT32 i=1;i<nCharArray;i++)
331				{
332					sLine << rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*i << " "
333						<< rcClient.bottom << " m\n"
334						<< rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*i << " "
335						<< rcClient.top << " l S\n";
336				}
337
338				sLine << "Q\n";
339			}
340			break;
341		}
342	}
343
344	sAppStream << sLine;
345
346	CFX_ByteTextBuf sText;
347
348	CPDF_Point ptOffset = CPDF_Point(0.0f,0.0f);
349
350	CPVT_WordRange wrWhole = m_pEdit->GetWholeWordRange();
351	CPVT_WordRange wrSelect = GetSelectWordRange();
352	CPVT_WordRange wrVisible = (HasFlag(PES_TEXTOVERFLOW) ? wrWhole : m_pEdit->GetVisibleWordRange());
353	CPVT_WordRange wrSelBefore(wrWhole.BeginPos,wrSelect.BeginPos);
354	CPVT_WordRange wrSelAfter(wrSelect.EndPos,wrWhole.EndPos);
355
356	CPVT_WordRange wrTemp = CPWL_Utils::OverlapWordRange(GetSelectWordRange(),wrVisible);
357	CFX_ByteString sEditSel = CPWL_Utils::GetEditSelAppStream(m_pEdit, ptOffset,
358			&wrTemp);
359
360	if (sEditSel.GetLength() > 0)
361		sText << CPWL_Utils::GetColorAppStream(PWL_DEFAULT_SELBACKCOLOR) << sEditSel ;
362
363	wrTemp = CPWL_Utils::OverlapWordRange(wrVisible,wrSelBefore);
364	CFX_ByteString sEditBefore = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset,
365			&wrTemp, !HasFlag(PES_CHARARRAY), m_pEdit->GetPasswordChar());
366
367	if (sEditBefore.GetLength() > 0)
368		sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEditBefore << "ET\n";
369
370	wrTemp = CPWL_Utils::OverlapWordRange(wrVisible,wrSelect);
371	CFX_ByteString sEditMid = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset,
372			&wrTemp, !HasFlag(PES_CHARARRAY), m_pEdit->GetPasswordChar());
373
374	if (sEditMid.GetLength() > 0)
375		sText << "BT\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY,1)) << sEditMid << "ET\n";
376
377	wrTemp = CPWL_Utils::OverlapWordRange(wrVisible,wrSelAfter);
378	CFX_ByteString sEditAfter = CPWL_Utils::GetEditAppStream(m_pEdit, ptOffset,
379			&wrTemp, !HasFlag(PES_CHARARRAY), m_pEdit->GetPasswordChar());
380
381	if (sEditAfter.GetLength() > 0)
382		sText << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEditAfter<< "ET\n";
383
384	if (HasFlag(PES_SPELLCHECK))
385	{
386		CFX_ByteString sSpellCheck = CPWL_Utils::GetSpellCheckAppStream(m_pEdit, m_pSpellCheck, ptOffset, &wrVisible);
387		if (sSpellCheck.GetLength() > 0)
388			sText << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_RGB,1,0,0),FALSE) << sSpellCheck;
389	}
390
391	if (sText.GetLength() > 0)
392	{
393		CPDF_Rect rcClient = this->GetClientRect();
394		sAppStream << "q\n/Tx BMC\n";
395
396		if (!HasFlag(PES_TEXTOVERFLOW))
397			sAppStream << rcClient.left << " " << rcClient.bottom << " "
398				<< rcClient.right - rcClient.left << " " << rcClient.top - rcClient.bottom << " re W n\n";
399
400		sAppStream << sText;
401
402		sAppStream << "EMC\nQ\n";
403	}
404}
405
406void CPWL_Edit::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
407{
408	CPWL_Wnd::DrawThisAppearance(pDevice,pUser2Device);
409
410	CPDF_Rect rcClient = GetClientRect();
411	CFX_ByteTextBuf sLine;
412
413	FX_INT32 nCharArray = m_pEdit->GetCharArray();
414
415	if (nCharArray > 0)
416	{
417		switch (GetBorderStyle())
418		{
419		case PBS_SOLID:
420			{
421				CFX_GraphStateData gsd;
422				gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();
423
424				CFX_PathData path;
425				path.SetPointCount((nCharArray-1)*2);
426
427				for (FX_INT32 i=0; i<nCharArray-1; i++)
428				{
429					path.SetPoint(i*2, rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*(i+1),
430						rcClient.bottom, FXPT_MOVETO);
431					path.SetPoint(i*2+1, rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*(i+1),
432						rcClient.top, FXPT_LINETO);
433				}
434				if (path.GetPointCount() > 0)
435					pDevice->DrawPath(&path, pUser2Device, &gsd,0,
436						CPWL_Utils::PWLColorToFXColor(GetBorderColor(),255), FXFILL_ALTERNATE);
437			}
438			break;
439		case PBS_DASH:
440			{
441				CFX_GraphStateData gsd;
442				gsd.m_LineWidth = (FX_FLOAT)GetBorderWidth();
443
444				gsd.SetDashCount(2);
445				gsd.m_DashArray[0] = (FX_FLOAT)GetBorderDash().nDash;
446				gsd.m_DashArray[1] = (FX_FLOAT)GetBorderDash().nGap;
447				gsd.m_DashPhase = (FX_FLOAT)GetBorderDash().nPhase;
448
449				CFX_PathData path;
450				path.SetPointCount((nCharArray-1)*2);
451
452				for (FX_INT32 i=0; i<nCharArray-1; i++)
453				{
454					path.SetPoint(i*2, rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*(i+1),
455						rcClient.bottom, FXPT_MOVETO);
456					path.SetPoint(i*2+1, rcClient.left + ((rcClient.right - rcClient.left)/nCharArray)*(i+1),
457						rcClient.top, FXPT_LINETO);
458				}
459				if (path.GetPointCount() > 0)
460					pDevice->DrawPath(&path, pUser2Device, &gsd,0,
461						CPWL_Utils::PWLColorToFXColor(GetBorderColor(),255), FXFILL_ALTERNATE);
462			}
463			break;
464		}
465	}
466
467	CPDF_Rect rcClip;
468	CPVT_WordRange wrRange = m_pEdit->GetVisibleWordRange();
469	CPVT_WordRange* pRange = NULL;
470
471	if (!HasFlag(PES_TEXTOVERFLOW))
472	{
473		rcClip = GetClientRect();
474		pRange = &wrRange;
475	}
476IFX_SystemHandler* pSysHandler = GetSystemHandler();
477	IFX_Edit::DrawEdit(pDevice,pUser2Device,m_pEdit,
478		CPWL_Utils::PWLColorToFXColor(GetTextColor(),this->GetTransparency()),
479		CPWL_Utils::PWLColorToFXColor(GetTextStrokeColor(),this->GetTransparency()),
480		rcClip,CPDF_Point(0.0f,0.0f),pRange, pSysHandler, m_pFormFiller);
481
482	if (HasFlag(PES_SPELLCHECK))
483	{
484		CPWL_Utils::DrawEditSpellCheck(pDevice,pUser2Device,m_pEdit,rcClip,
485			CPDF_Point(0.0f,0.0f),pRange, this->GetCreationParam().pSpellCheck);
486	}
487}
488
489FX_BOOL CPWL_Edit::OnLButtonDown(const CPDF_Point & point, FX_DWORD nFlag)
490{
491	CPWL_Wnd::OnLButtonDown(point,nFlag);
492
493	if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point))
494	{
495		if (m_bMouseDown)
496			this->InvalidateRect();
497
498		m_bMouseDown = TRUE;
499		SetCapture();
500
501		m_pEdit->OnMouseDown(point,IsSHIFTpressed(nFlag),IsCTRLpressed(nFlag));
502	}
503
504	return TRUE;
505}
506
507FX_BOOL	CPWL_Edit::OnLButtonDblClk(const CPDF_Point & point, FX_DWORD nFlag)
508{
509	CPWL_Wnd::OnLButtonDblClk(point, nFlag);
510
511	if (HasFlag(PES_TEXTOVERFLOW) || ClientHitTest(point))
512	{
513		m_pEdit->SelectAll();
514	}
515
516	return TRUE;
517}
518
519#define WM_PWLEDIT_UNDO					0x01
520#define WM_PWLEDIT_REDO					0x02
521#define WM_PWLEDIT_CUT					0x03
522#define WM_PWLEDIT_COPY					0x04
523#define WM_PWLEDIT_PASTE				0x05
524#define WM_PWLEDIT_DELETE				0x06
525#define WM_PWLEDIT_SELECTALL			0x07
526#define WM_PWLEDIT_SUGGEST				0x08
527
528FX_BOOL CPWL_Edit::OnRButtonUp(const CPDF_Point & point, FX_DWORD nFlag)
529{
530	if (m_bMouseDown) return FALSE;
531
532	CPWL_Wnd::OnRButtonUp(point, nFlag);
533
534	if (!HasFlag(PES_TEXTOVERFLOW) && !ClientHitTest(point)) return TRUE;
535
536	IFX_SystemHandler* pSH = GetSystemHandler();
537	if (!pSH) return FALSE;
538
539	this->SetFocus();
540
541	CPVT_WordRange wrLatin = GetLatinWordsRange(point);
542	CFX_WideString swLatin = m_pEdit->GetRangeText(wrLatin);
543
544	FX_HMENU hPopup = pSH->CreatePopupMenu();
545	if (!hPopup) return FALSE;
546
547	CFX_ByteStringArray sSuggestWords;
548	CPDF_Point ptPopup = point;
549
550	if (!IsReadOnly())
551	{
552		if (HasFlag(PES_SPELLCHECK) && !swLatin.IsEmpty())
553		{
554			if (m_pSpellCheck)
555			{
556				CFX_ByteString sLatin = CFX_ByteString::FromUnicode(swLatin);
557
558				if (!m_pSpellCheck->CheckWord(sLatin))
559				{
560					m_pSpellCheck->SuggestWords(sLatin,sSuggestWords);
561
562					FX_INT32 nSuggest = sSuggestWords.GetSize();
563
564					for (FX_INT32 nWord=0; nWord<nSuggest; nWord++)
565					{
566						pSH->AppendMenuItem(hPopup, WM_PWLEDIT_SUGGEST+nWord, sSuggestWords[nWord].UTF8Decode());
567					}
568
569					if (nSuggest > 0)
570						pSH->AppendMenuItem(hPopup, 0, L"");
571
572					ptPopup = GetWordRightBottomPoint(wrLatin.EndPos);
573				}
574			}
575		}
576	}
577
578	IPWL_Provider* pProvider = this->GetProvider();
579
580	if (HasFlag(PES_UNDO))
581	{
582		pSH->AppendMenuItem(hPopup, WM_PWLEDIT_UNDO,
583			pProvider ? pProvider->LoadPopupMenuString(0) : L"&Undo");
584		pSH->AppendMenuItem(hPopup, WM_PWLEDIT_REDO,
585			pProvider ? pProvider->LoadPopupMenuString(1) : L"&Redo");
586		pSH->AppendMenuItem(hPopup, 0, L"");
587
588		if (!m_pEdit->CanUndo())
589			pSH->EnableMenuItem(hPopup, WM_PWLEDIT_UNDO, FALSE);
590		if (!m_pEdit->CanRedo())
591			pSH->EnableMenuItem(hPopup, WM_PWLEDIT_REDO, FALSE);
592	}
593
594	pSH->AppendMenuItem(hPopup, WM_PWLEDIT_CUT,
595		pProvider ? pProvider->LoadPopupMenuString(2) : L"Cu&t");
596	pSH->AppendMenuItem(hPopup, WM_PWLEDIT_COPY,
597		pProvider ? pProvider->LoadPopupMenuString(3) : L"&Copy");
598	pSH->AppendMenuItem(hPopup, WM_PWLEDIT_PASTE,
599		pProvider ? pProvider->LoadPopupMenuString(4) : L"&Paste");
600	pSH->AppendMenuItem(hPopup, WM_PWLEDIT_DELETE,
601		pProvider ? pProvider->LoadPopupMenuString(5) : L"&Delete");
602
603	CFX_WideString swText = pSH->GetClipboardText(this->GetAttachedHWnd());
604	if (swText.IsEmpty())
605		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);
606
607	if (!m_pEdit->IsSelected())
608	{
609		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
610		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
611		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
612	}
613
614	if (IsReadOnly())
615	{
616		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
617		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_DELETE, FALSE);
618		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_PASTE, FALSE);
619	}
620
621	if (HasFlag(PES_PASSWORD))
622	{
623		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
624		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
625	}
626
627	if (HasFlag(PES_NOREAD))
628	{
629		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_CUT, FALSE);
630		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_COPY, FALSE);
631	}
632
633	pSH->AppendMenuItem(hPopup, 0, L"");
634	pSH->AppendMenuItem(hPopup, WM_PWLEDIT_SELECTALL,
635		pProvider ? pProvider->LoadPopupMenuString(6) : L"&Select All");
636
637	if (m_pEdit->GetTotalWords() == 0)
638	{
639		pSH->EnableMenuItem(hPopup, WM_PWLEDIT_SELECTALL, FALSE);
640	}
641
642	FX_INT32 x, y;
643	PWLtoWnd(ptPopup, x, y);
644	pSH->ClientToScreen(GetAttachedHWnd(), x, y);
645	pSH->SetCursor(FXCT_ARROW);
646	FX_INT32 nCmd = pSH->TrackPopupMenu(hPopup,
647					 x,
648					 y,
649					 GetAttachedHWnd());
650
651
652	switch (nCmd)
653	{
654	case WM_PWLEDIT_UNDO:
655		Undo();
656		break;
657	case WM_PWLEDIT_REDO:
658		Redo();
659		break;
660	case WM_PWLEDIT_CUT:
661		this->CutText();
662		break;
663	case WM_PWLEDIT_COPY:
664		this->CopyText();
665		break;
666	case WM_PWLEDIT_PASTE:
667		this->PasteText();
668		break;
669	case WM_PWLEDIT_DELETE:
670		this->Clear();
671		break;
672	case WM_PWLEDIT_SELECTALL:
673		this->SelectAll();
674		break;
675	case WM_PWLEDIT_SUGGEST + 0:
676		SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
677		ReplaceSel(sSuggestWords[0].UTF8Decode());
678		break;
679	case WM_PWLEDIT_SUGGEST + 1:
680		SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
681		ReplaceSel(sSuggestWords[1].UTF8Decode());
682		break;
683	case WM_PWLEDIT_SUGGEST + 2:
684		SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
685		ReplaceSel(sSuggestWords[2].UTF8Decode());
686		break;
687	case WM_PWLEDIT_SUGGEST + 3:
688		SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
689		ReplaceSel(sSuggestWords[3].UTF8Decode());
690		break;
691	case WM_PWLEDIT_SUGGEST + 4:
692		SetSel(m_pEdit->WordPlaceToWordIndex(wrLatin.BeginPos),m_pEdit->WordPlaceToWordIndex(wrLatin.EndPos));
693		ReplaceSel(sSuggestWords[4].UTF8Decode());
694		break;
695	default:
696		break;
697	}
698
699	pSH->DestroyMenu(hPopup);
700
701	return TRUE;
702}
703
704void CPWL_Edit::OnSetFocus()
705{
706	SetEditCaret(TRUE);
707
708	if (!IsReadOnly())
709	{
710		if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
711			pFocusHandler->OnSetFocus(this);
712	}
713
714	m_bFocus = TRUE;
715}
716
717void CPWL_Edit::OnKillFocus()
718{
719	ShowVScrollBar(FALSE);
720
721	m_pEdit->SelectNone();
722	SetCaret(FALSE, CPDF_Point(0.0f,0.0f), CPDF_Point(0.0f,0.0f));
723
724	SetCharSet(0);
725
726	if (!IsReadOnly())
727	{
728		if (IPWL_FocusHandler* pFocusHandler = GetFocusHandler())
729			pFocusHandler->OnKillFocus(this);
730	}
731
732	m_bFocus = FALSE;
733}
734
735void CPWL_Edit::SetHorzScale(FX_INT32 nHorzScale, FX_BOOL bPaint/* = TRUE*/)
736{
737	m_pEdit->SetHorzScale(nHorzScale, bPaint);
738}
739
740void CPWL_Edit::SetCharSpace(FX_FLOAT fCharSpace, FX_BOOL bPaint/* = TRUE*/)
741{
742	m_pEdit->SetCharSpace(fCharSpace, bPaint);
743}
744
745void CPWL_Edit::SetLineLeading(FX_FLOAT fLineLeading, FX_BOOL bPaint/* = TRUE*/)
746{
747	m_pEdit->SetLineLeading(fLineLeading, bPaint);
748}
749
750CFX_ByteString CPWL_Edit::GetSelectAppearanceStream(const CPDF_Point & ptOffset) const
751{
752	CPVT_WordRange wr = GetSelectWordRange();
753	return CPWL_Utils::GetEditSelAppStream(m_pEdit,ptOffset,&wr);
754}
755
756CPVT_WordRange CPWL_Edit::GetSelectWordRange() const
757{
758	if (m_pEdit->IsSelected())
759	{
760		FX_INT32 nStart = -1;
761		FX_INT32 nEnd = -1;
762
763		m_pEdit->GetSel(nStart, nEnd);
764
765		CPVT_WordPlace wpStart = m_pEdit->WordIndexToWordPlace(nStart);
766		CPVT_WordPlace wpEnd = m_pEdit->WordIndexToWordPlace(nEnd);
767
768		return CPVT_WordRange(wpStart,wpEnd);
769	}
770
771	return CPVT_WordRange();
772}
773
774CFX_ByteString CPWL_Edit::GetTextAppearanceStream(const CPDF_Point & ptOffset) const
775{
776	CFX_ByteTextBuf sRet;
777	CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(m_pEdit,ptOffset);
778
779	if (sEdit.GetLength() > 0)
780	{
781		sRet << "BT\n" << CPWL_Utils::GetColorAppStream(GetTextColor()) << sEdit << "ET\n";
782	}
783
784	return sRet.GetByteString();
785}
786
787CFX_ByteString CPWL_Edit::GetCaretAppearanceStream(const CPDF_Point & ptOffset) const
788{
789	if (m_pEditCaret)
790		return m_pEditCaret->GetCaretAppearanceStream(ptOffset);
791
792	return CFX_ByteString();
793}
794
795CPDF_Point CPWL_Edit::GetWordRightBottomPoint(const CPVT_WordPlace& wpWord)
796{
797	CPDF_Point pt(0.0f, 0.0f);
798
799	if (IFX_Edit_Iterator * pIterator = m_pEdit->GetIterator())
800	{
801		CPVT_WordPlace wpOld = pIterator->GetAt();
802		pIterator->SetAt(wpWord);
803		CPVT_Word word;
804		if (pIterator->GetWord(word))
805		{
806			pt = CPDF_Point(word.ptWord.x + word.fWidth, word.ptWord.y + word.fDescent);
807		}
808
809		pIterator->SetAt(wpOld);
810	}
811
812	return pt;
813}
814
815FX_BOOL	CPWL_Edit::IsTextFull() const
816{
817	return m_pEdit->IsTextFull();
818}
819
820FX_FLOAT CPWL_Edit::GetCharArrayAutoFontSize(CPDF_Font* pFont, const CPDF_Rect& rcPlate, FX_INT32 nCharArray)
821{
822	if (pFont && !pFont->IsStandardFont())
823	{
824		FX_RECT rcBBox;
825		pFont->GetFontBBox(rcBBox);
826
827		CPDF_Rect rcCell = rcPlate;
828		FX_FLOAT xdiv = rcCell.Width() / nCharArray * 1000.0f / rcBBox.Width();
829		FX_FLOAT ydiv = - rcCell.Height() * 1000.0f / rcBBox.Height();
830
831		return xdiv < ydiv ? xdiv : ydiv;
832	}
833
834	return 0.0f;
835}
836
837void CPWL_Edit::SetCharArray(FX_INT32 nCharArray)
838{
839	if (HasFlag(PES_CHARARRAY) && nCharArray > 0)
840	{
841		m_pEdit->SetCharArray(nCharArray);
842		m_pEdit->SetTextOverflow(TRUE);
843
844		if (HasFlag(PWS_AUTOFONTSIZE))
845		{
846			if (IFX_Edit_FontMap* pFontMap = this->GetFontMap())
847			{
848				FX_FLOAT fFontSize = GetCharArrayAutoFontSize(pFontMap->GetPDFFont(0), GetClientRect(), nCharArray);
849				if (fFontSize > 0.0f)
850				{
851					m_pEdit->SetAutoFontSize(FALSE);
852					m_pEdit->SetFontSize(fFontSize);
853				}
854			}
855		}
856	}
857}
858
859void CPWL_Edit::SetLimitChar(FX_INT32 nLimitChar)
860{
861	m_pEdit->SetLimitChar(nLimitChar);
862}
863
864void CPWL_Edit::ReplaceSel(FX_LPCWSTR csText)
865{
866	m_pEdit->Clear();
867	m_pEdit->InsertText(csText);
868}
869
870CPDF_Rect CPWL_Edit::GetFocusRect() const
871{
872	return CPDF_Rect();
873}
874
875void CPWL_Edit::ShowVScrollBar(FX_BOOL bShow)
876{
877	if (CPWL_ScrollBar * pScroll = GetVScrollBar())
878	{
879		if (bShow)
880		{
881			if (!pScroll->IsVisible())
882			{
883				pScroll->SetVisible(TRUE);
884				CPDF_Rect rcWindow = GetWindowRect();
885				m_rcOldWindow = rcWindow;
886				rcWindow.right += PWL_SCROLLBAR_WIDTH;
887				Move(rcWindow, TRUE, TRUE);
888			}
889		}
890		else
891		{
892			if (pScroll->IsVisible())
893			{
894				pScroll->SetVisible(FALSE);
895				Move(m_rcOldWindow, TRUE, TRUE);
896			}
897		}
898	}
899}
900
901FX_BOOL	CPWL_Edit::IsVScrollBarVisible() const
902{
903	if (CPWL_ScrollBar * pScroll = GetVScrollBar())
904	{
905		return pScroll->IsVisible();
906	}
907
908	return FALSE;
909}
910
911void CPWL_Edit::EnableSpellCheck(FX_BOOL bEnabled)
912{
913	if (bEnabled)
914		AddFlag(PES_SPELLCHECK);
915	else
916		RemoveFlag(PES_SPELLCHECK);
917}
918
919FX_BOOL CPWL_Edit::OnKeyDown(FX_WORD nChar, FX_DWORD nFlag)
920{
921	if (m_bMouseDown) return TRUE;
922
923	if (nChar == FWL_VKEY_Delete)
924	{
925		if (m_pFillerNotify)
926		{
927			FX_BOOL bRC = TRUE;
928			FX_BOOL bExit = FALSE;
929			CFX_WideString strChange;
930			CFX_WideString strChangeEx;
931
932			int nSelStart = 0;
933			int nSelEnd = 0;
934			GetSel(nSelStart, nSelEnd);
935
936			if (nSelStart == nSelEnd)
937				nSelEnd = nSelStart + 1;
938			m_pFillerNotify->OnBeforeKeyStroke(TRUE, GetAttachedData(), FWL_VKEY_Delete, strChange, strChangeEx, nSelStart, nSelEnd, TRUE, bRC, bExit, nFlag);
939			if (!bRC) return FALSE;
940			if (bExit) return FALSE;
941		}
942	}
943
944	FX_BOOL bRet = CPWL_EditCtrl::OnKeyDown(nChar,  nFlag);
945
946	if (nChar == FWL_VKEY_Delete)
947	{
948		if (m_pFillerNotify)
949		{
950			FX_BOOL bExit = FALSE;
951			m_pFillerNotify->OnAfterKeyStroke(TRUE, GetAttachedData(), bExit,nFlag);
952			if (bExit) return FALSE;
953		}
954	}
955
956	//In case of implementation swallow the OnKeyDown event.
957	if(IsProceedtoOnChar(nChar, nFlag))
958			return TRUE;
959
960	return bRet;
961}
962
963/**
964*In case of implementation swallow the OnKeyDown event.
965*If the event is swallowed, implementation may do other unexpected things, which is not the control means to do.
966*/
967FX_BOOL CPWL_Edit::IsProceedtoOnChar(FX_WORD nKeyCode, FX_DWORD nFlag)
968{
969
970	FX_BOOL bCtrl = IsCTRLpressed(nFlag);
971	FX_BOOL bAlt = IsALTpressed(nFlag);
972	if(bCtrl && !bAlt)
973	{
974	//hot keys for edit control.
975		switch(nKeyCode)
976		{
977		case 'C':
978		case 'V':
979		case 'X':
980		case 'A':
981		case 'Z':
982			return TRUE;
983		default:
984			break;
985		}
986	}
987	//control characters.
988	switch(nKeyCode)
989	{
990	case FWL_VKEY_Escape:
991	case FWL_VKEY_Back:
992	case FWL_VKEY_Return:
993	case FWL_VKEY_Space:
994		return TRUE;
995	default:
996		break;
997	}
998	return FALSE;
999
1000}
1001
1002FX_BOOL CPWL_Edit::OnChar(FX_WORD nChar, FX_DWORD nFlag)
1003{
1004	if (m_bMouseDown) return TRUE;
1005
1006	FX_BOOL bRC = TRUE;
1007	FX_BOOL bExit = FALSE;
1008
1009	FX_BOOL bCtrl = IsCTRLpressed(nFlag);
1010	if (!bCtrl)
1011	{
1012		if (m_pFillerNotify)
1013		{
1014			CFX_WideString swChange;
1015			FX_INT32 nKeyCode;
1016
1017			int nSelStart = 0;
1018			int nSelEnd = 0;
1019			GetSel(nSelStart, nSelEnd);
1020
1021			switch (nChar)
1022			{
1023			case FWL_VKEY_Back:
1024				nKeyCode = nChar;
1025				if (nSelStart == nSelEnd)
1026					nSelStart = nSelEnd - 1;
1027				break;
1028			case FWL_VKEY_Return:
1029				nKeyCode = nChar;
1030				break;
1031			default:
1032				nKeyCode = 0;
1033				swChange += nChar;
1034				break;
1035			}
1036
1037			CFX_WideString strChangeEx;
1038			m_pFillerNotify->OnBeforeKeyStroke(TRUE, GetAttachedData(), nKeyCode, swChange, strChangeEx, nSelStart, nSelEnd, TRUE, bRC, bExit, nFlag);
1039		}
1040	}
1041
1042	if (!bRC) return TRUE;
1043	if (bExit) return FALSE;
1044
1045	if (IFX_Edit_FontMap * pFontMap = GetFontMap())
1046	{
1047		FX_INT32 nOldCharSet = GetCharSet();
1048		FX_INT32 nNewCharSet = pFontMap->CharSetFromUnicode(nChar, DEFAULT_CHARSET);
1049		if(nOldCharSet != nNewCharSet)
1050		{
1051			SetCharSet(nNewCharSet);
1052		}
1053	}
1054	FX_BOOL bRet = CPWL_EditCtrl::OnChar(nChar,nFlag);
1055
1056	if (!bCtrl)
1057	{
1058		if (m_pFillerNotify)
1059		{
1060			m_pFillerNotify->OnAfterKeyStroke(TRUE, GetAttachedData(), bExit,nFlag);
1061			if (bExit) return FALSE;
1062		}
1063	}
1064
1065	return bRet;
1066}
1067
1068FX_BOOL	CPWL_Edit::OnMouseWheel(short zDelta, const CPDF_Point & point, FX_DWORD nFlag)
1069{
1070	if (HasFlag(PES_MULTILINE))
1071	{
1072		CPDF_Point ptScroll = GetScrollPos();
1073
1074		if (zDelta > 0)
1075		{
1076			ptScroll.y += this->GetFontSize();
1077		}
1078		else
1079		{
1080			ptScroll.y -= this->GetFontSize();
1081		}
1082		this->SetScrollPos(ptScroll);
1083
1084		return TRUE;
1085	}
1086
1087	return FALSE;
1088}
1089
1090void CPWL_Edit::OnInsertReturn(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace)
1091{
1092	if (HasFlag(PES_SPELLCHECK))
1093	{
1094		m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place)));
1095	}
1096
1097	if (m_pEditNotify)
1098	{
1099		m_pEditNotify->OnInsertReturn(place, oldplace);
1100	}
1101}
1102
1103void CPWL_Edit::OnBackSpace(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace)
1104{
1105	if (HasFlag(PES_SPELLCHECK))
1106	{
1107		m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place)));
1108	}
1109
1110	if (m_pEditNotify)
1111	{
1112		m_pEditNotify->OnBackSpace(place, oldplace);
1113	}
1114}
1115
1116void CPWL_Edit::OnDelete(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace)
1117{
1118	if (HasFlag(PES_SPELLCHECK))
1119	{
1120		m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place)));
1121	}
1122
1123	if (m_pEditNotify)
1124	{
1125		m_pEditNotify->OnDelete(place, oldplace);
1126	}
1127}
1128
1129void CPWL_Edit::OnClear(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace)
1130{
1131	if (HasFlag(PES_SPELLCHECK))
1132	{
1133		m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place)));
1134	}
1135
1136	if (m_pEditNotify)
1137	{
1138		m_pEditNotify->OnClear(place, oldplace);
1139	}
1140}
1141
1142void CPWL_Edit::OnInsertWord(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace)
1143{
1144	if (HasFlag(PES_SPELLCHECK))
1145	{
1146		m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place)));
1147	}
1148
1149	if (m_pEditNotify)
1150	{
1151		m_pEditNotify->OnInsertWord(place, oldplace);
1152	}
1153}
1154
1155void CPWL_Edit::OnSetText(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace)
1156{
1157}
1158
1159void CPWL_Edit::OnInsertText(const CPVT_WordPlace& place, const CPVT_WordPlace& oldplace)
1160{
1161	if (HasFlag(PES_SPELLCHECK))
1162	{
1163		m_pEdit->RefreshWordRange(CombineWordRange(GetLatinWordsRange(oldplace),GetLatinWordsRange(place)));
1164	}
1165
1166	if (m_pEditNotify)
1167	{
1168		m_pEditNotify->OnInsertText(place, oldplace);
1169	}
1170}
1171
1172void CPWL_Edit::OnAddUndo(IFX_Edit_UndoItem* pUndoItem)
1173{
1174	if (m_pEditNotify)
1175	{
1176		m_pEditNotify->OnAddUndo(this);
1177	}
1178}
1179
1180CPVT_WordRange CPWL_Edit::CombineWordRange(const CPVT_WordRange& wr1, const CPVT_WordRange& wr2)
1181{
1182	CPVT_WordRange wrRet;
1183
1184	if (wr1.BeginPos.WordCmp(wr2.BeginPos) < 0)
1185	{
1186		wrRet.BeginPos = wr1.BeginPos;
1187	}
1188	else
1189	{
1190		wrRet.BeginPos = wr2.BeginPos;
1191	}
1192
1193	if (wr1.EndPos.WordCmp(wr2.EndPos) < 0)
1194	{
1195		wrRet.EndPos = wr2.EndPos;
1196	}
1197	else
1198	{
1199		wrRet.EndPos = wr1.EndPos;
1200	}
1201
1202	return wrRet;
1203}
1204
1205CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CPDF_Point& point) const
1206{
1207	return GetSameWordsRange(m_pEdit->SearchWordPlace(point), TRUE, FALSE);
1208}
1209
1210CPVT_WordRange CPWL_Edit::GetLatinWordsRange(const CPVT_WordPlace & place) const
1211{
1212	return GetSameWordsRange(place, TRUE, FALSE);
1213}
1214
1215CPVT_WordRange CPWL_Edit::GetArabicWordsRange(const CPVT_WordPlace & place) const
1216{
1217	return GetSameWordsRange(place, FALSE, TRUE);
1218}
1219
1220#define PWL_ISARABICWORD(word) ((word >= 0x0600 && word <= 0x06FF) || (word >= 0xFB50 && word <= 0xFEFC))
1221
1222CPVT_WordRange CPWL_Edit::GetSameWordsRange(const CPVT_WordPlace & place, FX_BOOL bLatin, FX_BOOL bArabic) const
1223{
1224	CPVT_WordRange range;
1225
1226	if (IFX_Edit_Iterator* pIterator = m_pEdit->GetIterator())
1227	{
1228		CPVT_Word wordinfo;
1229		CPVT_WordPlace wpStart(place),wpEnd(place);
1230		pIterator->SetAt(place);
1231
1232		if (bLatin)
1233		{
1234			while (pIterator->NextWord())
1235			{
1236				if (pIterator->GetWord(wordinfo) && FX_EDIT_ISLATINWORD(wordinfo.Word))
1237				{
1238					wpEnd = pIterator->GetAt();
1239					continue;
1240				}
1241				else
1242					break;
1243			};
1244		}
1245		else if (bArabic)
1246		{
1247			while (pIterator->NextWord())
1248			{
1249				if (pIterator->GetWord(wordinfo) && PWL_ISARABICWORD(wordinfo.Word))
1250				{
1251					wpEnd = pIterator->GetAt();
1252					continue;
1253				}
1254				else
1255					break;
1256			};
1257		}
1258
1259		pIterator->SetAt(place);
1260
1261		if (bLatin)
1262		{
1263			do
1264			{
1265				if (pIterator->GetWord(wordinfo) && FX_EDIT_ISLATINWORD(wordinfo.Word))
1266				{
1267					continue;
1268				}
1269				else
1270				{
1271					wpStart = pIterator->GetAt();
1272					break;
1273				}
1274			}
1275			while (pIterator->PrevWord());
1276		}
1277		else if (bArabic)
1278		{
1279			do
1280			{
1281				if (pIterator->GetWord(wordinfo) && PWL_ISARABICWORD(wordinfo.Word))
1282				{
1283					continue;
1284				}
1285				else
1286				{
1287					wpStart = pIterator->GetAt();
1288					break;
1289				}
1290			}
1291			while (pIterator->PrevWord());
1292		}
1293
1294		range.Set(wpStart,wpEnd);
1295	}
1296
1297	return range;
1298}
1299
1300void CPWL_Edit::AjustArabicWords(const CPVT_WordRange& wr)
1301{
1302}
1303
1304void CPWL_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects,
1305										const CPDF_Point& ptOffset, CFX_ArrayTemplate<CPDF_TextObject*>& ObjArray)
1306{
1307	IFX_Edit::GeneratePageObjects(pPageObjects, m_pEdit, ptOffset, NULL, CPWL_Utils::PWLColorToFXColor(GetTextColor(),GetTransparency()), ObjArray);
1308}
1309
1310void CPWL_Edit::GeneratePageObjects(CPDF_PageObjects* pPageObjects,
1311									const CPDF_Point& ptOffset)
1312{
1313	CFX_ArrayTemplate<CPDF_TextObject*> ObjArray;
1314	IFX_Edit::GeneratePageObjects(pPageObjects, m_pEdit, ptOffset, NULL, CPWL_Utils::PWLColorToFXColor(GetTextColor(),GetTransparency()), ObjArray);
1315}
1316
1317