Title: [98965] trunk/Source/WebKit2
Revision
98965
Author
[email protected]
Date
2011-11-01 08:40:36 -0700 (Tue, 01 Nov 2011)

Log Message

The QtViewportInteractionEngine should consider DPI adjustment
https://bugs.webkit.org/show_bug.cgi?id=71283

Reviewed by Simon Hausmann.

* UIProcess/API/qt/qtouchwebview.cpp:

    Add some default values for now to make sure we are testing the
    DPI adjustment / CSS-item space conversion.

(QTouchWebViewPrivate::updateViewportConstraints):
* UIProcess/qt/QtViewportInteractionEngine.cpp:
(WebKit::ViewportUpdateGuard::ViewportUpdateGuard):
(WebKit::ViewportUpdateGuard::~ViewportUpdateGuard):

    Clean up the guard to be more understandable.

(WebKit::QtViewportInteractionEngine::cssScaleFromItem):
(WebKit::QtViewportInteractionEngine::itemScaleFromCSS):

    Add methods for converting between CSS and item space.

(WebKit::QtViewportInteractionEngine::innerBoundedCSSScale):
(WebKit::QtViewportInteractionEngine::outerBoundedCSSScale):

    Make it clean which methods uses which coord space.

(WebKit::QtViewportInteractionEngine::updateVisibleRect):
(WebKit::QtViewportInteractionEngine::event):
(WebKit::QtViewportInteractionEngine::computePosRangeForItemScale):

    Rename calculateBoundariesForScale and change its implementation to
    be correct. The new name reflects the space in which the computation
    takes place and reflects similar Qt API.

(WebKit::QtViewportInteractionEngine::animateContentIntoBoundariesIfNeeded):
(WebKit::QtViewportInteractionEngine::pinchGestureRequestUpdate):
(WebKit::QtViewportInteractionEngine::scaleContent):

    Make sure to consider the right coord space.

* UIProcess/qt/QtViewportInteractionEngine.h:
(WebKit::QtViewportInteractionEngine::Constraints::Constraints):

    Add the devicePixelRatio.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (98964 => 98965)


--- trunk/Source/WebKit2/ChangeLog	2011-11-01 15:32:04 UTC (rev 98964)
+++ trunk/Source/WebKit2/ChangeLog	2011-11-01 15:40:36 UTC (rev 98965)
@@ -1,3 +1,51 @@
+2011-11-01  Kenneth Rohde Christiansen  <[email protected]>
+
+        The QtViewportInteractionEngine should consider DPI adjustment
+        https://bugs.webkit.org/show_bug.cgi?id=71283
+
+        Reviewed by Simon Hausmann.
+
+        * UIProcess/API/qt/qtouchwebview.cpp:
+
+            Add some default values for now to make sure we are testing the
+            DPI adjustment / CSS-item space conversion.
+
+        (QTouchWebViewPrivate::updateViewportConstraints):
+        * UIProcess/qt/QtViewportInteractionEngine.cpp:
+        (WebKit::ViewportUpdateGuard::ViewportUpdateGuard):
+        (WebKit::ViewportUpdateGuard::~ViewportUpdateGuard):
+
+            Clean up the guard to be more understandable.
+
+        (WebKit::QtViewportInteractionEngine::cssScaleFromItem):
+        (WebKit::QtViewportInteractionEngine::itemScaleFromCSS):
+
+            Add methods for converting between CSS and item space.
+
+        (WebKit::QtViewportInteractionEngine::innerBoundedCSSScale):
+        (WebKit::QtViewportInteractionEngine::outerBoundedCSSScale):
+
+            Make it clean which methods uses which coord space.
+
+        (WebKit::QtViewportInteractionEngine::updateVisibleRect):
+        (WebKit::QtViewportInteractionEngine::event):
+        (WebKit::QtViewportInteractionEngine::computePosRangeForItemScale):
+
+            Rename calculateBoundariesForScale and change its implementation to
+            be correct. The new name reflects the space in which the computation
+            takes place and reflects similar Qt API.
+
+        (WebKit::QtViewportInteractionEngine::animateContentIntoBoundariesIfNeeded):
+        (WebKit::QtViewportInteractionEngine::pinchGestureRequestUpdate):
+        (WebKit::QtViewportInteractionEngine::scaleContent):
+
+            Make sure to consider the right coord space.
+
+        * UIProcess/qt/QtViewportInteractionEngine.h:
+        (WebKit::QtViewportInteractionEngine::Constraints::Constraints):
+
+            Add the devicePixelRatio.
+
 2011-11-01  Simon Hausmann  <[email protected]>
 
         Prospective clang build fix.

Modified: trunk/Source/WebKit2/UIProcess/API/qt/qtouchwebview.cpp (98964 => 98965)


--- trunk/Source/WebKit2/UIProcess/API/qt/qtouchwebview.cpp	2011-11-01 15:32:04 UTC (rev 98964)
+++ trunk/Source/WebKit2/UIProcess/API/qt/qtouchwebview.cpp	2011-11-01 15:40:36 UTC (rev 98965)
@@ -69,12 +69,18 @@
     WebPageProxy* wkPage = toImpl(page.pageRef());
     WebPreferences* wkPrefs = wkPage->pageGroup()->preferences();
 
+    // FIXME: Remove later; Hardcode some values for now to make sure the DPI adjustment is being tested.
+    wkPrefs->setDeviceDPI(240);
+    wkPrefs->setDeviceWidth(480);
+    wkPrefs->setDeviceHeight(720);
+
     WebCore::ViewportAttributes attr = WebCore::computeViewportAttributes(viewportArguments, wkPrefs->layoutFallbackWidth(), wkPrefs->deviceWidth(), wkPrefs->deviceHeight(), wkPrefs->deviceDPI(), availableSize);
 
     QtViewportInteractionEngine::Constraints newConstraints;
     newConstraints.initialScale = attr.initialScale;
     newConstraints.minimumScale = attr.minimumScale;
     newConstraints.maximumScale = attr.maximumScale;
+    newConstraints.devicePixelRatio = attr.devicePixelRatio;
     newConstraints.isUserScalable = !!attr.userScalable;
     interactionEngine.setConstraints(newConstraints);
 

Modified: trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp (98964 => 98965)


--- trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp	2011-11-01 15:32:04 UTC (rev 98964)
+++ trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.cpp	2011-11-01 15:40:36 UTC (rev 98965)
@@ -33,60 +33,65 @@
 
 static const int kScaleAnimationDurationMillis = 400;
 
-static inline QRectF contentRectInViewportCoordinates(const QQuickItem* content, const QQuickItem* viewport)
-{
-    return viewport->mapRectFromItem(content, content->boundingRect());
-}
-
-static inline qreal bindToScaleLimits(qreal scale)
-{
-    // Bounded by [0.1, 10.0] like the viewport meta code in WebCore.
-    return qBound(qreal(0.1), scale, qreal(10.0));
-}
-
 // Updating content properties cause the notify signals to be sent by the content item itself.
-// Since we manage those differently, we do not want to respond
-// to them when we are the one changing the content.
+// We manage these differently, as we do not want to act on them when we are the ones changing the content.
 //
-// The guard makes sure that the signal viewportUpdateRequested() is sent if necessary.
-// When multiple guards are alive, their lifetime must be perfectly imbricated (e.g. if used ouside stack frames).
-// We rely on the first one to trigger the update at the end.
+// This guard makes sure that the signal viewportUpdateRequested() is sent only when necessary.
 //
-// The public methods should create the guard if they might update content.
+// When multiple guards are alive, their lifetime must be perfectly imbricated (e.g. if used ouside stack
+// frames). We rely on the first one to trigger the update at the end.
+//
+// Our public QtViewportInteractionEngine methods should use the guard if they update content in any situation.
+
 class ViewportUpdateGuard {
 public:
-    ViewportUpdateGuard(QtViewportInteractionEngine* viewportInteractionEngine)
-        : viewportInteractionEngine(viewportInteractionEngine)
-        , previousPosition(viewportInteractionEngine->m_content->pos())
-        , previousSize(viewportInteractionEngine->m_content->width(), viewportInteractionEngine->m_content->height())
-        , previousScale(viewportInteractionEngine->m_content->scale())
+    ViewportUpdateGuard(QtViewportInteractionEngine* engine)
+        : engine(engine)
+        , startPosition(engine->m_content->pos())
+        , startScale(engine->m_content->scale())
+        , startWidth(engine->m_content->width())
+        , startHeight(engine->m_content->height())
 
     {
-        ++(viewportInteractionEngine->m_pendingUpdates);
+        ++(engine->m_pendingUpdates);
     }
 
     ~ViewportUpdateGuard()
     {
-        --(viewportInteractionEngine->m_pendingUpdates);
-        if (!viewportInteractionEngine->m_pendingUpdates) {
-            // Reset the tiling look-ahead vector so that tiles all around the viewport will be requested.
-            emit viewportInteractionEngine->viewportTrajectoryVectorChanged(QPointF());
-            if (previousPosition != viewportInteractionEngine->m_content->pos()
-                    || previousSize.width() != viewportInteractionEngine->m_content->width()
-                    || previousSize.height() != viewportInteractionEngine->m_content->height()
-                    || previousScale != viewportInteractionEngine->m_content->scale())
-                // We must notify the change so the client can rely on us for all changes of geometry.
-                emit viewportInteractionEngine->viewportUpdateRequested();
-        }
+        if (--(engine->m_pendingUpdates))
+            return;
+
+        // Make sure that tiles all around the viewport will be requested.
+        emit engine->viewportTrajectoryVectorChanged(QPointF());
+
+        QQuickItem* item = engine->m_content;
+        bool needsRepaint = startPosition != item->pos() || startScale != item->scale()
+            || startWidth != item->width() || startHeight != item->height();
+
+        // We must notify the change so the client can rely on us for all changes of geometry.
+        if (needsRepaint)
+            emit engine->viewportUpdateRequested();
     }
 
 private:
-    QtViewportInteractionEngine* const viewportInteractionEngine;
-    const QPointF previousPosition;
-    const QSizeF previousSize;
-    const qreal previousScale;
+    QtViewportInteractionEngine* const engine;
+
+    const QPointF startPosition;
+    const qreal startScale;
+    const qreal startWidth;
+    const qreal startHeight;
 };
 
+inline qreal QtViewportInteractionEngine::cssScaleFromItem(qreal itemScale)
+{
+    return itemScale / m_constraints.devicePixelRatio;
+}
+
+inline qreal QtViewportInteractionEngine::itemScaleFromCSS(qreal cssScale)
+{
+    return cssScale * m_constraints.devicePixelRatio;
+}
+
 QtViewportInteractionEngine::QtViewportInteractionEngine(const QQuickItem* viewport, QQuickItem* content)
     : m_viewport(viewport)
     , m_content(content)
@@ -109,19 +114,20 @@
 {
 }
 
-qreal QtViewportInteractionEngine::innerBoundedScale(qreal scale)
+qreal QtViewportInteractionEngine::innerBoundedCSSScale(qreal cssScale)
 {
-    return qBound(m_constraints.minimumScale, scale, m_constraints.maximumScale);
+    return qBound(m_constraints.minimumScale, cssScale, m_constraints.maximumScale);
 }
 
-qreal QtViewportInteractionEngine::outerBoundedScale(qreal scale)
+qreal QtViewportInteractionEngine::outerBoundedCSSScale(qreal cssScale)
 {
     if (m_constraints.isUserScalable) {
-        qreal hardMin = qreal(0.5) * m_constraints.minimumScale;
-        qreal hardMax = qreal(2.0) * m_constraints.maximumScale;
-        return bindToScaleLimits(qBound(hardMin, scale, hardMax));
+        // Bounded by [0.1, 10.0] like the viewport meta code in WebCore.
+        qreal hardMin = qMax<qreal>(0.1, qreal(0.5) * m_constraints.minimumScale);
+        qreal hardMax = qMin<qreal>(10, qreal(2.0) * m_constraints.maximumScale);
+        return qBound(hardMin, cssScale, hardMax);
     }
-    return innerBoundedScale(scale);
+    return innerBoundedCSSScale(cssScale);
 }
 
 void QtViewportInteractionEngine::updateVisibleRect(QVariant rect)
@@ -129,13 +135,13 @@
     ViewportUpdateGuard guard(this);
 
     QRectF visibleRect = rect.toRectF();
-    qreal currentScale = m_viewport->width() / visibleRect.width();
+    qreal itemScale = m_viewport->width() / visibleRect.width();
 
-    m_content->setScale(currentScale);
+    m_content->setScale(itemScale);
 
     // We need to animate the content but the position represents the viewport hence we need to invert the position here.
     // To animate the position together with the scale we multiply the position with the current scale;
-    m_content->setPos(-visibleRect.topLeft() * currentScale);
+    m_content->setPos(-visibleRect.topLeft() * itemScale);
 }
 
 void QtViewportInteractionEngine::scaleAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State /*oldState*/)
@@ -158,9 +164,9 @@
     case QEvent::ScrollPrepare: {
         QScrollPrepareEvent* prepareEvent = static_cast<QScrollPrepareEvent*>(event);
         const QRectF viewportRect = m_viewport->boundingRect();
-        const QRectF contentRect = contentRectInViewportCoordinates(m_content, m_viewport);
-        const QRectF contentPositionRange = calculateBoundariesForScale(contentRect.size(), viewportRect.size(), 1);
-        prepareEvent->setContentPosRange(contentPositionRange);
+        const QRectF contentRect = m_viewport->mapRectFromItem(m_content, m_content->boundingRect());
+        const QRectF posRange = computePosRangeForItemScale(m_content->scale());
+        prepareEvent->setContentPosRange(posRange);
         prepareEvent->setViewportSize(viewportRect.size());
 
         // As we want to push the contents and not actually scroll it, we need to invert the positions here.
@@ -200,57 +206,56 @@
     m_userInteractionFlags &= ~UserHasStoppedAnimations;
 }
 
-const QRectF QtViewportInteractionEngine::calculateBoundariesForScale(const QSizeF contentSize, const QSizeF viewportSize, qreal scale)
+QRectF QtViewportInteractionEngine::computePosRangeForItemScale(qreal itemScale) const
 {
-    const QSizeF scaledViewportSize = viewportSize / scale;
+    const QSizeF contentItemSize = m_content->boundingRect().size() * itemScale;
+    const QSizeF viewportItemSize = m_viewport->boundingRect().size();
 
-    const qreal horizontalOffset = contentSize.width() - scaledViewportSize.width();
-    const qreal verticalOffset = contentSize.height() - scaledViewportSize.height();
+    const qreal horizontalRange = contentItemSize.width() - viewportItemSize.width();
+    const qreal verticalRange = contentItemSize.height() - viewportItemSize.height();
 
-    const QPointF contentPositionRangeTopLeft(qMin<qreal>(0, horizontalOffset / 2), 0);
-    const qreal contentPositionRangeWidth = qMax<qreal>(0, horizontalOffset);
-    const qreal contentPositionRangeHeight = qMax<qreal>(0, verticalOffset);
-
-    return QRectF(contentPositionRangeTopLeft, QSizeF(contentPositionRangeWidth, contentPositionRangeHeight));
+    return QRectF(QPointF(0, 0), QSizeF(horizontalRange, verticalRange));
 }
 
 void QtViewportInteractionEngine::animateContentIntoBoundariesIfNeeded()
 {
     m_scaleAnimation->stop();
 
-    qreal currentScale = m_content->scale();
+    qreal currentCSSScale = cssScaleFromItem(m_content->scale());
     bool userHasScaledContent = m_userInteractionFlags & UserHasScaledContent;
     bool userHasStoppedAnimations = m_userInteractionFlags & UserHasStoppedAnimations;
 
     if (!userHasScaledContent)
-        currentScale = m_constraints.initialScale;
+        currentCSSScale = m_constraints.initialScale;
 
-    qreal boundedScale = innerBoundedScale(currentScale);
+    qreal endItemScale = itemScaleFromCSS(innerBoundedCSSScale(currentCSSScale));
 
-    QRectF viewportRect = m_viewport->boundingRect();
-    QPointF viewportHotspot = viewportRect.center();
-    QPointF position = m_content->mapFromItem(m_viewport, viewportHotspot) - viewportHotspot / boundedScale;
-    QRectF positionBoundaries = calculateBoundariesForScale(m_content->boundingRect().size(), viewportRect.size(), boundedScale);
-    QPointF minOffset = positionBoundaries.topLeft();
-    QPointF maxOffset = positionBoundaries.bottomRight();
-    QPointF boundedPosition;
-    boundedPosition.setX(qBound(minOffset.x(), position.x(), maxOffset.x()));
-    boundedPosition.setY(qBound(minOffset.y(), position.y(), maxOffset.y()));
+    const QRectF viewportRect = m_viewport->boundingRect();
+    const QPointF viewportHotspot = viewportRect.center();
 
-    QRectF scaledRect(boundedPosition, viewportRect.size() / boundedScale);
-    QRectF currentRect = m_viewport->mapRectToItem(m_content, viewportRect);
+    QPointF endPosition = m_content->mapFromItem(m_viewport, viewportHotspot) - viewportHotspot / endItemScale;
 
-    if (scaledRect == currentRect)
+    QRectF endPosRange = computePosRangeForItemScale(endItemScale);
+    QPointF minValue = endPosRange.topLeft();
+    QPointF maxValue = endPosRange.bottomRight();
+
+    endPosition.setX(qBound(minValue.x(), endPosition.x(), maxValue.x()));
+    endPosition.setY(qBound(minValue.y(), endPosition.y(), maxValue.y()));
+
+    QRectF startVisibleContentRect(m_viewport->mapRectToItem(m_content, viewportRect));
+    QRectF endVisibleContentRect(endPosition, viewportRect.size() / endItemScale);
+
+    if (endVisibleContentRect == startVisibleContentRect)
         return;
 
     if (userHasScaledContent && !userHasStoppedAnimations) {
         m_scaleAnimation->setDuration(kScaleAnimationDurationMillis);
         m_scaleAnimation->setEasingCurve(QEasingCurve::OutCubic);
-        m_scaleAnimation->setStartValue(currentRect);
-        m_scaleAnimation->setEndValue(scaledRect);
+        m_scaleAnimation->setStartValue(startVisibleContentRect);
+        m_scaleAnimation->setEndValue(endVisibleContentRect);
         m_scaleAnimation->start();
     } else
-        updateVisibleRect(scaledRect);
+        updateVisibleRect(endVisibleContentRect);
 }
 
 void QtViewportInteractionEngine::reset()
@@ -337,14 +342,14 @@
 
     //  Changes of the center position should move the page even if the zoom factor
     //  does not change.
-    const qreal scale = m_pinchStartScale * totalScaleFactor;
+    const qreal cssScale = cssScaleFromItem(m_pinchStartScale * totalScaleFactor);
 
     // Allow zooming out beyond mimimum scale on pages that do not explicitly disallow it.
-    const qreal boundedScale = outerBoundedScale(scale);
+    const qreal targetCSSScale = outerBoundedCSSScale(cssScale);
 
     QPointF pinchCenterInViewportCoordinates = m_viewport->mapFromItem(m_content, pinchCenterInContentCoordinates);
 
-    scaleContent(pinchCenterInContentCoordinates, boundedScale);
+    scaleContent(pinchCenterInContentCoordinates, targetCSSScale);
 
     const QPointF positionDiff = pinchCenterInViewportCoordinates - m_lastPinchCenterInViewportCoordinates;
     m_lastPinchCenterInViewportCoordinates = pinchCenterInViewportCoordinates;
@@ -371,10 +376,10 @@
     animateContentIntoBoundariesIfNeeded();
 }
 
-void QtViewportInteractionEngine::scaleContent(const QPointF& centerInContentCoordinates, qreal scale)
+void QtViewportInteractionEngine::scaleContent(const QPointF& centerInContentCoordinates, qreal cssScale)
 {
     QPointF oldPinchCenterOnParent = m_content->mapToItem(m_content->parentItem(), centerInContentCoordinates);
-    m_content->setScale(scale);
+    m_content->setScale(itemScaleFromCSS(cssScale));
     QPointF newPinchCenterOnParent = m_content->mapToItem(m_content->parentItem(), centerInContentCoordinates);
     m_content->setPos(m_content->pos() - (newPinchCenterOnParent - oldPinchCenterOnParent));
 }

Modified: trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h (98964 => 98965)


--- trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h	2011-11-01 15:32:04 UTC (rev 98964)
+++ trunk/Source/WebKit2/UIProcess/qt/QtViewportInteractionEngine.h	2011-11-01 15:40:36 UTC (rev 98965)
@@ -42,21 +42,22 @@
     Q_OBJECT
 
 public:
-    QtViewportInteractionEngine(const QQuickItem *, QQuickItem *);
+    QtViewportInteractionEngine(const QQuickItem*, QQuickItem*);
     ~QtViewportInteractionEngine();
 
-
     struct Constraints {
         Constraints()
             : initialScale(1.0)
             , minimumScale(0.25)
             , maximumScale(1.8)
+            , devicePixelRatio(1.0)
             , isUserScalable(true)
         { }
 
         qreal initialScale;
         qreal minimumScale;
         qreal maximumScale;
+        qreal devicePixelRatio;
         bool isUserScalable;
     };
 
@@ -86,9 +87,12 @@
     void scaleAnimationStateChanged(QAbstractAnimation::State, QAbstractAnimation::State);
 
 private:
-    qreal innerBoundedScale(qreal scale);
-    qreal outerBoundedScale(qreal scale);
-    const QRectF calculateBoundariesForScale(const QSizeF contentSize, const QSizeF viewportSize, qreal scale);
+    qreal cssScaleFromItem(qreal);
+    qreal itemScaleFromCSS(qreal);
+    qreal innerBoundedCSSScale(qreal);
+    qreal outerBoundedCSSScale(qreal);
+
+    QRectF computePosRangeForItemScale(qreal itemScale) const;
     void animateContentIntoBoundariesIfNeeded();
 
     void scaleContent(const QPointF& centerInContentCoordinates, qreal scale);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to