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