blob: bea601860cdee9dc5aa72a4c228d95032b3d2b03 [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
Leon Scroggins III42ee2842018-01-14 14:46:51 -05008#include "SkAndroidCodec.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -05009#include "SkAnimatedImage.h"
10#include "SkAnimTimer.h"
11#include "SkCanvas.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -050012#include "SkPaint.h"
13#include "SkPictureRecorder.h"
14#include "SkRect.h"
15#include "SkScalar.h"
16#include "SkString.h"
17
18#include "SampleCode.h"
19#include "Resources.h"
20
21static constexpr char kPauseKey = 'p';
22static constexpr char kResetKey = 'r';
23
24class SampleAnimatedImage : public SampleView {
25public:
26 SampleAnimatedImage()
27 : INHERITED()
Leon Scroggins III7a10b332018-01-12 11:24:30 -050028 , fYOffset(0)
29 {}
30
31protected:
32 void onDrawBackground(SkCanvas* canvas) override {
33 SkPaint paint;
34 paint.setAntiAlias(true);
35 constexpr SkScalar kTextSize = 20;
36 paint.setTextSize(kTextSize);
37
38 SkString str = SkStringPrintf("Press '%c' to start/pause; '%c' to reset.",
39 kPauseKey, kResetKey);
40 const char* text = str.c_str();
41 SkRect bounds;
42 paint.measureText(text, strlen(text), &bounds);
43 fYOffset = bounds.height();
44
45 canvas->drawText(text, strlen(text), 5, fYOffset, paint);
46 fYOffset *= 2;
47 }
48
49 void onDrawContent(SkCanvas* canvas) override {
50 if (!fImage) {
51 return;
52 }
53
54 canvas->translate(0, fYOffset);
55
56 canvas->drawDrawable(fImage.get());
57 canvas->drawDrawable(fDrawable.get(), fImage->getBounds().width(), 0);
58 }
59
60 bool onAnimate(const SkAnimTimer& animTimer) override {
61 if (!fImage) {
62 return false;
63 }
64
Leon Scroggins III495e0f02018-01-29 19:35:55 -050065 const double lastWallTime = fLastWallTime;
66 fLastWallTime = animTimer.msec();
67
68 if (fRunning) {
69 fCurrentTime += fLastWallTime - lastWallTime;
70 if (fCurrentTime > fTimeToShowNextFrame) {
71 fTimeToShowNextFrame += fImage->decodeNextFrame();
72 if (fImage->isFinished()) {
73 fRunning = false;
74 }
75 }
76 }
77
Leon Scroggins III7a10b332018-01-12 11:24:30 -050078 return true;
79 }
80
81 void onOnceBeforeDraw() override {
82 sk_sp<SkData> file(GetResourceAsData("images/alphabetAnim.gif"));
83 std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(file));
84 if (!codec) {
85 return;
86 }
87
Leon Scroggins III42ee2842018-01-14 14:46:51 -050088 fImage = SkAnimatedImage::Make(SkAndroidCodec::MakeFromCodec(std::move(codec)));
Leon Scroggins III7a10b332018-01-12 11:24:30 -050089 if (!fImage) {
90 return;
91 }
92
Leon Scroggins III495e0f02018-01-29 19:35:55 -050093 fTimeToShowNextFrame = fImage->currentFrameDuration();
Leon Scroggins III7a10b332018-01-12 11:24:30 -050094 SkPictureRecorder recorder;
95 auto canvas = recorder.beginRecording(fImage->getBounds());
96 canvas->drawDrawable(fImage.get());
97 fDrawable = recorder.finishRecordingAsDrawable();
98 }
99
100 bool onQuery(SkEvent* evt) override {
101 if (SampleCode::TitleQ(*evt)) {
102 SampleCode::TitleR(evt, "AnimatedImage");
103 return true;
104 }
105
106 SkUnichar uni;
107 if (fImage && SampleCode::CharQ(*evt, &uni)) {
108 switch (uni) {
109 case kPauseKey:
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500110 fRunning = !fRunning;
111 if (fImage->isFinished()) {
112 // fall through
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500113 } else {
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500114 return true;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500115 }
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500116 case kResetKey:
117 fImage->reset();
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500118 fCurrentTime = fLastWallTime;
119 fTimeToShowNextFrame = fCurrentTime + fImage->currentFrameDuration();
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500120 return true;
121 default:
122 break;
123 }
124 }
125 return this->INHERITED::onQuery(evt);
126 }
127
128private:
129 sk_sp<SkAnimatedImage> fImage;
130 sk_sp<SkDrawable> fDrawable;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500131 SkScalar fYOffset;
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500132 bool fRunning = false;
133 double fCurrentTime = 0.0;
134 double fLastWallTime = 0.0;
135 double fTimeToShowNextFrame = 0.0;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500136 typedef SampleView INHERITED;
137};
138
139///////////////////////////////////////////////////////////////////////////////
140
141static SkView* MyFactory() {
142 return new SampleAnimatedImage;
143}
144
145static SkViewRegister reg(MyFactory);