2018-01-12 16:24:30 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2018 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
2018-01-14 19:46:51 +00:00
|
|
|
#include "SkAndroidCodec.h"
|
2018-01-12 16:24:30 +00:00
|
|
|
#include "SkAnimatedImage.h"
|
|
|
|
#include "SkAnimTimer.h"
|
|
|
|
#include "SkCanvas.h"
|
2019-01-02 17:21:01 +00:00
|
|
|
#include "SkFont.h"
|
2018-01-12 16:24:30 +00:00
|
|
|
#include "SkPaint.h"
|
|
|
|
#include "SkPictureRecorder.h"
|
|
|
|
#include "SkRect.h"
|
|
|
|
#include "SkScalar.h"
|
|
|
|
#include "SkString.h"
|
|
|
|
|
2018-08-08 15:36:17 +00:00
|
|
|
#include "Sample.h"
|
2018-01-12 16:24:30 +00:00
|
|
|
#include "Resources.h"
|
|
|
|
|
|
|
|
static constexpr char kPauseKey = 'p';
|
|
|
|
static constexpr char kResetKey = 'r';
|
|
|
|
|
2018-08-08 15:36:17 +00:00
|
|
|
class SampleAnimatedImage : public Sample {
|
2018-01-12 16:24:30 +00:00
|
|
|
public:
|
|
|
|
SampleAnimatedImage()
|
|
|
|
: INHERITED()
|
|
|
|
, fYOffset(0)
|
|
|
|
{}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void onDrawBackground(SkCanvas* canvas) override {
|
2019-01-02 17:21:01 +00:00
|
|
|
SkFont font;
|
|
|
|
font.setSize(20);
|
2018-01-12 16:24:30 +00:00
|
|
|
|
|
|
|
SkString str = SkStringPrintf("Press '%c' to start/pause; '%c' to reset.",
|
|
|
|
kPauseKey, kResetKey);
|
|
|
|
const char* text = str.c_str();
|
|
|
|
SkRect bounds;
|
2019-01-02 17:21:01 +00:00
|
|
|
font.measureText(text, strlen(text), kUTF8_SkTextEncoding, &bounds);
|
2018-01-12 16:24:30 +00:00
|
|
|
fYOffset = bounds.height();
|
|
|
|
|
2019-01-02 17:21:01 +00:00
|
|
|
canvas->drawSimpleText(text, strlen(text), kUTF8_SkTextEncoding, 5, fYOffset, font, SkPaint());
|
2018-01-12 16:24:30 +00:00
|
|
|
fYOffset *= 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
void onDrawContent(SkCanvas* canvas) override {
|
|
|
|
if (!fImage) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
canvas->translate(0, fYOffset);
|
|
|
|
|
|
|
|
canvas->drawDrawable(fImage.get());
|
|
|
|
canvas->drawDrawable(fDrawable.get(), fImage->getBounds().width(), 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool onAnimate(const SkAnimTimer& animTimer) override {
|
|
|
|
if (!fImage) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-01-30 00:35:55 +00:00
|
|
|
const double lastWallTime = fLastWallTime;
|
|
|
|
fLastWallTime = animTimer.msec();
|
|
|
|
|
|
|
|
if (fRunning) {
|
|
|
|
fCurrentTime += fLastWallTime - lastWallTime;
|
|
|
|
if (fCurrentTime > fTimeToShowNextFrame) {
|
|
|
|
fTimeToShowNextFrame += fImage->decodeNextFrame();
|
|
|
|
if (fImage->isFinished()) {
|
|
|
|
fRunning = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-12 16:24:30 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void onOnceBeforeDraw() override {
|
|
|
|
sk_sp<SkData> file(GetResourceAsData("images/alphabetAnim.gif"));
|
|
|
|
std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(file));
|
|
|
|
if (!codec) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-14 19:46:51 +00:00
|
|
|
fImage = SkAnimatedImage::Make(SkAndroidCodec::MakeFromCodec(std::move(codec)));
|
2018-01-12 16:24:30 +00:00
|
|
|
if (!fImage) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-30 00:35:55 +00:00
|
|
|
fTimeToShowNextFrame = fImage->currentFrameDuration();
|
2018-01-12 16:24:30 +00:00
|
|
|
SkPictureRecorder recorder;
|
|
|
|
auto canvas = recorder.beginRecording(fImage->getBounds());
|
|
|
|
canvas->drawDrawable(fImage.get());
|
|
|
|
fDrawable = recorder.finishRecordingAsDrawable();
|
|
|
|
}
|
|
|
|
|
2018-08-08 15:36:17 +00:00
|
|
|
bool onQuery(Sample::Event* evt) override {
|
|
|
|
if (Sample::TitleQ(*evt)) {
|
|
|
|
Sample::TitleR(evt, "AnimatedImage");
|
2018-01-12 16:24:30 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
SkUnichar uni;
|
2018-08-08 15:36:17 +00:00
|
|
|
if (fImage && Sample::CharQ(*evt, &uni)) {
|
2018-01-12 16:24:30 +00:00
|
|
|
switch (uni) {
|
|
|
|
case kPauseKey:
|
2018-01-30 00:35:55 +00:00
|
|
|
fRunning = !fRunning;
|
|
|
|
if (fImage->isFinished()) {
|
|
|
|
// fall through
|
2018-01-12 16:24:30 +00:00
|
|
|
} else {
|
2018-01-30 00:35:55 +00:00
|
|
|
return true;
|
2018-01-12 16:24:30 +00:00
|
|
|
}
|
|
|
|
case kResetKey:
|
|
|
|
fImage->reset();
|
2018-01-30 00:35:55 +00:00
|
|
|
fCurrentTime = fLastWallTime;
|
|
|
|
fTimeToShowNextFrame = fCurrentTime + fImage->currentFrameDuration();
|
2018-01-12 16:24:30 +00:00
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this->INHERITED::onQuery(evt);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
sk_sp<SkAnimatedImage> fImage;
|
|
|
|
sk_sp<SkDrawable> fDrawable;
|
|
|
|
SkScalar fYOffset;
|
2018-01-30 00:35:55 +00:00
|
|
|
bool fRunning = false;
|
|
|
|
double fCurrentTime = 0.0;
|
|
|
|
double fLastWallTime = 0.0;
|
|
|
|
double fTimeToShowNextFrame = 0.0;
|
2018-08-08 15:36:17 +00:00
|
|
|
typedef Sample INHERITED;
|
2018-01-12 16:24:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2018-08-08 15:36:17 +00:00
|
|
|
DEF_SAMPLE( return new SampleAnimatedImage(); )
|