| Differences between
and this patch
- a/Source/WebCore/ChangeLog +23 lines
Lines 1-3 a/Source/WebCore/ChangeLog_sec1
1
2021-09-12  Alan Bujtas  <zalan@apple.com>
2
3
        [LFC][IFC] Add scrollable overflow to LineGeometry
4
        https://bugs.webkit.org/show_bug.cgi?id=230200
5
6
        Reviewed by Antti Koivisto.
7
8
        This is in preparation for making the integration line structure redundant.
9
        (LineGeometry should be able to contain all the geometry information required for layout/paint/hittest).
10
11
        * layout/formattingContexts/inline/InlineLineBoxBuilder.cpp:
12
        (WebCore::Layout::LineBoxBuilder::build):
13
        * layout/formattingContexts/inline/InlineLineGeometry.h:
14
        (WebCore::Layout::LineGeometry::scrollableOverflow const):
15
        (WebCore::Layout::LineGeometry::LineGeometry):
16
        * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
17
        (WebCore::LayoutIntegration::lineOverflowWidth):
18
        (WebCore::LayoutIntegration::InlineContentBuilder::InlineContentBuilder):
19
        (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLines const):
20
        * layout/integration/LayoutIntegrationInlineContentBuilder.h:
21
        * layout/integration/LayoutIntegrationLineLayout.cpp:
22
        (WebCore::LayoutIntegration::LineLayout::constructContent):
23
1
2021-09-11  Antti Koivisto  <antti@apple.com>
24
2021-09-11  Antti Koivisto  <antti@apple.com>
2
25
3
        Move rest of the LegacyInlineTextBox painting code to TextBoxPainter
26
        Move rest of the LegacyInlineTextBox painting code to TextBoxPainter
- a/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp -8 / +20 lines
Lines 120-147 LineBoxBuilder::LineBoxAndGeometry LineBoxBuilder::build(const LineBuilder::Line a/Source/WebCore/layout/formattingContexts/inline/InlineLineBoxBuilder.cpp_sec1
120
120
121
    auto lineGeometry = [&] {
121
    auto lineGeometry = [&] {
122
        auto lineBoxLogicalRect = InlineRect { lineContent.logicalTopLeft, lineContent.lineLogicalWidth, lineBoxLogicalHeight };
122
        auto lineBoxLogicalRect = InlineRect { lineContent.logicalTopLeft, lineContent.lineLogicalWidth, lineBoxLogicalHeight };
123
        auto scrollableOverflowRect = lineBoxLogicalRect;
123
        auto& rootInlineBox = lineBox.rootInlineBox();
124
        auto& rootInlineBox = lineBox.rootInlineBox();
124
        auto enclosingTopAndBottom = LineGeometry::EnclosingTopAndBottom { rootInlineBox.logicalTop(), rootInlineBox.logicalBottom() };
125
        auto enclosingTopAndBottom = LineGeometry::EnclosingTopAndBottom { lineBoxLogicalRect.top() + rootInlineBox.logicalTop(), lineBoxLogicalRect.top() + rootInlineBox.logicalBottom() };
125
126
126
        for (auto& inlineLevelBox : lineBox.nonRootInlineLevelBoxes()) {
127
        for (auto& inlineLevelBox : lineBox.nonRootInlineLevelBoxes()) {
127
            if (!inlineLevelBox.isAtomicInlineLevelBox() || !inlineLevelBox.isInlineBox())
128
            if (!inlineLevelBox.isAtomicInlineLevelBox() && !inlineLevelBox.isInlineBox())
128
                continue;
129
                continue;
129
130
130
            auto& layoutBox = inlineLevelBox.layoutBox();
131
            auto& layoutBox = inlineLevelBox.layoutBox();
131
            auto borderBox = InlineRect { };
132
            auto borderBox = InlineRect { };
132
133
133
            if (inlineLevelBox.isAtomicInlineLevelBox())
134
            if (inlineLevelBox.isAtomicInlineLevelBox()) {
134
                borderBox = lineBox.logicalBorderBoxForAtomicInlineLevelBox(layoutBox, formattingContext().geometryForBox(layoutBox));
135
                borderBox = lineBox.logicalBorderBoxForAtomicInlineLevelBox(layoutBox, formattingContext().geometryForBox(layoutBox));
135
            else if (inlineLevelBox.isInlineBox())
136
                borderBox.moveBy(lineBoxLogicalRect.topLeft());
136
                borderBox = lineBox.logicalBorderBoxForInlineBox(layoutBox, formattingContext().geometryForBox(layoutBox));
137
            } else if (inlineLevelBox.isInlineBox()) {
137
            else
138
                auto& boxGeometry = formattingContext().geometryForBox(layoutBox);
139
                borderBox = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
140
                borderBox.moveBy(lineBoxLogicalRect.topLeft());
141
                // Collect scrollable overflow from inline boxes. All other inline level boxes (e.g atomic inline level boxes) stretch the line.
142
                auto hasScrollableContent = [&] {
143
                    // In standards mode, inline boxes always start with an imaginary strut.
144
                    return layoutState().inStandardsMode() || inlineLevelBox.hasContent() || boxGeometry.horizontalBorder() || (boxGeometry.horizontalPadding() && boxGeometry.horizontalPadding().value());
145
                };
146
                if (lineBox.hasContent() && hasScrollableContent()) {
147
                    // Empty lines (e.g. continuation pre/post blocks) don't expect scrollbar overflow.
148
                    scrollableOverflowRect.expandToContain(borderBox);
149
                }
150
            } else
138
                ASSERT_NOT_REACHED();
151
                ASSERT_NOT_REACHED();
139
152
140
            borderBox.moveBy(lineBoxLogicalRect.topLeft());
141
            enclosingTopAndBottom.top = std::min(enclosingTopAndBottom.top, borderBox.top());
153
            enclosingTopAndBottom.top = std::min(enclosingTopAndBottom.top, borderBox.top());
142
            enclosingTopAndBottom.bottom = std::max(enclosingTopAndBottom.bottom, borderBox.bottom());
154
            enclosingTopAndBottom.bottom = std::max(enclosingTopAndBottom.bottom, borderBox.bottom());
143
        }
155
        }
144
        return LineGeometry { lineBoxLogicalRect, enclosingTopAndBottom, rootInlineBox.logicalTop() + rootInlineBox.baseline(), rootInlineBox.logicalLeft(), rootInlineBox.logicalWidth() };
156
        return LineGeometry { lineBoxLogicalRect, scrollableOverflowRect, enclosingTopAndBottom, rootInlineBox.logicalTop() + rootInlineBox.baseline(), rootInlineBox.logicalLeft(), rootInlineBox.logicalWidth() };
145
    };
157
    };
146
    return { lineBox, lineGeometry() };
158
    return { lineBox, lineGeometry() };
147
}
159
}
- a/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h -2 / +5 lines
Lines 40-48 public: a/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h_sec1
40
        InlineLayoutUnit top { 0 };
40
        InlineLayoutUnit top { 0 };
41
        InlineLayoutUnit bottom { 0 };
41
        InlineLayoutUnit bottom { 0 };
42
    };
42
    };
43
    LineGeometry(const InlineRect& lineBoxLogicalRect, EnclosingTopAndBottom, InlineLayoutUnit aligmentBaseline, InlineLayoutUnit contentLogicalLeft, InlineLayoutUnit contentLogicalWidth);
43
    LineGeometry(const InlineRect& lineBoxLogicalRect, const InlineRect& scrollableOverflow, EnclosingTopAndBottom, InlineLayoutUnit aligmentBaseline, InlineLayoutUnit contentLogicalLeft, InlineLayoutUnit contentLogicalWidth);
44
44
45
    const InlineRect& lineBoxLogicalRect() const { return m_lineBoxLogicalRect; }
45
    const InlineRect& lineBoxLogicalRect() const { return m_lineBoxLogicalRect; }
46
    const InlineRect& scrollableOverflow() const { return m_scrollableOverflow; }
46
47
47
    EnclosingTopAndBottom enclosingTopAndBottom() const { return m_enclosingTopAndBottom; }
48
    EnclosingTopAndBottom enclosingTopAndBottom() const { return m_enclosingTopAndBottom; }
48
49
Lines 56-61 public: a/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h_sec2
56
private:
57
private:
57
    // This is line box geometry (see https://www.w3.org/TR/css-inline-3/#line-box).
58
    // This is line box geometry (see https://www.w3.org/TR/css-inline-3/#line-box).
58
    InlineRect m_lineBoxLogicalRect;
59
    InlineRect m_lineBoxLogicalRect;
60
    InlineRect m_scrollableOverflow;
59
    // Enclosing top and bottom includes all inline level boxes (border box) vertically.
61
    // Enclosing top and bottom includes all inline level boxes (border box) vertically.
60
    // While the line box usually enclose them as well, its vertical geometry is based on
62
    // While the line box usually enclose them as well, its vertical geometry is based on
61
    // the layout bounds of the inline level boxes which may be different when line-height is present.
63
    // the layout bounds of the inline level boxes which may be different when line-height is present.
Lines 65-72 private: a/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h_sec3
65
    InlineLayoutUnit m_contentLogicalWidth { 0 };
67
    InlineLayoutUnit m_contentLogicalWidth { 0 };
66
};
68
};
67
69
68
inline LineGeometry::LineGeometry(const InlineRect& lineBoxLogicalRect, EnclosingTopAndBottom enclosingTopAndBottom, InlineLayoutUnit aligmentBaseline, InlineLayoutUnit contentLogicalLeft, InlineLayoutUnit contentLogicalWidth)
70
inline LineGeometry::LineGeometry(const InlineRect& lineBoxLogicalRect, const InlineRect& scrollableOverflow, EnclosingTopAndBottom enclosingTopAndBottom, InlineLayoutUnit aligmentBaseline, InlineLayoutUnit contentLogicalLeft, InlineLayoutUnit contentLogicalWidth)
69
    : m_lineBoxLogicalRect(lineBoxLogicalRect)
71
    : m_lineBoxLogicalRect(lineBoxLogicalRect)
72
    , m_scrollableOverflow(scrollableOverflow)
70
    , m_enclosingTopAndBottom(enclosingTopAndBottom)
73
    , m_enclosingTopAndBottom(enclosingTopAndBottom)
71
    , m_aligmentBaseline(aligmentBaseline)
74
    , m_aligmentBaseline(aligmentBaseline)
72
    , m_contentLogicalLeft(contentLogicalLeft)
75
    , m_contentLogicalLeft(contentLogicalLeft)
- a/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp -26 / +9 lines
Lines 46-52 inline Layout::LineGeometry::EnclosingTopAndBottom operator+(const Layout::LineG a/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp_sec1
46
    return { enclosingTopAndBottom.top + offset, enclosingTopAndBottom.bottom + offset };
46
    return { enclosingTopAndBottom.top + offset, enclosingTopAndBottom.bottom + offset };
47
}
47
}
48
48
49
inline static float lineOverflowWidth(const RenderBlockFlow& flow, Layout::InlineLayoutUnit lineBoxLogicalWidth, Layout::InlineLayoutUnit lineContentLogicalWidth)
49
inline static float lineOverflowWidth(const RenderBlockFlow& flow, Layout::InlineLayoutUnit lineContentLogicalWidth)
50
{
50
{
51
    // FIXME: It's the copy of the lets-adjust-overflow-for-the-caret behavior from LegacyLineLayout::addOverflowFromInlineChildren.
51
    // FIXME: It's the copy of the lets-adjust-overflow-for-the-caret behavior from LegacyLineLayout::addOverflowFromInlineChildren.
52
    auto endPadding = flow.hasNonVisibleOverflow() ? flow.paddingEnd() : 0_lu;
52
    auto endPadding = flow.hasNonVisibleOverflow() ? flow.paddingEnd() : 0_lu;
Lines 54-66 inline static float lineOverflowWidth(const RenderBlockFlow& flow, Layout::Inlin a/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp_sec2
54
        endPadding = flow.endPaddingWidthForCaret();
54
        endPadding = flow.endPaddingWidthForCaret();
55
    if (flow.hasNonVisibleOverflow() && !endPadding && flow.element() && flow.element()->isRootEditableElement())
55
    if (flow.hasNonVisibleOverflow() && !endPadding && flow.element() && flow.element()->isRootEditableElement())
56
        endPadding = 1;
56
        endPadding = 1;
57
    lineContentLogicalWidth += endPadding;
57
    return lineContentLogicalWidth + endPadding;
58
    return std::max(lineBoxLogicalWidth, lineContentLogicalWidth);
59
}
58
}
60
59
61
InlineContentBuilder::InlineContentBuilder(const Layout::LayoutState& layoutState, const RenderBlockFlow& blockFlow, const BoxTree& boxTree)
60
InlineContentBuilder::InlineContentBuilder(const RenderBlockFlow& blockFlow, const BoxTree& boxTree)
62
    : m_layoutState(layoutState)
61
    : m_blockFlow(blockFlow)
63
    , m_blockFlow(blockFlow)
64
    , m_boxTree(boxTree)
62
    , m_boxTree(boxTree)
65
{
63
{
66
}
64
}
Lines 80-88 void InlineContentBuilder::createDisplayLines(Layout::InlineFormattingState& inl a/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp_sec3
80
    inlineContent.lines.reserveInitialCapacity(lines.size());
78
    inlineContent.lines.reserveInitialCapacity(lines.size());
81
    for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) {
79
    for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) {
82
        auto& line = lines[lineIndex];
80
        auto& line = lines[lineIndex];
83
        auto& lineBoxLogicalRect = line.lineBoxLogicalRect();
81
        auto scrollableOverflowRect = FloatRect { line.scrollableOverflow() };
84
        // FIXME: This is where the logical to physical translate should happen.
82
        if (auto overflowWidth = lineOverflowWidth(m_blockFlow, line.contentLogicalWidth()); overflowWidth > scrollableOverflowRect.width())
85
        auto scrollableOverflowRect = FloatRect { lineBoxLogicalRect.left(), lineBoxLogicalRect.top(), lineOverflowWidth(m_blockFlow, lineBoxLogicalRect.width(), line.contentLogicalWidth()), lineBoxLogicalRect.height() };
83
            scrollableOverflowRect.setWidth(overflowWidth);
86
84
87
        auto firstRunIndex = runIndex;
85
        auto firstRunIndex = runIndex;
88
        auto lineInkOverflowRect = scrollableOverflowRect;
86
        auto lineInkOverflowRect = scrollableOverflowRect;
Lines 93-109 void InlineContentBuilder::createDisplayLines(Layout::InlineFormattingState& inl a/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp_sec4
93
            lineInkOverflowRect.unite(run.inkOverflow());
91
            lineInkOverflowRect.unite(run.inkOverflow());
94
92
95
            auto& layoutBox = run.layoutBox();
93
            auto& layoutBox = run.layoutBox();
96
            if (run.isNonRootInlineBox()) {
97
                // Collect scrollable overflow from inline boxes. All other inline level boxes (e.g atomic inline level boxes) stretch the line.
98
                auto hasScrollableContent = [&] {
99
                    // In standards mode, inline boxes always start with an imaginary strut.
100
                    auto& boxGeometry = inlineFormattingState.boxGeometry(layoutBox);
101
                    return m_layoutState.inStandardsMode() || run.hasContent() || boxGeometry.horizontalBorder() || (boxGeometry.horizontalPadding() && boxGeometry.horizontalPadding().value());
102
                };
103
                if (hasScrollableContent())
104
                    scrollableOverflowRect.unite(run.logicalRect());
105
                continue;
106
            }
107
            if (layoutBox.isReplacedBox()) {
94
            if (layoutBox.isReplacedBox()) {
108
                // Similar to LegacyInlineFlowBox::addReplacedChildOverflow.
95
                // Similar to LegacyInlineFlowBox::addReplacedChildOverflow.
109
                auto& box = downcast<RenderBox>(m_boxTree.rendererForLayoutBox(layoutBox));
96
                auto& box = downcast<RenderBox>(m_boxTree.rendererForLayoutBox(layoutBox));
Lines 116-130 void InlineContentBuilder::createDisplayLines(Layout::InlineFormattingState& inl a/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp_sec5
116
                auto childScrollableOverflow = box.logicalLayoutOverflowRectForPropagation(&box.parent()->style());
103
                auto childScrollableOverflow = box.logicalLayoutOverflowRectForPropagation(&box.parent()->style());
117
                childScrollableOverflow.move(runLogicalRect.left(), runLogicalRect.top());
104
                childScrollableOverflow.move(runLogicalRect.left(), runLogicalRect.top());
118
                scrollableOverflowRect.unite(childScrollableOverflow);
105
                scrollableOverflowRect.unite(childScrollableOverflow);
119
                continue;
120
            }
106
            }
121
        }
107
        }
122
108
        auto lineBoxLogicalRect = FloatRect { line.lineBoxLogicalRect() };
123
        auto adjustedLineBoxRect = FloatRect { lineBoxLogicalRect };
124
        // Final enclosing top and bottom values are in the same coordinate space as the line itself.
125
        auto enclosingTopAndBottom = line.enclosingTopAndBottom() + lineBoxLogicalRect.top();
126
        auto runCount = runIndex - firstRunIndex;
109
        auto runCount = runIndex - firstRunIndex;
127
        inlineContent.lines.append({ firstRunIndex, runCount, adjustedLineBoxRect, enclosingTopAndBottom.top, enclosingTopAndBottom.bottom, scrollableOverflowRect, lineInkOverflowRect, line.baseline(), line.contentLogicalLeft(), line.contentLogicalWidth() });
110
        inlineContent.lines.append({ firstRunIndex, runCount, lineBoxLogicalRect, line.enclosingTopAndBottom().top, line.enclosingTopAndBottom().bottom, scrollableOverflowRect, lineInkOverflowRect, line.baseline(), line.contentLogicalLeft(), line.contentLogicalWidth() });
128
    }
111
    }
129
}
112
}
130
113
- a/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h -2 / +1 lines
Lines 41-54 struct InlineContent; a/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h_sec1
41
41
42
class InlineContentBuilder {
42
class InlineContentBuilder {
43
public:
43
public:
44
    InlineContentBuilder(const Layout::LayoutState&, const RenderBlockFlow&, const BoxTree&);
44
    InlineContentBuilder(const RenderBlockFlow&, const BoxTree&);
45
45
46
    void build(Layout::InlineFormattingState&, InlineContent&) const;
46
    void build(Layout::InlineFormattingState&, InlineContent&) const;
47
47
48
private:
48
private:
49
    void createDisplayLines(Layout::InlineFormattingState&, InlineContent&) const;
49
    void createDisplayLines(Layout::InlineFormattingState&, InlineContent&) const;
50
50
51
    const Layout::LayoutState& m_layoutState;
52
    const RenderBlockFlow& m_blockFlow;
51
    const RenderBlockFlow& m_blockFlow;
53
    const BoxTree& m_boxTree;
52
    const BoxTree& m_boxTree;
54
};
53
};
- a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp -1 / +1 lines
Lines 226-232 void LineLayout::layout() a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp_sec1
226
226
227
void LineLayout::constructContent()
227
void LineLayout::constructContent()
228
{
228
{
229
    auto inlineContentBuilder = InlineContentBuilder { m_layoutState, flow(), m_boxTree };
229
    auto inlineContentBuilder = InlineContentBuilder { flow(), m_boxTree };
230
    inlineContentBuilder.build(m_inlineFormattingState, ensureInlineContent());
230
    inlineContentBuilder.build(m_inlineFormattingState, ensureInlineContent());
231
    ASSERT(m_inlineContent);
231
    ASSERT(m_inlineContent);
232
232

Return to Bug 230200