OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |