Title: [271351] trunk/Source/WebCore
Revision
271351
Author
[email protected]
Date
2021-01-10 11:13:01 -0800 (Sun, 10 Jan 2021)

Log Message

[LFC][IFC] Make "inline level box affects line box geometry" logic more explicit
https://bugs.webkit.org/show_bug.cgi?id=220232

Reviewed by Antti Koivisto.

Since InlineLevelBox::isEmpty makes little sense in case of non-inline-boxes (e.g. <br>), let's make
the following set of changes:
1. Introduce InlineLevelBox::setHasContent for inline boxes only (<span>has content</span>, <div>root inlinebox has content</div>)
2. Both atomic and line box logic is moved to InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox
This is also in preparation for getting rid of the is-considered-empty concept for line/line box.

* layout/inlineformatting/InlineFormattingContext.h:
* layout/inlineformatting/InlineFormattingContextGeometry.cpp:
(WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes):
(WebCore::Layout::LineBoxBuilder::computeLineBoxHeightAndAlignInlineLevelBoxesVertically):
* layout/inlineformatting/InlineFormattingContextQuirks.cpp:
(WebCore::Layout::InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox const):
(WebCore::Layout::InlineFormattingContext::Quirks::shouldInlineLevelBoxStretchLineBox const): Deleted.
* layout/inlineformatting/InlineLineBox.cpp:
(WebCore::Layout::LineBox::InlineLevelBox::setHasContent):
* layout/inlineformatting/InlineLineBox.h:
(WebCore::Layout::LineBox::InlineLevelBox::hasContent const):
(WebCore::Layout::LineBox::InlineLevelBox::isEmpty const): Deleted.
(WebCore::Layout::LineBox::InlineLevelBox::setIsNonEmpty): Deleted.

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (271350 => 271351)


--- trunk/Source/WebCore/ChangeLog	2021-01-10 18:09:09 UTC (rev 271350)
+++ trunk/Source/WebCore/ChangeLog	2021-01-10 19:13:01 UTC (rev 271351)
@@ -1,3 +1,30 @@
+2021-01-10  Zalan Bujtas  <[email protected]>
+
+        [LFC][IFC] Make "inline level box affects line box geometry" logic more explicit
+        https://bugs.webkit.org/show_bug.cgi?id=220232
+
+        Reviewed by Antti Koivisto.
+
+        Since InlineLevelBox::isEmpty makes little sense in case of non-inline-boxes (e.g. <br>), let's make
+        the following set of changes:
+        1. Introduce InlineLevelBox::setHasContent for inline boxes only (<span>has content</span>, <div>root inlinebox has content</div>)
+        2. Both atomic and line box logic is moved to InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox
+        This is also in preparation for getting rid of the is-considered-empty concept for line/line box.
+
+        * layout/inlineformatting/InlineFormattingContext.h:
+        * layout/inlineformatting/InlineFormattingContextGeometry.cpp:
+        (WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes):
+        (WebCore::Layout::LineBoxBuilder::computeLineBoxHeightAndAlignInlineLevelBoxesVertically):
+        * layout/inlineformatting/InlineFormattingContextQuirks.cpp:
+        (WebCore::Layout::InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox const):
+        (WebCore::Layout::InlineFormattingContext::Quirks::shouldInlineLevelBoxStretchLineBox const): Deleted.
+        * layout/inlineformatting/InlineLineBox.cpp:
+        (WebCore::Layout::LineBox::InlineLevelBox::setHasContent):
+        * layout/inlineformatting/InlineLineBox.h:
+        (WebCore::Layout::LineBox::InlineLevelBox::hasContent const):
+        (WebCore::Layout::LineBox::InlineLevelBox::isEmpty const): Deleted.
+        (WebCore::Layout::LineBox::InlineLevelBox::setIsNonEmpty): Deleted.
+
 2021-01-10  Antti Koivisto  <[email protected]>
 
         [LFC][Integration] Factor marked text style collection code out of InlineTextBox

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (271350 => 271351)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2021-01-10 18:09:09 UTC (rev 271350)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2021-01-10 19:13:01 UTC (rev 271351)
@@ -51,7 +51,7 @@
     public:
         InlineLayoutUnit initialLineHeight() const;
         bool hasSoftWrapOpportunityAtImage() const;
-        bool shouldInlineLevelBoxStretchLineBox(const LineBox&, const LineBox::InlineLevelBox&) const;
+        bool inlineLevelBoxAffectsLineBox(const LineBox::InlineLevelBox&, const LineBox&) const;
 
     private:
         friend class InlineFormattingContext;

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp (271350 => 271351)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2021-01-10 18:09:09 UTC (rev 271350)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2021-01-10 19:13:01 UTC (rev 271351)
@@ -221,7 +221,7 @@
         auto inlineBoxHasImaginaryStrut = layoutState().inNoQuirksMode();
         auto isInitiallyConsideredNonEmpty = !lineBox.isConsideredEmpty() && inlineBoxHasImaginaryStrut;
         if (isInitiallyConsideredNonEmpty)
-            rootInlineBox->setIsNonEmpty();
+            rootInlineBox->setHasContent();
         setVerticalGeometryForInlineBox(*rootInlineBox);
         simplifiedVerticalAlignment = { { } , rootInlineBox->layoutBounds().height(), rootInlineBox->layoutBounds().ascent - rootInlineBox->baseline() };
         lineBox.addRootInlineBox(WTFMove(rootInlineBox));
@@ -294,10 +294,6 @@
             auto atomicInlineLevelBox = LineBox::InlineLevelBox::createAtomicInlineLevelBox(layoutBox, logicalLeft, { run.logicalWidth(), marginBoxHeight });
             atomicInlineLevelBox->setBaseline(ascent);
             atomicInlineLevelBox->setLayoutBounds(LineBox::InlineLevelBox::LayoutBounds { ascent, marginBoxHeight - ascent });
-            // While in practice when the negative vertical margin makes the layout bounds empty (e.g: height: 100px; margin-top: -100px;), and this inline
-            // level box contributes 0px to the line box height, it should not be considered empty.
-            if (marginBoxHeight || inlineLevelBoxGeometry.marginBefore() || inlineLevelBoxGeometry.marginAfter())
-                atomicInlineLevelBox->setIsNonEmpty();
             // Let's estimate the logical top so that we can avoid running the alignment on simple inline boxes.
             auto alignInlineBoxIfEligible = [&] {
                 if (m_inlineLevelBoxesNeedVerticalAlignment)
@@ -335,7 +331,7 @@
             auto inlineBoxHasImaginaryStrut = layoutState().inNoQuirksMode() && !lineBox.isConsideredEmpty();
             auto isConsideredNonEmpty = inlineBoxHasImaginaryStrut || inlineBoxGeometry.horizontalPadding().valueOr(0_lu) || inlineBoxGeometry.horizontalBorder();
             if (isConsideredNonEmpty)
-                inlineBox->setIsNonEmpty();
+                inlineBox->setHasContent();
             setVerticalGeometryForInlineBox(*inlineBox);
             lineBox.addInlineLevelBox(WTFMove(inlineBox));
             continue;
@@ -349,13 +345,12 @@
         }
         if (run.isText() || run.isSoftLineBreak()) {
             // FIXME: Adjust non-empty inline box height when glyphs from the non-primary font stretch the box.
-            lineBox.inlineLevelBoxForLayoutBox(layoutBox.parent()).setIsNonEmpty();
+            lineBox.inlineLevelBoxForLayoutBox(layoutBox.parent()).setHasContent();
             continue;
         }
         if (run.isHardLineBreak()) {
             auto lineBreakBox = LineBox::InlineLevelBox::createLineBreakBox(layoutBox, logicalLeft);
             setVerticalGeometryForInlineBox(*lineBreakBox);
-            lineBreakBox->setIsNonEmpty();
             lineBox.addInlineLevelBox(WTFMove(lineBreakBox));
             continue;
         }
@@ -392,7 +387,7 @@
 
         auto minimumLogicalTop = Optional<InlineLayoutUnit> { };
         auto maximumLogicalBottom = Optional<InlineLayoutUnit> { };
-        if (!rootInlineBox.isEmpty()) {
+        if (quirks.inlineLevelBoxAffectsLineBox(rootInlineBox, lineBox)) {
             minimumLogicalTop = InlineLayoutUnit { };
             maximumLogicalBottom = rootInlineBox.layoutBounds().height();
             inlineLevelBoxAbsoluteTopAndBottomMap.add(&rootInlineBox, AbsoluteTopAndBottom { *minimumLogicalTop, *maximumLogicalBottom });
@@ -454,7 +449,7 @@
             auto absoluteLogicalBottom = absoluteLogicalTop + inlineLevelBox->layoutBounds().height();
             inlineLevelBoxAbsoluteTopAndBottomMap.add(inlineLevelBox.get(), AbsoluteTopAndBottom { absoluteLogicalTop, absoluteLogicalBottom });
             // Stretch the min/max absolute values if applicable.
-            if (quirks.shouldInlineLevelBoxStretchLineBox(lineBox, *inlineLevelBox)) {
+            if (quirks.inlineLevelBoxAffectsLineBox(*inlineLevelBox, lineBox)) {
                 minimumLogicalTop = std::min(minimumLogicalTop.valueOr(absoluteLogicalTop), absoluteLogicalTop);
                 maximumLogicalBottom = std::max(maximumLogicalBottom.valueOr(absoluteLogicalBottom), absoluteLogicalBottom);
             }
@@ -464,7 +459,7 @@
         // 2. Check if the line box relative aligned inline boxes (top, bottom etc) have enough room and stretch the line box further if needed.
         auto lineBoxLogicalHeight = maximumLogicalBottom.valueOr(InlineLayoutUnit()) - minimumLogicalTop.valueOr(InlineLayoutUnit());
         for (auto* lineBoxRelativeInlineLevelBox : lineBoxRelativeInlineLevelBoxes) {
-            if (!quirks.shouldInlineLevelBoxStretchLineBox(lineBox, *lineBoxRelativeInlineLevelBox))
+            if (!quirks.inlineLevelBoxAffectsLineBox(*lineBoxRelativeInlineLevelBox, lineBox))
                 continue;
             lineBoxLogicalHeight = std::max(lineBoxLogicalHeight, lineBoxRelativeInlineLevelBox->layoutBounds().height());
         }
@@ -477,7 +472,7 @@
         inlineLevelBoxAbsoluteBaselineOffsetMap.add(&rootInlineBox, InlineLayoutUnit { });
 
         auto maximumTopOffsetFromRootInlineBoxBaseline = Optional<InlineLayoutUnit> { };
-        if (!rootInlineBox.isEmpty())
+        if (quirks.inlineLevelBoxAffectsLineBox(rootInlineBox, lineBox))
             maximumTopOffsetFromRootInlineBoxBaseline = rootInlineBox.layoutBounds().ascent;
 
         for (auto& inlineLevelBox : lineBox.nonRootInlineLevelBoxes()) {
@@ -535,7 +530,7 @@
                 }
             }
             inlineLevelBoxAbsoluteBaselineOffsetMap.add(inlineLevelBox.get(), absoluteBaselineOffset);
-            auto affectsRootInlineBoxVerticalPosition = quirks.shouldInlineLevelBoxStretchLineBox(lineBox, *inlineLevelBox);
+            auto affectsRootInlineBoxVerticalPosition = quirks.inlineLevelBoxAffectsLineBox(*inlineLevelBox, lineBox);
             if (affectsRootInlineBoxVerticalPosition)
                 maximumTopOffsetFromRootInlineBoxBaseline = std::max(maximumTopOffsetFromRootInlineBoxBaseline.valueOr(std::numeric_limits<InlineLayoutUnit>::lowest()), absoluteBaselineOffset + inlineLevelBox->layoutBounds().ascent);
         }

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp (271350 => 271351)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp	2021-01-10 18:09:09 UTC (rev 271350)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp	2021-01-10 19:13:01 UTC (rev 271351)
@@ -40,17 +40,24 @@
     return root.style().fontMetrics().floatHeight();
 }
 
-bool InlineFormattingContext::Quirks::shouldInlineLevelBoxStretchLineBox(const LineBox& lineBox, const LineBox::InlineLevelBox& inlineLevelBox) const
+bool InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox(const LineBox::InlineLevelBox& inlineLevelBox, const LineBox& lineBox) const
 {
-    if (inlineLevelBox.isEmpty())
-        return false;
-    if (layoutState().inNoQuirksMode())
-        return true;
-    if (!inlineLevelBox.isLineBreakBox())
-        return true;
-    // <br> in non-standard mode stretches the line box only when the line is empty.
-    // e.g. <div><span><br></span></div> will stretch but <div>this will not stretch to 200px<span style="font-size: 200px;"><br></span></div>
-    return lineBox.isConsideredEmpty();
+    if (inlineLevelBox.isInlineBox())
+        return inlineLevelBox.hasContent();
+    if (inlineLevelBox.isLineBreakBox()) {
+        // <br> in non-standard mode stretches the line box only when the line is empty.
+        // e.g. <div><span><br></span></div> will stretch but <div>this will not stretch to 200px<span style="font-size: 200px;"><br></span></div>
+        return layoutState().inNoQuirksMode() ? true : lineBox.isConsideredEmpty();
+    }
+    if (inlineLevelBox.isAtomicInlineLevelBox()) {
+        if (inlineLevelBox.layoutBounds().height())
+            return true;
+        // While in practice when the negative vertical margin makes the layout bounds empty (e.g: height: 100px; margin-top: -100px;), and this inline
+        // level box contributes 0px to the line box height, it still needs to be taken into account while computing line box geometries.
+        auto& boxGeometry = formattingContext().geometryForBox(inlineLevelBox.layoutBox());
+        return boxGeometry.marginBefore() || boxGeometry.marginAfter();
+    }
+    return false;
 }
 
 bool InlineFormattingContext::Quirks::hasSoftWrapOpportunityAtImage() const

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp (271350 => 271351)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp	2021-01-10 18:09:09 UTC (rev 271350)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp	2021-01-10 19:13:01 UTC (rev 271351)
@@ -71,6 +71,12 @@
     m_logicalRect.setHeight(roundToInt(logicalHeight));
 }
 
+void LineBox::InlineLevelBox::setHasContent()
+{
+    ASSERT(isInlineBox());
+    m_hasContent = true;
+}
+
 bool LineBox::InlineLevelBox::hasLineBoxRelativeAlignment() const
 {
     auto verticalAlignment = layoutBox().style().verticalAlign();

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h (271350 => 271351)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h	2021-01-10 18:09:09 UTC (rev 271350)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h	2021-01-10 19:13:01 UTC (rev 271351)
@@ -77,8 +77,8 @@
         };
         LayoutBounds layoutBounds() const { return m_layoutBounds; }
 
-        bool isEmpty() const { return m_isEmpty; }
-        void setIsNonEmpty() { m_isEmpty = false; }
+        bool hasContent() const { return m_hasContent; }
+        void setHasContent();
 
         VerticalAlign verticalAlign() const { return layoutBox().style().verticalAlign(); }
         const Box& layoutBox() const { return *m_layoutBox; }
@@ -124,7 +124,7 @@
         LayoutBounds m_layoutBounds;
         InlineLayoutUnit m_baseline { 0 };
         Optional<InlineLayoutUnit> m_descent;
-        bool m_isEmpty { true };
+        bool m_hasContent { false };
         Type m_type { Type::InlineBox };
     };
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to