/* * 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 "third_party/blink/renderer/core/layout/layout_geometry_map.h" #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" #include "third_party/blink/public/web/web_local_frame_client.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/frame/frame_test_helpers.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/paint/paint_layer.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/testing/url_test_helpers.h" namespace blink { class LayoutGeometryMapTest : public testing::Test { public: LayoutGeometryMapTest() : base_url_("http://www.test.com/") {} void TearDown() override { url_test_helpers::UnregisterAllURLsAndClearMemoryCache(); } protected: static LayoutBox* GetFrameElement(const char* iframe_name, WebView* web_view, const WTF::AtomicString& element_id) { WebFrame* iframe = static_cast(web_view)->MainFrameImpl()->FindFrameByName( WebString::FromUTF8(iframe_name)); auto* web_local_frame = DynamicTo(iframe); if (!web_local_frame) return nullptr; LocalFrame* frame = web_local_frame->GetFrame(); Document* doc = frame->GetDocument(); Element* element = doc->getElementById(element_id); if (!element) return nullptr; return element->GetLayoutBox(); } static Element* GetElement(WebView* web_view, const WTF::AtomicString& element_id) { WebViewImpl* web_view_impl = static_cast(web_view); if (!web_view_impl) return nullptr; LocalFrame* frame = web_view_impl->MainFrameImpl()->GetFrame(); Document* doc = frame->GetDocument(); return doc->getElementById(element_id); } static LayoutBox* GetLayoutBox(WebView* web_view, const WTF::AtomicString& element_id) { Element* element = GetElement(web_view, element_id); if (!element) return nullptr; return element->GetLayoutBox(); } static const LayoutBoxModelObject* GetLayoutContainer( WebView* web_view, const WTF::AtomicString& element_id) { LayoutBox* rb = GetLayoutBox(web_view, element_id); if (!rb) return nullptr; PaintLayer* compositing_layer = rb->EnclosingLayer()->EnclosingLayerForPaintInvalidation(); if (!compositing_layer) return nullptr; return &compositing_layer->GetLayoutObject(); } static const LayoutBoxModelObject* GetFrameLayoutContainer( const char* frame_id, WebView* web_view, const WTF::AtomicString& element_id) { LayoutBox* rb = GetFrameElement(frame_id, web_view, element_id); if (!rb) return nullptr; PaintLayer* compositing_layer = rb->EnclosingLayer()->EnclosingLayerForPaintInvalidation(); if (!compositing_layer) return nullptr; return &compositing_layer->GetLayoutObject(); } // 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 PhysicalRect AdjustForFrameScroll(WebView* web_view, const PhysicalRect& rect) { PhysicalRect result(rect); LocalFrame* frame = static_cast(web_view)->MainFrameImpl()->GetFrame(); LayoutView* layout_view = frame->GetDocument()->GetLayoutView(); if (layout_view->HasOverflowClip()) result.Move(PhysicalOffset(layout_view->ScrolledContentOffset())); return result; } void RegisterMockedHttpURLLoad(const std::string& file_name) { // TODO(crbug.com/751425): We should use the mock functionality // via the WebViewHelper instance in each test case. url_test_helpers::RegisterMockedURLLoadFromBase( WebString::FromUTF8(base_url_), test::CoreTestDataPath(), WebString::FromUTF8(file_name)); } void UpdateAllLifecyclePhases(WebView* web_view) { web_view->MainFrameWidget()->UpdateAllLifecyclePhases( DocumentUpdateReason::kTest); } const std::string base_url_; }; TEST_F(LayoutGeometryMapTest, SimpleGeometryMapTest) { RegisterMockedHttpURLLoad("rgm_test.html"); frame_test_helpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad(base_url_ + "rgm_test.html"); web_view->MainFrameWidget()->Resize(WebSize(1000, 1000)); UpdateAllLifecyclePhases(web_view); // 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(web_view, "InitialDiv"), nullptr); PhysicalRect rect(0, 0, 1, 2); EXPECT_EQ(PhysicalRect(8, 8, 1, 2), rgm.MapToAncestor(rect, nullptr)); rgm.PopMappingsToAncestor(static_cast(nullptr)); EXPECT_EQ(rect, rgm.MapToAncestor(rect, nullptr)); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "InnerDiv"), nullptr); EXPECT_EQ(PhysicalRect(21, 6, 1, 2), rgm.MapToAncestor(rect, GetLayoutBox(web_view, "CenterDiv"))); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "OtherDiv"), GetLayoutBox(web_view, "InnerDiv")); EXPECT_EQ(PhysicalRect(22, 12, 1, 2), rgm.MapToAncestor(rect, GetLayoutBox(web_view, "CenterDiv"))); EXPECT_EQ(PhysicalRect(1, 6, 1, 2), rgm.MapToAncestor(rect, GetLayoutBox(web_view, "InnerDiv"))); EXPECT_EQ(PhysicalRect(50, 44, 1, 2), 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 defined(OS_WIN) TEST_F(LayoutGeometryMapTest, DISABLED_TransformedGeometryTest) #else TEST_F(LayoutGeometryMapTest, TransformedGeometryTest) #endif { RegisterMockedHttpURLLoad("rgm_transformed_test.html"); frame_test_helpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( base_url_ + "rgm_transformed_test.html"); web_view->MainFrameWidget()->Resize(WebSize(1000, 1000)); UpdateAllLifecyclePhases(web_view); LayoutGeometryMap rgm; rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "InitialDiv"), nullptr); const int kRectWidth = 15; const int kScaleWidth = 2; const int kScaleHeight = 3; PhysicalRect rect(0, 0, 15, 25); EXPECT_EQ(PhysicalRect(8, 8, 15, 25), rgm.MapToAncestor(rect, nullptr)); rgm.PopMappingsToAncestor(static_cast(nullptr)); EXPECT_EQ(PhysicalRect(0, 0, 15, 25), rgm.MapToAncestor(rect, nullptr)); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "InnerDiv"), nullptr); EXPECT_EQ(PhysicalRect(523.0f - kRectWidth, 6, 15, 25), rgm.MapToAncestor(rect, GetLayoutBox(web_view, "CenterDiv"))); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "OtherDiv"), GetLayoutBox(web_view, "InnerDiv")); EXPECT_EQ(PhysicalRect(522.0f - kRectWidth, 12, 15, 25), rgm.MapToAncestor(rect, GetLayoutBox(web_view, "CenterDiv"))); EXPECT_EQ(PhysicalRect(1, 6, 15, 25), rgm.MapToAncestor(rect, GetLayoutBox(web_view, "InnerDiv"))); EXPECT_EQ(PhysicalRect(821 - kRectWidth * kScaleWidth, 31, 15 * kScaleWidth, 25 * kScaleHeight), rgm.MapToAncestor(rect, nullptr)); rect = PhysicalRect(10, 25, 15, 25); EXPECT_EQ(PhysicalRect(512.0f - kRectWidth, 37, 15, 25), rgm.MapToAncestor(rect, GetLayoutBox(web_view, "CenterDiv"))); EXPECT_EQ(PhysicalRect(11, 31, 15, 25), rgm.MapToAncestor(rect, GetLayoutBox(web_view, "InnerDiv"))); EXPECT_EQ(PhysicalRect(801 - kRectWidth * kScaleWidth, 106, 15 * kScaleWidth, 25 * kScaleHeight), rgm.MapToAncestor(rect, nullptr)); } TEST_F(LayoutGeometryMapTest, FixedGeometryTest) { RegisterMockedHttpURLLoad("rgm_fixed_position_test.html"); frame_test_helpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( base_url_ + "rgm_fixed_position_test.html"); web_view->MainFrameWidget()->Resize(WebSize(1000, 1000)); UpdateAllLifecyclePhases(web_view); LayoutGeometryMap rgm; rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "InitialDiv"), nullptr); PhysicalRect rect(0, 0, 15, 25); EXPECT_EQ(PhysicalRect(8, 8, 15, 25), rgm.MapToAncestor(rect, nullptr)); rgm.PopMappingsToAncestor(static_cast(nullptr)); EXPECT_EQ(PhysicalRect(0, 0, 15, 25), rgm.MapToAncestor(rect, nullptr)); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "InnerDiv"), nullptr); EXPECT_EQ(PhysicalRect(20, 14, 15, 25), rgm.MapToAncestor(rect, nullptr)); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "OtherDiv"), GetLayoutBox(web_view, "InnerDiv")); EXPECT_EQ(PhysicalRect(21, 20, 15, 25), rgm.MapToAncestor(rect, GetLayoutContainer(web_view, "CenterDiv"))); rect = PhysicalRect(LayoutUnit(22), LayoutUnit(15.2f), LayoutUnit(15.3f), LayoutUnit()); EXPECT_EQ(PhysicalRect(LayoutUnit(43), LayoutUnit(35.2f), rect.Width(), rect.Height()), rgm.MapToAncestor(rect, GetLayoutContainer(web_view, "CenterDiv"))); EXPECT_EQ(PhysicalRect(LayoutUnit(43), LayoutUnit(35.2f), rect.Width(), rect.Height()), rgm.MapToAncestor(rect, GetLayoutContainer(web_view, "InnerDiv"))); EXPECT_EQ(PhysicalRect(LayoutUnit(43), LayoutUnit(35.2f), rect.Width(), rect.Height()), rgm.MapToAncestor(rect, nullptr)); } TEST_F(LayoutGeometryMapTest, ContainsFixedPositionTest) { RegisterMockedHttpURLLoad("rgm_contains_fixed_position_test.html"); frame_test_helpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( base_url_ + "rgm_contains_fixed_position_test.html"); web_view->MainFrameWidget()->Resize(WebSize(1000, 1000)); UpdateAllLifecyclePhases(web_view); PhysicalRect rect(0, 0, 100, 100); LayoutGeometryMap rgm; // This fixed position element is not contained and so is attached at the top // of the viewport. rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "simple-container"), nullptr); EXPECT_EQ(PhysicalRect(8, 100, 100, 100), AdjustForFrameScroll(web_view, rgm.AbsoluteRect(rect))); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "fixed1"), GetLayoutBox(web_view, "simple-container")); EXPECT_EQ(PhysicalRect(8, 50, 100, 100), AdjustForFrameScroll(web_view, rgm.AbsoluteRect(rect))); EXPECT_EQ( PhysicalRect(0, -50, 100, 100), rgm.MapToAncestor(rect, GetLayoutBox(web_view, "simple-container"))); rgm.PopMappingsToAncestor(static_cast(nullptr)); // Transforms contain fixed position descendants. rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "has-transform"), nullptr); EXPECT_EQ(PhysicalRect(8, 100, 100, 100), AdjustForFrameScroll(web_view, rgm.AbsoluteRect(rect))); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "fixed2"), GetLayoutBox(web_view, "has-transform")); EXPECT_EQ(PhysicalRect(8, 100, 100, 100), AdjustForFrameScroll(web_view, rgm.AbsoluteRect(rect))); rgm.PopMappingsToAncestor(static_cast(nullptr)); // Paint containment contains fixed position descendants. rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "contains-paint"), nullptr); EXPECT_EQ(PhysicalRect(8, 100, 100, 100), AdjustForFrameScroll(web_view, rgm.AbsoluteRect(rect))); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "fixed3"), GetLayoutBox(web_view, "contains-paint")); EXPECT_EQ(PhysicalRect(8, 100, 100, 100), AdjustForFrameScroll(web_view, rgm.AbsoluteRect(rect))); rgm.PopMappingsToAncestor(static_cast(nullptr)); } TEST_F(LayoutGeometryMapTest, IframeTest) { RegisterMockedHttpURLLoad("rgm_iframe_test.html"); RegisterMockedHttpURLLoad("rgm_test.html"); frame_test_helpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad(base_url_ + "rgm_iframe_test.html"); web_view->MainFrameWidget()->Resize(WebSize(1000, 1000)); UpdateAllLifecyclePhases(web_view); LayoutGeometryMap rgm(kTraverseDocumentBoundaries); LayoutGeometryMap rgm_no_frame; rgm_no_frame.PushMappingsToAncestor( GetFrameElement("test_frame", web_view, "InitialDiv"), nullptr); rgm.PushMappingsToAncestor( GetFrameElement("test_frame", web_view, "InitialDiv"), nullptr); PhysicalRect rect(0, 0, 1, 2); EXPECT_EQ(PhysicalRect(8, 8, 1, 2), rgm_no_frame.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. FloatRect mapped_bounding_box = rgm.MapToAncestorQuad(rect, nullptr).BoundingBox(); EXPECT_NEAR(69.5244f, mapped_bounding_box.X(), 0.0001f); EXPECT_NEAR(-44.0237, mapped_bounding_box.Y(), 0.0001f); EXPECT_NEAR(1.866, mapped_bounding_box.Width(), 0.0001f); EXPECT_NEAR(2.232, mapped_bounding_box.Height(), 0.0001f); rgm.PopMappingsToAncestor(static_cast(nullptr)); rgm_no_frame.PopMappingsToAncestor(static_cast(nullptr)); rgm.PushMappingsToAncestor( GetFrameElement("test_frame", web_view, "InnerDiv"), nullptr); rgm_no_frame.PushMappingsToAncestor( GetFrameElement("test_frame", web_view, "InnerDiv"), nullptr); EXPECT_EQ(PhysicalRect(21, 6, 1, 2), rgm.MapToAncestor(rect, GetFrameLayoutContainer( "test_frame", web_view, "CenterDiv"))); EXPECT_EQ( PhysicalRect(21, 6, 1, 2), rgm_no_frame.MapToAncestor( rect, GetFrameLayoutContainer("test_frame", web_view, "CenterDiv"))); rgm.PushMappingsToAncestor( GetFrameElement("test_frame", web_view, "OtherDiv"), GetFrameLayoutContainer("test_frame", web_view, "InnerDiv")); rgm_no_frame.PushMappingsToAncestor( GetFrameElement("test_frame", web_view, "OtherDiv"), GetFrameLayoutContainer("test_frame", web_view, "InnerDiv")); EXPECT_EQ(PhysicalRect(22, 12, 1, 2), rgm.MapToAncestor(rect, GetFrameLayoutContainer( "test_frame", web_view, "CenterDiv"))); EXPECT_EQ( PhysicalRect(22, 12, 1, 2), rgm_no_frame.MapToAncestor( rect, GetFrameLayoutContainer("test_frame", web_view, "CenterDiv"))); EXPECT_EQ(PhysicalRect(1, 6, 1, 2), rgm.MapToAncestor(rect, GetFrameLayoutContainer( "test_frame", web_view, "InnerDiv"))); EXPECT_EQ( PhysicalRect(1, 6, 1, 2), rgm_no_frame.MapToAncestor( rect, GetFrameLayoutContainer("test_frame", web_view, "InnerDiv"))); mapped_bounding_box = rgm.MapToAncestorQuad(rect, nullptr).BoundingBox(); EXPECT_NEAR(87.8975f, mapped_bounding_box.X(), 0.0001f); EXPECT_NEAR(8.1532f, mapped_bounding_box.Y(), 0.0001f); EXPECT_NEAR(1.866, mapped_bounding_box.Width(), 0.0001f); EXPECT_NEAR(2.232, mapped_bounding_box.Height(), 0.0001f); EXPECT_EQ(PhysicalRect(50, 44, 1, 2), rgm_no_frame.MapToAncestor(rect, nullptr)); } TEST_F(LayoutGeometryMapTest, ColumnTest) { RegisterMockedHttpURLLoad("rgm_column_test.html"); frame_test_helpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad(base_url_ + "rgm_column_test.html"); web_view->MainFrameWidget()->Resize(WebSize(1000, 1000)); UpdateAllLifecyclePhases(web_view); // 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(web_view, "A"), nullptr); PhysicalRect rect(0, 0, 5, 3); EXPECT_EQ(PhysicalRect(8, 8, 5, 3), rgm.MapToAncestor(rect, nullptr)); rgm.PopMappingsToAncestor(static_cast(nullptr)); EXPECT_EQ(PhysicalRect(0, 0, 5, 3), rgm.MapToAncestor(rect, nullptr)); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "Col1"), nullptr); EXPECT_EQ(PhysicalRect(8, 8, 5, 3), rgm.MapToAncestor(rect, nullptr)); rgm.PopMappingsToAncestor(static_cast(nullptr)); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "Col2"), nullptr); PhysicalRect mapped_rect = rgm.MapToAncestor(rect, nullptr); EXPECT_NEAR(8.0f + offset, mapped_rect.X().ToFloat(), 0.1f); EXPECT_NEAR(8.0f, mapped_rect.Y().ToFloat(), 0.1f); EXPECT_EQ(PhysicalSize(5, 3), mapped_rect.size); rgm.PopMappingsToAncestor(static_cast(nullptr)); rgm.PushMappingsToAncestor(GetLayoutBox(web_view, "Col3"), nullptr); mapped_rect = rgm.MapToAncestor(rect, nullptr); EXPECT_NEAR(8.0f + offset * 2.0f, mapped_rect.X().ToFloat(), 0.1f); EXPECT_NEAR(8.0f, mapped_rect.Y().ToFloat(), 0.1f); EXPECT_EQ(PhysicalSize(5, 3), mapped_rect.size); } TEST_F(LayoutGeometryMapTest, FloatUnderInlineLayer) { RegisterMockedHttpURLLoad("rgm_float_under_inline.html"); frame_test_helpers::WebViewHelper web_view_helper; WebView* web_view = web_view_helper.InitializeAndLoad( base_url_ + "rgm_float_under_inline.html"); web_view->MainFrameWidget()->Resize(WebSize(1000, 1000)); UpdateAllLifecyclePhases(web_view); LayoutGeometryMap rgm; auto* layer_under_float = GetLayoutBox(web_view, "layer-under-float"); auto* span = GetElement(web_view, "span")->GetLayoutBoxModelObject(); auto* floating = GetLayoutBox(web_view, "float"); auto* container = GetLayoutBox(web_view, "container"); PhysicalRect rect(3, 4, 10, 8); rgm.PushMappingsToAncestor(container->Layer(), nullptr); rgm.PushMappingsToAncestor(span->Layer(), container->Layer()); rgm.PushMappingsToAncestor(layer_under_float->Layer(), span->Layer()); if (RuntimeEnabledFeatures::LayoutNGEnabled()) { // LayoutNG inline-level floats are children of their inline-level // containers. As such they are positioned relative to their inline-level // container, (and shifted by an additional 200,100 in this case). EXPECT_EQ(PhysicalRect(203, 104, 10, 8), rgm.MapToAncestor(rect, container)); EXPECT_EQ(PhysicalRect(263, 154, 10, 8), rgm.MapToAncestor(rect, nullptr)); } else { EXPECT_EQ(rect, rgm.MapToAncestor(rect, container)); EXPECT_EQ(PhysicalRect(63, 54, 10, 8), rgm.MapToAncestor(rect, nullptr)); } rgm.PopMappingsToAncestor(span->Layer()); EXPECT_EQ(PhysicalRect(203, 104, 10, 8), rgm.MapToAncestor(rect, container)); EXPECT_EQ(PhysicalRect(263, 154, 10, 8), rgm.MapToAncestor(rect, nullptr)); rgm.PushMappingsToAncestor(floating, span); if (RuntimeEnabledFeatures::LayoutNGEnabled()) { EXPECT_EQ(PhysicalRect(203, 104, 10, 8), rgm.MapToAncestor(rect, container)); EXPECT_EQ(PhysicalRect(263, 154, 10, 8), rgm.MapToAncestor(rect, nullptr)); } else { EXPECT_EQ(rect, rgm.MapToAncestor(rect, container)); EXPECT_EQ(PhysicalRect(63, 54, 10, 8), rgm.MapToAncestor(rect, nullptr)); } } } // namespace blink