Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_43355755
engine
提交
f49bd050
E
engine
项目概览
weixin_43355755
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
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,发现更多精彩内容 >>
未验证
提交
f49bd050
编写于
6月 01, 2020
作者:
Y
Yegor
提交者:
GitHub
6月 01, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
implement SkPath.computeMetrics (#18667)
* implement SkPath.computeMetrics
上级
175a92b4
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
324 addition
and
157 deletion
+324
-157
lib/web_ui/build.canvaskit.yaml
lib/web_ui/build.canvaskit.yaml
+17
-0
lib/web_ui/build.html.yaml
lib/web_ui/build.html.yaml
+4
-1
lib/web_ui/dev/environment.dart
lib/web_ui/dev/environment.dart
+66
-46
lib/web_ui/dev/test_runner.dart
lib/web_ui/dev/test_runner.dart
+100
-28
lib/web_ui/lib/src/engine/compositor/path.dart
lib/web_ui/lib/src/engine/compositor/path.dart
+11
-2
lib/web_ui/lib/src/engine/compositor/path_metrics.dart
lib/web_ui/lib/src/engine/compositor/path_metrics.dart
+57
-80
lib/web_ui/pubspec.yaml
lib/web_ui/pubspec.yaml
+2
-0
lib/web_ui/test/canvaskit/path_metrics_test.dart
lib/web_ui/test/canvaskit/path_metrics_test.dart
+67
-0
lib/web_ui/test/canvaskit/util_test.dart
lib/web_ui/test/canvaskit/util_test.dart
+0
-0
未找到文件。
lib/web_ui/build.canvaskit.yaml
0 → 100644
浏览文件 @
f49bd050
# Build configuration used by CanvasKit tests. When building for CanvasKit
# we must pass FLUTTER_WEB_USE_SKIA=true to dart2js.
#
# See also `build.html.yaml`.
targets
:
$default
:
builders
:
build_web_compilers|entrypoint
:
options
:
compiler
:
dart2js
dart2js_args
:
-
--no-minify
-
--enable-asserts
-
-DFLUTTER_WEB_USE_SKIA=true
generate_for
:
include
:
-
test/canvaskit/**.dart
lib/web_ui/build.yaml
→
lib/web_ui/build.
html.
yaml
浏览文件 @
f49bd050
# Build configuration used by HTML (non-CanvasKit) tests.
#
# See also `build.canvaskit.yaml`.
targets
:
$default
:
builders
:
...
...
@@ -12,4 +15,4 @@ targets:
-
test/**.dart
exclude
:
-
test/**vm_test.dart
-
test/canvaskit/**.dart
lib/web_ui/dev/environment.dart
浏览文件 @
f49bd050
...
...
@@ -13,6 +13,7 @@ Environment get environment {
_environment
??=
Environment
();
return
_environment
;
}
Environment
_environment
;
/// Contains various environment variables, such as common file paths and command-line options.
...
...
@@ -20,14 +21,26 @@ class Environment {
factory
Environment
()
{
final
io
.
File
self
=
io
.
File
.
fromUri
(
io
.
Platform
.
script
);
final
io
.
Directory
engineSrcDir
=
self
.
parent
.
parent
.
parent
.
parent
.
parent
;
final
io
.
Directory
engineToolsDir
=
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'flutter'
,
'tools'
));
final
io
.
Directory
outDir
=
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'out'
));
final
io
.
Directory
hostDebugUnoptDir
=
io
.
Directory
(
pathlib
.
join
(
outDir
.
path
,
'host_debug_unopt'
));
final
io
.
Directory
dartSdkDir
=
io
.
Directory
(
pathlib
.
join
(
hostDebugUnoptDir
.
path
,
'dart-sdk'
));
final
io
.
Directory
webUiRootDir
=
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'flutter'
,
'lib'
,
'web_ui'
));
final
io
.
Directory
integrationTestsDir
=
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'flutter'
,
'e2etests'
,
'web'
));
for
(
io
.
Directory
expectedDirectory
in
<
io
.
Directory
>[
engineSrcDir
,
outDir
,
hostDebugUnoptDir
,
dartSdkDir
,
webUiRootDir
])
{
final
io
.
Directory
engineToolsDir
=
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'flutter'
,
'tools'
));
final
io
.
Directory
outDir
=
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'out'
));
final
io
.
Directory
hostDebugUnoptDir
=
io
.
Directory
(
pathlib
.
join
(
outDir
.
path
,
'host_debug_unopt'
));
final
io
.
Directory
dartSdkDir
=
io
.
Directory
(
pathlib
.
join
(
hostDebugUnoptDir
.
path
,
'dart-sdk'
));
final
io
.
Directory
webUiRootDir
=
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'flutter'
,
'lib'
,
'web_ui'
));
final
io
.
Directory
integrationTestsDir
=
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'flutter'
,
'e2etests'
,
'web'
));
for
(
io
.
Directory
expectedDirectory
in
<
io
.
Directory
>[
engineSrcDir
,
outDir
,
hostDebugUnoptDir
,
dartSdkDir
,
webUiRootDir
])
{
if
(!
expectedDirectory
.
existsSync
())
{
throw
ToolException
(
'
$expectedDirectory
does not exist.'
);
}
...
...
@@ -89,63 +102,71 @@ class Environment {
String
get
pubExecutable
=>
pathlib
.
join
(
dartSdkDir
.
path
,
'bin'
,
'pub'
);
/// The "dart2js" executable file.
String
get
dart2jsExecutable
=>
pathlib
.
join
(
dartSdkDir
.
path
,
'bin'
,
'dart2js'
);
String
get
dart2jsExecutable
=>
pathlib
.
join
(
dartSdkDir
.
path
,
'bin'
,
'dart2js'
);
/// Path to where github.com/flutter/engine is checked out inside the engine workspace.
io
.
Directory
get
flutterDirectory
=>
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'flutter'
));
io
.
Directory
get
flutterDirectory
=>
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'flutter'
));
io
.
Directory
get
webSdkRootDir
=>
io
.
Directory
(
pathlib
.
join
(
flutterDirectory
.
path
,
'web_sdk'
,
));
flutterDirectory
.
path
,
'web_sdk'
,
));
/// Path to the "web_engine_tester" package.
io
.
Directory
get
webEngineTesterRootDir
=>
io
.
Directory
(
pathlib
.
join
(
webSdkRootDir
.
path
,
'web_engine_tester'
,
));
webSdkRootDir
.
path
,
'web_engine_tester'
,
));
/// Path to the "build" directory, generated by "package:build_runner".
///
/// This is where compiled output goes.
io
.
Directory
get
webUiBuildDir
=>
io
.
Directory
(
pathlib
.
join
(
webUiRootDir
.
path
,
'build'
,
));
webUiRootDir
.
path
,
'build'
,
));
/// Path to the ".dart_tool" directory, generated by various Dart tools.
io
.
Directory
get
webUiDartToolDir
=>
io
.
Directory
(
pathlib
.
join
(
webUiRootDir
.
path
,
'.dart_tool'
,
));
/// Path to the ".dart_tool" directory living under `engine/src/flutter`.
///
/// This is a designated area for tool downloads which can be used by
/// multiple platforms. For exampe: Flutter repo for e2e tests.
webUiRootDir
.
path
,
'.dart_tool'
,
));
/// Path to the ".dart_tool" directory living under `engine/src/flutter`.
///
/// This is a designated area for tool downloads which can be used by
/// multiple platforms. For exampe: Flutter repo for e2e tests.
io
.
Directory
get
engineDartToolDir
=>
io
.
Directory
(
pathlib
.
join
(
engineSrcDir
.
path
,
'flutter'
,
'.dart_tool'
,
));
engineSrcDir
.
path
,
'flutter'
,
'.dart_tool'
,
));
/// Path to the "dev" directory containing engine developer tools and
/// configuration files.
io
.
Directory
get
webUiDevDir
=>
io
.
Directory
(
pathlib
.
join
(
webUiRootDir
.
path
,
'dev'
,
));
webUiRootDir
.
path
,
'dev'
,
));
/// Path to the "test" directory containing web engine tests.
io
.
Directory
get
webUiTestDir
=>
io
.
Directory
(
pathlib
.
join
(
webUiRootDir
.
path
,
'test'
,
));
/// Path to the clone of the flutter/goldens repository.
io
.
Directory
get
webUiGoldensRepositoryDirectory
=>
io
.
Directory
(
pathlib
.
join
(
webUiDartToolDir
.
path
,
'goldens'
,
));
webUiDartToolDir
.
path
,
'goldens'
,
));
/// Path to the script that clones the Flutter repo.
io
.
File
get
cloneFlutterScript
=>
io
.
File
(
pathlib
.
join
(
engineToolsDir
.
path
,
'clone_flutter.sh'
,
));
engineToolsDir
.
path
,
'clone_flutter.sh'
,
));
/// Path to flutter.
///
...
...
@@ -153,10 +174,9 @@ class Environment {
///
/// Only use [cloneFlutterScript] to clone flutter to the engine build.
io
.
File
get
flutterCommand
=>
io
.
File
(
pathlib
.
join
(
engineDartToolDir
.
path
,
'flutter'
,
'bin'
,
'flutter'
,
));
engineDartToolDir
.
path
,
'flutter'
,
'bin'
,
'flutter'
,
));
}
lib/web_ui/dev/test_runner.dart
浏览文件 @
f49bd050
...
...
@@ -57,17 +57,17 @@ class TestCommand extends Command<bool> with ArgUtils {
'tests.'
,
)
..
addFlag
(
'use-system-flutter'
,
defaultsTo:
false
,
help:
'integration tests are using flutter repository for various tasks'
', such as flutter drive, flutter pub get. If this flag is set, felt
'
'will use flutter command without cloning the repository. This flag
'
'can save internet bandwidth. However use with caution. Note that
'
'since flutter repo is always synced to youngest commit older than
'
'the engine commit for the tests running in CI, the tests results
'
'won
\'
t be consistent with CIs when this flag is set. flutter
'
'command should be set in the PATH for this flag to be useful.
'
'This flag can also be used to test local Flutter changes
.'
)
defaultsTo:
false
,
help:
'integration tests are using flutter repository for various tasks
'
', such as flutter drive, flutter pub get. If this flag is set, felt
'
'will use flutter command without cloning the repository. This flag
'
'can save internet bandwidth. However use with caution. Note that
'
'since flutter repo is always synced to youngest commit older than
'
'the engine commit for the tests running in CI, the tests results
'
'won
\'
t be consistent with CIs when this flag is set. flutter
'
'command should be set in the PATH for this flag to be useful
.'
'This flag can also be used to test local Flutter changes.'
)
..
addFlag
(
'update-screenshot-goldens'
,
defaultsTo:
false
,
...
...
@@ -159,8 +159,6 @@ class TestCommand extends Command<bool> with ArgUtils {
await
_runPubGet
();
}
await
_buildTests
(
targets:
targetFiles
);
// Many tabs will be left open after Safari runs, quit Safari during
// cleanup.
if
(
browser
==
'safari'
)
{
...
...
@@ -180,14 +178,57 @@ class TestCommand extends Command<bool> with ArgUtils {
});
}
await
_buildTargets
();
if
(
runAllTests
)
{
await
_runAllTests
();
await
_runAllTests
ForCurrentPlatform
();
}
else
{
await
_run
Target
Tests
(
targetFiles
);
await
_run
Specific
Tests
(
targetFiles
);
}
return
true
;
}
/// Builds all test targets that will be run.
Future
<
void
>
_buildTargets
()
async
{
final
Stopwatch
stopwatch
=
Stopwatch
()..
start
();
List
<
FilePath
>
allTargets
;
if
(
runAllTests
)
{
allTargets
=
environment
.
webUiTestDir
.
listSync
(
recursive:
true
)
.
whereType
<
io
.
File
>()
.
where
((
io
.
File
f
)
=>
f
.
path
.
endsWith
(
'_test.dart'
))
.
map
<
FilePath
>((
io
.
File
f
)
=>
FilePath
.
fromWebUi
(
path
.
relative
(
f
.
path
,
from:
environment
.
webUiRootDir
.
path
)))
.
toList
();
}
else
{
allTargets
=
targetFiles
;
}
// Separate HTML targets from CanvasKit targets because the two use
// different dart2js options (and different build.*.yaml files).
final
List
<
FilePath
>
htmlTargets
=
<
FilePath
>[];
final
List
<
FilePath
>
canvasKitTargets
=
<
FilePath
>[];
final
String
canvasKitTestDirectory
=
path
.
join
(
environment
.
webUiTestDir
.
path
,
'canvaskit'
);
for
(
FilePath
target
in
allTargets
)
{
if
(
path
.
isWithin
(
canvasKitTestDirectory
,
target
.
absolute
))
{
canvasKitTargets
.
add
(
target
);
}
else
{
htmlTargets
.
add
(
target
);
}
}
if
(
htmlTargets
.
isNotEmpty
)
{
await
_buildTests
(
targets:
htmlTargets
,
forCanvasKit:
false
);
}
if
(
canvasKitTargets
.
isNotEmpty
)
{
await
_buildTests
(
targets:
canvasKitTargets
,
forCanvasKit:
true
);
}
stopwatch
.
stop
();
print
(
'The build took
${stopwatch.elapsedMilliseconds ~/ 1000}
seconds.'
);
}
/// Whether to start the browser in debug mode.
///
/// In this mode the browser pauses before running the test to allow
...
...
@@ -222,12 +263,18 @@ class TestCommand extends Command<bool> with ArgUtils {
/// ".dart_tool/goldens".
bool
get
doUpdateScreenshotGoldens
=>
boolArg
(
'update-screenshot-goldens'
);
Future
<
void
>
_runTargetTests
(
List
<
FilePath
>
targets
)
async
{
/// Runs all tests specified in [targets].
///
/// Unlike [_runAllTestsForCurrentPlatform], this does not filter targets
/// by platform/browser capabilites, and instead attempts to run all of
/// them.
Future
<
void
>
_runSpecificTests
(
List
<
FilePath
>
targets
)
async
{
await
_runTestBatch
(
targets
,
concurrency:
1
,
expectFailure:
false
);
_checkExitCode
();
}
Future
<
void
>
_runAllTests
()
async
{
/// Runs as many tests as possible on the current OS/browser combination.
Future
<
void
>
_runAllTestsForCurrentPlatform
()
async
{
final
io
.
Directory
testDir
=
io
.
Directory
(
path
.
join
(
environment
.
webUiRootDir
.
path
,
'test'
,
...
...
@@ -373,21 +420,34 @@ class TestCommand extends Command<bool> with ArgUtils {
timestampFile
.
writeAsStringSync
(
timestamp
);
}
Future
<
void
>
_buildTests
({
List
<
FilePath
>
targets
})
async
{
/// Builds the specific test [targets].
///
/// [targets] must not be null.
///
/// When building for CanvasKit we have to use a separate `build.canvaskit.yaml`
/// config file. Otherwise, `build.html.yaml` is used. Because `build_runner`
/// overwrites the output directories, we redirect the CanvasKit output to a
/// separate directory, then copy the files back to `build/test`.
Future
<
void
>
_buildTests
({
List
<
FilePath
>
targets
,
bool
forCanvasKit
})
async
{
print
(
'Building
${targets.length}
targets for
${forCanvasKit ? 'CanvasKit' : 'HTML'}
'
);
final
String
canvasKitOutputRelativePath
=
path
.
join
(
'.dart_tool'
,
'canvaskit_tests'
);
List
<
String
>
arguments
=
<
String
>[
'run'
,
'build_runner'
,
'build'
,
'test'
,
'-o'
,
'build'
,
if
(
targets
!=
null
)
for
(
FilePath
path
in
targets
)
...[
'--build-filter=
${path.relativeToWebUi}
.js'
,
'--build-filter=
${path.relativeToWebUi}
.browser_test.dart.js'
,
],
forCanvasKit
?
canvasKitOutputRelativePath
:
'build'
,
'--config'
,
// CanvasKit uses `build.canvaskit.yaml`, which HTML Uses `build.html.yaml`.
forCanvasKit
?
'canvaskit'
:
'html'
,
for
(
FilePath
path
in
targets
)
...[
'--build-filter=
${path.relativeToWebUi}
.js'
,
'--build-filter=
${path.relativeToWebUi}
.browser_test.dart.js'
,
],
];
final
Stopwatch
stopwatch
=
Stopwatch
()..
start
();
final
int
exitCode
=
await
runProcess
(
environment
.
pubExecutable
,
...
...
@@ -401,16 +461,28 @@ class TestCommand extends Command<bool> with ArgUtils {
// In a testing on a 32-core 132GB workstation increasing this number to
// 32 sped up the build from ~4min to ~1.5min.
if
(
io
.
Platform
.
environment
.
containsKey
(
'BUILD_MAX_WORKERS_PER_TASK'
))
'BUILD_MAX_WORKERS_PER_TASK'
:
io
.
Platform
.
environment
[
'BUILD_MAX_WORKERS_PER_TASK'
],
'BUILD_MAX_WORKERS_PER_TASK'
:
io
.
Platform
.
environment
[
'BUILD_MAX_WORKERS_PER_TASK'
],
},
);
stopwatch
.
stop
();
print
(
'The build took
${stopwatch.elapsedMilliseconds ~/ 1000}
seconds.'
);
if
(
exitCode
!=
0
)
{
throw
ToolException
(
'Failed to compile tests. Compiler exited with exit code
$exitCode
'
);
}
if
(
forCanvasKit
)
{
final
io
.
Directory
canvasKitTemporaryOutputDirectory
=
io
.
Directory
(
path
.
join
(
environment
.
webUiRootDir
.
path
,
canvasKitOutputRelativePath
,
'test'
,
'canvaskit'
));
final
io
.
Directory
canvasKitOutputDirectory
=
io
.
Directory
(
path
.
join
(
environment
.
webUiBuildDir
.
path
,
'test'
,
'canvaskit'
));
if
(
await
canvasKitOutputDirectory
.
exists
())
{
await
canvasKitOutputDirectory
.
delete
(
recursive:
true
);
}
await
canvasKitTemporaryOutputDirectory
.
rename
(
canvasKitOutputDirectory
.
path
);
}
}
/// Runs a batch of tests.
...
...
lib/web_ui/lib/src/engine/compositor/path.dart
浏览文件 @
f49bd050
...
...
@@ -11,13 +11,17 @@ part of engine;
class
SkPath
implements
ui
.
Path
{
js
.
JsObject
_skPath
;
/// Cached constructor function for `SkPath`, so we don't have to look it up
/// every time we construct a new path.
static
final
js
.
JsFunction
_skPathConstructor
=
canvasKit
[
'SkPath'
];
SkPath
()
{
_skPath
=
js
.
JsObject
(
canvasKit
[
'SkPath'
]
);
_skPath
=
js
.
JsObject
(
_skPathConstructor
);
fillType
=
ui
.
PathFillType
.
nonZero
;
}
SkPath
.
from
(
SkPath
other
)
{
_skPath
=
js
.
JsObject
(
canvasKit
[
'SkPath'
]
,
<
js
.
JsObject
>[
other
.
_skPath
]);
_skPath
=
js
.
JsObject
(
_skPathConstructor
,
<
js
.
JsObject
>[
other
.
_skPath
]);
fillType
=
other
.
fillType
;
}
...
...
@@ -323,4 +327,9 @@ class SkPath implements ui.Path {
String
toSvgString
()
{
return
_skPath
.
callMethod
(
'toSVGString'
);
}
/// Return `true` if this path contains no segments.
bool
get
isEmpty
{
return
_skPath
.
callMethod
(
'isEmpty'
);
}
}
lib/web_ui/lib/src/engine/compositor/path_metrics.dart
浏览文件 @
f49bd050
...
...
@@ -7,120 +7,97 @@ part of engine;
class
SkPathMetrics
extends
IterableBase
<
ui
.
PathMetric
>
implements
ui
.
PathMetrics
{
SkPathMetrics
(
SkPath
path
,
bool
forceClosed
)
:
_iterator
=
SkPathMetricIterator
.
_
(
_SkPathMeasure
(
path
,
forceClosed
));
SkPathMetrics
(
this
.
_path
,
this
.
_forceClosed
);
final
Iterator
<
ui
.
PathMetric
>
_iterator
;
final
SkPath
_path
;
final
bool
_forceClosed
;
/// The [SkPath.isEmpty] case is special-cased to avoid booting the WASM machinery just to find out there are no contours.
@override
Iterator
<
ui
.
PathMetric
>
get
iterator
=>
_
iterator
;
Iterator
<
ui
.
PathMetric
>
get
iterator
=>
_
path
.
isEmpty
?
const
SkPathMetricIteratorEmpty
.
_
()
:
SkContourMeasureIter
(
_path
,
_forceClosed
)
;
}
class
SkPathMetricIterator
implements
Iterator
<
ui
.
PathMetric
>
{
SkPathMetricIterator
.
_
(
this
.
_pathMeasure
)
:
assert
(
_pathMeasure
!=
null
);
class
SkContourMeasureIter
implements
Iterator
<
ui
.
PathMetric
>
{
/// Cached constructor function for `SkContourMeasureIter`, so we don't have to look it
/// up every time we're constructing a new instance.
static
final
js
.
JsFunction
_skContourMeasureIterConstructor
=
canvasKit
[
'SkContourMeasureIter'
];
_SkPathMetric
_pathMetric
;
_SkPathMeasure
_pathMeasure
;
SkContourMeasureIter
(
SkPath
path
,
bool
forceClosed
)
:
_skObject
=
js
.
JsObject
(
_skContourMeasureIterConstructor
,
<
dynamic
>[
path
.
_skPath
,
forceClosed
,
1
,
]);
/// The JavaScript `SkContourMeasureIter` object.
final
js
.
JsObject
_skObject
;
/// A monotonically increasing counter used to generate [ui.PathMetric.contourIndex].
///
/// CanvasKit does not supply the contour index. We have to add it ourselves.
int
_contourIndexCounter
=
0
;
@override
ui
.
PathMetric
get
current
=>
_pathMetric
;
ui
.
PathMetric
get
current
=>
_current
;
SkContourMeasure
_current
;
@override
bool
moveNext
()
{
if
(
_pathMeasure
.
_nextContour
())
{
_pathMetric
=
_SkPathMetric
.
_
(
_pathMeasure
);
return
true
;
final
js
.
JsObject
skContourMeasure
=
_skObject
.
callMethod
(
'next'
);
if
(
skContourMeasure
==
null
)
{
_current
=
null
;
return
false
;
}
_pathMetric
=
null
;
return
false
;
_current
=
SkContourMeasure
(
_contourIndexCounter
,
skContourMeasure
);
_contourIndexCounter
+=
1
;
return
true
;
}
}
class
_SkPathMetric
implements
ui
.
PathMetric
{
_SkPathMetric
.
_
(
this
.
_measure
)
:
assert
(
_measure
!=
null
),
length
=
_measure
.
length
(
_measure
.
currentContourIndex
),
isClosed
=
_measure
.
isClosed
(
_measure
.
currentContourIndex
),
contourIndex
=
_measure
.
currentContourIndex
;
class
SkContourMeasure
implements
ui
.
PathMetric
{
SkContourMeasure
(
this
.
contourIndex
,
this
.
_skObject
);
@override
final
double
length
;
@override
final
bool
isClosed
;
final
js
.
JsObject
_skObject
;
@override
final
int
contourIndex
;
final
_SkPathMeasure
_measure
;
@override
ui
.
Tangent
getTangentForOffset
(
double
distance
)
{
return
_measure
.
getTangentForOffset
(
contourIndex
,
distance
);
}
@override
ui
.
Path
extractPath
(
double
start
,
double
end
,
{
bool
startWithMoveTo
=
true
})
{
return
_measure
.
extractPath
(
contourIndex
,
start
,
end
,
startWithMoveTo:
startWithMoveTo
);
final
js
.
JsObject
skPath
=
_skObject
.
callMethod
(
'getSegment'
,
<
dynamic
>[
start
,
end
,
startWithMoveTo
]);
return
SkPath
.
_fromSkPath
(
skPath
);
}
@override
String
toString
()
=>
'PathMetric{length:
$length
, isClosed:
$isClosed
, '
'contourIndex:
$contourIndex
}'
;
}
class
_SkPathMeasure
{
_SkPathMeasure
(
SkPath
path
,
bool
forceClosed
)
{
currentContourIndex
=
-
1
;
pathMeasure
=
js
.
JsObject
(
canvasKit
[
'SkPathMeasure'
],
<
dynamic
>[
path
.
_skPath
,
forceClosed
,
1
,
]);
}
js
.
JsObject
pathMeasure
;
double
length
(
int
contourIndex
)
{
assert
(
contourIndex
==
currentContourIndex
,
'PathMetrics are invalid if it is not the current contour.'
);
return
pathMeasure
.
callMethod
(
'getLength'
);
}
ui
.
Tangent
getTangentForOffset
(
int
contourIndex
,
double
distance
)
{
assert
(
contourIndex
==
currentContourIndex
,
'PathMetrics are invalid if it is not the current contour.'
);
final
js
.
JsObject
posTan
=
pathMeasure
.
callMethod
(
'getPosTan'
,
<
double
>[
distance
]);
ui
.
Tangent
getTangentForOffset
(
double
distance
)
{
final
js
.
JsObject
posTan
=
_skObject
.
callMethod
(
'getPosTan'
,
<
double
>[
distance
]);
return
ui
.
Tangent
(
ui
.
Offset
(
posTan
[
0
],
posTan
[
1
]),
ui
.
Offset
(
posTan
[
2
],
posTan
[
3
]),
);
}
ui
.
Path
extractPath
(
int
contourIndex
,
double
start
,
double
end
,
{
bool
startWithMoveTo
=
true
})
{
assert
(
contourIndex
==
currentContourIndex
,
'PathMetrics are invalid if it is not the current contour.'
);
final
js
.
JsObject
skPath
=
pathMeasure
.
callMethod
(
'getSegment'
,
<
dynamic
>[
start
,
end
,
startWithMoveTo
]);
return
SkPath
.
_fromSkPath
(
skPath
);
@override
bool
get
isClosed
{
return
_skObject
.
callMethod
(
'isClosed'
);
}
bool
isClosed
(
int
contourIndex
)
{
assert
(
contourIndex
==
currentContourIndex
,
'PathMetrics are invalid if it is not the current contour.'
);
return
pathMeasure
.
callMethod
(
'isClosed'
);
@override
double
get
length
{
return
_skObject
.
callMethod
(
'length'
);
}
}
bool
_nextContour
()
{
final
bool
next
=
pathMeasure
.
callMethod
(
'nextContour'
);
if
(
next
)
{
currentContourIndex
++;
}
return
next
;
}
class
SkPathMetricIteratorEmpty
implements
Iterator
<
ui
.
PathMetric
>
{
const
SkPathMetricIteratorEmpty
.
_
();
@override
ui
.
PathMetric
get
current
=>
null
;
int
currentContourIndex
;
@override
bool
moveNext
()
{
return
false
;
}
}
lib/web_ui/pubspec.yaml
浏览文件 @
f49bd050
...
...
@@ -17,6 +17,8 @@ dev_dependencies:
build_runner
:
1.7.2
build_test
:
1.0.0
build_web_compilers
:
2.7.1
# TODO(yjbanov): the Dart SDK complains about nonVirtual for some reason.
petitparser
:
3.0.2
yaml
:
2.2.0
watcher
:
0.9.7+12
web_engine_tester
:
...
...
lib/web_ui/test/canvaskit/path_metrics_test.dart
0 → 100644
浏览文件 @
f49bd050
// 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
import
'package:test/test.dart'
;
import
'package:ui/src/engine.dart'
;
import
'package:ui/ui.dart'
as
ui
;
void
main
(
)
{
setUpAll
(()
async
{
await
ui
.
webOnlyInitializePlatform
();
});
test
(
'Using CanvasKit'
,
()
{
expect
(
experimentalUseSkia
,
true
);
});
test
(
SkPathMetrics
,
()
{
final
ui
.
Path
path
=
ui
.
Path
();
expect
(
path
,
isA
<
SkPath
>());
expect
(
path
.
computeMetrics
().
length
,
0
);
path
.
addRect
(
ui
.
Rect
.
fromLTRB
(
0
,
0
,
10
,
10
));
final
ui
.
PathMetric
metric
=
path
.
computeMetrics
().
single
;
expect
(
metric
.
contourIndex
,
0
);
expect
(
metric
.
extractPath
(
0
,
0.5
).
computeMetrics
().
length
,
1
);
final
ui
.
Tangent
tangent1
=
metric
.
getTangentForOffset
(
5
);
expect
(
tangent1
.
position
,
ui
.
Offset
(
5
,
0
));
expect
(
tangent1
.
vector
,
ui
.
Offset
(
1
,
0
));
final
ui
.
Tangent
tangent2
=
metric
.
getTangentForOffset
(
15
);
expect
(
tangent2
.
position
,
ui
.
Offset
(
10
,
5
));
expect
(
tangent2
.
vector
,
ui
.
Offset
(
0
,
1
));
expect
(
metric
.
isClosed
,
true
);
path
.
addOval
(
ui
.
Rect
.
fromLTRB
(
10
,
10
,
100
,
100
));
expect
(
path
.
computeMetrics
().
length
,
2
);
// Path metrics can be iterated over multiple times.
final
ui
.
PathMetrics
metrics
=
path
.
computeMetrics
();
expect
(
metrics
.
toList
().
length
,
2
);
expect
(
metrics
.
toList
().
length
,
2
);
expect
(
metrics
.
toList
().
length
,
2
);
// Can simultaneously iterate over multiple metrics from the same path.
final
ui
.
PathMetrics
metrics1
=
path
.
computeMetrics
();
final
ui
.
PathMetrics
metrics2
=
path
.
computeMetrics
();
final
Iterator
<
ui
.
PathMetric
>
iter1
=
metrics1
.
iterator
;
final
Iterator
<
ui
.
PathMetric
>
iter2
=
metrics2
.
iterator
;
expect
(
iter1
.
moveNext
(),
true
);
expect
(
iter2
.
moveNext
(),
true
);
expect
(
iter1
.
current
,
isNotNull
);
expect
(
iter2
.
current
,
isNotNull
);
expect
(
iter1
.
moveNext
(),
true
);
expect
(
iter2
.
moveNext
(),
true
);
expect
(
iter1
.
current
,
isNotNull
);
expect
(
iter2
.
current
,
isNotNull
);
expect
(
iter1
.
moveNext
(),
false
);
expect
(
iter2
.
moveNext
(),
false
);
expect
(
iter1
.
current
,
isNull
);
expect
(
iter2
.
current
,
isNull
);
});
}
lib/web_ui/test/
engine/compositor
/util_test.dart
→
lib/web_ui/test/
canvaskit
/util_test.dart
浏览文件 @
f49bd050
文件已移动
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录