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