Separate constraining for overhang from fixed-position zooming behavior in scrollOffs...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Feb 2013 00:25:06 +0000 (00:25 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Feb 2013 00:25:06 +0000 (00:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=110267

Reviewed by Beth Dakin.

The static scrollOffsetForFixedPosition() function in ScrollingCoordinator did two things;
it constrained the scroll position when rubber-banding, and applied the special scaling for
fixed position when zoomed.

Separate these out so that we can use the rubber-banding constrained elsewhere.

* page/FrameView.cpp:
(WebCore::FrameView::scrollOffsetForFixedPosition): The static function is here now.
* page/FrameView.h:
* page/scrolling/ScrollingCoordinator.cpp: Code moved to FrameView.
* page/scrolling/ScrollingCoordinator.h:
* page/scrolling/mac/ScrollingTreeScrollingNodeMac.mm:
(WebCore::ScrollingTreeScrollingNodeMac::setScrollLayerPosition): scrollOffsetForFixedPosition()
is now on FrameView.
* platform/ScrollableArea.cpp:
(WebCore::constrainedScrollPosition): Helper to constrain one axis for overhang.
(WebCore::ScrollableArea::constrainScrollPositionForOverhang): Static function that
can be called by FrameView::scrollOffsetForFixedPosition().
* platform/ScrollableArea.h: Static function constrainScrollPositionForOverhang()
so we can call it from another thread. Also a member fuction of the same name, which takes
the scrollPosition as input (so we can feed it a layer position in a later patch).

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@143404 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/page/scrolling/ScrollingCoordinator.cpp
Source/WebCore/page/scrolling/ScrollingCoordinator.h
Source/WebCore/page/scrolling/mac/ScrollingTreeScrollingNodeMac.mm
Source/WebCore/platform/ScrollableArea.cpp
Source/WebCore/platform/ScrollableArea.h

index f270e23..87164b1 100644 (file)
@@ -1,3 +1,32 @@
+2013-02-19  Simon Fraser  <simon.fraser@apple.com>
+
+        Separate constraining for overhang from fixed-position zooming behavior in scrollOffsetForFixedPosition()
+        https://bugs.webkit.org/show_bug.cgi?id=110267
+
+        Reviewed by Beth Dakin.
+
+        The static scrollOffsetForFixedPosition() function in ScrollingCoordinator did two things;
+        it constrained the scroll position when rubber-banding, and applied the special scaling for
+        fixed position when zoomed.
+        
+        Separate these out so that we can use the rubber-banding constrained elsewhere.
+
+        * page/FrameView.cpp:
+        (WebCore::FrameView::scrollOffsetForFixedPosition): The static function is here now.
+        * page/FrameView.h:
+        * page/scrolling/ScrollingCoordinator.cpp: Code moved to FrameView.
+        * page/scrolling/ScrollingCoordinator.h:
+        * page/scrolling/mac/ScrollingTreeScrollingNodeMac.mm:
+        (WebCore::ScrollingTreeScrollingNodeMac::setScrollLayerPosition): scrollOffsetForFixedPosition()
+        is now on FrameView.
+        * platform/ScrollableArea.cpp:
+        (WebCore::constrainedScrollPosition): Helper to constrain one axis for overhang.
+        (WebCore::ScrollableArea::constrainScrollPositionForOverhang): Static function that
+        can be called by FrameView::scrollOffsetForFixedPosition().
+        * platform/ScrollableArea.h: Static function constrainScrollPositionForOverhang()
+        so we can call it from another thread. Also a member fuction of the same name, which takes
+        the scrollPosition as input (so we can feed it a layer position in a later patch).
+
 2013-02-19  Tony Gentilcore  <tonyg@chromium.org>
 
         Fix checkThatTokensAreSafeToSendToAnotherThread() now that the preload scanner is enabled
index 6b6b71f..3e6f88e 100644 (file)
@@ -1512,6 +1512,18 @@ LayoutRect FrameView::viewportConstrainedVisibleContentRect() const
     return viewportRect;
 }
 
+IntSize FrameView::scrollOffsetForFixedPosition(const IntRect& visibleContentRect, const IntSize& contentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame)
+{
+    IntPoint constrainedPosition = ScrollableArea::constrainScrollPositionForOverhang(visibleContentRect, contentsSize, scrollPosition, scrollOrigin);
+
+    IntSize maxSize = contentsSize - visibleContentRect.size();
+
+    float dragFactorX = (fixedElementsLayoutRelativeToFrame || !maxSize.width()) ? 1 : (contentsSize.width() - visibleContentRect.width() * frameScaleFactor) / maxSize.width();
+    float dragFactorY = (fixedElementsLayoutRelativeToFrame || !maxSize.height()) ? 1 : (contentsSize.height() - visibleContentRect.height() * frameScaleFactor) / maxSize.height();
+
+    return IntSize(constrainedPosition.x() * dragFactorX / frameScaleFactor, constrainedPosition.y() * dragFactorY / frameScaleFactor);
+}
+
 IntSize FrameView::scrollOffsetForFixedPosition() const
 {
     IntRect visibleContentRect = this->visibleContentRect();
@@ -1519,7 +1531,7 @@ IntSize FrameView::scrollOffsetForFixedPosition() const
     IntPoint scrollPosition = this->scrollPosition();
     IntPoint scrollOrigin = this->scrollOrigin();
     float frameScaleFactor = m_frame ? m_frame->frameScaleFactor() : 1;
-    return WebCore::scrollOffsetForFixedPosition(visibleContentRect, contentsSize, scrollPosition, scrollOrigin, frameScaleFactor, fixedElementsLayoutRelativeToFrame());
+    return scrollOffsetForFixedPosition(visibleContentRect, contentsSize, scrollPosition, scrollOrigin, frameScaleFactor, fixedElementsLayoutRelativeToFrame());
 }
 
 bool FrameView::fixedElementsLayoutRelativeToFrame() const
index 2bafe62..33d4e39 100644 (file)
@@ -222,6 +222,8 @@ public:
     // Functions for querying the current scrolled position, negating the effects of overhang
     // and adjusting for page scale.
     IntSize scrollOffsetForFixedPosition() const;
+    // Static function can be called from another thread.
+    static IntSize scrollOffsetForFixedPosition(const IntRect& visibleContentRect, const IntSize& contentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame);
 
     bool fixedElementsLayoutRelativeToFrame() const;
 
index 2ec7165..1440d9c 100644 (file)
@@ -75,35 +75,6 @@ PassRefPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
     return adoptRef(new ScrollingCoordinator(page));
 }
 
-static int fixedPositionScrollOffset(int visibleContentSize, int contentsSize, int scrollPosition, int scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame)
-{
-    int maxValue = contentsSize - visibleContentSize;
-    if (maxValue <= 0)
-        return 0;
-
-    if (!scrollOrigin) {
-        if (scrollPosition <= 0)
-            return 0;
-        if (scrollPosition > maxValue)
-            scrollPosition = maxValue;
-    } else {
-        if (scrollPosition >= 0)
-            return 0;
-        if (scrollPosition < -maxValue)
-            scrollPosition = -maxValue;
-    }
-
-    float dragFactor = fixedElementsLayoutRelativeToFrame ? 1 : (contentsSize - visibleContentSize * frameScaleFactor) / maxValue;
-    return scrollPosition * dragFactor / frameScaleFactor;
-}
-
-IntSize scrollOffsetForFixedPosition(const IntRect& visibleContentRect, const IntSize& contentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame)
-{
-    int x = fixedPositionScrollOffset(visibleContentRect.width(), contentsSize.width(), scrollPosition.x(), scrollOrigin.x(), frameScaleFactor, fixedElementsLayoutRelativeToFrame);
-    int y = fixedPositionScrollOffset(visibleContentRect.height(), contentsSize.height(), scrollPosition.y(), scrollOrigin.y(), frameScaleFactor, fixedElementsLayoutRelativeToFrame);
-    return IntSize(x, y);
-}
-
 ScrollingCoordinator::ScrollingCoordinator(Page* page)
     : m_page(page)
     , m_updateMainFrameScrollPositionTimer(this, &ScrollingCoordinator::updateMainFrameScrollPositionTimerFired)
index 0aa8880..d84fbdb 100644 (file)
@@ -64,9 +64,6 @@ class ViewportConstraints;
 class ScrollingTree;
 #endif
 
-IntSize scrollOffsetForFixedPosition(const IntRect& visibleContentRect, const IntSize& contentsSize, const IntPoint& scrollPosition,
-    const IntPoint& scrollOrigin, float frameScaleFactor, bool fixedElementsLayoutRelativeToFrame);
-
 enum SetOrSyncScrollingLayerPosition {
     SetScrollingLayerPosition,
     SyncScrollingLayerPosition
index 7c722cc..e79eae6 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(THREADED_SCROLLING)
 
+#include "FrameView.h"
 #include "PlatformWheelEvent.h"
 #include "ScrollingCoordinator.h"
 #include "ScrollingTree.h"
@@ -304,7 +305,7 @@ void ScrollingTreeScrollingNodeMac::setScrollLayerPosition(const IntPoint& posit
     ASSERT(!shouldUpdateScrollLayerPositionOnMainThread());
     m_scrollLayer.get().position = CGPointMake(-position.x() + scrollOrigin().x(), -position.y() + scrollOrigin().y());
 
-    IntSize scrollOffsetForFixedChildren = WebCore::scrollOffsetForFixedPosition(viewportRect(), contentsSize(), position, scrollOrigin(), frameScaleFactor(), false);
+    IntSize scrollOffsetForFixedChildren = FrameView::scrollOffsetForFixedPosition(viewportRect(), contentsSize(), position, scrollOrigin(), frameScaleFactor(), false);
     if (m_counterScrollingLayer)
         m_counterScrollingLayer.get().position = FloatPoint(scrollOffsetForFixedChildren);
 
index f69be03..3546841 100644 (file)
@@ -421,6 +421,38 @@ IntRect ScrollableArea::visibleContentRect(VisibleContentRectIncludesScrollbars
                    std::max(0, visibleHeight() + horizontalScrollbarHeight));
 }
 
+static int constrainedScrollPosition(int visibleContentSize, int contentsSize, int scrollPosition, int scrollOrigin)
+{
+    int maxValue = contentsSize - visibleContentSize;
+    if (maxValue <= 0)
+        return 0;
+
+    if (!scrollOrigin) {
+        if (scrollPosition <= 0)
+            return 0;
+        if (scrollPosition > maxValue)
+            scrollPosition = maxValue;
+    } else {
+        if (scrollPosition >= 0)
+            return 0;
+        if (scrollPosition < -maxValue)
+            scrollPosition = -maxValue;
+    }
+
+    return scrollPosition;
+}
+
+IntPoint ScrollableArea::constrainScrollPositionForOverhang(const IntRect& visibleContentRect, const IntSize& contentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin)
+{
+    return IntPoint(constrainedScrollPosition(visibleContentRect.width(), contentsSize.width(), scrollPosition.x(), scrollOrigin.x()),
+        constrainedScrollPosition(visibleContentRect.height(), contentsSize.height(), scrollPosition.y(), scrollOrigin.y()));
+}
+
+IntPoint ScrollableArea::constrainScrollPositionForOverhang(const IntPoint& scrollPosition)
+{
+    return constrainScrollPositionForOverhang(visibleContentRect(), contentsSize(), scrollPosition, scrollOrigin());
+}
+
 void ScrollableArea::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
 {
     MemoryClassInfo info(memoryObjectInfo, this);
index 358bd8f..0049c23 100644 (file)
@@ -167,6 +167,9 @@ public:
     // NOTE: Only called from Internals for testing.
     void setScrollOffsetFromInternals(const IntPoint&);
 
+    static IntPoint constrainScrollPositionForOverhang(const IntRect& visibleContentRect, const IntSize& contentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin);
+    IntPoint constrainScrollPositionForOverhang(const IntPoint& scrollPosition);
+
     // Let subclasses provide a way of asking for and servicing scroll
     // animations.
     virtual bool scheduleAnimation() { return false; }