| 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/paint/ObjectPaintProperties.h" | 12 #include "core/paint/ObjectPaintProperties.h" |
| 13 #include "core/paint/PaintLayer.h" | 13 #include "core/paint/PaintLayer.h" |
| 14 #include "platform/graphics/paint/ClipPaintPropertyNode.h" | |
| 15 #include "platform/graphics/paint/TransformPaintPropertyNode.h" | |
| 16 #include "platform/transforms/TransformationMatrix.h" | 14 #include "platform/transforms/TransformationMatrix.h" |
| 17 | 15 |
| 18 namespace blink { | 16 namespace blink { |
| 19 | 17 |
| 20 // The context for layout tree walk. | 18 void PaintPropertyTreeBuilder::buildTreeRootNodes(FrameView& rootFrame, PaintPro
pertyTreeBuilderRootContext& rootContext) |
| 21 // The walk will be done in the primary tree order (= DOM order), thus the conte
xt will also be | |
| 22 // responsible for bookkeeping tree state in other order, for example, the most
recent position | |
| 23 // container seen. | |
| 24 struct PaintPropertyTreeBuilderContext { | |
| 25 PaintPropertyTreeBuilderContext() | |
| 26 : currentTransform(nullptr) | |
| 27 , currentClip(nullptr) | |
| 28 , transformForAbsolutePosition(nullptr) | |
| 29 , containerForAbsolutePosition(nullptr) | |
| 30 , clipForAbsolutePosition(nullptr) | |
| 31 , transformForFixedPosition(nullptr) | |
| 32 , clipForFixedPosition(nullptr) | |
| 33 , currentEffect(nullptr) { } | |
| 34 | |
| 35 // The combination of a transform and paint offset describes a linear space. | |
| 36 // When a layout object recur to its children, the main context is expected
to refer | |
| 37 // the object's border box, then the callee will derive its own border box b
y translating | |
| 38 // the space with its own layout location. | |
| 39 TransformPaintPropertyNode* currentTransform; | |
| 40 LayoutPoint paintOffset; | |
| 41 // The clip node describes the accumulated raster clip for the current subtr
ee. | |
| 42 // Note that the computed raster region in canvas space for a clip node is i
ndependent from | |
| 43 // the transform and paint offset above. Also the actual raster region may b
e affected | |
| 44 // by layerization and occlusion tracking. | |
| 45 ClipPaintPropertyNode* currentClip; | |
| 46 | |
| 47 // Separate context for out-of-flow positioned and fixed positioned elements
are needed | |
| 48 // because they don't use DOM parent as their containing block. | |
| 49 // These additional contexts normally pass through untouched, and are only c
opied from | |
| 50 // the main context when the current element serves as the containing block
of corresponding | |
| 51 // positioned descendants. | |
| 52 // Overflow clips are also inherited by containing block tree instead of DOM
tree, thus they | |
| 53 // are included in the additional context too. | |
| 54 TransformPaintPropertyNode* transformForAbsolutePosition; | |
| 55 LayoutPoint paintOffsetForAbsolutePosition; | |
| 56 LayoutObject* containerForAbsolutePosition; | |
| 57 ClipPaintPropertyNode* clipForAbsolutePosition; | |
| 58 | |
| 59 TransformPaintPropertyNode* transformForFixedPosition; | |
| 60 LayoutPoint paintOffsetForFixedPosition; | |
| 61 ClipPaintPropertyNode* clipForFixedPosition; | |
| 62 | |
| 63 // The effect hierarchy is applied by the stacking context tree. It is guara
nteed that every | |
| 64 // DOM descendant is also a stacking context descendant. Therefore, we don't
need extra | |
| 65 // bookkeeping for effect nodes and can generate the effect tree from a DOM-
order traversal. | |
| 66 EffectPaintPropertyNode* currentEffect; | |
| 67 }; | |
| 68 | |
| 69 void PaintPropertyTreeBuilder::buildPropertyTrees(FrameView& rootFrame) | |
| 70 { | 19 { |
| 71 PaintPropertyTreeBuilderContext rootContext; | |
| 72 | |
| 73 // We don't retain permanent reference of these nodes except by child nodes. | |
| 74 // Keeps local reference until the walk finishes. | |
| 75 RefPtr<TransformPaintPropertyNode> transformRoot; | |
| 76 RefPtr<ClipPaintPropertyNode> clipRoot; | |
| 77 RefPtr<EffectPaintPropertyNode> effectRoot; | |
| 78 | |
| 79 // Only create extra root clip and transform nodes when RLS is enabled, beca
use the main frame | 20 // Only create extra root clip and transform nodes when RLS is enabled, beca
use the main frame |
| 80 // unconditionally create frame translation / clip nodes otherwise. | 21 // unconditionally create frame translation / clip nodes otherwise. |
| 81 if (rootFrame.frame().settings() && rootFrame.frame().settings()->rootLayerS
crolls()) { | 22 if (rootFrame.frame().settings() && rootFrame.frame().settings()->rootLayerS
crolls()) { |
| 82 transformRoot = TransformPaintPropertyNode::create(TransformationMatrix(
), FloatPoint3D(), nullptr); | 23 rootContext.transformRoot = TransformPaintPropertyNode::create(Transform
ationMatrix(), FloatPoint3D(), nullptr); |
| 83 rootContext.currentTransform = rootContext.transformForAbsolutePosition
= rootContext.transformForFixedPosition = transformRoot.get(); | 24 rootContext.currentTransform = rootContext.transformForAbsolutePosition
= rootContext.transformForFixedPosition = rootContext.transformRoot.get(); |
| 84 | 25 |
| 85 clipRoot = ClipPaintPropertyNode::create(transformRoot, FloatRoundedRect
(LayoutRect::infiniteIntRect()), nullptr); | 26 rootContext.clipRoot = ClipPaintPropertyNode::create(rootContext.transfo
rmRoot, FloatRoundedRect(LayoutRect::infiniteIntRect()), nullptr); |
| 86 rootContext.currentClip = rootContext.clipForAbsolutePosition = rootCont
ext.clipForFixedPosition = clipRoot.get(); | 27 rootContext.currentClip = rootContext.clipForAbsolutePosition = rootCont
ext.clipForFixedPosition = rootContext.clipRoot.get(); |
| 87 } | 28 } |
| 88 | 29 |
| 89 // The root frame never creates effect node so we unconditionally create a r
oot node here. | 30 // The root frame never creates effect node so we unconditionally create a r
oot node here. |
| 90 effectRoot = EffectPaintPropertyNode::create(1.0, nullptr); | 31 rootContext.effectRoot = EffectPaintPropertyNode::create(1.0, nullptr); |
| 91 rootContext.currentEffect = effectRoot.get(); | 32 rootContext.currentEffect = rootContext.effectRoot.get(); |
| 92 | |
| 93 walk(rootFrame, rootContext); | |
| 94 } | 33 } |
| 95 | 34 |
| 96 void PaintPropertyTreeBuilder::walk(FrameView& frameView, const PaintPropertyTre
eBuilderContext& context) | 35 void PaintPropertyTreeBuilder::buildTreeNodes(FrameView& frameView, PaintPropert
yTreeBuilderContext& context) |
| 97 { | 36 { |
| 98 PaintPropertyTreeBuilderContext localContext(context); | |
| 99 | |
| 100 // TODO(pdr): Creating paint properties for FrameView here will not be | 37 // TODO(pdr): Creating paint properties for FrameView here will not be |
| 101 // needed once settings()->rootLayerScrolls() is enabled. | 38 // needed once settings()->rootLayerScrolls() is enabled. |
| 102 // TODO(pdr): Make this conditional on the rootLayerScrolls setting. | 39 // TODO(pdr): Make this conditional on the rootLayerScrolls setting. |
| 103 | 40 |
| 104 TransformationMatrix frameTranslate; | 41 TransformationMatrix frameTranslate; |
| 105 frameTranslate.translate(frameView.x() + context.paintOffset.x(), frameView.
y() + context.paintOffset.y()); | 42 frameTranslate.translate(frameView.x() + context.paintOffset.x(), frameView.
y() + context.paintOffset.y()); |
| 106 RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation = Trans
formPaintPropertyNode::create(frameTranslate, FloatPoint3D(), context.currentTra
nsform); | 43 RefPtr<TransformPaintPropertyNode> newTransformNodeForPreTranslation = Trans
formPaintPropertyNode::create(frameTranslate, FloatPoint3D(), context.currentTra
nsform); |
| 107 localContext.transformForFixedPosition = newTransformNodeForPreTranslation.g
et(); | 44 context.transformForFixedPosition = newTransformNodeForPreTranslation.get(); |
| 108 localContext.paintOffsetForFixedPosition = LayoutPoint(); | 45 context.paintOffsetForFixedPosition = LayoutPoint(); |
| 109 | 46 |
| 110 FloatRoundedRect contentClip(IntRect(IntPoint(), frameView.visibleContentSiz
e())); | 47 FloatRoundedRect contentClip(IntRect(IntPoint(), frameView.visibleContentSiz
e())); |
| 111 RefPtr<ClipPaintPropertyNode> newClipNodeForContentClip = ClipPaintPropertyN
ode::create(newTransformNodeForPreTranslation.get(), contentClip, localContext.c
urrentClip); | 48 RefPtr<ClipPaintPropertyNode> newClipNodeForContentClip = ClipPaintPropertyN
ode::create(newTransformNodeForPreTranslation.get(), contentClip, context.curren
tClip); |
| 112 localContext.currentClip = localContext.clipForAbsolutePosition = localConte
xt.clipForFixedPosition = newClipNodeForContentClip.get(); | 49 context.currentClip = context.clipForAbsolutePosition = context.clipForFixed
Position = newClipNodeForContentClip.get(); |
| 113 | 50 |
| 114 DoubleSize scrollOffset = frameView.scrollOffsetDouble(); | 51 DoubleSize scrollOffset = frameView.scrollOffsetDouble(); |
| 115 TransformationMatrix frameScroll; | 52 TransformationMatrix frameScroll; |
| 116 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); | 53 frameScroll.translate(-scrollOffset.width(), -scrollOffset.height()); |
| 117 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr
ansformPaintPropertyNode::create(frameScroll, FloatPoint3D(), newTransformNodeFo
rPreTranslation); | 54 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr
ansformPaintPropertyNode::create(frameScroll, FloatPoint3D(), newTransformNodeFo
rPreTranslation); |
| 118 localContext.currentTransform = localContext.transformForAbsolutePosition =
newTransformNodeForScrollTranslation.get(); | 55 context.currentTransform = context.transformForAbsolutePosition = newTransfo
rmNodeForScrollTranslation.get(); |
| 119 localContext.paintOffset = LayoutPoint(); | 56 context.paintOffset = LayoutPoint(); |
| 120 localContext.paintOffsetForAbsolutePosition = LayoutPoint(); | 57 context.paintOffsetForAbsolutePosition = LayoutPoint(); |
| 121 localContext.containerForAbsolutePosition = nullptr; | 58 context.containerForAbsolutePosition = nullptr; |
| 122 | 59 |
| 123 frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); | 60 frameView.setPreTranslation(newTransformNodeForPreTranslation.release()); |
| 124 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release(
)); | 61 frameView.setScrollTranslation(newTransformNodeForScrollTranslation.release(
)); |
| 125 frameView.setContentClip(newClipNodeForContentClip.release()); | 62 frameView.setContentClip(newClipNodeForContentClip.release()); |
| 126 | |
| 127 if (LayoutView* layoutView = frameView.layoutView()) | |
| 128 walk(*layoutView, localContext); | |
| 129 } | 63 } |
| 130 | 64 |
| 131 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(LayoutObject& object
, PaintPropertyTreeBuilderContext& context) | 65 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation(const LayoutObject&
object, PaintPropertyTreeBuilderContext& context) |
| 132 { | 66 { |
| 133 bool shouldCreatePaintOffsetTranslationNode = false; | 67 bool shouldCreatePaintOffsetTranslationNode = false; |
| 134 if (object.isSVGRoot()) { | 68 if (object.isSVGRoot()) { |
| 135 // SVG doesn't use paint offset internally so emit a paint offset at the
html->svg boundary. | 69 // SVG doesn't use paint offset internally so emit a paint offset at the
html->svg boundary. |
| 136 shouldCreatePaintOffsetTranslationNode = true; | 70 shouldCreatePaintOffsetTranslationNode = true; |
| 137 } else if (object.isBoxModelObject()) { | 71 } else if (object.isBoxModelObject()) { |
| 138 // TODO(trchen): Eliminate PaintLayer dependency. | 72 // TODO(trchen): Eliminate PaintLayer dependency. |
| 139 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 73 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 140 shouldCreatePaintOffsetTranslationNode = layer && layer->paintsWithTrans
form(GlobalPaintNormalPhase); | 74 shouldCreatePaintOffsetTranslationNode = layer && layer->paintsWithTrans
form(GlobalPaintNormalPhase); |
| 141 } | 75 } |
| 142 | 76 |
| 143 if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslat
ionNode) | 77 if (context.paintOffset == LayoutPoint() || !shouldCreatePaintOffsetTranslat
ionNode) |
| 144 return; | 78 return; |
| 145 | 79 |
| 146 RefPtr<TransformPaintPropertyNode> paintOffsetTranslation = TransformPaintPr
opertyNode::create( | 80 RefPtr<TransformPaintPropertyNode> paintOffsetTranslation = TransformPaintPr
opertyNode::create( |
| 147 TransformationMatrix().translate(context.paintOffset.x(), context.paintO
ffset.y()), | 81 TransformationMatrix().translate(context.paintOffset.x(), context.paintO
ffset.y()), |
| 148 FloatPoint3D(), context.currentTransform); | 82 FloatPoint3D(), context.currentTransform); |
| 149 context.currentTransform = paintOffsetTranslation.get(); | 83 context.currentTransform = paintOffsetTranslation.get(); |
| 150 context.paintOffset = LayoutPoint(); | 84 context.paintOffset = LayoutPoint(); |
| 151 object.ensureObjectPaintProperties().setPaintOffsetTranslation(paintOffsetTr
anslation.release()); | 85 object.getMutableForPainting().ensureObjectPaintProperties().setPaintOffsetT
ranslation(paintOffsetTranslation.release()); |
| 152 } | 86 } |
| 153 | 87 |
| 154 static FloatPoint3D transformOrigin(const LayoutBox& box) | 88 static FloatPoint3D transformOrigin(const LayoutBox& box) |
| 155 { | 89 { |
| 156 const ComputedStyle& style = box.styleRef(); | 90 const ComputedStyle& style = box.styleRef(); |
| 157 FloatSize borderBoxSize(box.size()); | 91 FloatSize borderBoxSize(box.size()); |
| 158 return FloatPoint3D( | 92 return FloatPoint3D( |
| 159 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), | 93 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), |
| 160 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), | 94 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), |
| 161 style.transformOriginZ()); | 95 style.transformOriginZ()); |
| 162 } | 96 } |
| 163 | 97 |
| 164 void PaintPropertyTreeBuilder::updateTransform(LayoutObject& object, PaintProper
tyTreeBuilderContext& context) | 98 void PaintPropertyTreeBuilder::updateTransform(const LayoutObject& object, Paint
PropertyTreeBuilderContext& context) |
| 165 { | 99 { |
| 166 const ComputedStyle& style = object.styleRef(); | 100 const ComputedStyle& style = object.styleRef(); |
| 167 if (!object.isBox() || !style.hasTransform()) | 101 if (!object.isBox() || !style.hasTransform()) |
| 168 return; | 102 return; |
| 169 ASSERT(context.paintOffset == LayoutPoint()); | 103 ASSERT(context.paintOffset == LayoutPoint()); |
| 170 | 104 |
| 171 TransformationMatrix matrix; | 105 TransformationMatrix matrix; |
| 172 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl
udeTransformOrigin, | 106 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl
udeTransformOrigin, |
| 173 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans
formProperties); | 107 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans
formProperties); |
| 174 RefPtr<TransformPaintPropertyNode> transformNode = TransformPaintPropertyNod
e::create( | 108 RefPtr<TransformPaintPropertyNode> transformNode = TransformPaintPropertyNod
e::create( |
| 175 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); | 109 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); |
| 176 context.currentTransform = transformNode.get(); | 110 context.currentTransform = transformNode.get(); |
| 177 object.ensureObjectPaintProperties().setTransform(transformNode.release()); | 111 object.getMutableForPainting().ensureObjectPaintProperties().setTransform(tr
ansformNode.release()); |
| 178 } | 112 } |
| 179 | 113 |
| 180 void PaintPropertyTreeBuilder::updateEffect(LayoutObject& object, PaintPropertyT
reeBuilderContext& context) | 114 void PaintPropertyTreeBuilder::updateEffect(const LayoutObject& object, PaintPro
pertyTreeBuilderContext& context) |
| 181 { | 115 { |
| 182 if (!object.styleRef().hasOpacity()) | 116 if (!object.styleRef().hasOpacity()) |
| 183 return; | 117 return; |
| 184 RefPtr<EffectPaintPropertyNode> effectNode = EffectPaintPropertyNode::create
(object.styleRef().opacity(), context.currentEffect); | 118 RefPtr<EffectPaintPropertyNode> effectNode = EffectPaintPropertyNode::create
(object.styleRef().opacity(), context.currentEffect); |
| 185 context.currentEffect = effectNode.get(); | 119 context.currentEffect = effectNode.get(); |
| 186 object.ensureObjectPaintProperties().setEffect(effectNode.release()); | 120 object.getMutableForPainting().ensureObjectPaintProperties().setEffect(effec
tNode.release()); |
| 187 } | 121 } |
| 188 | 122 |
| 189 void PaintPropertyTreeBuilder::updateCssClip(LayoutObject& object, PaintProperty
TreeBuilderContext& context) | 123 void PaintPropertyTreeBuilder::updateCssClip(const LayoutObject& object, PaintPr
opertyTreeBuilderContext& context) |
| 190 { | 124 { |
| 191 if (!object.hasClip()) | 125 if (!object.hasClip()) |
| 192 return; | 126 return; |
| 193 ASSERT(object.canContainAbsolutePositionObjects()); | 127 ASSERT(object.canContainAbsolutePositionObjects()); |
| 194 | 128 |
| 195 // Create clip node for descendants that are not fixed position. | 129 // Create clip node for descendants that are not fixed position. |
| 196 // We don't have to setup context.clipForAbsolutePosition here because this
object must be | 130 // We don't have to setup context.clipForAbsolutePosition here because this
object must be |
| 197 // a container for absolute position descendants, and will copy from in-flow
context later | 131 // a container for absolute position descendants, and will copy from in-flow
context later |
| 198 // at updateOutOfFlowContext() step. | 132 // at updateOutOfFlowContext() step. |
| 199 LayoutRect clipRect = toLayoutBox(object).clipRect(context.paintOffset); | 133 LayoutRect clipRect = toLayoutBox(object).clipRect(context.paintOffset); |
| 200 RefPtr<ClipPaintPropertyNode> clipNode = ClipPaintPropertyNode::create( | 134 RefPtr<ClipPaintPropertyNode> clipNode = ClipPaintPropertyNode::create( |
| 201 context.currentTransform, | 135 context.currentTransform, |
| 202 FloatRoundedRect(FloatRect(clipRect)), | 136 FloatRoundedRect(FloatRect(clipRect)), |
| 203 context.currentClip); | 137 context.currentClip); |
| 204 context.currentClip = clipNode.get(); | 138 context.currentClip = clipNode.get(); |
| 205 object.ensureObjectPaintProperties().setCssClip(clipNode.release()); | 139 object.getMutableForPainting().ensureObjectPaintProperties().setCssClip(clip
Node.release()); |
| 206 } | 140 } |
| 207 | 141 |
| 208 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(LayoutObject& object,
const PaintPropertyTreeBuilderContext& context) | 142 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext(const LayoutObject& o
bject, const PaintPropertyTreeBuilderContext& context) |
| 209 { | 143 { |
| 210 // Note: Currently only layer painter makes use of the pre-computed context. | 144 // Note: Currently only layer painter makes use of the pre-computed context. |
| 211 // This condition may be loosened with no adverse effects beside memory use. | 145 // This condition may be loosened with no adverse effects beside memory use. |
| 212 if (!object.hasLayer()) | 146 if (!object.hasLayer()) |
| 213 return; | 147 return; |
| 214 | 148 |
| 215 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> borderBoxContext = | 149 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> borderBoxContext = |
| 216 adoptPtr(new ObjectPaintProperties::LocalBorderBoxProperties); | 150 adoptPtr(new ObjectPaintProperties::LocalBorderBoxProperties); |
| 217 borderBoxContext->paintOffset = context.paintOffset; | 151 borderBoxContext->paintOffset = context.paintOffset; |
| 218 borderBoxContext->transform = context.currentTransform; | 152 borderBoxContext->transform = context.currentTransform; |
| 219 borderBoxContext->clip = context.currentClip; | 153 borderBoxContext->clip = context.currentClip; |
| 220 borderBoxContext->effect = context.currentEffect; | 154 borderBoxContext->effect = context.currentEffect; |
| 221 object.ensureObjectPaintProperties().setLocalBorderBoxProperties(std::move(b
orderBoxContext)); | 155 object.getMutableForPainting().ensureObjectPaintProperties().setLocalBorderB
oxProperties(std::move(borderBoxContext)); |
| 222 } | 156 } |
| 223 | 157 |
| 224 // TODO(trchen): Remove this once we bake the paint offset into frameRect. | 158 // TODO(trchen): Remove this once we bake the paint offset into frameRect. |
| 225 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(LayoutObject& object,
const PaintPropertyTreeBuilderContext& context) | 159 void PaintPropertyTreeBuilder::updateScrollbarPaintOffset(const LayoutObject& ob
ject, const PaintPropertyTreeBuilderContext& context) |
| 226 { | 160 { |
| 227 IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); | 161 IntPoint roundedPaintOffset = roundedIntPoint(context.paintOffset); |
| 228 if (roundedPaintOffset == IntPoint()) | 162 if (roundedPaintOffset == IntPoint()) |
| 229 return; | 163 return; |
| 230 | 164 |
| 231 if (!object.isBoxModelObject()) | 165 if (!object.isBoxModelObject()) |
| 232 return; | 166 return; |
| 233 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge
tScrollableArea(); | 167 PaintLayerScrollableArea* scrollableArea = toLayoutBoxModelObject(object).ge
tScrollableArea(); |
| 234 if (!scrollableArea) | 168 if (!scrollableArea) |
| 235 return; | 169 return; |
| 236 if (!scrollableArea->horizontalScrollbar() && !scrollableArea->verticalScrol
lbar()) | 170 if (!scrollableArea->horizontalScrollbar() && !scrollableArea->verticalScrol
lbar()) |
| 237 return; | 171 return; |
| 238 | 172 |
| 239 auto paintOffset = TransformationMatrix().translate(roundedPaintOffset.x(),
roundedPaintOffset.y()); | 173 auto paintOffset = TransformationMatrix().translate(roundedPaintOffset.x(),
roundedPaintOffset.y()); |
| 240 object.ensureObjectPaintProperties().setScrollbarPaintOffset( | 174 object.getMutableForPainting().ensureObjectPaintProperties().setScrollbarPai
ntOffset( |
| 241 TransformPaintPropertyNode::create(paintOffset, FloatPoint3D(), context.
currentTransform)); | 175 TransformPaintPropertyNode::create(paintOffset, FloatPoint3D(), context.
currentTransform)); |
| 242 } | 176 } |
| 243 | 177 |
| 244 void PaintPropertyTreeBuilder::updateOverflowClip(LayoutObject& object, PaintPro
pertyTreeBuilderContext& context) | 178 void PaintPropertyTreeBuilder::updateOverflowClip(const LayoutObject& object, Pa
intPropertyTreeBuilderContext& context) |
| 245 { | 179 { |
| 246 if (!object.isBox()) | 180 if (!object.isBox()) |
| 247 return; | 181 return; |
| 248 const LayoutBox& box = toLayoutBox(object); | 182 const LayoutBox& box = toLayoutBox(object); |
| 249 | 183 |
| 250 // The <input> elements can't have contents thus CSS overflow property doesn
't apply. | 184 // The <input> elements can't have contents thus CSS overflow property doesn
't apply. |
| 251 // However for layout purposes we do generate child layout objects for them,
e.g. button label. | 185 // However for layout purposes we do generate child layout objects for them,
e.g. button label. |
| 252 // We should clip the overflow from those children. This is called control c
lip and we | 186 // We should clip the overflow from those children. This is called control c
lip and we |
| 253 // technically treat them like overflow clip. | 187 // technically treat them like overflow clip. |
| 254 LayoutRect clipRect; | 188 LayoutRect clipRect; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 265 LayoutRect(context.paintOffset, box.size())); | 199 LayoutRect(context.paintOffset, box.size())); |
| 266 borderRadiusClip = ClipPaintPropertyNode::create( | 200 borderRadiusClip = ClipPaintPropertyNode::create( |
| 267 context.currentTransform, innerBorder, context.currentClip); | 201 context.currentTransform, innerBorder, context.currentClip); |
| 268 } | 202 } |
| 269 | 203 |
| 270 RefPtr<ClipPaintPropertyNode> overflowClip = ClipPaintPropertyNode::create( | 204 RefPtr<ClipPaintPropertyNode> overflowClip = ClipPaintPropertyNode::create( |
| 271 context.currentTransform, | 205 context.currentTransform, |
| 272 FloatRoundedRect(FloatRect(clipRect)), | 206 FloatRoundedRect(FloatRect(clipRect)), |
| 273 borderRadiusClip ? borderRadiusClip.release() : context.currentClip); | 207 borderRadiusClip ? borderRadiusClip.release() : context.currentClip); |
| 274 context.currentClip = overflowClip.get(); | 208 context.currentClip = overflowClip.get(); |
| 275 object.ensureObjectPaintProperties().setOverflowClip(overflowClip.release())
; | 209 object.getMutableForPainting().ensureObjectPaintProperties().setOverflowClip
(overflowClip.release()); |
| 276 } | 210 } |
| 277 | 211 |
| 278 static FloatPoint perspectiveOrigin(const LayoutBox& box) | 212 static FloatPoint perspectiveOrigin(const LayoutBox& box) |
| 279 { | 213 { |
| 280 const ComputedStyle& style = box.styleRef(); | 214 const ComputedStyle& style = box.styleRef(); |
| 281 FloatSize borderBoxSize(box.size()); | 215 FloatSize borderBoxSize(box.size()); |
| 282 return FloatPoint( | 216 return FloatPoint( |
| 283 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), | 217 floatValueForLength(style.perspectiveOriginX(), borderBoxSize.width()), |
| 284 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()))
; | 218 floatValueForLength(style.perspectiveOriginY(), borderBoxSize.height()))
; |
| 285 } | 219 } |
| 286 | 220 |
| 287 void PaintPropertyTreeBuilder::updatePerspective(LayoutObject& object, PaintProp
ertyTreeBuilderContext& context) | 221 void PaintPropertyTreeBuilder::updatePerspective(const LayoutObject& object, Pai
ntPropertyTreeBuilderContext& context) |
| 288 { | 222 { |
| 289 const ComputedStyle& style = object.styleRef(); | 223 const ComputedStyle& style = object.styleRef(); |
| 290 if (!object.isBox() || !style.hasPerspective()) | 224 if (!object.isBox() || !style.hasPerspective()) |
| 291 return; | 225 return; |
| 292 | 226 |
| 293 RefPtr<TransformPaintPropertyNode> perspective = TransformPaintPropertyNode:
:create( | 227 RefPtr<TransformPaintPropertyNode> perspective = TransformPaintPropertyNode:
:create( |
| 294 TransformationMatrix().applyPerspective(style.perspective()), | 228 TransformationMatrix().applyPerspective(style.perspective()), |
| 295 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse
t), | 229 perspectiveOrigin(toLayoutBox(object)) + toLayoutSize(context.paintOffse
t), |
| 296 context.currentTransform); | 230 context.currentTransform); |
| 297 context.currentTransform = perspective.get(); | 231 context.currentTransform = perspective.get(); |
| 298 object.ensureObjectPaintProperties().setPerspective(perspective.release()); | 232 object.getMutableForPainting().ensureObjectPaintProperties().setPerspective(
perspective.release()); |
| 299 } | 233 } |
| 300 | 234 |
| 301 void PaintPropertyTreeBuilder::updateSvgLocalTransform(LayoutObject& object, Pai
ntPropertyTreeBuilderContext& context) | 235 void PaintPropertyTreeBuilder::updateSvgLocalTransform(const LayoutObject& objec
t, PaintPropertyTreeBuilderContext& context) |
| 302 { | 236 { |
| 303 if (!object.isSVG()) | 237 if (!object.isSVG()) |
| 304 return; | 238 return; |
| 305 | 239 |
| 306 const AffineTransform& transform = object.localToSVGParentTransform(); | 240 const AffineTransform& transform = object.localToSVGParentTransform(); |
| 307 if (transform.isIdentity()) | 241 if (transform.isIdentity()) |
| 308 return; | 242 return; |
| 309 | 243 |
| 310 // The origin is included in the local transform, so use an empty origin. | 244 // The origin is included in the local transform, so use an empty origin. |
| 311 RefPtr<TransformPaintPropertyNode> svgLocalTransform = TransformPaintPropert
yNode::create( | 245 RefPtr<TransformPaintPropertyNode> svgLocalTransform = TransformPaintPropert
yNode::create( |
| 312 transform, FloatPoint3D(0, 0, 0), context.currentTransform); | 246 transform, FloatPoint3D(0, 0, 0), context.currentTransform); |
| 313 context.currentTransform = svgLocalTransform.get(); | 247 context.currentTransform = svgLocalTransform.get(); |
| 314 object.ensureObjectPaintProperties().setSvgLocalTransform(svgLocalTransform.
release()); | 248 object.getMutableForPainting().ensureObjectPaintProperties().setSvgLocalTran
sform(svgLocalTransform.release()); |
| 315 } | 249 } |
| 316 | 250 |
| 317 void PaintPropertyTreeBuilder::updateScrollTranslation(LayoutObject& object, Pai
ntPropertyTreeBuilderContext& context) | 251 void PaintPropertyTreeBuilder::updateScrollTranslation(const LayoutObject& objec
t, PaintPropertyTreeBuilderContext& context) |
| 318 { | 252 { |
| 319 if (!object.isBoxModelObject() || !object.hasOverflowClip()) | 253 if (!object.isBoxModelObject() || !object.hasOverflowClip()) |
| 320 return; | 254 return; |
| 321 | 255 |
| 322 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 256 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 323 ASSERT(layer); | 257 ASSERT(layer); |
| 324 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); | 258 DoubleSize scrollOffset = layer->getScrollableArea()->scrollOffset(); |
| 325 if (scrollOffset.isZero() && !layer->scrollsOverflow()) | 259 if (scrollOffset.isZero() && !layer->scrollsOverflow()) |
| 326 return; | 260 return; |
| 327 | 261 |
| 328 RefPtr<TransformPaintPropertyNode> scrollTranslation = TransformPaintPropert
yNode::create( | 262 RefPtr<TransformPaintPropertyNode> scrollTranslation = TransformPaintPropert
yNode::create( |
| 329 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he
ight()), | 263 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he
ight()), |
| 330 FloatPoint3D(), | 264 FloatPoint3D(), |
| 331 context.currentTransform); | 265 context.currentTransform); |
| 332 context.currentTransform = scrollTranslation.get(); | 266 context.currentTransform = scrollTranslation.get(); |
| 333 object.ensureObjectPaintProperties().setScrollTranslation(scrollTranslation.
release()); | 267 object.getMutableForPainting().ensureObjectPaintProperties().setScrollTransl
ation(scrollTranslation.release()); |
| 334 } | 268 } |
| 335 | 269 |
| 336 void PaintPropertyTreeBuilder::updateOutOfFlowContext(LayoutObject& object, Pain
tPropertyTreeBuilderContext& context) | 270 void PaintPropertyTreeBuilder::updateOutOfFlowContext(const LayoutObject& object
, PaintPropertyTreeBuilderContext& context) |
| 337 { | 271 { |
| 338 if (object.canContainAbsolutePositionObjects()) { | 272 if (object.canContainAbsolutePositionObjects()) { |
| 339 context.transformForAbsolutePosition = context.currentTransform; | 273 context.transformForAbsolutePosition = context.currentTransform; |
| 340 context.paintOffsetForAbsolutePosition = context.paintOffset; | 274 context.paintOffsetForAbsolutePosition = context.paintOffset; |
| 341 context.clipForAbsolutePosition = context.currentClip; | 275 context.clipForAbsolutePosition = context.currentClip; |
| 342 context.containerForAbsolutePosition = &object; | 276 context.containerForAbsolutePosition = &object; |
| 343 } | 277 } |
| 344 | 278 |
| 345 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram
eView | 279 // TODO(pdr): Remove the !object.isLayoutView() condition when removing Fram
eView |
| 346 // paint properties for rootLayerScrolls. | 280 // paint properties for rootLayerScrolls. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 361 if (context.clipForFixedPosition == cssClip->parent()) { | 295 if (context.clipForFixedPosition == cssClip->parent()) { |
| 362 context.clipForFixedPosition = cssClip; | 296 context.clipForFixedPosition = cssClip; |
| 363 return; | 297 return; |
| 364 } | 298 } |
| 365 | 299 |
| 366 RefPtr<ClipPaintPropertyNode> clipFixedPosition = ClipPaintPropertyNode:
:create( | 300 RefPtr<ClipPaintPropertyNode> clipFixedPosition = ClipPaintPropertyNode:
:create( |
| 367 const_cast<TransformPaintPropertyNode*>(cssClip->localTransformSpace
()), | 301 const_cast<TransformPaintPropertyNode*>(cssClip->localTransformSpace
()), |
| 368 cssClip->clipRect(), | 302 cssClip->clipRect(), |
| 369 context.clipForFixedPosition); | 303 context.clipForFixedPosition); |
| 370 context.clipForFixedPosition = clipFixedPosition.get(); | 304 context.clipForFixedPosition = clipFixedPosition.get(); |
| 371 object.ensureObjectPaintProperties().setCssClipFixedPosition(clipFixedPo
sition.release()); | 305 object.getMutableForPainting().ensureObjectPaintProperties().setCssClipF
ixedPosition(clipFixedPosition.release()); |
| 372 } | 306 } |
| 373 } | 307 } |
| 374 | 308 |
| 375 static void deriveBorderBoxFromContainerContext(const LayoutObject& object, Pain
tPropertyTreeBuilderContext& context) | 309 static void deriveBorderBoxFromContainerContext(const LayoutObject& object, Pain
tPropertyTreeBuilderContext& context) |
| 376 { | 310 { |
| 377 if (!object.isBoxModelObject()) | 311 if (!object.isBoxModelObject()) |
| 378 return; | 312 return; |
| 379 | 313 |
| 380 const LayoutBoxModelObject& boxModelObject = toLayoutBoxModelObject(object); | 314 const LayoutBoxModelObject& boxModelObject = toLayoutBoxModelObject(object); |
| 381 | 315 |
| 382 switch (object.styleRef().position()) { | 316 switch (object.styleRef().position()) { |
| 383 case StaticPosition: | 317 case StaticPosition: |
| 384 break; | 318 break; |
| 385 case RelativePosition: | 319 case RelativePosition: |
| 386 context.paintOffset += boxModelObject.offsetForInFlowPosition(); | 320 context.paintOffset += boxModelObject.offsetForInFlowPosition(); |
| 387 break; | 321 break; |
| 388 case AbsolutePosition: { | 322 case AbsolutePosition: { |
| 389 context.currentTransform = context.transformForAbsolutePosition; | 323 context.currentTransform = context.transformForAbsolutePosition; |
| 390 context.paintOffset = context.paintOffsetForAbsolutePosition; | 324 context.paintOffset = context.paintOffsetForAbsolutePosition; |
| 391 | 325 |
| 392 // Absolutely positioned content in an inline should be positioned relat
ive to the inline. | 326 // Absolutely positioned content in an inline should be positioned relat
ive to the inline. |
| 393 LayoutObject* container = context.containerForAbsolutePosition; | 327 const LayoutObject* container = context.containerForAbsolutePosition; |
| 394 if (container && container->isInFlowPositioned() && container->isLayoutI
nline()) { | 328 if (container && container->isInFlowPositioned() && container->isLayoutI
nline()) { |
| 395 DCHECK(object.isBox()); | 329 DCHECK(object.isBox()); |
| 396 context.paintOffset += toLayoutInline(container)->offsetForInFlowPos
itionedInline(toLayoutBox(object)); | 330 context.paintOffset += toLayoutInline(container)->offsetForInFlowPos
itionedInline(toLayoutBox(object)); |
| 397 } | 331 } |
| 398 | 332 |
| 399 context.currentClip = context.clipForAbsolutePosition; | 333 context.currentClip = context.clipForAbsolutePosition; |
| 400 break; | 334 break; |
| 401 } | 335 } |
| 402 case StickyPosition: | 336 case StickyPosition: |
| 403 context.paintOffset += boxModelObject.offsetForInFlowPosition(); | 337 context.paintOffset += boxModelObject.offsetForInFlowPosition(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 416 // but their location have the row's location baked-in. | 350 // but their location have the row's location baked-in. |
| 417 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). | 351 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). |
| 418 if (boxModelObject.isTableCell()) { | 352 if (boxModelObject.isTableCell()) { |
| 419 LayoutObject* parentRow = boxModelObject.parent(); | 353 LayoutObject* parentRow = boxModelObject.parent(); |
| 420 ASSERT(parentRow && parentRow->isTableRow()); | 354 ASSERT(parentRow && parentRow->isTableRow()); |
| 421 context.paintOffset -= toLayoutBox(parentRow)->locationOffset(); | 355 context.paintOffset -= toLayoutBox(parentRow)->locationOffset(); |
| 422 } | 356 } |
| 423 } | 357 } |
| 424 } | 358 } |
| 425 | 359 |
| 426 void PaintPropertyTreeBuilder::walk(LayoutObject& object, const PaintPropertyTre
eBuilderContext& context) | 360 void PaintPropertyTreeBuilder::buildTreeNodes(const LayoutObject& object, PaintP
ropertyTreeBuilderContext& context) |
| 427 { | 361 { |
| 428 PaintPropertyTreeBuilderContext localContext(context); | 362 object.getMutableForPainting().clearObjectPaintProperties(); |
| 429 object.clearObjectPaintProperties(); | |
| 430 | 363 |
| 431 deriveBorderBoxFromContainerContext(object, localContext); | 364 deriveBorderBoxFromContainerContext(object, context); |
| 432 | 365 |
| 433 updatePaintOffsetTranslation(object, localContext); | 366 updatePaintOffsetTranslation(object, context); |
| 434 updateTransform(object, localContext); | 367 updateTransform(object, context); |
| 435 updateEffect(object, localContext); | 368 updateEffect(object, context); |
| 436 updateCssClip(object, localContext); | 369 updateCssClip(object, context); |
| 437 updateLocalBorderBoxContext(object, localContext); | 370 updateLocalBorderBoxContext(object, context); |
| 438 updateScrollbarPaintOffset(object, localContext); | 371 updateScrollbarPaintOffset(object, context); |
| 439 updateOverflowClip(object, localContext); | 372 updateOverflowClip(object, context); |
| 440 // TODO(trchen): Insert flattening transform here, as specified by | 373 // TODO(trchen): Insert flattening transform here, as specified by |
| 441 // http://www.w3.org/TR/css3-transforms/#transform-style-property | 374 // http://www.w3.org/TR/css3-transforms/#transform-style-property |
| 442 updatePerspective(object, localContext); | 375 updatePerspective(object, context); |
| 443 updateSvgLocalTransform(object, localContext); | 376 updateSvgLocalTransform(object, context); |
| 444 updateScrollTranslation(object, localContext); | 377 updateScrollTranslation(object, context); |
| 445 updateOutOfFlowContext(object, localContext); | 378 updateOutOfFlowContext(object, context); |
| 446 | |
| 447 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne
xtSibling()) { | |
| 448 if (child->isBoxModelObject() || child->isSVG()) | |
| 449 walk(*child, localContext); | |
| 450 } | |
| 451 | |
| 452 if (object.isLayoutPart()) { | |
| 453 Widget* widget = toLayoutPart(object).widget(); | |
| 454 if (widget && widget->isFrameView()) | |
| 455 walk(*toFrameView(widget), localContext); | |
| 456 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). | |
| 457 } | |
| 458 } | 379 } |
| 459 | 380 |
| 460 } // namespace blink | 381 } // namespace blink |
| OLD | NEW |