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