Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1782)

Side by Side Diff: third_party/WebKit/Source/core/paint/PaintLayer.cpp

Issue 2650873002: Refactor PaintLayer location and offset calculation especially for floats (Closed)
Patch Set: - Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights
3 * reserved. 3 * reserved.
4 * 4 *
5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. 5 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
6 * 6 *
7 * Other contributors: 7 * Other contributors:
8 * Robert O'Callahan <roc+@cs.cmu.edu> 8 * Robert O'Callahan <roc+@cs.cmu.edu>
9 * David Baron <dbaron@fas.harvard.edu> 9 * David Baron <dbaron@fas.harvard.edu>
10 * Christian Biesinger <cbiesinger@web.de> 10 * Christian Biesinger <cbiesinger@web.de>
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 localPoint.moveBy(toLayoutBox(curr)->physicalLocation()); 794 localPoint.moveBy(toLayoutBox(curr)->physicalLocation());
795 } 795 }
796 curr = curr->container(); 796 curr = curr->container();
797 } 797 }
798 if (curr && curr->isTableRow()) { 798 if (curr && curr->isTableRow()) {
799 // Put ourselves into the row coordinate space. 799 // Put ourselves into the row coordinate space.
800 localPoint.moveBy(-toLayoutBox(curr)->physicalLocation()); 800 localPoint.moveBy(-toLayoutBox(curr)->physicalLocation());
801 } 801 }
802 } 802 }
803 803
804 // Subtract our parent's scroll offset. 804 if (PaintLayer* containingLayer = this->containingLayer()) {
805 if (PaintLayer* containingLayer =
806 layoutObject()->isOutOfFlowPositioned()
807 ? containingLayerForOutOfFlowPositioned()
808 : nullptr) {
809 // For positioned layers, we subtract out the enclosing positioned layer's
810 // scroll offset.
811 if (containingLayer->layoutObject()->hasOverflowClip()) { 805 if (containingLayer->layoutObject()->hasOverflowClip()) {
806 // Subtract our container's scroll offset.
812 IntSize offset = containingLayer->layoutBox()->scrolledContentOffset(); 807 IntSize offset = containingLayer->layoutBox()->scrolledContentOffset();
813 localPoint -= offset; 808 localPoint -= offset;
814 } 809 } else if (layoutObject()->isAbsolutePositioned() &&
815 810 containingLayer->layoutObject()->isInFlowPositioned() &&
816 if (containingLayer->layoutObject()->isInFlowPositioned() && 811 containingLayer->layoutObject()->isLayoutInline()) {
817 containingLayer->layoutObject()->isLayoutInline()) { 812 // Adjust offset for absolute under in-flow positioned inline.
818 LayoutSize offset = 813 LayoutSize offset =
819 toLayoutInline(containingLayer->layoutObject()) 814 toLayoutInline(containingLayer->layoutObject())
820 ->offsetForInFlowPositionedInline(*toLayoutBox(layoutObject())); 815 ->offsetForInFlowPositionedInline(*toLayoutBox(layoutObject()));
821 localPoint += offset; 816 localPoint += offset;
822 } 817 }
823 } else if (parent() && parent()->layoutObject()->hasOverflowClip()) {
824 IntSize scrollOffset = parent()->layoutBox()->scrolledContentOffset();
825 localPoint -= scrollOffset;
826 } 818 }
827 819
828 if (layoutObject()->isInFlowPositioned()) { 820 if (layoutObject()->isInFlowPositioned()) {
829 LayoutSize newOffset = layoutObject()->offsetForInFlowPosition(); 821 LayoutSize newOffset = layoutObject()->offsetForInFlowPosition();
830 if (m_rareData || !newOffset.isZero()) 822 if (m_rareData || !newOffset.isZero())
831 ensureRareData().offsetForInFlowPosition = newOffset; 823 ensureRareData().offsetForInFlowPosition = newOffset;
832 localPoint.move(newOffset); 824 localPoint.move(newOffset);
833 } else if (m_rareData) { 825 } else if (m_rareData) {
834 m_rareData->offsetForInFlowPosition = LayoutSize(); 826 m_rareData->offsetForInFlowPosition = LayoutSize();
835 } 827 }
(...skipping 27 matching lines...) Expand all
863 855
864 const LayoutRect borderBox = toLayoutBox(layoutObject())->borderBoxRect(); 856 const LayoutRect borderBox = toLayoutBox(layoutObject())->borderBoxRect();
865 const ComputedStyle& style = layoutObject()->styleRef(); 857 const ComputedStyle& style = layoutObject()->styleRef();
866 858
867 return FloatPoint(floatValueForLength(style.perspectiveOriginX(), 859 return FloatPoint(floatValueForLength(style.perspectiveOriginX(),
868 borderBox.width().toFloat()), 860 borderBox.width().toFloat()),
869 floatValueForLength(style.perspectiveOriginY(), 861 floatValueForLength(style.perspectiveOriginY(),
870 borderBox.height().toFloat())); 862 borderBox.height().toFloat()));
871 } 863 }
872 864
873 PaintLayer* PaintLayer::containingLayerForOutOfFlowPositioned( 865 PaintLayer* PaintLayer::containingLayer(const PaintLayer* ancestor,
874 const PaintLayer* ancestor, 866 bool* skippedAncestor) const {
875 bool* skippedAncestor) const {
876 // If we have specified an ancestor, surely the caller needs to know whether 867 // If we have specified an ancestor, surely the caller needs to know whether
877 // we skipped it. 868 // we skipped it.
878 DCHECK(!ancestor || skippedAncestor); 869 DCHECK(!ancestor || skippedAncestor);
879 if (skippedAncestor) 870 if (skippedAncestor)
880 *skippedAncestor = false; 871 *skippedAncestor = false;
881 if (layoutObject()->style()->position() == FixedPosition) { 872
873 LayoutObject* layoutObject = this->layoutObject();
874 if (layoutObject->isColumnSpanAll() ||
875 layoutObject->isFloatingWithNonContainingBlockParent()) {
876 Optional<LayoutObject::AncestorSkipInfo> skipInfo;
877 if (skippedAncestor)
878 skipInfo.emplace(ancestor->layoutObject());
879 if (auto containingBlock = layoutObject->containingBlock(
880 skippedAncestor ? &*skipInfo : nullptr)) {
881 if (skippedAncestor && skipInfo->ancestorSkipped())
882 *skippedAncestor = true;
883 return containingBlock->enclosingLayer();
884 }
885 return nullptr;
886 }
887
888 if (layoutObject->isOutOfFlowPositioned()) {
889 auto canContainThisLayer =
890 layoutObject->isFixedPositioned()
891 ? &LayoutObject::canContainFixedPositionObjects
892 : &LayoutObject::canContainAbsolutePositionObjects;
893
882 PaintLayer* curr = parent(); 894 PaintLayer* curr = parent();
883 while (curr && !curr->layoutObject()->canContainFixedPositionObjects()) { 895 while (curr && !(curr->layoutObject()->*canContainThisLayer)()) {
884 if (skippedAncestor && curr == ancestor) 896 if (skippedAncestor && curr == ancestor)
885 *skippedAncestor = true; 897 *skippedAncestor = true;
886 curr = curr->parent(); 898 curr = curr->parent();
887 } 899 }
888
889 return curr; 900 return curr;
890 } 901 }
891 902
892 PaintLayer* curr = parent(); 903 return parent();
893 while (curr && !curr->layoutObject()->canContainAbsolutePositionObjects()) {
894 if (skippedAncestor && curr == ancestor)
895 *skippedAncestor = true;
896 curr = curr->parent();
897 }
898
899 return curr;
900 } 904 }
901 905
902 PaintLayer* PaintLayer::enclosingTransformedAncestor() const { 906 PaintLayer* PaintLayer::enclosingTransformedAncestor() const {
903 PaintLayer* curr = parent(); 907 PaintLayer* curr = parent();
904 while (curr && !curr->isRootLayer() && !curr->transform()) 908 while (curr && !curr->isRootLayer() && !curr->transform())
905 curr = curr->parent(); 909 curr = curr->parent();
906 910
907 return curr; 911 return curr;
908 } 912 }
909 913
910 LayoutPoint PaintLayer::computeOffsetFromTransformedAncestor() const { 914 LayoutPoint PaintLayer::computeOffsetFromTransformedAncestor() const {
911 TransformState transformState(TransformState::ApplyTransformDirection, 915 TransformState transformState(TransformState::ApplyTransformDirection,
912 FloatPoint()); 916 FloatPoint());
913 layoutObject()->mapLocalToAncestor( 917 layoutObject()->mapLocalToAncestor(
914 transformAncestor() ? transformAncestor()->layoutObject() : nullptr, 918 transformAncestor() ? transformAncestor()->layoutObject() : nullptr,
915 transformState, 0); 919 transformState, 0);
916 transformState.flatten(); 920 transformState.flatten();
917 return LayoutPoint(transformState.lastPlanarPoint()); 921 return LayoutPoint(transformState.lastPlanarPoint());
918 } 922 }
919 923
920 PaintLayer* PaintLayer::compositingContainer() const { 924 PaintLayer* PaintLayer::compositingContainer() const {
921 if (!stackingNode()->isStacked()) { 925 if (!stackingNode()->isStacked())
922 // Floats have special painting order, which has complicated semantics. 926 return containingLayer();
923 // See the comments around FloatObject::setShouldPaint.
924 if (m_layoutObject->isFloating() && m_layoutObject->parent() &&
925 !m_layoutObject->parent()->isLayoutBlockFlow())
926 return m_layoutObject->containingBlock()->enclosingLayer();
927
928 return parent();
929 }
930 if (PaintLayerStackingNode* ancestorStackingNode = 927 if (PaintLayerStackingNode* ancestorStackingNode =
931 stackingNode()->ancestorStackingContextNode()) 928 stackingNode()->ancestorStackingContextNode())
932 return ancestorStackingNode->layer(); 929 return ancestorStackingNode->layer();
933 return nullptr; 930 return nullptr;
934 } 931 }
935 932
936 bool PaintLayer::isPaintInvalidationContainer() const { 933 bool PaintLayer::isPaintInvalidationContainer() const {
937 return compositingState() == PaintsIntoOwnBacking || 934 return compositingState() == PaintsIntoOwnBacking ||
938 compositingState() == PaintsIntoGroupedBacking; 935 compositingState() == PaintsIntoGroupedBacking;
939 } 936 }
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 } 1398 }
1402 1399
1403 // Returns the layer reached on the walk up towards the ancestor. 1400 // Returns the layer reached on the walk up towards the ancestor.
1404 static inline const PaintLayer* accumulateOffsetTowardsAncestor( 1401 static inline const PaintLayer* accumulateOffsetTowardsAncestor(
1405 const PaintLayer* layer, 1402 const PaintLayer* layer,
1406 const PaintLayer* ancestorLayer, 1403 const PaintLayer* ancestorLayer,
1407 LayoutPoint& location) { 1404 LayoutPoint& location) {
1408 DCHECK(ancestorLayer != layer); 1405 DCHECK(ancestorLayer != layer);
1409 1406
1410 const LayoutBoxModelObject* layoutObject = layer->layoutObject(); 1407 const LayoutBoxModelObject* layoutObject = layer->layoutObject();
1411 EPosition position = layoutObject->style()->position();
1412 1408
1413 if (position == FixedPosition && 1409 if (layoutObject->isFixedPositioned() &&
1414 (!ancestorLayer || ancestorLayer == layoutObject->view()->layer())) { 1410 (!ancestorLayer || ancestorLayer == layoutObject->view()->layer())) {
1415 // If the fixed layer's container is the root, just add in the offset of the 1411 // If the fixed layer's container is the root, just add in the offset of the
1416 // view. We can obtain this by calling localToAbsolute() on the LayoutView. 1412 // view. We can obtain this by calling localToAbsolute() on the LayoutView.
1417 FloatPoint absPos = layoutObject->localToAbsolute(); 1413 FloatPoint absPos = layoutObject->localToAbsolute();
1418 location += LayoutSize(absPos.x(), absPos.y()); 1414 location += LayoutSize(absPos.x(), absPos.y());
1419 return ancestorLayer; 1415 return ancestorLayer;
1420 } 1416 }
1421 1417
1422 PaintLayer* parentLayer = nullptr; 1418 bool foundAncestorFirst;
1423 if (position == AbsolutePosition || position == FixedPosition || 1419 PaintLayer* containingLayer =
1424 (layoutObject->isFloating() && layoutObject->parent() && 1420 layer->containingLayer(ancestorLayer, &foundAncestorFirst);
1425 !layoutObject->parent()->isLayoutBlockFlow())) {
1426 bool foundAncestorFirst = false;
1427 if (layoutObject->isFloating()) {
1428 Optional<LayoutObject::AncestorSkipInfo> skipInfo;
1429 if (ancestorLayer)
1430 skipInfo.emplace(ancestorLayer->layoutObject());
1431 if (auto* containingBlock = layoutObject->containingBlock(
1432 ancestorLayer ? &*skipInfo : nullptr)) {
1433 parentLayer = containingBlock->enclosingLayer();
1434 foundAncestorFirst = ancestorLayer && skipInfo->ancestorSkipped();
1435 }
1436 } else {
1437 parentLayer = layer->containingLayerForOutOfFlowPositioned(
1438 ancestorLayer, &foundAncestorFirst);
1439 }
1440 1421
1441 if (foundAncestorFirst) { 1422 if (foundAncestorFirst) {
1442 // Found ancestorLayer before the container of the out-of-flow object, so 1423 // Found ancestorLayer before the containing layer, so compute offset of
1443 // compute offset of both relative to the container and subtract. 1424 // both relative to the container and subtract.
1425 LayoutPoint thisCoords;
1426 layer->convertToLayerCoords(containingLayer, thisCoords);
1444 1427
1445 LayoutPoint thisCoords; 1428 LayoutPoint ancestorCoords;
1446 layer->convertToLayerCoords(parentLayer, thisCoords); 1429 ancestorLayer->convertToLayerCoords(containingLayer, ancestorCoords);
1447 1430
1448 LayoutPoint ancestorCoords; 1431 location += (thisCoords - ancestorCoords);
1449 ancestorLayer->convertToLayerCoords(parentLayer, ancestorCoords); 1432 return ancestorLayer;
1450
1451 location += (thisCoords - ancestorCoords);
1452 return ancestorLayer;
1453 }
1454 } else if (layoutObject->isColumnSpanAll()) {
1455 LayoutBlock* multicolContainer = layoutObject->containingBlock();
1456 DCHECK(toLayoutBlockFlow(multicolContainer)->multiColumnFlowThread());
1457 parentLayer = multicolContainer->layer();
1458 DCHECK(parentLayer);
1459 } else {
1460 parentLayer = layer->parent();
1461 } 1433 }
1462 1434
1463 if (!parentLayer) 1435 if (!containingLayer)
1464 return nullptr; 1436 return nullptr;
1465 1437
1466 location += layer->location(); 1438 location += layer->location();
1467 return parentLayer; 1439 return containingLayer;
1468 } 1440 }
1469 1441
1470 void PaintLayer::convertToLayerCoords(const PaintLayer* ancestorLayer, 1442 void PaintLayer::convertToLayerCoords(const PaintLayer* ancestorLayer,
1471 LayoutPoint& location) const { 1443 LayoutPoint& location) const {
1472 if (ancestorLayer == this) 1444 if (ancestorLayer == this)
1473 return; 1445 return;
1474 1446
1475 const PaintLayer* currLayer = this; 1447 const PaintLayer* currLayer = this;
1476 while (currLayer && currLayer != ancestorLayer) 1448 while (currLayer && currLayer != ancestorLayer)
1477 currLayer = 1449 currLayer =
(...skipping 1743 matching lines...) Expand 10 before | Expand all | Expand 10 after
3221 } 3193 }
3222 3194
3223 void showLayerTree(const blink::LayoutObject* layoutObject) { 3195 void showLayerTree(const blink::LayoutObject* layoutObject) {
3224 if (!layoutObject) { 3196 if (!layoutObject) {
3225 LOG(INFO) << "Cannot showLayerTree. Root is (nil)"; 3197 LOG(INFO) << "Cannot showLayerTree. Root is (nil)";
3226 return; 3198 return;
3227 } 3199 }
3228 showLayerTree(layoutObject->enclosingLayer()); 3200 showLayerTree(layoutObject->enclosingLayer());
3229 } 3201 }
3230 #endif 3202 #endif
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/paint/PaintLayer.h ('k') | third_party/WebKit/Source/core/paint/PaintLayerTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698