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
This commit is contained in:
liyuqian 2016-05-20 07:32:19 -07:00 committed by Commit bot
parent 8775112717
commit e46e4f075b
4 changed files with 61 additions and 11 deletions

View 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);

View 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);
}

View 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;
}
}

View 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;
};