Title: [266276] trunk/Source/WebCore
Revision
266276
Author
[email protected]
Date
2020-08-28 06:37:03 -0700 (Fri, 28 Aug 2020)

Log Message

[LFC][IFC] Move inline alignment code to LineBox
https://bugs.webkit.org/show_bug.cgi?id=215117

Reviewed by Antti Koivisto.

LineBox is responsible for aligning the runs both vertically and horizontally (LineContentAligner -> LineBox).
(Note that LineBox::m_runRectList is transitional and will eventually be converted to inline boxes.)

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::lineLayout):
(WebCore::Layout::InlineFormattingContext::setDisplayBoxesForLine):
(WebCore::Layout::HangingContent::width const): Deleted.
(WebCore::Layout::HangingContent::isConditional const): Deleted.
(WebCore::Layout::HangingContent::setIsConditional): Deleted.
(WebCore::Layout::HangingContent::expand): Deleted.
(): Deleted.
(WebCore::Layout::HangingContent::reset): Deleted.
(WebCore::Layout::LineContentAligner::inlineRectList const): Deleted.
(WebCore::Layout::LineContentAligner::formattingContext const): Deleted.
(WebCore::Layout::LineContentAligner::layoutState const): Deleted.
(WebCore::Layout::LineContentAligner::LineContentAligner): Deleted.
(WebCore::Layout::LineContentAligner::alignHorizontally): Deleted.
(WebCore::Layout::LineContentAligner::alignVertically): Deleted.
(WebCore::Layout::LineContentAligner::adjustBaselineAndLineHeight): Deleted.
(WebCore::Layout::LineContentAligner::collectHangingContent const): Deleted.
* layout/inlineformatting/InlineFormattingContext.h:
* layout/inlineformatting/InlineLineBox.h:
(WebCore::Layout::LineBox::inlineRectList const):
(WebCore::Layout::LineBox::logicalBottom const):
(WebCore::Layout::LineBox::logicalRect const):
(WebCore::Layout::LineBox::scrollableOverflow const):
(WebCore::Layout::LineBox::formattingContext const):
(WebCore::Layout::LineBox::layoutState const):
(WebCore::Layout::LineBox::setLogicalHeight): Deleted.
(WebCore::Layout::LineBox::setLogicalWidth): Deleted.
(WebCore::Layout::LineBox::moveHorizontally): Deleted.
(WebCore::Layout::LineBox::expandHorizontally): Deleted.
(WebCore::Layout::LineBox::shrinkHorizontally): Deleted.
(WebCore::Layout::LineBox::expandVertically): Deleted.
(WebCore::Layout::LineBox::shrinkVertically): Deleted.
(WebCore::Layout::LineBox::isConsideredEmpty const): Deleted.
(WebCore::Layout::LineBox::setIsConsideredEmpty): Deleted.
(WebCore::Layout::LineBox::setIsConsideredNonEmpty): Deleted.
(WebCore::Layout::LineBox::LineBox): Deleted.
(WebCore::Layout::LineBox::resetAlignmentBaseline): Deleted.
* layout/inlineformatting/InlineLineBuilder.h:
(WebCore::Layout::LineBuilder::lineLogicalWidth const):
(WebCore::Layout::LineBuilder::availableWidth const):
* layout/inlineformatting/LineLayoutContext.cpp:
(WebCore::Layout::LineLayoutContext::close):
* layout/inlineformatting/LineLayoutContext.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (266275 => 266276)


--- trunk/Source/WebCore/ChangeLog	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/ChangeLog	2020-08-28 13:37:03 UTC (rev 266276)
@@ -1,3 +1,59 @@
+2020-08-28  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Move inline alignment code to LineBox
+        https://bugs.webkit.org/show_bug.cgi?id=215117
+
+        Reviewed by Antti Koivisto.
+
+        LineBox is responsible for aligning the runs both vertically and horizontally (LineContentAligner -> LineBox).
+        (Note that LineBox::m_runRectList is transitional and will eventually be converted to inline boxes.)
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::lineLayout):
+        (WebCore::Layout::InlineFormattingContext::setDisplayBoxesForLine):
+        (WebCore::Layout::HangingContent::width const): Deleted.
+        (WebCore::Layout::HangingContent::isConditional const): Deleted.
+        (WebCore::Layout::HangingContent::setIsConditional): Deleted.
+        (WebCore::Layout::HangingContent::expand): Deleted.
+        (): Deleted.
+        (WebCore::Layout::HangingContent::reset): Deleted.
+        (WebCore::Layout::LineContentAligner::inlineRectList const): Deleted.
+        (WebCore::Layout::LineContentAligner::formattingContext const): Deleted.
+        (WebCore::Layout::LineContentAligner::layoutState const): Deleted.
+        (WebCore::Layout::LineContentAligner::LineContentAligner): Deleted.
+        (WebCore::Layout::LineContentAligner::alignHorizontally): Deleted.
+        (WebCore::Layout::LineContentAligner::alignVertically): Deleted.
+        (WebCore::Layout::LineContentAligner::adjustBaselineAndLineHeight): Deleted.
+        (WebCore::Layout::LineContentAligner::collectHangingContent const): Deleted.
+        * layout/inlineformatting/InlineFormattingContext.h:
+        * layout/inlineformatting/InlineLineBox.h:
+        (WebCore::Layout::LineBox::inlineRectList const):
+        (WebCore::Layout::LineBox::logicalBottom const):
+        (WebCore::Layout::LineBox::logicalRect const):
+        (WebCore::Layout::LineBox::scrollableOverflow const):
+        (WebCore::Layout::LineBox::formattingContext const):
+        (WebCore::Layout::LineBox::layoutState const):
+        (WebCore::Layout::LineBox::setLogicalHeight): Deleted.
+        (WebCore::Layout::LineBox::setLogicalWidth): Deleted.
+        (WebCore::Layout::LineBox::moveHorizontally): Deleted.
+        (WebCore::Layout::LineBox::expandHorizontally): Deleted.
+        (WebCore::Layout::LineBox::shrinkHorizontally): Deleted.
+        (WebCore::Layout::LineBox::expandVertically): Deleted.
+        (WebCore::Layout::LineBox::shrinkVertically): Deleted.
+        (WebCore::Layout::LineBox::isConsideredEmpty const): Deleted.
+        (WebCore::Layout::LineBox::setIsConsideredEmpty): Deleted.
+        (WebCore::Layout::LineBox::setIsConsideredNonEmpty): Deleted.
+        (WebCore::Layout::LineBox::LineBox): Deleted.
+        (WebCore::Layout::LineBox::resetAlignmentBaseline): Deleted.
+        * layout/inlineformatting/InlineLineBuilder.h:
+        (WebCore::Layout::LineBuilder::lineLogicalWidth const):
+        (WebCore::Layout::LineBuilder::availableWidth const):
+        * layout/inlineformatting/LineLayoutContext.cpp:
+        (WebCore::Layout::LineLayoutContext::close):
+        * layout/inlineformatting/LineLayoutContext.h:
+
 2020-08-28  Chris Lord  <[email protected]>
 
         Add WebGL(2) context support to OffscreenCanvas
@@ -44,7 +100,7 @@
         * workers/service/context/ServiceWorkerThread.cpp:
         (WebCore::ServiceWorkerThread::ServiceWorkerThread):
 
-2020-08-27  Zalan Bujtas  <[email protected]>
+2020-08-28  Zalan Bujtas  <[email protected]>
 
         [LFC][IFC] LineBuilder:Run should not have vertical geometry
         https://bugs.webkit.org/show_bug.cgi?id=215068

Modified: trunk/Source/WebCore/Sources.txt (266275 => 266276)


--- trunk/Source/WebCore/Sources.txt	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/Sources.txt	2020-08-28 13:37:03 UTC (rev 266276)
@@ -1436,6 +1436,7 @@
 layout/inlineformatting/InlineFormattingContextQuirks.cpp
 layout/inlineformatting/InlineFormattingState.cpp
 layout/inlineformatting/InlineItem.cpp
+layout/inlineformatting/InlineLineBox.cpp
 layout/inlineformatting/InlineLineBreaker.cpp
 layout/inlineformatting/InlineLineBuilder.cpp
 layout/inlineformatting/InlineTextItem.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (266275 => 266276)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-08-28 13:37:03 UTC (rev 266276)
@@ -9560,6 +9560,7 @@
 		6F5B7EAA2300A79E0067D9C3 /* TableGrid.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TableGrid.cpp; sourceTree = "<group>"; };
 		6F6383F42427AF4900DABA53 /* LayoutInitialContainingBlock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutInitialContainingBlock.h; sourceTree = "<group>"; };
 		6F6638D4249E268B001925FC /* TableWrapperBlockFormattingContextQuirks.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TableWrapperBlockFormattingContextQuirks.cpp; sourceTree = "<group>"; };
+		6F69A79924D6FAB800E6B85D /* InlineLineBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineLineBox.cpp; sourceTree = "<group>"; };
 		6F73918C2106CEDD006AF262 /* LayoutUnits.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutUnits.h; sourceTree = "<group>"; };
 		6F77868523491AC6004D9636 /* DisplayPainter.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DisplayPainter.cpp; sourceTree = "<group>"; };
 		6F77868723491AD7004D9636 /* DisplayPainter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayPainter.h; sourceTree = "<group>"; };
@@ -17420,6 +17421,7 @@
 				115CFA7C208B8E10001E6991 /* InlineFormattingState.h */,
 				6F7B8CEC23626E6600C9FF15 /* InlineItem.cpp */,
 				6FE7CFA02177EEF1005B1573 /* InlineItem.h */,
+				6F69A79924D6FAB800E6B85D /* InlineLineBox.cpp */,
 				6FB2400323DFF12700796458 /* InlineLineBox.h */,
 				6FE198132178397B00446F08 /* InlineLineBreaker.cpp */,
 				6FE198152178397C00446F08 /* InlineLineBreaker.h */,

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (266275 => 266276)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2020-08-28 13:37:03 UTC (rev 266276)
@@ -31,6 +31,7 @@
 #include "FloatingContext.h"
 #include "FontCascade.h"
 #include "InlineFormattingState.h"
+#include "InlineLineBox.h"
 #include "InlineTextItem.h"
 #include "InvalidationState.h"
 #include "LayoutBox.h"
@@ -76,301 +77,6 @@
     return nullptr;
 }
 
-struct HangingContent {
-public:
-    void reset();
-
-    InlineLayoutUnit width() const { return m_width; }
-    bool isConditional() const { return m_isConditional; }
-
-    void setIsConditional() { m_isConditional = true; }
-    void expand(InlineLayoutUnit width) { m_width += width; }
-
-private:
-    bool m_isConditional { false };
-    InlineLayoutUnit m_width { 0 };
-};
-
-void HangingContent::reset()
-{
-    m_isConditional = false;
-    m_width =  0;
-}
-
-class LineContentAligner {
-public:
-    LineContentAligner(const InlineFormattingContext&, LineBox&, const LineBuilder::RunList&, InlineLayoutUnit availableWidth);
-
-    enum class IsLastLineWithInlineContent { No, Yes };
-    void alignHorizontally(TextAlignMode, IsLastLineWithInlineContent);
-    void alignVertically();
-    void adjustBaselineAndLineHeight();
-
-    using InlineRunRectList = Vector<Display::InlineRect, 10>;
-    const InlineRunRectList& inlineRectList() const { return m_runRectList; }
-
-private:
-    HangingContent collectHangingContent(IsLastLineWithInlineContent) const;
-
-    const InlineFormattingContext& formattingContext() const { return m_inlineFormattingContext; }
-    LayoutState& layoutState() const { return formattingContext().layoutState(); }
-
-    const InlineFormattingContext& m_inlineFormattingContext;
-    LineBox& m_lineBox;
-    const LineBuilder::RunList& m_runs;
-    InlineRunRectList m_runRectList;
-    InlineLayoutUnit m_availableWidth;
-};
-
-LineContentAligner::LineContentAligner(const InlineFormattingContext& inlineFormattingContext, LineBox& lineBox, const LineBuilder::RunList& runs, InlineLayoutUnit availableWidth)
-    : m_inlineFormattingContext(inlineFormattingContext)
-    , m_lineBox(lineBox)
-    , m_runs(runs)
-    , m_availableWidth(availableWidth)
-{
-    for (auto& run : m_runs) {
-        auto runHeight = [&]() -> InlineLayoutUnit {
-            auto& fontMetrics = run.style().fontMetrics();
-            if (run.isText() || run.isLineBreak())
-                return fontMetrics.height();
-
-            if (run.isContainerStart() || run.isContainerEnd())
-                return fontMetrics.height();
-
-            auto& layoutBox = run.layoutBox();
-            auto& boxGeometry = inlineFormattingContext.geometryForBox(layoutBox);
-            if (layoutBox.isReplacedBox() || layoutBox.isFloatingPositioned())
-                return boxGeometry.contentBoxHeight();
-
-            // Non-replaced inline box (e.g. inline-block). It looks a bit misleading but their margin box is considered the content height here.
-            return boxGeometry.marginBoxHeight();
-        };
-        m_runRectList.append({ 0, run.logicalLeft(), run.logicalWidth(), runHeight() });
-    }
-}
-
-void LineContentAligner::alignHorizontally(TextAlignMode horizontalAlignment, IsLastLineWithInlineContent isLastLine)
-{
-    auto hangingContent = collectHangingContent(isLastLine);
-    auto availableWidth = m_availableWidth + hangingContent.width();
-    if (m_runs.isEmpty() || availableWidth <= 0)
-        return;
-
-    if (horizontalAlignment == TextAlignMode::Justify) {
-        auto accumulatedExpansion = InlineLayoutUnit { };
-        for (size_t index = 0; index < m_runs.size(); ++index) {
-            m_runRectList[index].moveHorizontally(accumulatedExpansion);
-
-            auto horizontalExpansion = m_runs[index].expansion().horizontalExpansion;
-            m_runRectList[index].expandHorizontally(horizontalExpansion);
-            accumulatedExpansion += horizontalExpansion;
-        }
-        return;
-    }
-
-    auto adjustmentForAlignment = [&] (auto availableWidth) -> Optional<InlineLayoutUnit> {
-        switch (horizontalAlignment) {
-        case TextAlignMode::Left:
-        case TextAlignMode::WebKitLeft:
-        case TextAlignMode::Start:
-            return { };
-        case TextAlignMode::Right:
-        case TextAlignMode::WebKitRight:
-        case TextAlignMode::End:
-            return std::max<InlineLayoutUnit>(availableWidth, 0);
-        case TextAlignMode::Center:
-        case TextAlignMode::WebKitCenter:
-            return std::max<InlineLayoutUnit>(availableWidth / 2, 0);
-        case TextAlignMode::Justify:
-            ASSERT_NOT_REACHED();
-            break;
-        }
-        ASSERT_NOT_REACHED();
-        return { };
-    };
-
-    if (auto adjustment = adjustmentForAlignment(availableWidth)) {
-        // FIXME: line box should not need to be moved, only the runs.
-        m_lineBox.moveHorizontally(*adjustment);
-        for (auto& runRect : m_runRectList)
-            runRect.moveHorizontally(*adjustment);
-    }
-}
-
-void LineContentAligner::alignVertically()
-{
-    auto scrollableOverflowRect = m_lineBox.logicalRect();
-    for (size_t index = 0; index < m_runs.size(); ++index) {
-        auto& run = m_runs[index];
-        auto& runRect = m_runRectList[index];
-        auto logicalTop = InlineLayoutUnit { };
-        auto& layoutBox = run.layoutBox();
-        auto verticalAlign = layoutBox.style().verticalAlign();
-        auto ascent = layoutBox.style().fontMetrics().ascent();
-
-        switch (verticalAlign) {
-        case VerticalAlign::Baseline:
-            if (run.isLineBreak() || run.isText())
-                logicalTop = m_lineBox.alignmentBaseline() - ascent;
-            else if (run.isContainerStart()) {
-                auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
-                logicalTop = m_lineBox.alignmentBaseline() - ascent - boxGeometry.borderTop() - boxGeometry.paddingTop().valueOr(0);
-            } else if (layoutBox.isInlineBlockBox() && layoutBox.establishesInlineFormattingContext()) {
-                auto& formattingState = layoutState().establishedInlineFormattingState(downcast<ContainerBox>(layoutBox));
-                // Spec makes us generate at least one line -even if it is empty.
-                auto inlineBlockBaseline = formattingState.displayInlineContent()->lineBoxes.last().baseline();
-                // The inline-block's baseline offset is relative to its content box. Let's convert it relative to the margin box.
-                //           _______________ <- margin box
-                //          |
-                //          |  ____________  <- border box
-                //          | |
-                //          | |  _________  <- content box
-                //          | | |   ^
-                //          | | |   |  <- baseline offset
-                //          | | |   |
-                //     text | | |   v text
-                //     -----|-|-|---------- <- baseline
-                //
-                auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
-                auto baselineFromMarginBox = boxGeometry.marginBefore() + boxGeometry.borderTop() + boxGeometry.paddingTop().valueOr(0) + inlineBlockBaseline;
-                logicalTop = m_lineBox.alignmentBaseline() - baselineFromMarginBox;
-            } else {
-                auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
-                logicalTop = m_lineBox.alignmentBaseline() - (boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0_lu) + runRect.height() + boxGeometry.marginAfter());
-            }
-            break;
-        case VerticalAlign::Top:
-            logicalTop = 0_lu;
-            break;
-        case VerticalAlign::Bottom:
-            logicalTop = m_lineBox.logicalBottom() - runRect.height();
-            break;
-        default:
-            ASSERT_NOT_IMPLEMENTED_YET();
-            break;
-        }
-        runRect.setTop(logicalTop);
-        // Adjust scrollable overflow if the run overflows the line.
-        scrollableOverflowRect.expandVerticallyToContain(runRect);
-        // Convert runs from relative to the line top/left to the formatting root's border box top/left.
-        runRect.moveVertically(m_lineBox.logicalTop());
-        runRect.moveHorizontally(m_lineBox.logicalLeft());
-    }
-    m_lineBox.setScrollableOverflow(scrollableOverflowRect);
-}
-
-void LineContentAligner::adjustBaselineAndLineHeight()
-{
-    unsigned inlineContainerNestingLevel = 0;
-    auto hasSeenDirectTextOrLineBreak = false;
-    for (auto& run : m_runs) {
-        auto& layoutBox = run.layoutBox();
-        auto& style = layoutBox.style();
-        if (run.isText() || run.isLineBreak()) {
-            if (inlineContainerNestingLevel) {
-                // We've already adjusted the line height/baseline through the parent inline container. 
-                continue;
-            }
-            if (hasSeenDirectTextOrLineBreak) {
-                // e.g div>first text</div> or <div><span>nested<span>first direct text</div>.
-                continue;
-            }
-            hasSeenDirectTextOrLineBreak = true;
-            continue;
-        }
-
-        if (run.isContainerStart()) {
-            ++inlineContainerNestingLevel;
-            // Inline containers stretch the line by their font size.
-            // Vertical margins, paddings and borders don't contribute to the line height.
-            auto& fontMetrics = style.fontMetrics();
-            if (style.verticalAlign() == VerticalAlign::Baseline) {
-                auto halfLeading = LineBox::halfLeadingMetrics(fontMetrics, style.computedLineHeight());
-                // Both halfleading ascent and descent could be negative (tall font vs. small line-height value)
-                if (halfLeading.descent > 0)
-                    m_lineBox.setDescentIfGreater(halfLeading.descent);
-                if (halfLeading.ascent > 0)
-                    m_lineBox.setAscentIfGreater(halfLeading.ascent);
-                m_lineBox.setLogicalHeightIfGreater(m_lineBox.ascentAndDescent().height());
-            } else
-                m_lineBox.setLogicalHeightIfGreater(fontMetrics.height());
-            continue;
-        }
-
-        if (run.isContainerEnd()) {
-            // The line's baseline and height have already been adjusted at ContainerStart.
-            ASSERT(inlineContainerNestingLevel);
-            --inlineContainerNestingLevel;
-            continue;
-        }
-
-        if (run.isBox()) {
-            auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
-            auto marginBoxHeight = boxGeometry.marginBoxHeight();
-
-            switch (style.verticalAlign()) {
-            case VerticalAlign::Baseline: {
-                if (layoutBox.isInlineBlockBox() && layoutBox.establishesInlineFormattingContext()) {
-                    // Inline-blocks with inline content always have baselines.
-                    auto& formattingState = layoutState().establishedInlineFormattingState(downcast<ContainerBox>(layoutBox));
-                    // There has to be at least one line -even if it is empty.
-                    auto& lastLineBox = formattingState.displayInlineContent()->lineBoxes.last();
-                    auto beforeHeight = boxGeometry.marginBefore() + boxGeometry.borderTop() + boxGeometry.paddingTop().valueOr(0);
-                    m_lineBox.setAlignmentBaselineIfGreater(beforeHeight + lastLineBox.baseline());
-                    m_lineBox.setLogicalHeightIfGreater(marginBoxHeight);
-                } else {
-                    // Non inline-block boxes sit on the baseline (including their bottom margin).
-                    m_lineBox.setAscentIfGreater(marginBoxHeight);
-                    // Ignore negative descent (yes, negative descent is a thing).
-                    m_lineBox.setLogicalHeightIfGreater(marginBoxHeight + std::max<InlineLayoutUnit>(0, m_lineBox.ascentAndDescent().descent));
-                }
-                break;
-            }
-            case VerticalAlign::Top:
-                // Top align content never changes the baseline, it only pushes the bottom of the line further down.
-                m_lineBox.setLogicalHeightIfGreater(marginBoxHeight);
-                break;
-            case VerticalAlign::Bottom: {
-                // Bottom aligned, tall content pushes the baseline further down from the line top.
-                auto lineLogicalHeight = m_lineBox.logicalHeight();
-                if (marginBoxHeight > lineLogicalHeight) {
-                    m_lineBox.setLogicalHeightIfGreater(marginBoxHeight);
-                    m_lineBox.setAlignmentBaselineIfGreater(m_lineBox.alignmentBaseline() + (marginBoxHeight - lineLogicalHeight));
-                }
-                break;
-            }
-            default:
-                ASSERT_NOT_IMPLEMENTED_YET();
-                break;
-            }
-            continue;
-        }
-    }
-}
-
-HangingContent LineContentAligner::collectHangingContent(IsLastLineWithInlineContent isLastLineWithInlineContent) const
-{
-    auto hangingContent = HangingContent { };
-    if (isLastLineWithInlineContent == IsLastLineWithInlineContent::Yes)
-        hangingContent.setIsConditional();
-    for (auto& run : WTF::makeReversedRange(m_runs)) {
-        if (run.isContainerStart() || run.isContainerEnd())
-            continue;
-        if (run.isLineBreak()) {
-            hangingContent.setIsConditional();
-            continue;
-        }
-        if (!run.hasTrailingWhitespace())
-            break;
-        // Check if we have a preserved or hung whitespace.
-        if (run.style().whiteSpace() != WhiteSpace::PreWrap)
-            break;
-        // This is either a normal or conditionally hanging trailing whitespace.
-        hangingContent.expand(run.trailingWhitespaceWidth());
-    }
-    return hangingContent;
-}
-
 void InlineFormattingContext::layoutInFlowContent(InvalidationState& invalidationState, const ConstraintsForInFlowContent& constraints)
 {
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Start] -> inline formatting context -> formatting root(" << &root() << ")");
@@ -446,55 +152,25 @@
         auto partialLeadingContentLength = previousLine ? previousLine->overflowContentLength : WTF::nullopt;
         auto lineContent = lineLayoutContext.layoutInlineContent(line, needsLayoutRange, partialLeadingContentLength);
         auto lineContentRange = lineContent.inlineItemRange;
-
-        // FIXME: This is temporary and will eventually get merged to LineBox.
         auto isLastLineWithInlineContent = [&] {
+            if (lineContent.partialContent)
+                return false;
             if (lineContentRange.end == needsLayoutRange.end)
-                return LineContentAligner::IsLastLineWithInlineContent::Yes;
-            if (lineContent.partialContent)
-                return LineContentAligner::IsLastLineWithInlineContent::No;
+                return true;
             // Omit floats to see if this is the last line with inline content.
             for (auto i = needsLayoutRange.end; i--;) {
                 if (!inlineItems[i].isFloat())
-                    return i == lineContentRange.end - 1 ? LineContentAligner::IsLastLineWithInlineContent::Yes : LineContentAligner::IsLastLineWithInlineContent::No;
+                    return i == lineContentRange.end - 1;
             }
             // There has to be at least one non-float item.
             ASSERT_NOT_REACHED();
-            return LineContentAligner::IsLastLineWithInlineContent::No;
+            return false;
         }();
-        line.close(isLastLineWithInlineContent == LineContentAligner::IsLastLineWithInlineContent::Yes);
+        line.close(isLastLineWithInlineContent);
+        auto lineRect = Display::InlineRect { lineConstraints.logicalTopLeft, line.lineLogicalWidth(), lineConstraints.lineHeight};
+        auto lineBox = LineBox { *this, lineRect, lineContent.runs, line.isVisuallyEmpty() ? LineBox::IsLineVisuallyEmpty::Yes : LineBox::IsLineVisuallyEmpty::No, isLastLineWithInlineContent ? LineBox::IsLastLineWithInlineContent::Yes : LineBox::IsLastLineWithInlineContent::No };
+        setDisplayBoxesForLine(lineContent, lineBox, constraints.horizontal);
 
-        auto lineBox = LineBox { Display::InlineRect { lineConstraints.logicalTopLeft, line.contentLogicalWidth(), lineConstraints.lineHeight }, LineBox::halfLeadingMetrics(root().style().fontMetrics(), lineConstraints.lineHeight) };
-        auto contentAligner = LineContentAligner { *this, lineBox, line.runs(), line.availableWidth() };
-        auto alignLineContent = [&] {
-            contentAligner.adjustBaselineAndLineHeight();
-            if (line.isVisuallyEmpty()) {
-                lineBox.resetAlignmentBaseline();
-                lineBox.setLogicalHeight({ });
-            }
-            // Remove descent when all content is baseline aligned but none of them have descent.
-            if (quirks().lineDescentNeedsCollapsing(line.runs())) {
-                lineBox.shrinkVertically(lineBox.ascentAndDescent().descent);
-                lineBox.resetDescent();
-            }
-            contentAligner.alignVertically();
-
-            auto computedHorizontalAlignment = [&] {
-                if (root().style().textAlign() != TextAlignMode::Justify)
-                    return root().style().textAlign();
-                // Text is justified according to the method specified by the text-justify property,
-                // in order to exactly fill the line box. Unless otherwise specified by text-align-last,
-                // the last line before a forced break or the end of the block is start-aligned.
-                if (line.runs().last().isLineBreak() || isLastLineWithInlineContent == LineContentAligner::IsLastLineWithInlineContent::Yes)
-                    return TextAlignMode::Start;
-                return TextAlignMode::Justify;
-            };
-            contentAligner.alignHorizontally(computedHorizontalAlignment(), isLastLineWithInlineContent);
-        };
-
-        alignLineContent();
-        setDisplayBoxesForLine(line, contentAligner.inlineRectList(), lineBox, lineContent, constraints.horizontal);
-
         if (!lineContentRange.isEmpty()) {
             ASSERT(needsLayoutRange.start < lineContentRange.end);
             lineLogicalTop = lineBox.logicalBottom();
@@ -517,7 +193,7 @@
             continue;
         }
         // Floats prevented us placing any content on the line.
-        ASSERT(line.runs().isEmpty());
+        ASSERT(lineContent.runs.isEmpty());
         ASSERT(line.hasIntrusiveFloat());
         // Move the next line below the intrusive float.
         auto floatingContext = FloatingContext { root(), *this, formattingState().floatingState() };
@@ -807,10 +483,9 @@
     return LineConstraints { { lineLogicalLeft, lineLogicalTop }, lineLogicalRight - lineLogicalLeft, initialLineHeight, lineIsConstrainedByFloat };
 }
 
-void InlineFormattingContext::setDisplayBoxesForLine(const LineBuilder& line, const LineContentAligner::InlineRunRectList& runRectList, const LineBox& lineBox, const LineLayoutContext::LineContent& lineContent, const HorizontalConstraints& horizontalConstraints)
+void InlineFormattingContext::setDisplayBoxesForLine(const LineLayoutContext::LineContent& lineContent, const LineBox& lineBox, const HorizontalConstraints& horizontalConstraints)
 {
     auto& formattingState = this->formattingState();
-
     if (!lineContent.floats.isEmpty()) {
         auto floatingContext = FloatingContext { root(), *this, formattingState.floatingState() };
         // Move floats to their final position.
@@ -836,7 +511,8 @@
     auto lineIndex = inlineContent.lineBoxes.size();
     auto lineInkOverflow = lineBox.scrollableOverflow();
     // Compute box final geometry.
-    auto& lineRuns = line.runs();
+    auto& runRectList = lineBox.inlineRectList();
+    auto& lineRuns = lineContent.runs;
     for (size_t index = 0; index < lineRuns.size(); ++index) {
         auto& lineRun = lineRuns.at(index);
         auto logicalRect = runRectList[index];

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (266275 => 266276)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2020-08-28 13:37:03 UTC (rev 266276)
@@ -36,6 +36,7 @@
 
 class InlineFormattingState;
 class InvalidationState;
+class LineBox;
 
 // This class implements the layout logic for inline formatting contexts.
 // https://www.w3.org/TR/CSS22/visuren.html#inline-formatting
@@ -94,7 +95,7 @@
         bool lineIsConstrainedByFloat { false };
     };
     LineConstraints constraintsForLine(const HorizontalConstraints&, InlineLayoutUnit lineLogicalTop);
-    void setDisplayBoxesForLine(const LineBuilder&, const Vector<Display::InlineRect, 10>&, const LineBox&, const LineLayoutContext::LineContent&, const HorizontalConstraints&);
+    void setDisplayBoxesForLine(const LineLayoutContext::LineContent&, const LineBox&, const HorizontalConstraints&);
     void invalidateFormattingState(const InvalidationState&);
 
     const InlineFormattingState& formattingState() const { return downcast<InlineFormattingState>(FormattingContext::formattingState()); }

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp (266275 => 266276)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp	2020-08-28 13:37:03 UTC (rev 266276)
@@ -24,7 +24,9 @@
  */
 
 #include "config.h"
+#include "DisplayBox.h"
 #include "InlineFormattingContext.h"
+#include "InlineLineBox.h"
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 

Added: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp (0 => 266276)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp	2020-08-28 13:37:03 UTC (rev 266276)
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "InlineLineBox.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+namespace Layout {
+
+struct HangingContent {
+public:
+    void reset();
+
+    InlineLayoutUnit width() const { return m_width; }
+    bool isConditional() const { return m_isConditional; }
+
+    void setIsConditional() { m_isConditional = true; }
+    void expand(InlineLayoutUnit width) { m_width += width; }
+
+private:
+    bool m_isConditional { false };
+    InlineLayoutUnit m_width { 0 };
+};
+
+void HangingContent::reset()
+{
+    m_isConditional = false;
+    m_width =  0;
+}
+
+LineBox::LineBox(const InlineFormattingContext& inlineFormattingContext, const Display::InlineRect& lineRect, const LineBuilder::RunList& runs, IsLineVisuallyEmpty isLineVisuallyEmpty, IsLastLineWithInlineContent isLastLineWithInlineContent)
+    : m_inlineFormattingContext(inlineFormattingContext)
+    , m_runs(runs)
+    , m_rect(lineRect)
+    , m_scrollableOverflow(lineRect)
+{
+#if ASSERT_ENABLED
+    m_hasValidAlignmentBaseline = true;
+#endif
+    auto& rootStyle = inlineFormattingContext.root().style();
+    auto halfLeadingMetrics = this->halfLeadingMetrics(rootStyle.fontMetrics(), lineRect.height());
+
+    m_alignmentBaseline = halfLeadingMetrics.ascent;
+    m_rootInlineBox = InlineBox { halfLeadingMetrics };
+
+    auto contentLogicalWidth = InlineLayoutUnit { };
+    for (auto& run : m_runs) {
+        auto runHeight = [&]() -> InlineLayoutUnit {
+            auto& fontMetrics = run.style().fontMetrics();
+            if (run.isText() || run.isLineBreak())
+                return fontMetrics.height();
+
+            if (run.isContainerStart() || run.isContainerEnd())
+                return fontMetrics.height();
+
+            auto& layoutBox = run.layoutBox();
+            auto& boxGeometry = inlineFormattingContext.geometryForBox(layoutBox);
+            if (layoutBox.isReplacedBox() || layoutBox.isFloatingPositioned())
+                return boxGeometry.contentBoxHeight();
+
+            // Non-replaced inline box (e.g. inline-block). It looks a bit misleading but their margin box is considered the content height here.
+            return boxGeometry.marginBoxHeight();
+        };
+        m_runRectList.append({ 0, run.logicalLeft(), run.logicalWidth(), runHeight() });
+        contentLogicalWidth += run.logicalWidth();
+    }
+    m_scrollableOverflow.setWidth(std::max(lineRect.width(), contentLogicalWidth));
+    alignVertically();
+    alignHorizontally(lineRect.width() - contentLogicalWidth, isLastLineWithInlineContent);
+
+    if (isLineVisuallyEmpty == IsLineVisuallyEmpty::Yes) {
+        m_rect.setHeight({ });
+        m_rootInlineBox.ascentAndDescent = { };
+    }
+}
+
+void LineBox::alignHorizontally(InlineLayoutUnit availableWidth, IsLastLineWithInlineContent isLastLine)
+{
+    auto hangingContent = collectHangingContent(isLastLine);
+    availableWidth += hangingContent.width();
+    if (m_runs.isEmpty() || availableWidth <= 0)
+        return;
+
+    auto computedHorizontalAlignment = [&] {
+        auto& rootStyle = formattingContext().root().style();
+        if (rootStyle.textAlign() != TextAlignMode::Justify)
+            return rootStyle.textAlign();
+        // Text is justified according to the method specified by the text-justify property,
+        // in order to exactly fill the line box. Unless otherwise specified by text-align-last,
+        // the last line before a forced break or the end of the block is start-aligned.
+        if (m_runs.last().isLineBreak() || isLastLine == IsLastLineWithInlineContent::Yes)
+            return TextAlignMode::Start;
+        return TextAlignMode::Justify;
+    }();
+
+    if (computedHorizontalAlignment == TextAlignMode::Justify) {
+        auto accumulatedExpansion = InlineLayoutUnit { };
+        for (size_t index = 0; index < m_runs.size(); ++index) {
+            m_runRectList[index].moveHorizontally(accumulatedExpansion);
+
+            auto horizontalExpansion = m_runs[index].expansion().horizontalExpansion;
+            m_runRectList[index].expandHorizontally(horizontalExpansion);
+            accumulatedExpansion += horizontalExpansion;
+        }
+        return;
+    }
+
+    auto adjustmentForAlignment = [&] (auto availableWidth) -> Optional<InlineLayoutUnit> {
+        switch (computedHorizontalAlignment) {
+        case TextAlignMode::Left:
+        case TextAlignMode::WebKitLeft:
+        case TextAlignMode::Start:
+            return { };
+        case TextAlignMode::Right:
+        case TextAlignMode::WebKitRight:
+        case TextAlignMode::End:
+            return std::max<InlineLayoutUnit>(availableWidth, 0);
+        case TextAlignMode::Center:
+        case TextAlignMode::WebKitCenter:
+            return std::max<InlineLayoutUnit>(availableWidth / 2, 0);
+        case TextAlignMode::Justify:
+            ASSERT_NOT_REACHED();
+            break;
+        }
+        ASSERT_NOT_REACHED();
+        return { };
+    };
+
+    if (auto adjustment = adjustmentForAlignment(availableWidth)) {
+        // FIXME: line box should not need to be moved, only the runs.
+        m_rect.moveHorizontally(*adjustment);
+        for (auto& runRect : m_runRectList)
+            runRect.moveHorizontally(*adjustment);
+    }
+}
+
+void LineBox::alignVertically()
+{
+    adjustBaselineAndLineHeight();
+    for (size_t index = 0; index < m_runs.size(); ++index) {
+        auto& run = m_runs[index];
+        auto& runRect = m_runRectList[index];
+        auto logicalTop = InlineLayoutUnit { };
+        auto& layoutBox = run.layoutBox();
+        auto verticalAlign = layoutBox.style().verticalAlign();
+        auto ascent = layoutBox.style().fontMetrics().ascent();
+
+        switch (verticalAlign) {
+        case VerticalAlign::Baseline:
+            if (run.isLineBreak() || run.isText())
+                logicalTop = alignmentBaseline() - ascent;
+            else if (run.isContainerStart()) {
+                auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
+                logicalTop = alignmentBaseline() - ascent - boxGeometry.borderTop() - boxGeometry.paddingTop().valueOr(0);
+            } else if (layoutBox.isInlineBlockBox() && layoutBox.establishesInlineFormattingContext()) {
+                auto& formattingState = layoutState().establishedInlineFormattingState(downcast<ContainerBox>(layoutBox));
+                // Spec makes us generate at least one line -even if it is empty.
+                auto inlineBlockBaseline = formattingState.displayInlineContent()->lineBoxes.last().baseline();
+                // The inline-block's baseline offset is relative to its content box. Let's convert it relative to the margin box.
+                //           _______________ <- margin box
+                //          |
+                //          |  ____________  <- border box
+                //          | |
+                //          | |  _________  <- content box
+                //          | | |   ^
+                //          | | |   |  <- baseline offset
+                //          | | |   |
+                //     text | | |   v text
+                //     -----|-|-|---------- <- baseline
+                //
+                auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
+                auto baselineFromMarginBox = boxGeometry.marginBefore() + boxGeometry.borderTop() + boxGeometry.paddingTop().valueOr(0) + inlineBlockBaseline;
+                logicalTop = alignmentBaseline() - baselineFromMarginBox;
+            } else {
+                auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
+                logicalTop = alignmentBaseline() - (boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0_lu) + runRect.height() + boxGeometry.marginAfter());
+            }
+            break;
+        case VerticalAlign::Top:
+            logicalTop = 0_lu;
+            break;
+        case VerticalAlign::Bottom:
+            logicalTop = logicalBottom() - runRect.height();
+            break;
+        default:
+            ASSERT_NOT_IMPLEMENTED_YET();
+            break;
+        }
+        runRect.setTop(logicalTop);
+        // Adjust scrollable overflow if the run overflows the line.
+        m_scrollableOverflow.expandVerticallyToContain(runRect);
+        // Convert runs from relative to the line top/left to the formatting root's border box top/left.
+        runRect.moveVertically(this->logicalTop());
+        runRect.moveHorizontally(logicalLeft());
+    }
+}
+
+void LineBox::adjustBaselineAndLineHeight()
+{
+    unsigned inlineContainerNestingLevel = 0;
+    auto hasSeenDirectTextOrLineBreak = false;
+    for (auto& run : m_runs) {
+        auto& layoutBox = run.layoutBox();
+        auto& style = layoutBox.style();
+        if (run.isText() || run.isLineBreak()) {
+            // For text content we set the baseline either through the initial strut (set by the formatting context root) or
+            // through the inline container (start). Normally the text content itself does not stretch the line.
+            if (inlineContainerNestingLevel) {
+                // We've already adjusted the line height/baseline through the parent inline container. 
+                continue;
+            }
+            if (hasSeenDirectTextOrLineBreak) {
+                // e.g div>first text</div> or <div><span>nested<span>first direct text</div>.
+                continue;
+            }
+            hasSeenDirectTextOrLineBreak = true;
+            continue;
+        }
+
+        if (run.isContainerStart()) {
+            ++inlineContainerNestingLevel;
+            // Inline containers stretch the line by their font size.
+            // Vertical margins, paddings and borders don't contribute to the line height.
+            auto& fontMetrics = style.fontMetrics();
+            if (style.verticalAlign() == VerticalAlign::Baseline) {
+                auto halfLeading = LineBox::halfLeadingMetrics(fontMetrics, style.computedLineHeight());
+                // Both halfleading ascent and descent could be negative (tall font vs. small line-height value)
+                if (halfLeading.descent > 0)
+                    setDescentIfGreater(halfLeading.descent);
+                if (halfLeading.ascent > 0)
+                    setAscentIfGreater(halfLeading.ascent);
+                setLogicalHeightIfGreater(ascentAndDescent().height());
+            } else
+                setLogicalHeightIfGreater(fontMetrics.height());
+            continue;
+        }
+
+        if (run.isContainerEnd()) {
+            // The line's baseline and height have already been adjusted at ContainerStart.
+            ASSERT(inlineContainerNestingLevel);
+            --inlineContainerNestingLevel;
+            continue;
+        }
+
+        if (run.isBox()) {
+            auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
+            auto marginBoxHeight = boxGeometry.marginBoxHeight();
+
+            switch (style.verticalAlign()) {
+            case VerticalAlign::Baseline: {
+                if (layoutBox.isInlineBlockBox() && layoutBox.establishesInlineFormattingContext()) {
+                    // Inline-blocks with inline content always have baselines.
+                    auto& formattingState = layoutState().establishedInlineFormattingState(downcast<ContainerBox>(layoutBox));
+                    // There has to be at least one line -even if it is empty.
+                    auto& lastLineBox = formattingState.displayInlineContent()->lineBoxes.last();
+                    auto beforeHeight = boxGeometry.marginBefore() + boxGeometry.borderTop() + boxGeometry.paddingTop().valueOr(0);
+                    setAlignmentBaselineIfGreater(beforeHeight + lastLineBox.baseline());
+                    setLogicalHeightIfGreater(marginBoxHeight);
+                } else {
+                    // Non inline-block boxes sit on the baseline (including their bottom margin).
+                    setAscentIfGreater(marginBoxHeight);
+                    // Ignore negative descent (yes, negative descent is a thing).
+                    setLogicalHeightIfGreater(marginBoxHeight + std::max<InlineLayoutUnit>(0, ascentAndDescent().descent));
+                }
+                break;
+            }
+            case VerticalAlign::Top:
+                // Top align content never changes the baseline, it only pushes the bottom of the line further down.
+                setLogicalHeightIfGreater(marginBoxHeight);
+                break;
+            case VerticalAlign::Bottom: {
+                // Bottom aligned, tall content pushes the baseline further down from the line top.
+                auto lineLogicalHeight = logicalHeight();
+                if (marginBoxHeight > lineLogicalHeight) {
+                    setLogicalHeightIfGreater(marginBoxHeight);
+                    setAlignmentBaselineIfGreater(alignmentBaseline() + (marginBoxHeight - lineLogicalHeight));
+                }
+                break;
+            }
+            default:
+                ASSERT_NOT_IMPLEMENTED_YET();
+                break;
+            }
+            continue;
+        }
+    }
+}
+
+HangingContent LineBox::collectHangingContent(IsLastLineWithInlineContent isLastLineWithInlineContent) const
+{
+    auto hangingContent = HangingContent { };
+    if (isLastLineWithInlineContent == IsLastLineWithInlineContent::Yes)
+        hangingContent.setIsConditional();
+    for (auto& run : WTF::makeReversedRange(m_runs)) {
+        if (run.isContainerStart() || run.isContainerEnd())
+            continue;
+        if (run.isLineBreak()) {
+            hangingContent.setIsConditional();
+            continue;
+        }
+        if (!run.hasTrailingWhitespace())
+            break;
+        // Check if we have a preserved or hung whitespace.
+        if (run.style().whiteSpace() != WhiteSpace::PreWrap)
+            break;
+        // This is either a normal or conditionally hanging trailing whitespace.
+        hangingContent.expand(run.trailingWhitespaceWidth());
+    }
+    return hangingContent;
+}
+
+}
+}
+
+#endif

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h (266275 => 266276)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h	2020-08-28 13:37:03 UTC (rev 266276)
@@ -29,10 +29,14 @@
 
 #include "DisplayBox.h"
 #include "DisplayInlineRect.h"
+#include "InlineLineBuilder.h"
 
 namespace WebCore {
 namespace Layout {
 
+class InlineFormattingContext;
+struct HangingContent;
+
 struct AscentAndDescent {
     InlineLayoutUnit height() const { return ascent + descent; }
 
@@ -50,20 +54,25 @@
         AscentAndDescent ascentAndDescent;
     };
 
-    LineBox(const Display::InlineRect&, const AscentAndDescent&);
-    LineBox() = default;
+    enum class IsLastLineWithInlineContent { No, Yes };
+    enum class IsLineVisuallyEmpty { No, Yes };
+    LineBox(const InlineFormattingContext&, const Display::InlineRect&, const LineBuilder::RunList&, IsLineVisuallyEmpty, IsLastLineWithInlineContent);
 
-    const Display::InlineRect& logicalRect() const { return m_rect; }
-    const Display::InlineRect& scrollableOverflow() const { return m_scrollableOverflow; }
+    using InlineRunRectList = Vector<Display::InlineRect, 10>;
+    const InlineRunRectList& inlineRectList() const { return m_runRectList; }
 
     InlineLayoutUnit logicalLeft() const { return m_rect.left(); }
     InlineLayoutUnit logicalRight() const { return m_rect.right(); }
     InlineLayoutUnit logicalTop() const { return m_rect.top(); }
     InlineLayoutUnit logicalBottom() const { return m_rect.bottom(); }
-
     InlineLayoutUnit logicalWidth() const { return m_rect.width(); }
     InlineLayoutUnit logicalHeight() const { return m_rect.height(); }
 
+    const Display::InlineRect& logicalRect() const { return m_rect; }
+    const Display::InlineRect& scrollableOverflow() const { return m_scrollableOverflow; }
+
+    static AscentAndDescent halfLeadingMetrics(const FontMetrics&, InlineLayoutUnit lineLogicalHeight);
+
     // Aligment baseline from line logical top.
     //
     // -------------------    line logical top     ------------------- (top align)
@@ -80,63 +89,39 @@
     //   v
     // -------------------    line logical bottom  -------------------
     InlineLayoutUnit alignmentBaseline() const;
+
+private:
     const AscentAndDescent& ascentAndDescent() const { return m_rootInlineBox.ascentAndDescent; }
 
     void setAlignmentBaselineIfGreater(InlineLayoutUnit);
     void setAscentIfGreater(InlineLayoutUnit);
     void setDescentIfGreater(InlineLayoutUnit);
-
-    void resetAlignmentBaseline();
-    void resetDescent() { m_rootInlineBox.ascentAndDescent.descent = { }; }
-
-    void setLogicalHeight(InlineLayoutUnit logicalHeight) { m_rect.setHeight(logicalHeight); }
-
     void setLogicalHeightIfGreater(InlineLayoutUnit);
-    void setLogicalWidth(InlineLayoutUnit logicalWidth) { m_rect.setWidth(logicalWidth); }
 
     void setScrollableOverflow(const Display::InlineRect& rect) { m_scrollableOverflow = rect; }
 
-    void moveHorizontally(InlineLayoutUnit delta) { m_rect.moveHorizontally(delta); }
+    void alignHorizontally(InlineLayoutUnit availableWidth, IsLastLineWithInlineContent);
+    void alignVertically();
+    void adjustBaselineAndLineHeight();
 
-    void expandHorizontally(InlineLayoutUnit delta) { m_rect.expandHorizontally(delta); }
-    void shrinkHorizontally(InlineLayoutUnit delta) { expandHorizontally(-delta); }
+    HangingContent collectHangingContent(IsLastLineWithInlineContent) const;
 
-    void expandVertically(InlineLayoutUnit delta) { m_rect.expandVertically(delta); }
-    void shrinkVertically(InlineLayoutUnit delta) { expandVertically(-delta); }
+    const InlineFormattingContext& formattingContext() const { return m_inlineFormattingContext; }
+    LayoutState& layoutState() const { return formattingContext().layoutState(); }
 
-    // https://www.w3.org/TR/CSS22/visuren.html#inline-formatting
-    // Line boxes that contain no text, no preserved white space, no inline elements with non-zero margins, padding, or borders,
-    // and no other in-flow content (such as images, inline blocks or inline tables), and do not end with a preserved newline
-    // must be treated as zero-height line boxes for the purposes of determining the positions of any elements inside of them,
-    // and must be treated as not existing for any other purpose.
-    // Note that it does not necessarily mean visually non-empty line. <span style="font-size: 0px">this is still considered non-empty</span>
-    bool isConsideredEmpty() const { return m_isConsideredEmpty; }
-    void setIsConsideredEmpty() { m_isConsideredEmpty = true; }
-    void setIsConsideredNonEmpty() { m_isConsideredEmpty = false; }
-
-    static AscentAndDescent halfLeadingMetrics(const FontMetrics&, InlineLayoutUnit lineLogicalHeight);
-
 private:
 #if ASSERT_ENABLED
     bool m_hasValidAlignmentBaseline { false };
 #endif
+    const InlineFormattingContext& m_inlineFormattingContext;
+    const LineBuilder::RunList& m_runs;
     Display::InlineRect m_rect;
     Display::InlineRect m_scrollableOverflow;
     InlineLayoutUnit m_alignmentBaseline { 0 };
-    bool m_isConsideredEmpty { true };
     InlineBox m_rootInlineBox;
+    InlineRunRectList m_runRectList;
 };
 
-inline LineBox::LineBox(const Display::InlineRect& rect, const AscentAndDescent& ascentAndDescent)
-    : m_rect(rect)
-    , m_alignmentBaseline(ascentAndDescent.ascent)
-    , m_rootInlineBox(ascentAndDescent)
-{
-#if ASSERT_ENABLED
-    m_hasValidAlignmentBaseline = true;
-#endif
-}
-
 inline LineBox::InlineBox::InlineBox(const AscentAndDescent& ascentAndDescent)
     : ascentAndDescent(ascentAndDescent)
 {
@@ -178,16 +163,6 @@
     return m_alignmentBaseline;
 }
 
-inline void LineBox::resetAlignmentBaseline()
-{
-#if ASSERT_ENABLED
-    m_hasValidAlignmentBaseline = true;
-#endif
-    m_alignmentBaseline = 0_lu;
-    m_rootInlineBox.ascentAndDescent.descent = { };
-    m_rootInlineBox.ascentAndDescent.ascent = { };
-}
-
 inline AscentAndDescent LineBox::halfLeadingMetrics(const FontMetrics& fontMetrics, InlineLayoutUnit lineLogicalHeight)
 {
     auto ascent = fontMetrics.ascent();

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h (266275 => 266276)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBuilder.h	2020-08-28 13:37:03 UTC (rev 266276)
@@ -29,7 +29,6 @@
 
 #include "DisplayRun.h"
 #include "InlineItem.h"
-#include "InlineLineBox.h"
 #include "InlineTextItem.h"
 
 namespace WebCore {
@@ -37,7 +36,6 @@
 
 class InlineFormattingContext;
 class InlineSoftLineBreakItem;
-class LineContentAligner;
 
 class LineBuilder {
 public:
@@ -56,8 +54,9 @@
 
     bool isVisuallyEmpty() const { return m_isVisuallyEmpty; }
 
-    InlineLayoutUnit availableWidth() const { return m_lineLogicalWidth - contentLogicalWidth(); }
+    InlineLayoutUnit lineLogicalWidth() const { return m_lineLogicalWidth; }
     InlineLayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
+    InlineLayoutUnit availableWidth() const { return lineLogicalWidth() - contentLogicalWidth(); }
 
     InlineLayoutUnit trimmableTrailingWidth() const { return m_trimmableTrailingContent.width(); }
     bool isTrailingRunFullyTrimmable() const { return m_trimmableTrailingContent.isTrailingRunFullyTrimmable(); }

Modified: trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp (266275 => 266276)


--- trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp	2020-08-28 13:37:03 UTC (rev 266276)
@@ -28,6 +28,7 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "DisplayBox.h"
 #include "InlineFormattingContext.h"
 #include "LayoutBox.h"
 #include "TextUtil.h"
@@ -334,7 +335,7 @@
     ASSERT(lineRange.end <= layoutRange.end);
     // Adjust hyphenated line count.
     m_successiveHyphenatedLineCount = partialContent && partialContent->trailingContentHasHyphen ? m_successiveHyphenatedLineCount + 1 : 0;
-    return LineContent { partialContent, lineRange, WTFMove(m_floats) };
+    return LineContent { partialContent, lineRange, WTFMove(m_floats), line.runs() };
 }
 
 void LineLayoutContext::nextContentForLine(LineCandidate& lineCandidate, unsigned currentInlineItemIndex, const InlineItemRange& layoutRange, Optional<unsigned> partialLeadingContentLength, InlineLayoutUnit availableLineWidth, InlineLayoutUnit currentLogicalRight)

Modified: trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h (266275 => 266276)


--- trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h	2020-08-28 08:46:45 UTC (rev 266275)
+++ trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h	2020-08-28 13:37:03 UTC (rev 266276)
@@ -58,6 +58,7 @@
         };
         using FloatList = Vector<Float>;
         FloatList floats;
+        const LineBuilder::RunList& runs;
     };
     LineContent layoutInlineContent(LineBuilder&, const InlineItemRange&, Optional<unsigned> partialLeadingContentLength);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to