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

Changeset 245961 in webkit


Ignore:
Timestamp:
May 31, 2019, 5:58:35 AM (7 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Move final runs to a dedicated class (Line::Content)
https://bugs.webkit.org/show_bug.cgi?id=198360
<rdar://problem/51247717>

Reviewed by Antti Koivisto.

It decouples the line and the final line content. So when we process the runs after closing the line,
LineContent should be able to answer all the content and geometry related questions.
This is also in preparation for
transfering the ownership of the line content when calling Line::close().

  • WebCore.xcodeproj/project.pbxproj:
  • layout/inlineformatting/InlineFormattingContextLineLayout.cpp:

(WebCore::Layout::InlineFormattingContext::LineLayout::processInlineRuns const):

  • layout/inlineformatting/InlineLine.cpp:

(WebCore::Layout::Line::Content::isVisuallyEmpty const):
(WebCore::Layout::Line::Content::Run::Run):
(WebCore::Layout::Line::reset):
(WebCore::Layout::Line::close):
(WebCore::Layout::Line::moveLogicalLeft):
(WebCore::Layout::Line::appendNonBreakableSpace):
(WebCore::Layout::Line::appendTextContent):
(WebCore::Layout::Line::appendNonReplacedInlineBox):
(WebCore::Layout::Line::appendHardLineBreak):
(WebCore::Layout::Line::LineItem::LineItem): Deleted.
(WebCore::Layout::Line::hasContent const): Deleted.

  • layout/inlineformatting/InlineLine.h:

(WebCore::Layout::Line::Content::runs const):
(WebCore::Layout::Line::Content::isEmpty const):
(WebCore::Layout::Line::Content::logicalTop const):
(WebCore::Layout::Line::Content::logicalLeft const):
(WebCore::Layout::Line::Content::logicalRight const):
(WebCore::Layout::Line::Content::logicalBottom const):
(WebCore::Layout::Line::Content::logicalWidth const):
(WebCore::Layout::Line::Content::logicalHeight const):
(WebCore::Layout::Line::Content::setLogicalRect):
(WebCore::Layout::Line::Content::runs):
(WebCore::Layout::Line::hasContent const):
(WebCore::Layout::Line::availableWidth const):
(WebCore::Layout::Line::contentLogicalRight const):
(WebCore::Layout::Line::logicalTop const):
(WebCore::Layout::Line::logicalBottom const):
(WebCore::Layout::Line::logicalLeft const):
(WebCore::Layout::Line::logicalRight const):
(WebCore::Layout::Line::logicalWidth const):
(WebCore::Layout::Line::logicalHeight const):
(WebCore::Layout::Line::contentLogicalWidth const):

  • page/FrameViewLayoutContext.cpp:

(WebCore::layoutUsingFormattingContext):

Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r245960 r245961  
     12019-05-31  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Move final runs to a dedicated class (Line::Content)
     4        https://bugs.webkit.org/show_bug.cgi?id=198360
     5        <rdar://problem/51247717>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        It decouples the line and the final line content. So when we process the runs after closing the line,
     10        LineContent should be able to answer all the content and geometry related questions.
     11        This is also in preparation for
     12        transfering the ownership of the line content when calling Line::close().
     13
     14        * WebCore.xcodeproj/project.pbxproj:
     15        * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
     16        (WebCore::Layout::InlineFormattingContext::LineLayout::processInlineRuns const):
     17        * layout/inlineformatting/InlineLine.cpp:
     18        (WebCore::Layout::Line::Content::isVisuallyEmpty const):
     19        (WebCore::Layout::Line::Content::Run::Run):
     20        (WebCore::Layout::Line::reset):
     21        (WebCore::Layout::Line::close):
     22        (WebCore::Layout::Line::moveLogicalLeft):
     23        (WebCore::Layout::Line::appendNonBreakableSpace):
     24        (WebCore::Layout::Line::appendTextContent):
     25        (WebCore::Layout::Line::appendNonReplacedInlineBox):
     26        (WebCore::Layout::Line::appendHardLineBreak):
     27        (WebCore::Layout::Line::LineItem::LineItem): Deleted.
     28        (WebCore::Layout::Line::hasContent const): Deleted.
     29        * layout/inlineformatting/InlineLine.h:
     30        (WebCore::Layout::Line::Content::runs const):
     31        (WebCore::Layout::Line::Content::isEmpty const):
     32        (WebCore::Layout::Line::Content::logicalTop const):
     33        (WebCore::Layout::Line::Content::logicalLeft const):
     34        (WebCore::Layout::Line::Content::logicalRight const):
     35        (WebCore::Layout::Line::Content::logicalBottom const):
     36        (WebCore::Layout::Line::Content::logicalWidth const):
     37        (WebCore::Layout::Line::Content::logicalHeight const):
     38        (WebCore::Layout::Line::Content::setLogicalRect):
     39        (WebCore::Layout::Line::Content::runs):
     40        (WebCore::Layout::Line::hasContent const):
     41        (WebCore::Layout::Line::availableWidth const):
     42        (WebCore::Layout::Line::contentLogicalRight const):
     43        (WebCore::Layout::Line::logicalTop const):
     44        (WebCore::Layout::Line::logicalBottom const):
     45        (WebCore::Layout::Line::logicalLeft const):
     46        (WebCore::Layout::Line::logicalRight const):
     47        (WebCore::Layout::Line::logicalWidth const):
     48        (WebCore::Layout::Line::logicalHeight const):
     49        (WebCore::Layout::Line::contentLogicalWidth const):
     50        * page/FrameViewLayoutContext.cpp:
     51        (WebCore::layoutUsingFormattingContext):
     52
    1532019-05-31  Joonghun Park  <jh718.park@samsung.com>
    254
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp

    r245850 r245961  
    217217void InlineFormattingContext::LineLayout::processInlineRuns(Line& line) const
    218218{
    219     auto& lineItems = line.close();
    220     if (lineItems.isEmpty()) {
     219    auto& lineContent = line.close();
     220    if (lineContent.isEmpty()) {
    221221        // Spec tells us to create a zero height, empty line box.
    222         auto lineBox = Display::Rect { line.logicalTop(), line.logicalLeft(), 0 , 0 };
     222        auto lineBox = Display::Rect { lineContent.logicalTop(), lineContent.logicalLeft(), 0 , 0 };
    223223        m_formattingState.addLineBox({ lineBox });
    224224        return;
     
    231231
    232232    // Ignore the initial strut.
    233     auto lineBox = Display::Rect { line.logicalTop(), line.logicalLeft(), 0 , line.hasContent() ? line.logicalHeight() : LayoutUnit { } };
     233    auto lineBox = Display::Rect { lineContent.logicalTop(), lineContent.logicalLeft(), 0 , !lineContent.isVisuallyEmpty() ? lineContent.logicalHeight() : LayoutUnit { } };
    234234    // Create final display runs.
    235     for (unsigned index = 0; index < lineItems.size(); ++index) {
    236         auto& lineItem = lineItems.at(index);
    237 
    238         auto& inlineItem = lineItem->inlineItem;
    239         auto& inlineRun = lineItem->inlineRun;
     235    auto& lineRuns = lineContent.runs();
     236    for (unsigned index = 0; index < lineRuns.size(); ++index) {
     237        auto& lineRun = lineRuns.at(index);
     238
     239        auto& inlineItem = lineRun->inlineItem;
     240        auto& inlineRun = lineRun->inlineRun;
    240241        auto& layoutBox = inlineItem.layoutBox();
    241242        auto& displayBox = layoutState().displayBoxForLayoutBox(layoutBox);
     
    285286        // Text content. Try to join multiple text runs when possible.
    286287        ASSERT(inlineRun.textContext());       
    287         const Line::LineItem* previousLineItem = !index ? nullptr : lineItems[index - 1].get();
    288         if (!lineItem->isCollapsed) {
     288        const Line::Content::Run* previousLineRun = !index ? nullptr : lineRuns[index - 1].get();
     289        if (!lineRun->isCollapsed) {
    289290            auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
    290             auto previousRunCanBeExtended = previousLineItem ? previousLineItem->canBeExtended : false;
    291             auto requiresNewRun = !index || !previousRunCanBeExtended || &layoutBox != &previousLineItem->inlineItem.layoutBox();
     291            auto previousRunCanBeExtended = previousLineRun ? previousLineRun->canBeExtended : false;
     292            auto requiresNewRun = !index || !previousRunCanBeExtended || &layoutBox != &previousLineRun->inlineItem.layoutBox();
    292293            if (requiresNewRun)
    293294                m_formattingState.addInlineRun(std::make_unique<Display::Run>(inlineRun));
     
    300301        }
    301302        // FIXME take content breaking into account when part of the layout box is on the previous line.
    302         auto firstInlineRunForLayoutBox = !previousLineItem || &previousLineItem->inlineItem.layoutBox() != &layoutBox;
     303        auto firstInlineRunForLayoutBox = !previousLineRun || &previousLineRun->inlineItem.layoutBox() != &layoutBox;
    303304        if (firstInlineRunForLayoutBox) {
    304305            // Setup display box for the associated layout box.
    305306            displayBox.setTopLeft(inlineRun.logicalTopLeft());
    306             displayBox.setContentBoxWidth(lineItem->isCollapsed ? LayoutUnit() : inlineRun.logicalWidth());
     307            displayBox.setContentBoxWidth(lineRun->isCollapsed ? LayoutUnit() : inlineRun.logicalWidth());
    307308            displayBox.setContentBoxHeight(inlineRun.logicalHeight());
    308         } else if (!lineItem->isCollapsed) {
     309        } else if (!lineRun->isCollapsed) {
    309310            // FIXME fix it for multirun/multiline.
    310311            displayBox.setContentBoxWidth(displayBox.contentBoxWidth() + inlineRun.logicalWidth());
     
    313314    // FIXME linebox needs to be ajusted after content alignment.
    314315    m_formattingState.addLineBox({ lineBox });
    315     if (line.hasContent())
     316    if (!lineContent.isVisuallyEmpty())
    316317        alignRuns(m_formattingRoot.style().textAlign(), previousLineLastRunIndex.valueOr(-1) + 1, line.availableWidth());
    317318}
  • trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp

    r245850 r245961  
    3232namespace Layout {
    3333
    34 Line::LineItem::LineItem(Display::Run inlineRun, const InlineItem& inlineItem, bool isCollapsed, bool canBeExtended)
     34bool Line::Content::isVisuallyEmpty() const
     35{
     36    // Return true for empty inline containers like <span></span>.
     37    for (auto& run : m_runs) {
     38        if (run->inlineItem.isContainerStart() || run->inlineItem.isContainerEnd())
     39            continue;
     40        if (!run->isCollapsed)
     41            return false;
     42    }
     43    return true;
     44}
     45
     46Line::Content::Run::Run(Display::Run inlineRun, const InlineItem& inlineItem, bool isCollapsed, bool canBeExtended)
    3547    : inlineRun(inlineRun)
    3648    , inlineItem(inlineItem)
     
    5365    m_contentLogicalWidth = { };
    5466
    55     m_lineItems.clear();
     67    m_content = { };
     68
    5669    m_trimmableContent.clear();
    5770}
    5871
    59 const Line::LineItems& Line::close()
     72const Line::Content& Line::close()
    6073{
    6174    removeTrailingTrimmableContent();
    6275    // Convert inline run geometry from relative to the baseline to relative to logical top.
    63     for (auto& lineItem : m_lineItems) {
    64         auto adjustedLogicalTop = lineItem->inlineRun.logicalTop() + m_logicalHeight.height + m_logicalTopLeft.y();
    65         lineItem->inlineRun.setLogicalTop(adjustedLogicalTop);
     76    for (auto& run : m_content.runs()) {
     77        auto adjustedLogicalTop = run->inlineRun.logicalTop() + m_logicalHeight.height + m_logicalTopLeft.y();
     78        run->inlineRun.setLogicalTop(adjustedLogicalTop);
    6679    }
    67     return m_lineItems;
     80    m_content.setLogicalRect({ logicalTop(), logicalLeft(), contentLogicalWidth(), logicalHeight() });
     81    return m_content;
    6882}
    6983
     
    87101    m_logicalTopLeft.move(delta, 0);
    88102    m_lineLogicalWidth -= delta;
    89     for (auto& lineItem : m_lineItems)
    90         lineItem->inlineRun.moveHorizontally(delta);
     103    for (auto& run : m_content.runs())
     104        run->inlineRun.moveHorizontally(delta);
    91105}
    92106
     
    105119}
    106120
    107 bool Line::hasContent() const
    108 {
    109     // Return false for empty containers like <span></span>.
    110     if (m_lineItems.isEmpty())
    111         return false;
    112     for (auto& lineItem : m_lineItems) {
    113         if (lineItem->inlineItem.isContainerStart() || lineItem->inlineItem.isContainerEnd())
    114             continue;
    115         if (!lineItem->isCollapsed)
    116             return true;
    117     }
    118     return false;
    119 }
    120 
    121121void Line::appendNonBreakableSpace(const InlineItem& inlineItem, const Display::Rect& logicalRect)
    122122{
    123     m_lineItems.append(std::make_unique<LineItem>(Display::Run { logicalRect }, inlineItem, false, false));
     123    m_content.runs().append(std::make_unique<Content::Run>(Display::Run { logicalRect }, inlineItem, false, false));
    124124    m_contentLogicalWidth += inlineItem.width();
    125125}
     
    166166            return false;
    167167        // Leading whitespace.
    168         if (m_lineItems.isEmpty())
     168        auto& runs = m_content.runs();
     169        if (runs.isEmpty())
    169170            return true;
    170171        // Check if the last item is trimmable as well.
    171         for (int index = m_lineItems.size() - 1; index >= 0; --index) {
    172             auto& inlineItem = m_lineItems[index]->inlineItem;
     172        for (int index = runs.size() - 1; index >= 0; --index) {
     173            auto& inlineItem = runs[index]->inlineItem;
    173174            if (inlineItem.isBox())
    174175                return false;
     
    187188    auto displayRun = Display::Run(logicalRect, textContext);
    188189
    189     auto lineItem = std::make_unique<LineItem>(displayRun, inlineItem, isCompletelyCollapsed, canBeExtended);
     190    auto lineItem = std::make_unique<Content::Run>(displayRun, inlineItem, isCompletelyCollapsed, canBeExtended);
    190191    if (isTrimmable)
    191192        m_trimmableContent.add(lineItem.get());
    192193
    193     m_lineItems.append(WTFMove(lineItem));
     194    m_content.runs().append(WTFMove(lineItem));
    194195    m_contentLogicalWidth += isCompletelyCollapsed ? LayoutUnit() : runSize.width();
    195196}
     
    219220    auto logicalRect = Display::Rect { logicalTop, contentLogicalRight() + horizontalMargin.start, runSize.width(), runSize.height() };
    220221
    221     m_lineItems.append(std::make_unique<LineItem>(Display::Run { logicalRect }, inlineItem, false, false));
     222    m_content.runs().append(std::make_unique<Content::Run>(Display::Run { logicalRect }, inlineItem, false, false));
    222223    m_contentLogicalWidth += (runSize.width() + horizontalMargin.start + horizontalMargin.end);
    223224    m_trimmableContent.clear();
     
    234235    auto ascent = inlineItem.layoutBox().style().fontMetrics().ascent();
    235236    auto logicalRect = Display::Rect { -ascent, contentLogicalRight(), { }, logicalHeight() };
    236     m_lineItems.append(std::make_unique<LineItem>(Display::Run { logicalRect }, inlineItem, false, false));
     237    m_content.runs().append(std::make_unique<Content::Run>(Display::Run { logicalRect }, inlineItem, false, false));
    237238}
    238239
  • trunk/Source/WebCore/layout/inlineformatting/InlineLine.h

    r245850 r245961  
    4040    void reset(const LayoutPoint& topLeft, LayoutUnit availableWidth, LayoutUnit minimumLineHeight, LayoutUnit baselineOffset);
    4141
    42     struct LineItem {
    43         LineItem(Display::Run, const InlineItem&, bool isCollapsed, bool canBeExtended);
     42    class Content {
     43    public:
     44        struct Run {
     45            Run(Display::Run, const InlineItem&, bool isCollapsed, bool canBeExtended);
    4446
    45         // Relative to the baseline.
    46         Display::Run inlineRun;
    47         const InlineItem& inlineItem;
    48         bool isCollapsed { false };
    49         bool canBeExtended { false };
     47            // Relative to the baseline.
     48            Display::Run inlineRun;
     49            const InlineItem& inlineItem;
     50            bool isCollapsed { false };
     51            bool canBeExtended { false };
     52        };
     53        using Runs = Vector<std::unique_ptr<Run>>;
     54        const Runs& runs() const { return m_runs; }
     55        bool isEmpty() const { return m_runs.isEmpty(); }
     56        // Not in painting sense though.
     57        bool isVisuallyEmpty() const;
     58
     59        LayoutUnit logicalTop() const { return m_logicalRect.top(); }
     60        LayoutUnit logicalLeft() const { return m_logicalRect.left(); }
     61        LayoutUnit logicalRight() const { return logicalLeft() + logicalWidth(); }
     62        LayoutUnit logicalBottom() const { return logicalTop() + logicalHeight(); }
     63        LayoutUnit logicalWidth() const { return m_logicalRect.width(); }
     64        LayoutUnit logicalHeight() const { return m_logicalRect.height(); }
     65
     66    private:
     67        friend class Line;
     68
     69        void setLogicalRect(const Display::Rect& logicalRect) { m_logicalRect = logicalRect; }
     70        Runs& runs() { return m_runs; }
     71
     72        Display::Rect m_logicalRect;
     73        Runs m_runs;
    5074    };
    51 
    52     using LineItems = Vector<std::unique_ptr<LineItem>>;
    53     const LineItems& close();
     75    const Content& close();
    5476
    5577    void appendTextContent(const InlineTextItem&, LayoutSize);
     
    6082    void appendHardLineBreak(const InlineItem&);
    6183
    62     bool hasContent() const;
     84    bool hasContent() const { return !m_content.isVisuallyEmpty(); }
    6385
    6486    LayoutUnit trailingTrimmableWidth() const;
     
    6890
    6991    LayoutUnit availableWidth() const { return logicalWidth() - contentLogicalWidth(); }
    70    
    7192    LayoutUnit contentLogicalRight() const { return logicalLeft() + contentLogicalWidth(); }
    72     LayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
    73 
    7493    LayoutUnit logicalTop() const { return m_logicalTopLeft.y(); }
    75     LayoutUnit logicalLeft() const { return m_logicalTopLeft.x(); }
    76     LayoutUnit logicalRight() const { return logicalLeft() + logicalWidth(); }
    7794    LayoutUnit logicalBottom() const { return logicalTop() + logicalHeight(); }
    78     LayoutUnit logicalWidth() const { return m_lineLogicalWidth; }
    79     LayoutUnit logicalHeight() const { return m_logicalHeight.height + m_logicalHeight.depth; }
    8095
    8196    struct UsedHeightAndDepth {
     
    86101
    87102private:
     103    LayoutUnit logicalLeft() const { return m_logicalTopLeft.x(); }
     104    LayoutUnit logicalRight() const { return logicalLeft() + logicalWidth(); }
     105
     106    LayoutUnit logicalWidth() const { return m_lineLogicalWidth; }
     107    LayoutUnit logicalHeight() const { return m_logicalHeight.height + m_logicalHeight.depth; }
     108
     109    LayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
     110
    88111    void appendNonBreakableSpace(const InlineItem&, const Display::Rect& logicalRect);
    89112    void removeTrailingTrimmableContent();
    90113
    91114    const LayoutState& m_layoutState;
    92     LineItems m_lineItems;
    93     ListHashSet<LineItem*> m_trimmableContent;
     115    Content m_content;
     116    ListHashSet<Content::Run*> m_trimmableContent;
    94117
    95118    LayoutPoint m_logicalTopLeft;
Note: See TracChangeset for help on using the changeset viewer.