// A generic function for finding the target node with the lowest distance metric. A distance metric here is the result // of a distance-like function, that computes how well the touch hits the node. // Distance functions could for instance be distance squared or area of intersection. bool findNodeWithLowestDistanceMetric(Node*& targetNode, IntPoint& targetPoint, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, SubtargetGeometryList& subtargets, DistanceFunction distanceFunction) { targetNode = 0; float bestDistanceMetric = std::numeric_limits<float>::infinity(); SubtargetGeometryList::const_iterator it = subtargets.begin(); const SubtargetGeometryList::const_iterator end = subtargets.end(); IntPoint adjustedPoint; for (; it != end; ++it) { Node* node = it->node(); float distanceMetric = distanceFunction(touchHotspot, touchArea, *it); if (distanceMetric < bestDistanceMetric) { if (snapTo(*it, touchHotspot, touchArea, adjustedPoint)) { targetPoint = adjustedPoint; targetArea = it->boundingBox(); targetNode = node; bestDistanceMetric = distanceMetric; } } else if (distanceMetric - bestDistanceMetric < zeroTolerance) { if (snapTo(*it, touchHotspot, touchArea, adjustedPoint)) { if (node->isDescendantOf(targetNode)) { // Try to always return the inner-most element. targetPoint = adjustedPoint; targetNode = node; targetArea = it->boundingBox(); } } } } if (targetNode) { targetArea = targetNode->document()->view()->contentsToWindow(targetArea); } return (targetNode); }
// A generic function for finding the target node with the lowest distance metric. A distance metric here is the result // of a distance-like function, that computes how well the touch hits the node. // Distance functions could for instance be distance squared or area of intersection. bool findNodeWithLowestDistanceMetric(Node*& targetNode, IntPoint& targetPoint, const IntPoint& touchHotspot, const IntRect& touchArea, SubtargetGeometryList& subtargets, DistanceFunction distanceFunction) { targetNode = 0; float bestDistanceMetric = INFINITY; SubtargetGeometryList::const_iterator it = subtargets.begin(); const SubtargetGeometryList::const_iterator end = subtargets.end(); for (; it != end; ++it) { Node* node = it->node(); float distanceMetric = distanceFunction(touchHotspot, touchArea, *it); if (distanceMetric < bestDistanceMetric) { targetPoint = roundedIntPoint(it->quad().center()); targetNode = node; bestDistanceMetric = distanceMetric; } else if (distanceMetric == bestDistanceMetric) { // Try to always return the inner-most element. if (node->isDescendantOf(targetNode)) targetNode = node; } } return (targetNode); }