| // Copyright 2014 PDFium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| |
| #include "xfa/fxfa/parser/xfa_utils.h" |
| |
| #include "core/fxcrt/include/fx_ext.h" |
| #include "xfa/fde/xml/fde_xml_imp.h" |
| #include "xfa/fxfa/fm2js/xfa_fm2jsapi.h" |
| #include "xfa/fxfa/parser/xfa_docdata.h" |
| #include "xfa/fxfa/parser/xfa_doclayout.h" |
| #include "xfa/fxfa/parser/xfa_document.h" |
| #include "xfa/fxfa/parser/xfa_localemgr.h" |
| #include "xfa/fxfa/parser/xfa_localevalue.h" |
| #include "xfa/fxfa/parser/xfa_object.h" |
| #include "xfa/fxfa/parser/xfa_parser.h" |
| #include "xfa/fxfa/parser/xfa_script.h" |
| |
| CXFA_Node* XFA_CreateUIChild(CXFA_Node* pNode, XFA_ELEMENT& eWidgetType) { |
| XFA_ELEMENT eType = pNode->GetClassID(); |
| eWidgetType = eType; |
| if (eType != XFA_ELEMENT_Field && eType != XFA_ELEMENT_Draw) { |
| return NULL; |
| } |
| eWidgetType = XFA_ELEMENT_UNKNOWN; |
| XFA_ELEMENT eUIType = XFA_ELEMENT_UNKNOWN; |
| CXFA_Value defValue(pNode->GetProperty(0, XFA_ELEMENT_Value, TRUE)); |
| XFA_ELEMENT eValueType = (XFA_ELEMENT)defValue.GetChildValueClassID(); |
| switch (eValueType) { |
| case XFA_ELEMENT_Boolean: |
| eUIType = XFA_ELEMENT_CheckButton; |
| break; |
| case XFA_ELEMENT_Integer: |
| case XFA_ELEMENT_Decimal: |
| case XFA_ELEMENT_Float: |
| eUIType = XFA_ELEMENT_NumericEdit; |
| break; |
| case XFA_ELEMENT_ExData: |
| case XFA_ELEMENT_Text: |
| eUIType = XFA_ELEMENT_TextEdit; |
| eWidgetType = XFA_ELEMENT_Text; |
| break; |
| case XFA_ELEMENT_Date: |
| case XFA_ELEMENT_Time: |
| case XFA_ELEMENT_DateTime: |
| eUIType = XFA_ELEMENT_DateTimeEdit; |
| break; |
| case XFA_ELEMENT_Image: |
| eUIType = XFA_ELEMENT_ImageEdit; |
| eWidgetType = XFA_ELEMENT_Image; |
| break; |
| case XFA_ELEMENT_Arc: |
| case XFA_ELEMENT_Line: |
| case XFA_ELEMENT_Rectangle: |
| eUIType = XFA_ELEMENT_DefaultUi; |
| eWidgetType = eValueType; |
| break; |
| default: |
| break; |
| } |
| CXFA_Node* pUIChild = NULL; |
| CXFA_Node* pUI = pNode->GetProperty(0, XFA_ELEMENT_Ui, TRUE); |
| CXFA_Node* pChild = pUI->GetNodeItem(XFA_NODEITEM_FirstChild); |
| for (; pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { |
| XFA_ELEMENT eChild = pChild->GetClassID(); |
| if (eChild == XFA_ELEMENT_Extras || eChild == XFA_ELEMENT_Picture) { |
| continue; |
| } |
| const XFA_PROPERTY* pProperty = |
| XFA_GetPropertyOfElement(XFA_ELEMENT_Ui, eChild, XFA_XDPPACKET_Form); |
| if (pProperty && (pProperty->uFlags & XFA_PROPERTYFLAG_OneOf)) { |
| pUIChild = pChild; |
| break; |
| } |
| } |
| if (eType == XFA_ELEMENT_Draw) { |
| XFA_ELEMENT eDraw = pUIChild ? pUIChild->GetClassID() : XFA_ELEMENT_UNKNOWN; |
| switch (eDraw) { |
| case XFA_ELEMENT_TextEdit: |
| eWidgetType = XFA_ELEMENT_Text; |
| break; |
| case XFA_ELEMENT_ImageEdit: |
| eWidgetType = XFA_ELEMENT_Image; |
| break; |
| default: |
| eWidgetType = |
| eWidgetType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_Text : eWidgetType; |
| break; |
| } |
| } else { |
| if (pUIChild && pUIChild->GetClassID() == XFA_ELEMENT_DefaultUi) { |
| eWidgetType = XFA_ELEMENT_TextEdit; |
| } else { |
| eWidgetType = pUIChild |
| ? pUIChild->GetClassID() |
| : (eUIType == XFA_ELEMENT_UNKNOWN ? XFA_ELEMENT_TextEdit |
| : eUIType); |
| } |
| } |
| if (!pUIChild) { |
| if (eUIType == XFA_ELEMENT_UNKNOWN) { |
| eUIType = XFA_ELEMENT_TextEdit; |
| defValue.GetNode()->GetProperty(0, XFA_ELEMENT_Text, TRUE); |
| } |
| pUIChild = pUI->GetProperty(0, eUIType, TRUE); |
| } else if (eUIType == XFA_ELEMENT_UNKNOWN) { |
| switch (pUIChild->GetClassID()) { |
| case XFA_ELEMENT_CheckButton: { |
| eValueType = XFA_ELEMENT_Text; |
| if (CXFA_Node* pItems = pNode->GetChild(0, XFA_ELEMENT_Items)) { |
| if (CXFA_Node* pItem = pItems->GetChild(0, XFA_ELEMENT_UNKNOWN)) { |
| eValueType = pItem->GetClassID(); |
| } |
| } |
| } break; |
| case XFA_ELEMENT_DateTimeEdit: |
| eValueType = XFA_ELEMENT_DateTime; |
| break; |
| case XFA_ELEMENT_ImageEdit: |
| eValueType = XFA_ELEMENT_Image; |
| break; |
| case XFA_ELEMENT_NumericEdit: |
| eValueType = XFA_ELEMENT_Float; |
| break; |
| case XFA_ELEMENT_ChoiceList: { |
| eValueType = (pUIChild->GetEnum(XFA_ATTRIBUTE_Open) == |
| XFA_ATTRIBUTEENUM_MultiSelect) |
| ? XFA_ELEMENT_ExData |
| : XFA_ELEMENT_Text; |
| } break; |
| case XFA_ELEMENT_Barcode: |
| case XFA_ELEMENT_Button: |
| case XFA_ELEMENT_PasswordEdit: |
| case XFA_ELEMENT_Signature: |
| case XFA_ELEMENT_TextEdit: |
| default: |
| eValueType = XFA_ELEMENT_Text; |
| break; |
| } |
| defValue.GetNode()->GetProperty(0, eValueType, TRUE); |
| } |
| return pUIChild; |
| } |
| CXFA_LocaleValue XFA_GetLocaleValue(CXFA_WidgetData* pWidgetData) { |
| CXFA_Node* pNodeValue = |
| pWidgetData->GetNode()->GetChild(0, XFA_ELEMENT_Value); |
| if (!pNodeValue) { |
| return CXFA_LocaleValue(); |
| } |
| CXFA_Node* pValueChild = pNodeValue->GetNodeItem(XFA_NODEITEM_FirstChild); |
| if (!pValueChild) { |
| return CXFA_LocaleValue(); |
| } |
| int32_t iVTType = XFA_VT_NULL; |
| XFA_ELEMENT eType = pValueChild->GetClassID(); |
| switch (eType) { |
| case XFA_ELEMENT_Decimal: |
| iVTType = XFA_VT_DECIMAL; |
| break; |
| case XFA_ELEMENT_Float: |
| iVTType = XFA_VT_FLOAT; |
| break; |
| case XFA_ELEMENT_Date: |
| iVTType = XFA_VT_DATE; |
| break; |
| case XFA_ELEMENT_Time: |
| iVTType = XFA_VT_TIME; |
| break; |
| case XFA_ELEMENT_DateTime: |
| iVTType = XFA_VT_DATETIME; |
| break; |
| case XFA_ELEMENT_Boolean: |
| iVTType = XFA_VT_BOOLEAN; |
| break; |
| case XFA_ELEMENT_Integer: |
| iVTType = XFA_VT_INTEGER; |
| break; |
| case XFA_ELEMENT_Text: |
| iVTType = XFA_VT_TEXT; |
| break; |
| default: |
| iVTType = XFA_VT_NULL; |
| break; |
| } |
| return CXFA_LocaleValue(iVTType, pWidgetData->GetRawValue(), |
| pWidgetData->GetNode()->GetDocument()->GetLocalMgr()); |
| } |
| void XFA_GetPlainTextFromRichText(CFDE_XMLNode* pXMLNode, |
| CFX_WideString& wsPlainText) { |
| if (pXMLNode == NULL) { |
| return; |
| } |
| switch (pXMLNode->GetType()) { |
| case FDE_XMLNODE_Element: { |
| CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode); |
| CFX_WideString wsTag; |
| pXMLElement->GetLocalTagName(wsTag); |
| uint32_t uTag = FX_HashCode_String_GetW(wsTag, wsTag.GetLength(), TRUE); |
| if (uTag == 0x0001f714) { |
| wsPlainText += L"\n"; |
| } else if (uTag == 0x00000070) { |
| if (!wsPlainText.IsEmpty()) { |
| wsPlainText += L"\n"; |
| } |
| } else if (uTag == 0xa48ac63) { |
| if (!wsPlainText.IsEmpty() && |
| wsPlainText[wsPlainText.GetLength() - 1] != '\n') { |
| wsPlainText += L"\n"; |
| } |
| } |
| } break; |
| case FDE_XMLNODE_Text: { |
| CFX_WideString wsContent; |
| static_cast<CFDE_XMLText*>(pXMLNode)->GetText(wsContent); |
| wsPlainText += wsContent; |
| } break; |
| case FDE_XMLNODE_CharData: { |
| CFX_WideString wsCharData; |
| static_cast<CFDE_XMLCharData*>(pXMLNode)->GetCharData(wsCharData); |
| wsPlainText += wsCharData; |
| } break; |
| default: |
| break; |
| } |
| for (CFDE_XMLNode* pChildXML = |
| pXMLNode->GetNodeItem(CFDE_XMLNode::FirstChild); |
| pChildXML; |
| pChildXML = pChildXML->GetNodeItem(CFDE_XMLNode::NextSibling)) { |
| XFA_GetPlainTextFromRichText(pChildXML, wsPlainText); |
| } |
| } |
| FX_BOOL XFA_FieldIsMultiListBox(CXFA_Node* pFieldNode) { |
| FX_BOOL bRet = FALSE; |
| if (!pFieldNode) { |
| return bRet; |
| } |
| CXFA_Node* pUIChild = pFieldNode->GetChild(0, XFA_ELEMENT_Ui); |
| if (pUIChild) { |
| CXFA_Node* pFirstChild = pUIChild->GetNodeItem(XFA_NODEITEM_FirstChild); |
| if (pFirstChild && pFirstChild->GetClassID() == XFA_ELEMENT_ChoiceList) { |
| bRet = pFirstChild->GetEnum(XFA_ATTRIBUTE_Open) == |
| XFA_ATTRIBUTEENUM_MultiSelect; |
| } |
| } |
| return bRet; |
| } |
| FX_BOOL XFA_IsLayoutElement(XFA_ELEMENT eElement, FX_BOOL bLayoutContainer) { |
| switch (eElement) { |
| case XFA_ELEMENT_Draw: |
| case XFA_ELEMENT_Field: |
| case XFA_ELEMENT_InstanceManager: |
| return !bLayoutContainer; |
| case XFA_ELEMENT_Area: |
| case XFA_ELEMENT_Subform: |
| case XFA_ELEMENT_ExclGroup: |
| case XFA_ELEMENT_SubformSet: |
| return TRUE; |
| case XFA_ELEMENT_PageArea: |
| case XFA_ELEMENT_Form: |
| return TRUE; |
| default: |
| return FALSE; |
| } |
| return FALSE; |
| } |
| FX_BOOL XFA_IsTakingupSpace(XFA_ATTRIBUTEENUM ePresence) { |
| switch (ePresence) { |
| case XFA_ATTRIBUTEENUM_Visible: |
| case XFA_ATTRIBUTEENUM_Invisible: |
| return TRUE; |
| default: |
| return FALSE; |
| } |
| return FALSE; |
| } |
| FX_BOOL XFA_IsFlowingLayout(XFA_ATTRIBUTEENUM eLayout) { |
| switch (eLayout) { |
| case XFA_ATTRIBUTEENUM_Tb: |
| case XFA_ATTRIBUTEENUM_Lr_tb: |
| case XFA_ATTRIBUTEENUM_Rl_tb: |
| return TRUE; |
| default: |
| return FALSE; |
| } |
| return FALSE; |
| } |
| FX_BOOL XFA_IsHorizontalFlow(XFA_ATTRIBUTEENUM eLayout) { |
| switch (eLayout) { |
| case XFA_ATTRIBUTEENUM_Lr_tb: |
| case XFA_ATTRIBUTEENUM_Rl_tb: |
| return TRUE; |
| default: |
| return FALSE; |
| } |
| return FALSE; |
| } |
| static const FX_DOUBLE fraction_scales[] = {0.1, |
| 0.01, |
| 0.001, |
| 0.0001, |
| 0.00001, |
| 0.000001, |
| 0.0000001, |
| 0.00000001, |
| 0.000000001, |
| 0.0000000001, |
| 0.00000000001, |
| 0.000000000001, |
| 0.0000000000001, |
| 0.00000000000001, |
| 0.000000000000001, |
| 0.0000000000000001}; |
| FX_DOUBLE XFA_WideStringToDouble(const CFX_WideString& wsStringVal) { |
| CFX_WideString wsValue = wsStringVal; |
| wsValue.TrimLeft(); |
| wsValue.TrimRight(); |
| int64_t nIntegral = 0; |
| uint32_t dwFractional = 0; |
| int32_t nExponent = 0; |
| int32_t cc = 0; |
| FX_BOOL bNegative = FALSE, bExpSign = FALSE; |
| const FX_WCHAR* str = (const FX_WCHAR*)wsValue; |
| int32_t len = wsValue.GetLength(); |
| if (str[0] == '+') { |
| cc++; |
| } else if (str[0] == '-') { |
| bNegative = TRUE; |
| cc++; |
| } |
| int32_t nIntegralLen = 0; |
| while (cc < len) { |
| if (str[cc] == '.' || str[cc] == 'E' || str[cc] == 'e' || |
| nIntegralLen > 17) { |
| break; |
| } |
| if (!XFA_IsDigit(str[cc])) { |
| return 0; |
| } |
| nIntegral = nIntegral * 10 + str[cc] - '0'; |
| cc++; |
| nIntegralLen++; |
| } |
| nIntegral = bNegative ? -nIntegral : nIntegral; |
| int32_t scale = 0; |
| FX_DOUBLE fraction = 0.0; |
| if (cc < len && str[cc] == '.') { |
| cc++; |
| while (cc < len) { |
| fraction += fraction_scales[scale] * (str[cc] - '0'); |
| scale++; |
| cc++; |
| if (cc == len) { |
| break; |
| } |
| if (scale == sizeof(fraction_scales) / sizeof(FX_DOUBLE) || |
| str[cc] == 'E' || str[cc] == 'e') { |
| break; |
| } |
| if (!XFA_IsDigit(str[cc])) { |
| return 0; |
| } |
| } |
| dwFractional = (uint32_t)(fraction * 4294967296.0); |
| } |
| if (cc < len && (str[cc] == 'E' || str[cc] == 'e')) { |
| cc++; |
| if (cc < len) { |
| if (str[cc] == '+') { |
| cc++; |
| } else if (str[cc] == '-') { |
| bExpSign = TRUE; |
| cc++; |
| } |
| } |
| while (cc < len) { |
| if (str[cc] == '.' || !XFA_IsDigit(str[cc])) { |
| return 0; |
| } |
| nExponent = nExponent * 10 + str[cc] - '0'; |
| cc++; |
| } |
| nExponent = bExpSign ? -nExponent : nExponent; |
| } |
| FX_DOUBLE dValue = (dwFractional / 4294967296.0); |
| dValue = nIntegral + (nIntegral >= 0 ? dValue : -dValue); |
| if (nExponent != 0) { |
| dValue *= FXSYS_pow(10, (FX_FLOAT)nExponent); |
| } |
| return dValue; |
| } |
| |
| FX_DOUBLE XFA_ByteStringToDouble(const CFX_ByteStringC& szStringVal) { |
| CFX_WideString wsValue = |
| CFX_WideString::FromUTF8(szStringVal.GetCStr(), szStringVal.GetLength()); |
| return XFA_WideStringToDouble(wsValue); |
| } |
| |
| int32_t XFA_MapRotation(int32_t nRotation) { |
| nRotation = nRotation % 360; |
| nRotation = nRotation < 0 ? nRotation + 360 : nRotation; |
| return nRotation; |
| } |