Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
27e91231
Unverified
Commit
27e91231
authored
Jul 26, 2023
by
Ian Hickson
Committed by
GitHub
Jul 26, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "ImageDecoration.lerp" (#131347)
Reverts flutter/flutter#130533 Tree breakage.
parent
bae1ac2f
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
59 additions
and
612 deletions
+59
-612
analysis_options.yaml
analysis_options.yaml
+1
-1
foundation.dart
packages/flutter/lib/foundation.dart
+1
-0
README.md
packages/flutter/lib/src/foundation/README.md
+5
-4
binding.dart
packages/flutter/lib/src/foundation/binding.dart
+1
-1
diagnostics.dart
packages/flutter/lib/src/foundation/diagnostics.dart
+1
-1
math.dart
packages/flutter/lib/src/foundation/math.dart
+23
-0
dialog.dart
packages/flutter/lib/src/material/dialog.dart
+2
-1
box_decoration.dart
packages/flutter/lib/src/painting/box_decoration.dart
+2
-2
decoration_image.dart
packages/flutter/lib/src/painting/decoration_image.dart
+22
-161
shape_decoration.dart
packages/flutter/lib/src/painting/shape_decoration.dart
+1
-1
decoration_image_lerp_test.dart
...ges/flutter/test/painting/decoration_image_lerp_test.dart
+0
-440
No files found.
analysis_options.yaml
View file @
27e91231
...
...
@@ -50,7 +50,7 @@ linter:
-
avoid_field_initializers_in_const_classes
# - avoid_final_parameters # incompatible with prefer_final_parameters
-
avoid_function_literals_in_foreach_calls
# - avoid_implementing_value_types # see https://github.com/dart-lang/linter/issues/4558
-
avoid_implementing_value_types
-
avoid_init_to_null
-
avoid_js_rounded_ints
# - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to
...
...
packages/flutter/lib/foundation.dart
View file @
27e91231
...
...
@@ -34,6 +34,7 @@ export 'src/foundation/diagnostics.dart';
export
'src/foundation/isolates.dart'
;
export
'src/foundation/key.dart'
;
export
'src/foundation/licenses.dart'
;
export
'src/foundation/math.dart'
;
export
'src/foundation/memory_allocations.dart'
;
export
'src/foundation/node.dart'
;
export
'src/foundation/object.dart'
;
...
...
packages/flutter/lib/src/foundation/README.md
View file @
27e91231
...
...
@@ -3,9 +3,9 @@ nothing but core Dart packages. They can't depend on `dart:ui`, they
can't depend on any
`package:`
, and they can't depend on anything
outside this directory.
Currently they do depend on dart:ui, but only for
`VoidCallback`
and
`clampDouble`
(and maybe one day
`lerpDouble`
), which are all intended
to be moved out
of
`dart:ui`
and into
`dart:core`
.
Currently they do depend on dart:ui, but only for
`VoidCallback`
(
and
maybe one day
`lerpDouble`
), which are all intended to be moved out
of
`dart:ui`
and into
`dart:core`
.
There is currently also an unfortunate dependency on the platform
dispatcher logic (SingletonFlutterWindow, Brightness,
...
...
@@ -14,4 +14,5 @@ PlatformDispatcher, window), though that should probably move to the
See also:
*
https://github.com/dart-lang/sdk/issues/25217
*
https://github.com/dart-lang/sdk/issues/27791 (
`VoidCallback`
)
*
https://github.com/dart-lang/sdk/issues/25217 (
`hashValues`
,
`hashList`
, and
`lerpDouble`
)
packages/flutter/lib/src/foundation/binding.dart
View file @
27e91231
...
...
@@ -22,7 +22,7 @@ import 'print.dart';
import
'service_extensions.dart'
;
import
'timeline.dart'
;
export
'dart:ui'
show
PlatformDispatcher
,
SingletonFlutterWindow
,
clampDouble
;
// ignore: deprecated_member_use
export
'dart:ui'
show
PlatformDispatcher
,
SingletonFlutterWindow
;
// ignore: deprecated_member_use
export
'basic_types.dart'
show
AsyncCallback
,
AsyncValueGetter
,
AsyncValueSetter
;
...
...
packages/flutter/lib/src/foundation/diagnostics.dart
View file @
27e91231
...
...
@@ -3,13 +3,13 @@
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'dart:ui'
show
clampDouble
;
import
'package:meta/meta.dart'
;
import
'assertions.dart'
;
import
'constants.dart'
;
import
'debug.dart'
;
import
'math.dart'
show
clampDouble
;
import
'object.dart'
;
// Examples can assume:
...
...
packages/flutter/lib/src/foundation/math.dart
0 → 100644
View file @
27e91231
// Copyright 2014 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.
/// Same as [num.clamp] but optimized for non-null [double].
///
/// This is faster because it avoids polymorphism, boxing, and special cases for
/// floating point numbers.
//
// See also: //dev/benchmarks/microbenchmarks/lib/foundation/clamp.dart
double
clampDouble
(
double
x
,
double
min
,
double
max
)
{
assert
(
min
<=
max
&&
!
max
.
isNaN
&&
!
min
.
isNaN
);
if
(
x
<
min
)
{
return
min
;
}
if
(
x
>
max
)
{
return
max
;
}
if
(
x
.
isNaN
)
{
return
max
;
}
return
x
;
}
packages/flutter/lib/src/material/dialog.dart
View file @
27e91231
...
...
@@ -2,9 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:ui'
show
clampDouble
,
lerpDouble
;
import
'dart:ui'
;
import
'package:flutter/cupertino.dart'
;
import
'package:flutter/foundation.dart'
show
clampDouble
;
import
'color_scheme.dart'
;
import
'colors.dart'
;
...
...
packages/flutter/lib/src/painting/box_decoration.dart
View file @
27e91231
...
...
@@ -232,7 +232,7 @@ class BoxDecoration extends Decoration {
BoxDecoration
scale
(
double
factor
)
{
return
BoxDecoration
(
color:
Color
.
lerp
(
null
,
color
,
factor
),
image:
DecorationImage
.
lerp
(
null
,
image
,
factor
),
image:
image
,
// TODO(ianh): fade the image from transparent
border:
BoxBorder
.
lerp
(
null
,
border
,
factor
),
borderRadius:
BorderRadiusGeometry
.
lerp
(
null
,
borderRadius
,
factor
),
boxShadow:
BoxShadow
.
lerpList
(
null
,
boxShadow
,
factor
),
...
...
@@ -307,7 +307,7 @@ class BoxDecoration extends Decoration {
}
return
BoxDecoration
(
color:
Color
.
lerp
(
a
.
color
,
b
.
color
,
t
),
image:
DecorationImage
.
lerp
(
a
.
image
,
b
.
image
,
t
),
image:
t
<
0.5
?
a
.
image
:
b
.
image
,
// TODO(ianh): cross-fade the image
border:
BoxBorder
.
lerp
(
a
.
border
,
b
.
border
,
t
),
borderRadius:
BorderRadiusGeometry
.
lerp
(
a
.
borderRadius
,
b
.
borderRadius
,
t
),
boxShadow:
BoxShadow
.
lerpList
(
a
.
boxShadow
,
b
.
boxShadow
,
t
),
...
...
packages/flutter/lib/src/painting/decoration_image.dart
View file @
27e91231
...
...
@@ -177,7 +177,7 @@ class DecorationImage {
/// image needs to be repainted, e.g. because it is loading incrementally or
/// because it is animated.
DecorationImagePainter
createPainter
(
VoidCallback
onChanged
)
{
return
_
DecorationImagePainter
.
_
(
this
,
onChanged
);
return
DecorationImagePainter
.
_
(
this
,
onChanged
);
}
@override
...
...
@@ -246,28 +246,6 @@ class DecorationImage {
];
return
'
${objectRuntimeType(this, 'DecorationImage')}
(
${properties.join(", ")}
)'
;
}
/// Linearly interpolates between two [DecorationImage]s.
///
/// The `t` argument represents position on the timeline, with 0.0 meaning
/// that the interpolation has not started, returning `a`, 1.0 meaning that
/// the interpolation has finished, returning `b`, and values in between
/// meaning that the interpolation is at the relevant point on the timeline
/// between `a` and `this`. The interpolation can be extrapolated beyond 0.0
/// and 1.0, so negative values and values greater than 1.0 are valid (and can
/// easily be generated by curves such as [Curves.elasticInOut]).
///
/// Values for `t` are usually obtained from an [Animation<double>], such as
/// an [AnimationController].
static
DecorationImage
?
lerp
(
DecorationImage
?
a
,
DecorationImage
?
b
,
double
t
)
{
if
(
identical
(
a
,
b
)
||
t
==
0.0
)
{
return
a
;
}
if
(
t
==
1.0
)
{
return
b
;
}
return
_BlendedDecorationImage
(
a
,
b
,
t
);
}
}
/// The painter for a [DecorationImage].
...
...
@@ -281,7 +259,15 @@ class DecorationImage {
///
/// This object should be disposed using the [dispose] method when it is no
/// longer needed.
abstract
interface
class
DecorationImagePainter
{
class
DecorationImagePainter
{
DecorationImagePainter
.
_
(
this
.
_details
,
this
.
_onChanged
);
final
DecorationImage
_details
;
final
VoidCallback
_onChanged
;
ImageStream
?
_imageStream
;
ImageInfo
?
_image
;
/// Draw the image onto the given canvas.
///
/// The image is drawn at the position and size given by the `rect` argument.
...
...
@@ -296,34 +282,8 @@ abstract interface class DecorationImagePainter {
/// because it had not yet been loaded the first time this method was called,
/// then the `onChanged` callback passed to [DecorationImage.createPainter]
/// will be called.
///
/// The `blend` argument specifies the opacity that should be applied to the
/// image due to this image being blended with another. The `blendMode`
/// argument can be specified to override the [DecorationImagePainter]'s
/// default [BlendMode] behavior. It is usually set to [BlendMode.srcOver] if
/// this is the first or only image being blended, and [BlendMode.plus] if it
/// is being blended with an image below.
void
paint
(
Canvas
canvas
,
Rect
rect
,
Path
?
clipPath
,
ImageConfiguration
configuration
,
{
double
blend
=
1.0
,
BlendMode
blendMode
=
BlendMode
.
srcOver
});
void
paint
(
Canvas
canvas
,
Rect
rect
,
Path
?
clipPath
,
ImageConfiguration
configuration
)
{
/// Releases the resources used by this painter.
///
/// This should be called whenever the painter is no longer needed.
///
/// After this method has been called, the object is no longer usable.
void
dispose
();
}
class
_DecorationImagePainter
implements
DecorationImagePainter
{
_DecorationImagePainter
.
_
(
this
.
_details
,
this
.
_onChanged
);
final
DecorationImage
_details
;
final
VoidCallback
_onChanged
;
ImageStream
?
_imageStream
;
ImageInfo
?
_image
;
@override
void
paint
(
Canvas
canvas
,
Rect
rect
,
Path
?
clipPath
,
ImageConfiguration
configuration
,
{
double
blend
=
1.0
,
BlendMode
blendMode
=
BlendMode
.
srcOver
})
{
bool
flipHorizontally
=
false
;
if
(
_details
.
matchTextDirection
)
{
assert
(()
{
...
...
@@ -378,11 +338,10 @@ class _DecorationImagePainter implements DecorationImagePainter {
centerSlice:
_details
.
centerSlice
,
repeat:
_details
.
repeat
,
flipHorizontally:
flipHorizontally
,
opacity:
_details
.
opacity
*
blend
,
opacity:
_details
.
opacity
,
filterQuality:
_details
.
filterQuality
,
invertColors:
_details
.
invertColors
,
isAntiAlias:
_details
.
isAntiAlias
,
blendMode:
blendMode
,
);
if
(
clipPath
!=
null
)
{
...
...
@@ -405,7 +364,12 @@ class _DecorationImagePainter implements DecorationImagePainter {
}
}
@override
/// Releases the resources used by this painter.
///
/// This should be called whenever the painter is no longer needed.
///
/// After this method has been called, the object is no longer usable.
@mustCallSuper
void
dispose
()
{
_imageStream
?.
removeListener
(
ImageStreamListener
(
_handleImage
,
...
...
@@ -480,7 +444,7 @@ void debugFlushLastFrameImageSizeInfo() {
/// corners of the destination rectangle defined by applying `fit`. The
/// remaining five regions are drawn by stretching them to fit such that they
/// exactly cover the destination rectangle while maintaining their relative
/// positions.
See also [Canvas.drawImageNine].
/// positions.
///
/// * `repeat`: If the image does not fill `rect`, whether and how the image
/// should be repeated to fill `rect`. By default, the image is not repeated.
...
...
@@ -526,7 +490,6 @@ void paintImage({
bool
invertColors
=
false
,
FilterQuality
filterQuality
=
FilterQuality
.
low
,
bool
isAntiAlias
=
false
,
BlendMode
blendMode
=
BlendMode
.
srcOver
,
})
{
assert
(
image
.
debugGetOpenHandleStackTraces
()?.
isNotEmpty
??
true
,
...
...
@@ -567,10 +530,9 @@ void paintImage({
if
(
colorFilter
!=
null
)
{
paint
.
colorFilter
=
colorFilter
;
}
paint
.
color
=
Color
.
fromRGBO
(
0
,
0
,
0
,
clampDouble
(
opacity
,
0.0
,
1.0
)
);
paint
.
color
=
Color
.
fromRGBO
(
0
,
0
,
0
,
opacity
);
paint
.
filterQuality
=
filterQuality
;
paint
.
invertColors
=
invertColors
;
paint
.
blendMode
=
blendMode
;
final
double
halfWidthDelta
=
(
outputSize
.
width
-
destinationSize
.
width
)
/
2.0
;
final
double
halfHeightDelta
=
(
outputSize
.
height
-
destinationSize
.
height
)
/
2.0
;
final
double
dx
=
halfWidthDelta
+
(
flipHorizontally
?
-
alignment
.
x
:
alignment
.
x
)
*
halfWidthDelta
;
...
...
@@ -581,12 +543,6 @@ void paintImage({
// Set to true if we added a saveLayer to the canvas to invert/flip the image.
bool
invertedCanvas
=
false
;
// Output size and destination rect are fully calculated.
// Implement debug-mode and profile-mode features:
// - cacheWidth/cacheHeight warning
// - debugInvertOversizedImages
// - debugOnPaintImage
// - Flutter.ImageSizesForFrame events in timeline
if
(!
kReleaseMode
)
{
// We can use the devicePixelRatio of the views directly here (instead of
// going through a MediaQuery) because if it changes, whatever is aware of
...
...
@@ -598,6 +554,7 @@ void paintImage({
0.0
,
(
double
previousValue
,
ui
.
FlutterView
view
)
=>
math
.
max
(
previousValue
,
view
.
devicePixelRatio
),
);
final
ImageSizeInfo
sizeInfo
=
ImageSizeInfo
(
// Some ImageProvider implementations may not have given this.
source
:
debugImageLabel
??
'<Unknown Image(
${image.width}
×
${image.height}
)>'
,
...
...
@@ -642,7 +599,7 @@ void paintImage({
return
true
;
}());
// Avoid emitting events that are the same as those emitted in the last frame.
if
(!
_lastFrameImageSizeInfo
.
contains
(
sizeInfo
))
{
if
(!
kReleaseMode
&&
!
_lastFrameImageSizeInfo
.
contains
(
sizeInfo
))
{
final
ImageSizeInfo
?
existingSizeInfo
=
_pendingImageSizeInfo
[
sizeInfo
.
source
];
if
(
existingSizeInfo
==
null
||
existingSizeInfo
.
displaySizeInBytes
<
sizeInfo
.
displaySizeInBytes
)
{
_pendingImageSizeInfo
[
sizeInfo
.
source
!]
=
sizeInfo
;
...
...
@@ -734,99 +691,3 @@ Iterable<Rect> _generateImageTileRects(Rect outputRect, Rect fundamentalRect, Im
}
Rect
_scaleRect
(
Rect
rect
,
double
scale
)
=>
Rect
.
fromLTRB
(
rect
.
left
*
scale
,
rect
.
top
*
scale
,
rect
.
right
*
scale
,
rect
.
bottom
*
scale
);
// Implements DecorationImage.lerp when the image is different.
//
// This class just paints both decorations on top of each other, blended together.
//
// The Decoration properties are faked by just forwarded to the target image.
class
_BlendedDecorationImage
implements
DecorationImage
{
const
_BlendedDecorationImage
(
this
.
a
,
this
.
b
,
this
.
t
)
:
assert
(
a
!=
null
||
b
!=
null
);
final
DecorationImage
?
a
;
final
DecorationImage
?
b
;
final
double
t
;
@override
ImageProvider
get
image
=>
b
?.
image
??
a
!.
image
;
@override
ImageErrorListener
?
get
onError
=>
b
?.
onError
??
a
!.
onError
;
@override
ColorFilter
?
get
colorFilter
=>
b
?.
colorFilter
??
a
!.
colorFilter
;
@override
BoxFit
?
get
fit
=>
b
?.
fit
??
a
!.
fit
;
@override
AlignmentGeometry
get
alignment
=>
b
?.
alignment
??
a
!.
alignment
;
@override
Rect
?
get
centerSlice
=>
b
?.
centerSlice
??
a
!.
centerSlice
;
@override
ImageRepeat
get
repeat
=>
b
?.
repeat
??
a
!.
repeat
;
@override
bool
get
matchTextDirection
=>
b
?.
matchTextDirection
??
a
!.
matchTextDirection
;
@override
double
get
scale
=>
b
?.
scale
??
a
!.
scale
;
@override
double
get
opacity
=>
b
?.
opacity
??
a
!.
opacity
;
@override
FilterQuality
get
filterQuality
=>
b
?.
filterQuality
??
a
!.
filterQuality
;
@override
bool
get
invertColors
=>
b
?.
invertColors
??
a
!.
invertColors
;
@override
bool
get
isAntiAlias
=>
b
?.
isAntiAlias
??
a
!.
isAntiAlias
;
@override
DecorationImagePainter
createPainter
(
VoidCallback
onChanged
)
{
return
_BlendedDecorationImagePainter
.
_
(
a
?.
createPainter
(
onChanged
),
b
?.
createPainter
(
onChanged
),
t
,
);
}
@override
bool
operator
==(
Object
other
)
{
if
(
identical
(
this
,
other
))
{
return
true
;
}
if
(
other
.
runtimeType
!=
runtimeType
)
{
return
false
;
}
return
other
is
_BlendedDecorationImage
&&
other
.
a
==
a
&&
other
.
b
==
b
&&
other
.
t
==
t
;
}
@override
int
get
hashCode
=>
Object
.
hash
(
a
,
b
,
t
);
@override
String
toString
()
{
return
'
${objectRuntimeType(this, '_BlendedDecorationImage')}
(
$a
,
$b
,
$t
)'
;
}
}
class
_BlendedDecorationImagePainter
implements
DecorationImagePainter
{
_BlendedDecorationImagePainter
.
_
(
this
.
a
,
this
.
b
,
this
.
t
);
final
DecorationImagePainter
?
a
;
final
DecorationImagePainter
?
b
;
final
double
t
;
@override
void
paint
(
Canvas
canvas
,
Rect
rect
,
Path
?
clipPath
,
ImageConfiguration
configuration
,
{
double
blend
=
1.0
,
BlendMode
blendMode
=
BlendMode
.
srcOver
})
{
a
?.
paint
(
canvas
,
rect
,
clipPath
,
configuration
,
blend:
blend
*
(
1.0
-
t
),
blendMode:
blendMode
);
b
?.
paint
(
canvas
,
rect
,
clipPath
,
configuration
,
blend:
blend
*
t
,
blendMode:
a
!=
null
?
BlendMode
.
plus
:
blendMode
);
}
@override
void
dispose
()
{
a
?.
dispose
();
b
?.
dispose
();
}
@override
String
toString
()
{
return
'
${objectRuntimeType(this, '_BlendedDecorationImagePainter')}
(
$a
,
$b
,
$t
)'
;
}
}
packages/flutter/lib/src/painting/shape_decoration.dart
View file @
27e91231
...
...
@@ -237,7 +237,7 @@ class ShapeDecoration extends Decoration {
return
ShapeDecoration
(
color:
Color
.
lerp
(
a
?.
color
,
b
?.
color
,
t
),
gradient:
Gradient
.
lerp
(
a
?.
gradient
,
b
?.
gradient
,
t
),
image:
DecorationImage
.
lerp
(
a
?.
image
,
b
?.
image
,
t
),
image:
t
<
0.5
?
a
?.
image
:
b
?.
image
,
// TODO(ianh): cross-fade the image
shadows:
BoxShadow
.
lerpList
(
a
?.
shadows
,
b
?.
shadows
,
t
),
shape:
ShapeBorder
.
lerp
(
a
?.
shape
,
b
?.
shape
,
t
)!,
);
...
...
packages/flutter/test/painting/decoration_image_lerp_test.dart
deleted
100644 → 0
View file @
bae1ac2f
// Copyright 2014 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.
// This file is run as part of a reduced test set in CI on Mac and Windows
// machines because it contains golden tests; see:
// https://github.com/flutter/flutter/wiki/Writing-a-golden-file-test-for-package:flutter#reduced-test-set-tag
@Tags
(<
String
>[
'reduced-test-set'
])
library
;
import
'dart:async'
;
import
'dart:ui'
as
ui
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
void
main
(
)
{
testWidgets
(
'ImageDecoration.lerp'
,
(
WidgetTester
tester
)
async
{
final
MemoryImage
green
=
MemoryImage
(
Uint8List
.
fromList
(<
int
>[
0x89
,
0x50
,
0x4e
,
0x47
,
0x0d
,
0x0a
,
0x1a
,
0x0a
,
0x00
,
0x00
,
0x00
,
0x0d
,
0x49
,
0x48
,
0x44
,
0x52
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x01
,
0x01
,
0x03
,
0x00
,
0x00
,
0x00
,
0x25
,
0xdb
,
0x56
,
0xca
,
0x00
,
0x00
,
0x00
,
0x03
,
0x50
,
0x4c
,
0x54
,
0x45
,
0x00
,
0xff
,
0x00
,
0x34
,
0x5e
,
0xc0
,
0xa8
,
0x00
,
0x00
,
0x00
,
0x0a
,
0x49
,
0x44
,
0x41
,
0x54
,
0x08
,
0xd7
,
0x63
,
0x60
,
0x00
,
0x00
,
0x00
,
0x02
,
0x00
,
0x01
,
0xe2
,
0x21
,
0xbc
,
0x33
,
0x00
,
0x00
,
0x00
,
0x00
,
0x49
,
0x45
,
0x4e
,
0x44
,
0xae
,
0x42
,
0x60
,
0x82
,
]));
final
MemoryImage
red
=
MemoryImage
(
Uint8List
.
fromList
(<
int
>[
0x89
,
0x50
,
0x4e
,
0x47
,
0x0d
,
0x0a
,
0x1a
,
0x0a
,
0x00
,
0x00
,
0x00
,
0x0d
,
0x49
,
0x48
,
0x44
,
0x52
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x01
,
0x01
,
0x03
,
0x00
,
0x00
,
0x00
,
0x25
,
0xdb
,
0x56
,
0xca
,
0x00
,
0x00
,
0x00
,
0x03
,
0x50
,
0x4c
,
0x54
,
0x45
,
0xff
,
0x00
,
0x00
,
0x19
,
0xe2
,
0x09
,
0x37
,
0x00
,
0x00
,
0x00
,
0x0a
,
0x49
,
0x44
,
0x41
,
0x54
,
0x08
,
0xd7
,
0x63
,
0x60
,
0x00
,
0x00
,
0x00
,
0x02
,
0x00
,
0x01
,
0xe2
,
0x21
,
0xbc
,
0x33
,
0x00
,
0x00
,
0x00
,
0x00
,
0x49
,
0x45
,
0x4e
,
0x44
,
0xae
,
0x42
,
0x60
,
0x82
,
]));
await
tester
.
runAsync
(()
async
{
await
load
(
green
);
await
load
(
red
);
});
await
tester
.
pumpWidget
(
ColoredBox
(
color:
Colors
.
white
,
child:
Align
(
alignment:
Alignment
.
topLeft
,
child:
RepaintBoundary
(
child:
Wrap
(
textDirection:
TextDirection
.
ltr
,
children:
<
Widget
>[
TestImage
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
)
),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
red
,
repeat:
ImageRepeat
.
repeat
),
0.0
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
red
,
repeat:
ImageRepeat
.
repeat
),
0.1
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
red
,
repeat:
ImageRepeat
.
repeat
),
0.2
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
red
,
repeat:
ImageRepeat
.
repeat
),
0.5
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
red
,
repeat:
ImageRepeat
.
repeat
),
0.8
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
red
,
repeat:
ImageRepeat
.
repeat
),
0.9
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
red
,
repeat:
ImageRepeat
.
repeat
),
1.0
,
)),
TestImage
(
DecorationImage
(
image:
red
,
repeat:
ImageRepeat
.
repeat
),
),
for
(
double
t
=
0.0
;
t
<
1.0
;
t
+=
0.125
)
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
t
,
),
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
t
,
),
t
,
)),
for
(
double
t
=
0.0
;
t
<
1.0
;
t
+=
0.125
)
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
1.0
-
t
,
),
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
t
,
),
t
,
)),
for
(
double
t
=
0.0
;
t
<
1.0
;
t
+=
0.125
)
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
t
,
),
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
1.0
-
t
,
),
t
,
)),
for
(
double
t
=
0.0
;
t
<
1.0
;
t
+=
0.125
)
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
1.0
-
t
,
),
DecorationImage
.
lerp
(
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
green
,
repeat:
ImageRepeat
.
repeat
),
1.0
-
t
,
),
t
,
)),
],
),
),
),
),
);
await
expectLater
(
find
.
byType
(
Wrap
),
matchesGoldenFile
(
'decoration_image.lerp.0.png'
),
);
if
(!
kIsWeb
)
{
// TODO(ianh): https://github.com/flutter/flutter/issues/130610
final
ui
.
Image
image
=
(
await
tester
.
binding
.
runAsync
<
ui
.
Image
>(()
=>
captureImage
(
find
.
byType
(
Wrap
).
evaluate
().
single
)))!;
final
Uint8List
bytes
=
(
await
tester
.
binding
.
runAsync
<
ByteData
?>(()
=>
image
.
toByteData
(
format:
ui
.
ImageByteFormat
.
rawStraightRgba
)))!.
buffer
.
asUint8List
();
expect
(
image
.
width
,
792
);
expect
(
image
.
height
,
48
);
expect
(
bytes
,
hasLength
(
image
.
width
*
image
.
height
*
4
));
Color
getPixel
(
int
x
,
int
y
)
{
final
int
offset
=
(
x
+
y
*
image
.
width
)
*
4
;
return
Color
.
fromARGB
(
0xFF
,
bytes
[
offset
],
bytes
[
offset
+
1
],
bytes
[
offset
+
2
]);
}
Color
getBlockPixel
(
int
index
)
{
int
x
=
12
+
index
*
24
;
final
int
y
=
12
+
(
x
~/
image
.
width
)
*
24
;
x
%=
image
.
width
;
return
getPixel
(
x
,
y
);
}
const
Color
lime
=
Color
(
0xFF00FF00
);
expect
(
getBlockPixel
(
0
),
lime
);
// pure green
expect
(
getBlockPixel
(
1
),
lime
);
// 100% green 0% red
expect
(
getBlockPixel
(
2
),
const
Color
(
0xFF19E600
));
expect
(
getBlockPixel
(
3
),
const
Color
(
0xFF33CC00
));
expect
(
getBlockPixel
(
4
),
const
Color
(
0xFF808000
));
// 50-50 mix green/red
expect
(
getBlockPixel
(
5
),
const
Color
(
0xFFCD3200
));
expect
(
getBlockPixel
(
6
),
const
Color
(
0xFFE61900
));
expect
(
getBlockPixel
(
7
),
const
Color
(
0xFFFF0000
));
// 0% green 100% red
expect
(
getBlockPixel
(
8
),
const
Color
(
0xFFFF0000
));
// pure red
for
(
int
index
=
9
;
index
<
40
;
index
+=
1
)
{
expect
(
getBlockPixel
(
index
),
lime
);
}
}
},
skip:
kIsWeb
);
// TODO(ianh): https://github.com/flutter/flutter/issues/130612, https://github.com/flutter/flutter/issues/130609
testWidgets
(
'ImageDecoration.lerp'
,
(
WidgetTester
tester
)
async
{
final
MemoryImage
cmyk
=
MemoryImage
(
Uint8List
.
fromList
(<
int
>[
0x89
,
0x50
,
0x4e
,
0x47
,
0x0d
,
0x0a
,
0x1a
,
0x0a
,
0x00
,
0x00
,
0x00
,
0x0d
,
0x49
,
0x48
,
0x44
,
0x52
,
0x00
,
0x00
,
0x00
,
0x04
,
0x00
,
0x00
,
0x00
,
0x04
,
0x02
,
0x03
,
0x00
,
0x00
,
0x00
,
0xd4
,
0x9f
,
0x76
,
0xed
,
0x00
,
0x00
,
0x00
,
0x0c
,
0x50
,
0x4c
,
0x54
,
0x45
,
0x00
,
0xff
,
0xff
,
0xff
,
0x00
,
0xff
,
0xff
,
0xff
,
0x00
,
0x00
,
0x00
,
0x00
,
0x3b
,
0x4c
,
0x59
,
0x13
,
0x00
,
0x00
,
0x00
,
0x0e
,
0x49
,
0x44
,
0x41
,
0x54
,
0x08
,
0xd7
,
0x63
,
0x60
,
0x05
,
0xc2
,
0xf5
,
0x0c
,
0xeb
,
0x01
,
0x03
,
0x00
,
0x01
,
0x69
,
0x19
,
0xea
,
0x34
,
0x7b
,
0x00
,
0x00
,
0x00
,
0x00
,
0x49
,
0x45
,
0x4e
,
0x44
,
0xae
,
0x42
,
0x60
,
0x82
,
]));
final
MemoryImage
wrgb
=
MemoryImage
(
Uint8List
.
fromList
(<
int
>[
0x89
,
0x50
,
0x4e
,
0x47
,
0x0d
,
0x0a
,
0x1a
,
0x0a
,
0x00
,
0x00
,
0x00
,
0x0d
,
0x49
,
0x48
,
0x44
,
0x52
,
0x00
,
0x00
,
0x00
,
0x04
,
0x00
,
0x00
,
0x00
,
0x04
,
0x02
,
0x03
,
0x00
,
0x00
,
0x00
,
0xd4
,
0x9f
,
0x76
,
0xed
,
0x00
,
0x00
,
0x00
,
0x0c
,
0x50
,
0x4c
,
0x54
,
0x45
,
0xff
,
0xff
,
0xff
,
0x00
,
0x00
,
0xff
,
0x00
,
0xff
,
0x00
,
0xff
,
0x00
,
0x00
,
0x1e
,
0x46
,
0xbb
,
0x1c
,
0x00
,
0x00
,
0x00
,
0x0e
,
0x49
,
0x44
,
0x41
,
0x54
,
0x08
,
0xd7
,
0x63
,
0xe0
,
0x07
,
0xc2
,
0xa5
,
0x0c
,
0x4b
,
0x01
,
0x03
,
0x50
,
0x01
,
0x69
,
0x4a
,
0x78
,
0x1d
,
0x41
,
0x00
,
0x00
,
0x00
,
0x00
,
0x49
,
0x45
,
0x4e
,
0x44
,
0xae
,
0x42
,
0x60
,
0x82
,
]));
await
tester
.
runAsync
(()
async
{
await
load
(
cmyk
);
await
load
(
wrgb
);
});
await
tester
.
pumpWidget
(
ColoredBox
(
color:
Colors
.
white
,
child:
Align
(
alignment:
Alignment
.
topLeft
,
child:
RepaintBoundary
(
child:
Wrap
(
textDirection:
TextDirection
.
ltr
,
children:
<
Widget
>[
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
fit:
BoxFit
.
contain
),
DecorationImage
(
image:
cmyk
,
fit:
BoxFit
.
contain
),
0.0
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
fit:
BoxFit
.
contain
),
DecorationImage
(
image:
cmyk
,
fit:
BoxFit
.
contain
),
0.1
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
fit:
BoxFit
.
contain
),
DecorationImage
(
image:
cmyk
,
fit:
BoxFit
.
contain
),
0.2
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
fit:
BoxFit
.
contain
),
DecorationImage
(
image:
cmyk
,
fit:
BoxFit
.
contain
),
0.5
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
fit:
BoxFit
.
contain
),
DecorationImage
(
image:
cmyk
,
fit:
BoxFit
.
contain
),
0.8
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
fit:
BoxFit
.
contain
),
DecorationImage
(
image:
cmyk
,
fit:
BoxFit
.
contain
),
0.9
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
fit:
BoxFit
.
contain
),
DecorationImage
(
image:
cmyk
,
fit:
BoxFit
.
contain
),
1.0
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
fit:
BoxFit
.
cover
),
DecorationImage
(
image:
cmyk
,
repeat:
ImageRepeat
.
repeat
),
0.5
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
repeat:
ImageRepeat
.
repeat
),
DecorationImage
(
image:
cmyk
,
repeat:
ImageRepeat
.
repeatY
),
0.5
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
repeat:
ImageRepeat
.
repeatX
),
DecorationImage
(
image:
cmyk
,
repeat:
ImageRepeat
.
repeat
),
0.5
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
repeat:
ImageRepeat
.
repeat
,
opacity:
0.2
),
DecorationImage
(
image:
cmyk
,
repeat:
ImageRepeat
.
repeat
,
opacity:
0.2
),
0.25
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
repeat:
ImageRepeat
.
repeat
,
opacity:
0.2
),
DecorationImage
(
image:
cmyk
,
repeat:
ImageRepeat
.
repeat
,
opacity:
0.2
),
0.5
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
repeat:
ImageRepeat
.
repeat
,
opacity:
0.2
),
DecorationImage
(
image:
cmyk
,
repeat:
ImageRepeat
.
repeat
,
opacity:
0.2
),
0.75
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
wrgb
,
scale:
0.5
,
repeat:
ImageRepeat
.
repeatX
),
DecorationImage
(
image:
cmyk
,
scale:
0.25
,
repeat:
ImageRepeat
.
repeatY
),
0.5
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
0.0
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
0.25
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
0.5
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
0.75
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
1.0
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
0.0
,
0.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
0.0
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
0.0
,
0.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
0.25
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
0.0
,
0.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
0.5
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
0.0
,
0.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
0.75
,
)),
TestImage
(
DecorationImage
.
lerp
(
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
0.0
,
0.0
,
1.0
,
1.0
)),
DecorationImage
(
image:
cmyk
,
centerSlice:
const
Rect
.
fromLTWH
(
2.0
,
2.0
,
1.0
,
1.0
)),
1.0
,
)),
],
),
),
),
),
);
await
expectLater
(
find
.
byType
(
Wrap
),
matchesGoldenFile
(
'decoration_image.lerp.1.png'
),
);
if
(!
kIsWeb
)
{
// TODO(ianh): https://github.com/flutter/flutter/issues/130610
final
ui
.
Image
image
=
(
await
tester
.
binding
.
runAsync
<
ui
.
Image
>(()
=>
captureImage
(
find
.
byType
(
Wrap
).
evaluate
().
single
)))!;
final
Uint8List
bytes
=
(
await
tester
.
binding
.
runAsync
<
ByteData
?>(()
=>
image
.
toByteData
(
format:
ui
.
ImageByteFormat
.
rawStraightRgba
)))!.
buffer
.
asUint8List
();
expect
(
image
.
width
,
24
*
24
);
expect
(
image
.
height
,
1
*
24
);
expect
(
bytes
,
hasLength
(
image
.
width
*
image
.
height
*
4
));
Color
getPixel
(
int
x
,
int
y
)
{
final
int
offset
=
(
x
+
y
*
image
.
width
)
*
4
;
return
Color
.
fromARGB
(
0xFF
,
bytes
[
offset
],
bytes
[
offset
+
1
],
bytes
[
offset
+
2
]);
}
Color
getPixelFromBlock
(
int
index
,
int
dx
,
int
dy
)
{
const
int
padding
=
2
;
int
x
=
index
*
24
+
dx
+
padding
;
final
int
y
=
(
x
~/
image
.
width
)
*
24
+
dy
+
padding
;
x
%=
image
.
width
;
return
getPixel
(
x
,
y
);
}
// wrgb image
expect
(
getPixelFromBlock
(
0
,
5
,
5
),
const
Color
(
0xFFFFFFFF
));
expect
(
getPixelFromBlock
(
0
,
15
,
5
),
const
Color
(
0xFFFF0000
));
expect
(
getPixelFromBlock
(
0
,
5
,
15
),
const
Color
(
0xFF00FF00
));
expect
(
getPixelFromBlock
(
0
,
15
,
15
),
const
Color
(
0xFF0000FF
));
// wrgb/cmyk 50/50 blended image
expect
(
getPixelFromBlock
(
3
,
5
,
5
),
const
Color
(
0xFF80FFFF
));
expect
(
getPixelFromBlock
(
3
,
15
,
5
),
const
Color
(
0xFFFF0080
));
expect
(
getPixelFromBlock
(
3
,
5
,
15
),
const
Color
(
0xFF80FF00
));
expect
(
getPixelFromBlock
(
3
,
15
,
15
),
const
Color
(
0xFF000080
));
// cmyk image
expect
(
getPixelFromBlock
(
6
,
5
,
5
),
const
Color
(
0xFF00FFFF
));
expect
(
getPixelFromBlock
(
6
,
15
,
5
),
const
Color
(
0xFFFF00FF
));
expect
(
getPixelFromBlock
(
6
,
5
,
15
),
const
Color
(
0xFFFFFF00
));
expect
(
getPixelFromBlock
(
6
,
15
,
15
),
const
Color
(
0xFF000000
));
// top left corner control
expect
(
getPixelFromBlock
(
14
,
0
,
0
),
const
Color
(
0xFF00FFFF
));
expect
(
getPixelFromBlock
(
14
,
1
,
1
),
const
Color
(
0xFF00FFFF
));
expect
(
getPixelFromBlock
(
14
,
2
,
0
),
const
Color
(
0xFFFF00FF
));
expect
(
getPixelFromBlock
(
14
,
19
,
0
),
const
Color
(
0xFFFF00FF
));
expect
(
getPixelFromBlock
(
14
,
0
,
2
),
const
Color
(
0xFFFFFF00
));
expect
(
getPixelFromBlock
(
14
,
0
,
19
),
const
Color
(
0xFFFFFF00
));
expect
(
getPixelFromBlock
(
14
,
2
,
2
),
const
Color
(
0xFF000000
));
expect
(
getPixelFromBlock
(
14
,
19
,
19
),
const
Color
(
0xFF000000
));
// bottom right corner control
expect
(
getPixelFromBlock
(
19
,
0
,
0
),
const
Color
(
0xFF00FFFF
));
expect
(
getPixelFromBlock
(
19
,
17
,
17
),
const
Color
(
0xFF00FFFF
));
expect
(
getPixelFromBlock
(
19
,
19
,
0
),
const
Color
(
0xFFFF00FF
));
expect
(
getPixelFromBlock
(
19
,
19
,
17
),
const
Color
(
0xFFFF00FF
));
expect
(
getPixelFromBlock
(
19
,
0
,
19
),
const
Color
(
0xFFFFFF00
));
expect
(
getPixelFromBlock
(
19
,
17
,
19
),
const
Color
(
0xFFFFFF00
));
expect
(
getPixelFromBlock
(
19
,
18
,
18
),
const
Color
(
0xFF000000
));
expect
(
getPixelFromBlock
(
19
,
19
,
19
),
const
Color
(
0xFF000000
));
}
},
skip:
kIsWeb
);
// TODO(ianh): https://github.com/flutter/flutter/issues/130612, https://github.com/flutter/flutter/issues/130609
}
Future
<
void
>
load
(
MemoryImage
image
)
{
final
ImageStream
stream
=
image
.
resolve
(
ImageConfiguration
.
empty
);
final
Completer
<
ImageInfo
>
completer
=
Completer
<
ImageInfo
>();
void
listener
(
ImageInfo
image
,
bool
syncCall
)
{
completer
.
complete
(
image
);
}
stream
.
addListener
(
ImageStreamListener
(
listener
));
return
completer
.
future
;
}
class
TestImage
extends
StatelessWidget
{
TestImage
(
this
.
image
);
// ignore: use_key_in_widget_constructors, prefer_const_constructors_in_immutables
final
DecorationImage
?
image
;
@override
Widget
build
(
BuildContext
context
)
{
return
Padding
(
padding:
const
EdgeInsets
.
all
(
2.0
),
child:
SizedBox
(
width:
20
,
height:
20
,
child:
DecoratedBox
(
decoration:
BoxDecoration
(
image:
image
,
),
),
),
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment