// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "core/paint/PaintPropertyTreeBuilderTest.h"

#include "core/html/HTMLIFrameElement.h"
#include "core/layout/LayoutTreeAsText.h"
#include "core/paint/ObjectPaintProperties.h"
#include "core/paint/PaintPropertyTreePrinter.h"
#include "platform/graphics/paint/GeometryMapper.h"

namespace blink {

void PaintPropertyTreeBuilderTest::LoadTestData(const char* file_name) {
  String full_path = testing::BlinkRootDir();
  full_path.append("/Source/core/paint/test_data/");
  full_path.append(file_name);
  const Vector<char> input_buffer = testing::ReadFromFile(full_path)->Copy();
  SetBodyInnerHTML(String(input_buffer.data(), input_buffer.size()));
}

const TransformPaintPropertyNode*
PaintPropertyTreeBuilderTest::FramePreTranslation() {
  LocalFrameView* frame_view = GetDocument().View();
  if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
    return frame_view->GetLayoutView()
        ->FirstFragment()
        .PaintProperties()
        ->PaintOffsetTranslation();
  }
  return frame_view->PreTranslation();
}

const TransformPaintPropertyNode*
PaintPropertyTreeBuilderTest::FrameScrollTranslation() {
  LocalFrameView* frame_view = GetDocument().View();
  if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
    return frame_view->GetLayoutView()
        ->FirstFragment()
        .PaintProperties()
        ->ScrollTranslation();
  }
  return frame_view->ScrollTranslation();
}

const ClipPaintPropertyNode* PaintPropertyTreeBuilderTest::FrameContentClip() {
  LocalFrameView* frame_view = GetDocument().View();
  if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
    return frame_view->GetLayoutView()
        ->FirstFragment()
        .PaintProperties()
        ->OverflowClip();
  }
  return frame_view->ContentClip();
}

const ScrollPaintPropertyNode* PaintPropertyTreeBuilderTest::FrameScroll(
    LocalFrameView* frame_view) {
  if (!frame_view)
    frame_view = GetDocument().View();
  if (RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
    return frame_view->GetLayoutView()
        ->FirstFragment()
        .PaintProperties()
        ->Scroll();
  }
  return frame_view->ScrollNode();
}

const ObjectPaintProperties*
PaintPropertyTreeBuilderTest::PaintPropertiesForElement(const char* name) {
  return GetDocument()
      .getElementById(name)
      ->GetLayoutObject()
      ->FirstFragment()
      .PaintProperties();
}

void PaintPropertyTreeBuilderTest::SetUp() {
  RenderingTest::SetUp();
  EnableCompositing();
}

#define CHECK_VISUAL_RECT(expected, source_object, ancestor, slop_factor)      \
  do {                                                                         \
    if ((source_object)->HasLayer() && (ancestor)->HasLayer()) {               \
      LayoutRect source((source_object)->LocalVisualRect());                   \
      source.MoveBy((source_object)->FirstFragment().PaintOffset());           \
      auto contents_properties =                                               \
          (ancestor)->FirstFragment().ContentsProperties();                    \
      FloatClipRect actual_float_rect((FloatRect(source)));                    \
      GeometryMapper::LocalToAncestorVisualRect(                               \
          *(source_object)->FirstFragment().LocalBorderBoxProperties(),        \
          contents_properties, actual_float_rect);                             \
      LayoutRect actual(actual_float_rect.Rect());                             \
      actual.MoveBy(-(ancestor)->FirstFragment().PaintOffset());               \
      SCOPED_TRACE("GeometryMapper: ");                                        \
      EXPECT_EQ(expected, actual);                                             \
    }                                                                          \
                                                                               \
    if (slop_factor == LayoutUnit::Max())                                      \
      break;                                                                   \
    LayoutRect slow_path_rect = (source_object)->LocalVisualRect();            \
    (source_object)->MapToVisualRectInAncestorSpace(ancestor, slow_path_rect); \
    if (slop_factor) {                                                         \
      LayoutRect inflated_expected = LayoutRect(expected);                     \
      inflated_expected.Inflate(slop_factor);                                  \
      SCOPED_TRACE(String::Format(                                             \
          "Slow path rect: %s, Expected: %s, Inflated expected: %s",           \
          slow_path_rect.ToString().Ascii().data(),                            \
          expected.ToString().Ascii().data(),                                  \
          inflated_expected.ToString().Ascii().data()));                       \
      EXPECT_TRUE(LayoutRect(EnclosingIntRect(slow_path_rect))                 \
                      .Contains(LayoutRect(expected)));                        \
      EXPECT_TRUE(inflated_expected.Contains(slow_path_rect));                 \
    } else {                                                                   \
      SCOPED_TRACE("Slow path: ");                                             \
      EXPECT_EQ(expected, slow_path_rect);                                     \
    }                                                                          \
  } while (0)

#define CHECK_EXACT_VISUAL_RECT(expected, source_object, ancestor) \
  CHECK_VISUAL_RECT(expected, source_object, ancestor, 0)

INSTANTIATE_TEST_CASE_P(
    All,
    PaintPropertyTreeBuilderTest,
    ::testing::ValuesIn(kSlimmingPaintNonV1TestConfigurations));

TEST_P(PaintPropertyTreeBuilderTest, FixedPosition) {
  LoadTestData("fixed-position.html");

  Element* positioned_scroll = GetDocument().getElementById("positionedScroll");
  positioned_scroll->setScrollTop(3);
  Element* transformed_scroll =
      GetDocument().getElementById("transformedScroll");
  transformed_scroll->setScrollTop(5);

  LocalFrameView* frame_view = GetDocument().View();
  frame_view->UpdateAllLifecyclePhases();

  // target1 is a fixed-position element inside an absolute-position scrolling
  // element.  It should be attached under the viewport to skip scrolling and
  // offset of the parent.
  Element* target1 = GetDocument().getElementById("target1");
  const ObjectPaintProperties* target1_properties =
      target1->GetLayoutObject()->FirstFragment().PaintProperties();
  EXPECT_EQ(FloatRoundedRect(200, 150, 100, 100),
            target1_properties->OverflowClip()->ClipRect());
  // Likewise, it inherits clip from the viewport, skipping overflow clip of the
  // scroller.
  EXPECT_EQ(FrameContentClip(), target1_properties->OverflowClip()->Parent());
  // target1 should not have its own scroll node and instead should inherit
  // positionedScroll's.
  const ObjectPaintProperties* positioned_scroll_properties =
      positioned_scroll->GetLayoutObject()->FirstFragment().PaintProperties();
  auto* positioned_scroll_translation =
      positioned_scroll_properties->ScrollTranslation();
  auto* positioned_scroll_node = positioned_scroll_translation->ScrollNode();
  EXPECT_TRUE(positioned_scroll_node->Parent()->IsRoot());
  EXPECT_EQ(TransformationMatrix().Translate(0, -3),
            positioned_scroll_translation->Matrix());
  EXPECT_EQ(nullptr, target1_properties->ScrollTranslation());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(200, 150, 100, 100),
                          target1->GetLayoutObject(),
                          frame_view->GetLayoutView());

  // target2 is a fixed-position element inside a transformed scrolling element.
  // It should be attached under the scrolled box of the transformed element.
  Element* target2 = GetDocument().getElementById("target2");
  const ObjectPaintProperties* target2_properties =
      target2->GetLayoutObject()->FirstFragment().PaintProperties();
  Element* scroller = GetDocument().getElementById("transformedScroll");
  const ObjectPaintProperties* scroller_properties =
      scroller->GetLayoutObject()->FirstFragment().PaintProperties();
  EXPECT_EQ(FloatRoundedRect(200, 150, 100, 100),
            target2_properties->OverflowClip()->ClipRect());
  EXPECT_EQ(scroller_properties->OverflowClip(),
            target2_properties->OverflowClip()->Parent());
  // target2 should not have it's own scroll node and instead should inherit
  // transformedScroll's.
  const ObjectPaintProperties* transformed_scroll_properties =
      transformed_scroll->GetLayoutObject()->FirstFragment().PaintProperties();
  auto* transformed_scroll_translation =
      transformed_scroll_properties->ScrollTranslation();
  auto* transformed_scroll_node = transformed_scroll_translation->ScrollNode();
  EXPECT_TRUE(transformed_scroll_node->Parent()->IsRoot());
  EXPECT_EQ(TransformationMatrix().Translate(0, -5),
            transformed_scroll_translation->Matrix());
  EXPECT_EQ(nullptr, target2_properties->ScrollTranslation());

  CHECK_EXACT_VISUAL_RECT(LayoutRect(208, 153, 200, 100),
                          target2->GetLayoutObject(),
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, PositionAndScroll) {
  LoadTestData("position-and-scroll.html");

  Element* scroller = GetDocument().getElementById("scroller");
  scroller->scrollTo(0, 100);
  LocalFrameView* frame_view = GetDocument().View();
  frame_view->UpdateAllLifecyclePhases();
  const ObjectPaintProperties* scroller_properties =
      scroller->GetLayoutObject()->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(0, -100),
            scroller_properties->ScrollTranslation()->Matrix());
  EXPECT_EQ(scroller_properties->PaintOffsetTranslation(),
            scroller_properties->ScrollTranslation()->Parent());
  EXPECT_EQ(FrameScrollTranslation(),
            scroller_properties->PaintOffsetTranslation()->Parent());
  EXPECT_EQ(scroller_properties->PaintOffsetTranslation(),
            scroller_properties->OverflowClip()->LocalTransformSpace());
  const auto* scroll = scroller_properties->ScrollTranslation()->ScrollNode();
  EXPECT_EQ(FrameScroll(), scroll->Parent());
  EXPECT_EQ(IntRect(0, 0, 413, 317), scroll->ContainerRect());
  EXPECT_EQ(IntRect(0, 0, 660, 10200), scroll->ContentsRect());
  EXPECT_FALSE(scroll->UserScrollableHorizontal());
  EXPECT_TRUE(scroll->UserScrollableVertical());
  EXPECT_EQ(FloatSize(120, 340), scroller_properties->PaintOffsetTranslation()
                                     ->Matrix()
                                     .To2DTranslation());
  EXPECT_EQ(FloatRoundedRect(0, 0, 413, 317),
            scroller_properties->OverflowClip()->ClipRect());
  EXPECT_EQ(FrameContentClip(), scroller_properties->OverflowClip()->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(120, 340, 413, 317),
                          scroller->GetLayoutObject(),
                          frame_view->GetLayoutView());

  // The relative-positioned element should have accumulated box offset (exclude
  // scrolling), and should be affected by ancestor scroll transforms.
  Element* rel_pos = GetDocument().getElementById("rel-pos");
  const ObjectPaintProperties* rel_pos_properties =
      rel_pos->GetLayoutObject()->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(560, 780),
            rel_pos_properties->PaintOffsetTranslation()->Matrix());
  EXPECT_EQ(scroller_properties->ScrollTranslation(),
            rel_pos_properties->PaintOffsetTranslation()->Parent());
  EXPECT_EQ(rel_pos_properties->Transform(),
            rel_pos_properties->OverflowClip()->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(0, 0, 100, 200),
            rel_pos_properties->OverflowClip()->ClipRect());
  EXPECT_EQ(scroller_properties->OverflowClip(),
            rel_pos_properties->OverflowClip()->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(), rel_pos->GetLayoutObject(),
                          frame_view->GetLayoutView());

  // The absolute-positioned element should not be affected by non-positioned
  // scroller at all.
  Element* abs_pos = GetDocument().getElementById("abs-pos");
  const ObjectPaintProperties* abs_pos_properties =
      abs_pos->GetLayoutObject()->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(123, 456),
            abs_pos_properties->PaintOffsetTranslation()->Matrix());
  EXPECT_EQ(FrameScrollTranslation(),
            abs_pos_properties->PaintOffsetTranslation()->Parent());
  EXPECT_EQ(abs_pos_properties->Transform(),
            abs_pos_properties->OverflowClip()->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(0, 0, 300, 400),
            abs_pos_properties->OverflowClip()->ClipRect());
  EXPECT_EQ(FrameContentClip(), abs_pos_properties->OverflowClip()->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(123, 456, 300, 400),
                          abs_pos->GetLayoutObject(),
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollVerticalRL) {
  SetBodyInnerHTML(R"HTML(
    <style>::-webkit-scrollbar {width: 15px; height: 15px}</style>
    <div id='scroller'
         style='width: 100px; height: 100px; overflow: scroll;
                writing-mode: vertical-rl; border: 10px solid blue'>
      <div style='width: 400px; height: 400px'></div>
    </div>
  )HTML");

  const auto* properties = PaintPropertiesForElement("scroller");
  const auto* overflow_clip = properties->OverflowClip();
  const auto* scroll_translation = properties->ScrollTranslation();
  const auto* scroll = properties->Scroll();

  EXPECT_EQ(TransformationMatrix().Translate(-15, 0),
            scroll_translation->Matrix());
  EXPECT_EQ(scroll, scroll_translation->ScrollNode());
  // 10: border width. 85: container client size (== 100 - scrollbar width).
  EXPECT_EQ(IntRect(10, 10, 85, 85), scroll->ContainerRect());
  // The content is placed at (-290, 10) so that its right edge aligns with the
  // right edge of the container's client box, with the initial
  // ScrollTranslation applied.
  EXPECT_EQ(IntRect(-290, 10, 400, 400), scroll->ContentsRect());

  EXPECT_EQ(FrameContentClip(), overflow_clip->Parent());
  EXPECT_EQ(properties->PaintOffsetTranslation(),
            overflow_clip->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(10, 10, 85, 85), overflow_clip->ClipRect());
}

TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollRTL) {
  SetBodyInnerHTML(R"HTML(
    <style>::-webkit-scrollbar {width: 15px; height: 15px}</style>
    <div id='scroller'
         style='width: 100px; height: 100px; overflow: scroll;
                direction: rtl; border: 10px solid blue'>
      <div style='width: 400px; height: 400px'></div>
    </div>
  )HTML");

  const auto* properties = PaintPropertiesForElement("scroller");
  const auto* overflow_clip = properties->OverflowClip();
  const auto* scroll_translation = properties->ScrollTranslation();
  const auto* scroll = properties->Scroll();

  EXPECT_EQ(TransformationMatrix(), scroll_translation->Matrix());
  EXPECT_EQ(scroll, scroll_translation->ScrollNode());
  // 25: border width (10) + scrollbar (on the left) width (15).
  // 85: container client size (== 100 - scrollbar width).
  EXPECT_EQ(IntRect(25, 10, 85, 85), scroll->ContainerRect());
  EXPECT_EQ(IntRect(-290, 10, 400, 400), scroll->ContentsRect());

  EXPECT_EQ(FrameContentClip(), overflow_clip->Parent());
  EXPECT_EQ(properties->PaintOffsetTranslation(),
            overflow_clip->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(25, 10, 85, 85), overflow_clip->ClipRect());
}

TEST_P(PaintPropertyTreeBuilderTest, FrameScrollingTraditional) {
  SetBodyInnerHTML("<style> body { height: 10000px; } </style>");

  GetDocument().domWindow()->scrollTo(0, 100);

  LocalFrameView* frame_view = GetDocument().View();
  frame_view->UpdateAllLifecyclePhases();
  EXPECT_EQ(TransformationMatrix(), FramePreTranslation()->Matrix());
  EXPECT_TRUE(FramePreTranslation()->Parent()->IsRoot());
  EXPECT_EQ(TransformationMatrix().Translate(0, -100),
            FrameScrollTranslation()->Matrix());
  EXPECT_EQ(FramePreTranslation(), FrameScrollTranslation()->Parent());
  EXPECT_EQ(FramePreTranslation(), FrameContentClip()->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600), FrameContentClip()->ClipRect());
  EXPECT_TRUE(FrameContentClip()->Parent()->IsRoot());

  if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
    // No scroll properties should be present.
    EXPECT_EQ(nullptr,
              frame_view->GetLayoutView()->FirstFragment().PaintProperties());
  }

  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 784, 10000),
                          GetDocument().body()->GetLayoutObject(),
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, Perspective) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #perspective {
        position: absolute;
        left: 50px;
        top: 100px;
        width: 400px;
        height: 300px;
        perspective: 100px;
      }
      #inner {
        transform: translateZ(0);
        width: 100px;
        height: 200px;
      }
    </style>
    <div id='perspective'>
      <div id='inner'></div>
    </div>
  )HTML");
  Element* perspective = GetDocument().getElementById("perspective");
  const ObjectPaintProperties* perspective_properties =
      perspective->GetLayoutObject()->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().ApplyPerspective(100),
            perspective_properties->Perspective()->Matrix());
  // The perspective origin is the center of the border box plus accumulated
  // paint offset.
  EXPECT_EQ(FloatPoint3D(250, 250, 0),
            perspective_properties->Perspective()->Origin());
  EXPECT_EQ(FramePreTranslation(),
            perspective_properties->Perspective()->Parent());

  // Adding perspective doesn't clear paint offset. The paint offset will be
  // passed down to children.
  Element* inner = GetDocument().getElementById("inner");
  const ObjectPaintProperties* inner_properties =
      inner->GetLayoutObject()->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(50, 100),
            inner_properties->PaintOffsetTranslation()->Matrix());
  EXPECT_EQ(perspective_properties->Perspective(),
            inner_properties->PaintOffsetTranslation()->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(50, 100, 100, 200),
                          inner->GetLayoutObject(),
                          GetDocument().View()->GetLayoutView());

  perspective->setAttribute(HTMLNames::styleAttr, "perspective: 200px");
  GetDocument().View()->UpdateAllLifecyclePhases();
  EXPECT_EQ(TransformationMatrix().ApplyPerspective(200),
            perspective_properties->Perspective()->Matrix());
  EXPECT_EQ(FloatPoint3D(250, 250, 0),
            perspective_properties->Perspective()->Origin());
  EXPECT_EQ(FramePreTranslation(),
            perspective_properties->Perspective()->Parent());

  perspective->setAttribute(HTMLNames::styleAttr, "perspective-origin: 5% 20%");
  GetDocument().View()->UpdateAllLifecyclePhases();
  EXPECT_EQ(TransformationMatrix().ApplyPerspective(100),
            perspective_properties->Perspective()->Matrix());
  EXPECT_EQ(FloatPoint3D(70, 160, 0),
            perspective_properties->Perspective()->Origin());
  EXPECT_EQ(FramePreTranslation(),
            perspective_properties->Perspective()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, Transform) {
  SetBodyInnerHTML(R"HTML(
    <style> body { margin: 0 } </style>
    <div id='transform' style='margin-left: 50px; margin-top: 100px;
        width: 400px; height: 300px;
        transform: translate3d(123px, 456px, 789px)'>
    </div>
  )HTML");

  Element* transform = GetDocument().getElementById("transform");
  const ObjectPaintProperties* transform_properties =
      transform->GetLayoutObject()->FirstFragment().PaintProperties();

  EXPECT_EQ(TransformationMatrix().Translate3d(123, 456, 789),
            transform_properties->Transform()->Matrix());
  EXPECT_EQ(FloatPoint3D(200, 150, 0),
            transform_properties->Transform()->Origin());
  EXPECT_EQ(transform_properties->PaintOffsetTranslation(),
            transform_properties->Transform()->Parent());
  EXPECT_EQ(TransformationMatrix().Translate(50, 100),
            transform_properties->PaintOffsetTranslation()->Matrix());
  EXPECT_EQ(FrameScrollTranslation(),
            transform_properties->PaintOffsetTranslation()->Parent());

  EXPECT_TRUE(transform_properties->Transform()->HasDirectCompositingReasons());
  EXPECT_FALSE(FrameScrollTranslation()->HasDirectCompositingReasons());

  CHECK_EXACT_VISUAL_RECT(LayoutRect(173, 556, 400, 300),
                          transform->GetLayoutObject(),
                          GetDocument().View()->GetLayoutView());

  transform->setAttribute(
      HTMLNames::styleAttr,
      "margin-left: 50px; margin-top: 100px; width: 400px; height: 300px;");
  GetDocument().View()->UpdateAllLifecyclePhases();
  EXPECT_EQ(nullptr,
            transform->GetLayoutObject()->FirstFragment().PaintProperties());

  transform->setAttribute(
      HTMLNames::styleAttr,
      "margin-left: 50px; margin-top: 100px; width: 400px; height: 300px; "
      "transform: translate3d(123px, 456px, 789px)");
  GetDocument().View()->UpdateAllLifecyclePhases();
  EXPECT_EQ(TransformationMatrix().Translate3d(123, 456, 789),
            transform->GetLayoutObject()
                ->FirstFragment()
                .PaintProperties()
                ->Transform()
                ->Matrix());
}

TEST_P(PaintPropertyTreeBuilderTest, Preserve3D3DTransformedDescendant) {
  SetBodyInnerHTML(R"HTML(
    <style> body { margin: 0 } </style>
    <div id='preserve' style='transform-style: preserve-3d'>
    <div id='transform' style='margin-left: 50px; margin-top: 100px;
        width: 400px; height: 300px;
        transform: translate3d(123px, 456px, 789px)'>
    </div>
    </div>
  )HTML");

  Element* preserve = GetDocument().getElementById("preserve");
  const ObjectPaintProperties* preserve_properties =
      preserve->GetLayoutObject()->FirstFragment().PaintProperties();

  EXPECT_TRUE(preserve_properties->Transform());
  EXPECT_TRUE(preserve_properties->Transform()->HasDirectCompositingReasons());
}

TEST_P(PaintPropertyTreeBuilderTest, Perspective3DTransformedDescendant) {
  SetBodyInnerHTML(R"HTML(
    <style> body { margin: 0 } </style>
    <div id='perspective' style='perspective: 800px;'>
    <div id='transform' style='margin-left: 50px; margin-top: 100px;
        width: 400px; height: 300px;
        transform: translate3d(123px, 456px, 789px)'>
    </div>
    </div>
  )HTML");

  Element* perspective = GetDocument().getElementById("perspective");
  const ObjectPaintProperties* perspective_properties =
      perspective->GetLayoutObject()->FirstFragment().PaintProperties();

  EXPECT_TRUE(perspective_properties->Transform());
  EXPECT_TRUE(
      perspective_properties->Transform()->HasDirectCompositingReasons());
}

TEST_P(PaintPropertyTreeBuilderTest,
       TransformNodeWithActiveAnimationHasDirectCompositingReason) {
  LoadTestData("transform-animation.html");
  EXPECT_TRUE(PaintPropertiesForElement("target")
                  ->Transform()
                  ->HasDirectCompositingReasons());
}

TEST_P(PaintPropertyTreeBuilderTest,
       OpacityAnimationDoesNotCreateTransformNode) {
  LoadTestData("opacity-animation.html");
  EXPECT_EQ(nullptr, PaintPropertiesForElement("target")->Transform());
}

TEST_P(PaintPropertyTreeBuilderTest,
       EffectNodeWithActiveAnimationHasDirectCompositingReason) {
  LoadTestData("opacity-animation.html");
  EXPECT_TRUE(PaintPropertiesForElement("target")
                  ->Effect()
                  ->HasDirectCompositingReasons());
}

TEST_P(PaintPropertyTreeBuilderTest, WillChangeTransform) {
  SetBodyInnerHTML(R"HTML(
    <style> body { margin: 0 } </style>
    <div id='transform' style='margin-left: 50px; margin-top: 100px;
        width: 400px; height: 300px;
        will-change: transform'>
    </div>
  )HTML");

  Element* transform = GetDocument().getElementById("transform");
  const ObjectPaintProperties* transform_properties =
      transform->GetLayoutObject()->FirstFragment().PaintProperties();

  EXPECT_EQ(TransformationMatrix(),
            transform_properties->Transform()->Matrix());
  EXPECT_EQ(TransformationMatrix().Translate(0, 0),
            transform_properties->Transform()->Matrix());
  // The value is zero without a transform property that needs transform-offset.
  EXPECT_EQ(FloatPoint3D(0, 0, 0), transform_properties->Transform()->Origin());
  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
    EXPECT_EQ(nullptr, transform_properties->PaintOffsetTranslation());
  } else {
    // SPv175 creates PaintOffsetTranslation for composited layers.
    EXPECT_EQ(TransformationMatrix().Translate(50, 100),
              transform_properties->PaintOffsetTranslation()->Matrix());
  }
  EXPECT_TRUE(transform_properties->Transform()->HasDirectCompositingReasons());

  CHECK_EXACT_VISUAL_RECT(LayoutRect(50, 100, 400, 300),
                          transform->GetLayoutObject(),
                          GetDocument().View()->GetLayoutView());

  transform->setAttribute(
      HTMLNames::styleAttr,
      "margin-left: 50px; margin-top: 100px; width: 400px; height: 300px;");
  GetDocument().View()->UpdateAllLifecyclePhases();
  EXPECT_EQ(nullptr,
            transform->GetLayoutObject()->FirstFragment().PaintProperties());

  transform->setAttribute(
      HTMLNames::styleAttr,
      "margin-left: 50px; margin-top: 100px; width: 400px; height: 300px; "
      "will-change: transform");
  GetDocument().View()->UpdateAllLifecyclePhases();
  EXPECT_EQ(TransformationMatrix(), transform->GetLayoutObject()
                                        ->FirstFragment()
                                        .PaintProperties()
                                        ->Transform()
                                        ->Matrix());
}

TEST_P(PaintPropertyTreeBuilderTest, WillChangeContents) {
  SetBodyInnerHTML(R"HTML(
    <style> body { margin: 0 } </style>
    <div id='transform' style='margin-left: 50px; margin-top: 100px;
        width: 400px; height: 300px;
        will-change: transform, contents'>
    </div>
  )HTML");

  Element* transform = GetDocument().getElementById("transform");
  EXPECT_EQ(nullptr,
            transform->GetLayoutObject()->FirstFragment().PaintProperties());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(50, 100, 400, 300),
                          transform->GetLayoutObject(),
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, RelativePositionInline) {
  LoadTestData("relative-position-inline.html");

  Element* inline_block = GetDocument().getElementById("inline-block");
  const ObjectPaintProperties* inline_block_properties =
      inline_block->GetLayoutObject()->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(135, 490),
            inline_block_properties->PaintOffsetTranslation()->Matrix());
  EXPECT_EQ(FramePreTranslation(),
            inline_block_properties->PaintOffsetTranslation()->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(135, 490, 10, 20),
                          inline_block->GetLayoutObject(),
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, NestedOpacityEffect) {
  SetBodyInnerHTML(R"HTML(
    <div id='nodeWithoutOpacity' style='width: 100px; height: 200px'>
      <div id='childWithOpacity'
          style='opacity: 0.5; width: 50px; height: 60px;'>
        <div id='grandChildWithoutOpacity'
            style='width: 20px; height: 30px'>
          <div id='greatGrandChildWithOpacity'
              style='opacity: 0.2; width: 10px; height: 15px'></div>
        </div>
      </div>
    </div>
  )HTML");

  LayoutObject* node_without_opacity =
      GetLayoutObjectByElementId("nodeWithoutOpacity");
  const auto* data_without_opacity_properties =
      node_without_opacity->FirstFragment().PaintProperties();
  EXPECT_EQ(nullptr, data_without_opacity_properties);
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 100, 200), node_without_opacity,
                          GetDocument().View()->GetLayoutView());

  LayoutObject* child_with_opacity =
      GetLayoutObjectByElementId("childWithOpacity");
  const ObjectPaintProperties* child_with_opacity_properties =
      child_with_opacity->FirstFragment().PaintProperties();
  EXPECT_EQ(0.5f, child_with_opacity_properties->Effect()->Opacity());
  // childWithOpacity is the root effect node.
  EXPECT_NE(nullptr, child_with_opacity_properties->Effect()->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 50, 60), child_with_opacity,
                          GetDocument().View()->GetLayoutView());

  LayoutObject* grand_child_without_opacity =
      GetDocument()
          .getElementById("grandChildWithoutOpacity")
          ->GetLayoutObject();
  EXPECT_EQ(nullptr,
            grand_child_without_opacity->FirstFragment().PaintProperties());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 20, 30), grand_child_without_opacity,
                          GetDocument().View()->GetLayoutView());

  LayoutObject* great_grand_child_with_opacity =
      GetDocument()
          .getElementById("greatGrandChildWithOpacity")
          ->GetLayoutObject();
  const ObjectPaintProperties* great_grand_child_with_opacity_properties =
      great_grand_child_with_opacity->FirstFragment().PaintProperties();
  EXPECT_EQ(0.2f,
            great_grand_child_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(child_with_opacity_properties->Effect(),
            great_grand_child_with_opacity_properties->Effect()->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 10, 15),
                          great_grand_child_with_opacity,
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, TransformNodeDoesNotAffectEffectNodes) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #nodeWithOpacity {
        opacity: 0.6;
        width: 100px;
        height: 200px;
      }
      #childWithTransform {
        transform: translate3d(10px, 10px, 0px);
        width: 50px;
        height: 60px;
      }
      #grandChildWithOpacity {
        opacity: 0.4;
        width: 20px;
        height: 30px;
      }
    </style>
    <div id='nodeWithOpacity'>
      <div id='childWithTransform'>
        <div id='grandChildWithOpacity'></div>
      </div>
    </div>
  )HTML");

  LayoutObject* node_with_opacity =
      GetLayoutObjectByElementId("nodeWithOpacity");
  const ObjectPaintProperties* node_with_opacity_properties =
      node_with_opacity->FirstFragment().PaintProperties();
  EXPECT_EQ(0.6f, node_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, node_with_opacity_properties->Effect()->OutputClip());
  EXPECT_NE(nullptr, node_with_opacity_properties->Effect()->Parent());
  EXPECT_EQ(nullptr, node_with_opacity_properties->Transform());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 100, 200), node_with_opacity,
                          GetDocument().View()->GetLayoutView());

  LayoutObject* child_with_transform =
      GetLayoutObjectByElementId("childWithTransform");
  const ObjectPaintProperties* child_with_transform_properties =
      child_with_transform->FirstFragment().PaintProperties();
  EXPECT_EQ(nullptr, child_with_transform_properties->Effect());
  EXPECT_EQ(TransformationMatrix().Translate(10, 10),
            child_with_transform_properties->Transform()->Matrix());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(18, 18, 50, 60), child_with_transform,
                          GetDocument().View()->GetLayoutView());

  LayoutObject* grand_child_with_opacity =
      GetLayoutObjectByElementId("grandChildWithOpacity");
  const ObjectPaintProperties* grand_child_with_opacity_properties =
      grand_child_with_opacity->FirstFragment().PaintProperties();
  EXPECT_EQ(0.4f, grand_child_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr,
            grand_child_with_opacity_properties->Effect()->OutputClip());
  EXPECT_EQ(node_with_opacity_properties->Effect(),
            grand_child_with_opacity_properties->Effect()->Parent());
  EXPECT_EQ(nullptr, grand_child_with_opacity_properties->Transform());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(18, 18, 20, 30), grand_child_with_opacity,
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossStackingContext) {
  SetBodyInnerHTML(R"HTML(
    <div id='nodeWithOpacity'
        style='opacity: 0.6; width: 100px; height: 200px'>
      <div id='childWithStackingContext'
          style='position:absolute; width: 50px; height: 60px;'>
        <div id='grandChildWithOpacity'
            style='opacity: 0.4; width: 20px; height: 30px'></div>
      </div>
    </div>
  )HTML");

  LayoutObject* node_with_opacity =
      GetLayoutObjectByElementId("nodeWithOpacity");
  const ObjectPaintProperties* node_with_opacity_properties =
      node_with_opacity->FirstFragment().PaintProperties();
  EXPECT_EQ(0.6f, node_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, node_with_opacity_properties->Effect()->OutputClip());
  EXPECT_NE(nullptr, node_with_opacity_properties->Effect()->Parent());
  EXPECT_EQ(nullptr, node_with_opacity_properties->Transform());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 100, 200), node_with_opacity,
                          GetDocument().View()->GetLayoutView());

  LayoutObject* child_with_stacking_context =
      GetDocument()
          .getElementById("childWithStackingContext")
          ->GetLayoutObject();
  const ObjectPaintProperties* child_with_stacking_context_properties =
      child_with_stacking_context->FirstFragment().PaintProperties();
  EXPECT_EQ(nullptr, child_with_stacking_context_properties);
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 50, 60), child_with_stacking_context,
                          GetDocument().View()->GetLayoutView());

  LayoutObject* grand_child_with_opacity =
      GetLayoutObjectByElementId("grandChildWithOpacity");
  const ObjectPaintProperties* grand_child_with_opacity_properties =
      grand_child_with_opacity->FirstFragment().PaintProperties();
  EXPECT_EQ(0.4f, grand_child_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr,
            grand_child_with_opacity_properties->Effect()->OutputClip());
  EXPECT_EQ(node_with_opacity_properties->Effect(),
            grand_child_with_opacity_properties->Effect()->Parent());
  EXPECT_EQ(nullptr, grand_child_with_opacity_properties->Transform());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 20, 30), grand_child_with_opacity,
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, EffectNodesInSVG) {
  SetBodyInnerHTML(R"HTML(
    <svg id='svgRoot'>
      <g id='groupWithOpacity' opacity='0.6'>
        <rect id='rectWithoutOpacity' />
        <rect id='rectWithOpacity' opacity='0.4' />
        <text id='textWithOpacity' opacity='0.2'>
          <tspan id='tspanWithOpacity' opacity='0.1' />
        </text>
      </g>
    </svg>
  )HTML");
  LayoutObject* group_with_opacity =
      GetLayoutObjectByElementId("groupWithOpacity");
  const ObjectPaintProperties* group_with_opacity_properties =
      group_with_opacity->FirstFragment().PaintProperties();
  EXPECT_EQ(0.6f, group_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, group_with_opacity_properties->Effect()->OutputClip());
  EXPECT_NE(nullptr, group_with_opacity_properties->Effect()->Parent());

  LayoutObject& rect_without_opacity =
      *GetLayoutObjectByElementId("rectWithoutOpacity");
  const auto* rect_without_opacity_properties =
      rect_without_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(nullptr, rect_without_opacity_properties);

  LayoutObject& rect_with_opacity =
      *GetLayoutObjectByElementId("rectWithOpacity");
  const ObjectPaintProperties* rect_with_opacity_properties =
      rect_with_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(0.4f, rect_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, rect_with_opacity_properties->Effect()->OutputClip());
  EXPECT_EQ(group_with_opacity_properties->Effect(),
            rect_with_opacity_properties->Effect()->Parent());

  // Ensure that opacity nodes are created for LayoutSVGText which inherits from
  // LayoutSVGBlock instead of LayoutSVGModelObject.
  LayoutObject& text_with_opacity =
      *GetLayoutObjectByElementId("textWithOpacity");
  const ObjectPaintProperties* text_with_opacity_properties =
      text_with_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(0.2f, text_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, text_with_opacity_properties->Effect()->OutputClip());
  EXPECT_EQ(group_with_opacity_properties->Effect(),
            text_with_opacity_properties->Effect()->Parent());

  // Ensure that opacity nodes are created for LayoutSVGTSpan which inherits
  // from LayoutSVGInline instead of LayoutSVGModelObject.
  LayoutObject& tspan_with_opacity =
      *GetLayoutObjectByElementId("tspanWithOpacity");
  const ObjectPaintProperties* tspan_with_opacity_properties =
      tspan_with_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(0.1f, tspan_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, tspan_with_opacity_properties->Effect()->OutputClip());
  EXPECT_EQ(text_with_opacity_properties->Effect(),
            tspan_with_opacity_properties->Effect()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossHTMLSVGBoundary) {
  SetBodyInnerHTML(R"HTML(
    <div id='divWithOpacity' style='opacity: 0.2;'>
      <svg id='svgRootWithOpacity' style='opacity: 0.3;'>
        <rect id='rectWithOpacity' opacity='0.4' />
      </svg>
    </div>
  )HTML");

  LayoutObject& div_with_opacity =
      *GetLayoutObjectByElementId("divWithOpacity");
  const ObjectPaintProperties* div_with_opacity_properties =
      div_with_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(0.2f, div_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, div_with_opacity_properties->Effect()->OutputClip());
  EXPECT_NE(nullptr, div_with_opacity_properties->Effect()->Parent());

  LayoutObject& svg_root_with_opacity =
      *GetLayoutObjectByElementId("svgRootWithOpacity");
  const ObjectPaintProperties* svg_root_with_opacity_properties =
      svg_root_with_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(0.3f, svg_root_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, svg_root_with_opacity_properties->Effect()->OutputClip());
  EXPECT_EQ(div_with_opacity_properties->Effect(),
            svg_root_with_opacity_properties->Effect()->Parent());

  LayoutObject& rect_with_opacity =
      *GetLayoutObjectByElementId("rectWithOpacity");
  const ObjectPaintProperties* rect_with_opacity_properties =
      rect_with_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(0.4f, rect_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, rect_with_opacity_properties->Effect()->OutputClip());
  EXPECT_EQ(svg_root_with_opacity_properties->Effect(),
            rect_with_opacity_properties->Effect()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, EffectNodesAcrossSVGHTMLBoundary) {
  SetBodyInnerHTML(R"HTML(
    <svg id='svgRootWithOpacity' style='opacity: 0.3;'>
      <foreignObject id='foreignObjectWithOpacity' opacity='0.4'>
        <body>
          <span id='spanWithOpacity' style='opacity: 0.5'/>
        </body>
      </foreignObject>
    </svg>
  )HTML");

  LayoutObject& svg_root_with_opacity =
      *GetLayoutObjectByElementId("svgRootWithOpacity");
  const ObjectPaintProperties* svg_root_with_opacity_properties =
      svg_root_with_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(0.3f, svg_root_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, svg_root_with_opacity_properties->Effect()->OutputClip());
  EXPECT_NE(nullptr, svg_root_with_opacity_properties->Effect()->Parent());

  LayoutObject& foreign_object_with_opacity =
      *GetDocument()
           .getElementById("foreignObjectWithOpacity")
           ->GetLayoutObject();
  const ObjectPaintProperties* foreign_object_with_opacity_properties =
      foreign_object_with_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(0.4f, foreign_object_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr,
            foreign_object_with_opacity_properties->Effect()->OutputClip());
  EXPECT_EQ(svg_root_with_opacity_properties->Effect(),
            foreign_object_with_opacity_properties->Effect()->Parent());

  LayoutObject& span_with_opacity =
      *GetLayoutObjectByElementId("spanWithOpacity");
  const ObjectPaintProperties* span_with_opacity_properties =
      span_with_opacity.FirstFragment().PaintProperties();
  EXPECT_EQ(0.5f, span_with_opacity_properties->Effect()->Opacity());
  EXPECT_EQ(nullptr, span_with_opacity_properties->Effect()->OutputClip());
  EXPECT_EQ(foreign_object_with_opacity_properties->Effect(),
            span_with_opacity_properties->Effect()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, TransformNodesInSVG) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 0px;
      }
      svg {
        margin-left: 50px;
        transform: translate3d(1px, 2px, 3px);
        position: absolute;
        left: 20px;
        top: 25px;
      }
      rect {
        transform: translate(100px, 100px) rotate(45deg);
        transform-origin: 50px 25px;
      }
    </style>
    <svg id='svgRootWith3dTransform' width='100px' height='100px'>
      <rect id='rectWith2dTransform' width='100px' height='100px' />
    </svg>
  )HTML");

  LayoutObject& svg_root_with3d_transform =
      *GetDocument()
           .getElementById("svgRootWith3dTransform")
           ->GetLayoutObject();
  const ObjectPaintProperties* svg_root_with3d_transform_properties =
      svg_root_with3d_transform.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3),
            svg_root_with3d_transform_properties->Transform()->Matrix());
  EXPECT_EQ(FloatPoint3D(50, 50, 0),
            svg_root_with3d_transform_properties->Transform()->Origin());
  EXPECT_EQ(svg_root_with3d_transform_properties->PaintOffsetTranslation(),
            svg_root_with3d_transform_properties->Transform()->Parent());
  EXPECT_EQ(
      TransformationMatrix().Translate(70, 25),
      svg_root_with3d_transform_properties->PaintOffsetTranslation()->Matrix());
  EXPECT_EQ(
      FramePreTranslation(),
      svg_root_with3d_transform_properties->PaintOffsetTranslation()->Parent());

  LayoutObject& rect_with2d_transform =
      *GetLayoutObjectByElementId("rectWith2dTransform");
  const ObjectPaintProperties* rect_with2d_transform_properties =
      rect_with2d_transform.FirstFragment().PaintProperties();
  TransformationMatrix matrix;
  matrix.Translate(100, 100);
  matrix.Rotate(45);
  // SVG's transform origin is baked into the transform.
  matrix.ApplyTransformOrigin(50, 25, 0);
  EXPECT_EQ(matrix, rect_with2d_transform_properties->Transform()->Matrix());
  EXPECT_EQ(FloatPoint3D(0, 0, 0),
            rect_with2d_transform_properties->Transform()->Origin());
  // SVG does not use paint offset.
  EXPECT_EQ(nullptr,
            rect_with2d_transform_properties->PaintOffsetTranslation());
}

TEST_P(PaintPropertyTreeBuilderTest, SVGViewBoxTransform) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 0px;
      }
      #svgWithViewBox {
        transform: translate3d(1px, 2px, 3px);
        position: absolute;
        width: 100px;
        height: 100px;
      }
      #rect {
        transform: translate(100px, 100px);
        width: 100px;
        height: 100px;
      }
    </style>
    <svg id='svgWithViewBox' viewBox='50 50 100 100'>
      <rect id='rect' />
    </svg>
  )HTML");

  LayoutObject& svg_with_view_box =
      *GetLayoutObjectByElementId("svgWithViewBox");
  const ObjectPaintProperties* svg_with_view_box_properties =
      svg_with_view_box.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3),
            svg_with_view_box_properties->Transform()->Matrix());
  EXPECT_EQ(
      TransformationMatrix().Translate(-50, -50),
      svg_with_view_box_properties->SvgLocalToBorderBoxTransform()->Matrix());
  EXPECT_EQ(
      svg_with_view_box_properties->SvgLocalToBorderBoxTransform()->Parent(),
      svg_with_view_box_properties->Transform());

  LayoutObject& rect = *GetLayoutObjectByElementId("rect");
  const ObjectPaintProperties* rect_properties =
      rect.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(100, 100),
            rect_properties->Transform()->Matrix());
  EXPECT_EQ(svg_with_view_box_properties->SvgLocalToBorderBoxTransform(),
            rect_properties->Transform()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, SVGRootPaintOffsetTransformNode) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body { margin: 0px; }
      #svg {
        margin-left: 50px;
        margin-top: 25px;
        width: 100px;
        height: 100px;
      }
    </style>
    <svg id='svg' />
  )HTML");

  LayoutObject& svg = *GetLayoutObjectByElementId("svg");
  const ObjectPaintProperties* svg_properties =
      svg.FirstFragment().PaintProperties();
  EXPECT_TRUE(svg_properties->PaintOffsetTranslation());
  EXPECT_EQ(
      FloatSize(50, 25),
      svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
  EXPECT_EQ(nullptr, svg_properties->SvgLocalToBorderBoxTransform());
  EXPECT_EQ(FramePreTranslation(),
            svg_properties->PaintOffsetTranslation()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, SVGRootLocalToBorderBoxTransformNode) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body { margin: 0px; }
      svg {
        margin-left: 2px;
        margin-top: 3px;
        transform: translate(5px, 7px);
        border: 11px solid green;
      }
    </style>
    <svg id='svg' width='100px' height='100px' viewBox='0 0 13 13'>
      <rect id='rect' transform='translate(17 19)' />
    </svg>
  )HTML");

  LayoutObject& svg = *GetLayoutObjectByElementId("svg");
  const ObjectPaintProperties* svg_properties =
      svg.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(2, 3),
            svg_properties->PaintOffsetTranslation()->Matrix());
  EXPECT_EQ(TransformationMatrix().Translate(5, 7),
            svg_properties->Transform()->Matrix());
  EXPECT_EQ(TransformationMatrix().Translate(11, 11).Scale(100.0 / 13.0),
            svg_properties->SvgLocalToBorderBoxTransform()->Matrix());
  EXPECT_EQ(svg_properties->PaintOffsetTranslation(),
            svg_properties->Transform()->Parent());
  EXPECT_EQ(svg_properties->Transform(),
            svg_properties->SvgLocalToBorderBoxTransform()->Parent());

  // Ensure the rect's transform is a child of the local to border box
  // transform.
  LayoutObject& rect = *GetLayoutObjectByElementId("rect");
  const ObjectPaintProperties* rect_properties =
      rect.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(17, 19),
            rect_properties->Transform()->Matrix());
  EXPECT_EQ(svg_properties->SvgLocalToBorderBoxTransform(),
            rect_properties->Transform()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, SVGNestedViewboxTransforms) {
  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 0px; } </style>
    <svg id='svg' width='100px' height='100px' viewBox='0 0 50 50'
        style='transform: translate(11px, 11px);'>
      <svg id='nestedSvg' width='50px' height='50px' viewBox='0 0 5 5'>
        <rect id='rect' transform='translate(13 13)' />
      </svg>
    </svg>
  )HTML");

  LayoutObject& svg = *GetLayoutObjectByElementId("svg");
  const ObjectPaintProperties* svg_properties =
      svg.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(11, 11),
            svg_properties->Transform()->Matrix());
  EXPECT_EQ(TransformationMatrix().Scale(2),
            svg_properties->SvgLocalToBorderBoxTransform()->Matrix());

  LayoutObject& nested_svg = *GetLayoutObjectByElementId("nestedSvg");
  const ObjectPaintProperties* nested_svg_properties =
      nested_svg.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Scale(10),
            nested_svg_properties->Transform()->Matrix());
  EXPECT_EQ(nullptr, nested_svg_properties->SvgLocalToBorderBoxTransform());
  EXPECT_EQ(svg_properties->SvgLocalToBorderBoxTransform(),
            nested_svg_properties->Transform()->Parent());

  LayoutObject& rect = *GetLayoutObjectByElementId("rect");
  const ObjectPaintProperties* rect_properties =
      rect.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(13, 13),
            rect_properties->Transform()->Matrix());
  EXPECT_EQ(nested_svg_properties->Transform(),
            rect_properties->Transform()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSVGHTMLBoundary) {
  SetBodyInnerHTML(R"HTML(
    <style> body { margin: 0px; } </style>
    <svg id='svgWithTransform'
        style='transform: translate3d(1px, 2px, 3px);'>
      <foreignObject>
        <body>
          <div id='divWithTransform'
              style='transform: translate3d(3px, 4px, 5px);'></div>
        </body>
      </foreignObject>
    </svg>
  )HTML");

  LayoutObject& svg_with_transform =
      *GetLayoutObjectByElementId("svgWithTransform");
  const ObjectPaintProperties* svg_with_transform_properties =
      svg_with_transform.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3),
            svg_with_transform_properties->Transform()->Matrix());

  LayoutObject& div_with_transform =
      *GetLayoutObjectByElementId("divWithTransform");
  const ObjectPaintProperties* div_with_transform_properties =
      div_with_transform.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(3, 4, 5),
            div_with_transform_properties->Transform()->Matrix());
  // Ensure the div's transform node is a child of the svg's transform node.
  EXPECT_EQ(svg_with_transform_properties->Transform(),
            div_with_transform_properties->Transform()->Parent()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetTranslationSVGHTMLBoundary) {
  SetBodyInnerHTML(R"HTML(
    <svg id='svg'
      <foreignObject>
        <body>
          <div id='divWithTransform'
              style='transform: translate3d(3px, 4px, 5px);'></div>
        </body>
      </foreignObject>
    </svg>
  )HTML");

  LayoutObject& svg = *GetLayoutObjectByElementId("svg");
  const ObjectPaintProperties* svg_properties =
      svg.FirstFragment().PaintProperties();
  EXPECT_EQ(
      FloatSize(8, 8),
      svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());

  LayoutObject& div_with_transform =
      *GetLayoutObjectByElementId("divWithTransform");
  const ObjectPaintProperties* div_with_transform_properties =
      div_with_transform.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(3, 4, 5),
            div_with_transform_properties->Transform()->Matrix());
  EXPECT_EQ(FloatSize(8, 158),
            div_with_transform_properties->PaintOffsetTranslation()
                ->Matrix()
                .To2DTranslation());
  EXPECT_EQ(div_with_transform_properties->PaintOffsetTranslation(),
            div_with_transform_properties->Transform()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest,
       PaintOffsetTranslationSVGHTMLBoundaryMulticol) {
  SetBodyInnerHTML(R"HTML(
    <svg id='svg'>
      <foreignObject>
        <body>
          <div id='divWithColumns' style='columns: 2'>
            <div style='width: 5px; height: 5px; background: blue'>
          </div>
        </body>
      </foreignObject>
    </svg>
  )HTML");

  LayoutObject& svg = *GetLayoutObjectByElementId("svg");
  const ObjectPaintProperties* svg_properties =
      svg.FirstFragment().PaintProperties();
  EXPECT_EQ(
      FloatSize(8, 8),
      svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
  LayoutObject& div_with_columns =
      *GetLayoutObjectByElementId("divWithColumns")->SlowFirstChild();
  EXPECT_EQ(LayoutPoint(0, 0), div_with_columns.FirstFragment().PaintOffset());
}

TEST_P(PaintPropertyTreeBuilderTest,
       FixedTransformAncestorAcrossSVGHTMLBoundary) {
  SetBodyInnerHTML(R"HTML(
    <style> body { margin: 0px; } </style>
    <svg id='svg' style='transform: translate3d(1px, 2px, 3px);'>
      <g id='container' transform='translate(20 30)'>
        <foreignObject>
          <body>
            <div id='fixed'
                style='position: fixed; left: 200px; top: 150px;'></div>
          </body>
        </foreignObject>
      </g>
    </svg>
  )HTML");

  LayoutObject& svg = *GetLayoutObjectByElementId("svg");
  const ObjectPaintProperties* svg_properties =
      svg.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3),
            svg_properties->Transform()->Matrix());

  LayoutObject& container = *GetLayoutObjectByElementId("container");
  const ObjectPaintProperties* container_properties =
      container.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(20, 30),
            container_properties->Transform()->Matrix());
  EXPECT_EQ(svg_properties->Transform(),
            container_properties->Transform()->Parent());

  Element* fixed = GetDocument().getElementById("fixed");
  // Ensure the fixed position element is rooted at the nearest transform
  // container.
  EXPECT_EQ(container_properties->Transform(), fixed->GetLayoutObject()
                                                   ->FirstFragment()
                                                   .LocalBorderBoxProperties()
                                                   ->Transform());
}

TEST_P(PaintPropertyTreeBuilderTest, ControlClip) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 0;
      }
      input {
        border-radius: 0;
        border-width: 5px;
        padding: 0;
      }
    </style>
    <input id='button' type='button'
        style='width:345px; height:123px' value='some text'/>
  )HTML");

  LayoutObject& button = *GetLayoutObjectByElementId("button");
  const ObjectPaintProperties* button_properties =
      button.FirstFragment().PaintProperties();
  // No scroll translation because the document does not scroll (not enough
  // content).
  EXPECT_TRUE(!FrameScrollTranslation());
  EXPECT_EQ(FramePreTranslation(),
            button_properties->OverflowClip()->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(5, 5, 335, 113),
            button_properties->OverflowClip()->ClipRect());
  EXPECT_EQ(FrameContentClip(), button_properties->OverflowClip()->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 345, 123), &button,
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, ControlClipInsideForeignObject) {
  SetBodyInnerHTML(R"HTML(
    <div style='column-count:2;'>
      <div style='columns: 2'>
        <svg style='width: 500px; height: 500px;'>
          <foreignObject>
            <input id='button' style='width:345px; height:123px'
                 value='some text'/>
          </foreignObject>
        </svg>
      </div>
    </div>
  )HTML");

  LayoutObject& button = *GetLayoutObjectByElementId("button");
  const ObjectPaintProperties* button_properties =
      button.FirstFragment().PaintProperties();
  // No scroll translation because the document does not scroll (not enough
  // content).
  EXPECT_TRUE(!FrameScrollTranslation());
  EXPECT_EQ(FloatRoundedRect(2, 2, 341, 119),
            button_properties->OverflowClip()->ClipRect());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 345, 123), &button,
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, BorderRadiusClip) {
  SetBodyInnerHTML(R"HTML(
    <style>
     body {
       margin: 0px;
     }
     #div {
       border-radius: 12px 34px 56px 78px;
       border-top: 45px solid;
       border-right: 50px solid;
       border-bottom: 55px solid;
       border-left: 60px solid;
       width: 500px;
       height: 400px;
       overflow: scroll;
     }
    </style>
    <div id='div'></div>
  )HTML");

  LayoutObject& div = *GetLayoutObjectByElementId("div");
  const ObjectPaintProperties* div_properties =
      div.FirstFragment().PaintProperties();
  // No scroll translation because the document does not scroll (not enough
  // content).
  EXPECT_TRUE(!FrameScrollTranslation());
  EXPECT_EQ(FramePreTranslation(),
            div_properties->OverflowClip()->LocalTransformSpace());
  // The overflow clip rect includes only the padding box.
  // padding box = border box(500+60+50, 400+45+55) - border outset(60+50,
  // 45+55) - scrollbars(15, 15)
  EXPECT_EQ(FloatRoundedRect(60, 45, 500, 400),
            div_properties->OverflowClip()->ClipRect());
  const ClipPaintPropertyNode* border_radius_clip =
      div_properties->OverflowClip()->Parent();
  EXPECT_EQ(FramePreTranslation(), border_radius_clip->LocalTransformSpace());
  // The border radius clip is the area enclosed by inner border edge, including
  // the scrollbars.  As the border-radius is specified in outer radius, the
  // inner radius is calculated by:
  //     inner radius = max(outer radius - border width, 0)
  // In the case that two adjacent borders have different width, the inner
  // radius of the corner may transition from one value to the other. i.e. being
  // an ellipse.
  // The following is border box(610, 500) - border outset(110, 100).
  FloatRect border_box_minus_border_outset(60, 45, 500, 400);
  EXPECT_EQ(
      FloatRoundedRect(
          border_box_minus_border_outset,
          FloatSize(0, 0),    // (top left) = max((12, 12) - (60, 45), (0, 0))
          FloatSize(0, 0),    // (top right) = max((34, 34) - (50, 45), (0, 0))
          FloatSize(18, 23),  // (bot left) = max((78, 78) - (60, 55), (0, 0))
          FloatSize(6, 1)),   // (bot right) = max((56, 56) - (50, 55), (0, 0))
      border_radius_clip->ClipRect());
  EXPECT_EQ(FrameContentClip(), border_radius_clip->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 610, 500), &div,
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, TransformNodesAcrossSubframes) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body { margin: 0; }
      #divWithTransform {
        transform: translate3d(1px, 2px, 3px);
      }
    </style>
    <div id='divWithTransform'>
      <iframe style='border: 7px solid black'></iframe>
    </div>
  )HTML");
  SetChildFrameHTML(R"HTML(
    <style>
      body { margin: 0; }
      #innerDivWithTransform {
        transform: translate3d(4px, 5px, 6px);
        width: 100px;
        height: 200px;
      }
    </style>
    <div id='innerDivWithTransform'></div>
  )HTML");

  LocalFrameView* frame_view = GetDocument().View();
  frame_view->UpdateAllLifecyclePhases();

  LayoutObject* div_with_transform =
      GetLayoutObjectByElementId("divWithTransform");
  const ObjectPaintProperties* div_with_transform_properties =
      div_with_transform->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3),
            div_with_transform_properties->Transform()->Matrix());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(1, 2, 800, 164), div_with_transform,
                          frame_view->GetLayoutView());

  LayoutObject* inner_div_with_transform =
      ChildDocument()
          .getElementById("innerDivWithTransform")
          ->GetLayoutObject();
  const ObjectPaintProperties* inner_div_with_transform_properties =
      inner_div_with_transform->FirstFragment().PaintProperties();
  auto* inner_div_transform = inner_div_with_transform_properties->Transform();
  EXPECT_EQ(TransformationMatrix().Translate3d(4, 5, 6),
            inner_div_transform->Matrix());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(12, 14, 100, 145),
                          inner_div_with_transform,
                          frame_view->GetLayoutView());

  // Ensure that the inner div's transform is correctly rooted in the root
  // frame's transform tree.
  // This asserts that we have the following tree structure:
  // ...
  //   Transform transform=translation=1.000000,2.000000,3.000000
  //     PreTranslation transform=translation=7.000000,7.000000,0.000000
  //       PaintOffsetTranslation transform=Identity
  //         ScrollTranslation transform=translation=0.000000,0.000000,0.000000
  //           Transform transform=translation=4.000000,5.000000,6.000000
  auto* inner_document_scroll_translation = inner_div_transform->Parent();
  EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0),
            inner_document_scroll_translation->Matrix());
  auto* paint_offset_translation = inner_document_scroll_translation->Parent();
  auto* iframe_pre_translation =
      inner_document_scroll_translation->Parent()->Parent();
  EXPECT_EQ(FloatSize(), paint_offset_translation->Matrix().To2DTranslation());
  EXPECT_EQ(TransformationMatrix().Translate3d(7, 7, 0),
            iframe_pre_translation->Matrix());
  EXPECT_EQ(div_with_transform_properties->Transform(),
            iframe_pre_translation->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, TransformNodesInTransformedSubframes) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body { margin: 0; }
      #divWithTransform {
        transform: translate3d(1px, 2px, 3px);
      }
      iframe {
        transform: translate3d(4px, 5px, 6px);
        border: 42px solid;
        margin: 7px;
      }
    </style>
    <div id='divWithTransform'>
      <iframe></iframe>
    </div>
  )HTML");
  SetChildFrameHTML(R"HTML(
    <style>
      body { margin: 31px; }
      #transform {
        transform: translate3d(7px, 8px, 9px);
        width: 100px;
        height: 200px;
      }
    </style>
    <div id='transform'></div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();
  frame_view->UpdateAllLifecyclePhases();

  // Assert that we have the following tree structure:
  // ...
  //   Transform transform=translation=1.000000,2.000000,3.000000
  //     PaintOffsetTranslation transform=translation=7.000000,7.000000,0.000000
  //       Transform transform=translation=4.000000,5.000000,6.000000
  //         PreTranslation transform=translation=42.000000,42.000000,0.000000
  //           ScrollTranslation transform=translation=0.000000,0.000000,0.00000
  //             PaintOffsetTranslation transform=translation=31.00,31.00,0.00
  //               Transform transform=translation=7.000000,8.000000,9.000000

  LayoutObject* inner_div_with_transform =
      ChildDocument().getElementById("transform")->GetLayoutObject();
  auto* inner_div_transform =
      inner_div_with_transform->FirstFragment().PaintProperties()->Transform();
  EXPECT_EQ(TransformationMatrix().Translate3d(7, 8, 9),
            inner_div_transform->Matrix());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(92, 95, 100, 111),
                          inner_div_with_transform,
                          frame_view->GetLayoutView());

  auto* inner_document_paint_offset_translation = inner_div_transform->Parent();
  EXPECT_EQ(TransformationMatrix().Translate3d(31, 31, 0),
            inner_document_paint_offset_translation->Matrix());
  auto* inner_document_scroll_translation =
      inner_document_paint_offset_translation->Parent();
  EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0),
            inner_document_scroll_translation->Matrix());
  auto* iframe_pre_translation = inner_document_scroll_translation->Parent();
  EXPECT_EQ(TransformationMatrix().Translate3d(42, 42, 0),
            iframe_pre_translation->Matrix());
  auto* iframe_transform = iframe_pre_translation->Parent();
  EXPECT_EQ(TransformationMatrix().Translate3d(4, 5, 6),
            iframe_transform->Matrix());
  auto* iframe_paint_offset_translation = iframe_transform->Parent();
  EXPECT_EQ(TransformationMatrix().Translate3d(7, 7, 0),
            iframe_paint_offset_translation->Matrix());
  auto* div_with_transform_transform =
      iframe_paint_offset_translation->Parent();
  EXPECT_EQ(TransformationMatrix().Translate3d(1, 2, 3),
            div_with_transform_transform->Matrix());

  LayoutObject* div_with_transform =
      GetLayoutObjectByElementId("divWithTransform");
  EXPECT_EQ(div_with_transform_transform,
            div_with_transform->FirstFragment().PaintProperties()->Transform());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(1, 2, 800, 248), div_with_transform,
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, TreeContextClipByNonStackingContext) {
  // This test verifies the tree builder correctly computes and records the
  // property tree context for a (pseudo) stacking context that is scrolled by a
  // containing block that is not one of the painting ancestors.
  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 0; }</style>
    <div id='scroller' style='overflow:scroll; width:400px; height:300px;'>
      <div id='child'
          style='position:relative; width:100px; height: 200px;'></div>
      <div style='height:10000px;'></div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* scroller = GetLayoutObjectByElementId("scroller");
  const ObjectPaintProperties* scroller_properties =
      scroller->FirstFragment().PaintProperties();
  LayoutObject* child = GetLayoutObjectByElementId("child");

  EXPECT_EQ(scroller_properties->OverflowClip(),
            child->FirstFragment().LocalBorderBoxProperties()->Clip());
  EXPECT_EQ(scroller_properties->ScrollTranslation(),
            child->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_NE(nullptr,
            child->FirstFragment().LocalBorderBoxProperties()->Effect());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 400, 300), scroller,
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 100, 200), child,
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest,
       TreeContextUnclipFromParentStackingContext) {
  // This test verifies the tree builder correctly computes and records the
  // property tree context for a (pseudo) stacking context that has a scrolling
  // painting ancestor that is not its containing block (thus should not be
  // scrolled by it).

  SetBodyInnerHTML(R"HTML(
    <style>
      body { margin: 0; }
      #scroller {
        overflow:scroll;
        opacity:0.5;
      }
      #child {
        position:absolute;
        left:0;
        top:0;
        width: 100px;
        height: 200px;
      }
    </style>
    <div id='scroller'>
      <div id='child'></div>
      <div id='forceScroll' style='height:10000px;'></div>
    </div>
  )HTML");

  auto& scroller = *GetLayoutObjectByElementId("scroller");
  const ObjectPaintProperties* scroller_properties =
      scroller.FirstFragment().PaintProperties();
  LayoutObject& child = *GetLayoutObjectByElementId("child");

  EXPECT_EQ(FrameContentClip(),
            child.FirstFragment().LocalBorderBoxProperties()->Clip());
  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
    EXPECT_EQ(FrameScrollTranslation(),
              child.FirstFragment().LocalBorderBoxProperties()->Transform());
  } else {
    // For SPv1*, |child| is composited so we created PaintOffsetTranslation.
    EXPECT_EQ(child.FirstFragment().PaintProperties()->PaintOffsetTranslation(),
              child.FirstFragment().LocalBorderBoxProperties()->Transform());
  }
  EXPECT_EQ(scroller_properties->Effect(),
            child.FirstFragment().LocalBorderBoxProperties()->Effect());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 800, 10000), &scroller,
                          GetDocument().View()->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 100, 200), &child,
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, TableCellLayoutLocation) {
  // This test verifies that the border box space of a table cell is being
  // correctly computed.  Table cells have weird location adjustment in our
  // layout/paint implementation.
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 0;
      }
      table {
        border-spacing: 0;
        margin: 20px;
        padding: 40px;
        border: 10px solid black;
      }
      td {
        width: 100px;
        height: 100px;
        padding: 0;
      }
      #target {
        position: relative;
        width: 100px;
        height: 100px;
      }
    </style>
    <table>
      <tr><td></td><td></td></tr>
      <tr><td></td><td><div id='target'></div></td></tr>
    </table>
  )HTML");

  LayoutObject& target = *GetLayoutObjectByElementId("target");
  EXPECT_EQ(LayoutPoint(170, 170), target.FirstFragment().PaintOffset());
  EXPECT_EQ(FramePreTranslation(),
            target.FirstFragment().LocalBorderBoxProperties()->Transform());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(170, 170, 100, 100), &target,
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendant) {
  // This test verifies that clip tree hierarchy being generated correctly for
  // the hard case such that a fixed position element getting clipped by an
  // absolute position CSS clip.
  SetBodyInnerHTML(R"HTML(
    <style>
      #clip {
        position: absolute;
        left: 123px;
        top: 456px;
        clip: rect(10px, 80px, 70px, 40px);
        width: 100px;
        height: 100px;
      }
      #fixed {
        position: fixed;
        left: 654px;
        top: 321px;
        width: 10px;
        height: 20px
      }
    </style>
    <div id='clip'><div id='fixed'></div></div>
  )HTML");
  LayoutRect local_clip_rect(40, 10, 40, 60);
  LayoutRect absolute_clip_rect = local_clip_rect;
  absolute_clip_rect.Move(123, 456);

  LayoutObject& clip = *GetLayoutObjectByElementId("clip");
  const ObjectPaintProperties* clip_properties =
      clip.FirstFragment().PaintProperties();
  EXPECT_EQ(FrameContentClip(), clip_properties->CssClip()->Parent());
  EXPECT_EQ(FramePreTranslation(),
            clip_properties->CssClip()->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
            clip_properties->CssClip()->ClipRect());
  CHECK_VISUAL_RECT(absolute_clip_rect, &clip,
                    GetDocument().View()->GetLayoutView(),
                    // TODO(crbug.com/599939): mapToVisualRectInAncestorSpace()
                    // doesn't apply css clip on the object itself.
                    LayoutUnit::Max());

  LayoutObject* fixed = GetLayoutObjectByElementId("fixed");
  EXPECT_EQ(clip_properties->CssClip(),
            fixed->FirstFragment().LocalBorderBoxProperties()->Clip());
  EXPECT_EQ(FramePreTranslation(),
            fixed->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_EQ(LayoutPoint(654, 321), fixed->FirstFragment().PaintOffset());
  CHECK_VISUAL_RECT(LayoutRect(), fixed, GetDocument().View()->GetLayoutView(),
                    // TODO(crbug.com/599939): CSS clip of fixed-position
                    // descendants is broken in
                    // mapToVisualRectInAncestorSpace().
                    LayoutUnit::Max());
}

TEST_P(PaintPropertyTreeBuilderTest, CSSClipAbsPositionDescendant) {
  // This test verifies that clip tree hierarchy being generated correctly for
  // the hard case such that a fixed position element getting clipped by an
  // absolute position CSS clip.
  SetBodyInnerHTML(R"HTML(
    <style>
      #clip {
        position: absolute;
        left: 123px;
        top: 456px;
        clip: rect(10px, 80px, 70px, 40px);
        width: 100px;
        height: 100px;
      }
      #absolute {
        position: absolute;
        left: 654px;
        top: 321px;
        width: 10px;
        heght: 20px
      }
    </style>
    <div id='clip'><div id='absolute'></div></div>
  )HTML");

  LayoutRect local_clip_rect(40, 10, 40, 60);
  LayoutRect absolute_clip_rect = local_clip_rect;
  absolute_clip_rect.Move(123, 456);

  auto* clip = GetLayoutObjectByElementId("clip");
  const ObjectPaintProperties* clip_properties =
      clip->FirstFragment().PaintProperties();
  EXPECT_EQ(FrameContentClip(), clip_properties->CssClip()->Parent());
  // No scroll translation because the document does not scroll (not enough
  // content).
  EXPECT_TRUE(!FrameScrollTranslation());
  EXPECT_EQ(FramePreTranslation(),
            clip_properties->CssClip()->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
            clip_properties->CssClip()->ClipRect());
  CHECK_VISUAL_RECT(absolute_clip_rect, clip,
                    GetDocument().View()->GetLayoutView(),
                    // TODO(crbug.com/599939): mapToVisualRectInAncestorSpace()
                    // doesn't apply css clip on the object itself.
                    LayoutUnit::Max());

  auto* absolute = GetLayoutObjectByElementId("absolute");
  EXPECT_EQ(clip_properties->CssClip(),
            absolute->FirstFragment().LocalBorderBoxProperties()->Clip());
  EXPECT_EQ(FramePreTranslation(),
            absolute->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_EQ(LayoutPoint(777, 777), absolute->FirstFragment().PaintOffset());
  CHECK_VISUAL_RECT(LayoutRect(), absolute,
                    GetDocument().View()->GetLayoutView(),
                    // TODO(crbug.com/599939): CSS clip of fixed-position
                    // descendants is broken in
                    // mapToVisualRectInAncestorSpace().
                    LayoutUnit::Max());
}

TEST_P(PaintPropertyTreeBuilderTest, CSSClipFixedPositionDescendantNonShared) {
  // This test is similar to CSSClipFixedPositionDescendant above, except that
  // now we have a parent overflow clip that should be escaped by the fixed
  // descendant.
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 0;
      }
      #overflow {
        position: relative;
        width: 50px;
        height: 50px;
        overflow: scroll;
      }
      #clip {
        position: absolute;
        left: 123px;
        top: 456px;
        clip: rect(10px, 80px, 70px, 40px);
        width: 100px;
        height: 100px;
      }
      #fixed {
        position: fixed;
        left: 654px;
        top: 321px;
      }
    </style>
    <div id='overflow'><div id='clip'><div id='fixed'></div></div></div>
  )HTML");
  LayoutRect local_clip_rect(40, 10, 40, 60);
  LayoutRect absolute_clip_rect = local_clip_rect;
  absolute_clip_rect.Move(123, 456);

  LayoutObject& overflow = *GetLayoutObjectByElementId("overflow");
  const ObjectPaintProperties* overflow_properties =
      overflow.FirstFragment().PaintProperties();
  EXPECT_EQ(FrameContentClip(), overflow_properties->OverflowClip()->Parent());
  // No scroll translation because the document does not scroll (not enough
  // content).
  EXPECT_TRUE(!FrameScrollTranslation());
  EXPECT_EQ(FramePreTranslation(),
            overflow_properties->ScrollTranslation()->Parent()->Parent());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 50, 50), &overflow,
                          GetDocument().View()->GetLayoutView());

  LayoutObject* clip = GetLayoutObjectByElementId("clip");
  const ObjectPaintProperties* clip_properties =
      clip->FirstFragment().PaintProperties();
  EXPECT_EQ(overflow_properties->OverflowClip(),
            clip_properties->CssClip()->Parent());
  EXPECT_EQ(overflow_properties->ScrollTranslation(),
            clip_properties->CssClip()->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
            clip_properties->CssClip()->ClipRect());
  EXPECT_EQ(FrameContentClip(),
            clip_properties->CssClipFixedPosition()->Parent());
  EXPECT_EQ(overflow_properties->ScrollTranslation(),
            clip_properties->CssClipFixedPosition()->LocalTransformSpace());
  EXPECT_EQ(FloatRoundedRect(FloatRect(absolute_clip_rect)),
            clip_properties->CssClipFixedPosition()->ClipRect());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(), clip,
                          GetDocument().View()->GetLayoutView());

  LayoutObject* fixed = GetLayoutObjectByElementId("fixed");
  EXPECT_EQ(clip_properties->CssClipFixedPosition(),
            fixed->FirstFragment().LocalBorderBoxProperties()->Clip());
  EXPECT_EQ(FramePreTranslation(),
            fixed->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_EQ(LayoutPoint(654, 321), fixed->FirstFragment().PaintOffset());
  CHECK_VISUAL_RECT(LayoutRect(), fixed, GetDocument().View()->GetLayoutView(),
                    // TODO(crbug.com/599939): CSS clip of fixed-position
                    // descendants is broken in geometry mapping.
                    LayoutUnit::Max());
}

TEST_P(PaintPropertyTreeBuilderTest, ColumnSpannerUnderRelativePositioned) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #spanner {
        column-span: all;
        opacity: 0.5;
        width: 100px;
        height: 100px;
      }
    </style>
    <div style='columns: 3; position: absolute; top: 44px; left: 55px;'>
      <div style='position: relative; top: 100px; left: 100px'>
        <div id='spanner'></div>
      </div>
    </div>
  )HTML");

  LayoutObject* spanner = GetLayoutObjectByElementId("spanner");
  EXPECT_EQ(LayoutPoint(55, 44), spanner->FirstFragment().PaintOffset());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(55, 44, 100, 100), spanner,
                          GetDocument().View()->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, FractionalPaintOffset) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * { margin: 0; }
      div { position: absolute; }
      #a {
        width: 70px;
        height: 70px;
        left: 0.1px;
        top: 0.3px;
      }
      #b {
        width: 40px;
        height: 40px;
        left: 0.5px;
        top: 11.1px;
      }
    </style>
    <div id='a'>
      <div id='b'></div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* a = GetLayoutObjectByElementId("a");
  LayoutPoint a_paint_offset = LayoutPoint(FloatPoint(0.1, 0.3));
  EXPECT_EQ(a_paint_offset, a->FirstFragment().PaintOffset());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(0.1), LayoutUnit(0.3),
                                     LayoutUnit(70), LayoutUnit(70)),
                          a, frame_view->GetLayoutView());

  LayoutObject* b = GetLayoutObjectByElementId("b");
  LayoutPoint b_paint_offset =
      a_paint_offset + LayoutPoint(FloatPoint(0.5, 11.1));
  EXPECT_EQ(b_paint_offset, b->FirstFragment().PaintOffset());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(0.1), LayoutUnit(0.3),
                                     LayoutUnit(70), LayoutUnit(70)),
                          a, frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetWithBasicPixelSnapping) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * { margin: 0; }
      div { position: relative; }
      #a {
        width: 70px;
        height: 70px;
        left: 0.3px;
        top: 0.3px;
      }
      #b {
        width: 40px;
        height: 40px;
        transform: translateZ(0);
      }
      #c {
        width: 40px;
        height: 40px;
       left: 0.1px;
       top: 0.1px;
      }
    </style>
    <div id='a'>
      <div id='b'>
        <div id='c'></div>
      </div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0),
            b_properties->Transform()->Matrix());
  // The paint offset transform should be snapped from (0.3,0.3) to (0,0).
  EXPECT_EQ(TransformationMatrix().Translate(0, 0),
            b_properties->Transform()->Parent()->Matrix());
  // The residual subpixel adjustment should be (0.3,0.3) - (0,0) = (0.3,0.3).
  LayoutPoint subpixel_accumulation = LayoutPoint(FloatPoint(0.3, 0.3));
  EXPECT_EQ(subpixel_accumulation, b->FirstFragment().PaintOffset());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(FloatRect(0.3, 0.3, 40, 40)), b,
                          frame_view->GetLayoutView());

  // c's painted should start at subpixelAccumulation + (0.1,0.1) = (0.4,0.4).
  LayoutObject* c = GetLayoutObjectByElementId("c");
  LayoutPoint c_paint_offset =
      subpixel_accumulation + LayoutPoint(FloatPoint(0.1, 0.1));
  EXPECT_EQ(c_paint_offset, c->FirstFragment().PaintOffset());
  // Visual rects via the non-paint properties system use enclosingIntRect
  // before applying transforms, because they are computed bottom-up and
  // therefore can't apply pixel snapping. Therefore apply a slop of 1px.
  CHECK_VISUAL_RECT(LayoutRect(FloatRect(0.4, 0.4, 40, 40)), c,
                    frame_view->GetLayoutView(), 1);
}

TEST_P(PaintPropertyTreeBuilderTest,
       PaintOffsetWithPixelSnappingThroughTransform) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * { margin: 0; }
      div { position: relative; }
      #a {
        width: 70px;
        height: 70px;
        left: 0.7px;
        top: 0.7px;
      }
      #b {
        width: 40px;
        height: 40px;
        transform: translateZ(0);
      }
      #c {
        width: 40px;
        height: 40px;
        left: 0.7px;
        top: 0.7px;
      }
    </style>
    <div id='a'>
      <div id='b'>
        <div id='c'></div>
      </div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(0, 0, 0),
            b_properties->Transform()->Matrix());
  // The paint offset transform should be snapped from (0.7,0.7) to (1,1).
  EXPECT_EQ(TransformationMatrix().Translate(1, 1),
            b_properties->Transform()->Parent()->Matrix());
  // The residual subpixel adjustment should be (0.7,0.7) - (1,1) = (-0.3,-0.3).
  LayoutPoint subpixel_accumulation =
      LayoutPoint(LayoutPoint(FloatPoint(0.7, 0.7)) - LayoutPoint(1, 1));
  EXPECT_EQ(subpixel_accumulation, b->FirstFragment().PaintOffset());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(0.7), LayoutUnit(0.7),
                                     LayoutUnit(40), LayoutUnit(40)),
                          b, frame_view->GetLayoutView());

  // c's painting should start at subpixelAccumulation + (0.7,0.7) = (0.4,0.4).
  LayoutObject* c = GetLayoutObjectByElementId("c");
  LayoutPoint c_paint_offset =
      subpixel_accumulation + LayoutPoint(FloatPoint(0.7, 0.7));
  EXPECT_EQ(c_paint_offset, c->FirstFragment().PaintOffset());
  // Visual rects via the non-paint properties system use enclosingIntRect
  // before applying transforms, because they are computed bottom-up and
  // therefore can't apply pixel snapping. Therefore apply a slop of 1px.
  CHECK_VISUAL_RECT(LayoutRect(LayoutUnit(0.7) + LayoutUnit(0.7),
                               LayoutUnit(0.7) + LayoutUnit(0.7),
                               LayoutUnit(40), LayoutUnit(40)),
                    c, frame_view->GetLayoutView(), 1);
}

TEST_P(PaintPropertyTreeBuilderTest,
       NonTranslationTransformShouldResetSubpixelPaintOffset) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * { margin: 0; }
      div { position: relative; }
      #a {
        width: 70px;
        height: 70px;
        left: 0.9px;
        top: 0.9px;
      }
      #b {
        width: 40px;
        height: 40px;
        transform: scale(10);
        transform-origin: 0 0;
      }
      #c {
        width: 40px;
        height: 40px;
        left: 0.6px;
        top: 0.6px;
      }
    </style>
    <div id='a'>
      <div id='b'>
        <div id='c'></div>
      </div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Scale(10),
            b_properties->Transform()->Matrix());
  // The paint offset transform should not be snapped.
  EXPECT_EQ(TransformationMatrix().Translate(1, 1),
            b_properties->Transform()->Parent()->Matrix());
  EXPECT_EQ(LayoutPoint(), b->FirstFragment().PaintOffset());
  // Visual rects via the non-paint properties system use enclosingIntRect
  // before applying transforms, because they are computed bottom-up and
  // therefore can't apply pixel snapping. Therefore apply a slop of 1px.
  CHECK_VISUAL_RECT(LayoutRect(LayoutUnit(1), LayoutUnit(1), LayoutUnit(400),
                               LayoutUnit(400)),
                    b, frame_view->GetLayoutView(), 1);

  // c's painting should start at c_offset.
  LayoutObject* c = GetLayoutObjectByElementId("c");
  LayoutUnit c_offset = LayoutUnit(0.6);
  EXPECT_EQ(LayoutPoint(c_offset, c_offset), c->FirstFragment().PaintOffset());
  // Visual rects via the non-paint properties system use enclosingIntRect
  // before applying transforms, because they are computed bottom-up and
  // therefore can't apply pixel snapping. Therefore apply a slop of 1px
  // in the transformed space (c_offset * 10 in view space) and 1px in the
  // view space.
  CHECK_VISUAL_RECT(LayoutRect(c_offset * 10 + 1, c_offset * 10 + 1,
                               LayoutUnit(400), LayoutUnit(400)),
                    c, frame_view->GetLayoutView(), c_offset * 10 + 1);
}

TEST_P(PaintPropertyTreeBuilderTest,
       PaintOffsetWithPixelSnappingThroughMultipleTransforms) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * { margin: 0; }
      div { position: relative; }
      #a {
        width: 70px;
        height: 70px;
        left: 0.7px;
        top: 0.7px;
      }
      #b {
        width: 40px;
        height: 40px;
        transform: translate3d(5px, 7px, 0);
      }
      #c {
        width: 40px;
        height: 40px;
        transform: translate3d(11px, 13px, 0);
      }
      #d {
        width: 40px;
        height: 40px;
        left: 0.7px;
        top: 0.7px;
      }
    </style>
    <div id='a'>
      <div id='b'>
        <div id='c'>
          <div id='d'></div>
        </div>
      </div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(5, 7, 0),
            b_properties->Transform()->Matrix());
  // The paint offset transform should be snapped from (0.7,0.7) to (1,1).
  EXPECT_EQ(TransformationMatrix().Translate(1, 1),
            b_properties->Transform()->Parent()->Matrix());
  // The residual subpixel adjustment should be (0.7,0.7) - (1,1) = (-0.3,-0.3).
  LayoutPoint subpixel_accumulation =
      LayoutPoint(LayoutPoint(FloatPoint(0.7, 0.7)) - LayoutPoint(1, 1));
  EXPECT_EQ(subpixel_accumulation, b->FirstFragment().PaintOffset());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(5.7), LayoutUnit(7.7),
                                     LayoutUnit(40), LayoutUnit(40)),
                          b, frame_view->GetLayoutView());

  LayoutObject* c = GetLayoutObjectByElementId("c");
  const ObjectPaintProperties* c_properties =
      c->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate3d(11, 13, 0),
            c_properties->Transform()->Matrix());
  // The paint offset should be (-0.3,-0.3) but the paint offset transform
  // should still be at (0,0) because it should be snapped.
  EXPECT_EQ(TransformationMatrix().Translate(0, 0),
            c_properties->Transform()->Parent()->Matrix());
  // The residual subpixel adjustment should still be (-0.3,-0.3).
  EXPECT_EQ(subpixel_accumulation, c->FirstFragment().PaintOffset());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(16.7), LayoutUnit(20.7),
                                     LayoutUnit(40), LayoutUnit(40)),
                          c, frame_view->GetLayoutView());

  // d should be painted starting at subpixelAccumulation + (0.7,0.7) =
  // (0.4,0.4).
  LayoutObject* d = GetLayoutObjectByElementId("d");
  LayoutPoint d_paint_offset =
      subpixel_accumulation + LayoutPoint(FloatPoint(0.7, 0.7));
  EXPECT_EQ(d_paint_offset, d->FirstFragment().PaintOffset());
  // Visual rects via the non-paint properties system use enclosingIntRect
  // before applying transforms, because they are computed bottom-up and
  // therefore can't apply pixel snapping. Therefore apply a slop of 1px.
  CHECK_VISUAL_RECT(LayoutRect(LayoutUnit(16.7) + LayoutUnit(0.7),
                               LayoutUnit(20.7) + LayoutUnit(0.7),
                               LayoutUnit(40), LayoutUnit(40)),
                    d, frame_view->GetLayoutView(), 1);
}

TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetWithPixelSnappingWithFixedPos) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * { margin: 0; }
      #a {
        width: 70px;
        height: 70px;
        left: 0.7px;
        position: relative;
      }
      #b {
        width: 40px;
        height: 40px;
        transform: translateZ(0);
        position: relative;
      }
      #fixed {
        width: 40px;
        height: 40px;
        position: fixed;
      }
      #d {
        width: 40px;
        height: 40px;
        left: 0.7px;
        position: relative;
      }
    </style>
    <div id='a'>
      <div id='b'>
        <div id='fixed'>
          <div id='d'></div>
        </div>
      </div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(0, 0),
            b_properties->Transform()->Matrix());
  // The paint offset transform should be snapped from (0.7,0) to (1,0).
  EXPECT_EQ(TransformationMatrix().Translate(1, 0),
            b_properties->Transform()->Parent()->Matrix());
  // The residual subpixel adjustment should be (0.7,0) - (1,0) = (-0.3,0).
  LayoutPoint subpixel_accumulation =
      LayoutPoint(LayoutPoint(FloatPoint(0.7, 0)) - LayoutPoint(1, 0));
  EXPECT_EQ(subpixel_accumulation, b->FirstFragment().PaintOffset());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(0.7), LayoutUnit(0),
                                     LayoutUnit(40), LayoutUnit(40)),
                          b, frame_view->GetLayoutView());

  LayoutObject* fixed = GetLayoutObjectByElementId("fixed");
  // The residual subpixel adjustment should still be (-0.3,0).
  EXPECT_EQ(subpixel_accumulation, fixed->FirstFragment().PaintOffset());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(LayoutUnit(0.7), LayoutUnit(0),
                                     LayoutUnit(40), LayoutUnit(40)),
                          fixed, frame_view->GetLayoutView());

  // d should be painted starting at subpixelAccumulation + (0.7,0) = (0.4,0).
  LayoutObject* d = GetLayoutObjectByElementId("d");
  LayoutPoint d_paint_offset =
      subpixel_accumulation + LayoutPoint(FloatPoint(0.7, 0));
  EXPECT_EQ(d_paint_offset, d->FirstFragment().PaintOffset());
  // Visual rects via the non-paint properties system use enclosingIntRect
  // before applying transforms, because they are computed bottom-up and
  // therefore can't apply pixel snapping. Therefore apply a slop of 1px.
  CHECK_VISUAL_RECT(LayoutRect(LayoutUnit(0.7) + LayoutUnit(0.7), LayoutUnit(),
                               LayoutUnit(40), LayoutUnit(40)),
                    d, frame_view->GetLayoutView(), 1);
}

TEST_P(PaintPropertyTreeBuilderTest, SvgPixelSnappingShouldResetPaintOffset) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #svg {
        position: relative;
        left: 0.1px;
        transform: matrix(1, 0, 0, 1, 0, 0);
      }
    </style>
    <svg id='svg'>
        <rect id='rect' transform='translate(1, 1)'/>
    </svg>
  )HTML");

  LayoutObject& svg_with_transform = *GetLayoutObjectByElementId("svg");
  const ObjectPaintProperties* svg_with_transform_properties =
      svg_with_transform.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix(),
            svg_with_transform_properties->Transform()->Matrix());
  EXPECT_EQ(LayoutPoint(FloatPoint(0.1, 0)),
            svg_with_transform.FirstFragment().PaintOffset());
  EXPECT_TRUE(svg_with_transform_properties->SvgLocalToBorderBoxTransform() ==
              nullptr);

  LayoutObject& rect_with_transform = *GetLayoutObjectByElementId("rect");
  const ObjectPaintProperties* rect_with_transform_properties =
      rect_with_transform.FirstFragment().PaintProperties();
  EXPECT_EQ(TransformationMatrix().Translate(1, 1),
            rect_with_transform_properties->Transform()->Matrix());

  // Ensure there is no PaintOffset transform between the rect and the svg's
  // transform.
  EXPECT_EQ(svg_with_transform_properties->Transform(),
            rect_with_transform_properties->Transform()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, SvgRootAndForeignObjectPixelSnapping) {
  SetBodyInnerHTML(R"HTML(
    <svg id=svg style='position: relative; left: 0.6px; top: 0.3px'>
      <foreignObject id=foreign x='3.5' y='5.4' transform='translate(1, 1)'>
        <div id=div style='position: absolute; left: 5.6px; top: 7.3px'>
        </div>
      </foreignObject>
    </svg>
  )HTML");

  const auto* svg = GetLayoutObjectByElementId("svg");
  const auto* svg_properties = svg->FirstFragment().PaintProperties();
  // The paint offset of (8.6, 8.3) is rounded off here. The fractional part
  // remains PaintOffset.
  EXPECT_EQ(
      FloatSize(9, 8),
      svg_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
  EXPECT_EQ(LayoutPoint(LayoutUnit(-0.40625), LayoutUnit(0.3)),
            svg->FirstFragment().PaintOffset());
  EXPECT_EQ(nullptr, svg_properties->SvgLocalToBorderBoxTransform());
  const auto* foreign_object = GetLayoutObjectByElementId("foreign");
  const auto* foreign_object_properties =
      foreign_object->FirstFragment().PaintProperties();
  EXPECT_EQ(nullptr, foreign_object_properties->PaintOffsetTranslation());
  // Paint offset of foreignObject should be originated from SVG root and
  // snapped to pixels.
  EXPECT_EQ(LayoutPoint(4, 5), foreign_object->FirstFragment().PaintOffset());

  const auto* div = GetLayoutObjectByElementId("div");
  // Paint offset of descendant of foreignObject accumulates on paint offset of
  // foreignObject.
  EXPECT_EQ(LayoutPoint(LayoutUnit(4 + 5.6), LayoutUnit(5 + 7.3)),
            div->FirstFragment().PaintOffset());
}

TEST_P(PaintPropertyTreeBuilderTest, NoRenderingContextByDefault) {
  SetBodyInnerHTML("<div style='transform: translateZ(0)'></div>");

  const ObjectPaintProperties* properties = GetDocument()
                                                .body()
                                                ->firstChild()
                                                ->GetLayoutObject()
                                                ->FirstFragment()
                                                .PaintProperties();
  ASSERT_TRUE(properties->Transform());
  EXPECT_FALSE(properties->Transform()->HasRenderingContext());
}

TEST_P(PaintPropertyTreeBuilderTest, Preserve3DCreatesSharedRenderingContext) {
  SetBodyInnerHTML(R"HTML(
    <div style='transform-style: preserve-3d'>
      <div id='a' style='transform: translateZ(0); width: 30px; height: 40px'>
      </div>
      <div id='b' style='transform: translateZ(0); width: 20px; height: 10px'>
      </div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* a = GetLayoutObjectByElementId("a");
  const ObjectPaintProperties* a_properties =
      a->FirstFragment().PaintProperties();
  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  ASSERT_TRUE(a_properties->Transform() && b_properties->Transform());
  EXPECT_NE(a_properties->Transform(), b_properties->Transform());
  EXPECT_TRUE(a_properties->Transform()->HasRenderingContext());
  EXPECT_TRUE(b_properties->Transform()->HasRenderingContext());
  EXPECT_EQ(a_properties->Transform()->RenderingContextId(),
            b_properties->Transform()->RenderingContextId());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 30, 40), a,
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 48, 20, 10), b,
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, FlatTransformStyleEndsRenderingContext) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #a {
        transform: translateZ(0);
        width: 30px;
        height: 40px;
      }
      #b {
        transform: translateZ(0);
        width: 10px;
        height: 20px;
      }
    </style>
    <div style='transform-style: preserve-3d'>
      <div id='a'>
        <div id='b'></div>
      </div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* a = GetLayoutObjectByElementId("a");
  const ObjectPaintProperties* a_properties =
      a->FirstFragment().PaintProperties();
  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  ASSERT_FALSE(a->StyleRef().Preserves3D());

  ASSERT_TRUE(a_properties->Transform() && b_properties->Transform());

  // #a should participate in a rendering context (due to its parent), but its
  // child #b should not.
  EXPECT_TRUE(a_properties->Transform()->HasRenderingContext());
  EXPECT_FALSE(b_properties->Transform()->HasRenderingContext());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 30, 40), a,
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 10, 20), b,
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, NestedRenderingContexts) {
  SetBodyInnerHTML(R"HTML(
    <div style='transform-style: preserve-3d'>
      <div id='a' style='transform: translateZ(0); width: 50px; height: 60px'>
        <div style='transform-style: preserve-3d; width: 30px; height: 40px'>
          <div id='b'
              style='transform: translateZ(0); width: 10px; height: 20px'>
          </div>
        </div>
      </div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* a = GetLayoutObjectByElementId("a");
  const ObjectPaintProperties* a_properties =
      a->FirstFragment().PaintProperties();
  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  ASSERT_FALSE(a->StyleRef().Preserves3D());
  ASSERT_TRUE(a_properties->Transform() && b_properties->Transform());

  // #a should participate in a rendering context (due to its parent). Its
  // child does preserve 3D, but since #a does not, #a's rendering context is
  // not passed on to its children. Thus #b ends up in a separate rendering
  // context rooted at its parent.
  EXPECT_TRUE(a_properties->Transform()->HasRenderingContext());
  EXPECT_TRUE(b_properties->Transform()->HasRenderingContext());
  EXPECT_NE(a_properties->Transform()->RenderingContextId(),
            b_properties->Transform()->RenderingContextId());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 50, 60), a,
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 10, 20), b,
                          frame_view->GetLayoutView());
}

// Returns true if the first node has the second as an ancestor.
static bool NodeHasAncestor(const TransformPaintPropertyNode* node,
                            const TransformPaintPropertyNode* ancestor) {
  while (node) {
    if (node == ancestor)
      return true;
    node = node->Parent();
  }
  return false;
}

// Returns true if some node will flatten the transform due to |node| before it
// is inherited by |node| (including if node->flattensInheritedTransform()).
static bool SomeNodeFlattensTransform(
    const TransformPaintPropertyNode* node,
    const TransformPaintPropertyNode* ancestor) {
  while (node != ancestor) {
    if (node->FlattensInheritedTransform())
      return true;
    node = node->Parent();
  }
  return false;
}

TEST_P(PaintPropertyTreeBuilderTest, FlatTransformStylePropagatesToChildren) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #a {
        transform: translateZ(0);
        transform-style: flat;
        width: 30px;
        height: 40px;
      }
      #b {
        transform: translateZ(0);
        width: 10px;
        height: 10px;
      }
    </style>
    <div id='a'>
      <div id='b'></div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* a = GetLayoutObjectByElementId("a");
  LayoutObject* b = GetLayoutObjectByElementId("b");
  const auto* a_transform = a->FirstFragment().PaintProperties()->Transform();
  ASSERT_TRUE(a_transform);
  const auto* b_transform = b->FirstFragment().PaintProperties()->Transform();
  ASSERT_TRUE(b_transform);
  ASSERT_TRUE(NodeHasAncestor(b_transform, a_transform));

  // Some node must flatten the inherited transform from #a before it reaches
  // #b's transform.
  EXPECT_TRUE(SomeNodeFlattensTransform(b_transform, a_transform));
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 30, 40), a,
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 10, 10), b,
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest,
       Preserve3DTransformStylePropagatesToChildren) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #a {
        transform: translateZ(0);
        transform-style: preserve-3d;
        width: 30px;
        height: 40px;
      }
      #b {
        transform: translateZ(0);
        width: 10px;
        height: 10px;
      }
    </style>
    <div id='a'>
      <div id='b'></div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* a = GetLayoutObjectByElementId("a");
  LayoutObject* b = GetLayoutObjectByElementId("b");
  const auto* a_transform = a->FirstFragment().PaintProperties()->Transform();
  ASSERT_TRUE(a_transform);
  const auto* b_transform = b->FirstFragment().PaintProperties()->Transform();
  ASSERT_TRUE(b_transform);
  ASSERT_TRUE(NodeHasAncestor(b_transform, a_transform));

  // No node may flatten the inherited transform from #a before it reaches
  // #b's transform.
  EXPECT_FALSE(SomeNodeFlattensTransform(b_transform, a_transform));
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 30, 40), a,
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 10, 10), b,
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, PerspectiveIsNotFlattened) {
  // It's necessary to make nodes from the one that applies perspective to
  // ones that combine with it preserve 3D. Otherwise, the perspective doesn't
  // do anything.
  SetBodyInnerHTML(R"HTML(
    <div id='a' style='perspective: 800px; width: 30px; height: 40px'>
      <div id='b'
          style='transform: translateZ(0); width: 10px; height: 20px'></div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* a = GetLayoutObjectByElementId("a");
  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* a_properties =
      a->FirstFragment().PaintProperties();
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  const TransformPaintPropertyNode* a_perspective = a_properties->Perspective();
  ASSERT_TRUE(a_perspective);
  const TransformPaintPropertyNode* b_transform = b_properties->Transform();
  ASSERT_TRUE(b_transform);
  ASSERT_TRUE(NodeHasAncestor(b_transform, a_perspective));
  EXPECT_FALSE(SomeNodeFlattensTransform(b_transform, a_perspective));
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 30, 40), a,
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 10, 20), b,
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest,
       PerspectiveDoesNotEstablishRenderingContext) {
  // It's necessary to make nodes from the one that applies perspective to
  // ones that combine with it preserve 3D. Otherwise, the perspective doesn't
  // do anything.
  SetBodyInnerHTML(R"HTML(
    <div id='a' style='perspective: 800px; width: 30px; height: 40px'>
      <div id='b'
          style='transform: translateZ(0); width: 10px; height: 20px'></div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  LayoutObject* a = GetLayoutObjectByElementId("a");
  LayoutObject* b = GetLayoutObjectByElementId("b");
  const ObjectPaintProperties* a_properties =
      a->FirstFragment().PaintProperties();
  const ObjectPaintProperties* b_properties =
      b->FirstFragment().PaintProperties();
  const TransformPaintPropertyNode* a_perspective = a_properties->Perspective();
  ASSERT_TRUE(a_perspective);
  EXPECT_FALSE(a_perspective->HasRenderingContext());
  const TransformPaintPropertyNode* b_transform = b_properties->Transform();
  ASSERT_TRUE(b_transform);
  EXPECT_FALSE(b_transform->HasRenderingContext());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 30, 40), a,
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 10, 20), b,
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, CachedProperties) {
  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 0 }</style>
    <div id='a' style='transform: translate(33px, 44px); width: 50px;
        height: 60px'>
      <div id='b' style='transform: translate(55px, 66px); width: 30px;
          height: 40px'>
        <div id='c' style='transform: translate(77px, 88px); width: 10px;
            height: 20px'>C<div>
      </div>
    </div>
  )HTML");
  LocalFrameView* frame_view = GetDocument().View();

  Element* a = GetDocument().getElementById("a");
  const ObjectPaintProperties* a_properties =
      a->GetLayoutObject()->FirstFragment().PaintProperties();
  const TransformPaintPropertyNode* a_transform_node =
      a_properties->Transform();
  EXPECT_EQ(TransformationMatrix().Translate(33, 44),
            a_transform_node->Matrix());

  Element* b = GetDocument().getElementById("b");
  const ObjectPaintProperties* b_properties =
      b->GetLayoutObject()->FirstFragment().PaintProperties();
  const TransformPaintPropertyNode* b_transform_node =
      b_properties->Transform();
  EXPECT_EQ(TransformationMatrix().Translate(55, 66),
            b_transform_node->Matrix());

  Element* c = GetDocument().getElementById("c");
  const ObjectPaintProperties* c_properties =
      c->GetLayoutObject()->FirstFragment().PaintProperties();
  const TransformPaintPropertyNode* c_transform_node =
      c_properties->Transform();
  EXPECT_EQ(TransformationMatrix().Translate(77, 88),
            c_transform_node->Matrix());

  CHECK_EXACT_VISUAL_RECT(LayoutRect(33, 44, 50, 60), a->GetLayoutObject(),
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(88, 110, 30, 40), b->GetLayoutObject(),
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(165, 198, 10, 20), c->GetLayoutObject(),
                          frame_view->GetLayoutView());

  // Change transform of b. B's transform node should be a new node with the new
  // value, and a and c's transform nodes should be unchanged (with c's parent
  // adjusted).
  b->setAttribute(HTMLNames::styleAttr, "transform: translate(111px, 222px)");
  GetDocument().View()->UpdateAllLifecyclePhases();

  EXPECT_EQ(a_properties,
            a->GetLayoutObject()->FirstFragment().PaintProperties());
  EXPECT_EQ(a_transform_node, a_properties->Transform());

  EXPECT_EQ(b_properties,
            b->GetLayoutObject()->FirstFragment().PaintProperties());
  b_transform_node = b_properties->Transform();
  EXPECT_EQ(TransformationMatrix().Translate(111, 222),
            b_transform_node->Matrix());
  EXPECT_EQ(a_transform_node, b_transform_node->Parent()->Parent());

  EXPECT_EQ(c_properties,
            c->GetLayoutObject()->FirstFragment().PaintProperties());
  EXPECT_EQ(c_transform_node, c_properties->Transform());
  EXPECT_EQ(b_transform_node, c_transform_node->Parent()->Parent());

  CHECK_EXACT_VISUAL_RECT(LayoutRect(33, 44, 50, 60), a->GetLayoutObject(),
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(144, 266, 50, 20), b->GetLayoutObject(),
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(221, 354, 10, 20), c->GetLayoutObject(),
                          frame_view->GetLayoutView());

  // Remove transform from b. B's transform node should be removed from the
  // tree, and a and c's transform nodes should be unchanged (with c's parent
  // adjusted).
  b->setAttribute(HTMLNames::styleAttr, "");
  GetDocument().View()->UpdateAllLifecyclePhases();

  EXPECT_EQ(a_properties,
            a->GetLayoutObject()->FirstFragment().PaintProperties());
  EXPECT_EQ(a_transform_node, a_properties->Transform());

  EXPECT_EQ(nullptr, b->GetLayoutObject()->FirstFragment().PaintProperties());

  EXPECT_EQ(c_properties,
            c->GetLayoutObject()->FirstFragment().PaintProperties());
  EXPECT_EQ(c_transform_node, c_properties->Transform());
  EXPECT_EQ(a_transform_node, c_transform_node->Parent()->Parent());

  CHECK_EXACT_VISUAL_RECT(LayoutRect(33, 44, 50, 60), a->GetLayoutObject(),
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(33, 44, 50, 20), b->GetLayoutObject(),
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(110, 132, 10, 20), c->GetLayoutObject(),
                          frame_view->GetLayoutView());

  // Re-add transform to b. B's transform node should be inserted into the tree,
  // and a and c's transform nodes should be unchanged (with c's parent
  // adjusted).
  b->setAttribute(HTMLNames::styleAttr, "transform: translate(4px, 5px)");
  GetDocument().View()->UpdateAllLifecyclePhases();

  EXPECT_EQ(a_properties,
            a->GetLayoutObject()->FirstFragment().PaintProperties());
  EXPECT_EQ(a_transform_node, a_properties->Transform());

  b_properties = b->GetLayoutObject()->FirstFragment().PaintProperties();
  EXPECT_EQ(b_properties,
            b->GetLayoutObject()->FirstFragment().PaintProperties());
  b_transform_node = b_properties->Transform();
  EXPECT_EQ(TransformationMatrix().Translate(4, 5), b_transform_node->Matrix());
  EXPECT_EQ(a_transform_node, b_transform_node->Parent()->Parent());

  EXPECT_EQ(c_properties,
            c->GetLayoutObject()->FirstFragment().PaintProperties());
  EXPECT_EQ(c_transform_node, c_properties->Transform());
  EXPECT_EQ(b_transform_node, c_transform_node->Parent()->Parent());

  CHECK_EXACT_VISUAL_RECT(LayoutRect(33, 44, 50, 60), a->GetLayoutObject(),
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(37, 49, 50, 20), b->GetLayoutObject(),
                          frame_view->GetLayoutView());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(114, 137, 10, 20), c->GetLayoutObject(),
                          frame_view->GetLayoutView());
}

TEST_P(PaintPropertyTreeBuilderTest, OverflowClipContentsTreeState) {
  // This test verifies the tree builder correctly computes and records the
  // property tree context for a (pseudo) stacking context that is scrolled by a
  // containing block that is not one of the painting ancestors.
  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 20px 30px; }</style>
    <div id='clipper'
        style='overflow: hidden; width: 400px; height: 300px;'>
      <div id='child'
          style='position: relative; width: 500px; height: 600px;'></div>
    </div>
  )HTML");

  LayoutBoxModelObject* clipper =
      ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper"));
  const ObjectPaintProperties* clip_properties =
      clipper->FirstFragment().PaintProperties();
  LayoutObject* child = GetLayoutObjectByElementId("child");

  // No scroll translation because the document does not scroll (not enough
  // content).
  EXPECT_TRUE(!FrameScrollTranslation());
  EXPECT_EQ(FramePreTranslation(),
            clipper->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_EQ(FrameContentClip(),
            clipper->FirstFragment().LocalBorderBoxProperties()->Clip());

  auto contents_properties = clipper->FirstFragment().ContentsProperties();
  EXPECT_EQ(LayoutPoint(30, 20), clipper->FirstFragment().PaintOffset());
  EXPECT_EQ(FramePreTranslation(), contents_properties.Transform());
  EXPECT_EQ(clip_properties->OverflowClip(), contents_properties.Clip());

  EXPECT_EQ(FramePreTranslation(),
            child->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_EQ(clip_properties->OverflowClip(),
            child->FirstFragment().LocalBorderBoxProperties()->Clip());

  EXPECT_NE(nullptr,
            child->FirstFragment().LocalBorderBoxProperties()->Effect());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 500, 600), child, clipper);
}

TEST_P(PaintPropertyTreeBuilderTest, ContainsPaintContentsTreeState) {
  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 20px 30px; }</style>
    <div id='clipper'
        style='contain: paint; width: 300px; height: 200px;'>
      <div id='child'
          style='position: relative; width: 400px; height: 500px;'></div>
    </div>
  )HTML");

  LayoutBoxModelObject* clipper =
      ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper"));
  const ObjectPaintProperties* clip_properties =
      clipper->FirstFragment().PaintProperties();
  LayoutObject* child = GetLayoutObjectByElementId("child");

  // No scroll translation because the document does not scroll (not enough
  // content).
  EXPECT_TRUE(!FrameScrollTranslation());
  EXPECT_EQ(FramePreTranslation(),
            clipper->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_EQ(FrameContentClip(),
            clipper->FirstFragment().LocalBorderBoxProperties()->Clip());

  auto contents_properties = clipper->FirstFragment().ContentsProperties();
  EXPECT_EQ(LayoutPoint(30, 20), clipper->FirstFragment().PaintOffset());
  EXPECT_EQ(FramePreTranslation(), contents_properties.Transform());
  EXPECT_EQ(clip_properties->OverflowClip(), contents_properties.Clip());

  EXPECT_EQ(FramePreTranslation(),
            child->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_EQ(clip_properties->OverflowClip(),
            child->FirstFragment().LocalBorderBoxProperties()->Clip());

  EXPECT_NE(nullptr,
            child->FirstFragment().LocalBorderBoxProperties()->Effect());
  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 400, 500), child, clipper);
}

TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollContentsTreeState) {
  // This test verifies the tree builder correctly computes and records the
  // property tree context for a (pseudo) stacking context that is scrolled by a
  // containing block that is not one of the painting ancestors.
  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 20px 30px; }</style>
    <div id='clipper' style='overflow:scroll; width:400px; height:300px;'>
      <div id='child'
          style='position:relative; width:500px; height: 600px;'></div>
      <div style='width: 200px; height: 10000px'></div>
    </div>
    <div id='forceScroll' style='height: 4000px;'></div>
  )HTML");

  Element* clipper_element = GetDocument().getElementById("clipper");
  clipper_element->scrollTo(1, 2);

  LayoutBoxModelObject* clipper =
      ToLayoutBoxModelObject(clipper_element->GetLayoutObject());
  const ObjectPaintProperties* clip_properties =
      clipper->FirstFragment().PaintProperties();
  LayoutObject* child = GetLayoutObjectByElementId("child");

  EXPECT_EQ(FrameScrollTranslation(), clipper->FirstFragment()
                                          .LocalBorderBoxProperties()
                                          ->Transform()
                                          ->Parent());
  EXPECT_EQ(clip_properties->PaintOffsetTranslation(),
            clipper->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_EQ(FrameContentClip(),
            clipper->FirstFragment().LocalBorderBoxProperties()->Clip());

  auto contents_properties = clipper->FirstFragment().ContentsProperties();
  EXPECT_EQ(
      FloatSize(30, 20),
      clip_properties->PaintOffsetTranslation()->Matrix().To2DTranslation());
  EXPECT_EQ(LayoutPoint(0, 0), clipper->FirstFragment().PaintOffset());
  EXPECT_EQ(clip_properties->ScrollTranslation(),
            contents_properties.Transform());
  EXPECT_EQ(clip_properties->OverflowClip(), contents_properties.Clip());

  EXPECT_EQ(clip_properties->ScrollTranslation(),
            child->FirstFragment().LocalBorderBoxProperties()->Transform());
  EXPECT_EQ(clip_properties->OverflowClip(),
            child->FirstFragment().LocalBorderBoxProperties()->Clip());

  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 500, 600), child, clipper);
}

TEST_P(PaintPropertyTreeBuilderTest, OverflowScrollWithRoundedRect) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * { margin: 0; }
      ::-webkit-scrollbar {
        width: 13px;
        height: 13px;
      }
      #roundedBox {
        width: 200px;
        height: 200px;
        border-radius: 100px;
        background-color: red;
        border: 50px solid green;
        overflow: scroll;
      }
      #roundedBoxChild {
        width: 200px;
        height: 200px;
        background-color: orange;
      }
    </style>
    <div id='roundedBox'>
      <div id='roundedBoxChild'></div>
    </div>
  )HTML");

  LayoutObject& rounded_box = *GetLayoutObjectByElementId("roundedBox");
  const ObjectPaintProperties* rounded_box_properties =
      rounded_box.FirstFragment().PaintProperties();
  EXPECT_EQ(
      FloatRoundedRect(FloatRect(50, 50, 200, 200), FloatSize(50, 50),
                       FloatSize(50, 50), FloatSize(50, 50), FloatSize(50, 50)),
      rounded_box_properties->InnerBorderRadiusClip()->ClipRect());

  // Unlike the inner border radius clip, the overflow clip is inset by the
  // scrollbars (13px).
  EXPECT_EQ(FloatRoundedRect(50, 50, 187, 187),
            rounded_box_properties->OverflowClip()->ClipRect());
  EXPECT_EQ(FrameContentClip(),
            rounded_box_properties->InnerBorderRadiusClip()->Parent());
  EXPECT_EQ(rounded_box_properties->InnerBorderRadiusClip(),
            rounded_box_properties->OverflowClip()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, CssClipContentsTreeState) {
  // This test verifies the tree builder correctly computes and records the
  // property tree context for a (pseudo) stacking context that is scrolled by a
  // containing block that is not one of the painting ancestors.
  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 20px 30px; }</style>
    <div id='clipper' style='position: absolute;
        clip: rect(10px, 80px, 70px, 40px); width:300px; height:200px;'>
      <div id='child' style='position:relative; width:400px; height: 500px;'>
      </div>
    </div>
  )HTML");

  LayoutBoxModelObject* clipper =
      ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper"));
  const ObjectPaintProperties* clip_properties =
      clipper->FirstFragment().PaintProperties();
  LayoutObject* child = GetLayoutObjectByElementId("child");

  // No scroll translation because the document does not scroll (not enough
  // content).
  EXPECT_TRUE(!FrameScrollTranslation());
  EXPECT_EQ(FramePreTranslation(),
            clipper->FirstFragment().LocalBorderBoxProperties()->Transform());
  // CSS clip on an element causes it to clip itself, not just descendants.
  EXPECT_EQ(clip_properties->CssClip(),
            clipper->FirstFragment().LocalBorderBoxProperties()->Clip());

  auto contents_properties = clipper->FirstFragment().ContentsProperties();
  EXPECT_EQ(LayoutPoint(30, 20), clipper->FirstFragment().PaintOffset());
  EXPECT_EQ(FramePreTranslation(), contents_properties.Transform());
  EXPECT_EQ(clip_properties->CssClip(), contents_properties.Clip());

  CHECK_EXACT_VISUAL_RECT(LayoutRect(0, 0, 400, 500), child, clipper);
}

TEST_P(PaintPropertyTreeBuilderTest,
       SvgLocalToBorderBoxTransformContentsTreeState) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 20px 30px;
      }
      svg {
        position: absolute;
      }
      rect {
        transform: translate(100px, 100px);
      }
    </style>
    <svg id='svgWithViewBox' width='100px' height='100px'
        viewBox='50 50 100 100'>
      <rect id='rect' width='100px' height='100px' />
    </svg>
  )HTML");

  LayoutObject& svg_with_view_box =
      *GetLayoutObjectByElementId("svgWithViewBox");
  EXPECT_EQ(FramePreTranslation(), svg_with_view_box.FirstFragment()
                                       .LocalBorderBoxProperties()
                                       ->Transform()
                                       ->Parent());
  EXPECT_EQ(FloatSize(30, 20), svg_with_view_box.FirstFragment()
                                   .LocalBorderBoxProperties()
                                   ->Transform()
                                   ->Matrix()
                                   .To2DTranslation());

  EXPECT_EQ(LayoutPoint(0, 0), svg_with_view_box.FirstFragment().PaintOffset());
  auto contents_properties =
      svg_with_view_box.FirstFragment().ContentsProperties();
  EXPECT_EQ(svg_with_view_box.FirstFragment()
                .PaintProperties()
                ->PaintOffsetTranslation(),
            contents_properties.Transform());
  EXPECT_EQ(FramePreTranslation(), contents_properties.Transform()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, OverflowHiddenScrollProperties) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 0px;
      }
      #overflowHidden {
        overflow: hidden;
        width: 5px;
        height: 3px;
      }
      .forceScroll {
        height: 79px;
      }
    </style>
    <div id='overflowHidden'>
      <div class='forceScroll'></div>
    </div>
  )HTML");

  Element* overflow_hidden = GetDocument().getElementById("overflowHidden");
  overflow_hidden->setScrollTop(37);

  GetDocument().View()->UpdateAllLifecyclePhases();

  const ObjectPaintProperties* overflow_hidden_scroll_properties =
      overflow_hidden->GetLayoutObject()->FirstFragment().PaintProperties();

  // Because the overflow hidden does not scroll and only has a static scroll
  // offset, there should be a scroll translation node but no scroll node.
  auto* scroll_translation =
      overflow_hidden_scroll_properties->ScrollTranslation();
  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
            scroll_translation->Matrix());
  EXPECT_EQ(nullptr, scroll_translation->ScrollNode());
  EXPECT_EQ(nullptr, overflow_hidden_scroll_properties->Scroll());
}

TEST_P(PaintPropertyTreeBuilderTest, FrameOverflowHiddenScrollProperties) {
  SetBodyInnerHTML(R"HTML(
    <style>
      html {
        margin: 0px;
        overflow: hidden;
        width: 300px;
        height: 300px;
      }
      .forceScroll {
        height: 5000px;
      }
    </style>
    <div class='forceScroll'></div>
  )HTML");

  GetDocument().domWindow()->scrollTo(0, 37);

  GetDocument().View()->UpdateAllLifecyclePhases();

  // Because the overflow hidden does not scroll and only has a static scroll
  // offset, there should be a scroll translation node but no scroll node.
  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
            FrameScrollTranslation()->Matrix());
  EXPECT_EQ(nullptr, FrameScrollTranslation()->ScrollNode());
  EXPECT_EQ(nullptr, FrameScroll());
}

TEST_P(PaintPropertyTreeBuilderTest, NestedScrollProperties) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * {
        margin: 0px;
      }
      #overflowA {
        overflow: scroll;
        width: 5px;
        height: 3px;
      }
      #overflowB {
        overflow: scroll;
        width: 9px;
        height: 7px;
      }
      .forceScroll {
        height: 100px;
      }
    </style>
    <div id='overflowA'>
      <div id='overflowB'>
        <div class='forceScroll'></div>
      </div>
      <div class='forceScroll'></div>
    </div>
  )HTML");

  Element* overflow_a = GetDocument().getElementById("overflowA");
  overflow_a->setScrollTop(37);
  Element* overflow_b = GetDocument().getElementById("overflowB");
  overflow_b->setScrollTop(41);

  GetDocument().View()->UpdateAllLifecyclePhases();

  const ObjectPaintProperties* overflow_a_scroll_properties =
      overflow_a->GetLayoutObject()->FirstFragment().PaintProperties();
  // Because the frameView is does not scroll, overflowA's scroll should be
  // under the root.
  auto* scroll_a_translation =
      overflow_a_scroll_properties->ScrollTranslation();
  auto* overflow_a_scroll_node = scroll_a_translation->ScrollNode();
  EXPECT_TRUE(overflow_a_scroll_node->Parent()->IsRoot());
  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
            scroll_a_translation->Matrix());
  EXPECT_EQ(IntRect(0, 0, 5, 3), overflow_a_scroll_node->ContainerRect());
  // 107 is the forceScroll element plus the height of the overflow scroll child
  // (overflowB).
  EXPECT_EQ(IntRect(0, 0, 9, 107), overflow_a_scroll_node->ContentsRect());
  EXPECT_TRUE(overflow_a_scroll_node->UserScrollableHorizontal());
  EXPECT_TRUE(overflow_a_scroll_node->UserScrollableVertical());

  const ObjectPaintProperties* overflow_b_scroll_properties =
      overflow_b->GetLayoutObject()->FirstFragment().PaintProperties();
  // The overflow child's scroll node should be a child of the parent's
  // (overflowA) scroll node.
  auto* scroll_b_translation =
      overflow_b_scroll_properties->ScrollTranslation();
  auto* overflow_b_scroll_node = scroll_b_translation->ScrollNode();
  EXPECT_EQ(overflow_a_scroll_node, overflow_b_scroll_node->Parent());
  EXPECT_EQ(TransformationMatrix().Translate(0, -41),
            scroll_b_translation->Matrix());
  EXPECT_EQ(IntRect(0, 0, 9, 7), overflow_b_scroll_node->ContainerRect());
  EXPECT_EQ(IntRect(0, 0, 9, 100), overflow_b_scroll_node->ContentsRect());
  EXPECT_TRUE(overflow_b_scroll_node->UserScrollableHorizontal());
  EXPECT_TRUE(overflow_b_scroll_node->UserScrollableVertical());
}

TEST_P(PaintPropertyTreeBuilderTest, PositionedScrollerIsNotNested) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * {
        margin: 0px;
      }
      #overflow {
        overflow: scroll;
        width: 5px;
        height: 3px;
      }
      #absposOverflow {
        position: absolute;
        top: 0;
        left: 0;
        overflow: scroll;
        width: 9px;
        height: 7px;
      }
      #fixedOverflow {
        position: fixed;
        top: 0;
        left: 0;
        overflow: scroll;
        width: 13px;
        height: 11px;
      }
      .forceScroll {
        height: 4000px;
      }
    </style>
    <div id='overflow'>
      <div id='absposOverflow'>
        <div class='forceScroll'></div>
      </div>
      <div id='fixedOverflow'>
        <div class='forceScroll'></div>
      </div>
      <div class='forceScroll'></div>
    </div>
    <div class='forceScroll'></div>
  )HTML");

  Element* overflow = GetDocument().getElementById("overflow");
  overflow->setScrollTop(37);
  Element* abspos_overflow = GetDocument().getElementById("absposOverflow");
  abspos_overflow->setScrollTop(41);
  Element* fixed_overflow = GetDocument().getElementById("fixedOverflow");
  fixed_overflow->setScrollTop(43);

  GetDocument().View()->UpdateAllLifecyclePhases();

  // The frame should scroll due to the "forceScroll" element.
  EXPECT_NE(nullptr, FrameScroll());

  const ObjectPaintProperties* overflow_scroll_properties =
      overflow->GetLayoutObject()->FirstFragment().PaintProperties();
  auto* scroll_translation = overflow_scroll_properties->ScrollTranslation();
  auto* overflow_scroll_node = scroll_translation->ScrollNode();
  EXPECT_EQ(
      FrameScroll(),
      overflow_scroll_properties->ScrollTranslation()->ScrollNode()->Parent());
  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
            scroll_translation->Matrix());
  EXPECT_EQ(IntRect(0, 0, 5, 3), overflow_scroll_node->ContainerRect());
  // The height should be 4000px because the (dom-order) overflow children are
  // positioned and do not contribute to the height. Only the 4000px
  // "forceScroll" height is present.
  EXPECT_EQ(IntRect(0, 0, 5, 4000), overflow_scroll_node->ContentsRect());

  const ObjectPaintProperties* abspos_overflow_scroll_properties =
      abspos_overflow->GetLayoutObject()->FirstFragment().PaintProperties();
  auto* abspos_scroll_translation =
      abspos_overflow_scroll_properties->ScrollTranslation();
  auto* abspos_overflow_scroll_node = abspos_scroll_translation->ScrollNode();
  // The absolute position overflow scroll node is parented under the frame, not
  // the dom-order parent.
  EXPECT_EQ(FrameScroll(), abspos_overflow_scroll_node->Parent());
  EXPECT_EQ(TransformationMatrix().Translate(0, -41),
            abspos_scroll_translation->Matrix());
  EXPECT_EQ(IntRect(0, 0, 9, 7), abspos_overflow_scroll_node->ContainerRect());
  EXPECT_EQ(IntRect(0, 0, 9, 4000),
            abspos_overflow_scroll_node->ContentsRect());

  const ObjectPaintProperties* fixed_overflow_scroll_properties =
      fixed_overflow->GetLayoutObject()->FirstFragment().PaintProperties();
  auto* fixed_scroll_translation =
      fixed_overflow_scroll_properties->ScrollTranslation();
  auto* fixed_overflow_scroll_node = fixed_scroll_translation->ScrollNode();
  // The fixed position overflow scroll node is parented under the root, not the
  // dom-order parent or frame's scroll.
  EXPECT_TRUE(fixed_overflow_scroll_node->Parent()->IsRoot());
  EXPECT_EQ(TransformationMatrix().Translate(0, -43),
            fixed_scroll_translation->Matrix());
  EXPECT_EQ(IntRect(0, 0, 13, 11), fixed_overflow_scroll_node->ContainerRect());
  EXPECT_EQ(IntRect(0, 0, 13, 4000),
            fixed_overflow_scroll_node->ContentsRect());
}

TEST_P(PaintPropertyTreeBuilderTest, NestedPositionedScrollProperties) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * {
        margin: 0px;
      }
      #overflowA {
        position: absolute;
        top: 7px;
        left: 11px;
        overflow: scroll;
        width: 20px;
        height: 20px;
      }
      #overflowB {
        position: absolute;
        top: 1px;
        left: 3px;
        overflow: scroll;
        width: 5px;
        height: 3px;
      }
      .forceScroll {
        height: 100px;
      }
    </style>
    <div id='overflowA'>
      <div id='overflowB'>
        <div class='forceScroll'></div>
      </div>
      <div class='forceScroll'></div>
    </div>
  )HTML");

  Element* overflow_a = GetDocument().getElementById("overflowA");
  overflow_a->setScrollTop(37);
  Element* overflow_b = GetDocument().getElementById("overflowB");
  overflow_b->setScrollTop(41);

  GetDocument().View()->UpdateAllLifecyclePhases();

  const ObjectPaintProperties* overflow_a_scroll_properties =
      overflow_a->GetLayoutObject()->FirstFragment().PaintProperties();
  // Because the frameView is does not scroll, overflowA's scroll should be
  // under the root.
  auto* scroll_a_translation =
      overflow_a_scroll_properties->ScrollTranslation();
  auto* overflow_a_scroll_node = scroll_a_translation->ScrollNode();
  EXPECT_TRUE(overflow_a_scroll_node->Parent()->IsRoot());
  EXPECT_EQ(TransformationMatrix().Translate(0, -37),
            scroll_a_translation->Matrix());
  EXPECT_EQ(IntRect(0, 0, 20, 20), overflow_a_scroll_node->ContainerRect());
  // 100 is the forceScroll element's height because the overflow child does not
  // contribute to the height.
  EXPECT_EQ(IntRect(0, 0, 20, 100), overflow_a_scroll_node->ContentsRect());
  EXPECT_TRUE(overflow_a_scroll_node->UserScrollableHorizontal());
  EXPECT_TRUE(overflow_a_scroll_node->UserScrollableVertical());

  const ObjectPaintProperties* overflow_b_scroll_properties =
      overflow_b->GetLayoutObject()->FirstFragment().PaintProperties();
  // The overflow child's scroll node should be a child of the parent's
  // (overflowA) scroll node.
  auto* scroll_b_translation =
      overflow_b_scroll_properties->ScrollTranslation();
  auto* overflow_b_scroll_node = scroll_b_translation->ScrollNode();
  EXPECT_EQ(overflow_a_scroll_node, overflow_b_scroll_node->Parent());
  EXPECT_EQ(TransformationMatrix().Translate(0, -41),
            scroll_b_translation->Matrix());
  EXPECT_EQ(IntRect(0, 0, 5, 3), overflow_b_scroll_node->ContainerRect());
  EXPECT_EQ(IntRect(0, 0, 5, 100), overflow_b_scroll_node->ContentsRect());
  EXPECT_TRUE(overflow_b_scroll_node->UserScrollableHorizontal());
  EXPECT_TRUE(overflow_b_scroll_node->UserScrollableVertical());
}

TEST_P(PaintPropertyTreeBuilderTest, SVGRootClip) {
  SetBodyInnerHTML(R"HTML(
    <svg id='svg' width='100px' height='100px'>
      <rect width='200' height='200' fill='red' />
    </svg>
  )HTML");

  const ClipPaintPropertyNode* clip = GetLayoutObjectByElementId("svg")
                                          ->FirstFragment()
                                          .PaintProperties()
                                          ->OverflowClip();
  EXPECT_EQ(FrameContentClip(), clip->Parent());
  EXPECT_EQ(FloatSize(8, 8), GetLayoutObjectByElementId("svg")
                                 ->FirstFragment()
                                 .PaintProperties()
                                 ->PaintOffsetTranslation()
                                 ->Matrix()
                                 .To2DTranslation());
  EXPECT_EQ(FloatRoundedRect(0, 0, 100, 100), clip->ClipRect());
}

TEST_P(PaintPropertyTreeBuilderTest, SVGRootNoClip) {
  SetBodyInnerHTML(R"HTML(
    <svg id='svg' xmlns='http://www.w3.org/2000/svg' width='100px'
        height='100px' style='overflow: visible'>
      <rect width='200' height='200' fill='red' />
    </svg>
  )HTML");

  EXPECT_FALSE(GetLayoutObjectByElementId("svg")
                   ->FirstFragment()
                   .PaintProperties()
                   ->OverflowClip());
}

TEST_P(PaintPropertyTreeBuilderTest, MainThreadScrollReasonsWithoutScrolling) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #overflow {
        overflow: scroll;
        width: 100px;
        height: 100px;
      }
      .backgroundAttachmentFixed {
        background-image: url('foo');
        background-attachment: fixed;
        width: 10px;
        height: 10px;
      }
      .forceScroll {
        height: 4000px;
      }
    </style>
    <div id='overflow'>
      <div class='backgroundAttachmentFixed'></div>
    </div>
    <div class='forceScroll'></div>
  )HTML");
  Element* overflow = GetDocument().getElementById("overflow");
  EXPECT_TRUE(FrameScroll()->HasBackgroundAttachmentFixedDescendants());
  // No scroll node is needed.
  EXPECT_EQ(overflow->GetLayoutObject()
                ->FirstFragment()
                .PaintProperties()
                ->ScrollTranslation(),
            nullptr);
}

static unsigned NumFragments(LayoutObject* obj) {
  unsigned count = 0;
  auto* fragment = &obj->FirstFragment();
  while (fragment) {
    count++;
    fragment = fragment->NextFragment();
  }
  return count;
}

static const FragmentData& FragmentAt(LayoutObject* obj, unsigned count) {
  auto* fragment = &obj->FirstFragment();
  while (count > 0) {
    count--;
    fragment = fragment->NextFragment();
  }
  return *fragment;
}

TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetsUnderMultiColumnScrolled) {
  SetBodyInnerHTML(R"HTML(
    <!doctype HTML>
    <div style='columns: 1;'>
       <div id=scroller style='height: 400px; width: 400px; overflow: auto;'>
         <div style='width: 50px; height: 1000px; background: lightgray'>
       </div>
     </div>
    </div>
  )HTML");

  LayoutObject* scroller = GetLayoutObjectByElementId("scroller");
  ToLayoutBoxModelObject(scroller)->Layer()->GetScrollableArea()->ScrollBy(
      ScrollOffset(0, 300), kUserScroll);
  GetDocument().View()->UpdateAllLifecyclePhases();

  EXPECT_EQ(FloatSize(8, 8), scroller->FirstFragment()
                                 .PaintProperties()
                                 ->PaintOffsetTranslation()
                                 ->Matrix()
                                 .To2DTranslation());
}

TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetsUnderMultiColumnWithOutline) {
  SetBodyInnerHTML(R"HTML(
    <div style='columns: 2; height: 100px'>
      <div id=target1 style='outline: 2px solid black; width: 100px;
          height: 100px'></div>
      <div id=target2 style='outline: 2px solid black; width: 100px;
          height: 100px'></div>
    </div>
  )HTML");

  LayoutObject* target1 = GetLayoutObjectByElementId("target1");

  // Outline does not affect paint offset, since it is positioned to the
  // top-left of the border box.
  EXPECT_EQ(LayoutPoint(8, 8), target1->FirstFragment().PaintOffset());
  // |target1| is only in the first column.
  EXPECT_FALSE(target1->FirstFragment().NextFragment());

  LayoutObject* target2 = GetLayoutObjectByElementId("target2");
  EXPECT_EQ(LayoutPoint(LayoutUnit(400.5f), LayoutUnit(8.0f)),
            target2->FirstFragment().PaintOffset());
  // |target2| is only in the second column.
  EXPECT_FALSE(target2->FirstFragment().NextFragment());
}

TEST_P(PaintPropertyTreeBuilderTest,
       PaintOffsetUnderMulticolumnScrollFixedPos) {
  SetBodyInnerHTML(R"HTML(
    <div id=fixed style='position: fixed; columns: 2'>
      <div style='width: 50px; height: 20px; background: lightblue'></div>
      <div style='width: 50px; height: 20px; background: lightgray'></div>
    </div>
    <div style='height: 2000px'></div>
  )HTML");
  LayoutObject* fixed = GetLayoutObjectByElementId("fixed");
  LayoutObject* multicol_container = fixed->SlowFirstChild();

  ASSERT_TRUE(multicol_container->FirstFragment().NextFragment());
  ASSERT_FALSE(
      multicol_container->FirstFragment().NextFragment()->NextFragment());
  EXPECT_EQ(LayoutPoint(8, 8),
            multicol_container->FirstFragment().PaintOffset());
  EXPECT_EQ(LayoutPoint(59, -12),
            multicol_container->FirstFragment().NextFragment()->PaintOffset());

  GetDocument().View()->LayoutViewportScrollableArea()->ScrollBy(
      ScrollOffset(0, 25), kUserScroll);
  GetDocument().View()->UpdateAllLifecyclePhases();

  ASSERT_TRUE(multicol_container->FirstFragment().NextFragment());
  ASSERT_FALSE(
      multicol_container->FirstFragment().NextFragment()->NextFragment());
  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() ||
      !RuntimeEnabledFeatures::RootLayerScrollingEnabled()) {
    EXPECT_EQ(LayoutPoint(8, 8),
              multicol_container->FirstFragment().PaintOffset());
    EXPECT_EQ(
        LayoutPoint(59, -12),
        multicol_container->FirstFragment().NextFragment()->PaintOffset());
  } else {
    // TODO(crbug.com/793051): The paint offsets are incorrect.
    EXPECT_EQ(LayoutPoint(8, 33),
              multicol_container->FirstFragment().PaintOffset());
    EXPECT_EQ(
        LayoutPoint(59, 13),
        multicol_container->FirstFragment().NextFragment()->PaintOffset());
  }
}

TEST_P(PaintPropertyTreeBuilderTest, PaintOffsetsUnderMultiColumn) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body { margin: 0; }
      .space { height: 30px; }
      .abs { position: absolute; width: 20px; height: 20px; }
    </style>
    <div style='columns:2; width: 200px; column-gap: 0'>
      <div id=relpos style='position: relative'>
        <div id=space1 class=space></div>
        <div id=space2 class=space></div>
        <div id=spanner style='column-span: all'>
          <div id=normal style='height: 50px'></div>
          <div id=top-left class=abs style='top: 0; left: 0'></div>
          <div id=bottom-right class=abs style='bottom: 0; right: 0'></div>
        </div>
        <div id=space3 class=space></div>
        <div id=space4 class=space></div>
      </div>
    </div>
  )HTML");

  LayoutObject* relpos = GetLayoutObjectByElementId("relpos");
  EXPECT_EQ(4u, NumFragments(relpos));
  EXPECT_EQ(LayoutPoint(0, 0), FragmentAt(relpos, 0).PaintOffset());
  EXPECT_EQ(LayoutPoint(0, 0), FragmentAt(relpos, 0).PaginationOffset());
  EXPECT_EQ(FloatRect(-1000000, -1000000, 1000100, 1000030),
            FragmentAt(relpos, 0)
                .PaintProperties()
                ->FragmentClip()
                ->ClipRect()
                .Rect());

  EXPECT_EQ(LayoutPoint(100, -30), FragmentAt(relpos, 1).PaintOffset());
  EXPECT_EQ(LayoutPoint(100, -30), FragmentAt(relpos, 1).PaginationOffset());
  EXPECT_EQ(FloatRect(100, 0, 1000000, 30), FragmentAt(relpos, 1)
                                                .PaintProperties()
                                                ->FragmentClip()
                                                ->ClipRect()
                                                .Rect());

  EXPECT_EQ(LayoutPoint(0, 20), FragmentAt(relpos, 2).PaintOffset());
  EXPECT_EQ(LayoutPoint(0, 20), FragmentAt(relpos, 2).PaginationOffset());
  EXPECT_EQ(FloatRect(-1000000, 80, 1000100, 30), FragmentAt(relpos, 2)
                                                      .PaintProperties()
                                                      ->FragmentClip()
                                                      ->ClipRect()
                                                      .Rect());

  EXPECT_EQ(LayoutPoint(100, -10), FragmentAt(relpos, 3).PaintOffset());
  EXPECT_EQ(LayoutPoint(100, -10), FragmentAt(relpos, 3).PaginationOffset());
  EXPECT_EQ(FloatRect(100, 80, 1000000, 999910), FragmentAt(relpos, 3)
                                                     .PaintProperties()
                                                     ->FragmentClip()
                                                     ->ClipRect()
                                                     .Rect());

  LayoutObject* flowthread = GetLayoutObjectByElementId("relpos")->Parent();
  EXPECT_EQ(4u, NumFragments(flowthread));
  EXPECT_EQ(LayoutPoint(0, 0), FragmentAt(flowthread, 0).PaintOffset());
  EXPECT_EQ(LayoutPoint(0, 0), FragmentAt(flowthread, 0).PaginationOffset());
  EXPECT_EQ(
      FragmentAt(flowthread, 0).PaintProperties()->FragmentClip()->ClipRect(),
      FragmentAt(relpos, 0).PaintProperties()->FragmentClip()->ClipRect());

  EXPECT_EQ(LayoutPoint(100, -30), FragmentAt(flowthread, 1).PaintOffset());
  EXPECT_EQ(LayoutPoint(100, -30),
            FragmentAt(flowthread, 1).PaginationOffset());
  EXPECT_EQ(
      FragmentAt(flowthread, 1).PaintProperties()->FragmentClip()->ClipRect(),
      FragmentAt(relpos, 1).PaintProperties()->FragmentClip()->ClipRect());

  EXPECT_EQ(LayoutPoint(0, 20), FragmentAt(flowthread, 2).PaintOffset());
  EXPECT_EQ(LayoutPoint(0, 20), FragmentAt(flowthread, 2).PaginationOffset());
  EXPECT_EQ(
      FragmentAt(flowthread, 2).PaintProperties()->FragmentClip()->ClipRect(),
      FragmentAt(relpos, 2).PaintProperties()->FragmentClip()->ClipRect());

  EXPECT_EQ(LayoutPoint(100, -10), FragmentAt(flowthread, 3).PaintOffset());
  EXPECT_EQ(LayoutPoint(100, -10),
            FragmentAt(flowthread, 3).PaginationOffset());
  EXPECT_EQ(
      FragmentAt(flowthread, 3).PaintProperties()->FragmentClip()->ClipRect(),
      FragmentAt(relpos, 3).PaintProperties()->FragmentClip()->ClipRect());

  // Above the spanner.
  // Column 1.
  EXPECT_EQ(
      LayoutPoint(),
      GetLayoutObjectByElementId("space1")->FirstFragment().PaintOffset());
  EXPECT_EQ(
      LayoutPoint(100, 0),
      GetLayoutObjectByElementId("space2")->FirstFragment().PaintOffset());

  // The spanner's normal flow.
  EXPECT_EQ(
      LayoutPoint(0, 30),
      GetLayoutObjectByElementId("spanner")->FirstFragment().PaintOffset());
  EXPECT_EQ(
      LayoutPoint(0, 30),
      GetLayoutObjectByElementId("normal")->FirstFragment().PaintOffset());

  // Below the spanner.
  EXPECT_EQ(
      LayoutPoint(0, 80),
      GetLayoutObjectByElementId("space3")->FirstFragment().PaintOffset());
  EXPECT_EQ(
      LayoutPoint(100, 80),
      GetLayoutObjectByElementId("space4")->FirstFragment().PaintOffset());

  // Out-of-flow positioned descendants of the spanner. They are laid out in
  // the relative-position container.

  // "top-left" should be aligned to the top-left corner of space1.
  EXPECT_EQ(
      LayoutPoint(0, 0),
      GetLayoutObjectByElementId("top-left")->FirstFragment().PaintOffset());

  // "bottom-right" should be aligned to the bottom-right corner of space4.
  EXPECT_EQ(LayoutPoint(180, 90), GetLayoutObjectByElementId("bottom-right")
                                      ->FirstFragment()
                                      .PaintOffset());
}

TEST_P(PaintPropertyTreeBuilderTest,
       PaintOffsetsUnderMultiColumnVerticalRLWithOverflow) {
  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 0; }</style>
    <div id='multicol' style='columns:2; column-fill:auto; column-gap: 0;
        width: 200px; height: 200px; writing-mode: vertical-rl'>
      <div style='width: 100px'>
        <div id='content' style='width: 400px'></div>
      </div>
    </div>
  )HTML");

  LayoutObject* thread =
      GetLayoutObjectByElementId("multicol")->SlowFirstChild();
  EXPECT_TRUE(thread->IsLayoutFlowThread());
  EXPECT_EQ(2u, NumFragments(thread));
  EXPECT_EQ(LayoutPoint(100, 0), FragmentAt(thread, 0).PaintOffset());
  EXPECT_EQ(LayoutPoint(0, 0), FragmentAt(thread, 0).PaginationOffset());
  EXPECT_EQ(LayoutPoint(300, 100), FragmentAt(thread, 1).PaintOffset());
  EXPECT_EQ(LayoutPoint(200, 100), FragmentAt(thread, 1).PaginationOffset());

  LayoutObject* content = GetLayoutObjectByElementId("content");
  EXPECT_EQ(2u, NumFragments(content));
  EXPECT_EQ(LayoutPoint(-200, 0), FragmentAt(content, 0).PaintOffset());
  EXPECT_EQ(LayoutPoint(0, 0), FragmentAt(content, 0).PaginationOffset());
  EXPECT_EQ(LayoutPoint(0, 100), FragmentAt(content, 1).PaintOffset());
  EXPECT_EQ(LayoutPoint(200, 100), FragmentAt(content, 1).PaginationOffset());
}

TEST_P(PaintPropertyTreeBuilderTest, CompositedUnderMultiColumn) {
  // TODO(crbug.com/796768): Currently this test crashes for SPv2 when mapping
  // layer clip rects from one fragment to another. May need to adjust fragment
  // clip hierarchy to fix the crash.
  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled())
    return;

  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 0; }</style>
    <div id='multicol' style='columns:3; column-fill:auto; column-gap: 0;
        width: 300px; height: 200px'>
      <div style='height: 300px'></div>
      <div id='composited' style='will-change: transform; height: 300px'>
        <div id='non-composited-child' style='height: 150px'></div>
        <div id='composited-child'
             style='will-change: transform; height: 150px'></div>
      </div>
    </div>
  )HTML");

  LayoutObject* thread =
      GetLayoutObjectByElementId("multicol")->SlowFirstChild();
  EXPECT_TRUE(thread->IsLayoutFlowThread());
  EXPECT_EQ(3u, NumFragments(thread));
  EXPECT_EQ(LayoutPoint(0, 0), FragmentAt(thread, 0).PaintOffset());
  EXPECT_EQ(LayoutPoint(0, 0), FragmentAt(thread, 0).PaginationOffset());
  EXPECT_EQ(LayoutPoint(100, -200), FragmentAt(thread, 1).PaintOffset());
  EXPECT_EQ(LayoutPoint(100, -200), FragmentAt(thread, 1).PaginationOffset());
  EXPECT_EQ(LayoutPoint(200, -400), FragmentAt(thread, 2).PaintOffset());
  EXPECT_EQ(LayoutPoint(200, -400), FragmentAt(thread, 2).PaginationOffset());

  LayoutObject* composited = GetLayoutObjectByElementId("composited");
  LayoutObject* non_composited_child =
      GetLayoutObjectByElementId("non-composited-child");
  LayoutObject* composited_child =
      GetLayoutObjectByElementId("composited-child");
  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
    // Compositing doesn't affect SPv2 fragmentation.
    EXPECT_EQ(2u, NumFragments(composited));
    EXPECT_EQ(LayoutPoint(100, 100), FragmentAt(composited, 0).PaintOffset());
    EXPECT_EQ(LayoutPoint(100, -200),
              FragmentAt(composited, 0).PaginationOffset());
    EXPECT_EQ(LayoutPoint(200, -100), FragmentAt(composited, 1).PaintOffset());
    EXPECT_EQ(LayoutPoint(200, -400),
              FragmentAt(composited, 1).PaginationOffset());
    EXPECT_EQ(2u, NumFragments(non_composited_child));
    EXPECT_EQ(LayoutPoint(100, 100),
              FragmentAt(non_composited_child, 0).PaintOffset());
    EXPECT_EQ(LayoutPoint(100, -200),
              FragmentAt(non_composited_child, 0).PaginationOffset());
    EXPECT_EQ(LayoutPoint(200, -100),
              FragmentAt(non_composited_child, 1).PaintOffset());
    EXPECT_EQ(LayoutPoint(200, -400),
              FragmentAt(non_composited_child, 1).PaginationOffset());
    EXPECT_EQ(1u, NumFragments(composited_child));
    EXPECT_EQ(LayoutPoint(200, 50),
              FragmentAt(composited_child, 0).PaintOffset());
    EXPECT_EQ(LayoutPoint(200, -400),
              FragmentAt(composited_child, 0).PaginationOffset());
  } else {
    // SPv1* forces single fragment for composited layers.
    EXPECT_EQ(1u, NumFragments(composited));
    EXPECT_EQ(LayoutPoint(100, 100), FragmentAt(composited, 0).PaintOffset());
    EXPECT_EQ(LayoutPoint(100, -200),
              FragmentAt(composited, 0).PaginationOffset());
    EXPECT_EQ(1u, NumFragments(non_composited_child));
    EXPECT_EQ(LayoutPoint(100, 100),
              FragmentAt(non_composited_child, 0).PaintOffset());
    EXPECT_EQ(LayoutPoint(100, -200),
              FragmentAt(non_composited_child, 0).PaginationOffset());
    EXPECT_EQ(1u, NumFragments(composited_child));
    EXPECT_EQ(LayoutPoint(100, 250),
              FragmentAt(composited_child, 0).PaintOffset());
    EXPECT_EQ(LayoutPoint(100, -200),
              FragmentAt(composited_child, 0).PaginationOffset());
  }
}

// Ensures no crash with multi-column containing relative-position inline with
// spanner with absolute-position children.
TEST_P(PaintPropertyTreeBuilderTest,
       MultiColumnInlineRelativeAndSpannerAndAbsPos) {
  SetBodyInnerHTML(R"HTML(
    <div style='columns:2; width: 200px; column-gap: 0'>
      <span style='position: relative'>
        <span id=spanner style='column-span: all'>
          <div id=absolute style='position: absolute'>absolute</div>
        </span>
      </span>
    </div>
  )HTML");
  // The "spanner" isn't a real spanner because it's an inline.
  EXPECT_FALSE(GetLayoutObjectByElementId("spanner")->IsColumnSpanAll());

  SetBodyInnerHTML(R"HTML(
    <div style='columns:2; width: 200px; column-gap: 0'>
      <span style='position: relative'>
        <div id=spanner style='column-span: all'>
          <div id=absolute style='position: absolute'>absolute</div>
        </div>
      </span>
    </div>
  )HTML");
  // There should be anonymous block created containing the inline "relative",
  // serving as the container of "absolute".
  EXPECT_TRUE(
      GetLayoutObjectByElementId("absolute")->Container()->IsLayoutBlock());
}

TEST_P(PaintPropertyTreeBuilderTest, FrameUnderMulticol) {
  SetBodyInnerHTML(R"HTML(
    <div style='columns: 2; width: 200px; height: 100px; coloum-gap: 0'>
      <iframe style='width: 50px; height: 150px'></iframe>
    </div>
  )HTML");
  SetChildFrameHTML(R"HTML(
    <style>
      body { margin: 0; }
      div { height: 60px; }
    </style>
    <div id='div1' style='background: blue'></div>
    <div id='div2' style='background: green'></div>
  )HTML");

  // This should not crash on duplicated subsequences in the iframe.
  GetDocument().View()->UpdateAllLifecyclePhases();

  // TODO(crbug.com/797779): Add code to verify fragments under the iframe.
}

TEST_P(PaintPropertyTreeBuilderTest,
       FragmentedBecomesUnfragmentedClearPaginationOffset) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #target {
         width: 30px; height: 20px; position: relative;
      }
    </style>
    <div style='columns: 2; height: 20px width: 400px'>
       <div style='height: 20px'></div>
       <div id=target></div>
     </div>
    </div>
  )HTML");

  LayoutObject* target = GetLayoutObjectByElementId("target");
  EXPECT_EQ(LayoutPoint(LayoutUnit(392.5f), LayoutUnit(-20)),
            target->FirstFragment().PaginationOffset());
  Element* target_element = GetDocument().getElementById("target");

  target_element->setAttribute(HTMLNames::styleAttr, "position: absolute");
  GetDocument().View()->UpdateAllLifecyclePhases();
  EXPECT_EQ(LayoutPoint(0, 0), target->FirstFragment().PaginationOffset());
}

TEST_P(PaintPropertyTreeBuilderTest, Reflection) {
  SetBodyInnerHTML(
      "<div id='filter' style='-webkit-box-reflect: below; height:1000px;'>"
      "</div>");
  const ObjectPaintProperties* filter_properties =
      GetLayoutObjectByElementId("filter")->FirstFragment().PaintProperties();
  EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
  EXPECT_EQ(FrameScrollTranslation(),
            filter_properties->Filter()->LocalTransformSpace());
  EXPECT_EQ(FrameContentClip(), filter_properties->Filter()->OutputClip());
  EXPECT_EQ(FloatPoint(8, 8), filter_properties->Filter()->PaintOffset());
}

TEST_P(PaintPropertyTreeBuilderTest, SimpleFilter) {
  SetBodyInnerHTML(
      "<div id='filter' style='filter:opacity(0.5); height:1000px;'>"
      "</div>");
  const ObjectPaintProperties* filter_properties =
      GetLayoutObjectByElementId("filter")->FirstFragment().PaintProperties();
  EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
  EXPECT_EQ(FrameScrollTranslation(),
            filter_properties->Filter()->LocalTransformSpace());
  EXPECT_EQ(FrameContentClip(), filter_properties->Filter()->OutputClip());
  EXPECT_EQ(FloatPoint(8, 8), filter_properties->Filter()->PaintOffset());
}

TEST_P(PaintPropertyTreeBuilderTest, FilterReparentClips) {
  SetBodyInnerHTML(R"HTML(
    <div id='clip' style='overflow:hidden;'>
      <div id='filter' style='filter:opacity(0.5); height:1000px;'>
        <div id='child' style='position:fixed;'></div>
      </div>
    </div>
  )HTML");
  const ObjectPaintProperties* clip_properties =
      GetLayoutObjectByElementId("clip")->FirstFragment().PaintProperties();
  const ObjectPaintProperties* filter_properties =
      GetLayoutObjectByElementId("filter")->FirstFragment().PaintProperties();
  EXPECT_TRUE(filter_properties->Filter()->Parent()->IsRoot());
  EXPECT_EQ(clip_properties->OverflowClip(),
            filter_properties->Filter()->OutputClip());
  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
    EXPECT_EQ(FrameScrollTranslation(),
              filter_properties->Filter()->LocalTransformSpace());
    EXPECT_EQ(FloatPoint(8, 8), filter_properties->Filter()->PaintOffset());
  } else {
    // For SPv1*, |filter| is composited so we created PaintOffsetTranslation.
    EXPECT_EQ(filter_properties->PaintOffsetTranslation(),
              filter_properties->Filter()->LocalTransformSpace());
    EXPECT_EQ(TransformationMatrix().Translate(8, 8),
              filter_properties->PaintOffsetTranslation()->Matrix());
    EXPECT_EQ(FloatPoint(), filter_properties->Filter()->PaintOffset());
  }

  const PropertyTreeState& child_paint_state =
      *GetLayoutObjectByElementId("child")
           ->FirstFragment()
           .LocalBorderBoxProperties();

  // This will change once we added clip expansion node.
  EXPECT_EQ(filter_properties->Filter()->OutputClip(),
            child_paint_state.Clip());
  EXPECT_EQ(filter_properties->Filter(), child_paint_state.Effect());
}

TEST_P(PaintPropertyTreeBuilderTest, TransformOriginWithAndWithoutTransform) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body { margin: 0 }
      div {
        width: 400px;
        height: 100px;
      }
      #transform {
        transform: translate(100px, 200px);
        transform-origin: 75% 75% 0;
      }
      #willChange {
        will-change: opacity;
        transform-origin: 75% 75% 0;
      }
    </style>
    <div id='transform'></div>
    <div id='willChange'></div>
  )HTML");

  auto* transform = GetLayoutObjectByElementId("transform");
  EXPECT_EQ(
      TransformationMatrix().Translate3d(100, 200, 0),
      transform->FirstFragment().PaintProperties()->Transform()->Matrix());
  EXPECT_EQ(
      FloatPoint3D(300, 75, 0),
      transform->FirstFragment().PaintProperties()->Transform()->Origin());

  auto* will_change = GetLayoutObjectByElementId("willChange");
  EXPECT_EQ(
      TransformationMatrix().Translate3d(0, 0, 0),
      will_change->FirstFragment().PaintProperties()->Transform()->Matrix());
  EXPECT_EQ(
      FloatPoint3D(0, 0, 0),
      will_change->FirstFragment().PaintProperties()->Transform()->Origin());
}

TEST_P(PaintPropertyTreeBuilderTest, TransformOriginWithAndWithoutMotionPath) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body { margin: 0 }
      div {
        width: 100px;
        height: 100px;
      }
      #motionPath {
        position: absolute;
        offset-path: path('M0 0 L 200 400');
        offset-distance: 50%;
        offset-rotate: 0deg;
        transform-origin: 50% 50% 0;
      }
      #willChange {
        will-change: opacity;
        transform-origin: 50% 50% 0;
      }
    </style>
    <div id='motionPath'></div>
    <div id='willChange'></div>
  )HTML");

  auto* motion_path = GetLayoutObjectByElementId("motionPath");
  EXPECT_EQ(
      TransformationMatrix().Translate3d(50, 150, 0),
      motion_path->FirstFragment().PaintProperties()->Transform()->Matrix());
  EXPECT_EQ(
      FloatPoint3D(50, 50, 0),
      motion_path->FirstFragment().PaintProperties()->Transform()->Origin());

  auto* will_change = GetLayoutObjectByElementId("willChange");
  EXPECT_EQ(
      TransformationMatrix().Translate3d(0, 0, 0),
      will_change->FirstFragment().PaintProperties()->Transform()->Matrix());
  EXPECT_EQ(
      FloatPoint3D(0, 0, 0),
      will_change->FirstFragment().PaintProperties()->Transform()->Origin());
}

TEST_P(PaintPropertyTreeBuilderTest, ChangePositionUpdateDescendantProperties) {
  SetBodyInnerHTML(R"HTML(
    <style>
      * { margin: 0; }
      #ancestor { position: absolute; overflow: hidden }
      #descendant { position: absolute }
    </style>
    <div id='ancestor'>
      <div id='descendant'></div>
    </div>
  )HTML");

  LayoutObject* ancestor = GetLayoutObjectByElementId("ancestor");
  LayoutObject* descendant = GetLayoutObjectByElementId("descendant");
  EXPECT_EQ(ancestor->FirstFragment().PaintProperties()->OverflowClip(),
            descendant->FirstFragment().LocalBorderBoxProperties()->Clip());

  ToElement(ancestor->GetNode())
      ->setAttribute(HTMLNames::styleAttr, "position: static");
  GetDocument().View()->UpdateAllLifecyclePhases();
  EXPECT_NE(ancestor->FirstFragment().PaintProperties()->OverflowClip(),
            descendant->FirstFragment().LocalBorderBoxProperties()->Clip());
}

TEST_P(PaintPropertyTreeBuilderTest,
       TransformNodeNotAnimatedStillHasCompositorElementId) {
  SetBodyInnerHTML("<div id='target' style='transform: translateX(2em)'></div");
  const ObjectPaintProperties* properties = PaintPropertiesForElement("target");
  EXPECT_TRUE(properties->Transform());
  EXPECT_NE(CompositorElementId(),
            properties->Transform()->GetCompositorElementId());
}

TEST_P(PaintPropertyTreeBuilderTest,
       EffectNodeNotAnimatedStillHasCompositorElementId) {
  SetBodyInnerHTML("<div id='target' style='opacity: 0.5'></div");
  const ObjectPaintProperties* properties = PaintPropertiesForElement("target");
  EXPECT_TRUE(properties->Effect());
  EXPECT_NE(CompositorElementId(),
            properties->Effect()->GetCompositorElementId());
}

TEST_P(PaintPropertyTreeBuilderTest,
       TransformNodeAnimatedHasCompositorElementId) {
  LoadTestData("transform-animation.html");
  const ObjectPaintProperties* properties = PaintPropertiesForElement("target");
  EXPECT_TRUE(properties->Transform());
  EXPECT_NE(CompositorElementId(),
            properties->Transform()->GetCompositorElementId());
  EXPECT_TRUE(properties->Transform()->RequiresCompositingForAnimation());
}

TEST_P(PaintPropertyTreeBuilderTest, EffectNodeAnimatedHasCompositorElementId) {
  LoadTestData("opacity-animation.html");
  const ObjectPaintProperties* properties = PaintPropertiesForElement("target");
  EXPECT_TRUE(properties->Effect());
  EXPECT_NE(CompositorElementId(),
            properties->Effect()->GetCompositorElementId());
  EXPECT_TRUE(properties->Effect()->RequiresCompositingForAnimation());
}

TEST_P(PaintPropertyTreeBuilderTest, FloatUnderInline) {
  SetBodyInnerHTML(R"HTML(
    <div style='position: absolute; top: 55px; left: 66px'>
      <span id='span'
          style='position: relative; top: 100px; left: 200px; opacity: 0.5'>
        <div id='target'
             style='overflow: hidden; float: left; width: 3px; height: 4px'>
        </div>
      </span>
    </div>
  )HTML");

  LayoutObject* span = GetLayoutObjectByElementId("span");
  const auto* effect = span->FirstFragment().PaintProperties()->Effect();
  ASSERT_TRUE(effect);
  EXPECT_EQ(0.5f, effect->Opacity());

  LayoutObject* target = GetLayoutObjectByElementId("target");
  ASSERT_TRUE(target->FirstFragment().LocalBorderBoxProperties());
  EXPECT_EQ(LayoutPoint(66, 55), target->FirstFragment().PaintOffset());
  EXPECT_EQ(effect,
            target->FirstFragment().LocalBorderBoxProperties()->Effect());
}

TEST_P(PaintPropertyTreeBuilderTest, ScrollNodeHasCompositorElementId) {
  SetBodyInnerHTML(R"HTML(
    <div id='target' style='overflow: auto; width: 100px; height: 100px'>
      <div style='width: 200px; height: 200px'></div>
    </div>
  )HTML");

  const ObjectPaintProperties* properties = PaintPropertiesForElement("target");
  // The scroll translation node should not have the element id as it should be
  // stored directly on the ScrollNode.
  EXPECT_EQ(CompositorElementId(),
            properties->ScrollTranslation()->GetCompositorElementId());
  EXPECT_NE(CompositorElementId(),
            properties->Scroll()->GetCompositorElementId());
}

TEST_P(PaintPropertyTreeBuilderTest, OverflowClipSubpixelPosition) {
  SetBodyInnerHTML(R"HTML(
    <style>body { margin: 20px 30px; }</style>
    <div id='clipper'
        style='position: relative; overflow: hidden;
               width: 400px; height: 300px; left: 1.5px'>
    </div>
  )HTML");

  LayoutBoxModelObject* clipper =
      ToLayoutBoxModelObject(GetLayoutObjectByElementId("clipper"));
  const ObjectPaintProperties* clip_properties =
      clipper->FirstFragment().PaintProperties();

  EXPECT_EQ(LayoutPoint(FloatPoint(31.5, 20)),
            clipper->FirstFragment().PaintOffset());
  EXPECT_EQ(FloatRect(31.5, 20, 400, 300),
            clip_properties->OverflowClip()->ClipRect().Rect());
}

TEST_P(PaintPropertyTreeBuilderTest, MaskSimple) {
  SetBodyInnerHTML(R"HTML(
    <div id='target' style='width:300px; height:200px;
        -webkit-mask:linear-gradient(red,red)'>
      Lorem ipsum
    </div>
  )HTML");

  const ObjectPaintProperties* properties = PaintPropertiesForElement("target");
  const ClipPaintPropertyNode* output_clip = properties->MaskClip();

  const auto* target = GetLayoutObjectByElementId("target");
  EXPECT_EQ(output_clip,
            target->FirstFragment().LocalBorderBoxProperties()->Clip());
  EXPECT_EQ(FrameContentClip(), output_clip->Parent());
  EXPECT_EQ(FloatRoundedRect(8, 8, 300, 200), output_clip->ClipRect());

  EXPECT_EQ(properties->Effect(),
            target->FirstFragment().LocalBorderBoxProperties()->Effect());
  EXPECT_TRUE(properties->Effect()->Parent()->IsRoot());
  EXPECT_EQ(SkBlendMode::kSrcOver, properties->Effect()->BlendMode());
  EXPECT_EQ(output_clip, properties->Effect()->OutputClip());

  EXPECT_EQ(properties->Effect(), properties->Mask()->Parent());
  EXPECT_EQ(SkBlendMode::kDstIn, properties->Mask()->BlendMode());
  EXPECT_EQ(output_clip, properties->Mask()->OutputClip());
}

TEST_P(PaintPropertyTreeBuilderTest, MaskWithOutset) {
  SetBodyInnerHTML(R"HTML(
    <div id='target' style='width:300px; height:200px;
        -webkit-mask-box-image-source:linear-gradient(red,red);
        -webkit-mask-box-image-outset:10px 20px;'>
      Lorem ipsum
    </div>
  )HTML");

  const ObjectPaintProperties* properties = PaintPropertiesForElement("target");
  const ClipPaintPropertyNode* output_clip = properties->MaskClip();

  const auto* target = GetLayoutObjectByElementId("target");
  EXPECT_EQ(output_clip,
            target->FirstFragment().LocalBorderBoxProperties()->Clip());
  EXPECT_EQ(FrameContentClip(), output_clip->Parent());
  EXPECT_EQ(FloatRoundedRect(-12, -2, 340, 220), output_clip->ClipRect());

  EXPECT_EQ(properties->Effect(),
            target->FirstFragment().LocalBorderBoxProperties()->Effect());
  EXPECT_TRUE(properties->Effect()->Parent()->IsRoot());
  EXPECT_EQ(SkBlendMode::kSrcOver, properties->Effect()->BlendMode());
  EXPECT_EQ(output_clip, properties->Effect()->OutputClip());

  EXPECT_EQ(properties->Effect(), properties->Mask()->Parent());
  EXPECT_EQ(SkBlendMode::kDstIn, properties->Mask()->BlendMode());
  EXPECT_EQ(output_clip, properties->Mask()->OutputClip());
}

TEST_P(PaintPropertyTreeBuilderTest, MaskEscapeClip) {
  // This test verifies an abs-pos element still escape the scroll of a
  // static-pos ancestor, but gets clipped due to the presence of a mask.
  SetBodyInnerHTML(R"HTML(
    <div id='scroll' style='width:300px; height:200px; overflow:scroll;'>
      <div id='target' style='width:200px; height:300px;
          -webkit-mask:linear-gradient(red,red); border:10px dashed black;
          overflow:hidden;'>
        <div id='absolute' style='position:absolute; left:0; top:0;'>
          Lorem ipsum
        </div>
      </div>
    </div>
  )HTML");

  const ObjectPaintProperties* target_properties =
      PaintPropertiesForElement("target");
  const ClipPaintPropertyNode* overflow_clip1 =
      target_properties->MaskClip()->Parent();
  const ClipPaintPropertyNode* mask_clip = target_properties->MaskClip();
  const ClipPaintPropertyNode* overflow_clip2 =
      target_properties->OverflowClip();
  const auto* target = GetLayoutObjectByElementId("target");
  const TransformPaintPropertyNode* scroll_translation =
      target->FirstFragment().LocalBorderBoxProperties()->Transform();

  const ObjectPaintProperties* scroll_properties =
      PaintPropertiesForElement("scroll");

  EXPECT_EQ(FrameContentClip(), overflow_clip1->Parent());
  EXPECT_EQ(FloatRoundedRect(0, 0, 300, 200), overflow_clip1->ClipRect());
  EXPECT_EQ(scroll_properties->PaintOffsetTranslation(),
            overflow_clip1->LocalTransformSpace());

  EXPECT_EQ(mask_clip,
            target->FirstFragment().LocalBorderBoxProperties()->Clip());
  EXPECT_EQ(overflow_clip1, mask_clip->Parent());
  EXPECT_EQ(FloatRoundedRect(0, 0, 220, 320), mask_clip->ClipRect());
  EXPECT_EQ(scroll_translation, mask_clip->LocalTransformSpace());

  EXPECT_EQ(mask_clip, overflow_clip2->Parent());
  EXPECT_EQ(FloatRoundedRect(10, 10, 200, 300), overflow_clip2->ClipRect());
  EXPECT_EQ(scroll_translation, overflow_clip2->LocalTransformSpace());

  EXPECT_EQ(target_properties->Effect(),
            target->FirstFragment().LocalBorderBoxProperties()->Effect());
  EXPECT_TRUE(target_properties->Effect()->Parent()->IsRoot());
  EXPECT_EQ(SkBlendMode::kSrcOver, target_properties->Effect()->BlendMode());
  EXPECT_EQ(mask_clip, target_properties->Effect()->OutputClip());

  EXPECT_EQ(target_properties->Effect(), target_properties->Mask()->Parent());
  EXPECT_EQ(SkBlendMode::kDstIn, target_properties->Mask()->BlendMode());
  EXPECT_EQ(mask_clip, target_properties->Mask()->OutputClip());

  const auto* absolute = GetLayoutObjectByElementId("absolute");
  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
    EXPECT_EQ(
        FramePreTranslation(),
        absolute->FirstFragment().LocalBorderBoxProperties()->Transform());
  } else {
    // For SPv1*, |absolute| is composited so we created PaintOffsetTranslation.
    EXPECT_EQ(
        absolute->FirstFragment().PaintProperties()->PaintOffsetTranslation(),
        absolute->FirstFragment().LocalBorderBoxProperties()->Transform());
  }
  EXPECT_EQ(mask_clip,
            absolute->FirstFragment().LocalBorderBoxProperties()->Clip());
}

TEST_P(PaintPropertyTreeBuilderTest, MaskInline) {
  LoadAhem();
  // This test verifies CSS mask applied on an inline element is clipped to
  // the line box of the said element. In this test the masked element has
  // only one box, and one of the child element overflows the box.
  SetBodyInnerHTML(R"HTML(
    <style>* { font-family:Ahem; font-size:16px; }</style>
    Lorem
    <span id='target' style='-webkit-mask:linear-gradient(red,red);'>
      ipsum
      <span id='overflowing' style='position:relative; font-size:32px;'>
        dolor
      </span>
      sit amet,
    </span>
  )HTML");

  const ObjectPaintProperties* properties = PaintPropertiesForElement("target");
  const ClipPaintPropertyNode* output_clip = properties->MaskClip();
  const auto* target = GetLayoutObjectByElementId("target");

  EXPECT_EQ(output_clip,
            target->FirstFragment().LocalBorderBoxProperties()->Clip());
  EXPECT_EQ(FrameContentClip(), output_clip->Parent());
  EXPECT_EQ(FloatRoundedRect(104, 21, 432, 16), output_clip->ClipRect());

  EXPECT_EQ(properties->Effect(),
            target->FirstFragment().LocalBorderBoxProperties()->Effect());
  EXPECT_TRUE(properties->Effect()->Parent()->IsRoot());
  EXPECT_EQ(SkBlendMode::kSrcOver, properties->Effect()->BlendMode());
  EXPECT_EQ(output_clip, properties->Effect()->OutputClip());

  EXPECT_EQ(properties->Effect(), properties->Mask()->Parent());
  EXPECT_EQ(SkBlendMode::kDstIn, properties->Mask()->BlendMode());
  EXPECT_EQ(output_clip, properties->Mask()->OutputClip());

  const auto* overflowing = GetLayoutObjectByElementId("overflowing");
  EXPECT_EQ(output_clip,
            overflowing->FirstFragment().LocalBorderBoxProperties()->Clip());
  EXPECT_EQ(properties->Effect(),
            overflowing->FirstFragment().LocalBorderBoxProperties()->Effect());
}

TEST_P(PaintPropertyTreeBuilderTest, SVGResource) {
  SetBodyInnerHTML(R"HTML(
    <svg id='svg' xmlns='http://www.w3.org/2000/svg' >
     <g transform='scale(1000)'>
       <marker id='markerMiddle'  markerWidth='2' markerHeight='2' refX='5'
           refY='5' markerUnits='strokeWidth'>
         <g id='transformInsideMarker' transform='scale(4)'>
           <circle cx='5' cy='5' r='7' fill='green'/>
         </g>
       </marker>
     </g>
     <g id='transformOutsidePath' transform='scale(2)'>
       <path d='M 130 135 L 180 135 L 180 185'
           marker-mid='url(#markerMiddle)' fill='none' stroke-width='8px'
           stroke='black'/>
     </g>
    </svg>
  )HTML");

  const ObjectPaintProperties* transform_inside_marker_properties =
      PaintPropertiesForElement("transformInsideMarker");
  const ObjectPaintProperties* transform_outside_path_properties =
      PaintPropertiesForElement("transformOutsidePath");
  const ObjectPaintProperties* svg_properties =
      PaintPropertiesForElement("svg");

  // The <marker> object resets to a new paint property tree, so the
  // transform within it should have the root as parent.
  EXPECT_EQ(TransformPaintPropertyNode::Root(),
            transform_inside_marker_properties->Transform()->Parent());

  // Whereas this is not true of the transform above the path.
  EXPECT_EQ(svg_properties->PaintOffsetTranslation(),
            transform_outside_path_properties->Transform()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, SVGHiddenResource) {
  SetBodyInnerHTML(R"HTML(
    <svg id='svg' xmlns='http://www.w3.org/2000/svg' >
     <g transform='scale(1000)'>
       <symbol id='symbol'>
         <g id='transformInsideSymbol' transform='scale(4)'>
           <circle cx='5' cy='5' r='7' fill='green'/>
         </g>
       </symbol>
     </g>
     <g id='transformOutsideUse' transform='scale(2)'>
       <use x='25' y='25' width='400' height='400' xlink:href='#symbol'/>
     </g>
    </svg>
  )HTML");

  const ObjectPaintProperties* transform_inside_symbol_properties =
      PaintPropertiesForElement("transformInsideSymbol");
  const ObjectPaintProperties* transform_outside_use_properties =
      PaintPropertiesForElement("transformOutsideUse");
  const ObjectPaintProperties* svg_properties =
      PaintPropertiesForElement("svg");

  // The <marker> object resets to a new paint property tree, so the
  // transform within it should have the root as parent.
  EXPECT_EQ(TransformPaintPropertyNode::Root(),
            transform_inside_symbol_properties->Transform()->Parent());

  // Whereas this is not true of the transform above the path.
  EXPECT_EQ(svg_properties->PaintOffsetTranslation(),
            transform_outside_use_properties->Transform()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, SVGRootBlending) {
  SetBodyInnerHTML(R"HTML(
    <svg id='svgroot' 'width=100' height='100'
        style='position: relative; z-index: 0'>
     <rect width='100' height='100' fill='#00FF00'
         style='mix-blend-mode: difference'/>
    </svg>
  )HTML");

  LayoutObject& svg_root = *GetLayoutObjectByElementId("svgroot");
  const ObjectPaintProperties* svg_root_properties =
      svg_root.FirstFragment().PaintProperties();
  EXPECT_TRUE(svg_root_properties->Effect());
  EXPECT_EQ(EffectPaintPropertyNode::Root(),
            svg_root_properties->Effect()->Parent());
}

TEST_P(PaintPropertyTreeBuilderTest, ScrollBoundsOffset) {
  SetBodyInnerHTML(R"HTML(
    <style>
      body {
        margin: 0px;
      }
      #scroller {
        overflow-y: scroll;
        width: 100px;
        height: 100px;
        margin-left: 7px;
        margin-top: 11px;
      }
      .forceScroll {
        height: 200px;
      }
    </style>
    <div id='scroller'>
      <div class='forceScroll'></div>
    </div>
  )HTML");

  Element* scroller = GetDocument().getElementById("scroller");
  scroller->setScrollTop(42);

  GetDocument().View()->UpdateAllLifecyclePhases();

  const ObjectPaintProperties* scroll_properties =
      scroller->GetLayoutObject()->FirstFragment().PaintProperties();
  // Because the frameView is does not scroll, overflowHidden's scroll should be
  // under the root.
  auto* scroll_translation = scroll_properties->ScrollTranslation();
  auto* paint_offset_translation = scroll_properties->PaintOffsetTranslation();
  auto* scroll_node = scroll_translation->ScrollNode();
  EXPECT_TRUE(scroll_node->Parent()->IsRoot());
  EXPECT_EQ(TransformationMatrix().Translate(0, -42),
            scroll_translation->Matrix());
  // The paint offset node should be offset by the margin.
  EXPECT_EQ(FloatSize(7, 11),
            paint_offset_translation->Matrix().To2DTranslation());
  // And the scroll node should not.
  EXPECT_EQ(IntRect(0, 0, 100, 100), scroll_node->ContainerRect());

  scroller->setAttribute(HTMLNames::styleAttr, "border: 20px solid black;");
  GetDocument().View()->UpdateAllLifecyclePhases();
  // The paint offset node should be offset by the margin.
  EXPECT_EQ(FloatSize(7, 11),
            paint_offset_translation->Matrix().To2DTranslation());
  // The scroll node should be offset by the border.
  EXPECT_EQ(IntRect(20, 20, 100, 100), scroll_node->ContainerRect());

  scroller->setAttribute(HTMLNames::styleAttr,
                         "border: 20px solid black;"
                         "transform: translate(20px, 30px);");
  GetDocument().View()->UpdateAllLifecyclePhases();
  // The scroll node's offset should not include margin if it has already been
  // included in a paint offset node.
  EXPECT_EQ(IntRect(20, 20, 100, 100), scroll_node->ContainerRect());
  EXPECT_EQ(TransformationMatrix().Translate(7, 11),
            scroll_properties->PaintOffsetTranslation()->Matrix());
}

TEST_P(PaintPropertyTreeBuilderTest, FilterContainingBlockUseCounterRelPos) {
  SetBodyInnerHTML(
      "<div style='filter:blur(2px)'>"
      "  <div id=target style='position:relative'></div>"
      "</div>");

  EXPECT_FALSE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

TEST_P(PaintPropertyTreeBuilderTest, FilterContainingBlockUseCounterAbsPos) {
  SetBodyInnerHTML(
      "<div style='filter:blur(2px)'>"
      "  <div id=target style='position:absolute'></div>"
      "</div>");

  EXPECT_TRUE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

TEST_P(PaintPropertyTreeBuilderTest, FilterContainingBlockUseCounterStickyPos) {
  SetBodyInnerHTML(
      "<div style='filter:blur(2px)'>"
      "  <div id=target style='position:sticky'></div>"
      "</div>");

  EXPECT_FALSE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

TEST_P(PaintPropertyTreeBuilderTest, FilterContainingBlockUseCounterFixedPos) {
  SetBodyInnerHTML(
      "<div style='filter:blur(2px)'>"
      "  <div id=target style='position:fixed'></div>"
      "</div>");

  EXPECT_TRUE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

TEST_P(PaintPropertyTreeBuilderTest,
       FilterContainingBlockUseCounterAbsPosAbsPos) {
  SetBodyInnerHTML(
      "<div style='filter:blur(2px); position:absolute'>"
      "  <div id=target style='position:absolute'></div>"
      "</div>");

  EXPECT_FALSE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

TEST_P(PaintPropertyTreeBuilderTest,
       FilterContainingBlockUseCounterAbsPosFixedPos) {
  SetBodyInnerHTML(
      "<div style='filter:blur(2px); position:absolute'>"
      "  <div id=target style='position:fixed'></div>"
      "</div>"
      "<div style='width: 10px; height: 1000px'></div>");

  EXPECT_TRUE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

TEST_P(PaintPropertyTreeBuilderTest,
       FilterContainingBlockUseCounterFixedPosFixedPos) {
  SetBodyInnerHTML(
      "<div style='filter:blur(2px); position:fixed'>"
      "  <div id=target style='position:fixed'></div>"
      "</div>");

  EXPECT_TRUE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

TEST_P(PaintPropertyTreeBuilderTest,
       FilterContainingBlockUseCounterFixedPosTransform) {
  SetBodyInnerHTML(
      "<div style='filter:blur(2px); transform: translateX(0)'>"
      "  <div id=target style='position:fixed'></div>"
      "</div>");

  EXPECT_FALSE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

// The body and html elements are special and won't affect change of
// containing block for filter.
TEST_P(PaintPropertyTreeBuilderTest,
       FilterContainingBlockUseCounterFixedPosUnderFilteredBody) {
  SetBodyInnerHTML(
      "<body style='filter:blur(2px);'>"
      "  <div id=target style='position:fixed'></div>"
      "</body>");

  EXPECT_FALSE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

TEST_P(PaintPropertyTreeBuilderTest,
       FilterContainingBlockUseCounterFixedPosUnderFilteredHTML) {
  SetBodyInnerHTML(
      "<html style='filter:blur(2px);'>"
      "  <div id=target style='position:fixed'></div>"
      "</html>");

  EXPECT_FALSE(UseCounter::IsCounted(
      GetDocument(), WebFeature::kFilterAsContainingBlockMayChangeOutput));
}

TEST_P(PaintPropertyTreeBuilderTest, CompositedLayerPaintOffsetTranslation) {
  SetBodyInnerHTML(R"HTML(
    <style>#target { position: absolute; top: 50px; left: 60px }</style>
    <div id='target' style='backface-visibility: hidden'></div>
  )HTML");

  const auto* target = GetLayoutObjectByElementId("target");
  if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) {
    EXPECT_EQ(nullptr, target->FirstFragment().PaintProperties());
    EXPECT_EQ(LayoutPoint(60, 50), target->FirstFragment().PaintOffset());
  } else {
    // For SPv1*, |target| is composited so we created PaintOffsetTranslation.
    const auto* paint_offset_translation =
        target->FirstFragment().PaintProperties()->PaintOffsetTranslation();
    ASSERT_NE(nullptr, paint_offset_translation);
    EXPECT_EQ(TransformationMatrix().Translate(60, 50),
              paint_offset_translation->Matrix());
  }

  ToElement(target->GetNode())->setAttribute(HTMLNames::styleAttr, "");
  GetDocument().View()->UpdateAllLifecyclePhases();
  EXPECT_EQ(LayoutPoint(60, 50), target->FirstFragment().PaintOffset());
  EXPECT_EQ(nullptr, target->FirstFragment().PaintProperties());
}

TEST_P(PaintPropertyTreeBuilderTest, FrameBorderRadius) {
  SetBodyInnerHTML(R"HTML(
    <style>
      #iframe {
        width: 200px;
        height: 200px;
        border: 10px solid blue;
        border-radius: 50px;
        padding: 10px;
      }
    </style>
    <iframe id='iframe'></iframe>
  )HTML");

  const auto* properties = PaintPropertiesForElement("iframe");
  const auto* border_radius_clip = properties->InnerBorderRadiusClip();
  ASSERT_NE(nullptr, border_radius_clip);
  FloatSize radius(30, 30);
  EXPECT_EQ(FloatRoundedRect(FloatRect(28, 28, 200, 200), radius, radius,
                             radius, radius),
            border_radius_clip->ClipRect());
  EXPECT_EQ(FrameContentClip(), border_radius_clip->Parent());
  EXPECT_EQ(FramePreTranslation(), border_radius_clip->LocalTransformSpace());
  EXPECT_EQ(nullptr, properties->OverflowClip());
}

TEST_P(PaintPropertyTreeBuilderTest, NoPropertyForSVGTextWithReflection) {
  SetBodyInnerHTML(R"HTML(
    <svg>
      <text id='target' style='-webkit-box-reflect: below 2px'>X</text>
    </svg>
  )HTML");
  EXPECT_FALSE(PaintPropertiesForElement("target"));
}

TEST_P(PaintPropertyTreeBuilderTest, ImageBorderRadius) {
  SetBodyInnerHTML(R"HTML(
    <img id='img'
        style='width: 50px; height: 50px; border-radius: 30px; padding: 10px'>
  )HTML");

  const auto* properties = PaintPropertiesForElement("img");
  const auto* border_radius_clip = properties->InnerBorderRadiusClip();
  ASSERT_NE(nullptr, border_radius_clip);
  FloatSize radius(20, 20);
  EXPECT_EQ(FloatRoundedRect(FloatRect(18, 18, 50, 50), radius, radius, radius,
                             radius),
            border_radius_clip->ClipRect());
  EXPECT_EQ(FrameContentClip(), border_radius_clip->Parent());
  EXPECT_EQ(FramePreTranslation(), border_radius_clip->LocalTransformSpace());
  EXPECT_EQ(nullptr, properties->OverflowClip());
}

}  // namespace blink
