| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "core/layout/LayoutTestHelper.h" | 5 #include "core/layout/LayoutTestHelper.h" |
| 6 #include "core/layout/LayoutView.h" | 6 #include "core/layout/LayoutView.h" |
| 7 #include "core/layout/PaintInvalidationState.h" | 7 #include "core/layout/PaintInvalidationState.h" |
| 8 #include "core/paint/PaintLayer.h" | 8 #include "core/paint/PaintLayer.h" |
| 9 #include "core/paint/PaintPropertyTreePrinter.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
| 10 | 11 |
| 11 namespace blink { | 12 namespace blink { |
| 12 | 13 |
| 13 class VisualRectMappingTest : public RenderingTest { | 14 class VisualRectMappingTest : public RenderingTest { |
| 14 public: | 15 public: |
| 15 VisualRectMappingTest() | 16 VisualRectMappingTest() |
| 16 : RenderingTest(SingleChildLocalFrameClient::create()) {} | 17 : RenderingTest(SingleChildLocalFrameClient::create()) {} |
| 17 | 18 |
| 18 protected: | 19 protected: |
| 19 LayoutView& layoutView() const { return *document().layoutView(); } | 20 LayoutView& layoutView() const { return *document().layoutView(); } |
| 20 | 21 |
| 21 void checkPaintInvalidationVisualRect(const LayoutObject& object) { | 22 void checkPaintInvalidationVisualRect(const LayoutObject& object) { |
| 22 LayoutRect rect = object.localVisualRect(); | 23 LayoutRect rect = object.localVisualRect(); |
| 23 if (object.isBox()) | 24 if (object.isBox()) |
| 24 toLayoutBox(object).flipForWritingMode(rect); | 25 toLayoutBox(object).flipForWritingMode(rect); |
| 25 const LayoutBoxModelObject& paintInvalidationContainer = | 26 const LayoutBoxModelObject& paintInvalidationContainer = |
| 26 object.containerForPaintInvalidation(); | 27 object.containerForPaintInvalidation(); |
| 27 object.mapToVisualRectInAncestorSpace(&paintInvalidationContainer, rect); | 28 |
| 28 if (rect.isEmpty() && object.visualRect().isEmpty()) | 29 checkVisualRect(object, paintInvalidationContainer, rect, |
| 30 object.visualRect(), true); |
| 31 } |
| 32 |
| 33 void checkVisualRect(const LayoutObject& object, |
| 34 const LayoutBoxModelObject& ancestor, |
| 35 const LayoutRect& localRect, |
| 36 const LayoutRect& expectedVisualRect, |
| 37 bool adjustForBacking = false) { |
| 38 LayoutRect slowMapRect = localRect; |
| 39 object.mapToVisualRectInAncestorSpace(&ancestor, slowMapRect); |
| 40 if (slowMapRect.isEmpty() && object.visualRect().isEmpty()) |
| 29 return; | 41 return; |
| 42 |
| 43 FloatRect geometryMapperRect(localRect); |
| 44 if (object.paintProperties()) { |
| 45 geometryMapperRect.moveBy(FloatPoint(object.paintOffset())); |
| 46 document().view()->geometryMapper().sourceToDestinationVisualRect( |
| 47 *object.paintProperties()->localBorderBoxProperties(), |
| 48 *ancestor.paintProperties()->contentsProperties(), |
| 49 geometryMapperRect); |
| 50 geometryMapperRect.moveBy(-FloatPoint(ancestor.paintOffset())); |
| 51 } |
| 52 |
| 30 // The following condition can be false if paintInvalidationContainer is | 53 // The following condition can be false if paintInvalidationContainer is |
| 31 // a LayoutView and compositing is not enabled. | 54 // a LayoutView and compositing is not enabled. |
| 32 if (paintInvalidationContainer.isPaintInvalidationContainer()) { | 55 if (adjustForBacking && ancestor.isPaintInvalidationContainer()) { |
| 33 PaintLayer::mapRectInPaintInvalidationContainerToBacking( | 56 PaintLayer::mapRectInPaintInvalidationContainerToBacking(ancestor, |
| 34 paintInvalidationContainer, rect); | 57 slowMapRect); |
| 58 LayoutRect temp(geometryMapperRect); |
| 59 PaintLayer::mapRectInPaintInvalidationContainerToBacking(ancestor, temp); |
| 60 geometryMapperRect = FloatRect(temp); |
| 35 } | 61 } |
| 36 EXPECT_EQ(enclosingIntRect(rect), enclosingIntRect(object.visualRect())); | 62 EXPECT_TRUE(enclosingIntRect(slowMapRect) |
| 63 .contains(enclosingIntRect(expectedVisualRect))); |
| 64 |
| 65 if (object.paintProperties()) { |
| 66 EXPECT_EQ(enclosingIntRect(expectedVisualRect), |
| 67 enclosingIntRect(geometryMapperRect)); |
| 68 } |
| 37 } | 69 } |
| 38 }; | 70 }; |
| 39 | 71 |
| 40 TEST_F(VisualRectMappingTest, LayoutText) { | 72 TEST_F(VisualRectMappingTest, LayoutText) { |
| 41 setBodyInnerHTML( | 73 setBodyInnerHTML( |
| 42 "<style>body { margin: 0; }</style>" | 74 "<style>body { margin: 0; }</style>" |
| 43 "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>" | 75 "<div id='container' style='overflow: scroll; width: 50px; height: 50px'>" |
| 44 " <span><img style='width: 20px; height: 100px'></span>" | 76 " <span><img style='width: 20px; height: 100px'></span>" |
| 45 " text text text text text text text" | 77 " text text text text text text text" |
| 46 "</div>"); | 78 "</div>"); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 // TODO(wkorman): The calls to flipForWritingMode() here and in other test | 266 // TODO(wkorman): The calls to flipForWritingMode() here and in other test |
| 235 // cases below are necessary because mapToVisualRectInAncestorSpace() | 267 // cases below are necessary because mapToVisualRectInAncestorSpace() |
| 236 // currently expects the input rect to be in "physical coordinates" (*not* | 268 // currently expects the input rect to be in "physical coordinates" (*not* |
| 237 // "physical coordinates with flipped block-flow direction"), see | 269 // "physical coordinates with flipped block-flow direction"), see |
| 238 // LayoutBoxModelObject.h. | 270 // LayoutBoxModelObject.h. |
| 239 target->flipForWritingMode(rect); | 271 target->flipForWritingMode(rect); |
| 240 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); | 272 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); |
| 241 // This rect is in physical coordinates of target. | 273 // This rect is in physical coordinates of target. |
| 242 EXPECT_EQ(LayoutRect(0, 0, 140, 70), rect); | 274 EXPECT_EQ(LayoutRect(0, 0, 140, 70), rect); |
| 243 | 275 |
| 244 rect = localVisualRect; | 276 checkPaintInvalidationVisualRect(*target); |
| 245 target->flipForWritingMode(rect); | 277 EXPECT_EQ(LayoutRect(222, 111, 140, 70), target->visualRect()); |
| 246 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | |
| 247 EXPECT_EQ(LayoutRect(222, 111, 140, 70), rect); | |
| 248 EXPECT_EQ(rect, target->visualRect()); | |
| 249 } | 278 } |
| 250 | 279 |
| 251 TEST_F(VisualRectMappingTest, ContainerFlippedWritingMode) { | 280 TEST_F(VisualRectMappingTest, ContainerFlippedWritingMode) { |
| 252 setBodyInnerHTML( | 281 setBodyInnerHTML( |
| 253 "<div id='container' style='writing-mode: vertical-rl;" | 282 "<div id='container' style='writing-mode: vertical-rl;" |
| 254 " position: absolute; top: 111px; left: 222px'>" | 283 " position: absolute; top: 111px; left: 222px'>" |
| 255 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" | 284 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" |
| 256 " height: 90px'></div>" | 285 " height: 90px'></div>" |
| 257 " <div style='width: 100px; height: 100px'></div>" | 286 " <div style='width: 100px; height: 100px'></div>" |
| 258 "</div>"); | 287 "</div>"); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 271 // This rect is in physical coordinates of target. | 300 // This rect is in physical coordinates of target. |
| 272 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); | 301 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); |
| 273 | 302 |
| 274 LayoutBlock* container = | 303 LayoutBlock* container = |
| 275 toLayoutBlock(getLayoutObjectByElementId("container")); | 304 toLayoutBlock(getLayoutObjectByElementId("container")); |
| 276 rect = targetLocalVisualRect; | 305 rect = targetLocalVisualRect; |
| 277 target->flipForWritingMode(rect); | 306 target->flipForWritingMode(rect); |
| 278 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); | 307 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); |
| 279 // 100 is the physical x location of target in container. | 308 // 100 is the physical x location of target in container. |
| 280 EXPECT_EQ(LayoutRect(100, 0, 140, 110), rect); | 309 EXPECT_EQ(LayoutRect(100, 0, 140, 110), rect); |
| 310 |
| 281 rect = targetLocalVisualRect; | 311 rect = targetLocalVisualRect; |
| 282 target->flipForWritingMode(rect); | 312 target->flipForWritingMode(rect); |
| 283 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 313 checkPaintInvalidationVisualRect(*target); |
| 284 EXPECT_EQ(LayoutRect(322, 111, 140, 110), rect); | 314 EXPECT_EQ(LayoutRect(322, 111, 140, 110), target->visualRect()); |
| 285 EXPECT_EQ(rect, target->visualRect()); | |
| 286 | 315 |
| 287 LayoutRect containerLocalVisualRect = container->localVisualRect(); | 316 LayoutRect containerLocalVisualRect = container->localVisualRect(); |
| 288 EXPECT_EQ(LayoutRect(0, 0, 200, 100), containerLocalVisualRect); | 317 EXPECT_EQ(LayoutRect(0, 0, 200, 100), containerLocalVisualRect); |
| 289 rect = containerLocalVisualRect; | 318 rect = containerLocalVisualRect; |
| 290 container->flipForWritingMode(rect); | 319 container->flipForWritingMode(rect); |
| 291 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); | 320 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); |
| 292 EXPECT_EQ(LayoutRect(0, 0, 200, 100), rect); | 321 EXPECT_EQ(LayoutRect(0, 0, 200, 100), rect); |
| 293 rect = containerLocalVisualRect; | 322 rect = containerLocalVisualRect; |
| 294 container->flipForWritingMode(rect); | 323 container->flipForWritingMode(rect); |
| 295 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 324 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 325 | 354 |
| 326 rect = targetLocalVisualRect; | 355 rect = targetLocalVisualRect; |
| 327 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); | 356 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); |
| 328 rect.move(-container->scrolledContentOffset()); | 357 rect.move(-container->scrolledContentOffset()); |
| 329 // 2 = target_x(0) + container_border_left(10) - scroll_left(8) | 358 // 2 = target_x(0) + container_border_left(10) - scroll_left(8) |
| 330 // 3 = target_y(0) + container_border_top(10) - scroll_top(7) | 359 // 3 = target_y(0) + container_border_top(10) - scroll_top(7) |
| 331 // Rect is not clipped by container's overflow clip because of | 360 // Rect is not clipped by container's overflow clip because of |
| 332 // overflow:scroll. | 361 // overflow:scroll. |
| 333 EXPECT_EQ(LayoutRect(2, 3, 140, 110), rect); | 362 EXPECT_EQ(LayoutRect(2, 3, 140, 110), rect); |
| 334 | 363 |
| 335 rect = targetLocalVisualRect; | 364 checkPaintInvalidationVisualRect(*target); |
| 336 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | |
| 337 // (2, 3, 140, 100) is first clipped by container's overflow clip, to | 365 // (2, 3, 140, 100) is first clipped by container's overflow clip, to |
| 338 // (10, 10, 50, 80), then is by added container's offset in LayoutView | 366 // (10, 10, 50, 80), then is by added container's offset in LayoutView |
| 339 // (111, 222). | 367 // (111, 222). |
| 340 EXPECT_EQ(LayoutRect(232, 121, 50, 80), rect); | 368 EXPECT_EQ(LayoutRect(232, 121, 50, 80), target->visualRect()); |
| 341 EXPECT_EQ(rect, target->visualRect()); | |
| 342 | 369 |
| 343 LayoutRect containerLocalVisualRect = container->localVisualRect(); | 370 LayoutRect containerLocalVisualRect = container->localVisualRect(); |
| 344 // Because container has overflow clip, its visual overflow doesn't include | 371 // Because container has overflow clip, its visual overflow doesn't include |
| 345 // overflow from children. | 372 // overflow from children. |
| 346 // 70 = width(50) + border_left_width(10) + border_right_width(10) | 373 // 70 = width(50) + border_left_width(10) + border_right_width(10) |
| 347 // 100 = height(80) + border_top_width(10) + border_bottom_width(10) | 374 // 100 = height(80) + border_top_width(10) + border_bottom_width(10) |
| 348 EXPECT_EQ(LayoutRect(0, 0, 70, 100), containerLocalVisualRect); | 375 EXPECT_EQ(LayoutRect(0, 0, 70, 100), containerLocalVisualRect); |
| 349 rect = containerLocalVisualRect; | 376 rect = containerLocalVisualRect; |
| 350 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); | 377 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); |
| 351 // Container should not apply overflow clip on its own overflow rect. | 378 // Container should not apply overflow clip on its own overflow rect. |
| 352 EXPECT_EQ(LayoutRect(0, 0, 70, 100), rect); | 379 EXPECT_EQ(LayoutRect(0, 0, 70, 100), rect); |
| 353 | 380 |
| 354 rect = containerLocalVisualRect; | 381 checkPaintInvalidationVisualRect(*container); |
| 355 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 382 EXPECT_EQ(LayoutRect(222, 111, 70, 100), container->visualRect()); |
| 356 EXPECT_EQ(LayoutRect(222, 111, 70, 100), rect); | |
| 357 EXPECT_EQ(rect, container->visualRect()); | |
| 358 } | 383 } |
| 359 | 384 |
| 360 TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowScroll) { | 385 TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowScroll) { |
| 361 setBodyInnerHTML( | 386 setBodyInnerHTML( |
| 362 "<div id='container' style='writing-mode: vertical-rl;" | 387 "<div id='container' style='writing-mode: vertical-rl;" |
| 363 " position: absolute; top: 111px; left: 222px; border: solid red;" | 388 " position: absolute; top: 111px; left: 222px; border: solid red;" |
| 364 " border-width: 10px 20px 30px 40px; overflow: scroll; width: 50px;" | 389 " border-width: 10px 20px 30px 40px; overflow: scroll; width: 50px;" |
| 365 " height: 80px'>" | 390 " height: 80px'>" |
| 366 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" | 391 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" |
| 367 " height: 90px'></div>" | 392 " height: 90px'></div>" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 396 | 421 |
| 397 rect = targetLocalVisualRect; | 422 rect = targetLocalVisualRect; |
| 398 target->flipForWritingMode(rect); | 423 target->flipForWritingMode(rect); |
| 399 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); | 424 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); |
| 400 rect.move(-container->scrolledContentOffset()); | 425 rect.move(-container->scrolledContentOffset()); |
| 401 // -2 = target_physical_x(100) + container_border_left(40) - scroll_left(142) | 426 // -2 = target_physical_x(100) + container_border_left(40) - scroll_left(142) |
| 402 // 3 = target_y(0) + container_border_top(10) - scroll_top(7) | 427 // 3 = target_y(0) + container_border_top(10) - scroll_top(7) |
| 403 // Rect is clipped by container's overflow clip because of overflow:scroll. | 428 // Rect is clipped by container's overflow clip because of overflow:scroll. |
| 404 EXPECT_EQ(LayoutRect(-2, 3, 140, 110), rect); | 429 EXPECT_EQ(LayoutRect(-2, 3, 140, 110), rect); |
| 405 | 430 |
| 406 rect = targetLocalVisualRect; | 431 checkPaintInvalidationVisualRect(*target); |
| 407 target->flipForWritingMode(rect); | |
| 408 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | |
| 409 // (-2, 3, 140, 100) is first clipped by container's overflow clip, to | 432 // (-2, 3, 140, 100) is first clipped by container's overflow clip, to |
| 410 // (40, 10, 50, 80), then is added by container's offset in LayoutView | 433 // (40, 10, 50, 80), then is added by container's offset in LayoutView |
| 411 // (111, 222). | 434 // (111, 222). |
| 412 // TODO(crbug.com/600039): rect.x() should be 262 (left + border-left), but is | 435 // TODO(crbug.com/600039): rect.x() should be 262 (left + border-left), but is |
| 413 // offset | 436 // offset |
| 414 // by extra horizontal border-widths because of layout error. | 437 // by extra horizontal border-widths because of layout error. |
| 415 EXPECT_EQ(LayoutRect(322, 121, 50, 80), rect); | 438 EXPECT_EQ(LayoutRect(322, 121, 50, 80), target->visualRect()); |
| 416 EXPECT_EQ(rect, target->visualRect()); | |
| 417 | 439 |
| 418 LayoutRect containerLocalVisualRect = container->localVisualRect(); | 440 LayoutRect containerLocalVisualRect = container->localVisualRect(); |
| 419 // Because container has overflow clip, its visual overflow doesn't include | 441 // Because container has overflow clip, its visual overflow doesn't include |
| 420 // overflow from children. | 442 // overflow from children. |
| 421 // 110 = width(50) + border_left_width(40) + border_right_width(20) | 443 // 110 = width(50) + border_left_width(40) + border_right_width(20) |
| 422 // 120 = height(80) + border_top_width(10) + border_bottom_width(30) | 444 // 120 = height(80) + border_top_width(10) + border_bottom_width(30) |
| 423 EXPECT_EQ(LayoutRect(0, 0, 110, 120), containerLocalVisualRect); | 445 EXPECT_EQ(LayoutRect(0, 0, 110, 120), containerLocalVisualRect); |
| 424 | 446 |
| 425 rect = containerLocalVisualRect; | 447 rect = containerLocalVisualRect; |
| 426 container->flipForWritingMode(rect); | 448 container->flipForWritingMode(rect); |
| 427 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); | 449 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(container, rect)); |
| 428 EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect); | 450 EXPECT_EQ(LayoutRect(0, 0, 110, 120), rect); |
| 429 | 451 |
| 430 rect = containerLocalVisualRect; | |
| 431 container->flipForWritingMode(rect); | |
| 432 EXPECT_TRUE(container->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | |
| 433 // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by | 452 // TODO(crbug.com/600039): rect.x() should be 222 (left), but is offset by |
| 434 // extra horizontal | 453 // extra horizontal |
| 435 // border-widths because of layout error. | 454 // border-widths because of layout error. |
| 436 EXPECT_EQ(LayoutRect(282, 111, 110, 120), rect); | 455 checkPaintInvalidationVisualRect(*container); |
| 437 EXPECT_EQ(rect, container->visualRect()); | 456 EXPECT_EQ(LayoutRect(282, 111, 110, 120), container->visualRect()); |
| 438 } | 457 } |
| 439 | 458 |
| 440 TEST_F(VisualRectMappingTest, ContainerOverflowHidden) { | 459 TEST_F(VisualRectMappingTest, ContainerOverflowHidden) { |
| 441 setBodyInnerHTML( | 460 setBodyInnerHTML( |
| 442 "<div id='container' style='position: absolute; top: 111px; left: 222px;" | 461 "<div id='container' style='position: absolute; top: 111px; left: 222px;" |
| 443 " border: 10px solid red; overflow: hidden; width: 50px;" | 462 " border: 10px solid red; overflow: hidden; width: 50px;" |
| 444 " height: 80px;'>" | 463 " height: 80px;'>" |
| 445 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" | 464 " <div id='target' style='box-shadow: 40px 20px black; width: 100px;" |
| 446 " height: 90px'></div>" | 465 " height: 90px'></div>" |
| 447 "</div>"); | 466 "</div>"); |
| 448 | 467 |
| 449 LayoutBlock* container = | 468 LayoutBlock* container = |
| 450 toLayoutBlock(getLayoutObjectByElementId("container")); | 469 toLayoutBlock(getLayoutObjectByElementId("container")); |
| 451 EXPECT_EQ(LayoutUnit(), container->scrollTop()); | 470 EXPECT_EQ(LayoutUnit(), container->scrollTop()); |
| 452 EXPECT_EQ(LayoutUnit(), container->scrollLeft()); | 471 EXPECT_EQ(LayoutUnit(), container->scrollLeft()); |
| 453 container->setScrollTop(LayoutUnit(27)); | 472 container->setScrollTop(LayoutUnit(27)); |
| 454 container->setScrollLeft(LayoutUnit(28)); | 473 container->setScrollLeft(LayoutUnit(28)); |
| 455 document().view()->updateAllLifecyclePhases(); | 474 document().view()->updateAllLifecyclePhases(); |
| 456 | 475 |
| 457 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); | 476 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); |
| 458 LayoutRect targetLocalVisualRect = target->localVisualRect(); | 477 LayoutRect targetLocalVisualRect = target->localVisualRect(); |
| 459 // 140 = width(100) + box_shadow_offset_x(40) | 478 // 140 = width(100) + box_shadow_offset_x(40) |
| 460 // 110 = height(90) + box_shadow_offset_y(20) | 479 // 110 = height(90) + box_shadow_offset_y(20) |
| 461 EXPECT_EQ(LayoutRect(0, 0, 140, 110), targetLocalVisualRect); | 480 EXPECT_EQ(LayoutRect(0, 0, 140, 110), targetLocalVisualRect); |
| 462 LayoutRect rect = targetLocalVisualRect; | 481 LayoutRect rect = targetLocalVisualRect; |
| 463 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); | 482 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); |
| 464 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); | 483 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); |
| 465 | 484 |
| 466 rect = targetLocalVisualRect; | 485 rect = targetLocalVisualRect; |
| 467 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); | |
| 468 // Rect is not clipped by container's overflow clip. | 486 // Rect is not clipped by container's overflow clip. |
| 469 EXPECT_EQ(LayoutRect(10, 10, 140, 110), rect); | 487 checkVisualRect(*target, *container, rect, LayoutRect(10, 10, 140, 110)); |
| 470 } | 488 } |
| 471 | 489 |
| 472 TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowHidden) { | 490 TEST_F(VisualRectMappingTest, ContainerFlippedWritingModeAndOverflowHidden) { |
| 473 setBodyInnerHTML( | 491 setBodyInnerHTML( |
| 474 "<div id='container' style='writing-mode: vertical-rl; " | 492 "<div id='container' style='writing-mode: vertical-rl; " |
| 475 " position: absolute; top: 111px; left: 222px; border: solid red; " | 493 " position: absolute; top: 111px; left: 222px; border: solid red; " |
| 476 " border-width: 10px 20px 30px 40px; overflow: hidden; width: 50px; " | 494 " border-width: 10px 20px 30px 40px; overflow: hidden; width: 50px; " |
| 477 " height: 80px'>" | 495 " height: 80px'>" |
| 478 " <div id='target' style='box-shadow: 40px 20px black; width: 100px; " | 496 " <div id='target' style='box-shadow: 40px 20px black; width: 100px; " |
| 479 " height: 90px'></div>" | 497 " height: 90px'></div>" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 500 EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetLocalVisualRect); | 518 EXPECT_EQ(LayoutRect(-40, 0, 140, 110), targetLocalVisualRect); |
| 501 | 519 |
| 502 LayoutRect rect = targetLocalVisualRect; | 520 LayoutRect rect = targetLocalVisualRect; |
| 503 target->flipForWritingMode(rect); | 521 target->flipForWritingMode(rect); |
| 504 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); | 522 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(target, rect)); |
| 505 // This rect is in physical coordinates of target. | 523 // This rect is in physical coordinates of target. |
| 506 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); | 524 EXPECT_EQ(LayoutRect(0, 0, 140, 110), rect); |
| 507 | 525 |
| 508 rect = targetLocalVisualRect; | 526 rect = targetLocalVisualRect; |
| 509 target->flipForWritingMode(rect); | 527 target->flipForWritingMode(rect); |
| 528 // 58 = target_physical_x(100) + container_border_left(40) - scroll_left(58) |
| 529 checkVisualRect(*target, *container, rect, LayoutRect(-10, 10, 140, 110)); |
| 510 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); | 530 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(container, rect)); |
| 511 // 58 = target_physical_x(100) + container_border_left(40) - scroll_left(58) | |
| 512 EXPECT_EQ(LayoutRect(-10, 10, 140, 110), rect); | |
| 513 } | 531 } |
| 514 | 532 |
| 515 TEST_F(VisualRectMappingTest, ContainerAndTargetDifferentFlippedWritingMode) { | 533 TEST_F(VisualRectMappingTest, ContainerAndTargetDifferentFlippedWritingMode) { |
| 516 setBodyInnerHTML( | 534 setBodyInnerHTML( |
| 517 "<div id='container' style='writing-mode: vertical-rl;" | 535 "<div id='container' style='writing-mode: vertical-rl;" |
| 518 " position: absolute; top: 111px; left: 222px; border: solid red;" | 536 " position: absolute; top: 111px; left: 222px; border: solid red;" |
| 519 " border-width: 10px 20px 30px 40px; overflow: scroll; width: 50px;" | 537 " border-width: 10px 20px 30px 40px; overflow: scroll; width: 50px;" |
| 520 " height: 80px'>" | 538 " height: 80px'>" |
| 521 " <div id='target' style='writing-mode: vertical-lr; width: 100px;" | 539 " <div id='target' style='writing-mode: vertical-lr; width: 100px;" |
| 522 " height: 90px; box-shadow: 40px 20px black'></div>" | 540 " height: 90px; box-shadow: 40px 20px black'></div>" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 588 EXPECT_TRUE(normalFlow->mapToVisualRectInAncestorSpace(scroller, rect)); | 606 EXPECT_TRUE(normalFlow->mapToVisualRectInAncestorSpace(scroller, rect)); |
| 589 EXPECT_EQ(LayoutRect(0, 0, 2000, 2000), rect); | 607 EXPECT_EQ(LayoutRect(0, 0, 2000, 2000), rect); |
| 590 EXPECT_EQ(rect, normalFlow->visualRect()); | 608 EXPECT_EQ(rect, normalFlow->visualRect()); |
| 591 | 609 |
| 592 LayoutBlock* stackingContext = | 610 LayoutBlock* stackingContext = |
| 593 toLayoutBlock(getLayoutObjectByElementId("stacking-context")); | 611 toLayoutBlock(getLayoutObjectByElementId("stacking-context")); |
| 594 LayoutBlock* absolute = toLayoutBlock(getLayoutObjectByElementId("absolute")); | 612 LayoutBlock* absolute = toLayoutBlock(getLayoutObjectByElementId("absolute")); |
| 595 EXPECT_EQ(stackingContext, &absolute->containerForPaintInvalidation()); | 613 EXPECT_EQ(stackingContext, &absolute->containerForPaintInvalidation()); |
| 596 EXPECT_EQ(stackingContext, absolute->container()); | 614 EXPECT_EQ(stackingContext, absolute->container()); |
| 597 | 615 |
| 598 LayoutRect absoluteVisualRect = absolute->localVisualRect(); | 616 EXPECT_EQ(LayoutRect(0, 0, 50, 50), absolute->localVisualRect()); |
| 599 EXPECT_EQ(LayoutRect(0, 0, 50, 50), absoluteVisualRect); | 617 checkPaintInvalidationVisualRect(*absolute); |
| 600 rect = absoluteVisualRect; | 618 EXPECT_EQ(LayoutRect(222, 111, 50, 50), absolute->visualRect()); |
| 601 EXPECT_TRUE(absolute->mapToVisualRectInAncestorSpace(stackingContext, rect)); | |
| 602 EXPECT_EQ(LayoutRect(222, 111, 50, 50), rect); | |
| 603 EXPECT_EQ(rect, absolute->visualRect()); | |
| 604 } | 619 } |
| 605 | 620 |
| 606 TEST_F(VisualRectMappingTest, | 621 TEST_F(VisualRectMappingTest, |
| 607 ContainerOfAbsoluteAbovePaintInvalidationContainer) { | 622 ContainerOfAbsoluteAbovePaintInvalidationContainer) { |
| 608 enableCompositing(); | 623 enableCompositing(); |
| 609 document().frame()->settings()->setPreferCompositingToLCDTextEnabled(true); | 624 document().frame()->settings()->setPreferCompositingToLCDTextEnabled(true); |
| 610 | 625 |
| 611 setBodyInnerHTML( | 626 setBodyInnerHTML( |
| 612 "<div id='container' style='position: absolute; top: 88px; left: 99px'>" | 627 "<div id='container' style='position: absolute; top: 88px; left: 99px'>" |
| 613 " <div style='height: 222px'></div>" | 628 " <div style='height: 222px'></div>" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 642 | 657 |
| 643 TEST_F(VisualRectMappingTest, CSSClip) { | 658 TEST_F(VisualRectMappingTest, CSSClip) { |
| 644 setBodyInnerHTML( | 659 setBodyInnerHTML( |
| 645 "<div id='container' style='position: absolute; top: 0px; left: 0px; " | 660 "<div id='container' style='position: absolute; top: 0px; left: 0px; " |
| 646 " clip: rect(0px, 200px, 200px, 0px)'>" | 661 " clip: rect(0px, 200px, 200px, 0px)'>" |
| 647 " <div id='target' style='width: 400px; height: 400px'></div>" | 662 " <div id='target' style='width: 400px; height: 400px'></div>" |
| 648 "</div>"); | 663 "</div>"); |
| 649 | 664 |
| 650 LayoutBox* target = toLayoutBox(getLayoutObjectByElementId("target")); | 665 LayoutBox* target = toLayoutBox(getLayoutObjectByElementId("target")); |
| 651 | 666 |
| 652 LayoutRect targetLocalVisualRect = target->localVisualRect(); | 667 EXPECT_EQ(LayoutRect(0, 0, 400, 400), target->localVisualRect()); |
| 653 EXPECT_EQ(LayoutRect(0, 0, 400, 400), targetLocalVisualRect); | 668 checkPaintInvalidationVisualRect(*target); |
| 654 LayoutRect rect = targetLocalVisualRect; | 669 EXPECT_EQ(LayoutRect(0, 0, 200, 200), target->visualRect()); |
| 655 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | |
| 656 EXPECT_EQ(LayoutRect(0, 0, 200, 200), rect); | |
| 657 EXPECT_EQ(rect, target->visualRect()); | |
| 658 } | 670 } |
| 659 | 671 |
| 660 TEST_F(VisualRectMappingTest, ContainPaint) { | 672 TEST_F(VisualRectMappingTest, ContainPaint) { |
| 661 setBodyInnerHTML( | 673 setBodyInnerHTML( |
| 662 "<div id='container' style='position: absolute; top: 0px; left: 0px; " | 674 "<div id='container' style='position: absolute; top: 0px; left: 0px; " |
| 663 " width: 200px; height: 200px; contain: paint'>" | 675 " width: 200px; height: 200px; contain: paint'>" |
| 664 " <div id='target' style='width: 400px; height: 400px'></div>" | 676 " <div id='target' style='width: 400px; height: 400px'></div>" |
| 665 "</div>"); | 677 "</div>"); |
| 666 | 678 |
| 667 LayoutBox* target = toLayoutBox(getLayoutObjectByElementId("target")); | 679 LayoutBox* target = toLayoutBox(getLayoutObjectByElementId("target")); |
| 668 | 680 |
| 669 LayoutRect targetLocalVisualRect = target->localVisualRect(); | 681 EXPECT_EQ(LayoutRect(0, 0, 400, 400), target->localVisualRect()); |
| 670 EXPECT_EQ(LayoutRect(0, 0, 400, 400), targetLocalVisualRect); | 682 checkPaintInvalidationVisualRect(*target); |
| 671 LayoutRect rect = targetLocalVisualRect; | 683 EXPECT_EQ(LayoutRect(0, 0, 200, 200), target->visualRect()); |
| 672 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | |
| 673 EXPECT_EQ(LayoutRect(0, 0, 200, 200), rect); | |
| 674 EXPECT_EQ(rect, target->visualRect()); | |
| 675 } | 684 } |
| 676 | 685 |
| 677 TEST_F(VisualRectMappingTest, FloatUnderInline) { | 686 TEST_F(VisualRectMappingTest, FloatUnderInline) { |
| 678 setBodyInnerHTML( | 687 setBodyInnerHTML( |
| 679 "<div style='position: absolute; top: 55px; left: 66px'>" | 688 "<div style='position: absolute; top: 55px; left: 66px'>" |
| 680 " <span id='span' style='position: relative; top: 100px; left: 200px'>" | 689 " <span id='span' style='position: relative; top: 100px; left: 200px'>" |
| 681 " <div id='target' style='float: left; width: 33px; height: 44px'>" | 690 " <div id='target' style='float: left; width: 33px; height: 44px'>" |
| 682 " </div>" | 691 " </div>" |
| 683 " </span>" | 692 " </span>" |
| 684 "</div>"); | 693 "</div>"); |
| 685 | 694 |
| 686 LayoutBoxModelObject* span = | 695 LayoutBoxModelObject* span = |
| 687 toLayoutBoxModelObject(getLayoutObjectByElementId("span")); | 696 toLayoutBoxModelObject(getLayoutObjectByElementId("span")); |
| 688 LayoutBox* target = toLayoutBox(getLayoutObjectByElementId("target")); | 697 LayoutBox* target = toLayoutBox(getLayoutObjectByElementId("target")); |
| 689 | 698 |
| 690 LayoutRect targetVisualRect = target->localVisualRect(); | 699 LayoutRect targetVisualRect = target->localVisualRect(); |
| 691 EXPECT_EQ(LayoutRect(0, 0, 33, 44), targetVisualRect); | 700 EXPECT_EQ(LayoutRect(0, 0, 33, 44), targetVisualRect); |
| 692 | 701 |
| 693 LayoutRect rect = targetVisualRect; | 702 LayoutRect rect = targetVisualRect; |
| 694 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); | 703 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(&layoutView(), rect)); |
| 695 EXPECT_EQ(LayoutRect(66, 55, 33, 44), rect); | 704 EXPECT_EQ(LayoutRect(66, 55, 33, 44), rect); |
| 696 EXPECT_EQ(rect, target->visualRect()); | 705 EXPECT_EQ(rect, target->visualRect()); |
| 697 | 706 |
| 698 rect = targetVisualRect; | 707 rect = targetVisualRect; |
| 699 EXPECT_TRUE(target->mapToVisualRectInAncestorSpace(span, rect)); | 708 |
| 700 EXPECT_EQ(LayoutRect(-200, -100, 33, 44), rect); | 709 checkVisualRect(*target, *span, rect, LayoutRect(-200, -100, 33, 44)); |
| 701 } | 710 } |
| 702 | 711 |
| 703 TEST_F(VisualRectMappingTest, ShouldAccountForPreserve3d) { | 712 TEST_F(VisualRectMappingTest, ShouldAccountForPreserve3d) { |
| 704 enableCompositing(); | 713 enableCompositing(); |
| 705 setBodyInnerHTML( | 714 setBodyInnerHTML( |
| 706 "<style>" | 715 "<style>" |
| 707 "* { margin: 0; }" | 716 "* { margin: 0; }" |
| 708 "#container {" | 717 "#container {" |
| 709 " transform: rotateX(-45deg);" | 718 " transform: rotateX(-45deg);" |
| 710 " width: 100px; height: 100px;" | 719 " width: 100px; height: 100px;" |
| 711 "}" | 720 "}" |
| 712 "#target {" | 721 "#target {" |
| 713 " transform-style: preserve-3d; transform: rotateX(45deg);" | 722 " transform-style: preserve-3d; transform: rotateX(45deg);" |
| 714 " background: lightblue;" | 723 " background: lightblue;" |
| 715 " width: 100px; height: 100px;" | 724 " width: 100px; height: 100px;" |
| 716 "}" | 725 "}" |
| 717 "</style>" | 726 "</style>" |
| 718 "<div id='container'><div id='target'></div></div>"); | 727 "<div id='container'><div id='target'></div></div>"); |
| 719 LayoutBlock* container = | 728 LayoutBlock* container = |
| 720 toLayoutBlock(getLayoutObjectByElementId("container")); | 729 toLayoutBlock(getLayoutObjectByElementId("container")); |
| 721 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); | 730 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); |
| 722 LayoutRect originalRect(0, 0, 100, 100); | 731 LayoutRect originalRect(0, 0, 100, 100); |
| 723 // Multiply both matrices together before flattening. | 732 // Multiply both matrices together before flattening. |
| 724 TransformationMatrix matrix = container->layer()->currentTransform(); | 733 TransformationMatrix matrix = container->layer()->currentTransform(); |
| 734 matrix.flattenTo2d(); |
| 735 matrix *= target->layer()->currentTransform(); |
| 736 LayoutRect output(matrix.mapRect(FloatRect(originalRect))); |
| 737 |
| 738 checkVisualRect(*target, *target->view(), originalRect, output); |
| 739 } |
| 740 |
| 741 TEST_F(VisualRectMappingTest, ShouldAccountForPreserve3dNested) { |
| 742 enableCompositing(); |
| 743 setBodyInnerHTML( |
| 744 "<style>" |
| 745 "* { margin: 0; }" |
| 746 "#container {" |
| 747 " transform-style: preserve-3d;" |
| 748 " transform: rotateX(-45deg);" |
| 749 " width: 100px; height: 100px;" |
| 750 "}" |
| 751 "#target {" |
| 752 " transform-style: preserve-3d; transform: rotateX(45deg);" |
| 753 " background: lightblue;" |
| 754 " width: 100px; height: 100px;" |
| 755 "}" |
| 756 "</style>" |
| 757 "<div id='container'><div id='target'></div></div>"); |
| 758 LayoutBlock* container = |
| 759 toLayoutBlock(getLayoutObjectByElementId("container")); |
| 760 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); |
| 761 LayoutRect originalRect(0, 0, 100, 100); |
| 762 // Multiply both matrices together before flattening. |
| 763 TransformationMatrix matrix = container->layer()->currentTransform(); |
| 725 matrix *= target->layer()->currentTransform(); | 764 matrix *= target->layer()->currentTransform(); |
| 726 matrix.flattenTo2d(); | 765 LayoutRect output(matrix.mapRect(FloatRect(originalRect))); |
| 727 FloatRect output = matrix.mapRect(FloatRect(originalRect)); | |
| 728 | 766 |
| 729 EXPECT_TRUE( | 767 checkVisualRect(*target, *target->view(), originalRect, output); |
| 730 target->mapToVisualRectInAncestorSpace(target->view(), originalRect)); | |
| 731 EXPECT_EQ(LayoutRect(enclosingIntRect(output)), originalRect); | |
| 732 } | 768 } |
| 733 | 769 |
| 734 TEST_F(VisualRectMappingTest, ShouldAccountForPerspective) { | 770 TEST_F(VisualRectMappingTest, ShouldAccountForPerspective) { |
| 735 enableCompositing(); | 771 enableCompositing(); |
| 736 setBodyInnerHTML( | 772 setBodyInnerHTML( |
| 737 "<style>" | 773 "<style>" |
| 738 "* { margin: 0; }" | 774 "* { margin: 0; }" |
| 739 "#container {" | 775 "#container {" |
| 740 " transform: rotateX(-45deg); perspective: 100px;" | 776 " transform: rotateX(-45deg); perspective: 100px;" |
| 741 " width: 100px; height: 100px;" | 777 " width: 100px; height: 100px;" |
| 742 "}" | 778 "}" |
| 743 "#target {" | 779 "#target {" |
| 744 " transform-style: preserve-3d; transform: rotateX(45deg);" | 780 " transform-style: preserve-3d; transform: rotateX(45deg);" |
| 745 " background: lightblue;" | 781 " background: lightblue;" |
| 746 " width: 100px; height: 100px;" | 782 " width: 100px; height: 100px;" |
| 747 "}" | 783 "}" |
| 748 "</style>" | 784 "</style>" |
| 749 "<div id='container'><div id='target'></div></div>"); | 785 "<div id='container'><div id='target'></div></div>"); |
| 750 LayoutBlock* container = | 786 LayoutBlock* container = |
| 751 toLayoutBlock(getLayoutObjectByElementId("container")); | 787 toLayoutBlock(getLayoutObjectByElementId("container")); |
| 752 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); | 788 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); |
| 753 LayoutRect originalRect(0, 0, 100, 100); | 789 LayoutRect originalRect(0, 0, 100, 100); |
| 754 TransformationMatrix matrix = container->layer()->currentTransform(); | 790 TransformationMatrix matrix = container->layer()->currentTransform(); |
| 791 matrix.flattenTo2d(); |
| 792 TransformationMatrix targetMatrix; |
| 793 // getTransformfromContainter includes transform and perspective matrix |
| 794 // of the container. |
| 795 target->getTransformFromContainer(container, LayoutSize(), targetMatrix); |
| 796 matrix *= targetMatrix; |
| 797 LayoutRect output(matrix.mapRect(FloatRect(originalRect))); |
| 798 |
| 799 checkVisualRect(*target, *target->view(), originalRect, output); |
| 800 } |
| 801 |
| 802 TEST_F(VisualRectMappingTest, ShouldAccountForPerspectiveNested) { |
| 803 enableCompositing(); |
| 804 setBodyInnerHTML( |
| 805 "<style>" |
| 806 "* { margin: 0; }" |
| 807 "#container {" |
| 808 " transform-style: preserve-3d;" |
| 809 " transform: rotateX(-45deg); perspective: 100px;" |
| 810 " width: 100px; height: 100px;" |
| 811 "}" |
| 812 "#target {" |
| 813 " transform-style: preserve-3d; transform: rotateX(45deg);" |
| 814 " background: lightblue;" |
| 815 " width: 100px; height: 100px;" |
| 816 "}" |
| 817 "</style>" |
| 818 "<div id='container'><div id='target'></div></div>"); |
| 819 LayoutBlock* container = |
| 820 toLayoutBlock(getLayoutObjectByElementId("container")); |
| 821 LayoutBlock* target = toLayoutBlock(getLayoutObjectByElementId("target")); |
| 822 LayoutRect originalRect(0, 0, 100, 100); |
| 823 TransformationMatrix matrix = container->layer()->currentTransform(); |
| 755 TransformationMatrix targetMatrix; | 824 TransformationMatrix targetMatrix; |
| 756 // getTransformfromContainter includes transform and perspective matrix | 825 // getTransformfromContainter includes transform and perspective matrix |
| 757 // of the container. | 826 // of the container. |
| 758 target->getTransformFromContainer(container, LayoutSize(), targetMatrix); | 827 target->getTransformFromContainer(container, LayoutSize(), targetMatrix); |
| 759 matrix *= targetMatrix; | 828 matrix *= targetMatrix; |
| 760 matrix.flattenTo2d(); | 829 LayoutRect output(matrix.mapRect(FloatRect(originalRect))); |
| 761 FloatRect output = matrix.mapRect(FloatRect(originalRect)); | |
| 762 | 830 |
| 763 EXPECT_TRUE( | 831 checkVisualRect(*target, *target->view(), originalRect, output); |
| 764 target->mapToVisualRectInAncestorSpace(target->view(), originalRect)); | |
| 765 EXPECT_EQ(LayoutRect(enclosingIntRect(output)), originalRect); | |
| 766 } | 832 } |
| 767 | 833 |
| 768 } // namespace blink | 834 } // namespace blink |
| OLD | NEW |