1  /*
2   * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3   * Licensed under the Apache License, Version 2.0 (the "License");
4   * you may not use this file except in compliance with the License.
5   * You may obtain a copy of the License at
6   *
7   *     http://www.apache.org/licenses/LICENSE-2.0
8   *
9   * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  
16  #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_RENDER_NODE_H
17  #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_RENDER_NODE_H
18  
19  #include <list>
20  
21  #include "base/geometry/dimension.h"
22  #include "base/geometry/matrix4.h"
23  #include "base/geometry/rect.h"
24  #include "base/memory/ace_type.h"
25  #include "base/utils/macros.h"
26  #include "base/utils/system_properties.h"
27  #include "core/accessibility/accessibility_manager.h"
28  #include "core/animation/animatable_properties.h"
29  #include "core/animation/keyframe_animation.h"
30  #include "core/animation/property_animatable.h"
31  #include "core/common/draw_delegate.h"
32  #include "core/components/common/layout/align_declaration.h"
33  #include "core/components/common/layout/constants.h"
34  #include "core/components/common/layout/layout_param.h"
35  #include "core/components/common/properties/motion_path_option.h"
36  #include "core/components/common/properties/state_attributes.h"
37  #include "core/components/common/properties/text_style.h"
38  #include "core/components_v2/extensions/events/event_extensions.h"
39  #include "core/components_v2/inspector/inspector_node.h"
40  #include "core/event/axis_event.h"
41  #include "core/event/mouse_raw_recognizer.h"
42  #include "core/event/touch_event.h"
43  #include "core/gestures/click_recognizer.h"
44  #include "core/gestures/drag_recognizer.h"
45  #include "core/pipeline/base/render_context.h"
46  #include "core/pipeline/base/render_layer.h"
47  #include "core/pipeline/pipeline_context.h"
48  
49  namespace OHOS::Ace {
50  
51  extern const Dimension FOCUS_BOUNDARY;
52  
53  class Component;
54  
55  // If no insertion location is specified, new child will be added to the end of children list by default.
56  constexpr int32_t DEFAULT_RENDER_NODE_SLOT = -1;
57  constexpr int32_t PRESS_DURATION = 100;
58  constexpr int32_t HOVER_DURATION = 250;
59  constexpr uint32_t FIND_MAX_COUNT = 64;
60  
61  using HoverAndPressCallback = std::function<void(const Color&)>;
62  using Rosen::RSNode;
63  
64  // RenderNode is the base class for different render backend, represent a render unit for render pipeline.
65  class ACE_EXPORT RenderNode : public PropertyAnimatable, public AnimatableProperties, public virtual AceType {
66      DECLARE_ACE_TYPE(RenderNode, PropertyAnimatable, AceType);
67  
68  public:
69      using OpacityCallback = std::function<void(uint8_t)>;
70      using SlipFactorSetting = std::function<void(double)>;
71      ~RenderNode() override = default;
72  
73      static void MarkTreeRender(const RefPtr<RenderNode>& root, bool& meetHole, bool needFlush);
74  
75      static void MarkWholeRender(const WeakPtr<RenderNode>& nodeWeak, bool needFlush);
76  
SetZIndex(int32_t zIndex)77      void SetZIndex(int32_t zIndex)
78      {
79          zIndex_ = zIndex;
80      }
81  
GetZIndex()82      int32_t GetZIndex() const
83      {
84          return zIndex_;
85      }
86  
SetIsPercentSize(bool isPercentSize)87      void SetIsPercentSize(bool isPercentSize)
88      {
89          isPercentSize_ = isPercentSize;
90      }
91  
GetIsPercentSize()92      bool GetIsPercentSize() const
93      {
94          return isPercentSize_;
95      }
96  
97      void AddChild(const RefPtr<RenderNode>& child, int32_t slot = DEFAULT_RENDER_NODE_SLOT);
98  
99      void RemoveChild(const RefPtr<RenderNode>& child);
100  
101      void MovePosition(int32_t slot);
102  
103      void ClearChildren();
104  
105      virtual void MoveWhenOutOfViewPort(bool hasEffect);
106  
107      bool IsPointInBox(const TouchEvent& point);
108      void Attach(const WeakPtr<PipelineContext>& context);
109  
110      // unmount from render tree
Unmount()111      void Unmount()
112      {
113          RefPtr<RenderNode> parent = parent_.Upgrade();
114          if (parent) {
115              parent->MarkNeedLayout();
116              parent->RemoveChild(AceType::Claim(this));
117          }
118          parent_ = nullptr;
119      }
120  
121      // Update node with attr, style, event, method and so on.
122      // This method will call Update virtual function.
123      void UpdateAll(const RefPtr<Component>& component);
124  
AddToScene()125      virtual void AddToScene() {}
126  
127      virtual void Update(const RefPtr<Component>& component) = 0;
128  
129      // Called when page context attached, subclass can initialize object which needs page context.
OnAttachContext()130      virtual void OnAttachContext() {}
131  
FinishRender(const std::unique_ptr<DrawDelegate> & delegate,const Rect & dirty)132      virtual void FinishRender(const std::unique_ptr<DrawDelegate>& delegate, const Rect& dirty) {}
133  
134      virtual void UpdateTouchRect();
135  
136      void SetTouchRectList(std::vector<Rect>& touchRectList);
137      bool CompareTouchRect(const Rect& parentTouchRect, const Rect& childTouchRect);
138      void CompareTouchRectList(std::vector<Rect>& touchRectList,
139          const std::vector<Rect>& childTouchRectList, const std::vector<Rect>& parentTouchRectList);
140  
NeedLayout()141      bool NeedLayout() const
142      {
143          return needLayout_;
144      }
145  
SetNeedLayout(bool needLayout)146      void SetNeedLayout(bool needLayout)
147      {
148          needLayout_ = needLayout;
149      }
150  
151      void MarkNeedLayout(bool selfOnly = false, bool forceParent = false);
152  
153      /**
154       * \brief check in mark need layout progress if parent need layout again.
155       * \return true if need layout again.
156       */
CheckIfNeedLayoutAgain()157      virtual bool CheckIfNeedLayoutAgain()
158      {
159          return true;
160      }
161  
162      void MarkNeedPredictLayout();
163  
164      void OnLayout();
165  
166      // deadline : The remaining time until the next vsync. (unit: microsecond)
OnPredictLayout(int64_t deadline)167      virtual void OnPredictLayout(int64_t deadline) {}
168  
GetChildViewPort()169      virtual Size GetChildViewPort()
170      {
171          return viewPort_;
172      }
173  
174      // Called by parent to perform layout.
Layout(const LayoutParam & layoutParam)175      void Layout(const LayoutParam& layoutParam)
176      {
177          auto pipeline = context_.Upgrade();
178          if (!pipeline) {
179              LOGE("pipeline is null when layout");
180              return;
181          }
182  
183          bool dipScaleChange = !NearEqual(pipeline->GetDipScale(), dipScale_);
184          dipScale_ = pipeline->GetDipScale();
185          if (dipScaleChange || layoutParam_ != layoutParam) {
186              layoutParam_ = layoutParam;
187              layoutParamChanged_ = true;
188              SetNeedLayout(true);
189          }
190  
191          if (onChangeCallback_) {
192              onChangeCallback_();
193          }
194          OnLayout();
195      }
196  
197      // Called by parent to update layout param without PerformLayout.
SetLayoutParam(const LayoutParam & layoutParam)198      void SetLayoutParam(const LayoutParam& layoutParam)
199      {
200          if (layoutParam_ != layoutParam) {
201              layoutParam_ = layoutParam;
202              layoutParamChanged_ = true;
203              MarkNeedLayout();
204          }
205      }
206  
GetLayoutParam()207      const LayoutParam& GetLayoutParam() const
208      {
209          return layoutParam_;
210      }
211  
212      // Each subclass should override this function for actual layout operation.
213      virtual void PerformLayout() = 0;
214  
GetPosition()215      Offset GetPosition() const
216      {
217          return paintRect_.GetOffset();
218      }
219  
220      void SetPosition(const Offset& offset);
221  
SetAbsolutePosition(const Offset & offset)222      void SetAbsolutePosition(const Offset& offset)
223      {
224          SetPositionInternal(offset);
225      }
226  
GetLayoutSize()227      Size GetLayoutSize() const
228      {
229          return paintRect_.GetSize();
230      }
231  
232      Rect GetRectWithShadow() const;
233  
SetShadow(const Shadow & shadow)234      void SetShadow(const Shadow& shadow)
235      {
236          shadow_ = shadow;
237          hasShadow_ = true;
238      }
239  
240      void SetLayoutSize(const Size& size);
241  
GetRectBasedWindowTopLeft()242      Rect GetRectBasedWindowTopLeft()
243      {
244          return Rect(GetGlobalOffset(), paintRect_.GetSize());
245      }
246  
GetTouchRect()247      virtual const Rect& GetTouchRect()
248      {
249          if (needUpdateTouchRect_) {
250              needUpdateTouchRect_ = false;
251              UpdateTouchRect();
252          }
253          return touchRect_;
254      }
255  
GetTouchRectList()256      virtual const std::vector<Rect>& GetTouchRectList()
257      {
258          if (needUpdateTouchRect_) {
259              needUpdateTouchRect_ = false;
260              touchRectList_.clear();
261              UpdateTouchRect();
262          }
263          return touchRectList_;
264      }
265  
ChangeTouchRectList(std::vector<Rect> & touchRectList)266      void ChangeTouchRectList(std::vector<Rect>& touchRectList)
267      {
268          touchRectList_ = touchRectList;
269      }
270  
InTouchRectList(const Point & parentLocalPoint,const std::vector<Rect> & touchRectList)271      bool InTouchRectList(const Point& parentLocalPoint, const std::vector<Rect>& touchRectList) const
272      {
273          for (auto& rect : touchRectList) {
274              if (rect.IsInRegion(parentLocalPoint)) {
275                  return true;
276              }
277          }
278          return false;
279      }
280  
IsUseOnly()281      virtual bool IsUseOnly()
282      {
283          return false;
284      }
285  
IsNotSiblingAddRecognizerToResult()286      virtual bool IsNotSiblingAddRecognizerToResult()
287      {
288          return isNotSiblingAddRecognizerToResult_;
289      }
290  
MarkIsNotSiblingAddRecognizerToResult(bool isNotSiblingAddRecognizerToResult)291      void MarkIsNotSiblingAddRecognizerToResult(bool isNotSiblingAddRecognizerToResult)
292      {
293          isNotSiblingAddRecognizerToResult_ = isNotSiblingAddRecognizerToResult;
294      }
295  
GetTransformPoint(const Point & point)296      virtual Point GetTransformPoint(const Point& point)
297      {
298          return point;
299      }
300  
GetTransformRect(const Rect & rect)301      virtual Rect GetTransformRect(const Rect& rect)
302      {
303          return rect;
304      }
305  
306      const Rect& GetPaintRect() const;
307  
308      Rect GetTransitionPaintRect() const;
309  
310      Offset GetTransitionGlobalOffset() const;
311  
312      void SetPaintRect(const Rect& rect);
313  
SetTouchRect(const Rect & rect)314      void SetTouchRect(const Rect& rect)
315      {
316          touchRect_ = rect;
317          needUpdateTouchRect_ = false;
318      }
319  
MarkNeedUpdateTouchRect(bool needUpdateTouchRect)320      void MarkNeedUpdateTouchRect(bool needUpdateTouchRect)
321      {
322          needUpdateTouchRect_ = needUpdateTouchRect;
323      }
324  
OnChildAdded(const RefPtr<RenderNode> & child)325      virtual void OnChildAdded(const RefPtr<RenderNode>& child)
326      {
327          if (slipFactorSetting_) {
328              child->SetSlipFactorSetting(slipFactorSetting_);
329          }
330      }
331  
OnChildRemoved(const RefPtr<RenderNode> & child)332      virtual void OnChildRemoved(const RefPtr<RenderNode>& child) {}
333  
OnRemove()334      virtual void OnRemove() {}
335  
GetAccessibilityText()336      const std::string& GetAccessibilityText() const
337      {
338          return accessibilityText_;
339      }
340  
SetAccessibilityText(const std::string & accessibilityText)341      void SetAccessibilityText(const std::string& accessibilityText)
342      {
343          accessibilityText_ = accessibilityText;
344      }
345  
346      virtual void DumpTree(int32_t depth);
347  
348      virtual void Dump();
349  
350      enum class BridgeType { NONE, ROSEN, FLUTTER };
351  
GetBridgeType()352      virtual BridgeType GetBridgeType() const
353      {
354          return BridgeType::NONE;
355      }
356  
SetNeedRender(bool needRender)357      void SetNeedRender(bool needRender)
358      {
359          needRender_ = needRender;
360      }
361  
362      void MarkNeedRender(bool overlay = false);
363  
NeedRender()364      bool NeedRender() const
365      {
366          return needRender_;
367      }
368  
369      void SetDepth(int32_t depth);
370  
SetPositionType(PositionType type)371      void SetPositionType(PositionType type)
372      {
373          positionParam_.type = type;
374      }
375  
GetDepth()376      int32_t GetDepth() const
377      {
378          return depth_;
379      }
380  
GetPositionType()381      PositionType GetPositionType() const
382      {
383          return positionParam_.type;
384      }
385  
GetLeft()386      virtual const Dimension& GetLeft() const
387      {
388          return positionParam_.left.first;
389      }
390  
GetRight()391      virtual const Dimension& GetRight() const
392      {
393          return positionParam_.right.first;
394      }
395  
GetTop()396      virtual const Dimension& GetTop() const
397      {
398          return positionParam_.top.first;
399      }
400  
GetBottom()401      virtual const Dimension& GetBottom() const
402      {
403          return positionParam_.bottom.first;
404      }
405  
GetAnchorX()406      const Dimension& GetAnchorX() const
407      {
408          return positionParam_.anchor.first;
409      }
410  
GetAnchorY()411      const Dimension& GetAnchorY() const
412      {
413          return positionParam_.anchor.second;
414      }
415  
HasLeft()416      virtual bool HasLeft() const
417      {
418          return positionParam_.left.second;
419      }
420  
HasRight()421      virtual bool HasRight() const
422      {
423          return positionParam_.right.second;
424      }
425  
HasTop()426      virtual bool HasTop() const
427      {
428          return positionParam_.top.second;
429      }
430  
HasBottom()431      virtual bool HasBottom() const
432      {
433          return positionParam_.bottom.second;
434      }
435  
SetLeft(const Dimension & left)436      virtual void SetLeft(const Dimension& left) // add for animation
437      {
438          if (positionParam_.left.first != left) {
439              positionParam_.left = std::make_pair(left, true);
440              MarkNeedLayout();
441          }
442      }
443  
SetTop(const Dimension & top)444      virtual void SetTop(const Dimension& top) // add for animation
445      {
446          if (positionParam_.top.first != top) {
447              positionParam_.top = std::make_pair(top, true);
448              MarkNeedLayout();
449          }
450      }
451  
SetRight(const Dimension & right)452      virtual void SetRight(const Dimension& right) // add for animation
453      {
454          if (positionParam_.right.first != right) {
455              positionParam_.top = std::make_pair(right, true);
456              MarkNeedLayout();
457          }
458      }
459  
SetBottom(const Dimension & bottom)460      virtual void SetBottom(const Dimension& bottom) // add for animation
461      {
462          if (positionParam_.bottom.first != bottom) {
463              positionParam_.bottom = std::make_pair(bottom, true);
464              MarkNeedLayout();
465          }
466      }
467  
GetParent()468      WeakPtr<RenderNode> GetParent() const
469      {
470          return parent_;
471      }
472  
GetContext()473      WeakPtr<PipelineContext> GetContext() const
474      {
475          return context_;
476      }
477  
GetRenderLayer()478      virtual RenderLayer GetRenderLayer()
479      {
480          return nullptr;
481      }
482  
483      virtual void SetVisible(bool visible, bool inRecursion = false);
484  
GetVisible()485      virtual bool GetVisible() const
486      {
487          return visible_;
488      }
489  
490      virtual void SetHidden(bool hidden, bool inRecursion = false)
491      {
492          if (hidden_ != hidden) {
493              hidden_ = hidden;
494              AddDirtyRenderBoundaryNode();
495              OnHiddenChanged(hidden);
496              if (!inRecursion && SystemProperties::GetRosenBackendEnabled()) {
497                  MarkParentNeedRender();
498              }
499              if (hidden_) {
500                  disableTouchEvent_ = true;
501              } else {
502                  disableTouchEvent_ = false;
503              }
504          }
505          for (auto& child : children_) {
506              child->SetHidden(hidden, true);
507          }
508      }
509  
SetSelfHidden(bool hidden)510      void SetSelfHidden(bool hidden)
511      {
512          if (hidden_ != hidden) {
513              hidden_ = hidden;
514              AddDirtyRenderBoundaryNode();
515              OnHiddenChanged(hidden);
516              if (SystemProperties::GetRosenBackendEnabled()) {
517                  MarkParentNeedRender();
518              }
519          }
520      }
521  
GetHidden()522      bool GetHidden() const
523      {
524          return hidden_;
525      }
526  
IsTakenBoundary()527      bool IsTakenBoundary() const
528      {
529          return takeBoundary_;
530      }
531  
IsRepaintBoundary()532      virtual bool IsRepaintBoundary() const
533      {
534          return IsHeadRenderNode();
535      }
536  
GetChildren()537      virtual const std::list<RefPtr<RenderNode>>& GetChildren() const
538      {
539          return children_;
540      }
541  
542      virtual void NotifyPaintFinish();
543  
544      virtual void RenderWithContext(RenderContext& context, const Offset& offset);
545      virtual void Paint(RenderContext& context, const Offset& offset);
546      void PaintChildList(const std::list<RefPtr<RenderNode>>& childList, RenderContext& context, const Offset& offset);
547      virtual void PaintChild(const RefPtr<RenderNode>& child, RenderContext& context, const Offset& offset);
548  
OnPaintFinish()549      virtual void OnPaintFinish() {}
550  
551      virtual bool TouchTest(const Point& globalPoint, const Point& parentLocalPoint, const TouchRestrict& touchRestrict,
552          TouchTestResult& result);
553  
554      virtual void MouseTest(const Point& globalPoint, const Point& parentLocalPoint, MouseRawResult& result);
555  
556      virtual bool MouseHoverTest(const Point& parentLocalPoint);
557  
558      virtual bool MouseDetect(const Point& globalPoint, const Point& parentLocalPoint, MouseHoverTestList& result,
559          WeakPtr<RenderNode>& hoverNode);
560  
561      virtual bool AxisDetect(const Point& globalPoint, const Point& parentLocalPoint, WeakPtr<RenderNode>& axisNode,
562          const AxisDirection direction);
563  
HandleMouseHoverEvent(const MouseState mouseState)564      virtual void HandleMouseHoverEvent(const MouseState mouseState) {}
565  
HandleMouseEvent(const MouseEvent & event)566      virtual bool HandleMouseEvent(const MouseEvent& event)
567      {
568          return false;
569      }
570  
HandleAxisEvent(const AxisEvent & event)571      virtual void HandleAxisEvent(const AxisEvent& event) {}
572  
573      virtual bool RotationMatchTest(const RefPtr<RenderNode>& requestRenderNode);
574  
575      virtual bool RotationTest(const RotationEvent& event);
576  
577      virtual bool RotationTestForward(const RotationEvent& event);
578  
579      virtual double GetBaselineDistance(TextBaseline textBaseline);
580  
581      virtual Size GetContentSize();
582  
583      virtual bool ScrollPageByChild(Offset& delta, int32_t source);
584  
585      // Change render nodes' status
ChangeStatus(RenderStatus renderStatus)586      void ChangeStatus(RenderStatus renderStatus)
587      {
588          // Myself status should be changed and function achieved by derived class which is component
589          OnStatusChanged(renderStatus);
590  
591          // Deep traversal
592          for (auto& child : children_) {
593              child->ChangeStatus(renderStatus);
594          }
595      }
596  
597      virtual void OnStatusStyleChanged(VisualState state);
598  
599      Offset GetOffsetFromOrigin(const Offset& offset) const;
600  
601      virtual Offset GetGlobalOffset() const;
602  
603      virtual Offset GetGlobalOffsetExternal() const;
604  
605      RefPtr<RenderNode> GetHeadRenderNode();
606  
607      // Whether |rect| is in the paint rect of render tree recursively.
608      bool IsVisible(const Rect& rect, bool totally = false) const;
609  
SetOnChangeCallback(std::function<void ()> && onChangeCallback)610      void SetOnChangeCallback(std::function<void()>&& onChangeCallback)
611      {
612          onChangeCallback_ = std::move(onChangeCallback);
613      }
614  
SetDisableTouchEvent(bool disableTouchEvent)615      void SetDisableTouchEvent(bool disableTouchEvent)
616      {
617          disableTouchEvent_ = disableTouchEvent;
618      }
619  
GetDisableTouchEvent()620      bool GetDisableTouchEvent() const
621      {
622          return disableTouchEvent_;
623      }
624  
IsChildrenTouchEnable()625      virtual bool IsChildrenTouchEnable()
626      {
627          return true;
628      }
629  
SetTextDirection(TextDirection textDirection)630      void SetTextDirection(TextDirection textDirection)
631      {
632          textDirection_ = textDirection;
633      }
634  
GetTextDirection()635      TextDirection GetTextDirection() const
636      {
637          return textDirection_;
638      }
639  
640      // Transfer any other dimension unit to logical px.
641      // NOTE: context_ MUST be initialized before call this method.
642      double NormalizeToPx(Dimension dimension) const;
643  
644      // Mainly use this function to convert Percent to Px. Do not call this function in Update().
645      double NormalizePercentToPx(const Dimension& dimension, bool isVertical, bool referSelf = false) const;
646  
647      // for accessibility
SetAccessibilityNode(const WeakPtr<AccessibilityNode> & accessibilityNode)648      void SetAccessibilityNode(const WeakPtr<AccessibilityNode>& accessibilityNode)
649      {
650          accessibilityNode_ = accessibilityNode;
651      }
652  
GetAccessibilityNode()653      const WeakPtr<AccessibilityNode>& GetAccessibilityNode() const
654      {
655          return accessibilityNode_;
656      }
657  
GetAccessibilityNodeId()658      int32_t GetAccessibilityNodeId() const
659      {
660          auto accessibilityNode = accessibilityNode_.Upgrade();
661          if (accessibilityNode) {
662              return accessibilityNode->GetNodeId();
663          }
664          return 0;
665      }
666  
ClearAccessibilityRect()667      void ClearAccessibilityRect()
668      {
669          auto node = accessibilityNode_.Upgrade();
670          if (node) {
671              node->ClearRect();
672          }
673          for (auto& child : children_) {
674              child->ClearAccessibilityRect();
675          }
676      }
677      void SetAccessibilityRect(const Rect& rect);
678  
SetNeedUpdateAccessibility(bool needUpdate)679      void SetNeedUpdateAccessibility(bool needUpdate)
680      {
681          needUpdateAccessibility_ = needUpdate;
682          for (auto& child : children_) {
683              child->SetNeedUpdateAccessibility(needUpdate);
684          }
685      }
686  
SetAccessibilityVisible(bool visible)687      void SetAccessibilityVisible(bool visible)
688      {
689          auto node = accessibilityNode_.Upgrade();
690          if (node) {
691              node->SetVisible(visible);
692          }
693          for (auto& child : children_) {
694              child->SetAccessibilityVisible(visible);
695          }
696      }
697  
698      RefPtr<RenderNode> GetLastChild() const;
699  
700      RefPtr<RenderNode> GetFirstChild() const;
701  
GetOffsetToStage()702      Offset GetOffsetToStage() const
703      {
704          auto offset = GetGlobalOffset();
705          auto context = GetContext().Upgrade();
706          if (context) {
707              offset = offset - context->GetStageRect().GetOffset();
708          }
709          return offset;
710      }
711  
712      Offset GetOffsetToPage() const;
713  
GetFlexWeight()714      double GetFlexWeight() const
715      {
716          return flexWeight_;
717      }
718  
GetDisplayIndex()719      int32_t GetDisplayIndex() const
720      {
721          return displayIndex_;
722      }
723  
GetDisplayIndexSetted()724      bool GetDisplayIndexSetted() const
725      {
726          return displayIndexSetted_;
727      }
728  
729      OpacityCallback GetOpacityCallback(int32_t domId);
730  
731      virtual bool SupportOpacity();
732  
733      void GetDomOpacityCallbacks(int32_t domId, std::list<OpacityCallback>& result);
734  
735      int32_t GetNodeId() const;
736  
737      uint8_t GetOpacity() const;
738  
739      virtual void UpdateOpacity(uint8_t opacity);
740  
InterceptTouchEvent()741      bool InterceptTouchEvent() const
742      {
743          return interceptTouchEvent_;
744      }
745  
SetInterceptTouchEvent(bool interceptTouchEvent)746      void SetInterceptTouchEvent(bool interceptTouchEvent)
747      {
748          interceptTouchEvent_ = interceptTouchEvent;
749      }
750  
DispatchCancelPressAnimation()751      void DispatchCancelPressAnimation()
752      {
753          OnCancelPressAnimation();
754          for (const auto& child : children_) {
755              child->DispatchCancelPressAnimation();
756          }
757      }
758  
CheckAxisNode()759      virtual WeakPtr<RenderNode> CheckAxisNode()
760      {
761          return nullptr;
762      }
MouseHoverEnterTest()763      virtual void MouseHoverEnterTest() {}
MouseHoverExitTest()764      virtual void MouseHoverExitTest() {}
AnimateMouseHoverEnter()765      virtual void AnimateMouseHoverEnter() {}
AnimateMouseHoverExit()766      virtual void AnimateMouseHoverExit() {}
OnCancelPressAnimation()767      virtual void OnCancelPressAnimation() {}
OnMouseHoverEnterAnimation()768      virtual void OnMouseHoverEnterAnimation() {}
OnMouseHoverExitAnimation()769      virtual void OnMouseHoverExitAnimation() {}
OnMouseClickDownAnimation()770      virtual void OnMouseClickDownAnimation() {}
OnMouseClickUpAnimation()771      virtual void OnMouseClickUpAnimation() {}
StopMouseHoverAnimation()772      virtual void StopMouseHoverAnimation() {}
IsAxisScrollable(AxisDirection direction)773      virtual bool IsAxisScrollable(AxisDirection direction)
774      {
775          return false;
776      }
777  
OnVisibleChanged()778      virtual void OnVisibleChanged() {}
779  
780      void CreateMouseAnimation(RefPtr<KeyframeAnimation<Color>>& animation, const Color& from, const Color& to);
SetHoverAndPressCallback(const HoverAndPressCallback & callback)781      void SetHoverAndPressCallback(const HoverAndPressCallback& callback)
782      {
783          hoveAndPressCallback_ = callback;
784      }
785  
GetEventEffectColor()786      Color GetEventEffectColor() const
787      {
788          return eventEffectColor_;
789      }
790  
791      void UpdateWindowBlurRRect(bool clear = false);
792  
793      void WindowBlurTest();
794  
GetWindowBlurRRect()795      virtual RRect GetWindowBlurRRect() const
796      {
797          return RRect::MakeRRect(Rect(Offset::Zero(), GetLayoutSize()), Radius(0.0));
798      }
799  
800      RRect GetGlobalWindowBlurRRect(std::vector<RRect>& coords) const;
801  
MarkNeedWindowBlur(bool flag)802      void MarkNeedWindowBlur(bool flag)
803      {
804          if (needWindowBlur_ != flag) {
805              needWindowBlur_ = flag;
806              if (!needWindowBlur_) {
807                  UpdateWindowBlurProgress(0.0f);
808                  SetWindowBlurStyle(WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT);
809              }
810              OnWindowBlurChanged();
811          }
812      }
813  
NeedWindowBlur()814      bool NeedWindowBlur() const
815      {
816          return needWindowBlur_;
817      }
818  
UpdateWindowBlurProgress(float progress)819      void UpdateWindowBlurProgress(float progress)
820      {
821          windowBlurProgress_ = progress;
822      }
823  
GetWindowBlurProgress()824      float GetWindowBlurProgress() const
825      {
826          return windowBlurProgress_;
827      }
828  
SetWindowBlurStyle(WindowBlurStyle style)829      void SetWindowBlurStyle(WindowBlurStyle style)
830      {
831          windowBlurStyle_ = style;
832      }
833  
GetWindowBlurStyle()834      WindowBlurStyle GetWindowBlurStyle() const
835      {
836          return windowBlurStyle_;
837      }
838  
SetSlipFactorSetting(const SlipFactorSetting & slipFactorSetting)839      void SetSlipFactorSetting(const SlipFactorSetting& slipFactorSetting)
840      {
841          slipFactorSetting_ = slipFactorSetting;
842      }
843  
IsInfiniteLayout()844      bool IsInfiniteLayout() const
845      {
846          return GetLayoutSize().Width() > INT32_MAX || GetLayoutSize().Height() > INT32_MAX;
847      }
848  
IsIgnored()849      bool IsIgnored() const
850      {
851          return isIgnored_;
852      }
853  
SetIsIgnored(bool ignore)854      void SetIsIgnored(bool ignore)
855      {
856          isIgnored_ = ignore;
857      }
858  
SetGlobalPoint(const Point & point)859      void SetGlobalPoint(const Point& point)
860      {
861          globalPoint_ = point;
862      }
863  
GetGlobalPoint()864      const Point& GetGlobalPoint()
865      {
866          return globalPoint_;
867      }
868  
SetCoordinatePoint(const Point & point)869      void SetCoordinatePoint(const Point& point)
870      {
871          coordinatePoint_ = point;
872      }
873  
GetCoordinatePoint()874      const Point& GetCoordinatePoint()
875      {
876          return coordinatePoint_;
877      }
878  
IsTouchable()879      bool IsTouchable() const
880      {
881          return touchable_;
882      }
883  
GetHitTestMode()884      HitTestMode GetHitTestMode() const
885      {
886          return hitTestMode_;
887      }
888  
IsDisabled()889      bool IsDisabled() const
890      {
891          return disabled_;
892      }
893  
OnAppShow()894      virtual void OnAppShow()
895      {
896          isAppOnShow_ = true;
897          for (const auto& child : children_) {
898              child->OnAppShow();
899          }
900      }
901  
OnAppHide()902      virtual void OnAppHide()
903      {
904          isAppOnShow_ = false;
905          for (const auto& child : children_) {
906              child->OnAppHide();
907          }
908      }
909  
IsAppShow()910      bool IsAppShow()
911      {
912          return isAppOnShow_;
913      }
914  
915      template<typename T>
GetTheme()916      RefPtr<T> GetTheme() const
917      {
918          auto context = context_.Upgrade();
919          if (!context) {
920              return nullptr;
921          }
922          auto themeManager = context->GetThemeManager();
923          if (!themeManager) {
924              return nullptr;
925          }
926          return themeManager->GetTheme<T>();
927      }
928  
929      virtual bool HasEffectiveTransform() const;
930  
OnTransition(TransitionType type,int32_t id)931      virtual void OnTransition(TransitionType type, int32_t id) {}
932  
933      bool IsDisappearing();
934      virtual bool HasDisappearingTransition(int32_t nodeId);
935      void NotifyTransition(TransitionType type, int32_t nodeId);
SetPendingAppearingTransition()936      virtual void SetPendingAppearingTransition() {}
937  
938      Rect GetDirtyRect() const;
939      std::function<void(const DragUpdateInfo&)> onDomDragEnter_ = nullptr;
940      std::function<void(const DragUpdateInfo&)> onDomDragOver_ = nullptr;
941      std::function<void(const DragUpdateInfo&)> onDomDragLeave_ = nullptr;
942      std::function<void(const DragEndInfo&)> onDomDragDrop_ = nullptr;
943      virtual bool GetAlignDeclarationOffset(AlignDeclarationPtr alignDeclarationPtr, Offset& offset) const;
944  
945      // Each subclass override this to return touch target object which is used to receive touch event.
946      // For convenience, it is recommended to return directly to the corresponding gesture recognizer.
947      // Sees gestures directory.
948      // Uses coordinateOffset for recognizer to calculate the local location of the touch point.
949      // Uses touchRestrict for restrict gesture recognition in some sense.
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)950      virtual void OnTouchTestHit(
951          const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
952      {}
OnPreDraw()953      virtual void OnPreDraw() {}
954  
955      template<typename T>
FindChildNodeOfClass(const Point & globalPoint,const Point & parentLocalPoint)956      RefPtr<T> FindChildNodeOfClass(const Point& globalPoint, const Point& parentLocalPoint)
957      {
958          Point transformPoint = GetTransformPoint(parentLocalPoint);
959          if (!InTouchRectList(transformPoint, GetTouchRectList())) {
960              return nullptr;
961          }
962  
963          // Calculates the local point location in this node.
964          const auto localPoint = transformPoint - GetPaintRect().GetOffset();
965          const auto& children = GetChildren();
966          for (auto iter = children.rbegin(); iter != children.rend(); ++iter) {
967              auto& child = *iter;
968              if (!child->GetVisible()) {
969                  continue;
970              }
971  
972              if (child->InterceptTouchEvent()) {
973                  continue;
974              }
975  
976              auto target = child->FindChildNodeOfClass<T>(globalPoint, localPoint);
977              if (target) {
978                  return target;
979              }
980          }
981  
982          for (auto& rect : GetTouchRectList()) {
983              if (touchable_ && rect.IsInRegion(transformPoint)) {
984                  RefPtr<RenderNode> renderNode = AceType::Claim<RenderNode>(this);
985                  if (AceType::InstanceOf<T>(renderNode)) {
986                      return AceType::DynamicCast<T>(renderNode);
987                  }
988              }
989          }
990          return nullptr;
991      }
992  
993      template<typename T>
FindTargetRenderNode(const RefPtr<PipelineContext> context,const GestureEvent & info)994      RefPtr<T> FindTargetRenderNode(const RefPtr<PipelineContext> context, const GestureEvent& info)
995      {
996          if (!context) {
997              return nullptr;
998          }
999  
1000          auto pageRenderNode = context->GetLastPageRender();
1001          if (!pageRenderNode) {
1002              return nullptr;
1003          }
1004  
1005          return pageRenderNode->FindChildNodeOfClass<T>(info.GetGlobalPoint(), info.GetGlobalPoint());
1006      }
1007  
1008      template<class T>
FindChildOfClass(const RefPtr<RenderNode> & parent)1009      RefPtr<T> FindChildOfClass(const RefPtr<RenderNode>& parent)
1010      {
1011          // BFS to find child in tree.
1012          uint32_t findCount = 0;
1013          auto searchQueue = parent->GetChildren(); // copy children to a queue
1014          while (++findCount <= FIND_MAX_COUNT && !searchQueue.empty()) {
1015              const auto child = searchQueue.front();
1016              searchQueue.pop_front();
1017              if (!child) {
1018                  continue;
1019              }
1020              if (AceType::InstanceOf<T>(child)) {
1021                  return AceType::DynamicCast<T>(child);
1022              }
1023              searchQueue.insert(searchQueue.end(), child->GetChildren().begin(), child->GetChildren().end());
1024          }
1025          return RefPtr<T>();
1026      }
1027  
1028      void SaveExplicitAnimationOption(const AnimationOption& option);
1029  
1030      const AnimationOption& GetExplicitAnimationOption() const;
1031  
1032      void ClearExplicitAnimationOption();
1033  
1034      void ClearDisappearingNode(RefPtr<RenderNode> child);
1035  
1036      void CreateLayoutTransition();
1037  
1038      void CreatePathAnimation();
1039  
IsExclusiveEventForChild()1040      bool IsExclusiveEventForChild() const
1041      {
1042          return exclusiveEventForChild_;
1043      }
SetExclusiveEventForChild(bool exclusiveEventForChild)1044      void SetExclusiveEventForChild(bool exclusiveEventForChild)
1045      {
1046          exclusiveEventForChild_ = exclusiveEventForChild;
1047      }
1048  
1049      void MarkUpdateType(const RefPtr<Component>& component);
1050  
GetComponent()1051      virtual RefPtr<Component> GetComponent()
1052      {
1053          return nullptr;
1054      }
1055  
1056      virtual void NotifySizeTransition(const AnimationOption& option, Size fromSize, Size toSize, int32_t nodeId);
1057      void CreateGeometryTransitionFrom(const RefPtr<RenderNode>& targetNode, AnimationOption& sharedOption);
1058      void CreateGeometryTransitionTo(const RefPtr<RenderNode>& targetNode, AnimationOption& sharedOption);
1059      void SetIsPaintGeometryTransition(bool isPaintGeometryTransition);
1060      void SetPaintOutOfParent(bool isPaintOutOfParent);
1061      bool IsPaintOutOfParent();
1062      void UpdatePosition();
1063  
SetHasSubWindow(bool hasSubWindow)1064      void SetHasSubWindow(bool hasSubWindow)
1065      {
1066          hasSubWindow_ = hasSubWindow;
1067      }
1068  
GetHasSubWindow()1069      bool GetHasSubWindow() const
1070      {
1071          return hasSubWindow_;
1072      }
1073  
1074      // mark JSview boundary, create/destroy RSNode if need
1075      void SyncRSNodeBoundary(bool isHead, bool isTail, const RefPtr<Component>& component = nullptr);
1076      bool ProcessExternalRSNode(const RefPtr<Component>& component);
1077      void SyncRSNode(const std::shared_ptr<RSNode>& rsNode);
GetRSNode()1078      const std::shared_ptr<RSNode>& GetRSNode() const
1079      {
1080          return rsNode_;
1081      }
1082      // sync geometry properties to ROSEN backend
1083      virtual void SyncGeometryProperties();
1084  
IsResponseRegion()1085      bool IsResponseRegion() const
1086      {
1087          return isResponseRegion_;
1088      }
1089  
1090      double GetPxValue(double standard, const Dimension& value);
1091  
GetResponseRegionList()1092      const std::vector<Rect>& GetResponseRegionList() const
1093      {
1094          return responseRegionList_;
1095      }
1096  
GetInspectorNode()1097      const WeakPtr<V2::InspectorNode>& GetInspectorNode() const
1098      {
1099          return inspector_;
1100      }
1101  
SetInspectorNode(const RefPtr<V2::InspectorNode> & inspectorNode)1102      void SetInspectorNode(const RefPtr<V2::InspectorNode>& inspectorNode)
1103      {
1104          inspector_ = inspectorNode;
1105      }
1106  
SetNeedClip(bool needClip)1107      virtual void SetNeedClip(bool needClip)
1108      {
1109          needClip_ = needClip;
1110      }
1111  
GetNeedClip()1112      bool GetNeedClip()
1113      {
1114          return needClip_;
1115      }
1116  
1117      RefPtr<RenderNode> FindDropChild(const Point& globalPoint, const Point& parentLocalPoint);
1118      static constexpr size_t DEFAULT_INDEX = -1;
1119  
ProvideRestoreInfo()1120      virtual std::string ProvideRestoreInfo()
1121      {
1122          return "";
1123      }
1124  
SetRestoreInfo(const std::string & restoreInfo)1125      void SetRestoreInfo(const std::string& restoreInfo)
1126      {
1127          restoreInfo_ = restoreInfo;
1128      }
1129  
GetRestoreInfo()1130      const std::string& GetRestoreInfo() const
1131      {
1132          return restoreInfo_;
1133      }
1134  
1135      // JSview boundary, all nodes in [head, tail] share the same RSNode
IsHeadRenderNode()1136      bool IsHeadRenderNode() const
1137      {
1138  #ifdef ENABLE_ROSEN_BACKEND
1139          return SystemProperties::GetRosenBackendEnabled() ? isHeadRenderNode_ : false;
1140  #else
1141          return false;
1142  #endif
1143      }
1144  
1145  protected:
1146      explicit RenderNode(bool takeBoundary = false);
1147      virtual void ClearRenderObject();
1148  
OnMouseTestHit(const Offset & coordinateOffset,MouseRawResult & result)1149      virtual void OnMouseTestHit(const Offset& coordinateOffset, MouseRawResult& result) {}
OnMouseHoverEnterTest()1150      virtual void OnMouseHoverEnterTest() {}
OnMouseHoverExitTest()1151      virtual void OnMouseHoverExitTest() {}
1152      void SendAccessibilityEvent(const std::string& eventType);
1153      void SetAccessibilityClick(RefPtr<ClickRecognizer> clickRecognizer);
1154      bool DispatchTouchTestToChildren(const Point& localPoint, const Point& globalPoint,
1155          const TouchRestrict& touchRestrict, TouchTestResult& result);
1156  
1157      void PrepareLayout();
1158  
SetParent(const WeakPtr<RenderNode> & parent)1159      void SetParent(const WeakPtr<RenderNode>& parent)
1160      {
1161          parent_ = parent;
1162      }
1163  
1164      void TakeBoundary(bool taken = true)
1165      {
1166          takeBoundary_ = taken;
1167      }
1168  
IsLayoutParamChanged()1169      bool IsLayoutParamChanged() const
1170      {
1171          return layoutParamChanged_;
1172      }
1173  
OnGlobalPositionChanged()1174      virtual void OnGlobalPositionChanged()
1175      {
1176          MarkNeedSyncGeometryProperties();
1177          if (IsTailRenderNode()) {
1178              return;
1179          }
1180          for (const auto& child : children_) {
1181              if (child) {
1182                  child->OnGlobalPositionChanged();
1183              }
1184          }
1185      };
OnPositionChanged()1186      virtual void OnPositionChanged() {}
OnSizeChanged()1187      virtual void OnSizeChanged() {}
OnRenderFinish(RenderContext & context)1188      virtual void OnRenderFinish(RenderContext& context) {}
OnStatusChanged(RenderStatus renderStatus)1189      virtual void OnStatusChanged(RenderStatus renderStatus) {}
OnHiddenChanged(bool hidden)1190      virtual void OnHiddenChanged(bool hidden) {}
OnWindowBlurChanged()1191      virtual void OnWindowBlurChanged() {}
1192      virtual bool MarkNeedRenderSpecial();
1193  
1194      double GetHighestChildBaseline(TextBaseline baseline);
1195      double GetFirstChildBaseline(TextBaseline baseline);
1196      Size GetLargestChildContentSize();
1197      void UpdateAccessibilityPosition();
1198      void UpdateAccessibilityEnable(bool isEnabled);
1199      void CheckIfNeedUpdateTouchRect();
1200  
GetThemeManager()1201      RefPtr<ThemeManager> GetThemeManager() const
1202      {
1203          auto context = context_.Upgrade();
1204          if (!context) {
1205              return nullptr;
1206          }
1207          return context->GetThemeManager();
1208      }
1209  
GetUpdateType()1210      uint32_t GetUpdateType()
1211      {
1212          return updateType_;
1213      }
1214  
1215      virtual std::shared_ptr<RSNode> CreateRSNode() const;
OnRSTransition(TransitionType type)1216      virtual void OnRSTransition(TransitionType type) {}
IsTailRenderNode()1217      bool IsTailRenderNode() const
1218      {
1219          return isTailRenderNode_;
1220      }
1221      Offset GetPaintOffset() const;
HasGeometryProperties()1222      virtual bool HasGeometryProperties() const
1223      {
1224          return IsTailRenderNode();
1225      }
1226      void MarkNeedSyncGeometryProperties();
1227  
1228      bool hasSubWindow_ = false;
1229      bool needClip_ = false;
1230      WeakPtr<PipelineContext> context_;
1231      Size viewPort_;
1232      Point globalPoint_;
1233      Point coordinatePoint_;
1234      WeakPtr<V2::InspectorNode> inspector_;
1235      WeakPtr<AccessibilityNode> accessibilityNode_;
1236  
1237      // Used for RS extra case.
1238      bool isFirstNode_ = false;
1239  
1240      Rect touchRect_;                  // Self touch rect
1241      std::vector<Rect> touchRectList_; // Self and all children touch rect
1242      std::vector<DimensionRect> responseRegion_;
1243      std::vector<Rect> responseRegionList_;
1244      PositionParam positionParam_;
1245      uint8_t opacity_ = 255;
1246      Shadow shadow_;
1247  
1248      float windowBlurProgress_ = 0.0f;
1249      WindowBlurStyle windowBlurStyle_ = WindowBlurStyle::STYLE_BACKGROUND_SMALL_LIGHT;
1250      bool touchable_ = true;
1251      bool interceptTouchEvent_ = false;
1252      bool needWindowBlur_ = false;
1253      bool needUpdateAccessibility_ = true;
1254      bool disabled_ = false;
1255      bool isResponseRegion_ = false;
1256      HoverAnimationType hoverAnimationType_ = HoverAnimationType::UNKNOWN;
1257      int32_t minPlatformVersion_ = 0;
1258  
1259      MouseState mouseState_ = MouseState::NONE;
1260      SlipFactorSetting slipFactorSetting_;
1261  
1262      HoverAndPressCallback hoveAndPressCallback_;
1263  
1264      // hover or press color
1265      Color eventEffectColor_ = Color::TRANSPARENT;
1266      std::function<void(const std::string&)> onLayoutReady_;
1267  
1268      bool isAppOnShow_ = true;
1269      AnimationOption nonStrictOption_; // clear after transition done
1270      MotionPathOption motionPathOption_;
1271      RefPtr<V2::EventExtensions> eventExtensions_;
1272  
1273      // Compute multiSelect zone
1274      Rect ComputeSelectedZone(const Offset& startOffset, const Offset& endOffset);
1275  
1276  private:
AddDirtyRenderBoundaryNode()1277      void AddDirtyRenderBoundaryNode()
1278      {
1279          if (visible_ && !hidden_ && IsRepaintBoundary()) {
1280              auto pipelineContext = context_.Upgrade();
1281              if (pipelineContext == nullptr) {
1282                  return;
1283              }
1284              pipelineContext->AddDirtyRenderNode(AceType::Claim(this));
1285          }
1286      }
1287  
1288      void SetPositionInternal(const Offset& offset);
1289      bool InLayoutTransition() const;
1290      // Sync view hierarchy to RSNode
1291      void RSNodeAddChild(const RefPtr<RenderNode>& child);
1292      void MarkParentNeedRender() const;
1293      static std::shared_ptr<RSNode> ExtractExternalRSNode(const RefPtr<Component>& component);
1294  
1295      std::list<RefPtr<RenderNode>> hoverChildren_;
1296      std::list<RefPtr<RenderNode>> children_;
1297      std::string accessibilityText_;
1298      LayoutParam layoutParam_;
1299      Rect paintRect_;
1300      WeakPtr<RenderNode> parent_;
1301      int32_t depth_ = 0;
1302      bool needRender_ = false;
1303      bool needLayout_ = false;
1304      bool visible_ = true;
1305      bool takeBoundary_ = false;
1306      bool layoutParamChanged_ = false;
1307      bool pendingDispatchLayoutReady_ = false;
1308      bool disableTouchEvent_ = false;
1309      bool needUpdateTouchRect_ = false;
1310      bool hasShadow_ = false;
1311  
1312      double flexWeight_ = 0.0;
1313      int32_t displayIndex_ = 1;
1314      bool displayIndexSetted_ = false;
1315  
1316      double dipScale_ = 0.0;
1317  
1318      TextDirection textDirection_ { TextDirection::LTR };
1319      Offset selfOffset_ { 0, 0 };
1320  
1321      bool hidden_ = false;
1322      bool isIgnored_ = false;
1323      std::function<void()> onChangeCallback_;
1324      std::list<RefPtr<RenderNode>> disappearingNodes_;
1325      AnimatableDimension paintX_;
1326      AnimatableDimension paintY_;
1327      AnimatableDimension paintW_;
1328      AnimatableDimension paintH_;
1329      Size transitionPaintRectSize_;
1330      Rect nonStrictPaintRect_;
1331      bool isFirstSizeAssign_ = true;
1332      bool isFirstPositionAssign_ = true;
1333  
1334      // for container, this flag controls only the last child in touch area is consuming event.
1335      bool exclusiveEventForChild_ = false;
1336      int32_t zIndex_ = 0;
1337      bool isPercentSize_ = false;
1338      uint32_t updateType_ = 0;
1339  
1340      std::shared_ptr<RSNode> rsNode_ = nullptr;
1341      bool isHeadRenderNode_ = false;
1342      bool isTailRenderNode_ = false;
1343  
1344      bool isPaintGeometryTransition_ = false;
1345      bool isPaintOutOfParent_ = false;
1346  
1347      std::string restoreInfo_;
1348      bool isNotSiblingAddRecognizerToResult_ = true;
1349      HitTestMode hitTestMode_ = HitTestMode::HTMDEFAULT;
1350  
1351      ACE_DISALLOW_COPY_AND_MOVE(RenderNode);
1352  };
1353  
1354  } // namespace OHOS::Ace
1355  
1356  #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_RENDER_NODE_H
1357