diff --git a/fpdfsdk/src/formfiller/FFL_FormFiller.cpp b/fpdfsdk/src/formfiller/FFL_FormFiller.cpp
index f514bf2..530b80c 100644
--- a/fpdfsdk/src/formfiller/FFL_FormFiller.cpp
+++ b/fpdfsdk/src/formfiller/FFL_FormFiller.cpp
@@ -1,925 +1,925 @@
-// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
- 
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-
-#include "../../include/formfiller/FFL_FormFiller.h"
-#include "../../include/formfiller/FFL_Notify.h"
-#include "../../include/formfiller/FFL_CBA_Fontmap.h"
-
-#define GetRed(rgb)			((FX_BYTE)(rgb))
-#define GetGreen(rgb)		((FX_BYTE)(((FX_WORD)(rgb)) >> 8))
-#define GetBlue(rgb)		((FX_BYTE)((rgb)>>16))
-
-#define FFL_HINT_ELAPSE		800
-
-/* ------------------------- CFFL_FormFiller ------------------------- */
-
-CFFL_FormFiller::CFFL_FormFiller(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot)
-	:m_pApp(pApp),
-	m_pAnnot(pAnnot),
-	m_bValid(FALSE),
-	m_ptOldPos(0,0)
-{ 
-	m_pWidget = (CPDFSDK_Widget*) pAnnot;
-}
-
-CFFL_FormFiller::~CFFL_FormFiller()
-{
-	FX_POSITION pos = m_Maps.GetStartPosition();
-	while (pos)
-	{
-		CPDFSDK_PageView * pPageView = NULL;
-		CPWL_Wnd* pWnd = NULL;
-		m_Maps.GetNextAssoc(pos, pPageView, pWnd);
-
-		if (pWnd)
-		{
-			CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
-			pWnd->Destroy();
-			delete pWnd;
-			delete pData;
-		}
-	}
-	m_Maps.RemoveAll();
-
-}
-
-void CFFL_FormFiller::SetWindowRect(CPDFSDK_PageView* pPageView, const CPDF_Rect& rcWindow)
-{
-	if (CPWL_Wnd* pWnd = this->GetPDFWindow(pPageView, FALSE))
-	{
-		pWnd->Move(CPDF_Rect(rcWindow), TRUE, FALSE);
-	}
-}
-
-CPDF_Rect CFFL_FormFiller::GetWindowRect(CPDFSDK_PageView* pPageView)
-{
-	if (CPWL_Wnd* pWnd = this->GetPDFWindow(pPageView, FALSE))
-	{
-		return pWnd->GetWindowRect();
-	}
-
-	return CPDF_Rect(0,0,0,0);
-}
-
-FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
-{
-	ASSERT(pPageView != NULL);
-	ASSERT(pAnnot != NULL);
-
-	CPDF_Rect rcAnnot = m_pWidget->GetRect();
-
-	if (CPWL_Wnd* pWnd = this->GetPDFWindow(pPageView, FALSE))
-	{
-		CPDF_Rect rcWindow = pWnd->GetWindowRect();
-		rcAnnot = PWLtoFFL(rcWindow);
-	}
-
-	CPDF_Rect rcWin = rcAnnot;
-//	pPageView->DocToWindow(rcAnnot, rcWin);
-
-	CPDF_Rect rcFocus = this->GetFocusBox(pPageView);
-	if (!rcFocus.IsEmpty())
-		rcWin.Union(rcFocus);
-
-	CPDF_Rect rect = CPWL_Utils::InflateRect(rcWin,1);
-
-	return rect.GetOutterRect();
-}
-
-void CFFL_FormFiller::OnDraw(CPDFSDK_PageView *pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
-						CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
-						/*const CRect& rcWindow,*/ FX_DWORD dwFlags)
-{
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
-	{
-		CPDF_Matrix mt = this->GetCurMatrix();
-		mt.Concat(*pUser2Device);
-		pWnd->DrawAppearance(pDevice,&mt);
-	}
-	else
-	{
-		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-		if (CFFL_IFormFiller::IsVisible(pWidget))
-			pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-	}
-}
-
-void CFFL_FormFiller::OnDrawDeactive(CPDFSDK_PageView *pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
-						CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
-						/*const CRect& rcWindow,*/ FX_DWORD dwFlags)
-{
-	ASSERT(pAnnot != NULL);
-	
-	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-	
-	pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-}
-
-
-void CFFL_FormFiller::OnCreate(CPDFSDK_Annot* pAnnot)
-{
-}
-
-void CFFL_FormFiller::OnLoad(CPDFSDK_Annot* pAnnot)
-{
-}
-
-void CFFL_FormFiller::OnDelete(CPDFSDK_Annot* pAnnot)
-{
-}
-
-void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
-{
-}
-
-void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
-{
-	EndTimer();
-	ASSERT(m_pWidget != NULL);
-}
-
-FX_BOOL CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, TRUE))
-	{		
-		m_bValid = TRUE;
-		FX_RECT rect = this->GetViewBBox(pPageView,pAnnot);
-		this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-
- 		if(!rect.Contains((int)point.x, (int)point.y))
-  			return FALSE;
-
-		return pWnd->OnLButtonDown(WndtoPWL(pPageView, point),nFlags);
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
-	{	
-		FX_RECT rcFFL =  this->GetViewBBox(pPageView, pAnnot);
-		this->InvalidateRect(rcFFL.left, rcFFL.top, rcFFL.right, rcFFL.bottom);
-		pWnd->OnLButtonUp(WndtoPWL(pPageView, point),nFlags);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
-	{				
-		pWnd->OnLButtonDblClk(WndtoPWL(pPageView, point),nFlags);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	if ((m_ptOldPos.x != point.x) || (m_ptOldPos.y != point.y))
-	{
-		m_ptOldPos = point;
-	}
-
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
-	{				
-		pWnd->OnMouseMove(WndtoPWL(pPageView, point),nFlags);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, short zDelta, const CPDF_Point& point)
-{
-	if (!IsValid()) return FALSE;
-
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, TRUE))
-	{				
-		return pWnd->OnMouseWheel(zDelta, WndtoPWL(pPageView, point),nFlags);
-	}
-
-	return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, TRUE))
-	{				
-		pWnd->OnRButtonDown(WndtoPWL(pPageView, point),nFlags);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
-	{				
-		pWnd->OnRButtonUp(WndtoPWL(pPageView, point),nFlags);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_FormFiller::OnRButtonDblClk(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
-	{				
-		pWnd->OnRButtonDblClk(WndtoPWL(pPageView, point),nFlags);
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot, FX_UINT nKeyCode, FX_UINT nFlags)
-{
-	if (IsValid())
-	{
-		CPDFSDK_PageView* pPageView = this->GetCurPageView();
-		ASSERT(pPageView != NULL);
-
-		if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
-		{				
-			return pWnd->OnKeyDown(nKeyCode,nFlags);
-		}
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_FormFiller::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
-{
-	if (IsValid())
-	{
-		CPDFSDK_PageView* pPageView = this->GetCurPageView();
-		ASSERT(pPageView != NULL);
-
-		if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
-		{				
-			return pWnd->OnChar(nChar,nFlags);
-		}
-	}
-
-	return FALSE;
-}
-
-void CFFL_FormFiller::OnDeSelected(CPDFSDK_Annot* pAnnot)
-{
-	ASSERT(FALSE);
-}
-
-void CFFL_FormFiller::OnSelected(CPDFSDK_Annot* pAnnot)
-{
-	ASSERT(FALSE);
-}
-
-FX_BOOL	CFFL_FormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
-{
-	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-
-	CPDF_Page * pPage = pWidget->GetPDFPage();
- 	CPDFSDK_Document * pDoc = m_pApp->GetCurrentDoc();
-	CPDFSDK_PageView* pPageView = pDoc->GetPageView(pPage);
- 	ASSERT(pPageView != NULL);
-
- 	
-
-	CPWL_Wnd * pWnd = NULL;
-	if ( (pWnd = GetPDFWindow(pPageView, TRUE)))
-	{				
-		pWnd->SetFocus();
-	}
-
-	m_bValid = TRUE;
-	
-	
-	
-
-	m_bValid = TRUE;
-	FX_RECT rcRect = this->GetViewBBox(pPageView,pAnnot);
-	this->InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
-	
-	return TRUE;
-}
-
-FX_BOOL	CFFL_FormFiller::OnKillFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
-{
-	if (IsValid())
-	{
-		CPDFSDK_PageView* pPageView = this->GetCurPageView();
-		ASSERT(pPageView != NULL);
-
-		CommitData(pPageView, nFlag);
-
-		if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE))
-		{				
-			pWnd->KillFocus();
-		}
-		
-		switch (m_pWidget->GetFieldType())
-		{
-		case FIELDTYPE_PUSHBUTTON:
-		case FIELDTYPE_CHECKBOX:
-		case FIELDTYPE_RADIOBUTTON:
-			EscapeFiller(pPageView, TRUE);
-			break;
-		default:
-			EscapeFiller(pPageView, FALSE);
-			break;
-		}
-	}
-
-	return TRUE;
-}
-
-FX_BOOL	CFFL_FormFiller::IsValid() const
-{
-	return m_bValid;
-}
-
-PWL_CREATEPARAM	CFFL_FormFiller::GetCreateParam()
-{
-	ASSERT(m_pApp != NULL);
-
-	PWL_CREATEPARAM cp;
-
-	cp.pParentWnd = NULL;	
-	cp.pProvider = this;
-	cp.rcRectWnd = GetPDFWindowRect();
-	
-	FX_DWORD dwCreateFlags = PWS_BORDER | PWS_BACKGROUND | PWS_VISIBLE;
-
-	ASSERT(m_pWidget != NULL);
-
-
-	FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
-
-	if (dwFieldFlag & FIELDFLAG_READONLY)
-	{		
-		dwCreateFlags |= PWS_READONLY;
-	}
-
-	FX_COLORREF color;
-	if (m_pWidget->GetFillColor(color))
-	{
-		cp.sBackgroundColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
-	}
-
-	if (m_pWidget->GetBorderColor(color))
-	{
-		cp.sBorderColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
-	}
-
-	cp.sTextColor = CPWL_Color(COLORTYPE_GRAY,0);
-
-	if (m_pWidget->GetTextColor(color))
-	{
-		cp.sTextColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
-	}
-
-	cp.fFontSize = m_pWidget->GetFontSize();
-	cp.dwBorderWidth = m_pWidget->GetBorderWidth();
-	
-	int nBorderStyle = m_pWidget->GetBorderStyle();
-
-	switch (nBorderStyle)
-	{
-	case BBS_SOLID:
-		cp.nBorderStyle = PBS_SOLID;
-		break;
-	case BBS_DASH:
-		cp.nBorderStyle = PBS_DASH;
-		cp.sDash = CPWL_Dash(3,3,0);			
-		break;
-	case BBS_BEVELED:
-		cp.nBorderStyle = PBS_BEVELED;
-		cp.dwBorderWidth *= 2;
-		break;
-	case BBS_INSET:
-		cp.nBorderStyle = PBS_INSET;
-		cp.dwBorderWidth *= 2;
-		break;
-	case BBS_UNDERLINE:
-		cp.nBorderStyle = PBS_UNDERLINED;
-		break;
-	}
-
-	if (cp.fFontSize <= 0)
-	{
-		dwCreateFlags |= PWS_AUTOFONTSIZE;
-	}
-
-	cp.dwFlags = dwCreateFlags;
-	cp.pSystemHandler = m_pApp->GetSysHandler();
-	return cp;
-}
-
-CPWL_Wnd* CFFL_FormFiller::GetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bNew)
-{
-	ASSERT(pPageView != NULL);
-	ASSERT(m_pWidget != NULL);
-
-	CPWL_Wnd* pWnd = NULL;
-	m_Maps.Lookup(pPageView, pWnd);
-
-	if (bNew)
-	{
-		if (pWnd)
-		{
-			CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pWnd->GetAttachedData();
-			ASSERT(pPrivateData != NULL);
-
-			if (pPrivateData->nWidgetAge != m_pWidget->GetAppearanceAge())
-			{
-				return this->ResetPDFWindow(pPageView, m_pWidget->GetValueAge() == pPrivateData->nValueAge);
-			}
-		}
-		else
-		{
-			PWL_CREATEPARAM cp = GetCreateParam();
-			cp.hAttachedWnd = (FX_HWND)m_pWidget;
-
-			CFFL_PrivateData* pPrivateData = new CFFL_PrivateData;
-			pPrivateData->pWidget = m_pWidget;
-			pPrivateData->pPageView = pPageView;
-			pPrivateData->nWidgetAge = m_pWidget->GetAppearanceAge();
-                        pPrivateData->nValueAge = 0;
-
-			cp.pAttachedData = pPrivateData;
-
-			pWnd = NewPDFWindow(cp, pPageView);
-
-			if (pWnd)
-			{
-				m_Maps.SetAt(pPageView, pWnd);
-			}
-		}
-	}
-
-	return pWnd;
-}
-
-void CFFL_FormFiller::DestroyPDFWindow(CPDFSDK_PageView* pPageView)
-{
-	CPWL_Wnd* pWnd = NULL;
-	m_Maps.Lookup(pPageView, pWnd);
-
-	if (pWnd)
-	{
-		CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
-		pData->pPageView = NULL;
-		pWnd->Destroy();
-		delete pWnd;
-		delete pData;
-	}
-
-	m_Maps.RemoveKey(pPageView);
-}
-
-CPDF_Matrix	CFFL_FormFiller::GetWindowMatrix(void* pAttachedData)
-{
-	if (CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pAttachedData)
-	{
-		if (pPrivateData->pPageView)
-		{
-			CPDF_Matrix mtPageView;
-			pPrivateData->pPageView->GetCurrentMatrix(mtPageView);
-			CPDF_Matrix mt = GetCurMatrix();
-			mt.Concat(mtPageView);
-			
-			return mt;
-		}
-	}
-	return CPDF_Matrix(1,0,0,1,0,0);
-}
-
-CPDF_Matrix	CFFL_FormFiller::GetCurMatrix()
-{
-	CPDF_Matrix mt;
-
-	ASSERT(m_pWidget != NULL);
-
-	CPDF_Rect rcDA ;
-	m_pWidget->GetPDFAnnot()->GetRect(rcDA);
-
-
-	switch (m_pWidget->GetRotate())
-	{
-	default:
-	case 0:		
-		mt = CPDF_Matrix(1,0,0,1,0,0);
-		break;
-	case 90:
-		mt = CPDF_Matrix(0,1,-1,0,rcDA.right - rcDA.left,0);
-		break;
-	case 180:
-		mt = CPDF_Matrix(-1,0,0,-1,rcDA.right - rcDA.left,rcDA.top - rcDA.bottom);
-		break;
-	case 270:
-		mt = CPDF_Matrix(0,-1,1,0,0,rcDA.top - rcDA.bottom);
-		break;
-	}
-	mt.e += rcDA.left;
-	mt.f += rcDA.bottom;
-
-	return mt;
-}
-
-CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex)
-{
-	ASSERT(m_pApp != NULL);
-
-	return L"";
-}
-
-CPDF_Rect CFFL_FormFiller::GetPDFWindowRect() const
-{
-	ASSERT(m_pWidget != NULL);
-
-	CPDF_Rect rectAnnot;
-	m_pWidget->GetPDFAnnot()->GetRect(rectAnnot);
-
-	FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
-	FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
-
-
-	if ((m_pWidget->GetRotate() / 90) & 0x01)
-		return CPDF_Rect(0,0,fHeight,fWidth);
-	else
-		return CPDF_Rect(0,0,fWidth,fHeight);
-}
-
-CPDFSDK_PageView* CFFL_FormFiller::GetCurPageView()
-{
-
-	CPDF_Page* pPage = m_pAnnot->GetPDFPage();
-	CPDFSDK_Document* pSDKDoc = m_pApp->GetCurrentDoc();
-	if(pSDKDoc)
-	{
-		return pSDKDoc->GetPageView(pPage);
-	}
-	return NULL;
-}
-
-CPDF_Rect CFFL_FormFiller::GetFocusBox(CPDFSDK_PageView* pPageView)
-{
-	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
-	{			
-		CPDF_Rect rcFocus =  FFLtoWnd(pPageView, PWLtoFFL(pWnd->GetFocusRect()));
-		ASSERT(pPageView);
-		CPDF_Rect rcPage = pPageView->GetPDFPage()->GetPageBBox();
-		if(rcPage.Contains(rcFocus))
-			return rcFocus;
-		else
-			return CPDF_Rect(0,0,0,0);
-	}
-	return CPDF_Rect(0,0,0,0);
-}
-
-CPDF_Rect CFFL_FormFiller::FFLtoPWL(const CPDF_Rect& rect)
-{
-	CPDF_Matrix mt;
-	mt.SetReverse(GetCurMatrix());
-	
-	CPDF_Rect temp = rect;
-	mt.TransformRect(temp);
-
-	return temp;
-}
-
-CPDF_Rect CFFL_FormFiller::PWLtoFFL(const CPDF_Rect& rect)
-{
-	CPDF_Matrix mt = GetCurMatrix();
-	
-	CPDF_Rect temp = rect;
-	mt.TransformRect(temp);
-
-	return temp;
-}
-
-CPDF_Point CFFL_FormFiller::FFLtoPWL(const CPDF_Point& point)
-{
-	CPDF_Matrix mt;
-	mt.SetReverse(GetCurMatrix());
-
-	CPDF_Point pt = point;
-	mt.Transform(pt.x,pt.y);
-
-	return pt;
-}
-
-CPDF_Point CFFL_FormFiller::PWLtoFFL(const CPDF_Point & point)
-{
-	CPDF_Matrix mt = GetCurMatrix();
-
-	CPDF_Point pt = point;
-	mt.Transform(pt.x,pt.y);
-
-	return pt;
-}
-
-CPDF_Point CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView, const CPDF_Point& pt)
-{
-// 	ASSERT(pPageView != NULL);
-// 
-// 	CPDF_Point point(0.0f, 0.0f);
-// 	pPageView->WindowToDoc(pt.x, pt.y, point.x, point.y);
-// 
- 	return FFLtoPWL(pt);
-//	return CPDF_Point(0, 0);
-}
-
-CPDF_Rect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView, const CPDF_Rect & rect)
-{
-// 	FX_RECT rcRet(0,0,0,0);
-// 
-// 	ASSERT(pPageView != NULL);	
-// 	pPageView->DocToWindow(rect, rcRet);
-// 	
- 	return rect;
-
-}
-
-void CFFL_FormFiller::FFL_FreeData(void* pData)
-{
-	ASSERT(pData != NULL);
-
-	delete (CFFL_PrivateData*)pData;
-}
-
-FX_BOOL CFFL_FormFiller::CommitData(CPDFSDK_PageView* pPageView, FX_UINT nFlag)
-{
-	if (IsDataChanged(pPageView))
-	{
-		//CFFL_IFormFiller* pIFormFiller = CFFL_Module::GetFormFiller(m_pApp);
-		CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();//NULL;
-		ASSERT(pIFormFiller != NULL);
-
-		FX_BOOL bRC = TRUE;
-		FX_BOOL bExit = FALSE;
-
-		pIFormFiller->OnKeyStrokeCommit(m_pWidget, pPageView, bRC, bExit, nFlag);
-		if (bExit) return TRUE;
-		if (!bRC)
-		{
-			this->ResetPDFWindow(pPageView, FALSE);
-			return TRUE;
-		}
-
-		pIFormFiller->OnValidate(m_pWidget, pPageView, bRC, bExit, nFlag);
-		if (bExit) return TRUE;
-		if (!bRC)
-		{
-			this->ResetPDFWindow(pPageView, FALSE);
-			return TRUE;
-		}
-
-		SaveData(pPageView);
-
-		pIFormFiller->OnCalculate(m_pWidget, pPageView, bExit,nFlag);
-		if (bExit) return TRUE;
-
-		pIFormFiller->OnFormat(m_pWidget, pPageView, bExit,nFlag);
-	}
-
-	return TRUE;
-}
-
-FX_BOOL	CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView)
-{
-	return FALSE;
-}
-
-void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView)
-{
-}
-
-void CFFL_FormFiller::GetKeyStrokeData(CPDFSDK_PageView* pPageView, FFL_KeyStrokeData& data)
-{
-}
-
-void CFFL_FormFiller::SetChangeMark()
-{
-	m_pApp->FFI_OnChange();
-}
-
-void CFFL_FormFiller::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
-							PDFSDK_FieldAction& fa)
-{
-	fa.sValue = m_pWidget->GetValue();
-}
-
-void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
-									const PDFSDK_FieldAction& fa)
-{
-}
-
-FX_BOOL	CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type, const PDFSDK_FieldAction& faOld, 
-									const PDFSDK_FieldAction& faNew)
-{
-	return FALSE;
-}
-
-void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView)
-{
-}
-
-void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView)
-{
-}
-
-CPWL_Wnd*  CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
-{
-	return GetPDFWindow(pPageView, FALSE); 
-}
-
-void CFFL_FormFiller::TimerProc()
-{
-
-}
-
-IFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const
-{
-	return m_pApp->GetSysHandler();
-//	return NULL;
-}
-
-void CFFL_FormFiller::OnKeyStroke(FX_BOOL bKeyDown)
-{
-}
-
-void CFFL_FormFiller::EscapeFiller(CPDFSDK_PageView* pPageView, FX_BOOL bDestroyPDFWindow)
-{
-	m_bValid = FALSE;
-	
-	FX_RECT rcRect = this->GetViewBBox(pPageView, m_pWidget);
-	this->InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
-
-	if(bDestroyPDFWindow)
- 		DestroyPDFWindow(pPageView);
-}
-
-FX_BOOL CFFL_FormFiller::CanCopy(CPDFSDK_Document* pDocument)
-{
-	return FALSE;
-}
-
-FX_BOOL CFFL_FormFiller::CanCut(CPDFSDK_Document* pDocument)
-{
-	return FALSE;
-}
-
-FX_BOOL	CFFL_FormFiller::CanPaste(CPDFSDK_Document* pDocument)
-{
-	return FALSE;
-}
-
-void CFFL_FormFiller::DoCopy(CPDFSDK_Document* pDocument)
-{
-}
-
-void CFFL_FormFiller::DoCut(CPDFSDK_Document* pDocument)
-{
-}
-
-void CFFL_FormFiller::DoPaste(CPDFSDK_Document* pDocument)
-{
-}
-
-void CFFL_FormFiller::InvalidateRect(double left, double top, double right, double bottom)
-{
-	CPDF_Page * pPage = m_pWidget->GetPDFPage();
-	m_pApp->FFI_Invalidate(pPage, left, top, right, bottom);
-}
-
-/* ------------------------- CFFL_Button ------------------------- */
-
-CFFL_Button::CFFL_Button(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget) :
-	CFFL_FormFiller(pApp, pWidget),
-	m_bMouseIn(FALSE),
-	m_bMouseDown(FALSE)
-{
-}
-
-CFFL_Button::~CFFL_Button()
-{
-}
-
-void CFFL_Button::OnMouseEnter(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
-{
-	m_bMouseIn = TRUE;
-	FX_RECT rect = this->GetViewBBox(pPageView,pAnnot);
-	this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-//	::InvalidateRect(pPageView->GetPageViewWnd(), &this->GetViewBBox(pPageView, pAnnot), TRUE);
-}
-
-void CFFL_Button::OnMouseExit(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
-{
-	m_bMouseIn = FALSE;
-
-	FX_RECT rect = this->GetViewBBox(pPageView,pAnnot);
-	this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-//	::InvalidateRect(pPageView->GetPageViewWnd(), &this->GetViewBBox(pPageView, pAnnot), TRUE);
-	EndTimer();
-	ASSERT(m_pWidget != NULL);
-//	m_pWidget->HideHint();
-}
-
-FX_BOOL CFFL_Button::OnLButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	CPDF_Rect rcAnnot = pAnnot->GetRect();
-	if(!rcAnnot.Contains(point.x, point.y))
-		return FALSE;
-
-	m_bMouseDown = TRUE;
-	m_bValid = TRUE;
-	FX_RECT rect = this->GetViewBBox(pPageView, pAnnot);
-	this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-//	::InvalidateRect(pPageView->GetPageViewWnd(), &this->GetViewBBox(pPageView, pAnnot), TRUE);
-	return TRUE;
-}
-
-FX_BOOL	CFFL_Button::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	CPDF_Rect rcAnnot = pAnnot->GetRect();
-	if(!rcAnnot.Contains(point.x, point.y))
-		return FALSE;
-
-	m_bMouseDown = FALSE;
-	m_pWidget->GetPDFPage();
-	
-
-	FX_RECT rect = this->GetViewBBox(pPageView, pAnnot);
-	this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
-// 	::InvalidateRect(pPageView->GetPageViewWnd(), &this->GetViewBBox(pPageView, pAnnot), TRUE);
-	return TRUE;
-}
-
-FX_BOOL	CFFL_Button::OnMouseMove(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	ASSERT(m_pApp != NULL);
-
-	return TRUE;
-}
-
-void CFFL_Button::OnDraw(CPDFSDK_PageView *pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
-							CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
-							/*const CRect& rcWindow,*/ FX_DWORD dwFlags)
-{
-	ASSERT(pPageView != NULL);
-	ASSERT(pAnnot != NULL);
-
-	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-
-	CPDF_FormControl* pCtrl = pWidget->GetFormControl();
-	ASSERT(pCtrl != NULL);
-
-	CPDF_FormControl::HighlightingMode eHM = pCtrl->GetHighlightingMode();
-
-	if (eHM == CPDF_FormControl::Push)
-	{
-		if (m_bMouseDown)
-		{
-			if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Down))
-				pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Down, NULL);
-			else
-				pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-		}
-		else if (m_bMouseIn)
-		{
-			if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Rollover))
-				pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Rollover, NULL);
-			else
-				pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-		}
-		else
-		{
-			pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-		}
-	}
-	else
-		pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-}
-
-
-void CFFL_Button::OnDrawDeactive(CPDFSDK_PageView *pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
-								 CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
-								 /*const CRect& rcWindow, */FX_DWORD dwFlags)
-{
-	OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
-}
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+ 
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+
+#include "../../include/formfiller/FFL_FormFiller.h"
+#include "../../include/formfiller/FFL_Notify.h"
+#include "../../include/formfiller/FFL_CBA_Fontmap.h"
+
+#define GetRed(rgb)			((FX_BYTE)(rgb))
+#define GetGreen(rgb)		((FX_BYTE)(((FX_WORD)(rgb)) >> 8))
+#define GetBlue(rgb)		((FX_BYTE)((rgb)>>16))
+
+#define FFL_HINT_ELAPSE		800
+
+/* ------------------------- CFFL_FormFiller ------------------------- */
+
+CFFL_FormFiller::CFFL_FormFiller(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot)
+	:m_pApp(pApp),
+	m_pAnnot(pAnnot),
+	m_bValid(FALSE),
+	m_ptOldPos(0,0)
+{ 
+	m_pWidget = (CPDFSDK_Widget*) pAnnot;
+}
+
+CFFL_FormFiller::~CFFL_FormFiller()
+{
+	FX_POSITION pos = m_Maps.GetStartPosition();
+	while (pos)
+	{
+		CPDFSDK_PageView * pPageView = NULL;
+		CPWL_Wnd* pWnd = NULL;
+		m_Maps.GetNextAssoc(pos, pPageView, pWnd);
+
+		if (pWnd)
+		{
+			CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
+			pWnd->Destroy();
+			delete pWnd;
+			delete pData;
+		}
+	}
+	m_Maps.RemoveAll();
+
+}
+
+void CFFL_FormFiller::SetWindowRect(CPDFSDK_PageView* pPageView, const CPDF_Rect& rcWindow)
+{
+	if (CPWL_Wnd* pWnd = this->GetPDFWindow(pPageView, FALSE))
+	{
+		pWnd->Move(CPDF_Rect(rcWindow), TRUE, FALSE);
+	}
+}
+
+CPDF_Rect CFFL_FormFiller::GetWindowRect(CPDFSDK_PageView* pPageView)
+{
+	if (CPWL_Wnd* pWnd = this->GetPDFWindow(pPageView, FALSE))
+	{
+		return pWnd->GetWindowRect();
+	}
+
+	return CPDF_Rect(0,0,0,0);
+}
+
+FX_RECT CFFL_FormFiller::GetViewBBox(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
+{
+	ASSERT(pPageView != NULL);
+	ASSERT(pAnnot != NULL);
+
+	CPDF_Rect rcAnnot = m_pWidget->GetRect();
+
+	if (CPWL_Wnd* pWnd = this->GetPDFWindow(pPageView, FALSE))
+	{
+		CPDF_Rect rcWindow = pWnd->GetWindowRect();
+		rcAnnot = PWLtoFFL(rcWindow);
+	}
+
+	CPDF_Rect rcWin = rcAnnot;
+//	pPageView->DocToWindow(rcAnnot, rcWin);
+
+	CPDF_Rect rcFocus = this->GetFocusBox(pPageView);
+	if (!rcFocus.IsEmpty())
+		rcWin.Union(rcFocus);
+
+	CPDF_Rect rect = CPWL_Utils::InflateRect(rcWin,1);
+
+	return rect.GetOutterRect();
+}
+
+void CFFL_FormFiller::OnDraw(CPDFSDK_PageView *pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
+						CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
+						/*const CRect& rcWindow,*/ FX_DWORD dwFlags)
+{
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
+	{
+		CPDF_Matrix mt = this->GetCurMatrix();
+		mt.Concat(*pUser2Device);
+		pWnd->DrawAppearance(pDevice,&mt);
+	}
+	else
+	{
+		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+		if (CFFL_IFormFiller::IsVisible(pWidget))
+			pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
+	}
+}
+
+void CFFL_FormFiller::OnDrawDeactive(CPDFSDK_PageView *pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
+						CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
+						/*const CRect& rcWindow,*/ FX_DWORD dwFlags)
+{
+	ASSERT(pAnnot != NULL);
+	
+	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+	
+	pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
+}
+
+
+void CFFL_FormFiller::OnCreate(CPDFSDK_Annot* pAnnot)
+{
+}
+
+void CFFL_FormFiller::OnLoad(CPDFSDK_Annot* pAnnot)
+{
+}
+
+void CFFL_FormFiller::OnDelete(CPDFSDK_Annot* pAnnot)
+{
+}
+
+void CFFL_FormFiller::OnMouseEnter(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
+{
+}
+
+void CFFL_FormFiller::OnMouseExit(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
+{
+	EndTimer();
+	ASSERT(m_pWidget != NULL);
+}
+
+FX_BOOL CFFL_FormFiller::OnLButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, TRUE))
+	{		
+		m_bValid = TRUE;
+		FX_RECT rect = this->GetViewBBox(pPageView,pAnnot);
+		this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+
+ 		if(!rect.Contains((int)point.x, (int)point.y))
+  			return FALSE;
+
+		return pWnd->OnLButtonDown(WndtoPWL(pPageView, point),nFlags);
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_FormFiller::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
+	{	
+		FX_RECT rcFFL =  this->GetViewBBox(pPageView, pAnnot);
+		this->InvalidateRect(rcFFL.left, rcFFL.top, rcFFL.right, rcFFL.bottom);
+		pWnd->OnLButtonUp(WndtoPWL(pPageView, point),nFlags);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_FormFiller::OnLButtonDblClk(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
+	{				
+		pWnd->OnLButtonDblClk(WndtoPWL(pPageView, point),nFlags);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+FX_BOOL CFFL_FormFiller::OnMouseMove(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	if ((m_ptOldPos.x != point.x) || (m_ptOldPos.y != point.y))
+	{
+		m_ptOldPos = point;
+	}
+
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
+	{				
+		pWnd->OnMouseMove(WndtoPWL(pPageView, point),nFlags);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+FX_BOOL CFFL_FormFiller::OnMouseWheel(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, short zDelta, const CPDF_Point& point)
+{
+	if (!IsValid()) return FALSE;
+
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, TRUE))
+	{				
+		return pWnd->OnMouseWheel(zDelta, WndtoPWL(pPageView, point),nFlags);
+	}
+
+	return FALSE;
+}
+
+FX_BOOL CFFL_FormFiller::OnRButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, TRUE))
+	{				
+		pWnd->OnRButtonDown(WndtoPWL(pPageView, point),nFlags);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_FormFiller::OnRButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
+	{				
+		pWnd->OnRButtonUp(WndtoPWL(pPageView, point),nFlags);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_FormFiller::OnRButtonDblClk(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
+	{				
+		pWnd->OnRButtonDblClk(WndtoPWL(pPageView, point),nFlags);
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+FX_BOOL CFFL_FormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot, FX_UINT nKeyCode, FX_UINT nFlags)
+{
+	if (IsValid())
+	{
+		CPDFSDK_PageView* pPageView = this->GetCurPageView();
+		ASSERT(pPageView != NULL);
+
+		if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
+		{				
+			return pWnd->OnKeyDown(nKeyCode,nFlags);
+		}
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_FormFiller::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
+{
+	if (IsValid())
+	{
+		CPDFSDK_PageView* pPageView = this->GetCurPageView();
+		ASSERT(pPageView != NULL);
+
+		if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
+		{				
+			return pWnd->OnChar(nChar,nFlags);
+		}
+	}
+
+	return FALSE;
+}
+
+void CFFL_FormFiller::OnDeSelected(CPDFSDK_Annot* pAnnot)
+{
+	ASSERT(FALSE);
+}
+
+void CFFL_FormFiller::OnSelected(CPDFSDK_Annot* pAnnot)
+{
+	ASSERT(FALSE);
+}
+
+FX_BOOL	CFFL_FormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
+{
+	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+
+	CPDF_Page * pPage = pWidget->GetPDFPage();
+ 	CPDFSDK_Document * pDoc = m_pApp->GetCurrentDoc();
+	CPDFSDK_PageView* pPageView = pDoc->GetPageView(pPage);
+ 	ASSERT(pPageView != NULL);
+
+ 	
+
+	CPWL_Wnd * pWnd = NULL;
+	if ( (pWnd = GetPDFWindow(pPageView, TRUE)))
+	{				
+		pWnd->SetFocus();
+	}
+
+	m_bValid = TRUE;
+	
+	
+	
+
+	m_bValid = TRUE;
+	FX_RECT rcRect = this->GetViewBBox(pPageView,pAnnot);
+	this->InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
+	
+	return TRUE;
+}
+
+FX_BOOL	CFFL_FormFiller::OnKillFocus(CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
+{
+	if (IsValid())
+	{
+		CPDFSDK_PageView* pPageView = this->GetCurPageView();
+		ASSERT(pPageView != NULL);
+
+		CommitData(pPageView, nFlag);
+
+		if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, FALSE))
+		{				
+			pWnd->KillFocus();
+		}
+		
+		switch (m_pWidget->GetFieldType())
+		{
+		case FIELDTYPE_PUSHBUTTON:
+		case FIELDTYPE_CHECKBOX:
+		case FIELDTYPE_RADIOBUTTON:
+			EscapeFiller(pPageView, TRUE);
+			break;
+		default:
+			EscapeFiller(pPageView, FALSE);
+			break;
+		}
+	}
+
+	return TRUE;
+}
+
+FX_BOOL	CFFL_FormFiller::IsValid() const
+{
+	return m_bValid;
+}
+
+PWL_CREATEPARAM	CFFL_FormFiller::GetCreateParam()
+{
+	ASSERT(m_pApp != NULL);
+
+	PWL_CREATEPARAM cp;
+
+	cp.pParentWnd = NULL;	
+	cp.pProvider = this;
+	cp.rcRectWnd = GetPDFWindowRect();
+	
+	FX_DWORD dwCreateFlags = PWS_BORDER | PWS_BACKGROUND | PWS_VISIBLE;
+
+	ASSERT(m_pWidget != NULL);
+
+
+	FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
+
+	if (dwFieldFlag & FIELDFLAG_READONLY)
+	{		
+		dwCreateFlags |= PWS_READONLY;
+	}
+
+	FX_COLORREF color;
+	if (m_pWidget->GetFillColor(color))
+	{
+		cp.sBackgroundColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
+	}
+
+	if (m_pWidget->GetBorderColor(color))
+	{
+		cp.sBorderColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
+	}
+
+	cp.sTextColor = CPWL_Color(COLORTYPE_GRAY,0);
+
+	if (m_pWidget->GetTextColor(color))
+	{
+		cp.sTextColor = CPWL_Color(GetRed(color), GetGreen(color), GetBlue(color));
+	}
+
+	cp.fFontSize = m_pWidget->GetFontSize();
+	cp.dwBorderWidth = m_pWidget->GetBorderWidth();
+	
+	int nBorderStyle = m_pWidget->GetBorderStyle();
+
+	switch (nBorderStyle)
+	{
+	case BBS_SOLID:
+		cp.nBorderStyle = PBS_SOLID;
+		break;
+	case BBS_DASH:
+		cp.nBorderStyle = PBS_DASH;
+		cp.sDash = CPWL_Dash(3,3,0);			
+		break;
+	case BBS_BEVELED:
+		cp.nBorderStyle = PBS_BEVELED;
+		cp.dwBorderWidth *= 2;
+		break;
+	case BBS_INSET:
+		cp.nBorderStyle = PBS_INSET;
+		cp.dwBorderWidth *= 2;
+		break;
+	case BBS_UNDERLINE:
+		cp.nBorderStyle = PBS_UNDERLINED;
+		break;
+	}
+
+	if (cp.fFontSize <= 0)
+	{
+		dwCreateFlags |= PWS_AUTOFONTSIZE;
+	}
+
+	cp.dwFlags = dwCreateFlags;
+	cp.pSystemHandler = m_pApp->GetSysHandler();
+	return cp;
+}
+
+CPWL_Wnd* CFFL_FormFiller::GetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bNew)
+{
+	ASSERT(pPageView != NULL);
+	ASSERT(m_pWidget != NULL);
+
+	CPWL_Wnd* pWnd = NULL;
+	m_Maps.Lookup(pPageView, pWnd);
+
+	if (bNew)
+	{
+		if (pWnd)
+		{
+			CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pWnd->GetAttachedData();
+			ASSERT(pPrivateData != NULL);
+
+			if (pPrivateData->nWidgetAge != m_pWidget->GetAppearanceAge())
+			{
+				return this->ResetPDFWindow(pPageView, m_pWidget->GetValueAge() == pPrivateData->nValueAge);
+			}
+		}
+		else
+		{
+			PWL_CREATEPARAM cp = GetCreateParam();
+			cp.hAttachedWnd = (FX_HWND)m_pWidget;
+
+			CFFL_PrivateData* pPrivateData = new CFFL_PrivateData;
+			pPrivateData->pWidget = m_pWidget;
+			pPrivateData->pPageView = pPageView;
+			pPrivateData->nWidgetAge = m_pWidget->GetAppearanceAge();
+                        pPrivateData->nValueAge = 0;
+
+			cp.pAttachedData = pPrivateData;
+
+			pWnd = NewPDFWindow(cp, pPageView);
+
+			if (pWnd)
+			{
+				m_Maps.SetAt(pPageView, pWnd);
+			}
+		}
+	}
+
+	return pWnd;
+}
+
+void CFFL_FormFiller::DestroyPDFWindow(CPDFSDK_PageView* pPageView)
+{
+	CPWL_Wnd* pWnd = NULL;
+	m_Maps.Lookup(pPageView, pWnd);
+
+	if (pWnd)
+	{
+		CFFL_PrivateData* pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
+		pData->pPageView = NULL;
+		pWnd->Destroy();
+		delete pWnd;
+		delete pData;
+	}
+
+	m_Maps.RemoveKey(pPageView);
+}
+
+CPDF_Matrix	CFFL_FormFiller::GetWindowMatrix(void* pAttachedData)
+{
+	if (CFFL_PrivateData* pPrivateData = (CFFL_PrivateData*)pAttachedData)
+	{
+		if (pPrivateData->pPageView)
+		{
+			CPDF_Matrix mtPageView;
+			pPrivateData->pPageView->GetCurrentMatrix(mtPageView);
+			CPDF_Matrix mt = GetCurMatrix();
+			mt.Concat(mtPageView);
+			
+			return mt;
+		}
+	}
+	return CPDF_Matrix(1,0,0,1,0,0);
+}
+
+CPDF_Matrix	CFFL_FormFiller::GetCurMatrix()
+{
+	CPDF_Matrix mt;
+
+	ASSERT(m_pWidget != NULL);
+
+	CPDF_Rect rcDA ;
+	m_pWidget->GetPDFAnnot()->GetRect(rcDA);
+
+
+	switch (m_pWidget->GetRotate())
+	{
+	default:
+	case 0:		
+		mt = CPDF_Matrix(1,0,0,1,0,0);
+		break;
+	case 90:
+		mt = CPDF_Matrix(0,1,-1,0,rcDA.right - rcDA.left,0);
+		break;
+	case 180:
+		mt = CPDF_Matrix(-1,0,0,-1,rcDA.right - rcDA.left,rcDA.top - rcDA.bottom);
+		break;
+	case 270:
+		mt = CPDF_Matrix(0,-1,1,0,0,rcDA.top - rcDA.bottom);
+		break;
+	}
+	mt.e += rcDA.left;
+	mt.f += rcDA.bottom;
+
+	return mt;
+}
+
+CFX_WideString CFFL_FormFiller::LoadPopupMenuString(int nIndex)
+{
+	ASSERT(m_pApp != NULL);
+
+	return L"";
+}
+
+CPDF_Rect CFFL_FormFiller::GetPDFWindowRect() const
+{
+	ASSERT(m_pWidget != NULL);
+
+	CPDF_Rect rectAnnot;
+	m_pWidget->GetPDFAnnot()->GetRect(rectAnnot);
+
+	FX_FLOAT fWidth = rectAnnot.right - rectAnnot.left;
+	FX_FLOAT fHeight = rectAnnot.top - rectAnnot.bottom;
+
+
+	if ((m_pWidget->GetRotate() / 90) & 0x01)
+		return CPDF_Rect(0,0,fHeight,fWidth);
+	else
+		return CPDF_Rect(0,0,fWidth,fHeight);
+}
+
+CPDFSDK_PageView* CFFL_FormFiller::GetCurPageView()
+{
+
+	CPDF_Page* pPage = m_pAnnot->GetPDFPage();
+	CPDFSDK_Document* pSDKDoc = m_pApp->GetCurrentDoc();
+	if(pSDKDoc)
+	{
+		return pSDKDoc->GetPageView(pPage);
+	}
+	return NULL;
+}
+
+CPDF_Rect CFFL_FormFiller::GetFocusBox(CPDFSDK_PageView* pPageView)
+{
+	if (CPWL_Wnd * pWnd = GetPDFWindow(pPageView, FALSE))
+	{			
+		CPDF_Rect rcFocus =  FFLtoWnd(pPageView, PWLtoFFL(pWnd->GetFocusRect()));
+		ASSERT(pPageView);
+		CPDF_Rect rcPage = pPageView->GetPDFPage()->GetPageBBox();
+		if(rcPage.Contains(rcFocus))
+			return rcFocus;
+		else
+			return CPDF_Rect(0,0,0,0);
+	}
+	return CPDF_Rect(0,0,0,0);
+}
+
+CPDF_Rect CFFL_FormFiller::FFLtoPWL(const CPDF_Rect& rect)
+{
+	CPDF_Matrix mt;
+	mt.SetReverse(GetCurMatrix());
+	
+	CPDF_Rect temp = rect;
+	mt.TransformRect(temp);
+
+	return temp;
+}
+
+CPDF_Rect CFFL_FormFiller::PWLtoFFL(const CPDF_Rect& rect)
+{
+	CPDF_Matrix mt = GetCurMatrix();
+	
+	CPDF_Rect temp = rect;
+	mt.TransformRect(temp);
+
+	return temp;
+}
+
+CPDF_Point CFFL_FormFiller::FFLtoPWL(const CPDF_Point& point)
+{
+	CPDF_Matrix mt;
+	mt.SetReverse(GetCurMatrix());
+
+	CPDF_Point pt = point;
+	mt.Transform(pt.x,pt.y);
+
+	return pt;
+}
+
+CPDF_Point CFFL_FormFiller::PWLtoFFL(const CPDF_Point & point)
+{
+	CPDF_Matrix mt = GetCurMatrix();
+
+	CPDF_Point pt = point;
+	mt.Transform(pt.x,pt.y);
+
+	return pt;
+}
+
+CPDF_Point CFFL_FormFiller::WndtoPWL(CPDFSDK_PageView* pPageView, const CPDF_Point& pt)
+{
+// 	ASSERT(pPageView != NULL);
+// 
+// 	CPDF_Point point(0.0f, 0.0f);
+// 	pPageView->WindowToDoc(pt.x, pt.y, point.x, point.y);
+// 
+ 	return FFLtoPWL(pt);
+//	return CPDF_Point(0, 0);
+}
+
+CPDF_Rect CFFL_FormFiller::FFLtoWnd(CPDFSDK_PageView* pPageView, const CPDF_Rect & rect)
+{
+// 	FX_RECT rcRet(0,0,0,0);
+// 
+// 	ASSERT(pPageView != NULL);	
+// 	pPageView->DocToWindow(rect, rcRet);
+// 	
+ 	return rect;
+
+}
+
+void CFFL_FormFiller::FFL_FreeData(void* pData)
+{
+	ASSERT(pData != NULL);
+
+	delete (CFFL_PrivateData*)pData;
+}
+
+FX_BOOL CFFL_FormFiller::CommitData(CPDFSDK_PageView* pPageView, FX_UINT nFlag)
+{
+	if (IsDataChanged(pPageView))
+	{
+		//CFFL_IFormFiller* pIFormFiller = CFFL_Module::GetFormFiller(m_pApp);
+		CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();//NULL;
+		ASSERT(pIFormFiller != NULL);
+
+		FX_BOOL bRC = TRUE;
+		FX_BOOL bExit = FALSE;
+
+		pIFormFiller->OnKeyStrokeCommit(m_pWidget, pPageView, bRC, bExit, nFlag);
+		if (bExit) return TRUE;
+		if (!bRC)
+		{
+			this->ResetPDFWindow(pPageView, FALSE);
+			return TRUE;
+		}
+
+		pIFormFiller->OnValidate(m_pWidget, pPageView, bRC, bExit, nFlag);
+		if (bExit) return TRUE;
+		if (!bRC)
+		{
+			this->ResetPDFWindow(pPageView, FALSE);
+			return TRUE;
+		}
+
+		SaveData(pPageView);
+
+		pIFormFiller->OnCalculate(m_pWidget, pPageView, bExit,nFlag);
+		if (bExit) return TRUE;
+
+		pIFormFiller->OnFormat(m_pWidget, pPageView, bExit,nFlag);
+	}
+
+	return TRUE;
+}
+
+FX_BOOL	CFFL_FormFiller::IsDataChanged(CPDFSDK_PageView* pPageView)
+{
+	return FALSE;
+}
+
+void CFFL_FormFiller::SaveData(CPDFSDK_PageView* pPageView)
+{
+}
+
+void CFFL_FormFiller::GetKeyStrokeData(CPDFSDK_PageView* pPageView, FFL_KeyStrokeData& data)
+{
+}
+
+void CFFL_FormFiller::SetChangeMark()
+{
+	m_pApp->FFI_OnChange();
+}
+
+void CFFL_FormFiller::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
+							PDFSDK_FieldAction& fa)
+{
+	fa.sValue = m_pWidget->GetValue();
+}
+
+void CFFL_FormFiller::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
+									const PDFSDK_FieldAction& fa)
+{
+}
+
+FX_BOOL	CFFL_FormFiller::IsActionDataChanged(CPDF_AAction::AActionType type, const PDFSDK_FieldAction& faOld, 
+									const PDFSDK_FieldAction& faNew)
+{
+	return FALSE;
+}
+
+void CFFL_FormFiller::SaveState(CPDFSDK_PageView* pPageView)
+{
+}
+
+void CFFL_FormFiller::RestoreState(CPDFSDK_PageView* pPageView)
+{
+}
+
+CPWL_Wnd*  CFFL_FormFiller::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
+{
+	return GetPDFWindow(pPageView, FALSE); 
+}
+
+void CFFL_FormFiller::TimerProc()
+{
+
+}
+
+IFX_SystemHandler* CFFL_FormFiller::GetSystemHandler() const
+{
+	return m_pApp->GetSysHandler();
+//	return NULL;
+}
+
+void CFFL_FormFiller::OnKeyStroke(FX_BOOL bKeyDown)
+{
+}
+
+void CFFL_FormFiller::EscapeFiller(CPDFSDK_PageView* pPageView, FX_BOOL bDestroyPDFWindow)
+{
+	m_bValid = FALSE;
+	
+	FX_RECT rcRect = this->GetViewBBox(pPageView, m_pWidget);
+	this->InvalidateRect(rcRect.left, rcRect.top, rcRect.right, rcRect.bottom);
+
+	if(bDestroyPDFWindow)
+ 		DestroyPDFWindow(pPageView);
+}
+
+FX_BOOL CFFL_FormFiller::CanCopy(CPDFSDK_Document* pDocument)
+{
+	return FALSE;
+}
+
+FX_BOOL CFFL_FormFiller::CanCut(CPDFSDK_Document* pDocument)
+{
+	return FALSE;
+}
+
+FX_BOOL	CFFL_FormFiller::CanPaste(CPDFSDK_Document* pDocument)
+{
+	return FALSE;
+}
+
+void CFFL_FormFiller::DoCopy(CPDFSDK_Document* pDocument)
+{
+}
+
+void CFFL_FormFiller::DoCut(CPDFSDK_Document* pDocument)
+{
+}
+
+void CFFL_FormFiller::DoPaste(CPDFSDK_Document* pDocument)
+{
+}
+
+void CFFL_FormFiller::InvalidateRect(double left, double top, double right, double bottom)
+{
+	CPDF_Page * pPage = m_pWidget->GetPDFPage();
+	m_pApp->FFI_Invalidate(pPage, left, top, right, bottom);
+}
+
+/* ------------------------- CFFL_Button ------------------------- */
+
+CFFL_Button::CFFL_Button(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget) :
+	CFFL_FormFiller(pApp, pWidget),
+	m_bMouseIn(FALSE),
+	m_bMouseDown(FALSE)
+{
+}
+
+CFFL_Button::~CFFL_Button()
+{
+}
+
+void CFFL_Button::OnMouseEnter(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
+{
+	m_bMouseIn = TRUE;
+	FX_RECT rect = this->GetViewBBox(pPageView,pAnnot);
+	this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+//	::InvalidateRect(pPageView->GetPageViewWnd(), &this->GetViewBBox(pPageView, pAnnot), TRUE);
+}
+
+void CFFL_Button::OnMouseExit(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot)
+{
+	m_bMouseIn = FALSE;
+
+	FX_RECT rect = this->GetViewBBox(pPageView,pAnnot);
+	this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+//	::InvalidateRect(pPageView->GetPageViewWnd(), &this->GetViewBBox(pPageView, pAnnot), TRUE);
+	EndTimer();
+	ASSERT(m_pWidget != NULL);
+//	m_pWidget->HideHint();
+}
+
+FX_BOOL CFFL_Button::OnLButtonDown(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	CPDF_Rect rcAnnot = pAnnot->GetRect();
+	if(!rcAnnot.Contains(point.x, point.y))
+		return FALSE;
+
+	m_bMouseDown = TRUE;
+	m_bValid = TRUE;
+	FX_RECT rect = this->GetViewBBox(pPageView, pAnnot);
+	this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+//	::InvalidateRect(pPageView->GetPageViewWnd(), &this->GetViewBBox(pPageView, pAnnot), TRUE);
+	return TRUE;
+}
+
+FX_BOOL	CFFL_Button::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	CPDF_Rect rcAnnot = pAnnot->GetRect();
+	if(!rcAnnot.Contains(point.x, point.y))
+		return FALSE;
+
+	m_bMouseDown = FALSE;
+	m_pWidget->GetPDFPage();
+	
+
+	FX_RECT rect = this->GetViewBBox(pPageView, pAnnot);
+	this->InvalidateRect(rect.left, rect.top, rect.right, rect.bottom);
+// 	::InvalidateRect(pPageView->GetPageViewWnd(), &this->GetViewBBox(pPageView, pAnnot), TRUE);
+	return TRUE;
+}
+
+FX_BOOL	CFFL_Button::OnMouseMove(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	ASSERT(m_pApp != NULL);
+
+	return TRUE;
+}
+
+void CFFL_Button::OnDraw(CPDFSDK_PageView *pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
+							CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
+							/*const CRect& rcWindow,*/ FX_DWORD dwFlags)
+{
+	ASSERT(pPageView != NULL);
+	ASSERT(pAnnot != NULL);
+
+	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+
+	CPDF_FormControl* pCtrl = pWidget->GetFormControl();
+	ASSERT(pCtrl != NULL);
+
+	CPDF_FormControl::HighlightingMode eHM = pCtrl->GetHighlightingMode();
+
+	if (eHM == CPDF_FormControl::Push)
+	{
+		if (m_bMouseDown)
+		{
+			if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Down))
+				pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Down, NULL);
+			else
+				pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
+		}
+		else if (m_bMouseIn)
+		{
+			if (pWidget->IsWidgetAppearanceValid(CPDF_Annot::Rollover))
+				pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Rollover, NULL);
+			else
+				pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
+		}
+		else
+		{
+			pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
+		}
+	}
+	else
+		pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
+}
+
+
+void CFFL_Button::OnDrawDeactive(CPDFSDK_PageView *pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
+								 CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
+								 /*const CRect& rcWindow, */FX_DWORD dwFlags)
+{
+	OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
+}
