void PaintPropertyTreeBuilder::updateOutOfFlowContext(
    const LayoutObject& object,
    PaintPropertyTreeBuilderContext& context) {
  if (object.canContainAbsolutePositionObjects()) {
    context.absolutePosition = context.current;
    context.containerForAbsolutePosition = &object;
  }

  if (object.isLayoutView()) {
    if (RuntimeEnabledFeatures::rootLayerScrollingEnabled()) {
      const auto* initialFixedTransform = context.fixedPosition.transform;
      auto* initialFixedScroll = context.fixedPosition.scroll;

      context.fixedPosition = context.current;

      // Fixed position transform and scroll nodes should not be affected.
      context.fixedPosition.transform = initialFixedTransform;
      context.fixedPosition.scroll = initialFixedScroll;
    }
  } else if (object.canContainFixedPositionObjects()) {
    context.fixedPosition = context.current;
  } else if (object.getMutableForPainting().paintProperties() &&
             object.paintProperties()->cssClip()) {
    // CSS clip applies to all descendants, even if this object is not a
    // containing block ancestor of the descendant. It is okay for
    // absolute-position descendants because having CSS clip implies being
    // absolute position container. However for fixed-position descendants we
    // need to insert the clip here if we are not a containing block ancestor of
    // them.
    auto* cssClip = object.getMutableForPainting().paintProperties()->cssClip();

    // Before we actually create anything, check whether in-flow context and
    // fixed-position context has exactly the same clip. Reuse if possible.
    if (context.fixedPosition.clip == cssClip->parent()) {
      context.fixedPosition.clip = cssClip;
    } else {
      object.getMutableForPainting()
          .ensurePaintProperties()
          .updateCssClipFixedPosition(context.fixedPosition.clip,
                                      const_cast<TransformPaintPropertyNode*>(
                                          cssClip->localTransformSpace()),
                                      cssClip->clipRect());
      const auto* properties = object.paintProperties();
      if (properties && properties->cssClipFixedPosition())
        context.fixedPosition.clip = properties->cssClipFixedPosition();
      return;
    }
  }

  if (auto* properties = object.getMutableForPainting().paintProperties())
    properties->clearCssClipFixedPosition();
}
void PaintPropertyTreeBuilder::updateCssClip(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
{
    if (!object.hasClip())
        return;
    ASSERT(object.canContainAbsolutePositionObjects());

    // Create clip node for descendants that are not fixed position.
    // We don't have to setup context.clipForAbsolutePosition here because this object must be
    // a container for absolute position descendants, and will copy from in-flow context later
    // at updateOutOfFlowContext() step.
    LayoutRect clipRect = toLayoutBox(object).clipRect(context.paintOffset);
    RefPtr<ClipPaintPropertyNode> clipNode = ClipPaintPropertyNode::create(
        context.currentTransform,
        FloatRoundedRect(FloatRect(clipRect)),
        context.currentClip);
    context.currentClip = clipNode.get();
    object.getMutableForPainting().ensureObjectPaintProperties().setCssClip(clipNode.release());
}
void PaintPropertyTreeBuilder::updateCssClip(
    const LayoutObject& object,
    PaintPropertyTreeBuilderContext& context) {
  if (object.hasClip()) {
    // Create clip node for descendants that are not fixed position.
    // We don't have to setup context.absolutePosition.clip here because this
    // object must be a container for absolute position descendants, and will
    // copy from in-flow context later at updateOutOfFlowContext() step.
    DCHECK(object.canContainAbsolutePositionObjects());
    LayoutRect clipRect =
        toLayoutBox(object).clipRect(context.current.paintOffset);
    context.current.clip =
        object.getMutableForPainting().ensurePaintProperties().updateCssClip(
            context.current.clip, context.current.transform,
            FloatRoundedRect(FloatRect(clipRect)));
    return;
  }

  if (auto* properties = object.getMutableForPainting().paintProperties())
    properties->clearCssClip();
}
void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTreeBuilderContext& context)
{
    if (object.canContainAbsolutePositionObjects()) {
        context.transformForAbsolutePosition = context.currentTransform;
        context.paintOffsetForAbsolutePosition = context.paintOffset;
        context.clipForAbsolutePosition = context.currentClip;
        context.containerForAbsolutePosition = &object;
    }

    // TODO(pdr): Remove the !object.isLayoutView() condition when removing FrameView
    // paint properties for rootLayerScrolls.
    if (!object.isLayoutView() && object.canContainFixedPositionObjects()) {
        context.transformForFixedPosition = context.currentTransform;
        context.paintOffsetForFixedPosition = context.paintOffset;
        context.clipForFixedPosition = context.currentClip;
    } else if (object.objectPaintProperties() && object.objectPaintProperties()->cssClip()) {
        // CSS clip applies to all descendants, even if this object is not a containing block
        // ancestor of the descendant. It is okay for absolute-position descendants because
        // having CSS clip implies being absolute position container. However for fixed-position
        // descendants we need to insert the clip here if we are not a containing block ancestor
        // of them.
        auto* cssClip = object.objectPaintProperties()->cssClip();

        // Before we actually create anything, check whether in-flow context and fixed-position
        // context has exactly the same clip. Reuse if possible.
        if (context.clipForFixedPosition == cssClip->parent()) {
            context.clipForFixedPosition = cssClip;
            return;
        }

        RefPtr<ClipPaintPropertyNode> clipFixedPosition = ClipPaintPropertyNode::create(
            const_cast<TransformPaintPropertyNode*>(cssClip->localTransformSpace()),
            cssClip->clipRect(),
            context.clipForFixedPosition);
        context.clipForFixedPosition = clipFixedPosition.get();
        object.getMutableForPainting().ensureObjectPaintProperties().setCssClipFixedPosition(clipFixedPosition.release());
    }
}