Title: [113179] trunk
Revision
113179
Author
[email protected]
Date
2012-04-04 05:47:54 -0700 (Wed, 04 Apr 2012)

Log Message

Best zoomable area does not balance intersection with target area.
https://bugs.webkit.org/show_bug.cgi?id=83148

Patch by Allan Sandfeld Jensen <[email protected]> on 2012-04-04
Reviewed by Kenneth Rohde Christiansen.

Source/WebCore:

Change the two step sort to simply picking the best quotient of touch intersection with target area.

Test: touchadjustment/zoom-fatfinger.html

* page/TouchAdjustment.cpp:
(WebCore::TouchAdjustment::distanceSquaredToTargetCenterLine):
(TouchAdjustment):
(WebCore::TouchAdjustment::zoomableIntersectionQuotient):
(WebCore::TouchAdjustment::findNodeWithLowestDistanceMetric):
(WebCore::findBestClickableCandidate):
(WebCore::findBestZoomableArea):

LayoutTests:

* touchadjustment/zoom-fatfinger-expected.txt: Added.
* touchadjustment/zoom-fatfinger.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (113178 => 113179)


--- trunk/LayoutTests/ChangeLog	2012-04-04 12:43:45 UTC (rev 113178)
+++ trunk/LayoutTests/ChangeLog	2012-04-04 12:47:54 UTC (rev 113179)
@@ -1,3 +1,13 @@
+2012-04-04  Allan Sandfeld Jensen  <[email protected]>
+
+        Best zoomable area does not balance intersection with target area.
+        https://bugs.webkit.org/show_bug.cgi?id=83148
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        * touchadjustment/zoom-fatfinger-expected.txt: Added.
+        * touchadjustment/zoom-fatfinger.html: Added.
+
 2012-04-04  Dominik Röttsches  <[email protected]>
 
         [EFL][DRT] FrameloaderClientEfl needs to handle media content correctly

Added: trunk/LayoutTests/touchadjustment/zoom-fatfinger-expected.txt (0 => 113179)


--- trunk/LayoutTests/touchadjustment/zoom-fatfinger-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/touchadjustment/zoom-fatfinger-expected.txt	2012-04-04 12:47:54 UTC (rev 113179)
@@ -0,0 +1,13 @@
+Test that targetted area is picked even if the touch area is not fully contained.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS zoomableArea.top is 100
+PASS zoomableArea.left is 100
+PASS zoomableArea.width is 200
+PASS zoomableArea.height is 20
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/touchadjustment/zoom-fatfinger.html (0 => 113179)


--- trunk/LayoutTests/touchadjustment/zoom-fatfinger.html	                        (rev 0)
+++ trunk/LayoutTests/touchadjustment/zoom-fatfinger.html	2012-04-04 12:47:54 UTC (rev 113179)
@@ -0,0 +1,50 @@
+<html>
+<head>
+    <script src=""
+    <style>
+        #div1 { position: absolute; left: 100px; top: 100
+px; width: 200px; height: 20px; }
+    </style>
+</head>
+<body _onload_="runTests()">
+
+<div id=div1></div>
+
+<p id='description'></p>
+<div id='console'></div>
+
+<script>
+    function testRoundTouch(x, y, radius)
+    {
+        var x = x - radius;
+        var y = y - radius;
+        var width = radius * 2;
+        var height = radius * 2;
+        var zoomableRect = internals.bestZoomableAreaForTouchPoint(x, y, width, height, document);
+        return zoomableRect;
+    }
+
+    function testDirectTouches()
+    {
+        zoomableArea = testRoundTouch(200, 110, 20);
+        shouldEvaluateTo('zoomableArea.top', 100);
+        shouldEvaluateTo('zoomableArea.left', 100);
+        shouldEvaluateTo('zoomableArea.width', 200);
+        shouldEvaluateTo('zoomableArea.height', 20);
+
+    }
+
+    function runTests()
+    {
+        if (window.layoutTestController && window.internals && internals.bestZoomableAreaForTouchPoint) {
+            description('Test that targetted area is picked even if the touch area is not fully contained.');
+            layoutTestController.dumpAsText();
+            layoutTestController.waitUntilDone();
+            testDirectTouches();
+            isSuccessfullyParsed();
+            layoutTestController.notifyDone();
+        }
+    }
+</script>
+</body>
+</html>
\ No newline at end of file

Modified: trunk/Source/WebCore/ChangeLog (113178 => 113179)


--- trunk/Source/WebCore/ChangeLog	2012-04-04 12:43:45 UTC (rev 113178)
+++ trunk/Source/WebCore/ChangeLog	2012-04-04 12:47:54 UTC (rev 113179)
@@ -1,3 +1,22 @@
+2012-04-04  Allan Sandfeld Jensen  <[email protected]>
+
+        Best zoomable area does not balance intersection with target area.
+        https://bugs.webkit.org/show_bug.cgi?id=83148
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Change the two step sort to simply picking the best quotient of touch intersection with target area.
+
+        Test: touchadjustment/zoom-fatfinger.html
+
+        * page/TouchAdjustment.cpp:
+        (WebCore::TouchAdjustment::distanceSquaredToTargetCenterLine):
+        (TouchAdjustment):
+        (WebCore::TouchAdjustment::zoomableIntersectionQuotient):
+        (WebCore::TouchAdjustment::findNodeWithLowestDistanceMetric):
+        (WebCore::findBestClickableCandidate):
+        (WebCore::findBestZoomableArea):
+
 2012-04-04  Andrey Kosyakov  <[email protected]>
 
         Web Inspector: make padding and client window width part of timeline calculator's state

Modified: trunk/Source/WebCore/page/TouchAdjustment.cpp (113178 => 113179)


--- trunk/Source/WebCore/page/TouchAdjustment.cpp	2012-04-04 12:43:45 UTC (rev 113178)
+++ trunk/Source/WebCore/page/TouchAdjustment.cpp	2012-04-04 12:47:54 UTC (rev 113179)
@@ -219,23 +219,31 @@
     return rect.distanceSquaredFromCenterLineToPoint(touchHotspot);
 }
 
-float areaOfIntersection(const IntPoint& touchHotspot, const IntRect& touchArea, const SubtargetGeometry& subtarget)
+
+// This returns quotient of the target area and its intersection with the touch area.
+// This will prioritize largest intersection and smallest area, while balancing the two against each other.
+float zoomableIntersectionQuotient(const IntPoint& touchHotspot, const IntRect& touchArea, const SubtargetGeometry& subtarget)
 {
-    UNUSED_PARAM(touchHotspot);
     IntRect rect = subtarget.boundingBox();
 
     // Convert from frame coordinates to window coordinates.
     rect = subtarget.node()->document()->view()->contentsToWindow(rect);
-    rect.intersect(touchArea);
 
-    return rect.size().area();
+    // Check the rectangle is meaningful zoom target. It should at least contain the hotspot.
+    if (!rect.contains(touchHotspot))
+        return INFINITY;
+    IntRect intersection = rect;
+    intersection.intersect(touchArea);
+
+    // Return the quotient of the intersection.
+    return rect.size().area() / (float)intersection.size().area();
 }
 
 
 // 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)
+bool findNodeWithLowestDistanceMetric(Node*& targetNode, IntPoint& targetPoint, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, SubtargetGeometryList& subtargets, DistanceFunction distanceFunction)
 {
     targetNode = 0;
     float bestDistanceMetric = INFINITY;
@@ -246,40 +254,14 @@
         float distanceMetric = distanceFunction(touchHotspot, touchArea, *it);
         if (distanceMetric < bestDistanceMetric) {
             targetPoint = roundedIntPoint(it->quad().center());
+            targetArea = it->boundingBox();
             targetNode = node;
             bestDistanceMetric = distanceMetric;
         } else if (distanceMetric == bestDistanceMetric) {
             // Try to always return the inner-most element.
-            if (node->isDescendantOf(targetNode))
+            if (node->isDescendantOf(targetNode)) {
                 targetNode = node;
-        }
-    }
-
-    return (targetNode);
-}
-
-// Similar generic function as findNodeWithLowestDistanceMetric, except this finds the innermost area with the largest intersection.
-bool findAreaWithLargestIntersection(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, SubtargetGeometryList& subtargets)
-{
-    targetNode = 0;
-    float bestDistanceMetric = 0.;
-    SubtargetGeometryList::const_iterator it = subtargets.begin();
-    const SubtargetGeometryList::const_iterator end = subtargets.end();
-    for (; it != end; ++it) {
-        Node* node = it->node();
-        float distanceMetric = areaOfIntersection(touchHotspot, touchArea, *it);
-        if (distanceMetric > bestDistanceMetric) {
-            targetArea = it->boundingBox();
-            targetNode = node;
-            bestDistanceMetric = distanceMetric;
-        } else if (distanceMetric == bestDistanceMetric) {
-            // Try to return the smallest inner-most subtarget.
-            if (node == targetNode) {
-                if (it->boundingBox().size().area() < targetArea.size().area())
-                    targetArea = it->boundingBox();
-            } else if (node->isDescendantOf(targetNode)) {
                 targetArea = it->boundingBox();
-                targetNode = node;
             }
         }
     }
@@ -287,21 +269,22 @@
     return (targetNode);
 }
 
-
 } // namespace TouchAdjustment
 
 bool findBestClickableCandidate(Node*& targetNode, IntPoint &targetPoint, const IntPoint &touchHotspot, const IntRect &touchArea, const NodeList& nodeList)
 {
+    IntRect targetArea;
     TouchAdjustment::SubtargetGeometryList subtargets;
     TouchAdjustment::compileSubtargetList(nodeList, subtargets, TouchAdjustment::nodeRespondsToTapGesture);
-    return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, touchHotspot, touchArea, subtargets, TouchAdjustment::distanceSquaredToTargetCenterLine);
+    return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::distanceSquaredToTargetCenterLine);
 }
 
 bool findBestZoomableArea(Node*& targetNode, IntRect& targetArea, const IntPoint& touchHotspot, const IntRect& touchArea, const NodeList& nodeList)
 {
+    IntPoint targetPoint;
     TouchAdjustment::SubtargetGeometryList subtargets;
     TouchAdjustment::compileZoomableSubtargets(nodeList, subtargets);
-    return TouchAdjustment::findAreaWithLargestIntersection(targetNode, targetArea, touchHotspot, touchArea, subtargets);
+    return TouchAdjustment::findNodeWithLowestDistanceMetric(targetNode, targetPoint, targetArea, touchHotspot, touchArea, subtargets, TouchAdjustment::zoomableIntersectionQuotient);
 }
 
 } // namespace WebCore
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to