diff options
-rw-r--r-- | WebCore/config.h | 3 | ||||
-rw-r--r-- | WebCore/page/EventHandler.cpp | 12 | ||||
-rw-r--r-- | WebCore/page/EventHandler.h | 4 | ||||
-rw-r--r-- | WebCore/rendering/EllipsisBox.cpp | 13 | ||||
-rw-r--r-- | WebCore/rendering/HitTestResult.cpp | 63 | ||||
-rw-r--r-- | WebCore/rendering/HitTestResult.h | 22 | ||||
-rw-r--r-- | WebCore/rendering/InlineFlowBox.cpp | 16 | ||||
-rw-r--r-- | WebCore/rendering/InlineTextBox.cpp | 12 | ||||
-rw-r--r-- | WebCore/rendering/RenderBlock.cpp | 36 | ||||
-rw-r--r-- | WebCore/rendering/RenderBox.cpp | 16 | ||||
-rw-r--r-- | WebCore/rendering/RenderImage.cpp | 12 | ||||
-rw-r--r-- | WebCore/rendering/RenderLayer.cpp | 68 | ||||
-rw-r--r-- | WebCore/rendering/RenderLineBoxList.cpp | 11 | ||||
-rw-r--r-- | WebCore/rendering/RenderSVGRoot.cpp | 10 | ||||
-rw-r--r-- | WebCore/rendering/RenderTable.cpp | 20 | ||||
-rw-r--r-- | WebCore/rendering/RenderTableSection.cpp | 7 | ||||
-rw-r--r-- | WebCore/rendering/RenderWidget.cpp | 6 |
17 files changed, 331 insertions, 0 deletions
diff --git a/WebCore/config.h b/WebCore/config.h index c812ee8..8e324a5 100644 --- a/WebCore/config.h +++ b/WebCore/config.h @@ -195,6 +195,9 @@ // Enable prefetching when specified via the rel element of <link> elements. #define ENABLE_LINK_PREFETCH 1 +// Enable hit test with point plus a size +#define ANDROID_HITTEST_WITHSIZE + #endif /* PLATFORM(ANDROID) */ #ifdef __cplusplus diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp index 8f63144..042f3d4 100644 --- a/WebCore/page/EventHandler.cpp +++ b/WebCore/page/EventHandler.cpp @@ -865,9 +865,17 @@ void EventHandler::allowDHTMLDrag(bool& flagDHTML, bool& flagUA) const } #endif // ENABLE(DRAG_SUPPORT) +#ifdef ANDROID_HITTEST_WITHSIZE +HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars, const IntSize& pointPadding) +#else HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool allowShadowContent, bool ignoreClipping, HitTestScrollbars testScrollbars) +#endif { +#ifdef ANDROID_HITTEST_WITHSIZE + HitTestResult result(point, pointPadding); +#else HitTestResult result(point); +#endif if (!m_frame->contentRenderer()) return result; int hitType = HitTestRequest::ReadOnly | HitTestRequest::Active; @@ -889,7 +897,11 @@ HitTestResult EventHandler::hitTestResultAtPoint(const IntPoint& point, bool all FrameView* view = static_cast<FrameView*>(widget); IntPoint widgetPoint(result.localPoint().x() + view->scrollX() - renderWidget->borderLeft() - renderWidget->paddingLeft(), result.localPoint().y() + view->scrollY() - renderWidget->borderTop() - renderWidget->paddingTop()); +#ifdef ANDROID_HITTEST_WITHSIZE + HitTestResult widgetHitTestResult(widgetPoint, pointPadding); +#else HitTestResult widgetHitTestResult(widgetPoint); +#endif frame->contentRenderer()->layer()->hitTest(HitTestRequest(hitType), widgetHitTestResult); result = widgetHitTestResult; diff --git a/WebCore/page/EventHandler.h b/WebCore/page/EventHandler.h index c83925c..39b165d 100644 --- a/WebCore/page/EventHandler.h +++ b/WebCore/page/EventHandler.h @@ -105,7 +105,11 @@ public: void dispatchFakeMouseMoveEventSoonInQuad(const FloatQuad&); +#ifdef ANDROID_HITTEST_WITHSIZE + HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars, const IntSize& pointPadding = IntSize()); +#else HitTestResult hitTestResultAtPoint(const IntPoint&, bool allowShadowContent, bool ignoreClipping = false, HitTestScrollbars scrollbars = DontHitTestScrollbars); +#endif bool mousePressed() const { return m_mousePressed; } void setMousePressed(bool pressed) { m_mousePressed = pressed; } diff --git a/WebCore/rendering/EllipsisBox.cpp b/WebCore/rendering/EllipsisBox.cpp index 6f25861..4a64fe4 100644 --- a/WebCore/rendering/EllipsisBox.cpp +++ b/WebCore/rendering/EllipsisBox.cpp @@ -113,8 +113,21 @@ bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu } } +#ifdef ANDROID_HITTEST_WITHSIZE + IntRect boundsRect = IntRect(tx, ty, m_width, m_height); + if (visibleToHitTesting() && result.intersects(x, y, boundsRect)) { +#else if (visibleToHitTesting() && IntRect(tx, ty, m_width, m_height).contains(x, y)) { +#endif renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) { + ASSERT(renderer()->node() || renderer()->isAnonymous()); + result.addRawNode(renderer()->node()); + if (!result.containedBy(x, y, boundsRect)) + return false; + } +#endif return true; } diff --git a/WebCore/rendering/HitTestResult.cpp b/WebCore/rendering/HitTestResult.cpp index 50933c6..8a4ef3c 100644 --- a/WebCore/rendering/HitTestResult.cpp +++ b/WebCore/rendering/HitTestResult.cpp @@ -52,6 +52,15 @@ HitTestResult::HitTestResult(const IntPoint& point) { } +#ifdef ANDROID_HITTEST_WITHSIZE +HitTestResult::HitTestResult(const IntPoint& point, const IntSize& padding) + : m_point(point) + , m_pointPadding(padding) + , m_isOverWidget(false) +{ +} +#endif + HitTestResult::HitTestResult(const HitTestResult& other) : m_innerNode(other.innerNode()) , m_innerNonSharedNode(other.innerNonSharedNode()) @@ -60,6 +69,10 @@ HitTestResult::HitTestResult(const HitTestResult& other) , m_innerURLElement(other.URLElement()) , m_scrollbar(other.scrollbar()) , m_isOverWidget(other.isOverWidget()) +#ifdef ANDROID_HITTEST_WITHSIZE + , m_pointPadding(other.pointPadding()) + , m_rawNodeList(other.rawNodeList()) +#endif { } @@ -76,6 +89,10 @@ HitTestResult& HitTestResult::operator=(const HitTestResult& other) m_innerURLElement = other.URLElement(); m_scrollbar = other.scrollbar(); m_isOverWidget = other.isOverWidget(); +#ifdef ANDROID_HITTEST_WITHSIZE + m_pointPadding = other.pointPadding(); + m_rawNodeList = other.rawNodeList(); +#endif return *this; } @@ -362,4 +379,50 @@ bool HitTestResult::isContentEditable() const return m_innerNonSharedNode->isContentEditable(); } +#ifdef ANDROID_HITTEST_WITHSIZE + +bool HitTestResult::intersects(int x, int y, const IntRect& other) const +{ + IntRect pointRect(x - m_pointPadding.width(), y - m_pointPadding.height(), 2 * m_pointPadding.width() + 1, 2* m_pointPadding.height() + 1); + return other.intersects(pointRect); +} + +bool HitTestResult::containedBy(int x, int y, const IntRect& other) const +{ + IntRect pointRect(x - m_pointPadding.width(), y - m_pointPadding.height(), 2 * m_pointPadding.width() + 1, 2* m_pointPadding.height() + 1); + return other.contains(pointRect); +} + +void HitTestResult::merge(const HitTestResult& other) +{ + if (!m_innerNode && other.innerNode()) { + m_innerNode = other.innerNode(); + m_innerNonSharedNode = other.innerNonSharedNode(); + m_localPoint = other.localPoint(); + m_innerURLElement = other.URLElement(); + m_scrollbar = other.scrollbar(); + m_isOverWidget = other.isOverWidget(); + } + + const Vector<RefPtr<Node> >& list = other.rawNodeList(); + Vector<RefPtr<Node> >::const_iterator last = list.end(); + for (Vector<RefPtr<Node> >::const_iterator it = list.begin(); it != last; ++it) + addRawNode(it->get()); +} + +void HitTestResult::addRawNode(Node* node) +{ + if (!node) + return; + + Vector<RefPtr<Node> >::const_iterator last = m_rawNodeList.end(); + for (Vector<RefPtr<Node> >::const_iterator it = m_rawNodeList.begin(); it != last; ++it) + if ((*it) == node) + return; + + m_rawNodeList.append(node); +} + +#endif // ANDROID_HITTEST_WITHSIZE + } // namespace WebCore diff --git a/WebCore/rendering/HitTestResult.h b/WebCore/rendering/HitTestResult.h index d1906ba..0f45900 100644 --- a/WebCore/rendering/HitTestResult.h +++ b/WebCore/rendering/HitTestResult.h @@ -22,6 +22,10 @@ #include "IntPoint.h" #include "TextDirection.h" +#ifdef ANDROID_HITTEST_WITHSIZE +#include <IntSize.h> +#include <wtf/Vector.h> +#endif #include <wtf/RefPtr.h> namespace WebCore { @@ -76,6 +80,19 @@ public: bool isLiveLink() const; bool isContentEditable() const; +#ifdef ANDROID_HITTEST_WITHSIZE + HitTestResult(const IntPoint&, const IntSize&); + + IntSize pointPadding() const { return m_pointPadding; } + bool isRegionTest() const { return !m_pointPadding.isEmpty(); } + bool intersects(int, int, const IntRect&) const; + bool containedBy(int, int, const IntRect&) const; + + void merge(const HitTestResult&); + void addRawNode(Node*); + const Vector<RefPtr<Node> >& rawNodeList() const { return m_rawNodeList; } +#endif + private: RefPtr<Node> m_innerNode; RefPtr<Node> m_innerNonSharedNode; @@ -85,6 +102,11 @@ private: RefPtr<Element> m_innerURLElement; RefPtr<Scrollbar> m_scrollbar; bool m_isOverWidget; // Returns true if we are over a widget (and not in the border/padding area of a RenderWidget for example). + +#ifdef ANDROID_HITTEST_WITHSIZE + IntSize m_pointPadding; + Vector<RefPtr<Node> > m_rawNodeList; +#endif }; String displayString(const String&, const Node*); diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp index 6ee610d..e31bf4f 100644 --- a/WebCore/rendering/InlineFlowBox.cpp +++ b/WebCore/rendering/InlineFlowBox.cpp @@ -607,7 +607,11 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re { IntRect overflowRect(visibleOverflowRect()); overflowRect.move(tx, ty); +#ifdef ANDROID_HITTEST_WITHSIZE + if (!result.intersects(x, y, overflowRect)) +#else if (!overflowRect.contains(x, y)) +#endif return false; // Check children first. @@ -620,8 +624,20 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re // Now check ourselves. IntRect rect(tx + m_x, ty + m_y, m_width, height()); +#ifdef ANDROID_HITTEST_WITHSIZE + if (visibleToHitTesting() && result.intersects(x, y, rect)) { +#else if (visibleToHitTesting() && rect.contains(x, y)) { +#endif renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); // Don't add in m_x or m_y here, we want coords in the containing block's space. +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) { + ASSERT(renderer()->node() || renderer()->isAnonymous()); + result.addRawNode(renderer()->node()); + if (!result.containedBy(x, y, rect)) + return false; + } +#endif return true; } diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp index 9c28b42..0c5df41 100644 --- a/WebCore/rendering/InlineTextBox.cpp +++ b/WebCore/rendering/InlineTextBox.cpp @@ -266,8 +266,20 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in return false; IntRect rect(tx + m_x, ty + m_y, m_width, height()); +#ifdef ANDROID_HITTEST_WITHSIZE + if (m_truncation != cFullTruncation && visibleToHitTesting() && result.intersects(x, y, rect)) { +#else if (m_truncation != cFullTruncation && visibleToHitTesting() && rect.contains(x, y)) { +#endif renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) { + ASSERT(renderer()->node() || renderer()->isAnonymous()); + result.addRawNode(renderer()->node()); + if (!result.containedBy(x, y, rect)) + return false; + } +#endif return true; } return false; diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp index cf4101b..f8c8b8d 100644 --- a/WebCore/rendering/RenderBlock.cpp +++ b/WebCore/rendering/RenderBlock.cpp @@ -3317,19 +3317,34 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu // Check if we need to do anything at all. IntRect overflowBox = visibleOverflowRect(); overflowBox.move(tx, ty); +#ifdef ANDROID_HITTEST_WITHSIZE + if (!result.intersects(_x, _y, overflowBox)) +#else if (!overflowBox.contains(_x, _y)) +#endif return false; } if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) { updateHitTestResult(result, IntPoint(_x - tx, _y - ty)); +#ifdef ANDROID_HITTEST_WITHSIZE + // TODO: isPointInOverflowControl() doesn't handle region test yet. + if (result.isRegionTest()) { + ASSERT(node() || isAnonymous()); + result.addRawNode(node()); + } else +#endif return true; } // If we have clipping, then we can't have any spillout. bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer(); bool useClip = (hasControlClip() || useOverflowClip); +#ifdef ANDROID_HITTEST_WITHSIZE + bool checkChildren = !useClip || (hasControlClip() ? result.intersects(_x, _y, controlClipRect(tx, ty)) : result.intersects(_x, _y, overflowClipRect(tx, ty))); +#else bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).contains(_x, _y) : overflowClipRect(tx, ty).contains(_x, _y)); +#endif if (checkChildren) { // Hit test descendants first. int scrolledX = tx; @@ -3373,8 +3388,20 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu // Now hit test our background if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) { IntRect boundsRect(tx, ty, width(), height()); +#ifdef ANDROID_HITTEST_WITHSIZE + if (visibleToHitTesting() && result.intersects(_x, _y, boundsRect)) { +#else if (visibleToHitTesting() && boundsRect.contains(_x, _y)) { +#endif updateHitTestResult(result, IntPoint(_x - tx, _y - ty)); +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) { + ASSERT(node() || isAnonymous()); + result.addRawNode(node()); + if (!result.containedBy(_x, _y, boundsRect)) + return false; + } +#endif return true; } } @@ -3395,12 +3422,21 @@ bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r IntRect colRect = colRects->at(i); colRect.move(tx, ty); +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.intersects(x, y, colRect)) { +#else if (colRect.contains(x, y)) { +#endif // The point is inside this column. // Adjust tx and ty to change where we hit test. int finalX = tx + currXOffset; int finalY = ty + currYOffset; +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest() && !result.containedBy(x, y, colRect)) + hitTestContents(request, result, x, y, finalX, finalY, hitTestAction); + else +#endif return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction); } diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp index 9204b64..4c5d702 100644 --- a/WebCore/rendering/RenderBox.cpp +++ b/WebCore/rendering/RenderBox.cpp @@ -34,6 +34,9 @@ #include "htmlediting.h" #include "HTMLElement.h" #include "HTMLNames.h" +#ifdef ANDROID_HITTEST_WITHSIZE +#include "HitTestResult.h" +#endif #include "ImageBuffer.h" #include "FloatQuad.h" #include "Frame.h" @@ -556,10 +559,23 @@ bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result } } +#ifdef ANDROID_HITTEST_WITHSIZE + IntRect boundsRect = IntRect(tx, ty, width(), height()); + if (visibleToHitTesting() && action == HitTestForeground && result.intersects(xPos, yPos, boundsRect)) { +#else // 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). if (visibleToHitTesting() && action == HitTestForeground && IntRect(tx, ty, width(), height()).contains(xPos, yPos)) { +#endif updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty)); +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) { + ASSERT(node() || isAnonymous()); + result.addRawNode(node()); + if (!result.containedBy(xPos, yPos, boundsRect)) + return false; + } +#endif return true; } diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp index 73cf73c..237dfb6 100644 --- a/WebCore/rendering/RenderImage.cpp +++ b/WebCore/rendering/RenderImage.cpp @@ -513,10 +513,18 @@ HTMLMapElement* RenderImage::imageMap() const bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction) { +#ifdef ANDROID_HITTEST_WITHSIZE + HitTestResult tempResult(result.point(), result.pointPadding()); +#else HitTestResult tempResult(result.point()); +#endif bool inside = RenderReplaced::nodeAtPoint(request, tempResult, x, y, tx, ty, hitTestAction); +#ifdef ANDROID_HITTEST_WITHSIZE + if (tempResult.innerNode() && node()) { +#else if (inside && node()) { +#endif if (HTMLMapElement* map = imageMap()) { IntRect contentBox = contentBoxRect(); float zoom = style()->effectiveZoom(); @@ -527,6 +535,10 @@ bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu } } +#ifdef ANDROID_HITTEST_WITHSIZE + if (!inside && result.isRegionTest()) + result.merge(tempResult); +#endif if (inside) result = tempResult; return inside; diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp index ea29087..37dbd38 100644 --- a/WebCore/rendering/RenderLayer.cpp +++ b/WebCore/rendering/RenderLayer.cpp @@ -2603,7 +2603,11 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont if (parent()) { IntRect clipRect = backgroundClipRect(rootLayer, useTemporaryClipRects); // Go ahead and test the enclosing clip now. +#ifdef ANDROID_HITTEST_WITHSIZE + if (!result.intersects(hitTestPoint.x(), hitTestPoint.y(), clipRect)) +#else if (!clipRect.contains(hitTestPoint)) +#endif return 0; } @@ -2700,9 +2704,20 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont // Begin by walking our list of positive layers from highest z-index down to the lowest z-index. if (m_posZOrderList) { for (int i = m_posZOrderList->size() - 1; i >= 0; --i) { +#ifdef ANDROID_HITTEST_WITHSIZE + HitTestResult tempResult(result.point(), result.pointPadding()); +#else HitTestResult tempResult(result.point()); +#endif RenderLayer* hitLayer = m_posZOrderList->at(i)->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, localTransformState.get(), zOffsetForDescendantsPtr); +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) + result.merge(tempResult); +#endif if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState.get())) { +#ifdef ANDROID_HITTEST_WITHSIZE + if (!result.isRegionTest()) +#endif result = tempResult; if (!depthSortDescendants) return hitLayer; @@ -2716,9 +2731,20 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont if (m_normalFlowList) { for (int i = m_normalFlowList->size() - 1; i >= 0; --i) { RenderLayer* currLayer = m_normalFlowList->at(i); +#ifdef ANDROID_HITTEST_WITHSIZE + HitTestResult tempResult(result.point(), result.pointPadding()); +#else HitTestResult tempResult(result.point()); +#endif RenderLayer* hitLayer = currLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, localTransformState.get(), zOffsetForDescendantsPtr); +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) + result.merge(tempResult); +#endif if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState.get())) { +#ifdef ANDROID_HITTEST_WITHSIZE + if (!result.isRegionTest()) +#endif result = tempResult; if (!depthSortDescendants) return hitLayer; @@ -2729,25 +2755,53 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont } // Next we want to see if the mouse pos is inside the child RenderObjects of the layer. +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.intersects(hitTestPoint.x(), hitTestPoint.y(), fgRect) && isSelfPaintingLayer()) { +#else if (fgRect.contains(hitTestPoint) && isSelfPaintingLayer()) { +#endif // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost. +#ifdef ANDROID_HITTEST_WITHSIZE + HitTestResult tempResult(result.point(), result.pointPadding()); +#else HitTestResult tempResult(result.point()); +#endif if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestDescendants) && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) { +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) + result.merge(tempResult); + else +#endif result = tempResult; if (!depthSortDescendants) return this; // Foreground can depth-sort with descendant layers, so keep this as a candidate. candidateLayer = this; } +#ifdef ANDROID_HITTEST_WITHSIZE + else if (result.isRegionTest()) + result.merge(tempResult); +#endif } // Now check our negative z-index children. if (m_negZOrderList) { for (int i = m_negZOrderList->size() - 1; i >= 0; --i) { +#ifdef ANDROID_HITTEST_WITHSIZE + HitTestResult tempResult(result.point(), result.pointPadding()); +#else HitTestResult tempResult(result.point()); +#endif RenderLayer* hitLayer = m_negZOrderList->at(i)->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, localTransformState.get(), zOffsetForDescendantsPtr); +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) + result.merge(tempResult); +#endif if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState.get())) { +#ifdef ANDROID_HITTEST_WITHSIZE + if (!result.isRegionTest()) +#endif result = tempResult; if (!depthSortDescendants) return hitLayer; @@ -2761,13 +2815,27 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont if (candidateLayer) return candidateLayer; +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.intersects(hitTestPoint.x(), hitTestPoint.y(), bgRect) && isSelfPaintingLayer()) { + HitTestResult tempResult(result.point(), result.pointPadding()); +#else if (bgRect.contains(hitTestPoint) && isSelfPaintingLayer()) { HitTestResult tempResult(result.point()); +#endif if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestSelf) && isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) { +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) + result.merge(tempResult); + else +#endif result = tempResult; return this; } +#ifdef ANDROID_HITTEST_WITHSIZE + else if (result.isRegionTest()) + result.merge(tempResult); +#endif } return 0; diff --git a/WebCore/rendering/RenderLineBoxList.cpp b/WebCore/rendering/RenderLineBoxList.cpp index 9736874..3395347 100644 --- a/WebCore/rendering/RenderLineBoxList.cpp +++ b/WebCore/rendering/RenderLineBoxList.cpp @@ -30,6 +30,9 @@ #include "RenderLineBoxList.h" #include "InlineTextBox.h" +#ifdef ANDROID_HITTEST_WITHSIZE +#include "HitTestResult.h" +#endif #include "RenderArena.h" #include "RenderInline.h" #include "RenderView.h" @@ -230,14 +233,22 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq // contain the point. This is a quick short-circuit that we can take to avoid walking any lines. // FIXME: This check is flawed in the following extremely obscure way: // if some line in the middle has a huge overflow, it might actually extend below the last line. +#ifdef ANDROID_HITTEST_WITHSIZE + if ((y - result.pointPadding().height() >= ty + lastLineBox()->root()->bottomVisibleOverflow()) || (y + result.pointPadding().height() < ty + firstLineBox()->root()->topVisibleOverflow())) +#else if ((y >= ty + lastLineBox()->root()->bottomVisibleOverflow()) || (y < ty + firstLineBox()->root()->topVisibleOverflow())) +#endif return false; // See if our root lines contain the point. If so, then we hit test // them further. Note that boxes can easily overlap, so we can't make any assumptions // based off positions of our first line box or our last line box. for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) { +#ifdef ANDROID_HITTEST_WITHSIZE + if (y + result.pointPadding().height() >= ty + curr->root()->topVisibleOverflow() && y - result.pointPadding().height() < ty + curr->root()->bottomVisibleOverflow()) { +#else if (y >= ty + curr->root()->topVisibleOverflow() && y < ty + curr->root()->bottomVisibleOverflow()) { +#endif bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty); if (inside) { renderer->updateHitTestResult(result, IntPoint(x - tx, y - ty)); diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp index 67a3b2a..6017513 100644 --- a/WebCore/rendering/RenderSVGRoot.cpp +++ b/WebCore/rendering/RenderSVGRoot.cpp @@ -26,6 +26,9 @@ #include "RenderSVGRoot.h" #include "GraphicsContext.h" +#ifdef ANDROID_HITTEST_WITHSIZE +#include "HitTestResult.h" +#endif #include "RenderSVGContainer.h" #include "RenderView.h" #include "SVGLength.h" @@ -313,6 +316,13 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re if (child->nodeAtFloatPoint(request, result, localPoint, hitTestAction)) { // FIXME: CSS/HTML assumes the local point is relative to the border box, right? updateHitTestResult(result, pointInBorderBox); +#ifdef ANDROID_HITTEST_WITHSIZE + // TODO: nodeAtFloatPoint() doesn't handle region test yet. + if (result.isRegionTest()) { + ASSERT(node() || isAnonymous()); + result.addRawNode(node()); + } else +#endif return true; } } diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp index 0a61a93..eac5c5d 100644 --- a/WebCore/rendering/RenderTable.cpp +++ b/WebCore/rendering/RenderTable.cpp @@ -31,6 +31,9 @@ #include "Document.h" #include "FixedTableLayout.h" #include "FrameView.h" +#ifdef ANDROID_HITTEST_WITHSIZE +#include "HitTestResult.h" +#endif #include "HTMLNames.h" #include "RenderLayer.h" #include "RenderTableCell.h" @@ -1202,7 +1205,11 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu ty += y(); // Check kids first. +#ifdef ANDROID_HITTEST_WITHSIZE + if (!hasOverflowClip() || result.intersects(xPos, yPos, overflowClipRect(tx, ty))) { +#else if (!hasOverflowClip() || overflowClipRect(tx, ty).contains(xPos, yPos)) { +#endif for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption) && child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) { @@ -1213,8 +1220,21 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu } // Check our bounds next. +#ifdef ANDROID_HITTEST_WITHSIZE + IntRect boundsRect = IntRect(tx, ty, width(), height()); + if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && result.intersects(xPos, yPos, boundsRect)) { +#else if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && IntRect(tx, ty, width(), height()).contains(xPos, yPos)) { +#endif updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty)); +#ifdef ANDROID_HITTEST_WITHSIZE + if (result.isRegionTest()) { + ASSERT(node() || isAnonymous()); + result.addRawNode(node()); + if (!result.containedBy(xPos, yPos, boundsRect)) + return false; + } +#endif return true; } diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp index e8ab4a4..e8f9cc4 100644 --- a/WebCore/rendering/RenderTableSection.cpp +++ b/WebCore/rendering/RenderTableSection.cpp @@ -28,6 +28,9 @@ #include "CachedImage.h" #include "Document.h" +#ifdef ANDROID_HITTEST_WITHSIZE +#include "HitTestResult.h" +#endif #include "HTMLNames.h" #include "RenderTableCell.h" #include "RenderTableCol.h" @@ -1259,7 +1262,11 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul tx += x(); ty += y(); +#ifdef ANDROID_HITTEST_WITHSIZE + if (hasOverflowClip() && !result.intersects(xPos, yPos, overflowClipRect(tx, ty))) +#else if (hasOverflowClip() && !overflowClipRect(tx, ty).contains(xPos, yPos)) +#endif return false; for (RenderObject* child = lastChild(); child; child = child->previousSibling()) { diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp index 15c75f1..2c53da4 100644 --- a/WebCore/rendering/RenderWidget.cpp +++ b/WebCore/rendering/RenderWidget.cpp @@ -378,6 +378,12 @@ bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& res // Check to see if we are really over the widget itself (and not just in the border/padding area). if (inside && !hadResult && result.innerNode() == node()) result.setIsOverWidget(contentBoxRect().contains(result.localPoint())); +#ifdef ANDROID_HITTEST_WITHSIZE + else if (result.isRegionTest() && !hadResult && result.innerNode() == node()) { + result.setIsOverWidget(contentBoxRect().contains(result.localPoint())); + return false; + } +#endif return inside; } |