Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
qq_34031325
engine
提交
8eab44c6
E
engine
项目概览
qq_34031325
/
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,发现更多精彩内容 >>
提交
8eab44c6
编写于
9月 26, 2016
作者:
J
Jason Simmons
提交者:
GitHub
9月 26, 2016
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement ellipsizing of text in the engine (#3056)
See
https://github.com/flutter/flutter/issues/4478
上级
2d585bc4
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
101 addition
and
16 deletion
+101
-16
lib/ui/text.dart
lib/ui/text.dart
+26
-7
lib/ui/text/paragraph_builder.cc
lib/ui/text/paragraph_builder.cc
+11
-4
sky/engine/core/rendering/BidiRun.h
sky/engine/core/rendering/BidiRun.h
+1
-0
sky/engine/core/rendering/InlineBox.h
sky/engine/core/rendering/InlineBox.h
+4
-0
sky/engine/core/rendering/InlineTextBox.cpp
sky/engine/core/rendering/InlineTextBox.cpp
+10
-1
sky/engine/core/rendering/InlineTextBox.h
sky/engine/core/rendering/InlineTextBox.h
+1
-0
sky/engine/core/rendering/RenderParagraph.cpp
sky/engine/core/rendering/RenderParagraph.cpp
+10
-0
sky/engine/core/rendering/line/BreakingContextInlineHeaders.h
...engine/core/rendering/line/BreakingContextInlineHeaders.h
+33
-3
sky/engine/core/rendering/line/LineBreaker.cpp
sky/engine/core/rendering/line/LineBreaker.cpp
+2
-1
sky/engine/core/rendering/line/LineBreaker.h
sky/engine/core/rendering/line/LineBreaker.h
+2
-0
sky/engine/platform/text/BidiCharacterRun.h
sky/engine/platform/text/BidiCharacterRun.h
+1
-0
未找到文件。
lib/ui/text.dart
浏览文件 @
8eab44c6
...
...
@@ -93,6 +93,15 @@ enum TextAlign {
center
}
/// How to handle text that overflows its bounds
enum
TextOverflow
{
/// Default
clip
,
/// Render as a single line that is ellipsized if it is too wide to fit
ellipsis
}
/// A horizontal line used for aligning text
enum
TextBaseline
{
// The horizontal line used to align the bottom of glyphs for alphabetic characters
...
...
@@ -375,13 +384,16 @@ class TextStyle {
//
// - Element 3: The enum index of the |fontStyle|.
//
// - Element 4: The enum index of the |textOverflow|.
//
Int32List
_encodeParagraphStyle
(
TextAlign
textAlign
,
FontWeight
fontWeight
,
FontStyle
fontStyle
,
TextOverflow
textOverflow
,
String
fontFamily
,
double
fontSize
,
double
lineHeight
)
{
Int32List
result
=
new
Int32List
(
4
);
Int32List
result
=
new
Int32List
(
5
);
if
(
textAlign
!=
null
)
{
result
[
0
]
|=
1
<<
1
;
result
[
1
]
=
textAlign
.
index
;
...
...
@@ -394,16 +406,20 @@ Int32List _encodeParagraphStyle(TextAlign textAlign,
result
[
0
]
|=
1
<<
3
;
result
[
3
]
=
fontStyle
.
index
;
}
if
(
fontFamily
!=
null
)
{
if
(
textOverflow
!=
null
)
{
result
[
0
]
|=
1
<<
4
;
result
[
4
]
=
textOverflow
.
index
;
}
if
(
fontFamily
!=
null
)
{
result
[
0
]
|=
1
<<
5
;
// Passed separately to native.
}
if
(
fontSize
!=
null
)
{
result
[
0
]
|=
1
<<
5
;
result
[
0
]
|=
1
<<
6
;
// Passed separately to native.
}
if
(
lineHeight
!=
null
)
{
result
[
0
]
|=
1
<<
6
;
result
[
0
]
|=
1
<<
7
;
// Passed separately to native.
}
return
result
;
...
...
@@ -423,12 +439,14 @@ class ParagraphStyle {
TextAlign
textAlign
,
FontWeight
fontWeight
,
FontStyle
fontStyle
,
TextOverflow
textOverflow
,
String
fontFamily
,
double
fontSize
,
double
lineHeight
})
:
_encoded
=
_encodeParagraphStyle
(
textAlign
,
fontWeight
,
fontStyle
,
textOverflow
,
fontFamily
,
fontSize
,
lineHeight
),
...
...
@@ -465,9 +483,10 @@ class ParagraphStyle {
'textAlign:
${ _encoded[0] & 0x02 == 0x02 ? TextAlign.values[_encoded[1]] : "unspecified"}
, '
'fontWeight:
${ _encoded[0] & 0x04 == 0x04 ? FontWeight.values[_encoded[2]] : "unspecified"}
, '
'fontStyle:
${ _encoded[0] & 0x08 == 0x08 ? FontStyle.values[_encoded[3]] : "unspecified"}
, '
'fontFamily:
${ _encoded[0] & 0x10 == 0x10 ? _fontFamily : "unspecified"}
, '
'fontSize:
${ _encoded[0] & 0x20 == 0x20 ? _fontSize : "unspecified"}
, '
'lineHeight:
${ _encoded[0] & 0x40 == 0x40 ? "${_lineHeight}
x" : "unspecified"}'
'textOverflow:
${ _encoded[0] & 0x10 == 0x10 ? TextOverflow.values[_encoded[4]] : "unspecified"}
, '
'fontFamily:
${ _encoded[0] & 0x20 == 0x20 ? _fontFamily : "unspecified"}
, '
'fontSize:
${ _encoded[0] & 0x40 == 0x40 ? _fontSize : "unspecified"}
, '
'lineHeight:
${ _encoded[0] & 0x80 == 0x80 ? "${_lineHeight}
x" : "unspecified"}'
')'
;
}
}
...
...
lib/ui/text/paragraph_builder.cc
浏览文件 @
8eab44c6
...
...
@@ -95,13 +95,15 @@ const int tsHeightMask = 1 << tsHeightIndex;
const
int
psTextAlignIndex
=
1
;
const
int
psFontWeightIndex
=
2
;
const
int
psFontStyleIndex
=
3
;
const
int
psFontFamilyIndex
=
4
;
const
int
psFontSizeIndex
=
5
;
const
int
psLineHeightIndex
=
6
;
const
int
psTextOverflowIndex
=
4
;
const
int
psFontFamilyIndex
=
5
;
const
int
psFontSizeIndex
=
6
;
const
int
psLineHeightIndex
=
7
;
const
int
psTextAlignMask
=
1
<<
psTextAlignIndex
;
const
int
psFontWeightMask
=
1
<<
psFontWeightIndex
;
const
int
psFontStyleMask
=
1
<<
psFontStyleIndex
;
const
int
psTextOverflowMask
=
1
<<
psTextOverflowIndex
;
const
int
psFontFamilyMask
=
1
<<
psFontFamilyIndex
;
const
int
psFontSizeMask
=
1
<<
psFontSizeIndex
;
const
int
psLineHeightMask
=
1
<<
psLineHeightIndex
;
...
...
@@ -241,7 +243,7 @@ ftl::RefPtr<Paragraph> ParagraphBuilder::build(tonic::Int32List& encoded,
const
std
::
string
&
fontFamily
,
double
fontSize
,
double
lineHeight
)
{
FTL_DCHECK
(
encoded
.
num_elements
()
==
4
);
FTL_DCHECK
(
encoded
.
num_elements
()
==
5
);
int32_t
mask
=
encoded
[
0
];
if
(
mask
)
{
...
...
@@ -282,6 +284,11 @@ ftl::RefPtr<Paragraph> ParagraphBuilder::build(tonic::Int32List& encoded,
if
(
mask
&
psLineHeightMask
)
style
->
setLineHeight
(
Length
(
lineHeight
*
100.0
,
Percent
));
if
(
mask
&
psTextOverflowMask
)
{
style
->
setTextOverflow
(
static_cast
<
TextOverflow
>
(
encoded
[
psTextOverflowIndex
]));
}
m_renderParagraph
->
setStyle
(
style
.
release
());
}
...
...
sky/engine/core/rendering/BidiRun.h
浏览文件 @
8eab44c6
...
...
@@ -41,6 +41,7 @@ struct BidiRun : BidiCharacterRun {
{
// Stored in base class to save space.
m_hasHyphen
=
false
;
m_hasAddedEllipsis
=
false
;
}
BidiRun
*
next
()
{
return
static_cast
<
BidiRun
*>
(
m_next
);
}
...
...
sky/engine/core/rendering/InlineBox.h
浏览文件 @
8eab44c6
...
...
@@ -296,6 +296,7 @@ public:
,
m_hasEllipsisBoxOrHyphen
(
false
)
,
m_dirOverride
(
false
)
,
m_isText
(
false
)
,
m_hasAddedEllipsis
(
false
)
,
m_determinedIfNextOnLineExists
(
false
)
,
m_nextOnLineExists
(
false
)
,
m_expansion
(
0
)
...
...
@@ -326,6 +327,7 @@ public:
// for InlineTextBox
ADD_BOOLEAN_BITFIELD
(
dirOverride
,
DirOverride
);
ADD_BOOLEAN_BITFIELD
(
isText
,
IsText
);
// Whether or not this object represents text with a non-zero height. Includes non-image list markers, text boxes.
ADD_BOOLEAN_BITFIELD
(
hasAddedEllipsis
,
HasAddedEllipsis
)
private:
mutable
unsigned
m_determinedIfNextOnLineExists
:
1
;
...
...
@@ -373,6 +375,8 @@ protected:
void
setCanHaveLeadingExpansion
(
bool
canHaveLeadingExpansion
)
{
m_bitfields
.
setHasSelectedChildrenOrCanHaveLeadingExpansion
(
canHaveLeadingExpansion
);
}
signed
expansion
()
{
return
m_bitfields
.
expansion
();
}
void
setExpansion
(
signed
expansion
)
{
m_bitfields
.
setExpansion
(
expansion
);
}
bool
hasAddedEllipsis
()
const
{
return
m_bitfields
.
hasAddedEllipsis
();
}
void
setHasAddedEllipsis
(
bool
hasAddedEllipsis
)
{
m_bitfields
.
setHasAddedEllipsis
(
hasAddedEllipsis
);
}
// For InlineFlowBox and InlineTextBox
bool
extracted
()
const
{
return
m_bitfields
.
extracted
();
}
...
...
sky/engine/core/rendering/InlineTextBox.cpp
浏览文件 @
8eab44c6
...
...
@@ -450,9 +450,18 @@ void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset,
string
.
narrow
(
m_start
,
length
);
maximumLength
=
renderer
().
textLength
()
-
m_start
;
StringBuilder
charactersWithEllipsis
;
if
(
hasAddedEllipsis
())
{
charactersWithEllipsis
.
reserveCapacity
(
string
.
length
()
+
1
);
charactersWithEllipsis
.
append
(
string
);
charactersWithEllipsis
.
append
(
WTF
::
Unicode
::
horizontalEllipsis
);
string
=
charactersWithEllipsis
.
toString
().
createView
();
maximumLength
=
string
.
length
();
}
StringBuilder
charactersWithHyphen
;
TextRun
textRun
=
constructTextRun
(
styleToUse
,
font
,
string
,
maximumLength
,
hasHyphen
()
?
&
charactersWithHyphen
:
0
);
if
(
hasHyphen
())
if
(
hasHyphen
()
||
hasAddedEllipsis
()
)
length
=
textRun
.
length
();
int
sPos
=
0
;
...
...
sky/engine/core/rendering/InlineTextBox.h
浏览文件 @
8eab44c6
...
...
@@ -76,6 +76,7 @@ public:
using
InlineBox
::
hasHyphen
;
using
InlineBox
::
setHasHyphen
;
using
InlineBox
::
setHasAddedEllipsis
;
using
InlineBox
::
canHaveLeadingExpansion
;
using
InlineBox
::
setCanHaveLeadingExpansion
;
...
...
sky/engine/core/rendering/RenderParagraph.cpp
浏览文件 @
8eab44c6
...
...
@@ -515,6 +515,8 @@ RootInlineBox* RenderParagraph::constructLine(BidiRunList<BidiRun>& bidiRuns, co
text
->
setDirOverride
(
r
->
dirOverride
());
if
(
r
->
m_hasHyphen
)
text
->
setHasHyphen
(
true
);
if
(
r
->
m_hasAddedEllipsis
)
text
->
setHasAddedEllipsis
(
true
);
}
}
...
...
@@ -909,6 +911,8 @@ void RenderParagraph::layoutRunsAndFloatsInRange(LineLayoutState& layoutState,
if
(
bidiRuns
.
runCount
()
&&
lineBreaker
.
lineWasHyphenated
())
bidiRuns
.
logicallyLastRun
()
->
m_hasHyphen
=
true
;
if
(
bidiRuns
.
runCount
()
&&
lineBreaker
.
lineWasEllipsized
())
bidiRuns
.
logicallyLastRun
()
->
m_hasAddedEllipsis
=
true
;
// Now that the runs have been ordered, we create the line boxes.
// At the same time we figure out where border/padding/margin should be applied for
...
...
@@ -928,6 +932,12 @@ void RenderParagraph::layoutRunsAndFloatsInRange(LineLayoutState& layoutState,
lineMidpointState
.
reset
();
resolver
.
setPosition
(
endOfLine
,
numberOfIsolateAncestors
(
endOfLine
));
// Limit ellipsized text to a single line.
if
(
lineBreaker
.
lineWasEllipsized
())
{
resolver
.
setPosition
(
InlineIterator
(
resolver
.
position
().
root
(),
0
,
0
),
0
);
break
;
}
}
}
...
...
sky/engine/core/rendering/line/BreakingContextInlineHeaders.h
浏览文件 @
8eab44c6
...
...
@@ -88,7 +88,7 @@ public:
void
handleOutOfFlowPositioned
(
Vector
<
RenderBox
*>&
positionedObjects
);
void
handleEmptyInline
();
void
handleReplaced
();
bool
handleText
(
WordMeasurements
&
,
bool
&
hyphenated
);
bool
handleText
(
WordMeasurements
&
,
bool
&
hyphenated
,
bool
&
ellipsized
);
void
commitAndUpdateLineBreakIfNeeded
();
InlineIterator
handleEndOfLine
();
...
...
@@ -409,6 +409,13 @@ inline float measureHyphenWidth(RenderText* renderer, const Font& font, TextDire
style
->
hyphenString
().
string
(),
style
,
style
->
direction
()));
}
inline
float
measureEllipsisWidth
(
RenderText
*
renderer
,
const
Font
&
font
)
{
RenderStyle
*
style
=
renderer
->
style
();
return
font
.
width
(
constructTextRun
(
renderer
,
font
,
String
(
&
WTF
::
Unicode
::
horizontalEllipsis
,
1
),
style
,
style
->
direction
()));
}
ALWAYS_INLINE
TextDirection
textDirectionFromUnicode
(
WTF
::
Unicode
::
Direction
direction
)
{
return
direction
==
WTF
::
Unicode
::
RightToLeft
...
...
@@ -428,7 +435,7 @@ ALWAYS_INLINE float textWidth(RenderText* text, unsigned from, unsigned len, con
return
font
.
width
(
run
,
fallbackFonts
,
&
glyphOverflow
);
}
inline
bool
BreakingContext
::
handleText
(
WordMeasurements
&
wordMeasurements
,
bool
&
hyphenated
)
inline
bool
BreakingContext
::
handleText
(
WordMeasurements
&
wordMeasurements
,
bool
&
hyphenated
,
bool
&
ellipsized
)
{
if
(
!
m_current
.
offset
())
m_appliedStartWidth
=
false
;
...
...
@@ -458,8 +465,17 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
bool
breakWords
=
m_currentStyle
->
breakWords
()
&&
((
m_autoWrap
&&
!
m_width
.
committedWidth
())
||
m_currWS
==
PRE
);
bool
midWordBreak
=
false
;
bool
breakAll
=
m_currentStyle
->
wordBreak
()
==
BreakAllWordBreak
&&
m_autoWrap
;
float
hyphenWidth
=
0
;
bool
ellipsizeMode
=
m_blockStyle
->
textOverflow
()
==
TextOverflowEllipsis
;
float
ellipsisWidth
=
0
;
unsigned
ellipsisBreakOffset
=
0
;
if
(
ellipsizeMode
)
{
ellipsisWidth
=
measureEllipsisWidth
(
renderText
,
font
);
breakAll
=
true
;
}
if
(
m_renderTextInfo
.
m_text
!=
renderText
)
{
m_renderTextInfo
.
m_text
=
renderText
;
m_renderTextInfo
.
m_font
=
&
font
;
...
...
@@ -496,7 +512,14 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
wrapW
+=
charWidth
;
bool
midWordBreakIsBeforeSurrogatePair
=
U16_IS_LEAD
(
c
)
&&
m_current
.
offset
()
+
1
<
renderText
->
textLength
()
&&
U16_IS_TRAIL
((
*
renderText
)[
m_current
.
offset
()
+
1
]);
charWidth
=
textWidth
(
renderText
,
m_current
.
offset
(),
midWordBreakIsBeforeSurrogatePair
?
2
:
1
,
font
,
m_width
.
committedWidth
()
+
wrapW
,
isFixedPitch
,
m_collapseWhiteSpace
);
midWordBreak
=
m_width
.
committedWidth
()
+
wrapW
+
charWidth
>
m_width
.
availableWidth
();
float
midWordWidth
=
m_width
.
committedWidth
()
+
wrapW
+
charWidth
;
midWordBreak
=
midWordWidth
>
m_width
.
availableWidth
();
// Check whether there is enough space to fit this character plus an ellipsis.
if
(
ellipsizeMode
&&
midWordWidth
+
ellipsisWidth
<=
m_width
.
availableWidth
())
{
ellipsisBreakOffset
=
m_current
.
offset
();
}
}
int
nextBreakablePosition
=
m_current
.
nextBreakablePosition
();
...
...
@@ -584,6 +607,13 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool
wordMeasurement
.
width
=
charWidth
;
}
}
if
(
ellipsizeMode
)
{
// Break the line at the position where an ellipsis would fit.
m_lineBreak
.
moveTo
(
m_current
.
object
(),
ellipsisBreakOffset
,
m_current
.
nextBreakablePosition
());
ellipsized
=
true
;
}
// Didn't fit. Jump to the end unless there's still an opportunity to collapse whitespace.
if
(
m_ignoringSpaces
||
!
m_collapseWhiteSpace
||
!
m_currentCharacterIsSpace
||
!
previousCharacterIsSpace
)
{
m_atEnd
=
true
;
...
...
sky/engine/core/rendering/line/LineBreaker.cpp
浏览文件 @
8eab44c6
...
...
@@ -45,6 +45,7 @@ void LineBreaker::reset()
{
m_positionedObjects
.
clear
();
m_hyphenated
=
false
;
m_ellipsized
=
false
;
}
InlineIterator
LineBreaker
::
nextLineBreak
(
InlineBidiResolver
&
resolver
,
LineInfo
&
lineInfo
,
...
...
@@ -75,7 +76,7 @@ InlineIterator LineBreaker::nextLineBreak(InlineBidiResolver& resolver, LineInfo
}
else
if
(
context
.
currentObject
()
->
isReplaced
())
{
context
.
handleReplaced
();
}
else
if
(
context
.
currentObject
()
->
isText
())
{
if
(
context
.
handleText
(
wordMeasurements
,
m_hyphenated
))
{
if
(
context
.
handleText
(
wordMeasurements
,
m_hyphenated
,
m_ellipsized
))
{
// We've hit a hard text line break. Our line break iterator is updated, so go ahead and early return.
return
context
.
lineBreak
();
}
...
...
sky/engine/core/rendering/line/LineBreaker.h
浏览文件 @
8eab44c6
...
...
@@ -46,6 +46,7 @@ public:
FloatingObject
*
lastFloatFromPreviousLine
,
WordMeasurements
&
);
bool
lineWasHyphenated
()
{
return
m_hyphenated
;
}
bool
lineWasEllipsized
()
{
return
m_ellipsized
;
}
const
Vector
<
RenderBox
*>&
positionedObjects
()
{
return
m_positionedObjects
;
}
private:
void
reset
();
...
...
@@ -54,6 +55,7 @@ private:
RenderParagraph
*
m_block
;
bool
m_hyphenated
;
bool
m_ellipsized
;
Vector
<
RenderBox
*>
m_positionedObjects
;
};
...
...
sky/engine/platform/text/BidiCharacterRun.h
浏览文件 @
8eab44c6
...
...
@@ -69,6 +69,7 @@ struct BidiCharacterRun {
// Do not add anything apart from bitfields until after m_next. See https://bugs.webkit.org/show_bug.cgi?id=100173
bool
m_override
:
1
;
bool
m_hasHyphen
:
1
;
// Used by BidiRun subclass which is a layering violation but enables us to save 8 bytes per object on 64-bit.
bool
m_hasAddedEllipsis
:
1
;
unsigned
char
m_level
;
BidiCharacterRun
*
m_next
;
int
m_start
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录