OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/paint/PaintPropertyTreeBuilder.h" | 6 #include "core/paint/PaintPropertyTreeBuilder.h" |
7 | 7 |
8 #include "core/frame/FrameView.h" | 8 #include "core/frame/FrameView.h" |
9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
10 #include "core/paint/ObjectPaintProperties.h" | 10 #include "core/paint/ObjectPaintProperties.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
72 localContext.currentTransform = localContext.transformForOutOfFlowPositioned = newTransformNodeForScrollTranslation.get(); | 72 localContext.currentTransform = localContext.transformForOutOfFlowPositioned = newTransformNodeForScrollTranslation.get(); |
73 localContext.paintOffset = localContext.paintOffsetForOutOfFlowPositioned = LayoutPoint(); | 73 localContext.paintOffset = localContext.paintOffsetForOutOfFlowPositioned = LayoutPoint(); |
74 | 74 |
75 frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); | 75 frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); |
76 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release( )); | 76 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release( )); |
77 | 77 |
78 if (LayoutView* layoutView = frameView.layoutView()) | 78 if (LayoutView* layoutView = frameView.layoutView()) |
79 walk(*layoutView, localContext); | 79 walk(*layoutView, localContext); |
80 } | 80 } |
81 | 81 |
82 static void deriveBorderBoxFromContainerContext(const LayoutBoxModelObject& obje ct, PaintPropertyTreeBuilderContext& context) | 82 static void deriveBorderBoxFromContainerContext(const LayoutObject& object, Pain tPropertyTreeBuilderContext& context) |
83 { | 83 { |
84 if (!object.isBoxModelObject()) | |
85 return; | |
86 | |
87 const LayoutBoxModelObject& boxModelObject = toLayoutBoxModelObject(object); | |
88 | |
84 // TODO(trchen): There is some insanity going on with tables. Double check r esults. | 89 // TODO(trchen): There is some insanity going on with tables. Double check r esults. |
85 switch (object.styleRef().position()) { | 90 switch (object.styleRef().position()) { |
86 case StaticPosition: | 91 case StaticPosition: |
87 break; | 92 break; |
88 case RelativePosition: | 93 case RelativePosition: |
89 context.paintOffset += object.offsetForInFlowPosition(); | 94 context.paintOffset += boxModelObject.offsetForInFlowPosition(); |
90 break; | 95 break; |
91 case AbsolutePosition: | 96 case AbsolutePosition: |
92 context.currentTransform = context.transformForOutOfFlowPositioned; | 97 context.currentTransform = context.transformForOutOfFlowPositioned; |
93 context.paintOffset = context.paintOffsetForOutOfFlowPositioned; | 98 context.paintOffset = context.paintOffsetForOutOfFlowPositioned; |
94 break; | 99 break; |
95 case StickyPosition: | 100 case StickyPosition: |
96 context.paintOffset += object.offsetForInFlowPosition(); | 101 context.paintOffset += boxModelObject.offsetForInFlowPosition(); |
97 break; | 102 break; |
98 case FixedPosition: | 103 case FixedPosition: |
99 context.currentTransform = context.transformForFixedPositioned; | 104 context.currentTransform = context.transformForFixedPositioned; |
100 context.paintOffset = context.paintOffsetForFixedPositioned; | 105 context.paintOffset = context.paintOffsetForFixedPositioned; |
101 break; | 106 break; |
102 default: | 107 default: |
103 ASSERT_NOT_REACHED(); | 108 ASSERT_NOT_REACHED(); |
104 } | 109 } |
105 if (object.isBox()) | 110 if (boxModelObject.isBox()) |
106 context.paintOffset += toLayoutBox(object).locationOffset(); | 111 context.paintOffset += toLayoutBox(boxModelObject).locationOffset(); |
107 } | 112 } |
108 | 113 |
109 static PassRefPtr<TransformPaintPropertyNode> createPaintOffsetTranslationIfNeed ed(const LayoutBoxModelObject& object, PaintPropertyTreeBuilderContext& context) | 114 static PassRefPtr<TransformPaintPropertyNode> createPaintOffsetTranslationIfNeed ed(const LayoutObject& object, PaintPropertyTreeBuilderContext& context) |
110 { | 115 { |
111 // TODO(trchen): Eliminate PaintLayer dependency. | 116 bool shouldCreatePaintOffsetTranslationNode = false; |
112 bool shouldCreatePaintOffsetTranslationNode = object.layer() && object.layer ()->paintsWithTransform(GlobalPaintNormalPhase); | 117 if (object.isSVGRoot()) { |
118 // SVG doesn't use paint offset internally so emit a paint offset at the html->svg boundary. | |
119 shouldCreatePaintOffsetTranslationNode = true; | |
120 } else if (object.isBoxModelObject()) { | |
121 // TODO(trchen): Eliminate PaintLayer dependency. | |
122 shouldCreatePaintOffsetTranslationNode = toLayoutBoxModelObject(object). layer() && toLayoutBoxModelObject(object).layer()->paintsWithTransform(GlobalPai ntNormalPhase); | |
jbroman
2015/11/20 19:09:20
nit: extract toLayoutBoxModelObject(object).layer(
pdr.
2015/11/20 19:33:41
I actually refactored this slightly differently so
jbroman
2015/11/20 19:53:40
...which is exactly what I asked you to do?
| |
123 } | |
113 | 124 |
114 if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslat ionNode) | 125 if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslat ionNode) |
115 return nullptr; | 126 return nullptr; |
116 | 127 |
117 TransformationMatrix matrix; | 128 TransformationMatrix matrix; |
118 matrix.translate(context.paintOffset.x(), context.paintOffset.y()); | 129 matrix.translate(context.paintOffset.x(), context.paintOffset.y()); |
119 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode::create( | 130 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = TransformPaintPropertyNode::create( |
120 TransformationMatrix().translate(context.paintOffset.x(), context.paintO ffset.y()), | 131 TransformationMatrix().translate(context.paintOffset.x(), context.paintO ffset.y()), |
121 FloatPoint3D(), context.currentTransform); | 132 FloatPoint3D(), context.currentTransform); |
122 context.currentTransform = newTransformNodeForPaintOffsetTranslation.get(); | 133 context.currentTransform = newTransformNodeForPaintOffsetTranslation.get(); |
123 context.paintOffset = LayoutPoint(); | 134 context.paintOffset = LayoutPoint(); |
124 return newTransformNodeForPaintOffsetTranslation.release(); | 135 return newTransformNodeForPaintOffsetTranslation.release(); |
125 } | 136 } |
126 | 137 |
127 static FloatPoint3D transformOrigin(const LayoutBox& box) | 138 static FloatPoint3D transformOrigin(const LayoutBox& box) |
128 { | 139 { |
129 const ComputedStyle& style = box.styleRef(); | 140 const ComputedStyle& style = box.styleRef(); |
130 FloatSize borderBoxSize(box.size()); | 141 FloatSize borderBoxSize(box.size()); |
131 return FloatPoint3D( | 142 return FloatPoint3D( |
132 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), | 143 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), |
133 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), | 144 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), |
134 style.transformOriginZ()); | 145 style.transformOriginZ()); |
135 } | 146 } |
136 | 147 |
137 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo utBoxModelObject& object, PaintPropertyTreeBuilderContext& context) | 148 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo utObject& object, PaintPropertyTreeBuilderContext& context) |
138 { | 149 { |
150 if (object.isSVG() && !object.isSVGRoot()) { | |
151 const AffineTransform& transform = object.localToParentTransform(); | |
152 if (transform.isIdentity()) | |
153 return nullptr; | |
154 | |
155 // SVG's transform origin is baked into the localToParentTransform. | |
156 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = Transf ormPaintPropertyNode::create( | |
157 transform, FloatPoint3D(0, 0, 0), context.currentTransform); | |
158 context.currentTransform = newTransformNodeForTransform.get(); | |
159 return newTransformNodeForTransform.release(); | |
160 } | |
161 | |
139 const ComputedStyle& style = object.styleRef(); | 162 const ComputedStyle& style = object.styleRef(); |
140 if (!object.isBox() || !style.hasTransform()) | 163 if (!object.isBox() || !style.hasTransform()) |
141 return nullptr; | 164 return nullptr; |
142 | 165 |
143 ASSERT(context.paintOffset == LayoutPoint()); | 166 ASSERT(context.paintOffset == LayoutPoint()); |
144 | 167 |
145 TransformationMatrix matrix; | 168 TransformationMatrix matrix; |
146 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin, | 169 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl udeTransformOrigin, |
147 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties); | 170 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans formProperties); |
148 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP aintPropertyNode::create( | 171 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP aintPropertyNode::create( |
149 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); | 172 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); |
150 context.currentTransform = newTransformNodeForTransform.get(); | 173 context.currentTransform = newTransformNodeForTransform.get(); |
151 return newTransformNodeForTransform.release(); | 174 return newTransformNodeForTransform.release(); |
152 } | 175 } |
153 | 176 |
154 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutBoxM odelObject& object, PaintPropertyTreeBuilderContext& context) | 177 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje ct& object, PaintPropertyTreeBuilderContext& context) |
155 { | 178 { |
156 const ComputedStyle& style = object.styleRef(); | 179 const ComputedStyle& style = object.styleRef(); |
157 if (!object.isBox() || !style.hasOpacity()) | 180 if (!style.hasOpacity()) |
158 return nullptr; | 181 return nullptr; |
159 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect); | 182 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre ate(style.opacity(), context.currentEffect); |
160 context.currentEffect = newEffectNode.get(); | 183 context.currentEffect = newEffectNode.get(); |
161 return newEffectNode.release(); | 184 return newEffectNode.release(); |
162 } | 185 } |
163 | 186 |
164 static FloatPoint perspectiveOrigin(const LayoutBox& box) | 187 static FloatPoint perspectiveOrigin(const LayoutBox& box) |
165 { | 188 { |
166 const ComputedStyle& style = box.styleRef(); | 189 const ComputedStyle& style = box.styleRef(); |
167 FloatSize borderBoxSize(box.size()); | 190 FloatSize borderBoxSize(box.size()); |
168 return FloatPoint( | 191 return FloatPoint( |
169 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), | 192 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), |
170 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())) ; | 193 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height())) ; |
171 } | 194 } |
172 | 195 |
173 static PassRefPtr<TransformPaintPropertyNode> createPerspectiveIfNeeded(const La youtBoxModelObject& object, PaintPropertyTreeBuilderContext& context) | 196 static PassRefPtr<TransformPaintPropertyNode> createPerspectiveIfNeeded(const La youtObject& object, PaintPropertyTreeBuilderContext& context) |
174 { | 197 { |
175 const ComputedStyle& style = object.styleRef(); | 198 const ComputedStyle& style = object.styleRef(); |
176 if (!object.isBox() || !style.hasPerspective()) | 199 if (!object.isBox() || !style.hasPerspective()) |
177 return nullptr; | 200 return nullptr; |
178 | 201 |
179 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = Transfor mPaintPropertyNode::create( | 202 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = Transfor mPaintPropertyNode::create( |
180 TransformationMatrix().applyPerspective(style.perspective()), | 203 TransformationMatrix().applyPerspective(style.perspective()), |
181 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse t), context.currentTransform); | 204 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse t), context.currentTransform); |
182 context.currentTransform = newTransformNodeForPerspective.get(); | 205 context.currentTransform = newTransformNodeForPerspective.get(); |
183 return newTransformNodeForPerspective.release(); | 206 return newTransformNodeForPerspective.release(); |
184 } | 207 } |
185 | 208 |
186 static PassRefPtr<TransformPaintPropertyNode> createScrollTranslationIfNeeded(co nst LayoutBoxModelObject& object, PaintPropertyTreeBuilderContext& context) | 209 static PassRefPtr<TransformPaintPropertyNode> createScrollTranslationIfNeeded(co nst LayoutObject& object, PaintPropertyTreeBuilderContext& context) |
187 { | 210 { |
188 if (!object.hasOverflowClip()) | 211 if (!object.isBoxModelObject() || !object.hasOverflowClip()) |
189 return nullptr; | 212 return nullptr; |
190 | 213 |
191 PaintLayer* layer = object.layer(); | 214 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
192 ASSERT(layer); | 215 ASSERT(layer); |
193 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset(); | 216 DoubleSize scrollOffset = layer->scrollableArea()->scrollOffset(); |
194 if (scrollOffset.isZero() && !layer->scrollsOverflow()) | 217 if (scrollOffset.isZero() && !layer->scrollsOverflow()) |
195 return nullptr; | 218 return nullptr; |
196 | 219 |
197 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create( | 220 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr ansformPaintPropertyNode::create( |
198 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()), | 221 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he ight()), |
199 FloatPoint3D(), context.currentTransform); | 222 FloatPoint3D(), context.currentTransform); |
200 context.currentTransform = newTransformNodeForScrollTranslation.get(); | 223 context.currentTransform = newTransformNodeForScrollTranslation.get(); |
201 return newTransformNodeForScrollTranslation.release(); | 224 return newTransformNodeForScrollTranslation.release(); |
202 } | 225 } |
203 | 226 |
204 static void updateOutOfFlowContext(const LayoutBoxModelObject& object, PaintProp ertyTreeBuilderContext& context) | 227 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree BuilderContext& context) |
205 { | 228 { |
206 const ComputedStyle& style = object.styleRef(); | 229 const ComputedStyle& style = object.styleRef(); |
207 bool hasTransform = object.isBox() && style.hasTransform(); | 230 bool hasTransform = object.isBox() && style.hasTransform(); |
208 if (style.position() != StaticPosition || hasTransform) { | 231 if (style.position() != StaticPosition || hasTransform) { |
209 context.transformForOutOfFlowPositioned = context.currentTransform; | 232 context.transformForOutOfFlowPositioned = context.currentTransform; |
210 context.paintOffsetForOutOfFlowPositioned = context.paintOffset; | 233 context.paintOffsetForOutOfFlowPositioned = context.paintOffset; |
211 } | 234 } |
212 if (hasTransform) { | 235 if (hasTransform) { |
213 context.transformForFixedPositioned = context.currentTransform; | 236 context.transformForFixedPositioned = context.currentTransform; |
214 context.paintOffsetForFixedPositioned = context.paintOffset; | 237 context.paintOffsetForFixedPositioned = context.paintOffset; |
215 } | 238 } |
216 } | 239 } |
217 | 240 |
218 void PaintPropertyTreeBuilder::walk(LayoutBoxModelObject& object, const PaintPro pertyTreeBuilderContext& context) | 241 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre eBuilderContext& context) |
219 { | 242 { |
220 ASSERT(object.isBox() != object.isLayoutInline()); // Either or. | |
221 | |
222 PaintPropertyTreeBuilderContext localContext(context); | 243 PaintPropertyTreeBuilderContext localContext(context); |
223 | 244 |
224 deriveBorderBoxFromContainerContext(object, localContext); | 245 deriveBorderBoxFromContainerContext(object, localContext); |
225 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext); | 246 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation = createPaintOffsetTranslationIfNeeded(object, localContext); |
226 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext); | 247 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran sformIfNeeded(object, localContext); |
227 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext); | 248 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object, localContext); |
228 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext); | 249 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe rspectiveIfNeeded(object, localContext); |
229 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext); | 250 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr eateScrollTranslationIfNeeded(object, localContext); |
230 updateOutOfFlowContext(object, localContext); | 251 updateOutOfFlowContext(object, localContext); |
231 | 252 |
232 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newTransformNodeForPerspective || newTransformNodeForScrol lTranslation) { | 253 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor m || newEffectNode || newTransformNodeForPerspective || newTransformNodeForScrol lTranslation) { |
233 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create( | 254 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper ties::create( |
234 newTransformNodeForPaintOffsetTranslation.release(), | 255 newTransformNodeForPaintOffsetTranslation.release(), |
235 newTransformNodeForTransform.release(), | 256 newTransformNodeForTransform.release(), |
236 newEffectNode.release(), | 257 newEffectNode.release(), |
237 newTransformNodeForPerspective.release(), | 258 newTransformNodeForPerspective.release(), |
238 newTransformNodeForScrollTranslation.release()); | 259 newTransformNodeForScrollTranslation.release()); |
239 object.setObjectPaintProperties(updatedPaintProperties.release()); | 260 object.setObjectPaintProperties(updatedPaintProperties.release()); |
240 } else { | 261 } else { |
241 object.clearObjectPaintProperties(); | 262 object.clearObjectPaintProperties(); |
242 } | 263 } |
243 | 264 |
244 // TODO(trchen): Walk subframes for LayoutFrame. | 265 // TODO(trchen): Walk subframes for LayoutFrame. |
245 | 266 |
246 // TODO(trchen): Implement SVG walk. | |
247 if (object.isSVGRoot()) { | |
248 return; | |
249 } | |
250 | |
251 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) { | 267 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne xtSibling()) { |
252 if (child->isText()) | 268 if (child->isBoxModelObject() || child->isSVG()) |
253 continue; | 269 walk(*child, localContext); |
254 walk(toLayoutBoxModelObject(*child), localContext); | |
255 } | 270 } |
256 } | 271 } |
257 | 272 |
258 } // namespace blink | 273 } // namespace blink |
OLD | NEW |