Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/graphics/paint/GeometryMapper.h" | 5 #include "platform/graphics/paint/GeometryMapper.h" |
| 6 | 6 |
| 7 #include "platform/geometry/GeometryTestHelpers.h" | 7 #include "platform/geometry/GeometryTestHelpers.h" |
| 8 #include "platform/geometry/LayoutRect.h" | 8 #include "platform/geometry/LayoutRect.h" |
| 9 #include "platform/graphics/paint/ClipPaintPropertyNode.h" | 9 #include "platform/graphics/paint/ClipPaintPropertyNode.h" |
| 10 #include "platform/graphics/paint/EffectPaintPropertyNode.h" | 10 #include "platform/graphics/paint/EffectPaintPropertyNode.h" |
| 11 #include "platform/graphics/paint/TransformPaintPropertyNode.h" | 11 #include "platform/graphics/paint/TransformPaintPropertyNode.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 13 | 13 |
| 14 namespace blink { | 14 namespace blink { |
| 15 | 15 |
| 16 class GeometryMapperTest : public ::testing::Test { | 16 class GeometryMapperTest : public ::testing::Test { |
| 17 public: | 17 public: |
| 18 RefPtr<TransformPaintPropertyNode> rootTransformNode; | 18 RefPtr<TransformPaintPropertyNode> rootTransformNode; |
| 19 RefPtr<ClipPaintPropertyNode> rootClipNode; | 19 RefPtr<ClipPaintPropertyNode> rootClipNode; |
| 20 RefPtr<EffectPaintPropertyNode> rootEffectNode; | 20 RefPtr<EffectPaintPropertyNode> rootEffectNode; |
| 21 | 21 |
| 22 std::unique_ptr<GeometryMapper> geometryMapper; | 22 std::unique_ptr<GeometryMapper> geometryMapper; |
| 23 | 23 |
| 24 PropertyTreeState rootPropertyTreeState() | 24 PropertyTreeState rootPropertyTreeState() |
| 25 { | 25 { |
| 26 PropertyTreeState state(rootTransformNode.get(), rootClipNode.get(), roo tEffectNode.get()); | 26 PropertyTreeState state(rootTransformNode.get(), rootClipNode.get(), roo tEffectNode.get()); |
| 27 return state; | 27 return state; |
| 28 } | 28 } |
| 29 | 29 |
| 30 PrecomputedDataForAncestor& GetPrecomputedDataForAncestor(const PropertyTree State& propertyTreeState) | 30 PrecomputedDataForAncestor& getPrecomputedDataForAncestor(const PropertyTree State& propertyTreeState) |
| 31 { | 31 { |
| 32 return geometryMapper->GetPrecomputedDataForAncestor(propertyTreeState); | 32 return geometryMapper->getPrecomputedDataForAncestor(propertyTreeState); |
| 33 } | 33 } |
| 34 | 34 |
| 35 PassRefPtr<TransformPaintPropertyNode> leastCommonAncestor(PassRefPtr<Transf ormPaintPropertyNode> a, PassRefPtr<TransformPaintPropertyNode> b) | |
| 36 { | |
| 37 return geometryMapper->leastCommonAncestor(a, b); | |
| 38 } | |
| 39 | |
|
pdr.
2016/06/30 21:21:50
Nit: extra newline
chrishtr
2016/07/01 17:52:24
Done.
| |
| 40 | |
| 35 private: | 41 private: |
| 36 void SetUp() override | 42 void SetUp() override |
| 37 { | 43 { |
| 38 rootTransformNode = TransformPaintPropertyNode::create(TransformationMat rix(), FloatPoint3D(), nullptr); | 44 rootTransformNode = TransformPaintPropertyNode::create(TransformationMat rix(), FloatPoint3D(), nullptr); |
| 39 rootClipNode = ClipPaintPropertyNode::create(rootTransformNode, FloatRou ndedRect(LayoutRect::infiniteIntRect()), nullptr); | 45 rootClipNode = ClipPaintPropertyNode::create(rootTransformNode, FloatRou ndedRect(LayoutRect::infiniteIntRect()), nullptr); |
| 40 rootEffectNode = EffectPaintPropertyNode::create(1.0, nullptr); | 46 rootEffectNode = EffectPaintPropertyNode::create(1.0, nullptr); |
| 41 geometryMapper = wrapUnique(new GeometryMapper()); | 47 geometryMapper = wrapUnique(new GeometryMapper()); |
| 42 } | 48 } |
| 43 | 49 |
| 44 void TearDown() override | 50 void TearDown() override |
| 45 { | 51 { |
| 46 geometryMapper.reset(); | 52 geometryMapper.reset(); |
| 47 } | 53 } |
| 48 }; | 54 }; |
| 49 | 55 |
| 50 const static float kTestEpsilon = 1e-6; | 56 const static float kTestEpsilon = 1e-6; |
| 51 | 57 |
| 52 #define EXPECT_RECT_EQ(expected, actual) \ | 58 #define EXPECT_RECT_EQ(expected, actual) \ |
| 53 do { \ | 59 do { \ |
| 54 const FloatRect& actualRect = actual; \ | 60 const FloatRect& actualRect = actual; \ |
| 55 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.x(), actualRect.x(), k TestEpsilon)) << "actual: " << actualRect.x() << ", expected: " << expected.x(); \ | 61 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.x(), actualRect.x(), k TestEpsilon)) << "actual: " << actualRect.x() << ", expected: " << expected.x(); \ |
| 56 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.y(), actualRect.y(), k TestEpsilon)) << "actual: " << actualRect.y() << ", expected: " << expected.y(); \ | 62 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.y(), actualRect.y(), k TestEpsilon)) << "actual: " << actualRect.y() << ", expected: " << expected.y(); \ |
| 57 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.width(), actualRect.wi dth(), kTestEpsilon)) << "actual: " << actualRect.width() << ", expected: " << e xpected.width(); \ | 63 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.width(), actualRect.wi dth(), kTestEpsilon)) << "actual: " << actualRect.width() << ", expected: " << e xpected.width(); \ |
| 58 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.height(), actualRect.h eight(), kTestEpsilon)) << "actual: " << actualRect.height() << ", expected: " < < expected.height(); \ | 64 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.height(), actualRect.h eight(), kTestEpsilon)) << "actual: " << actualRect.height() << ", expected: " < < expected.height(); \ |
| 59 } while (false) | 65 } while (false) |
| 60 | 66 |
| 61 #define CHECK_MAPPINGS(inputRect, expectedVisualRect, expectedTransformedRect, e xpectedTransformToAncestor, expectedClipInAncestorSpace, localPropertyTreeState, ancestorPropertyTreeState) \ | 67 #define CHECK_MAPPINGS(inputRect, expectedVisualRect, expectedTransformedRect, e xpectedTransformToAncestor, expectedClipInAncestorSpace, localPropertyTreeState, ancestorPropertyTreeState) \ |
| 62 do { \ | 68 do { \ |
| 69 bool success = false; \ | |
| 63 EXPECT_RECT_EQ(expectedVisualRect, \ | 70 EXPECT_RECT_EQ(expectedVisualRect, \ |
| 64 geometryMapper->LocalToVisualRectInAncestorSpace(inputRect, localPropert yTreeState, ancestorPropertyTreeState)); \ | 71 geometryMapper->localToVisualRectInAncestorSpace(inputRect, localPropert yTreeState, ancestorPropertyTreeState, &success)); \ |
| 72 EXPECT_TRUE(success); \ | |
| 65 EXPECT_RECT_EQ(expectedTransformedRect, \ | 73 EXPECT_RECT_EQ(expectedTransformedRect, \ |
| 66 geometryMapper->LocalToAncestorRect(inputRect, localPropertyTreeState, a ncestorPropertyTreeState)); \ | 74 geometryMapper->localToAncestorRect(inputRect, localPropertyTreeState, a ncestorPropertyTreeState, &success)); \ |
| 67 EXPECT_EQ(expectedTransformToAncestor, GetPrecomputedDataForAncestor(ancesto rPropertyTreeState).toAncestorTransforms.get(localPropertyTreeState.transform)); \ | 75 EXPECT_TRUE(success); \ |
| 68 EXPECT_EQ(expectedClipInAncestorSpace, GetPrecomputedDataForAncestor(ancesto rPropertyTreeState).toAncestorClipRects.get(localPropertyTreeState.clip)); \ | 76 EXPECT_EQ(expectedTransformToAncestor, getPrecomputedDataForAncestor(ancesto rPropertyTreeState).toAncestorTransforms.get(localPropertyTreeState.transform.ge t())); \ |
| 77 EXPECT_EQ(expectedClipInAncestorSpace, getPrecomputedDataForAncestor(ancesto rPropertyTreeState).toAncestorClipRects.get(localPropertyTreeState.clip.get())); \ | |
| 69 } while (false) | 78 } while (false) |
| 70 | 79 |
| 71 TEST_F(GeometryMapperTest, Root) | 80 TEST_F(GeometryMapperTest, Root) |
| 72 { | 81 { |
| 73 FloatRect input(0, 0, 100, 100); | 82 FloatRect input(0, 0, 100, 100); |
| 74 | 83 |
| 75 CHECK_MAPPINGS(input, input, input, rootTransformNode->matrix(), rootClipNod e->clipRect().rect(), rootPropertyTreeState(), rootPropertyTreeState()); | 84 CHECK_MAPPINGS(input, input, input, rootTransformNode->matrix(), rootClipNod e->clipRect().rect(), rootPropertyTreeState(), rootPropertyTreeState()); |
| 76 } | 85 } |
| 77 | 86 |
| 78 TEST_F(GeometryMapperTest, IdentityTransform) | 87 TEST_F(GeometryMapperTest, IdentityTransform) |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 94 PropertyTreeState localState = rootPropertyTreeState(); | 103 PropertyTreeState localState = rootPropertyTreeState(); |
| 95 localState.transform = transform.get(); | 104 localState.transform = transform.get(); |
| 96 | 105 |
| 97 FloatRect input(0, 0, 100, 100); | 106 FloatRect input(0, 0, 100, 100); |
| 98 FloatRect output = transformMatrix.mapRect(input); | 107 FloatRect output = transformMatrix.mapRect(input); |
| 99 | 108 |
| 100 CHECK_MAPPINGS(input, output, output, transform->matrix(), rootClipNode->cli pRect().rect(), localState, rootPropertyTreeState()); | 109 CHECK_MAPPINGS(input, output, output, transform->matrix(), rootClipNode->cli pRect().rect(), localState, rootPropertyTreeState()); |
| 101 | 110 |
| 102 bool success = false; | 111 bool success = false; |
| 103 EXPECT_RECT_EQ(input, | 112 EXPECT_RECT_EQ(input, |
| 104 geometryMapper->AncestorToLocalRect(output, localState, rootPropertyTree State(), &success)); | 113 geometryMapper->ancestorToLocalRect(output, localState, rootPropertyTree State(), &success)); |
| 105 EXPECT_TRUE(success); | 114 EXPECT_TRUE(success); |
| 106 } | 115 } |
| 107 | 116 |
| 108 TEST_F(GeometryMapperTest, RotationAndScaleTransform) | 117 TEST_F(GeometryMapperTest, RotationAndScaleTransform) |
| 109 { | 118 { |
| 110 TransformationMatrix transformMatrix; | 119 TransformationMatrix transformMatrix; |
| 111 transformMatrix.rotate(45); | 120 transformMatrix.rotate(45); |
| 112 transformMatrix.scale(2); | 121 transformMatrix.scale(2); |
| 113 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c reate(transformMatrix, FloatPoint3D(0, 0, 0), rootPropertyTreeState().transform) ; | 122 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c reate(transformMatrix, FloatPoint3D(0, 0, 0), rootPropertyTreeState().transform) ; |
| 114 PropertyTreeState localState = rootPropertyTreeState(); | 123 PropertyTreeState localState = rootPropertyTreeState(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 149 PropertyTreeState localState = rootPropertyTreeState(); | 158 PropertyTreeState localState = rootPropertyTreeState(); |
| 150 localState.transform = transform2.get(); | 159 localState.transform = transform2.get(); |
| 151 | 160 |
| 152 FloatRect input(0, 0, 100, 100); | 161 FloatRect input(0, 0, 100, 100); |
| 153 TransformationMatrix final = rotateTransform * scaleTransform; | 162 TransformationMatrix final = rotateTransform * scaleTransform; |
| 154 FloatRect output = final.mapRect(input); | 163 FloatRect output = final.mapRect(input); |
| 155 | 164 |
| 156 CHECK_MAPPINGS(input, output, output, final, rootClipNode->clipRect().rect() , localState, rootPropertyTreeState()); | 165 CHECK_MAPPINGS(input, output, output, final, rootClipNode->clipRect().rect() , localState, rootPropertyTreeState()); |
| 157 | 166 |
| 158 // Check the cached matrix for the intermediate transform. | 167 // Check the cached matrix for the intermediate transform. |
| 159 EXPECT_EQ(rotateTransform, GetPrecomputedDataForAncestor(rootPropertyTreeSta te()).toAncestorTransforms.get(transform1.get())); | 168 EXPECT_EQ(rotateTransform, getPrecomputedDataForAncestor(rootPropertyTreeSta te()).toAncestorTransforms.get(transform1.get())); |
| 160 } | 169 } |
| 161 | 170 |
| 162 TEST_F(GeometryMapperTest, NestedTransformsIntermediateDestination) | 171 TEST_F(GeometryMapperTest, NestedTransformsIntermediateDestination) |
| 163 { | 172 { |
| 164 TransformationMatrix rotateTransform; | 173 TransformationMatrix rotateTransform; |
| 165 rotateTransform.rotate(45); | 174 rotateTransform.rotate(45); |
| 166 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode:: create(rotateTransform, FloatPoint3D(), rootPropertyTreeState().transform); | 175 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode:: create(rotateTransform, FloatPoint3D(), rootPropertyTreeState().transform); |
| 167 | 176 |
| 168 TransformationMatrix scaleTransform; | 177 TransformationMatrix scaleTransform; |
| 169 scaleTransform.scale(2); | 178 scaleTransform.scale(2); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 CHECK_MAPPINGS( | 311 CHECK_MAPPINGS( |
| 303 input, // Input | 312 input, // Input |
| 304 output, // Visual rect | 313 output, // Visual rect |
| 305 rotateTransform.mapRect(input), // Transformed rect (not clipped) | 314 rotateTransform.mapRect(input), // Transformed rect (not clipped) |
| 306 rotateTransform, // Transform matrix to ancestor space | 315 rotateTransform, // Transform matrix to ancestor space |
| 307 mappedClip, // Clip rect in ancestor space | 316 mappedClip, // Clip rect in ancestor space |
| 308 localState, rootPropertyTreeState()); | 317 localState, rootPropertyTreeState()); |
| 309 } | 318 } |
| 310 } | 319 } |
| 311 | 320 |
| 321 TEST_F(GeometryMapperTest, SiblingTransforms) | |
| 322 { | |
| 323 // These transforms are siblings. Thus mapping from one to the other require s going through the root. | |
| 324 TransformationMatrix rotateTransform1; | |
| 325 rotateTransform1.rotate(45); | |
| 326 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode:: create(rotateTransform1, FloatPoint3D(), rootPropertyTreeState().transform); | |
| 327 | |
| 328 TransformationMatrix rotateTransform2; | |
| 329 rotateTransform2.rotate(-45); | |
| 330 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode:: create(rotateTransform2, FloatPoint3D(), rootPropertyTreeState().transform); | |
| 331 | |
| 332 PropertyTreeState transform1State = rootPropertyTreeState(); | |
| 333 transform1State.transform = transform1; | |
| 334 PropertyTreeState transform2State = rootPropertyTreeState(); | |
| 335 transform2State.transform = transform2; | |
| 336 | |
| 337 bool success; | |
| 338 FloatRect input(0, 0, 100, 100); | |
| 339 FloatRect result = geometryMapper->localToVisualRectInAncestorSpace(input, t ransform1State, transform2State, &success); | |
| 340 // Fails, because the transform2state is not an ancestor of transform1State. | |
| 341 EXPECT_FALSE(success); | |
| 342 EXPECT_RECT_EQ(input, result); | |
| 343 | |
| 344 result = geometryMapper->localToVisualRectInAncestorSpace(input, transform2S tate, transform1State, &success); | |
| 345 // Fails, because the transform1state is not an ancestor of transform2State. | |
| 346 EXPECT_FALSE(success); | |
| 347 EXPECT_RECT_EQ(input, result); | |
| 348 | |
| 349 FloatRect expected = rotateTransform2.inverse().mapRect(rotateTransform1.map Rect(input)); | |
| 350 result = geometryMapper->mapToVisualRectInDestinationSpace(input, transform1 State, transform2State, &success); | |
| 351 EXPECT_TRUE(success); | |
| 352 EXPECT_RECT_EQ(expected, result); | |
|
pdr.
2016/06/30 21:21:50
Can you use real numbers for this test? Maybe tran
| |
| 353 } | |
| 354 | |
| 355 TEST_F(GeometryMapperTest, LeastCommonAncestor) | |
| 356 { | |
| 357 TransformationMatrix matrix; | |
| 358 RefPtr<TransformPaintPropertyNode> child1 = TransformPaintPropertyNode::crea te(matrix, FloatPoint3D(), rootPropertyTreeState().transform); | |
| 359 RefPtr<TransformPaintPropertyNode> child2 = TransformPaintPropertyNode::crea te(matrix, FloatPoint3D(), rootPropertyTreeState().transform); | |
| 360 | |
| 361 RefPtr<TransformPaintPropertyNode> childOfChild1 = TransformPaintPropertyNod e::create(matrix, FloatPoint3D(), child1); | |
| 362 RefPtr<TransformPaintPropertyNode> childOfChild2 = TransformPaintPropertyNod e::create(matrix, FloatPoint3D(), child2); | |
| 363 | |
| 364 EXPECT_EQ(rootPropertyTreeState().transform, leastCommonAncestor(childOfChil d1, childOfChild2)); | |
| 365 EXPECT_EQ(rootPropertyTreeState().transform, leastCommonAncestor(childOfChil d1, child2)); | |
| 366 EXPECT_EQ(rootPropertyTreeState().transform, leastCommonAncestor(childOfChil d1, rootPropertyTreeState().transform)); | |
| 367 EXPECT_EQ(child1, leastCommonAncestor(childOfChild1, child1)); | |
| 368 | |
| 369 EXPECT_EQ(rootPropertyTreeState().transform, leastCommonAncestor(childOfChil d2, childOfChild1)); | |
| 370 EXPECT_EQ(rootPropertyTreeState().transform, leastCommonAncestor(childOfChil d2, child1)); | |
| 371 EXPECT_EQ(rootPropertyTreeState().transform, leastCommonAncestor(childOfChil d2, rootPropertyTreeState().transform)); | |
| 372 EXPECT_EQ(child2, leastCommonAncestor(childOfChild2, child2)); | |
| 373 | |
| 374 EXPECT_EQ(rootPropertyTreeState().transform, leastCommonAncestor(child1, chi ld2)); | |
| 375 } | |
| 376 | |
| 312 } // namespace blink | 377 } // namespace blink |
| OLD | NEW |