blob: 1ca7ac1ef3e2a689ce708a3f8a5b3c1b95616923 [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"
Hal Canary41248072019-07-11 16:32:53 -040017#include "tools/timer/TimeUtils.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 {
Hal Canaryd7639af2019-07-17 09:08:11 -040026 sk_sp<SkAnimatedImage> fImage;
27 sk_sp<SkDrawable> fDrawable;
28 SkScalar fYOffset = 0;
29 bool fRunning = false;
30 double fCurrentTime = 0.0;
31 double fLastWallTime = 0.0;
32 double fTimeToShowNextFrame = 0.0;
Leon Scroggins III7a10b332018-01-12 11:24:30 -050033
Leon Scroggins III7a10b332018-01-12 11:24:30 -050034 void onDrawBackground(SkCanvas* canvas) override {
Mike Reed91919132019-01-02 12:21:01 -050035 SkFont font;
36 font.setSize(20);
Leon Scroggins III7a10b332018-01-12 11:24:30 -050037
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;
Ben Wagner51e15a62019-05-07 15:38:46 -040042 font.measureText(text, strlen(text), SkTextEncoding::kUTF8, &bounds);
Leon Scroggins III7a10b332018-01-12 11:24:30 -050043 fYOffset = bounds.height();
44
Ben Wagner51e15a62019-05-07 15:38:46 -040045 canvas->drawSimpleText(text, strlen(text), SkTextEncoding::kUTF8, 5, fYOffset, font, SkPaint());
Leon Scroggins III7a10b332018-01-12 11:24:30 -050046 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
Hal Canary41248072019-07-11 16:32:53 -040060 bool onAnimate(double nanos) override {
Leon Scroggins III7a10b332018-01-12 11:24:30 -050061 if (!fImage) {
62 return false;
63 }
64
Leon Scroggins III495e0f02018-01-29 19:35:55 -050065 const double lastWallTime = fLastWallTime;
Hal Canary41248072019-07-11 16:32:53 -040066 fLastWallTime = TimeUtils::NanosToMSec(nanos);
Leon Scroggins III495e0f02018-01-29 19:35:55 -050067
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
Hal Canary8a027312019-07-03 10:55:44 -0400100 SkString name() override { return SkString("AnimatedImage"); }
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500101
Hal Canary6cc65e12019-07-03 15:53:04 -0400102 bool onChar(SkUnichar uni) override {
103 if (fImage) {
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;
John Stiles30212b72020-06-11 17:55:07 -0400107 if (!fImage->isFinished()) {
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500108 return true;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500109 }
John Stiles30212b72020-06-11 17:55:07 -0400110 [[fallthrough]];
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500111 case kResetKey:
112 fImage->reset();
Leon Scroggins III495e0f02018-01-29 19:35:55 -0500113 fCurrentTime = fLastWallTime;
114 fTimeToShowNextFrame = fCurrentTime + fImage->currentFrameDuration();
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500115 return true;
116 default:
117 break;
118 }
119 }
Hal Canary6cc65e12019-07-03 15:53:04 -0400120 return false;
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500121 }
Leon Scroggins III7a10b332018-01-12 11:24:30 -0500122};
123
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400124DEF_SAMPLE( return new SampleAnimatedImage(); )