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

Changeset 245970 in webkit


Ignore:
Timestamp:
May 31, 2019, 10:05:33 AM (7 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] InlineFormattingContext::LineLayout::processInlineItemsForLine should create and destroy Line.
https://bugs.webkit.org/show_bug.cgi?id=198419
<rdar://problem/51300837>

Reviewed by Antti Koivisto.

This is in preparation for using "createInlineRunsForLine" logic when computing preferred width.

  1. Line object is now constructed and destroyed in processInlineItemsForLine (caller does not need to know about Line).
  2. processInlineItemsForLine returns a Line::Content instance.
  • layout/inlineformatting/InlineFormattingContext.h:
  • layout/inlineformatting/InlineFormattingContextLineLayout.cpp:

(WebCore::Layout::InlineFormattingContext::LineLayout::LineInput::LineInput):
(WebCore::Layout::constructLine):
(WebCore::Layout::InlineFormattingContext::LineLayout::processInlineItemsForLine const):
(WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
(WebCore::Layout::InlineFormattingContext::LineLayout::createDisplayRuns const):
(WebCore::Layout::InlineFormattingContext::LineLayout::createLine const): Deleted.
(WebCore::Layout::InlineFormattingContext::LineLayout::createInlineRunsForLine const): Deleted.
(WebCore::Layout::InlineFormattingContext::LineLayout::processInlineRuns const): Deleted.

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r245968 r245970  
     12019-05-31  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] InlineFormattingContext::LineLayout::processInlineItemsForLine should create and destroy Line.
     4        https://bugs.webkit.org/show_bug.cgi?id=198419
     5        <rdar://problem/51300837>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        This is in preparation for using "createInlineRunsForLine" logic when computing preferred width.
     10        1. Line object is now constructed and destroyed in processInlineItemsForLine (caller does not need to know about Line).
     11        2. processInlineItemsForLine returns a Line::Content instance.
     12
     13        * layout/inlineformatting/InlineFormattingContext.h:
     14        * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
     15        (WebCore::Layout::InlineFormattingContext::LineLayout::LineInput::LineInput):
     16        (WebCore::Layout::constructLine):
     17        (WebCore::Layout::InlineFormattingContext::LineLayout::processInlineItemsForLine const):
     18        (WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
     19        (WebCore::Layout::InlineFormattingContext::LineLayout::createDisplayRuns const):
     20        (WebCore::Layout::InlineFormattingContext::LineLayout::createLine const): Deleted.
     21        (WebCore::Layout::InlineFormattingContext::LineLayout::createInlineRunsForLine const): Deleted.
     22        (WebCore::Layout::InlineFormattingContext::LineLayout::processInlineRuns const): Deleted.
     23
    1242019-05-31  Don Olmstead  <don.olmstead@sony.com>
    225
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h

    r245962 r245970  
    5959    private:
    6060        LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
    61         std::unique_ptr<Line> createLine(LayoutUnit lineLogicalTop, LayoutUnit widthConstraint) const;
    62         unsigned createInlineRunsForLine(Line&, unsigned firstInlineItemIndex) const;
    63         void processInlineRuns(const Line::Content&, LayoutUnit availableWidth) const;
     61
     62        struct LineContent {
     63            Optional<unsigned> lastInlineItemIndex;
     64            std::unique_ptr<Line::Content> runs;
     65        };
     66
     67        struct LineInput {
     68            LineInput(LayoutUnit logicalTop, LayoutUnit availableLogicalWidth, unsigned firstInlineItemIndex, const InlineItems&);
     69
     70            LayoutUnit logicalTop;
     71            LayoutUnit availableLogicalWidth;
     72            unsigned firstInlineItemIndex { 0 };
     73            const InlineItems& inlineItems;
     74        };
     75        LineContent placeInlineItems(const LineInput&) const;
     76        void createDisplayRuns(const Line::Content&, LayoutUnit widthConstraint) const;
    6477        void commitInlineItemToLine(Line&, const InlineItem&) const;
    6578        void handleFloat(Line&, const FloatingContext&, const InlineItem& floatBox) const;
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp

    r245962 r245970  
    6868}
    6969
     70InlineFormattingContext::LineLayout::LineInput::LineInput(LayoutUnit logicalTop, LayoutUnit availableLogicalWidth, unsigned firstInlineItemIndex, const InlineItems& inlineItems)
     71    : logicalTop(logicalTop)
     72    , availableLogicalWidth(availableLogicalWidth)
     73    , firstInlineItemIndex(firstInlineItemIndex)
     74    , inlineItems(inlineItems)
     75{
     76}
     77
    7078InlineFormattingContext::LineLayout::LineLayout(const InlineFormattingContext& inlineFormattingContext)
    7179    : m_formattingContext(inlineFormattingContext)
     
    7684}
    7785
    78 std::unique_ptr<Line> InlineFormattingContext::LineLayout::createLine(LayoutUnit lineLogicalTop, LayoutUnit availableWidth) const
    79 {
    80     auto& formattingRootDisplayBox = layoutState().displayBoxForLayoutBox(m_formattingRoot);
     86static std::unique_ptr<Line> constructLine(const LayoutState& layoutState, const FloatingState& floatingState, const Box& formattingRoot,
     87    LayoutUnit lineLogicalTop, LayoutUnit availableWidth)
     88{
     89    auto& formattingRootDisplayBox = layoutState.displayBoxForLayoutBox(formattingRoot);
    8190    auto lineLogicalLeft = formattingRootDisplayBox.contentBoxLeft();
    8291
    8392    // Check for intruding floats and adjust logical left/available width for this line accordingly.
    84     if (!m_floatingState.isEmpty()) {
    85         auto floatConstraints = m_floatingState.constraints({ lineLogicalTop }, m_formattingRoot);
     93    if (!floatingState.isEmpty()) {
     94        auto floatConstraints = floatingState.constraints({ lineLogicalTop }, formattingRoot);
    8695        // Check if these constraints actually put limitation on the line.
    8796        if (floatConstraints.left && *floatConstraints.left <= formattingRootDisplayBox.contentBoxLeft())
     
    105114    }
    106115
    107     auto& formattingRootStyle = m_formattingRoot.style();
     116    auto& formattingRootStyle = formattingRoot.style();
    108117    auto mimimumLineHeight = formattingRootStyle.computedLineHeight();
    109118    auto baselineOffset = Line::halfLeadingMetrics(formattingRootStyle.fontMetrics(), mimimumLineHeight).height;
    110     return std::make_unique<Line>(layoutState(), LayoutPoint { lineLogicalLeft, lineLogicalTop }, availableWidth, mimimumLineHeight, baselineOffset);
    111 }
    112 
    113 unsigned InlineFormattingContext::LineLayout::createInlineRunsForLine(Line& line, unsigned startInlineItemIndex) const
    114 {
     119    return std::make_unique<Line>(layoutState, LayoutPoint { lineLogicalLeft, lineLogicalTop }, availableWidth, mimimumLineHeight, baselineOffset);
     120}
     121
     122InlineFormattingContext::LineLayout::LineContent InlineFormattingContext::LineLayout::placeInlineItems(const LineInput& lineInput) const
     123{
     124    auto line = constructLine(layoutState(), m_floatingState, m_formattingRoot, lineInput.logicalTop, lineInput.availableLogicalWidth);
    115125    auto floatingContext = FloatingContext { m_floatingState };
    116     Optional<unsigned> lastCommittedIndex;
     126    unsigned committedInlineItemCount = 0;
    117127
    118128    UncommittedContent uncommittedContent;
     
    120130        if (uncommittedContent.isEmpty())
    121131            return;
    122 
    123         lastCommittedIndex = lastCommittedIndex.valueOr(startInlineItemIndex) + uncommittedContent.size();
     132        committedInlineItemCount += uncommittedContent.size();
    124133        for (auto* uncommitted : uncommittedContent.inlineItems())
    125             commitInlineItemToLine(line, *uncommitted);
     134            commitInlineItemToLine(*line, *uncommitted);
    126135        uncommittedContent.reset();
    127136    };
    128137
     138    auto closeLine = [&] {
     139        // This might change at some point.
     140        ASSERT(committedInlineItemCount);
     141        return LineContent { lineInput.firstInlineItemIndex + (committedInlineItemCount - 1), line->close() };
     142    };
    129143    LineBreaker lineBreaker(layoutState());
    130144    // Iterate through the inline content and place the inline boxes on the current line.
    131     auto& inlineContent = m_formattingState.inlineItems();
    132     for (auto inlineItemIndex = startInlineItemIndex; inlineItemIndex < inlineContent.size(); ++inlineItemIndex) {
    133         auto& inlineItem = inlineContent[inlineItemIndex];
     145    for (auto inlineItemIndex = lineInput.firstInlineItemIndex; inlineItemIndex < lineInput.inlineItems.size(); ++inlineItemIndex) {
     146        auto& inlineItem = lineInput.inlineItems[inlineItemIndex];
    134147        if (inlineItem->isHardLineBreak()) {
    135148            uncommittedContent.add(*inlineItem);
    136149            commitPendingContent();
    137             return *lastCommittedIndex;
    138         }
    139         auto availableWidth = line.availableWidth() - uncommittedContent.width();
    140         auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
     150            return closeLine();
     151        }
     152        auto availableWidth = line->availableWidth() - uncommittedContent.width();
     153        auto currentLogicalRight = line->contentLogicalRight() + uncommittedContent.width();
    141154        // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
    142         auto breakingContext = lineBreaker.breakingContext(*inlineItem, { availableWidth, currentLogicalRight, line.trailingTrimmableWidth(), !line.hasContent() });
     155        auto breakingContext = lineBreaker.breakingContext(*inlineItem, { availableWidth, currentLogicalRight, line->trailingTrimmableWidth(), !line->hasContent() });
    143156        if (breakingContext.isAtBreakingOpportunity)
    144157            commitPendingContent();
     
    146159        // Content does not fit the current line.
    147160        if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
    148             return *lastCommittedIndex;
     161            return closeLine();
    149162
    150163        // Partial content stays on the current line.
     
    153166
    154167            ASSERT_NOT_IMPLEMENTED_YET();
    155             return *lastCommittedIndex;
     168            return closeLine();
    156169        }
    157170
    158171        if (inlineItem->isFloat()) {
    159             handleFloat(line, floatingContext, *inlineItem);
     172            handleFloat(*line, floatingContext, *inlineItem);
     173            ++committedInlineItemCount;
    160174            continue;
    161175        }
     
    166180    }
    167181    commitPendingContent();
    168     return *lastCommittedIndex;
     182    return closeLine();
    169183}
    170184
     
    173187    ASSERT(!m_formattingState.inlineItems().isEmpty());
    174188
    175     unsigned startInlineItemIndex = 0;
    176189    auto lineLogicalTop = layoutState().displayBoxForLayoutBox(m_formattingRoot).contentBoxTop();
    177     while (true) {
    178         auto line = createLine(lineLogicalTop, widthConstraint);
    179         auto nextInlineItemIndex = createInlineRunsForLine(*line, startInlineItemIndex);
    180         auto lineContent = line->close();
    181         processInlineRuns(*lineContent, line->availableWidth());
    182         if (nextInlineItemIndex == m_formattingState.inlineItems().size())
    183             break;
    184         startInlineItemIndex = nextInlineItemIndex;
    185         lineLogicalTop = lineContent->logicalBottom();
     190    auto& inlineItems = m_formattingState.inlineItems();
     191    unsigned currentInlineItemIndex = 0;
     192    while (currentInlineItemIndex < inlineItems.size()) {
     193        auto lineContent = placeInlineItems({ lineLogicalTop, widthConstraint, currentInlineItemIndex, inlineItems });
     194        createDisplayRuns(*lineContent.runs, widthConstraint);
     195        // We should always put at least one run on the line atm. This might change later on though.
     196        ASSERT(lineContent.lastInlineItemIndex);
     197        currentInlineItemIndex = *lineContent.lastInlineItemIndex + 1;
     198        lineLogicalTop = lineContent.runs->logicalBottom();
    186199    }
    187200}
     
    215228}
    216229
    217 void InlineFormattingContext::LineLayout::processInlineRuns(const Line::Content& lineContent, LayoutUnit availableWidth) const
     230void InlineFormattingContext::LineLayout::createDisplayRuns(const Line::Content& lineContent, LayoutUnit widthConstraint) const
    218231{
    219232    if (lineContent.isEmpty()) {
     
    314327    m_formattingState.addLineBox({ lineBox });
    315328    if (!lineContent.isVisuallyEmpty())
    316         alignRuns(m_formattingRoot.style().textAlign(), previousLineLastRunIndex.valueOr(-1) + 1, availableWidth);
     329        alignRuns(m_formattingRoot.style().textAlign(), previousLineLastRunIndex.valueOr(-1) + 1, widthConstraint - lineContent.logicalWidth());
    317330}
    318331
Note: See TracChangeset for help on using the changeset viewer.