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