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

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp

Issue 2532573003: Position a float before laying it out. (Closed)
Patch Set: Created 4 years 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) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 3515 matching lines...) Expand 10 before | Expand all | Expand 10 after
3526 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 3526 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3527 FloatingObjectSetIterator it = 3527 FloatingObjectSetIterator it =
3528 floatingObjectSet.find<FloatingObjectHashTranslator>(&floatBox); 3528 floatingObjectSet.find<FloatingObjectHashTranslator>(&floatBox);
3529 if (it != floatingObjectSet.end()) 3529 if (it != floatingObjectSet.end())
3530 return it->get(); 3530 return it->get();
3531 } 3531 }
3532 3532
3533 // Create the special object entry & append it to the list 3533 // Create the special object entry & append it to the list
3534 3534
3535 std::unique_ptr<FloatingObject> newObj = FloatingObject::create(&floatBox); 3535 std::unique_ptr<FloatingObject> newObj = FloatingObject::create(&floatBox);
3536
3537 // TODO(mstensho): Avoid laying out before positioning the object, as that's
3538 // bad for pagination.
3539 floatBox.layoutIfNeeded();
3540
3541 setLogicalWidthForFloat(*newObj, logicalWidthForChild(floatBox) +
3542 marginStartForChild(floatBox) +
3543 marginEndForChild(floatBox));
3544
3545 return m_floatingObjects->add(std::move(newObj)); 3536 return m_floatingObjects->add(std::move(newObj));
3546 } 3537 }
3547 3538
3548 void LayoutBlockFlow::removeFloatingObject(LayoutBox* floatBox) { 3539 void LayoutBlockFlow::removeFloatingObject(LayoutBox* floatBox) {
3549 if (m_floatingObjects) { 3540 if (m_floatingObjects) {
3550 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set(); 3541 const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
3551 FloatingObjectSetIterator it = 3542 FloatingObjectSetIterator it =
3552 floatingObjectSet.find<FloatingObjectHashTranslator>(floatBox); 3543 floatingObjectSet.find<FloatingObjectHashTranslator>(floatBox);
3553 if (it != floatingObjectSet.end()) { 3544 if (it != floatingObjectSet.end()) {
3554 FloatingObject& floatingObject = *it->get(); 3545 FloatingObject& floatingObject = *it->get();
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
3668 bool isPaginated = view()->layoutState()->isPaginated(); 3659 bool isPaginated = view()->layoutState()->isPaginated();
3669 if (isPaginated && !childrenInline()) { 3660 if (isPaginated && !childrenInline()) {
3670 // Forced breaks are inserted at class A break points. Floats may be 3661 // Forced breaks are inserted at class A break points. Floats may be
3671 // affected by a break-after value on the previous in-flow sibling. 3662 // affected by a break-after value on the previous in-flow sibling.
3672 if (LayoutBox* previousInFlowBox = child.previousInFlowSiblingBox()) { 3663 if (LayoutBox* previousInFlowBox = child.previousInFlowSiblingBox()) {
3673 logicalTopMarginEdge = applyForcedBreak(logicalTopMarginEdge, 3664 logicalTopMarginEdge = applyForcedBreak(logicalTopMarginEdge,
3674 previousInFlowBox->breakAfter()); 3665 previousInFlowBox->breakAfter());
3675 } 3666 }
3676 } 3667 }
3677 3668
3669 if (child.needsLayout()) {
3670 if (isPaginated) {
3671 // Before we can lay out the float, we need to estimate a position for
3672 // it. In order to do that, we first need to know its block start margin.
3673 child.computeAndSetBlockDirectionMargins(this);
3674 LayoutUnit marginBefore = marginBeforeForChild(child);
3675
3676 // We have found the highest possible position for the float, so we'll
3677 // lay out right there. Later on, we may be pushed further down by
3678 // adjacent floats which we don't fit beside, or pushed by fragmentation
3679 // if we need to break before the top margin edge of the float.
3680 setLogicalTopForChild(child, logicalTopMarginEdge + marginBefore);
3681 child.layout();
3682
3683 // May need to push the float to the next fragmentainer before attempting
3684 // to place it.
3685 logicalTopMarginEdge =
3686 adjustFloatLogicalTopForPagination(child, logicalTopMarginEdge);
3687 } else {
3688 child.layout();
3689 }
3690 }
3691
3692 LayoutUnit marginStart = marginStartForChild(child);
3693 LayoutUnit marginEnd = marginEndForChild(child);
3694 setLogicalWidthForFloat(
3695 floatingObject, logicalWidthForChild(child) + marginStart + marginEnd);
3696
3697 // We have determined the logical width of the float. This is enough
3698 // information to fit it among other floats according to float positioning
3699 // rules. Note that logical *height* doesn't really matter yet (until we're
3700 // going to place subsequent floats or other objects that are affected by
3701 // floats), since no float may be positioned above the outer logical top edge
3702 // of any other earlier float in the block formatting context.
3678 LayoutUnit marginBefore = marginBeforeForChild(child); 3703 LayoutUnit marginBefore = marginBeforeForChild(child);
3679 LayoutUnit marginAfter = marginAfterForChild(child); 3704 LayoutUnit marginAfter = marginAfterForChild(child);
3680 LayoutPoint floatLogicalLocation = 3705 LayoutPoint floatLogicalLocation =
3681 computeLogicalLocationForFloat(floatingObject, logicalTopMarginEdge); 3706 computeLogicalLocationForFloat(floatingObject, logicalTopMarginEdge);
3682 logicalTopMarginEdge = floatLogicalLocation.y(); 3707 logicalTopMarginEdge = floatLogicalLocation.y();
3683
3684 setLogicalTopForChild(child, logicalTopMarginEdge + marginBefore); 3708 setLogicalTopForChild(child, logicalTopMarginEdge + marginBefore);
3685 3709
3686 SubtreeLayoutScope layoutScope(child); 3710 SubtreeLayoutScope layoutScope(child);
3687 if (!child.needsLayout())
3688 markChildForPaginationRelayoutIfNeeded(child, layoutScope);
3689 3711
3712 // A new position may mean that we need to insert, move or remove breaks
3713 // inside the float. We may also need to lay out if we just ceased to be
3714 // fragmented, in order to remove pagination struts inside the child.
3715 markChildForPaginationRelayoutIfNeeded(child, layoutScope);
3690 child.layoutIfNeeded(); 3716 child.layoutIfNeeded();
3691 3717
3692 if (isPaginated) { 3718 if (isPaginated) {
3719 // We may have to insert a break before the float.
3693 LayoutUnit newLogicalTopMarginEdge = 3720 LayoutUnit newLogicalTopMarginEdge =
3694 adjustFloatLogicalTopForPagination(child, logicalTopMarginEdge); 3721 adjustFloatLogicalTopForPagination(child, logicalTopMarginEdge);
3695 if (logicalTopMarginEdge != newLogicalTopMarginEdge) { 3722 if (logicalTopMarginEdge != newLogicalTopMarginEdge) {
3723 // We had already found a location for the float, but a soft
3724 // fragmentainer break then made us push it further down. This may affect
3725 // the inline position of the float (since we may no longer be beside the
3726 // same floats anymore). Block position will remain unaffected, though.
3696 floatLogicalLocation = computeLogicalLocationForFloat( 3727 floatLogicalLocation = computeLogicalLocationForFloat(
3697 floatingObject, newLogicalTopMarginEdge); 3728 floatingObject, newLogicalTopMarginEdge);
3698 logicalTopMarginEdge = floatLogicalLocation.y(); 3729 DCHECK_EQ(floatLogicalLocation.y(), newLogicalTopMarginEdge);
3730 logicalTopMarginEdge = newLogicalTopMarginEdge;
3731
3699 setLogicalTopForChild(child, logicalTopMarginEdge + marginBefore); 3732 setLogicalTopForChild(child, logicalTopMarginEdge + marginBefore);
3700 3733
3734 // Pushing the child to the next fragmentainer most likely means that we
3735 // need to recalculate pagination struts inside it.
3701 if (child.isLayoutBlock()) 3736 if (child.isLayoutBlock())
3702 child.setChildNeedsLayout(MarkOnlyThis); 3737 child.setChildNeedsLayout(MarkOnlyThis);
3703 child.layoutIfNeeded(); 3738 child.layoutIfNeeded();
3704 } 3739 }
3705 } 3740 }
3706 3741
3707 LayoutUnit childLogicalLeftMargin = style()->isLeftToRightDirection() 3742 LayoutUnit childLogicalLeftMargin =
3708 ? marginStartForChild(child) 3743 style()->isLeftToRightDirection() ? marginStart : marginEnd;
3709 : marginEndForChild(child);
3710 setLogicalLeftForChild(child, 3744 setLogicalLeftForChild(child,
3711 floatLogicalLocation.x() + childLogicalLeftMargin); 3745 floatLogicalLocation.x() + childLogicalLeftMargin);
3712 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x()); 3746 setLogicalLeftForFloat(floatingObject, floatLogicalLocation.x());
3713 setLogicalTopForFloat(floatingObject, logicalTopMarginEdge); 3747 setLogicalTopForFloat(floatingObject, logicalTopMarginEdge);
3714 setLogicalHeightForFloat(floatingObject, logicalHeightForChild(child) + 3748 setLogicalHeightForFloat(floatingObject, logicalHeightForChild(child) +
3715 marginBefore + marginAfter); 3749 marginBefore + marginAfter);
3716 3750
3717 if (ShapeOutsideInfo* shapeOutside = child.shapeOutsideInfo()) 3751 if (ShapeOutsideInfo* shapeOutside = child.shapeOutsideInfo())
3718 shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(child)); 3752 shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(child));
3719 3753
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
4538 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState); 4572 return LayoutBlock::invalidatePaintIfNeeded(paintInvalidationState);
4539 } 4573 }
4540 4574
4541 void LayoutBlockFlow::invalidateDisplayItemClients( 4575 void LayoutBlockFlow::invalidateDisplayItemClients(
4542 PaintInvalidationReason invalidationReason) const { 4576 PaintInvalidationReason invalidationReason) const {
4543 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients( 4577 BlockFlowPaintInvalidator(*this).invalidateDisplayItemClients(
4544 invalidationReason); 4578 invalidationReason);
4545 } 4579 }
4546 4580
4547 } // namespace blink 4581 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698