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