1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #include "../../include/fpdfdoc/fpdf_doc.h" 8 #include "../../include/fxcrt/fx_xml.h" 9 CFX_WideString GetFullName(CPDF_Dictionary* pFieldDict); 10 void InitInterFormDict(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument); 11 FX_DWORD CountInterFormFonts(CPDF_Dictionary* pFormDict); 12 CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_DWORD index, CFX_ByteString& csNameTag); 13 CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csNameTag); 14 CPDF_Font* GetInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CFX_ByteString& csNameTag); 15 CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag); 16 CPDF_Font* GetNativeInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag); 17 FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont, CFX_ByteString& csNameTag); 18 FX_BOOL FindInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument, CFX_ByteString csFontName, CPDF_Font*& pFont, CFX_ByteString& csNameTag); 19 void AddInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, const CPDF_Font* pFont, CFX_ByteString& csNameTag); 20 CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, FX_BYTE charSet, CFX_ByteString& csNameTag); 21 CPDF_Font* AddNativeInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, CFX_ByteString& csNameTag); 22 void RemoveInterFormFont(CPDF_Dictionary* pFormDict, const CPDF_Font* pFont); 23 void RemoveInterFormFont(CPDF_Dictionary* pFormDict, CFX_ByteString csNameTag); 24 CPDF_Font* GetDefaultInterFormFont(CPDF_Dictionary* pFormDict, CPDF_Document* pDocument); 25 void SetDefaultInterFormFont(CPDF_Dictionary*& pFormDict, CPDF_Document* pDocument, const CPDF_Font* pFont); 26 void SaveCheckedFieldStatus(CPDF_FormField* pField, CFX_ByteArray& statusArray); 27 FX_BOOL NeedPDFEncodeForFieldFullName(const CFX_WideString& csFieldName); 28 FX_BOOL NeedPDFEncodeForFieldTree(CPDF_Dictionary* pFieldDict, int nLevel = 0); 29 void EncodeFieldName(const CFX_WideString& csName, CFX_ByteString& csT); 30 void UpdateEncodeFieldName(CPDF_Dictionary* pFieldDict, int nLevel = 0); 31 const int nMaxRecursion = 32; 32 class _CFieldNameExtractor : public CFX_Object 33 { 34 public: 35 _CFieldNameExtractor(const CFX_WideString& full_name) 36 { 37 m_pStart = full_name; 38 m_pEnd = m_pStart + full_name.GetLength(); 39 m_pCur = m_pStart; 40 } 41 void GetNext(FX_LPCWSTR &pSubName, FX_STRSIZE& size) 42 { 43 pSubName = m_pCur; 44 while (m_pCur < m_pEnd && m_pCur[0] != L'.') { 45 m_pCur++; 46 } 47 size = (FX_STRSIZE)(m_pCur - pSubName); 48 if (m_pCur < m_pEnd && m_pCur[0] == L'.') { 49 m_pCur++; 50 } 51 } 52 protected: 53 FX_LPCWSTR m_pStart; 54 FX_LPCWSTR m_pEnd; 55 FX_LPCWSTR m_pCur; 56 }; 57 class CFieldTree : public CFX_Object 58 { 59 public: 60 struct _Node : public CFX_Object { 61 _Node *parent; 62 CFX_PtrArray children; 63 CFX_WideString short_name; 64 CPDF_FormField *field_ptr; 65 int CountFields(int nLevel = 0) 66 { 67 if (nLevel > nMaxRecursion) { 68 return 0; 69 } 70 if (field_ptr) { 71 return 1; 72 } 73 int count = 0; 74 for (int i = 0; i < children.GetSize(); i ++) { 75 count += ((_Node *)children.GetAt(i))->CountFields(nLevel + 1); 76 } 77 return count; 78 } 79 CPDF_FormField* GetField(int* fields_to_go) 80 { 81 if (field_ptr) { 82 if (*fields_to_go == 0) { 83 return field_ptr; 84 } 85 --*fields_to_go; 86 return NULL; 87 } 88 for (int i = 0; i < children.GetSize(); i++) { 89 _Node *pNode = (_Node *)children.GetAt(i); 90 CPDF_FormField* pField = pNode->GetField(fields_to_go); 91 if (pField) { 92 return pField; 93 } 94 } 95 return NULL; 96 } 97 CPDF_FormField* GetField(int index) 98 { 99 int fields_to_go = index; 100 return GetField(&fields_to_go); 101 } 102 }; 103 CFieldTree(); 104 ~CFieldTree(); 105 void SetField(const CFX_WideString &full_name, CPDF_FormField *field_ptr); 106 CPDF_FormField *GetField(const CFX_WideString &full_name); 107 CPDF_FormField *RemoveField(const CFX_WideString &full_name); 108 void RemoveAll(); 109 _Node *FindNode(const CFX_WideString &full_name); 110 _Node * AddChild(_Node *pParent, const CFX_WideString &short_name, CPDF_FormField *field_ptr); 111 void RemoveNode(_Node *pNode, int nLevel = 0); 112 _Node *_Lookup(_Node *pParent, const CFX_WideString &short_name); 113 _Node m_Root; 114 }; 115 CFieldTree::CFieldTree() 116 { 117 m_Root.parent = NULL; 118 m_Root.field_ptr = NULL; 119 } 120 CFieldTree::~CFieldTree() 121 { 122 RemoveAll(); 123 } 124 CFieldTree::_Node *CFieldTree::AddChild(_Node *pParent, const CFX_WideString &short_name, CPDF_FormField *field_ptr) 125 { 126 if (pParent == NULL) { 127 return NULL; 128 } 129 _Node *pNode = FX_NEW _Node; 130 if (pNode == NULL) { 131 return NULL; 132 } 133 pNode->parent = pParent; 134 pNode->short_name = short_name; 135 pNode->field_ptr = field_ptr; 136 pParent->children.Add(pNode); 137 return pNode; 138 } 139 void CFieldTree::RemoveNode(_Node *pNode, int nLevel) 140 { 141 if (pNode == NULL) { 142 return ; 143 } 144 if (nLevel > nMaxRecursion) { 145 delete pNode; 146 return ; 147 } 148 CFX_PtrArray& ptr_array = pNode->children; 149 for (int i = 0; i < ptr_array.GetSize(); i ++) { 150 _Node *pChild = (_Node *)ptr_array[i]; 151 RemoveNode(pChild, nLevel + 1); 152 } 153 delete pNode; 154 } 155 CFieldTree::_Node *CFieldTree::_Lookup(_Node *pParent, const CFX_WideString &short_name) 156 { 157 if (pParent == NULL) { 158 return NULL; 159 } 160 CFX_PtrArray& ptr_array = pParent->children; 161 for (int i = 0; i < ptr_array.GetSize(); i ++) { 162 _Node *pNode = (_Node *)ptr_array[i]; 163 if (pNode->short_name.GetLength() == short_name.GetLength() && 164 FXSYS_memcmp32((FX_LPCWSTR)pNode->short_name, (FX_LPCWSTR)short_name, short_name.GetLength()*sizeof(FX_WCHAR)) == 0) { 165 return pNode; 166 } 167 } 168 return NULL; 169 } 170 void CFieldTree::RemoveAll() 171 { 172 CFX_PtrArray& ptr_array = m_Root.children; 173 for (int i = 0; i < ptr_array.GetSize(); i ++) { 174 _Node *pNode = (_Node *)ptr_array[i]; 175 RemoveNode(pNode); 176 } 177 } 178 void CFieldTree::SetField(const CFX_WideString &full_name, CPDF_FormField *field_ptr) 179 { 180 if (full_name == L"") { 181 return; 182 } 183 _CFieldNameExtractor name_extractor(full_name); 184 FX_LPCWSTR pName; 185 FX_STRSIZE nLength; 186 name_extractor.GetNext(pName, nLength); 187 _Node *pNode = &m_Root, *pLast = NULL; 188 while (nLength > 0) { 189 pLast = pNode; 190 CFX_WideString name = CFX_WideString(pName, nLength); 191 pNode = _Lookup(pLast, name); 192 if (pNode == NULL) { 193 pNode = AddChild(pLast, name, NULL); 194 } 195 name_extractor.GetNext(pName, nLength); 196 } 197 if (pNode != &m_Root) { 198 pNode->field_ptr = field_ptr; 199 } 200 } 201 CPDF_FormField *CFieldTree::GetField(const CFX_WideString &full_name) 202 { 203 if (full_name == L"") { 204 return NULL; 205 } 206 _CFieldNameExtractor name_extractor(full_name); 207 FX_LPCWSTR pName; 208 FX_STRSIZE nLength; 209 name_extractor.GetNext(pName, nLength); 210 _Node *pNode = &m_Root, *pLast = NULL; 211 while (nLength > 0 && pNode) { 212 pLast = pNode; 213 CFX_WideString name = CFX_WideString(pName, nLength); 214 pNode = _Lookup(pLast, name); 215 name_extractor.GetNext(pName, nLength); 216 } 217 return pNode ? pNode->field_ptr : NULL; 218 } 219 CPDF_FormField *CFieldTree::RemoveField(const CFX_WideString & full_name) 220 { 221 if (full_name == L"") { 222 return NULL; 223 } 224 _CFieldNameExtractor name_extractor(full_name); 225 FX_LPCWSTR pName; 226 FX_STRSIZE nLength; 227 name_extractor.GetNext(pName, nLength); 228 _Node *pNode = &m_Root, *pLast = NULL; 229 while (nLength > 0 && pNode) { 230 pLast = pNode; 231 CFX_WideString name = CFX_WideString(pName, nLength); 232 pNode = _Lookup(pLast, name); 233 name_extractor.GetNext(pName, nLength); 234 } 235 if (pNode && pNode != &m_Root) { 236 CFX_PtrArray& ptr_array = pLast->children; 237 for (int i = 0; i < ptr_array.GetSize(); i ++) { 238 if (pNode == (_Node *)ptr_array[i]) { 239 ptr_array.RemoveAt(i); 240 break; 241 } 242 } 243 CPDF_FormField *pField = pNode->field_ptr; 244 RemoveNode(pNode); 245 return pField; 246 } 247 return NULL; 248 } 249 CFieldTree::_Node *CFieldTree::FindNode(const CFX_WideString& full_name) 250 { 251 if (full_name == L"") { 252 return NULL; 253 } 254 _CFieldNameExtractor name_extractor(full_name); 255 FX_LPCWSTR pName; 256 FX_STRSIZE nLength; 257 name_extractor.GetNext(pName, nLength); 258 _Node *pNode = &m_Root, *pLast = NULL; 259 while (nLength > 0 && pNode) { 260 pLast = pNode; 261 CFX_WideString name = CFX_WideString(pName, nLength); 262 pNode = _Lookup(pLast, name); 263 name_extractor.GetNext(pName, nLength); 264 } 265 return pNode; 266 } 267 CPDF_InterForm::CPDF_InterForm(CPDF_Document* pDocument, FX_BOOL bGenerateAP) : CFX_PrivateData() 268 { 269 m_pDocument = pDocument; 270 m_bGenerateAP = bGenerateAP; 271 m_pFormNotify = NULL; 272 m_bUpdated = FALSE; 273 m_pFieldTree = FX_NEW CFieldTree; 274 CPDF_Dictionary* pRoot = m_pDocument->GetRoot(); 275 m_pFormDict = pRoot->GetDict("AcroForm"); 276 if (m_pFormDict == NULL) { 277 return; 278 } 279 CPDF_Array* pFields = m_pFormDict->GetArray("Fields"); 280 if (pFields == NULL) { 281 return; 282 } 283 int count = pFields->GetCount(); 284 for (int i = 0; i < count; i ++) { 285 LoadField(pFields->GetDict(i)); 286 } 287 } 288 CPDF_InterForm::~CPDF_InterForm() 289 { 290 FX_POSITION pos = m_ControlMap.GetStartPosition(); 291 while (pos) { 292 FX_LPVOID key, value; 293 m_ControlMap.GetNextAssoc(pos, key, value); 294 delete (CPDF_FormControl*)value; 295 } 296 if (m_pFieldTree != NULL) { 297 int nCount = m_pFieldTree->m_Root.CountFields(); 298 for (int i = 0; i < nCount; i++) { 299 CPDF_FormField *pField = m_pFieldTree->m_Root.GetField(i); 300 delete pField; 301 } 302 delete m_pFieldTree; 303 } 304 } 305 FX_BOOL CPDF_InterForm::m_bUpdateAP = TRUE; 306 FX_BOOL CPDF_InterForm::UpdatingAPEnabled() 307 { 308 return m_bUpdateAP; 309 } 310 void CPDF_InterForm::EnableUpdateAP(FX_BOOL bUpdateAP) 311 { 312 m_bUpdateAP = bUpdateAP; 313 } 314 CFX_ByteString CPDF_InterForm::GenerateNewResourceName(const CPDF_Dictionary* pResDict, FX_LPCSTR csType, int iMinLen, FX_LPCSTR csPrefix) 315 { 316 CFX_ByteString csStr = csPrefix; 317 CFX_ByteString csBType = csType; 318 if (csStr.IsEmpty()) { 319 if (csBType == "ExtGState") { 320 csStr = "GS"; 321 } else if (csBType == "ColorSpace") { 322 csStr = "CS"; 323 } else if (csBType == "Font") { 324 csStr = "ZiTi"; 325 } else { 326 csStr = "Res"; 327 } 328 } 329 CFX_ByteString csTmp = csStr; 330 int iCount = csStr.GetLength(); 331 int m = 0; 332 if (iMinLen > 0) { 333 csTmp = ""; 334 while (m < iMinLen && m < iCount) { 335 csTmp += csStr[m ++]; 336 } 337 while (m < iMinLen) { 338 csTmp += '0' + m % 10; 339 m ++; 340 } 341 } else { 342 m = iCount; 343 } 344 if (pResDict == NULL) { 345 return csTmp; 346 } 347 CPDF_Dictionary* pDict = pResDict->GetDict(csType); 348 if (pDict == NULL) { 349 return csTmp; 350 } 351 int num = 0; 352 CFX_ByteString bsNum; 353 while (TRUE) { 354 if (!pDict->KeyExist(csTmp + bsNum)) { 355 return csTmp + bsNum; 356 } 357 if (m < iCount) { 358 csTmp += csStr[m ++]; 359 } else { 360 bsNum.Format("%d", num++); 361 } 362 m ++; 363 } 364 return csTmp; 365 } 366 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 367 typedef struct _PDF_FONTDATA { 368 FX_BOOL bFind; 369 LOGFONTA lf; 370 } PDF_FONTDATA, FAR* LPDF_FONTDATA; 371 static int CALLBACK EnumFontFamExProc( ENUMLOGFONTEXA *lpelfe, 372 NEWTEXTMETRICEX *lpntme, 373 DWORD FontType, 374 LPARAM lParam 375 ) 376 { 377 if (FontType != 0x004 || strchr(lpelfe->elfLogFont.lfFaceName, '@') != NULL) { 378 return 1; 379 } else { 380 LPDF_FONTDATA pData = (LPDF_FONTDATA)lParam; 381 memcpy(&pData->lf, &lpelfe->elfLogFont, sizeof(LOGFONTA)); 382 pData->bFind = TRUE; 383 return 0; 384 } 385 } 386 static FX_BOOL RetrieveSpecificFont(LOGFONTA& lf) 387 { 388 PDF_FONTDATA fd; 389 memset(&fd, 0, sizeof(PDF_FONTDATA)); 390 HDC hDC = ::GetDC(NULL); 391 EnumFontFamiliesExA(hDC, &lf, (FONTENUMPROCA)EnumFontFamExProc, (LPARAM)&fd, 0); 392 ::ReleaseDC(NULL, hDC); 393 if (fd.bFind) { 394 memcpy(&lf, &fd.lf, sizeof(LOGFONTA)); 395 } 396 return fd.bFind; 397 } 398 static FX_BOOL RetrieveSpecificFont(FX_BYTE charSet, FX_BYTE pitchAndFamily, LPCSTR pcsFontName, LOGFONTA& lf) 399 { 400 memset(&lf, 0, sizeof(LOGFONTA)); 401 lf.lfCharSet = charSet; 402 lf.lfPitchAndFamily = pitchAndFamily; 403 if (pcsFontName != NULL) { 404 strcpy(lf.lfFaceName, pcsFontName); 405 } 406 return RetrieveSpecificFont(lf); 407 } 408 static FX_BOOL RetrieveStockFont(int iFontObject, FX_BYTE charSet, LOGFONTA& lf) 409 { 410 HFONT hFont = (HFONT)::GetStockObject(iFontObject); 411 if (hFont != NULL) { 412 memset(&lf, 0, sizeof(LOGFONTA)); 413 int iRet = ::GetObject(hFont, sizeof(LOGFONTA), &lf); 414 if (iRet > 0 && (lf.lfCharSet == charSet || charSet == 255)) { 415 return RetrieveSpecificFont(lf); 416 } 417 } 418 return FALSE; 419 } 420 #endif 421 CPDF_Font* CPDF_InterForm::AddSystemDefaultFont(const CPDF_Document* pDocument) 422 { 423 if (pDocument == NULL) { 424 return NULL; 425 } 426 CPDF_Font* pFont = NULL; 427 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 428 LOGFONTA lf; 429 FX_BOOL bRet; 430 bRet = RetrieveStockFont(DEFAULT_GUI_FONT, 255, lf); 431 if (!bRet) { 432 bRet = RetrieveStockFont(SYSTEM_FONT, 255, lf); 433 } 434 if (bRet) { 435 pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE); 436 } 437 #endif 438 return pFont; 439 } 440 CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument, CFX_ByteString csFontName, FX_BYTE iCharSet) 441 { 442 if (pDocument == NULL || csFontName.IsEmpty()) { 443 return NULL; 444 } 445 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 446 if (iCharSet == 1) { 447 iCharSet = GetNativeCharSet(); 448 } 449 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); 450 if (hFont != NULL) { 451 LOGFONTA lf; 452 memset(&lf, 0, sizeof(LOGFONTA)); 453 ::GetObjectA(hFont, sizeof(LOGFONTA), &lf); 454 ::DeleteObject(hFont); 455 if (strlen(lf.lfFaceName) > 0) { 456 return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE); 457 } 458 } 459 #endif 460 return NULL; 461 } 462 CPDF_Font* CPDF_InterForm::AddSystemFont(const CPDF_Document* pDocument, CFX_WideString csFontName, FX_BYTE iCharSet) 463 { 464 if (pDocument == NULL || csFontName.IsEmpty()) { 465 return NULL; 466 } 467 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 468 if (iCharSet == 1) { 469 iCharSet = GetNativeCharSet(); 470 } 471 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); 472 if (hFont != NULL) { 473 LOGFONTA lf; 474 memset(&lf, 0, sizeof(LOGFONTA)); 475 ::GetObject(hFont, sizeof(LOGFONTA), &lf); 476 ::DeleteObject(hFont); 477 if (strlen(lf.lfFaceName) > 0) { 478 return ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE); 479 } 480 } 481 #endif 482 return NULL; 483 } 484 CPDF_Font* CPDF_InterForm::AddStandardFont(const CPDF_Document* pDocument, CFX_ByteString csFontName) 485 { 486 if (pDocument == NULL || csFontName.IsEmpty()) { 487 return NULL; 488 } 489 CPDF_Font* pFont = NULL; 490 if (csFontName == "ZapfDingbats") { 491 pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, NULL); 492 } else { 493 CPDF_FontEncoding encoding(PDFFONT_ENCODING_WINANSI); 494 pFont = ((CPDF_Document*)pDocument)->AddStandardFont(csFontName, &encoding); 495 } 496 return pFont; 497 } 498 CFX_ByteString CPDF_InterForm::GetNativeFont(FX_BYTE charSet, FX_LPVOID pLogFont) 499 { 500 CFX_ByteString csFontName; 501 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 502 LOGFONTA lf; 503 FX_BOOL bRet; 504 if (charSet == ANSI_CHARSET) { 505 csFontName = "Helvetica"; 506 return csFontName; 507 } 508 bRet = FALSE; 509 if (charSet == SHIFTJIS_CHARSET) { 510 bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "MS Mincho", lf); 511 } else if (charSet == GB2312_CHARSET) { 512 bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "SimSun", lf); 513 } else if (charSet == CHINESEBIG5_CHARSET) { 514 bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "MingLiU", lf); 515 } 516 if (!bRet) { 517 bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "Arial Unicode MS", lf); 518 } 519 if (!bRet) { 520 bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, "Microsoft Sans Serif", lf); 521 } 522 if (!bRet) { 523 bRet = RetrieveSpecificFont(charSet, DEFAULT_PITCH | FF_DONTCARE, NULL, lf); 524 } 525 if (bRet) { 526 if (pLogFont != NULL) { 527 memcpy(pLogFont, &lf, sizeof(LOGFONTA)); 528 } 529 csFontName = lf.lfFaceName; 530 return csFontName; 531 } 532 #endif 533 return csFontName; 534 } 535 CFX_ByteString CPDF_InterForm::GetNativeFont(FX_LPVOID pLogFont) 536 { 537 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 538 FX_BYTE charSet = GetNativeCharSet(); 539 return GetNativeFont(charSet, pLogFont); 540 #else 541 return CFX_ByteString(); 542 #endif 543 } 544 FX_BYTE CPDF_InterForm::GetNativeCharSet() 545 { 546 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 547 FX_BYTE charSet = ANSI_CHARSET; 548 UINT iCodePage = ::GetACP(); 549 switch (iCodePage) { 550 case 932: 551 charSet = SHIFTJIS_CHARSET; 552 break; 553 case 936: 554 charSet = GB2312_CHARSET; 555 break; 556 case 950: 557 charSet = CHINESEBIG5_CHARSET; 558 break; 559 case 1252: 560 charSet = ANSI_CHARSET; 561 break; 562 case 874: 563 charSet = THAI_CHARSET; 564 break; 565 case 949: 566 charSet = HANGUL_CHARSET; 567 break; 568 case 1200: 569 charSet = ANSI_CHARSET; 570 break; 571 case 1250: 572 charSet = EASTEUROPE_CHARSET; 573 break; 574 case 1251: 575 charSet = RUSSIAN_CHARSET; 576 break; 577 case 1253: 578 charSet = GREEK_CHARSET; 579 break; 580 case 1254: 581 charSet = TURKISH_CHARSET; 582 break; 583 case 1255: 584 charSet = HEBREW_CHARSET; 585 break; 586 case 1256: 587 charSet = ARABIC_CHARSET; 588 break; 589 case 1257: 590 charSet = BALTIC_CHARSET; 591 break; 592 case 1258: 593 charSet = VIETNAMESE_CHARSET; 594 break; 595 case 1361: 596 charSet = JOHAB_CHARSET; 597 break; 598 } 599 return charSet; 600 #else 601 return 0; 602 #endif 603 } 604 CPDF_Font* CPDF_InterForm::AddNativeFont(FX_BYTE charSet, const CPDF_Document* pDocument) 605 { 606 if (pDocument == NULL) { 607 return NULL; 608 } 609 CPDF_Font* pFont = NULL; 610 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ 611 LOGFONTA lf; 612 CFX_ByteString csFontName = GetNativeFont(charSet, &lf); 613 if (!csFontName.IsEmpty()) { 614 if (csFontName == "Helvetica") { 615 pFont = AddStandardFont(pDocument, csFontName); 616 } else { 617 pFont = ((CPDF_Document*)pDocument)->AddWindowsFont(&lf, FALSE, TRUE); 618 } 619 } 620 #endif 621 return pFont; 622 } 623 CPDF_Font* CPDF_InterForm::AddNativeFont(const CPDF_Document* pDocument) 624 { 625 if (pDocument == NULL) { 626 return NULL; 627 } 628 CPDF_Font* pFont = NULL; 629 FX_BYTE charSet = GetNativeCharSet(); 630 pFont = AddNativeFont(charSet, pDocument); 631 return pFont; 632 } 633 FX_BOOL CPDF_InterForm::ValidateFieldName(CFX_WideString& csNewFieldName, int iType, const CPDF_FormField* pExcludedField, const CPDF_FormControl* pExcludedControl) 634 { 635 if (csNewFieldName.IsEmpty()) { 636 return FALSE; 637 } 638 int iPos = 0; 639 int iLength = csNewFieldName.GetLength(); 640 CFX_WideString csSub; 641 while (TRUE) { 642 while (iPos < iLength && (csNewFieldName[iPos] == L'.' || csNewFieldName[iPos] == L' ')) { 643 iPos ++; 644 } 645 if (iPos < iLength && !csSub.IsEmpty()) { 646 csSub += L'.'; 647 } 648 while (iPos < iLength && csNewFieldName[iPos] != L'.') { 649 csSub += csNewFieldName[iPos ++]; 650 } 651 for (int i = csSub.GetLength() - 1; i > -1; i --) { 652 if (csSub[i] == L' ' || csSub[i] == L'.') { 653 csSub.SetAt(i, L'\0'); 654 } else { 655 break; 656 } 657 } 658 FX_DWORD dwCount = m_pFieldTree->m_Root.CountFields(); 659 for (FX_DWORD m = 0; m < dwCount; m ++) { 660 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(m); 661 if (pField == NULL) { 662 continue; 663 } 664 if (pField == pExcludedField) { 665 if (pExcludedControl != NULL) { 666 if (pField->CountControls() < 2) { 667 continue; 668 } 669 } else { 670 continue; 671 } 672 } 673 CFX_WideString csFullName = pField->GetFullName(); 674 int iRet = CompareFieldName(csSub, csFullName); 675 if (iRet == 1) { 676 if (pField->GetFieldType() != iType) { 677 return FALSE; 678 } 679 } else if (iRet == 2 && csSub == csNewFieldName) { 680 if (csFullName[iPos] == L'.') { 681 return FALSE; 682 } 683 } else if (iRet == 3 && csSub == csNewFieldName) { 684 if (csNewFieldName[csFullName.GetLength()] == L'.') { 685 return FALSE; 686 } 687 } 688 } 689 if (iPos >= iLength) { 690 break; 691 } 692 } 693 if (csSub.IsEmpty()) { 694 return FALSE; 695 } 696 csNewFieldName = csSub; 697 return TRUE; 698 } 699 FX_BOOL CPDF_InterForm::ValidateFieldName(CFX_WideString& csNewFieldName, int iType) 700 { 701 return ValidateFieldName(csNewFieldName, iType, NULL, NULL); 702 } 703 FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormField* pField, CFX_WideString& csNewFieldName) 704 { 705 if (pField == NULL || csNewFieldName.IsEmpty()) { 706 return FALSE; 707 } 708 return ValidateFieldName(csNewFieldName, ((CPDF_FormField*)pField)->GetFieldType(), pField, NULL); 709 } 710 FX_BOOL CPDF_InterForm::ValidateFieldName(const CPDF_FormControl* pControl, CFX_WideString& csNewFieldName) 711 { 712 if (pControl == NULL || csNewFieldName.IsEmpty()) { 713 return FALSE; 714 } 715 CPDF_FormField* pField = ((CPDF_FormControl*)pControl)->GetField(); 716 return ValidateFieldName(csNewFieldName, pField->GetFieldType(), pField, pControl); 717 } 718 int CPDF_InterForm::CompareFieldName(const CFX_ByteString& name1, const CFX_ByteString& name2) 719 { 720 FX_LPCSTR ptr1 = name1, ptr2 = name2; 721 if (name1.GetLength() != name2.GetLength()) { 722 int i = 0; 723 while (ptr1[i] == ptr2[i]) { 724 i ++; 725 } 726 if (i == name1.GetLength()) { 727 return 2; 728 } 729 if (i == name2.GetLength()) { 730 return 3; 731 } 732 return 0; 733 } else { 734 return name1 == name2 ? 1 : 0; 735 } 736 } 737 int CPDF_InterForm::CompareFieldName(const CFX_WideString& name1, const CFX_WideString& name2) 738 { 739 FX_LPCWSTR ptr1 = name1, ptr2 = name2; 740 if (name1.GetLength() != name2.GetLength()) { 741 int i = 0; 742 while (ptr1[i] == ptr2[i]) { 743 i ++; 744 } 745 if (i == name1.GetLength()) { 746 return 2; 747 } 748 if (i == name2.GetLength()) { 749 return 3; 750 } 751 return 0; 752 } else { 753 return name1 == name2 ? 1 : 0; 754 } 755 } 756 FX_DWORD CPDF_InterForm::CountFields(const CFX_WideString &csFieldName) 757 { 758 if (csFieldName.IsEmpty()) { 759 return (FX_DWORD)m_pFieldTree->m_Root.CountFields(); 760 } 761 CFieldTree::_Node *pNode = m_pFieldTree->FindNode(csFieldName); 762 if (pNode == NULL) { 763 return 0; 764 } 765 return pNode->CountFields(); 766 } 767 CPDF_FormField* CPDF_InterForm::GetField(FX_DWORD index, const CFX_WideString &csFieldName) 768 { 769 if (csFieldName == L"") { 770 return m_pFieldTree->m_Root.GetField(index); 771 } 772 CFieldTree::_Node *pNode = m_pFieldTree->FindNode(csFieldName); 773 if (pNode == NULL) { 774 return NULL; 775 } 776 return pNode->GetField(index); 777 } 778 void CPDF_InterForm::GetAllFieldNames(CFX_WideStringArray& allFieldNames) 779 { 780 allFieldNames.RemoveAll(); 781 int nCount = m_pFieldTree->m_Root.CountFields(); 782 for (int i = 0; i < nCount; i ++) { 783 CPDF_FormField *pField = m_pFieldTree->m_Root.GetField(i); 784 if (pField) { 785 CFX_WideString full_name = GetFullName(pField->GetFieldDict()); 786 allFieldNames.Add(full_name); 787 } 788 } 789 } 790 FX_BOOL CPDF_InterForm::IsValidFormField(const void* pField) 791 { 792 if (pField == NULL) { 793 return FALSE; 794 } 795 int nCount = m_pFieldTree->m_Root.CountFields(); 796 for (int i = 0; i < nCount; i++) { 797 CPDF_FormField *pFormField = m_pFieldTree->m_Root.GetField(i); 798 if (pField == pFormField) { 799 return TRUE; 800 } 801 } 802 return FALSE; 803 } 804 CPDF_FormField* CPDF_InterForm::GetFieldByDict(CPDF_Dictionary* pFieldDict) const 805 { 806 if (pFieldDict == NULL) { 807 return NULL; 808 } 809 CFX_WideString csWName = GetFullName(pFieldDict); 810 return m_pFieldTree->GetField(csWName); 811 } 812 FX_DWORD CPDF_InterForm::CountControls(CFX_WideString csFieldName) 813 { 814 if (csFieldName.IsEmpty()) { 815 return (FX_DWORD)m_ControlMap.GetCount(); 816 } 817 CPDF_FormField *pField = m_pFieldTree->GetField(csFieldName); 818 if (pField == NULL) { 819 return 0; 820 } 821 return pField->m_ControlList.GetSize(); 822 } 823 CPDF_FormControl* CPDF_InterForm::GetControl(FX_DWORD index, CFX_WideString csFieldName) 824 { 825 CPDF_FormField *pField = m_pFieldTree->GetField(csFieldName); 826 if (pField == NULL) { 827 return NULL; 828 } 829 if (index < (FX_DWORD)pField->m_ControlList.GetSize()) { 830 return (CPDF_FormControl *)pField->m_ControlList.GetAt(index); 831 } 832 return NULL; 833 } 834 FX_BOOL CPDF_InterForm::IsValidFormControl(const void* pControl) 835 { 836 if (pControl == NULL) { 837 return FALSE; 838 } 839 FX_POSITION pos = m_ControlMap.GetStartPosition(); 840 while (pos) { 841 CPDF_Dictionary* pWidgetDict = NULL; 842 void* pFormControl = NULL; 843 m_ControlMap.GetNextAssoc(pos, (FX_LPVOID&)pWidgetDict, pFormControl); 844 if (pControl == pFormControl) { 845 return TRUE; 846 } 847 } 848 return FALSE; 849 } 850 int CPDF_InterForm::CountPageControls(CPDF_Page* pPage) const 851 { 852 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); 853 if (pAnnotList == NULL) { 854 return 0; 855 } 856 int count = 0; 857 for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i ++) { 858 CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i); 859 if (pAnnot == NULL) { 860 continue; 861 } 862 CPDF_FormControl* pControl; 863 if (!m_ControlMap.Lookup(pAnnot, (FX_LPVOID&)pControl)) { 864 continue; 865 } 866 count ++; 867 } 868 return count; 869 } 870 CPDF_FormControl* CPDF_InterForm::GetPageControl(CPDF_Page* pPage, int index) const 871 { 872 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); 873 if (pAnnotList == NULL) { 874 return NULL; 875 } 876 int count = 0; 877 for (FX_DWORD i = 0; i < pAnnotList->GetCount(); i ++) { 878 CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i); 879 if (pAnnot == NULL) { 880 continue; 881 } 882 CPDF_FormControl* pControl; 883 if (!m_ControlMap.Lookup(pAnnot, (FX_LPVOID&)pControl)) { 884 continue; 885 } 886 if (index == count) { 887 return pControl; 888 } 889 count ++; 890 } 891 return NULL; 892 } 893 CPDF_FormControl* CPDF_InterForm::GetControlAtPoint(CPDF_Page* pPage, FX_FLOAT pdf_x, FX_FLOAT pdf_y) const 894 { 895 CPDF_Array* pAnnotList = pPage->m_pFormDict->GetArray("Annots"); 896 if (pAnnotList == NULL) { 897 return NULL; 898 } 899 for (FX_DWORD i = pAnnotList->GetCount(); i > 0; i --) { 900 CPDF_Dictionary* pAnnot = pAnnotList->GetDict(i - 1); 901 if (pAnnot == NULL) { 902 continue; 903 } 904 CPDF_FormControl* pControl; 905 if (!m_ControlMap.Lookup(pAnnot, (FX_LPVOID&)pControl)) { 906 continue; 907 } 908 CFX_FloatRect rect = pControl->GetRect(); 909 if (rect.Contains(pdf_x, pdf_y)) { 910 return pControl; 911 } 912 } 913 return NULL; 914 } 915 CPDF_FormControl* CPDF_InterForm::GetControlByDict(CPDF_Dictionary* pWidgetDict) const 916 { 917 CPDF_FormControl* pControl = NULL; 918 m_ControlMap.Lookup(pWidgetDict, (FX_LPVOID&)pControl); 919 return pControl; 920 } 921 FX_DWORD CPDF_InterForm::CountInternalFields(const CFX_WideString& csFieldName) const 922 { 923 if (m_pFormDict == NULL) { 924 return 0; 925 } 926 CPDF_Array* pArray = m_pFormDict->GetArray("Fields"); 927 if (pArray == NULL) { 928 return 0; 929 } 930 if (csFieldName.IsEmpty()) { 931 return pArray->GetCount(); 932 } else { 933 int iLength = csFieldName.GetLength(); 934 int iPos = 0; 935 CPDF_Dictionary* pDict = NULL; 936 while (pArray != NULL) { 937 CFX_WideString csSub; 938 if (iPos < iLength && csFieldName[iPos] == L'.') { 939 iPos ++; 940 } 941 while (iPos < iLength && csFieldName[iPos] != L'.') { 942 csSub += csFieldName[iPos ++]; 943 } 944 int iCount = pArray->GetCount(); 945 FX_BOOL bFind = FALSE; 946 for (int i = 0; i < iCount; i ++) { 947 pDict = pArray->GetDict(i); 948 if (pDict == NULL) { 949 continue; 950 } 951 CFX_WideString csT = pDict->GetUnicodeText("T"); 952 if (csT == csSub) { 953 bFind = TRUE; 954 break; 955 } 956 } 957 if (!bFind) { 958 return 0; 959 } 960 if (iPos >= iLength) { 961 break; 962 } 963 pArray = pDict->GetArray("Kids"); 964 } 965 if (pDict == NULL) { 966 return 0; 967 } else { 968 pArray = pDict->GetArray("Kids"); 969 if (pArray == NULL) { 970 return 1; 971 } else { 972 return pArray->GetCount(); 973 } 974 } 975 } 976 } 977 CPDF_Dictionary* CPDF_InterForm::GetInternalField(FX_DWORD index, const CFX_WideString& csFieldName) const 978 { 979 if (m_pFormDict == NULL) { 980 return NULL; 981 } 982 CPDF_Array* pArray = m_pFormDict->GetArray("Fields"); 983 if (pArray == NULL) { 984 return 0; 985 } 986 if (csFieldName.IsEmpty()) { 987 return pArray->GetDict(index); 988 } else { 989 int iLength = csFieldName.GetLength(); 990 int iPos = 0; 991 CPDF_Dictionary* pDict = NULL; 992 while (pArray != NULL) { 993 CFX_WideString csSub; 994 if (iPos < iLength && csFieldName[iPos] == L'.') { 995 iPos ++; 996 } 997 while (iPos < iLength && csFieldName[iPos] != L'.') { 998 csSub += csFieldName[iPos ++]; 999 } 1000 int iCount = pArray->GetCount(); 1001 FX_BOOL bFind = FALSE; 1002 for (int i = 0; i < iCount; i ++) { 1003 pDict = pArray->GetDict(i); 1004 if (pDict == NULL) { 1005 continue; 1006 } 1007 CFX_WideString csT = pDict->GetUnicodeText("T"); 1008 if (csT == csSub) { 1009 bFind = TRUE; 1010 break; 1011 } 1012 } 1013 if (!bFind) { 1014 return NULL; 1015 } 1016 if (iPos >= iLength) { 1017 break; 1018 } 1019 pArray = pDict->GetArray("Kids"); 1020 } 1021 if (pDict == NULL) { 1022 return NULL; 1023 } else { 1024 pArray = pDict->GetArray("Kids"); 1025 if (pArray == NULL) { 1026 return pDict; 1027 } else { 1028 return pArray->GetDict(index); 1029 } 1030 } 1031 } 1032 } 1033 FX_BOOL CPDF_InterForm::NeedConstructAP() 1034 { 1035 if (m_pFormDict == NULL) { 1036 return FALSE; 1037 } 1038 return m_pFormDict->GetBoolean("NeedAppearances"); 1039 } 1040 void CPDF_InterForm::NeedConstructAP(FX_BOOL bNeedAP) 1041 { 1042 if (m_pFormDict == NULL) { 1043 InitInterFormDict(m_pFormDict, m_pDocument); 1044 } 1045 m_pFormDict->SetAtBoolean("NeedAppearances", bNeedAP); 1046 m_bGenerateAP = bNeedAP; 1047 } 1048 int CPDF_InterForm::CountFieldsInCalculationOrder() 1049 { 1050 if (m_pFormDict == NULL) { 1051 return 0; 1052 } 1053 CPDF_Array* pArray = m_pFormDict->GetArray("CO"); 1054 if (pArray == NULL) { 1055 return 0; 1056 } 1057 return pArray->GetCount(); 1058 } 1059 CPDF_FormField* CPDF_InterForm::GetFieldInCalculationOrder(int index) 1060 { 1061 if (m_pFormDict == NULL || index < 0) { 1062 return NULL; 1063 } 1064 CPDF_Array* pArray = m_pFormDict->GetArray("CO"); 1065 if (pArray == NULL) { 1066 return NULL; 1067 } 1068 CPDF_Object* pElement = pArray->GetElementValue(index); 1069 if (pElement != NULL && pElement->GetType() == PDFOBJ_DICTIONARY) { 1070 return GetFieldByDict((CPDF_Dictionary*)pElement); 1071 } 1072 return NULL; 1073 } 1074 int CPDF_InterForm::FindFieldInCalculationOrder(const CPDF_FormField* pField) 1075 { 1076 if (m_pFormDict == NULL || pField == NULL) { 1077 return -1; 1078 } 1079 CPDF_Array* pArray = m_pFormDict->GetArray("CO"); 1080 if (pArray == NULL) { 1081 return -1; 1082 } 1083 for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { 1084 CPDF_Object* pElement = pArray->GetElementValue(i); 1085 if (pElement == pField->m_pDict) { 1086 return i; 1087 } 1088 } 1089 return -1; 1090 } 1091 FX_DWORD CPDF_InterForm::CountFormFonts() 1092 { 1093 return CountInterFormFonts(m_pFormDict); 1094 } 1095 CPDF_Font* CPDF_InterForm::GetFormFont(FX_DWORD index, CFX_ByteString& csNameTag) 1096 { 1097 return GetInterFormFont(m_pFormDict, m_pDocument, index, csNameTag); 1098 } 1099 CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csNameTag) 1100 { 1101 return GetInterFormFont(m_pFormDict, m_pDocument, csNameTag); 1102 } 1103 CPDF_Font* CPDF_InterForm::GetFormFont(CFX_ByteString csFontName, CFX_ByteString& csNameTag) 1104 { 1105 return GetInterFormFont(m_pFormDict, m_pDocument, csFontName, csNameTag); 1106 } 1107 CPDF_Font* CPDF_InterForm::GetNativeFormFont(FX_BYTE charSet, CFX_ByteString& csNameTag) 1108 { 1109 return GetNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag); 1110 } 1111 CPDF_Font* CPDF_InterForm::GetNativeFormFont(CFX_ByteString& csNameTag) 1112 { 1113 return GetNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag); 1114 } 1115 FX_BOOL CPDF_InterForm::FindFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag) 1116 { 1117 return FindInterFormFont(m_pFormDict, pFont, csNameTag); 1118 } 1119 FX_BOOL CPDF_InterForm::FindFormFont(CFX_ByteString csFontName, CPDF_Font*& pFont, CFX_ByteString& csNameTag) 1120 { 1121 return FindInterFormFont(m_pFormDict, m_pDocument, csFontName, pFont, csNameTag); 1122 } 1123 void CPDF_InterForm::AddFormFont(const CPDF_Font* pFont, CFX_ByteString& csNameTag) 1124 { 1125 AddInterFormFont(m_pFormDict, m_pDocument, pFont, csNameTag); 1126 m_bUpdated = TRUE; 1127 } 1128 CPDF_Font* CPDF_InterForm::AddNativeFormFont(FX_BYTE charSet, CFX_ByteString& csNameTag) 1129 { 1130 m_bUpdated = TRUE; 1131 return AddNativeInterFormFont(m_pFormDict, m_pDocument, charSet, csNameTag); 1132 } 1133 CPDF_Font* CPDF_InterForm::AddNativeFormFont(CFX_ByteString& csNameTag) 1134 { 1135 m_bUpdated = TRUE; 1136 return AddNativeInterFormFont(m_pFormDict, m_pDocument, csNameTag); 1137 } 1138 void CPDF_InterForm::RemoveFormFont(const CPDF_Font* pFont) 1139 { 1140 m_bUpdated = TRUE; 1141 RemoveInterFormFont(m_pFormDict, pFont); 1142 } 1143 void CPDF_InterForm::RemoveFormFont(CFX_ByteString csNameTag) 1144 { 1145 m_bUpdated = TRUE; 1146 RemoveInterFormFont(m_pFormDict, csNameTag); 1147 } 1148 CPDF_DefaultAppearance CPDF_InterForm::GetDefaultAppearance() 1149 { 1150 CFX_ByteString csDA; 1151 if (m_pFormDict == NULL) { 1152 return csDA; 1153 } 1154 csDA = m_pFormDict->GetString("DA"); 1155 return csDA; 1156 } 1157 CPDF_Font* CPDF_InterForm::GetDefaultFormFont() 1158 { 1159 return GetDefaultInterFormFont(m_pFormDict, m_pDocument); 1160 } 1161 int CPDF_InterForm::GetFormAlignment() 1162 { 1163 if (m_pFormDict == NULL) { 1164 return 0; 1165 } 1166 return m_pFormDict->GetInteger("Q", 0); 1167 } 1168 FX_BOOL CPDF_InterForm::ResetForm(const CFX_PtrArray& fields, FX_BOOL bIncludeOrExclude, FX_BOOL bNotify) 1169 { 1170 if (bNotify && m_pFormNotify != NULL) { 1171 int iRet = m_pFormNotify->BeforeFormReset(this); 1172 if (iRet < 0) { 1173 return FALSE; 1174 } 1175 } 1176 int nCount = m_pFieldTree->m_Root.CountFields(); 1177 for (int i = 0; i < nCount; i++) { 1178 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); 1179 if (pField == NULL) { 1180 continue; 1181 } 1182 FX_BOOL bFind = FALSE; 1183 int iCount = fields.GetSize(); 1184 for (int i = 0; i < iCount; i ++) { 1185 if (pField == (CPDF_FormField*)fields[i]) { 1186 bFind = TRUE; 1187 break; 1188 } 1189 } 1190 if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) { 1191 pField->ResetField(bNotify); 1192 } 1193 } 1194 if (bNotify && m_pFormNotify != NULL) { 1195 m_pFormNotify->AfterFormReset(this); 1196 } 1197 return TRUE; 1198 } 1199 FX_BOOL CPDF_InterForm::ResetForm(FX_BOOL bNotify) 1200 { 1201 if (bNotify && m_pFormNotify != NULL) { 1202 int iRet = m_pFormNotify->BeforeFormReset(this); 1203 if (iRet < 0) { 1204 return FALSE; 1205 } 1206 } 1207 int nCount = m_pFieldTree->m_Root.CountFields(); 1208 for (int i = 0; i < nCount; i++) { 1209 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); 1210 if (pField == NULL) { 1211 continue; 1212 } 1213 pField->ResetField(bNotify); 1214 } 1215 if (bNotify && m_pFormNotify != NULL) { 1216 m_pFormNotify->AfterFormReset(this); 1217 } 1218 return TRUE; 1219 } 1220 void CPDF_InterForm::ReloadForm() 1221 { 1222 FX_POSITION pos = m_ControlMap.GetStartPosition(); 1223 while (pos) { 1224 CPDF_Dictionary* pWidgetDict; 1225 CPDF_FormControl* pControl; 1226 m_ControlMap.GetNextAssoc(pos, (FX_LPVOID&)pWidgetDict, (FX_LPVOID&)pControl); 1227 delete pControl; 1228 } 1229 m_ControlMap.RemoveAll(); 1230 int nCount = m_pFieldTree->m_Root.CountFields(); 1231 for (int k = 0; k < nCount; k ++) { 1232 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(k); 1233 delete pField; 1234 } 1235 m_pFieldTree->RemoveAll(); 1236 if (m_pFormDict == NULL) { 1237 return; 1238 } 1239 CPDF_Array* pFields = m_pFormDict->GetArray("Fields"); 1240 if (pFields == NULL) { 1241 return; 1242 } 1243 int iCount = pFields->GetCount(); 1244 for (int i = 0; i < iCount; i ++) { 1245 LoadField(pFields->GetDict(i)); 1246 } 1247 } 1248 void CPDF_InterForm::LoadField(CPDF_Dictionary* pFieldDict, int nLevel) 1249 { 1250 if (nLevel > nMaxRecursion) { 1251 return; 1252 } 1253 if (pFieldDict == NULL) { 1254 return; 1255 } 1256 FX_DWORD dwParentObjNum = pFieldDict->GetObjNum(); 1257 CPDF_Array* pKids = pFieldDict->GetArray("Kids"); 1258 if (!pKids) { 1259 AddTerminalField(pFieldDict); 1260 return; 1261 } 1262 CPDF_Dictionary* pFirstKid = pKids->GetDict(0); 1263 if (pFirstKid == NULL) { 1264 return; 1265 } 1266 if (pFirstKid->KeyExist("T") || pFirstKid->KeyExist("Kids")) { 1267 for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) { 1268 CPDF_Dictionary * pChildDict = pKids->GetDict(i); 1269 if (pChildDict) { 1270 if (pChildDict->GetObjNum() != dwParentObjNum) { 1271 LoadField(pChildDict, nLevel + 1); 1272 } 1273 } 1274 } 1275 } else { 1276 AddTerminalField(pFieldDict); 1277 } 1278 } 1279 FX_BOOL CPDF_InterForm::HasXFAForm() const 1280 { 1281 return m_pFormDict && m_pFormDict->GetArray(FX_BSTRC("XFA")) != NULL; 1282 } 1283 void CPDF_InterForm::FixPageFields(const CPDF_Page* pPage) 1284 { 1285 ASSERT(pPage != NULL); 1286 CPDF_Dictionary* pPageDict = pPage->m_pFormDict; 1287 if (pPageDict == NULL) { 1288 return; 1289 } 1290 CPDF_Array* pAnnots = pPageDict->GetArray(FX_BSTRC("Annots")); 1291 if (pAnnots == NULL) { 1292 return; 1293 } 1294 int iAnnotCount = pAnnots->GetCount(); 1295 for (int i = 0; i < iAnnotCount; i++) { 1296 CPDF_Dictionary* pAnnot = pAnnots->GetDict(i); 1297 if (pAnnot != NULL && pAnnot->GetString(FX_BSTRC("Subtype")) == "Widget") { 1298 LoadField(pAnnot); 1299 } 1300 } 1301 } 1302 CPDF_FormField* CPDF_InterForm::AddTerminalField(const CPDF_Dictionary* pFieldDict) 1303 { 1304 if (!pFieldDict->KeyExist(FX_BSTRC("T"))) { 1305 return NULL; 1306 } 1307 CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFieldDict; 1308 CFX_WideString csWName = GetFullName(pDict); 1309 if (csWName.IsEmpty()) { 1310 return NULL; 1311 } 1312 CPDF_FormField* pField = NULL; 1313 pField = m_pFieldTree->GetField(csWName); 1314 if (pField == NULL) { 1315 CPDF_Dictionary *pParent = (CPDF_Dictionary*)pFieldDict; 1316 if (!pFieldDict->KeyExist(FX_BSTR("T")) && 1317 pFieldDict->GetString(FX_BSTRC("Subtype")) == FX_BSTRC("Widget")) { 1318 pParent = pFieldDict->GetDict(FX_BSTRC("Parent")); 1319 if (!pParent) { 1320 pParent = (CPDF_Dictionary*)pFieldDict; 1321 } 1322 } 1323 if (pParent && pParent != pFieldDict && !pParent->KeyExist(FX_BSTRC("FT"))) { 1324 if (pFieldDict->KeyExist(FX_BSTRC("FT"))) { 1325 CPDF_Object *pFTValue = pFieldDict->GetElementValue(FX_BSTRC("FT")); 1326 if (pFTValue) { 1327 pParent->SetAt(FX_BSTRC("FT"), pFTValue->Clone()); 1328 } 1329 } 1330 if (pFieldDict->KeyExist(FX_BSTRC("Ff"))) { 1331 CPDF_Object *pFfValue = pFieldDict->GetElementValue(FX_BSTRC("Ff")); 1332 if (pFfValue) { 1333 pParent->SetAt(FX_BSTRC("Ff"), pFfValue->Clone()); 1334 } 1335 } 1336 } 1337 pField = FX_NEW CPDF_FormField(this, pParent); 1338 CPDF_Object* pTObj = pDict->GetElement("T"); 1339 if (pTObj && pTObj->GetType() == PDFOBJ_REFERENCE) { 1340 CPDF_Object* pClone = pTObj->Clone(TRUE); 1341 if (pClone) { 1342 pDict->SetAt("T", pClone); 1343 } else { 1344 pDict->SetAtName("T", ""); 1345 } 1346 } 1347 m_pFieldTree->SetField(csWName, pField); 1348 } 1349 CPDF_Array* pKids = pFieldDict->GetArray("Kids"); 1350 if (pKids == NULL) { 1351 if (pFieldDict->GetString("Subtype") == "Widget") { 1352 AddControl(pField, pFieldDict); 1353 } 1354 } else { 1355 for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) { 1356 CPDF_Dictionary* pKid = pKids->GetDict(i); 1357 if (pKid == NULL) { 1358 continue; 1359 } 1360 if (pKid->GetString("Subtype") != "Widget") { 1361 continue; 1362 } 1363 AddControl(pField, pKid); 1364 } 1365 } 1366 return pField; 1367 } 1368 CPDF_FormControl* CPDF_InterForm::AddControl(const CPDF_FormField* pField, const CPDF_Dictionary* pWidgetDict) 1369 { 1370 void *rValue = NULL; 1371 if (m_ControlMap.Lookup((CPDF_Dictionary*)pWidgetDict, rValue)) { 1372 return (CPDF_FormControl*)rValue; 1373 } 1374 CPDF_FormControl* pControl = FX_NEW CPDF_FormControl((CPDF_FormField*)pField, (CPDF_Dictionary*)pWidgetDict); 1375 if (pControl == NULL) { 1376 return NULL; 1377 } 1378 m_ControlMap.SetAt((CPDF_Dictionary*)pWidgetDict, pControl); 1379 ((CPDF_FormField*)pField)->m_ControlList.Add(pControl); 1380 return pControl; 1381 } 1382 CPDF_FormField* CPDF_InterForm::CheckRequiredFields(const CFX_PtrArray *fields, FX_BOOL bIncludeOrExclude) const 1383 { 1384 int nCount = m_pFieldTree->m_Root.CountFields(); 1385 for (int i = 0; i < nCount; i++) { 1386 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); 1387 if (pField == NULL) { 1388 continue; 1389 } 1390 FX_INT32 iType = pField->GetType(); 1391 if (iType == CPDF_FormField::PushButton || iType == CPDF_FormField::CheckBox || iType == CPDF_FormField::ListBox) { 1392 continue; 1393 } 1394 FX_DWORD dwFlags = pField->GetFieldFlags(); 1395 if (dwFlags & 0x04) { 1396 continue; 1397 } 1398 FX_BOOL bFind = TRUE; 1399 if (fields != NULL) { 1400 bFind = fields->Find(pField, 0) >= 0; 1401 } 1402 if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) { 1403 CPDF_Dictionary *pFieldDict = pField->m_pDict; 1404 if ((dwFlags & 0x02) != 0 && pFieldDict->GetString("V").IsEmpty()) { 1405 return pField; 1406 } 1407 } 1408 } 1409 return NULL; 1410 } 1411 CFDF_Document* CPDF_InterForm::ExportToFDF(FX_WSTR pdf_path, FX_BOOL bSimpleFileSpec) const 1412 { 1413 CFX_PtrArray fields; 1414 int nCount = m_pFieldTree->m_Root.CountFields(); 1415 for (int i = 0; i < nCount; i ++) { 1416 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); 1417 fields.Add(pField); 1418 } 1419 return ExportToFDF(pdf_path, fields, TRUE, bSimpleFileSpec); 1420 } 1421 CFX_WideString FILESPEC_EncodeFileName(FX_WSTR filepath); 1422 CFDF_Document* CPDF_InterForm::ExportToFDF(FX_WSTR pdf_path, CFX_PtrArray& fields, FX_BOOL bIncludeOrExclude, FX_BOOL bSimpleFileSpec) const 1423 { 1424 CFDF_Document* pDoc = CFDF_Document::CreateNewDoc(); 1425 if (pDoc == NULL) { 1426 return NULL; 1427 } 1428 CPDF_Dictionary* pMainDict = pDoc->GetRoot()->GetDict("FDF"); 1429 if (!pdf_path.IsEmpty()) { 1430 if (bSimpleFileSpec) { 1431 CFX_WideString wsFilePath = FILESPEC_EncodeFileName(pdf_path); 1432 pMainDict->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(wsFilePath)); 1433 pMainDict->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(wsFilePath)); 1434 } else { 1435 CPDF_FileSpec filespec; 1436 filespec.SetFileName(pdf_path); 1437 pMainDict->SetAt("F", (CPDF_Object*)filespec); 1438 } 1439 } 1440 CPDF_Array* pFields = CPDF_Array::Create(); 1441 if (pFields == NULL) { 1442 return NULL; 1443 } 1444 pMainDict->SetAt("Fields", pFields); 1445 int nCount = m_pFieldTree->m_Root.CountFields(); 1446 for (int i = 0; i < nCount; i ++) { 1447 CPDF_FormField* pField = m_pFieldTree->m_Root.GetField(i); 1448 if (pField == NULL || pField->GetType() == CPDF_FormField::PushButton) { 1449 continue; 1450 } 1451 FX_DWORD dwFlags = pField->GetFieldFlags(); 1452 if (dwFlags & 0x04) { 1453 continue; 1454 } 1455 FX_BOOL bFind = fields.Find(pField, 0) >= 0; 1456 if ((bIncludeOrExclude && bFind) || (!bIncludeOrExclude && !bFind)) { 1457 if ((dwFlags & 0x02) != 0 && pField->m_pDict->GetString("V").IsEmpty()) { 1458 continue; 1459 } 1460 CFX_WideString fullname = GetFullName(pField->GetFieldDict()); 1461 CPDF_Dictionary* pFieldDict = CPDF_Dictionary::Create(); 1462 if (pFieldDict == NULL) { 1463 return NULL; 1464 } 1465 CPDF_String* pString = CPDF_String::Create(fullname); 1466 if (pString == NULL) { 1467 pFieldDict->Release(); 1468 return NULL; 1469 } 1470 pFieldDict->SetAt("T", pString); 1471 if (pField->GetType() == CPDF_FormField::CheckBox || pField->GetType() == CPDF_FormField::RadioButton) { 1472 CFX_WideString csExport = pField->GetCheckValue(FALSE); 1473 CFX_ByteString csBExport = PDF_EncodeText(csExport); 1474 CPDF_Object* pOpt = FPDF_GetFieldAttr(pField->m_pDict, "Opt"); 1475 if (pOpt == NULL) { 1476 pFieldDict->SetAtName("V", csBExport); 1477 } else { 1478 pFieldDict->SetAtString("V", csBExport); 1479 } 1480 } else { 1481 CPDF_Object* pV = FPDF_GetFieldAttr(pField->m_pDict, "V"); 1482 if (pV != NULL) { 1483 pFieldDict->SetAt("V", pV->Clone(TRUE)); 1484 } 1485 } 1486 pFields->Add(pFieldDict); 1487 } 1488 } 1489 return pDoc; 1490 } 1491 const struct _SupportFieldEncoding { 1492 FX_LPCSTR m_name; 1493 FX_INT32 m_codePage; 1494 } g_fieldEncoding[] = { 1495 "BigFive", 950, 1496 "GBK", 936, 1497 "Shift-JIS", 932, 1498 "UHC", 949, 1499 }; 1500 static void FPDFDOC_FDF_GetFieldValue(CPDF_Dictionary *pFieldDict, CFX_WideString &csValue, CFX_ByteString &bsEncoding) 1501 { 1502 ASSERT(pFieldDict != NULL); 1503 CFX_ByteString csBValue = pFieldDict->GetString("V"); 1504 FX_INT32 iCount = sizeof(g_fieldEncoding) / sizeof(g_fieldEncoding[0]); 1505 FX_INT32 i = 0; 1506 for (; i < iCount; ++i) 1507 if (bsEncoding == g_fieldEncoding[i].m_name) { 1508 break; 1509 } 1510 if (i < iCount) { 1511 CFX_CharMap *pCharMap = CFX_CharMap::GetDefaultMapper(g_fieldEncoding[i].m_codePage); 1512 FXSYS_assert(pCharMap != NULL); 1513 csValue.ConvertFrom(csBValue, pCharMap); 1514 return; 1515 } 1516 CFX_ByteString csTemp = csBValue.Left(2); 1517 if (csTemp == "\xFF\xFE" || csTemp == "\xFE\xFF") { 1518 csValue = PDF_DecodeText(csBValue); 1519 } else { 1520 csValue = CFX_WideString::FromLocal(csBValue); 1521 } 1522 } 1523 void CPDF_InterForm::FDF_ImportField(CPDF_Dictionary* pFieldDict, const CFX_WideString& parent_name, FX_BOOL bNotify, int nLevel) 1524 { 1525 CFX_WideString name; 1526 if (!parent_name.IsEmpty()) { 1527 name = parent_name + L"."; 1528 } 1529 name += pFieldDict->GetUnicodeText("T"); 1530 CPDF_Array* pKids = pFieldDict->GetArray("Kids"); 1531 if (pKids) { 1532 for (FX_DWORD i = 0; i < pKids->GetCount(); i ++) { 1533 CPDF_Dictionary* pKid = pKids->GetDict(i); 1534 if (pKid == NULL) { 1535 continue; 1536 } 1537 if (nLevel <= nMaxRecursion) { 1538 FDF_ImportField(pKid, name, bNotify, nLevel + 1); 1539 } 1540 } 1541 return; 1542 } 1543 if (!pFieldDict->KeyExist("V")) { 1544 return; 1545 } 1546 CPDF_FormField* pField = m_pFieldTree->GetField(name); 1547 if (pField == NULL) { 1548 return; 1549 } 1550 CFX_WideString csWValue; 1551 FPDFDOC_FDF_GetFieldValue(pFieldDict, csWValue, m_bsEncoding); 1552 int iType = pField->GetFieldType(); 1553 if (bNotify && m_pFormNotify != NULL) { 1554 int iRet = 0; 1555 if (iType == FIELDTYPE_LISTBOX) { 1556 iRet = m_pFormNotify->BeforeSelectionChange(pField, csWValue); 1557 } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) { 1558 iRet = m_pFormNotify->BeforeValueChange(pField, csWValue); 1559 } 1560 if (iRet < 0) { 1561 return; 1562 } 1563 } 1564 CFX_ByteArray statusArray; 1565 if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) { 1566 SaveCheckedFieldStatus(pField, statusArray); 1567 } 1568 pField->SetValue(csWValue); 1569 CPDF_FormField::Type eType = pField->GetType(); 1570 if ((eType == CPDF_FormField::ListBox || eType == CPDF_FormField::ComboBox) && pFieldDict->KeyExist("Opt")) { 1571 pField->m_pDict->SetAt("Opt", pFieldDict->GetElementValue("Opt")->Clone(TRUE)); 1572 } 1573 if (bNotify && m_pFormNotify != NULL) { 1574 if (iType == FIELDTYPE_CHECKBOX || iType == FIELDTYPE_RADIOBUTTON) { 1575 m_pFormNotify->AfterCheckedStatusChange(pField, statusArray); 1576 } else if (iType == FIELDTYPE_LISTBOX) { 1577 m_pFormNotify->AfterSelectionChange(pField); 1578 } else if (iType == FIELDTYPE_COMBOBOX || iType == FIELDTYPE_TEXTFIELD) { 1579 m_pFormNotify->AfterValueChange(pField); 1580 } 1581 } 1582 if (CPDF_InterForm::m_bUpdateAP) { 1583 pField->UpdateAP(NULL); 1584 } 1585 } 1586 FX_BOOL CPDF_InterForm::ImportFromFDF(const CFDF_Document* pFDF, FX_BOOL bNotify) 1587 { 1588 if (pFDF == NULL) { 1589 return FALSE; 1590 } 1591 CPDF_Dictionary* pMainDict = pFDF->GetRoot()->GetDict("FDF"); 1592 if (pMainDict == NULL) { 1593 return FALSE; 1594 } 1595 CPDF_Array* pFields = pMainDict->GetArray("Fields"); 1596 if (pFields == NULL) { 1597 return FALSE; 1598 } 1599 m_bsEncoding = pMainDict->GetString(FX_BSTRC("Encoding")); 1600 if (bNotify && m_pFormNotify != NULL) { 1601 int iRet = m_pFormNotify->BeforeFormImportData(this); 1602 if (iRet < 0) { 1603 return FALSE; 1604 } 1605 } 1606 for (FX_DWORD i = 0; i < pFields->GetCount(); i ++) { 1607 CPDF_Dictionary* pField = pFields->GetDict(i); 1608 if (pField == NULL) { 1609 continue; 1610 } 1611 FDF_ImportField(pField, L"", bNotify); 1612 } 1613 if (bNotify && m_pFormNotify != NULL) { 1614 m_pFormNotify->AfterFormImportData(this); 1615 } 1616 return TRUE; 1617 } 1618 void CPDF_InterForm::SetFormNotify(const CPDF_FormNotify* pNotify) 1619 { 1620 m_pFormNotify = (CPDF_FormNotify*)pNotify; 1621 } 1622 int CPDF_InterForm::GetPageWithWidget(int iCurPage, FX_BOOL bNext) 1623 { 1624 if (iCurPage < 0) { 1625 return -1; 1626 } 1627 int iPageCount = m_pDocument->GetPageCount(); 1628 if (iCurPage >= iPageCount) { 1629 return -1; 1630 } 1631 int iNewPage = iCurPage; 1632 do { 1633 iNewPage += bNext ? 1 : -1; 1634 if (iNewPage >= iPageCount) { 1635 iNewPage = 0; 1636 } 1637 if (iNewPage < 0) { 1638 iNewPage = iPageCount - 1; 1639 } 1640 if (iNewPage == iCurPage) { 1641 break; 1642 } 1643 CPDF_Dictionary* pPageDict = m_pDocument->GetPage(iNewPage); 1644 if (pPageDict == NULL) { 1645 continue; 1646 } 1647 CPDF_Array* pAnnots = pPageDict->GetArray("Annots"); 1648 if (pAnnots == NULL) { 1649 continue; 1650 } 1651 FX_DWORD dwCount = pAnnots->GetCount(); 1652 for (FX_DWORD i = 0; i < dwCount; i ++) { 1653 CPDF_Object* pAnnotDict = pAnnots->GetElementValue(i); 1654 if (pAnnotDict == NULL) { 1655 continue; 1656 } 1657 CPDF_FormControl* pControl = NULL; 1658 if (m_ControlMap.Lookup(pAnnotDict, (void*&)pControl)) { 1659 return iNewPage; 1660 } 1661 } 1662 } while (TRUE); 1663 return -1; 1664 } 1665