blob: 647ae26ec1c663b9f5260ba678dd353dba5fd31e [file] [log] [blame]
Leon Scroggins III7a10b332018-01-12 11:24:30 -05001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "include/android/SkAnimatedImage.h"
9#include "include/codec/SkAndroidCodec.h"
10#include "include/core/SkCanvas.h"
11#include "include/core/SkFont.h"
12#include "include/core/SkPaint.h"
13#include "include/core/SkPictureRecorder.h"
14#include "include/core/SkRect.h"
15#include "include/core/SkScalar.h"
16#include "include/core/SkString.h"
17#include "tools/timer/AnimTimer.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -050018
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "samplecode/Sample.h"
20#include "tools/Resources.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -050021
22static constexpr char kPauseKey = 'p';
23static constexpr char kResetKey = 'r';
24
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040025class SampleAnimatedImage : public Sample {
Leon Scroggins III7a10b332018-01-12 11:24:30 -050026public:
27 SampleAnimatedImage()
28 : INHERITED()
Leon Scroggins III7a10b332018-01-12 11:24:30 -050029 , fYOffset(0)
30 {}
31
32protected:
33 void onDrawBackground(SkCanvas* canvas) override {
Mike Reed91919132019-01-02 12:21:01 -050034 SkFont font;
35 font.setSize(20);
Leon Scroggins III7a10b332018-01-12 11:24:30 -050036
37 SkString str = SkStringPrintf("Press '%c' to start/pause; '%c' to reset.",
38 kPauseKey, kResetKey);
39 const char* text = str.c_str();
40 SkRect bounds;
Ben Wagner51e15a62019-05-07 15:38:46 -040041 font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
Leon Scroggins III7a10b332018-01-12 11:24:30 -050042 fYOffset = bounds.height();
43
Ben Wagner51e15a62019-05-07 15:38:46 -040044 canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, 5, fYOffset, font, SkPaint());
Leon Scroggins III7a10b332018-01-12 11:24:30 -050045 fYOffset *= 2;
46 }
47
48 void onDrawContent(SkCanvas* canvas) override {
49 if (!fImage) {
50 return;
51 }
52
53 canvas->translate(0, fYOffset);
54
55 canvas->drawDrawable(fImage.get());
56 canvas->drawDrawable(fDrawable.get(), fImage->getBounds().width(), 0);
57 }
58
Mike Kleincd5104e2019-03-20 11:55:08 -050059 bool onAnimate(const AnimTimer& animTimer) override {
Leon Scroggins III7a10b332018-01-12 11:24:30 -050060 if (!fImage) {
61 return false;
62 }
63
Leon Scroggins III495e0f02018-01-29 19:35:55 -050064 const double lastWallTime = fLastWallTime;
65 fLastWallTime = animTimer.msec();
66
67 if (fRunning) {
68 fCurrentTime += fLastWallTime - lastWallTime;
69 if (fCurrentTime > fTimeToShowNextFrame) {
70 fTimeToShowNextFrame += fImage->decodeNextFrame();
71 if (fImage->isFinished()) {
72 fRunning = false;
73 }
74 }
75 }
76
Leon Scroggins III7a10b332018-01-12 11:24:30 -050077 return true;
78 }
79
80 void onOnceBeforeDraw() override {
81 sk_sp<SkData> file(GetResourceAsData("images/alphabetAnim.gif"));
82 std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(file));
83 if (!codec) {
84 return;
85 }
86
Leon Scroggins III42ee2842018-01-14 14:46:51 -050087 fImage = SkAnimatedImage::Make(SkAndroidCodec::MakeFromCodec(std::move(codec)));
Leon Scroggins III7a10b332018-01-12 11:24:30 -050088 if (!fImage) {
89 return;
90 }
91
Leon Scroggins III495e0f02018-01-29 19:35:55 -050092 fTimeToShowNextFrame = fImage->currentFrameDuration();
Leon Scroggins III7a10b332018-01-12 11:24:30 -050093 SkPictureRecorder recorder;
94 auto canvas = recorder.beginRecording(fImage->getBounds());
95 canvas->drawDrawable(fImage.get());
96 fDrawable = recorder.finishRecordingAsDrawable();
97 }
98
Hal Canary8a027312019-07-03 10:55:44 -040099 SkString name() override { return SkString("AnimatedImage"); }
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500100
Hal Canary8a027312019-07-03 10:55:44 -0400101 bool onQuery(Sample::Event* evt) override {
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500102 SkUnichar uni;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400103 if (fImage && Sample::CharQ(*evt, &uni)) {
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500104 switch (uni) {
105 case kPauseKey:
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500106 fRunning = !fRunning;
107 if (fImage->isFinished()) {
108 // fall through
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500109 } else {
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500110 return true;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500111 }
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500112 case kResetKey:
113 fImage->reset();
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500114 fCurrentTime = fLastWallTime;
115 fTimeToShowNextFrame = fCurrentTime + fImage->currentFrameDuration();
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500116 return true;
117 default:
118 break;
119 }
120 }
121 return this->INHERITED::onQuery(evt);
122 }
123
124private:
125 sk_sp<SkAnimatedImage> fImage;
126 sk_sp<SkDrawable> fDrawable;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500127 SkScalar fYOffset;
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500128 bool fRunning = false;
129 double fCurrentTime = 0.0;
130 double fLastWallTime = 0.0;
131 double fTimeToShowNextFrame = 0.0;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400132 typedef Sample INHERITED;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500133};
134
135///////////////////////////////////////////////////////////////////////////////
136
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400137DEF_SAMPLE( return new SampleAnimatedImage(); )