Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_43355755
engine
提交
185087a6
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,发现更多精彩内容 >>
未验证
提交
185087a6
编写于
6月 27, 2019
作者:
G
Gary Qian
提交者:
GitHub
6月 27, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Manually draw remainder curve for wavy decorations (#9468)
上级
6f7700fc
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
193 addition
and
11 deletion
+193
-11
third_party/txt/src/txt/paragraph.cc
third_party/txt/src/txt/paragraph.cc
+45
-11
third_party/txt/src/txt/paragraph.h
third_party/txt/src/txt/paragraph.h
+9
-0
third_party/txt/tests/paragraph_unittests.cc
third_party/txt/tests/paragraph_unittests.cc
+139
-0
未找到文件。
third_party/txt/src/txt/paragraph.cc
浏览文件 @
185087a6
...
...
@@ -1347,17 +1347,9 @@ void Paragraph::PaintDecorations(SkCanvas* canvas,
break
;
}
case
TextDecorationStyle
::
kWavy
:
{
int
wave_count
=
0
;
double
x_start
=
0
;
double
wavelength
=
underline_thickness
*
record
.
style
().
decoration_thickness_multiplier
;
path
.
moveTo
(
x
,
y
);
while
(
x_start
+
wavelength
*
2
<
width
)
{
path
.
rQuadTo
(
wavelength
,
wave_count
%
2
!=
0
?
wavelength
:
-
wavelength
,
wavelength
*
2
,
0
);
x_start
+=
wavelength
*
2
;
++
wave_count
;
}
ComputeWavyDecoration
(
path
,
x
,
y
,
width
,
underline_thickness
*
record
.
style
().
decoration_thickness_multiplier
);
break
;
}
}
...
...
@@ -1425,6 +1417,48 @@ void Paragraph::PaintDecorations(SkCanvas* canvas,
}
}
void
Paragraph
::
ComputeWavyDecoration
(
SkPath
&
path
,
double
x
,
double
y
,
double
width
,
double
thickness
)
{
int
wave_count
=
0
;
double
x_start
=
0
;
// One full wavelength is 4 * thickness.
double
quarter
=
thickness
;
path
.
moveTo
(
x
,
y
);
double
remaining
=
width
;
while
(
x_start
+
(
quarter
*
2
)
<
width
)
{
path
.
rQuadTo
(
quarter
,
wave_count
%
2
==
0
?
-
quarter
:
quarter
,
quarter
*
2
,
0
);
x_start
+=
quarter
*
2
;
remaining
=
width
-
x_start
;
++
wave_count
;
}
// Manually add a final partial quad for the remaining width that do
// not fit nicely into a half-wavelength.
// The following math is based off of quadratic bezier equations:
//
// * Let P(x) be the equation for the curve.
// * Let P0 = start, P1 = control point, P2 = end
// * P(x) = -2x^2 - 2x
// * P0 = (0, 0)
// * P1 = 2P(0.5) - 0.5 * P0 - 0.5 * P2
// * P2 = P(remaining / (wavelength / 2))
//
// Simplified implementation coursesy of @jim-flar at
// https://github.com/flutter/engine/pull/9468#discussion_r297872739
// Unsimplified original version at
// https://github.com/flutter/engine/pull/9468#discussion_r297879129
double
x1
=
remaining
/
2
;
double
y1
=
remaining
/
2
*
(
wave_count
%
2
==
0
?
-
1
:
1
);
double
x2
=
remaining
;
double
y2
=
(
remaining
-
remaining
*
remaining
/
(
quarter
*
2
))
*
(
wave_count
%
2
==
0
?
-
1
:
1
);
path
.
rQuadTo
(
x1
,
y1
,
x2
,
y2
);
}
void
Paragraph
::
PaintBackground
(
SkCanvas
*
canvas
,
const
PaintRecord
&
record
,
SkPoint
base_offset
)
{
...
...
third_party/txt/src/txt/paragraph.h
浏览文件 @
185087a6
...
...
@@ -253,6 +253,7 @@ class Paragraph {
FRIEND_TEST
(
ParagraphTest
,
RepeatLayoutParagraph
);
FRIEND_TEST
(
ParagraphTest
,
Ellipsize
);
FRIEND_TEST
(
ParagraphTest
,
UnderlineShiftParagraph
);
FRIEND_TEST
(
ParagraphTest
,
WavyDecorationParagraph
);
FRIEND_TEST
(
ParagraphTest
,
SimpleShadow
);
FRIEND_TEST
(
ParagraphTest
,
ComplexShadow
);
FRIEND_TEST
(
ParagraphTest
,
FontFallbackParagraph
);
...
...
@@ -478,6 +479,14 @@ class Paragraph {
const
PaintRecord
&
record
,
SkPoint
base_offset
);
// Computes the beziers for a wavy decoration. The results will be
// applied to path.
void
ComputeWavyDecoration
(
SkPath
&
path
,
double
x
,
double
y
,
double
width
,
double
thickness
);
// Draws the background onto the canvas.
void
PaintBackground
(
SkCanvas
*
canvas
,
const
PaintRecord
&
record
,
...
...
third_party/txt/tests/paragraph_unittests.cc
浏览文件 @
185087a6
...
...
@@ -20,6 +20,7 @@
#include "render_test.h"
#include "third_party/icu/source/common/unicode/unistr.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkPath.h"
#include "txt/font_style.h"
#include "txt/font_weight.h"
#include "txt/paragraph.h"
...
...
@@ -1902,6 +1903,144 @@ TEST_F(ParagraphTest, DecorationsParagraph) {
1.0
);
}
TEST_F
(
ParagraphTest
,
WavyDecorationParagraph
)
{
txt
::
ParagraphStyle
paragraph_style
;
paragraph_style
.
max_lines
=
14
;
paragraph_style
.
text_align
=
TextAlign
::
left
;
txt
::
ParagraphBuilder
builder
(
paragraph_style
,
GetTestFontCollection
());
txt
::
TextStyle
text_style
;
text_style
.
font_families
=
std
::
vector
<
std
::
string
>
(
1
,
"Roboto"
);
text_style
.
font_size
=
26
;
text_style
.
letter_spacing
=
0
;
text_style
.
word_spacing
=
5
;
text_style
.
color
=
SK_ColorBLACK
;
text_style
.
height
=
2
;
text_style
.
decoration
=
TextDecoration
::
kUnderline
|
TextDecoration
::
kOverline
|
TextDecoration
::
kLineThrough
;
text_style
.
decoration_style
=
txt
::
TextDecorationStyle
::
kWavy
;
text_style
.
decoration_color
=
SK_ColorRED
;
text_style
.
decoration_thickness_multiplier
=
1.0
;
builder
.
PushStyle
(
text_style
);
builder
.
AddText
(
u" Otherwise, bad things happen."
);
builder
.
Pop
();
auto
paragraph
=
builder
.
Build
();
paragraph
->
Layout
(
GetTestCanvasWidth
()
-
100
);
paragraph
->
Paint
(
GetCanvas
(),
0
,
0
);
ASSERT_TRUE
(
Snapshot
());
ASSERT_EQ
(
paragraph
->
runs_
.
size
(),
1ull
);
ASSERT_EQ
(
paragraph
->
records_
.
size
(),
1ull
);
for
(
size_t
i
=
0
;
i
<
1
;
++
i
)
{
ASSERT_EQ
(
paragraph
->
records_
[
i
].
style
().
decoration
,
TextDecoration
::
kUnderline
|
TextDecoration
::
kOverline
|
TextDecoration
::
kLineThrough
);
}
ASSERT_EQ
(
paragraph
->
records_
[
0
].
style
().
decoration_style
,
txt
::
TextDecorationStyle
::
kWavy
);
ASSERT_EQ
(
paragraph
->
records_
[
0
].
style
().
decoration_color
,
SK_ColorRED
);
ASSERT_EQ
(
paragraph
->
records_
[
0
].
style
().
decoration_thickness_multiplier
,
1.0
);
SkPath
path0
;
SkPath
canonical_path0
;
paragraph
->
ComputeWavyDecoration
(
path0
,
1
,
1
,
9.56
,
1
);
canonical_path0
.
moveTo
(
1
,
1
);
canonical_path0
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path0
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path0
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path0
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path0
.
rQuadTo
(
0.78
,
-
0.78
,
1.56
,
-
0.3432
);
ASSERT_EQ
(
path0
.
countPoints
(),
canonical_path0
.
countPoints
());
for
(
int
i
=
0
;
i
<
canonical_path0
.
countPoints
();
++
i
)
{
ASSERT_EQ
(
path0
.
getPoint
(
i
).
x
(),
canonical_path0
.
getPoint
(
i
).
x
());
ASSERT_EQ
(
path0
.
getPoint
(
i
).
y
(),
canonical_path0
.
getPoint
(
i
).
y
());
}
SkPath
path1
;
SkPath
canonical_path1
;
paragraph
->
ComputeWavyDecoration
(
path1
,
1
,
1
,
8.35
,
1
);
canonical_path1
.
moveTo
(
1
,
1
);
canonical_path1
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path1
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path1
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path1
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path1
.
rQuadTo
(
0.175
,
-
0.175
,
0.35
,
-
0.28875
);
ASSERT_EQ
(
path1
.
countPoints
(),
canonical_path1
.
countPoints
());
for
(
int
i
=
0
;
i
<
canonical_path1
.
countPoints
();
++
i
)
{
ASSERT_EQ
(
path1
.
getPoint
(
i
).
x
(),
canonical_path1
.
getPoint
(
i
).
x
());
ASSERT_EQ
(
path1
.
getPoint
(
i
).
y
(),
canonical_path1
.
getPoint
(
i
).
y
());
}
SkPath
path2
;
SkPath
canonical_path2
;
paragraph
->
ComputeWavyDecoration
(
path2
,
1
,
1
,
10.59
,
1
);
canonical_path2
.
moveTo
(
1
,
1
);
canonical_path2
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path2
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path2
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path2
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path2
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path2
.
rQuadTo
(
0.295
,
0.295
,
0.59
,
0.41595
);
ASSERT_EQ
(
path2
.
countPoints
(),
canonical_path2
.
countPoints
());
for
(
int
i
=
0
;
i
<
canonical_path2
.
countPoints
();
++
i
)
{
ASSERT_EQ
(
path2
.
getPoint
(
i
).
x
(),
canonical_path2
.
getPoint
(
i
).
x
());
ASSERT_EQ
(
path2
.
getPoint
(
i
).
y
(),
canonical_path2
.
getPoint
(
i
).
y
());
}
SkPath
path3
;
SkPath
canonical_path3
;
paragraph
->
ComputeWavyDecoration
(
path3
,
1
,
1
,
11.2
,
1
);
canonical_path3
.
moveTo
(
1
,
1
);
canonical_path3
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path3
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path3
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path3
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path3
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path3
.
rQuadTo
(
0.6
,
0.6
,
1.2
,
0.48
);
ASSERT_EQ
(
path3
.
countPoints
(),
canonical_path3
.
countPoints
());
for
(
int
i
=
0
;
i
<
canonical_path3
.
countPoints
();
++
i
)
{
ASSERT_EQ
(
path3
.
getPoint
(
i
).
x
(),
canonical_path3
.
getPoint
(
i
).
x
());
ASSERT_EQ
(
path3
.
getPoint
(
i
).
y
(),
canonical_path3
.
getPoint
(
i
).
y
());
}
SkPath
path4
;
SkPath
canonical_path4
;
paragraph
->
ComputeWavyDecoration
(
path4
,
1
,
1
,
12
,
1
);
canonical_path4
.
moveTo
(
1
,
1
);
canonical_path4
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path4
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path4
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path4
.
rQuadTo
(
1
,
1
,
2
,
0
);
canonical_path4
.
rQuadTo
(
1
,
-
1
,
2
,
0
);
canonical_path4
.
rQuadTo
(
1
,
1
,
2
,
0
);
ASSERT_EQ
(
path4
.
countPoints
(),
canonical_path4
.
countPoints
());
for
(
int
i
=
0
;
i
<
canonical_path4
.
countPoints
();
++
i
)
{
ASSERT_EQ
(
path4
.
getPoint
(
i
).
x
(),
canonical_path4
.
getPoint
(
i
).
x
());
ASSERT_EQ
(
path4
.
getPoint
(
i
).
y
(),
canonical_path4
.
getPoint
(
i
).
y
());
}
}
TEST_F
(
ParagraphTest
,
ItalicsParagraph
)
{
txt
::
ParagraphStyle
paragraph_style
;
txt
::
ParagraphBuilder
builder
(
paragraph_style
,
GetTestFontCollection
());
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录