From ed4038bc335385b7e341d8de5c2bec8db5dcdcb6 Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Mon, 22 Jan 2018 18:43:17 +0000 Subject: Move the UI elements from CXFA_WidgetAcc to CXFA_Node This CL moves the methods and members related to the UI nodes from the CXFA_WidgetAcc class to the CXFA_Node class. Change-Id: I1fdc5173787141065f1e607bbfefa3b22af738b4 Reviewed-on: https://pdfium-review.googlesource.com/23290 Reviewed-by: Henrique Nakashima Commit-Queue: dsinclair --- xfa/fxfa/parser/cxfa_node.cpp | 265 +++++++++++++++++++++--- xfa/fxfa/parser/cxfa_node.h | 7 + xfa/fxfa/parser/xfa_document_datamerger_imp.cpp | 8 +- xfa/fxfa/parser/xfa_utils.cpp | 6 +- 4 files changed, 252 insertions(+), 34 deletions(-) (limited to 'xfa/fxfa/parser') diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp index 1d2af4c858..935392373a 100644 --- a/xfa/fxfa/parser/cxfa_node.cpp +++ b/xfa/fxfa/parser/cxfa_node.cpp @@ -40,6 +40,7 @@ #include "xfa/fxfa/parser/cxfa_document.h" #include "xfa/fxfa/parser/cxfa_event.h" #include "xfa/fxfa/parser/cxfa_font.h" +#include "xfa/fxfa/parser/cxfa_items.h" #include "xfa/fxfa/parser/cxfa_keep.h" #include "xfa/fxfa/parser/cxfa_layoutprocessor.h" #include "xfa/fxfa/parser/cxfa_localevalue.h" @@ -49,8 +50,10 @@ #include "xfa/fxfa/parser/cxfa_occur.h" #include "xfa/fxfa/parser/cxfa_para.h" #include "xfa/fxfa/parser/cxfa_simple_parser.h" +#include "xfa/fxfa/parser/cxfa_stroke.h" #include "xfa/fxfa/parser/cxfa_subform.h" #include "xfa/fxfa/parser/cxfa_traversestrategy_xfacontainernode.h" +#include "xfa/fxfa/parser/cxfa_ui.h" #include "xfa/fxfa/parser/cxfa_validate.h" #include "xfa/fxfa/parser/cxfa_value.h" #include "xfa/fxfa/parser/xfa_basic_data.h" @@ -150,6 +153,170 @@ void ReorderDataNodes(const std::set& sSet1, } } +std::pair CreateUIChild(CXFA_Node* pNode) { + XFA_Element eType = pNode->GetElementType(); + XFA_Element eWidgetType = eType; + if (eType != XFA_Element::Field && eType != XFA_Element::Draw) + return {eWidgetType, nullptr}; + + eWidgetType = XFA_Element::Unknown; + XFA_Element eUIType = XFA_Element::Unknown; + auto* defValue = + pNode->JSObject()->GetOrCreateProperty(0, XFA_Element::Value); + XFA_Element eValueType = + defValue ? defValue->GetChildValueClassID() : XFA_Element::Unknown; + 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 = nullptr; + CXFA_Ui* pUI = + pNode->JSObject()->GetOrCreateProperty(0, XFA_Element::Ui); + CXFA_Node* pChild = pUI ? pUI->GetFirstChild() : nullptr; + for (; pChild; pChild = pChild->GetNextSibling()) { + XFA_Element eChildType = pChild->GetElementType(); + if (eChildType == XFA_Element::Extras || + eChildType == XFA_Element::Picture) { + continue; + } + + auto node = CXFA_Node::Create(pChild->GetDocument(), XFA_Element::Ui, + XFA_PacketType::Form); + if (node && node->HasPropertyFlags(eChildType, XFA_PROPERTYFLAG_OneOf)) { + pUIChild = pChild; + break; + } + } + + if (eType == XFA_Element::Draw) { + XFA_Element eDraw = + pUIChild ? pUIChild->GetElementType() : 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->GetElementType() == XFA_Element::DefaultUi) { + eWidgetType = XFA_Element::TextEdit; + } else { + eWidgetType = + pUIChild ? pUIChild->GetElementType() + : (eUIType == XFA_Element::Unknown ? XFA_Element::TextEdit + : eUIType); + } + } + + if (!pUIChild) { + if (eUIType == XFA_Element::Unknown) { + eUIType = XFA_Element::TextEdit; + if (defValue) { + defValue->JSObject()->GetOrCreateProperty(0, + XFA_Element::Text); + } + } + return {eWidgetType, + pUI ? pUI->JSObject()->GetOrCreateProperty(0, eUIType) + : nullptr}; + } + + if (eUIType != XFA_Element::Unknown) + return {eWidgetType, pUIChild}; + + switch (pUIChild->GetElementType()) { + case XFA_Element::CheckButton: { + eValueType = XFA_Element::Text; + if (CXFA_Items* pItems = + pNode->GetChild(0, XFA_Element::Items, false)) { + if (CXFA_Node* pItem = + pItems->GetChild(0, XFA_Element::Unknown, false)) { + eValueType = pItem->GetElementType(); + } + } + 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->JSObject()->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; + } + if (defValue) + defValue->JSObject()->GetOrCreateProperty(0, eValueType); + + return {eWidgetType, pUIChild}; +} + +float GetEdgeThickness(const std::vector& strokes, + bool b3DStyle, + int32_t nIndex) { + float fThickness = 0; + + CXFA_Stroke* stroke = strokes[nIndex * 2 + 1]; + if (stroke->IsVisible()) { + if (nIndex == 0) + fThickness += 2.5f; + + fThickness += stroke->GetThickness() * (b3DStyle ? 4 : 2); + } + return fThickness; +} + } // namespace // static @@ -2059,7 +2226,7 @@ std::pair CXFA_Node::ExecuteBoolScript( } WideString CXFA_Node::GetBarcodeType() { - CXFA_Node* pUIChild = GetWidgetAcc()->GetUIChild(); + CXFA_Node* pUIChild = GetUIChild(); return pUIChild ? WideString(pUIChild->JSObject()->GetCData(XFA_Attribute::Type)) : WideString(); @@ -2067,8 +2234,7 @@ WideString CXFA_Node::GetBarcodeType() { Optional CXFA_Node::GetBarcodeAttribute_CharEncoding() { Optional wsCharEncoding = - GetWidgetAcc()->GetUIChild()->JSObject()->TryCData( - XFA_Attribute::CharEncoding, true); + GetUIChild()->JSObject()->TryCData(XFA_Attribute::CharEncoding, true); if (!wsCharEncoding) return {}; if (wsCharEncoding->CompareNoCase(L"UTF-16")) @@ -2080,8 +2246,7 @@ Optional CXFA_Node::GetBarcodeAttribute_CharEncoding() { Optional CXFA_Node::GetBarcodeAttribute_Checksum() { Optional checksum = - GetWidgetAcc()->GetUIChild()->JSObject()->TryEnum(XFA_Attribute::Checksum, - true); + GetUIChild()->JSObject()->TryEnum(XFA_Attribute::Checksum, true); if (!checksum) return {}; @@ -2101,8 +2266,7 @@ Optional CXFA_Node::GetBarcodeAttribute_Checksum() { Optional CXFA_Node::GetBarcodeAttribute_DataLength() { Optional wsDataLength = - GetWidgetAcc()->GetUIChild()->JSObject()->TryCData( - XFA_Attribute::DataLength, true); + GetUIChild()->JSObject()->TryCData(XFA_Attribute::DataLength, true); if (!wsDataLength) return {}; @@ -2111,8 +2275,7 @@ Optional CXFA_Node::GetBarcodeAttribute_DataLength() { Optional CXFA_Node::GetBarcodeAttribute_StartChar() { Optional wsStartEndChar = - GetWidgetAcc()->GetUIChild()->JSObject()->TryCData( - XFA_Attribute::StartChar, true); + GetUIChild()->JSObject()->TryCData(XFA_Attribute::StartChar, true); if (!wsStartEndChar || wsStartEndChar->IsEmpty()) return {}; @@ -2121,8 +2284,7 @@ Optional CXFA_Node::GetBarcodeAttribute_StartChar() { Optional CXFA_Node::GetBarcodeAttribute_EndChar() { Optional wsStartEndChar = - GetWidgetAcc()->GetUIChild()->JSObject()->TryCData(XFA_Attribute::EndChar, - true); + GetUIChild()->JSObject()->TryCData(XFA_Attribute::EndChar, true); if (!wsStartEndChar || wsStartEndChar->IsEmpty()) return {}; @@ -2130,9 +2292,8 @@ Optional CXFA_Node::GetBarcodeAttribute_EndChar() { } Optional CXFA_Node::GetBarcodeAttribute_ECLevel() { - Optional wsECLevel = - GetWidgetAcc()->GetUIChild()->JSObject()->TryCData( - XFA_Attribute::ErrorCorrectionLevel, true); + Optional wsECLevel = GetUIChild()->JSObject()->TryCData( + XFA_Attribute::ErrorCorrectionLevel, true); if (!wsECLevel) return {}; return {FXSYS_wtoi(wsECLevel->c_str())}; @@ -2140,8 +2301,7 @@ Optional CXFA_Node::GetBarcodeAttribute_ECLevel() { Optional CXFA_Node::GetBarcodeAttribute_ModuleWidth() { Optional moduleWidthHeight = - GetWidgetAcc()->GetUIChild()->JSObject()->TryMeasure( - XFA_Attribute::ModuleWidth, true); + GetUIChild()->JSObject()->TryMeasure(XFA_Attribute::ModuleWidth, true); if (!moduleWidthHeight) return {}; @@ -2150,8 +2310,7 @@ Optional CXFA_Node::GetBarcodeAttribute_ModuleWidth() { Optional CXFA_Node::GetBarcodeAttribute_ModuleHeight() { Optional moduleWidthHeight = - GetWidgetAcc()->GetUIChild()->JSObject()->TryMeasure( - XFA_Attribute::ModuleHeight, true); + GetUIChild()->JSObject()->TryMeasure(XFA_Attribute::ModuleHeight, true); if (!moduleWidthHeight) return {}; @@ -2159,14 +2318,13 @@ Optional CXFA_Node::GetBarcodeAttribute_ModuleHeight() { } Optional CXFA_Node::GetBarcodeAttribute_PrintChecksum() { - return GetWidgetAcc()->GetUIChild()->JSObject()->TryBoolean( - XFA_Attribute::PrintCheckDigit, true); + return GetUIChild()->JSObject()->TryBoolean(XFA_Attribute::PrintCheckDigit, + true); } Optional CXFA_Node::GetBarcodeAttribute_TextLocation() { Optional textLocation = - GetWidgetAcc()->GetUIChild()->JSObject()->TryEnum( - XFA_Attribute::TextLocation, true); + GetUIChild()->JSObject()->TryEnum(XFA_Attribute::TextLocation, true); if (!textLocation) return {}; @@ -2188,14 +2346,12 @@ Optional CXFA_Node::GetBarcodeAttribute_TextLocation() { } Optional CXFA_Node::GetBarcodeAttribute_Truncate() { - return GetWidgetAcc()->GetUIChild()->JSObject()->TryBoolean( - XFA_Attribute::Truncate, true); + return GetUIChild()->JSObject()->TryBoolean(XFA_Attribute::Truncate, true); } Optional CXFA_Node::GetBarcodeAttribute_WideNarrowRatio() { Optional wsWideNarrowRatio = - GetWidgetAcc()->GetUIChild()->JSObject()->TryCData( - XFA_Attribute::WideNarrowRatio, true); + GetUIChild()->JSObject()->TryCData(XFA_Attribute::WideNarrowRatio, true); if (!wsWideNarrowRatio) return {}; @@ -2213,3 +2369,60 @@ Optional CXFA_Node::GetBarcodeAttribute_WideNarrowRatio() { float result = static_cast(fA) / static_cast(fB); return {static_cast(result)}; } + +CXFA_Node* CXFA_Node::GetUIChild() { + if (m_eUIType == XFA_Element::Unknown) + std::tie(m_eUIType, m_pUiChildNode) = CreateUIChild(this); + return m_pUiChildNode; +} + +XFA_Element CXFA_Node::GetUIType() { + GetUIChild(); + return m_eUIType; +} + +CXFA_Border* CXFA_Node::GetUIBorder() { + CXFA_Node* pUIChild = GetUIChild(); + return pUIChild ? pUIChild->JSObject()->GetProperty( + 0, XFA_Element::Border) + : nullptr; +} + +CFX_RectF CXFA_Node::GetUIMargin() { + CXFA_Node* pUIChild = GetUIChild(); + if (!pUIChild) + return CFX_RectF(); + + CXFA_Margin* mgUI = + pUIChild->JSObject()->GetProperty(0, XFA_Element::Margin); + if (!mgUI) + return CFX_RectF(); + + CXFA_Border* border = GetUIBorder(); + if (border && border->GetPresence() != XFA_AttributeEnum::Visible) + return CFX_RectF(); + + Optional left = mgUI->TryLeftInset(); + Optional top = mgUI->TryTopInset(); + Optional right = mgUI->TryRightInset(); + Optional bottom = mgUI->TryBottomInset(); + if (border) { + bool bVisible = false; + float fThickness = 0; + XFA_AttributeEnum iType = XFA_AttributeEnum::Unknown; + std::tie(iType, bVisible, fThickness) = border->Get3DStyle(); + if (!left || !top || !right || !bottom) { + std::vector strokes = border->GetStrokes(); + if (!top) + top = GetEdgeThickness(strokes, bVisible, 0); + if (!right) + right = GetEdgeThickness(strokes, bVisible, 1); + if (!bottom) + bottom = GetEdgeThickness(strokes, bVisible, 2); + if (!left) + left = GetEdgeThickness(strokes, bVisible, 3); + } + } + return CFX_RectF(left.value_or(0.0), top.value_or(0.0), right.value_or(0.0), + bottom.value_or(0.0)); +} diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h index c08a9affdd..4fae752ea0 100644 --- a/xfa/fxfa/parser/cxfa_node.h +++ b/xfa/fxfa/parser/cxfa_node.h @@ -294,6 +294,11 @@ class CXFA_Node : public CXFA_Object { Optional GetBarcodeAttribute_Truncate(); Optional GetBarcodeAttribute_WideNarrowRatio(); + CXFA_Node* GetUIChild(); + XFA_Element GetUIType(); + CFX_RectF GetUIMargin(); + CXFA_Border* GetUIBorder(); + protected: CXFA_Node(CXFA_Document* pDoc, XFA_PacketType ePacket, @@ -357,6 +362,8 @@ class CXFA_Node : public CXFA_Object { uint32_t m_dwNameHash; CXFA_Node* m_pAuxNode; std::vector> binding_nodes_; + CXFA_Node* m_pUiChildNode = nullptr; + XFA_Element m_eUIType = XFA_Element::Unknown; }; #endif // XFA_FXFA_PARSER_CXFA_NODE_H_ diff --git a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp index 422ba4e58a..05846f2e3f 100644 --- a/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp +++ b/xfa/fxfa/parser/xfa_document_datamerger_imp.cpp @@ -71,7 +71,8 @@ CXFA_Node* FormValueNode_CreateChild(CXFA_Node* pValueNode, XFA_Element iType) { void FormValueNode_MatchNoneCreateChild(CXFA_Node* pFormNode) { ASSERT(pFormNode->IsWidgetReady()); - pFormNode->GetWidgetAcc()->GetUIType(); + // GetUIChild has the side effect of creating the UI child. + pFormNode->GetUIChild(); } bool FormValueNode_SetChildContent(CXFA_Node* pValueNode, @@ -133,12 +134,11 @@ void CreateDataBinding(CXFA_Node* pFormNode, ASSERT(pFormNode->IsWidgetReady()); CXFA_WidgetAcc* pWidgetAcc = pFormNode->GetWidgetAcc(); - XFA_Element eUIType = pWidgetAcc->GetUIType(); auto* defValue = pFormNode->JSObject()->GetOrCreateProperty( 0, XFA_Element::Value); if (!bDataToForm) { WideString wsValue; - switch (eUIType) { + switch (pFormNode->GetUIType()) { case XFA_Element::ImageEdit: { CXFA_Image* image = defValue ? defValue->GetImageIfExists() : nullptr; WideString wsContentType; @@ -289,7 +289,7 @@ void CreateDataBinding(CXFA_Node* pFormNode, pDataNode->JSObject()->SetAttributeValue(wsNormalizeValue, wsXMLValue, false, false); - switch (eUIType) { + switch (pFormNode->GetUIType()) { case XFA_Element::ImageEdit: { FormValueNode_SetChildContent(defValue, wsNormalizeValue, XFA_Element::Image); diff --git a/xfa/fxfa/parser/xfa_utils.cpp b/xfa/fxfa/parser/xfa_utils.cpp index 5d2f222a3b..226aaed83b 100644 --- a/xfa/fxfa/parser/xfa_utils.cpp +++ b/xfa/fxfa/parser/xfa_utils.cpp @@ -142,11 +142,9 @@ bool ContentNodeNeedtoExport(CXFA_Node* pContentNode) { CXFA_Node* pGrandParentNode = pParentNode->GetParent(); if (!pGrandParentNode || !pGrandParentNode->IsContainerNode()) return true; - if (pGrandParentNode->GetBindData()) + if (!pGrandParentNode->GetBindData()) return false; - - XFA_Element eUIType = pGrandParentNode->GetWidgetAcc()->GetUIType(); - if (eUIType == XFA_Element::PasswordEdit) + if (pGrandParentNode->GetUIType() == XFA_Element::PasswordEdit) return false; return true; } -- cgit v1.2.3