/*
 * Copyright (C) 2014 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "core/layout/LayoutGeometryMap.h"

#include "core/dom/Document.h"
#include "core/layout/LayoutBox.h"
#include "core/layout/LayoutView.h"
#include "core/paint/PaintLayer.h"
#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
#include "platform/testing/URLTestHelpers.h"
#include "public/platform/Platform.h"
#include "public/platform/WebURLLoaderMockFactory.h"
#include "public/web/WebCache.h"
#include "public/web/WebFrameClient.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "web/WebLocalFrameImpl.h"
#include "web/tests/FrameTestHelpers.h"

namespace blink {

typedef bool TestParamRootLayerScrolling;
class LayoutGeometryMapTest
    : public testing::Test,
      public testing::WithParamInterface<TestParamRootLayerScrolling>,
      private ScopedRootLayerScrollingForTest {
 public:
  LayoutGeometryMapTest()
      : ScopedRootLayerScrollingForTest(GetParam()),
        m_baseURL("http://www.test.com/") {}

  void TearDown() override {
    Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
    WebCache::clear();
  }

 protected:
  static LayoutBox* getFrameElement(const char* iframeName,
                                    WebView* webView,
                                    const WTF::AtomicString& elementId) {
    WebLocalFrameImpl* iframe = toWebLocalFrameImpl(
        webView->findFrameByName(WebString::fromUTF8(iframeName)));
    if (!iframe)
      return nullptr;
    LocalFrame* frame = iframe->frame();
    Document* doc = frame->document();
    Element* element = doc->getElementById(elementId);
    if (!element)
      return nullptr;
    return element->layoutBox();
  }

  static LayoutBox* getLayoutBox(WebView* webView,
                                 const WTF::AtomicString& elementId) {
    WebViewImpl* webViewImpl = toWebViewImpl(webView);
    if (!webViewImpl)
      return nullptr;
    LocalFrame* frame = webViewImpl->mainFrameImpl()->frame();
    Document* doc = frame->document();
    Element* element = doc->getElementById(elementId);
    if (!element)
      return nullptr;
    return element->layoutBox();
  }

  static const LayoutBoxModelObject* getLayoutContainer(
      WebView* webView,
      const WTF::AtomicString& elementId) {
    LayoutBox* rb = getLayoutBox(webView, elementId);
    if (!rb)
      return nullptr;
    PaintLayer* compositingLayer =
        rb->enclosingLayer()->enclosingLayerForPaintInvalidation();
    if (!compositingLayer)
      return nullptr;
    return compositingLayer->layoutObject();
  }

  static const LayoutBoxModelObject* getFrameLayoutContainer(
      const char* frameId,
      WebView* webView,
      const WTF::AtomicString& elementId) {
    LayoutBox* rb = getFrameElement(frameId, webView, elementId);
    if (!rb)
      return nullptr;
    PaintLayer* compositingLayer =
        rb->enclosingLayer()->enclosingLayerForPaintInvalidation();
    if (!compositingLayer)
      return nullptr;
    return compositingLayer->layoutObject();
  }

  static const FloatRect rectFromQuad(const FloatQuad& quad) {
    FloatRect rect;
    rect.setX(std::min(
        quad.p1().x(),
        std::min(quad.p2().x(), std::min(quad.p3().x(), quad.p4().x()))));
    rect.setY(std::min(
        quad.p1().y(),
        std::min(quad.p2().y(), std::min(quad.p3().y(), quad.p4().y()))));

    rect.setWidth(std::max(quad.p1().x(),
                           std::max(quad.p2().x(),
                                    std::max(quad.p3().x(), quad.p4().x()))) -
                  rect.x());
    rect.setHeight(std::max(quad.p1().y(),
                            std::max(quad.p2().y(),
                                     std::max(quad.p3().y(), quad.p4().y()))) -
                   rect.y());
    return rect;
  }

  // Adjust rect by the scroll offset of the LayoutView.  This only has an
  // effect if root layer scrolling is enabled.  The only reason for doing
  // this here is so the test expected values can be the same whether or not
  // root layer scrolling is enabled.  For more context, see:
  // https://codereview.chromium.org/2417103002/#msg11
  static FloatRect adjustForFrameScroll(WebView* webView,
                                        const FloatRect& rect) {
    FloatRect result(rect);
    LocalFrame* frame = toWebViewImpl(webView)->mainFrameImpl()->frame();
    LayoutView* layoutView = frame->document()->layoutView();
    if (layoutView->hasOverflowClip())
      result.move(layoutView->scrolledContentOffset());
    return result;
  }

  void registerMockedHttpURLLoad(const std::string& fileName) {
    URLTestHelpers::registerMockedURLFromBaseURL(
        WebString::fromUTF8(m_baseURL.c_str()),
        WebString::fromUTF8(fileName.c_str()));
  }

  const std::string m_baseURL;
  FrameTestHelpers::TestWebFrameClient m_mockWebViewClient;
};

INSTANTIATE_TEST_CASE_P(All, LayoutGeometryMapTest, ::testing::Bool());

TEST_P(LayoutGeometryMapTest, SimpleGeometryMapTest) {
  registerMockedHttpURLLoad("rgm_test.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebView* webView =
      webViewHelper.initializeAndLoad(m_baseURL + "rgm_test.html", true, 0, 0);
  webView->resize(WebSize(1000, 1000));
  webView->updateAllLifecyclePhases();

  // We are going test everything twice. Once with FloatPoints and once with
  // FloatRects. This is because LayoutGeometryMap treats both slightly
  // differently
  LayoutGeometryMap rgm;
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "InitialDiv"), 0);
  FloatRect rect(0.0f, 0.0f, 1.0f, 2.0f);
  EXPECT_EQ(FloatQuad(FloatRect(8.0f, 8.0f, 1.0f, 2.0f)),
            rgm.mapToAncestor(rect, nullptr));

  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));
  EXPECT_EQ(FloatQuad(FloatRect(0.0f, 0.0f, 1.0f, 2.0f)),
            rgm.mapToAncestor(rect, nullptr));

  rgm.pushMappingsToAncestor(getLayoutBox(webView, "InnerDiv"), 0);
  EXPECT_EQ(FloatQuad(FloatRect(21.0f, 6.0f, 1.0f, 2.0f)),
            rgm.mapToAncestor(rect, getLayoutBox(webView, "CenterDiv")));

  rgm.pushMappingsToAncestor(getLayoutBox(webView, "OtherDiv"),
                             getLayoutBox(webView, "InnerDiv"));
  EXPECT_EQ(FloatQuad(FloatRect(22.0f, 12.0f, 1.0f, 2.0f)),
            rgm.mapToAncestor(rect, getLayoutBox(webView, "CenterDiv")));

  EXPECT_EQ(FloatQuad(FloatRect(1.0f, 6.0f, 1.0f, 2.0f)),
            rgm.mapToAncestor(rect, getLayoutBox(webView, "InnerDiv")));

  EXPECT_EQ(FloatQuad(FloatRect(50.0f, 44.0f, 1.0f, 2.0f)),
            rgm.mapToAncestor(rect, nullptr));
}

// Fails on Windows due to crbug.com/391457. When run through the transform the
// position on windows differs by a pixel
#if OS(WIN)
TEST_P(LayoutGeometryMapTest, DISABLED_TransformedGeometryTest)
#else
TEST_P(LayoutGeometryMapTest, TransformedGeometryTest)
#endif
{
  registerMockedHttpURLLoad("rgm_transformed_test.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebView* webView = webViewHelper.initializeAndLoad(
      m_baseURL + "rgm_transformed_test.html", true, 0, 0);
  webView->resize(WebSize(1000, 1000));
  webView->updateAllLifecyclePhases();

  LayoutGeometryMap rgm;
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "InitialDiv"), 0);
  const float rectWidth = 15.0f;
  const float scaleWidth = 2.0f;
  const float scaleHeight = 3.0f;
  FloatRect rect(0.0f, 0.0f, 15.0f, 25.0f);
  EXPECT_EQ(FloatQuad(FloatRect(8.0f, 8.0f, 15.0f, 25.0f)),
            rgm.mapToAncestor(rect, nullptr));

  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));
  EXPECT_EQ(FloatQuad(FloatRect(0.0f, 0.0f, 15.0f, 25.0f)).boundingBox(),
            rgm.mapToAncestor(rect, nullptr).boundingBox());

  rgm.pushMappingsToAncestor(getLayoutBox(webView, "InnerDiv"), 0);
  EXPECT_EQ(FloatQuad(FloatRect(523.0f - rectWidth, 6.0f, 15.0f, 25.0f))
                .boundingBox(),
            rgm.mapToAncestor(rect, getLayoutBox(webView, "CenterDiv"))
                .boundingBox());

  rgm.pushMappingsToAncestor(getLayoutBox(webView, "OtherDiv"),
                             getLayoutBox(webView, "InnerDiv"));
  EXPECT_EQ(FloatQuad(FloatRect(522.0f - rectWidth, 12.0f, 15.0f, 25.0f))
                .boundingBox(),
            rgm.mapToAncestor(rect, getLayoutBox(webView, "CenterDiv"))
                .boundingBox());

  EXPECT_EQ(
      FloatQuad(FloatRect(1.0f, 6.0f, 15.0f, 25.0f)).boundingBox(),
      rgm.mapToAncestor(rect, getLayoutBox(webView, "InnerDiv")).boundingBox());

  EXPECT_EQ(FloatQuad(FloatRect(821.0f - rectWidth * scaleWidth, 31.0f,
                                15.0f * scaleWidth, 25.0f * scaleHeight))
                .boundingBox(),
            rgm.mapToAncestor(rect, nullptr).boundingBox());

  rect = FloatRect(10.0f, 25.0f, 15.0f, 25.0f);
  EXPECT_EQ(FloatQuad(FloatRect(512.0f - rectWidth, 37.0f, 15.0f, 25.0f))
                .boundingBox(),
            rgm.mapToAncestor(rect, getLayoutBox(webView, "CenterDiv"))
                .boundingBox());

  EXPECT_EQ(
      FloatQuad(FloatRect(11.0f, 31.0f, 15.0f, 25.0f)).boundingBox(),
      rgm.mapToAncestor(rect, getLayoutBox(webView, "InnerDiv")).boundingBox());

  EXPECT_EQ(FloatQuad(FloatRect(801.0f - rectWidth * scaleWidth, 106.0f,
                                15.0f * scaleWidth, 25.0f * scaleHeight))
                .boundingBox(),
            rgm.mapToAncestor(rect, nullptr).boundingBox());
}

TEST_P(LayoutGeometryMapTest, FixedGeometryTest) {
  registerMockedHttpURLLoad("rgm_fixed_position_test.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebView* webView = webViewHelper.initializeAndLoad(
      m_baseURL + "rgm_fixed_position_test.html", true, 0, 0);
  webView->resize(WebSize(1000, 1000));
  webView->updateAllLifecyclePhases();

  LayoutGeometryMap rgm;
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "InitialDiv"), 0);
  FloatRect rect(0.0f, 0.0f, 15.0f, 25.0f);
  EXPECT_EQ(FloatQuad(FloatRect(8.0f, 8.0f, 15.0f, 25.0f)),
            rgm.mapToAncestor(rect, nullptr));

  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));
  EXPECT_EQ(FloatQuad(FloatRect(0.0f, 0.0f, 15.0f, 25.0f)),
            rgm.mapToAncestor(rect, nullptr));

  rgm.pushMappingsToAncestor(getLayoutBox(webView, "InnerDiv"), 0);
  EXPECT_EQ(FloatQuad(FloatRect(20.0f, 14.0f, 15.0f, 25.0f)),
            rgm.mapToAncestor(rect, nullptr));

  rgm.pushMappingsToAncestor(getLayoutBox(webView, "OtherDiv"),
                             getLayoutBox(webView, "InnerDiv"));
  EXPECT_EQ(FloatQuad(FloatRect(21.0f, 20.0f, 15.0f, 25.0f)),
            rgm.mapToAncestor(rect, getLayoutContainer(webView, "CenterDiv")));

  rect = FloatRect(22.0f, 15.2f, 15.3f, 0.0f);
  EXPECT_EQ(FloatQuad(FloatRect(43.0f, 35.2f, 15.3f, 0.0f)),
            rgm.mapToAncestor(rect, getLayoutContainer(webView, "CenterDiv")));

  EXPECT_EQ(FloatQuad(FloatRect(43.0f, 35.2f, 15.3f, 0.0f)),
            rgm.mapToAncestor(rect, getLayoutContainer(webView, "InnerDiv")));

  EXPECT_EQ(FloatQuad(FloatRect(43.0f, 35.2f, 15.3f, 0.0f)),
            rgm.mapToAncestor(rect, nullptr));
}

TEST_P(LayoutGeometryMapTest, ContainsFixedPositionTest) {
  registerMockedHttpURLLoad("rgm_contains_fixed_position_test.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebView* webView = webViewHelper.initializeAndLoad(
      m_baseURL + "rgm_contains_fixed_position_test.html", true, 0, 0);
  webView->resize(WebSize(1000, 1000));
  webView->updateAllLifecyclePhases();

  FloatRect rect(0.0f, 0.0f, 100.0f, 100.0f);
  LayoutGeometryMap rgm;

  // This fixed position element is not contained and so is attached at the top
  // of the viewport.
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "simple-container"), 0);
  EXPECT_EQ(FloatRect(8.0f, 100.0f, 100.0f, 100.0f),
            adjustForFrameScroll(webView, rgm.absoluteRect(rect)));
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "fixed1"),
                             getLayoutBox(webView, "simple-container"));
  EXPECT_EQ(FloatRect(8.0f, 50.0f, 100.0f, 100.0f),
            adjustForFrameScroll(webView, rgm.absoluteRect(rect)));
  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));

  // Transforms contain fixed position descendants.
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "has-transform"), 0);
  EXPECT_EQ(FloatRect(8.0f, 100.0f, 100.0f, 100.0f),
            adjustForFrameScroll(webView, rgm.absoluteRect(rect)));
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "fixed2"),
                             getLayoutBox(webView, "has-transform"));
  EXPECT_EQ(FloatRect(8.0f, 100.0f, 100.0f, 100.0f),
            adjustForFrameScroll(webView, rgm.absoluteRect(rect)));
  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));

  // Paint containment contains fixed position descendants.
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "contains-paint"), 0);
  EXPECT_EQ(FloatRect(8.0f, 100.0f, 100.0f, 100.0f),
            adjustForFrameScroll(webView, rgm.absoluteRect(rect)));
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "fixed3"),
                             getLayoutBox(webView, "contains-paint"));
  EXPECT_EQ(FloatRect(8.0f, 100.0f, 100.0f, 100.0f),
            adjustForFrameScroll(webView, rgm.absoluteRect(rect)));
  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));
}

TEST_P(LayoutGeometryMapTest, IframeTest) {
  registerMockedHttpURLLoad("rgm_iframe_test.html");
  registerMockedHttpURLLoad("rgm_test.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebView* webView = webViewHelper.initializeAndLoad(
      m_baseURL + "rgm_iframe_test.html", true, 0, 0);
  webView->resize(WebSize(1000, 1000));
  webView->updateAllLifecyclePhases();

  LayoutGeometryMap rgm(TraverseDocumentBoundaries);
  LayoutGeometryMap rgmNoFrame;

  rgmNoFrame.pushMappingsToAncestor(
      getFrameElement("test_frame", webView, "InitialDiv"), 0);
  rgm.pushMappingsToAncestor(
      getFrameElement("test_frame", webView, "InitialDiv"), 0);
  FloatRect rect(0.0f, 0.0f, 1.0f, 2.0f);

  EXPECT_EQ(FloatQuad(FloatRect(8.0f, 8.0f, 1.0f, 2.0f)),
            rgmNoFrame.mapToAncestor(rect, nullptr));

  // Our initial rect looks like: (0, 0, 1, 2)
  //        p0_____
  //          |   |
  //          |   |
  //          |   |
  //          |___|
  // When we rotate we get a rect of the form:
  //         p0_
  //          / -_
  //         /   /
  //        /   /
  //         -_/
  // So it is sensible that the minimum y is the same as for a point at 0, 0.
  // The minimum x should be p0.x - 2 * sin(30deg) = p0.x - 1.
  // That maximum x should likewise be p0.x + cos(30deg) = p0.x + 0.866.
  // And the maximum y should be p0.x + sin(30deg) + 2*cos(30deg)
  //      = p0.y + 2.232.
  EXPECT_NEAR(69.5244f, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).x(),
              0.0001f);
  EXPECT_NEAR(-44.0237, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).y(),
              0.0001f);
  EXPECT_NEAR(1.866, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).width(),
              0.0001f);
  EXPECT_NEAR(2.232, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).height(),
              0.0001f);

  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));
  rgmNoFrame.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));

  rgm.pushMappingsToAncestor(getFrameElement("test_frame", webView, "InnerDiv"),
                             0);
  rgmNoFrame.pushMappingsToAncestor(
      getFrameElement("test_frame", webView, "InnerDiv"), 0);
  EXPECT_EQ(FloatQuad(FloatRect(21.0f, 6.0f, 1.0f, 2.0f)),
            rgm.mapToAncestor(rect, getFrameLayoutContainer(
                                        "test_frame", webView, "CenterDiv")));
  EXPECT_EQ(
      FloatQuad(FloatRect(21.0f, 6.0f, 1.0f, 2.0f)),
      rgmNoFrame.mapToAncestor(
          rect, getFrameLayoutContainer("test_frame", webView, "CenterDiv")));

  rgm.pushMappingsToAncestor(
      getFrameElement("test_frame", webView, "OtherDiv"),
      getFrameLayoutContainer("test_frame", webView, "InnerDiv"));
  rgmNoFrame.pushMappingsToAncestor(
      getFrameElement("test_frame", webView, "OtherDiv"),
      getFrameLayoutContainer("test_frame", webView, "InnerDiv"));
  EXPECT_EQ(FloatQuad(FloatRect(22.0f, 12.0f, 1.0f, 2.0f)),
            rgm.mapToAncestor(rect, getFrameLayoutContainer(
                                        "test_frame", webView, "CenterDiv")));
  EXPECT_EQ(
      FloatQuad(FloatRect(22.0f, 12.0f, 1.0f, 2.0f)),
      rgmNoFrame.mapToAncestor(
          rect, getFrameLayoutContainer("test_frame", webView, "CenterDiv")));

  EXPECT_EQ(FloatQuad(FloatRect(1.0f, 6.0f, 1.0f, 2.0f)),
            rgm.mapToAncestor(rect, getFrameLayoutContainer(
                                        "test_frame", webView, "InnerDiv")));
  EXPECT_EQ(
      FloatQuad(FloatRect(1.0f, 6.0f, 1.0f, 2.0f)),
      rgmNoFrame.mapToAncestor(
          rect, getFrameLayoutContainer("test_frame", webView, "InnerDiv")));

  EXPECT_NEAR(87.8975f, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).x(),
              0.0001f);
  EXPECT_NEAR(8.1532f, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).y(),
              0.0001f);
  EXPECT_NEAR(1.866, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).width(),
              0.0001f);
  EXPECT_NEAR(2.232, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).height(),
              0.0001f);

  EXPECT_EQ(FloatQuad(FloatRect(50.0f, 44.0f, 1.0f, 2.0f)),
            rgmNoFrame.mapToAncestor(rect, nullptr));
}

TEST_P(LayoutGeometryMapTest, ColumnTest) {
  registerMockedHttpURLLoad("rgm_column_test.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebView* webView = webViewHelper.initializeAndLoad(
      m_baseURL + "rgm_column_test.html", true, 0, 0);
  webView->resize(WebSize(1000, 1000));
  webView->updateAllLifecyclePhases();

  // The document is 1000f wide (we resized to that size).
  // We have a 8px margin on either side of the document.
  // Between each column we have a 10px gap, and we have 3 columns.
  // The width of a given column is (1000 - 16 - 20)/3.
  // The total offset between any column and it's neighbour is width + 10px
  // (for the gap).
  float offset = (1000.0f - 16.0f - 20.0f) / 3.0f + 10.0f;

  LayoutGeometryMap rgm;
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "A"), 0);
  FloatPoint point;
  FloatRect rect(0.0f, 0.0f, 5.0f, 3.0f);

  EXPECT_EQ(FloatQuad(FloatRect(8.0f, 8.0f, 5.0f, 3.0f)),
            rgm.mapToAncestor(rect, nullptr));

  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));
  EXPECT_EQ(FloatQuad(FloatRect(0.0f, 0.0f, 5.0f, 3.0f)),
            rgm.mapToAncestor(rect, nullptr));

  rgm.pushMappingsToAncestor(getLayoutBox(webView, "Col1"), 0);
  EXPECT_EQ(FloatQuad(FloatRect(8.0f, 8.0f, 5.0f, 3.0f)),
            rgm.mapToAncestor(rect, nullptr));

  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "Col2"), nullptr);
  EXPECT_NEAR(8.0f + offset, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).x(),
              0.1f);
  EXPECT_NEAR(8.0f, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).y(), 0.1f);
  EXPECT_EQ(5.0f, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).width());
  EXPECT_EQ(3.0f, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).height());

  rgm.popMappingsToAncestor(static_cast<PaintLayer*>(nullptr));
  rgm.pushMappingsToAncestor(getLayoutBox(webView, "Col3"), nullptr);
  EXPECT_NEAR(8.0f + offset * 2.0f,
              rectFromQuad(rgm.mapToAncestor(rect, nullptr)).x(), 0.1f);
  EXPECT_NEAR(8.0f, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).y(), 0.1f);
  EXPECT_EQ(5.0f, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).width());
  EXPECT_EQ(3.0f, rectFromQuad(rgm.mapToAncestor(rect, nullptr)).height());
}

}  // namespace blink
