Title: [129108] trunk/Source/WebCore
Revision
129108
Author
[email protected]
Date
2012-09-20 01:44:43 -0700 (Thu, 20 Sep 2012)

Log Message

[TouchAdjustment] Simplify and improve hybrid distance function.
https://bugs.webkit.org/show_bug.cgi?id=96519

Reviewed by Antonio Gomes.

The current distance function is a combination of two functions. One measuring the distance from
the hot-spot in the touch-area to the centerline of the target, and one measuring how much of the
target is covered.

The distance to the center-line was used instead of just the distance to the target, to make it
easier to hit small targets near big targets. The very same feature is however also the reason
measuring how much the target is covered is added. Using the distance to center-line is therefore
redundant now, and can be replaced with the simpler 'distance the hot-spot needs to be adjusted'.

Tested by existing touchadjustment tests.

* page/TouchAdjustment.cpp:
(TouchAdjustment):
(WebCore::TouchAdjustment::hybridDistanceFunction):
* platform/graphics/IntRect.cpp:
* platform/graphics/IntRect.h:
(IntRect):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (129107 => 129108)


--- trunk/Source/WebCore/ChangeLog	2012-09-20 08:41:27 UTC (rev 129107)
+++ trunk/Source/WebCore/ChangeLog	2012-09-20 08:44:43 UTC (rev 129108)
@@ -1,3 +1,28 @@
+2012-09-20  Allan Sandfeld Jensen  <[email protected]>
+
+        [TouchAdjustment] Simplify and improve hybrid distance function.
+        https://bugs.webkit.org/show_bug.cgi?id=96519
+
+        Reviewed by Antonio Gomes.
+
+        The current distance function is a combination of two functions. One measuring the distance from
+        the hot-spot in the touch-area to the centerline of the target, and one measuring how much of the
+        target is covered.
+
+        The distance to the center-line was used instead of just the distance to the target, to make it
+        easier to hit small targets near big targets. The very same feature is however also the reason
+        measuring how much the target is covered is added. Using the distance to center-line is therefore
+        redundant now, and can be replaced with the simpler 'distance the hot-spot needs to be adjusted'.
+
+        Tested by existing touchadjustment tests.
+
+        * page/TouchAdjustment.cpp:
+        (TouchAdjustment):
+        (WebCore::TouchAdjustment::hybridDistanceFunction):
+        * platform/graphics/IntRect.cpp:
+        * platform/graphics/IntRect.h:
+        (IntRect):
+
 2012-09-20  Yoshifumi Inoue  <[email protected]>
 
         [Forms] HTMLSelectElement should call formStateDidChange on both menulist and lisbox mode

Modified: trunk/Source/WebCore/page/TouchAdjustment.cpp (129107 => 129108)


--- trunk/Source/WebCore/page/TouchAdjustment.cpp	2012-09-20 08:41:27 UTC (rev 129107)
+++ trunk/Source/WebCore/page/TouchAdjustment.cpp	2012-09-20 08:44:43 UTC (rev 129108)
@@ -285,23 +285,6 @@
     }
 }
 
-
-float distanceSquaredToTargetCenterLine(const IntPoint& touchHotspot, const IntRect& touchArea, const SubtargetGeometry& subtarget)
-{
-    UNUSED_PARAM(touchArea);
-    // For a better center of a line-box we use the center-line instead of the center-point.
-    // We use the center-line of the bounding box of the quad though, since it is much faster
-    // and gives the same result in all untransformed cases, and in transformed cases still
-    // gives a better distance-function than the distance to the center-point.
-    IntRect rect = subtarget.boundingBox();
-    ASSERT(subtarget.node()->document());
-    ASSERT(subtarget.node()->document()->view());
-    // Convert from frame coordinates to window coordinates.
-    rect = subtarget.node()->document()->view()->contentsToWindow(rect);
-
-    return rect.distanceSquaredFromCenterLineToPoint(touchHotspot);
-}
-
 // 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)
@@ -321,32 +304,30 @@
     return rect.size().area() / (float)intersection.size().area();
 }
 
-// Uses a hybrid of distance to center and intersect ratio, normalizing each
-// score between 0 and 1 and choosing the better score. The distance to
-// centerline works best for disambiguating clicks on targets such as links,
-// where the width may be significantly larger than the touch width. Using
-// area of overlap in such cases can lead to a bias towards shorter links.
-// Conversely, percentage of overlap can provide strong confidence in tapping
-// on a small target, where the overlap is often quite high, and works well
-// for tightly packed controls.
-float hybridDistanceFunction(const IntPoint& touchHotspot, const IntRect& touchArea, const SubtargetGeometry& subtarget)
+// Uses a hybrid of distance to adjust and intersect ratio, normalizing each score between 0 and 1
+// and combining them. The distance to adjust works best for disambiguating clicks on targets such
+// as links, where the width may be significantly larger than the touch width. Using area of overlap
+// in such cases can lead to a bias towards shorter links. Conversely, percentage of overlap can
+// provide strong confidence in tapping on a small target, where the overlap is often quite high,
+// and works well for tightly packed controls.
+float hybridDistanceFunction(const IntPoint& touchHotspot, const IntRect& touchRect, const SubtargetGeometry& subtarget)
 {
     IntRect rect = subtarget.boundingBox();
 
     // Convert from frame coordinates to window coordinates.
     rect = subtarget.node()->document()->view()->contentsToWindow(rect);
    
-    float touchWidth = touchArea.width();
-    float touchHeight = touchArea.height();
-    float distanceScale =  touchWidth * touchWidth + touchHeight * touchHeight;
-    float distanceToCenterScore = rect.distanceSquaredFromCenterLineToPoint(touchHotspot) / distanceScale;
+    float radiusSquared = 0.25f * (touchRect.size().diagonalLengthSquared());
+    float distanceToAdjustScore = rect.distanceSquaredToPoint(touchHotspot) / radiusSquared;
 
     float targetArea = rect.size().area();
-    rect.intersect(touchArea);
+    rect.intersect(touchRect);
     float intersectArea = rect.size().area();
     float intersectionScore = 1 - intersectArea / targetArea;
 
-    return intersectionScore < distanceToCenterScore ? intersectionScore : distanceToCenterScore;
+    float hybridScore = intersectionScore + distanceToAdjustScore;
+
+    return hybridScore;
 }
 
 FloatPoint contentsToWindow(FrameView *view, FloatPoint pt)
@@ -446,19 +427,6 @@
                     targetPoint = adjustedPoint;
                     targetNode = node;
                     targetArea = it->boundingBox();
-                } else {
-                    // Minimize adjustment distance.
-                    float dx = targetPoint.x() - touchHotspot.x();
-                    float dy = targetPoint.y() - touchHotspot.y();
-                    float bestDistance = dx * dx + dy * dy;
-                    dx = adjustedPoint.x() - touchHotspot.x();
-                    dy = adjustedPoint.y() - touchHotspot.y();
-                    float distance = dx * dx + dy * dy;
-                    if (distance < bestDistance) {
-                        targetPoint = adjustedPoint;
-                        targetNode = node;
-                        targetArea = it->boundingBox();
-                    }
                 }
             }
         }

Modified: trunk/Source/WebCore/platform/graphics/IntRect.cpp (129107 => 129108)


--- trunk/Source/WebCore/platform/graphics/IntRect.cpp	2012-09-20 08:41:27 UTC (rev 129107)
+++ trunk/Source/WebCore/platform/graphics/IntRect.cpp	2012-09-20 08:44:43 UTC (rev 129108)
@@ -148,19 +148,6 @@
     return IntSize(xdistance, ydistance);
 }
 
-IntSize IntRect::differenceFromCenterLineToPoint(const IntPoint& point) const
-{
-    // The center-line is the natural center of a rectangle. It has an equal distance to all sides of the rectangle.
-    IntPoint centerPoint = center();
-    int xdistance = centerPoint.x() - point.x();
-    int ydistance = centerPoint.y() - point.y();
-    if (width() > height())
-        xdistance = distanceToInterval(point.x(), x() + (height() / 2), maxX() - (height() / 2));
-    else
-        ydistance = distanceToInterval(point.y(), y() + (width() / 2), maxY() - (width() / 2));
-    return IntSize(xdistance, ydistance);
-}
-
 IntRect unionRect(const Vector<IntRect>& rects)
 {
     IntRect result;

Modified: trunk/Source/WebCore/platform/graphics/IntRect.h (129107 => 129108)


--- trunk/Source/WebCore/platform/graphics/IntRect.h	2012-09-20 08:41:27 UTC (rev 129107)
+++ trunk/Source/WebCore/platform/graphics/IntRect.h	2012-09-20 08:44:43 UTC (rev 129108)
@@ -190,9 +190,7 @@
     void scale(float s);
 
     IntSize differenceToPoint(const IntPoint&) const;
-    IntSize differenceFromCenterLineToPoint(const IntPoint&) const;
     int distanceSquaredToPoint(const IntPoint& p) const { return differenceToPoint(p).diagonalLengthSquared(); }
-    int distanceSquaredFromCenterLineToPoint(const IntPoint& p) const { return differenceFromCenterLineToPoint(p).diagonalLengthSquared(); }
 
     IntRect transposedRect() const { return IntRect(m_location.transposedPoint(), m_size.transposedSize()); }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to