| 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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; | 71 context.current.renderingContextID = 0; |
| 72 context.current.shouldFlattenInheritedTransform = true; | 72 context.current.shouldFlattenInheritedTransform = true; |
| 73 context.absolutePosition = context.current; | 73 context.absolutePosition = context.current; |
| 74 context.containerForAbsolutePosition = nullptr; | 74 context.containerForAbsolutePosition = nullptr; |
| 75 context.fixedPosition = context.current; | 75 context.fixedPosition = context.current; |
| 76 context.fixedPosition.transform = frameView.preTranslation(); | 76 context.fixedPosition.transform = frameView.preTranslation(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 template <typename PropertyNode, void (ObjectPaintProperties::*Setter)(PassRefPt
r<PropertyNode>)> | |
| 80 void PaintPropertyTreeBuilder::clearPaintProperty(const LayoutObject& object) | |
| 81 { | |
| 82 if (ObjectPaintProperties* existingProperties = object.objectPaintProperties
()) | |
| 83 (existingProperties->*Setter)(nullptr); | |
| 84 } | |
| 85 | |
| 86 template < | |
| 87 typename PropertyNode, | |
| 88 PropertyNode* (ObjectPaintProperties::*Getter)() const, | |
| 89 void (ObjectPaintProperties::*Setter)(PassRefPtr<PropertyNode>), | |
| 90 typename... Args> | |
| 91 void PaintPropertyTreeBuilder::updateOrCreatePaintProperty(const LayoutObject& o
bject, const PaintPropertyTreeBuilderContext& context, PropertyNode*& contextPro
perty, const Args&... args) | |
| 92 { | |
| 93 ObjectPaintProperties* existingProperties = object.objectPaintProperties(); | |
| 94 PropertyNode* existingPropertyNode = existingProperties ? (existingPropertie
s->*Getter)() : nullptr; | |
| 95 if (existingPropertyNode) { | |
| 96 existingPropertyNode->update(contextProperty, args...); | |
| 97 contextProperty = existingPropertyNode; | |
| 98 } else { | |
| 99 RefPtr<PropertyNode> newPropertyNode = PropertyNode::create(contextPrope
rty, args...); | |
| 100 contextProperty = newPropertyNode.get(); | |
| 101 (object.getMutableForPainting().ensureObjectPaintProperties().*Setter)(n
ewPropertyNode.release()); | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject&
object, PaintPropertyTreeBuilderContext& context) | 79 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject&
object, PaintPropertyTreeBuilderContext& context) |
| 106 { | 80 { |
| 107 if (object.isBoxModelObject() && context.current.paintOffset != LayoutPoint(
)) { | 81 if (object.isBoxModelObject() && context.current.paintOffset != LayoutPoint(
)) { |
| 108 // TODO(trchen): Eliminate PaintLayer dependency. | 82 // TODO(trchen): Eliminate PaintLayer dependency. |
| 109 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 83 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 110 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { | 84 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { |
| 111 // We should use the same subpixel paint offset values for snapping
regardless of whether a | 85 // We should use the same subpixel paint offset values for snapping
regardless of whether a |
| 112 // transform is present. If there is a transform we round the paint
offset but keep around | 86 // transform is present. If there is a transform we round the paint
offset but keep around |
| 113 // the residual fractional component for the transformed content to
paint with. | 87 // the residual fractional component for the transformed content to
paint with. |
| 114 // In spv1 this was called "subpixel accumulation". For more informa
tion, see | 88 // In spv1 this was called "subpixel accumulation". For more informa
tion, see |
| 115 // PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFr
agmentByApplyingTransform. | 89 // PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFr
agmentByApplyingTransform. |
| 116 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintO
ffset); | 90 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintO
ffset); |
| 117 LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.pain
tOffset - roundedPaintOffset); | 91 LayoutPoint fractionalPaintOffset = LayoutPoint(context.current.pain
tOffset - roundedPaintOffset); |
| 118 | 92 |
| 119 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::paintOffsetTranslation, &ObjectPaintProperties::setPaintOffsetTransl
ation>( | 93 context.current.transform = object.getMutableForPainting().ensureObj
ectPaintProperties().createOrUpdatePaintOffsetTranslation( |
| 120 object, context, context.current.transform, TransformationMatrix
().translate(roundedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D(), | 94 context.current.transform, TransformationMatrix().translate(roun
dedPaintOffset.x(), roundedPaintOffset.y()), FloatPoint3D(), |
| 121 context.current.shouldFlattenInheritedTransform, context.current
.renderingContextID); | 95 context.current.shouldFlattenInheritedTransform, context.current
.renderingContextID); |
| 122 context.current.paintOffset = fractionalPaintOffset; | 96 context.current.paintOffset = fractionalPaintOffset; |
| 123 return; | 97 return; |
| 124 } | 98 } |
| 125 } | 99 } |
| 126 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setPa
intOffsetTranslation>(object); | 100 |
| 101 if (ObjectPaintProperties* properties = object.getMutableForPainting().objec
tPaintProperties()) |
| 102 properties->clearPaintOffsetTranslation(); |
| 127 } | 103 } |
| 128 | 104 |
| 129 static FloatPoint3D transformOrigin(const LayoutBox& box) | 105 static FloatPoint3D transformOrigin(const LayoutBox& box) |
| 130 { | 106 { |
| 131 const ComputedStyle& style = box.styleRef(); | 107 const ComputedStyle& style = box.styleRef(); |
| 132 FloatSize borderBoxSize(box.size()); | 108 FloatSize borderBoxSize(box.size()); |
| 133 return FloatPoint3D( | 109 return FloatPoint3D( |
| 134 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), | 110 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), |
| 135 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), | 111 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), |
| 136 style.transformOriginZ()); | 112 style.transformOriginZ()); |
| 137 } | 113 } |
| 138 | 114 |
| 139 void PaintPropertyTreeBuilder::updateTransform(const LayoutObject& object, Paint
PropertyTreeBuilderContext& context) | 115 void PaintPropertyTreeBuilder::updateTransform(const LayoutObject& object, Paint
PropertyTreeBuilderContext& context) |
| 140 { | 116 { |
| 141 if (object.isSVG() && !object.isSVGRoot()) { | 117 if (object.isSVG() && !object.isSVGRoot()) { |
| 142 // SVG does not use paint offset internally. | 118 // SVG does not use paint offset internally. |
| 143 DCHECK(context.current.paintOffset == LayoutPoint()); | 119 DCHECK(context.current.paintOffset == LayoutPoint()); |
| 144 | 120 |
| 145 // FIXME(pdr): Check for the presence of a transform instead of the valu
e. Checking for an | 121 // FIXME(pdr): Check for the presence of a transform instead of the valu
e. Checking for an |
| 146 // identity matrix will cause the property tree structure to change duri
ng animations if | 122 // identity matrix will cause the property tree structure to change duri
ng animations if |
| 147 // the animation passes through the identity matrix. | 123 // the animation passes through the identity matrix. |
| 148 // FIXME(pdr): Refactor this so all non-root SVG objects use the same tr
ansform function. | 124 // FIXME(pdr): Refactor this so all non-root SVG objects use the same tr
ansform function. |
| 149 const AffineTransform& transform = object.isSVGForeignObject() ? object.
localSVGTransform() : object.localToSVGParentTransform(); | 125 const AffineTransform& transform = object.isSVGForeignObject() ? object.
localSVGTransform() : object.localToSVGParentTransform(); |
| 150 if (!transform.isIdentity()) { | 126 if (!transform.isIdentity()) { |
| 151 // The origin is included in the local transform, so leave origin em
pty. | 127 // The origin is included in the local transform, so leave origin em
pty. |
| 152 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::transform, &ObjectPaintProperties::setTransform>( | 128 context.current.transform = object.getMutableForPainting().ensureObj
ectPaintProperties().createOrUpdateTransform( |
| 153 object, context, context.current.transform, TransformationMatrix
(transform), FloatPoint3D()); | 129 context.current.transform, TransformationMatrix(transform), Floa
tPoint3D()); |
| 154 context.current.renderingContextID = 0; | 130 context.current.renderingContextID = 0; |
| 155 context.current.shouldFlattenInheritedTransform = false; | 131 context.current.shouldFlattenInheritedTransform = false; |
| 156 return; | 132 return; |
| 157 } | 133 } |
| 158 } else { | 134 } else { |
| 159 const ComputedStyle& style = object.styleRef(); | 135 const ComputedStyle& style = object.styleRef(); |
| 160 if (object.isBox() && (style.hasTransform() || style.preserves3D())) { | 136 if (object.isBox() && (style.hasTransform() || style.preserves3D())) { |
| 161 TransformationMatrix matrix; | 137 TransformationMatrix matrix; |
| 162 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedSty
le::ExcludeTransformOrigin, | 138 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedSty
le::ExcludeTransformOrigin, |
| 163 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndepend
entTransformProperties); | 139 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndepend
entTransformProperties); |
| 164 FloatPoint3D origin = transformOrigin(toLayoutBox(object)); | 140 FloatPoint3D origin = transformOrigin(toLayoutBox(object)); |
| 165 | 141 |
| 166 unsigned renderingContextID = context.current.renderingContextID; | 142 unsigned renderingContextID = context.current.renderingContextID; |
| 167 unsigned renderingContextIDForChildren = 0; | 143 unsigned renderingContextIDForChildren = 0; |
| 168 bool flattensInheritedTransform = context.current.shouldFlattenInher
itedTransform; | 144 bool flattensInheritedTransform = context.current.shouldFlattenInher
itedTransform; |
| 169 bool childrenFlattenInheritedTransform = true; | 145 bool childrenFlattenInheritedTransform = true; |
| 170 | 146 |
| 171 // TODO(trchen): transform-style should only be respected if a Paint
Layer is | 147 // TODO(trchen): transform-style should only be respected if a Paint
Layer is |
| 172 // created. | 148 // created. |
| 173 if (style.preserves3D()) { | 149 if (style.preserves3D()) { |
| 174 // If a node with transform-style: preserve-3d does not exist in
an | 150 // If a node with transform-style: preserve-3d does not exist in
an |
| 175 // existing rendering context, it establishes a new one. | 151 // existing rendering context, it establishes a new one. |
| 176 if (!renderingContextID) | 152 if (!renderingContextID) |
| 177 renderingContextID = PtrHash<const LayoutObject>::hash(&obje
ct); | 153 renderingContextID = PtrHash<const LayoutObject>::hash(&obje
ct); |
| 178 renderingContextIDForChildren = renderingContextID; | 154 renderingContextIDForChildren = renderingContextID; |
| 179 childrenFlattenInheritedTransform = false; | 155 childrenFlattenInheritedTransform = false; |
| 180 } | 156 } |
| 181 | 157 |
| 182 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::transform, &ObjectPaintProperties::setTransform>( | 158 context.current.transform = object.getMutableForPainting().ensureObj
ectPaintProperties().createOrUpdateTransform( |
| 183 object, context, context.current.transform, matrix, origin, flat
tensInheritedTransform, renderingContextID); | 159 context.current.transform, matrix, origin, flattensInheritedTran
sform, renderingContextID); |
| 184 context.current.renderingContextID = renderingContextIDForChildren; | 160 context.current.renderingContextID = renderingContextIDForChildren; |
| 185 context.current.shouldFlattenInheritedTransform = childrenFlattenInh
eritedTransform; | 161 context.current.shouldFlattenInheritedTransform = childrenFlattenInh
eritedTransform; |
| 186 return; | 162 return; |
| 187 } | 163 } |
| 188 } | 164 } |
| 189 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setTr
ansform>(object); | 165 |
| 166 if (ObjectPaintProperties* properties = object.getMutableForPainting().objec
tPaintProperties()) |
| 167 properties->clearTransform(); |
| 190 } | 168 } |
| 191 | 169 |
| 192 void PaintPropertyTreeBuilder::updateEffect(const LayoutObject& object, PaintPro
pertyTreeBuilderContext& context) | 170 void PaintPropertyTreeBuilder::updateEffect(const LayoutObject& object, PaintPro
pertyTreeBuilderContext& context) |
| 193 { | 171 { |
| 194 if (!object.styleRef().hasOpacity()) { | 172 if (!object.styleRef().hasOpacity()) { |
| 195 clearPaintProperty<EffectPaintPropertyNode, &ObjectPaintProperties::setE
ffect>(object); | 173 if (ObjectPaintProperties* properties = object.getMutableForPainting().o
bjectPaintProperties()) |
| 174 properties->clearEffect(); |
| 196 return; | 175 return; |
| 197 } | 176 } |
| 198 | 177 |
| 199 updateOrCreatePaintProperty<EffectPaintPropertyNode, &ObjectPaintProperties:
:effect, &ObjectPaintProperties::setEffect>( | 178 context.currentEffect = object.getMutableForPainting().ensureObjectPaintProp
erties().createOrUpdateEffect( |
| 200 object, context, context.currentEffect, object.styleRef().opacity()); | 179 context.currentEffect, object.styleRef().opacity()); |
| 201 } | 180 } |
| 202 | 181 |
| 203 void PaintPropertyTreeBuilder::updateCssClip(const LayoutObject& object, PaintPr
opertyTreeBuilderContext& context) | 182 void PaintPropertyTreeBuilder::updateCssClip(const LayoutObject& object, PaintPr
opertyTreeBuilderContext& context) |
| 204 { | 183 { |
| 205 if (object.hasClip()) { | 184 if (object.hasClip()) { |
| 206 // Create clip node for descendants that are not fixed position. | 185 // Create clip node for descendants that are not fixed position. |
| 207 // We don't have to setup context.absolutePosition.clip here because thi
s object must be | 186 // We don't have to setup context.absolutePosition.clip here because thi
s object must be |
| 208 // a container for absolute position descendants, and will copy from in-
flow context later | 187 // a container for absolute position descendants, and will copy from in-
flow context later |
| 209 // at updateOutOfFlowContext() step. | 188 // at updateOutOfFlowContext() step. |
| 210 DCHECK(object.canContainAbsolutePositionObjects()); | 189 DCHECK(object.canContainAbsolutePositionObjects()); |
| 211 LayoutRect clipRect = toLayoutBox(object).clipRect(context.current.paint
Offset); | 190 LayoutRect clipRect = toLayoutBox(object).clipRect(context.current.paint
Offset); |
| 212 updateOrCreatePaintProperty<ClipPaintPropertyNode, &ObjectPaintPropertie
s::cssClip, &ObjectPaintProperties::setCssClip>( | 191 context.current.clip = object.getMutableForPainting().ensureObjectPaintP
roperties().createOrUpdateCssClip( |
| 213 object, context, context.current.clip, context.current.transform, Fl
oatRoundedRect(FloatRect(clipRect))); | 192 context.current.clip, context.current.transform, FloatRoundedRect(Fl
oatRect(clipRect))); |
| 214 return; | 193 return; |
| 215 } | 194 } |
| 216 clearPaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::setCssClip
>(object); | 195 |
| 196 if (ObjectPaintProperties* properties = object.getMutableForPainting().objec
tPaintProperties()) |
| 197 properties->clearCssClip(); |
| 217 } | 198 } |
| 218 | 199 |
| 219 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(const LayoutObject& o
bject, const PaintPropertyTreeBuilderContext& context) | 200 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(const LayoutObject& o
bject, const PaintPropertyTreeBuilderContext& context) |
| 220 { | 201 { |
| 221 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since
we don't need them at the moment. | 202 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since
we don't need them at the moment. |
| 222 if (!object.isBox() && !object.hasLayer()) | 203 if (!object.isBox() && !object.hasLayer()) |
| 223 return; | 204 return; |
| 224 | 205 |
| 225 std::unique_ptr<ObjectPaintProperties::LocalBorderBoxProperties> borderBoxCo
ntext = | 206 std::unique_ptr<ObjectPaintProperties::LocalBorderBoxProperties> borderBoxCo
ntext = |
| 226 wrapUnique(new ObjectPaintProperties::LocalBorderBoxProperties); | 207 wrapUnique(new ObjectPaintProperties::LocalBorderBoxProperties); |
| 227 borderBoxContext->paintOffset = context.current.paintOffset; | 208 borderBoxContext->paintOffset = context.current.paintOffset; |
| 228 borderBoxContext->propertyTreeState = PropertyTreeState(context.current.tran
sform, context.current.clip, context.currentEffect); | 209 borderBoxContext->propertyTreeState = PropertyTreeState(context.current.tran
sform, context.current.clip, context.currentEffect); |
| 229 object.getMutableForPainting().ensureObjectPaintProperties().setLocalBorderB
oxProperties(std::move(borderBoxContext)); | 210 object.getMutableForPainting().ensureObjectPaintProperties().setLocalBorderB
oxProperties(std::move(borderBoxContext)); |
| 230 } | 211 } |
| 231 | 212 |
| 232 // TODO(trchen): Remove this once we bake the paint offset into frameRect. | 213 // TODO(trchen): Remove this once we bake the paint offset into frameRect. |
| 233 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(const LayoutObject& ob
ject, const PaintPropertyTreeBuilderContext& context) | 214 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(const LayoutObject& ob
ject, const PaintPropertyTreeBuilderContext& context) |
| 234 { | 215 { |
| 235 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); | 216 IntPoint roundedPaintOffset = roundedIntPoint(context.current.paintOffset); |
| 236 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) { | 217 if (roundedPaintOffset != IntPoint() && object.isBoxModelObject()) { |
| 237 if (PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(ob
ject).getScrollableArea()) { | 218 if (PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(ob
ject).getScrollableArea()) { |
| 238 if (scrollableArea->horizontalScrollbar() || scrollableArea->vertica
lScrollbar()) { | 219 if (scrollableArea->horizontalScrollbar() || scrollableArea->vertica
lScrollbar()) { |
| 239 auto paintOffset = TransformationMatrix().translate(roundedPaint
Offset.x(), roundedPaintOffset.y()); | 220 auto paintOffset = TransformationMatrix().translate(roundedPaint
Offset.x(), roundedPaintOffset.y()); |
| 240 // Make a copy of context.current.transform because we don't wan
t to set the scrollbarPaintOffset node | 221 object.getMutableForPainting().ensureObjectPaintProperties().cre
ateOrUpdateScrollbarPaintOffset( |
| 241 // as the current transform. | 222 context.current.transform, paintOffset, FloatPoint3D()); |
| 242 TransformPaintPropertyNode* parentTransform = context.current.tr
ansform; | |
| 243 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectP
aintProperties::scrollbarPaintOffset, &ObjectPaintProperties::setScrollbarPaintO
ffset>( | |
| 244 object, context, parentTransform, paintOffset, FloatPoint3D(
)); | |
| 245 return; | 223 return; |
| 246 } | 224 } |
| 247 } | 225 } |
| 248 } | 226 } |
| 249 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setSc
rollbarPaintOffset>(object); | 227 |
| 228 if (ObjectPaintProperties* properties = object.getMutableForPainting().objec
tPaintProperties()) |
| 229 properties->clearScrollbarPaintOffset(); |
| 250 } | 230 } |
| 251 | 231 |
| 252 void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, Pa
intPropertyTreeBuilderContext& context) | 232 void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, Pa
intPropertyTreeBuilderContext& context) |
| 253 { | 233 { |
| 254 if (!object.isBox()) | 234 if (!object.isBox()) |
| 255 return; | 235 return; |
| 256 const LayoutBox& box = toLayoutBox(object); | 236 const LayoutBox& box = toLayoutBox(object); |
| 257 | 237 |
| 258 // The <input> elements can't have contents thus CSS overflow property doesn
't apply. | 238 // The <input> elements can't have contents thus CSS overflow property doesn
't apply. |
| 259 // However for layout purposes we do generate child layout objects for them,
e.g. button label. | 239 // However for layout purposes we do generate child layout objects for them,
e.g. button label. |
| 260 // We should clip the overflow from those children. This is called control c
lip and we | 240 // We should clip the overflow from those children. This is called control c
lip and we |
| 261 // technically treat them like overflow clip. | 241 // technically treat them like overflow clip. |
| 262 LayoutRect clipRect; | 242 LayoutRect clipRect; |
| 263 if (box.hasControlClip()) { | 243 if (box.hasControlClip()) { |
| 264 clipRect = box.controlClipRect(context.current.paintOffset); | 244 clipRect = box.controlClipRect(context.current.paintOffset); |
| 265 } else if (box.hasOverflowClip()) { | 245 } else if (box.hasOverflowClip()) { |
| 266 clipRect = box.overflowClipRect(context.current.paintOffset); | 246 clipRect = box.overflowClipRect(context.current.paintOffset); |
| 267 } else { | 247 } else { |
| 268 clearPaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::setOve
rflowClip>(object); | 248 if (ObjectPaintProperties* properties = object.getMutableForPainting().o
bjectPaintProperties()) |
| 249 properties->clearOverflowClip(); |
| 269 return; | 250 return; |
| 270 } | 251 } |
| 271 | 252 |
| 272 // This need to be in top-level block to hold the reference until we finish
creating the normal clip node. | 253 // This need to be in top-level block to hold the reference until we finish
creating the normal clip node. |
| 273 RefPtr<ClipPaintPropertyNode> borderRadiusClip; | 254 RefPtr<ClipPaintPropertyNode> borderRadiusClip; |
| 274 if (box.styleRef().hasBorderRadius()) { | 255 if (box.styleRef().hasBorderRadius()) { |
| 275 auto innerBorder = box.styleRef().getRoundedInnerBorderFor( | 256 auto innerBorder = box.styleRef().getRoundedInnerBorderFor( |
| 276 LayoutRect(context.current.paintOffset, box.size())); | 257 LayoutRect(context.current.paintOffset, box.size())); |
| 277 borderRadiusClip = ClipPaintPropertyNode::create(context.current.clip, c
ontext.current.transform, innerBorder); | 258 borderRadiusClip = ClipPaintPropertyNode::create(context.current.clip, c
ontext.current.transform, innerBorder); |
| 278 context.current.clip = borderRadiusClip.get(); | 259 context.current.clip = borderRadiusClip.get(); |
| 279 } | 260 } |
| 280 | 261 |
| 281 updateOrCreatePaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::o
verflowClip, &ObjectPaintProperties::setOverflowClip>( | 262 context.current.clip = object.getMutableForPainting().ensureObjectPaintPrope
rties().createOrUpdateOverflowClip( |
| 282 object, context, context.current.clip, context.current.transform, FloatR
oundedRect(FloatRect(clipRect))); | 263 context.current.clip, context.current.transform, FloatRoundedRect(FloatR
ect(clipRect))); |
| 283 } | 264 } |
| 284 | 265 |
| 285 static FloatPoint perspectiveOrigin(const LayoutBox& box) | 266 static FloatPoint perspectiveOrigin(const LayoutBox& box) |
| 286 { | 267 { |
| 287 const ComputedStyle& style = box.styleRef(); | 268 const ComputedStyle& style = box.styleRef(); |
| 288 FloatSize borderBoxSize(box.size()); | 269 FloatSize borderBoxSize(box.size()); |
| 289 return FloatPoint( | 270 return FloatPoint( |
| 290 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), | 271 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), |
| 291 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()))
; | 272 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()))
; |
| 292 } | 273 } |
| 293 | 274 |
| 294 void PaintPropertyTreeBuilder::updatePerspective(const LayoutObject& object, Pai
ntPropertyTreeBuilderContext& context) | 275 void PaintPropertyTreeBuilder::updatePerspective(const LayoutObject& object, Pai
ntPropertyTreeBuilderContext& context) |
| 295 { | 276 { |
| 296 const ComputedStyle& style = object.styleRef(); | 277 const ComputedStyle& style = object.styleRef(); |
| 297 if (!object.isBox() || !style.hasPerspective()) { | 278 if (!object.isBox() || !style.hasPerspective()) { |
| 298 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::s
etPerspective>(object); | 279 if (ObjectPaintProperties* properties = object.getMutableForPainting().o
bjectPaintProperties()) |
| 280 properties->clearPerspective(); |
| 299 return; | 281 return; |
| 300 } | 282 } |
| 301 | 283 |
| 302 // The perspective node must not flatten (else nothing will get | 284 // The perspective node must not flatten (else nothing will get |
| 303 // perspective), but it should still extend the rendering context as most | 285 // perspective), but it should still extend the rendering context as most |
| 304 // transform nodes do. | 286 // transform nodes do. |
| 305 TransformationMatrix matrix = TransformationMatrix().applyPerspective(style.
perspective()); | 287 TransformationMatrix matrix = TransformationMatrix().applyPerspective(style.
perspective()); |
| 306 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(
context.current.paintOffset); | 288 FloatPoint3D origin = perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(
context.current.paintOffset); |
| 307 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperti
es::perspective, &ObjectPaintProperties::setPerspective>( | 289 context.current.transform = object.getMutableForPainting().ensureObjectPaint
Properties().createOrUpdatePerspective( |
| 308 object, context, context.current.transform, matrix, origin, context.curr
ent.shouldFlattenInheritedTransform, context.current.renderingContextID); | 290 context.current.transform, matrix, origin, context.current.shouldFlatten
InheritedTransform, context.current.renderingContextID); |
| 309 context.current.shouldFlattenInheritedTransform = false; | 291 context.current.shouldFlattenInheritedTransform = false; |
| 310 } | 292 } |
| 311 | 293 |
| 312 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutOb
ject& object, PaintPropertyTreeBuilderContext& context) | 294 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform(const LayoutOb
ject& object, PaintPropertyTreeBuilderContext& context) |
| 313 { | 295 { |
| 314 if (!object.isSVGRoot()) | 296 if (!object.isSVGRoot()) |
| 315 return; | 297 return; |
| 316 | 298 |
| 317 AffineTransform transformToBorderBox = SVGRootPainter(toLayoutSVGRoot(object
)).transformToPixelSnappedBorderBox(context.current.paintOffset); | 299 AffineTransform transformToBorderBox = SVGRootPainter(toLayoutSVGRoot(object
)).transformToPixelSnappedBorderBox(context.current.paintOffset); |
| 318 | 300 |
| 319 // The paint offset is included in |transformToBorderBox| so SVG does not ne
ed to handle paint | 301 // The paint offset is included in |transformToBorderBox| so SVG does not ne
ed to handle paint |
| 320 // offset internally. | 302 // offset internally. |
| 321 context.current.paintOffset = LayoutPoint(); | 303 context.current.paintOffset = LayoutPoint(); |
| 322 | 304 |
| 323 if (transformToBorderBox.isIdentity()) { | 305 if (transformToBorderBox.isIdentity()) { |
| 324 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::s
etSvgLocalToBorderBoxTransform>(object); | 306 if (ObjectPaintProperties* properties = object.getMutableForPainting().o
bjectPaintProperties()) |
| 307 properties->clearSvgLocalToBorderBoxTransform(); |
| 325 return; | 308 return; |
| 326 } | 309 } |
| 327 | 310 |
| 328 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaintProperti
es::svgLocalToBorderBoxTransform, &ObjectPaintProperties::setSvgLocalToBorderBox
Transform>( | 311 context.current.transform = object.getMutableForPainting().ensureObjectPaint
Properties().createOrUpdateSvgLocalToBorderBoxTransform( |
| 329 object, context, context.current.transform, transformToBorderBox, FloatP
oint3D()); | 312 context.current.transform, transformToBorderBox, FloatPoint3D()); |
| 330 context.current.shouldFlattenInheritedTransform = false; | 313 context.current.shouldFlattenInheritedTransform = false; |
| 331 context.current.renderingContextID = 0; | 314 context.current.renderingContextID = 0; |
| 332 } | 315 } |
| 333 | 316 |
| 334 void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& objec
t, PaintPropertyTreeBuilderContext& context) | 317 void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& objec
t, PaintPropertyTreeBuilderContext& context) |
| 335 { | 318 { |
| 336 if (object.isBoxModelObject() && object.hasOverflowClip()) { | 319 if (object.isBoxModelObject() && object.hasOverflowClip()) { |
| 337 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 320 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 338 DCHECK(layer); | 321 DCHECK(layer); |
| 339 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); | 322 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); |
| 340 | 323 |
| 341 if (!scrollOffset.isZero() || layer->scrollsOverflow()) { | 324 if (!scrollOffset.isZero() || layer->scrollsOverflow()) { |
| 342 TransformationMatrix matrix = TransformationMatrix().translate(-scro
llOffset.width(), -scrollOffset.height()); | 325 TransformationMatrix matrix = TransformationMatrix().translate(-scro
llOffset.width(), -scrollOffset.height()); |
| 343 updateOrCreatePaintProperty<TransformPaintPropertyNode, &ObjectPaint
Properties::scrollTranslation, &ObjectPaintProperties::setScrollTranslation>( | 326 context.current.transform = object.getMutableForPainting().ensureObj
ectPaintProperties().createOrUpdateScrollTranslation( |
| 344 object, context, context.current.transform, matrix, FloatPoint3D
(), context.current.shouldFlattenInheritedTransform, context.current.renderingCo
ntextID); | 327 context.current.transform, matrix, FloatPoint3D(), context.curre
nt.shouldFlattenInheritedTransform, context.current.renderingContextID); |
| 345 context.current.shouldFlattenInheritedTransform = false; | 328 context.current.shouldFlattenInheritedTransform = false; |
| 346 return; | 329 return; |
| 347 } | 330 } |
| 348 } | 331 } |
| 349 clearPaintProperty<TransformPaintPropertyNode, &ObjectPaintProperties::setSc
rollTranslation>(object); | 332 |
| 333 if (ObjectPaintProperties* properties = object.getMutableForPainting().objec
tPaintProperties()) |
| 334 properties->clearScrollTranslation(); |
| 350 } | 335 } |
| 351 | 336 |
| 352 void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object
, PaintPropertyTreeBuilderContext& context) | 337 void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object
, PaintPropertyTreeBuilderContext& context) |
| 353 { | 338 { |
| 354 if (object.canContainAbsolutePositionObjects()) { | 339 if (object.canContainAbsolutePositionObjects()) { |
| 355 context.absolutePosition = context.current; | 340 context.absolutePosition = context.current; |
| 356 context.containerForAbsolutePosition = &object; | 341 context.containerForAbsolutePosition = &object; |
| 357 } | 342 } |
| 358 | 343 |
| 359 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram
eView | 344 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram
eView |
| 360 // paint properties for rootLayerScrolls. | 345 // paint properties for rootLayerScrolls. |
| 361 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) { | 346 if (!object.isLayoutView() && object.canContainFixedPositionObjects()) { |
| 362 context.fixedPosition = context.current; | 347 context.fixedPosition = context.current; |
| 363 } else if (object.objectPaintProperties() && object.objectPaintProperties()-
>cssClip()) { | 348 } else if (object.getMutableForPainting().objectPaintProperties() && object.
objectPaintProperties()->cssClip()) { |
| 364 // CSS clip applies to all descendants, even if this object is not a con
taining block | 349 // CSS clip applies to all descendants, even if this object is not a con
taining block |
| 365 // ancestor of the descendant. It is okay for absolute-position descenda
nts because | 350 // ancestor of the descendant. It is okay for absolute-position descenda
nts because |
| 366 // having CSS clip implies being absolute position container. However fo
r fixed-position | 351 // having CSS clip implies being absolute position container. However fo
r fixed-position |
| 367 // descendants we need to insert the clip here if we are not a containin
g block ancestor | 352 // descendants we need to insert the clip here if we are not a containin
g block ancestor |
| 368 // of them. | 353 // of them. |
| 369 auto* cssClip = object.objectPaintProperties()->cssClip(); | 354 auto* cssClip = object.getMutableForPainting().objectPaintProperties()->
cssClip(); |
| 370 | 355 |
| 371 // Before we actually create anything, check whether in-flow context and
fixed-position | 356 // Before we actually create anything, check whether in-flow context and
fixed-position |
| 372 // context has exactly the same clip. Reuse if possible. | 357 // context has exactly the same clip. Reuse if possible. |
| 373 if (context.fixedPosition.clip == cssClip->parent()) { | 358 if (context.fixedPosition.clip == cssClip->parent()) { |
| 374 context.fixedPosition.clip = cssClip; | 359 context.fixedPosition.clip = cssClip; |
| 375 } else { | 360 } else { |
| 376 updateOrCreatePaintProperty<ClipPaintPropertyNode, &ObjectPaintPrope
rties::cssClipFixedPosition, &ObjectPaintProperties::setCssClipFixedPosition>( | 361 context.fixedPosition.clip = object.getMutableForPainting().ensureOb
jectPaintProperties().createOrUpdateCssClipFixedPosition( |
| 377 object, context, context.fixedPosition.clip, const_cast<Transfor
mPaintPropertyNode*>(cssClip->localTransformSpace()), cssClip->clipRect()); | 362 context.fixedPosition.clip, const_cast<TransformPaintPropertyNod
e*>(cssClip->localTransformSpace()), cssClip->clipRect()); |
| 378 return; | 363 return; |
| 379 } | 364 } |
| 380 } | 365 } |
| 381 clearPaintProperty<ClipPaintPropertyNode, &ObjectPaintProperties::setCssClip
FixedPosition>(object); | 366 |
| 367 if (ObjectPaintProperties* properties = object.getMutableForPainting().objec
tPaintProperties()) |
| 368 properties->clearCssClipFixedPosition(); |
| 382 } | 369 } |
| 383 | 370 |
| 384 static void deriveBorderBoxFromContainerContext(const LayoutObject& object, Pain
tPropertyTreeBuilderContext& context) | 371 static void deriveBorderBoxFromContainerContext(const LayoutObject& object, Pain
tPropertyTreeBuilderContext& context) |
| 385 { | 372 { |
| 386 if (!object.isBoxModelObject()) | 373 if (!object.isBoxModelObject()) |
| 387 return; | 374 return; |
| 388 | 375 |
| 389 const LayoutBoxModelObject& boxModelObject = toLayoutBoxModelObject(object); | 376 const LayoutBoxModelObject& boxModelObject = toLayoutBoxModelObject(object); |
| 390 | 377 |
| 391 switch (object.styleRef().position()) { | 378 switch (object.styleRef().position()) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 updateLocalBorderBoxContext(object, context); | 431 updateLocalBorderBoxContext(object, context); |
| 445 updateScrollbarPaintOffset(object, context); | 432 updateScrollbarPaintOffset(object, context); |
| 446 updateOverflowClip(object, context); | 433 updateOverflowClip(object, context); |
| 447 updatePerspective(object, context); | 434 updatePerspective(object, context); |
| 448 updateSvgLocalToBorderBoxTransform(object, context); | 435 updateSvgLocalToBorderBoxTransform(object, context); |
| 449 updateScrollTranslation(object, context); | 436 updateScrollTranslation(object, context); |
| 450 updateOutOfFlowContext(object, context); | 437 updateOutOfFlowContext(object, context); |
| 451 } | 438 } |
| 452 | 439 |
| 453 } // namespace blink | 440 } // namespace blink |
| OLD | NEW |