1 // Copyright 2017 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 #ifndef XFA_FXFA_PARSER_CXFA_NODE_H_ 8 #define XFA_FXFA_PARSER_CXFA_NODE_H_ 9 10 #include <memory> 11 #include <utility> 12 #include <vector> 13 14 #include "core/fxcrt/fx_string.h" 15 #include "core/fxcrt/tree_node.h" 16 #include "core/fxge/fx_dib.h" 17 #include "third_party/base/optional.h" 18 #include "third_party/base/span.h" 19 #include "xfa/fxfa/cxfa_ffwidget_type.h" 20 #include "xfa/fxfa/fxfa.h" 21 #include "xfa/fxfa/parser/cxfa_object.h" 22 23 class CFGAS_GEFont; 24 class CFX_DIBitmap; 25 class CFX_XMLDocument; 26 class CFX_XMLNode; 27 class CXFA_Bind; 28 class CXFA_Border; 29 class CXFA_Calculate; 30 class CXFA_Caption; 31 class CXFA_Event; 32 class CXFA_EventParam; 33 class CXFA_FFDoc; 34 class CXFA_FFDocView; 35 class CXFA_Font; 36 class CXFA_Keep; 37 class CXFA_Margin; 38 class CXFA_Occur; 39 class CXFA_Para; 40 class CXFA_Script; 41 class CXFA_TextLayout; 42 class CXFA_Ui; 43 class CXFA_Validate; 44 class CXFA_Value; 45 class CXFA_WidgetLayoutData; 46 class LocaleIface; 47 48 #define XFA_NODEFILTER_Children 0x01 49 #define XFA_NODEFILTER_Properties 0x02 50 #define XFA_NODEFILTER_OneOfProperty 0x04 51 52 enum XFA_CHECKSTATE { 53 XFA_CHECKSTATE_On = 0, 54 XFA_CHECKSTATE_Off = 1, 55 XFA_CHECKSTATE_Neutral = 2, 56 }; 57 58 enum XFA_VALUEPICTURE { 59 XFA_VALUEPICTURE_Raw = 0, 60 XFA_VALUEPICTURE_Display, 61 XFA_VALUEPICTURE_Edit, 62 XFA_VALUEPICTURE_DataBind, 63 }; 64 65 enum XFA_NodeFlag { 66 XFA_NodeFlag_None = 0, 67 XFA_NodeFlag_Initialized = 1 << 0, 68 XFA_NodeFlag_HasRemovedChildren = 1 << 1, 69 XFA_NodeFlag_NeedsInitApp = 1 << 2, 70 XFA_NodeFlag_BindFormItems = 1 << 3, 71 XFA_NodeFlag_UserInteractive = 1 << 4, 72 XFA_NodeFlag_UnusedNode = 1 << 5, 73 XFA_NodeFlag_LayoutGeneratedNode = 1 << 6 74 }; 75 76 class CXFA_Node : public CXFA_Object, public TreeNode<CXFA_Node> { 77 public: 78 struct PropertyData { 79 XFA_Element property; 80 uint8_t occurance_count; 81 uint8_t flags; 82 }; 83 84 struct AttributeData { 85 XFA_Attribute attribute; 86 XFA_AttributeType type; 87 void* default_value; 88 }; 89 90 static std::unique_ptr<CXFA_Node> Create(CXFA_Document* doc, 91 XFA_Element element, 92 XFA_PacketType packet); 93 94 ~CXFA_Node() override; 95 96 bool HasProperty(XFA_Element property) const; 97 bool HasPropertyFlags(XFA_Element property, uint8_t flags) const; 98 uint8_t PropertyOccuranceCount(XFA_Element property) const; 99 100 std::pair<CXFA_Node*, int32_t> GetProperty(int32_t index, 101 XFA_Element eProperty) const; 102 CXFA_Node* GetOrCreateProperty(int32_t index, XFA_Element eProperty); 103 104 void SendAttributeChangeMessage(XFA_Attribute eAttribute, bool bScriptModify); 105 106 bool HasAttribute(XFA_Attribute attr) const; 107 XFA_AttributeType GetAttributeType(XFA_Attribute type) const; 108 109 // Note: returns XFA_Attribute::Unknown for invalid indicies. 110 XFA_Attribute GetAttribute(size_t i) const; 111 GetPacketType()112 XFA_PacketType GetPacketType() const { return m_ePacket; } 113 114 void SetFlag(uint32_t dwFlag); 115 void SetFlagAndNotify(uint32_t dwFlag); 116 void ClearFlag(uint32_t dwFlag); 117 118 CXFA_Node* CreateInstanceIfPossible(bool bDataMerge); 119 int32_t GetCount(); 120 CXFA_Node* GetItemIfExists(int32_t iIndex); 121 void RemoveItem(CXFA_Node* pRemoveInstance, bool bRemoveDataBinding); 122 void InsertItem(CXFA_Node* pNewInstance, 123 int32_t iPos, 124 int32_t iCount, 125 bool bMoveDataBindingNodes); 126 IsInitialized()127 bool IsInitialized() const { return HasFlag(XFA_NodeFlag_Initialized); } IsUserInteractive()128 bool IsUserInteractive() const { 129 return HasFlag(XFA_NodeFlag_UserInteractive); 130 } IsUnusedNode()131 bool IsUnusedNode() const { return HasFlag(XFA_NodeFlag_UnusedNode); } IsLayoutGeneratedNode()132 bool IsLayoutGeneratedNode() const { 133 return HasFlag(XFA_NodeFlag_LayoutGeneratedNode); 134 } 135 136 bool PresenceRequiresSpace() const; 137 void SetBindingNode(CXFA_Node* node); 138 void SetNodeAndDescendantsUnused(); 139 HasRemovedChildren()140 bool HasRemovedChildren() const { 141 return HasFlag(XFA_NodeFlag_HasRemovedChildren); 142 } 143 144 bool IsAttributeInXML(); IsFormContainer()145 bool IsFormContainer() const { 146 return m_ePacket == XFA_PacketType::Form && IsContainerNode(); 147 } 148 SetXMLMappingNode(CFX_XMLNode * node)149 void SetXMLMappingNode(CFX_XMLNode* node) { xml_node_ = node; } GetXMLMappingNode()150 CFX_XMLNode* GetXMLMappingNode() const { return xml_node_.Get(); } 151 CFX_XMLNode* CreateXMLMappingNode(); 152 bool IsNeedSavingXMLNode() const; 153 154 void SetToXML(const WideString& value); 155 GetNameHash()156 uint32_t GetNameHash() const { return m_dwNameHash; } IsUnnamed()157 bool IsUnnamed() const { return m_dwNameHash == 0; } 158 CXFA_Node* GetModelNode(); 159 void UpdateNameHash(); 160 161 size_t CountChildren(XFA_Element eType, bool bOnlyChild); 162 163 template <typename T> GetChild(size_t index,XFA_Element eType,bool bOnlyChild)164 T* GetChild(size_t index, XFA_Element eType, bool bOnlyChild) { 165 return static_cast<T*>(GetChildInternal(index, eType, bOnlyChild)); 166 } 167 168 void InsertChildAndNotify(int32_t index, CXFA_Node* pNode); 169 void InsertChildAndNotify(CXFA_Node* pNode, CXFA_Node* pBeforeNode); 170 void RemoveChildAndNotify(CXFA_Node* pNode, bool bNotify); 171 172 CXFA_Node* Clone(bool bRecursive); 173 174 CXFA_Node* GetNextContainerSibling() const; 175 CXFA_Node* GetPrevContainerSibling() const; 176 CXFA_Node* GetFirstContainerChild() const; 177 CXFA_Node* GetContainerParent() const; 178 179 std::vector<CXFA_Node*> GetNodeListForType(XFA_Element eTypeFilter); 180 std::vector<CXFA_Node*> GetNodeListWithFilter(uint32_t dwTypeFilter); 181 CXFA_Node* CreateSamePacketNode(XFA_Element eType); 182 CXFA_Node* CloneTemplateToForm(bool bRecursive); 183 CXFA_Node* GetTemplateNodeIfExists() const; 184 void SetTemplateNode(CXFA_Node* pTemplateNode); 185 CXFA_Node* GetDataDescriptionNode(); 186 void SetDataDescriptionNode(CXFA_Node* pDataDescriptionNode); 187 CXFA_Node* GetBindData(); HasBindItems()188 bool HasBindItems() const { return !binding_nodes_.empty(); } GetBindItemsCopy()189 std::vector<CXFA_Node*> GetBindItemsCopy() { return binding_nodes_; } 190 int32_t AddBindItem(CXFA_Node* pFormNode); 191 int32_t RemoveBindItem(CXFA_Node* pFormNode); 192 bool HasBindItem() const; 193 CXFA_Node* GetContainerNode(); 194 LocaleIface* GetLocale(); 195 Optional<WideString> GetLocaleName(); 196 XFA_AttributeValue GetIntact(); 197 WideString GetNameExpression(); 198 199 CXFA_Node* GetFirstChildByName(WideStringView wsNodeName) const; 200 CXFA_Node* GetFirstChildByName(uint32_t dwNodeNameHash) const; 201 template <typename T> GetFirstChildByClass(XFA_Element eType)202 T* GetFirstChildByClass(XFA_Element eType) const { 203 return static_cast<T*>(GetFirstChildByClassInternal(eType)); 204 } 205 CXFA_Node* GetNextSameNameSibling(uint32_t dwNodeNameHash) const; 206 template <typename T> GetNextSameNameSibling(WideStringView wsNodeName)207 T* GetNextSameNameSibling(WideStringView wsNodeName) const { 208 return static_cast<T*>(GetNextSameNameSiblingInternal(wsNodeName)); 209 } 210 template <typename T> GetNextSameClassSibling(XFA_Element eType)211 T* GetNextSameClassSibling(XFA_Element eType) const { 212 return static_cast<T*>(GetNextSameClassSiblingInternal(eType)); 213 } 214 215 CXFA_Node* GetOneChildNamed(WideStringView wsName); 216 CXFA_Node* GetOneChildOfClass(WideStringView wsClass); 217 218 std::vector<CXFA_Node*> GetSiblings(bool bIsClassName); 219 size_t GetIndex(bool bIsProperty, bool bIsClassIndex); 220 size_t GetIndexByName(); 221 size_t GetIndexByClassName(); 222 223 CXFA_Node* GetInstanceMgrOfSubform(); 224 225 Optional<bool> GetDefaultBoolean(XFA_Attribute attr) const; 226 Optional<int32_t> GetDefaultInteger(XFA_Attribute attr) const; 227 Optional<CXFA_Measurement> GetDefaultMeasurement(XFA_Attribute attr) const; 228 Optional<WideString> GetDefaultCData(XFA_Attribute attr) const; 229 Optional<XFA_AttributeValue> GetDefaultEnum(XFA_Attribute attr) const; 230 231 bool IsOpenAccess() const; 232 233 CXFA_Occur* GetOccurIfExists(); 234 CXFA_Border* GetBorderIfExists() const; 235 CXFA_Border* GetOrCreateBorderIfPossible(); 236 CXFA_Caption* GetCaptionIfExists() const; 237 CXFA_Font* GetFontIfExists() const; 238 CXFA_Font* GetOrCreateFontIfPossible(); 239 240 float GetFontSize() const; 241 FX_ARGB GetTextColor() const; 242 float GetLineHeight() const; 243 244 CXFA_Margin* GetMarginIfExists() const; 245 CXFA_Para* GetParaIfExists() const; 246 CXFA_Calculate* GetCalculateIfExists() const; 247 CXFA_Validate* GetValidateIfExists() const; 248 CXFA_Validate* GetOrCreateValidateIfPossible(); 249 250 CXFA_Value* GetFormValueIfExists() const; 251 WideString GetRawValue(); 252 253 int32_t GetRotate() const; 254 Optional<float> TryWidth(); 255 256 CXFA_Node* GetExclGroupIfExists(); 257 258 XFA_EventError ProcessEvent(CXFA_FFDocView* pDocView, 259 XFA_AttributeValue iActivity, 260 CXFA_EventParam* pEventParam); 261 XFA_EventError ProcessCalculate(CXFA_FFDocView* pDocView); 262 XFA_EventError ProcessValidate(CXFA_FFDocView* pDocView, int32_t iFlags); 263 XFA_EventError ExecuteScript(CXFA_FFDocView* pDocView, 264 CXFA_Script* script, 265 CXFA_EventParam* pEventParam); 266 std::pair<XFA_EventError, bool> ExecuteBoolScript( 267 CXFA_FFDocView* pDocView, 268 CXFA_Script* script, 269 CXFA_EventParam* pEventParam); 270 271 CXFA_Node* GetUIChildNode(); 272 273 // NOTE: value returned is often determined by child UI node, and 274 // can't be used to infer anything about this particual node itself. 275 XFA_FFWidgetType GetFFWidgetType(); 276 277 CFX_RectF GetUIMargin(); 278 CXFA_Border* GetUIBorder(); 279 SetPreNull(bool val)280 void SetPreNull(bool val) { m_bPreNull = val; } IsNull()281 bool IsNull() const { return m_bIsNull; } SetIsNull(bool val)282 void SetIsNull(bool val) { m_bIsNull = val; } 283 SetWidgetReady()284 void SetWidgetReady() { is_widget_ready_ = true; } IsWidgetReady()285 bool IsWidgetReady() const { return is_widget_ready_; } 286 std::vector<CXFA_Event*> GetEventByActivity(XFA_AttributeValue iActivity, 287 bool bIsFormReady); 288 289 void ResetData(); 290 void StartWidgetLayout(CXFA_FFDoc* doc, 291 float* pCalcWidth, 292 float* pCalcHeight); 293 Optional<float> FindSplitPos(CXFA_FFDocView* pDocView, 294 size_t szBlockIndex, 295 float fCalcHeight); 296 297 bool LoadCaption(CXFA_FFDoc* doc); 298 CXFA_TextLayout* GetCaptionTextLayout(); 299 CXFA_TextLayout* GetTextLayout(); 300 301 bool LoadImageImage(CXFA_FFDoc* doc); 302 bool LoadImageEditImage(CXFA_FFDoc* doc); 303 CFX_Size GetImageDpi() const; 304 CFX_Size GetImageEditDpi() const; 305 306 RetainPtr<CFX_DIBitmap> GetImageImage(); 307 RetainPtr<CFX_DIBitmap> GetImageEditImage(); 308 void SetImageImage(const RetainPtr<CFX_DIBitmap>& newImage); 309 void SetImageEditImage(const RetainPtr<CFX_DIBitmap>& newImage); 310 311 RetainPtr<CFGAS_GEFont> GetFDEFont(CXFA_FFDoc* doc); 312 313 bool IsListBox(); 314 bool IsRadioButton(); 315 bool IsMultiLine(); 316 317 bool HasButtonRollover(); 318 bool HasButtonDown(); 319 320 float GetCheckButtonSize(); 321 322 XFA_CHECKSTATE GetCheckState(); 323 void SetCheckState(XFA_CHECKSTATE eCheckState, bool bNotify); 324 325 CXFA_Node* GetSelectedMember(); 326 CXFA_Node* SetSelectedMember(WideStringView wsName, bool bNotify); 327 void SetSelectedMemberByValue(WideStringView wsValue, 328 bool bNotify, 329 bool bScriptModify, 330 bool bSyncData); 331 332 CXFA_Node* GetExclGroupFirstMember(); 333 CXFA_Node* GetExclGroupNextMember(CXFA_Node* pNode); 334 335 bool IsChoiceListAllowTextEntry(); 336 int32_t CountChoiceListItems(bool bSaveValue); 337 Optional<WideString> GetChoiceListItem(int32_t nIndex, bool bSaveValue); 338 bool IsChoiceListMultiSelect(); 339 bool IsChoiceListCommitOnSelect(); 340 std::vector<WideString> GetChoiceListItems(bool bSaveValue); 341 342 int32_t CountSelectedItems(); 343 int32_t GetSelectedItem(int32_t nIndex); 344 std::vector<int32_t> GetSelectedItems(); 345 std::vector<WideString> GetSelectedItemsValue(); 346 void SetSelectedItems(const std::vector<int32_t>& iSelArray, 347 bool bNotify, 348 bool bScriptModify, 349 bool bSyncData); 350 void InsertItem(const WideString& wsLabel, 351 const WideString& wsValue, 352 bool bNotify); 353 bool DeleteItem(int32_t nIndex, bool bNotify, bool bScriptModify); 354 void ClearAllSelections(); 355 356 bool GetItemState(int32_t nIndex); 357 void SetItemState(int32_t nIndex, 358 bool bSelected, 359 bool bNotify, 360 bool bScriptModify, 361 bool bSyncData); 362 363 WideString GetItemValue(WideStringView wsLabel); 364 365 bool IsHorizontalScrollPolicyOff(); 366 bool IsVerticalScrollPolicyOff(); 367 Optional<int32_t> GetNumberOfCells(); 368 369 bool SetValue(XFA_VALUEPICTURE eValueType, const WideString& wsValue); 370 WideString GetValue(XFA_VALUEPICTURE eValueType); 371 372 WideString GetPictureContent(XFA_VALUEPICTURE ePicture); 373 WideString GetNormalizeDataValue(const WideString& wsValue); 374 WideString GetFormatDataValue(const WideString& wsValue); 375 WideString NormalizeNumStr(const WideString& wsValue); 376 377 std::pair<XFA_Element, int32_t> GetMaxChars(); 378 int32_t GetFracDigits(); 379 int32_t GetLeadDigits(); 380 381 WideString NumericLimit(const WideString& wsValue); 382 383 bool IsTransparent() const; 384 bool IsProperty() const; 385 386 protected: 387 CXFA_Node(CXFA_Document* pDoc, 388 XFA_PacketType ePacket, 389 uint32_t validPackets, 390 XFA_ObjectType oType, 391 XFA_Element eType, 392 pdfium::span<const PropertyData> properties, 393 pdfium::span<const AttributeData> attributes, 394 std::unique_ptr<CJX_Object> js_object); 395 396 virtual XFA_Element GetValueNodeType() const; 397 virtual XFA_FFWidgetType GetDefaultFFWidgetType() const; 398 399 private: 400 void ProcessScriptTestValidate(CXFA_FFDocView* pDocView, 401 CXFA_Validate* validate, 402 XFA_EventError iRet, 403 bool pRetValue, 404 bool bVersionFlag); 405 XFA_EventError ProcessFormatTestValidate(CXFA_FFDocView* pDocView, 406 CXFA_Validate* validate, 407 bool bVersionFlag); 408 XFA_EventError ProcessNullTestValidate(CXFA_FFDocView* pDocView, 409 CXFA_Validate* validate, 410 int32_t iFlags, 411 bool bVersionFlag); 412 WideString GetValidateCaptionName(bool bVersionFlag); 413 WideString GetValidateMessage(bool bError, bool bVersionFlag); 414 415 bool HasFlag(XFA_NodeFlag dwFlag) const; 416 const PropertyData* GetPropertyData(XFA_Element property) const; 417 const AttributeData* GetAttributeData(XFA_Attribute attr) const; 418 Optional<XFA_Element> GetFirstPropertyWithFlag(uint8_t flag) const; 419 void OnRemoved(bool bNotify) const; 420 Optional<void*> GetDefaultValue(XFA_Attribute attr, 421 XFA_AttributeType eType) const; 422 CXFA_Node* GetChildInternal(size_t index, 423 XFA_Element eType, 424 bool bOnlyChild) const; 425 CXFA_Node* GetFirstChildByClassInternal(XFA_Element eType) const; 426 CXFA_Node* GetNextSameNameSiblingInternal(WideStringView wsNodeName) const; 427 CXFA_Node* GetNextSameClassSiblingInternal(XFA_Element eType) const; 428 void CalcCaptionSize(CXFA_FFDoc* doc, CFX_SizeF* pszCap); 429 bool CalculateFieldAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize); 430 bool CalculateWidgetAutoSize(CFX_SizeF* pSize); 431 bool CalculateTextEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize); 432 bool CalculateCheckButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize); 433 bool CalculatePushButtonAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize); 434 CFX_SizeF CalculateImageSize(float img_width, 435 float img_height, 436 const CFX_Size& dpi); 437 bool CalculateImageEditAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize); 438 bool CalculateImageAutoSize(CXFA_FFDoc* doc, CFX_SizeF* pSize); 439 float CalculateWidgetAutoHeight(float fHeightCalc); 440 float CalculateWidgetAutoWidth(float fWidthCalc); 441 float GetWidthWithoutMargin(float fWidthCalc) const; 442 float GetHeightWithoutMargin(float fHeightCalc) const; 443 void CalculateTextContentSize(CXFA_FFDoc* doc, CFX_SizeF* pSize); 444 CFX_SizeF CalculateAccWidthAndHeight(CXFA_FFDoc* doc, float fWidth); 445 void InitLayoutData(); 446 void StartTextLayout(CXFA_FFDoc* doc, float* pCalcWidth, float* pCalcHeight); 447 448 void InsertListTextItem(CXFA_Node* pItems, 449 const WideString& wsText, 450 int32_t nIndex); 451 WideString GetItemLabel(WideStringView wsValue) const; 452 453 std::pair<XFA_FFWidgetType, CXFA_Ui*> CreateChildUIAndValueNodesIfNeeded(); 454 void CreateValueNodeIfNeeded(CXFA_Value* value, CXFA_Node* pUIChild); 455 CXFA_Node* CreateUINodeIfNeeded(CXFA_Ui* ui, XFA_Element type); 456 bool IsValidInPacket(XFA_PacketType packet) const; 457 void SetImageEdit(const WideString& wsContentType, 458 const WideString& wsHref, 459 const WideString& wsData); GetBindingNode()460 CXFA_Node* GetBindingNode() const { 461 if (binding_nodes_.empty()) 462 return nullptr; 463 return binding_nodes_[0]; 464 } BindsFormItems()465 bool BindsFormItems() const { return HasFlag(XFA_NodeFlag_BindFormItems); } NeedsInitApp()466 bool NeedsInitApp() const { return HasFlag(XFA_NodeFlag_NeedsInitApp); } 467 void SyncValue(const WideString& wsValue, bool bNotify); 468 CXFA_Value* GetDefaultValueIfExists(); 469 CXFA_Bind* GetBindIfExists() const; 470 Optional<XFA_AttributeValue> GetIntactFromKeep( 471 const CXFA_Keep* pKeep, 472 XFA_AttributeValue eLayoutType) const; 473 CXFA_Node* GetTransparentParent(); 474 475 Optional<float> TryHeight(); 476 Optional<float> TryMinWidth(); 477 Optional<float> TryMinHeight(); 478 Optional<float> TryMaxWidth(); 479 Optional<float> TryMaxHeight(); 480 XFA_EventError ProcessEventInternal(CXFA_FFDocView* pDocView, 481 XFA_AttributeValue iActivity, 482 CXFA_Event* event, 483 CXFA_EventParam* pEventParam); 484 485 CFX_XMLDocument* GetXMLDocument() const; 486 487 const pdfium::span<const PropertyData> m_Properties; 488 const pdfium::span<const AttributeData> m_Attributes; 489 const uint32_t m_ValidPackets; 490 UnownedPtr<CFX_XMLNode> xml_node_; 491 const XFA_PacketType m_ePacket; 492 uint8_t m_ExecuteRecursionDepth = 0; 493 uint16_t m_uNodeFlags = XFA_NodeFlag_None; 494 uint32_t m_dwNameHash = 0; 495 CXFA_Node* m_pAuxNode = nullptr; // Raw, node tree cleanup order. 496 std::vector<CXFA_Node*> binding_nodes_; // Raw, node tree cleanup order. 497 bool m_bIsNull = true; 498 bool m_bPreNull = true; 499 bool is_widget_ready_ = false; 500 std::unique_ptr<CXFA_WidgetLayoutData> m_pLayoutData; 501 CXFA_Ui* ui_ = nullptr; 502 XFA_FFWidgetType ff_widget_type_ = XFA_FFWidgetType::kNone; 503 }; 504 505 #endif // XFA_FXFA_PARSER_CXFA_NODE_H_ 506