OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "config.h" | |
6 #include "core/paint/PaintPropertyTreeBuilder.h" | |
7 | |
8 #include "core/frame/FrameView.h" | |
9 #include "core/layout/LayoutView.h" | |
10 #include "core/paint/ObjectPaintProperties.h" | |
11 #include "core/paint/PaintLayer.h" | |
12 #include "platform/graphics/paint/TransformPaintPropertyNode.h" | |
13 #include "platform/transforms/TransformationMatrix.h" | |
14 | |
15 namespace blink { | |
16 | |
17 struct PaintPropertyTreeBuilder::Context { | |
pdr.
2015/10/20 22:02:30
Lets doc this with a small comment describing why
jbroman
2015/10/20 23:50:13
I'd also like a brief explanation of how it works.
trchen
2015/10/21 06:16:20
Done.
| |
18 Context() : currentTransform(nullptr), transformForOutOfFlowPositioned(nullp tr), transformForFixedPositioned(nullptr) { } | |
19 | |
20 TransformPaintPropertyNode* currentTransform; | |
21 LayoutPoint paintOffset; | |
22 | |
23 TransformPaintPropertyNode* transformForOutOfFlowPositioned; | |
24 LayoutPoint paintOffsetForOutOfFlowPositioned; | |
25 | |
26 TransformPaintPropertyNode* transformForFixedPositioned; | |
27 LayoutPoint paintOffsetForFixedPositioned; | |
28 }; | |
29 | |
30 void PaintPropertyTreeBuilder::buildPropertyTrees(FrameView& rootFrame) | |
31 { | |
32 walk(rootFrame, Context()); | |
33 } | |
34 | |
35 void PaintPropertyTreeBuilder::walk(FrameView& frameView, const Context& context ) | |
36 { | |
37 Context localContext(context); | |
38 RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation; | |
pdr.
2015/10/20 22:02:30
In this function only, lets move these decls down
trchen
2015/10/21 06:16:20
Done.
| |
39 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation; | |
40 | |
41 TransformationMatrix frameTranslate; | |
42 frameTranslate.translate(frameView.x(), frameView.y()); | |
43 // The frame owner applies paint offset already. | |
44 // This assumption may change in the future. | |
45 ASSERT(context.paintOffset == LayoutPoint()); | |
46 newTransformNodeForPreTranslation = TransformPaintPropertyNode::create(frame Translate, FloatPoint3D(), context.currentTransform); | |
47 localContext.transformForFixedPositioned = newTransformNodeForPreTranslation .get(); | |
48 localContext.paintOffsetForFixedPositioned = LayoutPoint(); | |
49 | |
50 // This is going away in favor of Settings::rootLayerScrolls. | |
51 DoubleSize scrollOffset = frameView.scrollOffsetDouble(); | |
52 TransformationMatrix frameScroll; | |
53 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); | |
54 newTransformNodeForScrollTranslation = TransformPaintPropertyNode::create(fr ameScroll, FloatPoint3D(), newTransformNodeForPreTranslation); | |
55 localContext.currentTransform = localContext.transformForOutOfFlowPositioned = newTransformNodeForScrollTranslation.get(); | |
56 localContext.paintOffset = localContext.paintOffsetForOutOfFlowPositioned = LayoutPoint(); | |
57 | |
58 frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); | |
59 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release( )); | |
60 | |
61 if (LayoutView* layoutView = frameView.layoutView()) | |
62 walk(*layoutView, localContext); | |
63 } | |
64 | |
65 static bool shouldCreatePreTranslationNode(LayoutBoxModelObject& object) | |
66 { | |
67 // TODO(trchen): Eliminate PaintLayer dependency. | |
68 PaintLayer* layer = object.layer(); | |
69 if (!layer) | |
70 return false; | |
71 | |
72 return layer->paintsWithTransform(GlobalPaintNormalPhase); | |
73 } | |
74 | |
75 static FloatPoint3D transformOrigin(const LayoutBox& box) | |
76 { | |
77 const ComputedStyle& style = box.styleRef(); | |
78 | |
79 FloatSize borderBoxSize(box.size()); | |
80 return FloatPoint3D(floatValueForLength(style.transformOriginX(), borderBoxS ize.width()), floatValueForLength(style.transformOriginY(), borderBoxSize.height ()), style.transformOriginZ()); | |
pdr.
2015/10/20 22:02:30
Can you break this line so it's a little easier to
trchen
2015/10/21 06:16:20
Done.
| |
81 } | |
82 | |
83 static FloatPoint perspectiveOrigin(const LayoutBox& box) | |
84 { | |
85 const ComputedStyle& style = box.styleRef(); | |
86 | |
jbroman
2015/10/20 23:50:13
super-nit: remove this newline?
trchen
2015/10/21 06:16:20
Done.
| |
87 FloatSize borderBoxSize(box.size()); | |
88 return FloatPoint(floatValueForLength(style.perspectiveOriginX(), borderBoxS ize.width()), floatValueForLength(style.perspectiveOriginY(), borderBoxSize.heig ht())); | |
89 } | |
90 | |
91 void PaintPropertyTreeBuilder::walk(LayoutBoxModelObject& object, const Context& context) | |
92 { | |
93 ASSERT(object.isBox() != object.isLayoutInline()); // Either or. | |
pdr.
2015/10/20 22:02:30
There are many checks for isBox() in this function
trchen
2015/10/21 06:16:20
Yea... Many CSS properties don't apply on inlines.
| |
94 | |
95 Context localContext(context); | |
96 RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation; | |
97 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform; | |
98 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective; | |
99 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation; | |
100 | |
101 // Step 1: Figure out the layout space of the current object. | |
102 const ComputedStyle& style = object.styleRef(); | |
103 // TODO(trchen): There is some insanity going on with tables. Double check r esults. | |
104 switch (style.position()) { | |
105 case StaticPosition: | |
106 break; | |
107 case RelativePosition: | |
108 localContext.paintOffset += object.offsetForInFlowPosition(); | |
109 break; | |
110 case AbsolutePosition: | |
111 localContext.currentTransform = context.transformForOutOfFlowPositioned; | |
112 localContext.paintOffset = context.paintOffsetForOutOfFlowPositioned; | |
113 break; | |
114 case StickyPosition: | |
115 localContext.paintOffset += object.offsetForInFlowPosition(); | |
116 break; | |
117 case FixedPosition: | |
118 localContext.currentTransform = context.transformForFixedPositioned; | |
119 localContext.paintOffset = context.paintOffsetForFixedPositioned; | |
120 break; | |
121 default: | |
122 ASSERT_NOT_REACHED(); | |
123 } | |
124 if (object.isBox()) | |
125 localContext.paintOffset += toLayoutBox(object).locationOffset(); | |
126 | |
127 // Step 2: Create a transform node to consolidate paint offset (if needed). | |
128 if (shouldCreatePreTranslationNode(object) && localContext.paintOffset != La youtPoint()) { | |
129 TransformationMatrix matrix; | |
130 matrix.translate(localContext.paintOffset.x(), localContext.paintOffset. y()); | |
131 newTransformNodeForPreTranslation = TransformPaintPropertyNode::create(m atrix, FloatPoint3D(), localContext.currentTransform); | |
132 localContext.currentTransform = newTransformNodeForPreTranslation.get(); | |
133 localContext.paintOffset = LayoutPoint(); | |
134 } | |
135 | |
136 // Step 3: Create a transform node for CSS transform (if presents). | |
pdr.
2015/10/20 22:02:30
Nit: "if presents" -> "if present" (here, and belo
trchen
2015/10/21 06:16:20
Done.
| |
137 bool hasTransform = object.isBox() && style.hasTransform(); | |
138 if (hasTransform) { | |
139 TransformationMatrix matrix; | |
140 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle:: ExcludeTransformOrigin, ComputedStyle::IncludeMotionPath, ComputedStyle::Include IndependentTransformProperties); | |
jbroman
2015/10/20 23:50:13
nit: Mind wrapping some of these long lines? I kno
trchen
2015/10/21 06:16:20
Done.
| |
141 newTransformNodeForTransform = TransformPaintPropertyNode::create(matrix , transformOrigin(toLayoutBox(object)), localContext.currentTransform); | |
142 localContext.currentTransform = newTransformNodeForTransform.get(); | |
143 ASSERT(localContext.paintOffset == LayoutPoint()); | |
144 } | |
145 // At this point, the current space is the space we paint the element itself . | |
146 | |
147 // Step 3: Create a transform node for CSS perspective (if presents). | |
jbroman
2015/10/20 23:50:13
nit: There are two step 3s. I would probably remov
trchen
2015/10/21 06:16:20
Done.
| |
148 if (object.isBox() && style.hasPerspective()) { | |
149 TransformationMatrix matrix; | |
150 matrix.applyPerspective(style.perspective()); | |
151 newTransformNodeForPerspective = TransformPaintPropertyNode::create(matr ix, perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(localContext.paintOffs et), localContext.currentTransform); | |
152 localContext.currentTransform = newTransformNodeForPerspective.get(); | |
153 } | |
154 | |
155 // Step 4: Create a transform node for overflow clip (if presents). | |
156 if (object.hasOverflowClip()) { | |
157 PaintLayer* layer = object.layer(); | |
158 ASSERT(layer); | |
159 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset(); | |
160 if (!scrollOffset.isZero() || layer->scrollsOverflow()) { | |
161 TransformationMatrix matrix; | |
162 matrix.translate(-scrollOffset.width(), -scrollOffset.height()); | |
163 newTransformNodeForScrollTranslation = TransformPaintPropertyNode::c reate(matrix, FloatPoint3D(), localContext.currentTransform); | |
164 localContext.currentTransform = newTransformNodeForScrollTranslation .get(); | |
165 } | |
166 } | |
167 // At this point, the current space is the space we paint in-flow children. | |
168 | |
169 // Step 5: Update the context for out-of-flow descendants (if position conta iner is established). | |
170 if (style.position() != StaticPosition || hasTransform) { | |
jbroman
2015/10/20 23:50:13
Does the logic for what creates a containing block
trchen
2015/10/21 06:16:20
Nope, any divergence is unintentional. shouldCreat
| |
171 localContext.transformForOutOfFlowPositioned = localContext.currentTrans form; | |
172 localContext.paintOffsetForOutOfFlowPositioned = localContext.paintOffse t; | |
173 } | |
174 if (hasTransform) { | |
175 localContext.transformForFixedPositioned = localContext.currentTransform ; | |
176 localContext.paintOffsetForFixedPositioned = localContext.paintOffset; | |
177 } | |
178 | |
179 // Step 6: Memorize the nodes we created for future reference during paint. | |
180 if (newTransformNodeForPreTranslation || newTransformNodeForTransform || new TransformNodeForPerspective || newTransformNodeForScrollTranslation) { | |
181 ObjectPaintProperties& properties = object.ensureObjectPaintProperties() ; | |
182 properties.setPreTranslation(newTransformNodeForPreTranslation.release() ); | |
183 properties.setTransform(newTransformNodeForTransform.release()); | |
184 properties.setPerspective(newTransformNodeForPerspective.release()); | |
185 properties.setScrollTranslation(newTransformNodeForScrollTranslation.rel ease()); | |
186 } else { | |
187 object.clearObjectPaintProperties(); | |
188 } | |
189 | |
190 // Step 7: Recur. | |
191 if (object.isSVGRoot()) { | |
pdr.
2015/10/20 22:02:30
Nit:
// TODO(trchen): Implement the SVG transform
trchen
2015/10/21 06:16:20
Done.
| |
192 // TODO(trchen): Implement SVG walk. | |
193 return; | |
194 } | |
195 | |
196 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) { | |
pdr.
2015/10/20 22:02:30
Lets move the recur comment here.
trchen
2015/10/21 06:16:20
Nah, for SVG walk it is going to recur too. Just t
| |
197 if (child->isText()) | |
198 continue; | |
199 walk(toLayoutBoxModelObject(*child), localContext); | |
200 } | |
201 } | |
202 | |
203 } // namespace blink | |
OLD | NEW |