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