Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
ce2704b1
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,发现更多精彩内容 >>
提交
ce2704b1
编写于
8月 14, 2015
作者:
C
Collin Jackson
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #621 from collinjackson/more_text_refactor
Refactor RenderParagraph to do more work at the painting layer
上级
59719a41
9f4b2fe7
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
188 addition
and
132 deletion
+188
-132
sky/packages/sky/lib/painting/paragraph_painter.dart
sky/packages/sky/lib/painting/paragraph_painter.dart
+150
-0
sky/packages/sky/lib/rendering/paragraph.dart
sky/packages/sky/lib/rendering/paragraph.dart
+25
-120
sky/packages/sky/lib/widgets/basic.dart
sky/packages/sky/lib/widgets/basic.dart
+13
-12
未找到文件。
sky/packages/sky/lib/painting/paragraph_painter.dart
0 → 100644
浏览文件 @
ce2704b1
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:sky'
as
sky
;
import
'package:sky/painting/text_style.dart'
;
// This must be immutable, because we won't notice when it changes
abstract
class
TextSpan
{
sky
.
Node
_toDOM
(
sky
.
Document
owner
);
String
toString
([
String
prefix
=
''
]);
void
_applyStyleToContainer
(
sky
.
Element
container
)
{
}
}
class
PlainTextSpan
extends
TextSpan
{
PlainTextSpan
(
this
.
text
)
{
assert
(
text
!=
null
);
}
final
String
text
;
sky
.
Node
_toDOM
(
sky
.
Document
owner
)
{
return
owner
.
createText
(
text
);
}
bool
operator
==(
other
)
=>
other
is
PlainTextSpan
&&
text
==
other
.
text
;
int
get
hashCode
=>
text
.
hashCode
;
String
toString
([
String
prefix
=
''
])
=>
'
${prefix}${runtimeType}
: "
${text}
"'
;
}
class
StyledTextSpan
extends
TextSpan
{
StyledTextSpan
(
this
.
style
,
this
.
children
)
{
assert
(
style
!=
null
);
assert
(
children
!=
null
);
}
final
TextStyle
style
;
final
List
<
TextSpan
>
children
;
sky
.
Node
_toDOM
(
sky
.
Document
owner
)
{
sky
.
Element
parent
=
owner
.
createElement
(
't'
);
style
.
applyToCSSStyle
(
parent
.
style
);
for
(
TextSpan
child
in
children
)
{
parent
.
appendChild
(
child
.
_toDOM
(
owner
));
}
return
parent
;
}
void
_applyStyleToContainer
(
sky
.
Element
container
)
{
style
.
applyToContainerCSSStyle
(
container
.
style
);
}
bool
operator
==(
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
other
is
!
StyledTextSpan
||
style
!=
other
.
style
||
children
.
length
!=
other
.
children
.
length
)
return
false
;
for
(
int
i
=
0
;
i
<
children
.
length
;
++
i
)
{
if
(
children
[
i
]
!=
other
.
children
[
i
])
return
false
;
}
return
true
;
}
int
get
hashCode
{
int
value
=
373
;
value
=
37
*
value
+
style
.
hashCode
;
for
(
TextSpan
child
in
children
)
value
=
37
*
value
+
child
.
hashCode
;
return
value
;
}
String
toString
([
String
prefix
=
''
])
{
List
<
String
>
result
=
[];
result
.
add
(
'
${prefix}${runtimeType}
:'
);
var
indent
=
'
${prefix}
'
;
result
.
add
(
'
${style.toString(indent)}
'
);
for
(
TextSpan
child
in
children
)
{
result
.
add
(
child
.
toString
(
indent
));
}
return
result
.
join
(
'
\n
'
);
}
}
class
ParagraphPainter
{
ParagraphPainter
(
TextSpan
text
)
{
_layoutRoot
.
rootElement
=
_document
.
createElement
(
'p'
);
assert
(
text
!=
null
);
this
.
text
=
text
;
}
final
sky
.
Document
_document
=
new
sky
.
Document
();
final
sky
.
LayoutRoot
_layoutRoot
=
new
sky
.
LayoutRoot
();
TextSpan
_text
;
TextSpan
get
text
=>
_text
;
void
set
text
(
TextSpan
value
)
{
_text
=
value
;
_layoutRoot
.
rootElement
.
setChild
(
_text
.
_toDOM
(
_document
));
_layoutRoot
.
rootElement
.
removeAttribute
(
'style'
);
_text
.
_applyStyleToContainer
(
_layoutRoot
.
rootElement
);
}
double
get
minWidth
=>
_layoutRoot
.
minWidth
;
void
set
minWidth
(
value
)
{
_layoutRoot
.
minWidth
=
value
;
}
double
get
maxWidth
=>
_layoutRoot
.
maxWidth
;
void
set
maxWidth
(
value
)
{
_layoutRoot
.
maxWidth
=
value
;
}
double
get
minHeight
=>
_layoutRoot
.
minHeight
;
void
set
minHeight
(
value
)
{
_layoutRoot
.
minHeight
=
value
;
}
double
get
maxHeight
=>
_layoutRoot
.
maxHeight
;
void
set
maxHeight
(
value
)
{
_layoutRoot
.
maxHeight
=
value
;
}
double
get
minContentWidth
=>
_layoutRoot
.
rootElement
.
minContentWidth
;
double
get
maxContentWidth
=>
_layoutRoot
.
rootElement
.
maxContentWidth
;
double
get
height
=>
_layoutRoot
.
rootElement
.
height
;
double
computeDistanceToActualBaseline
(
TextBaseline
baseline
)
{
sky
.
Element
root
=
_layoutRoot
.
rootElement
;
switch
(
baseline
)
{
case
TextBaseline
.
alphabetic
:
return
root
.
alphabeticBaseline
;
case
TextBaseline
.
ideographic
:
return
root
.
ideographicBaseline
;
}
}
void
layout
()
=>
_layoutRoot
.
layout
();
void
paint
(
sky
.
Canvas
canvas
,
sky
.
Offset
offset
)
{
// TODO(ianh): Make LayoutRoot support a paint offset so we don't
// need to translate for each span of text.
canvas
.
translate
(
offset
.
dx
,
offset
.
dy
);
_layoutRoot
.
paint
(
canvas
);
canvas
.
translate
(-
offset
.
dx
,
-
offset
.
dy
);
}
}
sky/packages/sky/lib/rendering/paragraph.dart
浏览文件 @
ce2704b1
...
...
@@ -2,92 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:sky'
as
sky
;
import
'package:sky/painting/text_style.dart'
;
import
'package:sky/painting/paragraph_painter.dart'
;
import
'package:sky/rendering/box.dart'
;
import
'package:sky/rendering/object.dart'
;
abstract
class
RenderInline
{
sky
.
Node
_toDOM
(
sky
.
Document
owner
);
String
toString
([
String
prefix
=
''
]);
void
_applyStyleToContainer
(
sky
.
Element
container
)
{
}
}
class
RenderText
extends
RenderInline
{
RenderText
(
this
.
text
)
{
assert
(
text
!=
null
);
}
final
String
text
;
sky
.
Node
_toDOM
(
sky
.
Document
owner
)
{
return
owner
.
createText
(
text
);
}
bool
operator
==(
other
)
=>
other
is
RenderText
&&
text
==
other
.
text
;
int
get
hashCode
=>
text
.
hashCode
;
String
toString
([
String
prefix
=
''
])
=>
'
${prefix}
InlineText: "
${text}
"'
;
}
class
RenderStyled
extends
RenderInline
{
RenderStyled
(
this
.
style
,
this
.
children
)
{
assert
(
style
!=
null
);
assert
(
children
!=
null
);
}
final
TextStyle
style
;
final
List
<
RenderInline
>
children
;
sky
.
Node
_toDOM
(
sky
.
Document
owner
)
{
sky
.
Element
parent
=
owner
.
createElement
(
't'
);
style
.
applyToCSSStyle
(
parent
.
style
);
for
(
RenderInline
child
in
children
)
{
parent
.
appendChild
(
child
.
_toDOM
(
owner
));
}
return
parent
;
}
void
_applyStyleToContainer
(
sky
.
Element
container
)
{
style
.
applyToContainerCSSStyle
(
container
.
style
);
}
bool
operator
==(
other
)
{
if
(
identical
(
this
,
other
))
return
true
;
if
(
other
is
!
RenderStyled
||
style
!=
other
.
style
||
children
.
length
!=
other
.
children
.
length
)
return
false
;
for
(
int
i
=
0
;
i
<
children
.
length
;
++
i
)
{
if
(
children
[
i
]
!=
other
.
children
[
i
])
return
false
;
}
return
true
;
}
int
get
hashCode
{
int
value
=
373
;
value
=
37
*
value
+
style
.
hashCode
;
for
(
RenderInline
child
in
children
)
value
=
37
*
value
+
child
.
hashCode
;
return
value
;
}
String
toString
([
String
prefix
=
''
])
{
List
<
String
>
result
=
[];
result
.
add
(
'
${prefix}
InlineStyle:'
);
var
indent
=
'
${prefix}
'
;
result
.
add
(
'
${style.toString(indent)}
'
);
for
(
RenderInline
child
in
children
)
{
result
.
add
(
child
.
toString
(
indent
));
}
return
result
.
join
(
'
\n
'
);
}
}
export
'package:sky/painting/paragraph_painter.dart'
show
TextSpan
,
PlainTextSpan
,
StyledTextSpan
;
// Unfortunately, using full precision floating point here causes bad layouts
// because floating point math isn't associative. If we add and subtract
...
...
@@ -102,25 +21,20 @@ double _applyFloatingPointHack(double layoutValue) {
class
RenderParagraph
extends
RenderBox
{
RenderParagraph
(
RenderInline
inline
)
{
_layoutRoot
.
rootElement
=
_document
.
createElement
(
'p'
);
this
.
inline
=
inline
;
RenderParagraph
(
TextSpan
text
)
:
_paragraphPainter
=
new
ParagraphPainter
(
text
)
{
assert
(
text
!=
null
)
;
}
final
sky
.
Document
_document
=
new
sky
.
Document
();
final
sky
.
LayoutRoot
_layoutRoot
=
new
sky
.
LayoutRoot
();
ParagraphPainter
_paragraphPainter
;
BoxConstraints
_constraintsForCurrentLayout
;
// when null, we don't have a current layout
RenderInline
_inline
;
RenderInline
get
inline
=>
_inline
;
void
set
inline
(
RenderInline
value
)
{
if
(
_inline
==
value
)
TextSpan
get
text
=>
_paragraphPainter
.
text
;
void
set
text
(
TextSpan
value
)
{
if
(
_paragraphPainter
.
text
==
value
)
return
;
_inline
=
value
;
_layoutRoot
.
rootElement
.
setChild
(
_inline
.
_toDOM
(
_document
));
_layoutRoot
.
rootElement
.
removeAttribute
(
'style'
);
_inline
.
_applyStyleToContainer
(
_layoutRoot
.
rootElement
);
_paragraphPainter
.
text
=
value
;
_constraintsForCurrentLayout
=
null
;
markNeedsLayout
();
}
...
...
@@ -129,30 +43,30 @@ class RenderParagraph extends RenderBox {
assert
(
constraints
!=
null
);
if
(
_constraintsForCurrentLayout
==
constraints
)
return
;
// already cached this layout
_
layoutRoot
.
maxWidth
=
constraints
.
maxWidth
;
_
layoutRoot
.
minWidth
=
constraints
.
minWidth
;
_
layoutRoot
.
minHeight
=
constraints
.
minHeight
;
_
layoutRoot
.
maxHeight
=
constraints
.
maxHeight
;
_
layoutRoot
.
layout
();
_
paragraphPainter
.
maxWidth
=
constraints
.
maxWidth
;
_
paragraphPainter
.
minWidth
=
constraints
.
minWidth
;
_
paragraphPainter
.
minHeight
=
constraints
.
minHeight
;
_
paragraphPainter
.
maxHeight
=
constraints
.
maxHeight
;
_
paragraphPainter
.
layout
();
_constraintsForCurrentLayout
=
constraints
;
}
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
_layout
(
constraints
);
return
constraints
.
constrainWidth
(
_applyFloatingPointHack
(
_
layoutRoot
.
rootElement
.
minContentWidth
));
_applyFloatingPointHack
(
_
paragraphPainter
.
minContentWidth
));
}
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
_layout
(
constraints
);
return
constraints
.
constrainWidth
(
_applyFloatingPointHack
(
_
layoutRoot
.
rootElement
.
maxContentWidth
));
_applyFloatingPointHack
(
_
paragraphPainter
.
maxContentWidth
));
}
double
_getIntrinsicHeight
(
BoxConstraints
constraints
)
{
_layout
(
constraints
);
return
constraints
.
constrainHeight
(
_applyFloatingPointHack
(
_
layoutRoot
.
rootElement
.
height
));
_applyFloatingPointHack
(
_
paragraphPainter
.
height
));
}
double
getMinIntrinsicHeight
(
BoxConstraints
constraints
)
{
...
...
@@ -166,42 +80,33 @@ class RenderParagraph extends RenderBox {
double
computeDistanceToActualBaseline
(
TextBaseline
baseline
)
{
assert
(!
needsLayout
);
_layout
(
constraints
);
sky
.
Element
root
=
_layoutRoot
.
rootElement
;
switch
(
baseline
)
{
case
TextBaseline
.
alphabetic
:
return
root
.
alphabeticBaseline
;
case
TextBaseline
.
ideographic
:
return
root
.
ideographicBaseline
;
}
return
_paragraphPainter
.
computeDistanceToActualBaseline
(
baseline
);
}
void
performLayout
()
{
_layout
(
constraints
);
sky
.
Element
root
=
_layoutRoot
.
rootElement
;
// rootElement.width always expands to fill, use maxContentWidth instead.
size
=
constraints
.
constrain
(
new
Size
(
_applyFloatingPointHack
(
root
.
maxContentWidth
),
_applyFloatingPointHack
(
root
.
height
)));
// _paragraphPainter.width always expands to fill, use maxContentWidth instead.
size
=
constraints
.
constrain
(
new
Size
(
_applyFloatingPointHack
(
_paragraphPainter
.
maxContentWidth
),
_applyFloatingPointHack
(
_paragraphPainter
.
height
)));
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
// Ideally we could compute the min/max intrinsic width/height with a
// non-destructive operation. However, currently, computing these values
// will destroy state inside the
layout root
. If that happens, we need to
// will destroy state inside the
painter
. If that happens, we need to
// get back the correct state by calling _layout again.
//
// TODO(abarth): Make computing the min/max intrinsic width/height
// a non-destructive operation.
// TODO(ianh): Make LayoutRoot support a paint offset so we don't
// need to translate for each span of text.
_layout
(
constraints
);
context
.
canvas
.
translate
(
offset
.
dx
,
offset
.
dy
);
_layoutRoot
.
paint
(
context
.
canvas
);
context
.
canvas
.
translate
(-
offset
.
dx
,
-
offset
.
dy
);
_paragraphPainter
.
paint
(
context
.
canvas
,
offset
);
}
// we should probably expose a way to do precise (inter-glpyh) hit testing
String
debugDescribeSettings
(
String
prefix
)
{
String
result
=
'
${super.debugDescribeSettings(prefix)}
'
;
result
+=
'
${prefix}
inline:
\n
${inline
.toString("$prefix ")}
\n
'
;
result
+=
'
${prefix}
text:
\n
${text
.toString("$prefix ")}
\n
'
;
return
result
;
}
}
sky/packages/sky/lib/widgets/basic.dart
浏览文件 @
ce2704b1
...
...
@@ -10,6 +10,7 @@ import 'package:sky/base/image_resource.dart';
import
'package:sky/mojo/asset_bundle.dart'
;
import
'package:sky/mojo/net/image_cache.dart'
as
image_cache
;
import
'package:sky/painting/text_style.dart'
;
import
'package:sky/painting/paragraph_painter.dart'
;
import
'package:sky/rendering/block.dart'
;
import
'package:sky/rendering/box.dart'
;
import
'package:sky/rendering/flex.dart'
;
...
...
@@ -446,16 +447,16 @@ class Flexible extends ParentDataNode {
}
class
Paragraph
extends
LeafRenderObjectWrapper
{
Paragraph
({
Key
key
,
this
.
inline
})
:
super
(
key:
key
);
Paragraph
({
Key
key
,
this
.
text
})
:
super
(
key:
key
);
final
RenderInline
inline
;
final
TextSpan
text
;
RenderParagraph
createNode
()
=>
new
RenderParagraph
(
inline
);
RenderParagraph
createNode
()
=>
new
RenderParagraph
(
text
);
RenderParagraph
get
root
=>
super
.
root
;
void
syncRenderObject
(
Widget
old
)
{
super
.
syncRenderObject
(
old
);
root
.
inline
=
inline
;
root
.
text
=
text
;
}
}
...
...
@@ -464,25 +465,25 @@ class StyledText extends Component {
// Where "string" is text to display and text-style is an instance of
// TextStyle. The text-style applies to all of the elements that follow.
StyledText
({
this
.
elements
,
Key
key
})
:
super
(
key:
key
)
{
assert
(
_to
Inline
(
elements
)
!=
null
);
assert
(
_to
Span
(
elements
)
!=
null
);
}
final
dynamic
elements
;
RenderInline
_toInline
(
dynamic
element
)
{
TextSpan
_toSpan
(
dynamic
element
)
{
if
(
element
is
String
)
return
new
RenderText
(
element
);
return
new
PlainTextSpan
(
element
);
if
(
element
is
Iterable
)
{
dynamic
first
=
element
.
first
;
if
(
first
is
!
TextStyle
)
throw
new
ArgumentError
(
"First element of Iterable is a
${first.runtimeType}
not a TextStyle"
);
return
new
RenderStyled
(
first
,
element
.
skip
(
1
).
map
(
_toInline
).
toList
());
return
new
StyledTextSpan
(
first
,
element
.
skip
(
1
).
map
(
_toSpan
).
toList
());
}
throw
new
ArgumentError
(
"Element is
${element.runtimeType}
not a String or an Iterable"
);
}
Widget
build
()
{
return
new
Paragraph
(
inline:
_toInline
(
elements
));
return
new
Paragraph
(
text:
_toSpan
(
elements
));
}
}
...
...
@@ -493,7 +494,7 @@ class Text extends Component {
final
TextStyle
style
;
Widget
build
()
{
RenderInline
inline
=
new
RenderText
(
data
);
TextSpan
text
=
new
PlainTextSpan
(
data
);
TextStyle
defaultStyle
=
DefaultTextStyle
.
of
(
this
);
TextStyle
combinedStyle
;
if
(
defaultStyle
!=
null
)
{
...
...
@@ -505,8 +506,8 @@ class Text extends Component {
combinedStyle
=
style
;
}
if
(
combinedStyle
!=
null
)
inline
=
new
RenderStyled
(
combinedStyle
,
[
inline
]);
return
new
Paragraph
(
inline:
inline
);
text
=
new
StyledTextSpan
(
combinedStyle
,
[
text
]);
return
new
Paragraph
(
text:
text
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录