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
c9c577ae
Commit
c9c577ae
authored
Dec 20, 2016
by
Hans Muller
Committed by
GitHub
Dec 20, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
BoxDecoration should clip its backgroundImage if shape is BoxShape.circle (#7292)
parent
82fc87fc
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
117 additions
and
3 deletions
+117
-3
box_painter.dart
packages/flutter/lib/src/painting/box_painter.dart
+17
-2
decoration_test.dart
packages/flutter/test/painting/decoration_test.dart
+100
-1
No files found.
packages/flutter/lib/src/painting/box_painter.dart
View file @
c9c577ae
...
@@ -1051,7 +1051,7 @@ class BoxDecoration extends Decoration {
...
@@ -1051,7 +1051,7 @@ class BoxDecoration extends Decoration {
/// * If [backgroundColor] is null, this decoration does not paint a background color.
/// * If [backgroundColor] is null, this decoration does not paint a background color.
/// * If [backgroundImage] is null, this decoration does not paint a background image.
/// * If [backgroundImage] is null, this decoration does not paint a background image.
/// * If [border] is null, this decoration does not paint a border.
/// * If [border] is null, this decoration does not paint a border.
/// * If [borderRadius] is null, this decoration use more efficient background
/// * If [borderRadius] is null, this decoration use
s
more efficient background
/// painting commands. The [borderRadius] argument must be be null if [shape] is
/// painting commands. The [borderRadius] argument must be be null if [shape] is
/// [BoxShape.circle].
/// [BoxShape.circle].
/// * If [boxShadow] is null, this decoration does not paint a shadow.
/// * If [boxShadow] is null, this decoration does not paint a shadow.
...
@@ -1079,7 +1079,8 @@ class BoxDecoration extends Decoration {
...
@@ -1079,7 +1079,8 @@ class BoxDecoration extends Decoration {
/// potentially with a border radius, or a circle).
/// potentially with a border radius, or a circle).
final
Color
backgroundColor
;
final
Color
backgroundColor
;
/// An image to paint above the background color.
/// An image to paint above the background color. If [shape] is [BoxShape.circle]
/// then the image is clipped to the circle's boundary.
final
BackgroundImage
backgroundImage
;
final
BackgroundImage
backgroundImage
;
/// A border to draw above the background.
/// A border to draw above the background.
...
@@ -1333,6 +1334,17 @@ class _BoxDecorationPainter extends BoxPainter {
...
@@ -1333,6 +1334,17 @@ class _BoxDecorationPainter extends BoxPainter {
final
ui
.
Image
image
=
_image
?.
image
;
final
ui
.
Image
image
=
_image
?.
image
;
if
(
image
==
null
)
if
(
image
==
null
)
return
;
return
;
Path
clipPath
;
if
(
_decoration
.
shape
==
BoxShape
.
circle
)
clipPath
=
new
Path
()..
addOval
(
rect
);
else
if
(
_decoration
.
borderRadius
!=
null
)
clipPath
=
new
Path
()..
addRRect
(
_decoration
.
borderRadius
.
toRRect
(
rect
));
if
(
clipPath
!=
null
)
{
canvas
.
save
();
canvas
.
clipPath
(
clipPath
);
}
paintImage
(
paintImage
(
canvas:
canvas
,
canvas:
canvas
,
rect:
rect
,
rect:
rect
,
...
@@ -1342,6 +1354,9 @@ class _BoxDecorationPainter extends BoxPainter {
...
@@ -1342,6 +1354,9 @@ class _BoxDecorationPainter extends BoxPainter {
fit:
backgroundImage
.
fit
,
fit:
backgroundImage
.
fit
,
repeat:
backgroundImage
.
repeat
repeat:
backgroundImage
.
repeat
);
);
if
(
clipPath
!=
null
)
canvas
.
restore
();
}
}
void
_imageListener
(
ImageInfo
value
,
bool
synchronousCall
)
{
void
_imageListener
(
ImageInfo
value
,
bool
synchronousCall
)
{
...
...
packages/flutter/test/painting/decoration_test.dart
View file @
c9c577ae
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
// found in the LICENSE file.
// found in the LICENSE file.
import
'dart:async'
;
import
'dart:async'
;
import
'dart:ui'
as
ui
show
Image
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/painting.dart'
;
import
'package:flutter/painting.dart'
;
...
@@ -13,8 +14,14 @@ import 'package:test/test.dart';
...
@@ -13,8 +14,14 @@ import 'package:test/test.dart';
import
'../services/mocks_for_image_cache.dart'
;
import
'../services/mocks_for_image_cache.dart'
;
class
TestCanvas
implements
Canvas
{
class
TestCanvas
implements
Canvas
{
TestCanvas
([
this
.
invocations
]);
final
List
<
Invocation
>
invocations
;
@override
@override
void
noSuchMethod
(
Invocation
invocation
)
{}
void
noSuchMethod
(
Invocation
invocation
)
{
invocations
?.
add
(
invocation
);
}
}
}
class
SynchronousTestImageProvider
extends
ImageProvider
<
int
>
{
class
SynchronousTestImageProvider
extends
ImageProvider
<
int
>
{
...
@@ -45,6 +52,43 @@ class AsyncTestImageProvider extends ImageProvider<int> {
...
@@ -45,6 +52,43 @@ class AsyncTestImageProvider extends ImageProvider<int> {
}
}
}
}
class
BackgroundImageProvider
extends
ImageProvider
<
BackgroundImageProvider
>
{
final
Completer
<
ImageInfo
>
_completer
=
new
Completer
<
ImageInfo
>();
@override
Future
<
BackgroundImageProvider
>
obtainKey
(
ImageConfiguration
configuration
)
{
return
new
SynchronousFuture
<
BackgroundImageProvider
>(
this
);
}
@override
ImageStream
resolve
(
ImageConfiguration
configuration
)
{
return
super
.
resolve
(
configuration
);
}
@override
ImageStreamCompleter
load
(
BackgroundImageProvider
key
)
{
return
new
OneFrameImageStreamCompleter
(
_completer
.
future
);
}
void
complete
()
{
_completer
.
complete
(
new
ImageInfo
(
image:
new
TestImage
()));
}
@override
String
toString
()
=>
'
$runtimeType
(
$hashCode
)'
;
}
class
TestImage
extends
ui
.
Image
{
@override
int
get
width
=>
100
;
@override
int
get
height
=>
100
;
@override
void
dispose
()
{
}
}
void
main
(
)
{
void
main
(
)
{
test
(
"Decoration.lerp()"
,
()
{
test
(
"Decoration.lerp()"
,
()
{
BoxDecoration
a
=
const
BoxDecoration
(
backgroundColor:
const
Color
(
0xFFFFFFFF
));
BoxDecoration
a
=
const
BoxDecoration
(
backgroundColor:
const
Color
(
0xFFFFFFFF
));
...
@@ -99,4 +143,59 @@ void main() {
...
@@ -99,4 +143,59 @@ void main() {
expect
(
onChangedCalled
,
equals
(
true
));
expect
(
onChangedCalled
,
equals
(
true
));
});
});
});
});
// Regression test for https://github.com/flutter/flutter/issues/7289.
// A reference test would be better.
test
(
"BoxDecoration backgroundImage clip"
,
()
{
void
testDecoration
({
BoxShape
shape
,
BorderRadius
borderRadius
,
bool
expectClip
})
{
new
FakeAsync
().
run
((
FakeAsync
async
)
{
BackgroundImageProvider
imageProvider
=
new
BackgroundImageProvider
();
BackgroundImage
backgroundImage
=
new
BackgroundImage
(
image:
imageProvider
);
BoxDecoration
boxDecoration
=
new
BoxDecoration
(
shape:
shape
,
borderRadius:
borderRadius
,
backgroundImage:
backgroundImage
,
);
List
<
Invocation
>
invocations
=
<
Invocation
>[];
TestCanvas
canvas
=
new
TestCanvas
(
invocations
);
ImageConfiguration
imageConfiguration
=
const
ImageConfiguration
(
size:
const
Size
(
100.0
,
100.0
)
);
bool
onChangedCalled
=
false
;
BoxPainter
boxPainter
=
boxDecoration
.
createBoxPainter
(()
{
onChangedCalled
=
true
;
});
// _BoxDecorationPainter._paintBackgroundImage() resolves the background
// image and adds a listener to the resolved image stream.
boxPainter
.
paint
(
canvas
,
Offset
.
zero
,
imageConfiguration
);
imageProvider
.
complete
();
// Run the listener which calls onChanged() which saves an internal
// reference to the TestImage.
async
.
flushMicrotasks
();
expect
(
onChangedCalled
,
isTrue
);
boxPainter
.
paint
(
canvas
,
Offset
.
zero
,
imageConfiguration
);
// We expect a clip to preceed the drawImageRect call.
List
<
Invocation
>
commands
=
canvas
.
invocations
.
where
((
Invocation
invocation
)
{
return
invocation
.
memberName
==
#clipPath
||
invocation
.
memberName
==
#drawImageRect
;
}).
toList
();
if
(
expectClip
)
{
// We expect a clip to preceed the drawImageRect call.
expect
(
commands
.
length
,
2
);
expect
(
commands
[
0
].
memberName
,
equals
(
#clipPath
));
expect
(
commands
[
1
].
memberName
,
equals
(
#drawImageRect
));
}
else
{
expect
(
commands
.
length
,
1
);
expect
(
commands
[
0
].
memberName
,
equals
(
#drawImageRect
));
}
});
}
testDecoration
(
shape:
BoxShape
.
circle
,
expectClip:
true
);
testDecoration
(
borderRadius:
new
BorderRadius
.
all
(
const
Radius
.
circular
(
16.0
)),
expectClip:
true
);
testDecoration
(
expectClip:
false
);
});
}
}
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