Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
194bf41e
Commit
194bf41e
authored
Jul 20, 2017
by
Ian Hickson
Committed by
GitHub
Jul 20, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Don't relayout a Text if only its color changed. (#11313)
parent
6dbf2269
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
170 additions
and
5 deletions
+170
-5
basic_types.dart
packages/flutter/lib/src/painting/basic_types.dart
+38
-0
text_span.dart
packages/flutter/lib/src/painting/text_span.dart
+33
-0
text_style.dart
packages/flutter/lib/src/painting/text_style.dart
+27
-0
object.dart
packages/flutter/lib/src/rendering/object.dart
+28
-0
paragraph.dart
packages/flutter/lib/src/rendering/paragraph.dart
+14
-5
paragraph_test.dart
packages/flutter/test/rendering/paragraph_test.dart
+30
-0
No files found.
packages/flutter/lib/src/painting/basic_types.dart
View file @
194bf41e
...
...
@@ -52,3 +52,41 @@ export 'dart:ui' show
// - window, WindowPadding
// These are generally wrapped by other APIs so we always refer to them directly
// as ui.* to avoid making them seem like high-level APIs.
/// The description of the difference between two objects, in the context of how
/// it will affect the rendering.
///
/// Used by [TextSpan.compareTo] and [TextStyle.compareTo].
///
/// The values in this enum are ordered such that they are in increasing order
/// of cost. A value with index N implies all the values with index less than N.
/// For example, [layout] (index 3) implies [paint] (2).
enum
RenderComparison
{
/// The two objects are identical (meaning deeply equal, not necessarily
/// [identical]).
identical
,
/// The two objects are identical for the purpose of layout, but may be different
/// in other ways.
///
/// For example, maybe some event handlers changed.
metadata
,
/// The two objects are different but only in ways that affect paint, not layout.
///
/// For example, only the color is changed.
///
/// [RenderObject.markNeedsPaint] would be necessary to handle this kind of
/// change in a render object.
paint
,
/// The two objects are different in ways that affect layout (and therefore paint).
///
/// For example, the size is changed.
///
/// This is the most drastic level of change possible.
///
/// [RenderObject.markNeedsLayout] would be necessary to handle this kind of
/// change in a render object.
layout
,
}
packages/flutter/lib/src/painting/text_span.dart
View file @
194bf41e
...
...
@@ -317,6 +317,39 @@ class TextSpan {
return
true
;
}
/// Describe the difference between this text span and another, in terms of
/// how much damage it will make to the rendering. The comparison is deep.
///
/// See also:
///
/// * [TextStyle.compareTo], which does the same thing for [TextStyle]s.
RenderComparison
compareTo
(
TextSpan
other
)
{
if
(
identical
(
this
,
other
))
return
RenderComparison
.
identical
;
if
(
other
.
text
!=
text
||
children
?.
length
!=
other
.
children
?.
length
||
(
style
==
null
)
!=
(
other
.
style
==
null
))
return
RenderComparison
.
layout
;
RenderComparison
result
=
recognizer
==
other
.
recognizer
?
RenderComparison
.
identical
:
RenderComparison
.
metadata
;
if
(
style
!=
null
)
{
final
RenderComparison
candidate
=
style
.
compareTo
(
other
.
style
);
if
(
candidate
.
index
>
result
.
index
)
result
=
candidate
;
if
(
result
==
RenderComparison
.
layout
)
return
result
;
}
if
(
children
!=
null
)
{
for
(
int
index
=
0
;
index
<
children
.
length
;
index
+=
1
)
{
final
RenderComparison
candidate
=
children
[
index
].
compareTo
(
other
.
children
[
index
]);
if
(
candidate
.
index
>
result
.
index
)
result
=
candidate
;
if
(
result
==
RenderComparison
.
layout
)
return
result
;
}
}
return
result
;
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
this
,
other
))
...
...
packages/flutter/lib/src/painting/text_style.dart
View file @
194bf41e
...
...
@@ -387,6 +387,33 @@ class TextStyle {
);
}
/// Describe the difference between this style and another, in terms of how
/// much damage it will make to the rendering.
///
/// See also:
///
/// * [TextSpan.compareTo], which does the same thing for entire [TextSpan]s.
RenderComparison
compareTo
(
TextStyle
other
)
{
if
(
identical
(
this
,
other
))
return
RenderComparison
.
identical
;
if
(
inherit
!=
other
.
inherit
||
fontFamily
!=
other
.
fontFamily
||
fontSize
!=
other
.
fontSize
||
fontWeight
!=
other
.
fontWeight
||
fontStyle
!=
other
.
fontStyle
||
letterSpacing
!=
other
.
letterSpacing
||
wordSpacing
!=
other
.
wordSpacing
||
textBaseline
!=
other
.
textBaseline
||
height
!=
other
.
height
)
return
RenderComparison
.
layout
;
if
(
color
!=
other
.
color
||
decoration
!=
other
.
decoration
||
decorationColor
!=
other
.
decorationColor
||
decorationStyle
!=
other
.
decorationStyle
)
return
RenderComparison
.
paint
;
return
RenderComparison
.
identical
;
}
@override
bool
operator
==(
dynamic
other
)
{
if
(
identical
(
this
,
other
))
...
...
packages/flutter/lib/src/rendering/object.dart
View file @
194bf41e
...
...
@@ -1559,6 +1559,8 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
/// to condition their runtime behavior on whether they are dirty or not,
/// since they should only be marked dirty immediately prior to being laid
/// out and painted.
///
/// It is intended to be used by tests and asserts.
bool
get
debugNeedsLayout
{
bool
result
;
assert
(()
{
...
...
@@ -2133,6 +2135,28 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
_needsCompositingBitsUpdate
=
false
;
}
/// Whether this render object's paint information is dirty.
///
/// This is only set in debug mode. In general, render objects should not need
/// to condition their runtime behavior on whether they are dirty or not,
/// since they should only be marked dirty immediately prior to being laid
/// out and painted.
///
/// It is intended to be used by tests and asserts.
///
/// It is possible (and indeed, quite common) for [debugNeedsPaint] to be
/// false and [debugNeedsLayout] to be true. The render object will still be
/// repainted in the next frame when this is the case, because the
/// [markNeedsPaint] method is implicitly called by the framework after a
/// render object is laid out, prior to the paint phase.
bool
get
debugNeedsPaint
{
bool
result
;
assert
(()
{
result
=
_needsPaint
;
return
true
;
});
return
result
;
}
bool
_needsPaint
=
true
;
/// Mark this render object as having changed its visual appearance.
...
...
@@ -2145,6 +2169,10 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
///
/// This mechanism batches the painting work so that multiple sequential
/// writes are coalesced, removing redundant computation.
///
/// Once [markNeedsPaint] has been called on a render object,
/// [debugNeedsPaint] returns true for that render object until just after
/// the pipeline owner has called [paint] on the render object.
void
markNeedsPaint
()
{
assert
(
owner
==
null
||
!
owner
.
debugDoingPaint
);
if
(
_needsPaint
)
...
...
packages/flutter/lib/src/rendering/paragraph.dart
View file @
194bf41e
...
...
@@ -64,11 +64,20 @@ class RenderParagraph extends RenderBox {
TextSpan
get
text
=>
_textPainter
.
text
;
set
text
(
TextSpan
value
)
{
assert
(
value
!=
null
);
if
(
_textPainter
.
text
==
value
)
return
;
_textPainter
.
text
=
value
;
_overflowShader
=
null
;
markNeedsLayout
();
switch
(
_textPainter
.
text
.
compareTo
(
value
))
{
case
RenderComparison
.
identical
:
case
RenderComparison
.
metadata
:
return
;
case
RenderComparison
.
paint
:
_textPainter
.
text
=
value
;
markNeedsPaint
();
break
;
case
RenderComparison
.
layout
:
_textPainter
.
text
=
value
;
_overflowShader
=
null
;
markNeedsLayout
();
break
;
}
}
/// How the text should be aligned horizontally.
...
...
packages/flutter/test/rendering/paragraph_test.dart
View file @
194bf41e
...
...
@@ -177,6 +177,36 @@ void main() {
expect
(
paragraph
.
size
.
height
,
30.0
);
});
test
(
'changing color does not do layout'
,
()
{
final
RenderParagraph
paragraph
=
new
RenderParagraph
(
const
TextSpan
(
text:
'Hello'
,
style:
const
TextStyle
(
color:
const
Color
(
0xFF000000
)),
),
);
layout
(
paragraph
,
constraints:
const
BoxConstraints
(
maxWidth:
100.0
),
phase:
EnginePhase
.
paint
);
expect
(
paragraph
.
debugNeedsLayout
,
isFalse
);
expect
(
paragraph
.
debugNeedsPaint
,
isFalse
);
paragraph
.
text
=
const
TextSpan
(
text:
'Hello World'
,
style:
const
TextStyle
(
color:
const
Color
(
0xFF000000
)),
);
expect
(
paragraph
.
debugNeedsLayout
,
isTrue
);
expect
(
paragraph
.
debugNeedsPaint
,
isFalse
);
pumpFrame
(
phase:
EnginePhase
.
paint
);
expect
(
paragraph
.
debugNeedsLayout
,
isFalse
);
expect
(
paragraph
.
debugNeedsPaint
,
isFalse
);
paragraph
.
text
=
const
TextSpan
(
text:
'Hello World'
,
style:
const
TextStyle
(
color:
const
Color
(
0xFFFFFFFF
)),
);
expect
(
paragraph
.
debugNeedsLayout
,
isFalse
);
expect
(
paragraph
.
debugNeedsPaint
,
isTrue
);
pumpFrame
(
phase:
EnginePhase
.
paint
);
expect
(
paragraph
.
debugNeedsLayout
,
isFalse
);
expect
(
paragraph
.
debugNeedsPaint
,
isFalse
);
});
test
(
'toStringDeep'
,
()
{
final
RenderParagraph
paragraph
=
new
RenderParagraph
(
const
TextSpan
(
text:
_kText
),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment