OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2007 David Smith (catfish.man@gmail.com) | 4 * (C) 2007 David Smith (catfish.man@gmail.com) |
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. | 5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. |
6 * All rights reserved. | 6 * All rights reserved. |
7 * Copyright (C) Research In Motion Limited 2010. All rights reserved. | 7 * Copyright (C) Research In Motion Limited 2010. All rights reserved. |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 } | 746 } |
747 return false; | 747 return false; |
748 } | 748 } |
749 | 749 |
750 void LayoutBlock::layoutPositionedObjects(bool relayoutChildren, | 750 void LayoutBlock::layoutPositionedObjects(bool relayoutChildren, |
751 PositionedLayoutBehavior info) { | 751 PositionedLayoutBehavior info) { |
752 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); | 752 TrackedLayoutBoxListHashSet* positionedDescendants = positionedObjects(); |
753 if (!positionedDescendants) | 753 if (!positionedDescendants) |
754 return; | 754 return; |
755 | 755 |
756 bool isPaginated = view()->layoutState()->isPaginated(); | |
757 | |
758 for (auto* positionedObject : *positionedDescendants) { | 756 for (auto* positionedObject : *positionedDescendants) { |
759 positionedObject->setMayNeedPaintInvalidation(); | 757 layoutPositionedObject(positionedObject, relayoutChildren, info); |
760 | |
761 SubtreeLayoutScope layoutScope(*positionedObject); | |
762 // If positionedObject is fixed-positioned and moves with an absolute- | |
763 // positioned ancestor (other than the LayoutView, which cannot move), | |
764 // mark it for layout now. | |
765 markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope); | |
766 if (info == LayoutOnlyFixedPositionedObjects) { | |
767 positionedObject->layoutIfNeeded(); | |
768 continue; | |
769 } | |
770 | |
771 if (!positionedObject->normalChildNeedsLayout() && | |
772 (relayoutChildren || m_heightAvailableToChildrenChanged || | |
773 needsLayoutDueToStaticPosition(positionedObject))) | |
774 layoutScope.setChildNeedsLayout(positionedObject); | |
775 | |
776 // If relayoutChildren is set and the child has percentage padding or an | |
777 // embedded content box, we also need to invalidate the childs pref widths. | |
778 if (relayoutChildren && | |
779 positionedObject->needsPreferredWidthsRecalculation()) | |
780 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis); | |
781 | |
782 LayoutUnit logicalTopEstimate; | |
783 bool needsBlockDirectionLocationSetBeforeLayout = | |
784 isPaginated && | |
785 positionedObject->getPaginationBreakability() != ForbidBreaks; | |
786 if (needsBlockDirectionLocationSetBeforeLayout) { | |
787 // Out-of-flow objects are normally positioned after layout (while in-flow | |
788 // objects are positioned before layout). If the child object is paginated | |
789 // in the same context as we are, estimate its logical top now. We need to | |
790 // know this up-front, to correctly evaluate if we need to mark for | |
791 // relayout, and, if our estimate is correct, we'll even be able to insert | |
792 // correct pagination struts on the first attempt. | |
793 LogicalExtentComputedValues computedValues; | |
794 positionedObject->computeLogicalHeight(positionedObject->logicalHeight(), | |
795 positionedObject->logicalTop(), | |
796 computedValues); | |
797 logicalTopEstimate = computedValues.m_position; | |
798 positionedObject->setLogicalTop(logicalTopEstimate); | |
799 } | |
800 | |
801 if (!positionedObject->needsLayout()) | |
802 markChildForPaginationRelayoutIfNeeded(*positionedObject, layoutScope); | |
803 | |
804 // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout() | |
805 // here instead of a full layout. Need to investigate why it does not | |
806 // trigger the correct invalidations in that case. crbug.com/350756 | |
807 if (info == ForcedLayoutAfterContainingBlockMoved) | |
808 positionedObject->setNeedsLayout(LayoutInvalidationReason::AncestorMoved, | |
809 MarkOnlyThis); | |
810 | |
811 positionedObject->layoutIfNeeded(); | |
812 | |
813 LayoutObject* parent = positionedObject->parent(); | |
814 bool layoutChanged = false; | |
815 if (parent->isFlexibleBox() && | |
816 toLayoutFlexibleBox(parent)->setStaticPositionForPositionedLayout( | |
817 *positionedObject)) { | |
818 // The static position of an abspos child of a flexbox depends on its size | |
819 // (for example, they can be centered). So we may have to reposition the | |
820 // item after layout. | |
821 // TODO(cbiesinger): We could probably avoid a layout here and just | |
822 // reposition? | |
823 positionedObject->forceChildLayout(); | |
824 layoutChanged = true; | |
825 } | |
826 | |
827 // Lay out again if our estimate was wrong. | |
828 if (!layoutChanged && needsBlockDirectionLocationSetBeforeLayout && | |
829 logicalTopEstimate != logicalTopForChild(*positionedObject)) | |
830 positionedObject->forceChildLayout(); | |
831 | |
832 if (isPaginated) | |
833 updateFragmentationInfoForChild(*positionedObject); | |
834 } | 758 } |
835 } | 759 } |
836 | 760 |
| 761 void LayoutBlock::layoutPositionedObject(LayoutBox* positionedObject, |
| 762 bool relayoutChildren, |
| 763 PositionedLayoutBehavior info) { |
| 764 positionedObject->setMayNeedPaintInvalidation(); |
| 765 |
| 766 SubtreeLayoutScope layoutScope(*positionedObject); |
| 767 // If positionedObject is fixed-positioned and moves with an absolute- |
| 768 // positioned ancestor (other than the LayoutView, which cannot move), |
| 769 // mark it for layout now. |
| 770 markFixedPositionObjectForLayoutIfNeeded(positionedObject, layoutScope); |
| 771 if (info == LayoutOnlyFixedPositionedObjects) { |
| 772 positionedObject->layoutIfNeeded(); |
| 773 return; |
| 774 } |
| 775 |
| 776 if (!positionedObject->normalChildNeedsLayout() && |
| 777 (relayoutChildren || m_heightAvailableToChildrenChanged || |
| 778 needsLayoutDueToStaticPosition(positionedObject))) |
| 779 layoutScope.setChildNeedsLayout(positionedObject); |
| 780 |
| 781 // If relayoutChildren is set and the child has percentage padding or an |
| 782 // embedded content box, we also need to invalidate the childs pref widths. |
| 783 if (relayoutChildren && positionedObject->needsPreferredWidthsRecalculation()) |
| 784 positionedObject->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
| 785 |
| 786 LayoutUnit logicalTopEstimate; |
| 787 bool isPaginated = view()->layoutState()->isPaginated(); |
| 788 bool needsBlockDirectionLocationSetBeforeLayout = |
| 789 isPaginated && |
| 790 positionedObject->getPaginationBreakability() != ForbidBreaks; |
| 791 if (needsBlockDirectionLocationSetBeforeLayout) { |
| 792 // Out-of-flow objects are normally positioned after layout (while in-flow |
| 793 // objects are positioned before layout). If the child object is paginated |
| 794 // in the same context as we are, estimate its logical top now. We need to |
| 795 // know this up-front, to correctly evaluate if we need to mark for |
| 796 // relayout, and, if our estimate is correct, we'll even be able to insert |
| 797 // correct pagination struts on the first attempt. |
| 798 LogicalExtentComputedValues computedValues; |
| 799 positionedObject->computeLogicalHeight(positionedObject->logicalHeight(), |
| 800 positionedObject->logicalTop(), |
| 801 computedValues); |
| 802 logicalTopEstimate = computedValues.m_position; |
| 803 positionedObject->setLogicalTop(logicalTopEstimate); |
| 804 } |
| 805 |
| 806 if (!positionedObject->needsLayout()) |
| 807 markChildForPaginationRelayoutIfNeeded(*positionedObject, layoutScope); |
| 808 |
| 809 // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout() |
| 810 // here instead of a full layout. Need to investigate why it does not |
| 811 // trigger the correct invalidations in that case. crbug.com/350756 |
| 812 if (info == ForcedLayoutAfterContainingBlockMoved) { |
| 813 positionedObject->setNeedsLayout(LayoutInvalidationReason::AncestorMoved, |
| 814 MarkOnlyThis); |
| 815 } |
| 816 |
| 817 positionedObject->layoutIfNeeded(); |
| 818 |
| 819 LayoutObject* parent = positionedObject->parent(); |
| 820 bool layoutChanged = false; |
| 821 if (parent->isFlexibleBox() && |
| 822 toLayoutFlexibleBox(parent)->setStaticPositionForPositionedLayout( |
| 823 *positionedObject)) { |
| 824 // The static position of an abspos child of a flexbox depends on its size |
| 825 // (for example, they can be centered). So we may have to reposition the |
| 826 // item after layout. |
| 827 // TODO(cbiesinger): We could probably avoid a layout here and just |
| 828 // reposition? |
| 829 positionedObject->forceChildLayout(); |
| 830 layoutChanged = true; |
| 831 } |
| 832 |
| 833 // Lay out again if our estimate was wrong. |
| 834 if (!layoutChanged && needsBlockDirectionLocationSetBeforeLayout && |
| 835 logicalTopEstimate != logicalTopForChild(*positionedObject)) |
| 836 positionedObject->forceChildLayout(); |
| 837 |
| 838 if (isPaginated) |
| 839 updateFragmentationInfoForChild(*positionedObject); |
| 840 } |
| 841 |
837 void LayoutBlock::markPositionedObjectsForLayout() { | 842 void LayoutBlock::markPositionedObjectsForLayout() { |
838 if (TrackedLayoutBoxListHashSet* positionedDescendants = | 843 if (TrackedLayoutBoxListHashSet* positionedDescendants = |
839 positionedObjects()) { | 844 positionedObjects()) { |
840 for (auto* descendant : *positionedDescendants) | 845 for (auto* descendant : *positionedDescendants) |
841 descendant->setChildNeedsLayout(); | 846 descendant->setChildNeedsLayout(); |
842 } | 847 } |
843 } | 848 } |
844 | 849 |
845 void LayoutBlock::paint(const PaintInfo& paintInfo, | 850 void LayoutBlock::paint(const PaintInfo& paintInfo, |
846 const LayoutPoint& paintOffset) const { | 851 const LayoutPoint& paintOffset) const { |
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2207 } | 2212 } |
2208 | 2213 |
2209 return availableHeight; | 2214 return availableHeight; |
2210 } | 2215 } |
2211 | 2216 |
2212 bool LayoutBlock::hasDefiniteLogicalHeight() const { | 2217 bool LayoutBlock::hasDefiniteLogicalHeight() const { |
2213 return availableLogicalHeightForPercentageComputation() != LayoutUnit(-1); | 2218 return availableLogicalHeightForPercentageComputation() != LayoutUnit(-1); |
2214 } | 2219 } |
2215 | 2220 |
2216 } // namespace blink | 2221 } // namespace blink |
OLD | NEW |