Changeset 246206 in webkit


Ignore:
Timestamp:
Jun 7, 2019 10:15:49 AM (5 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Line should skip all vertical adjustment when running preferred width computation
https://bugs.webkit.org/show_bug.cgi?id=198642
<rdar://problem/51511043>

Reviewed by Antti Koivisto.

While layout triggers both horizontal and vertical aligment, preferred width computation should only do (logical)horizontal.
Make all vertical alignment computation optional in Line.

  • layout/inlineformatting/InlineFormattingContextLineLayout.cpp:

(WebCore::Layout::UncommittedContent::add):
(WebCore::Layout::InlineFormattingContext::LineLayout::placeInlineItems const):
(WebCore::Layout::InlineFormattingContext::LineLayout::computedIntrinsicWidth const):
(WebCore::Layout::InlineFormattingContext::LineLayout::createDisplayRuns const):
(WebCore::Layout::inlineItemHeight): Deleted.

  • layout/inlineformatting/InlineLine.cpp:

(WebCore::Layout::Line::Content::Run::Run):
(WebCore::Layout::Line::Line):
(WebCore::Layout::Line::close):
(WebCore::Layout::Line::removeTrailingTrimmableContent):
(WebCore::Layout::Line::moveLogicalLeft):
(WebCore::Layout::Line::trailingTrimmableWidth const):
(WebCore::Layout::Line::appendNonBreakableSpace):
(WebCore::Layout::Line::appendInlineContainerStart):
(WebCore::Layout::Line::appendInlineContainerEnd):
(WebCore::Layout::Line::appendTextContent):
(WebCore::Layout::Line::appendNonReplacedInlineBox):
(WebCore::Layout::Line::appendReplacedInlineBox):
(WebCore::Layout::Line::appendHardLineBreak):
(WebCore::Layout::Line::inlineItemHeight const):

  • layout/inlineformatting/InlineLine.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r246205 r246206  
     12019-06-07  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Line should skip all vertical adjustment when running preferred width computation
     4        https://bugs.webkit.org/show_bug.cgi?id=198642
     5        <rdar://problem/51511043>
     6
     7        Reviewed by Antti Koivisto.
     8
     9        While layout triggers both horizontal and vertical aligment, preferred width computation should only do (logical)horizontal.
     10        Make all vertical alignment computation optional in Line.
     11
     12        * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
     13        (WebCore::Layout::UncommittedContent::add):
     14        (WebCore::Layout::InlineFormattingContext::LineLayout::placeInlineItems const):
     15        (WebCore::Layout::InlineFormattingContext::LineLayout::computedIntrinsicWidth const):
     16        (WebCore::Layout::InlineFormattingContext::LineLayout::createDisplayRuns const):
     17        (WebCore::Layout::inlineItemHeight): Deleted.
     18        * layout/inlineformatting/InlineLine.cpp:
     19        (WebCore::Layout::Line::Content::Run::Run):
     20        (WebCore::Layout::Line::Line):
     21        (WebCore::Layout::Line::close):
     22        (WebCore::Layout::Line::removeTrailingTrimmableContent):
     23        (WebCore::Layout::Line::moveLogicalLeft):
     24        (WebCore::Layout::Line::trailingTrimmableWidth const):
     25        (WebCore::Layout::Line::appendNonBreakableSpace):
     26        (WebCore::Layout::Line::appendInlineContainerStart):
     27        (WebCore::Layout::Line::appendInlineContainerEnd):
     28        (WebCore::Layout::Line::appendTextContent):
     29        (WebCore::Layout::Line::appendNonReplacedInlineBox):
     30        (WebCore::Layout::Line::appendReplacedInlineBox):
     31        (WebCore::Layout::Line::appendHardLineBreak):
     32        (WebCore::Layout::Line::inlineItemHeight const):
     33        * layout/inlineformatting/InlineLine.h:
     34
    1352019-06-07  Antoine Quint  <graouts@apple.com>
    236
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp

    r246154 r246206  
    4545    struct Run {
    4646        const InlineItem& inlineItem;
    47         Line::InlineItemSize size;
     47        LayoutUnit logicalWidth;
    4848        // FIXME: add optional breaking context (start and end position) for split text content.
    4949    };
    50     void add(const InlineItem&, const Line::InlineItemSize&);
     50    void add(const InlineItem&, LayoutUnit logicalWidth);
    5151    void reset();
    5252
     
    6161};
    6262
    63 void UncommittedContent::add(const InlineItem& inlineItem, const Line::InlineItemSize& size)
    64 {
    65     m_uncommittedRuns.append({ inlineItem, size });
    66     m_width += size.logicalWidth;
     63void UncommittedContent::add(const InlineItem& inlineItem, LayoutUnit logicalWidth)
     64{
     65    m_uncommittedRuns.append({ inlineItem, logicalWidth });
     66    m_width += logicalWidth;
    6767}
    6868
     
    126126}
    127127
    128 static LayoutUnit inlineItemHeight(const LayoutState& layoutState, const InlineItem& inlineItem)
    129 {
    130     auto& fontMetrics = inlineItem.style().fontMetrics();
    131     if (inlineItem.isLineBreak() || is<InlineTextItem>(inlineItem))
    132         return fontMetrics.height();
    133 
    134     auto& layoutBox = inlineItem.layoutBox();
    135     ASSERT(layoutState.hasDisplayBox(layoutBox));
    136     auto& displayBox = layoutState.displayBoxForLayoutBox(layoutBox);
    137 
    138     if (layoutBox.isFloatingPositioned())
    139         return displayBox.marginBox().height();
    140 
    141     if (layoutBox.isReplaced())
    142         return displayBox.height();
    143 
    144     if (inlineItem.isContainerStart() || inlineItem.isContainerEnd())
    145         return fontMetrics.height() + displayBox.verticalBorder() + displayBox.verticalPadding().valueOr(0);
    146 
    147     // Non-replaced inline box (e.g. inline-block)
    148     return displayBox.height();
    149 }
    150 
    151128InlineFormattingContext::LineLayout::LineContent InlineFormattingContext::LineLayout::placeInlineItems(const LineInput& lineInput) const
    152129{
    153     auto mimimumLineHeight = m_formattingRoot.style().computedLineHeight();
    154     auto baselineOffset = Line::halfLeadingMetrics(m_formattingRoot.style().fontMetrics(), mimimumLineHeight).height;
    155     auto line = Line { layoutState(), lineInput.horizontalConstraint.logicalTopLeft, lineInput.horizontalConstraint.availableLogicalWidth, mimimumLineHeight, baselineOffset };
     130    std::unique_ptr<Line> line;
     131    if (lineInput.skipVerticalAligment == LineInput::SkipVerticalAligment::No) {
     132        auto mimimumLineHeight = m_formattingRoot.style().computedLineHeight();
     133        auto baselineOffset = Line::halfLeadingMetrics(m_formattingRoot.style().fontMetrics(), mimimumLineHeight).height;
     134        line = std::make_unique<Line>(layoutState(), lineInput.horizontalConstraint.logicalTopLeft, lineInput.horizontalConstraint.availableLogicalWidth, mimimumLineHeight, baselineOffset);
     135    } else
     136        line = std::make_unique<Line>(layoutState(), lineInput.horizontalConstraint.logicalTopLeft.x(), lineInput.horizontalConstraint.availableLogicalWidth);
    156137
    157138    Vector<WeakPtr<InlineItem>> floats;
     
    166147            auto& inlineItem = uncommittedRun.inlineItem;
    167148            if (inlineItem.isHardLineBreak())
    168                 line.appendHardLineBreak(inlineItem);
     149                line->appendHardLineBreak(inlineItem);
    169150            else if (is<InlineTextItem>(inlineItem))
    170                 line.appendTextContent(downcast<InlineTextItem>(inlineItem), uncommittedRun.size);
     151                line->appendTextContent(downcast<InlineTextItem>(inlineItem), uncommittedRun.logicalWidth);
    171152            else if (inlineItem.isContainerStart())
    172                 line.appendInlineContainerStart(inlineItem, uncommittedRun.size);
     153                line->appendInlineContainerStart(inlineItem, uncommittedRun.logicalWidth);
    173154            else if (inlineItem.isContainerEnd())
    174                 line.appendInlineContainerEnd(inlineItem, uncommittedRun.size);
     155                line->appendInlineContainerEnd(inlineItem, uncommittedRun.logicalWidth);
    175156            else if (inlineItem.layoutBox().isReplaced())
    176                 line.appendReplacedInlineBox(inlineItem, uncommittedRun.size);
     157                line->appendReplacedInlineBox(inlineItem, uncommittedRun.logicalWidth);
    177158            else
    178                 line.appendNonReplacedInlineBox(inlineItem, uncommittedRun.size);
     159                line->appendNonReplacedInlineBox(inlineItem, uncommittedRun.logicalWidth);
    179160        }
    180161        uncommittedContent.reset();
     
    184165        // This might change at some point.
    185166        ASSERT(committedInlineItemCount);
    186         return LineContent { lineInput.firstInlineItemIndex + (committedInlineItemCount - 1), WTFMove(floats), line.close() };
     167        return LineContent { lineInput.firstInlineItemIndex + (committedInlineItemCount - 1), WTFMove(floats), line->close() };
    187168    };
    188169    LineBreaker lineBreaker;
    189170    // Iterate through the inline content and place the inline boxes on the current line.
    190171    for (auto inlineItemIndex = lineInput.firstInlineItemIndex; inlineItemIndex < lineInput.inlineItems.size(); ++inlineItemIndex) {
    191         auto availableWidth = line.availableWidth() - uncommittedContent.width();
    192         auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
     172        auto availableWidth = line->availableWidth() - uncommittedContent.width();
     173        auto currentLogicalRight = line->contentLogicalRight() + uncommittedContent.width();
    193174        auto& inlineItem = lineInput.inlineItems[inlineItemIndex];
    194175        auto itemLogicalWidth = inlineItemWidth(layoutState(), *inlineItem, currentLogicalRight);
    195176
    196177        // FIXME: Ensure LineContext::trimmableWidth includes uncommitted content if needed.
    197         auto breakingContext = lineBreaker.breakingContext(*inlineItem, itemLogicalWidth, { availableWidth, currentLogicalRight, line.trailingTrimmableWidth(), !line.hasContent() });
     178        auto breakingContext = lineBreaker.breakingContext(*inlineItem, itemLogicalWidth, { availableWidth, currentLogicalRight, line->trailingTrimmableWidth(), !line->hasContent() });
    198179        if (breakingContext.isAtBreakingOpportunity)
    199180            commitPendingContent();
     
    217198            // Shrink availble space for current line and move existing inline runs.
    218199            auto floatBoxWidth = layoutState().displayBoxForLayoutBox(floatBox).marginBoxWidth();
    219             floatBox.isLeftFloatingPositioned() ? line.moveLogicalLeft(floatBoxWidth) : line.moveLogicalRight(floatBoxWidth);
     200            floatBox.isLeftFloatingPositioned() ? line->moveLogicalLeft(floatBoxWidth) : line->moveLogicalRight(floatBoxWidth);
    220201            floats.append(makeWeakPtr(*inlineItem));
    221202            ++committedInlineItemCount;
     
    223204        }
    224205
    225         Optional<LayoutUnit> itemLogicalHeight;
    226         if (lineInput.skipVerticalAligment == LineInput::SkipVerticalAligment::No)
    227             itemLogicalHeight = inlineItemHeight(layoutState(), *inlineItem);
    228         uncommittedContent.add(*inlineItem, { itemLogicalWidth, itemLogicalHeight });
    229 
     206        uncommittedContent.add(*inlineItem, itemLogicalWidth);
    230207        if (breakingContext.isAtBreakingOpportunity)
    231208            commitPendingContent();
     
    342319
    343320        auto& inlineItem = lineRun->inlineItem;
    344         auto& inlineRun = lineRun->inlineRun;
     321        auto& logicalRect = lineRun->logicalRect;
    345322        auto& layoutBox = inlineItem.layoutBox();
    346323        auto& displayBox = layoutState().displayBoxForLayoutBox(layoutBox);
    347324
    348325        if (inlineItem.isHardLineBreak()) {
    349             displayBox.setTopLeft(inlineRun.logicalTopLeft());
    350             displayBox.setContentBoxWidth(inlineRun.logicalWidth());
    351             displayBox.setContentBoxHeight(inlineRun.logicalHeight());
    352             m_formattingState.addInlineRun(std::make_unique<Display::Run>(inlineRun));
     326            displayBox.setTopLeft(logicalRect.topLeft());
     327            displayBox.setContentBoxWidth(logicalRect.width());
     328            displayBox.setContentBoxHeight(logicalRect.height());
     329            m_formattingState.addInlineRun(std::make_unique<Display::Run>(logicalRect));
    353330            continue;
    354331        }
     
    356333        // Inline level box (replaced or inline-block)
    357334        if (inlineItem.isBox()) {
    358             auto topLeft = inlineRun.logicalTopLeft();
     335            auto topLeft = logicalRect.topLeft();
    359336            if (layoutBox.isInFlowPositioned())
    360337                topLeft += Geometry::inFlowPositionedPositionOffset(layoutState(), layoutBox);
    361338            displayBox.setTopLeft(topLeft);
    362             lineBox.expandHorizontally(inlineRun.logicalWidth());
    363             m_formattingState.addInlineRun(std::make_unique<Display::Run>(inlineRun));
     339            lineBox.expandHorizontally(logicalRect.width());
     340            m_formattingState.addInlineRun(std::make_unique<Display::Run>(logicalRect));
    364341            continue;
    365342        }
     
    367344        // Inline level container start (<span>)
    368345        if (inlineItem.isContainerStart()) {
    369             displayBox.setTopLeft(inlineRun.logicalTopLeft());
    370             lineBox.expandHorizontally(inlineRun.logicalWidth());
     346            displayBox.setTopLeft(logicalRect.topLeft());
     347            lineBox.expandHorizontally(logicalRect.width());
    371348            continue;
    372349        }
     
    379356                displayBox.moveVertically(inflowOffset.height());
    380357            }
    381             auto marginBoxWidth = inlineRun.logicalLeft() - displayBox.left();
     358            auto marginBoxWidth = logicalRect.left() - displayBox.left();
    382359            auto contentBoxWidth = marginBoxWidth - (displayBox.marginStart() + displayBox.borderLeft() + displayBox.paddingLeft().valueOr(0));
    383360            // FIXME fix it for multiline.
    384361            displayBox.setContentBoxWidth(contentBoxWidth);
    385             displayBox.setContentBoxHeight(inlineRun.logicalHeight());
    386             lineBox.expandHorizontally(inlineRun.logicalWidth());
     362            displayBox.setContentBoxHeight(logicalRect.height());
     363            lineBox.expandHorizontally(logicalRect.width());
    387364            continue;
    388365        }
    389366
    390367        // Text content. Try to join multiple text runs when possible.
    391         ASSERT(inlineRun.textContext());       
     368        ASSERT(lineRun->textContext);       
    392369        const Line::Content::Run* previousLineRun = !index ? nullptr : lineRuns[index - 1].get();
    393370        if (!lineRun->isCollapsed) {
     
    395372            auto requiresNewRun = !index || !previousRunCanBeExtended || &layoutBox != &previousLineRun->inlineItem.layoutBox();
    396373            if (requiresNewRun)
    397                 m_formattingState.addInlineRun(std::make_unique<Display::Run>(inlineRun));
     374                m_formattingState.addInlineRun(std::make_unique<Display::Run>(logicalRect, Display::Run::TextContext { lineRun->textContext->start, lineRun->textContext->length }));
    398375            else {
    399376                auto& lastDisplayRun = m_formattingState.inlineRuns().last();
    400                 lastDisplayRun->expandHorizontally(inlineRun.logicalWidth());
    401                 lastDisplayRun->textContext()->expand(inlineRun.textContext()->length());
     377                lastDisplayRun->expandHorizontally(logicalRect.width());
     378                lastDisplayRun->textContext()->expand(lineRun->textContext->length);
    402379            }
    403             lineBox.expandHorizontally(inlineRun.logicalWidth());
     380            lineBox.expandHorizontally(logicalRect.width());
    404381        }
    405382        // FIXME take content breaking into account when part of the layout box is on the previous line.
     
    407384        if (firstInlineRunForLayoutBox) {
    408385            // Setup display box for the associated layout box.
    409             displayBox.setTopLeft(inlineRun.logicalTopLeft());
    410             displayBox.setContentBoxWidth(lineRun->isCollapsed ? LayoutUnit() : inlineRun.logicalWidth());
    411             displayBox.setContentBoxHeight(inlineRun.logicalHeight());
     386            displayBox.setTopLeft(logicalRect.topLeft());
     387            displayBox.setContentBoxWidth(lineRun->isCollapsed ? LayoutUnit() : logicalRect.width());
     388            displayBox.setContentBoxHeight(logicalRect.height());
    412389        } else if (!lineRun->isCollapsed) {
    413390            // FIXME fix it for multirun/multiline.
    414             displayBox.setContentBoxWidth(displayBox.contentBoxWidth() + inlineRun.logicalWidth());
     391            displayBox.setContentBoxWidth(displayBox.contentBoxWidth() + logicalRect.width());
    415392        }
    416393    }
  • trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp

    r246158 r246206  
    4848}
    4949
    50 Line::Content::Run::Run(Display::Run inlineRun, const InlineItem& inlineItem, bool isCollapsed, bool canBeExtended)
    51     : inlineRun(inlineRun)
    52     , inlineItem(inlineItem)
     50Line::Content::Run::Run(const InlineItem& inlineItem, const Display::Rect& logicalRect, TextContext textContext, bool isCollapsed, bool canBeExtended)
     51    : inlineItem(inlineItem)
     52    , logicalRect(logicalRect)
     53    , textContext(textContext)
    5354    , isCollapsed(isCollapsed)
    5455    , canBeExtended(canBeExtended)
     56{
     57}
     58
     59Line::Line(const LayoutState& layoutState, LayoutUnit logicalLeft, LayoutUnit availableWidth)
     60    : m_layoutState(layoutState)
     61    , m_content(std::make_unique<Line::Content>())
     62    , m_logicalTopLeft(logicalLeft, 0)
     63    , m_lineLogicalWidth(availableWidth)
     64    , m_skipVerticalAligment(true)
    5565{
    5666}
     
    6878{
    6979    removeTrailingTrimmableContent();
    70     // Convert inline run geometry from relative to the baseline to relative to logical top.
    71     for (auto& run : m_content->runs()) {
    72         auto adjustedLogicalTop = run->inlineRun.logicalTop() + m_logicalHeight.height + m_logicalTopLeft.y();
    73         run->inlineRun.setLogicalTop(adjustedLogicalTop);
     80    if (!m_skipVerticalAligment) {
     81        // Convert inline run geometry from relative to the baseline to relative to logical top.
     82        for (auto& run : m_content->runs()) {
     83            auto adjustedLogicalTop = run->logicalRect.top() + m_logicalHeight.height + m_logicalTopLeft.y();
     84            run->logicalRect.setTop(adjustedLogicalTop);
     85        }
    7486    }
    7587    m_content->setLogicalRect({ logicalTop(), logicalLeft(), contentLogicalWidth(), logicalHeight() });
     
    8395    for (auto* trimmableRun : m_trimmableContent) {
    8496        trimmableRun->isCollapsed = true;
    85         trimmableWidth += trimmableRun->inlineRun.logicalWidth();
     97        trimmableWidth += trimmableRun->logicalRect.width();
    8698    }
    8799    m_contentLogicalWidth -= trimmableWidth;
     
    97109    m_lineLogicalWidth -= delta;
    98110    for (auto& run : m_content->runs())
    99         run->inlineRun.moveHorizontally(delta);
     111        run->logicalRect.moveHorizontally(delta);
    100112}
    101113
     
    110122    LayoutUnit trimmableWidth;
    111123    for (auto* trimmableRun : m_trimmableContent)
    112         trimmableWidth += trimmableRun->inlineRun.logicalWidth();
     124        trimmableWidth += trimmableRun->logicalRect.width();
    113125    return trimmableWidth;
    114126}
     
    116128void Line::appendNonBreakableSpace(const InlineItem& inlineItem, const Display::Rect& logicalRect)
    117129{
    118     m_content->runs().append(std::make_unique<Content::Run>(Display::Run { logicalRect }, inlineItem, false, false));
     130    m_content->runs().append(std::make_unique<Content::Run>(inlineItem, logicalRect, Content::Run::TextContext { }, false, false));
    119131    m_contentLogicalWidth += logicalRect.width();
    120132}
    121133
    122 void Line::appendInlineContainerStart(const InlineItem& inlineItem, InlineItemSize runSize)
    123 {
    124     if (runSize.logicalHeight)
    125         adjustBaselineAndLineHeight(inlineItem, *runSize.logicalHeight);
    126 
    127     auto& layoutBox = inlineItem.layoutBox();
    128     auto& fontMetrics = layoutBox.style().fontMetrics();
    129     auto& displayBox = m_layoutState.displayBoxForLayoutBox(layoutBox);
    130 
    131     auto logicalTop = -fontMetrics.ascent() - displayBox.borderTop() - displayBox.paddingTop().valueOr(0);
    132     auto logicalRect = Display::Rect { logicalTop, contentLogicalRight(), runSize.logicalWidth, runSize.logicalHeight.valueOr(0) };
     134void Line::appendInlineContainerStart(const InlineItem& inlineItem, LayoutUnit logicalWidth)
     135{
     136    auto logicalRect = Display::Rect { };
     137    logicalRect.setLeft(contentLogicalRight());
     138    logicalRect.setWidth(logicalWidth);
     139
     140    if (!m_skipVerticalAligment) {
     141        auto logicalHeight = inlineItemHeight(inlineItem);
     142        adjustBaselineAndLineHeight(inlineItem, logicalHeight);
     143
     144        auto& displayBox = m_layoutState.displayBoxForLayoutBox(inlineItem.layoutBox());
     145        auto logicalTop = -inlineItem.style().fontMetrics().ascent() - displayBox.borderTop() - displayBox.paddingTop().valueOr(0);
     146        logicalRect.setTop(logicalTop);
     147        logicalRect.setHeight(logicalHeight);
     148    }
    133149    appendNonBreakableSpace(inlineItem, logicalRect);
    134150}
    135151
    136 void Line::appendInlineContainerEnd(const InlineItem& inlineItem, InlineItemSize runSize)
     152void Line::appendInlineContainerEnd(const InlineItem& inlineItem, LayoutUnit logicalWidth)
    137153{
    138154    // This is really just a placeholder to mark the end of the inline level container.
    139     auto logicalRect = Display::Rect { 0, contentLogicalRight(), runSize.logicalWidth, runSize.logicalHeight.valueOr(0) };
     155    auto logicalRect = Display::Rect { 0, contentLogicalRight(), logicalWidth, 0 };
    140156    appendNonBreakableSpace(inlineItem, logicalRect);
    141157}
    142158
    143 void Line::appendTextContent(const InlineTextItem& inlineItem, InlineItemSize runSize)
     159void Line::appendTextContent(const InlineTextItem& inlineItem, LayoutUnit logicalWidth)
    144160{
    145161    auto isTrimmable = TextUtil::isTrimmableContent(inlineItem);
     
    169185    auto isCompletelyCollapsed = shouldCollapseCompletely();
    170186    auto canBeExtended = !isCompletelyCollapsed && !inlineItem.isCollapsed();
    171     auto logicalRect = Display::Rect { -inlineItem.style().fontMetrics().ascent(), contentLogicalRight(), runSize.logicalWidth, runSize.logicalHeight.valueOr(0) };
    172     auto textContext = Display::Run::TextContext { inlineItem.start(), inlineItem.isCollapsed() ? 1 : inlineItem.length() };
    173     auto displayRun = Display::Run(logicalRect, textContext);
    174 
    175     auto lineItem = std::make_unique<Content::Run>(displayRun, inlineItem, isCompletelyCollapsed, canBeExtended);
     187   
     188    auto logicalRect = Display::Rect { };
     189    logicalRect.setLeft(contentLogicalRight());
     190    logicalRect.setWidth(logicalWidth);
     191    if (!m_skipVerticalAligment) {
     192        logicalRect.setTop(-inlineItem.style().fontMetrics().ascent());
     193        logicalRect.setHeight(inlineItemHeight(inlineItem));
     194    }
     195
     196    auto textContext = Content::Run::TextContext { inlineItem.start(), inlineItem.isCollapsed() ? 1 : inlineItem.length() };
     197    auto lineItem = std::make_unique<Content::Run>(inlineItem, logicalRect, textContext, isCompletelyCollapsed, canBeExtended);
    176198    if (isTrimmable)
    177199        m_trimmableContent.add(lineItem.get());
    178200
    179201    m_content->runs().append(WTFMove(lineItem));
    180     m_contentLogicalWidth += isCompletelyCollapsed ? LayoutUnit() : runSize.logicalWidth;
    181 }
    182 
    183 void Line::appendNonReplacedInlineBox(const InlineItem& inlineItem, InlineItemSize runSize)
    184 {
    185     if (runSize.logicalHeight)
    186         adjustBaselineAndLineHeight(inlineItem, *runSize.logicalHeight);
    187 
    188     auto inlineBoxHeight = runSize.logicalHeight.valueOr(0);
     202    m_contentLogicalWidth += isCompletelyCollapsed ? LayoutUnit() : logicalWidth;
     203}
     204
     205void Line::appendNonReplacedInlineBox(const InlineItem& inlineItem, LayoutUnit logicalWidth)
     206{
    189207    auto& displayBox = m_layoutState.displayBoxForLayoutBox(inlineItem.layoutBox());
    190     auto logicalTop = -inlineBoxHeight;
    191     auto horizontalMargin = displayBox.horizontalMargin();
    192     auto logicalRect = Display::Rect { logicalTop, contentLogicalRight() + horizontalMargin.start, runSize.logicalWidth, inlineBoxHeight };
    193 
    194     m_content->runs().append(std::make_unique<Content::Run>(Display::Run { logicalRect }, inlineItem, false, false));
    195     m_contentLogicalWidth += (runSize.logicalWidth + horizontalMargin.start + horizontalMargin.end);
     208    auto horizontalMargin = displayBox.horizontalMargin();   
     209    auto logicalRect = Display::Rect { };
     210
     211    logicalRect.setLeft(contentLogicalRight() + horizontalMargin.start);
     212    logicalRect.setWidth(logicalWidth);
     213    if (!m_skipVerticalAligment) {
     214        auto logicalHeight = inlineItemHeight(inlineItem);
     215        adjustBaselineAndLineHeight(inlineItem, logicalHeight);
     216
     217        logicalRect.setTop(-logicalHeight);
     218        logicalRect.setHeight(logicalHeight);
     219    }
     220
     221    m_content->runs().append(std::make_unique<Content::Run>(inlineItem, logicalRect, Content::Run::TextContext { }, false, false));
     222    m_contentLogicalWidth += (logicalWidth + horizontalMargin.start + horizontalMargin.end);
    196223    m_trimmableContent.clear();
    197224}
    198225
    199 void Line::appendReplacedInlineBox(const InlineItem& inlineItem, InlineItemSize runSize)
     226void Line::appendReplacedInlineBox(const InlineItem& inlineItem, LayoutUnit logicalWidth)
    200227{
    201228    // FIXME Surely replaced boxes behave differently.
    202     appendNonReplacedInlineBox(inlineItem, runSize);
     229    appendNonReplacedInlineBox(inlineItem, logicalWidth);
    203230}
    204231
     
    207234    auto ascent = inlineItem.layoutBox().style().fontMetrics().ascent();
    208235    auto logicalRect = Display::Rect { -ascent, contentLogicalRight(), { }, logicalHeight() };
    209     m_content->runs().append(std::make_unique<Content::Run>(Display::Run { logicalRect }, inlineItem, false, false));
     236    m_content->runs().append(std::make_unique<Content::Run>(inlineItem, logicalRect, Content::Run::TextContext { }, false, false));
    210237}
    211238
     
    240267}
    241268
     269LayoutUnit Line::inlineItemHeight(const InlineItem& inlineItem) const
     270{
     271    ASSERT(!m_skipVerticalAligment);
     272    auto& fontMetrics = inlineItem.style().fontMetrics();
     273    if (inlineItem.isLineBreak() || is<InlineTextItem>(inlineItem))
     274        return fontMetrics.height();
     275
     276    auto& layoutBox = inlineItem.layoutBox();
     277    ASSERT(m_layoutState.hasDisplayBox(layoutBox));
     278    auto& displayBox = m_layoutState.displayBoxForLayoutBox(layoutBox);
     279
     280    if (layoutBox.isFloatingPositioned())
     281        return displayBox.marginBox().height();
     282
     283    if (layoutBox.isReplaced())
     284        return displayBox.height();
     285
     286    if (inlineItem.isContainerStart() || inlineItem.isContainerEnd())
     287        return fontMetrics.height() + displayBox.verticalBorder() + displayBox.verticalPadding().valueOr(0);
     288
     289    // Non-replaced inline box (e.g. inline-block)
     290    return displayBox.height();
     291}
     292
    242293Line::UsedHeightAndDepth Line::halfLeadingMetrics(const FontMetrics& fontMetrics, LayoutUnit lineLogicalHeight)
    243294{
  • trunk/Source/WebCore/layout/inlineformatting/InlineLine.h

    r246158 r246206  
    4040public:
    4141    Line(const LayoutState&, const LayoutPoint& topLeft, LayoutUnit availableWidth, LayoutUnit minimumLineHeight, LayoutUnit baselineOffset);
     42    Line(const LayoutState&, LayoutUnit logicalLeft, LayoutUnit availableWidth);
    4243
    4344    class Content {
    4445    public:
    4546        struct Run {
    46             Run(Display::Run, const InlineItem&, bool isCollapsed, bool canBeExtended);
     47            struct TextContext {
     48                unsigned start { 0 };
     49                unsigned length { 0 };
     50            };
     51            Run(const InlineItem&, const Display::Rect&, TextContext, bool isCollapsed, bool canBeExtended);
    4752
     53            const InlineItem& inlineItem;
    4854            // Relative to the baseline.
    49             Display::Run inlineRun;
    50             const InlineItem& inlineItem;
     55            Display::Rect logicalRect;
     56            Optional<TextContext> textContext;
    5157            bool isCollapsed { false };
    5258            bool canBeExtended { false };
     
    7682    std::unique_ptr<Content> close();
    7783
    78     struct InlineItemSize {
    79         LayoutUnit logicalWidth;
    80         Optional<LayoutUnit> logicalHeight;
    81     };
    82     void appendTextContent(const InlineTextItem&, InlineItemSize);
    83     void appendNonReplacedInlineBox(const InlineItem&, InlineItemSize);
    84     void appendReplacedInlineBox(const InlineItem&, InlineItemSize);
    85     void appendInlineContainerStart(const InlineItem&, InlineItemSize);
    86     void appendInlineContainerEnd(const InlineItem&, InlineItemSize);
     84    void appendTextContent(const InlineTextItem&, LayoutUnit logicalWidth);
     85    void appendNonReplacedInlineBox(const InlineItem&, LayoutUnit logicalWidth);
     86    void appendReplacedInlineBox(const InlineItem&, LayoutUnit logicalWidth);
     87    void appendInlineContainerStart(const InlineItem&, LayoutUnit logicalWidth);
     88    void appendInlineContainerEnd(const InlineItem&, LayoutUnit logicalWidth);
    8789    void appendHardLineBreak(const InlineItem&);
    8890
     
    118120
    119121    void adjustBaselineAndLineHeight(const InlineItem&, LayoutUnit runHeight);
     122    LayoutUnit inlineItemHeight(const InlineItem&) const;
    120123
    121124    const LayoutState& m_layoutState;
     
    128131    UsedHeightAndDepth m_logicalHeight;
    129132    LayoutUnit m_lineLogicalWidth;
     133    bool m_skipVerticalAligment { false };
    130134};
    131135
Note: See TracChangeset for help on using the changeset viewer.