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 "core/paint/PaintPropertyTreeBuilder.h" | 5 #include "core/paint/PaintPropertyTreeBuilder.h" |
6 | 6 |
7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
8 #include "core/frame/LocalFrame.h" | 8 #include "core/frame/LocalFrame.h" |
9 #include "core/frame/Settings.h" | 9 #include "core/frame/Settings.h" |
10 #include "core/layout/LayoutInline.h" | 10 #include "core/layout/LayoutInline.h" |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 existingScrollTranslation->update(frameView.preTranslation(), frameScrol
l, FloatPoint3D()); | 61 existingScrollTranslation->update(frameView.preTranslation(), frameScrol
l, FloatPoint3D()); |
62 else | 62 else |
63 frameView.setScrollTranslation(TransformPaintPropertyNode::create(frameV
iew.preTranslation(), frameScroll, FloatPoint3D())); | 63 frameView.setScrollTranslation(TransformPaintPropertyNode::create(frameV
iew.preTranslation(), frameScroll, FloatPoint3D())); |
64 | 64 |
65 // Initialize the context for current, absolute and fixed position cases. | 65 // Initialize the context for current, absolute and fixed position cases. |
66 // They are the same, except that scroll translation does not apply to | 66 // They are the same, except that scroll translation does not apply to |
67 // fixed position descendants. | 67 // fixed position descendants. |
68 context.current.transform = frameView.scrollTranslation(); | 68 context.current.transform = frameView.scrollTranslation(); |
69 context.current.paintOffset = LayoutPoint(); | 69 context.current.paintOffset = LayoutPoint(); |
70 context.current.clip = frameView.contentClip(); | 70 context.current.clip = frameView.contentClip(); |
| 71 context.current.renderingContextID = 0; |
| 72 context.current.shouldFlattenInheritedTransform = true; |
71 context.absolutePosition = context.current; | 73 context.absolutePosition = context.current; |
72 context.containerForAbsolutePosition = nullptr; | 74 context.containerForAbsolutePosition = nullptr; |
73 context.fixedPosition = context.current; | 75 context.fixedPosition = context.current; |
74 context.fixedPosition.transform = frameView.preTranslation(); | 76 context.fixedPosition.transform = frameView.preTranslation(); |
75 } | 77 } |
76 | 78 |
77 template <typename PropertyNode, void (ObjectPaintProperties::*Setter)(PassRefPt
r<PropertyNode>)> | 79 template <typename PropertyNode, void (ObjectPaintProperties::*Setter)(PassRefPt
r<PropertyNode>)> |
78 void PaintPropertyTreeBuilder::clearPaintProperty(const LayoutObject& object) | 80 void PaintPropertyTreeBuilder::clearPaintProperty(const LayoutObject& object) |
79 { | 81 { |
80 if (ObjectPaintProperties* existingProperties = object.objectPaintProperties
()) | 82 if (ObjectPaintProperties* existingProperties = object.objectPaintProperties
()) |
(...skipping 27 matching lines...) Expand all Loading... |
108 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { | 110 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { |
109 // We should use the same subpixel paint offset values for snapping
regardless of whether a | 111 // We should use the same subpixel paint offset values for snapping
regardless of whether a |
110 // transform is present. If there is a transform we round the paint
offset but keep around | 112 // transform is present. If there is a transform we round the paint
offset but keep around |
111 // the residual fractional component for the transformed content to
paint with. | 113 // the residual fractional component for the transformed content to
paint with. |
112 // In spv1 this was called "subpixel accumulation". For more informa
tion, see | 114 // In spv1 this was called "subpixel accumulation". For more informa
tion, see |
113 // PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFr
agmentByApplyingTransform. | 115 // PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFr
agmentByApplyingTransform. |
114 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintO
ffset); | 116 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintO
ffset); |
115 LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.pain
tOffset - roundedPaintOffset); | 117 LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.pain
tOffset - roundedPaintOffset); |
116 | 118 |
117 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::paintOffsetTranslation, &ObjectPaintProperties::setPaintOffsetTransl
ation>( | 119 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::paintOffsetTranslation, &ObjectPaintProperties::setPaintOffsetTransl
ation>( |
118 object, context, context.current.transform, TransformationMatrix
().translate(roundedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D()); | 120 object, context, context.current.transform, TransformationMatrix
().translate(roundedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D(), |
| 121 context.current.shouldFlattenInheritedTransform, context.current
.renderingContextID); |
119 context.current.paintOffset = fractionalPaintOffset; | 122 context.current.paintOffset = fractionalPaintOffset; |
120 return; | 123 return; |
121 } | 124 } |
122 } | 125 } |
123 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setPa
intOffsetTranslation>(object); | 126 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setPa
intOffsetTranslation>(object); |
124 } | 127 } |
125 | 128 |
126 static FloatPoint3D transformOrigin(const LayoutBox& box) | 129 static FloatPoint3D transformOrigin(const LayoutBox& box) |
127 { | 130 { |
128 const ComputedStyle& style = box.styleRef(); | 131 const ComputedStyle& style = box.styleRef(); |
(...skipping 12 matching lines...) Expand all Loading... |
141 | 144 |
142 // FIXME(pdr): Check for the presence of a transform instead of the valu
e. Checking for an | 145 // FIXME(pdr): Check for the presence of a transform instead of the valu
e. Checking for an |
143 // identity matrix will cause the property tree structure to change duri
ng animations if | 146 // identity matrix will cause the property tree structure to change duri
ng animations if |
144 // the animation passes through the identity matrix. | 147 // the animation passes through the identity matrix. |
145 // FIXME(pdr): Refactor this so all non-root SVG objects use the same tr
ansform function. | 148 // FIXME(pdr): Refactor this so all non-root SVG objects use the same tr
ansform function. |
146 const AffineTransform& transform = object.isSVGForeignObject() ? object.
localSVGTransform() : object.localToSVGParentTransform(); | 149 const AffineTransform& transform = object.isSVGForeignObject() ? object.
localSVGTransform() : object.localToSVGParentTransform(); |
147 if (!transform.isIdentity()) { | 150 if (!transform.isIdentity()) { |
148 // The origin is included in the local transform, so leave origin em
pty. | 151 // The origin is included in the local transform, so leave origin em
pty. |
149 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::transform, &ObjectPaintProperties::setTransform>( | 152 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::transform, &ObjectPaintProperties::setTransform>( |
150 object, context, context.current.transform, TransformationMatrix
(transform), FloatPoint3D()); | 153 object, context, context.current.transform, TransformationMatrix
(transform), FloatPoint3D()); |
| 154 context.current.renderingContextID = 0; |
| 155 context.current.shouldFlattenInheritedTransform = false; |
151 return; | 156 return; |
152 } | 157 } |
153 } else { | 158 } else { |
154 const ComputedStyle& style = object.styleRef(); | 159 const ComputedStyle& style = object.styleRef(); |
155 if (object.isBox() && style.hasTransform()) { | 160 if (object.isBox() && (style.hasTransform() || style.preserves3D())) { |
156 TransformationMatrix matrix; | 161 TransformationMatrix matrix; |
157 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedSty
le::ExcludeTransformOrigin, | 162 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedSty
le::ExcludeTransformOrigin, |
158 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndepend
entTransformProperties); | 163 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndepend
entTransformProperties); |
159 FloatPoint3D origin = transformOrigin(toLayoutBox(object)); | 164 FloatPoint3D origin = transformOrigin(toLayoutBox(object)); |
| 165 |
| 166 unsigned renderingContextID = context.current.renderingContextID; |
| 167 unsigned renderingContextIDForChildren = 0; |
| 168 bool flattensInheritedTransform = context.current.shouldFlattenInher
itedTransform; |
| 169 bool childrenFlattenInheritedTransform = true; |
| 170 |
| 171 // TODO(trchen): transform-style should only be respected if a Paint
Layer is |
| 172 // created. |
| 173 if (style.preserves3D()) { |
| 174 // If a node with transform-style: preserve-3d does not exist in
an |
| 175 // existing rendering context, it establishes a new one. |
| 176 if (!renderingContextID) |
| 177 renderingContextID = PtrHash<const LayoutObject>::hash(&obje
ct); |
| 178 renderingContextIDForChildren = renderingContextID; |
| 179 childrenFlattenInheritedTransform = false; |
| 180 } |
| 181 |
160 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::transform, &ObjectPaintProperties::setTransform>( | 182 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::transform, &ObjectPaintProperties::setTransform>( |
161 object, context, context.current.transform, matrix, origin); | 183 object, context, context.current.transform, matrix, origin, flat
tensInheritedTransform, renderingContextID); |
| 184 context.current.renderingContextID = renderingContextIDForChildren; |
| 185 context.current.shouldFlattenInheritedTransform = childrenFlattenInh
eritedTransform; |
162 return; | 186 return; |
163 } | 187 } |
164 } | 188 } |
165 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setTr
ansform>(object); | 189 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setTr
ansform>(object); |
166 } | 190 } |
167 | 191 |
168 void PaintPropertyTreeBuilder::updateEffect(const LayoutObject& object, PaintPro
pertyTreeBuilderContext& context) | 192 void PaintPropertyTreeBuilder::updateEffect(const LayoutObject& object, PaintPro
pertyTreeBuilderContext& context) |
169 { | 193 { |
170 if (!object.styleRef().hasOpacity()) { | 194 if (!object.styleRef().hasOpacity()) { |
171 clearPaintProperty<EffectPaintPropertyNode, &ObjectPaintProperties::setE
ffect>(object); | 195 clearPaintProperty<EffectPaintPropertyNode, &ObjectPaintProperties::setE
ffect>(object); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 } | 292 } |
269 | 293 |
270 void PaintPropertyTreeBuilder::updatePerspective(const LayoutObject& object, Pai
ntPropertyTreeBuilderContext& context) | 294 void PaintPropertyTreeBuilder::updatePerspective(const LayoutObject& object, Pai
ntPropertyTreeBuilderContext& context) |
271 { | 295 { |
272 const ComputedStyle& style = object.styleRef(); | 296 const ComputedStyle& style = object.styleRef(); |
273 if (!object.isBox() || !style.hasPerspective()) { | 297 if (!object.isBox() || !style.hasPerspective()) { |
274 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::s
etPerspective>(object); | 298 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::s
etPerspective>(object); |
275 return; | 299 return; |
276 } | 300 } |
277 | 301 |
| 302 // The perspective node must not flatten (else nothing will get |
| 303 // perspective), but it should still extend the rendering context as most |
| 304 // transform nodes do. |
| 305 TransformationMatrix matrix = TransformationMatrix().applyPerspective(style.
perspective()); |
278 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(
context.current.paintOffset); | 306 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(
context.current.paintOffset); |
279 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperti
es::perspective, &ObjectPaintProperties::setPerspective>( | 307 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperti
es::perspective, &ObjectPaintProperties::setPerspective>( |
280 object, context, context.current.transform, TransformationMatrix().apply
Perspective(style.perspective()), origin); | 308 object, context, context.current.transform, matrix, origin, context.curr
ent.shouldFlattenInheritedTransform, context.current.renderingContextID); |
| 309 context.current.shouldFlattenInheritedTransform = false; |
281 } | 310 } |
282 | 311 |
283 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutOb
ject& object, PaintPropertyTreeBuilderContext& context) | 312 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutOb
ject& object, PaintPropertyTreeBuilderContext& context) |
284 { | 313 { |
285 if (!object.isSVGRoot()) | 314 if (!object.isSVGRoot()) |
286 return; | 315 return; |
287 | 316 |
288 AffineTransform transformToBorderBox = SVGRootPainter(toLayoutSVGRoot(object
)).transformToPixelSnappedBorderBox(context.current.paintOffset); | 317 AffineTransform transformToBorderBox = SVGRootPainter(toLayoutSVGRoot(object
)).transformToPixelSnappedBorderBox(context.current.paintOffset); |
289 | 318 |
290 // The paint offset is included in |transformToBorderBox| so SVG does not ne
ed to handle paint | 319 // The paint offset is included in |transformToBorderBox| so SVG does not ne
ed to handle paint |
291 // offset internally. | 320 // offset internally. |
292 context.current.paintOffset = LayoutPoint(); | 321 context.current.paintOffset = LayoutPoint(); |
293 | 322 |
294 if (transformToBorderBox.isIdentity()) { | 323 if (transformToBorderBox.isIdentity()) { |
295 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::s
etSvgLocalToBorderBoxTransform>(object); | 324 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::s
etSvgLocalToBorderBoxTransform>(object); |
296 return; | 325 return; |
297 } | 326 } |
298 | 327 |
299 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperti
es::svgLocalToBorderBoxTransform, &ObjectPaintProperties::setSvgLocalToBorderBox
Transform>( | 328 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperti
es::svgLocalToBorderBoxTransform, &ObjectPaintProperties::setSvgLocalToBorderBox
Transform>( |
300 object, context, context.current.transform, transformToBorderBox, FloatP
oint3D()); | 329 object, context, context.current.transform, transformToBorderBox, FloatP
oint3D()); |
| 330 context.current.shouldFlattenInheritedTransform = false; |
| 331 context.current.renderingContextID = 0; |
301 } | 332 } |
302 | 333 |
303 void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& objec
t, PaintPropertyTreeBuilderContext& context) | 334 void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& objec
t, PaintPropertyTreeBuilderContext& context) |
304 { | 335 { |
305 if (object.isBoxModelObject() && object.hasOverflowClip()) { | 336 if (object.isBoxModelObject() && object.hasOverflowClip()) { |
306 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 337 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
307 DCHECK(layer); | 338 DCHECK(layer); |
308 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); | 339 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); |
309 | 340 |
310 if (!scrollOffset.isZero() || layer->scrollsOverflow()) { | 341 if (!scrollOffset.isZero() || layer->scrollsOverflow()) { |
311 TransformationMatrix matrix = TransformationMatrix().translate(-scro
llOffset.width(), -scrollOffset.height()); | 342 TransformationMatrix matrix = TransformationMatrix().translate(-scro
llOffset.width(), -scrollOffset.height()); |
312 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::scrollTranslation, &ObjectPaintProperties::setScrollTranslation>( | 343 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::scrollTranslation, &ObjectPaintProperties::setScrollTranslation>( |
313 object, context, context.current.transform, matrix, FloatPoint3D
()); | 344 object, context, context.current.transform, matrix, FloatPoint3D
(), context.current.shouldFlattenInheritedTransform, context.current.renderingCo
ntextID); |
| 345 context.current.shouldFlattenInheritedTransform = false; |
314 return; | 346 return; |
315 } | 347 } |
316 } | 348 } |
317 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setSc
rollTranslation>(object); | 349 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setSc
rollTranslation>(object); |
318 } | 350 } |
319 | 351 |
320 void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object
, PaintPropertyTreeBuilderContext& context) | 352 void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object
, PaintPropertyTreeBuilderContext& context) |
321 { | 353 { |
322 if (object.canContainAbsolutePositionObjects()) { | 354 if (object.canContainAbsolutePositionObjects()) { |
323 context.absolutePosition = context.current; | 355 context.absolutePosition = context.current; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 | 437 |
406 deriveBorderBoxFromContainerContext(object, context); | 438 deriveBorderBoxFromContainerContext(object, context); |
407 | 439 |
408 updatePaintOffsetTranslation(object, context); | 440 updatePaintOffsetTranslation(object, context); |
409 updateTransform(object, context); | 441 updateTransform(object, context); |
410 updateEffect(object, context); | 442 updateEffect(object, context); |
411 updateCssClip(object, context); | 443 updateCssClip(object, context); |
412 updateLocalBorderBoxContext(object, context); | 444 updateLocalBorderBoxContext(object, context); |
413 updateScrollbarPaintOffset(object, context); | 445 updateScrollbarPaintOffset(object, context); |
414 updateOverflowClip(object, context); | 446 updateOverflowClip(object, context); |
415 // TODO(trchen): Insert flattening transform here, as specified by | |
416 // http://www.w3.org/TR/css3-transforms/#transform-style-property | |
417 updatePerspective(object, context); | 447 updatePerspective(object, context); |
418 updateSvgLocalToBorderBoxTransform(object, context); | 448 updateSvgLocalToBorderBoxTransform(object, context); |
419 updateScrollTranslation(object, context); | 449 updateScrollTranslation(object, context); |
420 updateOutOfFlowContext(object, context); | 450 updateOutOfFlowContext(object, context); |
421 } | 451 } |
422 | 452 |
423 } // namespace blink | 453 } // namespace blink |
OLD | NEW |