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" 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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}; 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 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 397 int32_t XFA_MapRotation(int32_t nRotation) { 398 nRotation = nRotation % 360; 399 nRotation = nRotation < 0 ? nRotation + 360 : nRotation; 400 return nRotation; 401 } 402