Changeset 279544 in webkit
- Timestamp:
- Jul 3, 2021, 10:27:46 AM (4 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r279543 r279544 1 2021-07-03 Alan Bujtas <zalan@apple.com> 2 3 REGRESSION (r278377): incorrect hit-testing with clip-path() 4 https://bugs.webkit.org/show_bug.cgi?id=227624 5 <rdar://problem/79845896> 6 7 Reviewed by Simon Fraser. 8 9 * fast/clip/hit-test-with-clip-path-expected.txt: Added. 10 * fast/clip/hit-test-with-clip-path.html: Added. 11 1 12 2021-07-03 Alan Bujtas <zalan@apple.com> 2 13 -
trunk/Source/WebCore/ChangeLog
r279543 r279544 1 2021-07-03 Alan Bujtas <zalan@apple.com> 2 3 REGRESSION (r278377): incorrect hit-testing with clip-path() 4 https://bugs.webkit.org/show_bug.cgi?id=227624 5 <rdar://problem/79845896> 6 7 Reviewed by Simon Fraser. 8 9 Use the correct coordinate space for clip-path based hittesting. 10 11 1. The hittest location is in the coordinate space of the painting root (hittesting is similar to painting in this context). 12 2. RenderBox::hitTestClipPath's accumulatedOffset (as the name implies) should include the offset from the (paint) hittest root. 13 3. The clip-path intersecting takes coordinates relative to the containing block. 14 15 Test: fast/clip/hit-test-with-clip-path.html 16 17 * rendering/RenderBox.cpp: 18 (WebCore::RenderBox::hitTestVisualOverflow const): 19 (WebCore::RenderBox::hitTestClipPath const): Make the hittest root coordinates relative to the containing block. 20 (WebCore::RenderBox::hitTestBorderRadius const): 21 * rendering/RenderBox.h: Let's not use locationInContainer name as it is way too generic and misleading. 22 * rendering/RenderLayer.cpp: Compute and pass in proper accumulated offset value. 23 (WebCore::RenderLayer::hitTestLayer): 24 1 25 2021-07-03 Alan Bujtas <zalan@apple.com> 2 26 -
trunk/Source/WebCore/rendering/RenderBox.cpp
r279218 r279544 1362 1362 1363 1363 // Hit Testing 1364 bool RenderBox::hitTestVisualOverflow(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const1364 bool RenderBox::hitTestVisualOverflow(const HitTestLocation& hitTestLocation, const LayoutPoint& accumulatedOffset) const 1365 1365 { 1366 1366 if (isRenderView()) … … 1371 1371 flipForWritingMode(overflowBox); 1372 1372 overflowBox.moveBy(adjustedLocation); 1373 return locationInContainer.intersects(overflowBox);1374 } 1375 1376 bool RenderBox::hitTestClipPath(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const1373 return hitTestLocation.intersects(overflowBox); 1374 } 1375 1376 bool RenderBox::hitTestClipPath(const HitTestLocation& hitTestLocation, const LayoutPoint& accumulatedOffset) const 1377 1377 { 1378 1378 if (!style().clipPath()) 1379 1379 return true; 1380 1380 1381 LayoutPoint adjustedLocation = accumulatedOffset + location(); 1382 const LayoutSize localOffset = toLayoutSize(adjustedLocation); 1383 1381 auto offsetFromHitTestRoot = toLayoutSize(accumulatedOffset + location()); 1382 auto hitTestLocationInLocalCoordinates = hitTestLocation.point() - offsetFromHitTestRoot; 1384 1383 switch (style().clipPath()->type()) { 1385 1384 case ClipPathOperation::Shape: { 1386 1385 auto& clipPath = downcast<ShapeClipPathOperation>(*style().clipPath()); 1387 1386 auto referenceBoxRect = referenceBox(clipPath.referenceBox()); 1388 if (!clipPath.pathForReferenceRect(referenceBoxRect).contains( locationInContainer.point() - localOffset, clipPath.windRule()))1387 if (!clipPath.pathForReferenceRect(referenceBoxRect).contains(hitTestLocationInLocalCoordinates, clipPath.windRule())) 1389 1388 return false; 1390 1389 break; … … 1398 1397 break; 1399 1398 auto& clipper = downcast<RenderSVGResourceClipper>(*element->renderer()); 1400 if (!clipper.hitTestClipContent(FloatRect(borderBoxRect()), FloatPoint (locationInContainer.point() - localOffset)))1399 if (!clipper.hitTestClipContent(FloatRect(borderBoxRect()), FloatPoint { hitTestLocationInLocalCoordinates })) 1401 1400 return false; 1402 1401 break; … … 1409 1408 } 1410 1409 1411 bool RenderBox::hitTestBorderRadius(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const1410 bool RenderBox::hitTestBorderRadius(const HitTestLocation& hitTestLocation, const LayoutPoint& accumulatedOffset) const 1412 1411 { 1413 1412 if (isRenderView() || !style().hasBorderRadius()) … … 1418 1417 borderRect.moveBy(adjustedLocation); 1419 1418 RoundedRect border = style().getRoundedBorderFor(borderRect); 1420 return locationInContainer.intersects(border);1419 return hitTestLocation.intersects(border); 1421 1420 } 1422 1421 -
trunk/Source/WebCore/rendering/RenderBox.h
r279278 r279544 306 306 307 307 void layout() override; 308 bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;309 bool hitTestVisualOverflow(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const;310 bool hitTestClipPath(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const;311 bool hitTestBorderRadius(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const;308 bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint& accumulatedOffset, HitTestAction) override; 309 bool hitTestVisualOverflow(const HitTestLocation&, const LayoutPoint& accumulatedOffset) const; 310 bool hitTestClipPath(const HitTestLocation&, const LayoutPoint& accumulatedOffset) const; 311 bool hitTestBorderRadius(const HitTestLocation&, const LayoutPoint& accumulatedOffset) const; 312 312 313 313 LayoutUnit minPreferredLogicalWidth() const override; -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r279056 r279544 4112 4112 #endif 4113 4113 4114 auto offsetFromRoot = offsetFromAncestor(rootLayer); 4114 4115 // FIXME: We need to correctly hit test the clip-path when we have a RenderInline too. 4115 if ( renderer().hasClipPath() && is<RenderBox>(renderer()) && !downcast<RenderBox>(renderer()).hitTestClipPath(hitTestLocation, toLayoutPoint(location() - renderBoxLocation())))4116 if (auto* rendererBox = this->renderBox(); rendererBox && !rendererBox->hitTestClipPath(hitTestLocation, toLayoutPoint(offsetFromRoot - toLayoutSize(renderBoxLocation())))) 4116 4117 return nullptr; 4117 4118 … … 4136 4137 // Collect the fragments. This will compute the clip rectangles for each layer fragment. 4137 4138 LayerFragments layerFragments; 4138 collectFragments(layerFragments, rootLayer, hitTestRect, IncludeCompositedPaginatedLayers, RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, 4139 offsetFromAncestor(rootLayer)); 4139 collectFragments(layerFragments, rootLayer, hitTestRect, IncludeCompositedPaginatedLayers, RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, offsetFromRoot); 4140 4140 4141 4141 LayoutPoint localPoint;
Note:
See TracChangeset
for help on using the changeset viewer.