Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_43355755
engine
提交
186f1158
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,体验更适合开发者的 AI 搜索 >>
提交
186f1158
编写于
3月 15, 2017
作者:
T
TreeHugger Robot
提交者:
Android (Google) Code Review
3月 15, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge "In greedy line breaking, repeat breaks until the line fits"
上级
f698f16c
67d1601c
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
50 addition
and
12 deletion
+50
-12
include/minikin/LineBreaker.h
include/minikin/LineBreaker.h
+4
-2
libs/minikin/LineBreaker.cpp
libs/minikin/LineBreaker.cpp
+46
-10
未找到文件。
include/minikin/LineBreaker.h
浏览文件 @
186f1158
...
...
@@ -191,8 +191,8 @@ class LineBreaker {
struct
Candidate
{
size_t
offset
;
// offset to text buffer, in code units
size_t
prev
;
// index to previous break
ParaWidth
preBreak
;
ParaWidth
postBreak
;
ParaWidth
preBreak
;
// width of text until this point, if we decide to not break here
ParaWidth
postBreak
;
// width of text until this point, if we decide to break here
float
penalty
;
// penalty of this break (for example, hyphen penalty)
float
score
;
// best score found for this break
size_t
lineNumber
;
// only updated for non-constant line widths
...
...
@@ -207,6 +207,7 @@ class LineBreaker {
size_t
preSpaceCount
,
size_t
postSpaceCount
,
float
penalty
,
HyphenationType
hyph
);
void
addCandidate
(
Candidate
cand
);
void
pushGreedyBreak
();
// push an actual break to the output. Takes care of setting flags for tab
void
pushBreak
(
int
offset
,
float
width
,
uint8_t
hyphenEdit
);
...
...
@@ -248,6 +249,7 @@ class LineBreaker {
size_t
mBestBreak
;
float
mBestScore
;
ParaWidth
mPreBreak
;
// prebreak of last break
uint32_t
mLastHyphenation
;
// hyphen edit of last break kept for next line
int
mFirstTabIndex
;
size_t
mSpaceCount
;
};
...
...
libs/minikin/LineBreaker.cpp
浏览文件 @
186f1158
...
...
@@ -84,6 +84,7 @@ void LineBreaker::setText() {
mBestBreak
=
0
;
mBestScore
=
SCORE_INFTY
;
mPreBreak
=
0
;
mLastHyphenation
=
HyphenEdit
::
NO_EDIT
;
mFirstTabIndex
=
INT_MAX
;
mSpaceCount
=
0
;
}
...
...
@@ -269,24 +270,59 @@ void LineBreaker::addWordBreak(size_t offset, ParaWidth preBreak, ParaWidth post
addCandidate
(
cand
);
}
// Helper method for addCandidate()
void
LineBreaker
::
pushGreedyBreak
()
{
const
Candidate
&
bestCandidate
=
mCandidates
[
mBestBreak
];
pushBreak
(
bestCandidate
.
offset
,
bestCandidate
.
postBreak
-
mPreBreak
,
mLastHyphenation
|
HyphenEdit
::
editForThisLine
(
bestCandidate
.
hyphenType
));
mBestScore
=
SCORE_INFTY
;
#if VERBOSE_DEBUG
ALOGD
(
"break: %d %g"
,
mBreaks
.
back
(),
mWidths
.
back
());
#endif
mLastBreak
=
mBestBreak
;
mPreBreak
=
bestCandidate
.
preBreak
;
mLastHyphenation
=
HyphenEdit
::
editForNextLine
(
bestCandidate
.
hyphenType
);
}
// TODO performance: could avoid populating mCandidates if greedy only
void
LineBreaker
::
addCandidate
(
Candidate
cand
)
{
size_t
candIndex
=
mCandidates
.
size
();
const
size_t
candIndex
=
mCandidates
.
size
();
mCandidates
.
push_back
(
cand
);
// mLastBreak is the index of the last line break we decided to do in mCandidates,
// and mPreBreak is its preBreak value. mBestBreak is the index of the best line breaking candidate
// we have found since then, and mBestScore is its penalty.
if
(
cand
.
postBreak
-
mPreBreak
>
currentLineWidth
())
{
// This break would create an overfull line, pick the best break and break there (greedy)
if
(
mBestBreak
==
mLastBreak
)
{
// No good break has been found since last break. Break here.
mBestBreak
=
candIndex
;
}
pushBreak
(
mCandidates
[
mBestBreak
].
offset
,
mCandidates
[
mBestBreak
].
postBreak
-
mPreBreak
,
HyphenEdit
::
editForThisLine
(
mCandidates
[
mBestBreak
].
hyphenType
));
mBestScore
=
SCORE_INFTY
;
#if VERBOSE_DEBUG
ALOGD
(
"break: %d %g"
,
mBreaks
.
back
(),
mWidths
.
back
());
#endif
mLastBreak
=
mBestBreak
;
mPreBreak
=
mCandidates
[
mBestBreak
].
preBreak
;
pushGreedyBreak
();
}
while
(
mLastBreak
!=
candIndex
&&
cand
.
postBreak
-
mPreBreak
>
currentLineWidth
())
{
// We should rarely come here. But if we are here, we have broken the line, but the
// remaining part still doesn't fit. We now need to break at the second best place after the
// last break, but we have not kept that information, so we need to go back and find it.
//
// In some really rare cases, postBreak - preBreak of a candidate itself may be over the
// current line width. We protect ourselves against an infinite loop in that case by
// checking that we have not broken the line at this candidate already.
for
(
size_t
i
=
mLastBreak
+
1
;
i
<
candIndex
;
i
++
)
{
const
float
penalty
=
mCandidates
[
i
].
penalty
;
if
(
penalty
<=
mBestScore
)
{
mBestBreak
=
i
;
mBestScore
=
penalty
;
}
}
if
(
mBestBreak
==
mLastBreak
)
{
// We didn't find anything good. Break here.
mBestBreak
=
candIndex
;
}
pushGreedyBreak
();
}
if
(
cand
.
penalty
<=
mBestScore
)
{
mBestBreak
=
candIndex
;
mBestScore
=
cand
.
penalty
;
...
...
@@ -329,7 +365,7 @@ void LineBreaker::computeBreaksGreedy() {
size_t
nCand
=
mCandidates
.
size
();
if
(
nCand
==
1
||
mLastBreak
!=
nCand
-
1
)
{
pushBreak
(
mCandidates
[
nCand
-
1
].
offset
,
mCandidates
[
nCand
-
1
].
postBreak
-
mPreBreak
,
HyphenEdit
::
NO_EDIT
);
mLastHyphenation
);
// don't need to update mBestScore, because we're done
#if VERBOSE_DEBUG
ALOGD
(
"final break: %d %g"
,
mBreaks
.
back
(),
mWidths
.
back
());
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录