Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Unified Diff: third_party/WebKit/Source/core/layout/LayoutBox.cpp

Issue 1506053003: Include clip-path and border radius when hit testing boxes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Hit test in PaintLayer, add transformed clip path tests Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/LayoutBox.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutBox.cpp b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
index bfad641c59b9089a771dba662875309972fedf8c..69333b1bfcf0df09978fde86db3b98ae368d2a0d 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBox.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutBox.cpp
@@ -54,6 +54,7 @@
#include "core/layout/LayoutView.h"
#include "core/layout/compositing/PaintLayerCompositor.h"
#include "core/layout/shapes/ShapeOutsideInfo.h"
+#include "core/layout/svg/LayoutSVGResourceClipper.h"
#include "core/page/AutoscrollController.h"
#include "core/page/Page.h"
#include "core/paint/BackgroundImageGeometry.h"
@@ -1165,9 +1166,14 @@ bool LayoutBox::nodeAtPoint(HitTestResult& result, const HitTestLocation& locati
// Exit early if no children can be hit.
LayoutRect overflowRect = visualOverflowRect();
overflowRect.moveBy(adjustedLocation);
- if (!locationInContainer.intersects(overflowRect)) {
+ if (!locationInContainer.intersects(overflowRect))
return false;
- }
+
+ // Clip path hit testing should already be handled by PaintLayer.
+ ASSERT(!hitTestClippedOutByClipPath(locationInContainer, adjustedLocation));
+
+ // TODO(pdr): We should also check for css clip in the !isSelfPaintingLayer
+ // case, similar to overflow clip in LayoutBlock::nodeAtPoint.
// Check kids first.
for (LayoutObject* child = slowLastChild(); child; child = child->previousSibling()) {
@@ -1177,6 +1183,9 @@ bool LayoutBox::nodeAtPoint(HitTestResult& result, const HitTestLocation& locati
}
}
+ if (hitTestClippedOutByRoundedBorder(locationInContainer, adjustedLocation))
+ return false;
+
// Check our bounds next. For this purpose always assume that we can only be hit in the
// foreground phase (which is true for replaced elements like images).
LayoutRect boundsRect = borderBoxRect();
@@ -1190,6 +1199,40 @@ bool LayoutBox::nodeAtPoint(HitTestResult& result, const HitTestLocation& locati
return false;
}
+bool LayoutBox::hitTestClippedOutByClipPath(const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset) const
+{
+ if (!style()->clipPath())
+ return false;
+
+ if (style()->clipPath()->type() == ClipPathOperation::SHAPE) {
+ ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()->clipPath());
+ // FIXME: handle marginBox etc.
+ if (!clipPath->path(FloatRect(borderBoxRect())).contains(FloatPoint(locationInContainer.point() - toLayoutSize(accumulatedOffset)), clipPath->windRule()))
+ return true;
+ } else {
+ ASSERT(style()->clipPath()->type() == ClipPathOperation::REFERENCE);
+ ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style()->clipPath());
+ Element* element = document().getElementById(referenceClipPathOperation->fragment());
+ if (isSVGClipPathElement(element) && element->layoutObject()) {
+ LayoutSVGResourceClipper* clipper = toLayoutSVGResourceClipper(toLayoutSVGResourceContainer(element->layoutObject()));
+ if (!clipper->hitTestClipContent(FloatRect(borderBoxRect()), FloatPoint(locationInContainer.point() - toLayoutSize(accumulatedOffset))))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool LayoutBox::hitTestClippedOutByRoundedBorder(const HitTestLocation& locationInContainer, const LayoutPoint& borderBoxLocation) const
+{
+ if (!style()->hasBorderRadius())
+ return false;
+
+ LayoutRect borderRect = borderBoxRect();
+ borderRect.moveBy(borderBoxLocation);
+ return !locationInContainer.intersects(style()->getRoundedBorderFor(borderRect));
+}
+
void LayoutBox::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) const
{
BoxPainter(*this).paint(paintInfo, paintOffset);
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutBox.h ('k') | third_party/WebKit/Source/core/paint/PaintLayer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698