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