Changeset 240253 in webkit


Ignore:
Timestamp:
Jan 22, 2019 9:25:59 AM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][Floats] Decouple clearance computation and margin collapsing reset.
https://bugs.webkit.org/show_bug.cgi?id=193670

Reviewed by Antti Koivisto.

Move margin collapsing reset logic from FloatingContext to BlockFormattingContext. It's the BlockFormattingContext's job to do.
This is also in preparation for adding clear to static position.

  • layout/FormattingContext.cpp:

(WebCore::Layout::FormattingContext::mapTopToAncestor):
(WebCore::Layout::FormattingContext::mapTopLeftToAncestor): Deleted.

  • layout/FormattingContext.h:
  • layout/blockformatting/BlockFormattingContext.cpp:

(WebCore::Layout::BlockFormattingContext::computeVerticalPositionForFloatClear const):

  • layout/floats/FloatingContext.cpp:

(WebCore::Layout::FloatingContext::verticalPositionWithClearance const):

  • layout/floats/FloatingContext.h:
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r240252 r240253  
     12019-01-22  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][Floats] Decouple clearance computation and margin collapsing reset.
     4        https://bugs.webkit.org/show_bug.cgi?id=193670
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Move margin collapsing reset logic from FloatingContext to BlockFormattingContext. It's the BlockFormattingContext's job to do.
     9        This is also in preparation for adding clear to static position.
     10
     11        * layout/FormattingContext.cpp:
     12        (WebCore::Layout::FormattingContext::mapTopToAncestor):
     13        (WebCore::Layout::FormattingContext::mapTopLeftToAncestor): Deleted.
     14        * layout/FormattingContext.h:
     15        * layout/blockformatting/BlockFormattingContext.cpp:
     16        (WebCore::Layout::BlockFormattingContext::computeVerticalPositionForFloatClear const):
     17        * layout/floats/FloatingContext.cpp:
     18        (WebCore::Layout::FloatingContext::verticalPositionWithClearance const):
     19        * layout/floats/FloatingContext.h:
     20
    1212019-01-22  Frederic Wang  <fwang@igalia.com>
    222
  • trunk/Source/WebCore/layout/FormattingContext.cpp

    r239903 r240253  
    185185}
    186186
    187 Point FormattingContext::mapTopLeftToAncestor(const LayoutState& layoutState, const Box& layoutBox, const Container& ancestor)
     187LayoutUnit FormattingContext::mapTopToAncestor(const LayoutState& layoutState, const Box& layoutBox, const Container& ancestor)
    188188{
    189189    ASSERT(layoutBox.isDescendantOf(ancestor));
    190     return mapCoordinateToAncestor(layoutState, layoutState.displayBoxForLayoutBox(layoutBox).topLeft(), *layoutBox.containingBlock(), ancestor);
     190    auto top = layoutState.displayBoxForLayoutBox(layoutBox).top();
     191    auto* container = layoutBox.containingBlock();
     192    for (; container && container != &ancestor; container = container->containingBlock())
     193        top += layoutState.displayBoxForLayoutBox(*container).top();
     194    return top;
    191195}
    192196
  • trunk/Source/WebCore/layout/FormattingContext.h

    r239903 r240253  
    6060
    6161    static Display::Box mapBoxToAncestor(const LayoutState&, const Box&, const Container& ancestor);
    62     static Point mapTopLeftToAncestor(const LayoutState&, const Box&, const Container& ancestor);
     62    static LayoutUnit mapTopToAncestor(const LayoutState&, const Box&, const Container& ancestor);
    6363    static Point mapCoordinateToAncestor(const LayoutState&, Point, const Container& containingBlock, const Container& ancestor);
    6464
  • trunk/Source/WebCore/layout/blockformatting/BlockFormattingContext.cpp

    r240093 r240253  
    292292        return;
    293293
    294     auto& layoutState = this->layoutState();
    295294    // For formatting roots, we already precomputed final position.
    296295    if (!layoutBox.establishesFormattingContext())
     
    298297    ASSERT(hasPrecomputedMarginBefore(layoutBox));
    299298
    300     if (auto verticalPositionWithClearance = floatingContext.verticalPositionWithClearance(layoutBox))
    301         layoutState.displayBoxForLayoutBox(layoutBox).setTop(*verticalPositionWithClearance);
     299    // 1. Compute and adjust the vertical position with clearance.
     300    // 2. Reset margin collapsing with previous in-flow sibling if clerance is present.
     301    auto verticalPositionAndClearance = floatingContext.verticalPositionWithClearance(layoutBox);
     302    if (!verticalPositionAndClearance.position)
     303        return;
     304
     305    // Adjust vertical position first.
     306    auto& layoutState = this->layoutState();
     307    auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
     308    displayBox.setTop(*verticalPositionAndClearance.position);
     309    if (!verticalPositionAndClearance.clearance)
     310        return;
     311
     312    displayBox.setHasClearance();
     313    // Adjust margin collapsing with clearance.
     314    auto* previousInFlowSibling = layoutBox.previousInFlowSibling();
     315    if (!previousInFlowSibling)
     316        return;
     317
     318    // Clearance inhibits margin collapsing. Let's reset the relevant adjoining margins.
     319    // Does this box with clearance actually collapse its margin before with the previous inflow box's margin after?
     320    auto verticalMargin = displayBox.verticalMargin();
     321    if (!verticalMargin.hasCollapsedValues() || !verticalMargin.collapsedValues().before)
     322        return;
     323
     324    // Reset previous after and current before margin values to non-collapsing.
     325    auto& previousInFlowDisplayBox = layoutState.displayBoxForLayoutBox(*previousInFlowSibling);
     326    auto previousVerticalMargin = previousInFlowDisplayBox.verticalMargin();
     327    ASSERT(previousVerticalMargin.hasCollapsedValues() && previousVerticalMargin.collapsedValues().after);
     328
     329    previousVerticalMargin.setCollapsedValues({ previousVerticalMargin.collapsedValues().before, { } });
     330    verticalMargin.setCollapsedValues({ { }, verticalMargin.collapsedValues().after });
     331
     332    previousInFlowDisplayBox.setVerticalMargin(previousVerticalMargin);
     333    displayBox.setVerticalMargin(verticalMargin);
    302334}
    303335
  • trunk/Source/WebCore/layout/floats/FloatingContext.cpp

    r240240 r240253  
    192192}
    193193
    194 Optional<Position> FloatingContext::verticalPositionWithClearance(const Box& layoutBox) const
     194FloatingContext::ClearancePosition FloatingContext::verticalPositionWithClearance(const Box& layoutBox) const
    195195{
    196196    ASSERT(layoutBox.hasFloatClear());
     
    201201        return { };
    202202
    203     auto bottom = [&](Optional<PositionInContextRoot> floatBottom) -> Optional<Position> {
     203    auto bottom = [&](Optional<PositionInContextRoot> floatBottom) -> ClearancePosition {
    204204        // 'bottom' is in the formatting root's coordinate system.
    205205        if (!floatBottom)
     
    211211        // 1. The amount necessary to place the border edge of the block even with the bottom outer edge of the lowest float that is to be cleared.
    212212        // 2. The amount necessary to place the top border edge of the block at its hypothetical position.
    213 
    214213        auto& layoutState = this->layoutState();
    215         auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
    216         auto rootRelativeTop = FormattingContext::mapTopLeftToAncestor(layoutState, layoutBox, downcast<Container>(m_floatingState.root())).y;
     214        auto rootRelativeTop = FormattingContext::mapTopToAncestor(layoutState, layoutBox, downcast<Container>(m_floatingState.root()));
    217215        auto clearance = *floatBottom - rootRelativeTop;
    218216        if (clearance <= 0)
    219217            return { };
    220218
    221         displayBox.setHasClearance();
    222         // Clearance inhibits margin collapsing. Let's reset the relevant adjoining margins.
     219        // Clearance inhibits margin collapsing.
    223220        if (auto* previousInFlowSibling = layoutBox.previousInFlowSibling()) {
    224             auto& previousInFlowDisplayBox = layoutState.displayBoxForLayoutBox(*previousInFlowSibling);
    225221            // Does this box with clearance actually collapse its margin before with the previous inflow box's margin after?
    226             auto verticalMargin = displayBox.verticalMargin();
     222            auto verticalMargin = layoutState.displayBoxForLayoutBox(layoutBox).verticalMargin();
    227223            if (verticalMargin.hasCollapsedValues() && verticalMargin.collapsedValues().before) {
    228                 // Reset previous bottom after and current margin before to non-collapsing.
    229                 auto previousVerticalMargin = previousInFlowDisplayBox.verticalMargin();
    230                 ASSERT(previousVerticalMargin.hasCollapsedValues() && previousVerticalMargin.collapsedValues().after);
    231 
     224                auto previousVerticalMargin = layoutState.displayBoxForLayoutBox(*previousInFlowSibling).verticalMargin();
    232225                auto collapsedMargin = *verticalMargin.collapsedValues().before;
    233                 previousVerticalMargin.setCollapsedValues({ previousVerticalMargin.collapsedValues().before, { } });
    234                 previousInFlowDisplayBox.setVerticalMargin(previousVerticalMargin);
    235 
    236                 verticalMargin.setCollapsedValues({ { }, verticalMargin.collapsedValues().after });
    237                 displayBox.setVerticalMargin(verticalMargin);
    238 
    239226                auto nonCollapsedMargin = previousVerticalMargin.after() + verticalMargin.before();
    240227                auto marginDifference = nonCollapsedMargin - collapsedMargin;
    241228                // Move the box to the position where it would be with non-collapsed margins.
    242229                rootRelativeTop += marginDifference;
    243 
    244230                // Having negative clearance is also normal. It just means that the box with the non-collapsed margins is now lower than it needs to be.
    245231                clearance -= marginDifference;
     
    252238        // The return vertical position is in the containing block's coordinate system. Convert it to the formatting root's coordinate system if needed.
    253239        if (layoutBox.containingBlock() == &m_floatingState.root())
    254             return Position { rootRelativeTop };
    255 
    256         auto containingBlockRootRelativeTop = FormattingContext::mapTopLeftToAncestor(layoutState, *layoutBox.containingBlock(), downcast<Container>(m_floatingState.root())).y;
    257         return Position { rootRelativeTop - containingBlockRootRelativeTop };
     240            return { Position { rootRelativeTop }, clearance };
     241
     242        auto containingBlockRootRelativeTop = FormattingContext::mapTopToAncestor(layoutState, *layoutBox.containingBlock(), downcast<Container>(m_floatingState.root()));
     243        return { Position { rootRelativeTop - containingBlockRootRelativeTop }, clearance };
    258244    };
    259245
  • trunk/Source/WebCore/layout/floats/FloatingContext.h

    r239427 r240253  
    5353    Point positionForFloat(const Box&) const;
    5454    Optional<Point> positionForFloatAvoiding(const Box&) const;
    55     Optional<Position> verticalPositionWithClearance(const Box&) const;
     55
     56    struct ClearancePosition {
     57        Optional<Position> position;
     58        Optional<LayoutUnit> clearance;
     59    };
     60    ClearancePosition verticalPositionWithClearance(const Box&) const;
    5661
    5762private:
Note: See TracChangeset for help on using the changeset viewer.