Home | History | Annotate | Download | only in src
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "../../third_party/base/nonstd_unique_ptr.h"
      8 #include "../include/fsdk_define.h"
      9 #include "../include/fsdk_mgr.h"
     10 #include "../include/fsdk_baseannot.h"
     11 #include "../include/fsdk_baseform.h"
     12 #include "../include/formfiller/FFL_FormFiller.h"
     13 #include "../include/fsdk_actionhandler.h"
     14 
     15 #include "../include/javascript/IJavaScript.h"
     16 
     17 //------------------------------------------------------------------------------------
     18 //*										CPDFSDK_Widget
     19 //------------------------------------------------------------------------------------
     20 
     21 #define IsFloatZero(f)						((f) < 0.01 && (f) > -0.01)
     22 #define IsFloatBigger(fa,fb)				((fa) > (fb) && !IsFloatZero((fa) - (fb)))
     23 #define IsFloatSmaller(fa,fb)				((fa) < (fb) && !IsFloatZero((fa) - (fb)))
     24 #define IsFloatEqual(fa,fb)					IsFloatZero((fa)-(fb))
     25 
     26 CPDFSDK_Widget::CPDFSDK_Widget(CPDF_Annot* pAnnot, CPDFSDK_PageView* pPageView, CPDFSDK_InterForm* pInterForm) :
     27 					CPDFSDK_Annot(pAnnot, pPageView),
     28 					m_pInterForm(pInterForm),
     29 					m_nAppAge(0),
     30 					m_nValueAge(0)
     31 {
     32 	ASSERT(m_pInterForm != NULL);
     33 }
     34 
     35 CPDFSDK_Widget::~CPDFSDK_Widget()
     36 {
     37 
     38 }
     39 
     40 FX_BOOL		CPDFSDK_Widget::IsWidgetAppearanceValid(CPDF_Annot::AppearanceMode mode)
     41 {
     42 	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 
     86 int	CPDFSDK_Widget::GetFieldType() const
     87 {
     88 	CPDF_FormField* pField = GetFormField();
     89 	ASSERT(pField != NULL);
     90 
     91 	return pField->GetFieldType();
     92 }
     93 
     94 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 
    104 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 
    113 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 
    123 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 }
    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 
    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 
    156 int CPDFSDK_Widget::GetRotate() const
    157 {
    158 	CPDF_FormControl* pCtrl = this->GetFormControl();
    159 	ASSERT(pCtrl != NULL);
    160 
    161 	return pCtrl->GetRotation() % 360;
    162 }
    163 
    164 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 
    175 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 
    186 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 
    205 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 
    218 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 
    226 CFX_WideString CPDFSDK_Widget::GetValue() const
    227 {
    228 	CPDF_FormField*	pFormField = GetFormField();
    229 	ASSERT(pFormField != NULL);
    230 
    231 	return pFormField->GetValue();
    232 }
    233 
    234 CFX_WideString CPDFSDK_Widget::GetDefaultValue() const
    235 {
    236 	CPDF_FormField*	pFormField = GetFormField();
    237 	ASSERT(pFormField != NULL);
    238 
    239 	return pFormField->GetDefaultValue();
    240 }
    241 
    242 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 
    250 int	CPDFSDK_Widget::CountOptions() const
    251 {
    252 	CPDF_FormField*	pFormField = GetFormField();
    253 	ASSERT(pFormField != NULL);
    254 
    255 	return pFormField->CountOptions();
    256 }
    257 
    258 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 
    266 int	CPDFSDK_Widget::GetTopVisibleIndex() const
    267 {
    268 	CPDF_FormField*	pFormField = GetFormField();
    269 	ASSERT(pFormField != NULL);
    270 
    271 	return pFormField->GetTopVisibleIndex();
    272 }
    273 
    274 FX_BOOL	CPDFSDK_Widget::IsChecked() const
    275 {
    276 	CPDF_FormControl* pFormCtrl = GetFormControl();
    277 	ASSERT(pFormCtrl != NULL);
    278 
    279 	return pFormCtrl->IsChecked();
    280 }
    281 
    282 int	CPDFSDK_Widget::GetAlignment() const
    283 {
    284 	CPDF_FormControl* pFormCtrl = GetFormControl();
    285 	ASSERT(pFormCtrl != NULL);
    286 
    287 	return pFormCtrl->GetControlAlignment();
    288 }
    289 
    290 int	CPDFSDK_Widget::GetMaxLen() const
    291 {
    292 	CPDF_FormField*	pFormField = GetFormField();
    293 	ASSERT(pFormField != NULL);
    294 
    295 	return pFormField->GetMaxLen();
    296 }
    297 
    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 
    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 
    317 void CPDFSDK_Widget::SetDefaultValue(const CFX_WideString& sValue)
    318 {
    319 }
    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 
    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 
    336 void CPDFSDK_Widget::SetTopVisibleIndex(int index)
    337 {
    338 }
    339 
    340 void CPDFSDK_Widget::SetAppModified()
    341 {
    342 	m_bAppModified = TRUE;
    343 }
    344 
    345 void CPDFSDK_Widget::ClearAppModified()
    346 {
    347 	m_bAppModified = FALSE;
    348 }
    349 
    350 FX_BOOL CPDFSDK_Widget::IsAppModified() const
    351 {
    352 	return m_bAppModified;
    353 }
    354 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
   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 
   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 
   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 
   1363 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 
   1378 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 
   1404 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 
   1413 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 
   1454 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 
   1486 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 
   1505 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 
   1521 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 
   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 
   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 
   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 
   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 
   1647 CFX_WideString CPDFSDK_Widget::GetAlternateName() const
   1648 {
   1649 	CPDF_FormField*	pFormField = GetFormField();
   1650 	ASSERT(pFormField != NULL);
   1651 
   1652 	return pFormField->GetAlternateName();
   1653 }
   1654 
   1655 FX_INT32	CPDFSDK_Widget::GetAppearanceAge() const
   1656 {
   1657 	return m_nAppAge;
   1658 }
   1659 
   1660 FX_INT32 CPDFSDK_Widget::GetValueAge() const
   1661 {
   1662 	return m_nValueAge;
   1663 }
   1664 
   1665 
   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 
   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 
   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 
   1709 void CPDFSDK_InterForm::Destroy()
   1710 {
   1711 	delete this;
   1712 }
   1713 
   1714 CPDF_InterForm* CPDFSDK_InterForm::GetInterForm()
   1715 {
   1716 	return m_pInterForm;
   1717 }
   1718 
   1719 CPDFSDK_Document* CPDFSDK_InterForm::GetDocument()
   1720 {
   1721 	return m_pDocument;
   1722 }
   1723 
   1724 FX_BOOL CPDFSDK_InterForm::HighlightWidgets()
   1725 {
   1726 	return FALSE;
   1727 }
   1728 
   1729 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 
   1740 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 
   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 
   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 
   1810 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 
   1836 void CPDFSDK_InterForm::AddMap(CPDF_FormControl* pControl, CPDFSDK_Widget* pWidget)
   1837 {
   1838 	m_Map.SetAt(pControl, pWidget);
   1839 }
   1840 
   1841 void CPDFSDK_InterForm::RemoveMap(CPDF_FormControl* pControl)
   1842 {
   1843 	m_Map.RemoveKey(pControl);
   1844 }
   1845 
   1846 void CPDFSDK_InterForm::EnableCalculate(FX_BOOL bEnabled)
   1847 {
   1848 	m_bCalculate = bEnabled;
   1849 }
   1850 
   1851 FX_BOOL CPDFSDK_InterForm::IsCalculateEnabled() const
   1852 {
   1853 	return m_bCalculate;
   1854 }
   1855 
   1856 #ifdef _WIN32
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   2317 FX_BOOL CPDFSDK_InterForm::FDFToURLEncodedData(CFX_WideString csFDFFile, CFX_WideString csTxtFile)
   2318 {
   2319 	return TRUE;
   2320 }
   2321 
   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 
   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 
   2376 CFX_WideString CPDFSDK_InterForm::GetTemporaryFileName(const CFX_WideString& sFileExt)
   2377 {
   2378 	CFX_WideString sFileName;
   2379 	return L"";
   2380 }
   2381 
   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 
   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 
   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 
   2457 FX_BOOL CPDFSDK_InterForm::DoAction_ImportData(const CPDF_Action& action)
   2458 {
   2459 	return FALSE;
   2460 }
   2461 
   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 
   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 
   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 
   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 
   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 
   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 
   2598 int	CPDFSDK_InterForm::BeforeFormReset(const CPDF_InterForm* pForm)
   2599 {
   2600 	return 0;
   2601 }
   2602 
   2603 int	CPDFSDK_InterForm::AfterFormReset(const CPDF_InterForm* pForm)
   2604 {
   2605 	this->OnCalculate(NULL);
   2606 
   2607 	return 0;
   2608 }
   2609 
   2610 int	CPDFSDK_InterForm::BeforeFormImportData(const CPDF_InterForm* pForm)
   2611 {
   2612 	return 0;
   2613 }
   2614 
   2615 int	CPDFSDK_InterForm::AfterFormImportData(const CPDF_InterForm* pForm)
   2616 {
   2617 	this->OnCalculate(NULL);
   2618 
   2619 	return 0;
   2620 }
   2621 
   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 
   2629 void CPDFSDK_InterForm::RemoveAllHighLight()
   2630 {
   2631 	memset((void*)m_bNeedHightlight, 0, 6*sizeof(FX_BOOL));
   2632 }
   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 
   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 
   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 
   2698 CBA_AnnotIterator::~CBA_AnnotIterator()
   2699 {
   2700 	m_Annots.RemoveAll();
   2701 }
   2702 
   2703 CPDFSDK_Annot* CBA_AnnotIterator::GetFirstAnnot()
   2704 {
   2705 	if (m_Annots.GetSize() > 0)
   2706 		return m_Annots[0];
   2707 
   2708 	return NULL;
   2709 }
   2710 
   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 
   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 
   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 
   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 
   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 
   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 
   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