blob: 9f66f3adb647c97b09e28ddadcb3751b7845ce18 [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 Kleincd5104e2019-03-20 11:55:08 -05008#include "AnimTimer.h"
Leon Scroggins III42ee2842018-01-14 14:46:51 -05009#include "SkAndroidCodec.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -050010#include "SkAnimatedImage.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -050011#include "SkCanvas.h"
Mike Reed91919132019-01-02 12:21:01 -050012#include "SkFont.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -050013#include "SkPaint.h"
14#include "SkPictureRecorder.h"
15#include "SkRect.h"
16#include "SkScalar.h"
17#include "SkString.h"
18
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040019#include "Sample.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -050020#include "Resources.h"
21
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;
Mike Reed91919132019-01-02 12:21:01 -050041 font.measureText(text, strlen(text), kUTF8_SkTextEncoding, &bounds);
Leon Scroggins III7a10b332018-01-12 11:24:30 -050042 fYOffset = bounds.height();
43
Mike Reed91919132019-01-02 12:21:01 -050044 canvas->drawSimpleText(text, strlen(text), kUTF8_SkTextEncoding, 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
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040099 bool onQuery(Sample::Event* evt) override {
100 if (Sample::TitleQ(*evt)) {
101 Sample::TitleR(evt, "AnimatedImage");
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500102 return true;
103 }
104
105 SkUnichar uni;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400106 if (fImage && Sample::CharQ(*evt, &uni)) {
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500107 switch (uni) {
108 case kPauseKey:
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500109 fRunning = !fRunning;
110 if (fImage->isFinished()) {
111 // fall through
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500112 } else {
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500113 return true;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500114 }
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500115 case kResetKey:
116 fImage->reset();
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500117 fCurrentTime = fLastWallTime;
118 fTimeToShowNextFrame = fCurrentTime + fImage->currentFrameDuration();
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500119 return true;
120 default:
121 break;
122 }
123 }
124 return this->INHERITED::onQuery(evt);
125 }
126
127private:
128 sk_sp<SkAnimatedImage> fImage;
129 sk_sp<SkDrawable> fDrawable;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500130 SkScalar fYOffset;
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500131 bool fRunning = false;
132 double fCurrentTime = 0.0;
133 double fLastWallTime = 0.0;
134 double fTimeToShowNextFrame = 0.0;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400135 typedef Sample INHERITED;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500136};
137
138///////////////////////////////////////////////////////////////////////////////
139
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400140DEF_SAMPLE( return new SampleAnimatedImage(); )