// 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/fpdfdoc/fpdf_doc.h"
#include "../../include/fxcrt/fx_xml.h"
CFX_WideString	GetFullName(CPDF_Dictionary* pFieldDict);
void			InitInterFormDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument);
FX_DWORD		CountInterFormFonts(CPDF_Dictionary* pFormDict);
CPDF_Font*		GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_DWORD index, CFX_ByteString& csNameTag);
CPDF_Font*		GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csNameTag);
CPDF_Font*		GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CFX_ByteString& csNameTag);
CPDF_Font*		GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag);
CPDF_Font*		GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag);
FX_BOOL			FindInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont, CFX_ByteString& csNameTag);
FX_BOOL			FindInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CPDF_Font*& pFont, CFX_ByteString& csNameTag);
void			AddInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, const CPDF_Font* pFont, CFX_ByteString& csNameTag);
CPDF_Font*		AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag);
CPDF_Font*		AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag);
void			RemoveInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont);
void			RemoveInterFormFont(CPDF_Dictionary* pFormDict, CFX_ByteString csNameTag);
CPDF_Font*		GetDefaultInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument);
void			SetDefaultInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, const CPDF_Font* pFont);
void			SaveCheckedFieldStatus(CPDF_FormField* pField, CFX_ByteArray& statusArray);
FX_BOOL			NeedPDFEncodeForFieldFullName(const CFX_WideString& csFieldName);
FX_BOOL			NeedPDFEncodeForFieldTree(CPDF_Dictionary* pFieldDict, int nLevel = 0);
void			EncodeFieldName(const CFX_WideString& csName, CFX_ByteString& csT);
void			UpdateEncodeFieldName(CPDF_Dictionary* pFieldDict, int nLevel = 0);
const int nMaxRecursion = 32;
class _CFieldNameExtractor : public CFX_Object
{
public:
    _CFieldNameExtractor(const CFX_WideString& full_name)
    {
        m_pStart = full_name;
        m_pEnd = m_pStart + full_name.GetLength();
        m_pCur = m_pStart;
    }
    void GetNext(FX_LPCWSTR &pSubName, FX_STRSIZE& size)
    {
        pSubName = m_pCur;
        while (m_pCur < m_pEnd && m_pCur[0] != L'.') {
            m_pCur++;
        }
        size = (FX_STRSIZE)(m_pCur - pSubName);
        if (m_pCur < m_pEnd && m_pCur[0] == L'.') {
            m_pCur++;
        }
    }
protected:
    FX_LPCWSTR m_pStart;
    FX_LPCWSTR m_pEnd;
    FX_LPCWSTR m_pCur;
};
class CFieldTree : public CFX_Object
{
public:
    struct _Node : public CFX_Object {
        _Node *parent;
        CFX_PtrArray children;
        CFX_WideString short_name;
        CPDF_FormField *field_ptr;
        int CountFields(int nLevel = 0)
        {
            if (nLevel > nMaxRecursion) {
                return 0;
            }
            if (field_ptr) {
                return 1;
            }
            int count = 0;
            for (int i = 0; i < children.GetSize(); i ++) {
                count += ((_Node *)children.GetAt(i))->CountFields(nLevel + 1);
            }
            return count;
        }
        CPDF_FormField* GetField(int* fields_to_go)
        {
            if (field_ptr) {
                if (*fields_to_go == 0) {
                    return field_ptr;
                }
                --*fields_to_go;
                return NULL;
            }
            for (int i = 0; i < children.GetSize(); i++) {
                _Node *pNode = (_Node *)children.GetAt(i);
                CPDF_FormField* pField = pNode->GetField(fields_to_go);
                if (pField) {
                    return pField;
                }
            }
            return NULL;
        }
        CPDF_FormField* GetField(int index)
        {
            int fields_to_go = index;
            return GetField(&fields_to_go);
        }
    };
    CFieldTree();
    ~CFieldTree();
    void SetField(const CFX_WideString &full_name, CPDF_FormField *field_ptr);
    CPDF_FormField *GetField(const CFX_WideString &full_name);
    CPDF_FormField *RemoveField(const CFX_WideString &full_name);
    void RemoveAll();
    _Node *FindNode(const CFX_WideString &full_name);
    _Node * AddChild(_Node *pParent, const CFX_WideString &short_name, CPDF_FormField *field_ptr);
    void RemoveNode(_Node *pNode, int nLevel = 0);
    _Node *_Lookup(_Node *pParent, const CFX_WideString &short_name);
    _Node m_Root;
};
CFieldTree::CFieldTree()
{
    m_Root.parent = NULL;
    m_Root.field_ptr = NULL;
}
CFieldTree::~CFieldTree()
{
    RemoveAll();
}
CFieldTree::_Node *CFieldTree::AddChild(_Node *pParent, const CFX_WideString &short_name, CPDF_FormField *field_ptr)
{
    if (pParent == NULL) {
        return NULL;
    }
    _Node *pNode = FX_NEW _Node;
    if (pNode == NULL) {
        return NULL;
    }
    pNode->parent = pParent;
    pNode->short_name = short_name;
    pNode->field_ptr = field_ptr;
    pParent->children.Add(pNode);
    return pNode;
}
void CFieldTree::RemoveNode(_Node *pNode, int nLevel)
{
    if (pNode == NULL) {
        return ;
    }
    if (nLevel > nMaxRecursion) {
        delete pNode;
        return ;
    }
    CFX_PtrArray& ptr_array = pNode->children;
    for (int i = 0; i < ptr_array.GetSize(); i ++) {
        _Node *pChild = (_Node *)ptr_array[i];
        RemoveNode(pChild, nLevel + 1);
    }
    delete pNode;
}
CFieldTree::_Node *CFieldTree::_Lookup(_Node *pParent, const CFX_WideString &short_name)
{
    if (pParent == NULL) {
        return NULL;
    }
    CFX_PtrArray& ptr_array = pParent->children;
    for (int i = 0; i < ptr_array.GetSize(); i ++) {
        _Node *pNode = (_Node *)ptr_array[i];
        if (pNode->short_name.GetLength() == short_name.GetLength() &&
                FXSYS_memcmp32((FX_LPCWSTR)pNode->short_name, (FX_LPCWSTR)short_name, short_name.GetLength()*sizeof(FX_WCHAR)) == 0) {
            return pNode;
        }
    }
    return NULL;
}
void CFieldTree::RemoveAll()
{
    CFX_PtrArray& ptr_array = m_Root.children;
    for (int i = 0; i < ptr_array.GetSize(); i ++) {
        _Node *pNode = (_Node *)ptr_array[i];
        RemoveNode(pNode);
    }
}
void CFieldTree::SetField(const CFX_WideString &full_name, CPDF_FormField *field_ptr)
{
    if (full_name == L"") {
        return;
    }
    _CFieldNameExtractor name_extractor(full_name);
    FX_LPCWSTR pName;
    FX_STRSIZE nLength;
    name_extractor.GetNext(pName, nLength);
    _Node *pNode = &m_Root, *pLast = NULL;
    while (nLength > 0) {
        pLast = pNode;
        CFX_WideString name = CFX_WideString(pName, nLength);
        pNode = _Lookup(pLast, name);
        if (pNode == NULL) {
            pNode = AddChild(pLast, name, NULL);
        }
        name_extractor.GetNext(pName, nLength);
    }
    if (pNode != &m_Root) {
        pNode->field_ptr = field_ptr;
    }
}
CPDF_FormField *CFieldTree::GetField(const CFX_WideString &full_name)
{
    if (full_name == L"") {
        return NULL;
    }
    _CFieldNameExtractor name_extractor(full_name);
    FX_LPCWSTR pName;
    FX_STRSIZE nLength;
    name_extractor.GetNext(pName, nLength);
    _Node *pNode = &m_Root, *pLast = NULL;
    while (nLength > 0 && pNode) {
        pLast = pNode;
        CFX_WideString name = CFX_WideString(pName, nLength);
        pNode = _Lookup(pLast, name);
        name_extractor.GetNext(pName, nLength);
    }
    return pNode ? pNode->field_ptr : NULL;
}
CPDF_FormField *CFieldTree::RemoveField(const CFX_WideString & full_name)
{
    if (full_name == L"") {
        return NULL;
    }
    _CFieldNameExtractor name_extractor(full_name);
    FX_LPCWSTR pName;
    FX_STRSIZE nLength;
    name_extractor.GetNext(pName, nLength);
    _Node *pNode = &m_Root, *pLast = NULL;
    while (nLength > 0 && pNode) {
        pLast = pNode;
        CFX_WideString name = CFX_WideString(pName, nLength);
        pNode = _Lookup(pLast, name);
        name_extractor.GetNext(pName, nLength);
    }
    if (pNode && pNode != &m_Root) {
        CFX_PtrArray& ptr_array = pLast->children;
        for (int i = 0; i < ptr_array.GetSize(); i ++) {
            if (pNode == (_Node *)ptr_array[i]) {
                ptr_array.RemoveAt(i);
                break;
            }
        }
        CPDF_FormField *pField = pNode->field_ptr;
        RemoveNode(pNode);
        return pField;
    }
    return NULL;
}
CFieldTree::_Node *CFieldTree::FindNode(const CFX_WideString& full_name)
{
    if (full_name == L"") {
        return NULL;
    }
    _CFieldNameExtractor name_extractor(full_name);
    FX_LPCWSTR pName;
    FX_STRSIZE nLength;
    name_extractor.GetNext(pName, nLength);
    _Node *pNode = &m_Root, *pLast = NULL;
    while (nLength > 0 && pNode) {
        pLast = pNode;
        CFX_WideString name = CFX_WideString(pName, nLength);
        pNode = _Lookup(pLast, name);
        name_extractor.GetNext(pName, nLength);
    }
    return pNode;
}
CPDF_InterForm::CPDF_InterForm(CPDF_Document* pDocument, FX_BOOL bGenerateAP) : CFX_PrivateData()
{
    m_pDocument = pDocument;
    m_bGenerateAP = bGenerateAP;
    m_pFormNotify = NULL;
    m_bUpdated = FALSE;
    m_pFieldTree = FX_NEW CFieldTree;
    CPDF_Dictionary* pRoot = m_pDocument->GetRoot();
    m_pFormDict = pRoot->GetDict("AcroForm");
    if (m_pFormDict == NULL) {
        return;
    }
    CPDF_Array* pFields = m_pFormDict->GetArray("Fields");
    if (pFields == NULL) {
        return;
    }
    int count = pFields->GetCount();
    for (int i = 0; i < count; i ++) {
        LoadField(pFields->GetDict(i));
    }
}
CPDF_InterForm::~CPDF_InterForm()
{
    FX_POSITION pos = m_ControlMap.GetStartPosition();
    while (pos) {
        FX_LPVOID key, value;
        m_ControlMap.GetNextAssoc(pos, key, value);
        delete (CPDF_FormControl*)value;
    }
    if (m_pFieldTree != NULL) {
        int nCount = m_pFieldTree->m_Root.CountFields();
        for (int i = 0; i < nCount; i++) {
            CPDF_FormField *pField = m_pFieldTree->m_Root.GetField(i);
            delete pField;
        }
        delete m_pFieldTree;
    }
}
FX_BOOL	CPDF_InterForm::m_bUpdateAP = TRUE;
FX_BOOL CPDF_InterForm::UpdatingAPEnabled()
{
    return m_bUpdateAP;
}
void CPDF_InterForm::EnableUpdateAP(FX_BOOL bUpdateAP)
{
    m_bUpdateAP = bUpdateAP;
}
CFX_ByteString CPDF_InterForm::GenerateNewResourceName(const CPDF_Dictionary* pResDict, FX_LPCSTR csType, int iMinLen, FX_LPCSTR csPrefix)
{
    CFX_ByteString csStr = csPrefix;
    CFX_ByteString csBType = csType;
    if (csStr.IsEmpty()) {
        if (csBType == "ExtGState") {
            csStr = "GS";
        } else if (csBType == "ColorSpace") {
            csStr = "CS";
        } else if (csBType == "Font") {
            csStr = "ZiTi";
        } else {
            csStr = "Res";
        }
    }
    CFX_ByteString csTmp = csStr;
    int iCount = csStr.GetLength();
    int m = 0;
    if (iMinLen > 0) {
        csTmp = "";
        while (m < iMinLen && m < iCount) {
            csTmp += csStr[m ++];
        }
        while (m < iMinLen) {
            csTmp += '0' + m % 10;
            m ++;
        }
    } else {
        m = iCount;
    }
    if (pResDict == NULL) {
        return csTmp;
    }
    CPDF_Dictionary* pDict = pResDict->GetDict(csType);
    if (pDict == NULL) {
        return csTmp;
    }
    int num = 0;
    CFX_ByteString bsNum;
    while (TRUE) {
        if (!pDict->KeyExist(csTmp + bsNum)) {
            return csTmp + bsNum;
        }
        if (m < iCount) {
            csTmp += csStr[m ++];
        } else {
            bsNum.Format("%d", num++);
        }
        m ++;
    }
    return csTmp;
}
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
typedef struct _PDF_FONTDATA {
    FX_BOOL		bFind;
    LOGFONTA	lf;
} PDF_FONTDATA, FAR* LPDF_FONTDATA;
static int CALLBACK EnumFontFamExProc(	ENUMLOGFONTEXA *lpelfe,
                                        NEWTEXTMETRICEX *lpntme,
                                        DWORD FontType,
                                        LPARAM lParam
                                     )
{
    if (FontType != 0x004 || strchr(lpelfe->elfLogFont.lfFaceName, '@') != NULL) {
        return 1;
    } else {
        LPDF_FONTDATA pData = (LPDF_FONTDATA)lParam;
        memcpy(&pData->lf, &lpelfe->elfLogFont, sizeof(LOGFONTA));
        pData->bFind = TRUE;
        return 0;
    }
}
static FX_BOOL RetrieveSpecificFont(LOGFONTA& lf)
{
    PDF_FONTDATA fd;
    memset(&fd, 0, sizeof(PDF_FONTDATA));
    HDC hDC = ::GetDC(NULL);
    EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)EnumFontFamExProc, (LPARAM)&fd, 0);
    ::ReleaseDC(NULL, hDC);
    if (fd.bFind) {
        memcpy(&lf, &fd.lf, sizeof(LOGFONTA));
    }
    return fd.bFind;
}
static FX_BOOL RetrieveSpecificFont(FX_BYTE charSet, FX_BYTE pitchAndFamily, LPCSTR pcsFontName, LOGFONTA& lf)
{
    memset(&lf, 0, sizeof(LOGFONTA));
    lf.lfCharSet = charSet;
    lf.lfPitchAndFamily = pitchAndFamily;
    if (pcsFontName != NULL) {
        strcpy(lf.lfFaceName, pcsFontName);
    }
    return RetrieveSpecificFont(lf);
}
static FX_BOOL RetrieveStockFont(int iFontObject, FX_BYTE charSet, LOGFONTA& lf)
{
    HFONT hFont = (HFONT)::GetStockObject(iFontObject);
    if (hFont != NULL) {
        memset(&lf, 0, sizeof(LOGFONTA));
        int iRet = ::GetObject(hFont, sizeof(LOGFONTA), &lf);
        if (iRet > 0 && (lf.lfCharSet == charSet || charSet == 255)) {
            return RetrieveSpecificFont(lf);
        }
    }
    return FALSE;
}
#endif
CPDF_Font* CPDF_InterForm::AddSystemDefaultFont(const CPDF_Document* pDocument)
{
    if (pDocument == NULL) {
        return NULL;
    }
    CPDF_Font* pFont = NULL;
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    LOGFONTA lf;
    FX_BOOL bRet;
    bRet = RetrieveStockFont(DEFAULT_GUI_FONT, 255, lf);
    if (!bRet) {
        bRet = RetrieveStockFont(SYSTEM_FONT, 255, lf);
    }
    if (bRet) {
        pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
    }
#endif
    return pFont;
}
CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument, CFX_ByteString csFontName, FX_BYTE iCharSet)
{
    if (pDocument == NULL || csFontName.IsEmpty()) {
        return NULL;
    }
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    if (iCharSet == 1) {
        iCharSet = GetNativeCharSet();
    }
    HFONT hFont = ::CreateFontA(0, 0, 0, 0, 0, 0, 0, 0, iCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, (FX_LPCSTR)csFontName);
    if (hFont != NULL) {
        LOGFONTA lf;
        memset(&lf, 0, sizeof(LOGFONTA));
        ::GetObjectA(hFont, sizeof(LOGFONTA), &lf);
        ::DeleteObject(hFont);
        if (strlen(lf.lfFaceName) > 0) {
            return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
        }
    }
#endif
    return NULL;
}
CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument, CFX_WideString csFontName, FX_BYTE iCharSet)
{
    if (pDocument == NULL || csFontName.IsEmpty()) {
        return NULL;
    }
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    if (iCharSet == 1) {
        iCharSet = GetNativeCharSet();
    }
    HFONT hFont = ::CreateFontW(0, 0, 0, 0, 0, 0, 0, 0, iCharSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, csFontName);
    if (hFont != NULL) {
        LOGFONTA lf;
        memset(&lf, 0, sizeof(LOGFONTA));
        ::GetObject(hFont, sizeof(LOGFONTA), &lf);
        ::DeleteObject(hFont);
        if (strlen(lf.lfFaceName) > 0) {
            return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
        }
    }
#endif
    return NULL;
}
CPDF_Font* CPDF_InterForm::AddStandardFont(const CPDF_Document* pDocument, CFX_ByteString csFontName)
{
    if (pDocument == NULL || csFontName.IsEmpty()) {
        return NULL;
    }
    CPDF_Font* pFont = NULL;
    if (csFontName == "ZapfDingbats") {
        pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, NULL);
    } else {
        CPDF_FontEncoding encoding(PDFFONT_ENCODING_WINANSI);
        pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, &encoding);
    }
    return pFont;
}
CFX_ByteString CPDF_InterForm::GetNativeFont(FX_BYTE charSet, FX_LPVOID pLogFont)
{
    CFX_ByteString csFontName;
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    LOGFONTA lf;
    FX_BOOL bRet;
    if (charSet == ANSI_CHARSET) {
        csFontName = "Helvetica";
        return csFontName;
    }
    bRet = FALSE;
    if (charSet == SHIFTJIS_CHARSET) {
        bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "MS Mincho", lf);
    } else if (charSet == GB2312_CHARSET) {
        bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "SimSun", lf);
    } else if (charSet == CHINESEBIG5_CHARSET) {
        bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "MingLiU", lf);
    }
    if (!bRet) {
        bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "Arial Unicode MS", lf);
    }
    if (!bRet) {
        bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "Microsoft Sans Serif", lf);
    }
    if (!bRet) {
        bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, NULL, lf);
    }
    if (bRet) {
        if (pLogFont != NULL) {
            memcpy(pLogFont, &lf, sizeof(LOGFONTA));
        }
        csFontName = lf.lfFaceName;
        return csFontName;
    }
#endif
    return csFontName;
}
CFX_ByteString CPDF_InterForm::GetNativeFont(FX_LPVOID pLogFont)
{
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    FX_BYTE charSet = GetNativeCharSet();
    return GetNativeFont(charSet, pLogFont);
#else
    return CFX_ByteString();
#endif
}
FX_BYTE CPDF_InterForm::GetNativeCharSet()
{
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    FX_BYTE charSet = ANSI_CHARSET;
    UINT iCodePage = ::GetACP();
    switch (iCodePage) {
        case 932:
            charSet = SHIFTJIS_CHARSET;
            break;
        case 936:
            charSet = GB2312_CHARSET;
            break;
        case 950:
            charSet = CHINESEBIG5_CHARSET;
            break;
        case 1252:
            charSet = ANSI_CHARSET;
            break;
        case 874:
            charSet = THAI_CHARSET;
            break;
        case 949:
            charSet = HANGUL_CHARSET;
            break;
        case 1200:
            charSet = ANSI_CHARSET;
            break;
        case 1250:
            charSet = EASTEUROPE_CHARSET;
            break;
        case 1251:
            charSet = RUSSIAN_CHARSET;
            break;
        case 1253:
            charSet = GREEK_CHARSET;
            break;
        case 1254:
            charSet = TURKISH_CHARSET;
            break;
        case 1255:
            charSet = HEBREW_CHARSET;
            break;
        case 1256:
            charSet = ARABIC_CHARSET;
            break;
        case 1257:
            charSet = BALTIC_CHARSET;
            break;
        case 1258:
            charSet = VIETNAMESE_CHARSET;
            break;
        case 1361:
            charSet = JOHAB_CHARSET;
            break;
    }
    return charSet;
#else
    return 0;
#endif
}
CPDF_Font* CPDF_InterForm::AddNativeFont(FX_BYTE charSet, const CPDF_Document* pDocument)
{
    if (pDocument == NULL) {
        return NULL;
    }
    CPDF_Font* pFont = NULL;
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
    LOGFONTA lf;
    CFX_ByteString csFontName = GetNativeFont(charSet, &lf);
    if (!csFontName.IsEmpty()) {
        if (csFontName == "Helvetica") {
            pFont = AddStandardFont(pDocument, csFontName);
        } else {
            pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE);
        }
    }
#endif
    return pFont;
}
CPDF_Font* CPDF_InterForm::AddNativeFont(const CPDF_Document* pDocument)
{
    if (pDocument == NULL) {
        return NULL;
    }
    CPDF_Font* pFont = NULL;
    FX_BYTE charSet = GetNativeCharSet();
    pFont = AddNativeFont(charSet, pDocument);
    return pFont;
}
FX_BOOL CPDF_InterForm::ValidateFieldName(CFX_WideString& csNewFieldName, int iType, const CPDF_FormField* pExcludedField, const CPDF_FormControl* pExcludedControl)
{
    if (csNewFieldName.IsEmpty()) {
        return FALSE;
    }
    int iPos = 0;
    int iLength = csNewFieldName.GetLength();
    CFX_WideString csSub;
    while (TRUE) {
        while (iPos < iLength && (csNewFieldName[iPos] == L'.' || csNewFieldName[iPos] == L' ')) {
            iPos ++;
        }
        if (iPos < iLength && !csSub.IsEmpty()) {
            csSub += L'.';
        }
        while (iPos < iLength && csNewFieldName[iPos] != L'.') {
            csSub += csNewFieldName[iPos ++];
        }
        for (int i = csSub.GetLength() - 1; i > -1; i --) {
            if (csSub[i] == L' ' || csSub[i] == L'.') {
                csSub.SetAt(i, L'\0');
            } else {
                break;
            }
        }
        FX_DWORD dwCount = m_pFieldTree->m_Root.CountFields();
        for (FX_DWORD m = 0; m < dwCount; m ++) {
            CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(m);
            if (pField == NULL) {
                continue;
            }
            if (pField == pExcludedField) {
                if (pExcludedControl != NULL) {
                    if (pField->CountControls() < 2) {
                        continue;
                    }
                } else {
                    continue;
                }
            }
            CFX_WideString csFullName = pField->GetFullName();
            int iRet = CompareFieldName(csSub, csFullName);
            if (iRet == 1) {
                if (pField->GetFieldType() != iType) {
                    return FALSE;
                }
            } else if (iRet == 2 && csSub == csNewFieldName) {
                if (csFullName[iPos] == L'.') {
                    return FALSE;
                }
            } else if (iRet == 3 && csSub == csNewFieldName) {
                if (csNewFieldName[csFullName.GetLength()] == L'.') {
                    return FALSE;
                }
            }
        }
        if (iPos >= iLength) {
            break;
        }
    }
    if (csSub.IsEmpty()) {
        return FALSE;
    }
    csNewFieldName = csSub;
    return TRUE;
}
FX_BOOL CPDF_InterForm::ValidateFieldName(CFX_WideString& csNewFieldName, int iType)
{
    return ValidateFieldName(csNewFieldName, iType, NULL, NULL);
}
FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormField* pField, CFX_WideString& csNewFieldName)
{
    if (pField == NULL || csNewFieldName.IsEmpty()) {
        return FALSE;
    }
    return ValidateFieldName(csNewFieldName, ((CPDF_FormField*)pField)->GetFieldType(), pField, NULL);
}
FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormControl* pControl, CFX_WideString& csNewFieldName)
{
    if (pControl == NULL || csNewFieldName.IsEmpty()) {
        return FALSE;
    }
    CPDF_FormField* pField = ((CPDF_FormControl*)pControl)->GetField();
    return ValidateFieldName(csNewFieldName, pField->GetFieldType(), pField, pControl);
}
int CPDF_InterForm::CompareFieldName(const CFX_ByteString& name1, const CFX_ByteString& name2)
{
    FX_LPCSTR ptr1 = name1, ptr2 = name2;
    if (name1.GetLength() != name2.GetLength()) {
        int i = 0;
        while (ptr1[i] == ptr2[i]) {
            i ++;
        }
        if (i == name1.GetLength()) {
            return 2;
        }
        if (i == name2.GetLength()) {
            return 3;
        }
        return 0;
    } else {
        return name1 == name2 ? 1 : 0;
    }
}
int CPDF_InterForm::CompareFieldName(const CFX_WideString& name1, const CFX_WideString& name2)
{
    FX_LPCWSTR ptr1 = name1, ptr2 = name2;
    if (name1.GetLength() != name2.GetLength()) {
        int i = 0;
        while (ptr1[i] == ptr2[i]) {
            i ++;
        }
        if (i == name1.GetLength()) {
            return 2;
        }
        if (i == name2.GetLength()) {
            return 3;
        }
        return 0;
    } else {
        return name1 == name2 ? 1 : 0;
    }
}
FX_DWORD CPDF_InterForm::CountFields(const CFX_WideString &csFieldName)
{
    if (csFieldName.IsEmpty()) {
        return (FX_DWORD)m_pFieldTree->m_Root.CountFields();
    }
    CFieldTree::_Node *pNode = m_pFieldTree->FindNode(csFieldName);
    if (pNode == NULL) {
        return 0;
    }
    return pNode->CountFields();
}
CPDF_FormField* CPDF_InterForm::GetField(FX_DWORD index, const CFX_WideString &csFieldName)
{
    if (csFieldName == L"") {
        return m_pFieldTree->m_Root.GetField(index);
    }
    CFieldTree::_Node *pNode = m_pFieldTree->FindNode(csFieldName);
    if (pNode == NULL) {
        return NULL;
    }
    return pNode->GetField(index);
}
void CPDF_InterForm::GetAllFieldNames(CFX_WideStringArray& allFieldNames)
{
    allFieldNames.RemoveAll();
    int nCount = m_pFieldTree->m_Root.CountFields();
    for (int i = 0; i < nCount; i ++) {
        CPDF_FormField *pField = m_pFieldTree->m_Root.GetField(i);
        if (pField) {
            CFX_WideString full_name = GetFullName(pField->GetFieldDict());
            allFieldNames.Add(full_name);
        }
    }
}
FX_BOOL CPDF_InterForm::IsValidFormField(const void* pField)
{
    if (pField == NULL) {
        return FALSE;
    }
    int nCount = m_pFieldTree->m_Root.CountFields();
    for (int i = 0; i < nCount; i++) {
        CPDF_FormField *pFormField = m_pFieldTree->m_Root.GetField(i);
        if (pField == pFormField) {
            return TRUE;
        }
    }
    return FALSE;
}
CPDF_FormField* CPDF_InterForm::GetFieldByDict(CPDF_Dictionary* pFieldDict) const
{
    if (pFieldDict == NULL) {
        return NULL;
    }
    CFX_WideString csWName = GetFullName(pFieldDict);
    return m_pFieldTree->GetField(csWName);
}
FX_DWORD CPDF_InterForm::CountControls(CFX_WideString csFieldName)
{
    if (csFieldName.IsEmpty()) {
        return (FX_DWORD)m_ControlMap.GetCount();
    }
    CPDF_FormField *pField = m_pFieldTree->GetField(csFieldName);
    if (pField == NULL) {
        return 0;
    }
    return pField->m_ControlList.GetSize();
}
CPDF_FormControl* CPDF_InterForm::GetControl(FX_DWORD index, CFX_WideString csFieldName)
{
    CPDF_FormField *pField = m_pFieldTree->GetField(csFieldName);
    if (pField == NULL) {
        return NULL;
    }
    if (index < (FX_DWORD)pField->m_ControlList.GetSize()) {
        return (CPDF_FormControl *)pField->m_ControlList.GetAt(index);
    }
    return NULL;
}
FX_BOOL CPDF_InterForm::IsValidFormControl(const void* pControl)
{
    if (pControl == NULL) {
        return FALSE;
    }
    FX_POSITION pos = m_ControlMap.GetStartPosition();
    while (pos) {
        CPDF_Dictionary* pWidgetDict = NULL;
        void* pFormControl = NULL;
        m_ControlMap.GetNextAssoc(pos, (FX_LPVOID&)pWidgetDict, pFormControl);
        if (pControl == pFormControl) {
            return TRUE;
        }
    }
    return FALSE;
}
int CPDF_InterForm::CountPageControls(CPDF_Page* pPage) const
{
    CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
    if (pAnnotList == NULL) {
        return 0;
    }
    int count = 0;
    for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i ++) {
        CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i);
        if (pAnnot == NULL) {
            continue;
        }
        CPDF_FormControl* pControl;
        if (!m_ControlMap.Lookup(pAnnot, (FX_LPVOID&)pControl)) {
            continue;
        }
        count ++;
    }
    return count;
}
CPDF_FormControl* CPDF_InterForm::GetPageControl(CPDF_Page* pPage, int index) const
{
    CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
    if (pAnnotList == NULL) {
        return NULL;
    }
    int count = 0;
    for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i ++) {
        CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i);
        if (pAnnot == NULL) {
            continue;
        }
        CPDF_FormControl* pControl;
        if (!m_ControlMap.Lookup(pAnnot, (FX_LPVOID&)pControl)) {
            continue;
        }
        if (index == count) {
            return pControl;
        }
        count ++;
    }
    return NULL;
}
CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage, FX_FLOAT pdf_x, FX_FLOAT pdf_y) const
{
    CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots");
    if (pAnnotList == NULL) {
        return NULL;
    }
    for (FX_DWORD i = pAnnotList->GetCount(); i > 0; i --) {
        CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i - 1);
        if (pAnnot == NULL) {
            continue;
        }
        CPDF_FormControl* pControl;
        if (!m_ControlMap.Lookup(pAnnot, (FX_LPVOID&)pControl)) {
            continue;
        }
        CFX_FloatRect rect = pControl->GetRect();
        if (rect.Contains(pdf_x, pdf_y)) {
            return pControl;
        }
    }
    return NULL;
}
CPDF_FormControl* CPDF_InterForm::GetControlByDict(CPDF_Dictionary* pWidgetDict) const
{
    CPDF_FormControl* pControl = NULL;
    m_ControlMap.Lookup(pWidgetDict, (FX_LPVOID&)pControl);
    return pControl;
}
FX_DWORD CPDF_InterForm::CountInternalFields(const CFX_WideString& csFieldName) const
{
    if (m_pFormDict == NULL) {
        return 0;
    }
    CPDF_Array* pArray = m_pFormDict->GetArray("Fields");
    if (pArray == NULL) {
        return 0;
    }
    if (csFieldName.IsEmpty()) {
        return pArray->GetCount();
    } else {
        int iLength = csFieldName.GetLength();
        int iPos = 0;
        CPDF_Dictionary* pDict = NULL;
        while (pArray != NULL) {
            CFX_WideString csSub;
            if (iPos < iLength && csFieldName[iPos] == L'.') {
                iPos ++;
            }
            while (iPos < iLength && csFieldName[iPos] != L'.') {
                csSub += csFieldName[iPos ++];
            }
            int iCount = pArray->GetCount();
            FX_BOOL bFind = FALSE;
            for (int i = 0; i < iCount; i ++) {
                pDict = pArray->GetDict(i);
                if (pDict == NULL) {
                    continue;
                }
                CFX_WideString csT = pDict->GetUnicodeText("T");
                if (csT == csSub) {
                    bFind = TRUE;
                    break;
                }
            }
            if (!bFind) {
                return 0;
            }
            if (iPos >= iLength) {
                break;
            }
            pArray = pDict->GetArray("Kids");
        }
        if (pDict == NULL) {
            return 0;
        } else {
            pArray = pDict->GetArray("Kids");
            if (pArray == NULL) {
                return 1;
            } else {
                return pArray->GetCount();
            }
        }
    }
}
CPDF_Dictionary* CPDF_InterForm::GetInternalField(FX_DWORD index, const CFX_WideString& csFieldName) const
{
    if (m_pFormDict == NULL) {
        return NULL;
    }
    CPDF_Array* pArray = m_pFormDict->GetArray("Fields");
    if (pArray == NULL) {
        return 0;
    }
    if (csFieldName.IsEmpty()) {
        return pArray->GetDict(index);
    } else {
        int iLength = csFieldName.GetLength();
        int iPos = 0;
        CPDF_Dictionary* pDict = NULL;
        while (pArray != NULL) {
            CFX_WideString csSub;
            if (iPos < iLength && csFieldName[iPos] == L'.') {
                iPos ++;
            }
            while (iPos < iLength && csFieldName[iPos] != L'.') {
                csSub += csFieldName[iPos ++];
            }
            int iCount = pArray->GetCount();
            FX_BOOL bFind = FALSE;
            for (int i = 0; i < iCount; i ++) {
                pDict = pArray->GetDict(i);
                if (pDict == NULL) {
                    continue;
                }
                CFX_WideString csT = pDict->GetUnicodeText("T");
                if (csT == csSub) {
                    bFind = TRUE;
                    break;
                }
            }
            if (!bFind) {
                return NULL;
            }
            if (iPos >= iLength) {
                break;
            }
            pArray = pDict->GetArray("Kids");
        }
        if (pDict == NULL) {
            return NULL;
        } else {
            pArray = pDict->GetArray("Kids");
            if (pArray == NULL) {
                return pDict;
            } else {
                return pArray->GetDict(index);
            }
        }
    }
}
FX_BOOL CPDF_InterForm::NeedConstructAP()
{
    if (m_pFormDict == NULL) {
        return FALSE;
    }
    return m_pFormDict->GetBoolean("NeedAppearances");
}
void CPDF_InterForm::NeedConstructAP(FX_BOOL bNeedAP)
{
    if (m_pFormDict == NULL) {
        InitInterFormDict(m_pFormDict, m_pDocument);
    }
    m_pFormDict->SetAtBoolean("NeedAppearances", bNeedAP);
    m_bGenerateAP = bNeedAP;
}
int CPDF_InterForm::CountFieldsInCalculationOrder()
{
    if (m_pFormDict == NULL) {
        return 0;
    }
    CPDF_Array* pArray = m_pFormDict->GetArray("CO");
    if (pArray == NULL) {
        return 0;
    }
    return pArray->GetCount();
}
CPDF_FormField* CPDF_InterForm::GetFieldInCalculationOrder(int index)
{
    if (m_pFormDict == NULL || index < 0) {
        return NULL;
    }
    CPDF_Array* pArray = m_pFormDict->GetArray("CO");
    if (pArray == NULL) {
        return NULL;
    }
    CPDF_Object* pElement = pArray->GetElementValue(index);
    if (pElement != NULL && pElement->GetType() == PDFOBJ_DICTIONARY) {
        return GetFieldByDict((CPDF_Dictionary*)pElement);
    }
    return NULL;
}
int CPDF_InterForm::FindFieldInCalculationOrder(const CPDF_FormField* pField)
{
    if (m_pFormDict == NULL || pField == NULL) {
        return -1;
    }
    CPDF_Array* pArray = m_pFormDict->GetArray("CO");
    if (pArray == NULL) {
        return -1;
    }
    for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) {
        CPDF_Object* pElement = pArray->GetElementValue(i);
        if (pElement == pField->m_pDict) {
            return i;
        }
    }
    return -1;
}
FX_DWORD CPDF_InterForm::CountFormFonts()
{
    return CountInterFormFonts(m_pFormDict);
}
CPDF_Font* CPDF_InterForm::GetFormFont(FX_DWORD index, CFX_ByteString& csNameTag)
{
    return GetInterFormFont(m_pFormDict, m_pDocument, index, csNameTag);
}
CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csNameTag)
{
    return GetInterFormFont(m_pFormDict, m_pDocument, csNameTag);
}
CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csFontName, CFX_ByteString& csNameTag)
{
    return GetInterFormFont(m_pFormDict, m_pDocument, csFontName, csNameTag);
}
CPDF_Font* CPDF_InterForm::GetNativeFormFont(FX_BYTE charSet, CFX_ByteString& csNameTag)
{
    return GetNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag);
}
CPDF_Font* CPDF_InterForm::GetNativeFormFont(CFX_ByteString& csNameTag)
{
    return GetNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag);
}
FX_BOOL CPDF_InterForm::FindFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag)
{
    return FindInterFormFont(m_pFormDict, pFont, csNameTag);
}
FX_BOOL CPDF_InterForm::FindFormFont(CFX_ByteString csFontName, CPDF_Font*& pFont, CFX_ByteString& csNameTag)
{
    return FindInterFormFont(m_pFormDict, m_pDocument, csFontName, pFont, csNameTag);
}
void CPDF_InterForm::AddFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag)
{
    AddInterFormFont(m_pFormDict, m_pDocument, pFont, csNameTag);
    m_bUpdated = TRUE;
}
CPDF_Font* CPDF_InterForm::AddNativeFormFont(FX_BYTE charSet, CFX_ByteString& csNameTag)
{
    m_bUpdated = TRUE;
    return AddNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag);
}
CPDF_Font* CPDF_InterForm::AddNativeFormFont(CFX_ByteString& csNameTag)
{
    m_bUpdated = TRUE;
    return AddNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag);
}
void CPDF_InterForm::RemoveFormFont(const CPDF_Font* pFont)
{
    m_bUpdated = TRUE;
    RemoveInterFormFont(m_pFormDict, pFont);
}
void CPDF_InterForm::RemoveFormFont(CFX_ByteString csNameTag)
{
    m_bUpdated = TRUE;
    RemoveInterFormFont(m_pFormDict, csNameTag);
}
CPDF_DefaultAppearance CPDF_InterForm::GetDefaultAppearance()
{
    CFX_ByteString csDA;
    if (m_pFormDict == NULL) {
        return csDA;
    }
    csDA = m_pFormDict->GetString("DA");
    return csDA;
}
CPDF_Font* CPDF_InterForm::GetDefaultFormFont()
{
    return GetDefaultInterFormFont(m_pFormDict, m_pDocument);
}
int CPDF_InterForm::GetFormAlignment()
{
    if (m_pFormDict == NULL) {
        return 0;
    }
    return m_pFormDict->GetInteger("Q", 0);
}
FX_BOOL CPDF_InterForm::ResetForm(const CFX_PtrArray& fields, FX_BOOL bIncludeOrExclude, FX_BOOL bNotify)
{
    if (bNotify && m_pFormNotify != NULL) {
        int iRet = m_pFormNotify->BeforeFormReset(this);
        if (iRet < 0) {
            return FALSE;
        }
    }
    int nCount = m_pFieldTree->m_Root.CountFields();
    for (int i = 0; i < nCount; i++) {
        CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
        if (pField == NULL) {
            continue;
        }
        FX_BOOL bFind = FALSE;
        int iCount = fields.GetSize();
        for (int i = 0; i < iCount; i ++) {
            if (pField == (CPDF_FormField*)fields[i]) {
                bFind = TRUE;
                break;
            }
        }
        if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
            pField->ResetField(bNotify);
        }
    }
    if (bNotify && m_pFormNotify != NULL) {
        m_pFormNotify->AfterFormReset(this);
    }
    return TRUE;
}
FX_BOOL CPDF_InterForm::ResetForm(FX_BOOL bNotify)
{
    if (bNotify && m_pFormNotify != NULL) {
        int iRet = m_pFormNotify->BeforeFormReset(this);
        if (iRet < 0) {
            return FALSE;
        }
    }
    int nCount = m_pFieldTree->m_Root.CountFields();
    for (int i = 0; i < nCount; i++) {
        CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
        if (pField == NULL) {
            continue;
        }
        pField->ResetField(bNotify);
    }
    if (bNotify && m_pFormNotify != NULL) {
        m_pFormNotify->AfterFormReset(this);
    }
    return TRUE;
}
void CPDF_InterForm::ReloadForm()
{
    FX_POSITION pos = m_ControlMap.GetStartPosition();
    while (pos) {
        CPDF_Dictionary* pWidgetDict;
        CPDF_FormControl* pControl;
        m_ControlMap.GetNextAssoc(pos, (FX_LPVOID&)pWidgetDict, (FX_LPVOID&)pControl);
        delete pControl;
    }
    m_ControlMap.RemoveAll();
    int nCount = m_pFieldTree->m_Root.CountFields();
    for (int k = 0; k < nCount; k ++) {
        CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(k);
        delete pField;
    }
    m_pFieldTree->RemoveAll();
    if (m_pFormDict == NULL) {
        return;
    }
    CPDF_Array* pFields = m_pFormDict->GetArray("Fields");
    if (pFields == NULL) {
        return;
    }
    int iCount = pFields->GetCount();
    for (int i = 0; i < iCount; i ++) {
        LoadField(pFields->GetDict(i));
    }
}
void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel)
{
    if (nLevel > nMaxRecursion) {
        return;
    }
    if (pFieldDict == NULL) {
        return;
    }
    FX_DWORD dwParentObjNum = pFieldDict->GetObjNum();
    CPDF_Array* pKids = pFieldDict->GetArray("Kids");
    if (!pKids) {
        AddTerminalField(pFieldDict);
        return;
    }
    CPDF_Dictionary* pFirstKid = pKids->GetDict(0);
    if (pFirstKid == NULL) {
        return;
    }
    if (pFirstKid->KeyExist("T") || pFirstKid->KeyExist("Kids")) {
        for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) {
            CPDF_Dictionary * pChildDict = pKids->GetDict(i);
            if (pChildDict) {
                if (pChildDict->GetObjNum() != dwParentObjNum) {
                    LoadField(pChildDict, nLevel + 1);
                }
            }
        }
    } else {
        AddTerminalField(pFieldDict);
    }
}
FX_BOOL CPDF_InterForm::HasXFAForm() const
{
    return m_pFormDict && m_pFormDict->GetArray(FX_BSTRC("XFA")) != NULL;
}
void CPDF_InterForm::FixPageFields(const CPDF_Page* pPage)
{
    ASSERT(pPage != NULL);
    CPDF_Dictionary* pPageDict = pPage->m_pFormDict;
    if (pPageDict == NULL) {
        return;
    }
    CPDF_Array* pAnnots = pPageDict->GetArray(FX_BSTRC("Annots"));
    if (pAnnots == NULL) {
        return;
    }
    int iAnnotCount = pAnnots->GetCount();
    for (int i = 0; i < iAnnotCount; i++) {
        CPDF_Dictionary* pAnnot = pAnnots->GetDict(i);
        if (pAnnot != NULL && pAnnot->GetString(FX_BSTRC("Subtype")) == "Widget") {
            LoadField(pAnnot);
        }
    }
}
CPDF_FormField* CPDF_InterForm::AddTerminalField(const CPDF_Dictionary* pFieldDict)
{
    if (!pFieldDict->KeyExist(FX_BSTRC("T"))) {
        return NULL;
    }
    CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFieldDict;
    CFX_WideString csWName = GetFullName(pDict);
    if (csWName.IsEmpty()) {
        return NULL;
    }
    CPDF_FormField* pField = NULL;
    pField = m_pFieldTree->GetField(csWName);
    if (pField == NULL) {
        CPDF_Dictionary *pParent = (CPDF_Dictionary*)pFieldDict;
        if (!pFieldDict->KeyExist(FX_BSTR("T")) &&
                pFieldDict->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget")) {
            pParent = pFieldDict->GetDict(FX_BSTRC("Parent"));
            if (!pParent) {
                pParent = (CPDF_Dictionary*)pFieldDict;
            }
        }
        if (pParent && pParent != pFieldDict && !pParent->KeyExist(FX_BSTRC("FT"))) {
            if (pFieldDict->KeyExist(FX_BSTRC("FT"))) {
                CPDF_Object *pFTValue = pFieldDict->GetElementValue(FX_BSTRC("FT"));
                if (pFTValue) {
                    pParent->SetAt(FX_BSTRC("FT"), pFTValue->Clone());
                }
            }
            if (pFieldDict->KeyExist(FX_BSTRC("Ff"))) {
                CPDF_Object *pFfValue = pFieldDict->GetElementValue(FX_BSTRC("Ff"));
                if (pFfValue) {
                    pParent->SetAt(FX_BSTRC("Ff"), pFfValue->Clone());
                }
            }
        }
        pField = FX_NEW CPDF_FormField(this, pParent);
        CPDF_Object* pTObj = pDict->GetElement("T");
        if (pTObj && pTObj->GetType() == PDFOBJ_REFERENCE) {
            CPDF_Object* pClone = pTObj->Clone(TRUE);
            if (pClone) {
                pDict->SetAt("T", pClone);
            } else {
                pDict->SetAtName("T", "");
            }
        }
        m_pFieldTree->SetField(csWName, pField);
    }
    CPDF_Array* pKids = pFieldDict->GetArray("Kids");
    if (pKids == NULL) {
        if (pFieldDict->GetString("Subtype") == "Widget") {
            AddControl(pField, pFieldDict);
        }
    } else {
        for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) {
            CPDF_Dictionary* pKid = pKids->GetDict(i);
            if (pKid == NULL) {
                continue;
            }
            if (pKid->GetString("Subtype") != "Widget") {
                continue;
            }
            AddControl(pField, pKid);
        }
    }
    return pField;
}
CPDF_FormControl* CPDF_InterForm::AddControl(const CPDF_FormField* pField, const CPDF_Dictionary* pWidgetDict)
{
    void *rValue = NULL;
    if (m_ControlMap.Lookup((CPDF_Dictionary*)pWidgetDict, rValue)) {
        return (CPDF_FormControl*)rValue;
    }
    CPDF_FormControl* pControl = FX_NEW CPDF_FormControl((CPDF_FormField*)pField, (CPDF_Dictionary*)pWidgetDict);
    if (pControl == NULL) {
        return NULL;
    }
    m_ControlMap.SetAt((CPDF_Dictionary*)pWidgetDict, pControl);
    ((CPDF_FormField*)pField)->m_ControlList.Add(pControl);
    return pControl;
}
CPDF_FormField* CPDF_InterForm::CheckRequiredFields(const CFX_PtrArray *fields, FX_BOOL bIncludeOrExclude) const
{
    int nCount = m_pFieldTree->m_Root.CountFields();
    for (int i = 0; i < nCount; i++) {
        CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
        if (pField == NULL) {
            continue;
        }
        FX_INT32 iType = pField->GetType();
        if (iType == CPDF_FormField::PushButton || iType == CPDF_FormField::CheckBox || iType == CPDF_FormField::ListBox) {
            continue;
        }
        FX_DWORD dwFlags = pField->GetFieldFlags();
        if (dwFlags & 0x04) {
            continue;
        }
        FX_BOOL bFind = TRUE;
        if (fields != NULL) {
            bFind = fields->Find(pField, 0) >= 0;
        }
        if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
            CPDF_Dictionary *pFieldDict = pField->m_pDict;
            if ((dwFlags & 0x02) != 0 && pFieldDict->GetString("V").IsEmpty()) {
                return pField;
            }
        }
    }
    return NULL;
}
CFDF_Document* CPDF_InterForm::ExportToFDF(FX_WSTR pdf_path, FX_BOOL bSimpleFileSpec) const
{
    CFX_PtrArray fields;
    int nCount = m_pFieldTree->m_Root.CountFields();
    for (int i = 0; i < nCount; i ++) {
        CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
        fields.Add(pField);
    }
    return ExportToFDF(pdf_path, fields, TRUE, bSimpleFileSpec);
}
CFX_WideString FILESPEC_EncodeFileName(FX_WSTR filepath);
CFDF_Document* CPDF_InterForm::ExportToFDF(FX_WSTR pdf_path, CFX_PtrArray& fields, FX_BOOL bIncludeOrExclude, FX_BOOL bSimpleFileSpec) const
{
    CFDF_Document* pDoc = CFDF_Document::CreateNewDoc();
    if (pDoc == NULL) {
        return NULL;
    }
    CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDict("FDF");
    if (!pdf_path.IsEmpty()) {
        if (bSimpleFileSpec) {
            CFX_WideString wsFilePath = FILESPEC_EncodeFileName(pdf_path);
            pMainDict->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(wsFilePath));
            pMainDict->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(wsFilePath));
        } else {
            CPDF_FileSpec filespec;
            filespec.SetFileName(pdf_path);
            pMainDict->SetAt("F", (CPDF_Object*)filespec);
        }
    }
    CPDF_Array* pFields = CPDF_Array::Create();
    if (pFields == NULL) {
        return NULL;
    }
    pMainDict->SetAt("Fields", pFields);
    int nCount = m_pFieldTree->m_Root.CountFields();
    for (int i = 0; i < nCount; i ++) {
        CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i);
        if (pField == NULL || pField->GetType() == CPDF_FormField::PushButton) {
            continue;
        }
        FX_DWORD dwFlags = pField->GetFieldFlags();
        if (dwFlags & 0x04) {
            continue;
        }
        FX_BOOL bFind = fields.Find(pField, 0) >= 0;
        if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) {
            if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetString("V").IsEmpty()) {
                continue;
            }
            CFX_WideString fullname = GetFullName(pField->GetFieldDict());
            CPDF_Dictionary* pFieldDict = CPDF_Dictionary::Create();
            if (pFieldDict == NULL) {
                return NULL;
            }
            CPDF_String* pString = CPDF_String::Create(fullname);
            if (pString == NULL) {
                pFieldDict->Release();
                return NULL;
            }
            pFieldDict->SetAt("T", pString);
            if (pField->GetType() == CPDF_FormField::CheckBox || pField->GetType() == CPDF_FormField::RadioButton) {
                CFX_WideString csExport = pField->GetCheckValue(FALSE);
                CFX_ByteString csBExport = PDF_EncodeText(csExport);
                CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt");
                if (pOpt == NULL) {
                    pFieldDict->SetAtName("V", csBExport);
                } else {
                    pFieldDict->SetAtString("V", csBExport);
                }
            } else {
                CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V");
                if (pV != NULL) {
                    pFieldDict->SetAt("V", pV->Clone(TRUE));
                }
            }
            pFields->Add(pFieldDict);
        }
    }
    return pDoc;
}
const struct _SupportFieldEncoding {
    FX_LPCSTR m_name;
    FX_INT32 m_codePage;
} g_fieldEncoding[] = {
    "BigFive", 950,
    "GBK", 936,
    "Shift-JIS", 932,
    "UHC", 949,
};
static void FPDFDOC_FDF_GetFieldValue(CPDF_Dictionary *pFieldDict, CFX_WideString &csValue, CFX_ByteString &bsEncoding)
{
    ASSERT(pFieldDict != NULL);
    CFX_ByteString csBValue = pFieldDict->GetString("V");
    FX_INT32 iCount = sizeof(g_fieldEncoding) / sizeof(g_fieldEncoding[0]);
    FX_INT32 i = 0;
    for (; i < iCount; ++i)
        if (bsEncoding == g_fieldEncoding[i].m_name) {
            break;
        }
    if (i < iCount) {
        CFX_CharMap *pCharMap = CFX_CharMap::GetDefaultMapper(g_fieldEncoding[i].m_codePage);
        FXSYS_assert(pCharMap != NULL);
        csValue.ConvertFrom(csBValue, pCharMap);
        return;
    }
    CFX_ByteString csTemp = csBValue.Left(2);
    if (csTemp == "\xFF\xFE" || csTemp == "\xFE\xFF") {
        csValue = PDF_DecodeText(csBValue);
    } else {
        csValue = CFX_WideString::FromLocal(csBValue);
    }
}
void CPDF_InterForm::FDF_ImportField(CPDF_Dictionary* pFieldDict, const CFX_WideString& parent_name, FX_BOOL bNotify, int nLevel)
{
    CFX_WideString name;
    if (!parent_name.IsEmpty()) {
        name = parent_name + L".";
    }
    name += pFieldDict->GetUnicodeText("T");
    CPDF_Array* pKids = pFieldDict->GetArray("Kids");
    if (pKids) {
        for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) {
            CPDF_Dictionary* pKid = pKids->GetDict(i);
            if (pKid == NULL) {
                continue;
            }
            if (nLevel <= nMaxRecursion) {
                FDF_ImportField(pKid, name, bNotify, nLevel + 1);
            }
        }
        return;
    }
    if (!pFieldDict->KeyExist("V")) {
        return;
    }
    CPDF_FormField* pField = m_pFieldTree->GetField(name);
    if (pField == NULL) {
        return;
    }
    CFX_WideString csWValue;
    FPDFDOC_FDF_GetFieldValue(pFieldDict, csWValue, m_bsEncoding);
    int iType = pField->GetFieldType();
    if (bNotify && m_pFormNotify != NULL) {
        int iRet = 0;
        if (iType == FIELDTYPE_LISTBOX) {
            iRet = m_pFormNotify->BeforeSelectionChange(pField, csWValue);
        } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) {
            iRet = m_pFormNotify->BeforeValueChange(pField, csWValue);
        }
        if (iRet < 0) {
            return;
        }
    }
    CFX_ByteArray statusArray;
    if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) {
        SaveCheckedFieldStatus(pField, statusArray);
    }
    pField->SetValue(csWValue);
    CPDF_FormField::Type eType = pField->GetType();
    if ((eType == CPDF_FormField::ListBox || eType == CPDF_FormField::ComboBox) && pFieldDict->KeyExist("Opt")) {
        pField->m_pDict->SetAt("Opt", pFieldDict->GetElementValue("Opt")->Clone(TRUE));
    }
    if (bNotify && m_pFormNotify != NULL) {
        if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) {
            m_pFormNotify->AfterCheckedStatusChange(pField, statusArray);
        } else if (iType == FIELDTYPE_LISTBOX) {
            m_pFormNotify->AfterSelectionChange(pField);
        } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) {
            m_pFormNotify->AfterValueChange(pField);
        }
    }
    if (CPDF_InterForm::m_bUpdateAP) {
        pField->UpdateAP(NULL);
    }
}
FX_BOOL CPDF_InterForm::ImportFromFDF(const CFDF_Document* pFDF, FX_BOOL bNotify)
{
    if (pFDF == NULL) {
        return FALSE;
    }
    CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF");
    if (pMainDict == NULL) {
        return FALSE;
    }
    CPDF_Array* pFields = pMainDict->GetArray("Fields");
    if (pFields == NULL) {
        return FALSE;
    }
    m_bsEncoding = pMainDict->GetString(FX_BSTRC("Encoding"));
    if (bNotify && m_pFormNotify != NULL) {
        int iRet = m_pFormNotify->BeforeFormImportData(this);
        if (iRet < 0) {
            return FALSE;
        }
    }
    for (FX_DWORD i = 0; i < pFields->GetCount(); i ++) {
        CPDF_Dictionary* pField = pFields->GetDict(i);
        if (pField == NULL) {
            continue;
        }
        FDF_ImportField(pField, L"", bNotify);
    }
    if (bNotify && m_pFormNotify != NULL) {
        m_pFormNotify->AfterFormImportData(this);
    }
    return TRUE;
}
void CPDF_InterForm::SetFormNotify(const CPDF_FormNotify* pNotify)
{
    m_pFormNotify = (CPDF_FormNotify*)pNotify;
}
int CPDF_InterForm::GetPageWithWidget(int iCurPage, FX_BOOL bNext)
{
    if (iCurPage < 0) {
        return -1;
    }
    int iPageCount = m_pDocument->GetPageCount();
    if (iCurPage >= iPageCount) {
        return -1;
    }
    int iNewPage = iCurPage;
    do {
        iNewPage += bNext ? 1 : -1;
        if (iNewPage >= iPageCount) {
            iNewPage = 0;
        }
        if (iNewPage < 0) {
            iNewPage = iPageCount - 1;
        }
        if (iNewPage == iCurPage) {
            break;
        }
        CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iNewPage);
        if (pPageDict == NULL) {
            continue;
        }
        CPDF_Array* pAnnots = pPageDict->GetArray("Annots");
        if (pAnnots == NULL) {
            continue;
        }
        FX_DWORD dwCount = pAnnots->GetCount();
        for (FX_DWORD i = 0; i < dwCount; i ++) {
            CPDF_Object* pAnnotDict = pAnnots->GetElementValue(i);
            if (pAnnotDict == NULL) {
                continue;
            }
            CPDF_FormControl* pControl = NULL;
            if (m_ControlMap.Lookup(pAnnotDict, (void*&)pControl)) {
                return iNewPage;
            }
        }
    } while (TRUE);
    return -1;
}
