blob: 0d9adad81eef3df8504f7a6635a29415eb9d04c1 [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
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040018#include "Sample.h"
Leon Scroggins III7a10b332018-01-12 11:24:30 -050019#include "Resources.h"
20
21static constexpr char kPauseKey = 'p';
22static constexpr char kResetKey = 'r';
23
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040024class SampleAnimatedImage : public Sample {
Leon Scroggins III7a10b332018-01-12 11:24:30 -050025public:
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
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400100 bool onQuery(Sample::Event* evt) override {
101 if (Sample::TitleQ(*evt)) {
102 Sample::TitleR(evt, "AnimatedImage");
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500103 return true;
104 }
105
106 SkUnichar uni;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400107 if (fImage && Sample::CharQ(*evt, &uni)) {
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500108 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;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400136 typedef Sample INHERITED;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500137};
138
139///////////////////////////////////////////////////////////////////////////////
140
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400141DEF_SAMPLE( return new SampleAnimatedImage(); )