diff --git a/fpdfsdk/src/formfiller/FFL_CBA_Fontmap.cpp b/fpdfsdk/src/formfiller/FFL_CBA_Fontmap.cpp
index 59617ac..0c7cd48 100644
--- a/fpdfsdk/src/formfiller/FFL_CBA_Fontmap.cpp
+++ b/fpdfsdk/src/formfiller/FFL_CBA_Fontmap.cpp
@@ -1,300 +1,300 @@
-// 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/FormFiller.h"
-#include "../../include/formfiller/FFL_CBA_Fontmap.h"
-
-CBA_FontMap::CBA_FontMap(CPDFSDK_Annot* pAnnot, IFX_SystemHandler* pSystemHandler) :
-	CPWL_FontMap(pSystemHandler),
-	m_pDocument(NULL),
-	m_pAnnotDict(NULL),
-	m_pDefaultFont(NULL),
-	m_sAPType("N")
-{
-	ASSERT(pAnnot != NULL);
-
-	CPDF_Page* pPage = pAnnot->GetPDFPage();
-
-	m_pDocument = pPage->m_pDocument;
-	m_pAnnotDict = pAnnot->GetPDFAnnot()->m_pAnnotDict;
-}
-
-CBA_FontMap::CBA_FontMap(CPDF_Document* pDocument, CPDF_Dictionary* pAnnotDict, 
-						 IFX_SystemHandler* pSystemHandler) :
-	CPWL_FontMap(pSystemHandler),
-	m_pDocument(pDocument),
-	m_pAnnotDict(pAnnotDict),
-	m_pDefaultFont(NULL),
-	m_sAPType("N")
-{
-}
-
-CBA_FontMap::~CBA_FontMap()
-{
-}
-
-void CBA_FontMap::Reset()
-{
-	Empty();
-	m_pDefaultFont = NULL;
-	m_sDefaultFontName = "";
-}
-
-void CBA_FontMap::Initial(FX_LPCSTR fontname)
-{
-	FX_INT32 nCharset = DEFAULT_CHARSET;
-
-	if (!m_pDefaultFont)
-	{
-		m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName);	
-		if (m_pDefaultFont)
-		{
-			if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
-				nCharset = pSubstFont->m_Charset;
-			else
-			{
-				if (m_sDefaultFontName == "Wingdings" || m_sDefaultFontName == "Wingdings2" ||
-					m_sDefaultFontName == "Wingdings3" || m_sDefaultFontName == "Webdings")
-						nCharset = SYMBOL_CHARSET;
-				else
-					nCharset = ANSI_CHARSET;
-			}
-			AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
-			AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
-		}
-	}
-
-	if (nCharset != ANSI_CHARSET)
-		CPWL_FontMap::Initial(fontname);
-}
-
-void CBA_FontMap::SetDefaultFont(CPDF_Font * pFont, const CFX_ByteString & sFontName)
-{
-	ASSERT(pFont != NULL);
-
-	if (m_pDefaultFont) return;
-
-	m_pDefaultFont = pFont;
-	m_sDefaultFontName = sFontName;
-
-//	if (m_sDefaultFontName.IsEmpty())
-//		m_sDefaultFontName = pFont->GetFontTypeName();
-
-	FX_INT32 nCharset = DEFAULT_CHARSET;
-	if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
-		nCharset = pSubstFont->m_Charset;
-	AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
-}
-
-CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias, FX_INT32 nCharset)
-{
-	ASSERT(m_pAnnotDict != NULL);
-
-	if (m_pAnnotDict->GetString("Subtype") == "Widget")
-	{
-		CPDF_Document* pDocument = GetDocument();
-		ASSERT(pDocument != NULL);
-
-		CPDF_Dictionary * pRootDict = pDocument->GetRoot();
-		if (!pRootDict) return NULL;
-
-		CPDF_Dictionary* pAcroFormDict = pRootDict->GetDict("AcroForm");
-		if (!pAcroFormDict) return NULL;
-
-		CPDF_Dictionary * pDRDict = pAcroFormDict->GetDict("DR");
-		if (!pDRDict) return NULL;
-
-		return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
-	}
-
-	return NULL;
-}
-
-CPDF_Document* CBA_FontMap::GetDocument()
-{
-	return m_pDocument;
-}
-
-CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict, CFX_ByteString& sFontAlias, 
-													FX_INT32 nCharset)
-{
-	if (!pResDict) return NULL;
-
-	CPDF_Document* pDocument = GetDocument();
-	ASSERT(pDocument != NULL);
-
-	CPDF_Dictionary* pFonts = pResDict->GetDict("Font");
-	if (pFonts == NULL) return NULL;
-
-	CPDF_Font* pFind = NULL;
-
-	FX_POSITION pos = pFonts->GetStartPos();
-	while (pos)
-	{
-		CPDF_Object* pObj = NULL;
-		CFX_ByteString csKey;
-		pObj = pFonts->GetNextElement(pos, csKey);
-		if (pObj == NULL) continue;
-
-		CPDF_Object* pDirect = pObj->GetDirect();
-		if (pDirect == NULL || pDirect->GetType() != PDFOBJ_DICTIONARY) continue;
-
-		CPDF_Dictionary* pElement = (CPDF_Dictionary*)pDirect;
-		if (pElement->GetString("Type") != "Font") continue;
-
-		CPDF_Font* pFont = pDocument->LoadFont(pElement);
-		if (pFont == NULL) continue;
-		const CFX_SubstFont* pSubst = pFont->GetSubstFont();
-		if (pSubst == NULL) continue;
-		if (pSubst->m_Charset == nCharset)
-		{
-			sFontAlias = csKey;
-			pFind = pFont;
-		}
-	}
-	return pFind;
-}
-
-void CBA_FontMap::AddedFont(CPDF_Font* pFont, const CFX_ByteString& sFontAlias)
-{
-	AddFontToAnnotDict(pFont, sFontAlias);
-}
-
-void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont, const CFX_ByteString& sAlias)
-{
-	if (!pFont)	return;
-
-	ASSERT(m_pAnnotDict != NULL);
-	ASSERT(m_pDocument != NULL);
-
-	CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDict("AP");
-
-	if (pAPDict == NULL) 
-	{
-		pAPDict = FX_NEW CPDF_Dictionary;
-		m_pAnnotDict->SetAt("AP", pAPDict);
-	}
-
-	//to avoid checkbox and radiobutton
-	CPDF_Object* pObject = pAPDict->GetElement(m_sAPType);
-	if (pObject && pObject->GetType() == PDFOBJ_DICTIONARY)
-		return;
-
-	CPDF_Stream* pStream = pAPDict->GetStream(m_sAPType);
-	if (pStream == NULL) 
-	{
-		pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
-		FX_INT32 objnum = m_pDocument->AddIndirectObject(pStream);
-		pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum);
-	}
-
-	CPDF_Dictionary * pStreamDict = pStream->GetDict();
-
-	if (!pStreamDict)
-	{
-		pStreamDict = FX_NEW CPDF_Dictionary;
-		pStream->InitStream(NULL, 0, pStreamDict);
-	}
-
-	if (pStreamDict)
-	{
-		CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
-		if (!pStreamResList)
-		{
-			pStreamResList = FX_NEW CPDF_Dictionary();
-			pStreamDict->SetAt("Resources", pStreamResList);
-		}
-
-		if (pStreamResList) 
-		{
-			CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDict("Font");
-			if (!pStreamResFontList) 
-			{
-				pStreamResFontList = FX_NEW CPDF_Dictionary;
-				FX_INT32 objnum = m_pDocument->AddIndirectObject(pStreamResFontList);
-				pStreamResList->SetAtReference("Font", m_pDocument, objnum);
-			}
-			if (!pStreamResFontList->KeyExist(sAlias))
-				pStreamResFontList->SetAtReference(sAlias, m_pDocument, pFont->GetFontDict());
-		}
-	}
-}
-
-CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString &sAlias)
-{
-	ASSERT(m_pAnnotDict != NULL);
-	ASSERT(m_pDocument != NULL);
-
-	CPDF_Dictionary* pAcroFormDict = NULL;
-
-	FX_BOOL bWidget = (m_pAnnotDict->GetString("Subtype") == "Widget");
-
-	if (bWidget)
-	{
-		if (CPDF_Dictionary * pRootDict = m_pDocument->GetRoot())
-			pAcroFormDict = pRootDict->GetDict("AcroForm");
-	}
-	
-	CFX_ByteString sDA;
-	
-	sDA = FPDF_GetFieldAttr(m_pAnnotDict, "DA")->GetString();
-
-	if (bWidget)
-	{
-		if (sDA.IsEmpty())
-		{
-			sDA = FPDF_GetFieldAttr(pAcroFormDict, "DA")->GetString();	
-		}
-	}
-	
-	CPDF_Dictionary * pFontDict = NULL;	
-
-	if (!sDA.IsEmpty())
-	{
-		CPDF_SimpleParser syntax(sDA);
-		syntax.FindTagParam("Tf", 2);
-		CFX_ByteString sFontName = syntax.GetWord();
-		sAlias = PDF_NameDecode(sFontName).Mid(1);
-
-		if (CPDF_Dictionary * pDRDict = m_pAnnotDict->GetDict("DR"))
-			if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDict("Font"))
-				pFontDict = pDRFontDict->GetDict(sAlias);
-
-		if (!pFontDict)
-			if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDict("AP"))
-				if (CPDF_Dictionary* pNormalDict = pAPDict->GetDict("N"))
-					if (CPDF_Dictionary* pNormalResDict = pNormalDict->GetDict("Resources"))
-						if (CPDF_Dictionary* pResFontDict = pNormalResDict->GetDict("Font"))
-							pFontDict = pResFontDict->GetDict(sAlias);
-
-		if (bWidget)
-		{			
-			if (!pFontDict)
-			{
-				if (pAcroFormDict)
-				{
-					if (CPDF_Dictionary * pDRDict = pAcroFormDict->GetDict("DR"))
-						if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDict("Font"))
-							pFontDict = pDRFontDict->GetDict(sAlias);
-				}
-			}
-		}
-	}
-
-	if (pFontDict)
-		return m_pDocument->LoadFont(pFontDict);
-	else
-		return NULL;
-}
-
-void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType)
-{
-	m_sAPType = sAPType;
-
-	Reset();
-	Initial();
-}
-
+// 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/FormFiller.h"
+#include "../../include/formfiller/FFL_CBA_Fontmap.h"
+
+CBA_FontMap::CBA_FontMap(CPDFSDK_Annot* pAnnot, IFX_SystemHandler* pSystemHandler) :
+	CPWL_FontMap(pSystemHandler),
+	m_pDocument(NULL),
+	m_pAnnotDict(NULL),
+	m_pDefaultFont(NULL),
+	m_sAPType("N")
+{
+	ASSERT(pAnnot != NULL);
+
+	CPDF_Page* pPage = pAnnot->GetPDFPage();
+
+	m_pDocument = pPage->m_pDocument;
+	m_pAnnotDict = pAnnot->GetPDFAnnot()->m_pAnnotDict;
+}
+
+CBA_FontMap::CBA_FontMap(CPDF_Document* pDocument, CPDF_Dictionary* pAnnotDict, 
+						 IFX_SystemHandler* pSystemHandler) :
+	CPWL_FontMap(pSystemHandler),
+	m_pDocument(pDocument),
+	m_pAnnotDict(pAnnotDict),
+	m_pDefaultFont(NULL),
+	m_sAPType("N")
+{
+}
+
+CBA_FontMap::~CBA_FontMap()
+{
+}
+
+void CBA_FontMap::Reset()
+{
+	Empty();
+	m_pDefaultFont = NULL;
+	m_sDefaultFontName = "";
+}
+
+void CBA_FontMap::Initial(FX_LPCSTR fontname)
+{
+	FX_INT32 nCharset = DEFAULT_CHARSET;
+
+	if (!m_pDefaultFont)
+	{
+		m_pDefaultFont = GetAnnotDefaultFont(m_sDefaultFontName);	
+		if (m_pDefaultFont)
+		{
+			if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
+				nCharset = pSubstFont->m_Charset;
+			else
+			{
+				if (m_sDefaultFontName == "Wingdings" || m_sDefaultFontName == "Wingdings2" ||
+					m_sDefaultFontName == "Wingdings3" || m_sDefaultFontName == "Webdings")
+						nCharset = SYMBOL_CHARSET;
+				else
+					nCharset = ANSI_CHARSET;
+			}
+			AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
+			AddFontToAnnotDict(m_pDefaultFont, m_sDefaultFontName);
+		}
+	}
+
+	if (nCharset != ANSI_CHARSET)
+		CPWL_FontMap::Initial(fontname);
+}
+
+void CBA_FontMap::SetDefaultFont(CPDF_Font * pFont, const CFX_ByteString & sFontName)
+{
+	ASSERT(pFont != NULL);
+
+	if (m_pDefaultFont) return;
+
+	m_pDefaultFont = pFont;
+	m_sDefaultFontName = sFontName;
+
+//	if (m_sDefaultFontName.IsEmpty())
+//		m_sDefaultFontName = pFont->GetFontTypeName();
+
+	FX_INT32 nCharset = DEFAULT_CHARSET;
+	if (const CFX_SubstFont* pSubstFont = m_pDefaultFont->GetSubstFont())
+		nCharset = pSubstFont->m_Charset;
+	AddFontData(m_pDefaultFont, m_sDefaultFontName, nCharset);
+}
+
+CPDF_Font* CBA_FontMap::FindFontSameCharset(CFX_ByteString& sFontAlias, FX_INT32 nCharset)
+{
+	ASSERT(m_pAnnotDict != NULL);
+
+	if (m_pAnnotDict->GetString("Subtype") == "Widget")
+	{
+		CPDF_Document* pDocument = GetDocument();
+		ASSERT(pDocument != NULL);
+
+		CPDF_Dictionary * pRootDict = pDocument->GetRoot();
+		if (!pRootDict) return NULL;
+
+		CPDF_Dictionary* pAcroFormDict = pRootDict->GetDict("AcroForm");
+		if (!pAcroFormDict) return NULL;
+
+		CPDF_Dictionary * pDRDict = pAcroFormDict->GetDict("DR");
+		if (!pDRDict) return NULL;
+
+		return FindResFontSameCharset(pDRDict, sFontAlias, nCharset);
+	}
+
+	return NULL;
+}
+
+CPDF_Document* CBA_FontMap::GetDocument()
+{
+	return m_pDocument;
+}
+
+CPDF_Font* CBA_FontMap::FindResFontSameCharset(CPDF_Dictionary* pResDict, CFX_ByteString& sFontAlias, 
+													FX_INT32 nCharset)
+{
+	if (!pResDict) return NULL;
+
+	CPDF_Document* pDocument = GetDocument();
+	ASSERT(pDocument != NULL);
+
+	CPDF_Dictionary* pFonts = pResDict->GetDict("Font");
+	if (pFonts == NULL) return NULL;
+
+	CPDF_Font* pFind = NULL;
+
+	FX_POSITION pos = pFonts->GetStartPos();
+	while (pos)
+	{
+		CPDF_Object* pObj = NULL;
+		CFX_ByteString csKey;
+		pObj = pFonts->GetNextElement(pos, csKey);
+		if (pObj == NULL) continue;
+
+		CPDF_Object* pDirect = pObj->GetDirect();
+		if (pDirect == NULL || pDirect->GetType() != PDFOBJ_DICTIONARY) continue;
+
+		CPDF_Dictionary* pElement = (CPDF_Dictionary*)pDirect;
+		if (pElement->GetString("Type") != "Font") continue;
+
+		CPDF_Font* pFont = pDocument->LoadFont(pElement);
+		if (pFont == NULL) continue;
+		const CFX_SubstFont* pSubst = pFont->GetSubstFont();
+		if (pSubst == NULL) continue;
+		if (pSubst->m_Charset == nCharset)
+		{
+			sFontAlias = csKey;
+			pFind = pFont;
+		}
+	}
+	return pFind;
+}
+
+void CBA_FontMap::AddedFont(CPDF_Font* pFont, const CFX_ByteString& sFontAlias)
+{
+	AddFontToAnnotDict(pFont, sFontAlias);
+}
+
+void CBA_FontMap::AddFontToAnnotDict(CPDF_Font* pFont, const CFX_ByteString& sAlias)
+{
+	if (!pFont)	return;
+
+	ASSERT(m_pAnnotDict != NULL);
+	ASSERT(m_pDocument != NULL);
+
+	CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDict("AP");
+
+	if (pAPDict == NULL) 
+	{
+		pAPDict = FX_NEW CPDF_Dictionary;
+		m_pAnnotDict->SetAt("AP", pAPDict);
+	}
+
+	//to avoid checkbox and radiobutton
+	CPDF_Object* pObject = pAPDict->GetElement(m_sAPType);
+	if (pObject && pObject->GetType() == PDFOBJ_DICTIONARY)
+		return;
+
+	CPDF_Stream* pStream = pAPDict->GetStream(m_sAPType);
+	if (pStream == NULL) 
+	{
+		pStream = FX_NEW CPDF_Stream(NULL, 0, NULL);
+		FX_INT32 objnum = m_pDocument->AddIndirectObject(pStream);
+		pAPDict->SetAtReference(m_sAPType, m_pDocument, objnum);
+	}
+
+	CPDF_Dictionary * pStreamDict = pStream->GetDict();
+
+	if (!pStreamDict)
+	{
+		pStreamDict = FX_NEW CPDF_Dictionary;
+		pStream->InitStream(NULL, 0, pStreamDict);
+	}
+
+	if (pStreamDict)
+	{
+		CPDF_Dictionary* pStreamResList = pStreamDict->GetDict("Resources");
+		if (!pStreamResList)
+		{
+			pStreamResList = FX_NEW CPDF_Dictionary();
+			pStreamDict->SetAt("Resources", pStreamResList);
+		}
+
+		if (pStreamResList) 
+		{
+			CPDF_Dictionary* pStreamResFontList = pStreamResList->GetDict("Font");
+			if (!pStreamResFontList) 
+			{
+				pStreamResFontList = FX_NEW CPDF_Dictionary;
+				FX_INT32 objnum = m_pDocument->AddIndirectObject(pStreamResFontList);
+				pStreamResList->SetAtReference("Font", m_pDocument, objnum);
+			}
+			if (!pStreamResFontList->KeyExist(sAlias))
+				pStreamResFontList->SetAtReference(sAlias, m_pDocument, pFont->GetFontDict());
+		}
+	}
+}
+
+CPDF_Font* CBA_FontMap::GetAnnotDefaultFont(CFX_ByteString &sAlias)
+{
+	ASSERT(m_pAnnotDict != NULL);
+	ASSERT(m_pDocument != NULL);
+
+	CPDF_Dictionary* pAcroFormDict = NULL;
+
+	FX_BOOL bWidget = (m_pAnnotDict->GetString("Subtype") == "Widget");
+
+	if (bWidget)
+	{
+		if (CPDF_Dictionary * pRootDict = m_pDocument->GetRoot())
+			pAcroFormDict = pRootDict->GetDict("AcroForm");
+	}
+	
+	CFX_ByteString sDA;
+	
+	sDA = FPDF_GetFieldAttr(m_pAnnotDict, "DA")->GetString();
+
+	if (bWidget)
+	{
+		if (sDA.IsEmpty())
+		{
+			sDA = FPDF_GetFieldAttr(pAcroFormDict, "DA")->GetString();	
+		}
+	}
+	
+	CPDF_Dictionary * pFontDict = NULL;	
+
+	if (!sDA.IsEmpty())
+	{
+		CPDF_SimpleParser syntax(sDA);
+		syntax.FindTagParam("Tf", 2);
+		CFX_ByteString sFontName = syntax.GetWord();
+		sAlias = PDF_NameDecode(sFontName).Mid(1);
+
+		if (CPDF_Dictionary * pDRDict = m_pAnnotDict->GetDict("DR"))
+			if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDict("Font"))
+				pFontDict = pDRFontDict->GetDict(sAlias);
+
+		if (!pFontDict)
+			if (CPDF_Dictionary* pAPDict = m_pAnnotDict->GetDict("AP"))
+				if (CPDF_Dictionary* pNormalDict = pAPDict->GetDict("N"))
+					if (CPDF_Dictionary* pNormalResDict = pNormalDict->GetDict("Resources"))
+						if (CPDF_Dictionary* pResFontDict = pNormalResDict->GetDict("Font"))
+							pFontDict = pResFontDict->GetDict(sAlias);
+
+		if (bWidget)
+		{			
+			if (!pFontDict)
+			{
+				if (pAcroFormDict)
+				{
+					if (CPDF_Dictionary * pDRDict = pAcroFormDict->GetDict("DR"))
+						if (CPDF_Dictionary* pDRFontDict = pDRDict->GetDict("Font"))
+							pFontDict = pDRFontDict->GetDict(sAlias);
+				}
+			}
+		}
+	}
+
+	if (pFontDict)
+		return m_pDocument->LoadFont(pFontDict);
+	else
+		return NULL;
+}
+
+void CBA_FontMap::SetAPType(const CFX_ByteString& sAPType)
+{
+	m_sAPType = sAPType;
+
+	Reset();
+	Initial();
+}
+
diff --git a/fpdfsdk/src/formfiller/FFL_CheckBox.cpp b/fpdfsdk/src/formfiller/FFL_CheckBox.cpp
index db79926..f8035c7 100644
--- a/fpdfsdk/src/formfiller/FFL_CheckBox.cpp
+++ b/fpdfsdk/src/formfiller/FFL_CheckBox.cpp
@@ -1,144 +1,144 @@
-// 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/FormFiller.h"
-#include "../../include/formfiller/FFL_FormFiller.h"
-#include "../../include/formfiller/FFL_CheckBox.h"
-
-
-/* ------------------------------- CFFL_CheckBox ------------------------------- */
-
-CFFL_CheckBox::CFFL_CheckBox(CPDFDoc_Environment* pApp, CPDFSDK_Widget* pWidget) :
-	CFFL_Button(pApp, pWidget)
-{
-}
-
-CFFL_CheckBox::~CFFL_CheckBox()
-{
-}
-
-CPWL_Wnd* CFFL_CheckBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
-{
-	CPWL_CheckBox* pWnd = new CPWL_CheckBox();
-	pWnd->Create(cp);
-
-	ASSERT(m_pWidget != NULL);
-	pWnd->SetCheck(m_pWidget->IsChecked());
-	
-	return pWnd;
-}
-
-FX_BOOL	CFFL_CheckBox::OnKeyDown(CPDFSDK_Annot* pAnnot, FX_UINT nKeyCode, FX_UINT nFlags)
-{
-	switch (nKeyCode)
-	{
-	case FWL_VKEY_Return:
-	case FWL_VKEY_Space:
-		return TRUE;
-	default:
-		return CFFL_FormFiller::OnKeyDown(pAnnot, nKeyCode, nFlags);
-	}
-}
-FX_BOOL	CFFL_CheckBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
-{
-	switch (nChar)
-	{
-	case FWL_VKEY_Return:	
-	case FWL_VKEY_Space:
-		{
-			CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
-			ASSERT(pIFormFiller != NULL);
-
-			CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
-			ASSERT(pPageView != NULL);
-
-			FX_BOOL bReset = FALSE;
-			FX_BOOL bExit = FALSE;
-
-			pIFormFiller->OnButtonUp(m_pWidget, pPageView, bReset, bExit,nFlags);
-
-			if (bReset) return TRUE;
-			if (bExit) return TRUE;
-
-			CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-
-			if (CPWL_CheckBox * pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, TRUE))
-				pWnd->SetCheck(!pWnd->IsChecked());
-
-			CommitData(pPageView,nFlags);
-			return TRUE;
-		}
-	default:
-		return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-	}
-}
-
-FX_BOOL CFFL_CheckBox::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point);
-
-	if (IsValid())
-	{
-		if (CPWL_CheckBox * pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, TRUE))
-		{
-			CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-			pWnd->SetCheck(!pWidget->IsChecked());
-		//	pWnd->SetCheck(!pWnd->IsChecked());
-		}
-
-		if (!CommitData(pPageView, nFlags)) return FALSE;
-	}
-
-	return TRUE;
-}
-
-FX_BOOL	CFFL_CheckBox::IsDataChanged(CPDFSDK_PageView* pPageView)
-{
-
-	ASSERT(m_pWidget != NULL);
-
-	if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		return pWnd->IsChecked() != m_pWidget->IsChecked();
-	}
-
-	return FALSE;
-}
-
-void CFFL_CheckBox::SaveData(CPDFSDK_PageView* pPageView)
-{
-
-	ASSERT(m_pWidget != NULL);
-
-	if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		
-		FX_BOOL bNewChecked = pWnd->IsChecked();
-		
-
-		if (bNewChecked)
-		{
-			CPDF_FormField* pField = m_pWidget->GetFormField();
-			ASSERT(pField != NULL);
-
-			for (FX_INT32 i=0,sz=pField->CountControls(); i<sz; i++)
-			{
-				if (CPDF_FormControl* pCtrl = pField->GetControl(i))
-				{
-					if (pCtrl->IsChecked())
-					{
-						break;
-					}
-				}
-			}
-		}
-
-		m_pWidget->SetCheck(bNewChecked, FALSE);
-		m_pWidget->UpdateField();
-		SetChangeMark();
-	}
-
-}
+// 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/FormFiller.h"
+#include "../../include/formfiller/FFL_FormFiller.h"
+#include "../../include/formfiller/FFL_CheckBox.h"
+
+
+/* ------------------------------- CFFL_CheckBox ------------------------------- */
+
+CFFL_CheckBox::CFFL_CheckBox(CPDFDoc_Environment* pApp, CPDFSDK_Widget* pWidget) :
+	CFFL_Button(pApp, pWidget)
+{
+}
+
+CFFL_CheckBox::~CFFL_CheckBox()
+{
+}
+
+CPWL_Wnd* CFFL_CheckBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
+{
+	CPWL_CheckBox* pWnd = new CPWL_CheckBox();
+	pWnd->Create(cp);
+
+	ASSERT(m_pWidget != NULL);
+	pWnd->SetCheck(m_pWidget->IsChecked());
+	
+	return pWnd;
+}
+
+FX_BOOL	CFFL_CheckBox::OnKeyDown(CPDFSDK_Annot* pAnnot, FX_UINT nKeyCode, FX_UINT nFlags)
+{
+	switch (nKeyCode)
+	{
+	case FWL_VKEY_Return:
+	case FWL_VKEY_Space:
+		return TRUE;
+	default:
+		return CFFL_FormFiller::OnKeyDown(pAnnot, nKeyCode, nFlags);
+	}
+}
+FX_BOOL	CFFL_CheckBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
+{
+	switch (nChar)
+	{
+	case FWL_VKEY_Return:	
+	case FWL_VKEY_Space:
+		{
+			CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
+			ASSERT(pIFormFiller != NULL);
+
+			CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+			ASSERT(pPageView != NULL);
+
+			FX_BOOL bReset = FALSE;
+			FX_BOOL bExit = FALSE;
+
+			pIFormFiller->OnButtonUp(m_pWidget, pPageView, bReset, bExit,nFlags);
+
+			if (bReset) return TRUE;
+			if (bExit) return TRUE;
+
+			CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+
+			if (CPWL_CheckBox * pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, TRUE))
+				pWnd->SetCheck(!pWnd->IsChecked());
+
+			CommitData(pPageView,nFlags);
+			return TRUE;
+		}
+	default:
+		return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+	}
+}
+
+FX_BOOL CFFL_CheckBox::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point);
+
+	if (IsValid())
+	{
+		if (CPWL_CheckBox * pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, TRUE))
+		{
+			CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+			pWnd->SetCheck(!pWidget->IsChecked());
+		//	pWnd->SetCheck(!pWnd->IsChecked());
+		}
+
+		if (!CommitData(pPageView, nFlags)) return FALSE;
+	}
+
+	return TRUE;
+}
+
+FX_BOOL	CFFL_CheckBox::IsDataChanged(CPDFSDK_PageView* pPageView)
+{
+
+	ASSERT(m_pWidget != NULL);
+
+	if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		return pWnd->IsChecked() != m_pWidget->IsChecked();
+	}
+
+	return FALSE;
+}
+
+void CFFL_CheckBox::SaveData(CPDFSDK_PageView* pPageView)
+{
+
+	ASSERT(m_pWidget != NULL);
+
+	if (CPWL_CheckBox* pWnd = (CPWL_CheckBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		
+		FX_BOOL bNewChecked = pWnd->IsChecked();
+		
+
+		if (bNewChecked)
+		{
+			CPDF_FormField* pField = m_pWidget->GetFormField();
+			ASSERT(pField != NULL);
+
+			for (FX_INT32 i=0,sz=pField->CountControls(); i<sz; i++)
+			{
+				if (CPDF_FormControl* pCtrl = pField->GetControl(i))
+				{
+					if (pCtrl->IsChecked())
+					{
+						break;
+					}
+				}
+			}
+		}
+
+		m_pWidget->SetCheck(bNewChecked, FALSE);
+		m_pWidget->UpdateField();
+		SetChangeMark();
+	}
+
+}
diff --git a/fpdfsdk/src/formfiller/FFL_ComboBox.cpp b/fpdfsdk/src/formfiller/FFL_ComboBox.cpp
index 3f2c453..ee6b7bd 100644
--- a/fpdfsdk/src/formfiller/FFL_ComboBox.cpp
+++ b/fpdfsdk/src/formfiller/FFL_ComboBox.cpp
@@ -1,442 +1,442 @@
-// 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/FormFiller.h"
-#include "../../include/formfiller/FFL_FormFiller.h"
-#include "../../include/formfiller/FFL_IFormFiller.h"
-#include "../../include/formfiller/FFL_CBA_Fontmap.h"
-#include "../../include/formfiller/FFL_ComboBox.h"
-
-
-/* ------------------------------- CFFL_ComboBox ------------------------------- */
-
-CFFL_ComboBox::CFFL_ComboBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot) :
-	CFFL_FormFiller(pApp, pAnnot), m_pFontMap( NULL )
-{
-	//m_pFontMap = new CBA_FontMap( pAnnot, GetSystemHandler() );
-        m_State.nIndex = 0;
-        m_State.nStart = 0;
-        m_State.nEnd   = 0;
-}
-
-CFFL_ComboBox::~CFFL_ComboBox()
-{
-	if (m_pFontMap)
-	{
-		delete m_pFontMap;
-		m_pFontMap = NULL;
-	}
-
-// 	for (int i=0,sz=m_IMBox.GetSize(); i<sz; i++)
-// 	{
-// 		delete m_IMBox.GetAt(i);
-// 	}
-// 
-// 	m_IMBox.RemoveAll();
-}
-
-PWL_CREATEPARAM CFFL_ComboBox::GetCreateParam()
-{
-	PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
-
-	ASSERT(m_pWidget != NULL);
-
-	int nFlags = m_pWidget->GetFieldFlags();
-	
-	if (nFlags & FIELDFLAG_EDIT)
-	{		
-		cp.dwFlags |= PCBS_ALLOWCUSTOMTEXT;
-	}
-
-	/*
-	if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
-	{		
-		m_bCommitOnSelectChange = TRUE;
-	}
-	*/
-
-	if (!m_pFontMap)
-	{
-		ASSERT(this->m_pApp != NULL);
-		m_pFontMap = new CBA_FontMap(m_pWidget, GetSystemHandler());
-		m_pFontMap->Initial();
-	}
-
-	cp.pFontMap = m_pFontMap;
-	cp.pFocusHandler = this;
-
-	return cp;
-}
-
-CPWL_Wnd* CFFL_ComboBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
-{
-	CPWL_ComboBox * pWnd = new CPWL_ComboBox();
-	pWnd->AttachFFLData(this);
-	pWnd->Create(cp);
-
-	ASSERT(m_pApp != NULL);
-	CFFL_IFormFiller* pFormFiller = m_pApp->GetIFormFiller();
-	pWnd->SetFillerNotify(pFormFiller);
-
-	ASSERT(m_pWidget != NULL);
-	FX_INT32 nCurSel = m_pWidget->GetSelectedIndex(0);
-	
-	CFX_WideString swText;
-	
-	if (nCurSel < 0)
-		swText = m_pWidget->GetValue();
-	else
-		swText = m_pWidget->GetOptionLabel(nCurSel);
-	
-	for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
-	{
-		pWnd->AddString(m_pWidget->GetOptionLabel(i));			
-	}
-	
-	pWnd->SetSelect(nCurSel);
-	pWnd->SetText(swText);
-	
-	return pWnd;
-}
-
-
-FX_BOOL	CFFL_ComboBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
-{
-	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-}
-
-FX_BOOL	CFFL_ComboBox::IsDataChanged(CPDFSDK_PageView* pPageView)
-{
-	if (CPWL_ComboBox * pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		FX_INT32 nCurSel = pWnd->GetSelect();
-
-		ASSERT(m_pWidget != NULL);
-
-		if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)
-		{
-			if (nCurSel >= 0)
-			{
-				return nCurSel != m_pWidget->GetSelectedIndex(0);
-			}
-			else
-			{
-				return pWnd->GetText() != m_pWidget->GetValue();
-			}
-		}
-		else
-		{
-			return nCurSel != m_pWidget->GetSelectedIndex(0);
-		}
-	}
-	
-	return FALSE;
-}
-
-void CFFL_ComboBox::SaveData(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(m_pWidget != NULL);
-
-	if (CPWL_ComboBox* pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		CFX_WideString swText = pWnd->GetText();
-		FX_INT32 nCurSel = pWnd->GetSelect();
-
-		//mantis:0004157
-		FX_BOOL bSetValue = TRUE;
-
-		if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)
-		{
-			if (nCurSel >= 0)
-			{
-				if (swText != m_pWidget->GetOptionLabel(nCurSel))
-					bSetValue = TRUE;
-				else
-					bSetValue = FALSE;
-			}
-			else
-				bSetValue = TRUE;
-		}
-		else
-			bSetValue = FALSE;
-
-		CFX_WideString sOldValue;
-		
-
-		if (bSetValue)
-		{
-			sOldValue = m_pWidget->GetValue();
-			m_pWidget->SetValue(swText, FALSE);
-		}
-		else
-		{
-			m_pWidget->GetSelectedIndex(0);
-			m_pWidget->SetOptionSelection(nCurSel, TRUE, FALSE);
-		}
-
-		m_pWidget->ResetFieldAppearance(TRUE);
-		m_pWidget->UpdateField();
-		SetChangeMark();
-
-		m_pWidget->GetPDFPage();
-		
-
-	}
-}
-
- void CFFL_ComboBox::GetActionData( CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, PDFSDK_FieldAction& fa)
-{
-	switch (type)
-	{
-	case CPDF_AAction::KeyStroke:
-		if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
-		{
-			if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
-			{
-				fa.bFieldFull = pEdit->IsTextFull();	
-				int nSelStart = 0;
-				int nSelEnd = 0;
-				pEdit->GetSel(nSelStart, nSelEnd);
-				fa.nSelEnd = nSelEnd;
-				fa.nSelStart = nSelStart;
-				fa.sValue = pEdit->GetText();
-				fa.sChangeEx = GetSelectExportText();
-
-				if (fa.bFieldFull)
-				{
-					fa.sChange = L"";
-					fa.sChangeEx = L"";
-				}
-			}
-		}
-		break;
-	case CPDF_AAction::Validate:
-		if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
-		{
-			if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
-			{
-				fa.sValue = pEdit->GetText();
-			}
-		}
-		break;
-	case CPDF_AAction::LoseFocus:
-	case CPDF_AAction::GetFocus:
-		ASSERT(m_pWidget != NULL);
-		fa.sValue = m_pWidget->GetValue();
-		break;
-	default:
-		break;
-	}
-}
-
-
-
-void CFFL_ComboBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
-									const PDFSDK_FieldAction& fa)
-{
-	switch (type)
-	{
-	case CPDF_AAction::KeyStroke:
-		if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
-		{
-			if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
-			{
-				pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
-				pEdit->ReplaceSel(fa.sChange);
-			}
-		}
-		break;
-	default:
-		break;
-	}
-}
-
-FX_BOOL	CFFL_ComboBox::IsActionDataChanged(CPDF_AAction::AActionType type, const PDFSDK_FieldAction& faOld, 
-									const PDFSDK_FieldAction& faNew)
-{
-	switch (type)
-	{
-	case CPDF_AAction::KeyStroke:
-		return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) || faOld.nSelStart != faNew.nSelStart ||
-			faOld.sChange != faNew.sChange;
-	default:
-		break;
-	}
-
-	return FALSE;
-}
-
-void CFFL_ComboBox::SaveState(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(pPageView != NULL);
-
-	if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		m_State.nIndex = pComboBox->GetSelect();
-
-		if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
-		{
-			pEdit->GetSel(m_State.nStart, m_State.nEnd);
-			m_State.sValue = pEdit->GetText();
-		}
-	}
-}
-
-void CFFL_ComboBox::RestoreState(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(pPageView != NULL);
-
-	if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, TRUE))
-	{
-		if (m_State.nIndex >= 0)
-			pComboBox->SetSelect(m_State.nIndex);
-		else
-		{
-			if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
-			{
-				pEdit->SetText(m_State.sValue);
-				pEdit->SetSel(m_State.nStart, m_State.nEnd);
-			}
-		}
-	}
-}
-
-CPWL_Wnd* CFFL_ComboBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
-{
-	if (bRestoreValue)
-		SaveState(pPageView);
-	
-	DestroyPDFWindow(pPageView);
-	
-	CPWL_Wnd* pRet = NULL;
-	
-	if (bRestoreValue)
-	{
-		RestoreState(pPageView);
-		pRet = this->GetPDFWindow(pPageView, FALSE);
-	}
-	else
-		pRet = this->GetPDFWindow(pPageView, TRUE);
-	
-	m_pWidget->UpdateField();
-	
-	return pRet;
-}
-
-void CFFL_ComboBox::OnKeyStroke(FX_BOOL bKeyDown, FX_UINT nFlag)
-{
-	ASSERT(m_pWidget != NULL);
-	
-	int nFlags = m_pWidget->GetFieldFlags();
-	
-	if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
-	{
-		if (m_bValid)
-		{
-			CPDFSDK_PageView* pPageView = this->GetCurPageView();
-			ASSERT(pPageView != NULL);
-
-			if (CommitData(pPageView, nFlag))
-			{
-				DestroyPDFWindow(pPageView);
-				m_bValid = FALSE;
-			}
-		}
-	}
-}
-
-void CFFL_ComboBox::OnSetFocus(CPWL_Wnd* pWnd)
-{
-	ASSERT(m_pApp != NULL);
-
-	ASSERT(pWnd != NULL);
-
-	if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT)
-	{
-		CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
-		pEdit->SetCharSet(134);
-		pEdit->SetCodePage(936);
-
-		pEdit->SetReadyToInput();
-		CFX_WideString wsText = pEdit->GetText();
-		int nCharacters = wsText.GetLength();
-		CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
-		unsigned short* pBuffer = (unsigned short*)(FX_LPCSTR)bsUTFText;
-		m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer, nCharacters, TRUE);
-
- 		pEdit->SetEditNotify(this);
-	}
-}
-
-void CFFL_ComboBox::OnKillFocus(CPWL_Wnd* pWnd)
-{
-	ASSERT(m_pApp != NULL);
-}
-
-FX_BOOL	CFFL_ComboBox::CanCopy(CPDFSDK_Document* pDocument)
-{
-	ASSERT(pDocument != NULL);
-
-	return FALSE;
-}
-
-FX_BOOL CFFL_ComboBox::CanCut(CPDFSDK_Document* pDocument)
-{
-	ASSERT(pDocument != NULL);
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_ComboBox::CanPaste(CPDFSDK_Document* pDocument)
-{
-	ASSERT(pDocument != NULL);
-
-	return FALSE;
-}
-
-void CFFL_ComboBox::DoCopy(CPDFSDK_Document* pDocument)
-{
-	ASSERT(pDocument != NULL);
-}
-
-void CFFL_ComboBox::DoCut(CPDFSDK_Document* pDocument)
-{
-	ASSERT(pDocument != NULL);
-}
-
-void CFFL_ComboBox::DoPaste(CPDFSDK_Document* pDocument)
-{
-	ASSERT(pDocument != NULL);
-}
-
-void CFFL_ComboBox::OnAddUndo(CPWL_Edit* pEdit)
-{
-	ASSERT(pEdit != NULL);
-}
-
-CFX_WideString CFFL_ComboBox::GetSelectExportText()
-{
-	CFX_WideString swRet;
-	
-	int nExport = -1;
-	CPDFSDK_PageView *pPageView = GetCurPageView();
-	if (CPWL_ComboBox * pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		nExport = pComboBox->GetSelect();
-	}
-	
-	if (nExport >= 0)
-	{
-		if (CPDF_FormField * pFormField = m_pWidget->GetFormField())
-		{
-			swRet = pFormField->GetOptionValue(nExport);
-			if (swRet.IsEmpty())
-				swRet = pFormField->GetOptionLabel(nExport);
-		}
-	}
-	
-	return swRet;
-}
+// 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/FormFiller.h"
+#include "../../include/formfiller/FFL_FormFiller.h"
+#include "../../include/formfiller/FFL_IFormFiller.h"
+#include "../../include/formfiller/FFL_CBA_Fontmap.h"
+#include "../../include/formfiller/FFL_ComboBox.h"
+
+
+/* ------------------------------- CFFL_ComboBox ------------------------------- */
+
+CFFL_ComboBox::CFFL_ComboBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot) :
+	CFFL_FormFiller(pApp, pAnnot), m_pFontMap( NULL )
+{
+	//m_pFontMap = new CBA_FontMap( pAnnot, GetSystemHandler() );
+        m_State.nIndex = 0;
+        m_State.nStart = 0;
+        m_State.nEnd   = 0;
+}
+
+CFFL_ComboBox::~CFFL_ComboBox()
+{
+	if (m_pFontMap)
+	{
+		delete m_pFontMap;
+		m_pFontMap = NULL;
+	}
+
+// 	for (int i=0,sz=m_IMBox.GetSize(); i<sz; i++)
+// 	{
+// 		delete m_IMBox.GetAt(i);
+// 	}
+// 
+// 	m_IMBox.RemoveAll();
+}
+
+PWL_CREATEPARAM CFFL_ComboBox::GetCreateParam()
+{
+	PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
+
+	ASSERT(m_pWidget != NULL);
+
+	int nFlags = m_pWidget->GetFieldFlags();
+	
+	if (nFlags & FIELDFLAG_EDIT)
+	{		
+		cp.dwFlags |= PCBS_ALLOWCUSTOMTEXT;
+	}
+
+	/*
+	if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
+	{		
+		m_bCommitOnSelectChange = TRUE;
+	}
+	*/
+
+	if (!m_pFontMap)
+	{
+		ASSERT(this->m_pApp != NULL);
+		m_pFontMap = new CBA_FontMap(m_pWidget, GetSystemHandler());
+		m_pFontMap->Initial();
+	}
+
+	cp.pFontMap = m_pFontMap;
+	cp.pFocusHandler = this;
+
+	return cp;
+}
+
+CPWL_Wnd* CFFL_ComboBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
+{
+	CPWL_ComboBox * pWnd = new CPWL_ComboBox();
+	pWnd->AttachFFLData(this);
+	pWnd->Create(cp);
+
+	ASSERT(m_pApp != NULL);
+	CFFL_IFormFiller* pFormFiller = m_pApp->GetIFormFiller();
+	pWnd->SetFillerNotify(pFormFiller);
+
+	ASSERT(m_pWidget != NULL);
+	FX_INT32 nCurSel = m_pWidget->GetSelectedIndex(0);
+	
+	CFX_WideString swText;
+	
+	if (nCurSel < 0)
+		swText = m_pWidget->GetValue();
+	else
+		swText = m_pWidget->GetOptionLabel(nCurSel);
+	
+	for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
+	{
+		pWnd->AddString(m_pWidget->GetOptionLabel(i));			
+	}
+	
+	pWnd->SetSelect(nCurSel);
+	pWnd->SetText(swText);
+	
+	return pWnd;
+}
+
+
+FX_BOOL	CFFL_ComboBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
+{
+	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+}
+
+FX_BOOL	CFFL_ComboBox::IsDataChanged(CPDFSDK_PageView* pPageView)
+{
+	if (CPWL_ComboBox * pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		FX_INT32 nCurSel = pWnd->GetSelect();
+
+		ASSERT(m_pWidget != NULL);
+
+		if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)
+		{
+			if (nCurSel >= 0)
+			{
+				return nCurSel != m_pWidget->GetSelectedIndex(0);
+			}
+			else
+			{
+				return pWnd->GetText() != m_pWidget->GetValue();
+			}
+		}
+		else
+		{
+			return nCurSel != m_pWidget->GetSelectedIndex(0);
+		}
+	}
+	
+	return FALSE;
+}
+
+void CFFL_ComboBox::SaveData(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(m_pWidget != NULL);
+
+	if (CPWL_ComboBox* pWnd = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		CFX_WideString swText = pWnd->GetText();
+		FX_INT32 nCurSel = pWnd->GetSelect();
+
+		//mantis:0004157
+		FX_BOOL bSetValue = TRUE;
+
+		if (m_pWidget->GetFieldFlags() & FIELDFLAG_EDIT)
+		{
+			if (nCurSel >= 0)
+			{
+				if (swText != m_pWidget->GetOptionLabel(nCurSel))
+					bSetValue = TRUE;
+				else
+					bSetValue = FALSE;
+			}
+			else
+				bSetValue = TRUE;
+		}
+		else
+			bSetValue = FALSE;
+
+		CFX_WideString sOldValue;
+		
+
+		if (bSetValue)
+		{
+			sOldValue = m_pWidget->GetValue();
+			m_pWidget->SetValue(swText, FALSE);
+		}
+		else
+		{
+			m_pWidget->GetSelectedIndex(0);
+			m_pWidget->SetOptionSelection(nCurSel, TRUE, FALSE);
+		}
+
+		m_pWidget->ResetFieldAppearance(TRUE);
+		m_pWidget->UpdateField();
+		SetChangeMark();
+
+		m_pWidget->GetPDFPage();
+		
+
+	}
+}
+
+ void CFFL_ComboBox::GetActionData( CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, PDFSDK_FieldAction& fa)
+{
+	switch (type)
+	{
+	case CPDF_AAction::KeyStroke:
+		if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
+		{
+			if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
+			{
+				fa.bFieldFull = pEdit->IsTextFull();	
+				int nSelStart = 0;
+				int nSelEnd = 0;
+				pEdit->GetSel(nSelStart, nSelEnd);
+				fa.nSelEnd = nSelEnd;
+				fa.nSelStart = nSelStart;
+				fa.sValue = pEdit->GetText();
+				fa.sChangeEx = GetSelectExportText();
+
+				if (fa.bFieldFull)
+				{
+					fa.sChange = L"";
+					fa.sChangeEx = L"";
+				}
+			}
+		}
+		break;
+	case CPDF_AAction::Validate:
+		if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
+		{
+			if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
+			{
+				fa.sValue = pEdit->GetText();
+			}
+		}
+		break;
+	case CPDF_AAction::LoseFocus:
+	case CPDF_AAction::GetFocus:
+		ASSERT(m_pWidget != NULL);
+		fa.sValue = m_pWidget->GetValue();
+		break;
+	default:
+		break;
+	}
+}
+
+
+
+void CFFL_ComboBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
+									const PDFSDK_FieldAction& fa)
+{
+	switch (type)
+	{
+	case CPDF_AAction::KeyStroke:
+		if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
+		{
+			if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
+			{
+				pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
+				pEdit->ReplaceSel(fa.sChange);
+			}
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+FX_BOOL	CFFL_ComboBox::IsActionDataChanged(CPDF_AAction::AActionType type, const PDFSDK_FieldAction& faOld, 
+									const PDFSDK_FieldAction& faNew)
+{
+	switch (type)
+	{
+	case CPDF_AAction::KeyStroke:
+		return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) || faOld.nSelStart != faNew.nSelStart ||
+			faOld.sChange != faNew.sChange;
+	default:
+		break;
+	}
+
+	return FALSE;
+}
+
+void CFFL_ComboBox::SaveState(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(pPageView != NULL);
+
+	if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		m_State.nIndex = pComboBox->GetSelect();
+
+		if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
+		{
+			pEdit->GetSel(m_State.nStart, m_State.nEnd);
+			m_State.sValue = pEdit->GetText();
+		}
+	}
+}
+
+void CFFL_ComboBox::RestoreState(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(pPageView != NULL);
+
+	if (CPWL_ComboBox* pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, TRUE))
+	{
+		if (m_State.nIndex >= 0)
+			pComboBox->SetSelect(m_State.nIndex);
+		else
+		{
+			if (CPWL_Edit* pEdit = (CPWL_Edit*)*pComboBox)
+			{
+				pEdit->SetText(m_State.sValue);
+				pEdit->SetSel(m_State.nStart, m_State.nEnd);
+			}
+		}
+	}
+}
+
+CPWL_Wnd* CFFL_ComboBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
+{
+	if (bRestoreValue)
+		SaveState(pPageView);
+	
+	DestroyPDFWindow(pPageView);
+	
+	CPWL_Wnd* pRet = NULL;
+	
+	if (bRestoreValue)
+	{
+		RestoreState(pPageView);
+		pRet = this->GetPDFWindow(pPageView, FALSE);
+	}
+	else
+		pRet = this->GetPDFWindow(pPageView, TRUE);
+	
+	m_pWidget->UpdateField();
+	
+	return pRet;
+}
+
+void CFFL_ComboBox::OnKeyStroke(FX_BOOL bKeyDown, FX_UINT nFlag)
+{
+	ASSERT(m_pWidget != NULL);
+	
+	int nFlags = m_pWidget->GetFieldFlags();
+	
+	if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
+	{
+		if (m_bValid)
+		{
+			CPDFSDK_PageView* pPageView = this->GetCurPageView();
+			ASSERT(pPageView != NULL);
+
+			if (CommitData(pPageView, nFlag))
+			{
+				DestroyPDFWindow(pPageView);
+				m_bValid = FALSE;
+			}
+		}
+	}
+}
+
+void CFFL_ComboBox::OnSetFocus(CPWL_Wnd* pWnd)
+{
+	ASSERT(m_pApp != NULL);
+
+	ASSERT(pWnd != NULL);
+
+	if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT)
+	{
+		CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
+		pEdit->SetCharSet(134);
+		pEdit->SetCodePage(936);
+
+		pEdit->SetReadyToInput();
+		CFX_WideString wsText = pEdit->GetText();
+		int nCharacters = wsText.GetLength();
+		CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
+		unsigned short* pBuffer = (unsigned short*)(FX_LPCSTR)bsUTFText;
+		m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer, nCharacters, TRUE);
+
+ 		pEdit->SetEditNotify(this);
+	}
+}
+
+void CFFL_ComboBox::OnKillFocus(CPWL_Wnd* pWnd)
+{
+	ASSERT(m_pApp != NULL);
+}
+
+FX_BOOL	CFFL_ComboBox::CanCopy(CPDFSDK_Document* pDocument)
+{
+	ASSERT(pDocument != NULL);
+
+	return FALSE;
+}
+
+FX_BOOL CFFL_ComboBox::CanCut(CPDFSDK_Document* pDocument)
+{
+	ASSERT(pDocument != NULL);
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_ComboBox::CanPaste(CPDFSDK_Document* pDocument)
+{
+	ASSERT(pDocument != NULL);
+
+	return FALSE;
+}
+
+void CFFL_ComboBox::DoCopy(CPDFSDK_Document* pDocument)
+{
+	ASSERT(pDocument != NULL);
+}
+
+void CFFL_ComboBox::DoCut(CPDFSDK_Document* pDocument)
+{
+	ASSERT(pDocument != NULL);
+}
+
+void CFFL_ComboBox::DoPaste(CPDFSDK_Document* pDocument)
+{
+	ASSERT(pDocument != NULL);
+}
+
+void CFFL_ComboBox::OnAddUndo(CPWL_Edit* pEdit)
+{
+	ASSERT(pEdit != NULL);
+}
+
+CFX_WideString CFFL_ComboBox::GetSelectExportText()
+{
+	CFX_WideString swRet;
+	
+	int nExport = -1;
+	CPDFSDK_PageView *pPageView = GetCurPageView();
+	if (CPWL_ComboBox * pComboBox = (CPWL_ComboBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		nExport = pComboBox->GetSelect();
+	}
+	
+	if (nExport >= 0)
+	{
+		if (CPDF_FormField * pFormField = m_pWidget->GetFormField())
+		{
+			swRet = pFormField->GetOptionValue(nExport);
+			if (swRet.IsEmpty())
+				swRet = pFormField->GetOptionLabel(nExport);
+		}
+	}
+	
+	return swRet;
+}
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);
+}
diff --git a/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp b/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp
index 686b38c..2b21e13 100644
--- a/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp
+++ b/fpdfsdk/src/formfiller/FFL_IFormFiller.cpp
@@ -1,1197 +1,1197 @@
-// 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_IFormFiller.h"
-#include "../../include/formfiller/FFL_CheckBox.h"
-#include "../../include/formfiller/FFL_ComboBox.h"
-#include "../../include/formfiller/FFL_ListBox.h"
-#include "../../include/formfiller/FFL_PushButton.h"
-#include "../../include/formfiller/FFL_RadioButton.h"
-#include "../../include/formfiller/FFL_TextField.h"
-
-#define FFL_MAXLISTBOXHEIGHT		140.0f
-
-// HHOOK CFFL_IFormFiller::m_hookSheet = NULL;
-// MSG CFFL_IFormFiller::g_Msg;
-
-/* ----------------------------- CFFL_IFormFiller ----------------------------- */
-
-CFFL_IFormFiller::CFFL_IFormFiller(CPDFDoc_Environment* pApp) : 
-	m_pApp(pApp),
-	m_bNotifying(FALSE)
-{
-}
-
-CFFL_IFormFiller::~CFFL_IFormFiller()
-{
-	FX_POSITION pos = m_Maps.GetStartPosition();
-	while (pos)
-	{
-		CPDFSDK_Annot * pAnnot = NULL;
-		CFFL_FormFiller * pFormFiller = NULL;
-		m_Maps.GetNextAssoc(pos,pAnnot,pFormFiller);
-		delete pFormFiller;
-	}
-	m_Maps.RemoveAll();
-}
-
-FX_BOOL	CFFL_IFormFiller::Annot_HitTest(CPDFSDK_PageView* pPageView,CPDFSDK_Annot* pAnnot, CPDF_Point point)
-{
-	CPDF_Rect rc = pAnnot->GetRect();
-	if(rc.Contains(point.x, point.y))
-		return TRUE;
-	return FALSE;
-}
-
-FX_RECT CFFL_IFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot)
-{
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		return pFormFiller->GetViewBBox(pPageView, pAnnot);
-	}
-	else
-	{
-		ASSERT(pPageView != NULL);
-		ASSERT(pAnnot != NULL);
-
-		CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
-		ASSERT(pPDFAnnot != NULL);
-
-		CPDF_Rect rcAnnot;
-		pPDFAnnot->GetRect(rcAnnot);
-
-// 		CRect rcWin;
-// 		pPageView->DocToWindow(rcAnnot, rcWin);
-		CPDF_Rect rcWin = CPWL_Utils::InflateRect(rcAnnot,1);
-//		rcWin.InflateRect(1, 1);
-
-		return rcWin.GetOutterRect();
-	}
-}
-
-void CFFL_IFormFiller::OnDraw(CPDFSDK_PageView* pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
-						CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
-						/*const CRect& rcWindow,*/ FX_DWORD dwFlags)
-{
-	ASSERT(pPageView != NULL);
-	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-
-	if (IsVisible(pWidget))
-	{
-		if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-		{
- 			if (pFormFiller->IsValid())
- 			{
-				pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
-				
-				pAnnot->GetPDFPage();
-				
-
-				CPDFSDK_Document* pDocument = m_pApp->GetCurrentDoc();
-				ASSERT(pDocument != NULL);
-
-				if (pDocument->GetFocusAnnot() == pAnnot)
-				{
-					CPDF_Rect rcFocus = pFormFiller->GetFocusBox(pPageView);
-					if (!rcFocus.IsEmpty())
-					{
-						CFX_PathData path;
-						
-						path.SetPointCount(5);
-						path.SetPoint(0, rcFocus.left,  rcFocus.top, FXPT_MOVETO);
-						path.SetPoint(1, rcFocus.left,  rcFocus.bottom, FXPT_LINETO);
-						path.SetPoint(2, rcFocus.right,  rcFocus.bottom, FXPT_LINETO);
-						path.SetPoint(3, rcFocus.right,  rcFocus.top, FXPT_LINETO);
-						path.SetPoint(4, rcFocus.left,  rcFocus.top, FXPT_LINETO);
-						
-						CFX_GraphStateData gsd;
-						gsd.SetDashCount(1);				
-						gsd.m_DashArray[0] = 1.0f;
-						gsd.m_DashPhase = 0;	
-						
-						gsd.m_LineWidth = 1.0f;
-						pDevice->DrawPath(&path, pUser2Device, &gsd, 0, ArgbEncode(255,0,0,0), FXFILL_ALTERNATE);
-
-					//	::DrawFocusRect(hDC, &rcFocus);	
-					}
-				}
-
-				return;
-			}
-		}
-
-		if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-			pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
-		else
-			pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
-
-		if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget))
-		{
-			pWidget->DrawShadow(pDevice, pPageView);
-		}
-	
-	}
-}
-
-void CFFL_IFormFiller::OnCreate(CPDFSDK_Annot* pAnnot)
-{
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		pFormFiller->OnCreate(pAnnot);
-	}
-}
-
-void CFFL_IFormFiller::OnLoad(CPDFSDK_Annot* pAnnot)
-{
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		pFormFiller->OnLoad(pAnnot);
-	}
-}
-
-void CFFL_IFormFiller::OnDelete(CPDFSDK_Annot* pAnnot)
-{
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		pFormFiller->OnDelete(pAnnot);
-	}
-
-	UnRegisterFormFiller(pAnnot);
-}
-
-void CFFL_IFormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-	
-	if (!m_bNotifying)
-	{
-		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-		if (pWidget->GetAAction(CPDF_AAction::CursorEnter))
-		{
-			m_bNotifying = TRUE;
-			
-			int nValueAge = pWidget->GetValueAge();
-
-			pWidget->ClearAppModified();
-			
-			ASSERT(pPageView != NULL);
-			
-			
-			
-			PDFSDK_FieldAction fa;
-			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
- 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-			pWidget->OnAAction(CPDF_AAction::CursorEnter, fa, pPageView );
-			m_bNotifying = FALSE;
-			
-			//if ( !IsValidAnnot(pPageView, pAnnot) ) return;
-			
-			if (pWidget->IsAppModified())
-			{
-				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
-				{
-					pFormFiller->ResetPDFWindow(pPageView, pWidget->GetValueAge() == nValueAge);
-				}
-			}
-		}
-	}
-	
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
-	{
-		pFormFiller->OnMouseEnter(pPageView, pAnnot);
-	}
-}
-
-void CFFL_IFormFiller::OnMouseExit(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-	
-	if (!m_bNotifying)
-	{
-		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-		if (pWidget->GetAAction(CPDF_AAction::CursorExit))
-		{
-			m_bNotifying = TRUE;
-			pWidget->GetAppearanceAge();
-			int nValueAge = pWidget->GetValueAge();
-			pWidget->ClearAppModified();
-			
-			ASSERT(pPageView != NULL);
-			
-			
-			
-			PDFSDK_FieldAction fa;
-			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
- 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-			
-			pWidget->OnAAction(CPDF_AAction::CursorExit, fa, pPageView);
-			m_bNotifying = FALSE;
-			
-			//if (!IsValidAnnot(pPageView, pAnnot)) return;
-			
-			if (pWidget->IsAppModified())
-			{
-				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
-				{
-					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
-				}
-			}
-		}
-	}
-	
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		pFormFiller->OnMouseExit(pPageView, pAnnot);
-	}
-}
-
-FX_BOOL	CFFL_IFormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-	
-	if (!m_bNotifying)
-	{
-		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-		if (Annot_HitTest(pPageView, pAnnot, point) && pWidget->GetAAction(CPDF_AAction::ButtonDown))
-		{
-			m_bNotifying = TRUE;
-			pWidget->GetAppearanceAge();
-			int nValueAge = pWidget->GetValueAge();
-			pWidget->ClearAppModified();
-			
-			ASSERT(pPageView != NULL);
-			
-			
-			
-			PDFSDK_FieldAction fa;
-			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlags);
- 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlags);
-			pWidget->OnAAction(CPDF_AAction::ButtonDown, fa, pPageView);
-			m_bNotifying = FALSE;
-			
-			if (!IsValidAnnot(pPageView, pAnnot)) return TRUE;
-			
-			if (pWidget->IsAppModified())
-			{
-				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
-				{
-					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
-				}
-			}
-		}
-	}
-	
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		return pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
-	}
-	
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-	
-	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
-	// 	CReader_Page* pPage = pAnnot->GetPage();
-	// 	ASSERT(pPage != NULL);
-	CPDFSDK_Document* pDocument = m_pApp->GetCurrentDoc();
-	ASSERT(pDocument != NULL);		
-	
-	switch (pWidget->GetFieldType())
-	{
-	case FIELDTYPE_PUSHBUTTON:
-	case FIELDTYPE_CHECKBOX:
-	case FIELDTYPE_RADIOBUTTON:
-		if (GetViewBBox(pPageView, pAnnot).Contains((int)point.x, (int)point.y))
-		{
-			pDocument->SetFocusAnnot(pAnnot);
-		}
-		break;
-	default:
-		pDocument->SetFocusAnnot(pAnnot);
-		break;
-	}
-	
-	FX_BOOL bRet = FALSE;
-	
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		bRet = pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
-	}
-
-	if (pDocument->GetFocusAnnot() == pAnnot)
-	{
-		FX_BOOL bExit = FALSE;
-		FX_BOOL bReset = FALSE;
-		OnButtonUp(pWidget, pPageView, bReset, bExit,nFlags);
-		if (bExit) return TRUE;
-	}
-	return bRet;
-}
-
-void CFFL_IFormFiller::OnButtonUp(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit,FX_UINT nFlag)
-{
-	ASSERT(pWidget != NULL);
-	
-	if (!m_bNotifying)
-	{
-		if (pWidget->GetAAction(CPDF_AAction::ButtonUp))
-		{
-			m_bNotifying = TRUE;
-			int nAge = pWidget->GetAppearanceAge();
-			int nValueAge = pWidget->GetValueAge();
-			
-			ASSERT(pPageView != NULL);
-// 			CReader_DocView* pDocView = pPageView->GetDocView();
-// 			ASSERT(pDocView != NULL);
-			
-			
-			
-			PDFSDK_FieldAction fa;
-			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
- 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
-			pWidget->OnAAction(CPDF_AAction::ButtonUp, fa, pPageView);
-			m_bNotifying = FALSE;
-			
-			if (!IsValidAnnot(pPageView, pWidget))
-			{
-				bExit = TRUE;
-				return;
-			}
-			
-			if (nAge != pWidget->GetAppearanceAge())
-			{
-				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
-				{
-					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
-				}
-				
-				bReset = TRUE;
-			}
-		}
-	}
-}
-
-FX_BOOL	CFFL_IFormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		return pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	//change cursor
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
-	{
-		return pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, short zDelta, const CPDF_Point& point)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		return pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		return pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		return pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::OnRButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		return pFormFiller->OnRButtonDblClk(pPageView, pAnnot, nFlags, point);
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot, FX_UINT nKeyCode, FX_UINT nFlags)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		return pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlags);	
-	}
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (nChar == FWL_VKEY_Tab) return TRUE;
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		return pFormFiller->OnChar(pAnnot, nChar, nFlags);
-	}
-
-	return FALSE;
-}
-
-void CFFL_IFormFiller::OnDeSelected(CPDFSDK_Annot* pAnnot)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		pFormFiller->OnDeSelected(pAnnot);
-	}
-}
-
-void CFFL_IFormFiller::OnSelected(CPDFSDK_Annot* pAnnot)
-{
-	ASSERT(pAnnot != NULL);
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		pFormFiller->OnSelected(pAnnot);
-	}
-}
-
-FX_BOOL CFFL_IFormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot,FX_UINT nFlag)
-{
-	if(!pAnnot) return FALSE;
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (!m_bNotifying)
-	{
-		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
- 		if (pWidget->GetAAction(CPDF_AAction::GetFocus))
- 		{
-  			m_bNotifying = TRUE;
-			pWidget->GetAppearanceAge();
-			int nValueAge = pWidget->GetValueAge();
- 			pWidget->ClearAppModified();
- 
- 
- 			CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
- 			ASSERT(pPageView != NULL);
- 			
- 			PDFSDK_FieldAction fa;
-			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
- 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-
- 
- 			CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, TRUE);
- 			if(!pFormFiller) return FALSE;
- 			pFormFiller->GetActionData(pPageView, CPDF_AAction::GetFocus, fa);
- 
- 			pWidget->OnAAction(CPDF_AAction::GetFocus, fa, pPageView);
- 			m_bNotifying = FALSE;
- 			
- //			if (!IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pAnnot)) return FALSE;
- 
- 			if (pWidget->IsAppModified())
- 			{
- 				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
- 				{
- 					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
- 				}
- 			}
-		}
-	}
-	
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
-	{
-		if (pFormFiller->OnSetFocus(pAnnot, nFlag))
-		{
-			return TRUE;
-		}
-		else
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-FX_BOOL	CFFL_IFormFiller::OnKillFocus(CPDFSDK_Annot* pAnnot,FX_UINT nFlag)
-{
-	if(!pAnnot) return FALSE;
-	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
-	{
-		if (pFormFiller->OnKillFocus(pAnnot, nFlag))
-		{
- 			if (!m_bNotifying)
- 			{
- 				CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
- 				if (pWidget->GetAAction(CPDF_AAction::LoseFocus))
- 				{
- 					m_bNotifying = TRUE;
- 					pWidget->ClearAppModified();
- 
- 					CPDFSDK_PageView* pPageView = pWidget->GetPageView();
- 					ASSERT(pPageView != NULL);
- 
- 					PDFSDK_FieldAction fa;
-					fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
- 					fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
- 
- 					pFormFiller->GetActionData(pPageView, CPDF_AAction::LoseFocus, fa);
- 
- 					pWidget->OnAAction(CPDF_AAction::LoseFocus, fa, pPageView);
- 					m_bNotifying = FALSE;
- 
- 				}
- 			}
-		}
-		else
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-FX_BOOL	CFFL_IFormFiller::IsVisible(CPDFSDK_Widget* pWidget)
-{
-	return pWidget->IsVisible();
-}
-
-FX_BOOL	CFFL_IFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget)
-{
-	ASSERT(pWidget != NULL);
-
-	int nFieldFlags = pWidget->GetFieldFlags();
-
-	return (nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY;
-}
-
-FX_BOOL	CFFL_IFormFiller::IsFillingAllowed(CPDFSDK_Widget* pWidget)
-{
-	ASSERT(pWidget != NULL);
-
-	if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
-		return TRUE;
- 	else
- 	{
- 		CPDF_Page* pPage = pWidget->GetPDFPage();
- 		ASSERT(pPage != NULL);
- 
- 		CPDF_Document* pDocument = pPage->m_pDocument;
- 		ASSERT(pDocument != NULL);
- 
-		FX_DWORD dwPermissions = pDocument->GetUserPermissions();
- 		return (dwPermissions&FPDFPERM_FILL_FORM) || 
- 				(dwPermissions&FPDFPERM_ANNOT_FORM) || 
- 			(dwPermissions&FPDFPERM_MODIFY);
- 	}
-	return TRUE;	
-}
-
-CFFL_FormFiller* CFFL_IFormFiller::GetFormFiller(CPDFSDK_Annot* pAnnot, FX_BOOL bRegister)
-{
-// 	ASSERT(pAnnot != NULL);
-// 	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
-
-	CFFL_FormFiller * pFormFiller = NULL;
-	m_Maps.Lookup(pAnnot, pFormFiller);
-
-	if (pFormFiller)
-		return pFormFiller;
-
-	if (bRegister)
-	{
-		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;		
-
-		int nFieldType = pWidget->GetFieldType();
-		switch(nFieldType)
-		{
- 		case FIELDTYPE_PUSHBUTTON:
- 			pFormFiller = new CFFL_PushButton(m_pApp, pWidget);
- 			break;
-		case FIELDTYPE_CHECKBOX:
-			pFormFiller = new CFFL_CheckBox(m_pApp, pWidget);
-			break;
- 		case FIELDTYPE_RADIOBUTTON:
- 			pFormFiller = new CFFL_RadioButton(m_pApp, pWidget);
- 			break;
- 		case FIELDTYPE_TEXTFIELD:
-			pFormFiller = new CFFL_TextField(m_pApp, pWidget);
-			break;
-		case FIELDTYPE_LISTBOX:
-			pFormFiller = new CFFL_ListBox(m_pApp, pWidget);
-			break;
-		case FIELDTYPE_COMBOBOX:
-			pFormFiller = new CFFL_ComboBox(m_pApp, pWidget);
-			break;
-		case FIELDTYPE_UNKNOWN:
-		default:
-			pFormFiller = NULL;
-			break;
-		}
-
-		if (pFormFiller)
-		{
-			m_Maps.SetAt(pAnnot, pFormFiller);
-		}
-	}
-
-	return pFormFiller;
-}
-
-void CFFL_IFormFiller::RemoveFormFiller(CPDFSDK_Annot* pAnnot)
-{
-	if ( pAnnot != NULL )
-	{
-		UnRegisterFormFiller( pAnnot );
-	}
-}
-
-void CFFL_IFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot)
-{
-	CFFL_FormFiller * pFormFiller = NULL;
-
-	if (m_Maps.Lookup(pAnnot,pFormFiller))
-	{
-		if (pFormFiller)
-			delete pFormFiller;
-		m_Maps.RemoveKey(pAnnot);
-	}
-}
-
-void CFFL_IFormFiller::SetFocusAnnotTab(CPDFSDK_Annot* pWidget, FX_BOOL bSameField, FX_BOOL bNext)
-{
-
-}
-
-void CFFL_IFormFiller::QueryWherePopup(void* pPrivateData, FX_FLOAT fPopupMin,FX_FLOAT fPopupMax, FX_INT32 & nRet, FX_FLOAT & fPopupRet)
-{
-	ASSERT(pPrivateData != NULL);
-
-	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
-
-	
-
-
-	CPDF_Rect rcPageView(0,0,0,0);
-	rcPageView.right = pData->pWidget->GetPDFPage()->GetPageWidth();
-	rcPageView.bottom = pData->pWidget->GetPDFPage()->GetPageHeight();
-	rcPageView.Normalize();
-
-
-	ASSERT(pData->pWidget != NULL);
-	CPDF_Rect rcAnnot = pData->pWidget->GetRect();
-
-	FX_FLOAT fTop = 0.0f;
-	FX_FLOAT fBottom = 0.0f;
-
-	CPDFSDK_Widget * pWidget = (CPDFSDK_Widget*)pData->pWidget;
-	switch (pWidget->GetRotate() / 90)
-	{
-	default:
-	case 0:
-		fTop = rcPageView.top - rcAnnot.top;
-		fBottom = rcAnnot.bottom - rcPageView.bottom;
-		break;
-	case 1:
-		fTop = rcAnnot.left - rcPageView.left;
-		fBottom = rcPageView.right - rcAnnot.right;
-		break;
-	case 2:
-		fTop = rcAnnot.bottom - rcPageView.bottom;
-		fBottom = rcPageView.top - rcAnnot.top;
-		break;
-	case 3:
-		fTop = rcPageView.right - rcAnnot.right;
-		fBottom = rcAnnot.left - rcPageView.left;
-		break;
-	}
-
-	FX_FLOAT fFactHeight = 0;
-	FX_BOOL bBottom = TRUE;
-	FX_FLOAT fMaxListBoxHeight = 0;
-	if (fPopupMax > FFL_MAXLISTBOXHEIGHT)
-	{
-		if (fPopupMin > FFL_MAXLISTBOXHEIGHT)
-		{
-			fMaxListBoxHeight = fPopupMin;
-		}
-		else
-		{
-			fMaxListBoxHeight = FFL_MAXLISTBOXHEIGHT;
-		}
-	}
-	else
-		fMaxListBoxHeight = fPopupMax;
-
-	if (fBottom > fMaxListBoxHeight)
-	{
-		fFactHeight = fMaxListBoxHeight;
-		bBottom = TRUE;
-	}
-	else
-	{
-		if (fTop > fMaxListBoxHeight)
-		{
-			fFactHeight = fMaxListBoxHeight;
-			bBottom = FALSE;
-		}
-		else
-		{
-			if (fTop > fBottom)
-			{
-				fFactHeight = fTop;
-				bBottom = FALSE;
-			}
-			else
-			{
-				fFactHeight = fBottom;
-				bBottom = TRUE;
-			}
-		}
-	}
-
-	nRet = bBottom ? 0 : 1;
-	fPopupRet = fFactHeight;
-}
-
-void CFFL_IFormFiller::OnSetWindowRect(void* pPrivateData, const CPDF_Rect & rcWindow)
-{
-	ASSERT(pPrivateData != NULL);
-
-	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
-
-	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, TRUE))
-	{
-
-		CPDF_Rect rcOld = pFormFiller->PWLtoFFL(pFormFiller->GetWindowRect(pData->pPageView));
-		CPDF_Rect rcNew = pFormFiller->PWLtoFFL(rcWindow);
-		pFormFiller->SetWindowRect(pData->pPageView, rcWindow);
-
-		CPDF_Rect unRect = rcOld;
-		unRect.Union(rcNew);
-		//FX_RECT rcRect = unRect.GetOutterRect();
-		unRect.left = (FX_FLOAT)(unRect.left - 0.5);
-		unRect.right = (FX_FLOAT)(unRect.right + 0.5);
-		unRect.top = (FX_FLOAT)(unRect.top + 0.5);
-		unRect.bottom = (FX_FLOAT)(unRect.bottom -0.5);
-		m_pApp->FFI_Invalidate(pData->pWidget->GetPDFPage(), unRect.left, unRect.top, unRect.right, unRect.bottom);
-	}
-}
-
-void CFFL_IFormFiller::OnKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_INT32 nKeyCode, CFX_WideString& strChange, 
-								   const CFX_WideString& strChangeEx, FX_BOOL bKeyDown, 
-								   FX_BOOL & bRC, FX_BOOL & bExit)
-{
-	ASSERT(pPrivateData != NULL);
-	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
-	ASSERT(pData->pWidget != NULL);
-
-	CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
-	ASSERT(pFormFiller != NULL);
-
-	pFormFiller->OnKeyStroke(bKeyDown);
-}
-
-void CFFL_IFormFiller::OnKeyStrokeCommit(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bRC, FX_BOOL& bExit, FX_DWORD nFlag)
-{
-	if (!m_bNotifying)
-	{
-		ASSERT(pWidget != NULL);
-		if (pWidget->GetAAction(CPDF_AAction::KeyStroke))
-		{
-			m_bNotifying = TRUE;
-			pWidget->ClearAppModified();
-
-			ASSERT(pPageView != NULL);
-// 			CReader_DocView* pDocView = pPageView->GetDocView();
-// 			ASSERT(pDocView != NULL);
-			
-		
-
-			PDFSDK_FieldAction fa;
-			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
- 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-			fa.bWillCommit = TRUE;
-			fa.nCommitKey = GetCommitKey();
-			fa.bKeyDown = GetKeyDown();
-			fa.bRC = TRUE;
-
-			CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
-			ASSERT(pFormFiller != NULL);
-
-			pFormFiller->GetActionData(pPageView, CPDF_AAction::KeyStroke, fa);
-			pFormFiller->SaveState(pPageView);
-
-			PDFSDK_FieldAction faOld = fa;
-			pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pPageView);
-
-			bRC = fa.bRC;
-//			bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);
-
-			m_bNotifying = FALSE;
-		}
-	}
-}
-
-void CFFL_IFormFiller::OnValidate(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bRC, FX_BOOL& bExit, FX_DWORD nFlag)
-{
-	if (!m_bNotifying)
-	{
-		ASSERT(pWidget != NULL);
-		if (pWidget->GetAAction(CPDF_AAction::Validate))
-		{
-			m_bNotifying = TRUE;
-			pWidget->ClearAppModified();
-
-			ASSERT(pPageView != NULL);
-// 			CReader_DocView* pDocView = pPageView->GetDocView();
-// 			ASSERT(pDocView != NULL);
-			
-			
-
-			PDFSDK_FieldAction fa;
-			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
- 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-			fa.bKeyDown = GetKeyDown();
-			fa.bRC = TRUE;
-
-			CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
-			ASSERT(pFormFiller != NULL);
-
-			pFormFiller->GetActionData(pPageView, CPDF_AAction::Validate, fa);
-			pFormFiller->SaveState(pPageView);
-
-			PDFSDK_FieldAction faOld = fa;
-			pWidget->OnAAction(CPDF_AAction::Validate, fa, pPageView);
-
-			bRC = fa.bRC;
-//			bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);
-
-			m_bNotifying = FALSE;
-		}
-	}
-}
-
-void CFFL_IFormFiller::OnCalculate(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bExit, FX_DWORD nFlag)
-{
-	if (!m_bNotifying)
-	{
-		ASSERT(pWidget != NULL);
-		ASSERT(pPageView != NULL);
-// 		CReader_DocView* pDocView = pPageView->GetDocView();
-// 		ASSERT(pDocView != NULL);
-		CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
-		ASSERT(pDocument != NULL);
-
-		CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-		ASSERT(pInterForm != NULL);
-
-		pInterForm->OnCalculate(pWidget->GetFormField());
-
-//		bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);
-
-		m_bNotifying = FALSE;
-	}
-}
-
-void CFFL_IFormFiller::OnFormat(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bExit, FX_DWORD nFlag)
-{
-	if (!m_bNotifying)
-	{
-		ASSERT(pWidget != NULL);
-		ASSERT(pPageView != NULL);
-// 		CReader_DocView* pDocView = pPageView->GetDocView();
-// 		ASSERT(pDocView != NULL);
-		CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
-		ASSERT(pDocument != NULL);
-
-		CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
-		ASSERT(pInterForm != NULL);
-
-		FX_BOOL bFormated = FALSE;
-		CFX_WideString sValue = pInterForm->OnFormat(pWidget->GetFormField(), GetCommitKey(), bFormated);
-
-//		bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);
-
-		if (bExit) return;
-
-		if (bFormated)
-		{
-			pInterForm->ResetFieldAppearance(pWidget->GetFormField(), sValue, TRUE);
-			pInterForm->UpdateField(pWidget->GetFormField());
-		}
-
-		m_bNotifying = FALSE;
-	}
-}
-
-// LRESULT CALLBACK CFFL_IFormFiller::FFL_WndProc(
-// 									  int code,       // hook code
-// 									  WPARAM wParam,  // virtual-key code
-// 									  LPARAM lParam   // keystroke-message information
-// 										)
-// {
-// 	if (code != HC_ACTION)
-// 	{
-// 		return CallNextHookEx (m_hookSheet, code, wParam, lParam);
-// 	}
-// 
-// 	FXSYS_memcpy(&g_Msg, (void*)lParam, sizeof(MSG));	
-// 
-// 	return 0;
-// }
-
-// MSG	CFFL_IFormFiller::GetLastMessage()
-// {
-// 	return g_Msg;
-// }
-
-int CFFL_IFormFiller::GetCommitKey()
-{
-//	MSG msg = CFFL_IFormFiller::GetLastMessage();
-
-	int nCommitKey = 0;
-// 	switch (msg.message)
-// 	{
-// 	case WM_LBUTTONDOWN:
-// 	case WM_LBUTTONUP:
-// 		nCommitKey = 1;
-// 		break;
-// 	case WM_KEYDOWN:
-// 		switch (msg.wParam)
-// 		{
-// 		case VK_RETURN:
-// 			nCommitKey = 2;
-// 			break;
-// 		case VK_TAB:
-// 			nCommitKey = 3;
-// 			break;
-// 		}
-// 		break;
-// 	}
-
-	return nCommitKey;
-}
-
-FX_BOOL CFFL_IFormFiller::GetKeyDown()
-{
-	return TRUE;
-// 	MSG msg = CFFL_IFormFiller::GetLastMessage();
-// 
-// 	return msg.message == WM_KEYDOWN || msg.message == WM_CHAR;
-}
-
-FX_BOOL	CFFL_IFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot)
-{
-
-	ASSERT(pPageView != NULL);
-	ASSERT(pAnnot != NULL);
-
-	if(pPageView)
-		return pPageView->IsValidAnnot(pAnnot->GetPDFAnnot());
-	else
-		return FALSE;
-}
-
-void CFFL_IFormFiller::BeforeUndo(CPDFSDK_Document* pDocument)
-{
-
-}
-
-void CFFL_IFormFiller::BeforeRedo(CPDFSDK_Document* pDocument)
-{
-	BeforeUndo(pDocument);
-}
-
-void CFFL_IFormFiller::AfterUndo(CPDFSDK_Document* pDocument)
-{
-}
-
-void CFFL_IFormFiller::AfterRedo(CPDFSDK_Document* pDocument)
-{
-}
-
-FX_BOOL	CFFL_IFormFiller::CanCopy(CPDFSDK_Document* pDocument)
-{
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::CanCut(CPDFSDK_Document* pDocument)
-{
-
-	return FALSE;
-}
-
-FX_BOOL	CFFL_IFormFiller::CanPaste(CPDFSDK_Document* pDocument)
-{
-
-	return FALSE;
-}
-
-void CFFL_IFormFiller::DoCopy(CPDFSDK_Document* pDocument)
-{
-}
-
-void CFFL_IFormFiller::DoCut(CPDFSDK_Document* pDocument)
-{
-}
-
-void CFFL_IFormFiller::DoPaste(CPDFSDK_Document* pDocument)
-{
-
-}
-void CFFL_IFormFiller::OnBeforeKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_INT32 nKeyCode,
-											  CFX_WideString & strChange, const CFX_WideString& strChangeEx, 
-											  int nSelStart, int nSelEnd,
-										FX_BOOL bKeyDown, FX_BOOL & bRC, FX_BOOL & bExit, FX_DWORD nFlag)
-{
-	ASSERT(pPrivateData != NULL);
-	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
-	ASSERT(pData->pWidget != NULL);
-	
-	CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
-	ASSERT(pFormFiller != NULL);
-	
-	if (!m_bNotifying)
-	{
-		if (pData->pWidget->GetAAction(CPDF_AAction::KeyStroke))
-		{
-			m_bNotifying = TRUE;
-			int nAge = pData->pWidget->GetAppearanceAge();
-			int nValueAge = pData->pWidget->GetValueAge();
-
-			ASSERT(pData->pPageView != NULL);
-			CPDFSDK_Document* pDocument  = pData->pPageView->GetSDKDocument();
-			
-			PDFSDK_FieldAction fa;
- 			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
- 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
-			fa.sChange = strChange;
-			fa.sChangeEx = strChangeEx;
-			fa.bKeyDown = bKeyDown;
-			fa.bWillCommit = FALSE;
-			fa.bRC = TRUE;
-			fa.nSelStart = nSelStart;
-			fa.nSelEnd = nSelEnd;
-
-
-			pFormFiller->GetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
-			pFormFiller->SaveState(pData->pPageView);
-			
-			if (pData->pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pData->pPageView))
-			{
-				if (!IsValidAnnot(pData->pPageView, pData->pWidget))
-				{
-					bExit = TRUE;
-					m_bNotifying = FALSE;
-					return;
-				}
-				
-				if (nAge != pData->pWidget->GetAppearanceAge())
-				{
-					CPWL_Wnd* pWnd = pFormFiller->ResetPDFWindow(pData->pPageView, nValueAge == pData->pWidget->GetValueAge());
-					pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
-					bExit = TRUE;
-				}
-				
-				if (fa.bRC)
-				{
-					pFormFiller->SetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
-					bRC = FALSE;
-				}
-				else
-				{
-					pFormFiller->RestoreState(pData->pPageView);
-					bRC = FALSE;
-				}
-				
-				if (pDocument->GetFocusAnnot() != pData->pWidget)
-				{
-					pFormFiller->CommitData(pData->pPageView,nFlag);
-					bExit = TRUE;
-				}
-			}
-			else
-			{			
-				if (!IsValidAnnot(pData->pPageView, pData->pWidget))
-				{
-					bExit = TRUE;
-					m_bNotifying = FALSE;
-					return;
-				}
-			}
-			
-			m_bNotifying = FALSE;
-		}
-	}
-}
-
-void	CFFL_IFormFiller::OnAfterKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_BOOL & bExit,FX_DWORD nFlag) 
-{
-	ASSERT(pPrivateData != NULL);
-	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
-	ASSERT(pData->pWidget != NULL);
-	
-	CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
-	ASSERT(pFormFiller != NULL);
-	
-	if (!bEditOrList)
-		pFormFiller->OnKeyStroke(bExit);
-}
+// 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_IFormFiller.h"
+#include "../../include/formfiller/FFL_CheckBox.h"
+#include "../../include/formfiller/FFL_ComboBox.h"
+#include "../../include/formfiller/FFL_ListBox.h"
+#include "../../include/formfiller/FFL_PushButton.h"
+#include "../../include/formfiller/FFL_RadioButton.h"
+#include "../../include/formfiller/FFL_TextField.h"
+
+#define FFL_MAXLISTBOXHEIGHT		140.0f
+
+// HHOOK CFFL_IFormFiller::m_hookSheet = NULL;
+// MSG CFFL_IFormFiller::g_Msg;
+
+/* ----------------------------- CFFL_IFormFiller ----------------------------- */
+
+CFFL_IFormFiller::CFFL_IFormFiller(CPDFDoc_Environment* pApp) : 
+	m_pApp(pApp),
+	m_bNotifying(FALSE)
+{
+}
+
+CFFL_IFormFiller::~CFFL_IFormFiller()
+{
+	FX_POSITION pos = m_Maps.GetStartPosition();
+	while (pos)
+	{
+		CPDFSDK_Annot * pAnnot = NULL;
+		CFFL_FormFiller * pFormFiller = NULL;
+		m_Maps.GetNextAssoc(pos,pAnnot,pFormFiller);
+		delete pFormFiller;
+	}
+	m_Maps.RemoveAll();
+}
+
+FX_BOOL	CFFL_IFormFiller::Annot_HitTest(CPDFSDK_PageView* pPageView,CPDFSDK_Annot* pAnnot, CPDF_Point point)
+{
+	CPDF_Rect rc = pAnnot->GetRect();
+	if(rc.Contains(point.x, point.y))
+		return TRUE;
+	return FALSE;
+}
+
+FX_RECT CFFL_IFormFiller::GetViewBBox(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot)
+{
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		return pFormFiller->GetViewBBox(pPageView, pAnnot);
+	}
+	else
+	{
+		ASSERT(pPageView != NULL);
+		ASSERT(pAnnot != NULL);
+
+		CPDF_Annot* pPDFAnnot = pAnnot->GetPDFAnnot();
+		ASSERT(pPDFAnnot != NULL);
+
+		CPDF_Rect rcAnnot;
+		pPDFAnnot->GetRect(rcAnnot);
+
+// 		CRect rcWin;
+// 		pPageView->DocToWindow(rcAnnot, rcWin);
+		CPDF_Rect rcWin = CPWL_Utils::InflateRect(rcAnnot,1);
+//		rcWin.InflateRect(1, 1);
+
+		return rcWin.GetOutterRect();
+	}
+}
+
+void CFFL_IFormFiller::OnDraw(CPDFSDK_PageView* pPageView, /*HDC hDC,*/ CPDFSDK_Annot* pAnnot, 
+						CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
+						/*const CRect& rcWindow,*/ FX_DWORD dwFlags)
+{
+	ASSERT(pPageView != NULL);
+	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+
+	if (IsVisible(pWidget))
+	{
+		if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+		{
+ 			if (pFormFiller->IsValid())
+ 			{
+				pFormFiller->OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
+				
+				pAnnot->GetPDFPage();
+				
+
+				CPDFSDK_Document* pDocument = m_pApp->GetCurrentDoc();
+				ASSERT(pDocument != NULL);
+
+				if (pDocument->GetFocusAnnot() == pAnnot)
+				{
+					CPDF_Rect rcFocus = pFormFiller->GetFocusBox(pPageView);
+					if (!rcFocus.IsEmpty())
+					{
+						CFX_PathData path;
+						
+						path.SetPointCount(5);
+						path.SetPoint(0, rcFocus.left,  rcFocus.top, FXPT_MOVETO);
+						path.SetPoint(1, rcFocus.left,  rcFocus.bottom, FXPT_LINETO);
+						path.SetPoint(2, rcFocus.right,  rcFocus.bottom, FXPT_LINETO);
+						path.SetPoint(3, rcFocus.right,  rcFocus.top, FXPT_LINETO);
+						path.SetPoint(4, rcFocus.left,  rcFocus.top, FXPT_LINETO);
+						
+						CFX_GraphStateData gsd;
+						gsd.SetDashCount(1);				
+						gsd.m_DashArray[0] = 1.0f;
+						gsd.m_DashPhase = 0;	
+						
+						gsd.m_LineWidth = 1.0f;
+						pDevice->DrawPath(&path, pUser2Device, &gsd, 0, ArgbEncode(255,0,0,0), FXFILL_ALTERNATE);
+
+					//	::DrawFocusRect(hDC, &rcFocus);	
+					}
+				}
+
+				return;
+			}
+		}
+
+		if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+			pFormFiller->OnDrawDeactive(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
+		else
+			pWidget->DrawAppearance(pDevice, pUser2Device, CPDF_Annot::Normal, NULL);
+
+		if (!IsReadOnly(pWidget) && IsFillingAllowed(pWidget))
+		{
+			pWidget->DrawShadow(pDevice, pPageView);
+		}
+	
+	}
+}
+
+void CFFL_IFormFiller::OnCreate(CPDFSDK_Annot* pAnnot)
+{
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		pFormFiller->OnCreate(pAnnot);
+	}
+}
+
+void CFFL_IFormFiller::OnLoad(CPDFSDK_Annot* pAnnot)
+{
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		pFormFiller->OnLoad(pAnnot);
+	}
+}
+
+void CFFL_IFormFiller::OnDelete(CPDFSDK_Annot* pAnnot)
+{
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		pFormFiller->OnDelete(pAnnot);
+	}
+
+	UnRegisterFormFiller(pAnnot);
+}
+
+void CFFL_IFormFiller::OnMouseEnter(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+	
+	if (!m_bNotifying)
+	{
+		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+		if (pWidget->GetAAction(CPDF_AAction::CursorEnter))
+		{
+			m_bNotifying = TRUE;
+			
+			int nValueAge = pWidget->GetValueAge();
+
+			pWidget->ClearAppModified();
+			
+			ASSERT(pPageView != NULL);
+			
+			
+			
+			PDFSDK_FieldAction fa;
+			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+			pWidget->OnAAction(CPDF_AAction::CursorEnter, fa, pPageView );
+			m_bNotifying = FALSE;
+			
+			//if ( !IsValidAnnot(pPageView, pAnnot) ) return;
+			
+			if (pWidget->IsAppModified())
+			{
+				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
+				{
+					pFormFiller->ResetPDFWindow(pPageView, pWidget->GetValueAge() == nValueAge);
+				}
+			}
+		}
+	}
+	
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
+	{
+		pFormFiller->OnMouseEnter(pPageView, pAnnot);
+	}
+}
+
+void CFFL_IFormFiller::OnMouseExit(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlag)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+	
+	if (!m_bNotifying)
+	{
+		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+		if (pWidget->GetAAction(CPDF_AAction::CursorExit))
+		{
+			m_bNotifying = TRUE;
+			pWidget->GetAppearanceAge();
+			int nValueAge = pWidget->GetValueAge();
+			pWidget->ClearAppModified();
+			
+			ASSERT(pPageView != NULL);
+			
+			
+			
+			PDFSDK_FieldAction fa;
+			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+			
+			pWidget->OnAAction(CPDF_AAction::CursorExit, fa, pPageView);
+			m_bNotifying = FALSE;
+			
+			//if (!IsValidAnnot(pPageView, pAnnot)) return;
+			
+			if (pWidget->IsAppModified())
+			{
+				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
+				{
+					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
+				}
+			}
+		}
+	}
+	
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		pFormFiller->OnMouseExit(pPageView, pAnnot);
+	}
+}
+
+FX_BOOL	CFFL_IFormFiller::OnLButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+	
+	if (!m_bNotifying)
+	{
+		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+		if (Annot_HitTest(pPageView, pAnnot, point) && pWidget->GetAAction(CPDF_AAction::ButtonDown))
+		{
+			m_bNotifying = TRUE;
+			pWidget->GetAppearanceAge();
+			int nValueAge = pWidget->GetValueAge();
+			pWidget->ClearAppModified();
+			
+			ASSERT(pPageView != NULL);
+			
+			
+			
+			PDFSDK_FieldAction fa;
+			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlags);
+ 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlags);
+			pWidget->OnAAction(CPDF_AAction::ButtonDown, fa, pPageView);
+			m_bNotifying = FALSE;
+			
+			if (!IsValidAnnot(pPageView, pAnnot)) return TRUE;
+			
+			if (pWidget->IsAppModified())
+			{
+				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
+				{
+					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
+				}
+			}
+		}
+	}
+	
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		return pFormFiller->OnLButtonDown(pPageView, pAnnot, nFlags, point);
+	}
+	
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::OnLButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+	
+	CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+	// 	CReader_Page* pPage = pAnnot->GetPage();
+	// 	ASSERT(pPage != NULL);
+	CPDFSDK_Document* pDocument = m_pApp->GetCurrentDoc();
+	ASSERT(pDocument != NULL);		
+	
+	switch (pWidget->GetFieldType())
+	{
+	case FIELDTYPE_PUSHBUTTON:
+	case FIELDTYPE_CHECKBOX:
+	case FIELDTYPE_RADIOBUTTON:
+		if (GetViewBBox(pPageView, pAnnot).Contains((int)point.x, (int)point.y))
+		{
+			pDocument->SetFocusAnnot(pAnnot);
+		}
+		break;
+	default:
+		pDocument->SetFocusAnnot(pAnnot);
+		break;
+	}
+	
+	FX_BOOL bRet = FALSE;
+	
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		bRet = pFormFiller->OnLButtonUp(pPageView, pAnnot, nFlags, point);
+	}
+
+	if (pDocument->GetFocusAnnot() == pAnnot)
+	{
+		FX_BOOL bExit = FALSE;
+		FX_BOOL bReset = FALSE;
+		OnButtonUp(pWidget, pPageView, bReset, bExit,nFlags);
+		if (bExit) return TRUE;
+	}
+	return bRet;
+}
+
+void CFFL_IFormFiller::OnButtonUp(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bReset, FX_BOOL& bExit,FX_UINT nFlag)
+{
+	ASSERT(pWidget != NULL);
+	
+	if (!m_bNotifying)
+	{
+		if (pWidget->GetAAction(CPDF_AAction::ButtonUp))
+		{
+			m_bNotifying = TRUE;
+			int nAge = pWidget->GetAppearanceAge();
+			int nValueAge = pWidget->GetValueAge();
+			
+			ASSERT(pPageView != NULL);
+// 			CReader_DocView* pDocView = pPageView->GetDocView();
+// 			ASSERT(pDocView != NULL);
+			
+			
+			
+			PDFSDK_FieldAction fa;
+			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+
+			pWidget->OnAAction(CPDF_AAction::ButtonUp, fa, pPageView);
+			m_bNotifying = FALSE;
+			
+			if (!IsValidAnnot(pPageView, pWidget))
+			{
+				bExit = TRUE;
+				return;
+			}
+			
+			if (nAge != pWidget->GetAppearanceAge())
+			{
+				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
+				{
+					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
+				}
+				
+				bReset = TRUE;
+			}
+		}
+	}
+}
+
+FX_BOOL	CFFL_IFormFiller::OnLButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		return pFormFiller->OnLButtonDblClk(pPageView, pAnnot, nFlags, point);
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::OnMouseMove(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	//change cursor
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
+	{
+		return pFormFiller->OnMouseMove(pPageView, pAnnot, nFlags, point);
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::OnMouseWheel(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, short zDelta, const CPDF_Point& point)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		return pFormFiller->OnMouseWheel(pPageView, pAnnot, nFlags, zDelta, point);
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::OnRButtonDown(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		return pFormFiller->OnRButtonDown(pPageView, pAnnot, nFlags, point);
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::OnRButtonUp(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		return pFormFiller->OnRButtonUp(pPageView, pAnnot, nFlags, point);
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::OnRButtonDblClk(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		return pFormFiller->OnRButtonDblClk(pPageView, pAnnot, nFlags, point);
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::OnKeyDown(CPDFSDK_Annot* pAnnot, FX_UINT nKeyCode, FX_UINT nFlags)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		return pFormFiller->OnKeyDown(pAnnot, nKeyCode, nFlags);	
+	}
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (nChar == FWL_VKEY_Tab) return TRUE;
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		return pFormFiller->OnChar(pAnnot, nChar, nFlags);
+	}
+
+	return FALSE;
+}
+
+void CFFL_IFormFiller::OnDeSelected(CPDFSDK_Annot* pAnnot)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		pFormFiller->OnDeSelected(pAnnot);
+	}
+}
+
+void CFFL_IFormFiller::OnSelected(CPDFSDK_Annot* pAnnot)
+{
+	ASSERT(pAnnot != NULL);
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		pFormFiller->OnSelected(pAnnot);
+	}
+}
+
+FX_BOOL CFFL_IFormFiller::OnSetFocus(CPDFSDK_Annot* pAnnot,FX_UINT nFlag)
+{
+	if(!pAnnot) return FALSE;
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (!m_bNotifying)
+	{
+		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+ 		if (pWidget->GetAAction(CPDF_AAction::GetFocus))
+ 		{
+  			m_bNotifying = TRUE;
+			pWidget->GetAppearanceAge();
+			int nValueAge = pWidget->GetValueAge();
+ 			pWidget->ClearAppModified();
+ 
+ 
+ 			CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+ 			ASSERT(pPageView != NULL);
+ 			
+ 			PDFSDK_FieldAction fa;
+			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+
+ 
+ 			CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, TRUE);
+ 			if(!pFormFiller) return FALSE;
+ 			pFormFiller->GetActionData(pPageView, CPDF_AAction::GetFocus, fa);
+ 
+ 			pWidget->OnAAction(CPDF_AAction::GetFocus, fa, pPageView);
+ 			m_bNotifying = FALSE;
+ 			
+ //			if (!IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pAnnot)) return FALSE;
+ 
+ 			if (pWidget->IsAppModified())
+ 			{
+ 				if (CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE))
+ 				{
+ 					pFormFiller->ResetPDFWindow(pPageView, nValueAge == pWidget->GetValueAge());
+ 				}
+ 			}
+		}
+	}
+	
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, TRUE))
+	{
+		if (pFormFiller->OnSetFocus(pAnnot, nFlag))
+		{
+			return TRUE;
+		}
+		else
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+FX_BOOL	CFFL_IFormFiller::OnKillFocus(CPDFSDK_Annot* pAnnot,FX_UINT nFlag)
+{
+	if(!pAnnot) return FALSE;
+	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pAnnot, FALSE))
+	{
+		if (pFormFiller->OnKillFocus(pAnnot, nFlag))
+		{
+ 			if (!m_bNotifying)
+ 			{
+ 				CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;
+ 				if (pWidget->GetAAction(CPDF_AAction::LoseFocus))
+ 				{
+ 					m_bNotifying = TRUE;
+ 					pWidget->ClearAppModified();
+ 
+ 					CPDFSDK_PageView* pPageView = pWidget->GetPageView();
+ 					ASSERT(pPageView != NULL);
+ 
+ 					PDFSDK_FieldAction fa;
+					fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ 					fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+ 
+ 					pFormFiller->GetActionData(pPageView, CPDF_AAction::LoseFocus, fa);
+ 
+ 					pWidget->OnAAction(CPDF_AAction::LoseFocus, fa, pPageView);
+ 					m_bNotifying = FALSE;
+ 
+ 				}
+ 			}
+		}
+		else
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+FX_BOOL	CFFL_IFormFiller::IsVisible(CPDFSDK_Widget* pWidget)
+{
+	return pWidget->IsVisible();
+}
+
+FX_BOOL	CFFL_IFormFiller::IsReadOnly(CPDFSDK_Widget* pWidget)
+{
+	ASSERT(pWidget != NULL);
+
+	int nFieldFlags = pWidget->GetFieldFlags();
+
+	return (nFieldFlags & FIELDFLAG_READONLY) == FIELDFLAG_READONLY;
+}
+
+FX_BOOL	CFFL_IFormFiller::IsFillingAllowed(CPDFSDK_Widget* pWidget)
+{
+	ASSERT(pWidget != NULL);
+
+	if (pWidget->GetFieldType() == FIELDTYPE_PUSHBUTTON)
+		return TRUE;
+ 	else
+ 	{
+ 		CPDF_Page* pPage = pWidget->GetPDFPage();
+ 		ASSERT(pPage != NULL);
+ 
+ 		CPDF_Document* pDocument = pPage->m_pDocument;
+ 		ASSERT(pDocument != NULL);
+ 
+		FX_DWORD dwPermissions = pDocument->GetUserPermissions();
+ 		return (dwPermissions&FPDFPERM_FILL_FORM) || 
+ 				(dwPermissions&FPDFPERM_ANNOT_FORM) || 
+ 			(dwPermissions&FPDFPERM_MODIFY);
+ 	}
+	return TRUE;	
+}
+
+CFFL_FormFiller* CFFL_IFormFiller::GetFormFiller(CPDFSDK_Annot* pAnnot, FX_BOOL bRegister)
+{
+// 	ASSERT(pAnnot != NULL);
+// 	ASSERT(pAnnot->GetPDFAnnot()->GetSubType() == "Widget");
+
+	CFFL_FormFiller * pFormFiller = NULL;
+	m_Maps.Lookup(pAnnot, pFormFiller);
+
+	if (pFormFiller)
+		return pFormFiller;
+
+	if (bRegister)
+	{
+		CPDFSDK_Widget* pWidget = (CPDFSDK_Widget*)pAnnot;		
+
+		int nFieldType = pWidget->GetFieldType();
+		switch(nFieldType)
+		{
+ 		case FIELDTYPE_PUSHBUTTON:
+ 			pFormFiller = new CFFL_PushButton(m_pApp, pWidget);
+ 			break;
+		case FIELDTYPE_CHECKBOX:
+			pFormFiller = new CFFL_CheckBox(m_pApp, pWidget);
+			break;
+ 		case FIELDTYPE_RADIOBUTTON:
+ 			pFormFiller = new CFFL_RadioButton(m_pApp, pWidget);
+ 			break;
+ 		case FIELDTYPE_TEXTFIELD:
+			pFormFiller = new CFFL_TextField(m_pApp, pWidget);
+			break;
+		case FIELDTYPE_LISTBOX:
+			pFormFiller = new CFFL_ListBox(m_pApp, pWidget);
+			break;
+		case FIELDTYPE_COMBOBOX:
+			pFormFiller = new CFFL_ComboBox(m_pApp, pWidget);
+			break;
+		case FIELDTYPE_UNKNOWN:
+		default:
+			pFormFiller = NULL;
+			break;
+		}
+
+		if (pFormFiller)
+		{
+			m_Maps.SetAt(pAnnot, pFormFiller);
+		}
+	}
+
+	return pFormFiller;
+}
+
+void CFFL_IFormFiller::RemoveFormFiller(CPDFSDK_Annot* pAnnot)
+{
+	if ( pAnnot != NULL )
+	{
+		UnRegisterFormFiller( pAnnot );
+	}
+}
+
+void CFFL_IFormFiller::UnRegisterFormFiller(CPDFSDK_Annot* pAnnot)
+{
+	CFFL_FormFiller * pFormFiller = NULL;
+
+	if (m_Maps.Lookup(pAnnot,pFormFiller))
+	{
+		if (pFormFiller)
+			delete pFormFiller;
+		m_Maps.RemoveKey(pAnnot);
+	}
+}
+
+void CFFL_IFormFiller::SetFocusAnnotTab(CPDFSDK_Annot* pWidget, FX_BOOL bSameField, FX_BOOL bNext)
+{
+
+}
+
+void CFFL_IFormFiller::QueryWherePopup(void* pPrivateData, FX_FLOAT fPopupMin,FX_FLOAT fPopupMax, FX_INT32 & nRet, FX_FLOAT & fPopupRet)
+{
+	ASSERT(pPrivateData != NULL);
+
+	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+
+	
+
+
+	CPDF_Rect rcPageView(0,0,0,0);
+	rcPageView.right = pData->pWidget->GetPDFPage()->GetPageWidth();
+	rcPageView.bottom = pData->pWidget->GetPDFPage()->GetPageHeight();
+	rcPageView.Normalize();
+
+
+	ASSERT(pData->pWidget != NULL);
+	CPDF_Rect rcAnnot = pData->pWidget->GetRect();
+
+	FX_FLOAT fTop = 0.0f;
+	FX_FLOAT fBottom = 0.0f;
+
+	CPDFSDK_Widget * pWidget = (CPDFSDK_Widget*)pData->pWidget;
+	switch (pWidget->GetRotate() / 90)
+	{
+	default:
+	case 0:
+		fTop = rcPageView.top - rcAnnot.top;
+		fBottom = rcAnnot.bottom - rcPageView.bottom;
+		break;
+	case 1:
+		fTop = rcAnnot.left - rcPageView.left;
+		fBottom = rcPageView.right - rcAnnot.right;
+		break;
+	case 2:
+		fTop = rcAnnot.bottom - rcPageView.bottom;
+		fBottom = rcPageView.top - rcAnnot.top;
+		break;
+	case 3:
+		fTop = rcPageView.right - rcAnnot.right;
+		fBottom = rcAnnot.left - rcPageView.left;
+		break;
+	}
+
+	FX_FLOAT fFactHeight = 0;
+	FX_BOOL bBottom = TRUE;
+	FX_FLOAT fMaxListBoxHeight = 0;
+	if (fPopupMax > FFL_MAXLISTBOXHEIGHT)
+	{
+		if (fPopupMin > FFL_MAXLISTBOXHEIGHT)
+		{
+			fMaxListBoxHeight = fPopupMin;
+		}
+		else
+		{
+			fMaxListBoxHeight = FFL_MAXLISTBOXHEIGHT;
+		}
+	}
+	else
+		fMaxListBoxHeight = fPopupMax;
+
+	if (fBottom > fMaxListBoxHeight)
+	{
+		fFactHeight = fMaxListBoxHeight;
+		bBottom = TRUE;
+	}
+	else
+	{
+		if (fTop > fMaxListBoxHeight)
+		{
+			fFactHeight = fMaxListBoxHeight;
+			bBottom = FALSE;
+		}
+		else
+		{
+			if (fTop > fBottom)
+			{
+				fFactHeight = fTop;
+				bBottom = FALSE;
+			}
+			else
+			{
+				fFactHeight = fBottom;
+				bBottom = TRUE;
+			}
+		}
+	}
+
+	nRet = bBottom ? 0 : 1;
+	fPopupRet = fFactHeight;
+}
+
+void CFFL_IFormFiller::OnSetWindowRect(void* pPrivateData, const CPDF_Rect & rcWindow)
+{
+	ASSERT(pPrivateData != NULL);
+
+	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+
+	if (CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, TRUE))
+	{
+
+		CPDF_Rect rcOld = pFormFiller->PWLtoFFL(pFormFiller->GetWindowRect(pData->pPageView));
+		CPDF_Rect rcNew = pFormFiller->PWLtoFFL(rcWindow);
+		pFormFiller->SetWindowRect(pData->pPageView, rcWindow);
+
+		CPDF_Rect unRect = rcOld;
+		unRect.Union(rcNew);
+		//FX_RECT rcRect = unRect.GetOutterRect();
+		unRect.left = (FX_FLOAT)(unRect.left - 0.5);
+		unRect.right = (FX_FLOAT)(unRect.right + 0.5);
+		unRect.top = (FX_FLOAT)(unRect.top + 0.5);
+		unRect.bottom = (FX_FLOAT)(unRect.bottom -0.5);
+		m_pApp->FFI_Invalidate(pData->pWidget->GetPDFPage(), unRect.left, unRect.top, unRect.right, unRect.bottom);
+	}
+}
+
+void CFFL_IFormFiller::OnKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_INT32 nKeyCode, CFX_WideString& strChange, 
+								   const CFX_WideString& strChangeEx, FX_BOOL bKeyDown, 
+								   FX_BOOL & bRC, FX_BOOL & bExit)
+{
+	ASSERT(pPrivateData != NULL);
+	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+	ASSERT(pData->pWidget != NULL);
+
+	CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
+	ASSERT(pFormFiller != NULL);
+
+	pFormFiller->OnKeyStroke(bKeyDown);
+}
+
+void CFFL_IFormFiller::OnKeyStrokeCommit(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bRC, FX_BOOL& bExit, FX_DWORD nFlag)
+{
+	if (!m_bNotifying)
+	{
+		ASSERT(pWidget != NULL);
+		if (pWidget->GetAAction(CPDF_AAction::KeyStroke))
+		{
+			m_bNotifying = TRUE;
+			pWidget->ClearAppModified();
+
+			ASSERT(pPageView != NULL);
+// 			CReader_DocView* pDocView = pPageView->GetDocView();
+// 			ASSERT(pDocView != NULL);
+			
+		
+
+			PDFSDK_FieldAction fa;
+			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+			fa.bWillCommit = TRUE;
+			fa.nCommitKey = GetCommitKey();
+			fa.bKeyDown = GetKeyDown();
+			fa.bRC = TRUE;
+
+			CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
+			ASSERT(pFormFiller != NULL);
+
+			pFormFiller->GetActionData(pPageView, CPDF_AAction::KeyStroke, fa);
+			pFormFiller->SaveState(pPageView);
+
+			PDFSDK_FieldAction faOld = fa;
+			pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pPageView);
+
+			bRC = fa.bRC;
+//			bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);
+
+			m_bNotifying = FALSE;
+		}
+	}
+}
+
+void CFFL_IFormFiller::OnValidate(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bRC, FX_BOOL& bExit, FX_DWORD nFlag)
+{
+	if (!m_bNotifying)
+	{
+		ASSERT(pWidget != NULL);
+		if (pWidget->GetAAction(CPDF_AAction::Validate))
+		{
+			m_bNotifying = TRUE;
+			pWidget->ClearAppModified();
+
+			ASSERT(pPageView != NULL);
+// 			CReader_DocView* pDocView = pPageView->GetDocView();
+// 			ASSERT(pDocView != NULL);
+			
+			
+
+			PDFSDK_FieldAction fa;
+			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+			fa.bKeyDown = GetKeyDown();
+			fa.bRC = TRUE;
+
+			CFFL_FormFiller* pFormFiller = GetFormFiller(pWidget, FALSE);
+			ASSERT(pFormFiller != NULL);
+
+			pFormFiller->GetActionData(pPageView, CPDF_AAction::Validate, fa);
+			pFormFiller->SaveState(pPageView);
+
+			PDFSDK_FieldAction faOld = fa;
+			pWidget->OnAAction(CPDF_AAction::Validate, fa, pPageView);
+
+			bRC = fa.bRC;
+//			bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);
+
+			m_bNotifying = FALSE;
+		}
+	}
+}
+
+void CFFL_IFormFiller::OnCalculate(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bExit, FX_DWORD nFlag)
+{
+	if (!m_bNotifying)
+	{
+		ASSERT(pWidget != NULL);
+		ASSERT(pPageView != NULL);
+// 		CReader_DocView* pDocView = pPageView->GetDocView();
+// 		ASSERT(pDocView != NULL);
+		CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
+		ASSERT(pDocument != NULL);
+
+		CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
+		ASSERT(pInterForm != NULL);
+
+		pInterForm->OnCalculate(pWidget->GetFormField());
+
+//		bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);
+
+		m_bNotifying = FALSE;
+	}
+}
+
+void CFFL_IFormFiller::OnFormat(CPDFSDK_Widget* pWidget, CPDFSDK_PageView* pPageView, FX_BOOL& bExit, FX_DWORD nFlag)
+{
+	if (!m_bNotifying)
+	{
+		ASSERT(pWidget != NULL);
+		ASSERT(pPageView != NULL);
+// 		CReader_DocView* pDocView = pPageView->GetDocView();
+// 		ASSERT(pDocView != NULL);
+		CPDFSDK_Document* pDocument = pPageView->GetSDKDocument();
+		ASSERT(pDocument != NULL);
+
+		CPDFSDK_InterForm* pInterForm = (CPDFSDK_InterForm*)pDocument->GetInterForm();
+		ASSERT(pInterForm != NULL);
+
+		FX_BOOL bFormated = FALSE;
+		CFX_WideString sValue = pInterForm->OnFormat(pWidget->GetFormField(), GetCommitKey(), bFormated);
+
+//		bExit = !IsValidAnnot(m_pApp, pDocument, pDocView, pPageView, pWidget);
+
+		if (bExit) return;
+
+		if (bFormated)
+		{
+			pInterForm->ResetFieldAppearance(pWidget->GetFormField(), sValue, TRUE);
+			pInterForm->UpdateField(pWidget->GetFormField());
+		}
+
+		m_bNotifying = FALSE;
+	}
+}
+
+// LRESULT CALLBACK CFFL_IFormFiller::FFL_WndProc(
+// 									  int code,       // hook code
+// 									  WPARAM wParam,  // virtual-key code
+// 									  LPARAM lParam   // keystroke-message information
+// 										)
+// {
+// 	if (code != HC_ACTION)
+// 	{
+// 		return CallNextHookEx (m_hookSheet, code, wParam, lParam);
+// 	}
+// 
+// 	FXSYS_memcpy(&g_Msg, (void*)lParam, sizeof(MSG));	
+// 
+// 	return 0;
+// }
+
+// MSG	CFFL_IFormFiller::GetLastMessage()
+// {
+// 	return g_Msg;
+// }
+
+int CFFL_IFormFiller::GetCommitKey()
+{
+//	MSG msg = CFFL_IFormFiller::GetLastMessage();
+
+	int nCommitKey = 0;
+// 	switch (msg.message)
+// 	{
+// 	case WM_LBUTTONDOWN:
+// 	case WM_LBUTTONUP:
+// 		nCommitKey = 1;
+// 		break;
+// 	case WM_KEYDOWN:
+// 		switch (msg.wParam)
+// 		{
+// 		case VK_RETURN:
+// 			nCommitKey = 2;
+// 			break;
+// 		case VK_TAB:
+// 			nCommitKey = 3;
+// 			break;
+// 		}
+// 		break;
+// 	}
+
+	return nCommitKey;
+}
+
+FX_BOOL CFFL_IFormFiller::GetKeyDown()
+{
+	return TRUE;
+// 	MSG msg = CFFL_IFormFiller::GetLastMessage();
+// 
+// 	return msg.message == WM_KEYDOWN || msg.message == WM_CHAR;
+}
+
+FX_BOOL	CFFL_IFormFiller::IsValidAnnot(CPDFSDK_PageView* pPageView, CPDFSDK_Annot* pAnnot)
+{
+
+	ASSERT(pPageView != NULL);
+	ASSERT(pAnnot != NULL);
+
+	if(pPageView)
+		return pPageView->IsValidAnnot(pAnnot->GetPDFAnnot());
+	else
+		return FALSE;
+}
+
+void CFFL_IFormFiller::BeforeUndo(CPDFSDK_Document* pDocument)
+{
+
+}
+
+void CFFL_IFormFiller::BeforeRedo(CPDFSDK_Document* pDocument)
+{
+	BeforeUndo(pDocument);
+}
+
+void CFFL_IFormFiller::AfterUndo(CPDFSDK_Document* pDocument)
+{
+}
+
+void CFFL_IFormFiller::AfterRedo(CPDFSDK_Document* pDocument)
+{
+}
+
+FX_BOOL	CFFL_IFormFiller::CanCopy(CPDFSDK_Document* pDocument)
+{
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::CanCut(CPDFSDK_Document* pDocument)
+{
+
+	return FALSE;
+}
+
+FX_BOOL	CFFL_IFormFiller::CanPaste(CPDFSDK_Document* pDocument)
+{
+
+	return FALSE;
+}
+
+void CFFL_IFormFiller::DoCopy(CPDFSDK_Document* pDocument)
+{
+}
+
+void CFFL_IFormFiller::DoCut(CPDFSDK_Document* pDocument)
+{
+}
+
+void CFFL_IFormFiller::DoPaste(CPDFSDK_Document* pDocument)
+{
+
+}
+void CFFL_IFormFiller::OnBeforeKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_INT32 nKeyCode,
+											  CFX_WideString & strChange, const CFX_WideString& strChangeEx, 
+											  int nSelStart, int nSelEnd,
+										FX_BOOL bKeyDown, FX_BOOL & bRC, FX_BOOL & bExit, FX_DWORD nFlag)
+{
+	ASSERT(pPrivateData != NULL);
+	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+	ASSERT(pData->pWidget != NULL);
+	
+	CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
+	ASSERT(pFormFiller != NULL);
+	
+	if (!m_bNotifying)
+	{
+		if (pData->pWidget->GetAAction(CPDF_AAction::KeyStroke))
+		{
+			m_bNotifying = TRUE;
+			int nAge = pData->pWidget->GetAppearanceAge();
+			int nValueAge = pData->pWidget->GetValueAge();
+
+			ASSERT(pData->pPageView != NULL);
+			CPDFSDK_Document* pDocument  = pData->pPageView->GetSDKDocument();
+			
+			PDFSDK_FieldAction fa;
+ 			fa.bModifier = m_pApp->FFI_IsCTRLKeyDown(nFlag);
+ 			fa.bShift = m_pApp->FFI_IsSHIFTKeyDown(nFlag);
+			fa.sChange = strChange;
+			fa.sChangeEx = strChangeEx;
+			fa.bKeyDown = bKeyDown;
+			fa.bWillCommit = FALSE;
+			fa.bRC = TRUE;
+			fa.nSelStart = nSelStart;
+			fa.nSelEnd = nSelEnd;
+
+
+			pFormFiller->GetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
+			pFormFiller->SaveState(pData->pPageView);
+			
+			if (pData->pWidget->OnAAction(CPDF_AAction::KeyStroke, fa, pData->pPageView))
+			{
+				if (!IsValidAnnot(pData->pPageView, pData->pWidget))
+				{
+					bExit = TRUE;
+					m_bNotifying = FALSE;
+					return;
+				}
+				
+				if (nAge != pData->pWidget->GetAppearanceAge())
+				{
+					CPWL_Wnd* pWnd = pFormFiller->ResetPDFWindow(pData->pPageView, nValueAge == pData->pWidget->GetValueAge());
+					pData = (CFFL_PrivateData*)pWnd->GetAttachedData();
+					bExit = TRUE;
+				}
+				
+				if (fa.bRC)
+				{
+					pFormFiller->SetActionData(pData->pPageView, CPDF_AAction::KeyStroke, fa);
+					bRC = FALSE;
+				}
+				else
+				{
+					pFormFiller->RestoreState(pData->pPageView);
+					bRC = FALSE;
+				}
+				
+				if (pDocument->GetFocusAnnot() != pData->pWidget)
+				{
+					pFormFiller->CommitData(pData->pPageView,nFlag);
+					bExit = TRUE;
+				}
+			}
+			else
+			{			
+				if (!IsValidAnnot(pData->pPageView, pData->pWidget))
+				{
+					bExit = TRUE;
+					m_bNotifying = FALSE;
+					return;
+				}
+			}
+			
+			m_bNotifying = FALSE;
+		}
+	}
+}
+
+void	CFFL_IFormFiller::OnAfterKeyStroke(FX_BOOL bEditOrList, void* pPrivateData, FX_BOOL & bExit,FX_DWORD nFlag) 
+{
+	ASSERT(pPrivateData != NULL);
+	CFFL_PrivateData* pData = (CFFL_PrivateData*)pPrivateData;
+	ASSERT(pData->pWidget != NULL);
+	
+	CFFL_FormFiller* pFormFiller = GetFormFiller(pData->pWidget, FALSE);
+	ASSERT(pFormFiller != NULL);
+	
+	if (!bEditOrList)
+		pFormFiller->OnKeyStroke(bExit);
+}
diff --git a/fpdfsdk/src/formfiller/FFL_ListBox.cpp b/fpdfsdk/src/formfiller/FFL_ListBox.cpp
index 9ddb6a0..87ae552 100644
--- a/fpdfsdk/src/formfiller/FFL_ListBox.cpp
+++ b/fpdfsdk/src/formfiller/FFL_ListBox.cpp
@@ -1,319 +1,319 @@
-// 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/FormFiller.h"
-#include "../../include/formfiller/FFL_FormFiller.h"
-#include "../../include/formfiller/FFL_ListBox.h"
-//#include "../../include/formfiller/FFL_Module.h"
-#include "../../include/formfiller/FFL_IFormFiller.h"
-//#include "../../include/formfiller/FFL_Undo.h"
-#include "../../include/formfiller/FFL_CBA_Fontmap.h"
-
-
-#define	FFL_DEFAULTLISTBOXFONTSIZE		12.0f
-
-
-/* ------------------------------- CFFL_ListBox ------------------------------- */
-
-CFFL_ListBox::CFFL_ListBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget) :
-	CFFL_FormFiller(pApp, pWidget),
-	m_pFontMap(NULL)
-{
-}
-
-CFFL_ListBox::~CFFL_ListBox()
-{
-	if (m_pFontMap)
-	{
-		delete m_pFontMap;
-		m_pFontMap = NULL;
-	}
-}
-
-PWL_CREATEPARAM	CFFL_ListBox::GetCreateParam()
-{
-	PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
-
-	ASSERT(m_pWidget != NULL);
-	FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
-		
-	if (dwFieldFlag & FIELDFLAG_MULTISELECT)
-	{		
-		cp.dwFlags |= PLBS_MULTIPLESEL;
-	}
-
-	if (dwFieldFlag & FIELDFLAG_COMMITONSELCHANGE)
-	{
-		//cp.dwFlags |= PLBS_COMMITSELECTEDVALUE;
-	}
-
-	cp.dwFlags |= PWS_VSCROLL;
-
-	if (cp.dwFlags & PWS_AUTOFONTSIZE)
-		cp.fFontSize = FFL_DEFAULTLISTBOXFONTSIZE;
-
-	if (!m_pFontMap)
-	{
-		ASSERT(this->m_pApp != NULL);
-		m_pFontMap = new CBA_FontMap(m_pWidget,m_pApp->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pApp));
-		m_pFontMap->Initial();
-	}
-	cp.pFontMap = m_pFontMap;
-
-	return cp;
-}
-
-CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
-{
-	CPWL_ListBox* pWnd = new CPWL_ListBox();
-	pWnd->AttachFFLData(this);
-	pWnd->Create(cp);
-
-	ASSERT(m_pApp != NULL);
-	CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
-	pWnd->SetFillerNotify(pIFormFiller);
-
-	ASSERT(m_pWidget != NULL);
-	
-	for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
-		pWnd->AddString(m_pWidget->GetOptionLabel(i));
-	
-	if (pWnd->HasFlag(PLBS_MULTIPLESEL))
-	{
-		m_OriginSelections.RemoveAll();
-		
-		FX_BOOL bSetCaret = FALSE;
-		for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
-		{
-			if (m_pWidget->IsOptionSelected(i))
-			{
-				if (!bSetCaret)
-				{
-					pWnd->SetCaret(i);
-					bSetCaret = TRUE;
-				}
-				pWnd->Select(i);
-				m_OriginSelections.SetAt(i, NULL);
-			}
-		}
-	}
-	else
-	{
-		for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
-		{
-			if (m_pWidget->IsOptionSelected(i))
-			{
-				pWnd->Select(i);
-				break;
-			}
-		}
-	}
-	
-	pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
-	
-	return pWnd;
-}
-
-
-FX_BOOL	CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
-{
-	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-}
-
-FX_BOOL	CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(m_pWidget != NULL);
-
-	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
-		{
-			int nSelCount = 0;
-			for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
-			{
-				if (pListBox->IsItemSelected(i))
-				{
-					void* p = NULL;
-					if (!m_OriginSelections.Lookup(i, p))
-						return TRUE;
-
-					nSelCount++;
-				}
-			}
-
-			return nSelCount != m_OriginSelections.GetCount();
-		}
-		else
-		{
-			return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0);
-		}
-	}
-	
-	return FALSE;
-}
-
-void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(m_pWidget != NULL);
-
-	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		CFX_IntArray aOldSelect, aNewSelect;
-
-		{
-			for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
-			{
-				if (m_pWidget->IsOptionSelected(i))
-				{
-					aOldSelect.Add(i);
-				}
-			}
-		}
-
-		
-		FX_INT32 nNewTopIndex = pListBox->GetTopVisibleIndex();
-
-		m_pWidget->ClearSelection(FALSE);	
-
-		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
-		{
-			for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
-			{
-				if (pListBox->IsItemSelected(i))
-				{
-					m_pWidget->SetOptionSelection(i, TRUE, FALSE);
-					aNewSelect.Add(i);
-				}
-			}
-		}
-		else
-		{
-			m_pWidget->SetOptionSelection(pListBox->GetCurSel(), TRUE, FALSE);
-			aNewSelect.Add(pListBox->GetCurSel());
-		}
-
-		m_pWidget->SetTopVisibleIndex(nNewTopIndex);
-		m_pWidget->ResetFieldAppearance(TRUE);
-		m_pWidget->UpdateField();
-		SetChangeMark();
-	}
-}
-
-void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
-						PDFSDK_FieldAction& fa)
-{
-	switch (type)
-	{
-	case CPDF_AAction::Validate:
-		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
-		{
-			fa.sValue = L"";
-		}
-		else
-		{
-			if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
-			{
-				ASSERT(m_pWidget != NULL);
-				FX_INT32 nCurSel = pListBox->GetCurSel();
-				if (nCurSel >= 0)
-					fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
-			}
-		}
-		break;
-	case CPDF_AAction::LoseFocus:
-	case CPDF_AAction::GetFocus:
-		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
-		{
-			fa.sValue = L"";
-		}
-		else
-		{
-			ASSERT(m_pWidget != NULL);
-			FX_INT32 nCurSel = m_pWidget->GetSelectedIndex(0);
-			if (nCurSel >= 0)
-				fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
-		}
-		break;
-	default:
-		break;
-	}
-}
-
-
-void CFFL_ListBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
-								const PDFSDK_FieldAction& fa)
-{
-}
-
-void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(pPageView != NULL);
-
-	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
-		{
-			if (pListBox->IsItemSelected(i))
-			{
-				m_State.Add(i);
-			}
-		}
-	}
-}
-
-void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView)
-{
-	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
-	{
-		for (int i=0,sz=m_State.GetSize(); i<sz; i++)
-			pListBox->Select(m_State[i]);
-	}
-}
-
-CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
-{
-	if (bRestoreValue)
-		SaveState(pPageView);
-	
-	DestroyPDFWindow(pPageView);
-	
-	CPWL_Wnd* pRet = NULL;
-	
-	if (bRestoreValue)
-	{
-		RestoreState(pPageView);
-		pRet = this->GetPDFWindow(pPageView, FALSE);
-	}
-	else
-		pRet = this->GetPDFWindow(pPageView, TRUE);
-	
-	m_pWidget->UpdateField();
-	
-	return pRet;
-}
-
-void CFFL_ListBox::OnKeyStroke(FX_BOOL bKeyDown, FX_DWORD nFlag)
-{
-	ASSERT(m_pWidget != NULL);
-
-	int nFlags = m_pWidget->GetFieldFlags();
-	
-	if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
-	{
-		if (m_bValid)
-		{
-			CPDFSDK_PageView* pPageView = this->GetCurPageView();
-			ASSERT(pPageView != NULL);
-
-			if (CommitData(pPageView, nFlag))
-			{
-				DestroyPDFWindow(pPageView);
-				m_bValid = FALSE;
-			}
-		}
-	}
-}
-
+// 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/FormFiller.h"
+#include "../../include/formfiller/FFL_FormFiller.h"
+#include "../../include/formfiller/FFL_ListBox.h"
+//#include "../../include/formfiller/FFL_Module.h"
+#include "../../include/formfiller/FFL_IFormFiller.h"
+//#include "../../include/formfiller/FFL_Undo.h"
+#include "../../include/formfiller/FFL_CBA_Fontmap.h"
+
+
+#define	FFL_DEFAULTLISTBOXFONTSIZE		12.0f
+
+
+/* ------------------------------- CFFL_ListBox ------------------------------- */
+
+CFFL_ListBox::CFFL_ListBox(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget) :
+	CFFL_FormFiller(pApp, pWidget),
+	m_pFontMap(NULL)
+{
+}
+
+CFFL_ListBox::~CFFL_ListBox()
+{
+	if (m_pFontMap)
+	{
+		delete m_pFontMap;
+		m_pFontMap = NULL;
+	}
+}
+
+PWL_CREATEPARAM	CFFL_ListBox::GetCreateParam()
+{
+	PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
+
+	ASSERT(m_pWidget != NULL);
+	FX_DWORD dwFieldFlag = m_pWidget->GetFieldFlags();
+		
+	if (dwFieldFlag & FIELDFLAG_MULTISELECT)
+	{		
+		cp.dwFlags |= PLBS_MULTIPLESEL;
+	}
+
+	if (dwFieldFlag & FIELDFLAG_COMMITONSELCHANGE)
+	{
+		//cp.dwFlags |= PLBS_COMMITSELECTEDVALUE;
+	}
+
+	cp.dwFlags |= PWS_VSCROLL;
+
+	if (cp.dwFlags & PWS_AUTOFONTSIZE)
+		cp.fFontSize = FFL_DEFAULTLISTBOXFONTSIZE;
+
+	if (!m_pFontMap)
+	{
+		ASSERT(this->m_pApp != NULL);
+		m_pFontMap = new CBA_FontMap(m_pWidget,m_pApp->GetSysHandler());//, ISystemHandle::GetSystemHandler(m_pApp));
+		m_pFontMap->Initial();
+	}
+	cp.pFontMap = m_pFontMap;
+
+	return cp;
+}
+
+CPWL_Wnd* CFFL_ListBox::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
+{
+	CPWL_ListBox* pWnd = new CPWL_ListBox();
+	pWnd->AttachFFLData(this);
+	pWnd->Create(cp);
+
+	ASSERT(m_pApp != NULL);
+	CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
+	pWnd->SetFillerNotify(pIFormFiller);
+
+	ASSERT(m_pWidget != NULL);
+	
+	for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
+		pWnd->AddString(m_pWidget->GetOptionLabel(i));
+	
+	if (pWnd->HasFlag(PLBS_MULTIPLESEL))
+	{
+		m_OriginSelections.RemoveAll();
+		
+		FX_BOOL bSetCaret = FALSE;
+		for (FX_INT32 i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
+		{
+			if (m_pWidget->IsOptionSelected(i))
+			{
+				if (!bSetCaret)
+				{
+					pWnd->SetCaret(i);
+					bSetCaret = TRUE;
+				}
+				pWnd->Select(i);
+				m_OriginSelections.SetAt(i, NULL);
+			}
+		}
+	}
+	else
+	{
+		for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
+		{
+			if (m_pWidget->IsOptionSelected(i))
+			{
+				pWnd->Select(i);
+				break;
+			}
+		}
+	}
+	
+	pWnd->SetTopVisibleIndex(m_pWidget->GetTopVisibleIndex());
+	
+	return pWnd;
+}
+
+
+FX_BOOL	CFFL_ListBox::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
+{
+	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+}
+
+FX_BOOL	CFFL_ListBox::IsDataChanged(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(m_pWidget != NULL);
+
+	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
+		{
+			int nSelCount = 0;
+			for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
+			{
+				if (pListBox->IsItemSelected(i))
+				{
+					void* p = NULL;
+					if (!m_OriginSelections.Lookup(i, p))
+						return TRUE;
+
+					nSelCount++;
+				}
+			}
+
+			return nSelCount != m_OriginSelections.GetCount();
+		}
+		else
+		{
+			return pListBox->GetCurSel() != m_pWidget->GetSelectedIndex(0);
+		}
+	}
+	
+	return FALSE;
+}
+
+void CFFL_ListBox::SaveData(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(m_pWidget != NULL);
+
+	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		CFX_IntArray aOldSelect, aNewSelect;
+
+		{
+			for (int i=0,sz=m_pWidget->CountOptions(); i<sz; i++)
+			{
+				if (m_pWidget->IsOptionSelected(i))
+				{
+					aOldSelect.Add(i);
+				}
+			}
+		}
+
+		
+		FX_INT32 nNewTopIndex = pListBox->GetTopVisibleIndex();
+
+		m_pWidget->ClearSelection(FALSE);	
+
+		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
+		{
+			for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
+			{
+				if (pListBox->IsItemSelected(i))
+				{
+					m_pWidget->SetOptionSelection(i, TRUE, FALSE);
+					aNewSelect.Add(i);
+				}
+			}
+		}
+		else
+		{
+			m_pWidget->SetOptionSelection(pListBox->GetCurSel(), TRUE, FALSE);
+			aNewSelect.Add(pListBox->GetCurSel());
+		}
+
+		m_pWidget->SetTopVisibleIndex(nNewTopIndex);
+		m_pWidget->ResetFieldAppearance(TRUE);
+		m_pWidget->UpdateField();
+		SetChangeMark();
+	}
+}
+
+void CFFL_ListBox::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
+						PDFSDK_FieldAction& fa)
+{
+	switch (type)
+	{
+	case CPDF_AAction::Validate:
+		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
+		{
+			fa.sValue = L"";
+		}
+		else
+		{
+			if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
+			{
+				ASSERT(m_pWidget != NULL);
+				FX_INT32 nCurSel = pListBox->GetCurSel();
+				if (nCurSel >= 0)
+					fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
+			}
+		}
+		break;
+	case CPDF_AAction::LoseFocus:
+	case CPDF_AAction::GetFocus:
+		if (m_pWidget->GetFieldFlags() & FIELDFLAG_MULTISELECT)
+		{
+			fa.sValue = L"";
+		}
+		else
+		{
+			ASSERT(m_pWidget != NULL);
+			FX_INT32 nCurSel = m_pWidget->GetSelectedIndex(0);
+			if (nCurSel >= 0)
+				fa.sValue = m_pWidget->GetOptionLabel(nCurSel);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+
+void CFFL_ListBox::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
+								const PDFSDK_FieldAction& fa)
+{
+}
+
+void CFFL_ListBox::SaveState(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(pPageView != NULL);
+
+	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		for (FX_INT32 i=0,sz=pListBox->GetCount(); i<sz; i++)
+		{
+			if (pListBox->IsItemSelected(i))
+			{
+				m_State.Add(i);
+			}
+		}
+	}
+}
+
+void CFFL_ListBox::RestoreState(CPDFSDK_PageView* pPageView)
+{
+	if (CPWL_ListBox* pListBox = (CPWL_ListBox*)GetPDFWindow(pPageView, FALSE))
+	{
+		for (int i=0,sz=m_State.GetSize(); i<sz; i++)
+			pListBox->Select(m_State[i]);
+	}
+}
+
+CPWL_Wnd* CFFL_ListBox::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
+{
+	if (bRestoreValue)
+		SaveState(pPageView);
+	
+	DestroyPDFWindow(pPageView);
+	
+	CPWL_Wnd* pRet = NULL;
+	
+	if (bRestoreValue)
+	{
+		RestoreState(pPageView);
+		pRet = this->GetPDFWindow(pPageView, FALSE);
+	}
+	else
+		pRet = this->GetPDFWindow(pPageView, TRUE);
+	
+	m_pWidget->UpdateField();
+	
+	return pRet;
+}
+
+void CFFL_ListBox::OnKeyStroke(FX_BOOL bKeyDown, FX_DWORD nFlag)
+{
+	ASSERT(m_pWidget != NULL);
+
+	int nFlags = m_pWidget->GetFieldFlags();
+	
+	if (nFlags & FIELDFLAG_COMMITONSELCHANGE)
+	{
+		if (m_bValid)
+		{
+			CPDFSDK_PageView* pPageView = this->GetCurPageView();
+			ASSERT(pPageView != NULL);
+
+			if (CommitData(pPageView, nFlag))
+			{
+				DestroyPDFWindow(pPageView);
+				m_bValid = FALSE;
+			}
+		}
+	}
+}
+
diff --git a/fpdfsdk/src/formfiller/FFL_Notify.cpp b/fpdfsdk/src/formfiller/FFL_Notify.cpp
index f18ed51..f6a2feb 100644
--- a/fpdfsdk/src/formfiller/FFL_Notify.cpp
+++ b/fpdfsdk/src/formfiller/FFL_Notify.cpp
@@ -1,172 +1,172 @@
-// 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/FormFiller.h"
-#include "../../include/formfiller/FFL_FormFiller.h"
-#include "../../include/formfiller/FFL_Notify.h"
-// #include "../../include/formfiller/FFL_ComboBox.h"
-// #include "../../include/formfiller/FFL_Module.h"
-
-/* -------------------------------- CFFL_Notify ------------------------------ */
-
-//#pragma warning(disable: 4800)
-
-CFFL_Notify::CFFL_Notify(CFFL_FormFiller * pFormFiller) : 
-	m_pFormFiller(pFormFiller),
-	m_bDoActioning(FALSE),
-	m_nNotifyFlag(0)
-{
-	ASSERT(m_pFormFiller != NULL);
-}
-
-CFFL_Notify::~CFFL_Notify()
-{
-}
-
-void CFFL_Notify::BeforeNotify()
-{
-	m_nNotifyFlag ++;
-}
-
-
-void CFFL_Notify::AfterNotify()
-{
-	m_nNotifyFlag --;
-}
-
-FX_BOOL CFFL_Notify::OnMouseUp(FX_BOOL & bExit)
-{
-	BeforeNotify();
-	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::ButtonUp, bExit);
-	AfterNotify();
-	return bRet;
-}
-
-FX_BOOL CFFL_Notify::OnMouseDown(FX_BOOL & bExit)
-{
-	BeforeNotify();
-	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::ButtonDown, bExit);
-	AfterNotify();
-	return bRet;
-}
-
-FX_BOOL CFFL_Notify::OnMouseEnter(FX_BOOL & bExit)
-{
-	BeforeNotify();
-	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::CursorEnter, bExit);
-	AfterNotify();
-	return bRet;
-}
-
-FX_BOOL CFFL_Notify::OnMouseExit(FX_BOOL & bExit)
-{
-	BeforeNotify();
-	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::CursorExit, bExit);
-	AfterNotify();
-	return bRet;
-}
-
-FX_BOOL CFFL_Notify::OnSetFocus(FX_BOOL & bExit)
-{
-	BeforeNotify();
-	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::GetFocus, bExit);
-	AfterNotify();
-	return bRet;
-}
-
-FX_BOOL CFFL_Notify::OnKillFocus(FX_BOOL & bExit)
-{
-	BeforeNotify();
-	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::LoseFocus, bExit);
-	AfterNotify();
-	return bRet;
-}
-
-FX_BOOL CFFL_Notify::OnCalculate()
-{
-	return TRUE;
-}
-
-FX_BOOL CFFL_Notify::OnFormat(int iCommitKey)
-{
-	return TRUE;
-}
-
-FX_BOOL CFFL_Notify::OnKeyStroke(CPDF_FormField* pFormField, int nCommitKey, CFX_WideString& strValue, CFX_WideString& strChange, 
-							   const CFX_WideString& strChangeEx, FX_BOOL bKeyDown, FX_BOOL bModifier,
-							   FX_BOOL bShift, FX_BOOL bWillCommit, FX_BOOL bFieldFull, 
-							   int& nSelStart, int& nSelEnd, FX_BOOL& bRC)
-{
-	return TRUE;
-}
-
-FX_BOOL CFFL_Notify::OnValidate(CPDF_FormField* pFormField, CFX_WideString& strValue, CFX_WideString & strChange, 
-									   const CFX_WideString& strChangeEx, FX_BOOL bKeyDown, FX_BOOL bModifier,
-									   FX_BOOL bShift, FX_BOOL & bRC)
-{
-	return TRUE;
-}
-
-FX_BOOL	CFFL_Notify::DoAAction(CPDF_AAction::AActionType eAAT, FX_BOOL & bExit)
-{
-	if (this->m_bDoActioning) return FALSE;
-	
-	CPDF_Action action;
-	if (!FindAAction(eAAT,action)) return FALSE;
-
-	this->m_bDoActioning = TRUE;	
-	ExecuteActionTree(eAAT,action,bExit);	
-	this->m_bDoActioning = FALSE;
-	return TRUE;
-}
-
-FX_BOOL	CFFL_Notify::ExecuteActionTree(CPDF_AAction::AActionType eAAT,CPDF_Action & action, FX_BOOL& bExit)
-{
-	if (!ExecuteAction(eAAT,action,bExit)) return FALSE;
-	if (bExit) return TRUE;
-
-	for (FX_INT32 i=0,sz=action.GetSubActionsCount(); i<sz; i++)
-	{
-		CPDF_Action subaction = action.GetSubAction(i);
-		if (!ExecuteActionTree(eAAT,subaction,bExit)) return FALSE;
-		if (bExit) break;
-	}
-
-	return TRUE;
-}
-
-
-FX_BOOL	CFFL_Notify::FindAAction(CPDF_AAction::AActionType eAAT,CPDF_Action & action)
-{
-	return FALSE;
-}
-
-FX_BOOL CFFL_Notify::FindAAction(CPDF_AAction aaction,CPDF_AAction::AActionType eAAT,CPDF_Action & action)
-{
-	CPDF_Action MyAction;
-
-	if (aaction.ActionExist(eAAT))
-	{
-		MyAction = aaction.GetAction(eAAT);
-	}
-	else
-		return FALSE;
-
-
-	if (MyAction.GetType() == CPDF_Action::Unknown)
-		return FALSE;
-
-	action = MyAction;
-
-	return TRUE;
-}
-
-FX_BOOL	CFFL_Notify::ExecuteAction(CPDF_AAction::AActionType eAAT,CPDF_Action & action,FX_BOOL& bExit)
-{
-	return FALSE;
-}
-//#pragma warning(default: 4800)
-
+// 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/FormFiller.h"
+#include "../../include/formfiller/FFL_FormFiller.h"
+#include "../../include/formfiller/FFL_Notify.h"
+// #include "../../include/formfiller/FFL_ComboBox.h"
+// #include "../../include/formfiller/FFL_Module.h"
+
+/* -------------------------------- CFFL_Notify ------------------------------ */
+
+//#pragma warning(disable: 4800)
+
+CFFL_Notify::CFFL_Notify(CFFL_FormFiller * pFormFiller) : 
+	m_pFormFiller(pFormFiller),
+	m_bDoActioning(FALSE),
+	m_nNotifyFlag(0)
+{
+	ASSERT(m_pFormFiller != NULL);
+}
+
+CFFL_Notify::~CFFL_Notify()
+{
+}
+
+void CFFL_Notify::BeforeNotify()
+{
+	m_nNotifyFlag ++;
+}
+
+
+void CFFL_Notify::AfterNotify()
+{
+	m_nNotifyFlag --;
+}
+
+FX_BOOL CFFL_Notify::OnMouseUp(FX_BOOL & bExit)
+{
+	BeforeNotify();
+	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::ButtonUp, bExit);
+	AfterNotify();
+	return bRet;
+}
+
+FX_BOOL CFFL_Notify::OnMouseDown(FX_BOOL & bExit)
+{
+	BeforeNotify();
+	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::ButtonDown, bExit);
+	AfterNotify();
+	return bRet;
+}
+
+FX_BOOL CFFL_Notify::OnMouseEnter(FX_BOOL & bExit)
+{
+	BeforeNotify();
+	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::CursorEnter, bExit);
+	AfterNotify();
+	return bRet;
+}
+
+FX_BOOL CFFL_Notify::OnMouseExit(FX_BOOL & bExit)
+{
+	BeforeNotify();
+	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::CursorExit, bExit);
+	AfterNotify();
+	return bRet;
+}
+
+FX_BOOL CFFL_Notify::OnSetFocus(FX_BOOL & bExit)
+{
+	BeforeNotify();
+	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::GetFocus, bExit);
+	AfterNotify();
+	return bRet;
+}
+
+FX_BOOL CFFL_Notify::OnKillFocus(FX_BOOL & bExit)
+{
+	BeforeNotify();
+	FX_BOOL bRet = FALSE;//DoAAction(CPDF_AAction::AActionType::LoseFocus, bExit);
+	AfterNotify();
+	return bRet;
+}
+
+FX_BOOL CFFL_Notify::OnCalculate()
+{
+	return TRUE;
+}
+
+FX_BOOL CFFL_Notify::OnFormat(int iCommitKey)
+{
+	return TRUE;
+}
+
+FX_BOOL CFFL_Notify::OnKeyStroke(CPDF_FormField* pFormField, int nCommitKey, CFX_WideString& strValue, CFX_WideString& strChange, 
+							   const CFX_WideString& strChangeEx, FX_BOOL bKeyDown, FX_BOOL bModifier,
+							   FX_BOOL bShift, FX_BOOL bWillCommit, FX_BOOL bFieldFull, 
+							   int& nSelStart, int& nSelEnd, FX_BOOL& bRC)
+{
+	return TRUE;
+}
+
+FX_BOOL CFFL_Notify::OnValidate(CPDF_FormField* pFormField, CFX_WideString& strValue, CFX_WideString & strChange, 
+									   const CFX_WideString& strChangeEx, FX_BOOL bKeyDown, FX_BOOL bModifier,
+									   FX_BOOL bShift, FX_BOOL & bRC)
+{
+	return TRUE;
+}
+
+FX_BOOL	CFFL_Notify::DoAAction(CPDF_AAction::AActionType eAAT, FX_BOOL & bExit)
+{
+	if (this->m_bDoActioning) return FALSE;
+	
+	CPDF_Action action;
+	if (!FindAAction(eAAT,action)) return FALSE;
+
+	this->m_bDoActioning = TRUE;	
+	ExecuteActionTree(eAAT,action,bExit);	
+	this->m_bDoActioning = FALSE;
+	return TRUE;
+}
+
+FX_BOOL	CFFL_Notify::ExecuteActionTree(CPDF_AAction::AActionType eAAT,CPDF_Action & action, FX_BOOL& bExit)
+{
+	if (!ExecuteAction(eAAT,action,bExit)) return FALSE;
+	if (bExit) return TRUE;
+
+	for (FX_INT32 i=0,sz=action.GetSubActionsCount(); i<sz; i++)
+	{
+		CPDF_Action subaction = action.GetSubAction(i);
+		if (!ExecuteActionTree(eAAT,subaction,bExit)) return FALSE;
+		if (bExit) break;
+	}
+
+	return TRUE;
+}
+
+
+FX_BOOL	CFFL_Notify::FindAAction(CPDF_AAction::AActionType eAAT,CPDF_Action & action)
+{
+	return FALSE;
+}
+
+FX_BOOL CFFL_Notify::FindAAction(CPDF_AAction aaction,CPDF_AAction::AActionType eAAT,CPDF_Action & action)
+{
+	CPDF_Action MyAction;
+
+	if (aaction.ActionExist(eAAT))
+	{
+		MyAction = aaction.GetAction(eAAT);
+	}
+	else
+		return FALSE;
+
+
+	if (MyAction.GetType() == CPDF_Action::Unknown)
+		return FALSE;
+
+	action = MyAction;
+
+	return TRUE;
+}
+
+FX_BOOL	CFFL_Notify::ExecuteAction(CPDF_AAction::AActionType eAAT,CPDF_Action & action,FX_BOOL& bExit)
+{
+	return FALSE;
+}
+//#pragma warning(default: 4800)
+
diff --git a/fpdfsdk/src/formfiller/FFL_PushButton.cpp b/fpdfsdk/src/formfiller/FFL_PushButton.cpp
index 1afbe8b..b8a07fb 100644
--- a/fpdfsdk/src/formfiller/FFL_PushButton.cpp
+++ b/fpdfsdk/src/formfiller/FFL_PushButton.cpp
@@ -1,43 +1,43 @@
-// 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/FormFiller.h"
-#include "../../include/formfiller/FFL_FormFiller.h"
-#include "../../include/formfiller/FFL_PushButton.h"
-
-/* ------------------------------- CFFL_PushButton ------------------------------- */
-
-CFFL_PushButton::CFFL_PushButton(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot):
-	CFFL_Button( pApp, pAnnot)
-{
-}
-
-CFFL_PushButton::~CFFL_PushButton()
-{
-}
-
-CPWL_Wnd* CFFL_PushButton::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
-{
-	CPWL_PushButton* pWnd = new CPWL_PushButton();
-	pWnd->Create(cp);
-	
-	return pWnd;
-}
-
-
-FX_BOOL	CFFL_PushButton::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
-{
-	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-}
-
-void CFFL_PushButton::OnDraw(CPDFSDK_PageView *pPageView,  CPDFSDK_Annot* pAnnot, 
-							 CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
-							 FX_DWORD dwFlags)
-{
-	CFFL_Button::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/FormFiller.h"
+#include "../../include/formfiller/FFL_FormFiller.h"
+#include "../../include/formfiller/FFL_PushButton.h"
+
+/* ------------------------------- CFFL_PushButton ------------------------------- */
+
+CFFL_PushButton::CFFL_PushButton(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot):
+	CFFL_Button( pApp, pAnnot)
+{
+}
+
+CFFL_PushButton::~CFFL_PushButton()
+{
+}
+
+CPWL_Wnd* CFFL_PushButton::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
+{
+	CPWL_PushButton* pWnd = new CPWL_PushButton();
+	pWnd->Create(cp);
+	
+	return pWnd;
+}
+
+
+FX_BOOL	CFFL_PushButton::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
+{
+	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+}
+
+void CFFL_PushButton::OnDraw(CPDFSDK_PageView *pPageView,  CPDFSDK_Annot* pAnnot, 
+							 CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device,
+							 FX_DWORD dwFlags)
+{
+	CFFL_Button::OnDraw(pPageView, pAnnot, pDevice, pUser2Device, dwFlags);
+}
+
+
diff --git a/fpdfsdk/src/formfiller/FFL_RadioButton.cpp b/fpdfsdk/src/formfiller/FFL_RadioButton.cpp
index 462c05e..aacb7d8 100644
--- a/fpdfsdk/src/formfiller/FFL_RadioButton.cpp
+++ b/fpdfsdk/src/formfiller/FFL_RadioButton.cpp
@@ -1,137 +1,137 @@
-// 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/FormFiller.h"
-#include "../../include/formfiller/FFL_FormFiller.h"
-#include "../../include/formfiller/FFL_RadioButton.h"
-//#include "../include/FFL_Undo.h"
-
-/* ------------------------------- CFFL_RadioButton ------------------------------- */
-
-CFFL_RadioButton::CFFL_RadioButton(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget) :
-	CFFL_Button(pApp, pWidget)
-{
-}
-
-CFFL_RadioButton::~CFFL_RadioButton()
-{
-}
-
-CPWL_Wnd* CFFL_RadioButton::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
-{
-	CPWL_RadioButton* pWnd = new CPWL_RadioButton();
-	pWnd->Create(cp);
-
-	ASSERT(m_pWidget != NULL);
-	pWnd->SetCheck(m_pWidget->IsChecked());
-	
-	return pWnd;
-}
-
-FX_BOOL	CFFL_RadioButton::OnKeyDown(CPDFSDK_Annot* pAnnot, FX_UINT nKeyCode, FX_UINT nFlags)
-{
-	switch (nKeyCode)
-	{
-	case FWL_VKEY_Return:
-	case FWL_VKEY_Space:
-		return TRUE;
-	default:
-		return CFFL_FormFiller::OnKeyDown(pAnnot, nKeyCode, nFlags);
-	}
-}
-
-FX_BOOL	CFFL_RadioButton::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
-{
-	switch (nChar)
-	{
-	case FWL_VKEY_Return:	
-	case FWL_VKEY_Space:
-		{
-			CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
-			ASSERT(pIFormFiller != NULL);
-
-			CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
-			ASSERT(pPageView != NULL);
-
-			FX_BOOL bReset = FALSE;
-			FX_BOOL bExit = FALSE;
-
-			pIFormFiller->OnButtonUp(m_pWidget, pPageView, bReset, bExit,nFlags);
-
-			if (bReset) return TRUE;
-			if (bExit) return TRUE;
-
-			CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-
-			if (CPWL_RadioButton * pWnd = (CPWL_RadioButton*)GetPDFWindow(pPageView, TRUE))
-				pWnd->SetCheck(TRUE);
-			CommitData(pPageView,nFlags);
-			return TRUE;
-		}
-	default:
-		return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-	}
-}
-
-FX_BOOL	CFFL_RadioButton::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
-{
-	CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point);
-
-	if (IsValid())
-	{
-		if (CPWL_RadioButton * pWnd = (CPWL_RadioButton*)GetPDFWindow(pPageView, TRUE))
-			pWnd->SetCheck(TRUE);
-
-		if (!CommitData(pPageView,nFlags)) return FALSE;
-	}
-
-	return TRUE;
-}
-
-FX_BOOL	CFFL_RadioButton::IsDataChanged(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(m_pWidget != NULL);
-
-	if (CPWL_RadioButton* pWnd = (CPWL_RadioButton*)GetPDFWindow(pPageView, FALSE))
-	{
-		return pWnd->IsChecked() != m_pWidget->IsChecked();
-	}
-
-	return FALSE;
-}
-
-void CFFL_RadioButton::SaveData(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(m_pWidget != NULL);
-
-	if (CPWL_RadioButton* pWnd = (CPWL_RadioButton*)GetPDFWindow(pPageView, FALSE))
-	{
-		
-		FX_BOOL bNewChecked = pWnd->IsChecked();
-
-		if (bNewChecked)
-		{
-			CPDF_FormField* pField = m_pWidget->GetFormField();
-			ASSERT(pField != NULL);
-
-			for (FX_INT32 i=0,sz=pField->CountControls(); i<sz; i++)
-			{
-				if (CPDF_FormControl* pCtrl = pField->GetControl(i))
-				{
-					if (pCtrl->IsChecked())
-					{
-						break;
-					}
-				}
-			}
-		}
-
-		m_pWidget->SetCheck(bNewChecked, FALSE);
-		m_pWidget->UpdateField();
-		SetChangeMark();
-	}
-}
-
+// 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/FormFiller.h"
+#include "../../include/formfiller/FFL_FormFiller.h"
+#include "../../include/formfiller/FFL_RadioButton.h"
+//#include "../include/FFL_Undo.h"
+
+/* ------------------------------- CFFL_RadioButton ------------------------------- */
+
+CFFL_RadioButton::CFFL_RadioButton(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pWidget) :
+	CFFL_Button(pApp, pWidget)
+{
+}
+
+CFFL_RadioButton::~CFFL_RadioButton()
+{
+}
+
+CPWL_Wnd* CFFL_RadioButton::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
+{
+	CPWL_RadioButton* pWnd = new CPWL_RadioButton();
+	pWnd->Create(cp);
+
+	ASSERT(m_pWidget != NULL);
+	pWnd->SetCheck(m_pWidget->IsChecked());
+	
+	return pWnd;
+}
+
+FX_BOOL	CFFL_RadioButton::OnKeyDown(CPDFSDK_Annot* pAnnot, FX_UINT nKeyCode, FX_UINT nFlags)
+{
+	switch (nKeyCode)
+	{
+	case FWL_VKEY_Return:
+	case FWL_VKEY_Space:
+		return TRUE;
+	default:
+		return CFFL_FormFiller::OnKeyDown(pAnnot, nKeyCode, nFlags);
+	}
+}
+
+FX_BOOL	CFFL_RadioButton::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
+{
+	switch (nChar)
+	{
+	case FWL_VKEY_Return:	
+	case FWL_VKEY_Space:
+		{
+			CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
+			ASSERT(pIFormFiller != NULL);
+
+			CPDFSDK_PageView* pPageView = pAnnot->GetPageView();
+			ASSERT(pPageView != NULL);
+
+			FX_BOOL bReset = FALSE;
+			FX_BOOL bExit = FALSE;
+
+			pIFormFiller->OnButtonUp(m_pWidget, pPageView, bReset, bExit,nFlags);
+
+			if (bReset) return TRUE;
+			if (bExit) return TRUE;
+
+			CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+
+			if (CPWL_RadioButton * pWnd = (CPWL_RadioButton*)GetPDFWindow(pPageView, TRUE))
+				pWnd->SetCheck(TRUE);
+			CommitData(pPageView,nFlags);
+			return TRUE;
+		}
+	default:
+		return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+	}
+}
+
+FX_BOOL	CFFL_RadioButton::OnLButtonUp(CPDFSDK_PageView *pPageView, CPDFSDK_Annot* pAnnot, FX_UINT nFlags, const CPDF_Point& point)
+{
+	CFFL_Button::OnLButtonUp(pPageView, pAnnot, nFlags, point);
+
+	if (IsValid())
+	{
+		if (CPWL_RadioButton * pWnd = (CPWL_RadioButton*)GetPDFWindow(pPageView, TRUE))
+			pWnd->SetCheck(TRUE);
+
+		if (!CommitData(pPageView,nFlags)) return FALSE;
+	}
+
+	return TRUE;
+}
+
+FX_BOOL	CFFL_RadioButton::IsDataChanged(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(m_pWidget != NULL);
+
+	if (CPWL_RadioButton* pWnd = (CPWL_RadioButton*)GetPDFWindow(pPageView, FALSE))
+	{
+		return pWnd->IsChecked() != m_pWidget->IsChecked();
+	}
+
+	return FALSE;
+}
+
+void CFFL_RadioButton::SaveData(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(m_pWidget != NULL);
+
+	if (CPWL_RadioButton* pWnd = (CPWL_RadioButton*)GetPDFWindow(pPageView, FALSE))
+	{
+		
+		FX_BOOL bNewChecked = pWnd->IsChecked();
+
+		if (bNewChecked)
+		{
+			CPDF_FormField* pField = m_pWidget->GetFormField();
+			ASSERT(pField != NULL);
+
+			for (FX_INT32 i=0,sz=pField->CountControls(); i<sz; i++)
+			{
+				if (CPDF_FormControl* pCtrl = pField->GetControl(i))
+				{
+					if (pCtrl->IsChecked())
+					{
+						break;
+					}
+				}
+			}
+		}
+
+		m_pWidget->SetCheck(bNewChecked, FALSE);
+		m_pWidget->UpdateField();
+		SetChangeMark();
+	}
+}
+
diff --git a/fpdfsdk/src/formfiller/FFL_TextField.cpp b/fpdfsdk/src/formfiller/FFL_TextField.cpp
index 7644d4b..8cd62fa 100644
--- a/fpdfsdk/src/formfiller/FFL_TextField.cpp
+++ b/fpdfsdk/src/formfiller/FFL_TextField.cpp
@@ -1,412 +1,412 @@
-// 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.h"
-//#include "../include/FFL_FormFiller.h"
-#include "../../include/formfiller/FFL_TextField.h"
-#include "../../include/formfiller/FFL_CBA_Fontmap.h"
-//#include "../include/FFL_Notify.h"
-
-CFFL_EditUndoItem::CFFL_EditUndoItem(CPWL_Edit* pEdit) : m_pEdit(pEdit)
-{
-}
-
-CFFL_EditUndoItem::~CFFL_EditUndoItem()
-{
-}
-
-void CFFL_EditUndoItem::Undo()
-{
-}
-
-void CFFL_EditUndoItem::Redo()
-{
-}
-
-CFX_WideString CFFL_EditUndoItem::GetDescr()
-{
-	return L"Input";
-}
-
-void CFFL_EditUndoItem::Release()
-{
-	delete this;
-}
-
-/* ------------------------------- CFFL_TextField ------------------------------- */
-
-CFFL_TextField::CFFL_TextField(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot) :
-	CFFL_FormFiller(pApp, pAnnot),
-	m_pFontMap(NULL)//,
-	//m_pSpellCheck(NULL)
-{
-	m_State.nStart = m_State.nEnd = 0;
-}
-
-CFFL_TextField::~CFFL_TextField()
-{
-	if (m_pFontMap)
-	{
-		delete m_pFontMap;
-		m_pFontMap = NULL;
-	}
-
-}
-
-PWL_CREATEPARAM CFFL_TextField::GetCreateParam()
-{
-	PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
-
-	ASSERT(m_pWidget != NULL);
-	int nFlags = m_pWidget->GetFieldFlags();
-
-
-	if (nFlags & FIELDFLAG_PASSWORD)
-	{		
-		cp.dwFlags |= PES_PASSWORD;
-	}
-
-	if (!(nFlags & FIELDFLAG_DONOTSPELLCHECK))
-	{		
-	}
-
-	if (nFlags & FIELDFLAG_MULTILINE)
-	{		
-		cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
-
-		if (!(nFlags & FIELDFLAG_DONOTSCROLL))
-		{
-			cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL;
-		}
-	}
-	else
-	{
-		cp.dwFlags |= PES_CENTER;
-
-		if (!(nFlags & FIELDFLAG_DONOTSCROLL))
-		{
-			cp.dwFlags |= PES_AUTOSCROLL;
-		}
-	}
-
-	if (nFlags & FIELDFLAG_COMB)
-	{		
-		cp.dwFlags |= PES_CHARARRAY;
-	}
-
-	if (nFlags & FIELDFLAG_RICHTEXT)
-	{		
-		cp.dwFlags |= PES_RICH;
-	}
-
-	cp.dwFlags |= PES_UNDO;
-	
- 	switch (m_pWidget->GetAlignment())
- 	{
- 	default:
- 	case BF_ALIGN_LEFT:
- 		cp.dwFlags |= PES_LEFT;
- 		break;
- 	case BF_ALIGN_MIDDLE:
- 		cp.dwFlags |= PES_MIDDLE;
- 		break;
- 	case BF_ALIGN_RIGHT:
- 		cp.dwFlags |= PES_RIGHT;
- 		break;
- 	}
-
-	if (!m_pFontMap)
-	{
-		ASSERT(this->m_pApp != NULL);
-		m_pFontMap = new CBA_FontMap(m_pWidget, /*ISystemHandle::GetSystemHandler(m_pApp)*/m_pApp->GetSysHandler());
-		m_pFontMap->Initial();
-	}
-	cp.pFontMap = m_pFontMap;
-	cp.pFocusHandler = this;
-
-	return cp;
-}
-
-CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
-{
-	CPWL_Edit * pWnd = new CPWL_Edit();
-		pWnd->AttachFFLData(this);
-	pWnd->Create(cp);
-
-
-
-	ASSERT(m_pApp != NULL);
-	CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
-	pWnd->SetFillerNotify(pIFormFiller);
-
-	ASSERT(m_pWidget != NULL);
-	FX_INT32 nMaxLen = m_pWidget->GetMaxLen();
-	CFX_WideString swValue = m_pWidget->GetValue();
-	
-	if (nMaxLen > 0)
-	{
-		if (pWnd->HasFlag(PES_CHARARRAY))
-		{
-			pWnd->SetCharArray(nMaxLen);
-			pWnd->SetAlignFormatV(PEAV_CENTER);
-		}
-		else
-		{
-			pWnd->SetLimitChar(nMaxLen);
-		}
-	}
-	
-	pWnd->SetText(swValue);
-	
-	return pWnd;
-}
-
-
-FX_BOOL	CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
-{
-	switch (nChar)
-	{
-	case FWL_VKEY_Return:
- 		if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE))
- 		{
- 			CPDFSDK_PageView* pPageView = this->GetCurPageView();
- 			ASSERT(pPageView != NULL);
- 			m_bValid = !m_bValid;
-			CPDF_Rect rcAnnot = pAnnot->GetRect();
-			m_pApp->FFI_Invalidate(pAnnot->GetPDFPage(), rcAnnot.left, rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
- 
- 			if (m_bValid)
- 			{
- 				if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
- 					pWnd->SetFocus();
- 			}
- 			else
- 			{
- 				if (CommitData(pPageView, nFlags))
- 				{
- 					DestroyPDFWindow(pPageView);
- 					return TRUE;
- 				}
- 				else
- 				{
- 					return FALSE;
- 				}
- 			}
- 		}
-		break;
-	case FWL_VKEY_Escape:
-		{
-			CPDFSDK_PageView* pPageView = this->GetCurPageView();
-			ASSERT(pPageView != NULL);
-			EscapeFiller(pPageView,TRUE);
-			return TRUE;
-		}
-	}
-
-	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
-}
-
-FX_BOOL	CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(m_pWidget != NULL);
-
- 	if (CPWL_Edit * pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
- 		return pEdit->GetText() != m_pWidget->GetValue();
-
-	return FALSE;
-}
-
-void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(m_pWidget != NULL);
-
-	if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
-	{
-		CFX_WideString sOldValue = m_pWidget->GetValue();
-		CFX_WideString sNewValue = pWnd->GetText();
-
-		m_pWidget->SetValue(sNewValue, FALSE);	
-		m_pWidget->ResetFieldAppearance(TRUE);
-		m_pWidget->UpdateField();
-		SetChangeMark();
-	}
-}
-
-void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
-									PDFSDK_FieldAction& fa)
-{
-	switch (type)
-	{
-	case CPDF_AAction::KeyStroke:
-		if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
-		{
-			fa.bFieldFull = pWnd->IsTextFull();	
-
-			fa.sValue = pWnd->GetText();
-			
-			if (fa.bFieldFull)
-			{
-				fa.sChange = L"";
-				fa.sChangeEx = L"";
-			}
-		}
-		break;
-	case CPDF_AAction::Validate:
-		if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
-		{
-			fa.sValue = pWnd->GetText();
-		}
-		break;
-	case CPDF_AAction::LoseFocus:
-	case CPDF_AAction::GetFocus:
-		ASSERT(m_pWidget != NULL);
-		fa.sValue = m_pWidget->GetValue();
-		break;
-	default:
-		break;
-	}
-}
-
-void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
- 									const PDFSDK_FieldAction& fa)
-{
-	switch (type)
-	{
-	case CPDF_AAction::KeyStroke:
-		if (CPWL_Edit * pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
-		{
-			pEdit->SetFocus();
-			pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
-			pEdit->ReplaceSel(fa.sChange);
-		}
-		break;
-	default:
-		break;
-	}
-}
-
-
-FX_BOOL	CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type, const PDFSDK_FieldAction& faOld, 
-									const PDFSDK_FieldAction& faNew)
-{
-	switch (type)
-	{
-	case CPDF_AAction::KeyStroke:
-		return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) || faOld.nSelStart != faNew.nSelStart ||
-			faOld.sChange != faNew.sChange;
-	default:
-		break;
-	}
-
-	return FALSE;
-}
-
-void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(pPageView != NULL);
-
-	if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
-	{
-		pWnd->GetSel(m_State.nStart, m_State.nEnd);
-		m_State.sValue = pWnd->GetText();
-	}
-}
-
-void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView)
-{
-	ASSERT(pPageView != NULL);
-
-	if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE))
-	{
-		pWnd->SetText(m_State.sValue);
-		pWnd->SetSel(m_State.nStart, m_State.nEnd);
-	}
-}
-
-CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
-{
-	if (bRestoreValue)
-		SaveState(pPageView);
-
-	DestroyPDFWindow(pPageView);
-
-	CPWL_Wnd* pRet = NULL;
-
-	if (bRestoreValue)
-	{
-		RestoreState(pPageView);
-		pRet = this->GetPDFWindow(pPageView, FALSE);
-	}
-	else
-		pRet = this->GetPDFWindow(pPageView, TRUE);
-
-	m_pWidget->UpdateField();
-	
-	return pRet;
-}
-
-void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd)
-{
-	ASSERT(m_pApp != NULL);
-	
- 	ASSERT(pWnd != NULL);
- 
- 	if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT)
- 	{
- 		CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
-		pEdit->SetCharSet(134);
-		pEdit->SetCodePage(936);
- 
-		pEdit->SetReadyToInput();
-		CFX_WideString wsText = pEdit->GetText();
-		int nCharacters = wsText.GetLength();
-		CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
-		unsigned short* pBuffer = (unsigned short*)(FX_LPCSTR)bsUTFText;
-		m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer, nCharacters, TRUE);
- 
- 		pEdit->SetEditNotify(this);
- 		//pUndo->BeginEdit(pDocument);
- 	}
-}
-
-void CFFL_TextField::OnKillFocus(CPWL_Wnd* pWnd)
-{
-
-}
-
-FX_BOOL	CFFL_TextField::CanCopy(CPDFSDK_Document* pDocument)
-{
-	return FALSE;
-}
-
-FX_BOOL CFFL_TextField::CanCut(CPDFSDK_Document* pDocument)
-{
-	return FALSE;
-}
-
-FX_BOOL	CFFL_TextField::CanPaste(CPDFSDK_Document* pDocument)
-{
-	return FALSE;
-}
-
-void CFFL_TextField::DoCopy(CPDFSDK_Document* pDocument)
-{
-
-}
-
-void CFFL_TextField::DoCut(CPDFSDK_Document* pDocument)
-{
-}
-
-void CFFL_TextField::DoPaste(CPDFSDK_Document* pDocument)
-{
-
-}
-
-void CFFL_TextField::OnAddUndo(CPWL_Edit* pEdit)
-{
-}
-
+// 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.h"
+//#include "../include/FFL_FormFiller.h"
+#include "../../include/formfiller/FFL_TextField.h"
+#include "../../include/formfiller/FFL_CBA_Fontmap.h"
+//#include "../include/FFL_Notify.h"
+
+CFFL_EditUndoItem::CFFL_EditUndoItem(CPWL_Edit* pEdit) : m_pEdit(pEdit)
+{
+}
+
+CFFL_EditUndoItem::~CFFL_EditUndoItem()
+{
+}
+
+void CFFL_EditUndoItem::Undo()
+{
+}
+
+void CFFL_EditUndoItem::Redo()
+{
+}
+
+CFX_WideString CFFL_EditUndoItem::GetDescr()
+{
+	return L"Input";
+}
+
+void CFFL_EditUndoItem::Release()
+{
+	delete this;
+}
+
+/* ------------------------------- CFFL_TextField ------------------------------- */
+
+CFFL_TextField::CFFL_TextField(CPDFDoc_Environment* pApp, CPDFSDK_Annot* pAnnot) :
+	CFFL_FormFiller(pApp, pAnnot),
+	m_pFontMap(NULL)//,
+	//m_pSpellCheck(NULL)
+{
+	m_State.nStart = m_State.nEnd = 0;
+}
+
+CFFL_TextField::~CFFL_TextField()
+{
+	if (m_pFontMap)
+	{
+		delete m_pFontMap;
+		m_pFontMap = NULL;
+	}
+
+}
+
+PWL_CREATEPARAM CFFL_TextField::GetCreateParam()
+{
+	PWL_CREATEPARAM cp = CFFL_FormFiller::GetCreateParam();
+
+	ASSERT(m_pWidget != NULL);
+	int nFlags = m_pWidget->GetFieldFlags();
+
+
+	if (nFlags & FIELDFLAG_PASSWORD)
+	{		
+		cp.dwFlags |= PES_PASSWORD;
+	}
+
+	if (!(nFlags & FIELDFLAG_DONOTSPELLCHECK))
+	{		
+	}
+
+	if (nFlags & FIELDFLAG_MULTILINE)
+	{		
+		cp.dwFlags |= PES_MULTILINE | PES_AUTORETURN | PES_TOP;
+
+		if (!(nFlags & FIELDFLAG_DONOTSCROLL))
+		{
+			cp.dwFlags |= PWS_VSCROLL | PES_AUTOSCROLL;
+		}
+	}
+	else
+	{
+		cp.dwFlags |= PES_CENTER;
+
+		if (!(nFlags & FIELDFLAG_DONOTSCROLL))
+		{
+			cp.dwFlags |= PES_AUTOSCROLL;
+		}
+	}
+
+	if (nFlags & FIELDFLAG_COMB)
+	{		
+		cp.dwFlags |= PES_CHARARRAY;
+	}
+
+	if (nFlags & FIELDFLAG_RICHTEXT)
+	{		
+		cp.dwFlags |= PES_RICH;
+	}
+
+	cp.dwFlags |= PES_UNDO;
+	
+ 	switch (m_pWidget->GetAlignment())
+ 	{
+ 	default:
+ 	case BF_ALIGN_LEFT:
+ 		cp.dwFlags |= PES_LEFT;
+ 		break;
+ 	case BF_ALIGN_MIDDLE:
+ 		cp.dwFlags |= PES_MIDDLE;
+ 		break;
+ 	case BF_ALIGN_RIGHT:
+ 		cp.dwFlags |= PES_RIGHT;
+ 		break;
+ 	}
+
+	if (!m_pFontMap)
+	{
+		ASSERT(this->m_pApp != NULL);
+		m_pFontMap = new CBA_FontMap(m_pWidget, /*ISystemHandle::GetSystemHandler(m_pApp)*/m_pApp->GetSysHandler());
+		m_pFontMap->Initial();
+	}
+	cp.pFontMap = m_pFontMap;
+	cp.pFocusHandler = this;
+
+	return cp;
+}
+
+CPWL_Wnd* CFFL_TextField::NewPDFWindow(const PWL_CREATEPARAM& cp, CPDFSDK_PageView* pPageView)
+{
+	CPWL_Edit * pWnd = new CPWL_Edit();
+		pWnd->AttachFFLData(this);
+	pWnd->Create(cp);
+
+
+
+	ASSERT(m_pApp != NULL);
+	CFFL_IFormFiller* pIFormFiller = m_pApp->GetIFormFiller();
+	pWnd->SetFillerNotify(pIFormFiller);
+
+	ASSERT(m_pWidget != NULL);
+	FX_INT32 nMaxLen = m_pWidget->GetMaxLen();
+	CFX_WideString swValue = m_pWidget->GetValue();
+	
+	if (nMaxLen > 0)
+	{
+		if (pWnd->HasFlag(PES_CHARARRAY))
+		{
+			pWnd->SetCharArray(nMaxLen);
+			pWnd->SetAlignFormatV(PEAV_CENTER);
+		}
+		else
+		{
+			pWnd->SetLimitChar(nMaxLen);
+		}
+	}
+	
+	pWnd->SetText(swValue);
+	
+	return pWnd;
+}
+
+
+FX_BOOL	CFFL_TextField::OnChar(CPDFSDK_Annot* pAnnot, FX_UINT nChar, FX_UINT nFlags)
+{
+	switch (nChar)
+	{
+	case FWL_VKEY_Return:
+ 		if (!(m_pWidget->GetFieldFlags() & FIELDFLAG_MULTILINE))
+ 		{
+ 			CPDFSDK_PageView* pPageView = this->GetCurPageView();
+ 			ASSERT(pPageView != NULL);
+ 			m_bValid = !m_bValid;
+			CPDF_Rect rcAnnot = pAnnot->GetRect();
+			m_pApp->FFI_Invalidate(pAnnot->GetPDFPage(), rcAnnot.left, rcAnnot.top, rcAnnot.right, rcAnnot.bottom);
+ 
+ 			if (m_bValid)
+ 			{
+ 				if (CPWL_Wnd* pWnd = GetPDFWindow(pPageView, TRUE))
+ 					pWnd->SetFocus();
+ 			}
+ 			else
+ 			{
+ 				if (CommitData(pPageView, nFlags))
+ 				{
+ 					DestroyPDFWindow(pPageView);
+ 					return TRUE;
+ 				}
+ 				else
+ 				{
+ 					return FALSE;
+ 				}
+ 			}
+ 		}
+		break;
+	case FWL_VKEY_Escape:
+		{
+			CPDFSDK_PageView* pPageView = this->GetCurPageView();
+			ASSERT(pPageView != NULL);
+			EscapeFiller(pPageView,TRUE);
+			return TRUE;
+		}
+	}
+
+	return CFFL_FormFiller::OnChar(pAnnot, nChar, nFlags);
+}
+
+FX_BOOL	CFFL_TextField::IsDataChanged(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(m_pWidget != NULL);
+
+ 	if (CPWL_Edit * pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
+ 		return pEdit->GetText() != m_pWidget->GetValue();
+
+	return FALSE;
+}
+
+void CFFL_TextField::SaveData(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(m_pWidget != NULL);
+
+	if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
+	{
+		CFX_WideString sOldValue = m_pWidget->GetValue();
+		CFX_WideString sNewValue = pWnd->GetText();
+
+		m_pWidget->SetValue(sNewValue, FALSE);	
+		m_pWidget->ResetFieldAppearance(TRUE);
+		m_pWidget->UpdateField();
+		SetChangeMark();
+	}
+}
+
+void CFFL_TextField::GetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type,
+									PDFSDK_FieldAction& fa)
+{
+	switch (type)
+	{
+	case CPDF_AAction::KeyStroke:
+		if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
+		{
+			fa.bFieldFull = pWnd->IsTextFull();	
+
+			fa.sValue = pWnd->GetText();
+			
+			if (fa.bFieldFull)
+			{
+				fa.sChange = L"";
+				fa.sChangeEx = L"";
+			}
+		}
+		break;
+	case CPDF_AAction::Validate:
+		if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
+		{
+			fa.sValue = pWnd->GetText();
+		}
+		break;
+	case CPDF_AAction::LoseFocus:
+	case CPDF_AAction::GetFocus:
+		ASSERT(m_pWidget != NULL);
+		fa.sValue = m_pWidget->GetValue();
+		break;
+	default:
+		break;
+	}
+}
+
+void CFFL_TextField::SetActionData(CPDFSDK_PageView* pPageView, CPDF_AAction::AActionType type, 
+ 									const PDFSDK_FieldAction& fa)
+{
+	switch (type)
+	{
+	case CPDF_AAction::KeyStroke:
+		if (CPWL_Edit * pEdit = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
+		{
+			pEdit->SetFocus();
+			pEdit->SetSel(fa.nSelStart, fa.nSelEnd);
+			pEdit->ReplaceSel(fa.sChange);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+
+FX_BOOL	CFFL_TextField::IsActionDataChanged(CPDF_AAction::AActionType type, const PDFSDK_FieldAction& faOld, 
+									const PDFSDK_FieldAction& faNew)
+{
+	switch (type)
+	{
+	case CPDF_AAction::KeyStroke:
+		return (!faOld.bFieldFull && faOld.nSelEnd != faNew.nSelEnd) || faOld.nSelStart != faNew.nSelStart ||
+			faOld.sChange != faNew.sChange;
+	default:
+		break;
+	}
+
+	return FALSE;
+}
+
+void CFFL_TextField::SaveState(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(pPageView != NULL);
+
+	if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, FALSE))
+	{
+		pWnd->GetSel(m_State.nStart, m_State.nEnd);
+		m_State.sValue = pWnd->GetText();
+	}
+}
+
+void CFFL_TextField::RestoreState(CPDFSDK_PageView* pPageView)
+{
+	ASSERT(pPageView != NULL);
+
+	if (CPWL_Edit* pWnd = (CPWL_Edit*)GetPDFWindow(pPageView, TRUE))
+	{
+		pWnd->SetText(m_State.sValue);
+		pWnd->SetSel(m_State.nStart, m_State.nEnd);
+	}
+}
+
+CPWL_Wnd* CFFL_TextField::ResetPDFWindow(CPDFSDK_PageView* pPageView, FX_BOOL bRestoreValue)
+{
+	if (bRestoreValue)
+		SaveState(pPageView);
+
+	DestroyPDFWindow(pPageView);
+
+	CPWL_Wnd* pRet = NULL;
+
+	if (bRestoreValue)
+	{
+		RestoreState(pPageView);
+		pRet = this->GetPDFWindow(pPageView, FALSE);
+	}
+	else
+		pRet = this->GetPDFWindow(pPageView, TRUE);
+
+	m_pWidget->UpdateField();
+	
+	return pRet;
+}
+
+void CFFL_TextField::OnSetFocus(CPWL_Wnd* pWnd)
+{
+	ASSERT(m_pApp != NULL);
+	
+ 	ASSERT(pWnd != NULL);
+ 
+ 	if (pWnd->GetClassName() == PWL_CLASSNAME_EDIT)
+ 	{
+ 		CPWL_Edit* pEdit = (CPWL_Edit*)pWnd;
+		pEdit->SetCharSet(134);
+		pEdit->SetCodePage(936);
+ 
+		pEdit->SetReadyToInput();
+		CFX_WideString wsText = pEdit->GetText();
+		int nCharacters = wsText.GetLength();
+		CFX_ByteString bsUTFText = wsText.UTF16LE_Encode();
+		unsigned short* pBuffer = (unsigned short*)(FX_LPCSTR)bsUTFText;
+		m_pApp->FFI_OnSetFieldInputFocus(m_pWidget->GetFormField(), pBuffer, nCharacters, TRUE);
+ 
+ 		pEdit->SetEditNotify(this);
+ 		//pUndo->BeginEdit(pDocument);
+ 	}
+}
+
+void CFFL_TextField::OnKillFocus(CPWL_Wnd* pWnd)
+{
+
+}
+
+FX_BOOL	CFFL_TextField::CanCopy(CPDFSDK_Document* pDocument)
+{
+	return FALSE;
+}
+
+FX_BOOL CFFL_TextField::CanCut(CPDFSDK_Document* pDocument)
+{
+	return FALSE;
+}
+
+FX_BOOL	CFFL_TextField::CanPaste(CPDFSDK_Document* pDocument)
+{
+	return FALSE;
+}
+
+void CFFL_TextField::DoCopy(CPDFSDK_Document* pDocument)
+{
+
+}
+
+void CFFL_TextField::DoCut(CPDFSDK_Document* pDocument)
+{
+}
+
+void CFFL_TextField::DoPaste(CPDFSDK_Document* pDocument)
+{
+
+}
+
+void CFFL_TextField::OnAddUndo(CPWL_Edit* pEdit)
+{
+}
+
diff --git a/fpdfsdk/src/formfiller/FFL_Utils.cpp b/fpdfsdk/src/formfiller/FFL_Utils.cpp
index 2e90810..3ea7891 100644
--- a/fpdfsdk/src/formfiller/FFL_Utils.cpp
+++ b/fpdfsdk/src/formfiller/FFL_Utils.cpp
@@ -1,133 +1,133 @@
-// 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/FormFiller.h"
-#include "../../include/formfiller/FFL_Utils.h"
-
-CPDF_Rect CFFL_Utils::MaxRect(const CPDF_Rect & rect1,const CPDF_Rect & rect2)
-{
-	CPDF_Rect rcRet;
-
-	rcRet.left = FFL_MIN(rect1.left,rect2.left);
-	rcRet.bottom = FFL_MIN(rect1.bottom,rect2.bottom);
-	rcRet.right = FFL_MAX(rect1.right,rect2.right);
-	rcRet.top = FFL_MAX(rect1.top,rect2.top);
-
-	return rcRet;
-}
-
-CPDF_Rect CFFL_Utils::InflateRect(const CPDF_Rect & crRect,const FX_FLOAT & fSize)
-{
-	CPDF_Rect crNew(crRect.left - fSize,
-					crRect.bottom - fSize,
-					crRect.right + fSize,
-					crRect.top + fSize);
-	crNew.Normalize();
-	return crNew;
-}
-
-CPDF_Rect CFFL_Utils::DeflateRect(const CPDF_Rect & crRect,const FX_FLOAT & fSize)
-{
-	CPDF_Rect crNew(crRect.left + fSize,
-					crRect.bottom + fSize,
-					crRect.right - fSize,
-					crRect.top - fSize);
-	crNew.Normalize();
-	return crNew;
-}
-
-/*
-FX_BOOL CFFL_Utils::RectContainsRect(const CPDF_Rect & father,const CPDF_Rect & son)
-{
-	return (father.left <= son.left && father.right >= son.right && 
-				father.bottom <= son.bottom && father.top >= son.top);
-
-}
-
-FX_BOOL CFFL_Utils::RectContainsPoint(const CPDF_Rect & father,const CPDF_Point & son)
-{
-	return (father.left <= son.x && father.right >= son.x && 
-				father.bottom <= son.y && father.top >= son.y);
-}
-
-FX_BOOL CFFL_Utils::RectContainsXY(const CPDF_Rect & father,FX_FLOAT x,FX_FLOAT y)
-{
-	return (father.left <= x && father.right >= x && 
-				father.bottom <= y && father.top >= y);
-}
-*/
-
-FX_BOOL CFFL_Utils::TraceObject(CPDF_Object* pObj)
-{
-	if (!pObj) return FALSE;
-
-	FX_DWORD	dwObjNum = pObj->GetObjNum();
-	switch (pObj->GetType())
-	{
-	case PDFOBJ_ARRAY:
-		{
-			CPDF_Array* pArray = (CPDF_Array*)pObj;
-			for (FX_DWORD i = 0; i < pArray->GetCount(); i ++)
-			{
-				CPDF_Object* pElement = pArray->GetElementValue(i);				
-				TraceObject(pElement);
-			}
-		}
-		break;
-
-	case PDFOBJ_DICTIONARY:
-		{
-			CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj;
-
-			FX_POSITION fPos = pDict->GetStartPos();
-			CFX_ByteString csKey;
-			do
-			{
-				CPDF_Object* pElement = pDict->GetNextElement(fPos, csKey);
- 				//TRACE(csKey + "\n");
-				if (!pElement) break;
-				TraceObject(pElement);
-			}while (TRUE);
-		}
-		break;
-
-	case PDFOBJ_STREAM:
-		{
-			CPDF_Stream* pStream = (CPDF_Stream*)pObj;
-			CPDF_Dictionary* pDict = pStream->GetDict();
-			TraceObject(pDict);
-		}
-		break;
-
-	case PDFOBJ_REFERENCE:
-		{
-			CPDF_Object* pDirectObj = pObj->GetDirect();
-			TraceObject(pDirectObj);
-		}
-		break;
-
-	case PDFOBJ_BOOLEAN:
-		break;
-	case PDFOBJ_NUMBER:
-		//TRACE("%d\n",(FX_INT32)pObj);
-		break;
-	case PDFOBJ_STRING:
-		//TRACE(((CPDF_String*)pObj)->GetString() + "\n");
-		break;
-	case PDFOBJ_NAME:
-		//TRACE(((CPDF_Name*)pObj)->GetString() + "\n");
-		break;
-	case PDFOBJ_NULL:
-//	case PDFOBJ_KEYWORD:
-//	case PDFOBJ_EOF:
-	default:
-		break;
-	}
-	if (dwObjNum == 0) return FALSE;
-
-	return TRUE;
-}
-
+// 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/FormFiller.h"
+#include "../../include/formfiller/FFL_Utils.h"
+
+CPDF_Rect CFFL_Utils::MaxRect(const CPDF_Rect & rect1,const CPDF_Rect & rect2)
+{
+	CPDF_Rect rcRet;
+
+	rcRet.left = FFL_MIN(rect1.left,rect2.left);
+	rcRet.bottom = FFL_MIN(rect1.bottom,rect2.bottom);
+	rcRet.right = FFL_MAX(rect1.right,rect2.right);
+	rcRet.top = FFL_MAX(rect1.top,rect2.top);
+
+	return rcRet;
+}
+
+CPDF_Rect CFFL_Utils::InflateRect(const CPDF_Rect & crRect,const FX_FLOAT & fSize)
+{
+	CPDF_Rect crNew(crRect.left - fSize,
+					crRect.bottom - fSize,
+					crRect.right + fSize,
+					crRect.top + fSize);
+	crNew.Normalize();
+	return crNew;
+}
+
+CPDF_Rect CFFL_Utils::DeflateRect(const CPDF_Rect & crRect,const FX_FLOAT & fSize)
+{
+	CPDF_Rect crNew(crRect.left + fSize,
+					crRect.bottom + fSize,
+					crRect.right - fSize,
+					crRect.top - fSize);
+	crNew.Normalize();
+	return crNew;
+}
+
+/*
+FX_BOOL CFFL_Utils::RectContainsRect(const CPDF_Rect & father,const CPDF_Rect & son)
+{
+	return (father.left <= son.left && father.right >= son.right && 
+				father.bottom <= son.bottom && father.top >= son.top);
+
+}
+
+FX_BOOL CFFL_Utils::RectContainsPoint(const CPDF_Rect & father,const CPDF_Point & son)
+{
+	return (father.left <= son.x && father.right >= son.x && 
+				father.bottom <= son.y && father.top >= son.y);
+}
+
+FX_BOOL CFFL_Utils::RectContainsXY(const CPDF_Rect & father,FX_FLOAT x,FX_FLOAT y)
+{
+	return (father.left <= x && father.right >= x && 
+				father.bottom <= y && father.top >= y);
+}
+*/
+
+FX_BOOL CFFL_Utils::TraceObject(CPDF_Object* pObj)
+{
+	if (!pObj) return FALSE;
+
+	FX_DWORD	dwObjNum = pObj->GetObjNum();
+	switch (pObj->GetType())
+	{
+	case PDFOBJ_ARRAY:
+		{
+			CPDF_Array* pArray = (CPDF_Array*)pObj;
+			for (FX_DWORD i = 0; i < pArray->GetCount(); i ++)
+			{
+				CPDF_Object* pElement = pArray->GetElementValue(i);				
+				TraceObject(pElement);
+			}
+		}
+		break;
+
+	case PDFOBJ_DICTIONARY:
+		{
+			CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj;
+
+			FX_POSITION fPos = pDict->GetStartPos();
+			CFX_ByteString csKey;
+			do
+			{
+				CPDF_Object* pElement = pDict->GetNextElement(fPos, csKey);
+ 				//TRACE(csKey + "\n");
+				if (!pElement) break;
+				TraceObject(pElement);
+			}while (TRUE);
+		}
+		break;
+
+	case PDFOBJ_STREAM:
+		{
+			CPDF_Stream* pStream = (CPDF_Stream*)pObj;
+			CPDF_Dictionary* pDict = pStream->GetDict();
+			TraceObject(pDict);
+		}
+		break;
+
+	case PDFOBJ_REFERENCE:
+		{
+			CPDF_Object* pDirectObj = pObj->GetDirect();
+			TraceObject(pDirectObj);
+		}
+		break;
+
+	case PDFOBJ_BOOLEAN:
+		break;
+	case PDFOBJ_NUMBER:
+		//TRACE("%d\n",(FX_INT32)pObj);
+		break;
+	case PDFOBJ_STRING:
+		//TRACE(((CPDF_String*)pObj)->GetString() + "\n");
+		break;
+	case PDFOBJ_NAME:
+		//TRACE(((CPDF_Name*)pObj)->GetString() + "\n");
+		break;
+	case PDFOBJ_NULL:
+//	case PDFOBJ_KEYWORD:
+//	case PDFOBJ_EOF:
+	default:
+		break;
+	}
+	if (dwObjNum == 0) return FALSE;
+
+	return TRUE;
+}
+
