| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/paint/PaintPropertyTreeBuilder.h" | 5 #include "core/paint/PaintPropertyTreeBuilder.h" |
| 6 | 6 |
| 7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "core/frame/LocalFrame.h" | 8 #include "core/frame/LocalFrame.h" |
| 9 #include "core/frame/Settings.h" | 9 #include "core/frame/Settings.h" |
| 10 #include "core/layout/LayoutInline.h" | 10 #include "core/layout/LayoutInline.h" |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 PaintPropertyTreeBuilderContext context; | 56 PaintPropertyTreeBuilderContext context; |
| 57 | 57 |
| 58 context.current.clip = context.absolutePosition.clip = | 58 context.current.clip = context.absolutePosition.clip = |
| 59 context.fixedPosition.clip = rootClipNode(); | 59 context.fixedPosition.clip = rootClipNode(); |
| 60 context.currentEffect = rootEffectNode(); | 60 context.currentEffect = rootEffectNode(); |
| 61 context.current.transform = context.absolutePosition.transform = | 61 context.current.transform = context.absolutePosition.transform = |
| 62 context.fixedPosition.transform = rootTransformNode(); | 62 context.fixedPosition.transform = rootTransformNode(); |
| 63 context.current.scroll = context.absolutePosition.scroll = | 63 context.current.scroll = context.absolutePosition.scroll = |
| 64 context.fixedPosition.scroll = rootScrollNode(); | 64 context.fixedPosition.scroll = rootScrollNode(); |
| 65 | 65 |
| 66 // Ensure scroll tree properties are reset. They will be rebuilt during the tr
ee walk. | 66 // Ensure scroll tree properties are reset. They will be rebuilt during the |
| 67 // tree walk. |
| 67 rootScrollNode()->clearMainThreadScrollingReasons(); | 68 rootScrollNode()->clearMainThreadScrollingReasons(); |
| 68 | 69 |
| 69 return context; | 70 return context; |
| 70 } | 71 } |
| 71 | 72 |
| 72 void createOrUpdateFrameViewPreTranslation( | 73 void createOrUpdateFrameViewPreTranslation( |
| 73 FrameView& frameView, | 74 FrameView& frameView, |
| 74 PassRefPtr<const TransformPaintPropertyNode> parent, | 75 PassRefPtr<const TransformPaintPropertyNode> parent, |
| 75 const TransformationMatrix& matrix, | 76 const TransformationMatrix& matrix, |
| 76 const FloatPoint3D& origin) { | 77 const FloatPoint3D& origin) { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 } | 218 } |
| 218 | 219 |
| 219 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation( | 220 void PaintPropertyTreeBuilder::updatePaintOffsetTranslation( |
| 220 const LayoutObject& object, | 221 const LayoutObject& object, |
| 221 PaintPropertyTreeBuilderContext& context) { | 222 PaintPropertyTreeBuilderContext& context) { |
| 222 if (object.isBoxModelObject() && | 223 if (object.isBoxModelObject() && |
| 223 context.current.paintOffset != LayoutPoint()) { | 224 context.current.paintOffset != LayoutPoint()) { |
| 224 // TODO(trchen): Eliminate PaintLayer dependency. | 225 // TODO(trchen): Eliminate PaintLayer dependency. |
| 225 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); | 226 PaintLayer* layer = toLayoutBoxModelObject(object).layer(); |
| 226 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { | 227 if (layer && layer->paintsWithTransform(GlobalPaintNormalPhase)) { |
| 227 // We should use the same subpixel paint offset values for snapping regard
less of whether a | 228 // We should use the same subpixel paint offset values for snapping |
| 228 // transform is present. If there is a transform we round the paint offset
but keep around | 229 // regardless of whether a transform is present. If there is a transform |
| 229 // the residual fractional component for the transformed content to paint
with. | 230 // we round the paint offset but keep around the residual fractional |
| 230 // In spv1 this was called "subpixel accumulation". For more information,
see | 231 // component for the transformed content to paint with. In spv1 this was |
| 231 // PaintLayer::subpixelAccumulation() and PaintLayerPainter::paintFragment
ByApplyingTransform. | 232 // called "subpixel accumulation". For more information, see |
| 233 // PaintLayer::subpixelAccumulation() and |
| 234 // PaintLayerPainter::paintFragmentByApplyingTransform. |
| 232 IntPoint roundedPaintOffset = | 235 IntPoint roundedPaintOffset = |
| 233 roundedIntPoint(context.current.paintOffset); | 236 roundedIntPoint(context.current.paintOffset); |
| 234 LayoutPoint fractionalPaintOffset = | 237 LayoutPoint fractionalPaintOffset = |
| 235 LayoutPoint(context.current.paintOffset - roundedPaintOffset); | 238 LayoutPoint(context.current.paintOffset - roundedPaintOffset); |
| 236 | 239 |
| 237 context.current.transform = | 240 context.current.transform = |
| 238 object.getMutableForPainting() | 241 object.getMutableForPainting() |
| 239 .ensureObjectPaintProperties() | 242 .ensureObjectPaintProperties() |
| 240 .createOrUpdatePaintOffsetTranslation( | 243 .createOrUpdatePaintOffsetTranslation( |
| 241 context.current.transform, | 244 context.current.transform, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 267 } | 270 } |
| 268 | 271 |
| 269 void PaintPropertyTreeBuilder::updateTransform( | 272 void PaintPropertyTreeBuilder::updateTransform( |
| 270 const LayoutObject& object, | 273 const LayoutObject& object, |
| 271 PaintPropertyTreeBuilderContext& context) { | 274 PaintPropertyTreeBuilderContext& context) { |
| 272 if (object.isSVG() && !object.isSVGRoot()) { | 275 if (object.isSVG() && !object.isSVGRoot()) { |
| 273 // SVG (other than SVGForeignObject) does not use paint offset internally. | 276 // SVG (other than SVGForeignObject) does not use paint offset internally. |
| 274 DCHECK(object.isSVGForeignObject() || | 277 DCHECK(object.isSVGForeignObject() || |
| 275 context.current.paintOffset == LayoutPoint()); | 278 context.current.paintOffset == LayoutPoint()); |
| 276 | 279 |
| 277 // FIXME(pdr): Check for the presence of a transform instead of the value. C
hecking for an | 280 // FIXME(pdr): Check for the presence of a transform instead of the value. |
| 278 // identity matrix will cause the property tree structure to change during a
nimations if | 281 // Checking for an identity matrix will cause the property tree structure to |
| 279 // the animation passes through the identity matrix. | 282 // change during animations if the animation passes through the identity |
| 280 // FIXME(pdr): Refactor this so all non-root SVG objects use the same transf
orm function. | 283 // matrix. |
| 284 // FIXME(pdr): Refactor this so all non-root SVG objects use the same |
| 285 // transform function. |
| 281 const AffineTransform& transform = object.isSVGForeignObject() | 286 const AffineTransform& transform = object.isSVGForeignObject() |
| 282 ? object.localSVGTransform() | 287 ? object.localSVGTransform() |
| 283 : object.localToSVGParentTransform(); | 288 : object.localToSVGParentTransform(); |
| 284 if (!transform.isIdentity()) { | 289 if (!transform.isIdentity()) { |
| 285 // The origin is included in the local transform, so leave origin empty. | 290 // The origin is included in the local transform, so leave origin empty. |
| 286 context.current.transform = | 291 context.current.transform = |
| 287 object.getMutableForPainting() | 292 object.getMutableForPainting() |
| 288 .ensureObjectPaintProperties() | 293 .ensureObjectPaintProperties() |
| 289 .createOrUpdateTransform(context.current.transform, | 294 .createOrUpdateTransform(context.current.transform, |
| 290 TransformationMatrix(transform), | 295 TransformationMatrix(transform), |
| (...skipping 12 matching lines...) Expand all Loading... |
| 303 ComputedStyle::IncludeMotionPath, | 308 ComputedStyle::IncludeMotionPath, |
| 304 ComputedStyle::IncludeIndependentTransformProperties); | 309 ComputedStyle::IncludeIndependentTransformProperties); |
| 305 FloatPoint3D origin = transformOrigin(toLayoutBox(object)); | 310 FloatPoint3D origin = transformOrigin(toLayoutBox(object)); |
| 306 | 311 |
| 307 unsigned renderingContextID = context.current.renderingContextID; | 312 unsigned renderingContextID = context.current.renderingContextID; |
| 308 unsigned renderingContextIDForChildren = 0; | 313 unsigned renderingContextIDForChildren = 0; |
| 309 bool flattensInheritedTransform = | 314 bool flattensInheritedTransform = |
| 310 context.current.shouldFlattenInheritedTransform; | 315 context.current.shouldFlattenInheritedTransform; |
| 311 bool childrenFlattenInheritedTransform = true; | 316 bool childrenFlattenInheritedTransform = true; |
| 312 | 317 |
| 313 // TODO(trchen): transform-style should only be respected if a PaintLayer
is | 318 // TODO(trchen): transform-style should only be respected if a PaintLayer |
| 314 // created. | 319 // is created. |
| 315 if (style.preserves3D()) { | 320 if (style.preserves3D()) { |
| 316 // If a node with transform-style: preserve-3d does not exist in an | 321 // If a node with transform-style: preserve-3d does not exist in an |
| 317 // existing rendering context, it establishes a new one. | 322 // existing rendering context, it establishes a new one. |
| 318 if (!renderingContextID) | 323 if (!renderingContextID) |
| 319 renderingContextID = PtrHash<const LayoutObject>::hash(&object); | 324 renderingContextID = PtrHash<const LayoutObject>::hash(&object); |
| 320 renderingContextIDForChildren = renderingContextID; | 325 renderingContextIDForChildren = renderingContextID; |
| 321 childrenFlattenInheritedTransform = false; | 326 childrenFlattenInheritedTransform = false; |
| 322 } | 327 } |
| 323 | 328 |
| 324 context.current.transform = | 329 context.current.transform = |
| (...skipping 29 matching lines...) Expand all Loading... |
| 354 .ensureObjectPaintProperties() | 359 .ensureObjectPaintProperties() |
| 355 .createOrUpdateEffect(context.currentEffect, | 360 .createOrUpdateEffect(context.currentEffect, |
| 356 object.styleRef().opacity()); | 361 object.styleRef().opacity()); |
| 357 } | 362 } |
| 358 | 363 |
| 359 void PaintPropertyTreeBuilder::updateCssClip( | 364 void PaintPropertyTreeBuilder::updateCssClip( |
| 360 const LayoutObject& object, | 365 const LayoutObject& object, |
| 361 PaintPropertyTreeBuilderContext& context) { | 366 PaintPropertyTreeBuilderContext& context) { |
| 362 if (object.hasClip()) { | 367 if (object.hasClip()) { |
| 363 // Create clip node for descendants that are not fixed position. | 368 // Create clip node for descendants that are not fixed position. |
| 364 // We don't have to setup context.absolutePosition.clip here because this ob
ject must be | 369 // We don't have to setup context.absolutePosition.clip here because this |
| 365 // a container for absolute position descendants, and will copy from in-flow
context later | 370 // object must be a container for absolute position descendants, and will |
| 366 // at updateOutOfFlowContext() step. | 371 // copy from in-flow context later at updateOutOfFlowContext() step. |
| 367 DCHECK(object.canContainAbsolutePositionObjects()); | 372 DCHECK(object.canContainAbsolutePositionObjects()); |
| 368 LayoutRect clipRect = | 373 LayoutRect clipRect = |
| 369 toLayoutBox(object).clipRect(context.current.paintOffset); | 374 toLayoutBox(object).clipRect(context.current.paintOffset); |
| 370 context.current.clip = | 375 context.current.clip = |
| 371 object.getMutableForPainting() | 376 object.getMutableForPainting() |
| 372 .ensureObjectPaintProperties() | 377 .ensureObjectPaintProperties() |
| 373 .createOrUpdateCssClip(context.current.clip, | 378 .createOrUpdateCssClip(context.current.clip, |
| 374 context.current.transform, | 379 context.current.transform, |
| 375 FloatRoundedRect(FloatRect(clipRect))); | 380 FloatRoundedRect(FloatRect(clipRect))); |
| 376 return; | 381 return; |
| 377 } | 382 } |
| 378 | 383 |
| 379 if (ObjectPaintProperties* properties = | 384 if (ObjectPaintProperties* properties = |
| 380 object.getMutableForPainting().objectPaintProperties()) | 385 object.getMutableForPainting().objectPaintProperties()) |
| 381 properties->clearCssClip(); | 386 properties->clearCssClip(); |
| 382 } | 387 } |
| 383 | 388 |
| 384 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext( | 389 void PaintPropertyTreeBuilder::updateLocalBorderBoxContext( |
| 385 const LayoutObject& object, | 390 const LayoutObject& object, |
| 386 PaintPropertyTreeBuilderContext& context) { | 391 PaintPropertyTreeBuilderContext& context) { |
| 387 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since w
e don't need them at the moment. | 392 // Avoid adding an ObjectPaintProperties for non-boxes to save memory, since |
| 393 // we don't need them at the moment. |
| 388 if (!object.isBox() && !object.hasLayer()) | 394 if (!object.isBox() && !object.hasLayer()) |
| 389 return; | 395 return; |
| 390 | 396 |
| 391 std::unique_ptr<ObjectPaintProperties::PropertyTreeStateWithOffset> | 397 std::unique_ptr<ObjectPaintProperties::PropertyTreeStateWithOffset> |
| 392 borderBoxContext = | 398 borderBoxContext = |
| 393 wrapUnique(new ObjectPaintProperties::PropertyTreeStateWithOffset( | 399 wrapUnique(new ObjectPaintProperties::PropertyTreeStateWithOffset( |
| 394 context.current.paintOffset, | 400 context.current.paintOffset, |
| 395 PropertyTreeState(context.current.transform, context.current.clip, | 401 PropertyTreeState(context.current.transform, context.current.clip, |
| 396 context.currentEffect, | 402 context.currentEffect, |
| 397 context.current.scroll))); | 403 context.current.scroll))); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 } | 453 } |
| 448 } | 454 } |
| 449 | 455 |
| 450 void PaintPropertyTreeBuilder::updateOverflowClip( | 456 void PaintPropertyTreeBuilder::updateOverflowClip( |
| 451 const LayoutObject& object, | 457 const LayoutObject& object, |
| 452 PaintPropertyTreeBuilderContext& context) { | 458 PaintPropertyTreeBuilderContext& context) { |
| 453 if (!object.isBox()) | 459 if (!object.isBox()) |
| 454 return; | 460 return; |
| 455 const LayoutBox& box = toLayoutBox(object); | 461 const LayoutBox& box = toLayoutBox(object); |
| 456 | 462 |
| 457 // The <input> elements can't have contents thus CSS overflow property doesn't
apply. | 463 // The <input> elements can't have contents thus CSS overflow property doesn't |
| 458 // However for layout purposes we do generate child layout objects for them, e
.g. button label. | 464 // apply. However for layout purposes we do generate child layout objects for |
| 459 // We should clip the overflow from those children. This is called control cli
p and we | 465 // them, e.g. button label. We should clip the overflow from those children. |
| 460 // technically treat them like overflow clip. | 466 // This is called control clip and we technically treat them like overflow |
| 467 // clip. |
| 461 LayoutRect clipRect; | 468 LayoutRect clipRect; |
| 462 if (box.hasControlClip()) { | 469 if (box.hasControlClip()) { |
| 463 clipRect = box.controlClipRect(context.current.paintOffset); | 470 clipRect = box.controlClipRect(context.current.paintOffset); |
| 464 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() || | 471 } else if (box.hasOverflowClip() || box.styleRef().containsPaint() || |
| 465 (box.isSVGRoot() && | 472 (box.isSVGRoot() && |
| 466 toLayoutSVGRoot(box).shouldApplyViewportClip())) { | 473 toLayoutSVGRoot(box).shouldApplyViewportClip())) { |
| 467 clipRect = box.overflowClipRect(context.current.paintOffset); | 474 clipRect = box.overflowClipRect(context.current.paintOffset); |
| 468 } else { | 475 } else { |
| 469 if (ObjectPaintProperties* properties = | 476 if (ObjectPaintProperties* properties = |
| 470 object.getMutableForPainting().objectPaintProperties()) { | 477 object.getMutableForPainting().objectPaintProperties()) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform( | 541 void PaintPropertyTreeBuilder::updateSvgLocalToBorderBoxTransform( |
| 535 const LayoutObject& object, | 542 const LayoutObject& object, |
| 536 PaintPropertyTreeBuilderContext& context) { | 543 PaintPropertyTreeBuilderContext& context) { |
| 537 if (!object.isSVGRoot()) | 544 if (!object.isSVGRoot()) |
| 538 return; | 545 return; |
| 539 | 546 |
| 540 AffineTransform transformToBorderBox = | 547 AffineTransform transformToBorderBox = |
| 541 SVGRootPainter(toLayoutSVGRoot(object)) | 548 SVGRootPainter(toLayoutSVGRoot(object)) |
| 542 .transformToPixelSnappedBorderBox(context.current.paintOffset); | 549 .transformToPixelSnappedBorderBox(context.current.paintOffset); |
| 543 | 550 |
| 544 // The paint offset is included in |transformToBorderBox| so SVG does not need
to handle paint | 551 // The paint offset is included in |transformToBorderBox| so SVG does not need |
| 545 // offset internally. | 552 // to handle paint offset internally. |
| 546 context.current.paintOffset = LayoutPoint(); | 553 context.current.paintOffset = LayoutPoint(); |
| 547 | 554 |
| 548 if (transformToBorderBox.isIdentity()) { | 555 if (transformToBorderBox.isIdentity()) { |
| 549 if (ObjectPaintProperties* properties = | 556 if (ObjectPaintProperties* properties = |
| 550 object.getMutableForPainting().objectPaintProperties()) | 557 object.getMutableForPainting().objectPaintProperties()) |
| 551 properties->clearSvgLocalToBorderBoxTransform(); | 558 properties->clearSvgLocalToBorderBoxTransform(); |
| 552 return; | 559 return; |
| 553 } | 560 } |
| 554 | 561 |
| 555 context.current.transform = | 562 context.current.transform = |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 context.fixedPosition = context.current; | 628 context.fixedPosition = context.current; |
| 622 | 629 |
| 623 // Fixed position transform and scroll nodes should not be affected. | 630 // Fixed position transform and scroll nodes should not be affected. |
| 624 context.fixedPosition.transform = initialFixedTransform; | 631 context.fixedPosition.transform = initialFixedTransform; |
| 625 context.fixedPosition.scroll = initialFixedScroll; | 632 context.fixedPosition.scroll = initialFixedScroll; |
| 626 } | 633 } |
| 627 } else if (object.canContainFixedPositionObjects()) { | 634 } else if (object.canContainFixedPositionObjects()) { |
| 628 context.fixedPosition = context.current; | 635 context.fixedPosition = context.current; |
| 629 } else if (object.getMutableForPainting().objectPaintProperties() && | 636 } else if (object.getMutableForPainting().objectPaintProperties() && |
| 630 object.objectPaintProperties()->cssClip()) { | 637 object.objectPaintProperties()->cssClip()) { |
| 631 // CSS clip applies to all descendants, even if this object is not a contain
ing block | 638 // CSS clip applies to all descendants, even if this object is not a |
| 632 // ancestor of the descendant. It is okay for absolute-position descendants
because | 639 // containing block ancestor of the descendant. It is okay for |
| 633 // having CSS clip implies being absolute position container. However for fi
xed-position | 640 // absolute-position descendants because having CSS clip implies being |
| 634 // descendants we need to insert the clip here if we are not a containing bl
ock ancestor | 641 // absolute position container. However for fixed-position descendants we |
| 635 // of them. | 642 // need to insert the clip here if we are not a containing block ancestor of |
| 643 // them. |
| 636 auto* cssClip = | 644 auto* cssClip = |
| 637 object.getMutableForPainting().objectPaintProperties()->cssClip(); | 645 object.getMutableForPainting().objectPaintProperties()->cssClip(); |
| 638 | 646 |
| 639 // Before we actually create anything, check whether in-flow context and fix
ed-position | 647 // Before we actually create anything, check whether in-flow context and |
| 640 // context has exactly the same clip. Reuse if possible. | 648 // fixed-position context has exactly the same clip. Reuse if possible. |
| 641 if (context.fixedPosition.clip == cssClip->parent()) { | 649 if (context.fixedPosition.clip == cssClip->parent()) { |
| 642 context.fixedPosition.clip = cssClip; | 650 context.fixedPosition.clip = cssClip; |
| 643 } else { | 651 } else { |
| 644 context.fixedPosition.clip = | 652 context.fixedPosition.clip = |
| 645 object.getMutableForPainting() | 653 object.getMutableForPainting() |
| 646 .ensureObjectPaintProperties() | 654 .ensureObjectPaintProperties() |
| 647 .createOrUpdateCssClipFixedPosition( | 655 .createOrUpdateCssClipFixedPosition( |
| 648 context.fixedPosition.clip, | 656 context.fixedPosition.clip, |
| 649 const_cast<TransformPaintPropertyNode*>( | 657 const_cast<TransformPaintPropertyNode*>( |
| 650 cssClip->localTransformSpace()), | 658 cssClip->localTransformSpace()), |
| (...skipping 17 matching lines...) Expand all Loading... |
| 668 | 676 |
| 669 switch (object.styleRef().position()) { | 677 switch (object.styleRef().position()) { |
| 670 case StaticPosition: | 678 case StaticPosition: |
| 671 break; | 679 break; |
| 672 case RelativePosition: | 680 case RelativePosition: |
| 673 context.current.paintOffset += boxModelObject.offsetForInFlowPosition(); | 681 context.current.paintOffset += boxModelObject.offsetForInFlowPosition(); |
| 674 break; | 682 break; |
| 675 case AbsolutePosition: { | 683 case AbsolutePosition: { |
| 676 context.current = context.absolutePosition; | 684 context.current = context.absolutePosition; |
| 677 | 685 |
| 678 // Absolutely positioned content in an inline should be positioned relativ
e to the inline. | 686 // Absolutely positioned content in an inline should be positioned |
| 687 // relative to the inline. |
| 679 const LayoutObject* container = context.containerForAbsolutePosition; | 688 const LayoutObject* container = context.containerForAbsolutePosition; |
| 680 if (container && container->isInFlowPositioned() && | 689 if (container && container->isInFlowPositioned() && |
| 681 container->isLayoutInline()) { | 690 container->isLayoutInline()) { |
| 682 DCHECK(object.isBox()); | 691 DCHECK(object.isBox()); |
| 683 context.current.paintOffset += | 692 context.current.paintOffset += |
| 684 toLayoutInline(container)->offsetForInFlowPositionedInline( | 693 toLayoutInline(container)->offsetForInFlowPositionedInline( |
| 685 toLayoutBox(object)); | 694 toLayoutBox(object)); |
| 686 } | 695 } |
| 687 break; | 696 break; |
| 688 } | 697 } |
| 689 case StickyPosition: | 698 case StickyPosition: |
| 690 context.current.paintOffset += boxModelObject.offsetForInFlowPosition(); | 699 context.current.paintOffset += boxModelObject.offsetForInFlowPosition(); |
| 691 break; | 700 break; |
| 692 case FixedPosition: | 701 case FixedPosition: |
| 693 context.current = context.fixedPosition; | 702 context.current = context.fixedPosition; |
| 694 break; | 703 break; |
| 695 default: | 704 default: |
| 696 ASSERT_NOT_REACHED(); | 705 ASSERT_NOT_REACHED(); |
| 697 } | 706 } |
| 698 | 707 |
| 699 // SVGForeignObject needs paint offset because its viewport offset is baked in
to its location(), | 708 // SVGForeignObject needs paint offset because its viewport offset is baked |
| 700 // while its localSVGTransform() doesn't contain the offset. | 709 // into its location(), while its localSVGTransform() doesn't contain the |
| 710 // offset. |
| 701 if (boxModelObject.isBox() && | 711 if (boxModelObject.isBox() && |
| 702 (!boxModelObject.isSVG() || boxModelObject.isSVGRoot() || | 712 (!boxModelObject.isSVG() || boxModelObject.isSVGRoot() || |
| 703 boxModelObject.isSVGForeignObject())) { | 713 boxModelObject.isSVGForeignObject())) { |
| 704 // TODO(pdr): Several calls in this function walk back up the tree to calcul
ate containers | 714 // TODO(pdr): Several calls in this function walk back up the tree to |
| 705 // (e.g., topLeftLocation, offsetForInFlowPosition*). The containing block a
nd other | 715 // calculate containers (e.g., topLeftLocation, offsetForInFlowPosition*). |
| 706 // containers can be stored on PaintPropertyTreeBuilderContext instead of re
computing them. | 716 // The containing block and other containers can be stored on |
| 717 // PaintPropertyTreeBuilderContext instead of recomputing them. |
| 707 context.current.paintOffset.moveBy( | 718 context.current.paintOffset.moveBy( |
| 708 toLayoutBox(boxModelObject).topLeftLocation()); | 719 toLayoutBox(boxModelObject).topLeftLocation()); |
| 709 // This is a weird quirk that table cells paint as children of table rows, | 720 // This is a weird quirk that table cells paint as children of table rows, |
| 710 // but their location have the row's location baked-in. | 721 // but their location have the row's location baked-in. |
| 711 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). | 722 // Similar adjustment is done in LayoutTableCell::offsetFromContainer(). |
| 712 if (boxModelObject.isTableCell()) { | 723 if (boxModelObject.isTableCell()) { |
| 713 LayoutObject* parentRow = boxModelObject.parent(); | 724 LayoutObject* parentRow = boxModelObject.parent(); |
| 714 ASSERT(parentRow && parentRow->isTableRow()); | 725 ASSERT(parentRow && parentRow->isTableRow()); |
| 715 context.current.paintOffset.moveBy( | 726 context.current.paintOffset.moveBy( |
| 716 -toLayoutBox(parentRow)->topLeftLocation()); | 727 -toLayoutBox(parentRow)->topLeftLocation()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 742 return; | 753 return; |
| 743 | 754 |
| 744 updateOverflowClip(object, context); | 755 updateOverflowClip(object, context); |
| 745 updatePerspective(object, context); | 756 updatePerspective(object, context); |
| 746 updateSvgLocalToBorderBoxTransform(object, context); | 757 updateSvgLocalToBorderBoxTransform(object, context); |
| 747 updateScrollAndScrollTranslation(object, context); | 758 updateScrollAndScrollTranslation(object, context); |
| 748 updateOutOfFlowContext(object, context); | 759 updateOutOfFlowContext(object, context); |
| 749 } | 760 } |
| 750 | 761 |
| 751 } // namespace blink | 762 } // namespace blink |
| OLD | NEW |