// 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;
}
