summaryrefslogtreecommitdiff
path: root/Source/WebKit2/Shared/CoordinatedGraphics/SimpleViewportController.cpp
diff options
context:
space:
mode:
authorKonstantin Tokarev <annulen@yandex.ru>2016-08-25 19:20:41 +0300
committerKonstantin Tokarev <annulen@yandex.ru>2017-02-02 12:30:55 +0000
commit6882a04fb36642862b11efe514251d32070c3d65 (patch)
treeb7959826000b061fd5ccc7512035c7478742f7b0 /Source/WebKit2/Shared/CoordinatedGraphics/SimpleViewportController.cpp
parentab6df191029eeeb0b0f16f127d553265659f739e (diff)
downloadqtwebkit-6882a04fb36642862b11efe514251d32070c3d65.tar.gz
Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443)
Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f Reviewed-by: Konstantin Tokarev <annulen@yandex.ru>
Diffstat (limited to 'Source/WebKit2/Shared/CoordinatedGraphics/SimpleViewportController.cpp')
-rw-r--r--Source/WebKit2/Shared/CoordinatedGraphics/SimpleViewportController.cpp201
1 files changed, 201 insertions, 0 deletions
diff --git a/Source/WebKit2/Shared/CoordinatedGraphics/SimpleViewportController.cpp b/Source/WebKit2/Shared/CoordinatedGraphics/SimpleViewportController.cpp
new file mode 100644
index 000000000..11b55bef7
--- /dev/null
+++ b/Source/WebKit2/Shared/CoordinatedGraphics/SimpleViewportController.cpp
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2011, 2012 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2011 Benjamin Poulain <benjamin@webkit.org>
+ * Copyright (C) 2014 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#if USE(COORDINATED_GRAPHICS_THREADED)
+#include "SimpleViewportController.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+SimpleViewportController::SimpleViewportController(Client* client)
+ : m_client(client)
+ , m_contentsPosition(FloatPoint())
+ , m_contentsSize(FloatSize())
+ , m_viewportSize(FloatSize())
+ , m_allowsUserScaling(false)
+ , m_initiallyFitToViewport(true)
+ , m_hasViewportAttribute(false)
+{
+ resetViewportToDefaultState();
+}
+
+void SimpleViewportController::didChangeViewportSize(const FloatSize& newSize)
+{
+ if (newSize.isEmpty())
+ return;
+
+ m_viewportSize = newSize;
+ updateMinimumScaleToFit();
+ syncVisibleContents();
+}
+
+void SimpleViewportController::didChangeContentsSize(const IntSize& newSize)
+{
+ m_contentsSize = newSize;
+
+ updateMinimumScaleToFit();
+
+ if (m_initiallyFitToViewport) {
+ // Restrict scale factors to m_minimumScaleToFit.
+ ASSERT(m_minimumScaleToFit > 0);
+ m_rawAttributes.initialScale = m_minimumScaleToFit;
+ restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes);
+ }
+
+ syncVisibleContents();
+}
+
+void SimpleViewportController::didChangeViewportAttribute(const ViewportAttributes& newAttributes)
+{
+ if (newAttributes.layoutSize.isEmpty()) {
+ resetViewportToDefaultState();
+ return;
+ }
+
+ m_hasViewportAttribute = true;
+
+ m_rawAttributes = newAttributes;
+ m_allowsUserScaling = m_rawAttributes.userScalable;
+ m_initiallyFitToViewport = m_rawAttributes.initialScale < 0;
+
+ if (!m_initiallyFitToViewport)
+ restrictScaleFactorToInitialScaleIfNotUserScalable(m_rawAttributes);
+
+ updateMinimumScaleToFit();
+
+ syncVisibleContents();
+}
+
+void SimpleViewportController::scrollBy(const IntSize& scrollOffset)
+{
+ m_contentsPosition.move(scrollOffset);
+ m_contentsPosition = boundContentsPosition(m_contentsPosition);
+
+ syncVisibleContents();
+}
+
+void SimpleViewportController::scrollTo(const IntPoint& position)
+{
+ if (m_contentsPosition == boundContentsPosition(position))
+ return;
+
+ m_contentsPosition = boundContentsPosition(position);
+ syncVisibleContents();
+}
+
+void SimpleViewportController::syncVisibleContents()
+{
+ if (m_viewportSize.isEmpty() || m_contentsSize.isEmpty())
+ return;
+
+ m_client->didChangeVisibleRect();
+}
+
+FloatRect SimpleViewportController::visibleContentsRect() const
+{
+ FloatRect visibleContentsRect(boundContentsPosition(m_contentsPosition), visibleContentsSize());
+ visibleContentsRect.intersect(FloatRect(FloatPoint::zero(), m_contentsSize));
+
+ return visibleContentsRect;
+}
+
+FloatSize SimpleViewportController::visibleContentsSize() const
+{
+ return FloatSize(m_viewportSize.width() / m_pageScaleFactor, m_viewportSize.height() / m_pageScaleFactor);
+}
+
+FloatPoint SimpleViewportController::boundContentsPositionAtScale(const FloatPoint& framePosition, float scale) const
+{
+ // We need to floor the viewport here as to allow aligning the content in device units. If not,
+ // it might not be possible to scroll the last pixel and that affects fixed position elements.
+ return FloatPoint(
+ clampTo(framePosition.x(), .0f, std::max(.0f, m_contentsSize.width() - floorf(m_viewportSize.width() / scale))),
+ clampTo(framePosition.y(), .0f, std::max(.0f, m_contentsSize.height() - floorf(m_viewportSize.height() / scale))));
+}
+
+FloatPoint SimpleViewportController::boundContentsPosition(const FloatPoint& framePosition) const
+{
+ return boundContentsPositionAtScale(framePosition, m_pageScaleFactor);
+}
+
+bool fuzzyCompare(float a, float b, float epsilon)
+{
+ return std::abs(a - b) < epsilon;
+}
+
+bool SimpleViewportController::updateMinimumScaleToFit()
+{
+ if (m_viewportSize.isEmpty() || m_contentsSize.isEmpty() || !m_hasViewportAttribute)
+ return false;
+
+ bool currentlyScaledToFit = fuzzyCompare(m_pageScaleFactor, m_minimumScaleToFit, 0.0001);
+
+ float minimumScale = computeMinimumScaleFactorForContentContained(m_rawAttributes, roundedIntSize(m_viewportSize), roundedIntSize(m_contentsSize));
+
+ if (minimumScale <= 0)
+ return false;
+
+ if (!fuzzyCompare(minimumScale, m_minimumScaleToFit, 0.0001)) {
+ m_minimumScaleToFit = minimumScale;
+
+ if (currentlyScaledToFit)
+ m_pageScaleFactor = m_minimumScaleToFit;
+ else {
+ // Ensure the effective scale stays within bounds.
+ float boundedScale = innerBoundedViewportScale(m_pageScaleFactor);
+ if (!fuzzyCompare(boundedScale, m_pageScaleFactor, 0.0001))
+ m_pageScaleFactor = boundedScale;
+ }
+
+ return true;
+ }
+ return false;
+}
+
+float SimpleViewportController::innerBoundedViewportScale(float viewportScale) const
+{
+ return clampTo(viewportScale, m_minimumScaleToFit, m_rawAttributes.maximumScale);
+}
+
+void SimpleViewportController::resetViewportToDefaultState()
+{
+ m_hasViewportAttribute = false;
+ m_pageScaleFactor = 1;
+ m_minimumScaleToFit = 1;
+
+ // Initializing Viewport Raw Attributes to avoid random negative or infinity scale factors
+ // if there is a race condition between the first layout and setting the viewport attributes for the first time.
+ m_rawAttributes.minimumScale = 1;
+ m_rawAttributes.maximumScale = 1;
+ m_rawAttributes.userScalable = m_allowsUserScaling;
+
+ // The initial scale might be implicit and set to -1, in this case we have to infer it
+ // using the viewport size and the final layout size.
+ // To be able to assert for valid scale we initialize it to -1.
+ m_rawAttributes.initialScale = -1;
+}
+
+} // namespace WebCore
+
+#endif // USE(COORDINATED_GRAPHICS_THREADED)