| 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 GeometryPropertyTreeState rootGeometryPropertyTreeState() |
| 25 { | 25 { |
| 26 PropertyTreeState state(rootTransformNode.get(), rootClipNode.get(), roo
tEffectNode.get()); | 26 GeometryPropertyTreeState state(rootTransformNode.get(), rootClipNode.ge
t(), rootEffectNode.get()); |
| 27 return state; | 27 return state; |
| 28 } | 28 } |
| 29 | 29 |
| 30 PrecomputedDataForAncestor& getPrecomputedDataForAncestor(const PropertyTree
State& propertyTreeState) | 30 PrecomputedDataForAncestor& getPrecomputedDataForAncestor(const GeometryProp
ertyTreeState& geometryPropertyTreeState) |
| 31 { | 31 { |
| 32 return geometryMapper->getPrecomputedDataForAncestor(propertyTreeState); | 32 return geometryMapper->getPrecomputedDataForAncestor(geometryPropertyTre
eState); |
| 33 } | 33 } |
| 34 | 34 |
| 35 private: | 35 private: |
| 36 void SetUp() override | 36 void SetUp() override |
| 37 { | 37 { |
| 38 rootTransformNode = TransformPaintPropertyNode::create(nullptr, Transfor
mationMatrix(), FloatPoint3D()); | 38 rootTransformNode = TransformPaintPropertyNode::create(nullptr, Transfor
mationMatrix(), FloatPoint3D()); |
| 39 rootClipNode = ClipPaintPropertyNode::create(nullptr, rootTransformNode,
FloatRoundedRect(LayoutRect::infiniteIntRect())); | 39 rootClipNode = ClipPaintPropertyNode::create(nullptr, rootTransformNode,
FloatRoundedRect(LayoutRect::infiniteIntRect())); |
| 40 rootEffectNode = EffectPaintPropertyNode::create(nullptr, 1.0); | 40 rootEffectNode = EffectPaintPropertyNode::create(nullptr, 1.0); |
| 41 geometryMapper = wrapUnique(new GeometryMapper()); | 41 geometryMapper = wrapUnique(new GeometryMapper()); |
| 42 } | 42 } |
| 43 | 43 |
| 44 void TearDown() override | 44 void TearDown() override |
| 45 { | 45 { |
| 46 geometryMapper.reset(); | 46 geometryMapper.reset(); |
| 47 } | 47 } |
| 48 }; | 48 }; |
| 49 | 49 |
| 50 const static float kTestEpsilon = 1e-6; | 50 const static float kTestEpsilon = 1e-6; |
| 51 | 51 |
| 52 #define EXPECT_RECT_EQ(expected, actual) \ | 52 #define EXPECT_RECT_EQ(expected, actual) \ |
| 53 do { \ | 53 do { \ |
| 54 const FloatRect& actualRect = actual; \ | 54 const FloatRect& actualRect = actual; \ |
| 55 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.x(), actualRect.x(), k
TestEpsilon)) << "actual: " << actualRect.x() << ", expected: " << expected.x();
\ | 55 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();
\ | 56 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(); \ | 57 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(); \ | 58 EXPECT_TRUE(GeometryTest::ApproximatelyEqual(expected.height(), actualRect.h
eight(), kTestEpsilon)) << "actual: " << actualRect.height() << ", expected: " <
< expected.height(); \ |
| 59 } while (false) | 59 } while (false) |
| 60 | 60 |
| 61 #define CHECK_MAPPINGS(inputRect, expectedVisualRect, expectedTransformedRect, e
xpectedTransformToAncestor, expectedClipInAncestorSpace, localPropertyTreeState,
ancestorPropertyTreeState) \ | 61 #define CHECK_MAPPINGS(inputRect, expectedVisualRect, expectedTransformedRect, e
xpectedTransformToAncestor, expectedClipInAncestorSpace, localGeometryPropertyTr
eeState, ancestorGeometryPropertyTreeState) \ |
| 62 do { \ | 62 do { \ |
| 63 bool success = false; \ | 63 bool success = false; \ |
| 64 EXPECT_RECT_EQ(expectedVisualRect, \ | 64 EXPECT_RECT_EQ(expectedVisualRect, \ |
| 65 geometryMapper->localToVisualRectInAncestorSpace(inputRect, localPropert
yTreeState, ancestorPropertyTreeState, success)); \ | 65 geometryMapper->localToVisualRectInAncestorSpace(inputRect, localGeometr
yPropertyTreeState, ancestorGeometryPropertyTreeState, success)); \ |
| 66 EXPECT_TRUE(success); \ | 66 EXPECT_TRUE(success); \ |
| 67 EXPECT_RECT_EQ(expectedVisualRect, \ | 67 EXPECT_RECT_EQ(expectedVisualRect, \ |
| 68 geometryMapper->mapToVisualRectInDestinationSpace(inputRect, localProper
tyTreeState, ancestorPropertyTreeState, success)); \ | 68 geometryMapper->mapToVisualRectInDestinationSpace(inputRect, localGeomet
ryPropertyTreeState, ancestorGeometryPropertyTreeState, success)); \ |
| 69 EXPECT_TRUE(success); \ | 69 EXPECT_TRUE(success); \ |
| 70 EXPECT_RECT_EQ(expectedTransformedRect, \ | 70 EXPECT_RECT_EQ(expectedTransformedRect, \ |
| 71 geometryMapper->localToAncestorRect(inputRect, localPropertyTreeState, a
ncestorPropertyTreeState, success)); \ | 71 geometryMapper->localToAncestorRect(inputRect, localGeometryPropertyTree
State, ancestorGeometryPropertyTreeState, success)); \ |
| 72 EXPECT_RECT_EQ(expectedTransformedRect, \ | 72 EXPECT_RECT_EQ(expectedTransformedRect, \ |
| 73 geometryMapper->mapRectToDestinationSpace(inputRect, localPropertyTreeSt
ate, ancestorPropertyTreeState, success)); \ | 73 geometryMapper->mapRectToDestinationSpace(inputRect, localGeometryProper
tyTreeState, ancestorGeometryPropertyTreeState, success)); \ |
| 74 EXPECT_TRUE(success); \ | 74 EXPECT_TRUE(success); \ |
| 75 EXPECT_EQ(expectedTransformToAncestor, getPrecomputedDataForAncestor(ancesto
rPropertyTreeState).toAncestorTransforms.get(localPropertyTreeState.transform.ge
t())); \ | 75 EXPECT_EQ(expectedTransformToAncestor, getPrecomputedDataForAncestor(ancesto
rGeometryPropertyTreeState).toAncestorTransforms.get(localGeometryPropertyTreeSt
ate.transform.get())); \ |
| 76 EXPECT_EQ(expectedClipInAncestorSpace, getPrecomputedDataForAncestor(ancesto
rPropertyTreeState).toAncestorClipRects.get(localPropertyTreeState.clip.get()));
\ | 76 EXPECT_EQ(expectedClipInAncestorSpace, getPrecomputedDataForAncestor(ancesto
rGeometryPropertyTreeState).toAncestorClipRects.get(localGeometryPropertyTreeSta
te.clip.get())); \ |
| 77 } while (false) | 77 } while (false) |
| 78 | 78 |
| 79 TEST_F(GeometryMapperTest, Root) | 79 TEST_F(GeometryMapperTest, Root) |
| 80 { | 80 { |
| 81 FloatRect input(0, 0, 100, 100); | 81 FloatRect input(0, 0, 100, 100); |
| 82 | 82 |
| 83 CHECK_MAPPINGS(input, input, input, rootTransformNode->matrix(), rootClipNod
e->clipRect().rect(), rootPropertyTreeState(), rootPropertyTreeState()); | 83 CHECK_MAPPINGS(input, input, input, rootTransformNode->matrix(), rootClipNod
e->clipRect().rect(), rootGeometryPropertyTreeState(), rootGeometryPropertyTreeS
tate()); |
| 84 } | 84 } |
| 85 | 85 |
| 86 TEST_F(GeometryMapperTest, IdentityTransform) | 86 TEST_F(GeometryMapperTest, IdentityTransform) |
| 87 { | 87 { |
| 88 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootPropertyTreeState().transform, TransformationMatrix(), FloatPoint3D())
; | 88 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootGeometryPropertyTreeState().transform, TransformationMatrix(), FloatPo
int3D()); |
| 89 PropertyTreeState localState = rootPropertyTreeState(); | 89 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 90 localState.transform = transform.get(); | 90 localState.transform = transform.get(); |
| 91 | 91 |
| 92 FloatRect input(0, 0, 100, 100); | 92 FloatRect input(0, 0, 100, 100); |
| 93 | 93 |
| 94 CHECK_MAPPINGS(input, input, input, transform->matrix(), rootClipNode->clipR
ect().rect(), localState, rootPropertyTreeState()); | 94 CHECK_MAPPINGS(input, input, input, transform->matrix(), rootClipNode->clipR
ect().rect(), localState, rootGeometryPropertyTreeState()); |
| 95 } | 95 } |
| 96 | 96 |
| 97 TEST_F(GeometryMapperTest, TranslationTransform) | 97 TEST_F(GeometryMapperTest, TranslationTransform) |
| 98 { | 98 { |
| 99 TransformationMatrix transformMatrix; | 99 TransformationMatrix transformMatrix; |
| 100 transformMatrix.translate(20, 10); | 100 transformMatrix.translate(20, 10); |
| 101 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootPropertyTreeState().transform, transformMatrix, FloatPoint3D()); | 101 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootGeometryPropertyTreeState().transform, transformMatrix, FloatPoint3D()
); |
| 102 PropertyTreeState localState = rootPropertyTreeState(); | 102 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 103 localState.transform = transform.get(); | 103 localState.transform = transform.get(); |
| 104 | 104 |
| 105 FloatRect input(0, 0, 100, 100); | 105 FloatRect input(0, 0, 100, 100); |
| 106 FloatRect output = transformMatrix.mapRect(input); | 106 FloatRect output = transformMatrix.mapRect(input); |
| 107 | 107 |
| 108 CHECK_MAPPINGS(input, output, output, transform->matrix(), rootClipNode->cli
pRect().rect(), localState, rootPropertyTreeState()); | 108 CHECK_MAPPINGS(input, output, output, transform->matrix(), rootClipNode->cli
pRect().rect(), localState, rootGeometryPropertyTreeState()); |
| 109 | 109 |
| 110 bool success = false; | 110 bool success = false; |
| 111 EXPECT_RECT_EQ(input, | 111 EXPECT_RECT_EQ(input, |
| 112 geometryMapper->ancestorToLocalRect(output, localState, rootPropertyTree
State(), success)); | 112 geometryMapper->ancestorToLocalRect(output, localState, rootGeometryProp
ertyTreeState(), success)); |
| 113 EXPECT_TRUE(success); | 113 EXPECT_TRUE(success); |
| 114 } | 114 } |
| 115 | 115 |
| 116 TEST_F(GeometryMapperTest, RotationAndScaleTransform) | 116 TEST_F(GeometryMapperTest, RotationAndScaleTransform) |
| 117 { | 117 { |
| 118 TransformationMatrix transformMatrix; | 118 TransformationMatrix transformMatrix; |
| 119 transformMatrix.rotate(45); | 119 transformMatrix.rotate(45); |
| 120 transformMatrix.scale(2); | 120 transformMatrix.scale(2); |
| 121 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootPropertyTreeState().transform, transformMatrix, FloatPoint3D(0, 0, 0))
; | 121 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootGeometryPropertyTreeState().transform, transformMatrix, FloatPoint3D(0
, 0, 0)); |
| 122 PropertyTreeState localState = rootPropertyTreeState(); | 122 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 123 localState.transform = transform.get(); | 123 localState.transform = transform.get(); |
| 124 | 124 |
| 125 FloatRect input(0, 0, 100, 100); | 125 FloatRect input(0, 0, 100, 100); |
| 126 FloatRect output = transformMatrix.mapRect(input); | 126 FloatRect output = transformMatrix.mapRect(input); |
| 127 | 127 |
| 128 CHECK_MAPPINGS(input, output, output, transformMatrix, rootClipNode->clipRec
t().rect(), localState, rootPropertyTreeState()); | 128 CHECK_MAPPINGS(input, output, output, transformMatrix, rootClipNode->clipRec
t().rect(), localState, rootGeometryPropertyTreeState()); |
| 129 } | 129 } |
| 130 | 130 |
| 131 TEST_F(GeometryMapperTest, RotationAndScaleTransformWithTransformOrigin) | 131 TEST_F(GeometryMapperTest, RotationAndScaleTransformWithTransformOrigin) |
| 132 { | 132 { |
| 133 TransformationMatrix transformMatrix; | 133 TransformationMatrix transformMatrix; |
| 134 transformMatrix.rotate(45); | 134 transformMatrix.rotate(45); |
| 135 transformMatrix.scale(2); | 135 transformMatrix.scale(2); |
| 136 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootPropertyTreeState().transform, transformMatrix, FloatPoint3D(50, 50, 0
)); | 136 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootGeometryPropertyTreeState().transform, transformMatrix, FloatPoint3D(5
0, 50, 0)); |
| 137 PropertyTreeState localState = rootPropertyTreeState(); | 137 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 138 localState.transform = transform.get(); | 138 localState.transform = transform.get(); |
| 139 | 139 |
| 140 FloatRect input(0, 0, 100, 100); | 140 FloatRect input(0, 0, 100, 100); |
| 141 transformMatrix.applyTransformOrigin(50, 50, 0); | 141 transformMatrix.applyTransformOrigin(50, 50, 0); |
| 142 FloatRect output = transformMatrix.mapRect(input); | 142 FloatRect output = transformMatrix.mapRect(input); |
| 143 | 143 |
| 144 CHECK_MAPPINGS(input, output, output, transformMatrix, rootClipNode->clipRec
t().rect(), localState, rootPropertyTreeState()); | 144 CHECK_MAPPINGS(input, output, output, transformMatrix, rootClipNode->clipRec
t().rect(), localState, rootGeometryPropertyTreeState()); |
| 145 } | 145 } |
| 146 | 146 |
| 147 TEST_F(GeometryMapperTest, NestedTransforms) | 147 TEST_F(GeometryMapperTest, NestedTransforms) |
| 148 { | 148 { |
| 149 TransformationMatrix rotateTransform; | 149 TransformationMatrix rotateTransform; |
| 150 rotateTransform.rotate(45); | 150 rotateTransform.rotate(45); |
| 151 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D()); | 151 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootGeometryPropertyTreeState().transform, rotateTransform, FloatPoint3D(
)); |
| 152 | 152 |
| 153 TransformationMatrix scaleTransform; | 153 TransformationMatrix scaleTransform; |
| 154 scaleTransform.scale(2); | 154 scaleTransform.scale(2); |
| 155 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(transform1, scaleTransform, FloatPoint3D()); | 155 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(transform1, scaleTransform, FloatPoint3D()); |
| 156 | 156 |
| 157 PropertyTreeState localState = rootPropertyTreeState(); | 157 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 158 localState.transform = transform2.get(); | 158 localState.transform = transform2.get(); |
| 159 | 159 |
| 160 FloatRect input(0, 0, 100, 100); | 160 FloatRect input(0, 0, 100, 100); |
| 161 TransformationMatrix final = rotateTransform * scaleTransform; | 161 TransformationMatrix final = rotateTransform * scaleTransform; |
| 162 FloatRect output = final.mapRect(input); | 162 FloatRect output = final.mapRect(input); |
| 163 | 163 |
| 164 CHECK_MAPPINGS(input, output, output, final, rootClipNode->clipRect().rect()
, localState, rootPropertyTreeState()); | 164 CHECK_MAPPINGS(input, output, output, final, rootClipNode->clipRect().rect()
, localState, rootGeometryPropertyTreeState()); |
| 165 | 165 |
| 166 // Check the cached matrix for the intermediate transform. | 166 // Check the cached matrix for the intermediate transform. |
| 167 EXPECT_EQ(rotateTransform, getPrecomputedDataForAncestor(rootPropertyTreeSta
te()).toAncestorTransforms.get(transform1.get())); | 167 EXPECT_EQ(rotateTransform, getPrecomputedDataForAncestor(rootGeometryPropert
yTreeState()).toAncestorTransforms.get(transform1.get())); |
| 168 } | 168 } |
| 169 | 169 |
| 170 TEST_F(GeometryMapperTest, NestedTransformsScaleAndTranslation) | 170 TEST_F(GeometryMapperTest, NestedTransformsScaleAndTranslation) |
| 171 { | 171 { |
| 172 TransformationMatrix scaleTransform; | 172 TransformationMatrix scaleTransform; |
| 173 scaleTransform.scale(2); | 173 scaleTransform.scale(2); |
| 174 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootPropertyTreeState().transform, scaleTransform, FloatPoint3D()); | 174 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootGeometryPropertyTreeState().transform, scaleTransform, FloatPoint3D()
); |
| 175 | 175 |
| 176 TransformationMatrix translateTransform; | 176 TransformationMatrix translateTransform; |
| 177 translateTransform.translate(100, 0); | 177 translateTransform.translate(100, 0); |
| 178 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(transform1, translateTransform, FloatPoint3D()); | 178 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(transform1, translateTransform, FloatPoint3D()); |
| 179 | 179 |
| 180 PropertyTreeState localState = rootPropertyTreeState(); | 180 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 181 localState.transform = transform2.get(); | 181 localState.transform = transform2.get(); |
| 182 | 182 |
| 183 FloatRect input(0, 0, 100, 100); | 183 FloatRect input(0, 0, 100, 100); |
| 184 // Note: unlike NestedTransforms, the order of these transforms matters. Thi
s tests correct order of matrix multiplication. | 184 // Note: unlike NestedTransforms, the order of these transforms matters. Thi
s tests correct order of matrix multiplication. |
| 185 TransformationMatrix final = scaleTransform * translateTransform; | 185 TransformationMatrix final = scaleTransform * translateTransform; |
| 186 FloatRect output = final.mapRect(input); | 186 FloatRect output = final.mapRect(input); |
| 187 | 187 |
| 188 CHECK_MAPPINGS(input, output, output, final, rootClipNode->clipRect().rect()
, localState, rootPropertyTreeState()); | 188 CHECK_MAPPINGS(input, output, output, final, rootClipNode->clipRect().rect()
, localState, rootGeometryPropertyTreeState()); |
| 189 | 189 |
| 190 // Check the cached matrix for the intermediate transform. | 190 // Check the cached matrix for the intermediate transform. |
| 191 EXPECT_EQ(scaleTransform, getPrecomputedDataForAncestor(rootPropertyTreeStat
e()).toAncestorTransforms.get(transform1.get())); | 191 EXPECT_EQ(scaleTransform, getPrecomputedDataForAncestor(rootGeometryProperty
TreeState()).toAncestorTransforms.get(transform1.get())); |
| 192 } | 192 } |
| 193 | 193 |
| 194 | 194 |
| 195 TEST_F(GeometryMapperTest, NestedTransformsIntermediateDestination) | 195 TEST_F(GeometryMapperTest, NestedTransformsIntermediateDestination) |
| 196 { | 196 { |
| 197 TransformationMatrix rotateTransform; | 197 TransformationMatrix rotateTransform; |
| 198 rotateTransform.rotate(45); | 198 rotateTransform.rotate(45); |
| 199 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D()); | 199 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootGeometryPropertyTreeState().transform, rotateTransform, FloatPoint3D(
)); |
| 200 | 200 |
| 201 TransformationMatrix scaleTransform; | 201 TransformationMatrix scaleTransform; |
| 202 scaleTransform.scale(2); | 202 scaleTransform.scale(2); |
| 203 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(transform1, scaleTransform, FloatPoint3D()); | 203 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(transform1, scaleTransform, FloatPoint3D()); |
| 204 | 204 |
| 205 PropertyTreeState localState = rootPropertyTreeState(); | 205 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 206 localState.transform = transform2.get(); | 206 localState.transform = transform2.get(); |
| 207 | 207 |
| 208 PropertyTreeState intermediateState = rootPropertyTreeState(); | 208 GeometryPropertyTreeState intermediateState = rootGeometryPropertyTreeState(
); |
| 209 intermediateState.transform = transform1.get(); | 209 intermediateState.transform = transform1.get(); |
| 210 | 210 |
| 211 FloatRect input(0, 0, 100, 100); | 211 FloatRect input(0, 0, 100, 100); |
| 212 FloatRect output = scaleTransform.mapRect(input); | 212 FloatRect output = scaleTransform.mapRect(input); |
| 213 | 213 |
| 214 CHECK_MAPPINGS(input, output, output, scaleTransform, rootClipNode->clipRect
().rect(), localState, intermediateState); | 214 CHECK_MAPPINGS(input, output, output, scaleTransform, rootClipNode->clipRect
().rect(), localState, intermediateState); |
| 215 } | 215 } |
| 216 | 216 |
| 217 TEST_F(GeometryMapperTest, SimpleClip) | 217 TEST_F(GeometryMapperTest, SimpleClip) |
| 218 { | 218 { |
| 219 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootClipN
ode, rootTransformNode, FloatRoundedRect(10, 10, 50, 50)); | 219 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootClipN
ode, rootTransformNode, FloatRoundedRect(10, 10, 50, 50)); |
| 220 | 220 |
| 221 PropertyTreeState localState = rootPropertyTreeState(); | 221 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 222 localState.clip = clip.get(); | 222 localState.clip = clip.get(); |
| 223 | 223 |
| 224 FloatRect input(0, 0, 100, 100); | 224 FloatRect input(0, 0, 100, 100); |
| 225 FloatRect output(10, 10, 50, 50); | 225 FloatRect output(10, 10, 50, 50); |
| 226 | 226 |
| 227 CHECK_MAPPINGS( | 227 CHECK_MAPPINGS( |
| 228 input, // Input | 228 input, // Input |
| 229 output, // Visual rect | 229 output, // Visual rect |
| 230 input, // Transformed rect (not clipped). | 230 input, // Transformed rect (not clipped). |
| 231 rootTransformNode->matrix(), // Transform matrix to ancestor space | 231 rootTransformNode->matrix(), // Transform matrix to ancestor space |
| 232 clip->clipRect().rect(), // Clip rect in ancestor space | 232 clip->clipRect().rect(), // Clip rect in ancestor space |
| 233 localState, rootPropertyTreeState()); | 233 localState, rootGeometryPropertyTreeState()); |
| 234 } | 234 } |
| 235 | 235 |
| 236 TEST_F(GeometryMapperTest, ClipBeforeTransform) | 236 TEST_F(GeometryMapperTest, ClipBeforeTransform) |
| 237 { | 237 { |
| 238 TransformationMatrix rotateTransform; | 238 TransformationMatrix rotateTransform; |
| 239 rotateTransform.rotate(45); | 239 rotateTransform.rotate(45); |
| 240 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D()); | 240 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootGeometryPropertyTreeState().transform, rotateTransform, FloatPoint3D()
); |
| 241 | 241 |
| 242 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootClipN
ode, transform.get(), FloatRoundedRect(10, 10, 50, 50)); | 242 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootClipN
ode, transform.get(), FloatRoundedRect(10, 10, 50, 50)); |
| 243 | 243 |
| 244 PropertyTreeState localState = rootPropertyTreeState(); | 244 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 245 localState.clip = clip.get(); | 245 localState.clip = clip.get(); |
| 246 localState.transform = transform.get(); | 246 localState.transform = transform.get(); |
| 247 | 247 |
| 248 FloatRect input(0, 0, 100, 100); | 248 FloatRect input(0, 0, 100, 100); |
| 249 FloatRect output(input); | 249 FloatRect output(input); |
| 250 output.intersect(clip->clipRect().rect()); | 250 output.intersect(clip->clipRect().rect()); |
| 251 output = rotateTransform.mapRect(output); | 251 output = rotateTransform.mapRect(output); |
| 252 | 252 |
| 253 CHECK_MAPPINGS( | 253 CHECK_MAPPINGS( |
| 254 input, // Input | 254 input, // Input |
| 255 output, // Visual rect | 255 output, // Visual rect |
| 256 rotateTransform.mapRect(input), // Transformed rect (not clipped). | 256 rotateTransform.mapRect(input), // Transformed rect (not clipped). |
| 257 rotateTransform, // Transform matrix to ancestor space | 257 rotateTransform, // Transform matrix to ancestor space |
| 258 rotateTransform.mapRect(clip->clipRect().rect()), // Clip rect in ancest
or space | 258 rotateTransform.mapRect(clip->clipRect().rect()), // Clip rect in ancest
or space |
| 259 localState, rootPropertyTreeState()); | 259 localState, rootGeometryPropertyTreeState()); |
| 260 } | 260 } |
| 261 | 261 |
| 262 TEST_F(GeometryMapperTest, ClipAfterTransform) | 262 TEST_F(GeometryMapperTest, ClipAfterTransform) |
| 263 { | 263 { |
| 264 TransformationMatrix rotateTransform; | 264 TransformationMatrix rotateTransform; |
| 265 rotateTransform.rotate(45); | 265 rotateTransform.rotate(45); |
| 266 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D()); | 266 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootGeometryPropertyTreeState().transform, rotateTransform, FloatPoint3D()
); |
| 267 | 267 |
| 268 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootClipN
ode, rootTransformNode.get(), FloatRoundedRect(10, 10, 200, 200)); | 268 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootClipN
ode, rootTransformNode.get(), FloatRoundedRect(10, 10, 200, 200)); |
| 269 | 269 |
| 270 PropertyTreeState localState = rootPropertyTreeState(); | 270 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 271 localState.clip = clip.get(); | 271 localState.clip = clip.get(); |
| 272 localState.transform = transform.get(); | 272 localState.transform = transform.get(); |
| 273 | 273 |
| 274 FloatRect input(0, 0, 100, 100); | 274 FloatRect input(0, 0, 100, 100); |
| 275 FloatRect output(input); | 275 FloatRect output(input); |
| 276 output = rotateTransform.mapRect(output); | 276 output = rotateTransform.mapRect(output); |
| 277 output.intersect(clip->clipRect().rect()); | 277 output.intersect(clip->clipRect().rect()); |
| 278 | 278 |
| 279 CHECK_MAPPINGS( | 279 CHECK_MAPPINGS( |
| 280 input, // Input | 280 input, // Input |
| 281 output, // Visual rect | 281 output, // Visual rect |
| 282 rotateTransform.mapRect(input), // Transformed rect (not clipped) | 282 rotateTransform.mapRect(input), // Transformed rect (not clipped) |
| 283 rotateTransform, // Transform matrix to ancestor space | 283 rotateTransform, // Transform matrix to ancestor space |
| 284 clip->clipRect().rect(), // Clip rect in ancestor space | 284 clip->clipRect().rect(), // Clip rect in ancestor space |
| 285 localState, rootPropertyTreeState()); | 285 localState, rootGeometryPropertyTreeState()); |
| 286 } | 286 } |
| 287 | 287 |
| 288 TEST_F(GeometryMapperTest, TwoClipsWithTransformBetween) | 288 TEST_F(GeometryMapperTest, TwoClipsWithTransformBetween) |
| 289 { | 289 { |
| 290 RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(rootClip
Node, rootTransformNode.get(), FloatRoundedRect(10, 10, 200, 200)); | 290 RefPtr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::create(rootClip
Node, rootTransformNode.get(), FloatRoundedRect(10, 10, 200, 200)); |
| 291 | 291 |
| 292 TransformationMatrix rotateTransform; | 292 TransformationMatrix rotateTransform; |
| 293 rotateTransform.rotate(45); | 293 rotateTransform.rotate(45); |
| 294 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootPropertyTreeState().transform, rotateTransform, FloatPoint3D()); | 294 RefPtr<TransformPaintPropertyNode> transform = TransformPaintPropertyNode::c
reate(rootGeometryPropertyTreeState().transform, rotateTransform, FloatPoint3D()
); |
| 295 | 295 |
| 296 RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(clip1, t
ransform.get(), FloatRoundedRect(10, 10, 200, 200)); | 296 RefPtr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::create(clip1, t
ransform.get(), FloatRoundedRect(10, 10, 200, 200)); |
| 297 | 297 |
| 298 FloatRect input(0, 0, 100, 100); | 298 FloatRect input(0, 0, 100, 100); |
| 299 | 299 |
| 300 { | 300 { |
| 301 PropertyTreeState localState = rootPropertyTreeState(); | 301 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 302 localState.clip = clip1.get(); | 302 localState.clip = clip1.get(); |
| 303 localState.transform = transform.get(); | 303 localState.transform = transform.get(); |
| 304 | 304 |
| 305 FloatRect output(input); | 305 FloatRect output(input); |
| 306 output = rotateTransform.mapRect(output); | 306 output = rotateTransform.mapRect(output); |
| 307 output.intersect(clip1->clipRect().rect()); | 307 output.intersect(clip1->clipRect().rect()); |
| 308 | 308 |
| 309 CHECK_MAPPINGS( | 309 CHECK_MAPPINGS( |
| 310 input, // Input | 310 input, // Input |
| 311 output, // Visual rect | 311 output, // Visual rect |
| 312 rotateTransform.mapRect(input), // Transformed rect (not clipped) | 312 rotateTransform.mapRect(input), // Transformed rect (not clipped) |
| 313 rotateTransform, // Transform matrix to ancestor space | 313 rotateTransform, // Transform matrix to ancestor space |
| 314 clip1->clipRect().rect(), // Clip rect in ancestor space | 314 clip1->clipRect().rect(), // Clip rect in ancestor space |
| 315 localState, rootPropertyTreeState()); | 315 localState, rootGeometryPropertyTreeState()); |
| 316 } | 316 } |
| 317 | 317 |
| 318 { | 318 { |
| 319 PropertyTreeState localState = rootPropertyTreeState(); | 319 GeometryPropertyTreeState localState = rootGeometryPropertyTreeState(); |
| 320 localState.clip = clip2.get(); | 320 localState.clip = clip2.get(); |
| 321 localState.transform = transform.get(); | 321 localState.transform = transform.get(); |
| 322 | 322 |
| 323 | 323 |
| 324 FloatRect mappedClip = rotateTransform.mapRect(clip2->clipRect().rect())
; | 324 FloatRect mappedClip = rotateTransform.mapRect(clip2->clipRect().rect())
; |
| 325 mappedClip.intersect(clip1->clipRect().rect()); | 325 mappedClip.intersect(clip1->clipRect().rect()); |
| 326 | 326 |
| 327 // All clips are performed in the space of the ancestor. In cases such a
s this, this means the | 327 // All clips are performed in the space of the ancestor. In cases such a
s this, this means the |
| 328 // clip is a bit lossy. | 328 // clip is a bit lossy. |
| 329 FloatRect output(input); | 329 FloatRect output(input); |
| 330 // Map to transformed rect in ancestor space. | 330 // Map to transformed rect in ancestor space. |
| 331 output = rotateTransform.mapRect(output); | 331 output = rotateTransform.mapRect(output); |
| 332 // Intersect with all clips between local and ancestor, independently ma
pped to ancestor space. | 332 // Intersect with all clips between local and ancestor, independently ma
pped to ancestor space. |
| 333 output.intersect(mappedClip); | 333 output.intersect(mappedClip); |
| 334 | 334 |
| 335 CHECK_MAPPINGS( | 335 CHECK_MAPPINGS( |
| 336 input, // Input | 336 input, // Input |
| 337 output, // Visual rect | 337 output, // Visual rect |
| 338 rotateTransform.mapRect(input), // Transformed rect (not clipped) | 338 rotateTransform.mapRect(input), // Transformed rect (not clipped) |
| 339 rotateTransform, // Transform matrix to ancestor space | 339 rotateTransform, // Transform matrix to ancestor space |
| 340 mappedClip, // Clip rect in ancestor space | 340 mappedClip, // Clip rect in ancestor space |
| 341 localState, rootPropertyTreeState()); | 341 localState, rootGeometryPropertyTreeState()); |
| 342 } | 342 } |
| 343 } | 343 } |
| 344 | 344 |
| 345 TEST_F(GeometryMapperTest, SiblingTransforms) | 345 TEST_F(GeometryMapperTest, SiblingTransforms) |
| 346 { | 346 { |
| 347 // These transforms are siblings. Thus mapping from one to the other require
s going through the root. | 347 // These transforms are siblings. Thus mapping from one to the other require
s going through the root. |
| 348 TransformationMatrix rotateTransform1; | 348 TransformationMatrix rotateTransform1; |
| 349 rotateTransform1.rotate(45); | 349 rotateTransform1.rotate(45); |
| 350 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootPropertyTreeState().transform, rotateTransform1, FloatPoint3D()); | 350 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootGeometryPropertyTreeState().transform, rotateTransform1, FloatPoint3D
()); |
| 351 | 351 |
| 352 TransformationMatrix rotateTransform2; | 352 TransformationMatrix rotateTransform2; |
| 353 rotateTransform2.rotate(-45); | 353 rotateTransform2.rotate(-45); |
| 354 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(rootPropertyTreeState().transform, rotateTransform2, FloatPoint3D()); | 354 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(rootGeometryPropertyTreeState().transform, rotateTransform2, FloatPoint3D
()); |
| 355 | 355 |
| 356 PropertyTreeState transform1State = rootPropertyTreeState(); | 356 GeometryPropertyTreeState transform1State = rootGeometryPropertyTreeState(); |
| 357 transform1State.transform = transform1; | 357 transform1State.transform = transform1; |
| 358 PropertyTreeState transform2State = rootPropertyTreeState(); | 358 GeometryPropertyTreeState transform2State = rootGeometryPropertyTreeState(); |
| 359 transform2State.transform = transform2; | 359 transform2State.transform = transform2; |
| 360 | 360 |
| 361 bool success; | 361 bool success; |
| 362 FloatRect input(0, 0, 100, 100); | 362 FloatRect input(0, 0, 100, 100); |
| 363 FloatRect result = geometryMapper->localToVisualRectInAncestorSpace(input, t
ransform1State, transform2State, success); | 363 FloatRect result = geometryMapper->localToVisualRectInAncestorSpace(input, t
ransform1State, transform2State, success); |
| 364 // Fails, because the transform2state is not an ancestor of transform1State. | 364 // Fails, because the transform2state is not an ancestor of transform1State. |
| 365 EXPECT_FALSE(success); | 365 EXPECT_FALSE(success); |
| 366 EXPECT_RECT_EQ(input, result); | 366 EXPECT_RECT_EQ(input, result); |
| 367 | 367 |
| 368 result = geometryMapper->localToAncestorRect(input, transform1State, transfo
rm2State, success); | 368 result = geometryMapper->localToAncestorRect(input, transform1State, transfo
rm2State, success); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 388 result = geometryMapper->mapRectToDestinationSpace(input, transform1State, t
ransform2State, success); | 388 result = geometryMapper->mapRectToDestinationSpace(input, transform1State, t
ransform2State, success); |
| 389 EXPECT_TRUE(success); | 389 EXPECT_TRUE(success); |
| 390 EXPECT_RECT_EQ(expected, result); | 390 EXPECT_RECT_EQ(expected, result); |
| 391 } | 391 } |
| 392 | 392 |
| 393 TEST_F(GeometryMapperTest, SiblingTransformsWithClip) | 393 TEST_F(GeometryMapperTest, SiblingTransformsWithClip) |
| 394 { | 394 { |
| 395 // These transforms are siblings. Thus mapping from one to the other require
s going through the root. | 395 // These transforms are siblings. Thus mapping from one to the other require
s going through the root. |
| 396 TransformationMatrix rotateTransform1; | 396 TransformationMatrix rotateTransform1; |
| 397 rotateTransform1.rotate(45); | 397 rotateTransform1.rotate(45); |
| 398 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootPropertyTreeState().transform, rotateTransform1, FloatPoint3D()); | 398 RefPtr<TransformPaintPropertyNode> transform1 = TransformPaintPropertyNode::
create(rootGeometryPropertyTreeState().transform, rotateTransform1, FloatPoint3D
()); |
| 399 | 399 |
| 400 TransformationMatrix rotateTransform2; | 400 TransformationMatrix rotateTransform2; |
| 401 rotateTransform2.rotate(-45); | 401 rotateTransform2.rotate(-45); |
| 402 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(rootPropertyTreeState().transform, rotateTransform2, FloatPoint3D()); | 402 RefPtr<TransformPaintPropertyNode> transform2 = TransformPaintPropertyNode::
create(rootGeometryPropertyTreeState().transform, rotateTransform2, FloatPoint3D
()); |
| 403 | 403 |
| 404 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootPrope
rtyTreeState().clip, transform2.get(), FloatRoundedRect(10, 10, 70, 70)); | 404 RefPtr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::create(rootGeome
tryPropertyTreeState().clip, transform2.get(), FloatRoundedRect(10, 10, 70, 70))
; |
| 405 | 405 |
| 406 PropertyTreeState transform1State = rootPropertyTreeState(); | 406 GeometryPropertyTreeState transform1State = rootGeometryPropertyTreeState(); |
| 407 transform1State.transform = transform1; | 407 transform1State.transform = transform1; |
| 408 PropertyTreeState transform2AndClipState = rootPropertyTreeState(); | 408 GeometryPropertyTreeState transform2AndClipState = rootGeometryPropertyTreeS
tate(); |
| 409 transform2AndClipState.transform = transform2; | 409 transform2AndClipState.transform = transform2; |
| 410 transform2AndClipState.clip = clip; | 410 transform2AndClipState.clip = clip; |
| 411 | 411 |
| 412 bool success; | 412 bool success; |
| 413 FloatRect input(0, 0, 100, 100); | 413 FloatRect input(0, 0, 100, 100); |
| 414 | 414 |
| 415 // Test map from transform1State to transform2AndClipState. | 415 // Test map from transform1State to transform2AndClipState. |
| 416 FloatRect expected = rotateTransform2.inverse().mapRect(rotateTransform1.map
Rect(input)); | 416 FloatRect expected = rotateTransform2.inverse().mapRect(rotateTransform1.map
Rect(input)); |
| 417 | 417 |
| 418 // mapToVisualRectInDestinationSpace ignores clip from the common ancestor t
o destination. | 418 // mapToVisualRectInDestinationSpace ignores clip from the common ancestor t
o destination. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 434 EXPECT_TRUE(success); | 434 EXPECT_TRUE(success); |
| 435 EXPECT_RECT_EQ(expectedClipped, result); | 435 EXPECT_RECT_EQ(expectedClipped, result); |
| 436 | 436 |
| 437 // mapRectToDestinationSpace ignores clip. | 437 // mapRectToDestinationSpace ignores clip. |
| 438 result = geometryMapper->mapRectToDestinationSpace(input, transform2AndClipS
tate, transform1State, success); | 438 result = geometryMapper->mapRectToDestinationSpace(input, transform2AndClipS
tate, transform1State, success); |
| 439 EXPECT_TRUE(success); | 439 EXPECT_TRUE(success); |
| 440 EXPECT_RECT_EQ(expectedUnclipped, result); | 440 EXPECT_RECT_EQ(expectedUnclipped, result); |
| 441 } | 441 } |
| 442 | 442 |
| 443 } // namespace blink | 443 } // namespace blink |
| OLD | NEW |