text: /**
   * Licensed to the Apache Software Foundation (ASF) under one
   * or more contributor license agreements.  See the NOTICE file
   * distributed with this work for additional information
   * regarding copyright ownership.  The ASF licenses this file
   * to you under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance
   * with the License.  You may obtain a copy of the License at
   *
   *   http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing,
   * software distributed under the License is distributed on an
   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   * KIND, either express or implied.  See the License for the
   * specific language governing permissions and limitations
   * under the License.
   */
  #ifndef CORE_RENDER_NODE_RENDER_OBJECT_H_
  #define CORE_RENDER_NODE_RENDER_OBJECT_H_
  
  #include <functional>
  #include <map>
  #include <set>
  #include <string>
  
  #include "core/render/node/factory/render_object_interface.h"
  
  #define JSON_OBJECT_MARK_CHAR '{'
  #define JSON_ARRAY_MARK_CHAR '['
  
  #define convert_render_object_to_long(render) ((long)((intptr_t)render))
  
  #define convert_long_to_render_object(ptr) ((RenderObject *)((intptr_t)ptr))
  
  namespace WeexCore {
  
  class RenderObject;
  
  class RenderPage;
  
  typedef enum StyleType {
    kTypeStyle,
    kTypeLayout,
    kTypeMargin,
    kTypePadding,
    kTypeBorder,
    kTypeInheritableLayout
  } StyleType;
  
  class RenderObject : public IRenderObject {
    friend class RenderPage;
  
   public:
    void LayoutBeforeImpl();
  
    void LayoutPlatformImpl();
      
    void LayoutAfterImpl();
  
    void CopyFrom(RenderObject *src);
  
    RenderObject* RichtextParent();
  
    bool hasShadow(const RenderObject* shadow) const;
  
    void MapInsertOrAssign(std::map<std::string, std::string> *targetMap,
                           const std::string &key, const std::string &value);
  
    bool ViewInit();
  
    virtual std::map<std::string, std::string> *GetDefaultStyle() {
      return nullptr;
    }
  
    virtual std::map<std::string, std::string> *GetDefaultAttr() {
      return nullptr;
    }
  
   protected:
    bool UpdateStyleInternal(const std::string key, const std::string value,
                             float fallback, std::function<void(float)> functor);
  
   public:
    RenderObject();
  
    virtual ~RenderObject();
  
    void BindMeasureFunc();
  
    void OnLayoutBefore();
      
    void OnLayoutPlatform();
  
    void OnLayoutAfter(float width, float height);
  
    virtual StyleType ApplyStyle(const std::string &key, const std::string &value,
                                 const bool updating);
  
    void ApplyDefaultStyle(bool reserve);
  
    void ApplyDefaultAttr();
  
    Index IndexOf(const RenderObject *render);
  
    virtual int AddRenderObject(int index, RenderObject *child);
  
    float GetViewPortWidth();
  
    const std::string GetAttr(const std::string &key);
  
    const std::string GetStyle(const std::string &key);
  
    RenderPage *GetRenderPage();
  
    virtual void UpdateAttr(std::string key, std::string value);
  
    virtual StyleType UpdateStyle(std::string key, std::string value);
    
    void MergeStyles(std::vector<std::pair<std::string, std::string>> *src);
  
    bool IsAppendTree();
  
    RenderObject *GetChild(const Index &index);
  
    void RemoveRenderObject(RenderObject *child);
  
    virtual void AddAttr(std::string key, std::string value);
  
    StyleType AddStyle(std::string key, std::string value, bool reserve);
  
    void AddEvent(std::string event);
  
    void RemoveEvent(const std::string &event);
  
   public:
    inline void set_parent_render(RenderObject *render) {
      this->parent_render_ = render;
    }
  
    inline RenderObject *parent_render() { return this->parent_render_; }
  
    const std::vector<RenderObject*>& get_shadow_objects() const {return shadow_objects_;}
  
    inline std::map<std::string, std::string> *styles() const {
      return this->styles_;
    }
  
    inline std::map<std::string, std::string> *attributes() const {
      return this->attributes_;
    }
  
    inline std::set<std::string> *events() const { return this->events_; }
  
    inline void set_is_root_render() { this->is_root_render_ = true; }
  
    inline bool is_root_render() { return this->is_root_render_; }
  
    inline bool is_sticky() { return this->is_sticky_; }
  
    bool is_richtext_child() const {return is_richtext_child_;}
  
    void set_is_richtext_child(const bool is_richtext_child) {is_richtext_child_ = is_richtext_child;}
  
   private:
    RenderObject *parent_render_;
    std::vector<RenderObject*> shadow_objects_;
    std::map<std::string, std::string> *styles_;
    std::map<std::string, std::string> *attributes_;
    std::set<std::string> *events_;
    bool is_root_render_;
    bool is_sticky_ = false;
    bool is_richtext_child_ = false;
  };
  }  // namespace WeexCore
  #endif  // CORE_RENDER_NODE_RENDER_OBJECT_H_
  