Correct gesture scale and translation
authorliyuqian <liyuqian@google.com>
Fri, 20 May 2016 14:32:19 +0000 (07:32 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 20 May 2016 14:32:19 +0000 (07:32 -0700)
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1996613002

Review-Url: https://codereview.chromium.org/1996613002

include/views/SkTouchGesture.h
src/views/SkTouchGesture.cpp
tools/viewer/Viewer.cpp
tools/viewer/Viewer.h

index 60487c7a2f285f0d62c820431c016363880bda69..4d4c0312d3304ef3391e48256aba36257c9d0316 100644 (file)
@@ -43,6 +43,8 @@ public:
     const SkMatrix& localM();
     const SkMatrix& globalM() const { return fGlobalM; }
 
+    void setTransLimit(const SkRect& contentRect, const SkRect& windowRect);
+
 private:
     enum State {
         kEmpty_State,
@@ -65,7 +67,11 @@ private:
     double          fLastUpMillis;
     SkPoint         fLastUpP;
 
+    // The following rects are used to limit the translation so the content never leaves the window
+    SkRect          fContentRect, fWindowRect;
+    bool            fIsTransLimited = false;
 
+    void limitTrans(); // here we only limit the translation with respect to globalM
     void flushLocalM();
     int findRec(void* owner) const;
     void appendNewRec(void* owner, float x, float y);
index 5fc8d7ee90b1e5c3fb371576e9cffbcfa6659115..752828e37f3a866edc2dc66ae86717ec64bce956 100644 (file)
@@ -5,7 +5,7 @@
  * found in the LICENSE file.
  */
 
-
+#include <algorithm>
 
 #include "SkTouchGesture.h"
 #include "SkMatrix.h"
@@ -109,6 +109,7 @@ SkTouchGesture::~SkTouchGesture() {
 }
 
 void SkTouchGesture::reset() {
+    fIsTransLimited = false;
     fTouches.reset();
     fState = kEmpty_State;
     fLocalM.reset();
@@ -293,6 +294,8 @@ void SkTouchGesture::touchEnd(void* owner) {
     }
 
     fTouches.removeShuffle(index);
+
+    limitTrans();
 }
 
 float SkTouchGesture::computePinch(const Rec& rec0, const Rec& rec1) {
@@ -327,3 +330,24 @@ bool SkTouchGesture::handleDblTap(float x, float y) {
     fLastUpP.set(x, y);
     return found;
 }
+
+void SkTouchGesture::setTransLimit(const SkRect& contentRect, const SkRect& windowRect) {
+    fIsTransLimited = true;
+    fContentRect = contentRect;
+    fWindowRect = windowRect;
+}
+
+void SkTouchGesture::limitTrans() {
+    if (!fIsTransLimited) {
+        return;
+    }
+
+    SkRect scaledContent = fContentRect;
+    fGlobalM.mapRect(&scaledContent);
+    const SkScalar ZERO = 0;
+
+    fGlobalM.postTranslate(ZERO, std::min(ZERO, fWindowRect.fBottom - scaledContent.fTop));
+    fGlobalM.postTranslate(ZERO, std::max(ZERO, fWindowRect.fTop - scaledContent.fBottom));
+    fGlobalM.postTranslate(std::min(ZERO, fWindowRect.fRight - scaledContent.fLeft), ZERO);
+    fGlobalM.postTranslate(std::max(ZERO, fWindowRect.fLeft - scaledContent.fRight), ZERO);
+}
index 7f18652c2c024ba98599f24969ba85e4f506a883..a0b2a2abe3ca53505895be1c8a7969fd526d0226 100644 (file)
@@ -213,6 +213,28 @@ void Viewer::updateTitle() {
 }
 
 void Viewer::setupCurrentSlide(int previousSlide) {
+    fGesture.reset();
+    fDefaultMatrix.reset();
+    fDefaultMatrixInv.reset();
+
+    if (fWindow->supportsContentRect() && fWindow->scaleContentToFit()) {
+        const SkRect contentRect = fWindow->getContentRect();
+        const SkISize slideSize = fSlides[fCurrentSlide]->getDimensions();
+        const SkRect slideBounds = SkRect::MakeIWH(slideSize.width(), slideSize.height());
+        if (contentRect.width() > 0 && contentRect.height() > 0) {
+            fDefaultMatrix.setRectToRect(slideBounds, contentRect, SkMatrix::kStart_ScaleToFit);
+            bool inverted = fDefaultMatrix.invert(&fDefaultMatrixInv);
+            SkASSERT(inverted);
+        }
+    }
+
+    if (fWindow->supportsContentRect()) {
+        const SkISize slideSize = fSlides[fCurrentSlide]->getDimensions();
+        SkRect windowRect = fWindow->getContentRect();
+        fDefaultMatrixInv.mapRect(&windowRect);
+        fGesture.setTransLimit(SkRect::MakeWH(slideSize.width(), slideSize.height()), windowRect);
+    }
+
     this->updateTitle();
     fSlides[fCurrentSlide]->load();
     if (previousSlide >= 0) {
@@ -269,14 +291,7 @@ void Viewer::onPaint(SkCanvas* canvas) {
     }
 
     canvas->clear(SK_ColorWHITE);
-    if (fWindow->supportsContentRect() && fWindow->scaleContentToFit()) {
-        const SkRect contentRect = fWindow->getContentRect();
-        const SkISize slideSize = fSlides[fCurrentSlide]->getDimensions();
-        const SkRect slideBounds = SkRect::MakeIWH(slideSize.width(), slideSize.height());
-        SkMatrix matrix;
-        matrix.setRectToRect(slideBounds, contentRect, SkMatrix::kCenter_ScaleToFit);
-        canvas->concat(matrix);
-    }
+    canvas->concat(fDefaultMatrix);
     canvas->concat(computeMatrix());
 
     fSlides[fCurrentSlide]->draw(canvas);
@@ -290,17 +305,18 @@ void Viewer::onPaint(SkCanvas* canvas) {
 
 bool Viewer::onTouch(int owner, Window::InputState state, float x, float y) {
     void* castedOwner = reinterpret_cast<void*>(owner);
+    SkPoint touchPoint = fDefaultMatrixInv.mapXY(x, y);
     switch (state) {
         case Window::kUp_InputState: {
             fGesture.touchEnd(castedOwner);
             break;
         }
         case Window::kDown_InputState: {
-            fGesture.touchBegin(castedOwner, x, y);
+            fGesture.touchBegin(castedOwner, touchPoint.fX, touchPoint.fY);
             break;
         }
         case Window::kMove_InputState: {
-            fGesture.touchMoved(castedOwner, x, y);
+            fGesture.touchMoved(castedOwner, touchPoint.fX, touchPoint.fY);
             break;
         }
     }
index c785cff78e04a133719f20cd66668043629c366a..0bafee175ba8b7d1165e3057dbb0495af2d075a4 100644 (file)
@@ -59,6 +59,10 @@ private:
     sk_app::CommandSet     fCommands;
 
     SkTouchGesture         fGesture;
+
+    // identity unless the window initially scales the content to fit the screen.
+    SkMatrix               fDefaultMatrix;
+    SkMatrix               fDefaultMatrixInv;
 };