1926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)/* 2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2006, 2008, 2011 Apple Inc. All rights reserved. 3926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) 4926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * This library is free software; you can redistribute it and/or 6926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * modify it under the terms of the GNU Library General Public 7926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * License as published by the Free Software Foundation; either 8926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * version 2 of the License, or (at your option) any later version. 9926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 10926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * This library is distributed in the hope that it will be useful, 11926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 12926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Library General Public License for more details. 14926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 15926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * You should have received a copy of the GNU Library General Public License 16926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 17926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Boston, MA 02110-1301, USA. 19926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 20926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)*/ 21926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 22926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)#include "config.h" 2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/HitTestLocation.h" 24926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 25926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)namespace WebCore { 26926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 27926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)HitTestLocation::HitTestLocation() 2809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) : m_isRectBased(false) 29926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectilinear(true) 30926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 31926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 32926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 33926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)HitTestLocation::HitTestLocation(const LayoutPoint& point) 34926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_point(point) 35926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_boundingBox(rectForPoint(point, 0, 0, 0, 0)) 36926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedPoint(point) 37926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedRect(m_boundingBox) 38926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectBased(false) 39926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectilinear(true) 40926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 41926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 42926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 43926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)HitTestLocation::HitTestLocation(const FloatPoint& point) 44926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_point(flooredLayoutPoint(point)) 45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_boundingBox(rectForPoint(m_point, 0, 0, 0, 0)) 46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedPoint(point) 47926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedRect(m_boundingBox) 48926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectBased(false) 49926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectilinear(true) 50926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 51926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 52926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 53926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)HitTestLocation::HitTestLocation(const FloatPoint& point, const FloatQuad& quad) 54926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_transformedPoint(point) 55926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedRect(quad) 56926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectBased(true) 57926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 58926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_point = flooredLayoutPoint(point); 59926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_boundingBox = enclosingIntRect(quad.boundingBox()); 60926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_isRectilinear = quad.isRectilinear(); 61926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 62926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 63926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)HitTestLocation::HitTestLocation(const LayoutPoint& centerPoint, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding) 64926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_point(centerPoint) 65926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_boundingBox(rectForPoint(centerPoint, topPadding, rightPadding, bottomPadding, leftPadding)) 66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedPoint(centerPoint) 67926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectBased(topPadding || rightPadding || bottomPadding || leftPadding) 68926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectilinear(true) 69926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 70926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_transformedRect = FloatQuad(m_boundingBox); 71926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 72926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 7309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)HitTestLocation::HitTestLocation(const HitTestLocation& other, const LayoutSize& offset) 74926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_point(other.m_point) 75926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_boundingBox(other.m_boundingBox) 76926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedPoint(other.m_transformedPoint) 77926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedRect(other.m_transformedRect) 78926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectBased(other.m_isRectBased) 79926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectilinear(other.m_isRectilinear) 80926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 81926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) move(offset); 82926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 83926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 84926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)HitTestLocation::HitTestLocation(const HitTestLocation& other) 85926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) : m_point(other.m_point) 86926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_boundingBox(other.m_boundingBox) 87926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedPoint(other.m_transformedPoint) 88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_transformedRect(other.m_transformedRect) 89926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectBased(other.m_isRectBased) 90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) , m_isRectilinear(other.m_isRectilinear) 91926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 92926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 93926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 94926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)HitTestLocation::~HitTestLocation() 95926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 96926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 97926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 98926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)HitTestLocation& HitTestLocation::operator=(const HitTestLocation& other) 99926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 100926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_point = other.m_point; 101926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_boundingBox = other.m_boundingBox; 102926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_transformedPoint = other.m_transformedPoint; 103926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_transformedRect = other.m_transformedRect; 104926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_isRectBased = other.m_isRectBased; 105926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_isRectilinear = other.m_isRectilinear; 106926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 107926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return *this; 108926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 109926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 110926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)void HitTestLocation::move(const LayoutSize& offset) 111926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 112926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_point.move(offset); 113926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_transformedPoint.move(offset); 114926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_transformedRect.move(offset); 115926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) m_boundingBox = enclosingIntRect(m_transformedRect.boundingBox()); 116926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 117926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 118926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template<typename RectType> 119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool HitTestLocation::intersectsRect(const RectType& rect) const 120926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FIXME: When the hit test is not rect based we should use rect.contains(m_point). 122926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // That does change some corner case tests though. 123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // First check if rect even intersects our bounding box. 125926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (!rect.intersects(m_boundingBox)) 126926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return false; 127926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 128926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If the transformed rect is rectilinear the bounding box intersection was accurate. 129926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (m_isRectilinear) 130926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 131926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 132926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // If rect fully contains our bounding box, we are also sure of an intersection. 133926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) if (rect.contains(m_boundingBox)) 134926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return true; 135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 136926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // Otherwise we need to do a slower quad based intersection test. 137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return m_transformedRect.intersectsRect(rect); 138926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 139926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 140926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool HitTestLocation::intersects(const LayoutRect& rect) const 141926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 142926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return intersectsRect(rect); 143926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 144926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 145926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool HitTestLocation::intersects(const FloatRect& rect) const 146926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 147926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return intersectsRect(rect); 148926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 149926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 150926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)bool HitTestLocation::intersects(const RoundedRect& rect) const 151926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 152926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return rect.intersectsQuad(m_transformedRect); 153926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 154926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 155926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)IntRect HitTestLocation::rectForPoint(const LayoutPoint& point, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding) 156926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){ 157926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) IntPoint actualPoint(flooredIntPoint(point)); 158926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) actualPoint -= IntSize(leftPadding, topPadding); 159926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 160926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) IntSize actualPadding(leftPadding + rightPadding, topPadding + bottomPadding); 161926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // As IntRect is left inclusive and right exclusive (seeing IntRect::contains(x, y)), adding "1". 162926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) // FIXME: Remove this once non-rect based hit-detection stops using IntRect:intersects. 163926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) actualPadding += IntSize(1, 1); 164926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 165926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) return IntRect(actualPoint, actualPadding); 166926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} 167926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 168926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)} // namespace WebCore 169