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

Changeset 273728 in webkit


Ignore:
Timestamp:
Mar 2, 2021, 6:44:38 AM (6 years ago)
Author:
Alan Bujtas
Message:

[LFC][IFC] Merge SimplifiedVerticalAlignment and m_useSimplifiedVerticalAlignment
​https://bugs.webkit.org/show_bug.cgi?id=222586

Reviewed by Antti Koivisto.

Let's have SimplifiedVerticalAlignment track if simplified alignment can be applied on the current content.
Also decouple the actual alignment and whether the inline level box can be (simplified)aligned.
(see SimplifiedVerticalAlignment::align and SimplifiedVerticalAlignment::canUseSimplifiedAlignment)
This is in preparation for supporting non-atomic inline level boxes.

  • layout/inlineformatting/InlineFormattingContextGeometry.cpp:

(WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::rootInlineBoxLogicalTop const):
(WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::lineBoxHeight const):
(WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::isEnabled const):
(WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::setEnabled):
(WebCore::Layout::LineBoxBuilder::LineBoxBuilder):
(WebCore::Layout::LineBoxBuilder::build):
(WebCore::Layout::LineBoxBuilder::constructAndAlignInlineLevelBoxes):
(WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::SimplifiedVerticalAlignment):
(WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::canUseSimplifiedAlignment):
(WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::align):
(WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::adjust):
(WebCore::Layout::SimplifiedVerticalAlignment::SimplifiedVerticalAlignment): Deleted.
(WebCore::Layout::SimplifiedVerticalAlignment::rootInlineBoxLogicalTop const): Deleted.
(WebCore::Layout::SimplifiedVerticalAlignment::lineBoxHeight const): Deleted.
(WebCore::Layout::SimplifiedVerticalAlignment::alignInlineLevelBoxIfApplicable): Deleted.
(WebCore::Layout::SimplifiedVerticalAlignment::adjust): Deleted.
(WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes): Deleted.

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r273726 r273728  
     12021-03-02  Zalan Bujtas  <zalan@apple.com>
     2
     3        [LFC][IFC] Merge SimplifiedVerticalAlignment and m_useSimplifiedVerticalAlignment
     4        https://bugs.webkit.org/show_bug.cgi?id=222586
     5
     6        Reviewed by Antti Koivisto.
     7
     8        Let's have SimplifiedVerticalAlignment track if simplified alignment can be applied on the current content.
     9        Also decouple the actual alignment and whether the inline level box can be (simplified)aligned.
     10        (see SimplifiedVerticalAlignment::align and SimplifiedVerticalAlignment::canUseSimplifiedAlignment)
     11        This is in preparation for supporting non-atomic inline level boxes.
     12
     13        * layout/inlineformatting/InlineFormattingContextGeometry.cpp:
     14        (WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::rootInlineBoxLogicalTop const):
     15        (WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::lineBoxHeight const):
     16        (WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::isEnabled const):
     17        (WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::setEnabled):
     18        (WebCore::Layout::LineBoxBuilder::LineBoxBuilder):
     19        (WebCore::Layout::LineBoxBuilder::build):
     20        (WebCore::Layout::LineBoxBuilder::constructAndAlignInlineLevelBoxes):
     21        (WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::SimplifiedVerticalAlignment):
     22        (WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::canUseSimplifiedAlignment):
     23        (WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::align):
     24        (WebCore::Layout::LineBoxBuilder::SimplifiedVerticalAlignment::adjust):
     25        (WebCore::Layout::SimplifiedVerticalAlignment::SimplifiedVerticalAlignment): Deleted.
     26        (WebCore::Layout::SimplifiedVerticalAlignment::rootInlineBoxLogicalTop const): Deleted.
     27        (WebCore::Layout::SimplifiedVerticalAlignment::lineBoxHeight const): Deleted.
     28        (WebCore::Layout::SimplifiedVerticalAlignment::alignInlineLevelBoxIfApplicable): Deleted.
     29        (WebCore::Layout::SimplifiedVerticalAlignment::adjust): Deleted.
     30        (WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes): Deleted.
     31
    1322021-03-02  Chris Lord  <clord@igalia.com>
    233
  • trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp

    r273723 r273728  
    4646
    4747private:
     48    struct SimplifiedVerticalAlignment {
     49        SimplifiedVerticalAlignment(const LineBox::InlineLevelBox& rootInlineBox);
     50
     51        static bool canUseSimplifiedAlignment(const LineBox::InlineLevelBox& rootInlineBox, const LineBox::InlineLevelBox&, const BoxGeometry& inlineLevelBoxGeometry);
     52
     53        void align(LineBox::InlineLevelBox&);
     54
     55        InlineLayoutUnit rootInlineBoxLogicalTop() const { return m_rootInlineBoxLogicalTop; }
     56        InlineLayoutUnit lineBoxHeight() const { return m_lineBoxLogicalBottom - m_lineBoxLogicalTop; }
     57
     58        void setEnabled(bool enabled) { m_isEnabled = enabled; }
     59        bool isEnabled() const { return m_isEnabled; }
     60
     61    private:
     62        void adjust(const LineBox::InlineLevelBox&);
     63
     64        const LineBox::InlineLevelBox& m_rootInlineBox;
     65        bool m_isEnabled { true };
     66        InlineLayoutUnit m_lineBoxLogicalTop { 0 };
     67        InlineLayoutUnit m_lineBoxLogicalBottom { 0 };
     68        InlineLayoutUnit m_rootInlineBoxLogicalTop { 0 };
     69    };
     70
    4871    void setVerticalGeometryForInlineBox(LineBox::InlineLevelBox&) const;
    49     void constructInlineLevelBoxes(LineBox&, const Line::RunList&);
     72    void constructAndAlignInlineLevelBoxes(LineBox&, const Line::RunList&);
    5073    void computeLineBoxHeightAndAlignInlineLevelBoxesVertically(LineBox&);
    5174
    … …  
    5881private:
    5982    const InlineFormattingContext& m_inlineFormattingContext;
    60     bool m_useSimplifiedVerticalAlignment { true };
    6183};
    6284
    … …  
    149171LineBoxBuilder::LineBoxBuilder(const InlineFormattingContext& inlineFormattingContext)
    150172    : m_inlineFormattingContext(inlineFormattingContext)
    151     // FIXME: Add fast path support for line-height content.
    152     , m_useSimplifiedVerticalAlignment(inlineFormattingContext.layoutState().inStandardsMode() && rootBox().style().lineHeight().isNegative())
    153173{
    154174}
    … …  
    161181    auto horizontalAlignmentOffset = Layout::horizontalAlignmentOffset(runs, rootBox().style().textAlign(), lineLogicalWidth, contentLogicalWidth, lineContent.isLastLineWithInlineContent);
    162182    auto lineBox = LineBox { rootBox(), lineContent.logicalTopLeft, lineLogicalWidth, horizontalAlignmentOffset.valueOr(InlineLayoutUnit { }), contentLogicalWidth, runs.size() };
    163 
    164     constructInlineLevelBoxes(lineBox, runs);
    165     if (!m_useSimplifiedVerticalAlignment)
    166         computeLineBoxHeightAndAlignInlineLevelBoxesVertically(lineBox);
     183    constructAndAlignInlineLevelBoxes(lineBox, runs);
    167184    return lineBox;
    168185}
    … …  
    202219}
    203220
    204 struct SimplifiedVerticalAlignment {
    205     SimplifiedVerticalAlignment(const LineBox::InlineLevelBox& rootInlineBox)
    206         : m_rootInlineBox(rootInlineBox)
    207     {
    208         adjust(rootInlineBox);
    209     }
    210 
    211     InlineLayoutUnit rootInlineBoxLogicalTop() const { return m_rootInlineBoxLogicalTop; }
    212     InlineLayoutUnit lineBoxHeight() const { return m_lineBoxLogicalBottom - m_lineBoxLogicalTop; }
    213 
    214     bool alignInlineLevelBoxIfApplicable(LineBox::InlineLevelBox& inlineLevelBox, const BoxGeometry& inlineLevelBoxGeometry)
    215     {
    216         if (inlineLevelBox.isAtomicInlineLevelBox()) {
    217             // Baseline aligned, non-stretchy direct children are considered to be simple for now.
    218             auto& layoutBox = inlineLevelBox.layoutBox();
    219             auto isConsideredSimple = &layoutBox.parent() == &m_rootInlineBox.layoutBox()
    220                 && layoutBox.style().verticalAlign() == VerticalAlign::Baseline
    221                 && !inlineLevelBoxGeometry.marginBefore()
    222                 && !inlineLevelBoxGeometry.marginAfter()
    223                 && inlineLevelBoxGeometry.marginBoxHeight() <= m_rootInlineBox.baseline();
    224             if (!isConsideredSimple)
    225                 return false;
    226             // Only baseline alignment for now.
    227             inlineLevelBox.setLogicalTop(m_rootInlineBox.baseline() - inlineLevelBox.baseline());
    228             adjust(inlineLevelBox);
    229             return true;
    230         }
    231         ASSERT_NOT_IMPLEMENTED_YET();
    232         return false;
    233     }
    234 private:
    235     void adjust(const LineBox::InlineLevelBox& inlineLevelBox)
    236     {
    237         auto layoutBoundsLogicalTop = m_rootInlineBox.layoutBounds().ascent - inlineLevelBox.layoutBounds().ascent;
    238         m_lineBoxLogicalTop = std::min(m_lineBoxLogicalTop, layoutBoundsLogicalTop);
    239         m_lineBoxLogicalBottom = std::max(m_lineBoxLogicalBottom, layoutBoundsLogicalTop + inlineLevelBox.layoutBounds().height());
    240         m_rootInlineBoxLogicalTop = std::max(m_rootInlineBoxLogicalTop, inlineLevelBox.layoutBounds().ascent - m_rootInlineBox.baseline());
    241     }
    242 
    243     const LineBox::InlineLevelBox& m_rootInlineBox;
    244 
    245     InlineLayoutUnit m_lineBoxLogicalTop { 0 };
    246     InlineLayoutUnit m_lineBoxLogicalBottom { 0 };
    247     InlineLayoutUnit m_rootInlineBoxLogicalTop { 0 };
    248 };
    249 
    250 void LineBoxBuilder::constructInlineLevelBoxes(LineBox& lineBox, const Line::RunList& runs)
     221void LineBoxBuilder::constructAndAlignInlineLevelBoxes(LineBox& lineBox, const Line::RunList& runs)
    251222{
    252223    auto& rootInlineBox = lineBox.rootInlineBox();
    253224    setVerticalGeometryForInlineBox(rootInlineBox);
     225
    254226    auto simplifiedVerticalAlignment = SimplifiedVerticalAlignment { rootInlineBox };
     227    // FIXME: Add fast path support for line-height content.
     228    simplifiedVerticalAlignment.setEnabled(layoutState().inStandardsMode() && rootBox().style().lineHeight().isNegative());
    255229
    256230    auto createWrappedInlineBoxes = [&] {
    … …  
    310284        lineHasContent = lineHasContent || runHasContent();
    311285
     286        auto simplifiedAlignVerticallyIfApplicable = [&](auto& inlineLevelBox, const auto& boxGeometry) {
     287            if (!simplifiedVerticalAlignment.isEnabled())
     288                return;
     289            if (!SimplifiedVerticalAlignment::canUseSimplifiedAlignment(rootInlineBox, inlineLevelBox, boxGeometry)) {
     290                simplifiedVerticalAlignment.setEnabled(false);
     291                return;
     292            }
     293            simplifiedVerticalAlignment.align(inlineLevelBox);
     294        };
     295
    312296        auto logicalLeft = rootInlineBox.logicalLeft() + run.logicalLeft();
    313297        if (run.isBox()) {
    … …  
    339323            atomicInlineLevelBox->setBaseline(ascent);
    340324            atomicInlineLevelBox->setLayoutBounds(LineBox::InlineLevelBox::LayoutBounds { ascent, marginBoxHeight - ascent });
    341             if (m_useSimplifiedVerticalAlignment) {
    342                 // Let's pre-compute the logical top so that we can avoid running the alignment on simple inline level boxes.
    343                 m_useSimplifiedVerticalAlignment = simplifiedVerticalAlignment.alignInlineLevelBoxIfApplicable(*atomicInlineLevelBox, inlineLevelBoxGeometry);
    344             }
     325            simplifiedAlignVerticallyIfApplicable(*atomicInlineLevelBox, inlineLevelBoxGeometry);
    345326            lineBox.addInlineLevelBox(WTFMove(atomicInlineLevelBox));
    346327            continue;
    … …  
    349330        // We can do simplified vertical alignment with non-atomic inline boxes as long as the line has no content.
    350331        // e.g. <div><span></span><span></span></div> is still okay.
    351         m_useSimplifiedVerticalAlignment = !lineHasContent;
     332        simplifiedVerticalAlignment.setEnabled(!lineHasContent);
    352333        if (run.isInlineBoxStart()) {
    353334            // At this point we don't know yet how wide this inline box is. Let's assume it's as long as the line is
    … …  
    393374
    394375    lineBox.setHasContent(lineHasContent);
    395     // We should always be able to exercise the fast path when the line has no content at all, even in non-standards mode or with line-height set.
    396     m_useSimplifiedVerticalAlignment = m_useSimplifiedVerticalAlignment || !lineHasContent;
    397     if (m_useSimplifiedVerticalAlignment) {
     376    if (simplifiedVerticalAlignment.isEnabled() || !lineHasContent) {
     377        // We should always be able to exercise the fast path when the line has no content at all, even in non-standards mode or with line-height set.
    398378        rootInlineBox.setLogicalTop(lineHasContent ? simplifiedVerticalAlignment.rootInlineBoxLogicalTop() : -rootInlineBox.baseline());
    399379        lineBox.setLogicalHeight(lineHasContent ? simplifiedVerticalAlignment.lineBoxHeight() : InlineLayoutUnit());
    400     }
     380    } else
     381        computeLineBoxHeightAndAlignInlineLevelBoxesVertically(lineBox);
    401382}
    402383
    … …  
    636617}
    637618
     619LineBoxBuilder::SimplifiedVerticalAlignment::SimplifiedVerticalAlignment(const LineBox::InlineLevelBox& rootInlineBox)
     620    : m_rootInlineBox(rootInlineBox)
     621{
     622    adjust(rootInlineBox);
     623}
     624
     625bool LineBoxBuilder::SimplifiedVerticalAlignment::canUseSimplifiedAlignment(const LineBox::InlineLevelBox& rootInlineBox, const LineBox::InlineLevelBox& inlineLevelBox, const BoxGeometry& inlineLevelBoxGeometry)
     626{
     627    if (inlineLevelBox.isAtomicInlineLevelBox()) {
     628        // Baseline aligned, non-stretchy direct children are considered to be simple for now.
     629        auto& layoutBox = inlineLevelBox.layoutBox();
     630        return &layoutBox.parent() == &rootInlineBox.layoutBox()
     631            && layoutBox.style().verticalAlign() == VerticalAlign::Baseline
     632            && !inlineLevelBoxGeometry.marginBefore()
     633            && !inlineLevelBoxGeometry.marginAfter()
     634            && inlineLevelBoxGeometry.marginBoxHeight() <= rootInlineBox.baseline();
     635    }
     636    return false;
     637}
     638
     639void LineBoxBuilder::SimplifiedVerticalAlignment::align(LineBox::InlineLevelBox& inlineLevelBox)
     640{
     641    if (inlineLevelBox.isAtomicInlineLevelBox()) {
     642        // Only baseline alignment for now.
     643        inlineLevelBox.setLogicalTop(m_rootInlineBox.baseline() - inlineLevelBox.baseline());
     644        adjust(inlineLevelBox);
     645        return;
     646    }
     647    ASSERT_NOT_IMPLEMENTED_YET();
     648}
     649
     650void LineBoxBuilder::SimplifiedVerticalAlignment::adjust(const LineBox::InlineLevelBox& inlineLevelBox)
     651{
     652    auto layoutBoundsLogicalTop = m_rootInlineBox.layoutBounds().ascent - inlineLevelBox.layoutBounds().ascent;
     653    m_lineBoxLogicalTop = std::min(m_lineBoxLogicalTop, layoutBoundsLogicalTop);
     654    m_lineBoxLogicalBottom = std::max(m_lineBoxLogicalBottom, layoutBoundsLogicalTop + inlineLevelBox.layoutBounds().height());
     655    m_rootInlineBoxLogicalTop = std::max(m_rootInlineBoxLogicalTop, inlineLevelBox.layoutBounds().ascent - m_rootInlineBox.baseline());
     656}
     657
    638658LineBox InlineFormattingContext::Geometry::lineBoxForLineContent(const LineBuilder::LineContent& lineContent)
    639659{
Note: See TracChangeset for help on using the changeset viewer.