| 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" |
| 11 #include "core/layout/LayoutPart.h" | 11 #include "core/layout/LayoutPart.h" |
| 12 #include "core/layout/svg/LayoutSVGRoot.h" | 12 #include "core/layout/svg/LayoutSVGRoot.h" |
| 13 #include "core/paint/ObjectPaintProperties.h" | 13 #include "core/paint/ObjectPaintProperties.h" |
| 14 #include "core/paint/PaintLayer.h" | 14 #include "core/paint/PaintLayer.h" |
| 15 #include "core/paint/SVGRootPainter.h" | 15 #include "core/paint/SVGRootPainter.h" |
| 16 #include "platform/transforms/TransformationMatrix.h" | 16 #include "platform/transforms/TransformationMatrix.h" |
| 17 #include "wtf/PtrUtil.h" | 17 #include "wtf/PtrUtil.h" |
| 18 #include <memory> | 18 #include <memory> |
| 19 | 19 |
| 20 namespace blink { | 20 namespace blink { |
| 21 | 21 |
| 22 void PaintPropertyTreeBuilder::buildTreeRootNodes(FrameView& rootFrame, PaintPro
pertyTreeBuilderContext& context) | 22 void PaintPropertyTreeBuilder::buildTreeRootNodes(FrameView& rootFrame, PaintPro
pertyTreeBuilderContext& context) |
| 23 { | 23 { |
| 24 if (!rootFrame.rootTransform() || rootFrame.rootTransform()->parent()) { | 24 if (!rootFrame.rootTransform() || rootFrame.rootTransform()->parent()) { |
| 25 rootFrame.setRootTransform(TransformPaintPropertyNode::create(Transforma
tionMatrix(), FloatPoint3D(), nullptr)); | 25 rootFrame.setRootTransform(TransformPaintPropertyNode::create(Transforma
tionMatrix(), FloatPoint3D(), nullptr)); |
| 26 rootFrame.setRootClip(ClipPaintPropertyNode::create(rootFrame.rootTransf
orm(), FloatRoundedRect(LayoutRect::infiniteIntRect()), nullptr)); | 26 rootFrame.setRootClip(ClipPaintPropertyNode::create(rootFrame.rootTransf
orm(), FloatRoundedRect(LayoutRect::infiniteIntRect()), nullptr)); |
| 27 rootFrame.setRootEffect(EffectPaintPropertyNode::create(1.0, nullptr)); | 27 rootFrame.setRootEffect(EffectPaintPropertyNode::create(1.0f, nullptr)); |
| 28 } else { | 28 } else { |
| 29 DCHECK(rootFrame.rootClip() && !rootFrame.rootClip()->parent()); | 29 DCHECK(rootFrame.rootClip() && !rootFrame.rootClip()->parent()); |
| 30 DCHECK(rootFrame.rootEffect() && !rootFrame.rootEffect()->parent()); | 30 DCHECK(rootFrame.rootEffect() && !rootFrame.rootEffect()->parent()); |
| 31 } | 31 } |
| 32 | 32 |
| 33 context.current.transform = context.absolutePosition.transform = context.fix
edPosition.transform = rootFrame.rootTransform(); | 33 context.current.transform = context.absolutePosition.transform = context.fix
edPosition.transform = rootFrame.rootTransform(); |
| 34 context.current.clip = context.absolutePosition.clip = context.fixedPosition
.clip = rootFrame.rootClip(); | 34 context.current.clip = context.absolutePosition.clip = context.fixedPosition
.clip = rootFrame.rootClip(); |
| 35 context.currentEffect = rootFrame.rootEffect(); | 35 context.currentEffect = rootFrame.rootEffect(); |
| 36 } | 36 } |
| 37 | 37 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 65 context.absolutePosition = context.current; | 65 context.absolutePosition = context.current; |
| 66 context.containerForAbsolutePosition = nullptr; | 66 context.containerForAbsolutePosition = nullptr; |
| 67 context.fixedPosition = context.current; | 67 context.fixedPosition = context.current; |
| 68 context.fixedPosition.transform = frameView.preTranslation(); | 68 context.fixedPosition.transform = frameView.preTranslation(); |
| 69 } | 69 } |
| 70 | 70 |
| 71 template < | 71 template < |
| 72 typename PropertyNode, | 72 typename PropertyNode, |
| 73 PropertyNode* (ObjectPaintProperties::*Getter)() const, | 73 PropertyNode* (ObjectPaintProperties::*Getter)() const, |
| 74 void (ObjectPaintProperties::*Setter)(PassRefPtr<PropertyNode>), | 74 void (ObjectPaintProperties::*Setter)(PassRefPtr<PropertyNode>), |
| 75 bool (*ComputeProperty)(const LayoutObject&, PaintPropertyTreeBuilderContext
&, typename PropertyNode::Value&)> | 75 PaintPropertyTreeBuilder::PaintPropertyNodeType (*ComputeProperty)(const Lay
outObject&, PaintPropertyTreeBuilderContext&, typename PropertyNode::Value&)> |
| 76 PropertyNode* PaintPropertyTreeBuilder::updateObjectPaintProperty(const LayoutOb
ject& object, PaintPropertyTreeBuilderContext& context, PropertyNode*& contextPr
operty) | 76 PropertyNode* PaintPropertyTreeBuilder::updateObjectPaintProperty(const LayoutOb
ject& object, PaintPropertyTreeBuilderContext& context, PropertyNode*& contextPr
operty) |
| 77 { | 77 { |
| 78 ObjectPaintProperties* previousProperties = object.objectPaintProperties(); | 78 ObjectPaintProperties* previousProperties = object.objectPaintProperties(); |
| 79 typename PropertyNode::Value newPropertyValue; | 79 typename PropertyNode::Value newPropertyValue; |
| 80 if (!ComputeProperty(object, context, newPropertyValue)) { | 80 PaintPropertyNodeType nodeType = ComputeProperty(object, context, newPropert
yValue); |
| 81 if (nodeType == NoNode) { |
| 81 if (previousProperties) | 82 if (previousProperties) |
| 82 (previousProperties->*Setter)(nullptr); | 83 (previousProperties->*Setter)(nullptr); |
| 83 return nullptr; | 84 return nullptr; |
| 84 } | 85 } |
| 85 | 86 |
| 86 PropertyNode* previousPropertyNode = previousProperties ? (previousPropertie
s->*Getter)() : nullptr; | 87 PropertyNode* previousPropertyNode = previousProperties ? (previousPropertie
s->*Getter)() : nullptr; |
| 87 if (previousPropertyNode && previousPropertyNode->value() == newPropertyValu
e) { | 88 if (previousPropertyNode && previousPropertyNode->value() == newPropertyValu
e) { |
| 88 previousPropertyNode->setParent(contextProperty); | 89 previousPropertyNode->setParent(contextProperty); |
| 89 contextProperty = previousPropertyNode; | 90 contextProperty = previousPropertyNode; |
| 90 return previousPropertyNode; | 91 } else { |
| 92 RefPtr<PropertyNode> newPropertyNode = PropertyNode::create(newPropertyV
alue, contextProperty); |
| 93 contextProperty = newPropertyNode.get(); |
| 94 (object.getMutableForPainting().ensureObjectPaintProperties().*Setter)(n
ewPropertyNode.release()); |
| 91 } | 95 } |
| 92 | 96 |
| 93 RefPtr<PropertyNode> newPropertyNode = PropertyNode::create(newPropertyValue
, contextProperty); | 97 if (nodeType == IsolationNode) |
| 94 contextProperty = newPropertyNode.get(); | 98 contextProperty->setIsIsolationNode(); |
| 95 (object.getMutableForPainting().ensureObjectPaintProperties().*Setter)(newPr
opertyNode.release()); | |
| 96 return contextProperty; | 99 return contextProperty; |
| 97 } | 100 } |
| 98 | 101 |
| 99 bool PaintPropertyTreeBuilder::computePaintOffsetTranslation(const LayoutObject&
object, PaintPropertyTreeBuilderContext& context, TransformPaintPropertyNode::V
alue& value) | 102 // We treat out-of-flow positioned objects and stacking context objects as "pain
t property isolation |
| 103 // boundaries". That is, we will create a no-op property nodes if needed that se
rve as the isolated |
| 104 // roots of the paint property subtrees, to ensure that there is no paint proper
ty parent references |
| 105 // from descendants to ancestors crossing the isolated boundaries. When a whole
stacking context is |
| 106 // unchanged in the current document cycle, no property node in the subtree will
need update. |
| 107 // |
| 108 // An exception of the above no-reference-crossing-isolation-boundaries rule is
for references from a |
| 109 // descendant which is a isolation boundary, e.g. from nodes for an out-of-flow
positioned object to |
| 110 // nodes for the container or ancestor of the container of the out-of-flow posit
ioned object, crossing |
| 111 // stacking contexts (isolation boundaries) which are are not the containers of
the out-of-flow |
| 112 // positioned object. For example, in |
| 113 // |
| 114 // <div id="transform" style="transform: translate(10px, 10px)"> |
| 115 // <div id="opacity" style="opacity: 0.5"> |
| 116 // <div id="absolute" style="position: absolute"></div> |
| 117 // <div> |
| 118 // </div> |
| 119 // |
| 120 // the property nodes for 'absolute' can directly reference nodes of 'transform'
, crossing 'opacity' |
| 121 // which is a stacking context and isolation boundary. |
| 122 // |
| 123 // The exception avoids the necessity to create multiple no-op property nodes fo
r normal descendants |
| 124 // and out-of-flow positioned descendants in different tree paths. |
| 125 static bool isPaintPropertyIsolationBoundary(const LayoutObject& object) |
| 126 { |
| 127 return |
| 128 // This condition excludes objects that have stacking-context style but
don't actually |
| 129 // create stacking contexts (e.g. SVG objects having opacity). |
| 130 object.hasLayer() |
| 131 // For now we already have property isolation for LayoutView by FrameVie
w paint properties. |
| 132 // TODO(wangxianzhu): Revisit this for root-layer-scrolls. |
| 133 && !object.isLayoutView() |
| 134 && (object.isOutOfFlowPositioned() || object.styleRef().isStackingContex
t()); |
| 135 } |
| 136 |
| 137 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
ePaintOffsetTranslation(const LayoutObject& object, PaintPropertyTreeBuilderCont
ext& context, TransformPaintPropertyNode::Value& value) |
| 100 { | 138 { |
| 101 if (!object.isBoxModelObject()) | 139 if (!object.isBoxModelObject()) |
| 102 return false; | 140 return NoNode; |
| 103 | 141 |
| 104 // TODO(trchen): Eliminate PaintLayer dependency. | 142 // TODO(trchen): Eliminate PaintLayer dependency. |
| 105 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 143 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 106 if (!layer || !layer->paintsWithTransform(GlobalPaintNormalPhase)) | 144 if (!layer) |
| 107 return false; | 145 return NoNode; |
| 108 | 146 |
| 109 if (context.current.paintOffset == LayoutPoint()) | 147 if (context.current.paintOffset == LayoutPoint() || !layer->paintsWithTransf
orm(GlobalPaintNormalPhase)) { |
| 110 return false; | 148 if (isPaintPropertyIsolationBoundary(object)) { |
| 149 // Will create a no-op paintOffsetTranslation node, if the object is
a isolation boundary |
| 150 // and it won't create other transform nodes. |
| 151 if (!object.styleRef().hasTransform() && !object.styleRef().hasPersp
ective()) |
| 152 return IsolationNode; |
| 153 } |
| 154 return NoNode; |
| 155 } |
| 111 | 156 |
| 112 // We should use the same subpixel paint offset values for snapping regardle
ss of whether a | 157 // We should use the same subpixel paint offset values for snapping regardle
ss of whether a |
| 113 // transform is present. If there is a transform we round the paint offset b
ut keep around | 158 // transform is present. If there is a transform we round the paint offset b
ut keep around |
| 114 // the residual fractional component for the transformed content to paint wi
th. | 159 // the residual fractional component for the transformed content to paint wi
th. |
| 115 // In spv1 this was called "subpixel accumulation". For more information, se
e | 160 // In spv1 this was called "subpixel accumulation". For more information, se
e |
| 116 // PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFragmentBy
ApplyingTransform. | 161 // PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFragmentBy
ApplyingTransform. |
| 117 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); | 162 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); |
| 118 LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.paintOffset
- roundedPaintOffset); | 163 LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.paintOffset
- roundedPaintOffset); |
| 119 | 164 |
| 120 value.matrix.translate(roundedPaintOffset.x(), roundedPaintOffset.y()); | 165 value.matrix.translate(roundedPaintOffset.x(), roundedPaintOffset.y()); |
| 121 context.current.paintOffset = fractionalPaintOffset; | 166 context.current.paintOffset = fractionalPaintOffset; |
| 122 return true; | 167 return NormalNode; |
| 123 } | 168 } |
| 124 | 169 |
| 125 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject&
object, PaintPropertyTreeBuilderContext& context) | 170 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject&
object, PaintPropertyTreeBuilderContext& context) |
| 126 { | 171 { |
| 127 updateObjectPaintProperty< | 172 updateObjectPaintProperty< |
| 128 TransformPaintPropertyNode, | 173 TransformPaintPropertyNode, |
| 129 &ObjectPaintProperties::paintOffsetTranslation, | 174 &ObjectPaintProperties::paintOffsetTranslation, |
| 130 &ObjectPaintProperties::setPaintOffsetTranslation, | 175 &ObjectPaintProperties::setPaintOffsetTranslation, |
| 131 &computePaintOffsetTranslation>(object, context, context.current.transfo
rm); | 176 &computePaintOffsetTranslation>(object, context, context.current.transfo
rm); |
| 132 } | 177 } |
| 133 | 178 |
| 134 static FloatPoint3D transformOrigin(const LayoutBox& box) | 179 static FloatPoint3D transformOrigin(const LayoutBox& box) |
| 135 { | 180 { |
| 136 const ComputedStyle& style = box.styleRef(); | 181 const ComputedStyle& style = box.styleRef(); |
| 137 FloatSize borderBoxSize(box.size()); | 182 FloatSize borderBoxSize(box.size()); |
| 138 return FloatPoint3D( | 183 return FloatPoint3D( |
| 139 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), | 184 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), |
| 140 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), | 185 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), |
| 141 style.transformOriginZ()); | 186 style.transformOriginZ()); |
| 142 } | 187 } |
| 143 | 188 |
| 144 bool PaintPropertyTreeBuilder::computeTransform(const LayoutObject& object, Pain
tPropertyTreeBuilderContext& context, TransformPaintPropertyNode::Value& value) | 189 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
eTransform(const LayoutObject& object, PaintPropertyTreeBuilderContext& context,
TransformPaintPropertyNode::Value& value) |
| 145 { | 190 { |
| 146 if (object.isSVG() && !object.isSVGRoot()) { | 191 if (object.isSVG() && !object.isSVGRoot()) { |
| 147 // SVG does not use paint offset internally. | 192 // SVG does not use paint offset internally. |
| 148 DCHECK(context.current.paintOffset == LayoutPoint()); | 193 DCHECK(context.current.paintOffset == LayoutPoint()); |
| 149 | 194 |
| 150 // FIXME(pdr): Check for the presence of a transform instead of the valu
e. Checking for an | 195 // FIXME(pdr): Check for the presence of a transform instead of the valu
e. Checking for an |
| 151 // identity matrix will cause the property tree structure to change duri
ng animations if | 196 // identity matrix will cause the property tree structure to change duri
ng animations if |
| 152 // the animation passes through the identity matrix. | 197 // the animation passes through the identity matrix. |
| 153 // FIXME(pdr): Refactor this so all non-root SVG objects use the same tr
ansform function. | 198 // FIXME(pdr): Refactor this so all non-root SVG objects use the same tr
ansform function. |
| 154 const AffineTransform& transform = object.isSVGForeignObject() ? object.
localSVGTransform() : object.localToSVGParentTransform(); | 199 const AffineTransform& transform = object.isSVGForeignObject() ? object.
localSVGTransform() : object.localToSVGParentTransform(); |
| 155 if (transform.isIdentity()) | 200 if (transform.isIdentity()) |
| 156 return false; | 201 return NoNode; |
| 157 | 202 |
| 158 value.matrix = transform; | 203 value.matrix = transform; |
| 159 // The origin is included in the local transform, so leave origin empty. | 204 // The origin is included in the local transform, so leave origin empty. |
| 160 return true; | 205 return NormalNode; |
| 161 } | 206 } |
| 162 | 207 |
| 163 const ComputedStyle& style = object.styleRef(); | 208 const ComputedStyle& style = object.styleRef(); |
| 164 if (!object.isBox() || !style.hasTransform()) | 209 if (!object.isBox() || !style.hasTransform()) |
| 165 return false; | 210 return NoNode; |
| 166 | 211 |
| 167 style.applyTransform(value.matrix, toLayoutBox(object).size(), ComputedStyle
::ExcludeTransformOrigin, | 212 style.applyTransform(value.matrix, toLayoutBox(object).size(), ComputedStyle
::ExcludeTransformOrigin, |
| 168 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans
formProperties); | 213 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans
formProperties); |
| 169 value.origin = transformOrigin(toLayoutBox(object)); | 214 value.origin = transformOrigin(toLayoutBox(object)); |
| 170 return true; | 215 return NormalNode; |
| 171 } | 216 } |
| 172 | 217 |
| 173 void PaintPropertyTreeBuilder::updateTransform(const LayoutObject& object, Paint
PropertyTreeBuilderContext& context) | 218 void PaintPropertyTreeBuilder::updateTransform(const LayoutObject& object, Paint
PropertyTreeBuilderContext& context) |
| 174 { | 219 { |
| 175 updateObjectPaintProperty< | 220 updateObjectPaintProperty< |
| 176 TransformPaintPropertyNode, | 221 TransformPaintPropertyNode, |
| 177 &ObjectPaintProperties::transform, | 222 &ObjectPaintProperties::transform, |
| 178 &ObjectPaintProperties::setTransform, | 223 &ObjectPaintProperties::setTransform, |
| 179 &computeTransform>(object, context, context.current.transform); | 224 &computeTransform>(object, context, context.current.transform); |
| 180 } | 225 } |
| 181 | 226 |
| 182 bool PaintPropertyTreeBuilder::computeEffect(const LayoutObject& object, PaintPr
opertyTreeBuilderContext& context, EffectPaintPropertyNode::Value& value) | 227 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
eEffect(const LayoutObject& object, PaintPropertyTreeBuilderContext& context, Ef
fectPaintPropertyNode::Value& value) |
| 183 { | 228 { |
| 184 if (!object.styleRef().hasOpacity()) | 229 if (!object.styleRef().hasOpacity()) { |
| 185 return false; | 230 if (isPaintPropertyIsolationBoundary(object)) { |
| 231 // Will create a no-op effect node if the object is a isolation boun
dary. |
| 232 value = 1.0f; |
| 233 return IsolationNode; |
| 234 } |
| 235 return NoNode; |
| 236 } |
| 186 | 237 |
| 187 value = object.styleRef().opacity(); | 238 value = object.styleRef().opacity(); |
| 188 return true; | 239 return NormalNode; |
| 189 } | 240 } |
| 190 | 241 |
| 191 void PaintPropertyTreeBuilder::updateEffect(const LayoutObject& object, PaintPro
pertyTreeBuilderContext& context) | 242 void PaintPropertyTreeBuilder::updateEffect(const LayoutObject& object, PaintPro
pertyTreeBuilderContext& context) |
| 192 { | 243 { |
| 193 updateObjectPaintProperty< | 244 updateObjectPaintProperty< |
| 194 EffectPaintPropertyNode, | 245 EffectPaintPropertyNode, |
| 195 &ObjectPaintProperties::effect, | 246 &ObjectPaintProperties::effect, |
| 196 &ObjectPaintProperties::setEffect, | 247 &ObjectPaintProperties::setEffect, |
| 197 &computeEffect>(object, context, context.currentEffect); | 248 &computeEffect>(object, context, context.currentEffect); |
| 198 } | 249 } |
| 199 | 250 |
| 200 bool PaintPropertyTreeBuilder::computeCssClip(const LayoutObject& object, PaintP
ropertyTreeBuilderContext& context, ClipPaintPropertyNode::Value& value) | 251 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
eCssClip(const LayoutObject& object, PaintPropertyTreeBuilderContext& context, C
lipPaintPropertyNode::Value& value) |
| 201 { | 252 { |
| 202 if (!object.hasClip()) | 253 if (!object.hasClip()) |
| 203 return false; | 254 return NoNode; |
| 255 |
| 204 DCHECK(object.canContainAbsolutePositionObjects()); | 256 DCHECK(object.canContainAbsolutePositionObjects()); |
| 205 | 257 |
| 206 // Create clip node for descendants that are not fixed position. | 258 // Create clip node for descendants that are not fixed position. |
| 207 // We don't have to setup context.absolutePosition.clip here because this ob
ject must be | 259 // We don't have to setup context.absolutePosition.clip here because this ob
ject must be |
| 208 // a container for absolute position descendants, and will copy from in-flow
context later | 260 // a container for absolute position descendants, and will copy from in-flow
context later |
| 209 // at updateOutOfFlowContext() step. | 261 // at updateOutOfFlowContext() step. |
| 210 LayoutRect clipRect = toLayoutBox(object).clipRect(context.current.paintOffs
et); | 262 LayoutRect clipRect = toLayoutBox(object).clipRect(context.current.paintOffs
et); |
| 211 value = FloatRoundedRect(FloatRect(clipRect)); | 263 value = FloatRoundedRect(FloatRect(clipRect)); |
| 212 return true; | 264 return NormalNode; |
| 213 } | 265 } |
| 214 | 266 |
| 215 void PaintPropertyTreeBuilder::updateCssClip(const LayoutObject& object, PaintPr
opertyTreeBuilderContext& context) | 267 void PaintPropertyTreeBuilder::updateCssClip(const LayoutObject& object, PaintPr
opertyTreeBuilderContext& context) |
| 216 { | 268 { |
| 217 if (ClipPaintPropertyNode* node = updateObjectPaintProperty< | 269 if (ClipPaintPropertyNode* node = updateObjectPaintProperty< |
| 218 ClipPaintPropertyNode, | 270 ClipPaintPropertyNode, |
| 219 &ObjectPaintProperties::cssClip, | 271 &ObjectPaintProperties::cssClip, |
| 220 &ObjectPaintProperties::setCssClip, | 272 &ObjectPaintProperties::setCssClip, |
| 221 &computeCssClip>(object, context, context.current.clip)) | 273 &computeCssClip>(object, context, context.current.clip)) |
| 222 node->setLocalTransformSpace(context.current.transform); | 274 node->setLocalTransformSpace(context.current.transform); |
| 223 } | 275 } |
| 224 | 276 |
| 225 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(const LayoutObject& o
bject, const PaintPropertyTreeBuilderContext& context) | 277 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(const LayoutObject& o
bject, const PaintPropertyTreeBuilderContext& context) |
| 226 { | 278 { |
| 227 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since
we don't need them at the moment. | 279 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since
we don't need them at the moment. |
| 228 if (!object.isBox() && !object.hasLayer()) | 280 if (!object.isBox() && !object.hasLayer()) |
| 229 return; | 281 return; |
| 230 | 282 |
| 231 std::unique_ptr<ObjectPaintProperties::LocalBorderBoxProperties> borderBoxCo
ntext = | 283 std::unique_ptr<ObjectPaintProperties::LocalBorderBoxProperties> borderBoxCo
ntext = |
| 232 wrapUnique(new ObjectPaintProperties::LocalBorderBoxProperties); | 284 wrapUnique(new ObjectPaintProperties::LocalBorderBoxProperties); |
| 233 borderBoxContext->paintOffset = context.current.paintOffset; | 285 borderBoxContext->paintOffset = context.current.paintOffset; |
| 234 borderBoxContext->propertyTreeState = PropertyTreeState(context.current.tran
sform, context.current.clip, context.currentEffect); | 286 borderBoxContext->propertyTreeState = PropertyTreeState(context.current.tran
sform, context.current.clip, context.currentEffect); |
| 235 object.getMutableForPainting().ensureObjectPaintProperties().setLocalBorderB
oxProperties(std::move(borderBoxContext)); | 287 object.getMutableForPainting().ensureObjectPaintProperties().setLocalBorderB
oxProperties(std::move(borderBoxContext)); |
| 236 } | 288 } |
| 237 | 289 |
| 238 // TODO(trchen): Remove this once we bake the paint offset into frameRect. | 290 // TODO(trchen): Remove this once we bake the paint offset into frameRect. |
| 239 bool PaintPropertyTreeBuilder::computeScrollbarPaintOffset(const LayoutObject& o
bject, const PaintPropertyTreeBuilderContext& context, TransformPaintPropertyNod
e::Value& value) | 291 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
eScrollbarPaintOffset(const LayoutObject& object, const PaintPropertyTreeBuilder
Context& context, TransformPaintPropertyNode::Value& value) |
| 240 { | 292 { |
| 241 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); | 293 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); |
| 242 if (roundedPaintOffset == IntPoint()) | 294 if (roundedPaintOffset == IntPoint()) |
| 243 return false; | 295 return NoNode; |
| 244 | 296 |
| 245 if (!object.isBoxModelObject()) | 297 if (!object.isBoxModelObject()) |
| 246 return false; | 298 return NoNode; |
| 247 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge
tScrollableArea(); | 299 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge
tScrollableArea(); |
| 248 if (!scrollableArea) | 300 if (!scrollableArea) |
| 249 return false; | 301 return NoNode; |
| 250 if (!scrollableArea->horizontalScrollbar() && !scrollableArea->verticalScrol
lbar()) | 302 if (!scrollableArea->horizontalScrollbar() && !scrollableArea->verticalScrol
lbar()) |
| 251 return false; | 303 return NoNode; |
| 252 | 304 |
| 253 value.matrix.translate(roundedPaintOffset.x(), roundedPaintOffset.y()); | 305 value.matrix.translate(roundedPaintOffset.x(), roundedPaintOffset.y()); |
| 254 return true; | 306 return NormalNode; |
| 255 } | 307 } |
| 256 | 308 |
| 257 // TODO(trchen): Remove this once we bake the paint offset into frameRect. | 309 // TODO(trchen): Remove this once we bake the paint offset into frameRect. |
| 258 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(const LayoutObject& ob
ject, const PaintPropertyTreeBuilderContext& context) | 310 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(const LayoutObject& ob
ject, const PaintPropertyTreeBuilderContext& context) |
| 259 { | 311 { |
| 260 // This method is almost the same as updateObjectPaintProperty template, exc
ept that it doesn't | 312 // This method is almost the same as updateObjectPaintProperty template, exc
ept that it doesn't |
| 261 // update any context property. | 313 // update any context property. |
| 262 ObjectPaintProperties* previousProperties = object.objectPaintProperties(); | 314 ObjectPaintProperties* previousProperties = object.objectPaintProperties(); |
| 263 TransformPaintPropertyNode::Value paintOffset; | 315 TransformPaintPropertyNode::Value paintOffset; |
| 264 if (!computeScrollbarPaintOffset(object, context, paintOffset)) { | 316 if (!computeScrollbarPaintOffset(object, context, paintOffset)) { |
| 265 if (previousProperties) | 317 if (previousProperties) |
| 266 (previousProperties->setScrollbarPaintOffset(nullptr)); | 318 (previousProperties->setScrollbarPaintOffset(nullptr)); |
| 267 return; | 319 return; |
| 268 } | 320 } |
| 269 | 321 |
| 270 TransformPaintPropertyNode* previousScrollbarPaintOffsetNode = previousPrope
rties ? previousProperties->scrollbarPaintOffset() : nullptr; | 322 TransformPaintPropertyNode* previousScrollbarPaintOffsetNode = previousPrope
rties ? previousProperties->scrollbarPaintOffset() : nullptr; |
| 271 if (previousScrollbarPaintOffsetNode && previousScrollbarPaintOffsetNode->va
lue() == paintOffset) { | 323 if (previousScrollbarPaintOffsetNode && previousScrollbarPaintOffsetNode->va
lue() == paintOffset) { |
| 272 previousScrollbarPaintOffsetNode->setParent(context.current.transform); | 324 previousScrollbarPaintOffsetNode->setParent(context.current.transform); |
| 273 return; | 325 return; |
| 274 } | 326 } |
| 275 | 327 |
| 276 object.getMutableForPainting().ensureObjectPaintProperties().setScrollbarPai
ntOffset( | 328 object.getMutableForPainting().ensureObjectPaintProperties().setScrollbarPai
ntOffset( |
| 277 TransformPaintPropertyNode::create(paintOffset, context.current.transfor
m)); | 329 TransformPaintPropertyNode::create(paintOffset, context.current.transfor
m)); |
| 278 } | 330 } |
| 279 | 331 |
| 280 bool PaintPropertyTreeBuilder::computeOverflowClip(const LayoutObject& object, P
aintPropertyTreeBuilderContext& context, ClipPaintPropertyNode::Value& value) | 332 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
eOverflowClip(const LayoutObject& object, PaintPropertyTreeBuilderContext& conte
xt, ClipPaintPropertyNode::Value& value) |
| 281 { | 333 { |
| 282 const LayoutBox& box = toLayoutBox(object); | 334 if (object.isBox()) { |
| 335 const LayoutBox& box = toLayoutBox(object); |
| 336 // The <input> elements can't have contents thus CSS overflow property d
oesn't apply. |
| 337 // However for layout purposes we do generate child layout objects for t
hem, e.g. button label. |
| 338 // We should clip the overflow from those children. This is called contr
ol clip and we |
| 339 // technically treat them like overflow clip. |
| 340 if (box.hasControlClip()) { |
| 341 value = FloatRoundedRect(FloatRect(box.controlClipRect(context.curre
nt.paintOffset))); |
| 342 return NormalNode; |
| 343 } |
| 344 if (box.hasOverflowClip()) { |
| 345 value = FloatRoundedRect(FloatRect(box.overflowClipRect(context.curr
ent.paintOffset))); |
| 346 return NormalNode; |
| 347 } |
| 348 } |
| 283 | 349 |
| 284 // The <input> elements can't have contents thus CSS overflow property doesn
't apply. | 350 if (isPaintPropertyIsolationBoundary(object)) { |
| 285 // However for layout purposes we do generate child layout objects for them,
e.g. button label. | 351 // Will create a no-op overflowClip node, if the object is an isolation
boundary |
| 286 // We should clip the overflow from those children. This is called control c
lip and we | 352 // and it hasn't create a cssClip node. |
| 287 // technically treat them like overflow clip. | 353 if (!object.hasClip()) { |
| 288 LayoutRect clipRect; | 354 value = FloatRoundedRect(LayoutRect::infiniteIntRect()); |
| 289 if (box.hasControlClip()) | 355 return IsolationNode; |
| 290 clipRect = box.controlClipRect(context.current.paintOffset); | 356 } |
| 291 else if (box.hasOverflowClip()) | 357 } |
| 292 clipRect = box.overflowClipRect(context.current.paintOffset); | 358 return NoNode; |
| 293 else | |
| 294 return false; | |
| 295 | |
| 296 value = FloatRoundedRect(FloatRect(clipRect)); | |
| 297 return true; | |
| 298 } | 359 } |
| 299 | 360 |
| 300 void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, Pa
intPropertyTreeBuilderContext& context) | 361 void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, Pa
intPropertyTreeBuilderContext& context) |
| 301 { | 362 { |
| 302 if (!object.isBox()) | |
| 303 return; | |
| 304 const LayoutBox& box = toLayoutBox(object); | |
| 305 | |
| 306 // This need to be in top-level block to hold the reference until we finish
creating the normal clip node. | 363 // This need to be in top-level block to hold the reference until we finish
creating the normal clip node. |
| 307 RefPtr<ClipPaintPropertyNode> borderRadiusClip; | 364 RefPtr<ClipPaintPropertyNode> borderRadiusClip; |
| 308 if ((box.hasControlClip() || box.hasOverflowClip()) && box.styleRef().hasBor
derRadius()) { | 365 if (object.isBox()) { |
| 309 auto innerBorder = box.styleRef().getRoundedInnerBorderFor( | 366 const LayoutBox& box = toLayoutBox(object); |
| 310 LayoutRect(context.current.paintOffset, box.size())); | 367 if ((box.hasControlClip() || box.hasOverflowClip()) && box.styleRef().ha
sBorderRadius()) { |
| 311 borderRadiusClip = ClipPaintPropertyNode::create(context.current.transfo
rm, innerBorder, context.current.clip); | 368 auto innerBorder = box.styleRef().getRoundedInnerBorderFor( |
| 312 context.current.clip = borderRadiusClip.get(); | 369 LayoutRect(context.current.paintOffset, box.size())); |
| 370 borderRadiusClip = ClipPaintPropertyNode::create(context.current.tra
nsform, innerBorder, context.current.clip); |
| 371 context.current.clip = borderRadiusClip.get(); |
| 372 } |
| 313 } | 373 } |
| 314 | 374 |
| 315 if (ClipPaintPropertyNode* node = updateObjectPaintProperty< | 375 if (ClipPaintPropertyNode* node = updateObjectPaintProperty< |
| 316 ClipPaintPropertyNode, | 376 ClipPaintPropertyNode, |
| 317 &ObjectPaintProperties::overflowClip, | 377 &ObjectPaintProperties::overflowClip, |
| 318 &ObjectPaintProperties::setOverflowClip, | 378 &ObjectPaintProperties::setOverflowClip, |
| 319 &computeOverflowClip>(object, context, context.current.clip)) | 379 &computeOverflowClip>(object, context, context.current.clip)) |
| 320 node->setLocalTransformSpace(context.current.transform); | 380 node->setLocalTransformSpace(context.current.transform); |
| 321 } | 381 } |
| 322 | 382 |
| 323 static FloatPoint perspectiveOrigin(const LayoutBox& box) | 383 static FloatPoint perspectiveOrigin(const LayoutBox& box) |
| 324 { | 384 { |
| 325 const ComputedStyle& style = box.styleRef(); | 385 const ComputedStyle& style = box.styleRef(); |
| 326 FloatSize borderBoxSize(box.size()); | 386 FloatSize borderBoxSize(box.size()); |
| 327 return FloatPoint( | 387 return FloatPoint( |
| 328 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), | 388 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), |
| 329 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()))
; | 389 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()))
; |
| 330 } | 390 } |
| 331 | 391 |
| 332 bool PaintPropertyTreeBuilder::computePerspective(const LayoutObject& object, Pa
intPropertyTreeBuilderContext& context, TransformPaintPropertyNode::Value& value
) | 392 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
ePerspective(const LayoutObject& object, PaintPropertyTreeBuilderContext& contex
t, TransformPaintPropertyNode::Value& value) |
| 333 { | 393 { |
| 334 const ComputedStyle& style = object.styleRef(); | 394 const ComputedStyle& style = object.styleRef(); |
| 335 if (!object.isBox() || !style.hasPerspective()) | 395 if (!object.isBox() || !style.hasPerspective()) |
| 336 return false; | 396 return NoNode; |
| 337 | 397 |
| 338 value.matrix.applyPerspective(style.perspective()); | 398 value.matrix.applyPerspective(style.perspective()); |
| 339 value.origin = perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context
.current.paintOffset); | 399 value.origin = perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context
.current.paintOffset); |
| 340 return true; | 400 return NormalNode; |
| 341 } | 401 } |
| 342 | 402 |
| 343 void PaintPropertyTreeBuilder::updatePerspective(const LayoutObject& object, Pai
ntPropertyTreeBuilderContext& context) | 403 void PaintPropertyTreeBuilder::updatePerspective(const LayoutObject& object, Pai
ntPropertyTreeBuilderContext& context) |
| 344 { | 404 { |
| 345 updateObjectPaintProperty< | 405 updateObjectPaintProperty< |
| 346 TransformPaintPropertyNode, | 406 TransformPaintPropertyNode, |
| 347 &ObjectPaintProperties::perspective, | 407 &ObjectPaintProperties::perspective, |
| 348 &ObjectPaintProperties::setPerspective, | 408 &ObjectPaintProperties::setPerspective, |
| 349 &computePerspective>(object, context, context.current.transform); | 409 &computePerspective>(object, context, context.current.transform); |
| 350 } | 410 } |
| 351 | 411 |
| 352 bool PaintPropertyTreeBuilder::computeSvgLocalToBorderBoxTransform(const LayoutO
bject& object, PaintPropertyTreeBuilderContext& context, TransformPaintPropertyN
ode::Value& value) | 412 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
eSvgLocalToBorderBoxTransform(const LayoutObject& object, PaintPropertyTreeBuild
erContext& context, TransformPaintPropertyNode::Value& value) |
| 353 { | 413 { |
| 354 if (!object.isSVGRoot()) | 414 if (!object.isSVGRoot()) |
| 355 return false; | 415 return NoNode; |
| 356 | 416 |
| 357 AffineTransform transformToBorderBox = SVGRootPainter(toLayoutSVGRoot(object
)).transformToPixelSnappedBorderBox(context.current.paintOffset); | 417 AffineTransform transformToBorderBox = SVGRootPainter(toLayoutSVGRoot(object
)).transformToPixelSnappedBorderBox(context.current.paintOffset); |
| 358 | 418 |
| 359 // The paint offset is included in |transformToBorderBox| so SVG does not ne
ed to handle paint | 419 // The paint offset is included in |transformToBorderBox| so SVG does not ne
ed to handle paint |
| 360 // offset internally. | 420 // offset internally. |
| 361 context.current.paintOffset = LayoutPoint(); | 421 context.current.paintOffset = LayoutPoint(); |
| 362 | 422 |
| 363 if (transformToBorderBox.isIdentity()) | 423 if (transformToBorderBox.isIdentity()) |
| 364 return false; | 424 return NoNode; |
| 365 | 425 |
| 366 value.matrix = transformToBorderBox; | 426 value.matrix = transformToBorderBox; |
| 367 context.current.paintOffset = LayoutPoint(); | 427 context.current.paintOffset = LayoutPoint(); |
| 368 return true; | 428 return NormalNode; |
| 369 } | 429 } |
| 370 | 430 |
| 371 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutOb
ject& object, PaintPropertyTreeBuilderContext& context) | 431 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutOb
ject& object, PaintPropertyTreeBuilderContext& context) |
| 372 { | 432 { |
| 373 updateObjectPaintProperty< | 433 updateObjectPaintProperty< |
| 374 TransformPaintPropertyNode, | 434 TransformPaintPropertyNode, |
| 375 &ObjectPaintProperties::svgLocalToBorderBoxTransform, | 435 &ObjectPaintProperties::svgLocalToBorderBoxTransform, |
| 376 &ObjectPaintProperties::setSvgLocalToBorderBoxTransform, | 436 &ObjectPaintProperties::setSvgLocalToBorderBoxTransform, |
| 377 &computeSvgLocalToBorderBoxTransform>(object, context, context.current.t
ransform); | 437 &computeSvgLocalToBorderBoxTransform>(object, context, context.current.t
ransform); |
| 378 } | 438 } |
| 379 | 439 |
| 380 bool PaintPropertyTreeBuilder::computeScrollTranslation(const LayoutObject& obje
ct, PaintPropertyTreeBuilderContext& context, TransformPaintPropertyNode::Value&
value) | 440 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
eScrollTranslation(const LayoutObject& object, PaintPropertyTreeBuilderContext&
context, TransformPaintPropertyNode::Value& value) |
| 381 { | 441 { |
| 382 if (!object.isBoxModelObject() || !object.hasOverflowClip()) | 442 if (!object.isBoxModelObject() || !object.hasOverflowClip()) |
| 383 return false; | 443 return NoNode; |
| 384 | 444 |
| 385 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 445 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 386 ASSERT(layer); | 446 ASSERT(layer); |
| 387 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); | 447 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); |
| 388 if (scrollOffset.isZero() && !layer->scrollsOverflow()) | 448 if (scrollOffset.isZero() && !layer->scrollsOverflow()) |
| 389 return false; | 449 return NoNode; |
| 390 | 450 |
| 391 value.matrix.translate(-scrollOffset.width(), -scrollOffset.height()); | 451 value.matrix.translate(-scrollOffset.width(), -scrollOffset.height()); |
| 392 return true; | 452 return NormalNode; |
| 393 } | 453 } |
| 394 | 454 |
| 395 void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& objec
t, PaintPropertyTreeBuilderContext& context) | 455 void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& objec
t, PaintPropertyTreeBuilderContext& context) |
| 396 { | 456 { |
| 397 updateObjectPaintProperty< | 457 updateObjectPaintProperty< |
| 398 TransformPaintPropertyNode, | 458 TransformPaintPropertyNode, |
| 399 &ObjectPaintProperties::scrollTranslation, | 459 &ObjectPaintProperties::scrollTranslation, |
| 400 &ObjectPaintProperties::setScrollTranslation, | 460 &ObjectPaintProperties::setScrollTranslation, |
| 401 &computeScrollTranslation>(object, context, context.current.transform); | 461 &computeScrollTranslation>(object, context, context.current.transform); |
| 402 } | 462 } |
| 403 | 463 |
| 404 // Returns true if we need to create a cssClip node for fixed position. | 464 // Returns true if we need to create a cssClip node for fixed position. |
| 405 bool PaintPropertyTreeBuilder::computeOutOfFlowContext(const LayoutObject& objec
t, PaintPropertyTreeBuilderContext& context, ClipPaintPropertyNode::Value& value
) | 465 PaintPropertyTreeBuilder::PaintPropertyNodeType PaintPropertyTreeBuilder::comput
eOutOfFlowContext(const LayoutObject& object, PaintPropertyTreeBuilderContext& c
ontext, ClipPaintPropertyNode::Value& value) |
| 406 { | 466 { |
| 407 if (object.canContainAbsolutePositionObjects()) { | 467 if (object.canContainAbsolutePositionObjects()) { |
| 408 context.absolutePosition = context.current; | 468 context.absolutePosition = context.current; |
| 409 context.containerForAbsolutePosition = &object; | 469 context.containerForAbsolutePosition = &object; |
| 410 } | 470 } |
| 411 | 471 |
| 412 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram
eView | 472 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram
eView |
| 413 // paint properties for rootLayerScrolls. | 473 // paint properties for rootLayerScrolls. |
| 414 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) { | 474 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) { |
| 415 context.fixedPosition = context.current; | 475 context.fixedPosition = context.current; |
| 416 return false; | 476 return NoNode; |
| 417 } | 477 } |
| 418 | 478 |
| 419 if (!object.objectPaintProperties() || !object.objectPaintProperties()->cssC
lip()) | 479 if (!object.objectPaintProperties() || !object.objectPaintProperties()->cssC
lip()) |
| 420 return false; | 480 return NoNode; |
| 421 | 481 |
| 422 // CSS clip applies to all descendants, even if this object is not a contain
ing block | 482 // CSS clip applies to all descendants, even if this object is not a contain
ing block |
| 423 // ancestor of the descendant. It is okay for absolute-position descendants
because | 483 // ancestor of the descendant. It is okay for absolute-position descendants
because |
| 424 // having CSS clip implies being absolute position container. However for fi
xed-position | 484 // having CSS clip implies being absolute position container. However for fi
xed-position |
| 425 // descendants we need to insert the clip here if we are not a containing bl
ock ancestor | 485 // descendants we need to insert the clip here if we are not a containing bl
ock ancestor |
| 426 // of them. | 486 // of them. |
| 427 auto* cssClip = object.objectPaintProperties()->cssClip(); | 487 auto* cssClip = object.objectPaintProperties()->cssClip(); |
| 428 | 488 |
| 429 // Before we actually create anything, check whether in-flow context and fix
ed-position | 489 // Before we actually create anything, check whether in-flow context and fix
ed-position |
| 430 // context has exactly the same clip. Reuse if possible. | 490 // context has exactly the same clip. Reuse if possible. |
| 431 if (context.fixedPosition.clip == cssClip->parent()) { | 491 if (context.fixedPosition.clip == cssClip->parent()) { |
| 432 context.fixedPosition.clip = cssClip; | 492 context.fixedPosition.clip = cssClip; |
| 433 return false; | 493 return NoNode; |
| 434 } | 494 } |
| 435 | 495 |
| 436 value = cssClip->clipRect(); | 496 value = cssClip->clipRect(); |
| 437 return true; | 497 return NormalNode; |
| 438 } | 498 } |
| 439 | 499 |
| 440 void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object
, PaintPropertyTreeBuilderContext& context) | 500 void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object
, PaintPropertyTreeBuilderContext& context) |
| 441 { | 501 { |
| 442 if (ClipPaintPropertyNode* node = updateObjectPaintProperty< | 502 if (ClipPaintPropertyNode* node = updateObjectPaintProperty< |
| 443 ClipPaintPropertyNode, | 503 ClipPaintPropertyNode, |
| 444 &ObjectPaintProperties::cssClipFixedPosition, | 504 &ObjectPaintProperties::cssClipFixedPosition, |
| 445 &ObjectPaintProperties::setCssClipFixedPosition, | 505 &ObjectPaintProperties::setCssClipFixedPosition, |
| 446 &computeOutOfFlowContext>(object, context, context.fixedPosition.clip)) | 506 &computeOutOfFlowContext>(object, context, context.fixedPosition.clip)) |
| 447 node->setLocalTransformSpace(const_cast<TransformPaintPropertyNode*>(obj
ect.objectPaintProperties()->cssClip()->localTransformSpace())); | 507 node->setLocalTransformSpace(const_cast<TransformPaintPropertyNode*>(obj
ect.objectPaintProperties()->cssClip()->localTransformSpace())); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 489 // but their location have the row's location baked-in. | 549 // but their location have the row's location baked-in. |
| 490 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). | 550 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). |
| 491 if (boxModelObject.isTableCell()) { | 551 if (boxModelObject.isTableCell()) { |
| 492 LayoutObject* parentRow = boxModelObject.parent(); | 552 LayoutObject* parentRow = boxModelObject.parent(); |
| 493 ASSERT(parentRow && parentRow->isTableRow()); | 553 ASSERT(parentRow && parentRow->isTableRow()); |
| 494 context.current.paintOffset.moveBy(-toLayoutBox(parentRow)->topLeftL
ocation()); | 554 context.current.paintOffset.moveBy(-toLayoutBox(parentRow)->topLeftL
ocation()); |
| 495 } | 555 } |
| 496 } | 556 } |
| 497 } | 557 } |
| 498 | 558 |
| 559 #if DCHECK_IS_ON() |
| 560 void PaintPropertyTreeBuilder::checkPropertyIsolationBoundaryForStackingContext(
const LayoutObject& object) |
| 561 { |
| 562 if (!isPaintPropertyIsolationBoundary(object)) |
| 563 return; |
| 564 |
| 565 ObjectPaintProperties* properties = object.objectPaintProperties(); |
| 566 DCHECK(properties); |
| 567 DCHECK(properties->paintOffsetTranslation() || properties->transform() || pr
operties->perspective()); |
| 568 DCHECK(properties->effect()); |
| 569 DCHECK(properties->cssClip() || properties->overflowClip()); |
| 570 } |
| 571 #endif |
| 572 |
| 499 void PaintPropertyTreeBuilder::buildTreeNodes(const LayoutObject& object, PaintP
ropertyTreeBuilderContext& context) | 573 void PaintPropertyTreeBuilder::buildTreeNodes(const LayoutObject& object, PaintP
ropertyTreeBuilderContext& context) |
| 500 { | 574 { |
| 501 if (!object.isBoxModelObject() && !object.isSVG()) | 575 if (!object.isBoxModelObject() && !object.isSVG()) |
| 502 return; | 576 return; |
| 503 | 577 |
| 504 deriveBorderBoxFromContainerContext(object, context); | 578 deriveBorderBoxFromContainerContext(object, context); |
| 505 | 579 |
| 506 updatePaintOffsetTranslation(object, context); | 580 updatePaintOffsetTranslation(object, context); |
| 507 updateTransform(object, context); | 581 updateTransform(object, context); |
| 508 updateEffect(object, context); | 582 updateEffect(object, context); |
| 509 updateCssClip(object, context); | 583 updateCssClip(object, context); |
| 510 updateLocalBorderBoxContext(object, context); | 584 updateLocalBorderBoxContext(object, context); |
| 511 updateScrollbarPaintOffset(object, context); | 585 updateScrollbarPaintOffset(object, context); |
| 512 updateOverflowClip(object, context); | 586 updateOverflowClip(object, context); |
| 513 // TODO(trchen): Insert flattening transform here, as specified by | 587 // TODO(trchen): Insert flattening transform here, as specified by |
| 514 // http://www.w3.org/TR/css3-transforms/#transform-style-property | 588 // http://www.w3.org/TR/css3-transforms/#transform-style-property |
| 515 updatePerspective(object, context); | 589 updatePerspective(object, context); |
| 516 updateSvgLocalToBorderBoxTransform(object, context); | 590 updateSvgLocalToBorderBoxTransform(object, context); |
| 517 updateScrollTranslation(object, context); | 591 updateScrollTranslation(object, context); |
| 518 updateOutOfFlowContext(object, context); | 592 updateOutOfFlowContext(object, context); |
| 593 #if DCHECK_IS_ON() |
| 594 checkPropertyIsolationBoundaryForStackingContext(object); |
| 595 #endif |
| 519 } | 596 } |
| 520 | 597 |
| 521 } // namespace blink | 598 } // namespace blink |
| OLD | NEW |