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()); }