diff options
Diffstat (limited to 'xfa/src/fxfa/parser/xfa_utils_imp.cpp')
-rw-r--r-- | xfa/src/fxfa/parser/xfa_utils_imp.cpp | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/xfa/src/fxfa/parser/xfa_utils_imp.cpp b/xfa/src/fxfa/parser/xfa_utils_imp.cpp new file mode 100644 index 0000000000..32f5ce125f --- /dev/null +++ b/xfa/src/fxfa/parser/xfa_utils_imp.cpp @@ -0,0 +1,403 @@ +// 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/src/fxfa/parser/xfa_utils.h" + +#include "core/include/fxcrt/fx_ext.h" +#include "xfa/src/fxfa/fm2js/xfa_fm2jsapi.h" +#include "xfa/src/fxfa/parser/xfa_docdata.h" +#include "xfa/src/fxfa/parser/xfa_doclayout.h" +#include "xfa/src/fxfa/parser/xfa_document.h" +#include "xfa/src/fxfa/parser/xfa_localemgr.h" +#include "xfa/src/fxfa/parser/xfa_localevalue.h" +#include "xfa/src/fxfa/parser/xfa_object.h" +#include "xfa/src/fxfa/parser/xfa_parser.h" +#include "xfa/src/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(IFDE_XMLNode* pXMLNode, + CFX_WideString& wsPlainText) { + if (pXMLNode == NULL) { + return; + } + switch (pXMLNode->GetType()) { + case FDE_XMLNODE_Element: { + IFDE_XMLElement* pXMLElement = (IFDE_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; + ((IFDE_XMLText*)pXMLNode)->GetText(wsContent); + wsPlainText += wsContent; + } break; + case FDE_XMLNODE_CharData: { + CFX_WideString wsCharData; + ((IFDE_XMLCharData*)pXMLNode)->GetCharData(wsCharData); + wsPlainText += wsCharData; + } break; + default: + break; + } + for (IFDE_XMLNode* pChildXML = + pXMLNode->GetNodeItem(IFDE_XMLNode::FirstChild); + pChildXML; + pChildXML = pChildXML->GetNodeItem(IFDE_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; + FX_DWORD 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 = (FX_DWORD)(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; +} |