⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 246483 in webkit


Ignore:
Timestamp:
Jun 16, 2019, 1:19:24 PM (7 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Intruding float may prevent adding any inline box
https://bugs.webkit.org/show_bug.cgi?id=198891
<rdar://problem/51779956>

Reviewed by Antti Koivisto.

Take the intruding left/right float pair and find the vertical position where the next line might go
if these floats prevent us from adding even one inline box to the current line.

  • layout/FormattingContext.cpp:

(WebCore::Layout::FormattingContext::mapPointToAncestor):
(WebCore::Layout::FormattingContext::mapPointToDescendent):

  • layout/FormattingContext.h:
  • layout/LayoutUnits.h:

(WebCore::Layout::Point::max):

  • layout/inlineformatting/InlineFormattingContext.h:
  • layout/inlineformatting/InlineFormattingContextLineLayout.cpp:

(WebCore::Layout::InlineFormattingContext::LineLayout::placeInlineItems const):
(WebCore::Layout::InlineFormattingContext::LineLayout::layout const):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r246482 r246483  
     12019-06-16  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Intruding float may prevent adding any inline box
     4        https://bugs.webkit.org/show_bug.cgi?id=198891
     5        <rdar://problem/51779956>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        Take the intruding left/right float pair and find the vertical position where the next line might go
     10        if these floats prevent us from adding even one inline box to the current line.
     11
     12        * layout/FormattingContext.cpp:
     13        (WebCore::Layout::FormattingContext::mapPointToAncestor):
     14        (WebCore::Layout::FormattingContext::mapPointToDescendent):
     15        * layout/FormattingContext.h:
     16        * layout/LayoutUnits.h:
     17        (WebCore::Layout::Point::max):
     18        * layout/inlineformatting/InlineFormattingContext.h:
     19        * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
     20        (WebCore::Layout::InlineFormattingContext::LineLayout::placeInlineItems const):
     21        (WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
     22
    1232019-06-16  Zalan Bujtas  <zalan@apple.com>
    224
  • trunk/Source/WebCore/layout/FormattingContext.cpp

    r246479 r246483  
    212212}
    213213
    214 Point FormattingContext::mapPointToAncestor(const LayoutState& layoutState, Point position, const Container& containingBlock, const Container& ancestor)
    215 {
    216     if (&containingBlock == &ancestor)
     214Point FormattingContext::mapPointToAncestor(const LayoutState& layoutState, Point position, const Container& from, const Container& to)
     215{
     216    if (&from == &to)
    217217        return position;
    218     ASSERT(containingBlock.isContainingBlockDescendantOf(ancestor));
     218    ASSERT(from.isContainingBlockDescendantOf(to));
    219219    auto mappedPosition = position;
    220     for (auto* container = &containingBlock; container && container != &ancestor; container = container->containingBlock())
     220    for (auto* container = &from; container && container != &to; container = container->containingBlock())
    221221        mappedPosition.moveBy(layoutState.displayBoxForLayoutBox(*container).topLeft());
    222222    return mappedPosition;
     223}
     224
     225Point FormattingContext::mapPointToDescendent(const LayoutState& layoutState, Point point, const Container& from, const Container& to)
     226{
     227    // "point" is in the coordinate system of the "from" container.
     228    if (&from == &to)
     229        return point;
     230    ASSERT(to.isContainingBlockDescendantOf(from));
     231    for (auto* container = &to; container && container != &from; container = container->containingBlock())
     232        point.moveBy(-layoutState.displayBoxForLayoutBox(*container).topLeft());
     233    return point;
    223234}
    224235
  • trunk/Source/WebCore/layout/FormattingContext.h

    r246468 r246483  
    6363    static LayoutUnit mapLeftToAncestor(const LayoutState&, const Box&, const Container& ancestor);
    6464    static LayoutUnit mapRightToAncestor(const LayoutState&, const Box&, const Container& ancestor);
    65     static Point mapPointToAncestor(const LayoutState&, Point, const Container& containingBlock, const Container& ancestor);
     65    static Point mapPointToAncestor(const LayoutState&, Point, const Container& from, const Container& to);
     66    static Point mapPointToDescendent(const LayoutState&, Point, const Container& from, const Container& to);
    6667
    6768protected:
  • trunk/Source/WebCore/layout/LayoutUnits.h

    r246482 r246483  
    6060    Point(LayoutUnit, LayoutUnit);
    6161    Point(LayoutPoint);
     62    static Point max() { return { LayoutUnit::max(), LayoutUnit::max() }; }
     63
    6264    void move(LayoutSize);
    6365    void moveBy(LayoutPoint);
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h

    r246154 r246483  
    8080            unsigned firstInlineItemIndex { 0 };
    8181            const InlineItems& inlineItems;
     82            Optional<LayoutUnit> floatMinimumLogicalBottom;
    8283        };
    8384        LineContent placeInlineItems(const LineInput&) const;
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp

    r246482 r246483  
    162162    };
    163163
     164    auto lineHasFloatBox = lineInput.floatMinimumLogicalBottom.hasValue();
    164165    auto closeLine = [&] {
    165         // This might change at some point.
    166         ASSERT(committedInlineItemCount);
    167         return LineContent { lineInput.firstInlineItemIndex + (committedInlineItemCount - 1), WTFMove(floats), line->close() };
     166        ASSERT(committedInlineItemCount || lineHasFloatBox);
     167        auto lastCommittedIndex = committedInlineItemCount ? Optional<unsigned> { lineInput.firstInlineItemIndex + (committedInlineItemCount - 1) } : WTF::nullopt;
     168        return LineContent { lastCommittedIndex, WTFMove(floats), line->close() };
    168169    };
    169170    LineBreaker lineBreaker;
     
    176177
    177178        // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
    178         auto breakingContext = lineBreaker.breakingContext(*inlineItem, itemLogicalWidth, { availableWidth, currentLogicalRight, line->trailingTrimmableWidth(), !line->hasContent() });
     179        auto lineIsConsideredEmpty = !line->hasContent() && !lineHasFloatBox;
     180        auto breakingContext = lineBreaker.breakingContext(*inlineItem, itemLogicalWidth, { availableWidth, currentLogicalRight, line->trailingTrimmableWidth(), lineIsConsideredEmpty });
    179181        if (breakingContext.isAtBreakingOpportunity)
    180182            commitPendingContent();
     
    201203            floats.append(makeWeakPtr(*inlineItem));
    202204            ++committedInlineItemCount;
     205            lineHasFloatBox = true;
    203206            continue;
    204207        }
     
    223226    auto lineLogicalLeft = formattingRootDisplayBox.contentBoxLeft();
    224227
    225     auto applyFloatConstraint = [&](auto& lineHorizontalConstraint) {
     228    auto applyFloatConstraint = [&](auto& lineInput) {
    226229        // Check for intruding floats and adjust logical left/available width for this line accordingly.
    227230        if (m_floatingState.isEmpty())
    228231            return;
    229         auto availableWidth = lineHorizontalConstraint.availableLogicalWidth;
    230         auto lineLogicalLeft = lineHorizontalConstraint.logicalTopLeft.x();
     232        auto availableWidth = lineInput.horizontalConstraint.availableLogicalWidth;
     233        auto lineLogicalLeft = lineInput.horizontalConstraint.logicalTopLeft.x();
    231234        auto floatConstraints = m_floatingState.constraints({ lineLogicalTop }, m_formattingRoot);
    232235        // Check if these constraints actually put limitation on the line.
     
    237240            floatConstraints.right = { };
    238241
     242        // Set the minimum float bottom value as a hint for the next line if needed.
     243        static auto inifitePoint = PointInContextRoot::max();
     244        auto floatMinimumLogicalBottom = std::min(floatConstraints.left.valueOr(inifitePoint).y, floatConstraints.right.valueOr(inifitePoint).y);
     245        if (floatMinimumLogicalBottom != inifitePoint.y)
     246            lineInput.floatMinimumLogicalBottom = floatMinimumLogicalBottom;
     247
    239248        if (floatConstraints.left && floatConstraints.right) {
    240             ASSERT(floatConstraints.left->x < floatConstraints.right->x);
     249            ASSERT(floatConstraints.left->x <= floatConstraints.right->x);
    241250            availableWidth = floatConstraints.right->x - floatConstraints.left->x;
    242251            lineLogicalLeft = floatConstraints.left->x;
    243252        } else if (floatConstraints.left) {
    244             ASSERT(floatConstraints.left->x > lineLogicalLeft);
     253            ASSERT(floatConstraints.left->x >= lineLogicalLeft);
    245254            availableWidth -= (floatConstraints.left->x - lineLogicalLeft);
    246255            lineLogicalLeft = floatConstraints.left->x;
    247256        } else if (floatConstraints.right) {
    248             ASSERT(floatConstraints.right->x > lineLogicalLeft);
     257            ASSERT(floatConstraints.right->x >= lineLogicalLeft);
    249258            availableWidth = floatConstraints.right->x - lineLogicalLeft;
    250259        }
    251         lineHorizontalConstraint.availableLogicalWidth = availableWidth;
    252         lineHorizontalConstraint.logicalTopLeft.setX(lineLogicalLeft);
     260        lineInput.horizontalConstraint.availableLogicalWidth = availableWidth;
     261        lineInput.horizontalConstraint.logicalTopLeft.setX(lineLogicalLeft);
    253262    };
    254263
     
    257266    while (currentInlineItemIndex < inlineItems.size()) {
    258267        auto lineInput = LineInput { { lineLogicalLeft, lineLogicalTop }, widthConstraint, LineInput::SkipVerticalAligment::No, currentInlineItemIndex, inlineItems };
    259         applyFloatConstraint(lineInput.horizontalConstraint);
     268        applyFloatConstraint(lineInput);
    260269        auto lineContent = placeInlineItems(lineInput);
    261270        createDisplayRuns(*lineContent.runs, lineContent.floats, widthConstraint);
    262         // We should always put at least one run on the line atm. This might change later on though.
    263         ASSERT(lineContent.lastInlineItemIndex);
    264         currentInlineItemIndex = *lineContent.lastInlineItemIndex + 1;
    265         lineLogicalTop = lineContent.runs->logicalBottom();
     271        if (!lineContent.lastInlineItemIndex) {
     272            // Floats prevented us putting any content on the line.
     273            ASSERT(lineInput.floatMinimumLogicalBottom);
     274            ASSERT(lineContent.runs->isEmpty());
     275            lineLogicalTop = *lineInput.floatMinimumLogicalBottom;
     276        } else {
     277            currentInlineItemIndex = *lineContent.lastInlineItemIndex + 1;
     278            lineLogicalTop = lineContent.runs->logicalBottom();
     279        }
    266280    }
    267281}
Note: See TracChangeset for help on using the changeset viewer.