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