Flutter Engine
The Flutter Engine
animated_image_orientation.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google LLC
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
8#include "gm/gm.h"
14#include "include/core/SkData.h"
21#include "tools/Resources.h"
22
24 int radius = (bounds.width() + bounds.height()) / 6;
25 SkPathBuilder pathBuilder;
27 .addRRect(SkRRect::MakeRectXY(bounds, radius, radius));
28
30 paint.setAntiAlias(true);
31 paint.setColor(SK_ColorTRANSPARENT);
32 paint.setBlendMode(SkBlendMode::kSrc);
33
34 SkPictureRecorder recorder;
35 auto* canvas = recorder.beginRecording(bounds);
36 canvas->drawPath(pathBuilder.detach(), paint);
37 return recorder.finishRecordingAsPicture();
38}
39
41 const char* fPath;
42 const char* fName;
43 const int fStep;
44 const SkIRect fCropRect;
45 SkISize fSize;
46 int fTranslate;
47 sk_sp<SkData> fData;
48
49 static const int kMaxFrames = 2;
50
51 void init() {
52 if (!fData) {
53 fData = GetResourceAsData(fPath);
54 auto codec = SkCodec::MakeFromData(fData);
55 auto dimensions = codec->dimensions();
56
57 fTranslate = std::max(dimensions.width(), dimensions.height()) // may be rotated
58 * 1.25f // will be scaled up
59 + 2; // padding
60
61 fSize = { fTranslate * kMaxFrames
62 * 2 // crop and no-crop
63 * 2, // post-process and no post-process
64 fTranslate * 4 // 4 scales
65 * 2 }; // makePictureSnapshot and getCurrentFrame
66 }
67 }
68public:
69 AnimatedImageGM(const char* path, const char* name, int step, SkIRect cropRect)
70 : fPath(path)
71 , fName(name)
72 , fStep(step)
73 , fCropRect(cropRect)
74 , fSize{0, 0}
75 , fTranslate(0)
76 {}
77 ~AnimatedImageGM() override = default;
78
79 SkString getName() const override { return SkStringPrintf("%s_animated_image", fName); }
80
81 SkISize getISize() override {
82 this->init();
83 return fSize;
84 }
85
86 void onDraw(SkCanvas* canvas) override {
87 this->init();
88 for (bool usePic : { true, false }) {
89 auto drawProc = [canvas, usePic](const sk_sp<SkAnimatedImage>& animatedImage) {
90 if (usePic) {
91 sk_sp<SkPicture> pic = animatedImage->makePictureSnapshot();
92 canvas->drawPicture(pic);
93 } else {
94 auto image = animatedImage->getCurrentFrame();
95 canvas->drawImage(image, 0, 0);
96 }
97 };
98 for (float scale : { 1.25f, 1.0f, .75f, .5f }) {
99 canvas->save();
100 for (bool doCrop : { false, true }) {
101 for (bool doPostProcess : { false, true }) {
102 auto codec = SkCodec::MakeFromData(fData);
103 const auto origin = codec->getOrigin();
104 auto androidCodec = SkAndroidCodec::MakeFromCodec(std::move(codec));
105 auto info = androidCodec->getInfo();
106 const auto unscaledSize = SkEncodedOriginSwapsWidthHeight(origin)
107 ? SkISize{ info.height(), info.width() } : info.dimensions();
108
109 SkISize scaledSize = { SkScalarFloorToInt(unscaledSize.width() * scale) ,
110 SkScalarFloorToInt(unscaledSize.height() * scale) };
111 info = info.makeDimensions(scaledSize);
112
113 auto cropRect = SkIRect::MakeSize(scaledSize);
114 if (doCrop) {
115 auto matrix = SkMatrix::RectToRect(SkRect::Make(unscaledSize),
116 SkRect::Make(scaledSize));
117 matrix.preConcat(SkEncodedOriginToMatrix(origin,
118 unscaledSize.width(), unscaledSize.height()));
119 SkRect cropRectFloat = SkRect::Make(fCropRect);
120 matrix.mapRect(&cropRectFloat);
121 cropRectFloat.roundOut(&cropRect);
122 }
123
124 sk_sp<SkPicture> postProcessor = doPostProcess
125 ? post_processor(SkRect::Make(cropRect.size())) : nullptr;
126 auto animatedImage = SkAnimatedImage::Make(std::move(androidCodec),
127 info, cropRect, std::move(postProcessor));
128 animatedImage->setRepetitionCount(0);
129
130 for (int frame = 0; frame < kMaxFrames; frame++) {
131 {
132 SkAutoCanvasRestore acr(canvas, doCrop);
133 if (doCrop) {
134 canvas->translate(cropRect.left(), cropRect.top());
135 }
136 drawProc(animatedImage);
137 }
138
139 canvas->translate(fTranslate, 0);
140 const auto duration = animatedImage->currentFrameDuration();
142 break;
143 }
144 for (int i = 0; i < fStep; i++) {
145 animatedImage->decodeNextFrame();
146 }
147 }
148 }
149 }
150 canvas->restore();
151 canvas->translate(0, fTranslate);
152 }
153 }
154 }
155};
156
157DEF_GM( return new AnimatedImageGM("images/stoplight_h.webp", "stoplight", 2,
158 // Deliberately not centered in X or Y, and shows all three
159 // lights, but otherwise arbitrary.
160 SkIRect::MakeLTRB(5, 6, 11, 29)); )
161DEF_GM( return new AnimatedImageGM("images/flightAnim.gif", "flight", 20,
162 // Deliberately starts in the upper left corner to exercise
163 // a special case, but otherwise arbitrary.
164 SkIRect::MakeLTRB(0, 0, 300, 200)); )
SkPath fPath
static int step(int x, SkScalar min, SkScalar max)
Definition: BlurTest.cpp:215
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
const char * fName
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition: Resources.cpp:42
constexpr SkColor SK_ColorTRANSPARENT
Definition: SkColor.h:99
static bool SkEncodedOriginSwapsWidthHeight(SkEncodedOrigin origin)
static SkMatrix SkEncodedOriginToMatrix(SkEncodedOrigin origin, int w, int h)
#define SkScalarFloorToInt(x)
Definition: SkScalar.h:35
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
DEF_GM(return new AnimatedImageGM("images/stoplight_h.webp", "stoplight", 2, SkIRect::MakeLTRB(5, 6, 11, 29));) DEF_GM(return new AnimatedImageGM("images/flightAnim.gif"
static sk_sp< SkPicture > post_processor(const SkRect &bounds)
SkString getName() const override
AnimatedImageGM(const char *path, const char *name, int step, SkIRect cropRect)
SkISize getISize() override
void onDraw(SkCanvas *canvas) override
~AnimatedImageGM() override=default
static std::unique_ptr< SkAndroidCodec > MakeFromCodec(std::unique_ptr< SkCodec >)
static sk_sp< SkAnimatedImage > Make(std::unique_ptr< SkAndroidCodec >, const SkImageInfo &info, SkIRect cropRect, sk_sp< SkPicture > postProcess)
static constexpr int kFinished
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
int save()
Definition: SkCanvas.cpp:447
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
void drawPicture(const SkPicture *picture)
Definition: SkCanvas.h:1961
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
Definition: SkCodec.cpp:241
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
Definition: SkMatrix.h:157
SkPathBuilder & setFillType(SkPathFillType ft)
Definition: SkPathBuilder.h:42
SkPathBuilder & addRRect(const SkRRect &, SkPathDirection, unsigned startIndex)
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition: SkRRect.h:180
Definition: gm.h:110
const Paint & paint
Definition: color_source.cc:38
double duration
Definition: examples.cpp:30
double frame
Definition: examples.cpp:31
static float max(float r, float g, float b)
Definition: hsl.cpp:49
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
Optional< SkRect > bounds
Definition: SkRecords.h:189
sk_sp< const SkImage > image
Definition: SkRecords.h:269
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
const Scalar scale
Definition: SkRect.h:32
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
Definition: SkRect.h:91
static constexpr SkIRect MakeSize(const SkISize &size)
Definition: SkRect.h:66
Definition: SkSize.h:16
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241