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