diff options
author | liyuqian <liyuqian@google.com> | 2016-05-20 07:32:19 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-05-20 07:32:19 -0700 |
commit | e46e4f075bfa8acf038aa68a8e7da282d4c1015b (patch) | |
tree | a599a8727b8903da82c1c192323b93def50943f4 | |
parent | 87751127172bd49c632c9290ffde43385d38ce61 (diff) |
Correct gesture scale and translation
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
-rw-r--r-- | include/views/SkTouchGesture.h | 6 | ||||
-rw-r--r-- | src/views/SkTouchGesture.cpp | 26 | ||||
-rw-r--r-- | tools/viewer/Viewer.cpp | 36 | ||||
-rw-r--r-- | tools/viewer/Viewer.h | 4 |
4 files changed, 61 insertions, 11 deletions
diff --git a/include/views/SkTouchGesture.h b/include/views/SkTouchGesture.h index 60487c7a2f..4d4c0312d3 100644 --- a/include/views/SkTouchGesture.h +++ b/include/views/SkTouchGesture.h @@ -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); diff --git a/src/views/SkTouchGesture.cpp b/src/views/SkTouchGesture.cpp index 5fc8d7ee90..752828e37f 100644 --- a/src/views/SkTouchGesture.cpp +++ b/src/views/SkTouchGesture.cpp @@ -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); +} diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 7f18652c2c..a0b2a2abe3 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -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; } } diff --git a/tools/viewer/Viewer.h b/tools/viewer/Viewer.h index c785cff78e..0bafee175b 100644 --- a/tools/viewer/Viewer.h +++ b/tools/viewer/Viewer.h @@ -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; }; |