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