Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: fpdfsdk/fsdk_baseform.cpp

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

Powered by Google App Engine
This is Rietveld 408576698