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