1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "xfa/src/foxitlib.h"
8 #include "xfa/src/fxfa/src/common/xfa_utils.h"
9 #include "xfa/src/fxfa/src/common/xfa_object.h"
10 #include "xfa/src/fxfa/src/common/xfa_document.h"
11 #include "xfa/src/fxfa/src/common/xfa_parser.h"
12 #include "xfa/src/fxfa/src/common/xfa_script.h"
13 #include "xfa/src/fxfa/src/common/xfa_docdata.h"
14 #include "xfa/src/fxfa/src/common/xfa_doclayout.h"
15 #include "xfa/src/fxfa/src/common/xfa_localemgr.h"
16 #include "xfa/src/fxfa/src/common/xfa_fm2jsapi.h"
XFA_CreateUIChild(CXFA_Node * pNode,XFA_ELEMENT & eWidgetType)17 CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType) {
18 XFA_ELEMENT eType = pNode->GetClassID();
19 eWidgetType = eType;
20 if (eType != XFA_ELEMENT_Field && eType != XFA_ELEMENT_Draw) {
21 return NULL;
22 }
23 eWidgetType = XFA_ELEMENT_UNKNOWN;
24 XFA_ELEMENT eUIType = XFA_ELEMENT_UNKNOWN;
25 CXFA_Value defValue = pNode->GetProperty(0, XFA_ELEMENT_Value, TRUE);
26 XFA_ELEMENT eValueType = (XFA_ELEMENT)defValue.GetChildValueClassID();
27 switch (eValueType) {
28 case XFA_ELEMENT_Boolean:
29 eUIType = XFA_ELEMENT_CheckButton;
30 break;
31 case XFA_ELEMENT_Integer:
32 case XFA_ELEMENT_Decimal:
33 case XFA_ELEMENT_Float:
34 eUIType = XFA_ELEMENT_NumericEdit;
35 break;
36 case XFA_ELEMENT_ExData:
37 case XFA_ELEMENT_Text:
38 eUIType = XFA_ELEMENT_TextEdit;
39 eWidgetType = XFA_ELEMENT_Text;
40 break;
41 case XFA_ELEMENT_Date:
42 case XFA_ELEMENT_Time:
43 case XFA_ELEMENT_DateTime:
44 eUIType = XFA_ELEMENT_DateTimeEdit;
45 break;
46 case XFA_ELEMENT_Image:
47 eUIType = XFA_ELEMENT_ImageEdit;
48 eWidgetType = XFA_ELEMENT_Image;
49 break;
50 ;
51 case XFA_ELEMENT_Arc:
52 case XFA_ELEMENT_Line:
53 case XFA_ELEMENT_Rectangle:
54 eUIType = XFA_ELEMENT_DefaultUi;
55 eWidgetType = eValueType;
56 break;
57 default:
58 break;
59 }
60 CXFA_Node* pUIChild = NULL;
61 CXFA_Node* pUI = pNode->GetProperty(0, XFA_ELEMENT_Ui, TRUE);
62 CXFA_Node* pChild = pUI->GetNodeItem(XFA_NODEITEM_FirstChild);
63 for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
64 XFA_ELEMENT eChild = pChild->GetClassID();
65 if (eChild == XFA_ELEMENT_Extras || eChild == XFA_ELEMENT_Picture) {
66 continue;
67 }
68 XFA_LPCPROPERTY pProterty =
69 XFA_GetPropertyOfElement(XFA_ELEMENT_Ui, eChild, XFA_XDPPACKET_Form);
70 if (pProterty && (pProterty->uFlags & XFA_PROPERTYFLAG_OneOf)) {
71 pUIChild = pChild;
72 break;
73 }
74 }
75 if (eType == XFA_ELEMENT_Draw) {
76 XFA_ELEMENT eDraw = pUIChild ? pUIChild->GetClassID() : XFA_ELEMENT_UNKNOWN;
77 switch (eDraw) {
78 case XFA_ELEMENT_TextEdit:
79 eWidgetType = XFA_ELEMENT_Text;
80 break;
81 case XFA_ELEMENT_ImageEdit:
82 eWidgetType = XFA_ELEMENT_Image;
83 break;
84 default:
85 eWidgetType =
86 eWidgetType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_Text : eWidgetType;
87 break;
88 }
89 } else {
90 if (pUIChild && pUIChild->GetClassID() == XFA_ELEMENT_DefaultUi) {
91 eWidgetType = XFA_ELEMENT_TextEdit;
92 } else {
93 eWidgetType = pUIChild
94 ? pUIChild->GetClassID()
95 : (eUIType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_TextEdit
96 : eUIType);
97 }
98 }
99 if (!pUIChild) {
100 if (eUIType == XFA_ELEMENT_UNKNOWN) {
101 eUIType = XFA_ELEMENT_TextEdit;
102 ((CXFA_Node*)defValue)->GetProperty(0, XFA_ELEMENT_Text, TRUE);
103 }
104 pUIChild = pUI->GetProperty(0, eUIType, TRUE);
105 } else if (eUIType == XFA_ELEMENT_UNKNOWN) {
106 switch (pUIChild->GetClassID()) {
107 case XFA_ELEMENT_CheckButton: {
108 eValueType = XFA_ELEMENT_Text;
109 if (CXFA_Node* pItems = pNode->GetChild(0, XFA_ELEMENT_Items)) {
110 if (CXFA_Node* pItem = pItems->GetChild(0, XFA_ELEMENT_UNKNOWN)) {
111 eValueType = pItem->GetClassID();
112 }
113 }
114 } break;
115 case XFA_ELEMENT_DateTimeEdit:
116 eValueType = XFA_ELEMENT_DateTime;
117 break;
118 case XFA_ELEMENT_ImageEdit:
119 eValueType = XFA_ELEMENT_Image;
120 break;
121 case XFA_ELEMENT_NumericEdit:
122 eValueType = XFA_ELEMENT_Float;
123 break;
124 case XFA_ELEMENT_ChoiceList: {
125 eValueType = (pUIChild->GetEnum(XFA_ATTRIBUTE_Open) ==
126 XFA_ATTRIBUTEENUM_MultiSelect)
127 ? XFA_ELEMENT_ExData
128 : XFA_ELEMENT_Text;
129 } break;
130 case XFA_ELEMENT_Barcode:
131 case XFA_ELEMENT_Button:
132 case XFA_ELEMENT_PasswordEdit:
133 case XFA_ELEMENT_Signature:
134 case XFA_ELEMENT_TextEdit:
135 default:
136 eValueType = XFA_ELEMENT_Text;
137 break;
138 }
139 ((CXFA_Node*)defValue)->GetProperty(0, eValueType, TRUE);
140 }
141 return pUIChild;
142 }
XFA_GetLocaleValue(CXFA_WidgetData * pWidgetData)143 CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData) {
144 CXFA_Node* pNodeValue =
145 pWidgetData->GetNode()->GetChild(0, XFA_ELEMENT_Value);
146 if (!pNodeValue) {
147 return CXFA_LocaleValue();
148 }
149 CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild);
150 if (!pValueChild) {
151 return CXFA_LocaleValue();
152 }
153 int32_t iVTType = XFA_VT_NULL;
154 XFA_ELEMENT eType = pValueChild->GetClassID();
155 switch (eType) {
156 case XFA_ELEMENT_Decimal:
157 iVTType = XFA_VT_DECIMAL;
158 break;
159 case XFA_ELEMENT_Float:
160 iVTType = XFA_VT_FLOAT;
161 break;
162 case XFA_ELEMENT_Date:
163 iVTType = XFA_VT_DATE;
164 break;
165 case XFA_ELEMENT_Time:
166 iVTType = XFA_VT_TIME;
167 break;
168 case XFA_ELEMENT_DateTime:
169 iVTType = XFA_VT_DATETIME;
170 break;
171 case XFA_ELEMENT_Boolean:
172 iVTType = XFA_VT_BOOLEAN;
173 break;
174 case XFA_ELEMENT_Integer:
175 iVTType = XFA_VT_INTEGER;
176 break;
177 case XFA_ELEMENT_Text:
178 iVTType = XFA_VT_TEXT;
179 break;
180 default:
181 iVTType = XFA_VT_NULL;
182 break;
183 }
184 return CXFA_LocaleValue(iVTType, pWidgetData->GetRawValue(),
185 pWidgetData->GetNode()->GetDocument()->GetLocalMgr());
186 }
XFA_GetPlainTextFromRichText(IFDE_XMLNode * pXMLNode,CFX_WideString & wsPlainText)187 void XFA_GetPlainTextFromRichText(IFDE_XMLNode* pXMLNode,
188 CFX_WideString& wsPlainText) {
189 if (pXMLNode == NULL) {
190 return;
191 }
192 switch (pXMLNode->GetType()) {
193 case FDE_XMLNODE_Element: {
194 IFDE_XMLElement* pXMLElement = (IFDE_XMLElement*)pXMLNode;
195 CFX_WideString wsTag;
196 pXMLElement->GetLocalTagName(wsTag);
197 uint32_t uTag = FX_HashCode_String_GetW(wsTag, wsTag.GetLength(), TRUE);
198 if (uTag == 0x0001f714) {
199 wsPlainText += L"\n";
200 } else if (uTag == 0x00000070) {
201 if (!wsPlainText.IsEmpty()) {
202 wsPlainText += L"\n";
203 }
204 } else if (uTag == 0xa48ac63) {
205 if (!wsPlainText.IsEmpty() &&
206 wsPlainText[wsPlainText.GetLength() - 1] != '\n') {
207 wsPlainText += L"\n";
208 }
209 }
210 } break;
211 case FDE_XMLNODE_Text: {
212 CFX_WideString wsContent;
213 ((IFDE_XMLText*)pXMLNode)->GetText(wsContent);
214 wsPlainText += wsContent;
215 } break;
216 case FDE_XMLNODE_CharData: {
217 CFX_WideString wsCharData;
218 ((IFDE_XMLCharData*)pXMLNode)->GetCharData(wsCharData);
219 wsPlainText += wsCharData;
220 } break;
221 default:
222 break;
223 }
224 for (IFDE_XMLNode* pChildXML =
225 pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild);
226 pChildXML;
227 pChildXML = pChildXML->GetNodeItem(IFDE_XMLNode::NextSibling)) {
228 XFA_GetPlainTextFromRichText(pChildXML, wsPlainText);
229 }
230 }
XFA_FieldIsMultiListBox(CXFA_Node * pFieldNode)231 FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode) {
232 FX_BOOL bRet = FALSE;
233 if (!pFieldNode) {
234 return bRet;
235 }
236 CXFA_Node* pUIChild = pFieldNode->GetChild(0, XFA_ELEMENT_Ui);
237 if (pUIChild) {
238 CXFA_Node* pFirstChild = pUIChild->GetNodeItem(XFA_NODEITEM_FirstChild);
239 if (pFirstChild && pFirstChild->GetClassID() == XFA_ELEMENT_ChoiceList) {
240 bRet = pFirstChild->GetEnum(XFA_ATTRIBUTE_Open) ==
241 XFA_ATTRIBUTEENUM_MultiSelect;
242 }
243 }
244 return bRet;
245 }
XFA_IsLayoutElement(XFA_ELEMENT eElement,FX_BOOL bLayoutContainer)246 FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer) {
247 switch (eElement) {
248 case XFA_ELEMENT_Draw:
249 case XFA_ELEMENT_Field:
250 case XFA_ELEMENT_InstanceManager:
251 return !bLayoutContainer;
252 case XFA_ELEMENT_Area:
253 case XFA_ELEMENT_Subform:
254 case XFA_ELEMENT_ExclGroup:
255 case XFA_ELEMENT_SubformSet:
256 return TRUE;
257 case XFA_ELEMENT_PageArea:
258 case XFA_ELEMENT_Form:
259 return TRUE;
260 default:
261 return FALSE;
262 }
263 return FALSE;
264 }
XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence)265 FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence) {
266 switch (ePresence) {
267 case XFA_ATTRIBUTEENUM_Visible:
268 case XFA_ATTRIBUTEENUM_Invisible:
269 return TRUE;
270 default:
271 return FALSE;
272 }
273 return FALSE;
274 }
XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout)275 FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout) {
276 switch (eLayout) {
277 case XFA_ATTRIBUTEENUM_Tb:
278 case XFA_ATTRIBUTEENUM_Lr_tb:
279 case XFA_ATTRIBUTEENUM_Rl_tb:
280 return TRUE;
281 default:
282 return FALSE;
283 }
284 return FALSE;
285 }
XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout)286 FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout) {
287 switch (eLayout) {
288 case XFA_ATTRIBUTEENUM_Lr_tb:
289 case XFA_ATTRIBUTEENUM_Rl_tb:
290 return TRUE;
291 default:
292 return FALSE;
293 }
294 return FALSE;
295 }
296 static const FX_DOUBLE fraction_scales[] = {0.1,
297 0.01,
298 0.001,
299 0.0001,
300 0.00001,
301 0.000001,
302 0.0000001,
303 0.00000001,
304 0.000000001,
305 0.0000000001,
306 0.00000000001,
307 0.000000000001,
308 0.0000000000001,
309 0.00000000000001,
310 0.000000000000001,
311 0.0000000000000001};
XFA_WideStringToDouble(const CFX_WideString & wsStringVal)312 FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString& wsStringVal) {
313 CFX_WideString wsValue = wsStringVal;
314 wsValue.TrimLeft();
315 wsValue.TrimRight();
316 int64_t nIntegral = 0;
317 FX_DWORD dwFractional = 0;
318 int32_t nExponent = 0;
319 int32_t cc = 0;
320 FX_BOOL bNegative = FALSE, bExpSign = FALSE;
321 const FX_WCHAR* str = (const FX_WCHAR*)wsValue;
322 int32_t len = wsValue.GetLength();
323 if (str[0] == '+') {
324 cc++;
325 } else if (str[0] == '-') {
326 bNegative = TRUE;
327 cc++;
328 }
329 int32_t nIntegralLen = 0;
330 while (cc < len) {
331 if (str[cc] == '.' || str[cc] == 'E' || str[cc] == 'e' ||
332 nIntegralLen > 17) {
333 break;
334 }
335 if (!XFA_IsDigit(str[cc])) {
336 return 0;
337 }
338 nIntegral = nIntegral * 10 + str[cc] - '0';
339 cc++;
340 nIntegralLen++;
341 }
342 nIntegral = bNegative ? -nIntegral : nIntegral;
343 int32_t scale = 0;
344 FX_DOUBLE fraction = 0.0;
345 if (cc < len && str[cc] == '.') {
346 cc++;
347 while (cc < len) {
348 fraction += fraction_scales[scale] * (str[cc] - '0');
349 scale++;
350 cc++;
351 if (cc == len) {
352 break;
353 }
354 if (scale == sizeof(fraction_scales) / sizeof(FX_DOUBLE) ||
355 str[cc] == 'E' || str[cc] == 'e') {
356 break;
357 }
358 if (!XFA_IsDigit(str[cc])) {
359 return 0;
360 }
361 }
362 dwFractional = (FX_DWORD)(fraction * 4294967296.0);
363 }
364 if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) {
365 cc++;
366 if (cc < len) {
367 if (str[cc] == '+') {
368 cc++;
369 } else if (str[cc] == '-') {
370 bExpSign = TRUE;
371 cc++;
372 }
373 }
374 while (cc < len) {
375 if (str[cc] == '.' || !XFA_IsDigit(str[cc])) {
376 return 0;
377 }
378 nExponent = nExponent * 10 + str[cc] - '0';
379 cc++;
380 }
381 nExponent = bExpSign ? -nExponent : nExponent;
382 }
383 FX_DOUBLE dValue = (dwFractional / 4294967296.0);
384 dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue);
385 if (nExponent != 0) {
386 dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent);
387 }
388 return dValue;
389 }
390
XFA_ByteStringToDouble(const CFX_ByteStringC & szStringVal)391 FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal) {
392 CFX_WideString wsValue =
393 CFX_WideString::FromUTF8(szStringVal.GetCStr(), szStringVal.GetLength());
394 return XFA_WideStringToDouble(wsValue);
395 }
396
XFA_MapRotation(int32_t nRotation)397 int32_t XFA_MapRotation(int32_t nRotation) {
398 nRotation = nRotation % 360;
399 nRotation = nRotation < 0 ? nRotation + 360 : nRotation;
400 return nRotation;
401 }
402