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
4fb5bcd8
Commit
4fb5bcd8
authored
Nov 19, 2015
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #486 from abarth/painting_context
Refactor PaintingContext
parents
c882d423
fc576814
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
227 additions
and
268 deletions
+227
-268
sector_layout.dart
examples/rendering/lib/sector_layout.dart
+3
-3
tabs.dart
packages/flutter/lib/src/material/tabs.dart
+1
-1
box.dart
packages/flutter/lib/src/rendering/box.dart
+4
-1
object.dart
packages/flutter/lib/src/rendering/object.dart
+189
-238
overflow.dart
packages/flutter/lib/src/rendering/overflow.dart
+2
-2
proxy_box.dart
packages/flutter/lib/src/rendering/proxy_box.dart
+15
-13
shifted_box.dart
packages/flutter/lib/src/rendering/shifted_box.dart
+1
-1
stack.dart
packages/flutter/lib/src/rendering/stack.dart
+1
-1
statistics_box.dart
packages/flutter/lib/src/rendering/statistics_box.dart
+1
-1
view.dart
packages/flutter/lib/src/rendering/view.dart
+1
-1
viewport.dart
packages/flutter/lib/src/rendering/viewport.dart
+9
-6
No files found.
examples/rendering/lib/sector_layout.dart
View file @
4fb5bcd8
...
@@ -282,7 +282,7 @@ class RenderSectorRing extends RenderSectorWithChildren {
...
@@ -282,7 +282,7 @@ class RenderSectorRing extends RenderSectorWithChildren {
super
.
paint
(
context
,
offset
);
super
.
paint
(
context
,
offset
);
RenderSector
child
=
firstChild
;
RenderSector
child
=
firstChild
;
while
(
child
!=
null
)
{
while
(
child
!=
null
)
{
context
.
paintChild
(
child
,
offset
.
toPoint
()
);
context
.
paintChild
(
child
,
offset
);
final
SectorChildListParentData
childParentData
=
child
.
parentData
;
final
SectorChildListParentData
childParentData
=
child
.
parentData
;
child
=
childParentData
.
nextSibling
;
child
=
childParentData
.
nextSibling
;
}
}
...
@@ -388,7 +388,7 @@ class RenderSectorSlice extends RenderSectorWithChildren {
...
@@ -388,7 +388,7 @@ class RenderSectorSlice extends RenderSectorWithChildren {
RenderSector
child
=
firstChild
;
RenderSector
child
=
firstChild
;
while
(
child
!=
null
)
{
while
(
child
!=
null
)
{
assert
(
child
.
parentData
is
SectorChildListParentData
);
assert
(
child
.
parentData
is
SectorChildListParentData
);
context
.
paintChild
(
child
,
offset
.
toPoint
()
);
context
.
paintChild
(
child
,
offset
);
final
SectorChildListParentData
childParentData
=
child
.
parentData
;
final
SectorChildListParentData
childParentData
=
child
.
parentData
;
child
=
childParentData
.
nextSibling
;
child
=
childParentData
.
nextSibling
;
}
}
...
@@ -470,7 +470,7 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
...
@@ -470,7 +470,7 @@ class RenderBoxToRenderSectorAdapter extends RenderBox with RenderObjectWithChil
if
(
child
!=
null
)
{
if
(
child
!=
null
)
{
Rect
bounds
=
offset
&
size
;
Rect
bounds
=
offset
&
size
;
// we move the offset to the center of the circle for the RenderSectors
// we move the offset to the center of the circle for the RenderSectors
context
.
paintChild
(
child
,
bounds
.
center
);
context
.
paintChild
(
child
,
bounds
.
center
.
toOffset
()
);
}
}
}
}
...
...
packages/flutter/lib/src/material/tabs.dart
View file @
4fb5bcd8
...
@@ -232,7 +232,7 @@ class _RenderTabBar extends RenderBox with
...
@@ -232,7 +232,7 @@ class _RenderTabBar extends RenderBox with
RenderBox
child
=
firstChild
;
RenderBox
child
=
firstChild
;
while
(
child
!=
null
)
{
while
(
child
!=
null
)
{
final
_TabBarParentData
childParentData
=
child
.
parentData
;
final
_TabBarParentData
childParentData
=
child
.
parentData
;
context
.
paintChild
(
child
,
childParentData
.
position
+
offset
);
context
.
paintChild
(
child
,
childParentData
.
offset
+
offset
);
if
(
index
++
==
selectedIndex
)
if
(
index
++
==
selectedIndex
)
_paintIndicator
(
context
.
canvas
,
child
,
offset
);
_paintIndicator
(
context
.
canvas
,
child
,
offset
);
child
=
childParentData
.
nextSibling
;
child
=
childParentData
.
nextSibling
;
...
...
packages/flutter/lib/src/rendering/box.dart
View file @
4fb5bcd8
...
@@ -287,6 +287,8 @@ class BoxHitTestEntry extends HitTestEntry {
...
@@ -287,6 +287,8 @@ class BoxHitTestEntry extends HitTestEntry {
/// Parent data used by [RenderBox] and its subclasses
/// Parent data used by [RenderBox] and its subclasses
class
BoxParentData
extends
ParentData
{
class
BoxParentData
extends
ParentData
{
// TODO(abarth): Switch to using an Offset rather than a Point here. This
// value is really the offset from the parent.
Point
_position
=
Point
.
origin
;
Point
_position
=
Point
.
origin
;
/// The point at which to paint the child in the parent's coordinate system
/// The point at which to paint the child in the parent's coordinate system
Point
get
position
=>
_position
;
Point
get
position
=>
_position
;
...
@@ -294,6 +296,7 @@ class BoxParentData extends ParentData {
...
@@ -294,6 +296,7 @@ class BoxParentData extends ParentData {
assert
(
RenderObject
.
debugDoingLayout
);
assert
(
RenderObject
.
debugDoingLayout
);
_position
=
value
;
_position
=
value
;
}
}
Offset
get
offset
=>
_position
.
toOffset
();
String
toString
()
=>
'position=
$position
'
;
String
toString
()
=>
'position=
$position
'
;
}
}
...
@@ -771,7 +774,7 @@ abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
...
@@ -771,7 +774,7 @@ abstract class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox, Pare
RenderBox
child
=
firstChild
;
RenderBox
child
=
firstChild
;
while
(
child
!=
null
)
{
while
(
child
!=
null
)
{
final
ParentDataType
childParentData
=
child
.
parentData
;
final
ParentDataType
childParentData
=
child
.
parentData
;
context
.
paintChild
(
child
,
childParentData
.
position
+
offset
);
context
.
paintChild
(
child
,
childParentData
.
offset
+
offset
);
child
=
childParentData
.
nextSibling
;
child
=
childParentData
.
nextSibling
;
}
}
}
}
...
...
packages/flutter/lib/src/rendering/object.dart
View file @
4fb5bcd8
...
@@ -44,7 +44,9 @@ class PaintingCanvas extends Canvas {
...
@@ -44,7 +44,9 @@ class PaintingCanvas extends Canvas {
// TODO(ianh): Just use ui.Canvas everywhere instead
// TODO(ianh): Just use ui.Canvas everywhere instead
}
}
/// A place to paint
typedef
void
PaintingContextCallback
(
PaintingContext
context
,
Offset
offset
);
/// A place to paint.
///
///
/// Rather than holding a canvas directly, render objects paint using a painting
/// Rather than holding a canvas directly, render objects paint using a painting
/// context. The painting context has a canvas, which receives the
/// context. The painting context has a canvas, which receives the
...
@@ -57,190 +59,211 @@ class PaintingCanvas extends Canvas {
...
@@ -57,190 +59,211 @@ class PaintingCanvas extends Canvas {
/// not hold a reference to the canvas across operations that might paint
/// not hold a reference to the canvas across operations that might paint
/// child render objects.
/// child render objects.
class
PaintingContext
{
class
PaintingContext
{
/// Construct a painting context at a given offset with the given bounds
PaintingContext
.
_
(
this
.
_containerLayer
,
this
.
_paintBounds
);
PaintingContext
.
withOffset
(
Offset
offset
,
Rect
paintBounds
)
{
_containerLayer
=
new
ContainerLayer
(
offset:
offset
);
final
ContainerLayer
_containerLayer
;
_startRecording
(
paintBounds
);
final
Rect
_paintBounds
;
/// Repaint the given render object.
///
/// The render object must have a composited layer and must be in need of
/// painting. The render object's layer is re-used, along with any layers in
/// the subtree that don't need to be repainted.
static
void
repaintCompositedChild
(
RenderObject
child
)
{
assert
(
child
.
hasLayer
);
assert
(
child
.
needsPaint
);
child
.
_layer
??=
new
ContainerLayer
();
child
.
_layer
.
removeAllChildren
();
PaintingContext
childContext
=
new
PaintingContext
.
_
(
child
.
_layer
,
child
.
paintBounds
);
child
.
_paintWithContext
(
childContext
,
Offset
.
zero
);
childContext
.
_stopRecordingIfNeeded
();
}
/// Paint a child render object.
///
/// If the child has its own composited layer, the child will be composited
/// into the layer subtree associated with this painting context. Otherwise,
/// the child will be painted into the current PictureLayer for this context.
void
paintChild
(
RenderObject
child
,
Offset
offset
)
{
if
(
child
.
hasLayer
)
{
_stopRecordingIfNeeded
();
_compositeChild
(
child
,
offset
);
}
else
{
child
.
_paintWithContext
(
this
,
offset
);
}
}
}
/// Construct a painting context for painting into the given layer with the given bounds
void
_compositeChild
(
RenderObject
child
,
Offset
offset
)
{
PaintingContext
.
withLayer
(
ContainerLayer
containerLayer
,
Rect
paintBounds
)
{
assert
(!
_isRecording
);
_containerLayer
=
containerLayer
;
assert
(
child
.
hasLayer
);
_startRecording
(
paintBounds
);
// Create a layer for our child, and paint the child into it.
if
(
child
.
needsPaint
)
{
repaintCompositedChild
(
child
);
}
else
{
assert
(
child
.
_layer
!=
null
);
child
.
_layer
.
detach
();
}
_appendLayer
(
child
.
_layer
,
offset
);
}
}
/// A backdoor for testing that lets the test set a specific canvas
void
_appendLayer
(
Layer
layer
,
Offset
offset
)
{
PaintingContext
.
forTesting
(
this
.
_canvas
);
assert
(!
_isRecording
);
layer
.
offset
=
offset
;
_containerLayer
.
append
(
layer
);
}
ContainerLayer
_containerLayer
;
bool
get
_isRecording
{
/// The layer contain all the composting layers that will be used for this context
final
bool
hasCanvas
=
(
_canvas
!=
null
);
ContainerLayer
get
containerLayer
=>
_containerLayer
;
assert
(()
{
if
(
hasCanvas
)
{
assert
(
_currentLayer
!=
null
);
assert
(
_recorder
!=
null
);
assert
(
_canvas
!=
null
);
}
else
{
assert
(
_currentLayer
==
null
);
assert
(
_recorder
==
null
);
assert
(
_canvas
==
null
);
}
return
true
;
});
return
hasCanvas
;
}
// Recording state
PictureLayer
_currentLayer
;
PictureLayer
_currentLayer
;
ui
.
PictureRecorder
_recorder
;
ui
.
PictureRecorder
_recorder
;
PaintingCanvas
_canvas
;
PaintingCanvas
_canvas
;
/// The canvas on which to paint
/// The canvas on which to paint.
///
///
/// This getter can return a different canvas object after painting child
/// The current canvas can change whenever you paint a child using this
/// render objects using this canvas because draw operations before and after
/// context, which means it's fragile to hold a reference to the canvas
/// a child might need to be recorded in separate compositing layers.
/// returned by this getter.
PaintingCanvas
get
canvas
=>
_canvas
;
PaintingCanvas
get
canvas
{
if
(
_canvas
==
null
)
void
_startRecording
(
Rect
paintBounds
)
{
_startRecording
();
assert
(
_currentLayer
==
null
);
return
_canvas
;
assert
(
_recorder
==
null
);
}
assert
(
_canvas
==
null
);
_currentLayer
=
new
PictureLayer
(
paintBounds:
paintBounds
);
void
_startRecording
()
{
assert
(!
_isRecording
);
_currentLayer
=
new
PictureLayer
(
paintBounds:
_paintBounds
);
_recorder
=
new
ui
.
PictureRecorder
();
_recorder
=
new
ui
.
PictureRecorder
();
_canvas
=
new
PaintingCanvas
(
_recorder
,
paintBounds
);
_canvas
=
new
PaintingCanvas
(
_recorder
,
_
paintBounds
);
_containerLayer
.
append
(
_currentLayer
);
_containerLayer
.
append
(
_currentLayer
);
}
}
/// Stop recording draw operations into the current compositing layer
void
_stopRecordingIfNeeded
()
{
void
endRecording
()
{
if
(!
_isRecording
)
assert
(
_currentLayer
!=
null
);
return
;
assert
(
_recorder
!=
null
);
assert
(
_canvas
!=
null
);
_currentLayer
.
picture
=
_recorder
.
endRecording
();
_currentLayer
.
picture
=
_recorder
.
endRecording
();
_currentLayer
=
null
;
_currentLayer
=
null
;
_recorder
=
null
;
_recorder
=
null
;
_canvas
=
null
;
_canvas
=
null
;
}
}
/// Whether the canvas is in a state that permits drawing the given child
static
final
Paint
_disableAntialias
=
new
Paint
()..
isAntiAlias
=
false
;
bool
debugCanPaintChild
(
RenderObject
child
)
{
// You need to use layers if you are applying transforms, clips,
// or similar, to a child. To do so, use the paintChildWith*()
// methods below.
// (commented out for now because we haven't ported everything yet)
assert
(
canvas
.
getSaveCount
()
==
1
||
!
child
.
needsCompositing
);
return
true
;
}
/// P
aint a child render object at the given position
/// P
ush a statistics overlay.
///
///
/// If the child needs compositing, a new composited layer will be created
/// Statistics overlays are always composited because they're drawn by the
/// and inserted into the containerLayer. If the child does not require
/// compositor.
/// compositing, the child will be painted into the current canvas.
void
pushStatistics
(
Offset
offset
,
int
optionsMask
,
int
rasterizerThreshold
,
Size
size
)
{
///
_stopRecordingIfNeeded
();
/// Note: After calling this function, the current canvas might change.
StatisticsLayer
statisticsLayer
=
new
StatisticsLayer
(
void
paintChild
(
RenderObject
child
,
Point
childPosition
)
{
assert
(
debugCanPaintChild
(
child
));
final
Offset
childOffset
=
childPosition
.
toOffset
();
if
(!
child
.
hasLayer
)
{
insertChild
(
child
,
childOffset
);
}
else
{
compositeChild
(
child
,
childOffset:
childOffset
,
parentLayer:
_containerLayer
);
}
}
void
paintStatistics
(
int
optionsMask
,
int
rasterizerThreshold
,
Offset
offset
,
Size
size
)
{
StatisticsLayer
statsLayer
=
new
StatisticsLayer
(
offset:
offset
,
paintBounds:
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
size
.
width
,
size
.
height
),
paintBounds:
new
Rect
.
fromLTWH
(
0.0
,
0.0
,
size
.
width
,
size
.
height
),
optionsMask
:
optionsMask
,
optionsMask:
optionsMask
,
rasterizerThreshold
:
rasterizerThreshold
rasterizerThreshold:
rasterizerThreshold
);
);
_
containerLayer
.
append
(
statsLayer
);
_
appendLayer
(
statisticsLayer
,
offset
);
}
}
// Below we have various variants of the paintChild() method, which
/// Push a rectangular clip rect.
// do additional work, such as clipping or transforming, at the same
// time as painting the children.
// If none of the descendants require compositing, then these don't
// need to use a new layer, because at no point will any of the
// children introduce a new layer of their own. In that case, we
// just use regular canvas commands to do the work.
// If at least one of the descendants requires compositing, though,
// we introduce a new layer to do the work, so that when the
// children are split into a new layer, the work (e.g. clip) is not
// lost, as it would if we didn't introduce a new layer.
static
final
Paint
_disableAntialias
=
new
Paint
()..
isAntiAlias
=
false
;
/// Paint a child with a rectangular clip
///
///
/// If the child needs compositing, the clip will be applied by a
/// This function will call painter synchronously with a painting context that
/// compositing layer. Otherwise, the clip will be applied by the canvas.
/// is clipped by the given clip. The given clip should not incorporate the
///
/// painting offset.
/// Note: clipRect is in the parent's coordinate space
void
pushClipRect
(
bool
needsCompositing
,
Offset
offset
,
Rect
clipRect
,
PaintingContextCallback
painter
)
{
void
paintChildWithClipRect
(
RenderObject
child
,
Point
childPosition
,
Rect
clipRect
)
{
if
(
needsCompositing
)
{
assert
(
debugCanPaintChild
(
child
));
_stopRecordingIfNeeded
();
final
Offset
childOffset
=
childPosition
.
toOffset
();
ClipRectLayer
clipLayer
=
new
ClipRectLayer
(
clipRect:
clipRect
);
if
(!
child
.
needsCompositing
)
{
_appendLayer
(
clipLayer
,
offset
);
PaintingContext
childContext
=
new
PaintingContext
.
_
(
clipLayer
,
clipRect
);
painter
(
childContext
,
Offset
.
zero
);
childContext
.
_stopRecordingIfNeeded
();
}
else
{
canvas
.
save
();
canvas
.
save
();
canvas
.
clipRect
(
clipRect
);
canvas
.
clipRect
(
clipRect
.
shift
(
offset
)
);
insertChild
(
child
,
childO
ffset
);
painter
(
this
,
o
ffset
);
canvas
.
restore
();
canvas
.
restore
();
}
else
{
ClipRectLayer
clipLayer
=
new
ClipRectLayer
(
offset:
childOffset
,
clipRect:
clipRect
);
_containerLayer
.
append
(
clipLayer
);
compositeChild
(
child
,
parentLayer:
clipLayer
);
}
}
}
}
/// P
aint a child with a rounded-rectangular clip
/// P
ush a rounded-rect clip rect.
///
///
/// If the child needs compositing, the clip will be applied by a
/// This function will call painter synchronously with a painting context that
/// compositing layer. Otherwise, the clip will be applied by the canvas.
/// is clipped by the given clip. The given clip should not incorporate the
///
/// painting offset.
/// Note: clipRRect is in the parent's coordinate space
void
pushClipRRect
(
bool
needsCompositing
,
Offset
offset
,
Rect
bounds
,
ui
.
RRect
clipRRect
,
PaintingContextCallback
painter
)
{
void
paintChildWithClipRRect
(
RenderObject
child
,
Point
childPosition
,
Rect
bounds
,
ui
.
RRect
clipRRect
)
{
if
(
needsCompositing
)
{
assert
(
debugCanPaintChild
(
child
));
_stopRecordingIfNeeded
();
final
Offset
childOffset
=
childPosition
.
toOffset
();
ClipRRectLayer
clipLayer
=
new
ClipRRectLayer
(
bounds:
bounds
,
clipRRect:
clipRRect
);
if
(!
child
.
needsCompositing
)
{
_appendLayer
(
clipLayer
,
offset
);
canvas
.
saveLayer
(
bounds
,
_disableAntialias
);
PaintingContext
childContext
=
new
PaintingContext
.
_
(
clipLayer
,
bounds
);
painter
(
childContext
,
Offset
.
zero
);
childContext
.
_stopRecordingIfNeeded
();
}
else
{
canvas
.
saveLayer
(
bounds
.
shift
(
offset
),
_disableAntialias
);
// TODO(abarth): Remove this translation once RRect.shift works again.
canvas
.
translate
(
offset
.
dx
,
offset
.
dy
);
canvas
.
clipRRect
(
clipRRect
);
canvas
.
clipRRect
(
clipRRect
);
insertChild
(
child
,
childOffset
);
painter
(
this
,
Offset
.
zero
);
canvas
.
restore
();
canvas
.
restore
();
}
else
{
ClipRRectLayer
clipLayer
=
new
ClipRRectLayer
(
offset:
childOffset
,
bounds:
bounds
,
clipRRect:
clipRRect
);
_containerLayer
.
append
(
clipLayer
);
compositeChild
(
child
,
parentLayer:
clipLayer
);
}
}
}
}
/// Paint a child with a clip path
/// Push a path clip.
///
/// If the child needs compositing, the clip will be applied by a
/// compositing layer. Otherwise, the clip will be applied by the canvas.
///
///
/// Note: bounds and clipPath are in the parent's coordinate space
/// This function will call painter synchronously with a painting context that
void
paintChildWithClipPath
(
RenderObject
child
,
Point
childPosition
,
Rect
bounds
,
Path
clipPath
)
{
/// is clipped by the given clip. The given clip should not incorporate the
assert
(
debugCanPaintChild
(
child
));
/// painting offset.
final
Offset
childOffset
=
childPosition
.
toOffset
();
void
pushClipPath
(
bool
needsCompositing
,
Offset
offset
,
Rect
bounds
,
Path
clipPath
,
PaintingContextCallback
painter
)
{
if
(!
child
.
needsCompositing
)
{
if
(
needsCompositing
)
{
canvas
.
saveLayer
(
bounds
,
_disableAntialias
);
_stopRecordingIfNeeded
();
canvas
.
clipPath
(
clipPath
);
ClipPathLayer
clipLayer
=
new
ClipPathLayer
(
bounds:
bounds
,
clipPath:
clipPath
);
canvas
.
translate
(
childOffset
.
dx
,
childOffset
.
dy
);
_appendLayer
(
clipLayer
,
offset
);
insertChild
(
child
,
Offset
.
zero
);
PaintingContext
childContext
=
new
PaintingContext
.
_
(
clipLayer
,
bounds
);
canvas
.
restore
();
painter
(
childContext
,
Offset
.
zero
);
childContext
.
_stopRecordingIfNeeded
();
}
else
{
}
else
{
ClipPathLayer
clipLayer
=
new
ClipPathLayer
(
offset:
childOffset
,
bounds:
bounds
,
clipPath:
clipPath
);
canvas
.
saveLayer
(
bounds
.
shift
(
offset
),
_disableAntialias
);
_containerLayer
.
append
(
clipLayer
);
canvas
.
clipPath
(
clipPath
.
shift
(
offset
));
compositeChild
(
child
,
parentLayer:
clipLayer
);
painter
(
this
,
offset
);
canvas
.
restore
();
}
}
}
}
/// P
aint a child with a transform
/// P
ush a transform.
///
///
/// If the child needs compositing, the transform will be applied by a
/// This function will call painter synchronously with a painting context that
/// compositing layer. Otherwise, the transform will be applied by the canvas.
/// is transformed by the given transform. The given transform should not
void
paintChildWithTransform
(
RenderObject
child
,
Point
childPosition
,
Matrix4
transform
)
{
/// incorporate the painting offset.
assert
(
debugCanPaintChild
(
child
));
void
pushTransform
(
bool
needsCompositing
,
Offset
offset
,
Matrix4
transform
,
PaintingContextCallback
painter
)
{
final
Offset
childOffset
=
childPosition
.
toOffset
();
if
(
needsCompositing
)
{
if
(!
child
.
needsCompositing
)
{
_stopRecordingIfNeeded
();
TransformLayer
transformLayer
=
new
TransformLayer
(
transform:
transform
);
_appendLayer
(
transformLayer
,
offset
);
PaintingContext
childContext
=
new
PaintingContext
.
_
(
transformLayer
,
_paintBounds
);
painter
(
childContext
,
Offset
.
zero
);
childContext
.
_stopRecordingIfNeeded
();
}
else
{
Matrix4
offsetMatrix
=
new
Matrix4
.
translationValues
(
offset
.
dx
,
offset
.
dy
,
0.0
);
Matrix4
trasnformWithOffset
=
offsetMatrix
*
transform
;
canvas
.
save
();
canvas
.
save
();
canvas
.
translate
(
childOffset
.
dx
,
childOffset
.
dy
);
canvas
.
concat
(
trasnformWithOffset
.
storage
);
canvas
.
concat
(
transform
.
storage
);
painter
(
this
,
Offset
.
zero
);
insertChild
(
child
,
Offset
.
zero
);
canvas
.
restore
();
canvas
.
restore
();
}
else
{
TransformLayer
transformLayer
=
new
TransformLayer
(
offset:
childOffset
,
transform:
transform
);
_containerLayer
.
append
(
transformLayer
);
compositeChild
(
child
,
parentLayer:
transformLayer
);
}
}
}
}
...
@@ -251,29 +274,23 @@ class PaintingContext {
...
@@ -251,29 +274,23 @@ class PaintingContext {
..
isAntiAlias
=
false
;
..
isAntiAlias
=
false
;
}
}
/// P
aint a child with an opacity
/// P
ush an opacity layer.
///
///
/// If the child needs compositing, the blending operation will be applied by
/// This function will call painter synchronously with a painting context that
/// a compositing layer. Otherwise, the blending operation will be applied by
/// will be blended with the given alpha value.
/// the canvas.
void
pushOpacity
(
bool
needsCompositing
,
Offset
offset
,
Rect
bounds
,
int
alpha
,
PaintingContextCallback
painter
)
{
void
paintChildWithOpacity
(
RenderObject
child
,
if
(
needsCompositing
)
{
Point
childPosition
,
_stopRecordingIfNeeded
();
Rect
bounds
,
OpacityLayer
opacityLayer
=
new
OpacityLayer
(
bounds:
bounds
,
alpha:
alpha
);
int
alpha
)
{
_appendLayer
(
opacityLayer
,
offset
);
assert
(
debugCanPaintChild
(
child
));
PaintingContext
childContext
=
new
PaintingContext
.
_
(
opacityLayer
,
bounds
);
final
Offset
childOffset
=
childPosition
.
toOffset
();
painter
(
childContext
,
Offset
.
zero
);
if
(!
child
.
needsCompositing
)
{
childContext
.
_stopRecordingIfNeeded
();
canvas
.
saveLayer
(
bounds
,
_getPaintForAlpha
(
alpha
));
canvas
.
translate
(
childOffset
.
dx
,
childOffset
.
dy
);
insertChild
(
child
,
Offset
.
zero
);
canvas
.
restore
();
}
else
{
}
else
{
OpacityLayer
paintLayer
=
new
OpacityLayer
(
// TODO(abarth): pushOpacity should require bounds.
offset:
childOffset
,
canvas
.
saveLayer
(
bounds
?.
shift
(
offset
),
_getPaintForAlpha
(
alpha
));
bounds:
bounds
,
painter
(
this
,
offset
);
alpha:
alpha
);
canvas
.
restore
();
_containerLayer
.
append
(
paintLayer
);
compositeChild
(
child
,
parentLayer:
paintLayer
);
}
}
}
}
...
@@ -285,77 +302,20 @@ class PaintingContext {
...
@@ -285,77 +302,20 @@ class PaintingContext {
..
shader
=
shaderCallback
(
bounds
);
..
shader
=
shaderCallback
(
bounds
);
}
}
void
paintChildWithShaderMask
(
RenderObject
child
,
/// Push a shader mask.
Point
childPosition
,
Rect
bounds
,
ShaderCallback
shaderCallback
,
TransferMode
transferMode
)
{
assert
(
debugCanPaintChild
(
child
));
final
Offset
childOffset
=
childPosition
.
toOffset
();
if
(!
child
.
needsCompositing
)
{
canvas
.
saveLayer
(
bounds
,
new
Paint
());
canvas
.
translate
(
childOffset
.
dx
,
childOffset
.
dy
);
insertChild
(
child
,
Offset
.
zero
);
Paint
shaderPaint
=
_getPaintForShaderMask
(
bounds
,
shaderCallback
,
transferMode
);
canvas
.
drawRect
(
Offset
.
zero
&
new
Size
(
bounds
.
width
,
bounds
.
height
),
shaderPaint
);
canvas
.
restore
();
}
else
{
// TODO(hansmuller) support compositing ShaderMasks
assert
(
'Support for compositing ShaderMasks is TBD'
is
String
);
}
}
/// Instructs the child to draw itself onto this context at the given offset
///
///
/// Do not call directly. This function is visible so that it can be
/// This function will call painter synchronously with a painting context that
/// overridden in tests.
/// will be masked with the given shader.
void
insertChild
(
RenderObject
child
,
Offset
offset
)
{
child
.
_paintWithContext
(
this
,
offset
);
}
/// Instructs the child to paint itself into a new composited layer using this context
///
///
/// Do not call directly. This function is visible so that it can be
/// WARNING: This function does not yet support compositing.
/// overridden in tests.
void
pushShaderMask
(
bool
needsCompositing
,
Offset
offset
,
Rect
bounds
,
ShaderCallback
shaderCallback
,
TransferMode
transferMode
,
PaintingContextCallback
painter
)
{
void
compositeChild
(
RenderObject
child
,
{
Offset
childOffset:
Offset
.
zero
,
ContainerLayer
parentLayer
})
{
assert
(!
needsCompositing
);
// TODO(abarth): Implement compositing for shader masks.
// This ends the current layer and starts a new layer for the
canvas
.
saveLayer
(
bounds
.
shift
(
offset
),
_disableAntialias
);
// remainder of our rendering. It also creates a new layer for the
painter
(
this
,
offset
);
// child, and inserts that layer into the given parentLayer, which
Paint
shaderPaint
=
_getPaintForShaderMask
(
bounds
,
shaderCallback
,
transferMode
);
// must either be our current layer's parent layer, or at least
canvas
.
drawRect
(
bounds
,
shaderPaint
);
// must have our current layer's parent layer as an ancestor.
canvas
.
restore
();
final
PictureLayer
originalLayer
=
_currentLayer
;
assert
(()
{
assert
(
parentLayer
!=
null
);
assert
(
originalLayer
!=
null
);
assert
(
originalLayer
.
parent
!=
null
);
ContainerLayer
ancestor
=
parentLayer
;
while
(
ancestor
!=
null
&&
ancestor
!=
originalLayer
.
parent
)
ancestor
=
ancestor
.
parent
;
assert
(
ancestor
==
originalLayer
.
parent
);
assert
(
originalLayer
.
parent
==
_containerLayer
);
return
true
;
});
// End our current layer.
endRecording
();
// Create a layer for our child, and paint the child into it.
if
(
child
.
needsPaint
||
!
child
.
hasLayer
)
{
PaintingContext
newContext
=
new
PaintingContext
.
withOffset
(
childOffset
,
child
.
paintBounds
);
child
.
_layer
=
newContext
.
containerLayer
;
child
.
_paintWithContext
(
newContext
,
Offset
.
zero
);
newContext
.
endRecording
();
}
else
{
assert
(
child
.
_layer
!=
null
);
child
.
_layer
.
detach
();
child
.
_layer
.
offset
=
childOffset
;
}
parentLayer
.
append
(
child
.
_layer
);
// Start a new layer for anything that remains of our own paint.
_startRecording
(
originalLayer
.
paintBounds
);
}
}
}
}
/// An encapsulation of a renderer and a paint() method.
/// An encapsulation of a renderer and a paint() method.
...
@@ -972,7 +932,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
...
@@ -972,7 +932,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
for
(
RenderObject
node
in
dirtyNodes
..
sort
((
RenderObject
a
,
RenderObject
b
)
=>
b
.
depth
-
a
.
depth
))
{
for
(
RenderObject
node
in
dirtyNodes
..
sort
((
RenderObject
a
,
RenderObject
b
)
=>
b
.
depth
-
a
.
depth
))
{
assert
(
node
.
_needsPaint
);
assert
(
node
.
_needsPaint
);
if
(
node
.
attached
)
if
(
node
.
attached
)
node
.
_repaint
(
);
PaintingContext
.
repaintCompositedChild
(
node
);
};
};
assert
(
_nodesNeedingPaint
.
length
==
0
);
assert
(
_nodesNeedingPaint
.
length
==
0
);
}
finally
{
}
finally
{
...
@@ -997,15 +957,6 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
...
@@ -997,15 +957,6 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
assert
(
_needsPaint
);
assert
(
_needsPaint
);
_nodesNeedingPaint
.
add
(
this
);
_nodesNeedingPaint
.
add
(
this
);
}
}
void
_repaint
()
{
assert
(
hasLayer
);
assert
(
_layer
!=
null
);
_layer
.
removeAllChildren
();
PaintingContext
context
=
new
PaintingContext
.
withLayer
(
_layer
,
paintBounds
);
_layer
=
context
.
_containerLayer
;
_paintWithContext
(
context
,
Offset
.
zero
);
context
.
endRecording
();
}
void
_paintWithContext
(
PaintingContext
context
,
Offset
offset
)
{
void
_paintWithContext
(
PaintingContext
context
,
Offset
offset
)
{
assert
(!
_debugDoingThisPaint
);
assert
(!
_debugDoingThisPaint
);
assert
(!
_needsLayout
);
assert
(!
_needsLayout
);
...
...
packages/flutter/lib/src/rendering/overflow.dart
View file @
4fb5bcd8
...
@@ -131,7 +131,7 @@ class RenderOverflowBox extends RenderBox with RenderObjectWithChildMixin<Render
...
@@ -131,7 +131,7 @@ class RenderOverflowBox extends RenderBox with RenderObjectWithChildMixin<Render
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
if
(
child
!=
null
)
context
.
paintChild
(
child
,
offset
.
toPoint
()
);
context
.
paintChild
(
child
,
offset
);
}
}
void
debugDescribeSettings
(
List
<
String
>
settings
)
{
void
debugDescribeSettings
(
List
<
String
>
settings
)
{
...
@@ -198,7 +198,7 @@ class RenderSizedOverflowBox extends RenderBox with RenderObjectWithChildMixin<R
...
@@ -198,7 +198,7 @@ class RenderSizedOverflowBox extends RenderBox with RenderObjectWithChildMixin<R
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
if
(
child
!=
null
)
context
.
paintChild
(
child
,
offset
.
toPoint
()
);
context
.
paintChild
(
child
,
offset
);
}
}
}
}
...
...
packages/flutter/lib/src/rendering/proxy_box.dart
View file @
4fb5bcd8
...
@@ -77,7 +77,7 @@ class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox
...
@@ -77,7 +77,7 @@ class RenderProxyBox extends RenderBox with RenderObjectWithChildMixin<RenderBox
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
if
(
child
!=
null
)
context
.
paintChild
(
child
,
offset
.
toPoint
()
);
context
.
paintChild
(
child
,
offset
);
}
}
}
}
...
@@ -501,10 +501,12 @@ class RenderOpacity extends RenderProxyBox {
...
@@ -501,10 +501,12 @@ class RenderOpacity extends RenderProxyBox {
int
a
=
_alpha
;
int
a
=
_alpha
;
if
(
a
==
0
)
if
(
a
==
0
)
return
;
return
;
if
(
a
==
255
)
if
(
a
==
255
)
{
context
.
paintChild
(
child
,
offset
.
toPoint
());
context
.
paintChild
(
child
,
offset
);
else
return
;
context
.
paintChildWithOpacity
(
child
,
offset
.
toPoint
(),
null
,
a
);
}
// TODO(abarth): We should pass bounds here.
context
.
pushOpacity
(
needsCompositing
,
offset
,
null
,
a
,
super
.
paint
);
}
}
}
}
...
@@ -540,7 +542,7 @@ class RenderShaderMask extends RenderProxyBox {
...
@@ -540,7 +542,7 @@ class RenderShaderMask extends RenderProxyBox {
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
if
(
child
!=
null
)
context
.
p
aintChildWithShaderMask
(
child
,
offset
.
toPoint
(),
offset
&
size
,
_shaderCallback
,
_transferMode
);
context
.
p
ushShaderMask
(
needsCompositing
,
offset
,
Point
.
origin
&
size
,
_shaderCallback
,
_transferMode
,
super
.
paint
);
}
}
}
}
...
@@ -552,7 +554,7 @@ class RenderClipRect extends RenderProxyBox {
...
@@ -552,7 +554,7 @@ class RenderClipRect extends RenderProxyBox {
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
if
(
child
!=
null
)
context
.
p
aintChildWithClipRect
(
child
,
offset
.
toPoint
(),
offset
&
size
);
context
.
p
ushClipRect
(
needsCompositing
,
offset
,
Point
.
origin
&
size
,
super
.
paint
);
}
}
}
}
...
@@ -598,9 +600,9 @@ class RenderClipRRect extends RenderProxyBox {
...
@@ -598,9 +600,9 @@ class RenderClipRRect extends RenderProxyBox {
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
{
if
(
child
!=
null
)
{
Rect
rect
=
offset
&
size
;
Rect
rect
=
Point
.
origin
&
size
;
ui
.
RRect
rrect
=
new
ui
.
RRect
.
fromRectXY
(
rect
,
xRadius
,
yRadius
);
ui
.
RRect
rrect
=
new
ui
.
RRect
.
fromRectXY
(
rect
,
xRadius
,
yRadius
);
context
.
p
aintChildWithClipRRect
(
child
,
offset
.
toPoint
(),
rect
,
rrec
t
);
context
.
p
ushClipRRect
(
needsCompositing
,
offset
,
rect
,
rrect
,
super
.
pain
t
);
}
}
}
}
}
}
...
@@ -615,7 +617,7 @@ class RenderClipOval extends RenderProxyBox {
...
@@ -615,7 +617,7 @@ class RenderClipOval extends RenderProxyBox {
Rect
_cachedRect
;
Rect
_cachedRect
;
Path
_cachedPath
;
Path
_cachedPath
;
Path
_getPath
(
Rect
rect
)
{
Path
_get
Clip
Path
(
Rect
rect
)
{
if
(
rect
!=
_cachedRect
)
{
if
(
rect
!=
_cachedRect
)
{
_cachedRect
=
rect
;
_cachedRect
=
rect
;
_cachedPath
=
new
Path
()..
addOval
(
_cachedRect
);
_cachedPath
=
new
Path
()..
addOval
(
_cachedRect
);
...
@@ -634,8 +636,8 @@ class RenderClipOval extends RenderProxyBox {
...
@@ -634,8 +636,8 @@ class RenderClipOval extends RenderProxyBox {
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
{
if
(
child
!=
null
)
{
Rect
rect
=
offset
&
size
;
Rect
bounds
=
Point
.
origin
&
size
;
context
.
p
aintChildWithClipPath
(
child
,
offset
.
toPoint
(),
rect
,
_getPath
(
rect
)
);
context
.
p
ushClipPath
(
needsCompositing
,
offset
,
bounds
,
_getClipPath
(
bounds
),
super
.
paint
);
}
}
}
}
}
}
...
@@ -863,7 +865,7 @@ class RenderTransform extends RenderProxyBox {
...
@@ -863,7 +865,7 @@ class RenderTransform extends RenderProxyBox {
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
if
(
child
!=
null
)
context
.
p
aintChildWithTransform
(
child
,
offset
.
toPoint
(),
_effectiveTransform
);
context
.
p
ushTransform
(
needsCompositing
,
offset
,
_effectiveTransform
,
super
.
paint
);
}
}
void
applyPaintTransform
(
Matrix4
transform
)
{
void
applyPaintTransform
(
Matrix4
transform
)
{
...
...
packages/flutter/lib/src/rendering/shifted_box.dart
View file @
4fb5bcd8
...
@@ -56,7 +56,7 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
...
@@ -56,7 +56,7 @@ abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixi
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
{
if
(
child
!=
null
)
{
final
BoxParentData
childParentData
=
child
.
parentData
;
final
BoxParentData
childParentData
=
child
.
parentData
;
context
.
paintChild
(
child
,
childParentData
.
position
+
offset
);
context
.
paintChild
(
child
,
childParentData
.
offset
+
offset
);
}
}
}
}
...
...
packages/flutter/lib/src/rendering/stack.dart
View file @
4fb5bcd8
...
@@ -489,6 +489,6 @@ class RenderIndexedStack extends RenderStackBase {
...
@@ -489,6 +489,6 @@ class RenderIndexedStack extends RenderStackBase {
return
;
return
;
RenderBox
child
=
_childAtIndex
();
RenderBox
child
=
_childAtIndex
();
final
StackParentData
childParentData
=
child
.
parentData
;
final
StackParentData
childParentData
=
child
.
parentData
;
context
.
paintChild
(
child
,
childParentData
.
position
+
offset
);
context
.
paintChild
(
child
,
childParentData
.
offset
+
offset
);
}
}
}
}
packages/flutter/lib/src/rendering/statistics_box.dart
View file @
4fb5bcd8
...
@@ -54,6 +54,6 @@ class RenderStatisticsBox extends RenderBox {
...
@@ -54,6 +54,6 @@ class RenderStatisticsBox extends RenderBox {
}
}
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
context
.
p
aintStatistics
(
optionsMask
,
rasterizerThreshold
,
offset
,
size
);
context
.
p
ushStatistics
(
offset
,
optionsMask
,
rasterizerThreshold
,
size
);
}
}
}
}
packages/flutter/lib/src/rendering/view.dart
View file @
4fb5bcd8
...
@@ -110,7 +110,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
...
@@ -110,7 +110,7 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
if
(
child
!=
null
)
context
.
paintChild
(
child
,
offset
.
toPoint
()
);
context
.
paintChild
(
child
,
offset
);
}
}
/// Uploads the composited layer tree to the engine
/// Uploads the composited layer tree to the engine
...
...
packages/flutter/lib/src/rendering/viewport.dart
View file @
4fb5bcd8
...
@@ -146,12 +146,15 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox
...
@@ -146,12 +146,15 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin<RenderBox
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
if
(
child
!=
null
)
{
if
(
child
!=
null
)
{
Offset
roundedScrollOffset
=
_scrollOffsetRoundedToIntegerDevicePixels
;
Offset
roundedScrollOffset
=
_scrollOffsetRoundedToIntegerDevicePixels
;
bool
_needsClip
=
offset
<
Offset
.
zero
||
bool
_needsClip
=
offset
<
Offset
.
zero
!(
offset
&
size
).
contains
(((
offset
-
roundedScrollOffset
)
&
child
.
size
).
bottomRight
);
||
!(
offset
&
size
).
contains
(((
offset
-
roundedScrollOffset
)
&
child
.
size
).
bottomRight
);
if
(
_needsClip
)
if
(
_needsClip
)
{
context
.
paintChildWithClipRect
(
child
,
(
offset
-
roundedScrollOffset
).
toPoint
(),
offset
&
size
);
context
.
pushClipRect
(
needsCompositing
,
offset
,
Point
.
origin
&
size
,
(
PaintingContext
context
,
Offset
offset
)
{
else
context
.
paintChild
(
child
,
offset
-
roundedScrollOffset
);
context
.
paintChild
(
child
,
(
offset
-
roundedScrollOffset
).
toPoint
());
});
}
else
{
context
.
paintChild
(
child
,
offset
-
roundedScrollOffset
);
}
}
}
}
}
...
...
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