diff options
-rw-r--r-- | BUILD.gn | 1 | ||||
-rw-r--r-- | experimental/skotty/Skotty.cpp | 8 | ||||
-rw-r--r-- | experimental/skotty/Skotty.h | 3 | ||||
-rw-r--r-- | tools/viewer/SkottySlide.cpp | 8 | ||||
-rw-r--r-- | tools/viewer/SkottySlide.h | 34 | ||||
-rw-r--r-- | tools/viewer/SkottySlide2.cpp | 131 | ||||
-rw-r--r-- | tools/viewer/Viewer.cpp | 2 |
7 files changed, 179 insertions, 8 deletions
@@ -1896,6 +1896,7 @@ if (skia_enable_tools) { "tools/viewer/SKPSlide.cpp", "tools/viewer/SampleSlide.cpp", "tools/viewer/SkottySlide.cpp", + "tools/viewer/SkottySlide2.cpp", "tools/viewer/StatsLayer.cpp", "tools/viewer/Viewer.cpp", ] diff --git a/experimental/skotty/Skotty.cpp b/experimental/skotty/Skotty.cpp index a13a04c03c..84cc08051f 100644 --- a/experimental/skotty/Skotty.cpp +++ b/experimental/skotty/Skotty.cpp @@ -752,7 +752,7 @@ Animation::Animation(SkString version, const SkSize& size, SkScalar fps, const J Animation::~Animation() = default; -void Animation::render(SkCanvas* canvas) const { +void Animation::render(SkCanvas* canvas, const SkRect* dstR) const { if (!fDom) return; @@ -760,6 +760,12 @@ void Animation::render(SkCanvas* canvas) const { fDom->revalidate(&ic, SkMatrix::I()); // TODO: proper inval + SkAutoCanvasRestore restore(canvas, true); + const SkRect srcR = SkRect::MakeSize(this->size()); + if (dstR) { + canvas->concat(SkMatrix::MakeRectToRect(srcR, *dstR, SkMatrix::kCenter_ScaleToFit)); + } + canvas->clipRect(srcR); fDom->render(canvas); if (!fShowInval) diff --git a/experimental/skotty/Skotty.h b/experimental/skotty/Skotty.h index c20feeb093..d02dc8d3ab 100644 --- a/experimental/skotty/Skotty.h +++ b/experimental/skotty/Skotty.h @@ -18,6 +18,7 @@ #include <memory> class SkCanvas; +struct SkRect; class SkStream; namespace Json { class Value; } @@ -34,7 +35,7 @@ public: ~Animation(); - void render(SkCanvas*) const; + void render(SkCanvas*, const SkRect* dst = nullptr) const; void animationTick(SkMSec); diff --git a/tools/viewer/SkottySlide.cpp b/tools/viewer/SkottySlide.cpp index 432b307a5e..6e3608c904 100644 --- a/tools/viewer/SkottySlide.cpp +++ b/tools/viewer/SkottySlide.cpp @@ -44,12 +44,8 @@ SkISize SkottySlide::getDimensions() const { void SkottySlide::draw(SkCanvas* canvas) { if (fAnimation) { SkAutoCanvasRestore acr(canvas, true); - const auto animationBounds = SkRect::Make(fAnimation->size().toCeil()); - canvas->concat(SkMatrix::MakeRectToRect(animationBounds, - SkRect::Make(canvas->imageInfo().bounds()), - SkMatrix::kCenter_ScaleToFit)); - canvas->clipRect(animationBounds); - fAnimation->render(canvas); + const SkRect dstR = SkRect::Make(canvas->imageInfo().bounds()); + fAnimation->render(canvas, &dstR); } } diff --git a/tools/viewer/SkottySlide.h b/tools/viewer/SkottySlide.h index 9b7ae7c890..ed0662f2ce 100644 --- a/tools/viewer/SkottySlide.h +++ b/tools/viewer/SkottySlide.h @@ -36,4 +36,38 @@ private: typedef Slide INHERITED; }; +class SkottySlide2 : public Slide { +public: + SkottySlide2(const SkString& path); + ~SkottySlide2() override = default; + + void load(SkScalar winWidth, SkScalar winHeight) override; + void unload() override; + + SkISize getDimensions() const override; + + void draw(SkCanvas*) override; + bool animate(const SkAnimTimer&) override; + bool onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState, uint32_t modifiers) override; +private: + struct Rec { + std::unique_ptr<skotty::Animation> fAnimation; + SkMSec fTimeBase = 0; + SkString fName; + bool fShowAnimationInval = false; + + Rec(std::unique_ptr<skotty::Animation> anim); + Rec(Rec&& o); + }; + + int findCell(float x, float y) const; + + SkString fPath; + SkTArray<Rec> fAnims; + + int fTrackingCell = -1; + + typedef Slide INHERITED; +}; + #endif // SkottySlide_DEFINED diff --git a/tools/viewer/SkottySlide2.cpp b/tools/viewer/SkottySlide2.cpp new file mode 100644 index 0000000000..7e76693a9a --- /dev/null +++ b/tools/viewer/SkottySlide2.cpp @@ -0,0 +1,131 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkottySlide.h" + +#include "SkAnimTimer.h" +#include "SkCanvas.h" +#include "Skotty.h" +#include "SkOSFile.h" +#include "SkOSPath.h" +#include "SkStream.h" + +const int CELL_WIDTH = 240; +const int CELL_HEIGHT = 160; +const int COL_COUNT = 4; +const int SPACER_X = 12; +const int SPACER_Y = 24; +const int MARGIN = 8; + +SkottySlide2::Rec::Rec(std::unique_ptr<skotty::Animation> anim) : fAnimation(std::move(anim)) +{} + +SkottySlide2::Rec::Rec(Rec&& o) + : fAnimation(std::move(o.fAnimation)) + , fTimeBase(o.fTimeBase) + , fName(o.fName) + , fShowAnimationInval(o.fShowAnimationInval) +{} + +SkottySlide2::SkottySlide2(const SkString& path) + : fPath(path) +{ + fName.set("skotty-dir"); +} + +void SkottySlide2::load(SkScalar, SkScalar) { + SkString name; + SkOSFile::Iter iter(fPath.c_str(), "json"); + while (iter.next(&name)) { + SkString path = SkOSPath::Join(fPath.c_str(), name.c_str()); + if (auto stream = SkStream::MakeFromFile(path.c_str())) { + if (auto anim = skotty::Animation::Make(stream.get())) { + fAnims.push_back(Rec(std::move(anim))).fName = name; + } + } + } +} + +void SkottySlide2::unload() { + fAnims.reset(); +} + +SkISize SkottySlide2::getDimensions() const { + const int rows = (fAnims.count() + COL_COUNT - 1) / COL_COUNT; + return { + MARGIN + (COL_COUNT - 1) * SPACER_X + COL_COUNT * CELL_WIDTH + MARGIN, + MARGIN + (rows - 1) * SPACER_Y + rows * CELL_HEIGHT + MARGIN, + }; +} + +void SkottySlide2::draw(SkCanvas* canvas) { + SkPaint paint; + paint.setTextSize(12); + paint.setAntiAlias(true); + paint.setTextAlign(SkPaint::kCenter_Align); + + const SkRect dst = SkRect::MakeIWH(CELL_WIDTH, CELL_HEIGHT); + int x = 0, y = 0; + + canvas->translate(MARGIN, MARGIN); + for (const auto& rec : fAnims) { + SkAutoCanvasRestore acr(canvas, true); + canvas->translate(x * (CELL_WIDTH + SPACER_X), y * (CELL_HEIGHT + SPACER_Y)); + canvas->drawText(rec.fName.c_str(), rec.fName.size(), + dst.centerX(), dst.bottom() + paint.getTextSize(), paint); + rec.fAnimation->render(canvas, &dst); + if (++x == COL_COUNT) { + x = 0; + y += 1; + } + } +} + +bool SkottySlide2::animate(const SkAnimTimer& timer) { + for (auto& rec : fAnims) { + if (rec.fTimeBase == 0) { + // Reset the animation time. + rec.fTimeBase = timer.msec(); + } + rec.fAnimation->animationTick(timer.msec() - rec.fTimeBase); + } + return true; +} + +bool SkottySlide2::onMouse(SkScalar x, SkScalar y, sk_app::Window::InputState state, + uint32_t modifiers) { + if (fTrackingCell < 0 && state == sk_app::Window::kDown_InputState) { + fTrackingCell = this->findCell(x, y); + } + if (fTrackingCell >= 0 && state == sk_app::Window::kUp_InputState) { + int index = this->findCell(x, y); + if (fTrackingCell == index) { + fAnims[index].fShowAnimationInval = !fAnims[index].fShowAnimationInval; + fAnims[index].fAnimation->setShowInval(fAnims[index].fShowAnimationInval); + } + fTrackingCell = -1; + } + return fTrackingCell >= 0; +} + +int SkottySlide2::findCell(float x, float y) const { + x -= MARGIN; + y -= MARGIN; + int index = -1; + if (x >= 0 && y >= 0) { + int ix = (int)x; + int iy = (int)y; + int col = ix / (CELL_WIDTH + SPACER_X); + int row = iy / (CELL_HEIGHT + SPACER_Y); + index = row * COL_COUNT + col; + if (index >= fAnims.count()) { + index = -1; + } + } + return index; +} + diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp index 68f8a8d4e5..59d5e50d5a 100644 --- a/tools/viewer/Viewer.cpp +++ b/tools/viewer/Viewer.cpp @@ -486,6 +486,8 @@ void Viewer::initSlides() { // JSONs for (const auto& json : FLAGS_jsons) { + fSlides.push_back(sk_make_sp<SkottySlide2>(json)); + SkOSFile::Iter it(json.c_str(), ".json"); SkString jsonName; while (it.next(&jsonName)) { |