Title: [273728] trunk/Source/WebCore
Revision
273728
Author
[email protected]
Date
2021-03-02 06:44:38 -0800 (Tue, 02 Mar 2021)

Log 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.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (273727 => 273728)


--- trunk/Source/WebCore/ChangeLog	2021-03-02 10:15:10 UTC (rev 273727)
+++ trunk/Source/WebCore/ChangeLog	2021-03-02 14:44:38 UTC (rev 273728)
@@ -1,3 +1,34 @@
+2021-03-02  Zalan Bujtas  <[email protected]>
+
+        [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.
+
 2021-03-02  Chris Lord  <[email protected]>
 
         Remove document accessor on CSSFontSelector

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp (273727 => 273728)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2021-03-02 10:15:10 UTC (rev 273727)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2021-03-02 14:44:38 UTC (rev 273728)
@@ -45,8 +45,31 @@
     LineBox build(const LineBuilder::LineContent&);
 
 private:
+    struct SimplifiedVerticalAlignment {
+        SimplifiedVerticalAlignment(const LineBox::InlineLevelBox& rootInlineBox);
+
+        static bool canUseSimplifiedAlignment(const LineBox::InlineLevelBox& rootInlineBox, const LineBox::InlineLevelBox&, const BoxGeometry& inlineLevelBoxGeometry);
+
+        void align(LineBox::InlineLevelBox&);
+
+        InlineLayoutUnit rootInlineBoxLogicalTop() const { return m_rootInlineBoxLogicalTop; }
+        InlineLayoutUnit lineBoxHeight() const { return m_lineBoxLogicalBottom - m_lineBoxLogicalTop; }
+
+        void setEnabled(bool enabled) { m_isEnabled = enabled; }
+        bool isEnabled() const { return m_isEnabled; }
+
+    private:
+        void adjust(const LineBox::InlineLevelBox&);
+
+        const LineBox::InlineLevelBox& m_rootInlineBox;
+        bool m_isEnabled { true };
+        InlineLayoutUnit m_lineBoxLogicalTop { 0 };
+        InlineLayoutUnit m_lineBoxLogicalBottom { 0 };
+        InlineLayoutUnit m_rootInlineBoxLogicalTop { 0 };
+    };
+
     void setVerticalGeometryForInlineBox(LineBox::InlineLevelBox&) const;
-    void constructInlineLevelBoxes(LineBox&, const Line::RunList&);
+    void constructAndAlignInlineLevelBoxes(LineBox&, const Line::RunList&);
     void computeLineBoxHeightAndAlignInlineLevelBoxesVertically(LineBox&);
 
     const InlineFormattingContext& formattingContext() const { return m_inlineFormattingContext; }
@@ -57,7 +80,6 @@
 
 private:
     const InlineFormattingContext& m_inlineFormattingContext;
-    bool m_useSimplifiedVerticalAlignment { true };
 };
 
 struct HangingTrailingWhitespaceContent {
@@ -148,8 +170,6 @@
 
 LineBoxBuilder::LineBoxBuilder(const InlineFormattingContext& inlineFormattingContext)
     : m_inlineFormattingContext(inlineFormattingContext)
-    // FIXME: Add fast path support for line-height content.
-    , m_useSimplifiedVerticalAlignment(inlineFormattingContext.layoutState().inStandardsMode() && rootBox().style().lineHeight().isNegative())
 {
 }
 
@@ -160,10 +180,7 @@
     auto contentLogicalWidth = lineContent.contentLogicalWidth;
     auto horizontalAlignmentOffset = Layout::horizontalAlignmentOffset(runs, rootBox().style().textAlign(), lineLogicalWidth, contentLogicalWidth, lineContent.isLastLineWithInlineContent);
     auto lineBox = LineBox { rootBox(), lineContent.logicalTopLeft, lineLogicalWidth, horizontalAlignmentOffset.valueOr(InlineLayoutUnit { }), contentLogicalWidth, runs.size() };
-
-    constructInlineLevelBoxes(lineBox, runs);
-    if (!m_useSimplifiedVerticalAlignment)
-        computeLineBoxHeightAndAlignInlineLevelBoxesVertically(lineBox);
+    constructAndAlignInlineLevelBoxes(lineBox, runs);
     return lineBox;
 }
 
@@ -201,57 +218,14 @@
     inlineLevelBox.setLayoutBounds(LineBox::InlineLevelBox::LayoutBounds { floorf(ascent), ceil(descent) });
 }
 
-struct SimplifiedVerticalAlignment {
-    SimplifiedVerticalAlignment(const LineBox::InlineLevelBox& rootInlineBox)
-        : m_rootInlineBox(rootInlineBox)
-    {
-        adjust(rootInlineBox);
-    }
-
-    InlineLayoutUnit rootInlineBoxLogicalTop() const { return m_rootInlineBoxLogicalTop; }
-    InlineLayoutUnit lineBoxHeight() const { return m_lineBoxLogicalBottom - m_lineBoxLogicalTop; }
-
-    bool alignInlineLevelBoxIfApplicable(LineBox::InlineLevelBox& inlineLevelBox, const BoxGeometry& inlineLevelBoxGeometry)
-    {
-        if (inlineLevelBox.isAtomicInlineLevelBox()) {
-            // Baseline aligned, non-stretchy direct children are considered to be simple for now.
-            auto& layoutBox = inlineLevelBox.layoutBox();
-            auto isConsideredSimple = &layoutBox.parent() == &m_rootInlineBox.layoutBox()
-                && layoutBox.style().verticalAlign() == VerticalAlign::Baseline
-                && !inlineLevelBoxGeometry.marginBefore()
-                && !inlineLevelBoxGeometry.marginAfter()
-                && inlineLevelBoxGeometry.marginBoxHeight() <= m_rootInlineBox.baseline();
-            if (!isConsideredSimple)
-                return false;
-            // Only baseline alignment for now.
-            inlineLevelBox.setLogicalTop(m_rootInlineBox.baseline() - inlineLevelBox.baseline());
-            adjust(inlineLevelBox);
-            return true;
-        }
-        ASSERT_NOT_IMPLEMENTED_YET();
-        return false;
-    }
-private:
-    void adjust(const LineBox::InlineLevelBox& inlineLevelBox)
-    {
-        auto layoutBoundsLogicalTop = m_rootInlineBox.layoutBounds().ascent - inlineLevelBox.layoutBounds().ascent;
-        m_lineBoxLogicalTop = std::min(m_lineBoxLogicalTop, layoutBoundsLogicalTop);
-        m_lineBoxLogicalBottom = std::max(m_lineBoxLogicalBottom, layoutBoundsLogicalTop + inlineLevelBox.layoutBounds().height());
-        m_rootInlineBoxLogicalTop = std::max(m_rootInlineBoxLogicalTop, inlineLevelBox.layoutBounds().ascent - m_rootInlineBox.baseline());
-    }
-
-    const LineBox::InlineLevelBox& m_rootInlineBox;
-
-    InlineLayoutUnit m_lineBoxLogicalTop { 0 };
-    InlineLayoutUnit m_lineBoxLogicalBottom { 0 };
-    InlineLayoutUnit m_rootInlineBoxLogicalTop { 0 };
-};
-
-void LineBoxBuilder::constructInlineLevelBoxes(LineBox& lineBox, const Line::RunList& runs)
+void LineBoxBuilder::constructAndAlignInlineLevelBoxes(LineBox& lineBox, const Line::RunList& runs)
 {
     auto& rootInlineBox = lineBox.rootInlineBox();
     setVerticalGeometryForInlineBox(rootInlineBox);
+
     auto simplifiedVerticalAlignment = SimplifiedVerticalAlignment { rootInlineBox };
+    // FIXME: Add fast path support for line-height content.
+    simplifiedVerticalAlignment.setEnabled(layoutState().inStandardsMode() && rootBox().style().lineHeight().isNegative());
 
     auto createWrappedInlineBoxes = [&] {
         if (runs.isEmpty())
@@ -309,6 +283,16 @@
         };
         lineHasContent = lineHasContent || runHasContent();
 
+        auto simplifiedAlignVerticallyIfApplicable = [&](auto& inlineLevelBox, const auto& boxGeometry) {
+            if (!simplifiedVerticalAlignment.isEnabled())
+                return;
+            if (!SimplifiedVerticalAlignment::canUseSimplifiedAlignment(rootInlineBox, inlineLevelBox, boxGeometry)) {
+                simplifiedVerticalAlignment.setEnabled(false);
+                return;
+            }
+            simplifiedVerticalAlignment.align(inlineLevelBox);
+        };
+
         auto logicalLeft = rootInlineBox.logicalLeft() + run.logicalLeft();
         if (run.isBox()) {
             auto& inlineLevelBoxGeometry = formattingContext().geometryForBox(layoutBox);
@@ -338,10 +322,7 @@
             auto atomicInlineLevelBox = LineBox::InlineLevelBox::createAtomicInlineLevelBox(layoutBox, logicalLeft, { inlineLevelBoxGeometry.borderBoxWidth(), marginBoxHeight });
             atomicInlineLevelBox->setBaseline(ascent);
             atomicInlineLevelBox->setLayoutBounds(LineBox::InlineLevelBox::LayoutBounds { ascent, marginBoxHeight - ascent });
-            if (m_useSimplifiedVerticalAlignment) {
-                // Let's pre-compute the logical top so that we can avoid running the alignment on simple inline level boxes.
-                m_useSimplifiedVerticalAlignment = simplifiedVerticalAlignment.alignInlineLevelBoxIfApplicable(*atomicInlineLevelBox, inlineLevelBoxGeometry);
-            }
+            simplifiedAlignVerticallyIfApplicable(*atomicInlineLevelBox, inlineLevelBoxGeometry);
             lineBox.addInlineLevelBox(WTFMove(atomicInlineLevelBox));
             continue;
         }
@@ -348,7 +329,7 @@
         // FIXME: Add support for simple inline boxes too.
         // We can do simplified vertical alignment with non-atomic inline boxes as long as the line has no content.
         // e.g. <div><span></span><span></span></div> is still okay.
-        m_useSimplifiedVerticalAlignment = !lineHasContent;
+        simplifiedVerticalAlignment.setEnabled(!lineHasContent);
         if (run.isInlineBoxStart()) {
             // 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
             // and adjust it later if we come across an inlineBoxEnd run (see below).
@@ -392,12 +373,12 @@
     }
 
     lineBox.setHasContent(lineHasContent);
-    // 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.
-    m_useSimplifiedVerticalAlignment = m_useSimplifiedVerticalAlignment || !lineHasContent;
-    if (m_useSimplifiedVerticalAlignment) {
+    if (simplifiedVerticalAlignment.isEnabled() || !lineHasContent) {
+        // 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.
         rootInlineBox.setLogicalTop(lineHasContent ? simplifiedVerticalAlignment.rootInlineBoxLogicalTop() : -rootInlineBox.baseline());
         lineBox.setLogicalHeight(lineHasContent ? simplifiedVerticalAlignment.lineBoxHeight() : InlineLayoutUnit());
-    }
+    } else
+        computeLineBoxHeightAndAlignInlineLevelBoxesVertically(lineBox);
 }
 
 void LineBoxBuilder::computeLineBoxHeightAndAlignInlineLevelBoxesVertically(LineBox& lineBox)
@@ -635,6 +616,45 @@
     alignInlineLevelBoxes();
 }
 
+LineBoxBuilder::SimplifiedVerticalAlignment::SimplifiedVerticalAlignment(const LineBox::InlineLevelBox& rootInlineBox)
+    : m_rootInlineBox(rootInlineBox)
+{
+    adjust(rootInlineBox);
+}
+
+bool LineBoxBuilder::SimplifiedVerticalAlignment::canUseSimplifiedAlignment(const LineBox::InlineLevelBox& rootInlineBox, const LineBox::InlineLevelBox& inlineLevelBox, const BoxGeometry& inlineLevelBoxGeometry)
+{
+    if (inlineLevelBox.isAtomicInlineLevelBox()) {
+        // Baseline aligned, non-stretchy direct children are considered to be simple for now.
+        auto& layoutBox = inlineLevelBox.layoutBox();
+        return &layoutBox.parent() == &rootInlineBox.layoutBox()
+            && layoutBox.style().verticalAlign() == VerticalAlign::Baseline
+            && !inlineLevelBoxGeometry.marginBefore()
+            && !inlineLevelBoxGeometry.marginAfter()
+            && inlineLevelBoxGeometry.marginBoxHeight() <= rootInlineBox.baseline();
+    }
+    return false;
+}
+
+void LineBoxBuilder::SimplifiedVerticalAlignment::align(LineBox::InlineLevelBox& inlineLevelBox)
+{
+    if (inlineLevelBox.isAtomicInlineLevelBox()) {
+        // Only baseline alignment for now.
+        inlineLevelBox.setLogicalTop(m_rootInlineBox.baseline() - inlineLevelBox.baseline());
+        adjust(inlineLevelBox);
+        return;
+    }
+    ASSERT_NOT_IMPLEMENTED_YET();
+}
+
+void LineBoxBuilder::SimplifiedVerticalAlignment::adjust(const LineBox::InlineLevelBox& inlineLevelBox)
+{
+    auto layoutBoundsLogicalTop = m_rootInlineBox.layoutBounds().ascent - inlineLevelBox.layoutBounds().ascent;
+    m_lineBoxLogicalTop = std::min(m_lineBoxLogicalTop, layoutBoundsLogicalTop);
+    m_lineBoxLogicalBottom = std::max(m_lineBoxLogicalBottom, layoutBoundsLogicalTop + inlineLevelBox.layoutBounds().height());
+    m_rootInlineBoxLogicalTop = std::max(m_rootInlineBoxLogicalTop, inlineLevelBox.layoutBounds().ascent - m_rootInlineBox.baseline());
+}
+
 LineBox InlineFormattingContext::Geometry::lineBoxForLineContent(const LineBuilder::LineContent& lineContent)
 {
     return LineBoxBuilder(formattingContext()).build(lineContent);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to