1 // Copyright 2016 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/cpdfsdk_widget.h"
8
9 #include <memory>
10
11 #include "core/fpdfapi/parser/cpdf_array.h"
12 #include "core/fpdfapi/parser/cpdf_dictionary.h"
13 #include "core/fpdfapi/parser/cpdf_document.h"
14 #include "core/fpdfapi/parser/cpdf_reference.h"
15 #include "core/fpdfapi/parser/cpdf_stream.h"
16 #include "core/fpdfapi/parser/cpdf_string.h"
17 #include "core/fpdfdoc/cpdf_defaultappearance.h"
18 #include "core/fpdfdoc/cpdf_formcontrol.h"
19 #include "core/fpdfdoc/cpdf_formfield.h"
20 #include "core/fpdfdoc/cpdf_iconfit.h"
21 #include "core/fpdfdoc/cpdf_interform.h"
22 #include "core/fxge/cfx_graphstatedata.h"
23 #include "core/fxge/cfx_pathdata.h"
24 #include "core/fxge/cfx_renderdevice.h"
25 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
26 #include "fpdfsdk/cpdfsdk_interform.h"
27 #include "fpdfsdk/cpdfsdk_pageview.h"
28 #include "fpdfsdk/formfiller/cba_fontmap.h"
29 #include "fpdfsdk/fsdk_actionhandler.h"
30 #include "fpdfsdk/fsdk_define.h"
31 #include "fpdfsdk/fxedit/fxet_edit.h"
32 #include "fpdfsdk/pdfwindow/PWL_Edit.h"
33 #include "fpdfsdk/pdfwindow/PWL_Utils.h"
34
35 #ifdef PDF_ENABLE_XFA
36 #include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
37 #include "xfa/fxfa/cxfa_eventparam.h"
38 #include "xfa/fxfa/fxfa_widget.h"
39 #include "xfa/fxfa/xfa_ffdocview.h"
40 #include "xfa/fxfa/xfa_ffwidget.h"
41 #include "xfa/fxfa/xfa_ffwidgethandler.h"
42 #endif // PDF_ENABLE_XFA
43
44 namespace {
45
46 // Convert a FX_ARGB to a FX_COLORREF.
ARGBToColorRef(FX_ARGB argb)47 FX_COLORREF ARGBToColorRef(FX_ARGB argb) {
48 return (((static_cast<uint32_t>(argb) & 0x00FF0000) >> 16) |
49 (static_cast<uint32_t>(argb) & 0x0000FF00) |
50 ((static_cast<uint32_t>(argb) & 0x000000FF) << 16));
51 }
52
53 } // namespace
54
CPDFSDK_Widget(CPDF_Annot * pAnnot,CPDFSDK_PageView * pPageView,CPDFSDK_InterForm * pInterForm)55 CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot,
56 CPDFSDK_PageView* pPageView,
57 CPDFSDK_InterForm* pInterForm)
58 : CPDFSDK_BAAnnot(pAnnot, pPageView),
59 m_pInterForm(pInterForm),
60 m_nAppAge(0),
61 m_nValueAge(0)
62 #ifdef PDF_ENABLE_XFA
63 ,
64 m_hMixXFAWidget(nullptr),
65 m_pWidgetHandler(nullptr)
66 #endif // PDF_ENABLE_XFA
67 {
68 }
69
~CPDFSDK_Widget()70 CPDFSDK_Widget::~CPDFSDK_Widget() {}
71
72 #ifdef PDF_ENABLE_XFA
GetMixXFAWidget() const73 CXFA_FFWidget* CPDFSDK_Widget::GetMixXFAWidget() const {
74 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
75 if (pContext->GetDocType() == DOCTYPE_STATIC_XFA) {
76 if (!m_hMixXFAWidget) {
77 if (CXFA_FFDocView* pDocView = pContext->GetXFADocView()) {
78 CFX_WideString sName;
79 if (GetFieldType() == FIELDTYPE_RADIOBUTTON) {
80 sName = GetAnnotName();
81 if (sName.IsEmpty())
82 sName = GetName();
83 } else {
84 sName = GetName();
85 }
86
87 if (!sName.IsEmpty())
88 m_hMixXFAWidget = pDocView->GetWidgetByName(sName, nullptr);
89 }
90 }
91 return m_hMixXFAWidget;
92 }
93
94 return nullptr;
95 }
96
GetGroupMixXFAWidget()97 CXFA_FFWidget* CPDFSDK_Widget::GetGroupMixXFAWidget() {
98 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
99 if (pContext->GetDocType() == DOCTYPE_STATIC_XFA) {
100 if (CXFA_FFDocView* pDocView = pContext->GetXFADocView()) {
101 CFX_WideString sName = GetName();
102 if (!sName.IsEmpty())
103 return pDocView->GetWidgetByName(sName, nullptr);
104 }
105 }
106
107 return nullptr;
108 }
109
GetXFAWidgetHandler() const110 CXFA_FFWidgetHandler* CPDFSDK_Widget::GetXFAWidgetHandler() const {
111 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
112 if (pContext->GetDocType() == DOCTYPE_STATIC_XFA) {
113 if (!m_pWidgetHandler) {
114 if (CXFA_FFDocView* pDocView = pContext->GetXFADocView())
115 m_pWidgetHandler = pDocView->GetWidgetHandler();
116 }
117 return m_pWidgetHandler;
118 }
119
120 return nullptr;
121 }
122
GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT)123 static XFA_EVENTTYPE GetXFAEventType(PDFSDK_XFAAActionType eXFAAAT) {
124 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
125
126 switch (eXFAAAT) {
127 case PDFSDK_XFA_Click:
128 eEventType = XFA_EVENT_Click;
129 break;
130 case PDFSDK_XFA_Full:
131 eEventType = XFA_EVENT_Full;
132 break;
133 case PDFSDK_XFA_PreOpen:
134 eEventType = XFA_EVENT_PreOpen;
135 break;
136 case PDFSDK_XFA_PostOpen:
137 eEventType = XFA_EVENT_PostOpen;
138 break;
139 }
140
141 return eEventType;
142 }
143
GetXFAEventType(CPDF_AAction::AActionType eAAT,bool bWillCommit)144 static XFA_EVENTTYPE GetXFAEventType(CPDF_AAction::AActionType eAAT,
145 bool bWillCommit) {
146 XFA_EVENTTYPE eEventType = XFA_EVENT_Unknown;
147
148 switch (eAAT) {
149 case CPDF_AAction::CursorEnter:
150 eEventType = XFA_EVENT_MouseEnter;
151 break;
152 case CPDF_AAction::CursorExit:
153 eEventType = XFA_EVENT_MouseExit;
154 break;
155 case CPDF_AAction::ButtonDown:
156 eEventType = XFA_EVENT_MouseDown;
157 break;
158 case CPDF_AAction::ButtonUp:
159 eEventType = XFA_EVENT_MouseUp;
160 break;
161 case CPDF_AAction::GetFocus:
162 eEventType = XFA_EVENT_Enter;
163 break;
164 case CPDF_AAction::LoseFocus:
165 eEventType = XFA_EVENT_Exit;
166 break;
167 case CPDF_AAction::PageOpen:
168 break;
169 case CPDF_AAction::PageClose:
170 break;
171 case CPDF_AAction::PageVisible:
172 break;
173 case CPDF_AAction::PageInvisible:
174 break;
175 case CPDF_AAction::KeyStroke:
176 if (!bWillCommit)
177 eEventType = XFA_EVENT_Change;
178 break;
179 case CPDF_AAction::Validate:
180 eEventType = XFA_EVENT_Validate;
181 break;
182 case CPDF_AAction::OpenPage:
183 case CPDF_AAction::ClosePage:
184 case CPDF_AAction::Format:
185 case CPDF_AAction::Calculate:
186 case CPDF_AAction::CloseDocument:
187 case CPDF_AAction::SaveDocument:
188 case CPDF_AAction::DocumentSaved:
189 case CPDF_AAction::PrintDocument:
190 case CPDF_AAction::DocumentPrinted:
191 break;
192 }
193
194 return eEventType;
195 }
196
HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT)197 bool CPDFSDK_Widget::HasXFAAAction(PDFSDK_XFAAActionType eXFAAAT) {
198 CXFA_FFWidget* hWidget = GetMixXFAWidget();
199 if (!hWidget)
200 return false;
201
202 CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
203 if (!pXFAWidgetHandler)
204 return false;
205
206 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
207
208 CXFA_WidgetAcc* pAcc;
209 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
210 GetFieldType() == FIELDTYPE_RADIOBUTTON) {
211 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
212 pAcc = hGroupWidget->GetDataAcc();
213 if (pXFAWidgetHandler->HasEvent(pAcc, eEventType))
214 return true;
215 }
216 }
217
218 pAcc = hWidget->GetDataAcc();
219 return pXFAWidgetHandler->HasEvent(pAcc, eEventType);
220 }
221
OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,PDFSDK_FieldAction & data,CPDFSDK_PageView * pPageView)222 bool CPDFSDK_Widget::OnXFAAAction(PDFSDK_XFAAActionType eXFAAAT,
223 PDFSDK_FieldAction& data,
224 CPDFSDK_PageView* pPageView) {
225 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
226
227 CXFA_FFWidget* hWidget = GetMixXFAWidget();
228 if (!hWidget)
229 return false;
230
231 XFA_EVENTTYPE eEventType = GetXFAEventType(eXFAAAT);
232 if (eEventType == XFA_EVENT_Unknown)
233 return false;
234
235 CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler();
236 if (!pXFAWidgetHandler)
237 return false;
238
239 CXFA_EventParam param;
240 param.m_eType = eEventType;
241 param.m_wsChange = data.sChange;
242 param.m_iCommitKey = data.nCommitKey;
243 param.m_bShift = data.bShift;
244 param.m_iSelStart = data.nSelStart;
245 param.m_iSelEnd = data.nSelEnd;
246 param.m_wsFullText = data.sValue;
247 param.m_bKeyDown = data.bKeyDown;
248 param.m_bModifier = data.bModifier;
249 param.m_wsNewText = data.sValue;
250 if (data.nSelEnd > data.nSelStart)
251 param.m_wsNewText.Delete(data.nSelStart, data.nSelEnd - data.nSelStart);
252
253 for (int i = 0; i < data.sChange.GetLength(); i++)
254 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
255 param.m_wsPrevText = data.sValue;
256
257 if ((eEventType == XFA_EVENT_Click || eEventType == XFA_EVENT_Change) &&
258 GetFieldType() == FIELDTYPE_RADIOBUTTON) {
259 if (CXFA_FFWidget* hGroupWidget = GetGroupMixXFAWidget()) {
260 CXFA_WidgetAcc* pAcc = hGroupWidget->GetDataAcc();
261 param.m_pTarget = pAcc;
262 if (pXFAWidgetHandler->ProcessEvent(pAcc, ¶m) !=
263 XFA_EVENTERROR_Success) {
264 return false;
265 }
266 }
267 }
268 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc();
269 param.m_pTarget = pAcc;
270 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m);
271
272 if (CXFA_FFDocView* pDocView = pContext->GetXFADocView())
273 pDocView->UpdateDocView();
274
275 return nRet == XFA_EVENTERROR_Success;
276 }
277
Synchronize(bool bSynchronizeElse)278 void CPDFSDK_Widget::Synchronize(bool bSynchronizeElse) {
279 CXFA_FFWidget* hWidget = GetMixXFAWidget();
280 if (!hWidget)
281 return;
282
283 CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc();
284 if (!pWidgetAcc)
285 return;
286
287 CPDF_FormField* pFormField = GetFormField();
288 switch (GetFieldType()) {
289 case FIELDTYPE_CHECKBOX:
290 case FIELDTYPE_RADIOBUTTON: {
291 CPDF_FormControl* pFormCtrl = GetFormControl();
292 XFA_CHECKSTATE eCheckState =
293 pFormCtrl->IsChecked() ? XFA_CHECKSTATE_On : XFA_CHECKSTATE_Off;
294 pWidgetAcc->SetCheckState(eCheckState, true);
295 break;
296 }
297 case FIELDTYPE_TEXTFIELD:
298 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
299 break;
300 case FIELDTYPE_LISTBOX: {
301 pWidgetAcc->ClearAllSelections();
302
303 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
304 int nIndex = pFormField->GetSelectedIndex(i);
305 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
306 pWidgetAcc->SetItemState(nIndex, true, false, false, true);
307 }
308 break;
309 }
310 case FIELDTYPE_COMBOBOX: {
311 pWidgetAcc->ClearAllSelections();
312
313 for (int i = 0, sz = pFormField->CountSelectedItems(); i < sz; i++) {
314 int nIndex = pFormField->GetSelectedIndex(i);
315 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
316 pWidgetAcc->SetItemState(nIndex, true, false, false, true);
317 }
318 pWidgetAcc->SetValue(pFormField->GetValue(), XFA_VALUEPICTURE_Edit);
319 break;
320 }
321 }
322
323 if (bSynchronizeElse)
324 pWidgetAcc->ProcessValueChanged();
325 }
326
SynchronizeXFAValue()327 void CPDFSDK_Widget::SynchronizeXFAValue() {
328 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
329 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
330 if (!pXFADocView)
331 return;
332
333 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
334 if (GetXFAWidgetHandler()) {
335 CPDFSDK_Widget::SynchronizeXFAValue(pXFADocView, hWidget, GetFormField(),
336 GetFormControl());
337 }
338 }
339 }
340
SynchronizeXFAItems()341 void CPDFSDK_Widget::SynchronizeXFAItems() {
342 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
343 CXFA_FFDocView* pXFADocView = pContext->GetXFADocView();
344 if (!pXFADocView)
345 return;
346
347 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
348 if (GetXFAWidgetHandler())
349 SynchronizeXFAItems(pXFADocView, hWidget, GetFormField(), nullptr);
350 }
351 }
352
SynchronizeXFAValue(CXFA_FFDocView * pXFADocView,CXFA_FFWidget * hWidget,CPDF_FormField * pFormField,CPDF_FormControl * pFormControl)353 void CPDFSDK_Widget::SynchronizeXFAValue(CXFA_FFDocView* pXFADocView,
354 CXFA_FFWidget* hWidget,
355 CPDF_FormField* pFormField,
356 CPDF_FormControl* pFormControl) {
357 ASSERT(hWidget);
358 ASSERT(pFormControl);
359
360 switch (pFormField->GetFieldType()) {
361 case FIELDTYPE_CHECKBOX: {
362 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
363 pFormField->CheckControl(
364 pFormField->GetControlIndex(pFormControl),
365 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
366 }
367 break;
368 }
369 case FIELDTYPE_RADIOBUTTON: {
370 // TODO(weili): Check whether we need to handle checkbox and radio
371 // button differently, otherwise, merge these two cases.
372 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
373 pFormField->CheckControl(
374 pFormField->GetControlIndex(pFormControl),
375 pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On, true);
376 }
377 break;
378 }
379 case FIELDTYPE_TEXTFIELD: {
380 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
381 CFX_WideString sValue;
382 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
383 pFormField->SetValue(sValue, true);
384 }
385 break;
386 }
387 case FIELDTYPE_LISTBOX: {
388 pFormField->ClearSelection(false);
389
390 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
391 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
392 int nIndex = pWidgetAcc->GetSelectedItem(i);
393
394 if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
395 pFormField->SetItemSelection(nIndex, true, true);
396 }
397 }
398 }
399 break;
400 }
401 case FIELDTYPE_COMBOBOX: {
402 pFormField->ClearSelection(false);
403
404 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
405 for (int i = 0, sz = pWidgetAcc->CountSelectedItems(); i < sz; i++) {
406 int nIndex = pWidgetAcc->GetSelectedItem(i);
407
408 if (nIndex > -1 && nIndex < pFormField->CountOptions()) {
409 pFormField->SetItemSelection(nIndex, true, true);
410 }
411 }
412
413 CFX_WideString sValue;
414 pWidgetAcc->GetValue(sValue, XFA_VALUEPICTURE_Display);
415 pFormField->SetValue(sValue, true);
416 }
417 break;
418 }
419 }
420 }
421
SynchronizeXFAItems(CXFA_FFDocView * pXFADocView,CXFA_FFWidget * hWidget,CPDF_FormField * pFormField,CPDF_FormControl * pFormControl)422 void CPDFSDK_Widget::SynchronizeXFAItems(CXFA_FFDocView* pXFADocView,
423 CXFA_FFWidget* hWidget,
424 CPDF_FormField* pFormField,
425 CPDF_FormControl* pFormControl) {
426 ASSERT(hWidget);
427
428 switch (pFormField->GetFieldType()) {
429 case FIELDTYPE_LISTBOX: {
430 pFormField->ClearSelection(false);
431 pFormField->ClearOptions(true);
432
433 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
434 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) {
435 CFX_WideString swText;
436 pWidgetAcc->GetChoiceListItem(swText, i);
437
438 pFormField->InsertOption(swText, i, true);
439 }
440 }
441 break;
442 }
443 case FIELDTYPE_COMBOBOX: {
444 pFormField->ClearSelection(false);
445 pFormField->ClearOptions(false);
446
447 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
448 for (int i = 0, sz = pWidgetAcc->CountChoiceListItems(); i < sz; i++) {
449 CFX_WideString swText;
450 pWidgetAcc->GetChoiceListItem(swText, i);
451
452 pFormField->InsertOption(swText, i, false);
453 }
454 }
455
456 pFormField->SetValue(L"", true);
457 break;
458 }
459 }
460 }
461 #endif // PDF_ENABLE_XFA
462
IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode)463 bool CPDFSDK_Widget::IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode) {
464 CPDF_Dictionary* pAP = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
465 if (!pAP)
466 return false;
467
468 // Choose the right sub-ap
469 const FX_CHAR* ap_entry = "N";
470 if (mode == CPDF_Annot::Down)
471 ap_entry = "D";
472 else if (mode == CPDF_Annot::Rollover)
473 ap_entry = "R";
474 if (!pAP->KeyExist(ap_entry))
475 ap_entry = "N";
476
477 // Get the AP stream or subdirectory
478 CPDF_Object* psub = pAP->GetDirectObjectFor(ap_entry);
479 if (!psub)
480 return false;
481
482 int nFieldType = GetFieldType();
483 switch (nFieldType) {
484 case FIELDTYPE_PUSHBUTTON:
485 case FIELDTYPE_COMBOBOX:
486 case FIELDTYPE_LISTBOX:
487 case FIELDTYPE_TEXTFIELD:
488 case FIELDTYPE_SIGNATURE:
489 return psub->IsStream();
490 case FIELDTYPE_CHECKBOX:
491 case FIELDTYPE_RADIOBUTTON:
492 if (CPDF_Dictionary* pSubDict = psub->AsDictionary()) {
493 return !!pSubDict->GetStreamFor(GetAppState());
494 }
495 return false;
496 }
497 return true;
498 }
499
GetFieldType() const500 int CPDFSDK_Widget::GetFieldType() const {
501 CPDF_FormField* pField = GetFormField();
502 return pField ? pField->GetFieldType() : FIELDTYPE_UNKNOWN;
503 }
504
IsAppearanceValid()505 bool CPDFSDK_Widget::IsAppearanceValid() {
506 #ifdef PDF_ENABLE_XFA
507 CPDFXFA_Context* pContext = m_pPageView->GetFormFillEnv()->GetXFAContext();
508 int nDocType = pContext->GetDocType();
509 if (nDocType != DOCTYPE_PDF && nDocType != DOCTYPE_STATIC_XFA)
510 return true;
511 #endif // PDF_ENABLE_XFA
512 return CPDFSDK_BAAnnot::IsAppearanceValid();
513 }
514
GetLayoutOrder() const515 int CPDFSDK_Widget::GetLayoutOrder() const {
516 return 2;
517 }
518
GetFieldFlags() const519 int CPDFSDK_Widget::GetFieldFlags() const {
520 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
521 CPDF_FormControl* pFormControl =
522 pPDFInterForm->GetControlByDict(m_pAnnot->GetAnnotDict());
523 CPDF_FormField* pFormField = pFormControl->GetField();
524 return pFormField->GetFieldFlags();
525 }
526
IsSignatureWidget() const527 bool CPDFSDK_Widget::IsSignatureWidget() const {
528 return GetFieldType() == FIELDTYPE_SIGNATURE;
529 }
530
GetFormField() const531 CPDF_FormField* CPDFSDK_Widget::GetFormField() const {
532 CPDF_FormControl* pControl = GetFormControl();
533 return pControl ? pControl->GetField() : nullptr;
534 }
535
GetFormControl() const536 CPDF_FormControl* CPDFSDK_Widget::GetFormControl() const {
537 CPDF_InterForm* pPDFInterForm = m_pInterForm->GetInterForm();
538 return pPDFInterForm->GetControlByDict(GetAnnotDict());
539 }
540
GetFormControl(CPDF_InterForm * pInterForm,const CPDF_Dictionary * pAnnotDict)541 CPDF_FormControl* CPDFSDK_Widget::GetFormControl(
542 CPDF_InterForm* pInterForm,
543 const CPDF_Dictionary* pAnnotDict) {
544 ASSERT(pAnnotDict);
545 return pInterForm->GetControlByDict(pAnnotDict);
546 }
547
GetRotate() const548 int CPDFSDK_Widget::GetRotate() const {
549 CPDF_FormControl* pCtrl = GetFormControl();
550 return pCtrl->GetRotation() % 360;
551 }
552
553 #ifdef PDF_ENABLE_XFA
GetName() const554 CFX_WideString CPDFSDK_Widget::GetName() const {
555 CPDF_FormField* pFormField = GetFormField();
556 return pFormField->GetFullName();
557 }
558 #endif // PDF_ENABLE_XFA
559
GetFillColor(FX_COLORREF & color) const560 bool CPDFSDK_Widget::GetFillColor(FX_COLORREF& color) const {
561 CPDF_FormControl* pFormCtrl = GetFormControl();
562 int iColorType = 0;
563 color = ARGBToColorRef(pFormCtrl->GetBackgroundColor(iColorType));
564 return iColorType != COLORTYPE_TRANSPARENT;
565 }
566
GetBorderColor(FX_COLORREF & color) const567 bool CPDFSDK_Widget::GetBorderColor(FX_COLORREF& color) const {
568 CPDF_FormControl* pFormCtrl = GetFormControl();
569 int iColorType = 0;
570 color = ARGBToColorRef(pFormCtrl->GetBorderColor(iColorType));
571 return iColorType != COLORTYPE_TRANSPARENT;
572 }
573
GetTextColor(FX_COLORREF & color) const574 bool CPDFSDK_Widget::GetTextColor(FX_COLORREF& color) const {
575 CPDF_FormControl* pFormCtrl = GetFormControl();
576 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
577 if (!da.HasColor())
578 return false;
579
580 FX_ARGB argb;
581 int iColorType = COLORTYPE_TRANSPARENT;
582 da.GetColor(argb, iColorType);
583 color = ARGBToColorRef(argb);
584 return iColorType != COLORTYPE_TRANSPARENT;
585 }
586
GetFontSize() const587 FX_FLOAT CPDFSDK_Widget::GetFontSize() const {
588 CPDF_FormControl* pFormCtrl = GetFormControl();
589 CPDF_DefaultAppearance pDa = pFormCtrl->GetDefaultAppearance();
590 CFX_ByteString csFont = "";
591 FX_FLOAT fFontSize = 0.0f;
592 pDa.GetFont(csFont, fFontSize);
593
594 return fFontSize;
595 }
596
GetSelectedIndex(int nIndex) const597 int CPDFSDK_Widget::GetSelectedIndex(int nIndex) const {
598 #ifdef PDF_ENABLE_XFA
599 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
600 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
601 if (nIndex < pWidgetAcc->CountSelectedItems())
602 return pWidgetAcc->GetSelectedItem(nIndex);
603 }
604 }
605 #endif // PDF_ENABLE_XFA
606 CPDF_FormField* pFormField = GetFormField();
607 return pFormField->GetSelectedIndex(nIndex);
608 }
609
610 #ifdef PDF_ENABLE_XFA
GetValue(bool bDisplay) const611 CFX_WideString CPDFSDK_Widget::GetValue(bool bDisplay) const {
612 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
613 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
614 CFX_WideString sValue;
615 pWidgetAcc->GetValue(
616 sValue, bDisplay ? XFA_VALUEPICTURE_Display : XFA_VALUEPICTURE_Edit);
617 return sValue;
618 }
619 }
620 #else
621 CFX_WideString CPDFSDK_Widget::GetValue() const {
622 #endif // PDF_ENABLE_XFA
623 CPDF_FormField* pFormField = GetFormField();
624 return pFormField->GetValue();
625 }
626
627 CFX_WideString CPDFSDK_Widget::GetDefaultValue() const {
628 CPDF_FormField* pFormField = GetFormField();
629 return pFormField->GetDefaultValue();
630 }
631
632 CFX_WideString CPDFSDK_Widget::GetOptionLabel(int nIndex) const {
633 CPDF_FormField* pFormField = GetFormField();
634 return pFormField->GetOptionLabel(nIndex);
635 }
636
637 int CPDFSDK_Widget::CountOptions() const {
638 CPDF_FormField* pFormField = GetFormField();
639 return pFormField->CountOptions();
640 }
641
642 bool CPDFSDK_Widget::IsOptionSelected(int nIndex) const {
643 #ifdef PDF_ENABLE_XFA
644 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
645 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc()) {
646 if (nIndex > -1 && nIndex < pWidgetAcc->CountChoiceListItems())
647 return pWidgetAcc->GetItemState(nIndex);
648
649 return false;
650 }
651 }
652 #endif // PDF_ENABLE_XFA
653 CPDF_FormField* pFormField = GetFormField();
654 return pFormField->IsItemSelected(nIndex);
655 }
656
657 int CPDFSDK_Widget::GetTopVisibleIndex() const {
658 CPDF_FormField* pFormField = GetFormField();
659 return pFormField->GetTopVisibleIndex();
660 }
661
662 bool CPDFSDK_Widget::IsChecked() const {
663 #ifdef PDF_ENABLE_XFA
664 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
665 if (CXFA_WidgetAcc* pWidgetAcc = hWidget->GetDataAcc())
666 return pWidgetAcc->GetCheckState() == XFA_CHECKSTATE_On;
667 }
668 #endif // PDF_ENABLE_XFA
669 CPDF_FormControl* pFormCtrl = GetFormControl();
670 return pFormCtrl->IsChecked();
671 }
672
673 int CPDFSDK_Widget::GetAlignment() const {
674 CPDF_FormControl* pFormCtrl = GetFormControl();
675 return pFormCtrl->GetControlAlignment();
676 }
677
678 int CPDFSDK_Widget::GetMaxLen() const {
679 CPDF_FormField* pFormField = GetFormField();
680 return pFormField->GetMaxLen();
681 }
682
683 void CPDFSDK_Widget::SetCheck(bool bChecked, bool bNotify) {
684 CPDF_FormControl* pFormCtrl = GetFormControl();
685 CPDF_FormField* pFormField = pFormCtrl->GetField();
686 pFormField->CheckControl(pFormField->GetControlIndex(pFormCtrl), bChecked,
687 bNotify);
688 #ifdef PDF_ENABLE_XFA
689 if (!IsWidgetAppearanceValid(CPDF_Annot::Normal))
690 ResetAppearance(true);
691 if (!bNotify)
692 Synchronize(true);
693 #endif // PDF_ENABLE_XFA
694 }
695
696 void CPDFSDK_Widget::SetValue(const CFX_WideString& sValue, bool bNotify) {
697 CPDF_FormField* pFormField = GetFormField();
698 pFormField->SetValue(sValue, bNotify);
699 #ifdef PDF_ENABLE_XFA
700 if (!bNotify)
701 Synchronize(true);
702 #endif // PDF_ENABLE_XFA
703 }
704
705 void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue) {}
706 void CPDFSDK_Widget::SetOptionSelection(int index,
707 bool bSelected,
708 bool bNotify) {
709 CPDF_FormField* pFormField = GetFormField();
710 pFormField->SetItemSelection(index, bSelected, bNotify);
711 #ifdef PDF_ENABLE_XFA
712 if (!bNotify)
713 Synchronize(true);
714 #endif // PDF_ENABLE_XFA
715 }
716
717 void CPDFSDK_Widget::ClearSelection(bool bNotify) {
718 CPDF_FormField* pFormField = GetFormField();
719 pFormField->ClearSelection(bNotify);
720 #ifdef PDF_ENABLE_XFA
721 if (!bNotify)
722 Synchronize(true);
723 #endif // PDF_ENABLE_XFA
724 }
725
726 void CPDFSDK_Widget::SetTopVisibleIndex(int index) {}
727
728 void CPDFSDK_Widget::SetAppModified() {
729 m_bAppModified = true;
730 }
731
732 void CPDFSDK_Widget::ClearAppModified() {
733 m_bAppModified = false;
734 }
735
736 bool CPDFSDK_Widget::IsAppModified() const {
737 return m_bAppModified;
738 }
739
740 #ifdef PDF_ENABLE_XFA
741 void CPDFSDK_Widget::ResetAppearance(bool bValueChanged) {
742 switch (GetFieldType()) {
743 case FIELDTYPE_TEXTFIELD:
744 case FIELDTYPE_COMBOBOX: {
745 bool bFormatted = false;
746 CFX_WideString sValue = OnFormat(bFormatted);
747 ResetAppearance(bFormatted ? &sValue : nullptr, true);
748 break;
749 }
750 default:
751 ResetAppearance(nullptr, false);
752 break;
753 }
754 }
755 #endif // PDF_ENABLE_XFA
756
757 void CPDFSDK_Widget::ResetAppearance(const CFX_WideString* sValue,
758 bool bValueChanged) {
759 SetAppModified();
760
761 m_nAppAge++;
762 if (m_nAppAge > 999999)
763 m_nAppAge = 0;
764 if (bValueChanged)
765 m_nValueAge++;
766
767 int nFieldType = GetFieldType();
768
769 switch (nFieldType) {
770 case FIELDTYPE_PUSHBUTTON:
771 ResetAppearance_PushButton();
772 break;
773 case FIELDTYPE_CHECKBOX:
774 ResetAppearance_CheckBox();
775 break;
776 case FIELDTYPE_RADIOBUTTON:
777 ResetAppearance_RadioButton();
778 break;
779 case FIELDTYPE_COMBOBOX:
780 ResetAppearance_ComboBox(sValue);
781 break;
782 case FIELDTYPE_LISTBOX:
783 ResetAppearance_ListBox();
784 break;
785 case FIELDTYPE_TEXTFIELD:
786 ResetAppearance_TextField(sValue);
787 break;
788 }
789
790 m_pAnnot->ClearCachedAP();
791 }
792
793 CFX_WideString CPDFSDK_Widget::OnFormat(bool& bFormatted) {
794 CPDF_FormField* pFormField = GetFormField();
795 ASSERT(pFormField);
796 return m_pInterForm->OnFormat(pFormField, bFormatted);
797 }
798
799 void CPDFSDK_Widget::ResetFieldAppearance(bool bValueChanged) {
800 CPDF_FormField* pFormField = GetFormField();
801 ASSERT(pFormField);
802 m_pInterForm->ResetFieldAppearance(pFormField, nullptr, bValueChanged);
803 }
804
805 void CPDFSDK_Widget::DrawAppearance(CFX_RenderDevice* pDevice,
806 const CFX_Matrix* pUser2Device,
807 CPDF_Annot::AppearanceMode mode,
808 const CPDF_RenderOptions* pOptions) {
809 int nFieldType = GetFieldType();
810
811 if ((nFieldType == FIELDTYPE_CHECKBOX ||
812 nFieldType == FIELDTYPE_RADIOBUTTON) &&
813 mode == CPDF_Annot::Normal &&
814 !IsWidgetAppearanceValid(CPDF_Annot::Normal)) {
815 CFX_PathData pathData;
816
817 CFX_FloatRect rcAnnot = GetRect();
818
819 pathData.AppendRect(rcAnnot.left, rcAnnot.bottom, rcAnnot.right,
820 rcAnnot.top);
821
822 CFX_GraphStateData gsd;
823 gsd.m_LineWidth = 0.0f;
824
825 pDevice->DrawPath(&pathData, pUser2Device, &gsd, 0, 0xFFAAAAAA,
826 FXFILL_ALTERNATE);
827 } else {
828 CPDFSDK_BAAnnot::DrawAppearance(pDevice, pUser2Device, mode, pOptions);
829 }
830 }
831
832 void CPDFSDK_Widget::UpdateField() {
833 CPDF_FormField* pFormField = GetFormField();
834 ASSERT(pFormField);
835 m_pInterForm->UpdateField(pFormField);
836 }
837
838 void CPDFSDK_Widget::DrawShadow(CFX_RenderDevice* pDevice,
839 CPDFSDK_PageView* pPageView) {
840 int nFieldType = GetFieldType();
841 if (!m_pInterForm->IsNeedHighLight(nFieldType))
842 return;
843
844 CFX_Matrix page2device;
845 pPageView->GetCurrentMatrix(page2device);
846
847 CFX_FloatRect rcDevice = GetRect();
848 CFX_PointF tmp =
849 page2device.Transform(CFX_PointF(rcDevice.left, rcDevice.bottom));
850 rcDevice.left = tmp.x;
851 rcDevice.bottom = tmp.y;
852
853 tmp = page2device.Transform(CFX_PointF(rcDevice.right, rcDevice.top));
854 rcDevice.right = tmp.x;
855 rcDevice.top = tmp.y;
856 rcDevice.Normalize();
857
858 FX_RECT rcDev = rcDevice.ToFxRect();
859 pDevice->FillRect(
860 &rcDev, ArgbEncode(static_cast<int>(m_pInterForm->GetHighlightAlpha()),
861 m_pInterForm->GetHighlightColor(nFieldType)));
862 }
863
864 void CPDFSDK_Widget::ResetAppearance_PushButton() {
865 CPDF_FormControl* pControl = GetFormControl();
866 CFX_FloatRect rcWindow = GetRotatedRect();
867 int32_t nLayout = 0;
868 switch (pControl->GetTextPosition()) {
869 case TEXTPOS_ICON:
870 nLayout = PPBL_ICON;
871 break;
872 case TEXTPOS_BELOW:
873 nLayout = PPBL_ICONTOPLABELBOTTOM;
874 break;
875 case TEXTPOS_ABOVE:
876 nLayout = PPBL_LABELTOPICONBOTTOM;
877 break;
878 case TEXTPOS_RIGHT:
879 nLayout = PPBL_ICONLEFTLABELRIGHT;
880 break;
881 case TEXTPOS_LEFT:
882 nLayout = PPBL_LABELLEFTICONRIGHT;
883 break;
884 case TEXTPOS_OVERLAID:
885 nLayout = PPBL_LABELOVERICON;
886 break;
887 default:
888 nLayout = PPBL_LABEL;
889 break;
890 }
891
892 CPWL_Color crBackground;
893 CPWL_Color crBorder;
894 int iColorType;
895 FX_FLOAT fc[4];
896 pControl->GetOriginalBackgroundColor(iColorType, fc);
897 if (iColorType > 0)
898 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
899
900 pControl->GetOriginalBorderColor(iColorType, fc);
901 if (iColorType > 0)
902 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
903
904 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
905 CPWL_Dash dsBorder(3, 0, 0);
906 CPWL_Color crLeftTop;
907 CPWL_Color crRightBottom;
908
909 BorderStyle nBorderStyle = GetBorderStyle();
910 switch (nBorderStyle) {
911 case BorderStyle::DASH:
912 dsBorder = CPWL_Dash(3, 3, 0);
913 break;
914 case BorderStyle::BEVELED:
915 fBorderWidth *= 2;
916 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
917 crRightBottom = crBackground / 2.0f;
918 break;
919 case BorderStyle::INSET:
920 fBorderWidth *= 2;
921 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
922 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
923 break;
924 default:
925 break;
926 }
927
928 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
929
930 CPWL_Color crText(COLORTYPE_GRAY, 0);
931
932 FX_FLOAT fFontSize = 12.0f;
933 CFX_ByteString csNameTag;
934
935 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
936 if (da.HasColor()) {
937 da.GetColor(iColorType, fc);
938 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
939 }
940
941 if (da.HasFont())
942 da.GetFont(csNameTag, fFontSize);
943
944 CFX_WideString csWCaption;
945 CFX_WideString csNormalCaption, csRolloverCaption, csDownCaption;
946
947 if (pControl->HasMKEntry("CA"))
948 csNormalCaption = pControl->GetNormalCaption();
949
950 if (pControl->HasMKEntry("RC"))
951 csRolloverCaption = pControl->GetRolloverCaption();
952
953 if (pControl->HasMKEntry("AC"))
954 csDownCaption = pControl->GetDownCaption();
955
956 CPDF_Stream* pNormalIcon = nullptr;
957 CPDF_Stream* pRolloverIcon = nullptr;
958 CPDF_Stream* pDownIcon = nullptr;
959
960 if (pControl->HasMKEntry("I"))
961 pNormalIcon = pControl->GetNormalIcon();
962
963 if (pControl->HasMKEntry("RI"))
964 pRolloverIcon = pControl->GetRolloverIcon();
965
966 if (pControl->HasMKEntry("IX"))
967 pDownIcon = pControl->GetDownIcon();
968
969 if (pNormalIcon) {
970 if (CPDF_Dictionary* pImageDict = pNormalIcon->GetDict()) {
971 if (pImageDict->GetStringFor("Name").IsEmpty())
972 pImageDict->SetNewFor<CPDF_String>("Name", "ImgA", false);
973 }
974 }
975
976 if (pRolloverIcon) {
977 if (CPDF_Dictionary* pImageDict = pRolloverIcon->GetDict()) {
978 if (pImageDict->GetStringFor("Name").IsEmpty())
979 pImageDict->SetNewFor<CPDF_String>("Name", "ImgB", false);
980 }
981 }
982
983 if (pDownIcon) {
984 if (CPDF_Dictionary* pImageDict = pDownIcon->GetDict()) {
985 if (pImageDict->GetStringFor("Name").IsEmpty())
986 pImageDict->SetNewFor<CPDF_String>("Name", "ImgC", false);
987 }
988 }
989
990 CPDF_IconFit iconFit = pControl->GetIconFit();
991
992 CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
993 font_map.SetAPType("N");
994
995 CFX_ByteString csAP =
996 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
997 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
998 crLeftTop, crRightBottom, nBorderStyle,
999 dsBorder) +
1000 CPWL_Utils::GetPushButtonAppStream(
1001 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
1002 pNormalIcon, iconFit, csNormalCaption, crText, fFontSize, nLayout);
1003
1004 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP);
1005 if (pNormalIcon)
1006 AddImageToAppearance("N", pNormalIcon);
1007
1008 CPDF_FormControl::HighlightingMode eHLM = pControl->GetHighlightingMode();
1009 if (eHLM == CPDF_FormControl::Push || eHLM == CPDF_FormControl::Toggle) {
1010 if (csRolloverCaption.IsEmpty() && !pRolloverIcon) {
1011 csRolloverCaption = csNormalCaption;
1012 pRolloverIcon = pNormalIcon;
1013 }
1014
1015 font_map.SetAPType("R");
1016
1017 csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1018 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1019 crLeftTop, crRightBottom,
1020 nBorderStyle, dsBorder) +
1021 CPWL_Utils::GetPushButtonAppStream(
1022 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
1023 pRolloverIcon, iconFit, csRolloverCaption, crText, fFontSize,
1024 nLayout);
1025
1026 WriteAppearance("R", GetRotatedRect(), GetMatrix(), csAP);
1027 if (pRolloverIcon)
1028 AddImageToAppearance("R", pRolloverIcon);
1029
1030 if (csDownCaption.IsEmpty() && !pDownIcon) {
1031 csDownCaption = csNormalCaption;
1032 pDownIcon = pNormalIcon;
1033 }
1034
1035 switch (nBorderStyle) {
1036 case BorderStyle::BEVELED: {
1037 CPWL_Color crTemp = crLeftTop;
1038 crLeftTop = crRightBottom;
1039 crRightBottom = crTemp;
1040 break;
1041 }
1042 case BorderStyle::INSET: {
1043 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1044 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1045 break;
1046 }
1047 default:
1048 break;
1049 }
1050
1051 font_map.SetAPType("D");
1052
1053 csAP = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
1054 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1055 crLeftTop, crRightBottom,
1056 nBorderStyle, dsBorder) +
1057 CPWL_Utils::GetPushButtonAppStream(
1058 iconFit.GetFittingBounds() ? rcWindow : rcClient, &font_map,
1059 pDownIcon, iconFit, csDownCaption, crText, fFontSize, nLayout);
1060
1061 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP);
1062 if (pDownIcon)
1063 AddImageToAppearance("D", pDownIcon);
1064 } else {
1065 RemoveAppearance("D");
1066 RemoveAppearance("R");
1067 }
1068 }
1069
1070 void CPDFSDK_Widget::ResetAppearance_CheckBox() {
1071 CPDF_FormControl* pControl = GetFormControl();
1072 CPWL_Color crBackground, crBorder, crText;
1073 int iColorType;
1074 FX_FLOAT fc[4];
1075
1076 pControl->GetOriginalBackgroundColor(iColorType, fc);
1077 if (iColorType > 0)
1078 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1079
1080 pControl->GetOriginalBorderColor(iColorType, fc);
1081 if (iColorType > 0)
1082 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1083
1084 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1085 CPWL_Dash dsBorder(3, 0, 0);
1086 CPWL_Color crLeftTop, crRightBottom;
1087
1088 BorderStyle nBorderStyle = GetBorderStyle();
1089 switch (nBorderStyle) {
1090 case BorderStyle::DASH:
1091 dsBorder = CPWL_Dash(3, 3, 0);
1092 break;
1093 case BorderStyle::BEVELED:
1094 fBorderWidth *= 2;
1095 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1096 crRightBottom = crBackground / 2.0f;
1097 break;
1098 case BorderStyle::INSET:
1099 fBorderWidth *= 2;
1100 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1101 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1102 break;
1103 default:
1104 break;
1105 }
1106
1107 CFX_FloatRect rcWindow = GetRotatedRect();
1108 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
1109 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
1110 if (da.HasColor()) {
1111 da.GetColor(iColorType, fc);
1112 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1113 }
1114
1115 int32_t nStyle = 0;
1116 CFX_WideString csWCaption = pControl->GetNormalCaption();
1117 if (csWCaption.GetLength() > 0) {
1118 switch (csWCaption[0]) {
1119 case L'l':
1120 nStyle = PCS_CIRCLE;
1121 break;
1122 case L'8':
1123 nStyle = PCS_CROSS;
1124 break;
1125 case L'u':
1126 nStyle = PCS_DIAMOND;
1127 break;
1128 case L'n':
1129 nStyle = PCS_SQUARE;
1130 break;
1131 case L'H':
1132 nStyle = PCS_STAR;
1133 break;
1134 default: // L'4'
1135 nStyle = PCS_CHECK;
1136 break;
1137 }
1138 } else {
1139 nStyle = PCS_CHECK;
1140 }
1141
1142 CFX_ByteString csAP_N_ON =
1143 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1144 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1145 crLeftTop, crRightBottom, nBorderStyle,
1146 dsBorder);
1147
1148 CFX_ByteString csAP_N_OFF = csAP_N_ON;
1149
1150 switch (nBorderStyle) {
1151 case BorderStyle::BEVELED: {
1152 CPWL_Color crTemp = crLeftTop;
1153 crLeftTop = crRightBottom;
1154 crRightBottom = crTemp;
1155 break;
1156 }
1157 case BorderStyle::INSET: {
1158 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1159 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1160 break;
1161 }
1162 default:
1163 break;
1164 }
1165
1166 CFX_ByteString csAP_D_ON =
1167 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
1168 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1169 crLeftTop, crRightBottom, nBorderStyle,
1170 dsBorder);
1171
1172 CFX_ByteString csAP_D_OFF = csAP_D_ON;
1173
1174 csAP_N_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
1175 csAP_D_ON += CPWL_Utils::GetCheckBoxAppStream(rcClient, nStyle, crText);
1176
1177 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
1178 pControl->GetCheckedAPState());
1179 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
1180
1181 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
1182 pControl->GetCheckedAPState());
1183 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
1184
1185 CFX_ByteString csAS = GetAppState();
1186 if (csAS.IsEmpty())
1187 SetAppState("Off");
1188 }
1189
1190 void CPDFSDK_Widget::ResetAppearance_RadioButton() {
1191 CPDF_FormControl* pControl = GetFormControl();
1192 CPWL_Color crBackground, crBorder, crText;
1193 int iColorType;
1194 FX_FLOAT fc[4];
1195
1196 pControl->GetOriginalBackgroundColor(iColorType, fc);
1197 if (iColorType > 0)
1198 crBackground = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1199
1200 pControl->GetOriginalBorderColor(iColorType, fc);
1201 if (iColorType > 0)
1202 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1203
1204 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1205 CPWL_Dash dsBorder(3, 0, 0);
1206 CPWL_Color crLeftTop;
1207 CPWL_Color crRightBottom;
1208 BorderStyle nBorderStyle = GetBorderStyle();
1209 switch (nBorderStyle) {
1210 case BorderStyle::DASH:
1211 dsBorder = CPWL_Dash(3, 3, 0);
1212 break;
1213 case BorderStyle::BEVELED:
1214 fBorderWidth *= 2;
1215 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1216 crRightBottom = crBackground / 2.0f;
1217 break;
1218 case BorderStyle::INSET:
1219 fBorderWidth *= 2;
1220 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1221 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1222 break;
1223 default:
1224 break;
1225 }
1226
1227 CFX_FloatRect rcWindow = GetRotatedRect();
1228 CFX_FloatRect rcClient = CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
1229
1230 CPDF_DefaultAppearance da = pControl->GetDefaultAppearance();
1231 if (da.HasColor()) {
1232 da.GetColor(iColorType, fc);
1233 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1234 }
1235
1236 int32_t nStyle = 0;
1237 CFX_WideString csWCaption = pControl->GetNormalCaption();
1238 if (csWCaption.GetLength() > 0) {
1239 switch (csWCaption[0]) {
1240 default: // L'l':
1241 nStyle = PCS_CIRCLE;
1242 break;
1243 case L'8':
1244 nStyle = PCS_CROSS;
1245 break;
1246 case L'u':
1247 nStyle = PCS_DIAMOND;
1248 break;
1249 case L'n':
1250 nStyle = PCS_SQUARE;
1251 break;
1252 case L'H':
1253 nStyle = PCS_STAR;
1254 break;
1255 case L'4':
1256 nStyle = PCS_CHECK;
1257 break;
1258 }
1259 } else {
1260 nStyle = PCS_CIRCLE;
1261 }
1262
1263 CFX_ByteString csAP_N_ON;
1264
1265 CFX_FloatRect rcCenter =
1266 CPWL_Utils::DeflateRect(CPWL_Utils::GetCenterSquare(rcWindow), 1.0f);
1267
1268 if (nStyle == PCS_CIRCLE) {
1269 if (nBorderStyle == BorderStyle::BEVELED) {
1270 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1271 crRightBottom = crBackground - 0.25f;
1272 } else if (nBorderStyle == BorderStyle::INSET) {
1273 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5f);
1274 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75f);
1275 }
1276
1277 csAP_N_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBackground) +
1278 CPWL_Utils::GetCircleBorderAppStream(
1279 rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
1280 nBorderStyle, dsBorder);
1281 } else {
1282 csAP_N_ON = CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground) +
1283 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1284 crLeftTop, crRightBottom,
1285 nBorderStyle, dsBorder);
1286 }
1287
1288 CFX_ByteString csAP_N_OFF = csAP_N_ON;
1289
1290 switch (nBorderStyle) {
1291 case BorderStyle::BEVELED: {
1292 CPWL_Color crTemp = crLeftTop;
1293 crLeftTop = crRightBottom;
1294 crRightBottom = crTemp;
1295 break;
1296 }
1297 case BorderStyle::INSET: {
1298 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1299 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1300 break;
1301 }
1302 default:
1303 break;
1304 }
1305
1306 CFX_ByteString csAP_D_ON;
1307
1308 if (nStyle == PCS_CIRCLE) {
1309 CPWL_Color crBK = crBackground - 0.25f;
1310 if (nBorderStyle == BorderStyle::BEVELED) {
1311 crLeftTop = crBackground - 0.25f;
1312 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1313 crBK = crBackground;
1314 } else if (nBorderStyle == BorderStyle::INSET) {
1315 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0);
1316 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 1);
1317 }
1318
1319 csAP_D_ON = CPWL_Utils::GetCircleFillAppStream(rcCenter, crBK) +
1320 CPWL_Utils::GetCircleBorderAppStream(
1321 rcCenter, fBorderWidth, crBorder, crLeftTop, crRightBottom,
1322 nBorderStyle, dsBorder);
1323 } else {
1324 csAP_D_ON =
1325 CPWL_Utils::GetRectFillAppStream(rcWindow, crBackground - 0.25f) +
1326 CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1327 crLeftTop, crRightBottom, nBorderStyle,
1328 dsBorder);
1329 }
1330
1331 CFX_ByteString csAP_D_OFF = csAP_D_ON;
1332
1333 csAP_N_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
1334 csAP_D_ON += CPWL_Utils::GetRadioButtonAppStream(rcClient, nStyle, crText);
1335
1336 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_ON,
1337 pControl->GetCheckedAPState());
1338 WriteAppearance("N", GetRotatedRect(), GetMatrix(), csAP_N_OFF, "Off");
1339
1340 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_ON,
1341 pControl->GetCheckedAPState());
1342 WriteAppearance("D", GetRotatedRect(), GetMatrix(), csAP_D_OFF, "Off");
1343
1344 CFX_ByteString csAS = GetAppState();
1345 if (csAS.IsEmpty())
1346 SetAppState("Off");
1347 }
1348
1349 void CPDFSDK_Widget::ResetAppearance_ComboBox(const CFX_WideString* sValue) {
1350 CPDF_FormControl* pControl = GetFormControl();
1351 CPDF_FormField* pField = pControl->GetField();
1352 CFX_ByteTextBuf sBody, sLines;
1353
1354 CFX_FloatRect rcClient = GetClientRect();
1355 CFX_FloatRect rcButton = rcClient;
1356 rcButton.left = rcButton.right - 13;
1357 rcButton.Normalize();
1358
1359 std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
1360 pEdit->EnableRefresh(false);
1361
1362 CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
1363 pEdit->SetFontMap(&font_map);
1364
1365 CFX_FloatRect rcEdit = rcClient;
1366 rcEdit.right = rcButton.left;
1367 rcEdit.Normalize();
1368
1369 pEdit->SetPlateRect(rcEdit);
1370 pEdit->SetAlignmentV(1, true);
1371
1372 FX_FLOAT fFontSize = GetFontSize();
1373 if (IsFloatZero(fFontSize))
1374 pEdit->SetAutoFontSize(true, true);
1375 else
1376 pEdit->SetFontSize(fFontSize);
1377
1378 pEdit->Initialize();
1379
1380 if (sValue) {
1381 pEdit->SetText(*sValue);
1382 } else {
1383 int32_t nCurSel = pField->GetSelectedIndex(0);
1384 if (nCurSel < 0)
1385 pEdit->SetText(pField->GetValue());
1386 else
1387 pEdit->SetText(pField->GetOptionLabel(nCurSel));
1388 }
1389
1390 CFX_FloatRect rcContent = pEdit->GetContentRect();
1391
1392 CFX_ByteString sEdit =
1393 CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF());
1394 if (sEdit.GetLength() > 0) {
1395 sBody << "/Tx BMC\n"
1396 << "q\n";
1397 if (rcContent.Width() > rcEdit.Width() ||
1398 rcContent.Height() > rcEdit.Height()) {
1399 sBody << rcEdit.left << " " << rcEdit.bottom << " " << rcEdit.Width()
1400 << " " << rcEdit.Height() << " re\nW\nn\n";
1401 }
1402
1403 CPWL_Color crText = GetTextPWLColor();
1404 sBody << "BT\n"
1405 << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
1406 << "Q\nEMC\n";
1407 }
1408
1409 sBody << CPWL_Utils::GetDropButtonAppStream(rcButton);
1410
1411 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
1412 sLines.AsStringC() + sBody.AsStringC();
1413
1414 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1415 }
1416
1417 void CPDFSDK_Widget::ResetAppearance_ListBox() {
1418 CPDF_FormControl* pControl = GetFormControl();
1419 CPDF_FormField* pField = pControl->GetField();
1420 CFX_FloatRect rcClient = GetClientRect();
1421 CFX_ByteTextBuf sBody, sLines;
1422
1423 std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
1424 pEdit->EnableRefresh(false);
1425
1426 CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
1427 pEdit->SetFontMap(&font_map);
1428
1429 pEdit->SetPlateRect(CFX_FloatRect(rcClient.left, 0.0f, rcClient.right, 0.0f));
1430
1431 FX_FLOAT fFontSize = GetFontSize();
1432
1433 pEdit->SetFontSize(IsFloatZero(fFontSize) ? 12.0f : fFontSize);
1434
1435 pEdit->Initialize();
1436
1437 CFX_ByteTextBuf sList;
1438 FX_FLOAT fy = rcClient.top;
1439
1440 int32_t nTop = pField->GetTopVisibleIndex();
1441 int32_t nCount = pField->CountOptions();
1442 int32_t nSelCount = pField->CountSelectedItems();
1443
1444 for (int32_t i = nTop; i < nCount; ++i) {
1445 bool bSelected = false;
1446 for (int32_t j = 0; j < nSelCount; ++j) {
1447 if (pField->GetSelectedIndex(j) == i) {
1448 bSelected = true;
1449 break;
1450 }
1451 }
1452
1453 pEdit->SetText(pField->GetOptionLabel(i));
1454
1455 CFX_FloatRect rcContent = pEdit->GetContentRect();
1456 FX_FLOAT fItemHeight = rcContent.Height();
1457
1458 if (bSelected) {
1459 CFX_FloatRect rcItem =
1460 CFX_FloatRect(rcClient.left, fy - fItemHeight, rcClient.right, fy);
1461 sList << "q\n"
1462 << CPWL_Utils::GetColorAppStream(
1463 CPWL_Color(COLORTYPE_RGB, 0, 51.0f / 255.0f,
1464 113.0f / 255.0f),
1465 true)
1466 << rcItem.left << " " << rcItem.bottom << " " << rcItem.Width()
1467 << " " << rcItem.Height() << " re f\n"
1468 << "Q\n";
1469
1470 sList << "BT\n"
1471 << CPWL_Utils::GetColorAppStream(CPWL_Color(COLORTYPE_GRAY, 1),
1472 true)
1473 << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
1474 << "ET\n";
1475 } else {
1476 CPWL_Color crText = GetTextPWLColor();
1477 sList << "BT\n"
1478 << CPWL_Utils::GetColorAppStream(crText, true)
1479 << CPWL_Utils::GetEditAppStream(pEdit.get(), CFX_PointF(0.0f, fy))
1480 << "ET\n";
1481 }
1482
1483 fy -= fItemHeight;
1484 }
1485
1486 if (sList.GetSize() > 0) {
1487 sBody << "/Tx BMC\n"
1488 << "q\n"
1489 << rcClient.left << " " << rcClient.bottom << " " << rcClient.Width()
1490 << " " << rcClient.Height() << " re\nW\nn\n";
1491 sBody << sList << "Q\nEMC\n";
1492 }
1493
1494 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
1495 sLines.AsStringC() + sBody.AsStringC();
1496
1497 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1498 }
1499
1500 void CPDFSDK_Widget::ResetAppearance_TextField(const CFX_WideString* sValue) {
1501 CPDF_FormControl* pControl = GetFormControl();
1502 CPDF_FormField* pField = pControl->GetField();
1503 CFX_ByteTextBuf sBody, sLines;
1504
1505 std::unique_ptr<CFX_Edit> pEdit(new CFX_Edit);
1506 pEdit->EnableRefresh(false);
1507
1508 CBA_FontMap font_map(this, m_pInterForm->GetFormFillEnv()->GetSysHandler());
1509 pEdit->SetFontMap(&font_map);
1510
1511 CFX_FloatRect rcClient = GetClientRect();
1512 pEdit->SetPlateRect(rcClient);
1513 pEdit->SetAlignmentH(pControl->GetControlAlignment(), true);
1514
1515 uint32_t dwFieldFlags = pField->GetFieldFlags();
1516 bool bMultiLine = (dwFieldFlags >> 12) & 1;
1517
1518 if (bMultiLine) {
1519 pEdit->SetMultiLine(true, true);
1520 pEdit->SetAutoReturn(true, true);
1521 } else {
1522 pEdit->SetAlignmentV(1, true);
1523 }
1524
1525 uint16_t subWord = 0;
1526 if ((dwFieldFlags >> 13) & 1) {
1527 subWord = '*';
1528 pEdit->SetPasswordChar(subWord, true);
1529 }
1530
1531 int nMaxLen = pField->GetMaxLen();
1532 bool bCharArray = (dwFieldFlags >> 24) & 1;
1533 FX_FLOAT fFontSize = GetFontSize();
1534
1535 #ifdef PDF_ENABLE_XFA
1536 CFX_WideString sValueTmp;
1537 if (!sValue && GetMixXFAWidget()) {
1538 sValueTmp = GetValue(true);
1539 sValue = &sValueTmp;
1540 }
1541 #endif // PDF_ENABLE_XFA
1542
1543 if (nMaxLen > 0) {
1544 if (bCharArray) {
1545 pEdit->SetCharArray(nMaxLen);
1546
1547 if (IsFloatZero(fFontSize)) {
1548 fFontSize = CPWL_Edit::GetCharArrayAutoFontSize(font_map.GetPDFFont(0),
1549 rcClient, nMaxLen);
1550 }
1551 } else {
1552 if (sValue)
1553 nMaxLen = sValue->GetLength();
1554 pEdit->SetLimitChar(nMaxLen);
1555 }
1556 }
1557
1558 if (IsFloatZero(fFontSize))
1559 pEdit->SetAutoFontSize(true, true);
1560 else
1561 pEdit->SetFontSize(fFontSize);
1562
1563 pEdit->Initialize();
1564 pEdit->SetText(sValue ? *sValue : pField->GetValue());
1565
1566 CFX_FloatRect rcContent = pEdit->GetContentRect();
1567 CFX_ByteString sEdit = CPWL_Utils::GetEditAppStream(
1568 pEdit.get(), CFX_PointF(), nullptr, !bCharArray, subWord);
1569
1570 if (sEdit.GetLength() > 0) {
1571 sBody << "/Tx BMC\n"
1572 << "q\n";
1573 if (rcContent.Width() > rcClient.Width() ||
1574 rcContent.Height() > rcClient.Height()) {
1575 sBody << rcClient.left << " " << rcClient.bottom << " "
1576 << rcClient.Width() << " " << rcClient.Height() << " re\nW\nn\n";
1577 }
1578 CPWL_Color crText = GetTextPWLColor();
1579 sBody << "BT\n"
1580 << CPWL_Utils::GetColorAppStream(crText) << sEdit << "ET\n"
1581 << "Q\nEMC\n";
1582 }
1583
1584 if (bCharArray) {
1585 switch (GetBorderStyle()) {
1586 case BorderStyle::SOLID: {
1587 CFX_ByteString sColor =
1588 CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false);
1589 if (sColor.GetLength() > 0) {
1590 sLines << "q\n"
1591 << GetBorderWidth() << " w\n"
1592 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false)
1593 << " 2 J 0 j\n";
1594
1595 for (int32_t i = 1; i < nMaxLen; ++i) {
1596 sLines << rcClient.left +
1597 ((rcClient.right - rcClient.left) / nMaxLen) * i
1598 << " " << rcClient.bottom << " m\n"
1599 << rcClient.left +
1600 ((rcClient.right - rcClient.left) / nMaxLen) * i
1601 << " " << rcClient.top << " l S\n";
1602 }
1603
1604 sLines << "Q\n";
1605 }
1606 break;
1607 }
1608 case BorderStyle::DASH: {
1609 CFX_ByteString sColor =
1610 CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false);
1611 if (sColor.GetLength() > 0) {
1612 CPWL_Dash dsBorder = CPWL_Dash(3, 3, 0);
1613
1614 sLines << "q\n"
1615 << GetBorderWidth() << " w\n"
1616 << CPWL_Utils::GetColorAppStream(GetBorderPWLColor(), false)
1617 << "[" << dsBorder.nDash << " " << dsBorder.nGap << "] "
1618 << dsBorder.nPhase << " d\n";
1619
1620 for (int32_t i = 1; i < nMaxLen; ++i) {
1621 sLines << rcClient.left +
1622 ((rcClient.right - rcClient.left) / nMaxLen) * i
1623 << " " << rcClient.bottom << " m\n"
1624 << rcClient.left +
1625 ((rcClient.right - rcClient.left) / nMaxLen) * i
1626 << " " << rcClient.top << " l S\n";
1627 }
1628
1629 sLines << "Q\n";
1630 }
1631 break;
1632 }
1633 default:
1634 break;
1635 }
1636 }
1637
1638 CFX_ByteString sAP = GetBackgroundAppStream() + GetBorderAppStream() +
1639 sLines.AsStringC() + sBody.AsStringC();
1640 WriteAppearance("N", GetRotatedRect(), GetMatrix(), sAP);
1641 }
1642
1643 CFX_FloatRect CPDFSDK_Widget::GetClientRect() const {
1644 CFX_FloatRect rcWindow = GetRotatedRect();
1645 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1646 switch (GetBorderStyle()) {
1647 case BorderStyle::BEVELED:
1648 case BorderStyle::INSET:
1649 fBorderWidth *= 2.0f;
1650 break;
1651 default:
1652 break;
1653 }
1654
1655 return CPWL_Utils::DeflateRect(rcWindow, fBorderWidth);
1656 }
1657
1658 CFX_FloatRect CPDFSDK_Widget::GetRotatedRect() const {
1659 CFX_FloatRect rectAnnot = GetRect();
1660 FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
1661 FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
1662
1663 CPDF_FormControl* pControl = GetFormControl();
1664 CFX_FloatRect rcPDFWindow;
1665 switch (abs(pControl->GetRotation() % 360)) {
1666 case 0:
1667 case 180:
1668 default:
1669 rcPDFWindow = CFX_FloatRect(0, 0, fWidth, fHeight);
1670 break;
1671 case 90:
1672 case 270:
1673 rcPDFWindow = CFX_FloatRect(0, 0, fHeight, fWidth);
1674 break;
1675 }
1676
1677 return rcPDFWindow;
1678 }
1679
1680 CFX_ByteString CPDFSDK_Widget::GetBackgroundAppStream() const {
1681 CPWL_Color crBackground = GetFillPWLColor();
1682 if (crBackground.nColorType != COLORTYPE_TRANSPARENT)
1683 return CPWL_Utils::GetRectFillAppStream(GetRotatedRect(), crBackground);
1684
1685 return "";
1686 }
1687
1688 CFX_ByteString CPDFSDK_Widget::GetBorderAppStream() const {
1689 CFX_FloatRect rcWindow = GetRotatedRect();
1690 CPWL_Color crBorder = GetBorderPWLColor();
1691 CPWL_Color crBackground = GetFillPWLColor();
1692 CPWL_Color crLeftTop, crRightBottom;
1693
1694 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth();
1695 CPWL_Dash dsBorder(3, 0, 0);
1696
1697 BorderStyle nBorderStyle = GetBorderStyle();
1698 switch (nBorderStyle) {
1699 case BorderStyle::DASH:
1700 dsBorder = CPWL_Dash(3, 3, 0);
1701 break;
1702 case BorderStyle::BEVELED:
1703 fBorderWidth *= 2;
1704 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 1);
1705 crRightBottom = crBackground / 2.0f;
1706 break;
1707 case BorderStyle::INSET:
1708 fBorderWidth *= 2;
1709 crLeftTop = CPWL_Color(COLORTYPE_GRAY, 0.5);
1710 crRightBottom = CPWL_Color(COLORTYPE_GRAY, 0.75);
1711 break;
1712 default:
1713 break;
1714 }
1715
1716 return CPWL_Utils::GetBorderAppStream(rcWindow, fBorderWidth, crBorder,
1717 crLeftTop, crRightBottom, nBorderStyle,
1718 dsBorder);
1719 }
1720
1721 CFX_Matrix CPDFSDK_Widget::GetMatrix() const {
1722 CFX_Matrix mt;
1723 CPDF_FormControl* pControl = GetFormControl();
1724 CFX_FloatRect rcAnnot = GetRect();
1725 FX_FLOAT fWidth = rcAnnot.right - rcAnnot.left;
1726 FX_FLOAT fHeight = rcAnnot.top - rcAnnot.bottom;
1727
1728 switch (abs(pControl->GetRotation() % 360)) {
1729 case 0:
1730 default:
1731 mt = CFX_Matrix(1, 0, 0, 1, 0, 0);
1732 break;
1733 case 90:
1734 mt = CFX_Matrix(0, 1, -1, 0, fWidth, 0);
1735 break;
1736 case 180:
1737 mt = CFX_Matrix(-1, 0, 0, -1, fWidth, fHeight);
1738 break;
1739 case 270:
1740 mt = CFX_Matrix(0, -1, 1, 0, 0, fHeight);
1741 break;
1742 }
1743
1744 return mt;
1745 }
1746
1747 CPWL_Color CPDFSDK_Widget::GetTextPWLColor() const {
1748 CPWL_Color crText = CPWL_Color(COLORTYPE_GRAY, 0);
1749
1750 CPDF_FormControl* pFormCtrl = GetFormControl();
1751 CPDF_DefaultAppearance da = pFormCtrl->GetDefaultAppearance();
1752 if (da.HasColor()) {
1753 int32_t iColorType;
1754 FX_FLOAT fc[4];
1755 da.GetColor(iColorType, fc);
1756 crText = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1757 }
1758
1759 return crText;
1760 }
1761
1762 CPWL_Color CPDFSDK_Widget::GetBorderPWLColor() const {
1763 CPWL_Color crBorder;
1764
1765 CPDF_FormControl* pFormCtrl = GetFormControl();
1766 int32_t iColorType;
1767 FX_FLOAT fc[4];
1768 pFormCtrl->GetOriginalBorderColor(iColorType, fc);
1769 if (iColorType > 0)
1770 crBorder = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1771
1772 return crBorder;
1773 }
1774
1775 CPWL_Color CPDFSDK_Widget::GetFillPWLColor() const {
1776 CPWL_Color crFill;
1777
1778 CPDF_FormControl* pFormCtrl = GetFormControl();
1779 int32_t iColorType;
1780 FX_FLOAT fc[4];
1781 pFormCtrl->GetOriginalBackgroundColor(iColorType, fc);
1782 if (iColorType > 0)
1783 crFill = CPWL_Color(iColorType, fc[0], fc[1], fc[2], fc[3]);
1784
1785 return crFill;
1786 }
1787
1788 void CPDFSDK_Widget::AddImageToAppearance(const CFX_ByteString& sAPType,
1789 CPDF_Stream* pImage) {
1790 CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP");
1791 CPDF_Stream* pStream = pAPDict->GetStreamFor(sAPType);
1792 CPDF_Dictionary* pStreamDict = pStream->GetDict();
1793 CFX_ByteString sImageAlias = "IMG";
1794
1795 if (CPDF_Dictionary* pImageDict = pImage->GetDict()) {
1796 sImageAlias = pImageDict->GetStringFor("Name");
1797 if (sImageAlias.IsEmpty())
1798 sImageAlias = "IMG";
1799 }
1800
1801 CPDF_Document* pDoc = m_pPageView->GetPDFDocument();
1802 CPDF_Dictionary* pStreamResList = pStreamDict->GetDictFor("Resources");
1803 if (!pStreamResList)
1804 pStreamResList = pStreamDict->SetNewFor<CPDF_Dictionary>("Resources");
1805
1806 CPDF_Dictionary* pXObject =
1807 pStreamResList->SetNewFor<CPDF_Dictionary>("XObject");
1808 pXObject->SetNewFor<CPDF_Reference>(sImageAlias, pDoc, pImage->GetObjNum());
1809 }
1810
1811 void CPDFSDK_Widget::RemoveAppearance(const CFX_ByteString& sAPType) {
1812 if (CPDF_Dictionary* pAPDict = m_pAnnot->GetAnnotDict()->GetDictFor("AP"))
1813 pAPDict->RemoveFor(sAPType);
1814 }
1815
1816 bool CPDFSDK_Widget::OnAAction(CPDF_AAction::AActionType type,
1817 PDFSDK_FieldAction& data,
1818 CPDFSDK_PageView* pPageView) {
1819 CPDFSDK_FormFillEnvironment* pFormFillEnv = pPageView->GetFormFillEnv();
1820
1821 #ifdef PDF_ENABLE_XFA
1822 CPDFXFA_Context* pContext = pFormFillEnv->GetXFAContext();
1823 if (CXFA_FFWidget* hWidget = GetMixXFAWidget()) {
1824 XFA_EVENTTYPE eEventType = GetXFAEventType(type, data.bWillCommit);
1825
1826 if (eEventType != XFA_EVENT_Unknown) {
1827 if (CXFA_FFWidgetHandler* pXFAWidgetHandler = GetXFAWidgetHandler()) {
1828 CXFA_EventParam param;
1829 param.m_eType = eEventType;
1830 param.m_wsChange = data.sChange;
1831 param.m_iCommitKey = data.nCommitKey;
1832 param.m_bShift = data.bShift;
1833 param.m_iSelStart = data.nSelStart;
1834 param.m_iSelEnd = data.nSelEnd;
1835 param.m_wsFullText = data.sValue;
1836 param.m_bKeyDown = data.bKeyDown;
1837 param.m_bModifier = data.bModifier;
1838 param.m_wsNewText = data.sValue;
1839 if (data.nSelEnd > data.nSelStart)
1840 param.m_wsNewText.Delete(data.nSelStart,
1841 data.nSelEnd - data.nSelStart);
1842 for (int i = data.sChange.GetLength() - 1; i >= 0; i--)
1843 param.m_wsNewText.Insert(data.nSelStart, data.sChange[i]);
1844 param.m_wsPrevText = data.sValue;
1845
1846 CXFA_WidgetAcc* pAcc = hWidget->GetDataAcc();
1847 param.m_pTarget = pAcc;
1848 int32_t nRet = pXFAWidgetHandler->ProcessEvent(pAcc, ¶m);
1849
1850 if (CXFA_FFDocView* pDocView = pContext->GetXFADocView())
1851 pDocView->UpdateDocView();
1852
1853 if (nRet == XFA_EVENTERROR_Success)
1854 return true;
1855 }
1856 }
1857 }
1858 #endif // PDF_ENABLE_XFA
1859
1860 CPDF_Action action = GetAAction(type);
1861 if (action.GetDict() && action.GetType() != CPDF_Action::Unknown) {
1862 CPDFSDK_ActionHandler* pActionHandler = pFormFillEnv->GetActionHander();
1863 return pActionHandler->DoAction_Field(action, type, pFormFillEnv,
1864 GetFormField(), data);
1865 }
1866 return false;
1867 }
1868
1869 CPDF_Action CPDFSDK_Widget::GetAAction(CPDF_AAction::AActionType eAAT) {
1870 switch (eAAT) {
1871 case CPDF_AAction::CursorEnter:
1872 case CPDF_AAction::CursorExit:
1873 case CPDF_AAction::ButtonDown:
1874 case CPDF_AAction::ButtonUp:
1875 case CPDF_AAction::GetFocus:
1876 case CPDF_AAction::LoseFocus:
1877 case CPDF_AAction::PageOpen:
1878 case CPDF_AAction::PageClose:
1879 case CPDF_AAction::PageVisible:
1880 case CPDF_AAction::PageInvisible:
1881 return CPDFSDK_BAAnnot::GetAAction(eAAT);
1882
1883 case CPDF_AAction::KeyStroke:
1884 case CPDF_AAction::Format:
1885 case CPDF_AAction::Validate:
1886 case CPDF_AAction::Calculate: {
1887 CPDF_FormField* pField = GetFormField();
1888 if (pField->GetAdditionalAction().GetDict())
1889 return pField->GetAdditionalAction().GetAction(eAAT);
1890 return CPDFSDK_BAAnnot::GetAAction(eAAT);
1891 }
1892 default:
1893 break;
1894 }
1895
1896 return CPDF_Action();
1897 }
1898
1899 CFX_WideString CPDFSDK_Widget::GetAlternateName() const {
1900 CPDF_FormField* pFormField = GetFormField();
1901 return pFormField->GetAlternateName();
1902 }
1903
1904 int32_t CPDFSDK_Widget::GetAppearanceAge() const {
1905 return m_nAppAge;
1906 }
1907
1908 int32_t CPDFSDK_Widget::GetValueAge() const {
1909 return m_nValueAge;
1910 }
1911