blob: 7816067269b85e6c05584dae49857ab9fd5df6e0 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.6
part of engine;
/// Instantiates a [ui.Codec] backed by an `SkImage` from Skia.
void skiaInstantiateImageCodec(Uint8List list, Callback<ui.Codec> callback,
[int width, int height, int format, int rowBytes]) {
final js.JsObject skAnimatedImage =
canvasKit.callMethod('MakeAnimatedImageFromEncoded', <Uint8List>[list]);
final SkAnimatedImage animatedImage = SkAnimatedImage(skAnimatedImage);
final SkAnimatedImageCodec codec = SkAnimatedImageCodec(animatedImage);
callback(codec);
}
/// A wrapper for `SkAnimatedImage`.
class SkAnimatedImage implements ui.Image {
final js.JsObject _skAnimatedImage;
SkAnimatedImage(this._skAnimatedImage);
@override
void dispose() {
_skAnimatedImage.callMethod('delete');
}
int get frameCount => _skAnimatedImage.callMethod('getFrameCount');
/// Decodes the next frame and returns the frame duration.
Duration decodeNextFrame() {
final int durationMillis = _skAnimatedImage.callMethod('decodeNextFrame');
return Duration(milliseconds: durationMillis);
}
int get repetitionCount => _skAnimatedImage.callMethod('getRepetitionCount');
SkImage get currentFrameAsImage {
final js.JsObject _currentFrame =
_skAnimatedImage.callMethod('getCurrentFrame');
return SkImage(_currentFrame);
}
@override
int get width => _skAnimatedImage.callMethod('width');
@override
int get height => _skAnimatedImage.callMethod('height');
@override
Future<ByteData> toByteData(
{ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba}) {
throw 'unimplemented';
}
}
/// A [ui.Image] backed by an `SkImage` from Skia.
class SkImage implements ui.Image {
js.JsObject skImage;
SkImage(this.skImage);
@override
void dispose() {
skImage.callMethod('delete');
skImage = null;
}
@override
int get width => skImage.callMethod('width');
@override
int get height => skImage.callMethod('height');
@override
Future<ByteData> toByteData(
{ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba}) {
throw 'unimplemented';
}
}
/// A [Codec] that wraps an `SkAnimatedImage`.
class SkAnimatedImageCodec implements ui.Codec {
SkAnimatedImage animatedImage;
SkAnimatedImageCodec(this.animatedImage);
@override
void dispose() {
animatedImage.dispose();
animatedImage = null;
}
@override
int get frameCount => animatedImage.frameCount;
@override
int get repetitionCount => animatedImage.repetitionCount;
@override
Future<ui.FrameInfo> getNextFrame() {
final Duration duration = animatedImage.decodeNextFrame();
final SkImage image = animatedImage.currentFrameAsImage;
return Future<ui.FrameInfo>.value(AnimatedImageFrameInfo(duration, image));
}
}
/// Data for a single frame of an animated image.
class AnimatedImageFrameInfo implements ui.FrameInfo {
final Duration _duration;
final SkImage _image;
AnimatedImageFrameInfo(this._duration, this._image);
@override
Duration get duration => _duration;
@override
ui.Image get image => _image;
}