skia2/samplecode/SampleAnimatedImage.cpp
Leon Scroggins III 4c11945a97 Respect repetition count in SkAnimatedImage
Bug: b/63908092

By default use the repetition count stored in the encoded data (if
any). Allow setting the repetition count manually, so that the
animation will stop after n+1 total cycles (unless -1 is used for
infinite).

If the animation is complete, make start reset it.

When the animation is not running, make update return max double (i.e.
no need to update any time soon).

Fix a bug where the first call to update returned -1.

Share write_bm with CodecAnimTest, for debugging.

Update Sample to check isRunning rather than keeping its own record
of whether the animation is running.

Change-Id: I883e4d7325f7a7b23a422fa9d756f9ea3018f0f8
Reviewed-on: https://skia-review.googlesource.com/97082
Reviewed-by: Derek Sollenberger <djsollen@google.com>
Commit-Queue: Leon Scroggins <scroggo@google.com>
2018-01-22 18:53:47 +00:00

127 lines
3.3 KiB
C++

/*
* Copyright 2018 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkAndroidCodec.h"
#include "SkAnimatedImage.h"
#include "SkAnimTimer.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkPictureRecorder.h"
#include "SkRect.h"
#include "SkScalar.h"
#include "SkString.h"
#include "SampleCode.h"
#include "Resources.h"
static constexpr char kPauseKey = 'p';
static constexpr char kResetKey = 'r';
class SampleAnimatedImage : public SampleView {
public:
SampleAnimatedImage()
: INHERITED()
, fYOffset(0)
{}
protected:
void onDrawBackground(SkCanvas* canvas) override {
SkPaint paint;
paint.setAntiAlias(true);
constexpr SkScalar kTextSize = 20;
paint.setTextSize(kTextSize);
SkString str = SkStringPrintf("Press '%c' to start/pause; '%c' to reset.",
kPauseKey, kResetKey);
const char* text = str.c_str();
SkRect bounds;
paint.measureText(text, strlen(text), &bounds);
fYOffset = bounds.height();
canvas->drawText(text, strlen(text), 5, fYOffset, paint);
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;
}
fImage->update(animTimer.msec());
return true;
}
void onOnceBeforeDraw() override {
sk_sp<SkData> file(GetResourceAsData("images/alphabetAnim.gif"));
std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(file));
if (!codec) {
return;
}
fImage = SkAnimatedImage::Make(SkAndroidCodec::MakeFromCodec(std::move(codec)));
if (!fImage) {
return;
}
SkPictureRecorder recorder;
auto canvas = recorder.beginRecording(fImage->getBounds());
canvas->drawDrawable(fImage.get());
fDrawable = recorder.finishRecordingAsDrawable();
}
bool onQuery(SkEvent* evt) override {
if (SampleCode::TitleQ(*evt)) {
SampleCode::TitleR(evt, "AnimatedImage");
return true;
}
SkUnichar uni;
if (fImage && SampleCode::CharQ(*evt, &uni)) {
switch (uni) {
case kPauseKey:
if (fImage->isRunning()) {
fImage->stop();
} else {
fImage->start();
}
return true;
case kResetKey:
fImage->reset();
return true;
default:
break;
}
}
return this->INHERITED::onQuery(evt);
}
private:
sk_sp<SkAnimatedImage> fImage;
sk_sp<SkDrawable> fDrawable;
SkScalar fYOffset;
typedef SampleView INHERITED;
};
///////////////////////////////////////////////////////////////////////////////
static SkView* MyFactory() {
return new SampleAnimatedImage;
}
static SkViewRegister reg(MyFactory);