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 "../../third_party/base/nonstd_unique_ptr.h"
8#include "../include/fsdk_define.h"
9#include "../include/fsdk_mgr.h"
10#include "../include/fsdk_baseannot.h"
11#include "../include/fsdk_baseform.h"
12#include "../include/formfiller/FFL_FormFiller.h"
13#include "../include/fsdk_actionhandler.h"
14
15#include "../include/javascript/IJavaScript.h"
16
17//------------------------------------------------------------------------------------
18//*										CPDFSDK_Widget
19//------------------------------------------------------------------------------------
20
21#define IsFloatZero(f)						((f) < 0.01 && (f) > -0.01)
22#define IsFloatBigger(fa,fb)				((fa) > (fb) && !IsFloatZero((fa) - (fb)))
23#define IsFloatSmaller(fa,fb)				((fa) < (fb) && !IsFloatZero((fa) - (fb)))
24#define IsFloatEqual(fa,fb)					IsFloatZero((fa)-(fb))
25
26CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm) :
27					CPDFSDK_Annot(pAnnot, pPageView),
28					m_pInterForm(pInterForm),
29					m_nAppAge(0),
30					m_nValueAge(0)
31{
32	ASSERT(m_pInterForm != NULL);
33}
34
35CPDFSDK_Widget::~CPDFSDK_Widget()
36{
37
38}
39
40FX_BOOL		CPDFSDK_Widget::IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode)
41{
42	ASSERT(m_pAnnot != NULL);
43	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
44
45	CPDF_Dictionary* pAP = m_pAnnot->m_pAnnotDict->GetDict("AP");
46	if (pAP == NULL) return FALSE;
47
48	// Choose the right sub-ap
49	const FX_CHAR* ap_entry = "N";
50	if (mode == CPDF_Annot::Down)
51		ap_entry = "D";
52	else if (mode == CPDF_Annot::Rollover)
53		ap_entry = "R";
54	if (!pAP->KeyExist(ap_entry))
55		ap_entry = "N";
56
57	// Get the AP stream or subdirectory
58	CPDF_Object* psub = pAP->GetElementValue(ap_entry);
59	if (psub == NULL) return FALSE;
60
61	int nFieldType = GetFieldType();
62	switch (nFieldType)
63	{
64	case FIELDTYPE_PUSHBUTTON:
65	case FIELDTYPE_COMBOBOX:
66	case FIELDTYPE_LISTBOX:
67	case FIELDTYPE_TEXTFIELD:
68	case FIELDTYPE_SIGNATURE:
69		return psub->GetType() == PDFOBJ_STREAM;
70	case FIELDTYPE_CHECKBOX:
71	case FIELDTYPE_RADIOBUTTON:
72		if (psub->GetType() == PDFOBJ_DICTIONARY)
73		{
74			CPDF_Dictionary* pSubDict = (CPDF_Dictionary*)psub;
75
76			return pSubDict->GetStream(this->GetAppState()) != NULL;
77		}
78		else
79			return FALSE;
80		break;
81	}
82
83	return TRUE;
84}
85
86int	CPDFSDK_Widget::GetFieldType() const
87{
88	CPDF_FormField* pField = GetFormField();
89	ASSERT(pField != NULL);
90
91	return pField->GetFieldType();
92}
93
94int CPDFSDK_Widget::GetFieldFlags() const
95{
96	CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
97	ASSERT(pPDFInterForm != NULL);
98
99	CPDF_FormControl* pFormControl = pPDFInterForm->GetControlByDict(m_pAnnot->m_pAnnotDict);
100	CPDF_FormField* pFormField = pFormControl->GetField();
101	return pFormField->GetFieldFlags();
102}
103
104CFX_ByteString CPDFSDK_Widget::GetSubType() const
105{
106	int nType = GetFieldType();
107
108	if (nType == FIELDTYPE_SIGNATURE)
109		return BFFT_SIGNATURE;
110	return CPDFSDK_Annot::GetSubType();
111}
112
113CPDF_FormField*	CPDFSDK_Widget::GetFormField() const
114{
115	ASSERT(m_pInterForm != NULL);
116
117	CPDF_FormControl* pCtrl = GetFormControl();
118	ASSERT(pCtrl != NULL);
119
120	return pCtrl->GetField();
121}
122
123CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const
124{
125	ASSERT(m_pInterForm != NULL);
126
127	CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
128	ASSERT(pPDFInterForm != NULL);
129
130	return pPDFInterForm->GetControlByDict(GetAnnotDict());
131}
132static CPDF_Dictionary* BF_GetField(CPDF_Dictionary* pFieldDict, const FX_CHAR* name)
133{
134	if (pFieldDict == NULL) return NULL;
135	// First check the dictionary itself
136	CPDF_Object* pAttr = pFieldDict->GetElementValue(name);
137	if (pAttr) return pFieldDict;
138
139	// Now we need to search from parents
140	CPDF_Dictionary* pParent = pFieldDict->GetDict("Parent");
141	if (pParent == NULL) return NULL;
142
143	return BF_GetField(pParent, name);
144}
145
146CPDF_FormControl* CPDFSDK_Widget::GetFormControl(CPDF_InterForm* pInterForm, CPDF_Dictionary* pAnnotDict)
147{
148	ASSERT(pInterForm != NULL);
149	ASSERT(pAnnotDict != NULL);
150
151	CPDF_FormControl* pControl = pInterForm->GetControlByDict(pAnnotDict);
152
153	return pControl;
154}
155
156int CPDFSDK_Widget::GetRotate() const
157{
158	CPDF_FormControl* pCtrl = this->GetFormControl();
159	ASSERT(pCtrl != NULL);
160
161	return pCtrl->GetRotation() % 360;
162}
163
164FX_BOOL	CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const
165{
166	CPDF_FormControl* pFormCtrl = GetFormControl();
167	ASSERT(pFormCtrl != NULL);
168
169	int iColorType = 0;
170	color = FX_ARGBTOCOLORREF(pFormCtrl->GetBackgroundColor(iColorType));
171
172	return iColorType != COLORTYPE_TRANSPARENT;
173}
174
175FX_BOOL	CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const
176{
177	CPDF_FormControl* pFormCtrl = GetFormControl();
178	ASSERT(pFormCtrl != NULL);
179
180	int iColorType = 0;
181	color = FX_ARGBTOCOLORREF(pFormCtrl->GetBorderColor(iColorType));
182
183	return iColorType != COLORTYPE_TRANSPARENT;
184}
185
186FX_BOOL	CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const
187{
188	CPDF_FormControl* pFormCtrl = GetFormControl();
189	ASSERT(pFormCtrl != NULL);
190
191	CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
192	if (da.HasColor())
193	{
194		FX_ARGB argb;
195		int iColorType = COLORTYPE_TRANSPARENT;
196		da.GetColor(argb, iColorType);
197		color = FX_ARGBTOCOLORREF(argb);
198
199		return iColorType != COLORTYPE_TRANSPARENT;
200	}
201
202	return FALSE;
203}
204
205FX_FLOAT CPDFSDK_Widget::GetFontSize() const
206{
207	CPDF_FormControl* pFormCtrl = GetFormControl();
208	ASSERT(pFormCtrl != NULL);
209
210	CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
211	CFX_ByteString csFont = "";
212	FX_FLOAT fFontSize = 0.0f;
213	pDa.GetFont(csFont, fFontSize);
214
215	return fFontSize;
216}
217
218int	CPDFSDK_Widget::GetSelectedIndex(int nIndex) const
219{
220	CPDF_FormField*	pFormField = GetFormField();
221	ASSERT(pFormField != NULL);
222
223	return pFormField->GetSelectedIndex(nIndex);
224}
225
226CFX_WideString CPDFSDK_Widget::GetValue() const
227{
228	CPDF_FormField*	pFormField = GetFormField();
229	ASSERT(pFormField != NULL);
230
231	return pFormField->GetValue();
232}
233
234CFX_WideString CPDFSDK_Widget::GetDefaultValue() const
235{
236	CPDF_FormField*	pFormField = GetFormField();
237	ASSERT(pFormField != NULL);
238
239	return pFormField->GetDefaultValue();
240}
241
242CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const
243{
244	CPDF_FormField*	pFormField = GetFormField();
245	ASSERT(pFormField != NULL);
246
247	return pFormField->GetOptionLabel(nIndex);
248}
249
250int	CPDFSDK_Widget::CountOptions() const
251{
252	CPDF_FormField*	pFormField = GetFormField();
253	ASSERT(pFormField != NULL);
254
255	return pFormField->CountOptions();
256}
257
258FX_BOOL	CPDFSDK_Widget::IsOptionSelected(int nIndex) const
259{
260	CPDF_FormField*	pFormField = GetFormField();
261	ASSERT(pFormField != NULL);
262
263	return pFormField->IsItemSelected(nIndex);
264}
265
266int	CPDFSDK_Widget::GetTopVisibleIndex() const
267{
268	CPDF_FormField*	pFormField = GetFormField();
269	ASSERT(pFormField != NULL);
270
271	return pFormField->GetTopVisibleIndex();
272}
273
274FX_BOOL	CPDFSDK_Widget::IsChecked() const
275{
276	CPDF_FormControl* pFormCtrl = GetFormControl();
277	ASSERT(pFormCtrl != NULL);
278
279	return pFormCtrl->IsChecked();
280}
281
282int	CPDFSDK_Widget::GetAlignment() const
283{
284	CPDF_FormControl* pFormCtrl = GetFormControl();
285	ASSERT(pFormCtrl != NULL);
286
287	return pFormCtrl->GetControlAlignment();
288}
289
290int	CPDFSDK_Widget::GetMaxLen() const
291{
292	CPDF_FormField*	pFormField = GetFormField();
293	ASSERT(pFormField != NULL);
294
295	return pFormField->GetMaxLen();
296}
297
298void CPDFSDK_Widget::SetCheck(FX_BOOL bChecked, FX_BOOL bNotify)
299{
300	CPDF_FormControl* pFormCtrl = GetFormControl();
301	ASSERT(pFormCtrl != NULL);
302
303	CPDF_FormField*	pFormField = pFormCtrl->GetField();
304	ASSERT(pFormField != NULL);
305
306	pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked, bNotify);
307}
308
309void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, FX_BOOL bNotify)
310{
311	CPDF_FormField*	pFormField = GetFormField();
312	ASSERT(pFormField != NULL);
313
314	pFormField->SetValue(sValue, bNotify);
315}
316
317void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue)
318{
319}
320void CPDFSDK_Widget::SetOptionSelection(int index, FX_BOOL bSelected, FX_BOOL bNotify)
321{
322	CPDF_FormField* pFormField = GetFormField();
323	ASSERT(pFormField != NULL);
324
325	pFormField->SetItemSelection(index, bSelected, bNotify);
326}
327
328void CPDFSDK_Widget::ClearSelection(FX_BOOL bNotify)
329{
330	CPDF_FormField* pFormField = GetFormField();
331	ASSERT(pFormField != NULL);
332
333	pFormField->ClearSelection(bNotify);
334}
335
336void CPDFSDK_Widget::SetTopVisibleIndex(int index)
337{
338}
339
340void CPDFSDK_Widget::SetAppModified()
341{
342	m_bAppModified = TRUE;
343}
344
345void CPDFSDK_Widget::ClearAppModified()
346{
347	m_bAppModified = FALSE;
348}
349
350FX_BOOL CPDFSDK_Widget::IsAppModified() const
351{
352	return m_bAppModified;
353}
354
355void CPDFSDK_Widget::ResetAppearance(FX_LPCWSTR sValue, FX_BOOL bValueChanged)
356{
357	SetAppModified();
358
359	m_nAppAge++;
360	if (m_nAppAge > 999999)
361		m_nAppAge = 0;
362	if (bValueChanged)
363		m_nValueAge++;
364
365	int nFieldType = GetFieldType();
366
367	switch (nFieldType)
368	{
369	case FIELDTYPE_PUSHBUTTON:
370		ResetAppearance_PushButton();
371		break;
372	case FIELDTYPE_CHECKBOX:
373		ResetAppearance_CheckBox();
374		break;
375	case FIELDTYPE_RADIOBUTTON:
376		ResetAppearance_RadioButton();
377		break;
378	case FIELDTYPE_COMBOBOX:
379		ResetAppearance_ComboBox(sValue);
380		break;
381	case FIELDTYPE_LISTBOX:
382		ResetAppearance_ListBox();
383		break;
384	case FIELDTYPE_TEXTFIELD:
385		ResetAppearance_TextField(sValue);
386		break;
387	}
388
389	ASSERT(m_pAnnot != NULL);
390	m_pAnnot->ClearCachedAP();
391}
392
393CFX_WideString CPDFSDK_Widget::OnFormat(int nCommitKey, FX_BOOL& bFormated)
394{
395 	CPDF_FormField* pFormField = GetFormField();
396 	ASSERT(pFormField != NULL);
397
398 	ASSERT(m_pInterForm != NULL);
399
400	return m_pInterForm->OnFormat(pFormField, nCommitKey, bFormated);
401
402}
403
404void CPDFSDK_Widget::ResetFieldAppearance(FX_BOOL bValueChanged)
405{
406	CPDF_FormField* pFormField = GetFormField();
407	ASSERT(pFormField != NULL);
408
409	ASSERT(m_pInterForm != NULL);
410
411	m_pInterForm->ResetFieldAppearance(pFormField, NULL, bValueChanged);
412}
413
414void	CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice, const CPDF_Matrix* pUser2Device,
415		CPDF_Annot::AppearanceMode mode, const CPDF_RenderOptions* pOptions)
416{
417	int nFieldType = GetFieldType();
418
419	if ((nFieldType == FIELDTYPE_CHECKBOX || nFieldType == FIELDTYPE_RADIOBUTTON) &&
420		mode == CPDF_Annot::Normal &&
421		!this->IsWidgetAppearanceValid(CPDF_Annot::Normal))
422	{
423		CFX_PathData pathData;
424
425		CPDF_Rect rcAnnot = this->GetRect();
426
427		pathData.AppendRect(rcAnnot.left, rcAnnot.bottom,
428			rcAnnot.right, rcAnnot.top);
429
430		CFX_GraphStateData gsd;
431		gsd.m_LineWidth = 0.0f;
432
433		pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA, FXFILL_ALTERNATE);
434	}
435	else
436	{
437		CPDFSDK_Annot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
438	}
439}
440
441void CPDFSDK_Widget::UpdateField()
442{
443	CPDF_FormField* pFormField = GetFormField();
444	ASSERT(pFormField != NULL);
445
446	ASSERT(m_pInterForm != NULL);
447	m_pInterForm->UpdateField(pFormField);
448}
449
450void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice, CPDFSDK_PageView* pPageView)
451{
452 	ASSERT(m_pInterForm != NULL);
453
454	int nFieldType = GetFieldType();
455 	if (m_pInterForm->IsNeedHighLight(nFieldType))
456 	{
457
458//  		if (nFieldType != FIELDTYPE_PUSHBUTTON)
459//  		{
460			CPDF_Rect rc  = GetRect();
461			FX_COLORREF color = m_pInterForm->GetHighlightColor(nFieldType);
462			FX_BYTE alpha = m_pInterForm->GetHighlightAlpha();
463
464			CFX_FloatRect rcDevice;
465			ASSERT(m_pInterForm->GetDocument());
466			CPDFDoc_Environment* pEnv = m_pInterForm->GetDocument()->GetEnv();
467			if(!pEnv)
468				return;
469			CFX_AffineMatrix page2device;
470			pPageView->GetCurrentMatrix(page2device);
471			page2device.Transform(((FX_FLOAT)rc.left), ((FX_FLOAT)rc.bottom), rcDevice.left, rcDevice.bottom);
472// 			pEnv->FFI_PageToDevice(m_pPageView->GetPDFPage(), rc.left, rc.bottom, &rcDevice.left, &rcDevice.bottom);
473// 			pEnv->FFI_PageToDevice(m_pPageView->GetPDFPage(), rc.right, rc.top, &rcDevice.right, &rcDevice.top);
474			page2device.Transform(((FX_FLOAT)rc.right), ((FX_FLOAT)rc.top), rcDevice.right, rcDevice.top);
475
476			rcDevice.Normalize();
477
478			FX_ARGB argb = ArgbEncode((int)alpha, color);
479			FX_RECT rcDev((int)rcDevice.left,(int)rcDevice.top,(int)rcDevice.right,(int)rcDevice.bottom);
480			pDevice->FillRect(&rcDev, argb);
481			/* 		}*/
482	}
483}
484
485void CPDFSDK_Widget::ResetAppearance_PushButton()
486{
487	CPDF_FormControl* pControl = GetFormControl();
488	ASSERT(pControl != NULL);
489
490
491
492	CPDF_Rect rcWindow = GetRotatedRect();
493
494	FX_INT32 nLayout = 0;
495
496	switch (pControl->GetTextPosition())
497	{
498	case TEXTPOS_ICON:
499		nLayout = PPBL_ICON;
500		break;
501	case TEXTPOS_BELOW:
502		nLayout = PPBL_ICONTOPLABELBOTTOM;
503		break;
504	case TEXTPOS_ABOVE:
505		nLayout = PPBL_LABELTOPICONBOTTOM;
506		break;
507	case TEXTPOS_RIGHT:
508		nLayout = PPBL_ICONLEFTLABELRIGHT;
509		break;
510	case TEXTPOS_LEFT:
511		nLayout = PPBL_LABELLEFTICONRIGHT;
512		break;
513	case TEXTPOS_OVERLAID:
514		nLayout = PPBL_LABELOVERICON;
515		break;
516	default:
517		nLayout = PPBL_LABEL;
518		break;
519	}
520
521	CPWL_Color crBackground, crBorder;
522
523	int iColorType;
524	FX_FLOAT fc[4];
525
526	pControl->GetOriginalBackgroundColor(iColorType, fc);
527	if (iColorType > 0)
528		crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
529
530	pControl->GetOriginalBorderColor(iColorType, fc);
531	if (iColorType > 0)
532		crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
533
534	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
535	FX_INT32 nBorderStyle = 0;
536	CPWL_Dash dsBorder(3,0,0);
537	CPWL_Color crLeftTop,crRightBottom;
538
539	switch (GetBorderStyle())
540	{
541	case BBS_DASH:
542		nBorderStyle = PBS_DASH;
543		dsBorder = CPWL_Dash(3, 3, 0);
544		break;
545	case BBS_BEVELED:
546		nBorderStyle = PBS_BEVELED;
547		fBorderWidth *= 2;
548		crLeftTop = CPWL_Color(COLORTYPE_GRAY,1);
549		crRightBottom = CPWL_Utils::DevideColor(crBackground,2);
550		break;
551	case BBS_INSET:
552		nBorderStyle = PBS_INSET;
553		fBorderWidth *= 2;
554		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5);
555		crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75);
556		break;
557	case BBS_UNDERLINE:
558		nBorderStyle = PBS_UNDERLINED;
559		break;
560	default:
561		nBorderStyle = PBS_SOLID;
562		break;
563	}
564
565	CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow,fBorderWidth);
566
567	CPWL_Color crText(COLORTYPE_GRAY,0);
568
569	FX_FLOAT fFontSize = 12.0f;
570	CFX_ByteString csNameTag;
571
572	CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
573	if (da.HasColor())
574	{
575		da.GetColor(iColorType, fc);
576		crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
577	}
578
579	if (da.HasFont())
580		da.GetFont(csNameTag, fFontSize);
581
582	CFX_WideString csWCaption;
583	CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;
584
585	if (pControl->HasMKEntry("CA"))
586	{
587		csNormalCaption = pControl->GetNormalCaption();
588	}
589	if (pControl->HasMKEntry("RC"))
590	{
591		csRolloverCaption = pControl->GetRolloverCaption();
592	}
593	if (pControl->HasMKEntry("AC"))
594	{
595		csDownCaption = pControl->GetDownCaption();
596	}
597
598	CPDF_Stream* pNormalIcon = NULL;
599	CPDF_Stream* pRolloverIcon = NULL;
600	CPDF_Stream* pDownIcon = NULL;
601
602	if (pControl->HasMKEntry("I"))
603	{
604		pNormalIcon = pControl->GetNormalIcon();
605	}
606	if (pControl->HasMKEntry("RI"))
607	{
608		pRolloverIcon = pControl->GetRolloverIcon();
609	}
610	if (pControl->HasMKEntry("IX"))
611	{
612		pDownIcon = pControl->GetDownIcon();
613	}
614
615	if (pNormalIcon)
616	{
617		if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict())
618		{
619			if (pImageDict->GetString("Name").IsEmpty())
620				pImageDict->SetAtString("Name", "ImgA");
621		}
622	}
623
624	if (pRolloverIcon)
625	{
626		if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict())
627		{
628			if (pImageDict->GetString("Name").IsEmpty())
629				pImageDict->SetAtString("Name", "ImgB");
630		}
631	}
632
633	if (pDownIcon)
634	{
635		if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict())
636		{
637			if (pImageDict->GetString("Name").IsEmpty())
638				pImageDict->SetAtString("Name", "ImgC");
639		}
640	}
641
642	CPDF_IconFit iconFit = pControl->GetIconFit();
643
644// 	ASSERT(this->m_pBaseForm != NULL);
645	ASSERT(this->m_pInterForm != NULL);
646	CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
647	ASSERT(pDoc != NULL);
648	CPDFDoc_Environment* pEnv = pDoc->GetEnv();
649
650 	CBA_FontMap FontMap(this,pEnv->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pBaseForm->GetEnv()));
651	FontMap.Initial();
652
653	FontMap.SetAPType("N");
654
655	CFX_ByteString csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
656		CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) +
657		CPWL_Utils::GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap, pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
658
659	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
660	if (pNormalIcon)
661		AddImageToAppearance("N", pNormalIcon);
662
663	CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
664	if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle)
665	{
666		if (csRolloverCaption.IsEmpty() && !pRolloverIcon)
667		{
668			csRolloverCaption = csNormalCaption;
669			pRolloverIcon = pNormalIcon;
670		}
671
672		FontMap.SetAPType("R");
673
674		csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
675				CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) +
676				CPWL_Utils::GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap, pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize, nLayout);
677
678		WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
679		if (pRolloverIcon)
680			AddImageToAppearance("R", pRolloverIcon);
681
682		if (csDownCaption.IsEmpty() && !pDownIcon)
683		{
684			csDownCaption = csNormalCaption;
685			pDownIcon = pNormalIcon;
686		}
687
688		switch (nBorderStyle)
689		{
690		case PBS_BEVELED:
691			{
692				CPWL_Color crTemp = crLeftTop;
693				crLeftTop = crRightBottom;
694				crRightBottom = crTemp;
695			}
696			break;
697		case PBS_INSET:
698			crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
699			crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
700			break;
701		}
702
703		FontMap.SetAPType("D");
704
705		csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, CPWL_Utils::SubstractColor(crBackground,0.25f)) +
706			CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop, crRightBottom, nBorderStyle, dsBorder) +
707			CPWL_Utils::GetPushButtonAppStream(iconFit.GetFittingBounds() ? rcWindow : rcClient, &FontMap, pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
708
709		WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
710		if (pDownIcon)
711			AddImageToAppearance("D", pDownIcon);
712	}
713	else
714	{
715		RemoveAppearance("D");
716		RemoveAppearance("R");
717	}
718}
719
720void CPDFSDK_Widget::ResetAppearance_CheckBox()
721{
722	CPDF_FormControl* pControl = GetFormControl();
723	ASSERT(pControl != NULL);
724
725
726
727	CPWL_Color crBackground, crBorder, crText;
728
729	int iColorType;
730	FX_FLOAT fc[4];
731
732	pControl->GetOriginalBackgroundColor(iColorType, fc);
733	if (iColorType > 0)
734		crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
735
736	pControl->GetOriginalBorderColor(iColorType, fc);
737	if (iColorType > 0)
738		crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
739
740	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
741	FX_INT32 nBorderStyle = 0;
742	CPWL_Dash dsBorder(3,0,0);
743	CPWL_Color crLeftTop,crRightBottom;
744
745	switch (GetBorderStyle())
746	{
747	case BBS_DASH:
748		nBorderStyle = PBS_DASH;
749		dsBorder = CPWL_Dash(3, 3, 0);
750		break;
751	case BBS_BEVELED:
752		nBorderStyle = PBS_BEVELED;
753		fBorderWidth *= 2;
754		crLeftTop = CPWL_Color(COLORTYPE_GRAY,1);
755		crRightBottom = CPWL_Utils::DevideColor(crBackground,2);
756		break;
757	case BBS_INSET:
758		nBorderStyle = PBS_INSET;
759		fBorderWidth *= 2;
760		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5);
761		crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75);
762		break;
763	case BBS_UNDERLINE:
764		nBorderStyle = PBS_UNDERLINED;
765		break;
766	default:
767		nBorderStyle = PBS_SOLID;
768		break;
769	}
770
771	CPDF_Rect rcWindow = GetRotatedRect();
772	CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow,fBorderWidth);
773
774	CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
775	if (da.HasColor())
776	{
777		da.GetColor(iColorType, fc);
778		crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
779	}
780
781	FX_INT32 nStyle = 0;
782
783	CFX_WideString csWCaption = pControl->GetNormalCaption();
784	if (csWCaption.GetLength() > 0)
785	{
786		switch (csWCaption[0])
787		{
788		case L'l':
789			nStyle = PCS_CIRCLE;
790			break;
791		case L'8':
792			nStyle = PCS_CROSS;
793			break;
794		case L'u':
795			nStyle = PCS_DIAMOND;
796			break;
797		case L'n':
798			nStyle = PCS_SQUARE;
799			break;
800		case L'H':
801			nStyle = PCS_STAR;
802			break;
803		default: //L'4'
804			nStyle = PCS_CHECK;
805			break;
806		}
807	}
808	else
809	{
810		nStyle = PCS_CHECK;
811	}
812
813	CFX_ByteString csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,crBackground) +
814		CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
815
816	CFX_ByteString csAP_N_OFF = csAP_N_ON;
817
818	switch (nBorderStyle)
819	{
820	case PBS_BEVELED:
821		{
822			CPWL_Color crTemp = crLeftTop;
823			crLeftTop = crRightBottom;
824			crRightBottom = crTemp;
825		}
826		break;
827	case PBS_INSET:
828		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
829		crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
830		break;
831	}
832
833	CFX_ByteString csAP_D_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,CPWL_Utils::SubstractColor(crBackground,0.25f)) +
834		CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
835
836	CFX_ByteString csAP_D_OFF = csAP_D_ON;
837
838	csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient,nStyle,crText);
839	csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient,nStyle,crText);
840
841	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON, pControl->GetCheckedAPState());
842	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
843
844	WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON, pControl->GetCheckedAPState());
845	WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
846
847	CFX_ByteString csAS = GetAppState();
848	if (csAS.IsEmpty())
849		SetAppState("Off");
850}
851
852void CPDFSDK_Widget::ResetAppearance_RadioButton()
853{
854	CPDF_FormControl* pControl = GetFormControl();
855	ASSERT(pControl != NULL);
856
857
858
859	CPWL_Color crBackground, crBorder, crText;
860
861	int iColorType;
862	FX_FLOAT fc[4];
863
864	pControl->GetOriginalBackgroundColor(iColorType, fc);
865	if (iColorType > 0)
866		crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
867
868	pControl->GetOriginalBorderColor(iColorType, fc);
869	if (iColorType > 0)
870		crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
871
872	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
873	FX_INT32 nBorderStyle = 0;
874	CPWL_Dash dsBorder(3,0,0);
875	CPWL_Color crLeftTop,crRightBottom;
876
877	switch (GetBorderStyle())
878	{
879	case BBS_DASH:
880		nBorderStyle = PBS_DASH;
881		dsBorder = CPWL_Dash(3, 3, 0);
882		break;
883	case BBS_BEVELED:
884		nBorderStyle = PBS_BEVELED;
885		fBorderWidth *= 2;
886		crLeftTop = CPWL_Color(COLORTYPE_GRAY,1);
887		crRightBottom = CPWL_Utils::DevideColor(crBackground,2);
888		break;
889	case BBS_INSET:
890		nBorderStyle = PBS_INSET;
891		fBorderWidth *= 2;
892		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5);
893		crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75);
894		break;
895	case BBS_UNDERLINE:
896		nBorderStyle = PBS_UNDERLINED;
897		break;
898	default:
899		nBorderStyle = PBS_SOLID;
900		break;
901	}
902
903	CPDF_Rect rcWindow = GetRotatedRect();
904	CPDF_Rect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
905
906	CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
907	if (da.HasColor())
908	{
909		da.GetColor(iColorType, fc);
910		crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
911	}
912
913	FX_INT32 nStyle = 0;
914
915	CFX_WideString csWCaption = pControl->GetNormalCaption();
916	if (csWCaption.GetLength() > 0)
917	{
918		switch (csWCaption[0])
919		{
920		default: //L'l':
921			nStyle = PCS_CIRCLE;
922			break;
923		case L'8':
924			nStyle = PCS_CROSS;
925			break;
926		case L'u':
927			nStyle = PCS_DIAMOND;
928			break;
929		case L'n':
930			nStyle = PCS_SQUARE;
931			break;
932		case L'H':
933			nStyle = PCS_STAR;
934			break;
935		case L'4':
936			nStyle = PCS_CHECK;
937			break;
938		}
939	}
940	else
941	{
942		nStyle = PCS_CIRCLE;
943	}
944
945	CFX_ByteString csAP_N_ON;
946
947	CPDF_Rect rcCenter = CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);
948
949	if (nStyle == PCS_CIRCLE)
950	{
951		if (nBorderStyle == PBS_BEVELED)
952		{
953			crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
954			crRightBottom = CPWL_Utils::SubstractColor(crBackground,0.25f);
955		}
956		else if (nBorderStyle == PBS_INSET)
957		{
958			crLeftTop = CPWL_Color(COLORTYPE_GRAY,0.5f);
959			crRightBottom = CPWL_Color(COLORTYPE_GRAY,0.75f);
960		}
961
962		csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter,crBackground) +
963			CPWL_Utils::GetCircleBorderAppStream(rcCenter,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
964	}
965	else
966	{
967		csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,crBackground) +
968			CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
969	}
970
971	CFX_ByteString csAP_N_OFF = csAP_N_ON;
972
973	switch (nBorderStyle)
974	{
975	case PBS_BEVELED:
976		{
977			CPWL_Color crTemp = crLeftTop;
978			crLeftTop = crRightBottom;
979			crRightBottom = crTemp;
980		}
981		break;
982	case PBS_INSET:
983		crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
984		crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
985		break;
986	}
987
988	CFX_ByteString csAP_D_ON;
989
990	if (nStyle == PCS_CIRCLE)
991	{
992		CPWL_Color crBK = CPWL_Utils::SubstractColor(crBackground,0.25f);
993		if (nBorderStyle == PBS_BEVELED)
994		{
995			crLeftTop = CPWL_Utils::SubstractColor(crBackground,0.25f);
996			crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
997			crBK = crBackground;
998		}
999		else if (nBorderStyle == PBS_INSET)
1000		{
1001			crLeftTop = CPWL_Color(COLORTYPE_GRAY,0);
1002			crRightBottom = CPWL_Color(COLORTYPE_GRAY,1);
1003		}
1004
1005		csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter,crBK)
1006			+ CPWL_Utils::GetCircleBorderAppStream(rcCenter,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
1007	}
1008	else
1009	{
1010		csAP_D_ON = CPWL_Utils::GetRectFillAppStream(rcWindow,CPWL_Utils::SubstractColor(crBackground,0.25f)) +
1011			CPWL_Utils::GetBorderAppStream(rcWindow,fBorderWidth,crBorder,crLeftTop,crRightBottom,nBorderStyle,dsBorder);
1012	}
1013
1014	CFX_ByteString csAP_D_OFF = csAP_D_ON;
1015
1016	csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient,nStyle,crText);
1017	csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient,nStyle,crText);
1018
1019	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON, pControl->GetCheckedAPState());
1020	WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
1021
1022	WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON, pControl->GetCheckedAPState());
1023	WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
1024
1025	CFX_ByteString csAS = GetAppState();
1026	if (csAS.IsEmpty())
1027		SetAppState("Off");
1028}
1029
1030void CPDFSDK_Widget::ResetAppearance_ComboBox(FX_LPCWSTR sValue)
1031{
1032	CPDF_FormControl* pControl = GetFormControl();
1033	ASSERT(pControl != NULL);
1034	CPDF_FormField* pField = pControl->GetField();
1035	ASSERT(pField != NULL);
1036
1037	CFX_ByteTextBuf sBody, sLines;
1038
1039	CPDF_Rect rcClient = GetClientRect();
1040	CPDF_Rect rcButton = rcClient;
1041	rcButton.left = rcButton.right - 13;
1042	rcButton.Normalize();
1043
1044	if (IFX_Edit * pEdit = IFX_Edit::NewEdit())
1045	{
1046		pEdit->EnableRefresh(FALSE);
1047
1048		ASSERT(this->m_pInterForm != NULL);
1049		CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
1050		ASSERT(pDoc != NULL);
1051		CPDFDoc_Environment* pEnv = pDoc->GetEnv();
1052		CBA_FontMap FontMap(this,pEnv->GetSysHandler());
1053		FontMap.Initial();
1054		pEdit->SetFontMap(&FontMap);
1055
1056		CPDF_Rect rcEdit = rcClient;
1057		rcEdit.right = rcButton.left;
1058		rcEdit.Normalize();
1059
1060		pEdit->SetPlateRect(rcEdit);
1061		pEdit->SetAlignmentV(1);
1062
1063		FX_FLOAT fFontSize = this->GetFontSize();
1064		if (IsFloatZero(fFontSize))
1065			pEdit->SetAutoFontSize(TRUE);
1066		else
1067			pEdit->SetFontSize(fFontSize);
1068
1069		pEdit->Initialize();
1070
1071		if (sValue)
1072			pEdit->SetText(sValue);
1073		else
1074		{
1075			FX_INT32 nCurSel = pField->GetSelectedIndex(0);
1076
1077			if (nCurSel < 0)
1078				pEdit->SetText(pField->GetValue().c_str());
1079			else
1080				pEdit->SetText(pField->GetOptionLabel(nCurSel).c_str());
1081		}
1082
1083		CPDF_Rect rcContent = pEdit->GetContentRect();
1084
1085		CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,0.0f));
1086		if (sEdit.GetLength() > 0)
1087		{
1088			sBody << "/Tx BMC\n" << "q\n";
1089			if (rcContent.Width() > rcEdit.Width() ||
1090				rcContent.Height() > rcEdit.Height())
1091			{
1092				sBody << rcEdit.left << " " << rcEdit.bottom << " "
1093					<< rcEdit.Width() << " " << rcEdit.Height() << " re\nW\nn\n";
1094			}
1095
1096			CPWL_Color crText = GetTextPWLColor();
1097			sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n" << "Q\nEMC\n";
1098		}
1099
1100		IFX_Edit::DelEdit(pEdit);
1101	}
1102
1103	sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
1104
1105	CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + sLines.GetByteString() + sBody.GetByteString();
1106
1107	WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1108}
1109
1110void CPDFSDK_Widget::ResetAppearance_ListBox()
1111{
1112	CPDF_FormControl* pControl = GetFormControl();
1113	ASSERT(pControl != NULL);
1114	CPDF_FormField* pField = pControl->GetField();
1115	ASSERT(pField != NULL);
1116
1117	CPDF_Rect rcClient = GetClientRect();
1118
1119	CFX_ByteTextBuf sBody, sLines;
1120
1121	if (IFX_Edit * pEdit = IFX_Edit::NewEdit())
1122	{
1123		pEdit->EnableRefresh(FALSE);
1124
1125//		ASSERT(this->m_pBaseForm != NULL);
1126		ASSERT(this->m_pInterForm != NULL);
1127		CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
1128		ASSERT(pDoc != NULL);
1129		CPDFDoc_Environment* pEnv = pDoc->GetEnv();
1130
1131		CBA_FontMap FontMap(this,pEnv->GetSysHandler());
1132		FontMap.Initial();
1133		pEdit->SetFontMap(&FontMap);
1134
1135		pEdit->SetPlateRect(CPDF_Rect(rcClient.left,0.0f,rcClient.right,0.0f));
1136
1137		FX_FLOAT fFontSize = GetFontSize();
1138
1139		if (IsFloatZero(fFontSize))
1140			pEdit->SetFontSize(12.0f);
1141		else
1142			pEdit->SetFontSize(fFontSize);
1143
1144		pEdit->Initialize();
1145
1146		CFX_ByteTextBuf sList;
1147		FX_FLOAT fy = rcClient.top;
1148
1149		FX_INT32 nTop = pField->GetTopVisibleIndex();
1150		FX_INT32 nCount = pField->CountOptions();
1151		FX_INT32 nSelCount = pField->CountSelectedItems();
1152
1153		for (FX_INT32 i=nTop; i<nCount; i++)
1154		{
1155			FX_BOOL bSelected = FALSE;
1156			for (FX_INT32 j=0; j<nSelCount; j++)
1157			{
1158				if (pField->GetSelectedIndex(j) == i)
1159				{
1160					bSelected = TRUE;
1161					break;
1162				}
1163			}
1164
1165			pEdit->SetText(pField->GetOptionLabel(i).c_str());
1166
1167			CPDF_Rect rcContent = pEdit->GetContentRect();
1168			FX_FLOAT fItemHeight = rcContent.Height();
1169
1170			if (bSelected)
1171			{
1172				CPDF_Rect rcItem = CPDF_Rect(rcClient.left,fy-fItemHeight,rcClient.right,fy);
1173				sList << "q\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_RGB,0,51.0f/255.0f,113.0f/255.0f),TRUE)
1174					<< rcItem.left << " " << rcItem.bottom << " " << rcItem.Width() << " " << rcItem.Height() << " re f\n" << "Q\n";
1175
1176				sList << "BT\n" << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY,1),TRUE) <<
1177					CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,fy)) << "ET\n";
1178			}
1179			else
1180			{
1181				CPWL_Color crText = GetTextPWLColor();
1182				sList << "BT\n" << CPWL_Utils::GetColorAppStream(crText,TRUE) <<
1183				CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,fy)) << "ET\n";
1184			}
1185
1186			fy -= fItemHeight;
1187		}
1188
1189		if (sList.GetSize() > 0)
1190		{
1191			sBody << "/Tx BMC\n" << "q\n" << rcClient.left << " " << rcClient.bottom << " "
1192					<< rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
1193			sBody << sList << "Q\nEMC\n";
1194		}
1195
1196		IFX_Edit::DelEdit(pEdit);
1197	}
1198
1199	CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + sLines.GetByteString() + sBody.GetByteString();
1200
1201	WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1202}
1203
1204void CPDFSDK_Widget::ResetAppearance_TextField(FX_LPCWSTR sValue)
1205{
1206	CPDF_FormControl* pControl = GetFormControl();
1207	ASSERT(pControl != NULL);
1208	CPDF_FormField* pField = pControl->GetField();
1209	ASSERT(pField != NULL);
1210
1211	CFX_ByteTextBuf sBody, sLines;
1212
1213	if (IFX_Edit * pEdit = IFX_Edit::NewEdit())
1214	{
1215		pEdit->EnableRefresh(FALSE);
1216
1217//		ASSERT(this->m_pBaseForm != NULL);
1218		ASSERT(this->m_pInterForm != NULL);
1219		CPDFSDK_Document* pDoc = m_pInterForm->GetDocument();
1220		ASSERT(pDoc != NULL);
1221		CPDFDoc_Environment* pEnv = pDoc->GetEnv();
1222
1223		CBA_FontMap FontMap(this,pEnv->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pBaseForm->GetEnv()));
1224		FontMap.Initial();
1225		pEdit->SetFontMap(&FontMap);
1226
1227		CPDF_Rect rcClient = GetClientRect();
1228		pEdit->SetPlateRect(rcClient);
1229		pEdit->SetAlignmentH(pControl->GetControlAlignment());
1230
1231		FX_DWORD dwFieldFlags = pField->GetFieldFlags();
1232		FX_BOOL bMultiLine = (dwFieldFlags >> 12) & 1;
1233
1234		if (bMultiLine)
1235		{
1236			pEdit->SetMultiLine(TRUE);
1237			pEdit->SetAutoReturn(TRUE);
1238		}
1239		else
1240		{
1241			pEdit->SetAlignmentV(1);
1242		}
1243
1244		FX_WORD subWord = 0;
1245		if ((dwFieldFlags >> 13) & 1)
1246		{
1247			subWord = '*';
1248			pEdit->SetPasswordChar(subWord);
1249		}
1250
1251		int nMaxLen = pField->GetMaxLen();
1252		FX_BOOL bCharArray = (dwFieldFlags >> 24) & 1;
1253		FX_FLOAT fFontSize = GetFontSize();
1254
1255		if (nMaxLen > 0)
1256		{
1257			if (bCharArray)
1258			{
1259				pEdit->SetCharArray(nMaxLen);
1260
1261				if (IsFloatZero(fFontSize))
1262				{
1263					fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(FontMap.GetPDFFont(0),rcClient,nMaxLen);
1264				}
1265			}
1266			else
1267			{
1268				if (sValue)
1269					nMaxLen = wcslen((const wchar_t*)sValue);
1270				pEdit->SetLimitChar(nMaxLen);
1271			}
1272		}
1273
1274		if (IsFloatZero(fFontSize))
1275			pEdit->SetAutoFontSize(TRUE);
1276		else
1277			pEdit->SetFontSize(fFontSize);
1278
1279		pEdit->Initialize();
1280
1281		if (sValue)
1282			pEdit->SetText(sValue);
1283		else
1284			pEdit->SetText(pField->GetValue().c_str());
1285
1286		CPDF_Rect rcContent = pEdit->GetContentRect();
1287
1288		CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(pEdit,CPDF_Point(0.0f,0.0f),
1289																	NULL,!bCharArray,subWord);
1290
1291		if (sEdit.GetLength() > 0)
1292		{
1293			sBody << "/Tx BMC\n" << "q\n";
1294			if (rcContent.Width() > rcClient.Width() ||
1295				rcContent.Height() > rcClient.Height())
1296			{
1297				sBody << rcClient.left << " " << rcClient.bottom << " "
1298					<< rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
1299			}
1300			CPWL_Color crText = GetTextPWLColor();
1301			sBody << "BT\n" << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n" << "Q\nEMC\n";
1302		}
1303
1304		if (bCharArray)
1305		{
1306			switch (GetBorderStyle())
1307			{
1308			case BBS_SOLID:
1309				{
1310					CFX_ByteString sColor = CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE);
1311					if (sColor.GetLength() > 0)
1312					{
1313						sLines << "q\n" << GetBorderWidth() << " w\n"
1314							<< CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE) << " 2 J 0 j\n";
1315
1316						for (FX_INT32 i=1;i<nMaxLen;i++)
1317						{
1318							sLines << rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
1319								<< rcClient.bottom << " m\n"
1320								<< rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
1321								<< rcClient.top << " l S\n";
1322						}
1323
1324						sLines << "Q\n";
1325					}
1326				}
1327				break;
1328			case BBS_DASH:
1329				{
1330					CFX_ByteString sColor = CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE);
1331					if (sColor.GetLength() > 0)
1332					{
1333						CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
1334
1335						sLines << "q\n" << GetBorderWidth() << " w\n"
1336							<< CPWL_Utils::GetColorAppStream(GetBorderPWLColor(),FALSE)
1337							<< "[" << dsBorder.nDash << " "
1338							<< dsBorder.nGap << "] "
1339							<< dsBorder.nPhase << " d\n";
1340
1341						for (FX_INT32 i=1;i<nMaxLen;i++)
1342						{
1343							sLines << rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
1344								<< rcClient.bottom << " m\n"
1345								<< rcClient.left + ((rcClient.right - rcClient.left)/nMaxLen)*i << " "
1346								<< rcClient.top << " l S\n";
1347						}
1348
1349						sLines << "Q\n";
1350					}
1351				}
1352				break;
1353			}
1354		}
1355
1356		IFX_Edit::DelEdit(pEdit);
1357	}
1358
1359	CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() + sLines.GetByteString() + sBody.GetByteString();
1360	WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1361}
1362
1363CPDF_Rect CPDFSDK_Widget::GetClientRect() const
1364{
1365	CPDF_Rect rcWindow = GetRotatedRect();
1366	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1367	switch (GetBorderStyle())
1368	{
1369	case BBS_BEVELED:
1370	case BBS_INSET:
1371		fBorderWidth *= 2.0f;
1372		break;
1373	}
1374
1375	return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
1376}
1377
1378CPDF_Rect CPDFSDK_Widget::GetRotatedRect() const
1379{
1380	CPDF_Rect rectAnnot = GetRect();
1381	FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
1382	FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
1383
1384	CPDF_FormControl* pControl = GetFormControl();
1385	ASSERT(pControl != NULL);
1386
1387	CPDF_Rect rcPDFWindow;
1388	switch(abs(pControl->GetRotation() % 360))
1389	{
1390		case 0:
1391		case 180:
1392		default:
1393			rcPDFWindow = CPDF_Rect(0, 0, fWidth, fHeight);
1394			break;
1395		case 90:
1396		case 270:
1397			rcPDFWindow = CPDF_Rect(0, 0, fHeight, fWidth);
1398			break;
1399	}
1400
1401	return rcPDFWindow;
1402}
1403
1404CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const
1405{
1406	CPWL_Color crBackground = GetFillPWLColor();
1407	if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
1408		return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
1409	else
1410		return "";
1411}
1412
1413CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const
1414{
1415	CPDF_Rect rcWindow = GetRotatedRect();
1416	CPWL_Color crBorder = GetBorderPWLColor();
1417	CPWL_Color crBackground = GetFillPWLColor();
1418	CPWL_Color crLeftTop, crRightBottom;
1419
1420	FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1421	FX_INT32 nBorderStyle = 0;
1422	CPWL_Dash dsBorder(3,0,0);
1423
1424	switch (GetBorderStyle())
1425	{
1426	case BBS_DASH:
1427		nBorderStyle = PBS_DASH;
1428		dsBorder = CPWL_Dash(3, 3, 0);
1429		break;
1430	case BBS_BEVELED:
1431		nBorderStyle = PBS_BEVELED;
1432		fBorderWidth *= 2;
1433		crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1434		crRightBottom = CPWL_Utils::DevideColor(crBackground, 2);
1435		break;
1436	case BBS_INSET:
1437		nBorderStyle = PBS_INSET;
1438		fBorderWidth *= 2;
1439		crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1440		crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1441		break;
1442	case BBS_UNDERLINE:
1443		nBorderStyle = PBS_UNDERLINED;
1444		break;
1445	default:
1446		nBorderStyle = PBS_SOLID;
1447		break;
1448	}
1449
1450	return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder, crLeftTop,
1451		crRightBottom, nBorderStyle, dsBorder);
1452}
1453
1454CPDF_Matrix CPDFSDK_Widget::GetMatrix() const
1455{
1456	CPDF_Matrix mt;
1457	CPDF_FormControl* pControl = GetFormControl();
1458	ASSERT(pControl != NULL);
1459
1460	CPDF_Rect rcAnnot = GetRect();
1461	FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
1462	FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;
1463
1464
1465
1466	switch (abs(pControl->GetRotation() % 360))
1467	{
1468		case 0:
1469		default:
1470			mt = CPDF_Matrix(1, 0, 0, 1, 0, 0);
1471			break;
1472		case 90:
1473			mt = CPDF_Matrix(0, 1, -1, 0, fWidth, 0);
1474			break;
1475		case 180:
1476			mt = CPDF_Matrix(-1, 0, 0, -1, fWidth, fHeight);
1477			break;
1478		case 270:
1479			mt = CPDF_Matrix(0, -1, 1, 0, 0, fHeight);
1480			break;
1481	}
1482
1483	return mt;
1484}
1485
1486CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const
1487{
1488	CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);
1489
1490	CPDF_FormControl* pFormCtrl = GetFormControl();
1491	ASSERT(pFormCtrl != NULL);
1492
1493	CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
1494	if (da.HasColor())
1495	{
1496		FX_INT32 iColorType;
1497		FX_FLOAT fc[4];
1498		da.GetColor(iColorType, fc);
1499		crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1500	}
1501
1502	return crText;
1503}
1504
1505CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const
1506{
1507	CPWL_Color crBorder;
1508
1509	CPDF_FormControl* pFormCtrl = GetFormControl();
1510	ASSERT(pFormCtrl != NULL);
1511
1512	FX_INT32 iColorType;
1513	FX_FLOAT fc[4];
1514	pFormCtrl->GetOriginalBorderColor(iColorType, fc);
1515	if (iColorType > 0)
1516		crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1517
1518	return crBorder;
1519}
1520
1521CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const
1522{
1523	CPWL_Color crFill;
1524
1525	CPDF_FormControl* pFormCtrl = GetFormControl();
1526	ASSERT(pFormCtrl != NULL);
1527
1528	FX_INT32 iColorType;
1529	FX_FLOAT fc[4];
1530	pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
1531	if (iColorType > 0)
1532		crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1533
1534	return crFill;
1535}
1536
1537void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType, CPDF_Stream* pImage)
1538{
1539	ASSERT(pImage != NULL);
1540
1541	ASSERT(m_pAnnot != NULL);
1542	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
1543
1544	CPDF_Document* pDoc = m_pPageView->GetPDFDocument();//pDocument->GetDocument();
1545	ASSERT(pDoc != NULL);
1546
1547	CPDF_Dictionary* pAPDict = m_pAnnot->m_pAnnotDict->GetDict("AP");
1548	ASSERT(pAPDict != NULL);
1549
1550	CPDF_Stream* pStream = pAPDict->GetStream(sAPType);
1551	ASSERT(pStream != NULL);
1552
1553	CPDF_Dictionary* pStreamDict = pStream->GetDict();
1554	ASSERT(pStreamDict != NULL);
1555
1556	CFX_ByteString sImageAlias = "IMG";
1557
1558	if (CPDF_Dictionary* pImageDict = pImage->GetDict())
1559	{
1560		sImageAlias = pImageDict->GetString("Name");
1561		if (sImageAlias.IsEmpty())
1562			sImageAlias = "IMG";
1563	}
1564
1565	CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
1566	if (!pStreamResList)
1567	{
1568		pStreamResList = new CPDF_Dictionary();
1569		pStreamDict->SetAt("Resources", pStreamResList);
1570	}
1571
1572	if (pStreamResList)
1573	{
1574		CPDF_Dictionary* pXObject = new CPDF_Dictionary;
1575		pXObject->SetAtReference(sImageAlias, pDoc, pImage);
1576		pStreamResList->SetAt("XObject", pXObject);
1577	}
1578}
1579
1580void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType)
1581{
1582	ASSERT(m_pAnnot != NULL);
1583	ASSERT(m_pAnnot->m_pAnnotDict != NULL);
1584
1585	if (CPDF_Dictionary* pAPDict = m_pAnnot->m_pAnnotDict->GetDict("AP"))
1586	{
1587		pAPDict->RemoveAt(sAPType);
1588	}
1589}
1590
1591FX_BOOL CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type, PDFSDK_FieldAction& data, CPDFSDK_PageView* pPageView)
1592{
1593	CPDF_Action action = GetAAction(type);
1594
1595	if (action && action.GetType() != CPDF_Action::Unknown)
1596	{
1597 		CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
1598 		ASSERT(pDocument != NULL);
1599
1600 		CPDFDoc_Environment* pEnv = pDocument->GetEnv();
1601 		ASSERT(pEnv != NULL);
1602
1603		CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();/*(CPDFSDK_ActionHandler*)pApp->GetActionHandler();*/
1604 		ASSERT(pActionHandler != NULL);
1605
1606 		return pActionHandler->DoAction_Field(action, type, pDocument, GetFormField(), data);
1607	}
1608
1609	return FALSE;
1610}
1611
1612CPDF_Action	CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT)
1613{
1614	switch (eAAT)
1615	{
1616	case CPDF_AAction::CursorEnter:
1617	case CPDF_AAction::CursorExit:
1618	case CPDF_AAction::ButtonDown:
1619	case CPDF_AAction::ButtonUp:
1620	case CPDF_AAction::GetFocus:
1621	case CPDF_AAction::LoseFocus:
1622	case CPDF_AAction::PageOpen:
1623	case CPDF_AAction::PageClose:
1624	case CPDF_AAction::PageVisible:
1625	case CPDF_AAction::PageInvisible:
1626		return CPDFSDK_Annot::GetAAction(eAAT);
1627
1628	case CPDF_AAction::KeyStroke:
1629	case CPDF_AAction::Format:
1630	case CPDF_AAction::Validate:
1631	case CPDF_AAction::Calculate:
1632		{
1633			CPDF_FormField* pField = this->GetFormField();
1634			if (CPDF_AAction aa = pField->GetAdditionalAction())
1635				return aa.GetAction(eAAT);
1636
1637			return CPDFSDK_Annot::GetAAction(eAAT);
1638		}
1639	default:
1640		break;
1641	}
1642
1643	return CPDF_Action();
1644}
1645
1646
1647CFX_WideString CPDFSDK_Widget::GetAlternateName() const
1648{
1649	CPDF_FormField*	pFormField = GetFormField();
1650	ASSERT(pFormField != NULL);
1651
1652	return pFormField->GetAlternateName();
1653}
1654
1655FX_INT32	CPDFSDK_Widget::GetAppearanceAge() const
1656{
1657	return m_nAppAge;
1658}
1659
1660FX_INT32 CPDFSDK_Widget::GetValueAge() const
1661{
1662	return m_nValueAge;
1663}
1664
1665
1666FX_BOOL	CPDFSDK_Widget::HitTest(FX_FLOAT pageX, FX_FLOAT pageY)
1667{
1668	CPDF_Annot* pAnnot = GetPDFAnnot();
1669	CFX_FloatRect annotRect;
1670	pAnnot->GetRect(annotRect);
1671	if(annotRect.Contains(pageX, pageY))
1672	{
1673		if (!IsVisible()) return FALSE;
1674
1675		int nFieldFlags = GetFieldFlags();
1676		if ((nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY)
1677			return FALSE;
1678
1679		return TRUE;
1680	}
1681	return FALSE;
1682}
1683
1684CPDFSDK_InterForm::CPDFSDK_InterForm(CPDFSDK_Document* pDocument)
1685	:m_pDocument(pDocument),
1686	m_pInterForm(NULL),
1687	m_bCalculate(TRUE),
1688	m_bBusy(FALSE)
1689{
1690	ASSERT(m_pDocument != NULL);
1691	m_pInterForm = new CPDF_InterForm(m_pDocument->GetDocument(), FALSE);
1692	ASSERT(m_pInterForm != NULL);
1693	m_pInterForm->SetFormNotify(this);
1694
1695	for(int i=0; i<6; i++)
1696		m_bNeedHightlight[i] = FALSE;
1697	m_iHighlightAlpha = 0;
1698}
1699
1700CPDFSDK_InterForm::~CPDFSDK_InterForm()
1701{
1702	ASSERT(m_pInterForm != NULL);
1703	delete m_pInterForm;
1704	m_pInterForm = NULL;
1705
1706	m_Map.RemoveAll();
1707}
1708
1709void CPDFSDK_InterForm::Destroy()
1710{
1711	delete this;
1712}
1713
1714CPDF_InterForm* CPDFSDK_InterForm::GetInterForm()
1715{
1716	return m_pInterForm;
1717}
1718
1719CPDFSDK_Document* CPDFSDK_InterForm::GetDocument()
1720{
1721	return m_pDocument;
1722}
1723
1724FX_BOOL CPDFSDK_InterForm::HighlightWidgets()
1725{
1726	return FALSE;
1727}
1728
1729CPDFSDK_Widget* CPDFSDK_InterForm::GetSibling(CPDFSDK_Widget* pWidget, FX_BOOL bNext) const
1730{
1731    nonstd::unique_ptr<CBA_AnnotIterator> pIterator(
1732        new CBA_AnnotIterator(pWidget->GetPageView(), "Widget", ""));
1733
1734    if (bNext) {
1735        return (CPDFSDK_Widget*)pIterator->GetNextAnnot(pWidget);
1736    }
1737    return (CPDFSDK_Widget*)pIterator->GetPrevAnnot(pWidget);
1738}
1739
1740CPDFSDK_Widget*	CPDFSDK_InterForm::GetWidget(CPDF_FormControl* pControl) const
1741{
1742	if(!pControl || !m_pInterForm) return NULL;
1743
1744	CPDFSDK_Widget* pWidget = NULL;
1745	m_Map.Lookup(pControl, pWidget);
1746
1747	if (pWidget) return pWidget;
1748
1749	CPDF_Dictionary* pControlDict = pControl->GetWidget();
1750	ASSERT(pControlDict != NULL);
1751
1752	ASSERT(m_pDocument != NULL);
1753	CPDF_Document* pDocument = m_pDocument->GetDocument();
1754
1755	CPDFSDK_PageView* pPage = NULL;
1756
1757	if (CPDF_Dictionary* pPageDict = pControlDict->GetDict("P"))
1758	{
1759		int nPageIndex = pDocument->GetPageIndex(pPageDict->GetObjNum());
1760		if (nPageIndex >= 0)
1761		{
1762			pPage = m_pDocument->GetPageView(nPageIndex);
1763		}
1764	}
1765
1766	if (!pPage)
1767	{
1768		int nPageIndex = GetPageIndexByAnnotDict(pDocument, pControlDict);
1769		if (nPageIndex >= 0)
1770		{
1771			pPage = m_pDocument->GetPageView(nPageIndex);
1772		}
1773	}
1774
1775	if (pPage)
1776		return (CPDFSDK_Widget*)pPage->GetAnnotByDict(pControlDict);
1777
1778	return NULL;
1779}
1780
1781void CPDFSDK_InterForm::GetWidgets(const CFX_WideString& sFieldName, CFX_PtrArray& widgets)
1782{
1783	ASSERT(m_pInterForm != NULL);
1784
1785	for (int i=0,sz=m_pInterForm->CountFields(sFieldName); i<sz; i++)
1786	{
1787		CPDF_FormField* pFormField = m_pInterForm->GetField(i, sFieldName);
1788		ASSERT(pFormField != NULL);
1789
1790		GetWidgets(pFormField, widgets);
1791	}
1792}
1793
1794void CPDFSDK_InterForm::GetWidgets(CPDF_FormField* pField, CFX_PtrArray& widgets)
1795{
1796	ASSERT(pField != NULL);
1797
1798	for (int i=0,isz=pField->CountControls(); i<isz; i++)
1799	{
1800		CPDF_FormControl* pFormCtrl = pField->GetControl(i);
1801		ASSERT(pFormCtrl != NULL);
1802
1803		CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl);
1804
1805		if (pWidget)
1806			widgets.Add(pWidget);
1807	}
1808}
1809
1810int CPDFSDK_InterForm::GetPageIndexByAnnotDict(CPDF_Document* pDocument, CPDF_Dictionary* pAnnotDict) const
1811{
1812	ASSERT(pDocument != NULL);
1813	ASSERT(pAnnotDict != NULL);
1814
1815	for (int i=0,sz=pDocument->GetPageCount(); i<sz; i++)
1816	{
1817		if (CPDF_Dictionary* pPageDict = pDocument->GetPage(i))
1818		{
1819			if (CPDF_Array* pAnnots = pPageDict->GetArray("Annots"))
1820			{
1821				for (int j=0,jsz=pAnnots->GetCount(); j<jsz; j++)
1822				{
1823					CPDF_Object* pDict = pAnnots->GetElementValue(j);
1824					if (pAnnotDict == pDict)
1825					{
1826						return i;
1827					}
1828				}
1829			}
1830		}
1831	}
1832
1833	return -1;
1834}
1835
1836void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget)
1837{
1838	m_Map.SetAt(pControl, pWidget);
1839}
1840
1841void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl)
1842{
1843	m_Map.RemoveKey(pControl);
1844}
1845
1846void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled)
1847{
1848	m_bCalculate = bEnabled;
1849}
1850
1851FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const
1852{
1853	return m_bCalculate;
1854}
1855
1856#ifdef _WIN32
1857CPDF_Stream* CPDFSDK_InterForm::LoadImageFromFile(const CFX_WideString& sFile)
1858{
1859	ASSERT(m_pDocument != NULL);
1860	CPDF_Document* pDocument = m_pDocument->GetDocument();
1861	ASSERT(pDocument != NULL);
1862
1863	CPDF_Stream* pRetStream = NULL;
1864
1865	if (CFX_DIBitmap* pBmp = CFX_WindowsDIB::LoadFromFile(sFile.c_str()))
1866	{
1867		int nWidth = pBmp->GetWidth();
1868		int nHeight = pBmp->GetHeight();
1869
1870		CPDF_Image Image(pDocument);
1871		Image.SetImage(pBmp, FALSE);
1872		CPDF_Stream* pImageStream = Image.GetStream();
1873		if (pImageStream)
1874		{
1875			if (pImageStream->GetObjNum() == 0)
1876				pDocument->AddIndirectObject(pImageStream);
1877
1878			CPDF_Dictionary* pStreamDict = new CPDF_Dictionary();
1879			pStreamDict->SetAtName("Subtype", "Form");
1880			pStreamDict->SetAtName("Name", "IMG");
1881			CPDF_Array* pMatrix = new CPDF_Array();
1882			pStreamDict->SetAt("Matrix", pMatrix);
1883			pMatrix->AddInteger(1);
1884			pMatrix->AddInteger(0);
1885			pMatrix->AddInteger(0);
1886			pMatrix->AddInteger(1);
1887			pMatrix->AddInteger(-nWidth / 2);
1888			pMatrix->AddInteger(-nHeight / 2);
1889			CPDF_Dictionary* pResource = new CPDF_Dictionary();
1890			pStreamDict->SetAt("Resources", pResource);
1891			CPDF_Dictionary* pXObject = new CPDF_Dictionary();
1892			pResource->SetAt("XObject", pXObject);
1893			pXObject->SetAtReference("Img", pDocument, pImageStream);
1894			CPDF_Array* pProcSet = new CPDF_Array();
1895			pResource->SetAt("ProcSet", pProcSet);
1896			pProcSet->AddName("PDF");
1897			pProcSet->AddName("ImageC");
1898			pStreamDict->SetAtName("Type", "XObject");
1899			CPDF_Array* pBBox = new CPDF_Array();
1900			pStreamDict->SetAt("BBox", pBBox);
1901			pBBox->AddInteger(0);
1902			pBBox->AddInteger(0);
1903			pBBox->AddInteger(nWidth);
1904			pBBox->AddInteger(nHeight);
1905			pStreamDict->SetAtInteger("FormType", 1);
1906
1907			pRetStream = new CPDF_Stream(NULL, 0, NULL);
1908			CFX_ByteString csStream;
1909			csStream.Format("q\n%d 0 0 %d 0 0 cm\n/Img Do\nQ", nWidth, nHeight);
1910			pRetStream->InitStream((FX_BYTE*)csStream.c_str(), csStream.GetLength(), pStreamDict);
1911			pDocument->AddIndirectObject(pRetStream);
1912		}
1913
1914		delete pBmp;
1915	}
1916
1917	return pRetStream;
1918}
1919#endif
1920
1921void CPDFSDK_InterForm::OnCalculate(CPDF_FormField* pFormField)
1922{
1923	ASSERT(m_pDocument != NULL);
1924	CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
1925	ASSERT(pEnv);
1926	if(!pEnv->IsJSInitiated())
1927		return;
1928
1929	if (m_bBusy) return;
1930
1931	m_bBusy = TRUE;
1932
1933	if (this->IsCalculateEnabled())
1934	{
1935		IFXJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
1936		ASSERT(pRuntime != NULL);
1937
1938		pRuntime->SetReaderDocument(m_pDocument);
1939
1940		int nSize = m_pInterForm->CountFieldsInCalculationOrder();
1941		for (int i=0; i<nSize; i++)
1942		{
1943			if(CPDF_FormField* pField = m_pInterForm->GetFieldInCalculationOrder(i))
1944			{
1945//			ASSERT(pField != NULL);
1946				int nType = pField->GetFieldType();
1947				if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
1948				{
1949					CPDF_AAction aAction = pField->GetAdditionalAction();
1950					if (aAction && aAction.ActionExist(CPDF_AAction::Calculate))
1951					{
1952						CPDF_Action action = aAction.GetAction(CPDF_AAction::Calculate);
1953						if (action)
1954						{
1955							CFX_WideString csJS = action.GetJavaScript();
1956							if (!csJS.IsEmpty())
1957							{
1958								IFXJS_Context* pContext = pRuntime->NewContext();
1959								ASSERT(pContext != NULL);
1960
1961								CFX_WideString sOldValue = pField->GetValue();
1962								CFX_WideString sValue = sOldValue;
1963								FX_BOOL bRC = TRUE;
1964								pContext->OnField_Calculate(pFormField, pField, sValue, bRC);
1965
1966								CFX_WideString sInfo;
1967								FX_BOOL bRet = pContext->RunScript(csJS, sInfo);
1968								pRuntime->ReleaseContext(pContext);
1969
1970								if (bRet)
1971								{
1972									if (bRC)
1973									{
1974										if (sValue.Compare(sOldValue) != 0)
1975											pField->SetValue(sValue, TRUE);
1976									}
1977								}
1978							}
1979						}
1980					}
1981				}
1982			}
1983		}
1984
1985
1986	}
1987
1988	m_bBusy = FALSE;
1989}
1990
1991CFX_WideString CPDFSDK_InterForm::OnFormat(CPDF_FormField* pFormField, int nCommitKey, FX_BOOL& bFormated)
1992{
1993	ASSERT(m_pDocument != NULL);
1994	ASSERT(pFormField != NULL);
1995
1996	CFX_WideString sValue = pFormField->GetValue();
1997	CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
1998	ASSERT(pEnv);
1999	if(!pEnv->IsJSInitiated())
2000	{
2001		bFormated = FALSE;
2002		return sValue;
2003	}
2004
2005	IFXJS_Runtime* pRuntime = m_pDocument->GetJsRuntime();
2006	ASSERT(pRuntime != NULL);
2007
2008	pRuntime->SetReaderDocument(m_pDocument);
2009
2010	if (pFormField->GetFieldType() == FIELDTYPE_COMBOBOX)
2011	{
2012		if (pFormField->CountSelectedItems() > 0)
2013		{
2014			int index = pFormField->GetSelectedIndex(0);
2015			if (index >= 0)
2016				sValue = pFormField->GetOptionLabel(index);
2017		}
2018	}
2019
2020	bFormated = FALSE;
2021
2022	CPDF_AAction aAction = pFormField->GetAdditionalAction();
2023	if (aAction != NULL && aAction.ActionExist(CPDF_AAction::Format))
2024	{
2025		CPDF_Action action = aAction.GetAction(CPDF_AAction::Format);
2026		if (action)
2027		{
2028			CFX_WideString script = action.GetJavaScript();
2029			if (!script.IsEmpty())
2030			{
2031				CFX_WideString Value = sValue;
2032
2033				IFXJS_Context* pContext = pRuntime->NewContext();
2034				ASSERT(pContext != NULL);
2035
2036				pContext->OnField_Format(nCommitKey, pFormField, Value, TRUE);
2037
2038				CFX_WideString sInfo;
2039 				FX_BOOL bRet = pContext->RunScript(script, sInfo);
2040				pRuntime->ReleaseContext(pContext);
2041
2042				if (bRet)
2043				{
2044					sValue = Value;
2045					bFormated = TRUE;
2046				}
2047			}
2048		}
2049	}
2050
2051	return sValue;
2052}
2053
2054void CPDFSDK_InterForm::ResetFieldAppearance(CPDF_FormField* pFormField, FX_LPCWSTR sValue, FX_BOOL bValueChanged)
2055{
2056	ASSERT(pFormField != NULL);
2057
2058	for (int i=0,sz=pFormField->CountControls(); i<sz; i++)
2059	{
2060		CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
2061		ASSERT(pFormCtrl != NULL);
2062
2063		ASSERT(m_pInterForm != NULL);
2064		if(CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
2065			pWidget->ResetAppearance(sValue, bValueChanged);
2066	}
2067}
2068
2069void CPDFSDK_InterForm::UpdateField(CPDF_FormField* pFormField)
2070{
2071	ASSERT(pFormField != NULL);
2072
2073	for (int i=0,sz=pFormField->CountControls(); i<sz; i++)
2074	{
2075		CPDF_FormControl* pFormCtrl = pFormField->GetControl(i);
2076		ASSERT(pFormCtrl != NULL);
2077
2078		if(CPDFSDK_Widget* pWidget = GetWidget(pFormCtrl))
2079		{
2080			CPDFDoc_Environment * pEnv = m_pDocument->GetEnv();
2081			CFFL_IFormFiller* pIFormFiller = pEnv->GetIFormFiller();
2082
2083			CPDF_Page * pPage = pWidget->GetPDFPage();
2084			CPDFSDK_PageView * pPageView = m_pDocument->GetPageView(pPage,FALSE);
2085
2086			FX_RECT rcBBox = pIFormFiller->GetViewBBox(pPageView, pWidget);
2087
2088			pEnv->FFI_Invalidate(pPage,rcBBox.left, rcBBox.top, rcBBox.right, rcBBox.bottom);
2089		}
2090	}
2091}
2092
2093void CPDFSDK_InterForm::OnKeyStrokeCommit(CPDF_FormField* pFormField, CFX_WideString& csValue, FX_BOOL& bRC)
2094{
2095	ASSERT(pFormField != NULL);
2096
2097 	CPDF_AAction aAction = pFormField->GetAdditionalAction();
2098 	if (aAction != NULL && aAction.ActionExist(CPDF_AAction::KeyStroke))
2099 	{
2100 		CPDF_Action action = aAction.GetAction(CPDF_AAction::KeyStroke);
2101 		if (action)
2102 		{
2103 			ASSERT(m_pDocument != NULL);
2104 			CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2105 			ASSERT(pEnv != NULL);
2106
2107			CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
2108			ASSERT(pActionHandler != NULL);
2109
2110			PDFSDK_FieldAction fa;
2111			fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
2112 			fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
2113			fa.sValue = csValue;
2114
2115   			pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::KeyStroke,
2116   				m_pDocument, pFormField, fa);
2117   			bRC = fa.bRC;
2118 		}
2119 	}
2120}
2121
2122void CPDFSDK_InterForm::OnValidate(CPDF_FormField* pFormField, CFX_WideString& csValue, FX_BOOL& bRC)
2123{
2124	ASSERT(pFormField != NULL);
2125
2126 	CPDF_AAction aAction = pFormField->GetAdditionalAction();
2127 	if (aAction != NULL && aAction.ActionExist(CPDF_AAction::Validate))
2128 	{
2129 		CPDF_Action action = aAction.GetAction(CPDF_AAction::Validate);
2130		if (action)
2131 		{
2132			ASSERT(m_pDocument != NULL);
2133			CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2134			ASSERT(pEnv != NULL);
2135
2136			CPDFSDK_ActionHandler* pActionHandler = pEnv->GetActionHander();
2137			ASSERT(pActionHandler != NULL);
2138
2139			PDFSDK_FieldAction fa;
2140			fa.bModifier = pEnv->FFI_IsCTRLKeyDown(0);
2141			fa.bShift = pEnv->FFI_IsSHIFTKeyDown(0);
2142			fa.sValue = csValue;
2143
2144			pActionHandler->DoAction_FieldJavaScript(action, CPDF_AAction::Validate, m_pDocument, pFormField, fa);
2145			bRC = fa.bRC;
2146
2147		}
2148 	}
2149}
2150
2151/* ----------------------------- action ----------------------------- */
2152
2153FX_BOOL CPDFSDK_InterForm::DoAction_Hide(const CPDF_Action& action)
2154{
2155	ASSERT(action);
2156
2157	CPDF_ActionFields af = action.GetWidgets();
2158	CFX_PtrArray fieldObjects;
2159	af.GetAllFields(fieldObjects);
2160	CFX_PtrArray widgetArray;
2161	CFX_PtrArray fields;
2162	GetFieldFromObjects(fieldObjects, fields);
2163
2164	FX_BOOL bHide = action.GetHideStatus();
2165
2166	FX_BOOL bChanged = FALSE;
2167
2168	for (int i=0, sz=fields.GetSize(); i<sz; i++)
2169	{
2170		CPDF_FormField* pField = (CPDF_FormField*)fields[i];
2171		ASSERT(pField != NULL);
2172
2173
2174		for (int j=0,jsz=pField->CountControls(); j<jsz; j++)
2175		{
2176			CPDF_FormControl* pControl = pField->GetControl(j);
2177			ASSERT(pControl != NULL);
2178
2179			if (CPDFSDK_Widget* pWidget = GetWidget(pControl))
2180			{
2181				int nFlags = pWidget->GetFlags();
2182				if (bHide)
2183				{
2184					nFlags &= (~ANNOTFLAG_INVISIBLE);
2185					nFlags &= (~ANNOTFLAG_NOVIEW);
2186					nFlags |= (ANNOTFLAG_HIDDEN);
2187				}
2188				else
2189				{
2190					nFlags &= (~ANNOTFLAG_INVISIBLE);
2191					nFlags &= (~ANNOTFLAG_HIDDEN);
2192					nFlags &= (~ANNOTFLAG_NOVIEW);
2193				}
2194				pWidget->SetFlags(nFlags);
2195
2196 				CPDFSDK_PageView* pPageView = pWidget->GetPageView();
2197 				ASSERT(pPageView != NULL);
2198
2199 				pPageView->UpdateView(pWidget);
2200
2201				bChanged = TRUE;
2202			}
2203		}
2204	}
2205
2206	return bChanged;
2207}
2208
2209FX_BOOL CPDFSDK_InterForm::DoAction_SubmitForm(const CPDF_Action& action)
2210{
2211	ASSERT(action);
2212	ASSERT(m_pInterForm != NULL);
2213
2214	CFX_WideString sDestination = action.GetFilePath();
2215	if (sDestination.IsEmpty()) return FALSE;
2216
2217	CPDF_Dictionary* pActionDict = action.GetDict();
2218	if (pActionDict->KeyExist("Fields"))
2219	{
2220		CPDF_ActionFields af = action.GetWidgets();
2221		FX_DWORD dwFlags = action.GetFlags();
2222
2223		CFX_PtrArray fieldObjects;
2224		af.GetAllFields(fieldObjects);
2225		CFX_PtrArray fields;
2226		GetFieldFromObjects(fieldObjects, fields);
2227
2228		if (fields.GetSize() != 0)
2229		{
2230			FX_BOOL bIncludeOrExclude = !(dwFlags & 0x01);
2231			if (m_pInterForm->CheckRequiredFields(&fields, bIncludeOrExclude))
2232			{
2233				return FALSE;
2234			}
2235			return SubmitFields(sDestination, fields, bIncludeOrExclude, FALSE);
2236		}
2237		else
2238		{
2239			if ( m_pInterForm->CheckRequiredFields())
2240			{
2241				return FALSE;
2242			}
2243
2244			return SubmitForm(sDestination, FALSE);
2245		}
2246	}
2247	else
2248	{
2249		if ( m_pInterForm->CheckRequiredFields())
2250		{
2251			return FALSE;
2252		}
2253
2254		return SubmitForm(sDestination, FALSE);
2255	}
2256}
2257
2258FX_BOOL CPDFSDK_InterForm::SubmitFields(const CFX_WideString& csDestination, const CFX_PtrArray& fields,
2259									FX_BOOL bIncludeOrExclude, FX_BOOL bUrlEncoded)
2260{
2261	CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2262	ASSERT(pEnv != NULL);
2263
2264	CFX_ByteTextBuf textBuf;
2265	ExportFieldsToFDFTextBuf(fields, bIncludeOrExclude, textBuf);
2266
2267	FX_LPBYTE pBuffer = textBuf.GetBuffer();
2268	FX_STRSIZE nBufSize = textBuf.GetLength();
2269
2270	if (bUrlEncoded)
2271	{
2272		if(!FDFToURLEncodedData(pBuffer, nBufSize))
2273			return FALSE;
2274	}
2275
2276	pEnv->JS_docSubmitForm(pBuffer, nBufSize, csDestination.c_str());
2277
2278	return TRUE;
2279}
2280
2281void CPDFSDK_InterForm::DoFDFBuffer(CFX_ByteString sBuffer)
2282{
2283	ASSERT(m_pDocument != NULL);
2284
2285	if (CFDF_Document *pFDFDocument = CFDF_Document::ParseMemory((const unsigned char *)sBuffer.GetBuffer(sBuffer.GetLength()), sBuffer.GetLength()))
2286	{
2287		CPDF_Dictionary* pRootDic = pFDFDocument->GetRoot();
2288		if(pRootDic)
2289		{
2290			CPDF_Dictionary * pFDFDict=pRootDic->GetDict("FDF");
2291			if(pFDFDict)
2292			{
2293				CPDF_Dictionary * pJSDict = pFDFDict->GetDict("JavaScript");
2294				if(pJSDict)
2295				{
2296					CFX_WideString csJS;
2297
2298					CPDF_Object* pJS = pJSDict->GetElementValue("Before");
2299					if (pJS != NULL)
2300					{
2301						int iType = pJS->GetType();
2302						if (iType == PDFOBJ_STRING)
2303							csJS = pJSDict->GetUnicodeText("Before");
2304						else if (iType == PDFOBJ_STREAM)
2305							csJS = pJS->GetUnicodeText();
2306					}
2307
2308				}
2309			}
2310		}
2311		delete pFDFDocument;
2312	}
2313
2314	sBuffer.ReleaseBuffer();
2315}
2316
2317FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile, CFX_WideString csTxtFile)
2318{
2319	return TRUE;
2320}
2321
2322FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(FX_LPBYTE& pBuf, FX_STRSIZE& nBufSize)
2323{
2324 	CFDF_Document* pFDF = CFDF_Document::ParseMemory(pBuf, nBufSize);
2325 	if (pFDF)
2326 	{
2327 		CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
2328 		if (pMainDict == NULL) return FALSE;
2329
2330 		// Get fields
2331 		CPDF_Array* pFields = pMainDict->GetArray("Fields");
2332 		if (pFields == NULL) return FALSE;
2333
2334		CFX_ByteTextBuf fdfEncodedData;
2335
2336 		for (FX_DWORD i = 0; i < pFields->GetCount(); i ++)
2337 		{
2338 			CPDF_Dictionary* pField = pFields->GetDict(i);
2339 			if (pField == NULL) continue;
2340 			CFX_WideString name;
2341 			name = pField->GetUnicodeText("T");
2342 			CFX_ByteString name_b = CFX_ByteString::FromUnicode(name);
2343 			CFX_ByteString csBValue = pField->GetString("V");
2344 			CFX_WideString csWValue = PDF_DecodeText(csBValue);
2345 			CFX_ByteString csValue_b = CFX_ByteString::FromUnicode(csWValue);
2346
2347			fdfEncodedData = fdfEncodedData<<name_b.GetBuffer(name_b.GetLength());
2348  			name_b.ReleaseBuffer();
2349			fdfEncodedData = fdfEncodedData<<"=";
2350			fdfEncodedData = fdfEncodedData<<csValue_b.GetBuffer(csValue_b.GetLength());
2351  			csValue_b.ReleaseBuffer();
2352  			if(i != pFields->GetCount()-1)
2353  				fdfEncodedData = fdfEncodedData<<"&";
2354 		}
2355
2356		nBufSize = fdfEncodedData.GetLength();
2357		pBuf = FX_Alloc(FX_BYTE, nBufSize);
2358		FXSYS_memcpy(pBuf, fdfEncodedData.GetBuffer(), nBufSize);
2359 	}
2360	return TRUE;
2361}
2362
2363FX_BOOL CPDFSDK_InterForm::ExportFieldsToFDFTextBuf(const CFX_PtrArray& fields,FX_BOOL bIncludeOrExclude, CFX_ByteTextBuf& textBuf)
2364{
2365	ASSERT(m_pDocument != NULL);
2366	ASSERT(m_pInterForm != NULL);
2367
2368	CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath(),(CFX_PtrArray&)fields, bIncludeOrExclude);
2369	if (!pFDF) return FALSE;
2370	FX_BOOL bRet = pFDF->WriteBuf(textBuf); // = FALSE;//
2371	delete pFDF;
2372
2373	return bRet;
2374}
2375
2376CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(const CFX_WideString& sFileExt)
2377{
2378	CFX_WideString sFileName;
2379	return L"";
2380}
2381
2382FX_BOOL CPDFSDK_InterForm::SubmitForm(const CFX_WideString& sDestination, FX_BOOL bUrlEncoded)
2383{
2384 	if (sDestination.IsEmpty()) return FALSE;
2385
2386	CPDFDoc_Environment* pEnv = m_pDocument->GetEnv();
2387	ASSERT(pEnv != NULL);
2388
2389	if(NULL == m_pDocument) return FALSE;
2390	CFX_WideString wsPDFFilePath = m_pDocument->GetPath();
2391
2392	if(NULL == m_pInterForm) return FALSE;
2393	CFDF_Document* pFDFDoc = m_pInterForm->ExportToFDF(wsPDFFilePath);
2394	if (NULL == pFDFDoc) return FALSE;
2395
2396	CFX_ByteTextBuf FdfBuffer;
2397	FX_BOOL bRet = pFDFDoc->WriteBuf(FdfBuffer);
2398	delete pFDFDoc;
2399	if (!bRet) return FALSE;
2400
2401	FX_LPBYTE pBuffer = FdfBuffer.GetBuffer();
2402	FX_STRSIZE nBufSize = FdfBuffer.GetLength();
2403
2404	if (bUrlEncoded)
2405	{
2406		if(!FDFToURLEncodedData(pBuffer, nBufSize))
2407			return FALSE;
2408	}
2409
2410	pEnv->JS_docSubmitForm(pBuffer, nBufSize, sDestination.c_str());
2411
2412	if (bUrlEncoded && pBuffer)
2413	{
2414		FX_Free(pBuffer);
2415		pBuffer = NULL;
2416	}
2417
2418	return TRUE;
2419}
2420
2421FX_BOOL CPDFSDK_InterForm::ExportFormToFDFTextBuf(CFX_ByteTextBuf& textBuf)
2422{
2423
2424	ASSERT(m_pInterForm != NULL);
2425	ASSERT(m_pDocument != NULL);
2426
2427	CFDF_Document* pFDF = m_pInterForm->ExportToFDF(m_pDocument->GetPath());
2428	if (!pFDF) return FALSE;
2429
2430	FX_BOOL bRet = pFDF->WriteBuf(textBuf);
2431	delete pFDF;
2432
2433	return bRet;
2434}
2435
2436
2437FX_BOOL CPDFSDK_InterForm::DoAction_ResetForm(const CPDF_Action& action)
2438{
2439	ASSERT(action);
2440
2441	CPDF_Dictionary* pActionDict = action.GetDict();
2442	if (pActionDict->KeyExist("Fields"))
2443	{
2444		CPDF_ActionFields af = action.GetWidgets();
2445		FX_DWORD dwFlags = action.GetFlags();
2446
2447		CFX_PtrArray fieldObjects;
2448		af.GetAllFields(fieldObjects);
2449		CFX_PtrArray fields;
2450		GetFieldFromObjects(fieldObjects, fields);
2451		return m_pInterForm->ResetForm(fields, !(dwFlags & 0x01), TRUE);
2452	}
2453
2454	return m_pInterForm->ResetForm(TRUE);
2455}
2456
2457FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action)
2458{
2459	return FALSE;
2460}
2461
2462void CPDFSDK_InterForm::GetFieldFromObjects(const CFX_PtrArray& objects, CFX_PtrArray& fields)
2463{
2464	ASSERT(m_pInterForm != NULL);
2465
2466	int iCount = objects.GetSize();
2467	for (int i = 0; i < iCount; i ++)
2468	{
2469		CPDF_Object* pObject = (CPDF_Object*)objects[i];
2470		if (pObject == NULL) continue;
2471
2472		int iType = pObject->GetType();
2473		if (iType == PDFOBJ_STRING)
2474		{
2475			CFX_WideString csName = pObject->GetUnicodeText();
2476			CPDF_FormField* pField = m_pInterForm->GetField(0, csName);
2477			if (pField != NULL)
2478				fields.Add(pField);
2479		}
2480		else if (iType == PDFOBJ_DICTIONARY)
2481		{
2482			if (m_pInterForm->IsValidFormField(pObject))
2483				fields.Add(pObject);
2484		}
2485	}
2486}
2487
2488/* ----------------------------- CPDF_FormNotify ----------------------------- */
2489
2490int	CPDFSDK_InterForm::BeforeValueChange(const CPDF_FormField* pField, CFX_WideString& csValue)
2491{
2492	ASSERT(pField != NULL);
2493
2494	CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2495
2496	int nType = pFormField->GetFieldType();
2497	if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
2498	{
2499		FX_BOOL bRC = TRUE;
2500		OnKeyStrokeCommit(pFormField, csValue, bRC);
2501		if (bRC)
2502		{
2503			OnValidate(pFormField, csValue, bRC);
2504			if (bRC)
2505				return 1;
2506			else
2507				return -1;
2508		}
2509		else
2510			return -1;
2511	}
2512	else
2513		return 0;
2514}
2515
2516int	CPDFSDK_InterForm::AfterValueChange(const CPDF_FormField* pField)
2517{
2518	ASSERT(pField != NULL);
2519
2520	CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2521	int nType = pFormField->GetFieldType();
2522
2523	if (nType == FIELDTYPE_COMBOBOX || nType == FIELDTYPE_TEXTFIELD)
2524	{
2525		this->OnCalculate(pFormField);
2526		FX_BOOL bFormated = FALSE;
2527		CFX_WideString sValue = this->OnFormat(pFormField, 0, bFormated);
2528		if (bFormated)
2529			this->ResetFieldAppearance(pFormField, sValue.c_str(), TRUE);
2530		else
2531			this->ResetFieldAppearance(pFormField, NULL, TRUE);
2532		this->UpdateField(pFormField);
2533	}
2534
2535	return 0;
2536}
2537
2538int	CPDFSDK_InterForm::BeforeSelectionChange(const CPDF_FormField* pField, CFX_WideString& csValue)
2539{
2540	ASSERT(pField != NULL);
2541
2542	CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2543
2544	int nType = pFormField->GetFieldType();
2545	if (nType == FIELDTYPE_LISTBOX)
2546	{
2547		FX_BOOL bRC = TRUE;
2548		OnKeyStrokeCommit(pFormField, csValue, bRC);
2549		if (bRC)
2550		{
2551			OnValidate(pFormField, csValue, bRC);
2552			if (bRC)
2553				return 1;
2554			else
2555				return -1;
2556		}
2557		else
2558			return -1;
2559	}
2560	else
2561		return 0;
2562}
2563
2564int	CPDFSDK_InterForm::AfterSelectionChange(const CPDF_FormField* pField)
2565{
2566	ASSERT(pField != NULL);
2567
2568	CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2569	int nType = pFormField->GetFieldType();
2570
2571	if (nType == FIELDTYPE_LISTBOX)
2572	{
2573		this->OnCalculate(pFormField);
2574		this->ResetFieldAppearance(pFormField, NULL, TRUE);
2575		this->UpdateField(pFormField);
2576	}
2577
2578	return 0;
2579}
2580
2581int	CPDFSDK_InterForm::AfterCheckedStatusChange(const CPDF_FormField* pField, const CFX_ByteArray& statusArray)
2582{
2583	ASSERT(pField != NULL);
2584
2585	CPDF_FormField* pFormField = (CPDF_FormField*)pField;
2586	int nType = pFormField->GetFieldType();
2587
2588	if (nType == FIELDTYPE_CHECKBOX || nType == FIELDTYPE_RADIOBUTTON)
2589	{
2590		this->OnCalculate(pFormField);
2591		//this->ResetFieldAppearance(pFormField, NULL);
2592		this->UpdateField(pFormField);
2593	}
2594
2595	return 0;
2596}
2597
2598int	CPDFSDK_InterForm::BeforeFormReset(const CPDF_InterForm* pForm)
2599{
2600	return 0;
2601}
2602
2603int	CPDFSDK_InterForm::AfterFormReset(const CPDF_InterForm* pForm)
2604{
2605	this->OnCalculate(NULL);
2606
2607	return 0;
2608}
2609
2610int	CPDFSDK_InterForm::BeforeFormImportData(const CPDF_InterForm* pForm)
2611{
2612	return 0;
2613}
2614
2615int	CPDFSDK_InterForm::AfterFormImportData(const CPDF_InterForm* pForm)
2616{
2617	this->OnCalculate(NULL);
2618
2619	return 0;
2620}
2621
2622FX_BOOL CPDFSDK_InterForm::IsNeedHighLight(int nFieldType)
2623{
2624	if(nFieldType <1 || nFieldType > 6)
2625		return FALSE;
2626	return m_bNeedHightlight[nFieldType-1];
2627}
2628
2629void CPDFSDK_InterForm::RemoveAllHighLight()
2630{
2631	memset((void*)m_bNeedHightlight, 0, 6*sizeof(FX_BOOL));
2632}
2633void   CPDFSDK_InterForm::SetHighlightColor(FX_COLORREF clr, int nFieldType)
2634{
2635	if(nFieldType <0 || nFieldType > 6) return;
2636	switch(nFieldType)
2637	{
2638	case 0:
2639		{
2640			for(int i=0; i<6; i++)
2641			{
2642				m_aHighlightColor[i] = clr;
2643				m_bNeedHightlight[i] = TRUE;
2644			}
2645			break;
2646		}
2647	default:
2648		{
2649			m_aHighlightColor[nFieldType-1] = clr;
2650			m_bNeedHightlight[nFieldType-1] = TRUE;
2651			break;
2652		}
2653	}
2654
2655}
2656
2657FX_COLORREF CPDFSDK_InterForm::GetHighlightColor(int nFieldType)
2658{
2659	if(nFieldType <0 || nFieldType >6) return FXSYS_RGB(255,255,255);
2660	if(nFieldType == 0)
2661		return m_aHighlightColor[0];
2662	else
2663		return m_aHighlightColor[nFieldType-1];
2664}
2665
2666/* ------------------------- CBA_AnnotIterator ------------------------- */
2667
2668CBA_AnnotIterator::CBA_AnnotIterator(CPDFSDK_PageView* pPageView, const CFX_ByteString& sType, const CFX_ByteString& sSubType)
2669	:m_pPageView(pPageView),
2670	m_sType(sType),
2671	m_sSubType(sSubType),
2672	m_nTabs(BAI_STRUCTURE)
2673{
2674	ASSERT(m_pPageView != NULL);
2675
2676	CPDF_Page* pPDFPage = m_pPageView->GetPDFPage();
2677	ASSERT(pPDFPage != NULL);
2678	ASSERT(pPDFPage->m_pFormDict != NULL);
2679
2680	CFX_ByteString sTabs = pPDFPage->m_pFormDict->GetString("Tabs");
2681
2682	if (sTabs == "R")
2683	{
2684		m_nTabs = BAI_ROW;
2685	}
2686	else if (sTabs == "C")
2687	{
2688		m_nTabs = BAI_COLUMN;
2689	}
2690	else
2691	{
2692		m_nTabs = BAI_STRUCTURE;
2693	}
2694
2695	GenerateResults();
2696}
2697
2698CBA_AnnotIterator::~CBA_AnnotIterator()
2699{
2700	m_Annots.RemoveAll();
2701}
2702
2703CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot()
2704{
2705	if (m_Annots.GetSize() > 0)
2706		return m_Annots[0];
2707
2708	return NULL;
2709}
2710
2711CPDFSDK_Annot* CBA_AnnotIterator::GetLastAnnot()
2712{
2713	if (m_Annots.GetSize() > 0)
2714		return m_Annots[m_Annots.GetSize() - 1];
2715
2716	return NULL;
2717}
2718
2719CPDFSDK_Annot* CBA_AnnotIterator::GetNextAnnot(CPDFSDK_Annot* pAnnot)
2720{
2721	for (int i=0,sz=m_Annots.GetSize(); i<sz; i++)
2722	{
2723		if (m_Annots[i] == pAnnot)
2724		{
2725			if (i+1 < sz)
2726				return m_Annots[i+1];
2727			else
2728				return m_Annots[0];
2729		}
2730	}
2731
2732	return NULL;
2733}
2734
2735CPDFSDK_Annot* CBA_AnnotIterator::GetPrevAnnot(CPDFSDK_Annot* pAnnot)
2736{
2737	for (int i=0,sz=m_Annots.GetSize(); i<sz; i++)
2738	{
2739		if (m_Annots[i] == pAnnot)
2740		{
2741			if (i-1 >= 0)
2742				return m_Annots[i-1];
2743			else
2744				return m_Annots[sz-1];
2745		}
2746	}
2747
2748	return NULL;
2749}
2750
2751int CBA_AnnotIterator::CompareByLeft(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2)
2752{
2753	ASSERT(p1 != NULL);
2754	ASSERT(p2 != NULL);
2755
2756	CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
2757	CPDF_Rect rcAnnot2 = GetAnnotRect(p2);
2758
2759	if (rcAnnot1.left < rcAnnot2.left)
2760		return -1;
2761	if (rcAnnot1.left > rcAnnot2.left)
2762		return 1;
2763	return 0;
2764}
2765
2766
2767int CBA_AnnotIterator::CompareByTop(CPDFSDK_Annot* p1, CPDFSDK_Annot* p2)
2768{
2769	ASSERT(p1 != NULL);
2770	ASSERT(p2 != NULL);
2771
2772	CPDF_Rect rcAnnot1 = GetAnnotRect(p1);
2773	CPDF_Rect rcAnnot2 = GetAnnotRect(p2);
2774
2775	if (rcAnnot1.top < rcAnnot2.top)
2776		return -1;
2777	if (rcAnnot1.top > rcAnnot2.top)
2778		return 1;
2779	return 0;
2780}
2781
2782void CBA_AnnotIterator::GenerateResults()
2783{
2784	ASSERT(m_pPageView != NULL);
2785
2786	switch (m_nTabs)
2787	{
2788	case BAI_STRUCTURE:
2789		{
2790			for (int i=0,sz=m_pPageView->CountAnnots(); i<sz; i++)
2791			{
2792				CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2793				ASSERT(pAnnot != NULL);
2794
2795				if (pAnnot->GetType() == m_sType
2796					&& pAnnot->GetSubType() == m_sSubType)
2797					m_Annots.Add(pAnnot);
2798			}
2799		}
2800		break;
2801	case BAI_ROW:
2802		{
2803			CPDFSDK_SortAnnots sa;
2804
2805			{
2806
2807				for (int i=0,sz=m_pPageView->CountAnnots(); i<sz; i++)
2808				{
2809					CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2810					ASSERT(pAnnot != NULL);
2811
2812					if (pAnnot->GetType() == m_sType
2813						&& pAnnot->GetSubType() == m_sSubType)
2814						sa.Add(pAnnot);
2815				}
2816			}
2817
2818			if (sa.GetSize() > 0)
2819			{
2820				sa.Sort(CBA_AnnotIterator::CompareByLeft);
2821			}
2822
2823			while (sa.GetSize() > 0)
2824			{
2825				int nLeftTopIndex = -1;
2826
2827				{
2828					FX_FLOAT fTop = 0.0f;
2829
2830					for (int i=sa.GetSize()-1; i>=0; i--)
2831					{
2832						CPDFSDK_Annot* pAnnot = sa.GetAt(i);
2833						ASSERT(pAnnot != NULL);
2834
2835						CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
2836
2837						if (rcAnnot.top > fTop)
2838						{
2839							nLeftTopIndex = i;
2840							fTop = rcAnnot.top;
2841						}
2842					}
2843				}
2844
2845				if (nLeftTopIndex >= 0)
2846				{
2847					CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
2848					ASSERT(pLeftTopAnnot != NULL);
2849
2850					CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
2851
2852					m_Annots.Add(pLeftTopAnnot);
2853					sa.RemoveAt(nLeftTopIndex);
2854
2855					CFX_ArrayTemplate<int> aSelect;
2856
2857					{
2858						for (int i=0,sz=sa.GetSize(); i<sz; i++)
2859						{
2860							CPDFSDK_Annot* pAnnot = sa.GetAt(i);
2861							ASSERT(pAnnot != NULL);
2862
2863							CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
2864
2865							FX_FLOAT fCenterY = (rcAnnot.top + rcAnnot.bottom) / 2.0f;
2866
2867							if (fCenterY > rcLeftTop.bottom && fCenterY < rcLeftTop.top)
2868								aSelect.Add(i);
2869						}
2870					}
2871
2872					{
2873						for (int i=0,sz=aSelect.GetSize(); i<sz; i++)
2874						{
2875							m_Annots.Add(sa[aSelect[i]]);
2876						}
2877					}
2878
2879					{
2880						for (int i=aSelect.GetSize()-1; i>=0; i--)
2881						{
2882							sa.RemoveAt(aSelect[i]);
2883						}
2884					}
2885
2886					aSelect.RemoveAll();
2887				}
2888			}
2889			sa.RemoveAll();
2890		}
2891		break;
2892	case BAI_COLUMN:
2893		{
2894			CPDFSDK_SortAnnots sa;
2895
2896			{
2897				for (int i=0,sz=m_pPageView->CountAnnots(); i<sz; i++)
2898				{
2899					CPDFSDK_Annot* pAnnot = m_pPageView->GetAnnot(i);
2900					ASSERT(pAnnot != NULL);
2901
2902					if (pAnnot->GetType() == m_sType
2903						&& pAnnot->GetSubType() == m_sSubType)
2904						sa.Add(pAnnot);
2905				}
2906			}
2907
2908			if (sa.GetSize() > 0)
2909			{
2910				sa.Sort(CBA_AnnotIterator::CompareByTop, FALSE);
2911			}
2912
2913			while (sa.GetSize() > 0)
2914			{
2915				int nLeftTopIndex = -1;
2916
2917				{
2918					FX_FLOAT fLeft = -1.0f;
2919
2920					for (int i=sa.GetSize()-1; i>=0; i--)
2921					{
2922						CPDFSDK_Annot* pAnnot = sa.GetAt(i);
2923						ASSERT(pAnnot != NULL);
2924
2925						CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
2926
2927						if (fLeft < 0)
2928						{
2929							nLeftTopIndex = 0;
2930							fLeft = rcAnnot.left;
2931						}
2932						else if (rcAnnot.left < fLeft)
2933						{
2934							nLeftTopIndex = i;
2935							fLeft = rcAnnot.left;
2936						}
2937					}
2938				}
2939
2940				if (nLeftTopIndex >= 0)
2941				{
2942					CPDFSDK_Annot* pLeftTopAnnot = sa.GetAt(nLeftTopIndex);
2943					ASSERT(pLeftTopAnnot != NULL);
2944
2945					CPDF_Rect rcLeftTop = GetAnnotRect(pLeftTopAnnot);
2946
2947					m_Annots.Add(pLeftTopAnnot);
2948					sa.RemoveAt(nLeftTopIndex);
2949
2950					CFX_ArrayTemplate<int> aSelect;
2951
2952					{
2953						for (int i=0,sz=sa.GetSize(); i<sz; i++)
2954						{
2955							CPDFSDK_Annot* pAnnot = sa.GetAt(i);
2956							ASSERT(pAnnot != NULL);
2957
2958							CPDF_Rect rcAnnot = GetAnnotRect(pAnnot);
2959
2960							FX_FLOAT fCenterX = (rcAnnot.left + rcAnnot.right) / 2.0f;
2961
2962							if (fCenterX > rcLeftTop.left && fCenterX < rcLeftTop.right)
2963								aSelect.Add(i);
2964						}
2965					}
2966
2967					{
2968						for (int i=0,sz=aSelect.GetSize(); i<sz; i++)
2969						{
2970							m_Annots.Add(sa[aSelect[i]]);
2971						}
2972					}
2973
2974					{
2975						for (int i=aSelect.GetSize()-1; i>=0; i--)
2976						{
2977							sa.RemoveAt(aSelect[i]);
2978						}
2979					}
2980
2981					aSelect.RemoveAll();
2982				}
2983			}
2984			sa.RemoveAll();
2985		}
2986		break;
2987	}
2988}
2989
2990CPDF_Rect CBA_AnnotIterator::GetAnnotRect(CPDFSDK_Annot* pAnnot)
2991{
2992	ASSERT(pAnnot != NULL);
2993
2994	CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
2995	ASSERT(pPDFAnnot != NULL);
2996
2997	CPDF_Rect rcAnnot;
2998	pPDFAnnot->GetRect(rcAnnot);
2999
3000	return rcAnnot;
3001}
3002
3003