| 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/layout/LayoutPart.h" | 8 #include "core/layout/LayoutPart.h" |
| 9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
| 10 #include "core/paint/ObjectPaintProperties.h" | 10 #include "core/paint/ObjectPaintProperties.h" |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 const ComputedStyle& style = box.styleRef(); | 170 const ComputedStyle& style = box.styleRef(); |
| 171 FloatSize borderBoxSize(box.size()); | 171 FloatSize borderBoxSize(box.size()); |
| 172 return FloatPoint3D( | 172 return FloatPoint3D( |
| 173 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), | 173 floatValueForLength(style.transformOriginX(), borderBoxSize.width()), |
| 174 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), | 174 floatValueForLength(style.transformOriginY(), borderBoxSize.height()), |
| 175 style.transformOriginZ()); | 175 style.transformOriginZ()); |
| 176 } | 176 } |
| 177 | 177 |
| 178 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo
utObject& object, PaintPropertyTreeBuilderContext& context) | 178 static PassRefPtr<TransformPaintPropertyNode> createTransformIfNeeded(const Layo
utObject& object, PaintPropertyTreeBuilderContext& context) |
| 179 { | 179 { |
| 180 if (object.isSVG() && !object.isSVGRoot()) { | |
| 181 const AffineTransform& transform = object.localToSVGParentTransform(); | |
| 182 if (transform.isIdentity()) | |
| 183 return nullptr; | |
| 184 | |
| 185 // SVG's transform origin is baked into the localToParentTransform. | |
| 186 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = Transf
ormPaintPropertyNode::create( | |
| 187 transform, FloatPoint3D(0, 0, 0), context.currentTransform); | |
| 188 context.currentTransform = newTransformNodeForTransform.get(); | |
| 189 return newTransformNodeForTransform.release(); | |
| 190 } | |
| 191 | |
| 192 const ComputedStyle& style = object.styleRef(); | 180 const ComputedStyle& style = object.styleRef(); |
| 193 if (!object.isBox() || !style.hasTransform()) | 181 if (!object.isBox() || !style.hasTransform()) |
| 194 return nullptr; | 182 return nullptr; |
| 195 | 183 |
| 196 ASSERT(context.paintOffset == LayoutPoint()); | 184 ASSERT(context.paintOffset == LayoutPoint()); |
| 197 | 185 |
| 198 TransformationMatrix matrix; | 186 TransformationMatrix matrix; |
| 199 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl
udeTransformOrigin, | 187 style.applyTransform(matrix, toLayoutBox(object).size(), ComputedStyle::Excl
udeTransformOrigin, |
| 200 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans
formProperties); | 188 ComputedStyle::IncludeMotionPath, ComputedStyle::IncludeIndependentTrans
formProperties); |
| 201 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP
aintPropertyNode::create( | 189 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP
aintPropertyNode::create( |
| 202 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); | 190 matrix, transformOrigin(toLayoutBox(object)), context.currentTransform); |
| 203 context.currentTransform = newTransformNodeForTransform.get(); | 191 context.currentTransform = newTransformNodeForTransform.get(); |
| 204 return newTransformNodeForTransform.release(); | 192 return newTransformNodeForTransform.release(); |
| 205 } | 193 } |
| 206 | 194 |
| 195 static PassRefPtr<TransformPaintPropertyNode> createSvgLocalTransformIfNeeded(co
nst LayoutObject& object, PaintPropertyTreeBuilderContext& context) |
| 196 { |
| 197 if (!object.isSVG()) |
| 198 return nullptr; |
| 199 |
| 200 const AffineTransform& transform = object.localToSVGParentTransform(); |
| 201 if (transform.isIdentity()) |
| 202 return nullptr; |
| 203 |
| 204 // SVG's transform origin is baked into the localToSVGParentTransform so we
use 0's for the origin. |
| 205 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = TransformP
aintPropertyNode::create( |
| 206 transform, FloatPoint3D(0, 0, 0), context.currentTransform); |
| 207 context.currentTransform = newTransformNodeForTransform.get(); |
| 208 return newTransformNodeForTransform.release(); |
| 209 } |
| 210 |
| 207 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje
ct& object, PaintPropertyTreeBuilderContext& context) | 211 static PassRefPtr<EffectPaintPropertyNode> createEffectIfNeeded(const LayoutObje
ct& object, PaintPropertyTreeBuilderContext& context) |
| 208 { | 212 { |
| 209 const ComputedStyle& style = object.styleRef(); | 213 const ComputedStyle& style = object.styleRef(); |
| 210 if (!style.hasOpacity()) | 214 if (!style.hasOpacity()) |
| 211 return nullptr; | 215 return nullptr; |
| 212 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre
ate(style.opacity(), context.currentEffect); | 216 RefPtr<EffectPaintPropertyNode> newEffectNode = EffectPaintPropertyNode::cre
ate(style.opacity(), context.currentEffect); |
| 213 context.currentEffect = newEffectNode.get(); | 217 context.currentEffect = newEffectNode.get(); |
| 214 return newEffectNode.release(); | 218 return newEffectNode.release(); |
| 215 } | 219 } |
| 216 | 220 |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 | 328 |
| 325 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr
ansformPaintPropertyNode::create( | 329 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = Tr
ansformPaintPropertyNode::create( |
| 326 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he
ight()), | 330 TransformationMatrix().translate(-scrollOffset.width(), -scrollOffset.he
ight()), |
| 327 FloatPoint3D(), context.currentTransform); | 331 FloatPoint3D(), context.currentTransform); |
| 328 context.currentTransform = newTransformNodeForScrollTranslation.get(); | 332 context.currentTransform = newTransformNodeForScrollTranslation.get(); |
| 329 return newTransformNodeForScrollTranslation.release(); | 333 return newTransformNodeForScrollTranslation.release(); |
| 330 } | 334 } |
| 331 | 335 |
| 332 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree
BuilderContext& context, ClipPaintPropertyNode* newClipNodeForCSSClip, RefPtr<Cl
ipPaintPropertyNode>& newClipNodeForCSSClipFixedPosition) | 336 static void updateOutOfFlowContext(const LayoutObject& object, PaintPropertyTree
BuilderContext& context, ClipPaintPropertyNode* newClipNodeForCSSClip, RefPtr<Cl
ipPaintPropertyNode>& newClipNodeForCSSClipFixedPosition) |
| 333 { | 337 { |
| 338 // TODO(pdr): Always create an SVG transform for the root and remove this pa
int offset quirk. |
| 334 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the
currentTransform is | 339 // At the html->svg boundary (see: createPaintOffsetTranslationIfNeeded) the
currentTransform is |
| 335 // up-to-date for all children of the svg root element. Additionally, inside
SVG, all positioning | 340 // up-to-date for all children of the svg root element. Additionally, inside
SVG, all positioning |
| 336 // uses transforms. Therefore, we only need to check createdNewTransform and
isSVGRoot() to | 341 // uses transforms. Therefore, we only need to check createdNewTransform and
isSVGRoot() to |
| 337 // ensure out-of-flow and fixed positioning is correct at the svg->html boun
dary. | 342 // ensure out-of-flow and fixed positioning is correct at the svg->html boun
dary. |
| 338 | 343 |
| 339 if (object.canContainAbsolutePositionObjects()) { | 344 if (object.canContainAbsolutePositionObjects()) { |
| 340 context.transformForAbsolutePosition = context.currentTransform; | 345 context.transformForAbsolutePosition = context.currentTransform; |
| 341 context.paintOffsetForAbsolutePosition = context.paintOffset; | 346 context.paintOffsetForAbsolutePosition = context.paintOffset; |
| 342 context.clipForAbsolutePosition = context.currentClip; | 347 context.clipForAbsolutePosition = context.currentClip; |
| 343 } | 348 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation
= createPaintOffsetTranslationIfNeeded(object, localContext); | 398 RefPtr<TransformPaintPropertyNode> newTransformNodeForPaintOffsetTranslation
= createPaintOffsetTranslationIfNeeded(object, localContext); |
| 394 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran
sformIfNeeded(object, localContext); | 399 RefPtr<TransformPaintPropertyNode> newTransformNodeForTransform = createTran
sformIfNeeded(object, localContext); |
| 395 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object,
localContext); | 400 RefPtr<EffectPaintPropertyNode> newEffectNode = createEffectIfNeeded(object,
localContext); |
| 396 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = createCSSClipIfNeeded(
object, localContext); | 401 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClip = createCSSClipIfNeeded(
object, localContext); |
| 397 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext =
recordTreeContextIfNeeded(object, localContext); | 402 OwnPtr<ObjectPaintProperties::LocalBorderBoxProperties> newRecordedContext =
recordTreeContextIfNeeded(object, localContext); |
| 398 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset =
createScrollbarPaintOffsetIfNeeded(object, localContext); | 403 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollbarPaintOffset =
createScrollbarPaintOffsetIfNeeded(object, localContext); |
| 399 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli
pIfNeeded(object, localContext); | 404 RefPtr<ClipPaintPropertyNode> newClipNodeForOverflowClip = createOverflowCli
pIfNeeded(object, localContext); |
| 400 // TODO(trchen): Insert flattening transform here, as specified by | 405 // TODO(trchen): Insert flattening transform here, as specified by |
| 401 // http://www.w3.org/TR/css3-transforms/#transform-style-property | 406 // http://www.w3.org/TR/css3-transforms/#transform-style-property |
| 402 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe
rspectiveIfNeeded(object, localContext); | 407 RefPtr<TransformPaintPropertyNode> newTransformNodeForPerspective = createPe
rspectiveIfNeeded(object, localContext); |
| 408 RefPtr<TransformPaintPropertyNode> newTransformNodeForSvgLocalTransform = cr
eateSvgLocalTransformIfNeeded(object, localContext); |
| 403 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr
eateScrollTranslationIfNeeded(object, localContext); | 409 RefPtr<TransformPaintPropertyNode> newTransformNodeForScrollTranslation = cr
eateScrollTranslationIfNeeded(object, localContext); |
| 404 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClipFixedPosition; | 410 RefPtr<ClipPaintPropertyNode> newClipNodeForCSSClipFixedPosition; |
| 405 updateOutOfFlowContext(object, localContext, newClipNodeForCSSClip.get(), ne
wClipNodeForCSSClipFixedPosition); | 411 updateOutOfFlowContext(object, localContext, newClipNodeForCSSClip.get(), ne
wClipNodeForCSSClipFixedPosition); |
| 406 | 412 |
| 407 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor
m || newEffectNode || newClipNodeForCSSClip || newClipNodeForCSSClipFixedPositio
n || newClipNodeForOverflowClip || newTransformNodeForPerspective || newTransfor
mNodeForScrollTranslation || newTransformNodeForScrollbarPaintOffset || newRecor
dedContext) { | 413 DCHECK(!newTransformNodeForSvgLocalTransform || !newTransformNodeForScrollTr
anslation) |
| 414 << "SVG elements cannot have scroll translation"; |
| 415 |
| 416 // TODO(pdr): Refactor this to use a less massive if statement. |
| 417 if (newTransformNodeForPaintOffsetTranslation || newTransformNodeForTransfor
m || newEffectNode || newClipNodeForCSSClip || newClipNodeForCSSClipFixedPositio
n || newClipNodeForOverflowClip || newTransformNodeForPerspective || newTransfor
mNodeForSvgLocalTransform || newTransformNodeForScrollTranslation || newTransfor
mNodeForScrollbarPaintOffset || newRecordedContext) { |
| 408 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper
ties::create( | 418 OwnPtr<ObjectPaintProperties> updatedPaintProperties = ObjectPaintProper
ties::create( |
| 409 newTransformNodeForPaintOffsetTranslation.release(), | 419 newTransformNodeForPaintOffsetTranslation.release(), |
| 410 newTransformNodeForTransform.release(), | 420 newTransformNodeForTransform.release(), |
| 411 newEffectNode.release(), | 421 newEffectNode.release(), |
| 412 newClipNodeForCSSClip.release(), | 422 newClipNodeForCSSClip.release(), |
| 413 newClipNodeForCSSClipFixedPosition.release(), | 423 newClipNodeForCSSClipFixedPosition.release(), |
| 414 newClipNodeForOverflowClip.release(), | 424 newClipNodeForOverflowClip.release(), |
| 415 newTransformNodeForPerspective.release(), | 425 newTransformNodeForPerspective.release(), |
| 426 newTransformNodeForSvgLocalTransform.release(), |
| 416 newTransformNodeForScrollTranslation.release(), | 427 newTransformNodeForScrollTranslation.release(), |
| 417 newTransformNodeForScrollbarPaintOffset.release(), | 428 newTransformNodeForScrollbarPaintOffset.release(), |
| 418 newRecordedContext.release()); | 429 newRecordedContext.release()); |
| 419 object.setObjectPaintProperties(updatedPaintProperties.release()); | 430 object.setObjectPaintProperties(updatedPaintProperties.release()); |
| 420 } else { | 431 } else { |
| 421 object.clearObjectPaintProperties(); | 432 object.clearObjectPaintProperties(); |
| 422 } | 433 } |
| 423 | 434 |
| 424 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne
xtSibling()) { | 435 for (LayoutObject* child = object.slowFirstChild(); child; child = child->ne
xtSibling()) { |
| 425 if (child->isBoxModelObject() || child->isSVG()) | 436 if (child->isBoxModelObject() || child->isSVG()) |
| 426 walk(*child, localContext); | 437 walk(*child, localContext); |
| 427 } | 438 } |
| 428 | 439 |
| 429 if (object.isLayoutPart()) { | 440 if (object.isLayoutPart()) { |
| 430 Widget* widget = toLayoutPart(object).widget(); | 441 Widget* widget = toLayoutPart(object).widget(); |
| 431 if (widget && widget->isFrameView()) | 442 if (widget && widget->isFrameView()) |
| 432 walk(*toFrameView(widget), localContext); | 443 walk(*toFrameView(widget), localContext); |
| 433 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). | 444 // TODO(pdr): Investigate RemoteFrameView (crbug.com/579281). |
| 434 } | 445 } |
| 435 } | 446 } |
| 436 | 447 |
| 437 } // namespace blink | 448 } // namespace blink |
| OLD | NEW |