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 |