/*
 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
 *           (C) 2000 Dirk Mueller (mueller@kde.org)
 *           (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc.
 *               All rights reserved.
 * Copyright (C) 2009 Google Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_OBJECT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_OBJECT_H_

#include "base/auto_reset.h"
#include "base/macros.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/document_lifecycle.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/html_names.h"
#include "third_party/blink/renderer/core/layout/api/hit_test_action.h"
#include "third_party/blink/renderer/core/layout/api/selection_state.h"
#include "third_party/blink/renderer/core/layout/hit_test_result.h"
#include "third_party/blink/renderer/core/layout/layout_object_child_list.h"
#include "third_party/blink/renderer/core/layout/map_coordinates_flags.h"
#include "third_party/blink/renderer/core/layout/subtree_layout_scope.h"
#include "third_party/blink/renderer/core/loader/resource/image_resource_observer.h"
#include "third_party/blink/renderer/core/paint/compositing/compositing_state.h"
#include "third_party/blink/renderer/core/paint/fragment_data.h"
#include "third_party/blink/renderer/core/paint/paint_phase.h"
#include "third_party/blink/renderer/core/style/computed_style.h"
#include "third_party/blink/renderer/core/style/style_difference.h"
#include "third_party/blink/renderer/platform/geometry/float_quad.h"
#include "third_party/blink/renderer/platform/geometry/layout_rect.h"
#include "third_party/blink/renderer/platform/graphics/compositing_reasons.h"
#include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h"
#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h"
#include "third_party/blink/renderer/platform/graphics/touch_action_rect.h"
#include "third_party/blink/renderer/platform/transforms/transform_state.h"
#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"

namespace blink {

class AffineTransform;
class Cursor;
class HitTestLocation;
class HitTestRequest;
class InlineBox;
class LayoutBoxModelObject;
class LayoutBlock;
class LayoutBlockFlow;
class LayoutFlowThread;
class LayoutGeometryMap;
class LayoutMultiColumnSpannerPlaceholder;
class LayoutView;
class LocalFrameView;
class NGPhysicalBoxFragment;
class ObjectPaintProperties;
class PaintLayer;
class PseudoStyleRequest;

struct PaintInfo;
struct PaintInvalidatorContext;
struct WebScrollIntoViewParams;

enum VisualRectFlags {
  kDefaultVisualRectFlags = 0,
  kEdgeInclusive = 1,
  kUseGeometryMapper = 2,  // Use the GeometryMapper fast-path, if possible.
};

enum CursorDirective { kSetCursorBasedOnStyle, kSetCursor, kDoNotSetCursor };

enum HitTestFilter { kHitTestAll, kHitTestSelf, kHitTestDescendants };

enum MarkingBehavior {
  kMarkOnlyThis,
  kMarkContainerChain,
};

enum ScheduleRelayoutBehavior { kScheduleRelayout, kDontScheduleRelayout };

struct AnnotatedRegionValue {
  DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
  bool operator==(const AnnotatedRegionValue& o) const {
    return draggable == o.draggable && bounds == o.bounds;
  }

  LayoutRect bounds;
  bool draggable;
};

#ifndef NDEBUG
const int kShowTreeCharacterOffset = 39;
#endif

// LayoutObject is the base class for all layout tree objects.
//
// LayoutObjects form a tree structure that is a close mapping of the DOM tree.
// The root of the LayoutObject tree is the LayoutView, which is the
// LayoutObject associated with the Document.
//
// Some LayoutObjects don't have an associated Node and are called "anonymous"
// (see the constructor below). Anonymous LayoutObjects exist for several
// purposes but are usually required by CSS. A good example is anonymous table
// parts (see LayoutTable for the expected structure). Anonymous LayoutObjects
// are generated when a new child is added to the tree in addChild(). See the
// function for some important information on this.
//
// Also some Node don't have an associated LayoutObjects e.g. if display: none
// or display: contents is set. For more detail, see LayoutObject::createObject
// that creates the right LayoutObject based on the style.
//
// Because the SVG and CSS classes both inherit from this object, functions can
// belong to either realm and sometimes to both.
//
// The purpose of the layout tree is to do layout (aka reflow) and store its
// results for painting and hit-testing. Layout is the process of sizing and
// positioning Nodes on the page. In Blink, layouts always start from a relayout
// boundary (see objectIsRelayoutBoundary in LayoutObject.cpp). As such, we
// need to mark the ancestors all the way to the enclosing relayout boundary in
// order to do a correct layout.
//
// Due to the high cost of layout, a lot of effort is done to avoid doing full
// layouts of nodes. This is why there are several types of layout available to
// bypass the complex operations. See the comments on the layout booleans in
// LayoutObjectBitfields below about the different layouts.
//
// To save memory, especially for the common child class LayoutText,
// LayoutObject doesn't provide storage for children. Descendant classes that do
// allow children have to have a LayoutObjectChildList member that stores the
// actual children and override virtualChildren().
//
// LayoutObject is an ImageResourceObserver, which means that it gets notified
// when associated images are changed. This is used for 2 main use cases:
// - reply to 'background-image' as we need to invalidate the background in this
//   case.
//   (See https://drafts.csswg.org/css-backgrounds-3/#the-background-image)
// - image (LayoutImage, LayoutSVGImage) or video (LayoutVideo) objects that are
//   placeholders for displaying them.
//
//
// ***** LIFETIME *****
//
// LayoutObjects are fully owned by their associated DOM node. In other words,
// it's the DOM node's responsibility to free its LayoutObject, this is why
// LayoutObjects are not and SHOULD NOT be RefCounted.
//
// LayoutObjects are created during the DOM attachment. This phase computes
// the style and create the LayoutObject associated with the Node (see
// Node::attachLayoutTree). LayoutObjects are destructed during detachment (see
// Node::detachLayoutTree), which can happen when the DOM node is removed from
// the
// DOM tree, during page tear down or when the style is changed to contain
// 'display: none'.
//
// Anonymous LayoutObjects are owned by their enclosing DOM node. This means
// that if the DOM node is detached, it has to destroy any anonymous
// descendants. This is done in LayoutObject::destroy().
//
// Note that for correctness, destroy() is expected to clean any anonymous
// wrappers as sequences of insertion / removal could make them visible to
// the page. This is done by LayoutObject::destroyAndCleanupAnonymousWrappers()
// which is the preferred way to destroy an object.
//
//
// ***** INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS *****
// The preferred logical widths are the intrinsic sizes of this element
// (https://drafts.csswg.org/css-sizing-3/#intrinsic). Intrinsic sizes depend
// mostly on the content and a limited set of style properties (e.g. any
// font-related property for text, 'min-width'/'max-width',
// 'min-height'/'max-height').
//
// Those widths are used to determine the final layout logical width, which
// depends on the layout algorithm used and the available logical width.
//
// LayoutObject only has getters for the widths (MinPreferredLogicalWidth and
// MaxPreferredLogicalWidth). However the storage for them is in LayoutBox (see
// min_preferred_logical_width_ and max_preferred_logical_width_). This is
// because only boxes implementing the full box model have a need for them.
// Because LayoutBlockFlow's intrinsic widths rely on the underlying text
// content, LayoutBlockFlow may call LayoutText::ComputePreferredLogicalWidths.
//
// The 2 widths are computed lazily during layout when the getters are called.
// The computation is done by calling ComputePreferredLogicalWidths() behind the
// scene. The boolean used to control the lazy recomputation is
// PreferredLogicalWidthsDirty.
//
// See the individual getters below for more details about what each width is.
class CORE_EXPORT LayoutObject : public ImageResourceObserver,
                                 public DisplayItemClient {
  friend class LayoutObjectChildList;
  FRIEND_TEST_ALL_PREFIXES(LayoutObjectTest, MutableForPaintingClearPaintFlags);
  friend class VisualRectMappingTest;

 public:
  // Anonymous objects should pass the document as their node, and they will
  // then automatically be marked as anonymous in the constructor.
  explicit LayoutObject(Node*);
  ~LayoutObject() override;

  // Returns the name of the layout object.
  virtual const char* GetName() const = 0;

  // Returns the decorated name used by run-layout-tests. The name contains the
  // name of the object along with extra information about the layout object
  // state (e.g. positioning).
  String DecoratedName() const;

  // This is an inexact determination of whether the display of this objects is
  // altered or obscured by CSS effects.
  bool HasDistortingVisualEffects() const;

  // Returns false iff this object or one of its ancestors has opacity:0.
  bool HasNonZeroEffectiveOpacity() const;

  // DisplayItemClient methods.

  // Do not call VisualRect directly outside of the DisplayItemClient
  // interface, use a per-fragment one on FragmentData instead.
 private:
  LayoutRect VisualRect() const final;

  void ClearPartialInvalidationVisualRect() const final {
    DCHECK(RuntimeEnabledFeatures::SlimmingPaintV175Enabled());
    return GetMutableForPainting()
        .FirstFragment()
        .SetPartialInvalidationVisualRect(LayoutRect());
  }

 public:
  LayoutRect PartialInvalidationVisualRect() const final {
    return FirstFragment().PartialInvalidationVisualRect();
  }

  String DebugName() const final;

  LayoutObject* Parent() const { return parent_; }
  bool IsDescendantOf(const LayoutObject*) const;

  LayoutObject* PreviousSibling() const { return previous_; }
  LayoutObject* NextSibling() const { return next_; }

  DISABLE_CFI_PERF
  LayoutObject* SlowFirstChild() const {
    if (const LayoutObjectChildList* children = VirtualChildren())
      return children->FirstChild();
    return nullptr;
  }
  LayoutObject* SlowLastChild() const {
    if (const LayoutObjectChildList* children = VirtualChildren())
      return children->LastChild();
    return nullptr;
  }

  // See comment in the class description as to why there is no child.
  virtual LayoutObjectChildList* VirtualChildren() { return nullptr; }
  virtual const LayoutObjectChildList* VirtualChildren() const {
    return nullptr;
  }

  LayoutObject* NextInPreOrder() const;
  LayoutObject* NextInPreOrder(const LayoutObject* stay_within) const;
  LayoutObject* NextInPreOrderAfterChildren() const;
  LayoutObject* NextInPreOrderAfterChildren(
      const LayoutObject* stay_within) const;
  LayoutObject* PreviousInPreOrder() const;
  LayoutObject* PreviousInPreOrder(const LayoutObject* stay_within) const;

  LayoutObject* LastLeafChild() const;

  // The following functions are used when the layout tree hierarchy changes to
  // make sure layers get properly added and removed. Since containership can be
  // implemented by any subclass, and since a hierarchy can contain a mixture of
  // boxes and other object types, these functions need to be in the base class.
  PaintLayer* EnclosingLayer() const;
  void AddLayers(PaintLayer* parent_layer);
  void RemoveLayers(PaintLayer* parent_layer);
  void MoveLayers(PaintLayer* old_parent, PaintLayer* new_parent);
  PaintLayer* FindNextLayer(PaintLayer* parent_layer,
                            LayoutObject* start_point,
                            bool check_parent = true);

  // Returns the layer that will paint this object. During paint invalidation,
  // we should use the faster PaintInvalidatorContext::painting_layer instead.
  PaintLayer* PaintingLayer() const;

  bool IsFixedPositionObjectInPagedMedia() const;

  // Takes the given rect, assumed to be in absolute coordinates, and scrolls
  // this Element and all it's containers such that the child content of this
  // Element at that rect is visible in the viewport. Returns the new absolute
  // rect of the target rect after all scrolls are completed, in the coordinate
  // space of the local root frame.
  LayoutRect ScrollRectToVisible(const LayoutRect&,
                                 const WebScrollIntoViewParams&);

  // Convenience function for getting to the nearest enclosing box of a
  // LayoutObject.
  LayoutBox* EnclosingBox() const;

  LayoutBox* EnclosingScrollableBox() const;

  // Returns |EnclosingBox()| if it's a LayoutNGBlockFlow, or nullptr otherwise.
  LayoutBlockFlow* EnclosingNGBlockFlow() const;

  // Returns |NGPhysicalBoxFragment| for |EnclosingNGBlockFlow()| or nullptr
  // otherwise.
  const NGPhysicalBoxFragment* EnclosingBlockFlowFragment() const;

  // Function to return our enclosing flow thread if we are contained inside
  // one. This function follows the containing block chain.
  LayoutFlowThread* FlowThreadContainingBlock() const {
    if (!IsInsideFlowThread())
      return nullptr;
    return LocateFlowThreadContainingBlock();
  }

#if DCHECK_IS_ON()
  void SetHasAXObject(bool flag) { has_ax_object_ = flag; }
  bool HasAXObject() const { return has_ax_object_; }

  // Helper class forbidding calls to setNeedsLayout() during its lifetime.
  class SetLayoutNeededForbiddenScope {
   public:
    explicit SetLayoutNeededForbiddenScope(LayoutObject&);
    ~SetLayoutNeededForbiddenScope();

   private:
    LayoutObject& layout_object_;
    bool preexisting_forbidden_;
  };

  void AssertLaidOut() const {
#ifndef NDEBUG
    if (NeedsLayout())
      ShowLayoutTreeForThis();
#endif
    SECURITY_DCHECK(!NeedsLayout());
  }

  void AssertSubtreeIsLaidOut() const {
    for (const LayoutObject* layout_object = this; layout_object;
         layout_object = layout_object->NextInPreOrder())
      layout_object->AssertLaidOut();
  }

  void AssertClearedPaintInvalidationFlags() const {
#ifndef NDEBUG
    if (PaintInvalidationStateIsDirty()) {
      ShowLayoutTreeForThis();
      NOTREACHED();
    }
#endif
  }

  void AssertSubtreeClearedPaintInvalidationFlags() const {
    for (const LayoutObject* layout_object = this; layout_object;
         layout_object = layout_object->NextInPreOrder())
      layout_object->AssertClearedPaintInvalidationFlags();
  }

#endif

  // LayoutObject tree manipulation
  //////////////////////////////////////////
  DISABLE_CFI_PERF virtual bool CanHaveChildren() const {
    return VirtualChildren();
  }
  virtual bool IsChildAllowed(LayoutObject*, const ComputedStyle&) const {
    return true;
  }

  // This function is called whenever a child is inserted under |this|.
  //
  // The main purpose of this function is to generate a consistent layout
  // tree, which means generating the missing anonymous objects. Most of the
  // time there'll be no anonymous objects to generate.
  //
  // The following invariants are true on the input:
  // - |newChild->node()| is a child of |node()|, if |this| is not
  //   anonymous. If |this| is anonymous, the invariant holds with the
  //   enclosing non-anonymous LayoutObject.
  // - |beforeChild->node()| (if |beforeChild| is provided and not anonymous)
  //   is a sibling of |newChild->node()| (if |newChild| is not anonymous).
  //
  // The reason for these invariants is that insertions are performed on the
  // DOM tree. Because the layout tree may insert extra anonymous renderers,
  // the previous invariants are only guaranteed for the DOM tree. In
  // particular, |beforeChild| may not be a direct child when it's wrapped in
  // anonymous wrappers.
  //
  // Classes inserting anonymous LayoutObjects in the tree are expected to
  // check for the anonymous wrapper case with:
  //                    beforeChild->parent() != this
  //
  // The usage of |child/parent/sibling| in this comment actually means
  // |child/parent/sibling| in a flat tree because a layout tree is generated
  // from a structure of a flat tree if Shadow DOM is used.
  // See LayoutTreeBuilderTraversal and FlatTreeTraversal.
  //
  // See LayoutTable::addChild and LayoutBlock::addChild.
  // TODO(jchaffraix): |newChild| cannot be nullptr and should be a reference.
  virtual void AddChild(LayoutObject* new_child,
                        LayoutObject* before_child = nullptr);
  virtual void AddChildIgnoringContinuation(
      LayoutObject* new_child,
      LayoutObject* before_child = nullptr) {
    return AddChild(new_child, before_child);
  }
  virtual void RemoveChild(LayoutObject*);
  virtual bool CreatesAnonymousWrapper() const { return false; }
  //////////////////////////////////////////

  // Sets the parent of this object but doesn't add it as a child of the parent.
  void SetDangerousOneWayParent(LayoutObject*);

  UniqueObjectId UniqueId() const { return fragment_.UniqueId(); }

  inline bool ShouldApplyPaintContainment() const {
    return StyleRef().ContainsPaint() &&
           (!IsInline() || IsAtomicInlineLevel()) && !IsRubyText() &&
           (!IsTablePart() || IsLayoutBlockFlow());
  }

  inline bool ShouldApplyLayoutContainment() const {
    return StyleRef().ContainsLayout() &&
           (!IsInline() || IsAtomicInlineLevel()) && !IsRubyText() &&
           (!IsTablePart() || IsLayoutBlockFlow());
  }

  inline bool ShouldApplySizeContainment() const {
    return StyleRef().ContainsSize() &&
           (!IsInline() || IsAtomicInlineLevel()) && !IsRubyText() &&
           (!IsTablePart() || IsTableCaption()) && !IsTable();
  }

 private:
  //////////////////////////////////////////
  // Helper functions. Dangerous to use!
  void SetPreviousSibling(LayoutObject* previous) { previous_ = previous; }
  void SetNextSibling(LayoutObject* next) { next_ = next; }
  void SetParent(LayoutObject* parent) {
    parent_ = parent;

    // Only update if our flow thread state is different from our new parent and
    // if we're not a LayoutFlowThread.
    // A LayoutFlowThread is always considered to be inside itself, so it never
    // has to change its state in response to parent changes.
    bool inside_flow_thread = parent && parent->IsInsideFlowThread();
    if (inside_flow_thread != IsInsideFlowThread() && !IsLayoutFlowThread())
      SetIsInsideFlowThreadIncludingDescendants(inside_flow_thread);
  }

  //////////////////////////////////////////
 private:
#if DCHECK_IS_ON()
  bool IsSetNeedsLayoutForbidden() const { return set_needs_layout_forbidden_; }
  void SetNeedsLayoutIsForbidden(bool flag) {
    set_needs_layout_forbidden_ = flag;
  }
#endif

  void AddAbsoluteRectForLayer(IntRect& result);
  bool RequiresAnonymousTableWrappers(const LayoutObject*) const;

 public:
  // Dump this layout object to the specified string builder.
  void DumpLayoutObject(StringBuilder&,
                        bool dump_address,
                        unsigned show_tree_character_offset) const;

#ifndef NDEBUG
  void ShowTreeForThis() const;
  void ShowLayoutTreeForThis() const;
  void ShowLineTreeForThis() const;
  void ShowLayoutObject() const;

  // Dump the subtree established by this layout object to the specified string
  // builder. There will be one object per line, and descendants will be
  // indented according to their tree level. The optional "marked_foo"
  // parameters can be used to mark up to two objects in the subtree with a
  // label.
  void DumpLayoutTreeAndMark(StringBuilder&,
                             const LayoutObject* marked_object1 = nullptr,
                             const char* marked_label1 = nullptr,
                             const LayoutObject* marked_object2 = nullptr,
                             const char* marked_label2 = nullptr,
                             unsigned depth = 0) const;
#endif

  // This function is used to create the appropriate LayoutObject based
  // on the style, in particular 'display' and 'content'.
  // "display: none" or "display: contents" are the only times this function
  // will return nullptr.
  //
  // For renderer creation, the inline-* values create the same renderer
  // as the non-inline version. The difference is that inline-* sets
  // is_inline_ during initialization. This means that
  // "display: inline-table" creates a LayoutTable, like "display: table".
  //
  // Ideally every Element::createLayoutObject would call this function to
  // respond to 'display' but there are deep rooted assumptions about
  // which LayoutObject is created on a fair number of Elements. This
  // function also doesn't handle the default association between a tag
  // and its renderer (e.g. <iframe> creates a LayoutIFrame even if the
  // initial 'display' value is inline).
  static LayoutObject* CreateObject(Element*, const ComputedStyle&);

  // LayoutObjects are allocated out of the rendering partition.
  void* operator new(size_t);
  void operator delete(void*);

  bool IsPseudoElement() const {
    return GetNode() && GetNode()->IsPseudoElement();
  }

  virtual bool IsBoxModelObject() const { return false; }
  bool IsBR() const { return IsOfType(kLayoutObjectBr); }
  bool IsCanvas() const { return IsOfType(kLayoutObjectCanvas); }
  bool IsCounter() const { return IsOfType(kLayoutObjectCounter); }
  bool IsDetailsMarker() const { return IsOfType(kLayoutObjectDetailsMarker); }
  bool IsEmbeddedObject() const {
    return IsOfType(kLayoutObjectEmbeddedObject);
  }
  bool IsFieldset() const { return IsOfType(kLayoutObjectFieldset); }
  bool IsFileUploadControl() const {
    return IsOfType(kLayoutObjectFileUploadControl);
  }
  bool IsFrame() const { return IsOfType(kLayoutObjectFrame); }
  bool IsFrameSet() const { return IsOfType(kLayoutObjectFrameSet); }
  bool IsLayoutNGBlockFlow() const {
    return IsOfType(kLayoutObjectNGBlockFlow);
  }
  bool IsLayoutNGFlexibleBox() const {
    return IsOfType(kLayoutObjectNGFlexibleBox);
  }
  bool IsLayoutNGMixin() const { return IsOfType(kLayoutObjectNGMixin); }
  bool IsLayoutNGListItem() const { return IsOfType(kLayoutObjectNGListItem); }
  bool IsLayoutNGListMarker() const {
    return IsOfType(kLayoutObjectNGListMarker);
  }
  bool IsLayoutNGListMarkerImage() const {
    return IsOfType(kLayoutObjectNGListMarkerImage);
  }
  bool IsLayoutNGText() const { return IsOfType(kLayoutObjectNGText); }
  bool IsLayoutTableCol() const {
    return IsOfType(kLayoutObjectLayoutTableCol);
  }
  bool IsListBox() const { return IsOfType(kLayoutObjectListBox); }
  bool IsListItem() const { return IsOfType(kLayoutObjectListItem); }
  bool IsListMarker() const { return IsOfType(kLayoutObjectListMarker); }
  bool IsMedia() const { return IsOfType(kLayoutObjectMedia); }
  bool IsMenuList() const { return IsOfType(kLayoutObjectMenuList); }
  bool IsProgress() const { return IsOfType(kLayoutObjectProgress); }
  bool IsQuote() const { return IsOfType(kLayoutObjectQuote); }
  bool IsLayoutButton() const { return IsOfType(kLayoutObjectLayoutButton); }
  bool IsLayoutCustom() const { return IsOfType(kLayoutObjectLayoutCustom); }
  bool IsLayoutGrid() const { return IsOfType(kLayoutObjectLayoutGrid); }
  bool IsLayoutIFrame() const { return IsOfType(kLayoutObjectLayoutIFrame); }
  bool IsLayoutImage() const { return IsOfType(kLayoutObjectLayoutImage); }
  bool IsLayoutMultiColumnSet() const {
    return IsOfType(kLayoutObjectLayoutMultiColumnSet);
  }
  bool IsLayoutMultiColumnSpannerPlaceholder() const {
    return IsOfType(kLayoutObjectLayoutMultiColumnSpannerPlaceholder);
  }
  bool IsLayoutReplaced() const {
    return IsOfType(kLayoutObjectLayoutReplaced);
  }
  bool IsLayoutScrollbarPart() const {
    return IsOfType(kLayoutObjectLayoutScrollbarPart);
  }
  bool IsLayoutView() const { return IsOfType(kLayoutObjectLayoutView); }
  bool IsRuby() const { return IsOfType(kLayoutObjectRuby); }
  bool IsRubyBase() const { return IsOfType(kLayoutObjectRubyBase); }
  bool IsRubyRun() const { return IsOfType(kLayoutObjectRubyRun); }
  bool IsRubyText() const { return IsOfType(kLayoutObjectRubyText); }
  bool IsSlider() const { return IsOfType(kLayoutObjectSlider); }
  bool IsSliderThumb() const { return IsOfType(kLayoutObjectSliderThumb); }
  bool IsTable() const { return IsOfType(kLayoutObjectTable); }
  bool IsTableCaption() const { return IsOfType(kLayoutObjectTableCaption); }
  bool IsTableCell() const { return IsOfType(kLayoutObjectTableCell); }
  bool IsTableRow() const { return IsOfType(kLayoutObjectTableRow); }
  bool IsTableSection() const { return IsOfType(kLayoutObjectTableSection); }
  bool IsTextArea() const { return IsOfType(kLayoutObjectTextArea); }
  bool IsTextControl() const { return IsOfType(kLayoutObjectTextControl); }
  bool IsTextField() const { return IsOfType(kLayoutObjectTextField); }
  bool IsVideo() const { return IsOfType(kLayoutObjectVideo); }
  bool IsWidget() const { return IsOfType(kLayoutObjectWidget); }

  virtual bool IsImage() const { return false; }

  virtual bool IsInlineBlockOrInlineTable() const { return false; }
  virtual bool IsLayoutBlock() const { return false; }
  virtual bool IsLayoutBlockFlow() const { return false; }
  virtual bool IsLayoutFlowThread() const { return false; }
  virtual bool IsLayoutInline() const { return false; }
  virtual bool IsLayoutEmbeddedContent() const { return false; }

  bool IsDocumentElement() const {
    return GetDocument().documentElement() == node_;
  }
  // isBody is called from LayoutBox::styleWillChange and is thus quite hot.
  bool IsBody() const {
    return GetNode() && GetNode()->HasTagName(HTMLNames::bodyTag);
  }
  bool IsHR() const;

  bool IsTablePart() const {
    return IsTableCell() || IsLayoutTableCol() || IsTableCaption() ||
           IsTableRow() || IsTableSection();
  }

  inline bool IsBeforeContent() const;
  inline bool IsAfterContent() const;
  inline bool IsBeforeOrAfterContent() const;
  static inline bool IsAfterContent(const LayoutObject* obj) {
    return obj && obj->IsAfterContent();
  }

  bool HasCounterNodeMap() const { return bitfields_.HasCounterNodeMap(); }
  void SetHasCounterNodeMap(bool has_counter_node_map) {
    bitfields_.SetHasCounterNodeMap(has_counter_node_map);
  }

  bool IsTruncated() const { return bitfields_.IsTruncated(); }
  void SetIsTruncated(bool is_truncated) {
    bitfields_.SetIsTruncated(is_truncated);
  }

  bool EverHadLayout() const { return bitfields_.EverHadLayout(); }

  bool ChildrenInline() const { return bitfields_.ChildrenInline(); }
  void SetChildrenInline(bool b) { bitfields_.SetChildrenInline(b); }

  bool AlwaysCreateLineBoxesForLayoutInline() const {
    DCHECK(IsLayoutInline());
    return bitfields_.AlwaysCreateLineBoxesForLayoutInline();
  }
  void SetAlwaysCreateLineBoxesForLayoutInline(bool always_create_line_boxes) {
    DCHECK(IsLayoutInline());
    bitfields_.SetAlwaysCreateLineBoxesForLayoutInline(
        always_create_line_boxes);
  }

  bool AncestorLineBoxDirty() const {
    return bitfields_.AncestorLineBoxDirty();
  }
  void SetAncestorLineBoxDirty(bool value = true) {
    bitfields_.SetAncestorLineBoxDirty(value);
    if (value)
      SetNeedsLayoutAndFullPaintInvalidation(
          LayoutInvalidationReason::kLineBoxesChanged);
  }

  void SetIsInsideFlowThreadIncludingDescendants(bool);

  bool IsInsideFlowThread() const { return bitfields_.IsInsideFlowThread(); }
  void SetIsInsideFlowThread(bool inside_flow_thread) {
    bitfields_.SetIsInsideFlowThread(inside_flow_thread);
  }

  // FIXME: Until all SVG layoutObjects can be subclasses of
  // LayoutSVGModelObject we have to add SVG layoutObject methods to
  // LayoutObject with an NOTREACHED() default implementation.
  bool IsSVG() const { return IsOfType(kLayoutObjectSVG); }
  bool IsSVGRoot() const { return IsOfType(kLayoutObjectSVGRoot); }
  bool IsSVGChild() const { return IsSVG() && !IsSVGRoot(); }
  bool IsSVGContainer() const { return IsOfType(kLayoutObjectSVGContainer); }
  bool IsSVGTransformableContainer() const {
    return IsOfType(kLayoutObjectSVGTransformableContainer);
  }
  bool IsSVGViewportContainer() const {
    return IsOfType(kLayoutObjectSVGViewportContainer);
  }
  bool IsSVGHiddenContainer() const {
    return IsOfType(kLayoutObjectSVGHiddenContainer);
  }
  bool IsSVGShape() const { return IsOfType(kLayoutObjectSVGShape); }
  bool IsSVGText() const { return IsOfType(kLayoutObjectSVGText); }
  bool IsSVGTextPath() const { return IsOfType(kLayoutObjectSVGTextPath); }
  bool IsSVGInline() const { return IsOfType(kLayoutObjectSVGInline); }
  bool IsSVGInlineText() const { return IsOfType(kLayoutObjectSVGInlineText); }
  bool IsSVGImage() const { return IsOfType(kLayoutObjectSVGImage); }
  bool IsSVGForeignObject() const {
    return IsOfType(kLayoutObjectSVGForeignObject);
  }
  bool IsSVGResourceContainer() const {
    return IsOfType(kLayoutObjectSVGResourceContainer);
  }
  bool IsSVGResourceFilter() const {
    return IsOfType(kLayoutObjectSVGResourceFilter);
  }
  bool IsSVGResourceFilterPrimitive() const {
    return IsOfType(kLayoutObjectSVGResourceFilterPrimitive);
  }

  // FIXME: Those belong into a SVG specific base-class for all layoutObjects
  // (see above). Unfortunately we don't have such a class yet, because it's not
  // possible for all layoutObjects to inherit from LayoutSVGObject ->
  // LayoutObject (some need LayoutBlock inheritance for instance)
  virtual void SetNeedsTransformUpdate() {}
  virtual void SetNeedsBoundariesUpdate();

  bool IsBlendingAllowed() const {
    return !IsSVG() || (IsSVGContainer() && !IsSVGHiddenContainer()) ||
           IsSVGShape() || IsSVGImage() || IsSVGText();
  }
  virtual bool HasNonIsolatedBlendingDescendants() const {
    // This is only implemented for layout objects that containt SVG flow.
    // For HTML/CSS layout objects, use the PaintLayer version instead.
    DCHECK(IsSVG());
    return false;
  }
  enum DescendantIsolationState {
    kDescendantIsolationRequired,
    kDescendantIsolationNeedsUpdate,
  };
  virtual void DescendantIsolationRequirementsChanged(
      DescendantIsolationState) {}

  // Per SVG 1.1 objectBoundingBox ignores clipping, masking, filter effects,
  // opacity and stroke-width.
  // This is used for all computation of objectBoundingBox relative units and by
  // SVGGraphicsElement::getBBox().
  // NOTE: Markers are not specifically ignored here by SVG 1.1 spec, but we
  // ignore them since stroke-width is ignored (and marker size can depend on
  // stroke-width). objectBoundingBox is returned local coordinates.
  // The name objectBoundingBox is taken from the SVG 1.1 spec.
  virtual FloatRect ObjectBoundingBox() const;
  virtual FloatRect StrokeBoundingBox() const;

  // Returns the smallest rectangle enclosing all of the painted content
  // respecting clipping, masking, filters, opacity, stroke-width and markers.
  // The local SVG coordinate space is the space where localSVGTransform
  // applies. For SVG objects defining viewports (e.g.
  // LayoutSVGViewportContainer and  LayoutSVGResourceMarker), the local SVG
  // coordinate space is the viewport space.
  virtual FloatRect VisualRectInLocalSVGCoordinates() const;

  // This returns the transform applying to the local SVG coordinate space,
  // which combines the CSS transform properties and animation motion transform.
  // See SVGElement::calculateTransform().
  // Most callsites want localToSVGParentTransform() instead.
  virtual AffineTransform LocalSVGTransform() const;

  // Returns the full transform mapping from local coordinates to parent's local
  // coordinates. For most SVG objects, this is the same as localSVGTransform.
  // For SVG objects defining viewports (see visualRectInLocalSVGCoordinates),
  // this includes any viewport transforms and x/y offsets as well as
  // localSVGTransform.
  virtual AffineTransform LocalToSVGParentTransform() const {
    return LocalSVGTransform();
  }

  // SVG uses FloatPoint precise hit testing, and passes the point in parent
  // coordinates instead of in paint invalidation container coordinates.
  // Eventually the rest of the layout tree will move to a similar model.
  virtual bool NodeAtFloatPoint(HitTestResult&,
                                const FloatPoint& point_in_parent,
                                HitTestAction);

  // End of SVG-specific methods.

  bool IsAnonymous() const { return bitfields_.IsAnonymous(); }
  bool IsAnonymousBlock() const {
    // This function is kept in sync with anonymous block creation conditions in
    // LayoutBlock::createAnonymousBlock(). This includes creating an anonymous
    // LayoutBlock having a BLOCK or BOX display. Other classes such as
    // LayoutTextFragment are not LayoutBlocks and will return false.
    // See https://bugs.webkit.org/show_bug.cgi?id=56709.
    return IsAnonymous() &&
           (StyleRef().Display() == EDisplay::kBlock ||
            StyleRef().Display() == EDisplay::kWebkitBox) &&
           StyleRef().StyleType() == kPseudoIdNone && IsLayoutBlock() &&
           !IsListMarker() && !IsLayoutFlowThread() &&
           !IsLayoutMultiColumnSet();
  }
  bool IsElementContinuation() const {
    return GetNode() && GetNode()->GetLayoutObject() != this;
  }
  bool IsInlineElementContinuation() const {
    return IsElementContinuation() && IsInline();
  }
  virtual LayoutBoxModelObject* VirtualContinuation() const { return nullptr; }

  bool IsFloating() const { return bitfields_.Floating(); }

  bool IsFloatingWithNonContainingBlockParent() const {
    return IsFloating() && Parent() && !Parent()->IsLayoutBlockFlow();
  }

  // absolute or fixed positioning
  bool IsOutOfFlowPositioned() const {
    return bitfields_.IsOutOfFlowPositioned();
  }
  // relative or sticky positioning
  bool IsInFlowPositioned() const { return bitfields_.IsInFlowPositioned(); }
  bool IsRelPositioned() const { return bitfields_.IsRelPositioned(); }
  bool IsStickyPositioned() const { return bitfields_.IsStickyPositioned(); }
  bool IsFixedPositioned() const {
    return IsOutOfFlowPositioned() &&
           StyleRef().GetPosition() == EPosition::kFixed;
  }
  bool IsAbsolutePositioned() const {
    return IsOutOfFlowPositioned() &&
           StyleRef().GetPosition() == EPosition::kAbsolute;
  }
  bool IsPositioned() const { return bitfields_.IsPositioned(); }

  bool IsText() const { return bitfields_.IsText(); }
  bool IsBox() const { return bitfields_.IsBox(); }
  bool IsInline() const { return bitfields_.IsInline(); }  // inline object
  bool IsAtomicInlineLevel() const { return bitfields_.IsAtomicInlineLevel(); }
  bool IsHorizontalWritingMode() const {
    return bitfields_.HorizontalWritingMode();
  }
  bool HasFlippedBlocksWritingMode() const {
    return StyleRef().IsFlippedBlocksWritingMode();
  }

  bool HasLayer() const { return bitfields_.HasLayer(); }

  // This may be different from StyleRef().hasBoxDecorationBackground() because
  // some objects may have box decoration background other than from their own
  // style.
  bool HasBoxDecorationBackground() const {
    return bitfields_.HasBoxDecorationBackground();
  }

  bool BackgroundIsKnownToBeObscured() const;

  bool NeedsLayout() const {
    return bitfields_.SelfNeedsLayout() ||
           bitfields_.NormalChildNeedsLayout() ||
           bitfields_.PosChildNeedsLayout() ||
           bitfields_.NeedsSimplifiedNormalFlowLayout() ||
           bitfields_.NeedsPositionedMovementLayout();
  }

  bool SelfNeedsLayout() const { return bitfields_.SelfNeedsLayout(); }
  bool NeedsPositionedMovementLayout() const {
    return bitfields_.NeedsPositionedMovementLayout();
  }

  bool PosChildNeedsLayout() const { return bitfields_.PosChildNeedsLayout(); }
  bool NeedsSimplifiedNormalFlowLayout() const {
    return bitfields_.NeedsSimplifiedNormalFlowLayout();
  }
  bool NormalChildNeedsLayout() const {
    return bitfields_.NormalChildNeedsLayout();
  }
  bool NeedsCollectInlines() const { return bitfields_.NeedsCollectInlines(); }

  bool PreferredLogicalWidthsDirty() const {
    return bitfields_.PreferredLogicalWidthsDirty();
  }

  bool NeedsOverflowRecalcAfterStyleChange() const {
    return bitfields_.SelfNeedsOverflowRecalcAfterStyleChange() ||
           bitfields_.ChildNeedsOverflowRecalcAfterStyleChange();
  }
  bool SelfNeedsOverflowRecalcAfterStyleChange() const {
    return bitfields_.SelfNeedsOverflowRecalcAfterStyleChange();
  }
  bool ChildNeedsOverflowRecalcAfterStyleChange() const {
    return bitfields_.ChildNeedsOverflowRecalcAfterStyleChange();
  }

  bool IsSelectionBorder() const;

  // CSS clip only applies when position is absolute or fixed. Prefer this check
  // over !Style()->HasAutoClip().
  bool HasClip() const {
    return IsOutOfFlowPositioned() && !StyleRef().HasAutoClip();
  }
  bool HasOverflowClip() const { return bitfields_.HasOverflowClip(); }
  bool ShouldClipOverflow() const { return bitfields_.ShouldClipOverflow(); }
  bool HasClipRelatedProperty() const;

  bool HasTransformRelatedProperty() const {
    return bitfields_.HasTransformRelatedProperty();
  }
  bool IsTransformApplicable() const { return IsBox() || IsSVG(); }
  bool HasMask() const { return StyleRef().HasMask(); }
  bool HasClipPath() const { return StyleRef().ClipPath(); }
  bool HasHiddenBackface() const {
    return StyleRef().BackfaceVisibility() == EBackfaceVisibility::kHidden;
  }
  bool HasBackdropFilter() const { return StyleRef().HasBackdropFilter(); }

  // Returns |true| if any property that renders using filter operations is
  // used (including, but not limited to, 'filter' and 'box-reflect').
  // Not calling style()->hasFilterInducingProperty because some objects force
  // to ignore reflection style (e.g. LayoutInline).
  bool HasFilterInducingProperty() const {
    return StyleRef().HasFilter() || HasReflection();
  }

  bool HasShapeOutside() const { return StyleRef().ShapeOutside(); }

  // The pseudo element style can be cached or uncached.  Use the cached method
  // if the pseudo element doesn't respect any pseudo classes (and therefore
  // has no concept of changing state).
  ComputedStyle* GetCachedPseudoStyle(
      PseudoId,
      const ComputedStyle* parent_style = nullptr) const;
  scoped_refptr<ComputedStyle> GetUncachedPseudoStyle(
      const PseudoStyleRequest&,
      const ComputedStyle* parent_style = nullptr) const;

  LayoutView* View() const { return GetDocument().GetLayoutView(); }
  LocalFrameView* GetFrameView() const { return GetDocument().View(); }

  bool IsRooted() const;

  Node* GetNode() const { return IsAnonymous() ? nullptr : node_; }

  Node* NonPseudoNode() const {
    return IsPseudoElement() ? nullptr : GetNode();
  }

  void ClearNode() { node_ = nullptr; }

  // Returns the styled node that caused the generation of this layoutObject.
  // This is the same as node() except for layoutObjects of :before, :after and
  // :first-letter pseudo elements for which their parent node is returned.
  Node* GeneratingNode() const {
    return IsPseudoElement() ? GetNode()->ParentOrShadowHostNode() : GetNode();
  }

  Document& GetDocument() const {
    DCHECK(node_ || Parent());  // crbug.com/402056
    return node_ ? node_->GetDocument() : Parent()->GetDocument();
  }
  LocalFrame* GetFrame() const { return GetDocument().GetFrame(); }

  virtual LayoutMultiColumnSpannerPlaceholder* SpannerPlaceholder() const {
    return nullptr;
  }
  bool IsColumnSpanAll() const {
    return StyleRef().GetColumnSpan() == EColumnSpan::kAll &&
           SpannerPlaceholder();
  }

  // We include isLayoutButton() in this check, because buttons are
  // implemented using flex box but should still support things like
  // first-line, first-letter and text-overflow.
  // The flex box and grid specs require that flex box and grid do not
  // support first-line|first-letter, though.
  // When LayoutObject and display do not agree, allow first-line|first-letter
  // only when both indicate it's a block container.
  // TODO(cbiesinger): Remove when buttons are implemented with align-items
  // instead of flex box. crbug.com/226252.
  bool BehavesLikeBlockContainer() const {
    return (IsLayoutBlockFlow() && StyleRef().IsDisplayBlockContainer()) ||
           IsLayoutButton();
  }

  // May be optionally passed to container() and various other similar methods
  // that search the ancestry for some sort of containing block. Used to
  // determine if we skipped certain objects while walking the ancestry.
  class AncestorSkipInfo {
   public:
    AncestorSkipInfo(const LayoutObject* ancestor,
                     bool check_for_filters = false)
        : ancestor_(ancestor), check_for_filters_(check_for_filters) {}

    // Update skip info output based on the layout object passed.
    void Update(const LayoutObject& object) {
      if (&object == ancestor_)
        ancestor_skipped_ = true;
      if (check_for_filters_ && object.HasFilterInducingProperty())
        filter_skipped_ = true;
    }

    // TODO(mstensho): Get rid of this. It's just a temporary thing to retain
    // old behavior in LayoutObject::container().
    void ResetOutput() {
      ancestor_skipped_ = false;
      filter_skipped_ = false;
    }

    bool AncestorSkipped() const { return ancestor_skipped_; }
    bool FilterSkipped() const {
      DCHECK(check_for_filters_);
      return filter_skipped_;
    }

   private:
    // Input: A potential ancestor to look for. If we walk past this one while
    // walking the ancestry in search of some containing block, ancestorSkipped
    // will be set to true.
    const LayoutObject* ancestor_;
    // Input: When set, we'll check if we skip objects with filter inducing
    // properties.
    bool check_for_filters_;

    // Output: Set to true if |ancestor| was walked past while walking the
    // ancestry.
    bool ancestor_skipped_ = false;
    // Output: Set to true if we walked past a filter object. This will be set
    // regardless of the value of |ancestor|.
    bool filter_skipped_ = false;
  };

  // This function returns the containing block of the object.
  // Due to CSS being inconsistent, a containing block can be a relatively
  // positioned inline, thus we can't return a LayoutBlock from this function.
  //
  // This method is extremely similar to containingBlock(), but with a few
  // notable exceptions.
  // (1) For normal flow elements, it just returns the parent.
  // (2) For absolute positioned elements, it will return a relative
  //     positioned inline. containingBlock() simply skips relpositioned inlines
  //     and lets an enclosing block handle the layout of the positioned object.
  //     This does mean that computePositionedLogicalWidth and
  //     computePositionedLogicalHeight have to use container().
  //
  // Note that floating objects don't belong to either of the above exceptions.
  //
  // This function should be used for any invalidation as it would correctly
  // walk the containing block chain. See e.g. markContainerChainForLayout.
  // It is also used for correctly sizing absolutely positioned elements
  // (point 3 above).
  LayoutObject* Container(AncestorSkipInfo* = nullptr) const;
  // Finds the container as if this object is fixed-position.
  LayoutBlock* ContainingBlockForFixedPosition(
      AncestorSkipInfo* = nullptr) const;
  // Finds the containing block as if this object is absolute-position.
  LayoutBlock* ContainingBlockForAbsolutePosition(
      AncestorSkipInfo* = nullptr) const;

  bool CanContainOutOfFlowPositionedElement(EPosition position) const {
    DCHECK(position == EPosition::kAbsolute || position == EPosition::kFixed);
    return (position == EPosition::kAbsolute &&
            CanContainAbsolutePositionObjects()) ||
           (position == EPosition::kFixed && CanContainFixedPositionObjects());
  }

  virtual LayoutObject* HoverAncestor() const { return Parent(); }

  Element* OffsetParent(const Element* = nullptr) const;

  void MarkContainerNeedsCollectInlines();
  void ClearNeedsCollectInlines() { SetNeedsCollectInlines(false); }

  void MarkContainerChainForLayout(bool schedule_relayout = true,
                                   SubtreeLayoutScope* = nullptr);
  void SetNeedsLayout(LayoutInvalidationReasonForTracing,
                      MarkingBehavior = kMarkContainerChain,
                      SubtreeLayoutScope* = nullptr);
  void SetNeedsLayoutAndFullPaintInvalidation(
      LayoutInvalidationReasonForTracing,
      MarkingBehavior = kMarkContainerChain,
      SubtreeLayoutScope* = nullptr);
  void ClearNeedsLayout();
  void SetChildNeedsLayout(MarkingBehavior = kMarkContainerChain,
                           SubtreeLayoutScope* = nullptr);
  void SetNeedsPositionedMovementLayout();
  void SetPreferredLogicalWidthsDirty(MarkingBehavior = kMarkContainerChain);
  void ClearPreferredLogicalWidthsDirty();

  void SetNeedsLayoutAndPrefWidthsRecalc(
      LayoutInvalidationReasonForTracing reason) {
    SetNeedsLayout(reason);
    SetPreferredLogicalWidthsDirty();
  }
  void SetNeedsLayoutAndPrefWidthsRecalcAndFullPaintInvalidation(
      LayoutInvalidationReasonForTracing reason) {
    SetNeedsLayoutAndFullPaintInvalidation(reason);
    SetPreferredLogicalWidthsDirty();
  }

  void SetPositionState(EPosition position) {
    DCHECK(
        (position != EPosition::kAbsolute && position != EPosition::kFixed) ||
        IsBox());
    bitfields_.SetPositionedState(position);
  }
  void ClearPositionedState() { bitfields_.ClearPositionedState(); }

  void SetFloating(bool is_floating) { bitfields_.SetFloating(is_floating); }
  void SetInline(bool is_inline) { bitfields_.SetIsInline(is_inline); }

  void SetHasBoxDecorationBackground(bool);

  enum BackgroundObscurationState {
    kBackgroundObscurationStatusInvalid,
    kBackgroundKnownToBeObscured,
    kBackgroundMayBeVisible,
  };
  void InvalidateBackgroundObscurationStatus();
  virtual bool ComputeBackgroundIsKnownToBeObscured() const { return false; }

  void SetIsText() { bitfields_.SetIsText(true); }
  void SetIsBox() { bitfields_.SetIsBox(true); }
  void SetIsAtomicInlineLevel(bool is_atomic_inline_level) {
    bitfields_.SetIsAtomicInlineLevel(is_atomic_inline_level);
  }
  void SetHorizontalWritingMode(bool has_horizontal_writing_mode) {
    bitfields_.SetHorizontalWritingMode(has_horizontal_writing_mode);
  }
  void SetHasOverflowClip(bool has_overflow_clip) {
    bitfields_.SetHasOverflowClip(has_overflow_clip);
  }
  void SetShouldClipOverflow(bool should_clip_overflow) {
    bitfields_.SetShouldClipOverflow(should_clip_overflow);
  }
  void SetHasLayer(bool has_layer) { bitfields_.SetHasLayer(has_layer); }
  void SetHasTransformRelatedProperty(bool has_transform) {
    bitfields_.SetHasTransformRelatedProperty(has_transform);
  }
  void SetHasReflection(bool has_reflection) {
    bitfields_.SetHasReflection(has_reflection);
  }
  void SetCanContainFixedPositionObjects(bool can_contain_fixed_position) {
    bitfields_.SetCanContainFixedPositionObjects(can_contain_fixed_position);
  }

  // paintOffset is the offset from the origin of the GraphicsContext at which
  // to paint the current object.
  virtual void Paint(const PaintInfo&, const LayoutPoint& paint_offset) const;

  virtual bool RecalcOverflowAfterStyleChange();

  // Subclasses must reimplement this method to compute the size and position
  // of this object and all its descendants.
  //
  // By default, layout only lays out the children that are marked for layout.
  // In some cases, layout has to force laying out more children. An example is
  // when the width of the LayoutObject changes as this impacts children with
  // 'width' set to auto.
  virtual void UpdateLayout() = 0;
  virtual bool UpdateImageLoadingPriorities() { return false; }

  void HandleSubtreeModifications();
  virtual void SubtreeDidChange() {}

  // Flags used to mark if an object consumes subtree change notifications.
  bool ConsumesSubtreeChangeNotification() const {
    return bitfields_.ConsumesSubtreeChangeNotification();
  }
  void SetConsumesSubtreeChangeNotification() {
    bitfields_.SetConsumesSubtreeChangeNotification(true);
  }

  // Flags used to mark if a descendant subtree of this object has changed.
  void NotifyOfSubtreeChange();
  void NotifyAncestorsOfSubtreeChange();
  bool WasNotifiedOfSubtreeChange() const {
    return bitfields_.NotifiedOfSubtreeChange();
  }

  // Flags used to signify that a layoutObject needs to be notified by its
  // descendants that they have had their child subtree changed.
  void RegisterSubtreeChangeListenerOnDescendants(bool);
  bool HasSubtreeChangeListenerRegistered() const {
    return bitfields_.SubtreeChangeListenerRegistered();
  }

  /* This function performs a layout only if one is needed. */
  DISABLE_CFI_PERF void LayoutIfNeeded() {
    if (NeedsLayout())
      UpdateLayout();
  }

  void ForceLayout();
  void ForceChildLayout();

  // Used for element state updates that cannot be fixed with a paint
  // invalidation and do not need a relayout.
  virtual void UpdateFromElement() {}

  virtual void AddAnnotatedRegions(Vector<AnnotatedRegionValue>&);

  CompositingState GetCompositingState() const;
  virtual CompositingReasons AdditionalCompositingReasons() const;

  virtual bool HitTestAllPhases(HitTestResult&,
                                const HitTestLocation& location_in_container,
                                const LayoutPoint& accumulated_offset,
                                HitTestFilter = kHitTestAll);
  // Returns the node that is ultimately added to the hit test result. Some
  // objects report a hit testing node that is not their own (such as
  // continuations and some psuedo elements) and it is important that the
  // node be consistent between point- and list-based hit test results.
  virtual Node* NodeForHitTest() const;
  virtual void UpdateHitTestResult(HitTestResult&, const LayoutPoint&) const;
  virtual bool NodeAtPoint(HitTestResult&,
                           const HitTestLocation& location_in_container,
                           const LayoutPoint& accumulated_offset,
                           HitTestAction);

  virtual PositionWithAffinity PositionForPoint(const LayoutPoint&) const;
  PositionWithAffinity CreatePositionWithAffinity(int offset,
                                                  TextAffinity) const;
  PositionWithAffinity CreatePositionWithAffinity(int offset) const;
  PositionWithAffinity CreatePositionWithAffinity(const Position&) const;

  virtual void DirtyLinesFromChangedChild(
      LayoutObject*,
      MarkingBehavior marking_behaviour = kMarkContainerChain);

  // Set the style of the object and update the state of the object accordingly.
  void SetStyle(scoped_refptr<ComputedStyle>);

  // Set the style of the object if it's generated content.
  void SetPseudoStyle(scoped_refptr<ComputedStyle>);

  // Updates only the local style ptr of the object.  Does not update the state
  // of the object, and so only should be called when the style is known not to
  // have changed (or from setStyle).
  void SetStyleInternal(scoped_refptr<ComputedStyle> style) {
    style_ = std::move(style);
  }

  void SetStyleWithWritingModeOf(scoped_refptr<ComputedStyle>,
                                 LayoutObject* parent);
  void SetStyleWithWritingModeOfParent(scoped_refptr<ComputedStyle>);

  void FirstLineStyleDidChange(const ComputedStyle& old_style,
                               const ComputedStyle& new_style);

  void ClearBaseComputedStyle();

  // This function returns an enclosing non-anonymous LayoutBlock for this
  // element. This function is not always returning the containing block as
  // defined by CSS. In particular:
  // - if the CSS containing block is a relatively positioned inline,
  //   the function returns the inline's enclosing non-anonymous LayoutBlock.
  //   This means that a LayoutInline would be skipped (expected as it's not a
  //   LayoutBlock) but so would be an inline LayoutTable or LayoutBlockFlow.
  //   TODO(jchaffraix): Is that REALLY what we want here?
  // - if the CSS containing block is anonymous, we find its enclosing
  //   non-anonymous LayoutBlock.
  //   Note that in the previous examples, the returned LayoutBlock has no
  //   logical relationship to the original element.
  //
  // LayoutBlocks are the one that handle laying out positioned elements,
  // thus this function is important during layout, to insert the positioned
  // elements into the correct LayoutBlock.
  //
  // See container() for the function that returns the containing block.
  // See LayoutBlock.h for some extra explanations on containing blocks.
  LayoutBlock* ContainingBlock(AncestorSkipInfo* = nullptr) const;

  const LayoutBlock* InclusiveContainingBlock() const;

  bool CanContainAbsolutePositionObjects() const {
    return style_->CanContainAbsolutePositionObjects() ||
           CanContainFixedPositionObjects();
  }
  bool CanContainFixedPositionObjects() const {
    return bitfields_.CanContainFixedPositionObjects();
  }

  // Convert the given local point to absolute coordinates
  // FIXME: Temporary. If UseTransforms is true, take transforms into account.
  // Eventually localToAbsolute() will always be transform-aware.
  FloatPoint LocalToAbsolute(const FloatPoint& local_point = FloatPoint(),
                             MapCoordinatesFlags = 0) const;

  // If the LayoutBoxModelObject ancestor is non-null, the input point is in the
  // space of the ancestor.
  // Otherwise:
  //   If TraverseDocumentBoundaries is specified, the input point is in the
  //   space of the local root frame.
  //   Otherwise, the input point is in the space of the containing frame.
  FloatPoint AncestorToLocal(LayoutBoxModelObject*,
                             const FloatPoint&,
                             MapCoordinatesFlags = 0) const;
  FloatPoint AbsoluteToLocal(const FloatPoint& point,
                             MapCoordinatesFlags mode = 0) const {
    return AncestorToLocal(nullptr, point, mode);
  }

  // Convert a local quad to absolute coordinates, taking transforms into
  // account.
  FloatQuad LocalToAbsoluteQuad(const FloatQuad& quad,
                                MapCoordinatesFlags mode = 0) const {
    return LocalToAncestorQuad(quad, nullptr, mode);
  }

  // Convert a quad in ancestor coordinates to local coordinates.
  // If the LayoutBoxModelObject ancestor is non-null, the input quad is in the
  // space of the ancestor.
  // Otherwise:
  //   If TraverseDocumentBoundaries is specified, the input quad is in the
  //   space of the local root frame.
  //   Otherwise, the input quad is in the space of the containing frame.
  FloatQuad AncestorToLocalQuad(LayoutBoxModelObject*,
                                const FloatQuad&,
                                MapCoordinatesFlags mode = 0) const;
  FloatQuad AbsoluteToLocalQuad(const FloatQuad& quad,
                                MapCoordinatesFlags mode = 0) const {
    return AncestorToLocalQuad(nullptr, quad, mode);
  }

  // Convert a local quad into the coordinate system of container, taking
  // transforms into account.
  // If the LayoutBoxModelObject ancestor is non-null, the result will be in the
  // space of the ancestor.
  // Otherwise:
  //   If TraverseDocumentBoundaries is specified, the result will be in the
  //   space of the local root frame.
  //   Otherwise, the result will be in the space of the containing frame.
  FloatQuad LocalToAncestorQuad(const FloatQuad&,
                                const LayoutBoxModelObject* ancestor,
                                MapCoordinatesFlags = 0) const;
  FloatPoint LocalToAncestorPoint(const FloatPoint&,
                                  const LayoutBoxModelObject* ancestor,
                                  MapCoordinatesFlags = 0) const;
  void LocalToAncestorRects(Vector<LayoutRect>&,
                            const LayoutBoxModelObject* ancestor,
                            const LayoutPoint& pre_offset,
                            const LayoutPoint& post_offset) const;

  // Convert a local quad into the coordinate system of container, not
  // include transforms. See localToAncestorQuad for details.
  FloatQuad LocalToAncestorQuadWithoutTransforms(
      const FloatQuad&,
      const LayoutBoxModelObject* ancestor,
      MapCoordinatesFlags = 0) const;

  // Return the transformation matrix to map points from local to the coordinate
  // system of a container, taking transforms into account.
  // Passing null for |ancestor| behaves the same as localToAncestorQuad.
  TransformationMatrix LocalToAncestorTransform(
      const LayoutBoxModelObject* ancestor,
      MapCoordinatesFlags = 0) const;
  TransformationMatrix LocalToAbsoluteTransform(
      MapCoordinatesFlags mode = 0) const {
    return LocalToAncestorTransform(nullptr, mode);
  }

  // Return the offset from the container() layoutObject (excluding transforms
  // and multicol).
  LayoutSize OffsetFromContainer(const LayoutObject*,
                                 bool ignore_scroll_offset = false) const;
  // Return the offset from an object up the container() chain. Asserts that
  // none of the intermediate objects have transforms.
  LayoutSize OffsetFromAncestorContainer(const LayoutObject*) const;

  virtual void AbsoluteRects(Vector<IntRect>&, const LayoutPoint&) const {}

  FloatRect AbsoluteBoundingBoxFloatRect() const;
  // This returns an IntRect enclosing this object. If this object has an
  // integral size and the position has fractional values, the resultant
  // IntRect can be larger than the integral size.
  IntRect AbsoluteBoundingBoxRect(MapCoordinatesFlags = 0) const;
  // FIXME: This function should go away eventually
  IntRect AbsoluteBoundingBoxRectIgnoringTransforms() const;
  // These two handles inline anchors without content as well.
  LayoutRect AbsoluteBoundingBoxRectHandlingEmptyAnchor() const;
  // This returns an IntRect expanded from
  // AbsoluteBoundingBoxRectHandlingEmptyAnchor by ScrollMargin.
  LayoutRect AbsoluteBoundingBoxRectForScrollIntoView() const;

  // Build an array of quads in absolute coords for line boxes
  virtual void AbsoluteQuads(Vector<FloatQuad>&,
                             MapCoordinatesFlags mode = 0) const {}

  static FloatRect AbsoluteBoundingBoxRectForRange(const EphemeralRange&);

  // The bounding box (see: absoluteBoundingBoxRect) including all descendant
  // bounding boxes.
  IntRect AbsoluteBoundingBoxRectIncludingDescendants() const;

  // For accessibility, we want the bounding box rect of this element
  // in local coordinates, which can then be converted to coordinates relative
  // to any ancestor using, e.g., localToAncestorTransform.
  virtual FloatRect LocalBoundingBoxRectForAccessibility() const = 0;

  // This function returns the minimal logical width this object can have
  // without overflowing. This means that all the opportunities for wrapping
  // have been taken.
  //
  // See INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS above.
  //
  // CSS 2.1 calls this width the "preferred minimum width" (thus this name)
  // and "minimum content width" (for table).
  // However CSS 3 calls it the "min-content inline size".
  // https://drafts.csswg.org/css-sizing-3/#min-content-inline-size
  // TODO(jchaffraix): We will probably want to rename it to match CSS 3.
  virtual LayoutUnit MinPreferredLogicalWidth() const { return LayoutUnit(); }

  // This function returns the maximum logical width this object can have.
  //
  // See INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS above.
  //
  // CSS 2.1 calls this width the "preferred width". However CSS 3 calls it
  // the "max-content inline size".
  // https://drafts.csswg.org/css-sizing-3/#max-content-inline-size
  // TODO(jchaffraix): We will probably want to rename it to match CSS 3.
  virtual LayoutUnit MaxPreferredLogicalWidth() const { return LayoutUnit(); }

  const ComputedStyle* Style() const { return style_.get(); }
  ComputedStyle* MutableStyle() const { return style_.get(); }

  // style_ can only be nullptr before the first style is set, thus most
  // callers will never see a nullptr style and should use StyleRef().
  const ComputedStyle& StyleRef() const { return MutableStyleRef(); }
  ComputedStyle& MutableStyleRef() const {
    DCHECK(style_);
    return *style_;
  }

  /* The following methods are inlined in LayoutObjectInlines.h */
  inline const ComputedStyle* FirstLineStyle() const;
  inline const ComputedStyle& FirstLineStyleRef() const;
  inline const ComputedStyle* Style(bool first_line) const;
  inline const ComputedStyle& StyleRef(bool first_line) const;

  static inline Color ResolveColor(const ComputedStyle& style_to_use,
                                   const CSSProperty& color_property) {
    return style_to_use.VisitedDependentColor(color_property);
  }

  inline Color ResolveColor(const CSSProperty& color_property) const {
    return StyleRef().VisitedDependentColor(color_property);
  }

  virtual CursorDirective GetCursor(const LayoutPoint&, Cursor&) const;

  // Return the LayoutBoxModelObject in the container chain which is responsible
  // for painting this object. The function crosses frames boundaries so the
  // returned value can be in a different document.
  //
  // This is the container that should be passed to the '*forPaintInvalidation'
  // methods.
  const LayoutBoxModelObject& ContainerForPaintInvalidation() const;

  bool IsPaintInvalidationContainer() const;

  // Invalidate the raster of a specific sub-rectangle within the object. The
  // rect is in the object's local coordinate space. This is useful e.g. when
  // a small region of a canvas changes.
  void InvalidatePaintRectangle(const LayoutRect&);

  void SetShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();

  // Returns the rect that should have paint invalidated whenever this object
  // changes. The rect is in the view's coordinate space. This method deals with
  // outlines and overflow.
  virtual LayoutRect AbsoluteVisualRect() const;

  // Returns the rect that should have paint invalidated whenever this object
  // changes. The rect is in the object's local coordinate space. This is for
  // non-SVG objects and LayoutSVGRoot only. SVG objects (except LayoutSVGRoot)
  // should use visualRectInLocalSVGCoordinates() and map with SVG transforms
  // instead.
  LayoutRect LocalVisualRect() const {
    if (StyleRef().Visibility() != EVisibility::kVisible &&
        VisualRectRespectsVisibility())
      return LayoutRect();
    return LocalVisualRectIgnoringVisibility();
  }

  // Given a rect in the object's coordinate space, mutates the rect into one
  // representing the size of its visual painted output as if |ancestor| was the
  // root of the page: the rect is modified by any intervening clips, transforms
  // and scrolls between |this| and |ancestor| (not inclusive of |ancestor|),
  // but not any above |ancestor|.
  // The output is in the physical, painted coordinate pixel space of
  // |ancestor|.
  // Overflow clipping, CSS clipping and scrolling is *not* applied for
  // |ancestor| itself if |ancestor| scrolls overflow.
  // The output rect is suitable for purposes such as paint invalidation.
  //
  // The ancestor can be nullptr which, if |this| is not the root view, will map
  // the rect to the main frame's space which includes the root view's scroll
  // and clip. This is even true if the main frame is remote.
  //
  // If visualRectFlags has the EdgeInclusive bit set, clipping operations will
  // use LayoutRect::InclusiveIntersect, and the return value of
  // InclusiveIntersect will be propagated to the return value of this method.
  // Otherwise, clipping operations will use LayoutRect::intersect, and the
  // return value will be true only if the clipped rect has non-zero area.
  // See the documentation for LayoutRect::InclusiveIntersect for more
  // information.
  bool MapToVisualRectInAncestorSpace(
      const LayoutBoxModelObject* ancestor,
      LayoutRect&,
      VisualRectFlags = kDefaultVisualRectFlags) const;

  // Do not call this method directly. Call mapToVisualRectInAncestorSpace
  // instead.
  virtual bool MapToVisualRectInAncestorSpaceInternal(
      const LayoutBoxModelObject* ancestor,
      TransformState&,
      VisualRectFlags = kDefaultVisualRectFlags) const;

  // Do a rect-based hit test with this object as the stop node.
  HitTestResult HitTestForOcclusion(const LayoutRect&) const;
  HitTestResult HitTestForOcclusion() const {
    return HitTestForOcclusion(AbsoluteVisualRect());
  }

  // Return the offset to the column in which the specified point (in
  // flow-thread coordinates) lives. This is used to convert a flow-thread point
  // to a point in the containing coordinate space.
  virtual LayoutSize ColumnOffset(const LayoutPoint&) const {
    return LayoutSize();
  }

  virtual unsigned length() const { return 1; }

  bool IsFloatingOrOutOfFlowPositioned() const {
    return (IsFloating() || IsOutOfFlowPositioned());
  }

  bool IsTransparent() const { return StyleRef().HasOpacity(); }
  float Opacity() const { return StyleRef().Opacity(); }

  bool HasReflection() const { return bitfields_.HasReflection(); }

  // The current selection state for an object.  For blocks, the state refers to
  // the state of the leaf descendants (as described above in the SelectionState
  // enum declaration).
  SelectionState GetSelectionState() const {
    return bitfields_.GetSelectionState();
  }
  void SetSelectionState(SelectionState state) {
    bitfields_.SetSelectionState(state);
  }
  bool CanUpdateSelectionOnRootLineBoxes() const;

  // A single rectangle that encompasses all of the selected objects within this
  // object. Used to determine the tightest possible bounding box for the
  // selection. The rect returned is in the object's local coordinate space.
  virtual LayoutRect LocalSelectionRect() const { return LayoutRect(); }

  LayoutRect AbsoluteSelectionRect() const;

  bool CanBeSelectionLeaf() const;
  bool HasSelectedChildren() const {
    return GetSelectionState() != SelectionState::kNone;
  }

  bool IsSelectable() const;

  /**
     * Returns the local coordinates of the caret within this layout object.
     * @param caretOffset zero-based offset determining position within the
   * layout object.
     * @param extraWidthToEndOfLine optional out arg to give extra width to end
   * of line -
     * useful for character range rect computations
     */
  virtual LayoutRect LocalCaretRect(
      const InlineBox*,
      int caret_offset,
      LayoutUnit* extra_width_to_end_of_line = nullptr) const;

  // When performing a global document tear-down, the layoutObject of the
  // document is cleared. We use this as a hook to detect the case of document
  // destruction and don't waste time doing unnecessary work.
  bool DocumentBeingDestroyed() const;

  void DestroyAndCleanupAnonymousWrappers();

  // While the destroy() method is virtual, this should only be overriden in
  // very rare circumstances.
  // You want to override willBeDestroyed() instead unless you explicitly need
  // to stop this object from being destroyed (for example,
  // LayoutEmbeddedContent overrides destroy() for this purpose).
  virtual void Destroy();

  // Virtual function helpers for the deprecated Flexible Box Layout (display:
  // -webkit-box).
  virtual bool IsDeprecatedFlexibleBox() const { return false; }

  // Virtual function helper for the new FlexibleBox Layout (display:
  // -webkit-flex).
  virtual bool IsFlexibleBox() const { return false; }

  bool IsFlexibleBoxIncludingDeprecated() const {
    return IsFlexibleBox() || IsDeprecatedFlexibleBox();
  }

  bool IsListItemIncludingNG() const {
    return IsListItem() || IsLayoutNGListItem();
  }

  bool IsListMarkerIncludingNG() const {
    return IsListMarker() || IsLayoutNGListMarker();
  }

  virtual bool IsCombineText() const { return false; }

  virtual int CaretMinOffset() const;
  virtual int CaretMaxOffset() const;

  // ImageResourceClient override.
  void ImageChanged(ImageResourceContent*,
                    CanDeferInvalidation,
                    const IntRect* = nullptr) final;
  void ImageChanged(WrappedImagePtr,
                    CanDeferInvalidation,
                    const IntRect* = nullptr) override {}
  bool WillRenderImage() final;
  bool GetImageAnimationPolicy(ImageAnimationPolicy&) final;

  void Remove() {
    if (Parent())
      Parent()->RemoveChild(this);
  }

  bool VisibleToHitTestRequest(const HitTestRequest& request) const {
    return StyleRef().Visibility() == EVisibility::kVisible &&
           (request.IgnorePointerEventsNone() ||
            StyleRef().PointerEvents() != EPointerEvents::kNone) &&
           !IsInert();
  }

  // Warning: inertness can change without causing relayout.
  bool VisibleToHitTesting() const {
    return StyleRef().VisibleToHitTesting() && !IsInert();
  }

  // Map points and quads through elements, potentially via 3d transforms. You
  // should never need to call these directly; use localToAbsolute/
  // absoluteToLocal methods instead.
  virtual void MapLocalToAncestor(
      const LayoutBoxModelObject* ancestor,
      TransformState&,
      MapCoordinatesFlags = kApplyContainerFlip) const;
  // If the LayoutBoxModelObject ancestor is non-null, the input quad is in the
  // space of the ancestor.
  // Otherwise:
  //   If TraverseDocumentBoundaries is specified, the input quad is in the
  //   space of the local root frame.
  //   Otherwise, the input quad is in the space of the containing frame.
  virtual void MapAncestorToLocal(
      const LayoutBoxModelObject*,
      TransformState&,
      MapCoordinatesFlags = kApplyContainerFlip) const;

  // Pushes state onto LayoutGeometryMap about how to map coordinates from this
  // layoutObject to its container, or ancestorToStopAt (whichever is
  // encountered first). Returns the layoutObject which was mapped to (container
  // or ancestorToStopAt).
  virtual const LayoutObject* PushMappingToContainer(
      const LayoutBoxModelObject* ancestor_to_stop_at,
      LayoutGeometryMap&) const;

  bool ShouldUseTransformFromContainer(const LayoutObject* container) const;
  void GetTransformFromContainer(const LayoutObject* container,
                                 const LayoutSize& offset_in_container,
                                 TransformationMatrix&) const;

  bool CreatesGroup() const {
    return IsTransparent() || HasMask() || HasClipPath() ||
           HasFilterInducingProperty() || StyleRef().HasBlendMode();
  }

  // Collects rectangles that the outline of this object would be drawing along
  // the outside of, even if the object isn't styled with a outline for now. The
  // rects also cover continuations.
  enum IncludeBlockVisualOverflowOrNot {
    kDontIncludeBlockVisualOverflow,
    kIncludeBlockVisualOverflow,
  };
  virtual void AddOutlineRects(Vector<LayoutRect>&,
                               const LayoutPoint& additional_offset,
                               IncludeBlockVisualOverflowOrNot) const {}

  // For history and compatibility reasons, we draw outline:auto (for focus
  // rings) and normal style outline differently.
  // Focus rings enclose block visual overflows (of line boxes and descendants),
  // while normal outlines don't.
  IncludeBlockVisualOverflowOrNot OutlineRectsShouldIncludeBlockVisualOverflow()
      const {
    return StyleRef().OutlineStyleIsAuto() ? kIncludeBlockVisualOverflow
                                           : kDontIncludeBlockVisualOverflow;
  }

  // Collects rectangles enclosing visual overflows of the DOM subtree under
  // this object.
  // The rects also cover continuations which may be not in the layout subtree
  // of this object.
  // TODO(crbug.com/614781): Currently the result rects don't cover list markers
  // and outlines.
  void AddElementVisualOverflowRects(
      Vector<LayoutRect>& rects,
      const LayoutPoint& additional_offset) const {
    AddOutlineRects(rects, additional_offset, kIncludeBlockVisualOverflow);
  }

  // Compute a list of hit-test rectangles per layer rooted at this
  // layoutObject with at most the given touch action.
  virtual void ComputeLayerHitTestRects(LayerHitTestRects&, TouchAction) const;

  static RespectImageOrientationEnum ShouldRespectImageOrientation(
      const LayoutObject*);

  bool IsRelayoutBoundaryForInspector() const;

  // The visual rect, in the the space of the paint invalidation container
  // (*not* the graphics layer that paints this object).
  LayoutRect VisualRectIncludingCompositedScrolling(
      const LayoutBoxModelObject& paint_invalidation_container) const;

  // Called when the previous visual rect(s) is no longer valid.
  virtual void ClearPreviousVisualRects();

  PaintInvalidationReason FullPaintInvalidationReason() const {
    return bitfields_.FullPaintInvalidationReason();
  }
  bool ShouldDoFullPaintInvalidation() const {
    return bitfields_.FullPaintInvalidationReason() !=
           PaintInvalidationReason::kNone;
  }
  void SetShouldDoFullPaintInvalidation(
      PaintInvalidationReason = PaintInvalidationReason::kFull);
  void SetShouldDoFullPaintInvalidationWithoutGeometryChange(
      PaintInvalidationReason = PaintInvalidationReason::kFull);
  void ClearShouldDoFullPaintInvalidation() {
    bitfields_.SetFullPaintInvalidationReason(PaintInvalidationReason::kNone);
  }

  void ClearPaintInvalidationFlags();

  bool MayNeedPaintInvalidation() const {
    return bitfields_.MayNeedPaintInvalidation();
  }
  void SetMayNeedPaintInvalidation();
  void SetMayNeedPaintInvalidationWithoutGeometryChange();

  bool MayNeedPaintInvalidationSubtree() const {
    return bitfields_.MayNeedPaintInvalidationSubtree();
  }
  void SetMayNeedPaintInvalidationSubtree();

  bool NeedsPaintOffsetAndVisualRectUpdate() const {
    return bitfields_.NeedsPaintOffsetAndVisualRectUpdate();
  }

  bool MayNeedPaintInvalidationAnimatedBackgroundImage() const {
    return bitfields_.MayNeedPaintInvalidationAnimatedBackgroundImage();
  }
  void SetMayNeedPaintInvalidationAnimatedBackgroundImage();

  bool ShouldInvalidateSelection() const {
    return bitfields_.ShouldInvalidateSelection();
  }
  void SetShouldInvalidateSelection();

  bool ShouldCheckForPaintInvalidation() const {
    return MayNeedPaintInvalidation() || ShouldDoFullPaintInvalidation();
  }

  virtual LayoutRect ViewRect() const;

  // New version to replace the above old version.
  virtual PaintInvalidationReason InvalidatePaint(
      const PaintInvalidatorContext&) const;

  // When this object is invalidated for paint, this method is called to
  // invalidate any DisplayItemClients owned by this object, including the
  // object itself, LayoutText/LayoutInline line boxes, etc.,
  // not including children which will be invalidated normally during
  // invalidateTreeIfNeeded() and parts which are invalidated separately (e.g.
  // scrollbars). The caller should ensure the painting layer has been
  // setNeedsRepaint before calling this function.
  virtual void InvalidateDisplayItemClients(PaintInvalidationReason) const;

  virtual bool HasNonCompositedScrollbars() const { return false; }

  // Called before setting style for existing/new anonymous child. Override to
  // set custom styles for the child. For new anonymous child, |child| is null.
  virtual void UpdateAnonymousChildStyle(const LayoutObject* child,
                                         ComputedStyle& style) const {}

  // Returns a rect corresponding to this LayoutObject's bounds for use in
  // debugging output
  virtual LayoutRect DebugRect() const;

  // Each LayoutObject has one or more painting fragments (exactly one
  // in the absence of multicol/pagination).
  // See ../paint/README.md for more on fragments.
  const FragmentData& FirstFragment() const { return fragment_; }

  // Returns the bounding box of the visual rects of all fragments.
  LayoutRect FragmentsVisualRectBoundingBox() const;

  void SetNeedsOverflowRecalcAfterStyleChange();

  void InvalidateClipPathCache();

  // Call |SetShouldDoFullPaintInvalidation| for LayoutNG or
  // |SetShouldInvalidateSelection| on all selected children.
  void InvalidateSelectedChildrenOnStyleChange();

  // The whitelisted touch action is the union of the effective touch action
  // (from style) and blocking touch event handlers.
  TouchAction EffectiveWhitelistedTouchAction() const {
    if (InsideBlockingTouchEventHandler())
      return TouchAction::kTouchActionNone;
    return StyleRef().GetEffectiveTouchAction();
  }

  // Whether this object's Node has a blocking touch event handler on itself
  // or an ancestor.
  bool InsideBlockingTouchEventHandler() const {
    return bitfields_.InsideBlockingTouchEventHandler();
  }
  // Mark this object as having a |EffectiveWhitelistedTouchAction| changed, and
  // mark all ancestors as having a descendant that changed. This will cause a
  // PrePaint tree walk to update effective whitelisted touch action.
  void MarkEffectiveWhitelistedTouchActionChanged();
  bool EffectiveWhitelistedTouchActionChanged() const {
    return bitfields_.EffectiveWhitelistedTouchActionChanged();
  }
  bool DescendantEffectiveWhitelistedTouchActionChanged() const {
    return bitfields_.DescendantEffectiveWhitelistedTouchActionChanged();
  }
  void UpdateInsideBlockingTouchEventHandler(bool inside) {
    bitfields_.SetInsideBlockingTouchEventHandler(inside);
  }

  // Painters can use const methods only, except for these explicitly declared
  // methods.
  class CORE_EXPORT MutableForPainting {
   public:
    // Convenience mutator that clears paint invalidation flags and this object
    // and its descendants' needs-paint-property-update flags.
    void ClearPaintFlags() {
      DCHECK_EQ(layout_object_.GetDocument().Lifecycle().GetState(),
                DocumentLifecycle::kInPrePaint);
      layout_object_.ClearPaintInvalidationFlags();
      layout_object_.bitfields_.SetNeedsPaintPropertyUpdate(false);
      layout_object_.bitfields_.SetSubtreeNeedsPaintPropertyUpdate(false);
      layout_object_.bitfields_.SetDescendantNeedsPaintPropertyUpdate(false);
      layout_object_.bitfields_.SetEffectiveWhitelistedTouchActionChanged(
          false);
      layout_object_.bitfields_
          .SetDescendantEffectiveWhitelistedTouchActionChanged(false);
    }
    void SetMayNeedPaintInvalidation() {
      layout_object_.SetMayNeedPaintInvalidation();
    }
    void SetShouldDoFullPaintInvalidation(PaintInvalidationReason reason) {
      layout_object_.SetShouldDoFullPaintInvalidation(reason);
    }
    void SetShouldDoFullPaintInvalidationWithoutGeometryChange(
        PaintInvalidationReason reason) {
      layout_object_.SetShouldDoFullPaintInvalidationWithoutGeometryChange(
          reason);
    }
    void SetBackgroundChangedSinceLastPaintInvalidation() {
      layout_object_.SetBackgroundChangedSinceLastPaintInvalidation();
    }
    void EnsureIsReadyForPaintInvalidation() {
      layout_object_.EnsureIsReadyForPaintInvalidation();
    }

    // The following setters store the current values as calculated during the
    // pre-paint tree walk. TODO(wangxianzhu): Add check of lifecycle states.
    void SetVisualRect(const LayoutRect& r) {
      layout_object_.fragment_.SetVisualRect(r);
    }

    void SetSelectionVisualRect(const LayoutRect& r) {
      layout_object_.fragment_.SetSelectionVisualRect(r);
    }

    void SetPreviousBackgroundObscured(bool b) {
      layout_object_.SetPreviousBackgroundObscured(b);
    }
    void UpdatePreviousOutlineMayBeAffectedByDescendants() {
      layout_object_.SetPreviousOutlineMayBeAffectedByDescendants(
          layout_object_.OutlineMayBeAffectedByDescendants());
    }

    void ClearPreviousVisualRects() {
      layout_object_.ClearPreviousVisualRects();
    }
    void SetNeedsPaintPropertyUpdate() {
      layout_object_.SetNeedsPaintPropertyUpdate();
    }
    void SetSubtreeNeedsPaintPropertyUpdate() {
      layout_object_.SetSubtreeNeedsPaintPropertyUpdate();
    }

    void SetPartialInvalidationVisualRect(const LayoutRect& r) {
      DCHECK_EQ(layout_object_.GetDocument().Lifecycle().GetState(),
                DocumentLifecycle::kInPrePaint);
      FirstFragment().SetPartialInvalidationVisualRect(r);
    }

    void InvalidateClipPathCache() { layout_object_.InvalidateClipPathCache(); }

    void UpdateInsideBlockingTouchEventHandler(bool inside) {
      layout_object_.UpdateInsideBlockingTouchEventHandler(inside);
    }

#if DCHECK_IS_ON()
    // Same as setNeedsPaintPropertyUpdate() but does not mark ancestors as
    // having a descendant needing a paint property update.
    void SetOnlyThisNeedsPaintPropertyUpdateForTesting() {
      layout_object_.bitfields_.SetNeedsPaintPropertyUpdate(true);
    }
    void ClearNeedsPaintPropertyUpdateForTesting() {
      layout_object_.bitfields_.SetNeedsPaintPropertyUpdate(false);
    }
#endif

    FragmentData& FirstFragment() { return layout_object_.fragment_; }

   protected:
    friend class LayoutBoxModelObject;
    friend class LayoutScrollbar;
    friend class PaintInvalidator;
    friend class PaintPropertyTreeBuilder;
    friend class PrePaintTreeWalk;
    FRIEND_TEST_ALL_PREFIXES(AnimationCompositorAnimationsTest,
                             canStartElementOnCompositorTransformSPv2);
    FRIEND_TEST_ALL_PREFIXES(AnimationCompositorAnimationsTest,
                             canStartElementOnCompositorEffectSPv2);
    FRIEND_TEST_ALL_PREFIXES(PrePaintTreeWalkTest, ClipRects);
    FRIEND_TEST_ALL_PREFIXES(LayoutObjectTest, VisualRect);
    FRIEND_TEST_ALL_PREFIXES(BoxPaintInvalidatorTest,
                             ComputePaintInvalidationReasonBasic);

    friend class LayoutObject;
    MutableForPainting(const LayoutObject& layout_object)
        : layout_object_(const_cast<LayoutObject&>(layout_object)) {}

    LayoutObject& layout_object_;
  };
  MutableForPainting GetMutableForPainting() const {
    return MutableForPainting(*this);
  }

  // Paint properties (see: |ObjectPaintProperties|) are built from an object's
  // state (location, transform, etc) as well as properties from ancestors.
  // When these inputs change, setNeedsPaintPropertyUpdate will cause a property
  // tree update during the next document lifecycle update.
  //
  // In addition to tracking if an object needs its own paint properties
  // updated, setNeedsPaintPropertyUpdate marks all ancestors as having a
  // descendant needing a paint property update too.
  void SetNeedsPaintPropertyUpdate();
  bool NeedsPaintPropertyUpdate() const {
    return bitfields_.NeedsPaintPropertyUpdate();
  }
  void SetSubtreeNeedsPaintPropertyUpdate() {
    bitfields_.SetSubtreeNeedsPaintPropertyUpdate(true);
    SetNeedsPaintPropertyUpdate();
  }
  bool SubtreeNeedsPaintPropertyUpdate() const {
    return bitfields_.SubtreeNeedsPaintPropertyUpdate();
  }
  bool DescendantNeedsPaintPropertyUpdate() const {
    return bitfields_.DescendantNeedsPaintPropertyUpdate();
  }
  // Main thread scrolling reasons require fully updating paint propeties of all
  // ancestors (see: ScrollPaintPropertyNode.h).
  void SetAncestorsNeedPaintPropertyUpdateForMainThreadScrolling();

  void SetIsScrollAnchorObject() { bitfields_.SetIsScrollAnchorObject(true); }
  // Clears the IsScrollAnchorObject bit if and only if no ScrollAnchors still
  // reference this LayoutObject.
  void MaybeClearIsScrollAnchorObject();

  bool ScrollAnchorDisablingStyleChanged() {
    return bitfields_.ScrollAnchorDisablingStyleChanged();
  }
  void SetScrollAnchorDisablingStyleChanged(bool changed) {
    bitfields_.SetScrollAnchorDisablingStyleChanged(changed);
  }

  void ClearChildNeedsOverflowRecalcAfterStyleChange() {
    bitfields_.SetChildNeedsOverflowRecalcAfterStyleChange(false);
  }

  bool CompositedScrollsWithRespectTo(
      const LayoutBoxModelObject& paint_invalidation_container) const;
  IntSize ScrollAdjustmentForPaintInvalidation(
      const LayoutBoxModelObject& paint_invalidation_container) const;

  bool PreviousBackgroundObscured() const {
    return bitfields_.PreviousBackgroundObscured();
  }
  void SetPreviousBackgroundObscured(bool b) {
    bitfields_.SetPreviousBackgroundObscured(b);
  }

  bool IsBackgroundAttachmentFixedObject() const {
    return bitfields_.IsBackgroundAttachmentFixedObject();
  }

  bool BackgroundChangedSinceLastPaintInvalidation() const {
    return bitfields_.BackgroundChangedSinceLastPaintInvalidation();
  }
  void SetBackgroundChangedSinceLastPaintInvalidation() {
    bitfields_.SetBackgroundChangedSinceLastPaintInvalidation(true);
  }

  bool OutlineMayBeAffectedByDescendants() const {
    return bitfields_.OutlineMayBeAffectedByDescendants();
  }
  bool PreviousOutlineMayBeAffectedByDescendants() const {
    return bitfields_.PreviousOutlineMayBeAffectedByDescendants();
  }

  LayoutRect SelectionVisualRect() const {
    return fragment_.SelectionVisualRect();
  }
  LayoutRect PartialInvalidationLocalRect() const {
    return fragment_.PartialInvalidationLocalRect();
  }

  void InvalidateIfControlStateChanged(ControlState);

  bool ContainsInlineWithOutlineAndContinuation() const {
    return bitfields_.ContainsInlineWithOutlineAndContinuation();
  }

  void SetOutlineMayBeAffectedByDescendants(bool b) {
    bitfields_.SetOutlineMayBeAffectedByDescendants(b);
  }

 protected:
  enum LayoutObjectType {
    kLayoutObjectBr,
    kLayoutObjectCanvas,
    kLayoutObjectFieldset,
    kLayoutObjectCounter,
    kLayoutObjectDetailsMarker,
    kLayoutObjectEmbeddedObject,
    kLayoutObjectFileUploadControl,
    kLayoutObjectFrame,
    kLayoutObjectFrameSet,
    kLayoutObjectLayoutTableCol,
    kLayoutObjectListBox,
    kLayoutObjectListItem,
    kLayoutObjectListMarker,
    kLayoutObjectMedia,
    kLayoutObjectMenuList,
    kLayoutObjectNGBlockFlow,
    kLayoutObjectNGFlexibleBox,
    kLayoutObjectNGMixin,
    kLayoutObjectNGListItem,
    kLayoutObjectNGListMarker,
    kLayoutObjectNGListMarkerImage,
    kLayoutObjectNGText,
    kLayoutObjectProgress,
    kLayoutObjectQuote,
    kLayoutObjectLayoutButton,
    kLayoutObjectLayoutCustom,
    kLayoutObjectLayoutFlowThread,
    kLayoutObjectLayoutGrid,
    kLayoutObjectLayoutIFrame,
    kLayoutObjectLayoutImage,
    kLayoutObjectLayoutInline,
    kLayoutObjectLayoutMultiColumnSet,
    kLayoutObjectLayoutMultiColumnSpannerPlaceholder,
    kLayoutObjectLayoutEmbeddedContent,
    kLayoutObjectLayoutReplaced,
    kLayoutObjectLayoutScrollbarPart,
    kLayoutObjectLayoutView,
    kLayoutObjectRuby,
    kLayoutObjectRubyBase,
    kLayoutObjectRubyRun,
    kLayoutObjectRubyText,
    kLayoutObjectSlider,
    kLayoutObjectSliderThumb,
    kLayoutObjectTable,
    kLayoutObjectTableCaption,
    kLayoutObjectTableCell,
    kLayoutObjectTableRow,
    kLayoutObjectTableSection,
    kLayoutObjectTextArea,
    kLayoutObjectTextControl,
    kLayoutObjectTextField,
    kLayoutObjectVideo,
    kLayoutObjectWidget,

    kLayoutObjectSVG, /* Keep by itself? */
    kLayoutObjectSVGRoot,
    kLayoutObjectSVGContainer,
    kLayoutObjectSVGTransformableContainer,
    kLayoutObjectSVGViewportContainer,
    kLayoutObjectSVGHiddenContainer,
    kLayoutObjectSVGShape,
    kLayoutObjectSVGText,
    kLayoutObjectSVGTextPath,
    kLayoutObjectSVGInline,
    kLayoutObjectSVGInlineText,
    kLayoutObjectSVGImage,
    kLayoutObjectSVGForeignObject,
    kLayoutObjectSVGResourceContainer,
    kLayoutObjectSVGResourceFilter,
    kLayoutObjectSVGResourceFilterPrimitive,
  };
  virtual bool IsOfType(LayoutObjectType type) const { return false; }

  // Overrides should call the superclass at the end. style_ will be 0 the
  // first time this function will be called.
  virtual void StyleWillChange(StyleDifference, const ComputedStyle& new_style);
  // Overrides should call the superclass at the start. |oldStyle| will be 0 the
  // first time this function is called.
  virtual void StyleDidChange(StyleDifference, const ComputedStyle* old_style);
  void PropagateStyleToAnonymousChildren();
  // Return true for objects that don't want style changes automatically
  // propagated via propagateStyleToAnonymousChildren(), but rather rely on
  // other custom mechanisms (if they need to be notified of parent style
  // changes at all).
  virtual bool AnonymousHasStylePropagationOverride() { return false; }

  // A fast path for MapToVisualRectInAncestorSpace for when GeometryMapper
  // can be used. |intersects| is set to whether the input rect intersected
  // (see documentation of return value of MapToVisualRectInAncestorSpace).
  //
  // The return value of this method is whether the fast path could be used.
  bool MapToVisualRectInAncestorSpaceInternalFastPath(
      const LayoutBoxModelObject* ancestor,
      LayoutRect&,
      VisualRectFlags,
      bool& intersects) const;

  // This function is called before calling the destructor so that some clean-up
  // can happen regardless of whether they call a virtual function or not. As a
  // rule of thumb, this function should be preferred to the destructor. See
  // destroy() that is the one calling willBeDestroyed().
  //
  // There are 2 types of destructions: regular destructions and tree tear-down.
  // Regular destructions happen when the renderer is not needed anymore (e.g.
  // 'display' changed or the DOM Node was removed).
  // Tree tear-down is when the whole tree destroyed during navigation. It is
  // handled in the code by checking if documentBeingDestroyed() returns 'true'.
  // In this case, the code skips some unneeded expensive operations as we know
  // the tree is not reused (e.g. avoid clearing the containing block's line
  // box).
  virtual void WillBeDestroyed();

  virtual void InsertedIntoTree();
  virtual void WillBeRemovedFromTree();

  void SetDocumentForAnonymous(Document* document) {
    DCHECK(IsAnonymous());
    node_ = document;
  }

  // Add hit-test rects for the layout tree rooted at this node to the provided
  // collection on a per-Layer basis.
  // currentLayer must be the enclosing layer, and layerOffset is the current
  // offset within this layer. Subclass implementations will add any offset for
  // this layoutObject within it's container, so callers should provide only the
  // offset of the container within it's layer.
  // containerRect is a rect that has already been added for the currentLayer
  // which is likely to be a container for child elements. Any rect wholly
  // contained by containerRect can be skipped.
  virtual void AddLayerHitTestRects(
      LayerHitTestRects&,
      const PaintLayer* current_layer,
      const LayoutPoint& layer_offset,
      TouchAction supported_fast_actions,
      const LayoutRect& container_rect,
      TouchAction container_whitelisted_touch_action) const;

  // Add hit-test rects for this layoutObject only to the provided list.
  // layerOffset is the offset of this layoutObject within the current layer
  // that should be used for each result.
  virtual void ComputeSelfHitTestRects(Vector<LayoutRect>&,
                                       const LayoutPoint& layer_offset) const {}

#if DCHECK_IS_ON()
  virtual bool PaintInvalidationStateIsDirty() const {
    return BackgroundChangedSinceLastPaintInvalidation() ||
           ShouldCheckForPaintInvalidation() || ShouldInvalidateSelection() ||
           NeedsPaintOffsetAndVisualRectUpdate() ||
           !fragment_.PartialInvalidationLocalRect().IsEmpty();
  }
#endif

  // Called before paint invalidation.
  virtual void EnsureIsReadyForPaintInvalidation() { DCHECK(!NeedsLayout()); }

  void SetIsBackgroundAttachmentFixedObject(bool);

  void ClearSelfNeedsOverflowRecalcAfterStyleChange() {
    bitfields_.SetSelfNeedsOverflowRecalcAfterStyleChange(false);
  }
  void SetEverHadLayout() { bitfields_.SetEverHadLayout(true); }

  // Remove this object and all descendants from the containing
  // LayoutFlowThread.
  void RemoveFromLayoutFlowThread();

  void SetContainsInlineWithOutlineAndContinuation(bool b) {
    bitfields_.SetContainsInlineWithOutlineAndContinuation(b);
  }

  void SetPreviousOutlineMayBeAffectedByDescendants(bool b) {
    bitfields_.SetPreviousOutlineMayBeAffectedByDescendants(b);
  }

  virtual bool VisualRectRespectsVisibility() const { return true; }
  virtual LayoutRect LocalVisualRectIgnoringVisibility() const;

  virtual bool CanBeSelectionLeafInternal() const { return false; }

  virtual LayoutSize OffsetFromContainerInternal(
      const LayoutObject*,
      bool ignore_scroll_offset) const;
  LayoutSize OffsetFromScrollableContainer(const LayoutObject*,
                                           bool ignore_scroll_offset) const;

 private:
  // Used only by applyFirstLineChanges to get a first line style based off of a
  // given new style, without accessing the cache.
  scoped_refptr<ComputedStyle> UncachedFirstLineStyle() const;

  // Adjusts a visual rect in the space of |visual_rect| to be in the space of
  // the |paint_invalidation_container|, if needed. They can be different only
  // if |paint_invalidation_container| is a composited scroller.
  void AdjustVisualRectForCompositedScrolling(
      LayoutRect& visual_rect,
      const LayoutBoxModelObject& paint_invalidation_container) const;

  FloatQuad LocalToAncestorQuadInternal(const FloatQuad&,
                                        const LayoutBoxModelObject* ancestor,
                                        MapCoordinatesFlags = 0) const;

  void ClearLayoutRootIfNeeded() const;

  bool IsInert() const;

  void UpdateImage(StyleImage*, StyleImage*);

  void ScheduleRelayout();

  void UpdateShapeImage(const ShapeValue*, const ShapeValue*);
  void UpdateFillImages(const FillLayer* old_layers,
                        const FillLayer& new_layers);
  void UpdateCursorImages(const CursorList* old_cursors,
                          const CursorList* new_cursors);
  void CheckCounterChanges(const ComputedStyle* old_style,
                           const ComputedStyle* new_style);

  // Walk up the parent chain and find the first scrolling block to disable
  // scroll anchoring on.
  void SetScrollAnchorDisablingStyleChangedOnAncestor();

  inline void MarkContainerChainForOverflowRecalcIfNeeded();

  inline void MarkAncestorsForPaintInvalidation();
  inline void SetNeedsPaintOffsetAndVisualRectUpdate();

  inline void InvalidateContainerPreferredLogicalWidths();

  LayoutObject* ContainerForAbsolutePosition(AncestorSkipInfo* = nullptr) const;
  LayoutObject* ContainerForFixedPosition(AncestorSkipInfo* = nullptr) const;

  const LayoutBoxModelObject* EnclosingCompositedContainer() const;

  LayoutFlowThread* LocateFlowThreadContainingBlock() const;
  void RemoveFromLayoutFlowThreadRecursive(LayoutFlowThread*);

  ComputedStyle* CachedFirstLineStyle() const;
  StyleDifference AdjustStyleDifference(StyleDifference) const;

  void RemoveShapeImageClient(ShapeValue*);
  void RemoveCursorImageClient(const CursorList*);

  // These are helper functions for AbsoluteBoudingBoxRectHandlingEmptyAnchor()
  // and AbsoluteBoundingBoxRectForScrollIntoView().
  enum class ExpandScrollMargin { kExpand, kIgnore };
  LayoutRect AbsoluteBoundingBoxRectHelper(ExpandScrollMargin) const;
  bool GetUpperLeftCorner(ExpandScrollMargin, FloatPoint&) const;
  bool GetLowerRightCorner(ExpandScrollMargin, FloatPoint&) const;

#if DCHECK_IS_ON()
  void CheckBlockPositionedObjectsNeedLayout();
#endif

  bool IsTextOrSVGChild() const { return IsText() || IsSVGChild(); }

  static bool IsAllowedToModifyLayoutTreeStructure(Document&);

  // Returns the parent LayoutObject, or nullptr. This has a special case for
  // LayoutView to return the owning LayoutObject in the containing frame.
  inline LayoutObject* ParentCrossingFrames() const;

  void ApplyPseudoStyleChanges(const ComputedStyle& old_style);
  void ApplyFirstLineChanges(const ComputedStyle& old_style);

  scoped_refptr<ComputedStyle> style_;

  // Oilpan: This untraced pointer to the owning Node is considered safe.
  UntracedMember<Node> node_;

  LayoutObject* parent_;
  LayoutObject* previous_;
  LayoutObject* next_;

#if DCHECK_IS_ON()
  unsigned has_ax_object_ : 1;
  unsigned set_needs_layout_forbidden_ : 1;
#endif

#define ADD_BOOLEAN_BITFIELD(field_name_, MethodNameBase) \
 private:                                                 \
  unsigned field_name_ : 1;                               \
                                                          \
 public:                                                  \
  bool MethodNameBase() const { return field_name_; }     \
  void Set##MethodNameBase(bool new_value) { field_name_ = new_value; }

  class LayoutObjectBitfields {
    enum PositionedState {
      kIsStaticallyPositioned = 0,
      kIsRelativelyPositioned = 1,
      kIsOutOfFlowPositioned = 2,
      kIsStickyPositioned = 3,
    };

   public:
    // LayoutObjectBitfields holds all the boolean values for LayoutObject.
    //
    // This is done to promote better packing on LayoutObject (at the expense of
    // preventing bit field packing for the subclasses). Classes concerned about
    // packing and memory use should hoist their boolean to this class. See
    // below the field from sub-classes (e.g. childrenInline).
    //
    // Some of those booleans are caches of ComputedStyle values (e.g.
    // positionState). This enables better memory locality and thus better
    // performance.
    //
    // This class is an artifact of the WebKit era where LayoutObject wasn't
    // allowed to grow and each sub-class was strictly monitored for memory
    // increase. Our measurements indicate that the size of LayoutObject and
    // subsequent classes do not impact memory or speed in a significant
    // manner. This is based on growing LayoutObject in
    // https://codereview.chromium.org/44673003 and subsequent relaxations
    // of the memory constraints on layout objects.
    LayoutObjectBitfields(Node* node)
        : self_needs_layout_(false),
          needs_positioned_movement_layout_(false),
          normal_child_needs_layout_(false),
          pos_child_needs_layout_(false),
          needs_simplified_normal_flow_layout_(false),
          self_needs_overflow_recalc_after_style_change_(false),
          child_needs_overflow_recalc_after_style_change_(false),
          preferred_logical_widths_dirty_(false),
          needs_collect_inlines_(false),
          may_need_paint_invalidation_(false),
          may_need_paint_invalidation_subtree_(false),
          may_need_paint_invalidation_animated_background_image_(false),
          needs_paint_offset_and_visual_rect_update_(false),
          should_invalidate_selection_(false),
          floating_(false),
          is_anonymous_(!node),
          is_text_(false),
          is_box_(false),
          is_inline_(true),
          is_atomic_inline_level_(false),
          horizontal_writing_mode_(true),
          has_layer_(false),
          has_overflow_clip_(false),
          should_clip_overflow_(false),
          has_transform_related_property_(false),
          has_reflection_(false),
          can_contain_fixed_position_objects_(false),
          has_counter_node_map_(false),
          ever_had_layout_(false),
          ancestor_line_box_dirty_(false),
          is_inside_flow_thread_(false),
          subtree_change_listener_registered_(false),
          notified_of_subtree_change_(false),
          consumes_subtree_change_notification_(false),
          children_inline_(false),
          contains_inline_with_outline_and_continuation_(false),
          always_create_line_boxes_for_layout_inline_(false),
          previous_background_obscured_(false),
          is_background_attachment_fixed_object_(false),
          is_scroll_anchor_object_(false),
          scroll_anchor_disabling_style_changed_(false),
          has_box_decoration_background_(false),
          needs_paint_property_update_(true),
          subtree_needs_paint_property_update_(true),
          descendant_needs_paint_property_update_(true),
          background_changed_since_last_paint_invalidation_(true),
          outline_may_be_affected_by_descendants_(false),
          previous_outline_may_be_affected_by_descendants_(false),
          is_truncated_(false),
          inside_blocking_touch_event_handler_(false),
          effective_whitelisted_touch_action_changed_(true),
          descendant_effective_whitelisted_touch_action_changed_(false),
          positioned_state_(kIsStaticallyPositioned),
          selection_state_(static_cast<unsigned>(SelectionState::kNone)),
          background_obscuration_state_(kBackgroundObscurationStatusInvalid),
          full_paint_invalidation_reason_(
              static_cast<unsigned>(PaintInvalidationReason::kNone)) {}

    // Self needs layout means that this layout object is marked for a full
    // layout. This is the default layout but it is expensive as it recomputes
    // everything. For CSS boxes, this includes the width (laying out the line
    // boxes again), the margins (due to block collapsing margins), the
    // positions, the height and the potential overflow.
    ADD_BOOLEAN_BITFIELD(self_needs_layout_, SelfNeedsLayout);

    // A positioned movement layout is a specialized type of layout used on
    // positioned objects that only visually moved. This layout is used when
    // changing 'top'/'left' on a positioned element or margins on an
    // out-of-flow one. Because the following operations don't impact the size
    // of the object or sibling LayoutObjects, this layout is very lightweight.
    //
    // Positioned movement layout is implemented in
    // LayoutBlock::simplifiedLayout.
    ADD_BOOLEAN_BITFIELD(needs_positioned_movement_layout_,
                         NeedsPositionedMovementLayout);

    // This boolean is set when a normal flow ('position' == static || relative)
    // child requires layout (but this object doesn't). Due to the nature of
    // CSS, laying out a child can cause the parent to resize (e.g., if 'height'
    // is auto).
    ADD_BOOLEAN_BITFIELD(normal_child_needs_layout_, NormalChildNeedsLayout);

    // This boolean is set when an out-of-flow positioned ('position' == fixed
    // || absolute) child requires layout (but this object doesn't).
    ADD_BOOLEAN_BITFIELD(pos_child_needs_layout_, PosChildNeedsLayout);

    // Simplified normal flow layout only relayouts the normal flow children,
    // ignoring the out-of-flow descendants.
    //
    // The implementation of this layout is in
    // LayoutBlock::simplifiedNormalFlowLayout.
    ADD_BOOLEAN_BITFIELD(needs_simplified_normal_flow_layout_,
                         NeedsSimplifiedNormalFlowLayout);

    // Some properties only have a visual impact and don't impact the actual
    // layout position and sizes of the object. An example of this is the
    // 'transform' property, who doesn't modify the layout but gets applied at
    // paint time. Setting this flag only recomputes the overflow information.
    ADD_BOOLEAN_BITFIELD(self_needs_overflow_recalc_after_style_change_,
                         SelfNeedsOverflowRecalcAfterStyleChange);

    // This flag is set on the ancestor of a LayoutObject needing
    // selfNeedsOverflowRecalcAfterStyleChange. This is needed as a descendant
    // overflow can bleed into its containing block's so we have to recompute it
    // in some cases.
    ADD_BOOLEAN_BITFIELD(child_needs_overflow_recalc_after_style_change_,
                         ChildNeedsOverflowRecalcAfterStyleChange);

    // This boolean marks preferred logical widths for lazy recomputation.
    //
    // See INTRINSIC SIZES / PREFERRED LOGICAL WIDTHS above about those
    // widths.
    ADD_BOOLEAN_BITFIELD(preferred_logical_widths_dirty_,
                         PreferredLogicalWidthsDirty);

    // This flag is set on inline container boxes that need to run the
    // Pre-layout phase in LayoutNG. See NGInlineNode::CollectInlines().
    // Also maybe set to inline boxes to optimize the propagation.
    ADD_BOOLEAN_BITFIELD(needs_collect_inlines_, NeedsCollectInlines);

    ADD_BOOLEAN_BITFIELD(may_need_paint_invalidation_,
                         MayNeedPaintInvalidation);
    ADD_BOOLEAN_BITFIELD(may_need_paint_invalidation_subtree_,
                         MayNeedPaintInvalidationSubtree);
    ADD_BOOLEAN_BITFIELD(may_need_paint_invalidation_animated_background_image_,
                         MayNeedPaintInvalidationAnimatedBackgroundImage);
    ADD_BOOLEAN_BITFIELD(needs_paint_offset_and_visual_rect_update_,
                         NeedsPaintOffsetAndVisualRectUpdate);
    ADD_BOOLEAN_BITFIELD(should_invalidate_selection_,
                         ShouldInvalidateSelection);

    // This boolean is the cached value of 'float'
    // (see ComputedStyle::isFloating).
    ADD_BOOLEAN_BITFIELD(floating_, Floating);

    ADD_BOOLEAN_BITFIELD(is_anonymous_, IsAnonymous);
    ADD_BOOLEAN_BITFIELD(is_text_, IsText);
    ADD_BOOLEAN_BITFIELD(is_box_, IsBox);

    // This boolean represents whether the LayoutObject is 'inline-level'
    // (a CSS concept). Inline-level boxes are laid out inside a line. If
    // unset, the box is 'block-level' and thus stack on top of its
    // siblings (think of paragraphs).
    ADD_BOOLEAN_BITFIELD(is_inline_, IsInline);

    // This boolean is set if the element is an atomic inline-level box.
    //
    // In CSS, atomic inline-level boxes are laid out on a line but they
    // are opaque from the perspective of line layout. This means that they
    // can't be split across lines like normal inline boxes (LayoutInline).
    // Examples of atomic inline-level elements: inline tables, inline
    // blocks and replaced inline elements.
    // See http://www.w3.org/TR/CSS2/visuren.html#inline-boxes.
    //
    // Our code is confused about the use of this boolean and confuses it
    // with being replaced (see LayoutReplaced about this).
    // TODO(jchaffraix): We should inspect callers and clarify their use.
    // TODO(jchaffraix): We set this boolean for replaced elements that are
    // not inline but shouldn't (crbug.com/567964). This should be enforced.
    ADD_BOOLEAN_BITFIELD(is_atomic_inline_level_, IsAtomicInlineLevel);
    ADD_BOOLEAN_BITFIELD(horizontal_writing_mode_, HorizontalWritingMode);

    ADD_BOOLEAN_BITFIELD(has_layer_, HasLayer);

    // This boolean is set if overflow != 'visible'.
    // This means that this object may need an overflow clip to be applied
    // at paint time to its visual overflow (see OverflowModel for more
    // details). Only set for LayoutBoxes and descendants.
    ADD_BOOLEAN_BITFIELD(has_overflow_clip_, HasOverflowClip);

    // Returns whether content which overflows should be clipped. This is not
    // just because of overflow clip, but other types of clip as well, such as
    // control clips or contain: paint.
    ADD_BOOLEAN_BITFIELD(should_clip_overflow_, ShouldClipOverflow);

    // This boolean is the cached value from
    // ComputedStyle::hasTransformRelatedProperty.
    ADD_BOOLEAN_BITFIELD(has_transform_related_property_,
                         HasTransformRelatedProperty);
    ADD_BOOLEAN_BITFIELD(has_reflection_, HasReflection);

    // This boolean is used to know if this LayoutObject is a container for
    // fixed position descendants.
    ADD_BOOLEAN_BITFIELD(can_contain_fixed_position_objects_,
                         CanContainFixedPositionObjects);

    // This boolean is used to know if this LayoutObject has one (or more)
    // associated CounterNode(s).
    // See class comment in LayoutCounter.h for more detail.
    ADD_BOOLEAN_BITFIELD(has_counter_node_map_, HasCounterNodeMap);

    ADD_BOOLEAN_BITFIELD(ever_had_layout_, EverHadLayout);
    ADD_BOOLEAN_BITFIELD(ancestor_line_box_dirty_, AncestorLineBoxDirty);

    ADD_BOOLEAN_BITFIELD(is_inside_flow_thread_, IsInsideFlowThread);

    ADD_BOOLEAN_BITFIELD(subtree_change_listener_registered_,
                         SubtreeChangeListenerRegistered);
    ADD_BOOLEAN_BITFIELD(notified_of_subtree_change_, NotifiedOfSubtreeChange);
    ADD_BOOLEAN_BITFIELD(consumes_subtree_change_notification_,
                         ConsumesSubtreeChangeNotification);

    // from LayoutBlock
    ADD_BOOLEAN_BITFIELD(children_inline_, ChildrenInline);

    // from LayoutBlockFlow
    ADD_BOOLEAN_BITFIELD(contains_inline_with_outline_and_continuation_,
                         ContainsInlineWithOutlineAndContinuation);

    // from LayoutInline
    ADD_BOOLEAN_BITFIELD(always_create_line_boxes_for_layout_inline_,
                         AlwaysCreateLineBoxesForLayoutInline);

    // Background obscuration status of the previous frame.
    ADD_BOOLEAN_BITFIELD(previous_background_obscured_,
                         PreviousBackgroundObscured);

    ADD_BOOLEAN_BITFIELD(is_background_attachment_fixed_object_,
                         IsBackgroundAttachmentFixedObject);
    ADD_BOOLEAN_BITFIELD(is_scroll_anchor_object_, IsScrollAnchorObject);

    // Whether changes in this LayoutObject's CSS properties since the last
    // layout should suppress any adjustments that would be made during the next
    // layout by ScrollAnchor objects for which this LayoutObject is on the path
    // from the anchor node to the scroller.
    // See http://bit.ly/sanaclap for more info.
    ADD_BOOLEAN_BITFIELD(scroll_anchor_disabling_style_changed_,
                         ScrollAnchorDisablingStyleChanged);

    ADD_BOOLEAN_BITFIELD(has_box_decoration_background_,
                         HasBoxDecorationBackground);

    // Whether the paint properties need to be updated. For more details, see
    // LayoutObject::needsPaintPropertyUpdate().
    ADD_BOOLEAN_BITFIELD(needs_paint_property_update_,
                         NeedsPaintPropertyUpdate);
    // Whether paint properties of the whole subtree need to be updated.
    ADD_BOOLEAN_BITFIELD(subtree_needs_paint_property_update_,
                         SubtreeNeedsPaintPropertyUpdate)
    // Whether the paint properties of a descendant need to be updated. For more
    // details, see LayoutObject::descendantNeedsPaintPropertyUpdate().
    ADD_BOOLEAN_BITFIELD(descendant_needs_paint_property_update_,
                         DescendantNeedsPaintPropertyUpdate);

    ADD_BOOLEAN_BITFIELD(background_changed_since_last_paint_invalidation_,
                         BackgroundChangedSinceLastPaintInvalidation);

    // Whether shape of outline may be affected by any descendants. This is
    // updated before paint invalidation, checked during paint invalidation.
    ADD_BOOLEAN_BITFIELD(outline_may_be_affected_by_descendants_,
                         OutlineMayBeAffectedByDescendants);
    // The outlineMayBeAffectedByDescendants status of the last paint
    // invalidation.
    ADD_BOOLEAN_BITFIELD(previous_outline_may_be_affected_by_descendants_,
                         PreviousOutlineMayBeAffectedByDescendants);

    ADD_BOOLEAN_BITFIELD(is_truncated_, IsTruncated);

    // Whether this object's Node has a blocking touch event handler on itself
    // or an ancestor. This is updated during the PrePaint phase.
    ADD_BOOLEAN_BITFIELD(inside_blocking_touch_event_handler_,
                         InsideBlockingTouchEventHandler);

    // Set when |EffectiveWhitelistedTouchAction| changes (i.e., blocking touch
    // event handlers change or effective touch action style changes). This only
    // needs to be set on the object that changes as the PrePaint walk will
    // ensure descendants are updated.
    ADD_BOOLEAN_BITFIELD(effective_whitelisted_touch_action_changed_,
                         EffectiveWhitelistedTouchActionChanged);

    // Set when a descendant's |EffectiveWhitelistedTouchAction| changes. This
    // is used to ensure the PrePaint tree walk processes objects with
    // |effective_whitelisted_touch_action_changed_|.
    ADD_BOOLEAN_BITFIELD(descendant_effective_whitelisted_touch_action_changed_,
                         DescendantEffectiveWhitelistedTouchActionChanged);

   protected:
    // Use protected to avoid warning about unused variable.
    // Increment this to 63 if a new bit is added.
    // unsigned unused_bits_ : 0;

   private:
    // This is the cached 'position' value of this object
    // (see ComputedStyle::position).
    unsigned positioned_state_ : 2;  // PositionedState
    unsigned selection_state_ : 3;   // SelectionState
    // Mutable for getter which lazily update this field.
    mutable unsigned
        background_obscuration_state_ : 2;         // BackgroundObscurationState

    unsigned full_paint_invalidation_reason_ : 5;  // PaintInvalidationReason
    static_assert(static_cast<unsigned>(PaintInvalidationReason::kMax) <
                      (1u << 5),
                  "PaintInvalidationReason should fit in the bit field");

   public:
    bool IsOutOfFlowPositioned() const {
      return positioned_state_ == kIsOutOfFlowPositioned;
    }
    bool IsRelPositioned() const {
      return positioned_state_ == kIsRelativelyPositioned;
    }
    bool IsStickyPositioned() const {
      return positioned_state_ == kIsStickyPositioned;
    }
    bool IsInFlowPositioned() const {
      return positioned_state_ == kIsRelativelyPositioned ||
             positioned_state_ == kIsStickyPositioned;
    }
    bool IsPositioned() const {
      return positioned_state_ != kIsStaticallyPositioned;
    }

    void SetPositionedState(EPosition position_state) {
      // This maps FixedPosition and AbsolutePosition to
      // IsOutOfFlowPositioned, saving one bit.
      switch (position_state) {
        case EPosition::kStatic:
          positioned_state_ = kIsStaticallyPositioned;
          break;
        case EPosition::kRelative:
          positioned_state_ = kIsRelativelyPositioned;
          break;
        case EPosition::kAbsolute:
        case EPosition::kFixed:
          positioned_state_ = kIsOutOfFlowPositioned;
          break;
        case EPosition::kSticky:
          positioned_state_ = kIsStickyPositioned;
          break;
        default:
          NOTREACHED();
          break;
      }
    }
    void ClearPositionedState() {
      positioned_state_ = kIsStaticallyPositioned;
    }

    ALWAYS_INLINE SelectionState GetSelectionState() const {
      return static_cast<SelectionState>(selection_state_);
    }
    ALWAYS_INLINE void SetSelectionState(SelectionState selection_state) {
      selection_state_ = static_cast<unsigned>(selection_state);
    }

    ALWAYS_INLINE BackgroundObscurationState
    GetBackgroundObscurationState() const {
      return static_cast<BackgroundObscurationState>(
          background_obscuration_state_);
    }
    ALWAYS_INLINE void SetBackgroundObscurationState(
        BackgroundObscurationState s) const {
      background_obscuration_state_ = s;
    }

    PaintInvalidationReason FullPaintInvalidationReason() const {
      return static_cast<PaintInvalidationReason>(
          full_paint_invalidation_reason_);
    }
    void SetFullPaintInvalidationReason(PaintInvalidationReason reason) {
      full_paint_invalidation_reason_ = static_cast<unsigned>(reason);
    }
  };

#undef ADD_BOOLEAN_BITFIELD

  LayoutObjectBitfields bitfields_;

  void SetSelfNeedsLayout(bool b) { bitfields_.SetSelfNeedsLayout(b); }
  void SetNeedsPositionedMovementLayout(bool b) {
    bitfields_.SetNeedsPositionedMovementLayout(b);
  }
  void SetNormalChildNeedsLayout(bool b) {
    bitfields_.SetNormalChildNeedsLayout(b);
  }
  void SetPosChildNeedsLayout(bool b) { bitfields_.SetPosChildNeedsLayout(b); }
  void SetNeedsSimplifiedNormalFlowLayout(bool b) {
    bitfields_.SetNeedsSimplifiedNormalFlowLayout(b);
  }
  void SetNeedsCollectInlines(bool b) { bitfields_.SetNeedsCollectInlines(b); }

  void SetSelfNeedsOverflowRecalcAfterStyleChange() {
    bitfields_.SetSelfNeedsOverflowRecalcAfterStyleChange(true);
  }
  void SetChildNeedsOverflowRecalcAfterStyleChange() {
    bitfields_.SetChildNeedsOverflowRecalcAfterStyleChange(true);
  }

 private:
  friend class LineLayoutItem;

  // Store state between styleWillChange and styleDidChange
  static bool affects_parent_block_;

  FragmentData fragment_;
  DISALLOW_COPY_AND_ASSIGN(LayoutObject);
};

// Allow equality comparisons of LayoutObjects by reference or pointer,
// interchangeably.
DEFINE_COMPARISON_OPERATORS_WITH_REFERENCES(LayoutObject)

inline bool LayoutObject::DocumentBeingDestroyed() const {
  return GetDocument().Lifecycle().GetState() >= DocumentLifecycle::kStopping;
}

inline bool LayoutObject::IsBeforeContent() const {
  if (StyleRef().StyleType() != kPseudoIdBefore)
    return false;
  // Text nodes don't have their own styles, so ignore the style on a text node.
  if (IsText() && !IsBR())
    return false;
  return true;
}

inline bool LayoutObject::IsAfterContent() const {
  if (StyleRef().StyleType() != kPseudoIdAfter)
    return false;
  // Text nodes don't have their own styles, so ignore the style on a text node.
  if (IsText() && !IsBR())
    return false;
  return true;
}

inline bool LayoutObject::IsBeforeOrAfterContent() const {
  return IsBeforeContent() || IsAfterContent();
}

// setNeedsLayout() won't cause full paint invalidations as
// setNeedsLayoutAndFullPaintInvalidation() does. Otherwise the two methods are
// identical.
inline void LayoutObject::SetNeedsLayout(
    LayoutInvalidationReasonForTracing reason,
    MarkingBehavior mark_parents,
    SubtreeLayoutScope* layouter) {
#if DCHECK_IS_ON()
  DCHECK(!IsSetNeedsLayoutForbidden());
#endif
  bool already_needed_layout = bitfields_.SelfNeedsLayout();
  SetSelfNeedsLayout(true);
  MarkContainerNeedsCollectInlines();
  if (!already_needed_layout) {
    TRACE_EVENT_INSTANT1(
        TRACE_DISABLED_BY_DEFAULT("devtools.timeline.invalidationTracking"),
        "LayoutInvalidationTracking", TRACE_EVENT_SCOPE_THREAD, "data",
        InspectorLayoutInvalidationTrackingEvent::Data(this, reason));
    if (mark_parents == kMarkContainerChain &&
        (!layouter || layouter->Root() != this))
      MarkContainerChainForLayout(!layouter, layouter);
  }
}

inline void LayoutObject::SetNeedsLayoutAndFullPaintInvalidation(
    LayoutInvalidationReasonForTracing reason,
    MarkingBehavior mark_parents,
    SubtreeLayoutScope* layouter) {
  SetNeedsLayout(reason, mark_parents, layouter);
  SetShouldDoFullPaintInvalidation();
}

inline void LayoutObject::ClearNeedsLayout() {
  // Set flags for later stages/cycles.
  SetEverHadLayout();
  SetMayNeedPaintInvalidation();

  // Clear needsLayout flags.
  SetSelfNeedsLayout(false);
  SetPosChildNeedsLayout(false);
  SetNeedsSimplifiedNormalFlowLayout(false);
  SetNormalChildNeedsLayout(false);
  SetNeedsPositionedMovementLayout(false);
  SetAncestorLineBoxDirty(false);

#if DCHECK_IS_ON()
  CheckBlockPositionedObjectsNeedLayout();
#endif

  SetScrollAnchorDisablingStyleChanged(false);
}

inline void LayoutObject::SetChildNeedsLayout(MarkingBehavior mark_parents,
                                              SubtreeLayoutScope* layouter) {
#if DCHECK_IS_ON()
  DCHECK(!IsSetNeedsLayoutForbidden());
#endif
  bool already_needed_layout = NormalChildNeedsLayout();
  SetNormalChildNeedsLayout(true);
  MarkContainerNeedsCollectInlines();
  // FIXME: Replace MarkOnlyThis with the SubtreeLayoutScope code path and
  // remove the MarkingBehavior argument entirely.
  if (!already_needed_layout && mark_parents == kMarkContainerChain &&
      (!layouter || layouter->Root() != this))
    MarkContainerChainForLayout(!layouter, layouter);
}

inline void LayoutObject::SetNeedsPositionedMovementLayout() {
  bool already_needed_layout = NeedsPositionedMovementLayout();
  SetNeedsPositionedMovementLayout(true);
#if DCHECK_IS_ON()
  DCHECK(!IsSetNeedsLayoutForbidden());
#endif
  if (!already_needed_layout)
    MarkContainerChainForLayout();
}

inline void LayoutObject::SetHasBoxDecorationBackground(bool b) {
  if (b == bitfields_.HasBoxDecorationBackground())
    return;

  bitfields_.SetHasBoxDecorationBackground(b);
  InvalidateBackgroundObscurationStatus();
}

inline void LayoutObject::InvalidateBackgroundObscurationStatus() {
  bitfields_.SetBackgroundObscurationState(kBackgroundObscurationStatusInvalid);
}

DISABLE_CFI_PERF
inline bool LayoutObject::BackgroundIsKnownToBeObscured() const {
  if (bitfields_.GetBackgroundObscurationState() ==
      kBackgroundObscurationStatusInvalid) {
    BackgroundObscurationState state = ComputeBackgroundIsKnownToBeObscured()
                                           ? kBackgroundKnownToBeObscured
                                           : kBackgroundMayBeVisible;
    bitfields_.SetBackgroundObscurationState(state);
  }
  return bitfields_.GetBackgroundObscurationState() ==
         kBackgroundKnownToBeObscured;
}

inline void MakeMatrixRenderable(TransformationMatrix& matrix,
                                 bool has3d_rendering) {
  if (!has3d_rendering)
    matrix.MakeAffine();
}

enum class LayoutObjectSide {
  kRemainingTextIfOnBoundary,
  kFirstLetterIfOnBoundary
};
CORE_EXPORT const LayoutObject* AssociatedLayoutObjectOf(
    const Node&,
    int offset_in_node,
    LayoutObjectSide = LayoutObjectSide::kRemainingTextIfOnBoundary);

CORE_EXPORT std::ostream& operator<<(std::ostream&, const LayoutObject*);
CORE_EXPORT std::ostream& operator<<(std::ostream&, const LayoutObject&);

#define DEFINE_LAYOUT_OBJECT_TYPE_CASTS(thisType, predicate)           \
  DEFINE_TYPE_CASTS(thisType, LayoutObject, object, object->predicate, \
                    object.predicate)

}  // namespace blink

#ifndef NDEBUG
// Outside the blink namespace for ease of invocation from gdb.
CORE_EXPORT void showTree(const blink::LayoutObject*);
CORE_EXPORT void showLineTree(const blink::LayoutObject*);
CORE_EXPORT void showLayoutTree(const blink::LayoutObject* object1);
// We don't make object2 an optional parameter so that showLayoutTree
// can be called from gdb easily.
CORE_EXPORT void showLayoutTree(const blink::LayoutObject* object1,
                                const blink::LayoutObject* object2);

#endif

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_LAYOUT_OBJECT_H_
