Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
c99deb00
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
c99deb00
编写于
7月 11, 2020
作者:
Y
Yegor
提交者:
GitHub
7月 11, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
CkPaint uses SkPaint (#19562)
上级
80639232
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
445 addition
and
226 deletion
+445
-226
lib/web_ui/lib/src/engine/compositor/canvaskit_api.dart
lib/web_ui/lib/src/engine/compositor/canvaskit_api.dart
+166
-5
lib/web_ui/lib/src/engine/compositor/color_filter.dart
lib/web_ui/lib/src/engine/compositor/color_filter.dart
+19
-12
lib/web_ui/lib/src/engine/compositor/image.dart
lib/web_ui/lib/src/engine/compositor/image.dart
+15
-19
lib/web_ui/lib/src/engine/compositor/image_filter.dart
lib/web_ui/lib/src/engine/compositor/image_filter.dart
+12
-9
lib/web_ui/lib/src/engine/compositor/mask_filter.dart
lib/web_ui/lib/src/engine/compositor/mask_filter.dart
+9
-18
lib/web_ui/lib/src/engine/compositor/painting.dart
lib/web_ui/lib/src/engine/compositor/painting.dart
+81
-120
lib/web_ui/lib/src/engine/shader.dart
lib/web_ui/lib/src/engine/shader.dart
+28
-40
lib/web_ui/test/canvaskit/canvaskit_api_test.dart
lib/web_ui/test/canvaskit/canvaskit_api_test.dart
+115
-3
未找到文件。
lib/web_ui/lib/src/engine/compositor/canvaskit_api.dart
浏览文件 @
c99deb00
...
...
@@ -5,10 +5,65 @@
/// Bindings for CanvasKit JavaScript API.
part of
engine
;
final
js
.
JsObject
_jsWindow
=
js
.
JsObject
.
fromBrowserObject
(
html
.
window
);
/// This and [_jsObjectWrapper] below are used to convert `@JS`-backed
/// objects to [js.JsObject]s. To do that we use `@JS` to pass the object
/// to JavaScript (see [JsObjectWrapper]), then use this variable (which
/// uses `dart:js`) to read the value back, causing it to be wrapped in
/// [js.JsObject].
///
// TODO(yjbanov): this is a temporary hack until we fully migrate to @JS.
final
js
.
JsObject
_jsObjectWrapperLegacy
=
js
.
JsObject
(
js
.
context
[
'Object'
]);
@JS
(
'window.flutter_js_object_wrapper'
)
external
JsObjectWrapper
get
_jsObjectWrapper
;
void
initializeCanvasKitBindings
(
js
.
JsObject
canvasKit
)
{
// Because JsObject cannot be cast to a @JS type, we stash CanvasKit into
// a global and use the [canvasKitJs] getter to access it.
js
.
JsObject
.
fromBrowserObject
(
html
.
window
)[
'flutter_canvas_kit'
]
=
canvasKit
;
_jsWindow
[
'flutter_canvas_kit'
]
=
canvasKit
;
_jsWindow
[
'flutter_js_object_wrapper'
]
=
_jsObjectWrapperLegacy
;
}
@JS
()
class
JsObjectWrapper
{
external
set
skPaint
(
SkPaint
?
paint
);
external
set
skMaskFilter
(
SkMaskFilter
?
filter
);
external
set
skColorFilter
(
SkColorFilter
?
filter
);
external
set
skImageFilter
(
SkImageFilter
?
filter
);
}
/// Specific methods that wrap `@JS`-backed objects into a [js.JsObject]
/// for use with legacy `dart:js` API.
extension
JsObjectWrappers
on
JsObjectWrapper
{
js
.
JsObject
wrapSkPaint
(
SkPaint
paint
)
{
_jsObjectWrapper
.
skPaint
=
paint
;
js
.
JsObject
wrapped
=
_jsObjectWrapperLegacy
[
'skPaint'
];
_jsObjectWrapper
.
skPaint
=
null
;
return
wrapped
;
}
js
.
JsObject
wrapSkMaskFilter
(
SkMaskFilter
filter
)
{
_jsObjectWrapper
.
skMaskFilter
=
filter
;
js
.
JsObject
wrapped
=
_jsObjectWrapperLegacy
[
'skMaskFilter'
];
_jsObjectWrapper
.
skMaskFilter
=
null
;
return
wrapped
;
}
js
.
JsObject
wrapSkColorFilter
(
SkColorFilter
filter
)
{
_jsObjectWrapper
.
skColorFilter
=
filter
;
js
.
JsObject
wrapped
=
_jsObjectWrapperLegacy
[
'skColorFilter'
];
_jsObjectWrapper
.
skColorFilter
=
null
;
return
wrapped
;
}
js
.
JsObject
wrapSkImageFilter
(
SkImageFilter
filter
)
{
_jsObjectWrapper
.
skImageFilter
=
filter
;
js
.
JsObject
wrapped
=
_jsObjectWrapperLegacy
[
'skImageFilter'
];
_jsObjectWrapper
.
skImageFilter
=
null
;
return
wrapped
;
}
}
@JS
(
'window.flutter_canvas_kit'
)
...
...
@@ -317,12 +372,12 @@ class SkPaint {
external
void
setStrokeJoin
(
SkStrokeJoin
join
);
external
void
setAntiAlias
(
bool
isAntiAlias
);
external
void
setColorInt
(
int
color
);
external
void
setShader
(
SkShader
shader
);
external
void
setMaskFilter
(
SkMaskFilter
maskFilter
);
external
void
setShader
(
SkShader
?
shader
);
external
void
setMaskFilter
(
SkMaskFilter
?
maskFilter
);
external
void
setFilterQuality
(
SkFilterQuality
filterQuality
);
external
void
setColorFilter
(
SkColorFilter
colorFilter
);
external
void
setColorFilter
(
SkColorFilter
?
colorFilter
);
external
void
setStrokeMiter
(
double
miterLimit
);
external
void
setImageFilter
(
SkImageFilter
imageFilter
);
external
void
setImageFilter
(
SkImageFilter
?
imageFilter
);
}
@JS
()
...
...
@@ -373,3 +428,109 @@ Float32List toSkMatrixFromFloat32(Float32List matrix4) {
}
return
skMatrix
;
}
/// Converts an [offset] into an `[x, y]` pair stored in a `Float32List`.
///
/// The returned list can be passed to CanvasKit API that take points.
Float32List
toSkPoint
(
ui
.
Offset
offset
)
{
final
Float32List
point
=
Float32List
(
2
);
point
[
0
]
=
offset
.
dx
;
point
[
1
]
=
offset
.
dy
;
return
point
;
}
/// Color stops used when the framework specifies `null`.
final
Float32List
_kDefaultSkColorStops
=
Float32List
(
2
)
..[
0
]
=
0
..[
1
]
=
1
;
/// Converts a list of color stops into a Skia-compatible JS array or color stops.
///
/// In Flutter `null` means two color stops `[0, 1]` that in Skia must be specified explicitly.
Float32List
toSkColorStops
(
List
<
double
>?
colorStops
)
{
if
(
colorStops
==
null
)
{
return
_kDefaultSkColorStops
;
}
final
int
len
=
colorStops
.
length
;
final
Float32List
skColorStops
=
Float32List
(
len
);
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
skColorStops
[
i
]
=
colorStops
[
i
];
}
return
skColorStops
;
}
@JS
(
'Float32Array'
)
external
_NativeFloat32ArrayType
get
_nativeFloat32ArrayType
;
@JS
()
class
_NativeFloat32ArrayType
{}
@JS
(
'window.flutter_canvas_kit.Malloc'
)
external
SkFloat32List
_mallocFloat32List
(
_NativeFloat32ArrayType
float32ListType
,
int
size
,
);
/// Allocates a [Float32List] backed by WASM memory, managed by
/// a [SkFloat32List].
SkFloat32List
mallocFloat32List
(
int
size
)
{
return
_mallocFloat32List
(
_nativeFloat32ArrayType
,
size
);
}
/// Wraps a [Float32List] backed by WASM memory.
///
/// This wrapper is necessary because the raw [Float32List] will get detached
/// when WASM grows its memory. Call [toTypedArray] to get a new instance
/// that's attached to the current WASM memory block.
@JS
()
class
SkFloat32List
{
/// Returns the [Float32List] object backed by WASM memory.
///
/// Do not reuse the returned list across multiple WASM function/method
/// invocations that may lead to WASM memory to grow. When WASM memory
/// grows the [Float32List] object becomes "detached" and is no longer
/// usable. Instead, call this method every time you need to read from
/// or write to the list.
external
Float32List
toTypedArray
();
}
/// Writes [color] information into the given [skColor] buffer.
Float32List
_populateSkColor
(
SkFloat32List
skColor
,
ui
.
Color
color
)
{
final
Float32List
array
=
skColor
.
toTypedArray
();
array
[
0
]
=
color
.
red
/
255.0
;
array
[
1
]
=
color
.
green
/
255.0
;
array
[
2
]
=
color
.
blue
/
255.0
;
array
[
3
]
=
color
.
alpha
/
255.0
;
return
array
;
}
/// Unpacks the [color] into CanvasKit-compatible representation stored
/// in a shared memory location #1.
///
/// Use this only for passing transient data to CanvasKit. Because the
/// memory is shared the value will not persist.
Float32List
toSharedSkColor1
(
ui
.
Color
color
)
{
return
_populateSkColor
(
_sharedSkColor1
,
color
);
}
final
SkFloat32List
_sharedSkColor1
=
mallocFloat32List
(
4
);
/// Unpacks the [color] into CanvasKit-compatible representation stored
/// in a shared memory location #2.
///
/// Use this only for passing transient data to CanvasKit. Because the
/// memory is shared the value will not persist.
Float32List
toSharedSkColor2
(
ui
.
Color
color
)
{
return
_populateSkColor
(
_sharedSkColor2
,
color
);
}
final
SkFloat32List
_sharedSkColor2
=
mallocFloat32List
(
4
);
/// Unpacks the [color] into CanvasKit-compatible representation stored
/// in a shared memory location #3.
///
/// Use this only for passing transient data to CanvasKit. Because the
/// memory is shared the value will not persist.
Float32List
toSharedSkColor3
(
ui
.
Color
color
)
{
return
_populateSkColor
(
_sharedSkColor3
,
color
);
}
final
SkFloat32List
_sharedSkColor3
=
mallocFloat32List
(
4
);
lib/web_ui/lib/src/engine/compositor/color_filter.dart
浏览文件 @
c99deb00
...
...
@@ -19,30 +19,37 @@ class CkColorFilter extends ResurrectableSkiaObject {
CkColorFilter
.
srgbToLinearGamma
(
EngineColorFilter
filter
)
:
_engineFilter
=
filter
;
SkColorFilter
?
_skColorFilter
;
js
.
JsObject
_createSkiaObjectFromFilter
()
{
SkColorFilter
skColorFilter
;
switch
(
_engineFilter
.
_type
)
{
case
EngineColorFilter
.
_TypeMode
:
s
etSharedSkColor1
(
_engineFilter
.
_color
!);
return
canvasKit
[
'SkColorFilter'
].
callMethod
(
'MakeBlend'
,
<
dynamic
>[
sharedSkColor1
,
makeSkBlendMode
(
_engineFilter
.
_blendMode
),
])
;
s
kColorFilter
=
canvasKitJs
.
SkColorFilter
.
MakeBlend
(
toSharedSkColor1
(
_engineFilter
.
_color
!),
toSkBlendMode
(
_engineFilter
.
_blendMode
!)
,
);
break
;
case
EngineColorFilter
.
_TypeMatrix
:
final
js
.
JsArray
<
double
>
colorMatrix
=
js
.
JsArray
<
double
>(
);
colorMatrix
.
length
=
20
;
final
Float32List
colorMatrix
=
Float32List
(
20
);
final
List
<
double
>
matrix
=
_engineFilter
.
_matrix
!
;
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
colorMatrix
[
i
]
=
_engineFilter
.
_matrix
!
[
i
];
colorMatrix
[
i
]
=
matrix
[
i
];
}
return
canvasKit
[
'SkColorFilter'
]
.
callMethod
(
'MakeMatrix'
,
<
js
.
JsArray
>[
colorMatrix
])
;
skColorFilter
=
canvasKitJs
.
SkColorFilter
.
MakeMatrix
(
colorMatrix
);
break
;
case
EngineColorFilter
.
_TypeLinearToSrgbGamma
:
return
canvasKit
[
'SkColorFilter'
].
callMethod
(
'MakeLinearToSRGBGamma'
);
skColorFilter
=
canvasKitJs
.
SkColorFilter
.
MakeLinearToSRGBGamma
();
break
;
case
EngineColorFilter
.
_TypeSrgbToLinearGamma
:
return
canvasKit
[
'SkColorFilter'
].
callMethod
(
'MakeSRGBToLinearGamma'
);
skColorFilter
=
canvasKitJs
.
SkColorFilter
.
MakeSRGBToLinearGamma
();
break
;
default
:
throw
StateError
(
'Unknown mode
${_engineFilter._type}
for ColorFilter.'
);
}
_skColorFilter
=
skColorFilter
;
return
_jsObjectWrapper
.
wrapSkColorFilter
(
skColorFilter
);
}
@override
...
...
lib/web_ui/lib/src/engine/compositor/image.dart
浏览文件 @
c99deb00
...
...
@@ -8,8 +8,7 @@ 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
skAnimatedImage
=
canvasKitJs
.
MakeAnimatedImageFromEncoded
(
list
);
final
CkAnimatedImage
animatedImage
=
CkAnimatedImage
(
skAnimatedImage
);
final
CkAnimatedImageCodec
codec
=
CkAnimatedImageCodec
(
animatedImage
);
callback
(
codec
);
...
...
@@ -17,36 +16,34 @@ void skiaInstantiateImageCodec(Uint8List list, Callback<ui.Codec> callback,
/// A wrapper for `SkAnimatedImage`.
class
CkAnimatedImage
implements
ui
.
Image
{
final
js
.
JsObject
?
_skAnimatedImage
;
final
SkAnimatedImage
_skAnimatedImage
;
CkAnimatedImage
(
this
.
_skAnimatedImage
);
@override
void
dispose
()
{
_skAnimatedImage
!.
callMethod
(
'delete'
);
_skAnimatedImage
.
delete
(
);
}
int
?
get
frameCount
=>
_skAnimatedImage
!.
callMethod
(
'getFrameCount'
);
int
get
frameCount
=>
_skAnimatedImage
.
getFrameCount
(
);
/// Decodes the next frame and returns the frame duration.
Duration
decodeNextFrame
()
{
final
int
durationMillis
=
_skAnimatedImage
!.
callMethod
(
'decodeNextFrame'
);
final
int
durationMillis
=
_skAnimatedImage
.
decodeNextFrame
(
);
return
Duration
(
milliseconds:
durationMillis
);
}
int
?
get
repetitionCount
=>
_skAnimatedImage
!.
callMethod
(
'getRepetitionCount'
);
int
get
repetitionCount
=>
_skAnimatedImage
.
getRepetitionCount
(
);
CkImage
get
currentFrameAsImage
{
final
js
.
JsObject
?
_currentFrame
=
_skAnimatedImage
!.
callMethod
(
'getCurrentFrame'
);
return
CkImage
(
_currentFrame
);
return
CkImage
(
_skAnimatedImage
.
getCurrentFrame
());
}
@override
int
get
width
=>
_skAnimatedImage
!.
callMethod
(
'width'
);
int
get
width
=>
_skAnimatedImage
.
width
(
);
@override
int
get
height
=>
_skAnimatedImage
!.
callMethod
(
'height'
);
int
get
height
=>
_skAnimatedImage
.
height
(
);
@override
Future
<
ByteData
>
toByteData
(
...
...
@@ -57,21 +54,20 @@ class CkAnimatedImage implements ui.Image {
/// A [ui.Image] backed by an `SkImage` from Skia.
class
CkImage
implements
ui
.
Image
{
js
.
JsObject
?
skImage
;
SkImage
skImage
;
CkImage
(
this
.
skImage
);
@override
void
dispose
()
{
skImage
!.
callMethod
(
'delete'
);
skImage
=
null
;
skImage
.
delete
();
}
@override
int
get
width
=>
skImage
!.
callMethod
(
'width'
);
int
get
width
=>
skImage
.
width
(
);
@override
int
get
height
=>
skImage
!.
callMethod
(
'height'
);
int
get
height
=>
skImage
.
height
(
);
@override
Future
<
ByteData
>
toByteData
(
...
...
@@ -93,10 +89,10 @@ class CkAnimatedImageCodec implements ui.Codec {
}
@override
int
get
frameCount
=>
animatedImage
!.
frameCount
!
;
int
get
frameCount
=>
animatedImage
!.
frameCount
;
@override
int
get
repetitionCount
=>
animatedImage
!.
repetitionCount
!
;
int
get
repetitionCount
=>
animatedImage
!.
repetitionCount
;
@override
Future
<
ui
.
FrameInfo
>
getNextFrame
()
{
...
...
lib/web_ui/lib/src/engine/compositor/image_filter.dart
浏览文件 @
c99deb00
...
...
@@ -15,21 +15,24 @@ class CkImageFilter extends ResurrectableSkiaObject implements ui.ImageFilter {
final
double
_sigmaX
;
final
double
_sigmaY
;
SkImageFilter
?
_skImageFilter
;
@override
js
.
JsObject
createDefault
()
=>
_initSkiaObject
();
@override
js
.
JsObject
resurrect
()
=>
_initSkiaObject
();
js
.
JsObject
_initSkiaObject
()
=>
canvasKit
[
'SkImageFilter'
].
callMethod
(
'MakeBlur'
,
<
dynamic
>[
_sigmaX
,
_sigmaY
,
canvasKit
[
'TileMode'
][
'Clamp'
],
null
,
],
);
js
.
JsObject
_initSkiaObject
()
{
final
SkImageFilter
skImageFilter
=
canvasKitJs
.
SkImageFilter
.
MakeBlur
(
_sigmaX
,
_sigmaY
,
canvasKitJs
.
TileMode
.
Clamp
,
null
,
);
_skImageFilter
=
skImageFilter
;
return
_jsObjectWrapper
.
wrapSkImageFilter
(
skImageFilter
);
}
@override
bool
operator
==(
Object
other
)
{
...
...
lib/web_ui/lib/src/engine/compositor/mask_filter.dart
浏览文件 @
c99deb00
...
...
@@ -13,6 +13,8 @@ class CkMaskFilter extends ResurrectableSkiaObject {
final
ui
.
BlurStyle
_blurStyle
;
final
double
_sigma
;
SkMaskFilter
?
_skMaskFilter
;
@override
js
.
JsObject
createDefault
()
=>
_initSkiaObject
();
...
...
@@ -20,23 +22,12 @@ class CkMaskFilter extends ResurrectableSkiaObject {
js
.
JsObject
resurrect
()
=>
_initSkiaObject
();
js
.
JsObject
_initSkiaObject
()
{
js
.
JsObject
skBlurStyle
;
switch
(
_blurStyle
)
{
case
ui
.
BlurStyle
.
normal
:
skBlurStyle
=
canvasKit
[
'BlurStyle'
][
'Normal'
];
break
;
case
ui
.
BlurStyle
.
solid
:
skBlurStyle
=
canvasKit
[
'BlurStyle'
][
'Solid'
];
break
;
case
ui
.
BlurStyle
.
outer
:
skBlurStyle
=
canvasKit
[
'BlurStyle'
][
'Outer'
];
break
;
case
ui
.
BlurStyle
.
inner
:
skBlurStyle
=
canvasKit
[
'BlurStyle'
][
'Inner'
];
break
;
}
return
canvasKit
.
callMethod
(
'MakeBlurMaskFilter'
,
<
dynamic
>[
skBlurStyle
,
_sigma
,
true
]);
final
SkMaskFilter
skMaskFilter
=
canvasKitJs
.
MakeBlurMaskFilter
(
toSkBlurStyle
(
_blurStyle
),
_sigma
,
true
,
);
_skMaskFilter
=
skMaskFilter
;
return
_jsObjectWrapper
.
wrapSkMaskFilter
(
skMaskFilter
);
}
}
lib/web_ui/lib/src/engine/compositor/painting.dart
浏览文件 @
c99deb00
...
...
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of
engine
;
/// The implementation of [ui.Paint] used by the CanvasKit backend.
...
...
@@ -13,21 +12,16 @@ class CkPaint extends ResurrectableSkiaObject implements ui.Paint {
CkPaint
();
static
const
ui
.
Color
_defaultPaintColor
=
ui
.
Color
(
0xFF000000
);
static
final
js
.
JsObject
?
_skPaintStyleStroke
=
canvasKit
[
'PaintStyle'
][
'Stroke'
];
static
final
js
.
JsObject
?
_skPaintStyleFill
=
canvasKit
[
'PaintStyle'
][
'Fill'
];
@override
ui
.
BlendMode
get
blendMode
=>
_blendMode
;
@override
set
blendMode
(
ui
.
BlendMode
value
)
{
if
(
_blendMode
==
value
)
{
return
;
}
_blendMode
=
value
;
_syncBlendMode
(
skiaObject
);
}
void
_syncBlendMode
(
js
.
JsObject
object
)
{
final
js
.
JsObject
?
skBlendMode
=
makeSkBlendMode
(
_blendMode
);
object
.
callMethod
(
'setBlendMode'
,
<
js
.
JsObject
?>[
skBlendMode
]);
_skPaint
.
setBlendMode
(
toSkBlendMode
(
value
));
}
ui
.
BlendMode
_blendMode
=
ui
.
BlendMode
.
srcOver
;
...
...
@@ -37,21 +31,11 @@ class CkPaint extends ResurrectableSkiaObject implements ui.Paint {
@override
set
style
(
ui
.
PaintingStyle
value
)
{
_style
=
value
;
_syncStyle
(
skiaObject
);
}
void
_syncStyle
(
js
.
JsObject
object
)
{
js
.
JsObject
?
skPaintStyle
;
switch
(
_style
)
{
case
ui
.
PaintingStyle
.
stroke
:
skPaintStyle
=
_skPaintStyleStroke
;
break
;
case
ui
.
PaintingStyle
.
fill
:
skPaintStyle
=
_skPaintStyleFill
;
break
;
if
(
_style
==
value
)
{
return
;
}
object
.
callMethod
(
'setStyle'
,
<
js
.
JsObject
?>[
skPaintStyle
]);
_style
=
value
;
_skPaint
.
setStyle
(
toSkPaintStyle
(
value
));
}
ui
.
PaintingStyle
_style
=
ui
.
PaintingStyle
.
fill
;
...
...
@@ -60,32 +44,37 @@ class CkPaint extends ResurrectableSkiaObject implements ui.Paint {
double
get
strokeWidth
=>
_strokeWidth
;
@override
set
strokeWidth
(
double
value
)
{
if
(
_strokeWidth
==
value
)
{
return
;
}
_strokeWidth
=
value
;
_syncStrokeWidth
(
skiaObject
);
}
void
_syncStrokeWidth
(
js
.
JsObject
object
)
{
object
.
callMethod
(
'setStrokeWidth'
,
<
double
>[
strokeWidth
]);
_skPaint
.
setStrokeWidth
(
value
);
}
double
_strokeWidth
=
0.0
;
// TODO(yjbanov): implement
@override
ui
.
StrokeCap
get
strokeCap
=>
_strokeCap
;
@override
set
strokeCap
(
ui
.
StrokeCap
value
)
{
if
(
_strokeCap
==
value
)
{
return
;
}
_strokeCap
=
value
;
_skPaint
.
setStrokeCap
(
toSkStrokeCap
(
value
));
}
ui
.
StrokeCap
_strokeCap
=
ui
.
StrokeCap
.
butt
;
// TODO(yjbanov): implement
@override
ui
.
StrokeJoin
get
strokeJoin
=>
_strokeJoin
;
@override
set
strokeJoin
(
ui
.
StrokeJoin
value
)
{
if
(
_strokeJoin
==
value
)
{
return
;
}
_strokeJoin
=
value
;
_skPaint
.
setStrokeJoin
(
toSkStrokeJoin
(
value
));
}
ui
.
StrokeJoin
_strokeJoin
=
ui
.
StrokeJoin
.
miter
;
...
...
@@ -94,12 +83,11 @@ class CkPaint extends ResurrectableSkiaObject implements ui.Paint {
bool
get
isAntiAlias
=>
_isAntiAlias
;
@override
set
isAntiAlias
(
bool
value
)
{
if
(
_isAntiAlias
==
value
)
{
return
;
}
_isAntiAlias
=
value
;
_syncAntiAlias
(
skiaObject
);
}
void
_syncAntiAlias
(
js
.
JsObject
object
)
{
object
.
callMethod
(
'setAntiAlias'
,
<
bool
>[
_isAntiAlias
]);
_skPaint
.
setAntiAlias
(
value
);
}
bool
_isAntiAlias
=
true
;
...
...
@@ -108,14 +96,11 @@ class CkPaint extends ResurrectableSkiaObject implements ui.Paint {
ui
.
Color
get
color
=>
_color
;
@override
set
color
(
ui
.
Color
value
)
{
if
(
_color
==
value
)
{
return
;
}
_color
=
value
;
_syncColor
(
skiaObject
);
}
void
_syncColor
(
js
.
JsObject
object
)
{
object
.
callMethod
(
'setColorInt'
,
<
int
>[
_color
.
value
,
]);
_skPaint
.
setColorInt
(
value
.
value
);
}
ui
.
Color
_color
=
_defaultPaintColor
;
...
...
@@ -134,16 +119,11 @@ class CkPaint extends ResurrectableSkiaObject implements ui.Paint {
ui
.
Shader
?
get
shader
=>
_shader
as
ui
.
Shader
?;
@override
set
shader
(
ui
.
Shader
?
value
)
{
_shader
=
value
as
EngineShader
?;
_syncShader
(
skiaObject
);
}
void
_syncShader
(
js
.
JsObject
object
)
{
js
.
JsObject
?
skShader
;
if
(
_shader
!=
null
)
{
skShader
=
_shader
!.
createSkiaShader
();
if
(
_shader
==
value
)
{
return
;
}
object
.
callMethod
(
'setShader'
,
<
js
.
JsObject
?>[
skShader
]);
_shader
=
value
as
EngineShader
?;
_skPaint
.
setShader
(
_shader
?.
createSkiaShader
());
}
EngineShader
?
_shader
;
...
...
@@ -152,48 +132,33 @@ class CkPaint extends ResurrectableSkiaObject implements ui.Paint {
ui
.
MaskFilter
?
get
maskFilter
=>
_maskFilter
;
@override
set
maskFilter
(
ui
.
MaskFilter
?
value
)
{
if
(
value
==
_maskFilter
)
{
return
;
}
_maskFilter
=
value
;
_syncMaskFilter
(
skiaObject
);
}
void
_syncMaskFilter
(
js
.
JsObject
object
)
{
CkMaskFilter
?
skMaskFilter
;
if
(
_maskFilter
!=
null
)
{
final
ui
.
BlurStyle
blurStyle
=
_maskFilter
!.
webOnlyBlurStyle
;
final
double
sigma
=
_maskFilter
!.
webOnlySigma
;
skMaskFilter
=
CkMaskFilter
.
blur
(
blurStyle
,
sigma
);
if
(
value
!=
null
)
{
_ckMaskFilter
=
CkMaskFilter
.
blur
(
value
.
webOnlyBlurStyle
,
value
.
webOnlySigma
,
);
}
else
{
_ckMaskFilter
=
null
;
}
object
.
callMethod
(
'setMaskFilter'
,
<
js
.
JsObject
?>[
skMaskFilter
?.
skiaObject
]
);
_skPaint
.
setMaskFilter
(
_ckMaskFilter
?.
_skMaskFilter
);
}
ui
.
MaskFilter
?
_maskFilter
;
CkMaskFilter
?
_ckMaskFilter
;
@override
ui
.
FilterQuality
get
filterQuality
=>
_filterQuality
;
@override
set
filterQuality
(
ui
.
FilterQuality
value
)
{
_filterQuality
=
value
;
_syncFilterQuality
(
skiaObject
);
}
void
_syncFilterQuality
(
js
.
JsObject
?
object
)
{
js
.
JsObject
?
skFilterQuality
;
switch
(
_filterQuality
)
{
case
ui
.
FilterQuality
.
none
:
skFilterQuality
=
canvasKit
[
'FilterQuality'
][
'None'
];
break
;
case
ui
.
FilterQuality
.
low
:
skFilterQuality
=
canvasKit
[
'FilterQuality'
][
'Low'
];
break
;
case
ui
.
FilterQuality
.
medium
:
skFilterQuality
=
canvasKit
[
'FilterQuality'
][
'Medium'
];
break
;
case
ui
.
FilterQuality
.
high
:
skFilterQuality
=
canvasKit
[
'FilterQuality'
][
'High'
];
break
;
if
(
_filterQuality
==
value
)
{
return
;
}
object
!.
callMethod
(
'setFilterQuality'
,
<
js
.
JsObject
?>[
skFilterQuality
]);
_filterQuality
=
value
;
_skPaint
.
setFilterQuality
(
toSkFilterQuality
(
value
));
}
ui
.
FilterQuality
_filterQuality
=
ui
.
FilterQuality
.
none
;
...
...
@@ -202,27 +167,27 @@ class CkPaint extends ResurrectableSkiaObject implements ui.Paint {
ui
.
ColorFilter
?
get
colorFilter
=>
_colorFilter
;
@override
set
colorFilter
(
ui
.
ColorFilter
?
value
)
{
_colorFilter
=
value
as
EngineColorFilter
?;
_syncColorFilter
(
skiaObject
);
}
void
_syncColorFilter
(
js
.
JsObject
object
)
{
js
.
JsObject
?
skColorFilterJs
;
if
(
_colorFilter
!=
null
)
{
CkColorFilter
?
skFilter
=
_colorFilter
!.
_toCkColorFilter
();
skColorFilterJs
=
skFilter
!.
skiaObject
;
if
(
_colorFilter
==
value
)
{
return
;
}
object
.
callMethod
(
'setColorFilter'
,
<
js
.
JsObject
?>[
skColorFilterJs
]);
final
EngineColorFilter
?
engineValue
=
value
as
EngineColorFilter
?;
_colorFilter
=
engineValue
;
_ckColorFilter
=
engineValue
?.
_toCkColorFilter
();
_skPaint
.
setColorFilter
(
_ckColorFilter
?.
_skColorFilter
);
}
EngineColorFilter
?
_colorFilter
;
CkColorFilter
?
_ckColorFilter
;
// TODO(yjbanov): implement
@override
double
get
strokeMiterLimit
=>
_strokeMiterLimit
;
@override
set
strokeMiterLimit
(
double
value
)
{
if
(
_strokeMiterLimit
==
value
)
{
return
;
}
_strokeMiterLimit
=
value
;
_skPaint
.
setStrokeMiter
(
value
);
}
double
_strokeMiterLimit
=
0.0
;
...
...
@@ -231,42 +196,38 @@ class CkPaint extends ResurrectableSkiaObject implements ui.Paint {
ui
.
ImageFilter
?
get
imageFilter
=>
_imageFilter
;
@override
set
imageFilter
(
ui
.
ImageFilter
?
value
)
{
_imageFilter
=
value
as
CkImageFilter
?;
_syncImageFilter
(
skiaObject
);
}
void
_syncImageFilter
(
js
.
JsObject
object
)
{
js
.
JsObject
?
imageFilterJs
;
if
(
_imageFilter
!=
null
)
{
imageFilterJs
=
_imageFilter
!.
skiaObject
;
if
(
_imageFilter
==
value
)
{
return
;
}
object
.
callMethod
(
'setImageFilter'
,
<
js
.
JsObject
?>[
imageFilterJs
]);
_imageFilter
=
value
as
CkImageFilter
?;
_skPaint
.
setImageFilter
(
_imageFilter
?.
_skImageFilter
);
}
CkImageFilter
?
_imageFilter
;
late
SkPaint
_skPaint
;
@override
js
.
JsObject
createDefault
()
{
final
obj
=
js
.
JsObject
(
canvasKit
[
'SkPaint'
]);
// Sync fields whose Skia defaults are different from Flutter's.
_syncAntiAlias
(
obj
);
_syncColor
(
obj
);
return
obj
;
_skPaint
=
SkPaint
();
_skPaint
.
setAntiAlias
(
_isAntiAlias
);
_skPaint
.
setColorInt
(
_color
.
value
);
return
_jsObjectWrapper
.
wrapSkPaint
(
_skPaint
);
}
@override
js
.
JsObject
resurrect
()
{
final
obj
=
js
.
JsObject
(
canvasKit
[
'SkPaint'
]
);
_s
yncBlendMode
(
obj
);
_s
yncStyle
(
obj
);
_s
yncStrokeWidth
(
obj
);
_s
yncAntiAlias
(
obj
);
_s
yncColor
(
obj
);
_s
yncShader
(
obj
);
_s
yncMaskFilter
(
obj
);
_s
yncColorFilter
(
obj
);
_s
yncImageFilter
(
obj
);
_s
yncFilterQuality
(
obj
);
return
obj
;
_skPaint
=
SkPaint
(
);
_s
kPaint
.
setBlendMode
(
toSkBlendMode
(
_blendMode
)
);
_s
kPaint
.
setStyle
(
toSkPaintStyle
(
_style
)
);
_s
kPaint
.
setStrokeWidth
(
_strokeWidth
);
_s
kPaint
.
setAntiAlias
(
_isAntiAlias
);
_s
kPaint
.
setColorInt
(
_color
.
value
);
_s
kPaint
.
setShader
(
_shader
?.
createSkiaShader
()
);
_s
kPaint
.
setMaskFilter
(
_ckMaskFilter
?.
_skMaskFilter
);
_s
kPaint
.
setColorFilter
(
_ckColorFilter
?.
_skColorFilter
);
_s
kPaint
.
setImageFilter
(
_imageFilter
?.
_skImageFilter
);
_s
kPaint
.
setFilterQuality
(
toSkFilterQuality
(
_filterQuality
)
);
return
_jsObjectWrapper
.
wrapSkPaint
(
_skPaint
)
;
}
}
lib/web_ui/lib/src/engine/shader.dart
浏览文件 @
c99deb00
...
...
@@ -20,7 +20,7 @@ bool _matrix4IsValid(Float32List matrix4) {
abstract
class
EngineShader
{
/// Create a shader for use in the Skia backend.
js
.
JsObject
?
createSkiaShader
();
SkShader
createSkiaShader
();
}
abstract
class
EngineGradient
implements
ui
.
Gradient
,
EngineShader
{
...
...
@@ -63,7 +63,7 @@ class GradientSweep extends EngineGradient {
final
Float32List
?
matrix4
;
@override
js
.
JsObject
createSkiaShader
()
{
SkShader
createSkiaShader
()
{
throw
UnimplementedError
();
}
}
...
...
@@ -155,18 +155,17 @@ class GradientLinear extends EngineGradient {
}
@override
js
.
JsObject
?
createSkiaShader
()
{
SkShader
createSkiaShader
()
{
assert
(
experimentalUseSkia
);
var
jsColors
=
makeColorList
(
colors
);
return
canvasKit
[
'SkShader'
].
callMethod
(
'MakeLinearGradient'
,
<
dynamic
>[
makeSkPoint
(
from
),
makeSkPoint
(
to
),
return
canvasKitJs
.
SkShader
.
MakeLinearGradient
(
toSkPoint
(
from
),
toSkPoint
(
to
),
jsColors
,
makeSkia
ColorStops
(
colorStops
),
t
ileMode
.
index
,
]
);
toSk
ColorStops
(
colorStops
),
t
oSkTileMode
(
tileMode
)
,
);
}
}
...
...
@@ -211,20 +210,20 @@ class GradientRadial extends EngineGradient {
}
@override
js
.
JsObject
?
createSkiaShader
()
{
SkShader
createSkiaShader
()
{
assert
(
experimentalUseSkia
);
var
jsColors
=
makeColorList
(
colors
);
return
canvasKit
[
'SkShader'
].
callMethod
(
'MakeRadialGradient'
,
<
dynamic
>[
make
SkPoint
(
center
),
return
canvasKit
Js
.
SkShader
.
MakeRadialGradient
(
to
SkPoint
(
center
),
radius
,
jsColors
,
makeSkia
ColorStops
(
colorStops
),
t
ileMode
.
index
,
matrix4
!=
null
?
makeSkMatrixFromFloat32
(
matrix4
)
:
null
,
toSk
ColorStops
(
colorStops
),
t
oSkTileMode
(
tileMode
)
,
matrix4
!=
null
?
toSkMatrixFromFloat32
(
matrix4
!
)
:
null
,
0
,
]
);
);
}
}
...
...
@@ -248,23 +247,22 @@ class GradientConical extends EngineGradient {
}
@override
js
.
JsObject
?
createSkiaShader
()
{
SkShader
createSkiaShader
()
{
assert
(
experimentalUseSkia
);
var
jsColors
=
makeColorList
(
colors
);
return
canvasKit
[
'SkShader'
]
.
callMethod
(
'MakeTwoPointConicalGradient'
,
<
dynamic
>[
makeSkPoint
(
focal
),
return
canvasKitJs
.
SkShader
.
MakeTwoPointConicalGradient
(
toSkPoint
(
focal
),
focalRadius
,
make
SkPoint
(
center
),
to
SkPoint
(
center
),
radius
,
jsColors
,
makeSkia
ColorStops
(
colorStops
),
t
ileMode
.
index
,
matrix4
!=
null
?
makeSkMatrixFromFloat32
(
matrix4
)
:
null
,
toSk
ColorStops
(
colorStops
),
t
oSkTileMode
(
tileMode
)
,
matrix4
!=
null
?
toSkMatrixFromFloat32
(
matrix4
!
)
:
null
,
0
,
]
);
);
}
}
...
...
@@ -293,18 +291,6 @@ class EngineImageFilter implements ui.ImageFilter {
}
}
js
.
JsObject
?
_skTileMode
(
ui
.
TileMode
tileMode
)
{
switch
(
tileMode
)
{
case
ui
.
TileMode
.
clamp
:
return
canvasKit
[
'TileMode'
][
'Clamp'
];
case
ui
.
TileMode
.
repeated
:
return
canvasKit
[
'TileMode'
][
'Repeat'
];
case
ui
.
TileMode
.
mirror
:
default
:
return
canvasKit
[
'TileMode'
][
'Mirror'
];
}
}
/// Backend implementation of [ui.ImageShader].
class
EngineImageShader
implements
ui
.
ImageShader
,
EngineShader
{
EngineImageShader
(
...
...
@@ -316,6 +302,8 @@ class EngineImageShader implements ui.ImageShader, EngineShader {
final
Float64List
matrix4
;
final
CkImage
_skImage
;
js
.
JsObject
?
createSkiaShader
()
=>
_skImage
.
skImage
!.
callMethod
(
'makeShader'
,
<
dynamic
>[
_skTileMode
(
tileModeX
),
_skTileMode
(
tileModeY
)]);
SkShader
createSkiaShader
()
=>
_skImage
.
skImage
.
makeShader
(
toSkTileMode
(
tileModeX
),
toSkTileMode
(
tileModeY
),
);
}
lib/web_ui/test/canvaskit/canvaskit_api_test.dart
浏览文件 @
c99deb00
...
...
@@ -33,6 +33,11 @@ void main() {
_maskFilterTests
();
_colorFilterTests
();
_imageFilterTests
();
_mallocTests
();
_sharedColorTests
();
_toSkPointTests
();
_toSkColorStopsTests
();
_toSkMatrixFromFloat32Tests
();
},
// This test failed on iOS Safari.
// TODO: https://github.com/flutter/flutter/issues/60040
...
...
@@ -258,11 +263,20 @@ void _paintTests() {
paint
.
setAntiAlias
(
true
);
paint
.
setColorInt
(
0x00FFCCAA
);
paint
.
setShader
(
_makeTestShader
());
// TODO(yjbanov): paint.setMaskFilter
paint
.
setMaskFilter
(
canvasKitJs
.
MakeBlurMaskFilter
(
canvasKitJs
.
BlurStyle
.
Outer
,
2.0
,
true
,
));
paint
.
setFilterQuality
(
canvasKitJs
.
FilterQuality
.
High
);
// TODO(yjbanov): paint.setColorFilter
paint
.
setColorFilter
(
canvasKitJs
.
SkColorFilter
.
MakeLinearToSRGBGamma
());
paint
.
setStrokeMiter
(
1.4
);
// TODO(yjbanov): paint.setImageFilter
paint
.
setImageFilter
(
canvasKitJs
.
SkImageFilter
.
MakeBlur
(
1
,
2
,
canvasKitJs
.
TileMode
.
Repeat
,
null
,
));
});
}
...
...
@@ -331,6 +345,104 @@ void _imageFilterTests() {
});
}
void
_mallocTests
(
)
{
test
(
'SkFloat32List'
,
()
{
for
(
int
size
=
0
;
size
<
1000
;
size
++)
{
final
SkFloat32List
skList
=
mallocFloat32List
(
4
);
expect
(
skList
,
isNotNull
);
expect
(
skList
.
toTypedArray
().
length
,
4
);
}
});
}
void
_sharedColorTests
(
)
{
test
(
'toSharedSkColor1'
,
()
{
expect
(
toSharedSkColor1
(
const
ui
.
Color
(
0xAABBCCDD
)),
Float32List
(
4
)
..[
0
]
=
0xBB
/
255.0
..[
1
]
=
0xCC
/
255.0
..[
2
]
=
0xDD
/
255.0
..[
3
]
=
0xAA
/
255.0
,
);
});
test
(
'toSharedSkColor2'
,
()
{
expect
(
toSharedSkColor2
(
const
ui
.
Color
(
0xAABBCCDD
)),
Float32List
(
4
)
..[
0
]
=
0xBB
/
255.0
..[
1
]
=
0xCC
/
255.0
..[
2
]
=
0xDD
/
255.0
..[
3
]
=
0xAA
/
255.0
,
);
});
test
(
'toSharedSkColor3'
,
()
{
expect
(
toSharedSkColor3
(
const
ui
.
Color
(
0xAABBCCDD
)),
Float32List
(
4
)
..[
0
]
=
0xBB
/
255.0
..[
1
]
=
0xCC
/
255.0
..[
2
]
=
0xDD
/
255.0
..[
3
]
=
0xAA
/
255.0
,
);
});
}
void
_toSkPointTests
(
)
{
test
(
'toSkPoint'
,
()
{
expect
(
toSkPoint
(
const
ui
.
Offset
(
4
,
5
)),
Float32List
(
2
)
..[
0
]
=
4.0
..[
1
]
=
5.0
,
);
});
}
void
_toSkColorStopsTests
(
)
{
test
(
'toSkColorStops default'
,
()
{
expect
(
toSkColorStops
(
null
),
Float32List
(
2
)
..[
0
]
=
0
..[
1
]
=
1
,
);
});
test
(
'toSkColorStops custom'
,
()
{
expect
(
toSkColorStops
(<
double
>[
1
,
2
,
3
,
4
]),
Float32List
(
4
)
..[
0
]
=
1
..[
1
]
=
2
..[
2
]
=
3
..[
3
]
=
4
,
);
});
}
void
_toSkMatrixFromFloat32Tests
(
)
{
test
(
'toSkMatrixFromFloat32'
,
()
{
final
Matrix4
matrix
=
Matrix4
.
identity
()
..
translate
(
1
,
2
,
3
)
..
rotateZ
(
4
);
expect
(
toSkMatrixFromFloat32
(
matrix
.
storage
),
Float32List
.
fromList
(<
double
>[
-
0.6536436080932617
,
0.756802499294281
,
1
,
-
0.756802499294281
,
-
0.6536436080932617
,
2
,
-
0.0
,
0
,
1
,
])
);
});
}
final
Uint8List
kTransparentImage
=
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
,
0x08
,
0x06
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录