Title: [271567] trunk/Source/WebCore
Revision
271567
Author
[email protected]
Date
2021-01-17 20:09:31 -0800 (Sun, 17 Jan 2021)

Log Message

[LFC][IFC] Extend simplified vertical alignment for cases when the line has only "empty" runs
https://bugs.webkit.org/show_bug.cgi?id=220689

Reviewed by Antti Koivisto.

Quirks::inlineLevelBoxAffectsLineBox now does not need to check for empty inline boxes as
those cases would always end up in the simplified vertical alignment path.

* layout/inlineformatting/InlineFormattingContextGeometry.cpp:
(WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes):
* layout/inlineformatting/InlineFormattingContextQuirks.cpp:
(WebCore::Layout::InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (271566 => 271567)


--- trunk/Source/WebCore/ChangeLog	2021-01-18 00:06:28 UTC (rev 271566)
+++ trunk/Source/WebCore/ChangeLog	2021-01-18 04:09:31 UTC (rev 271567)
@@ -1,5 +1,20 @@
 2021-01-17  Zalan Bujtas  <[email protected]>
 
+        [LFC][IFC] Extend simplified vertical alignment for cases when the line has only "empty" runs
+        https://bugs.webkit.org/show_bug.cgi?id=220689
+
+        Reviewed by Antti Koivisto.
+
+        Quirks::inlineLevelBoxAffectsLineBox now does not need to check for empty inline boxes as
+        those cases would always end up in the simplified vertical alignment path. 
+
+        * layout/inlineformatting/InlineFormattingContextGeometry.cpp:
+        (WebCore::Layout::LineBoxBuilder::constructInlineLevelBoxes):
+        * layout/inlineformatting/InlineFormattingContextQuirks.cpp:
+        (WebCore::Layout::InlineFormattingContext::Quirks::inlineLevelBoxAffectsLineBox const):
+
+2021-01-17  Zalan Bujtas  <[email protected]>
+
         [LFC][IFC] Add the root inline collapsing case to simplified vertical alignment
         https://bugs.webkit.org/show_bug.cgi?id=220685
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp (271566 => 271567)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2021-01-18 00:06:28 UTC (rev 271566)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextGeometry.cpp	2021-01-18 04:09:31 UTC (rev 271567)
@@ -206,9 +206,9 @@
 {
     auto horizontalAligmentOffset = lineBox.horizontalAlignmentOffset().valueOr(InlineLayoutUnit { });
     struct SimplifiedVerticalAlignment {
-        InlineLayoutUnit inlineLevelBoxTop { 0 };
-        InlineLayoutUnit inlineLevelBoxBottom { 0 };
-        InlineLayoutUnit rootInlineBoxLogicalTop { 0 };
+        InlineLayoutUnit lineBoxTop { 0 };
+        InlineLayoutUnit lineBoxBottom { 0 };
+        InlineLayoutUnit rootInlineBoxTop { 0 };
     };
     auto simplifiedVerticalAlignment = SimplifiedVerticalAlignment { };
 
@@ -215,17 +215,10 @@
     auto createRootInlineBox = [&] {
         auto rootInlineBox = LineBox::InlineLevelBox::createRootInlineBox(rootBox(), horizontalAligmentOffset, lineBox.logicalWidth());
         setVerticalGeometryForInlineBox(*rootInlineBox);
+        simplifiedVerticalAlignment = { { } , rootInlineBox->layoutBounds().height(), rootInlineBox->layoutBounds().ascent - rootInlineBox->baseline() };
         lineBox.addRootInlineBox(WTFMove(rootInlineBox));
     };
     createRootInlineBox();
-    // Set the initial simplified vertical alignment if applicable.
-    auto& rootInlineBox = lineBox.rootInlineBox();
-    if (!m_inlineLevelBoxesNeedVerticalAlignment) {
-        auto lineHasNoContent = runs.isEmpty();
-        auto lineBoxBottom = lineHasNoContent ? InlineLayoutUnit(0.0f) : rootInlineBox.layoutBounds().height();
-        auto rootInlineBoxLogicalTop = lineHasNoContent ? -rootInlineBox.baseline() : rootInlineBox.layoutBounds().ascent - rootInlineBox.baseline();
-        simplifiedVerticalAlignment = { { }, lineBoxBottom, rootInlineBoxLogicalTop };
-    }
 
     auto createWrappedInlineBoxes = [&] {
         if (runs.isEmpty())
@@ -262,8 +255,28 @@
         }
     };
     createWrappedInlineBoxes();
+
+    auto& rootInlineBox = lineBox.rootInlineBox();
+    auto lineHasContent = false;
     for (auto& run : runs) {
         auto& layoutBox = run.layoutBox();
+        auto runHasContent = [&] () -> bool {
+            ASSERT(!lineHasContent);
+            if (run.isText() || run.isBox() || run.isSoftLineBreak() || run.isHardLineBreak())
+                return true;
+            auto& inlineBoxGeometry = formattingContext().geometryForBox(layoutBox);
+            // Even negative horizontal margin makes the line "contentful".
+            if (run.isInlineBoxStart())
+                return inlineBoxGeometry.marginStart() || inlineBoxGeometry.borderLeft() || inlineBoxGeometry.paddingLeft().valueOr(0_lu);
+            if (run.isInlineBoxEnd())
+                return inlineBoxGeometry.marginEnd() || inlineBoxGeometry.borderRight() || inlineBoxGeometry.paddingRight().valueOr(0_lu);
+            if (run.isWordBreakOpportunity())
+                return false;
+            ASSERT_NOT_REACHED();
+            return true;
+        };
+        lineHasContent = lineHasContent || runHasContent();
+
         auto logicalLeft = horizontalAligmentOffset + run.logicalLeft();
         if (run.isBox()) {
             auto& inlineLevelBoxGeometry = formattingContext().geometryForBox(layoutBox);
@@ -309,9 +322,9 @@
                 // Only baseline alignment for now.
                 auto logicalTop = rootInlineBox.baseline() - ascent;
                 auto layoutBoundsTop = rootInlineBox.layoutBounds().ascent - ascent;
-                simplifiedVerticalAlignment.inlineLevelBoxTop = std::min(simplifiedVerticalAlignment.inlineLevelBoxTop, layoutBoundsTop);
-                simplifiedVerticalAlignment.inlineLevelBoxBottom = std::max(simplifiedVerticalAlignment.inlineLevelBoxBottom, layoutBoundsTop + marginBoxHeight);
-                simplifiedVerticalAlignment.rootInlineBoxLogicalTop = std::max(simplifiedVerticalAlignment.rootInlineBoxLogicalTop, ascent - rootInlineBox.baseline());
+                simplifiedVerticalAlignment.lineBoxTop = std::min(simplifiedVerticalAlignment.lineBoxTop, layoutBoundsTop);
+                simplifiedVerticalAlignment.lineBoxBottom = std::max(simplifiedVerticalAlignment.lineBoxBottom, layoutBoundsTop + marginBoxHeight);
+                simplifiedVerticalAlignment.rootInlineBoxTop = std::max(simplifiedVerticalAlignment.rootInlineBoxTop, ascent - rootInlineBox.baseline());
                 atomicInlineLevelBox->setLogicalTop(logicalTop);
             };
             alignInlineBoxIfEligible();
@@ -319,7 +332,9 @@
             continue;
         }
         // FIXME: Add support for simple inline boxes too.
-        m_inlineLevelBoxesNeedVerticalAlignment = true;
+        // 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_inlineLevelBoxesNeedVerticalAlignment = lineHasContent;
         if (run.isInlineBoxStart()) {
             auto initialLogicalWidth = lineBox.logicalWidth() - run.logicalLeft();
             ASSERT(initialLogicalWidth >= 0);
@@ -352,9 +367,15 @@
         }
         ASSERT_NOT_REACHED();
     }
+
     if (!m_inlineLevelBoxesNeedVerticalAlignment) {
-        rootInlineBox.setLogicalTop(simplifiedVerticalAlignment.rootInlineBoxLogicalTop);
-        lineBox.setLogicalHeight(simplifiedVerticalAlignment.inlineLevelBoxBottom - simplifiedVerticalAlignment.inlineLevelBoxTop);
+        if (!lineHasContent) {
+            simplifiedVerticalAlignment.rootInlineBoxTop = -rootInlineBox.baseline();
+            simplifiedVerticalAlignment.lineBoxTop = { };
+            simplifiedVerticalAlignment.lineBoxBottom = { };
+        }
+        rootInlineBox.setLogicalTop(simplifiedVerticalAlignment.rootInlineBoxTop);
+        lineBox.setLogicalHeight(simplifiedVerticalAlignment.lineBoxBottom - simplifiedVerticalAlignment.lineBoxTop);
     }
 }
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp (271566 => 271567)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp	2021-01-18 00:06:28 UTC (rev 271566)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp	2021-01-18 04:09:31 UTC (rev 271567)
@@ -48,11 +48,13 @@
         if (layoutState().inStandardsMode())
             return true;
         // In quirks mode linebreak boxes (<br>) affect the line box when they are inside a non-root inline box (<span></span>) or when
-        // the line has no other inline level box/root inlinebox has no content.
+        // the line has no other inline level box.
+        // e.g <div><img><br></div> should produce a line with no descent.
         auto& parentInlineBox = lineBox.inlineLevelBoxForLayoutBox(inlineLevelBox.layoutBox().parent());
         if (!parentInlineBox.isRootInlineBox())
             return true;
-        return !parentInlineBox.hasContent() && lineBox.nonRootInlineLevelBoxes().size() == 1;
+        // is <br> the only inline level box on the line?
+        return lineBox.nonRootInlineLevelBoxes().size() == 1;
     }
     if (inlineLevelBox.isInlineBox()) {
         // Inline boxes (e.g. root inline box or <span>) affects line boxes either through the strut or actual content.
@@ -66,9 +68,7 @@
             }
         }
         auto inlineBoxHasImaginaryStrut = layoutState().inStandardsMode();
-        // Inline box with strut only stetches the line box when it has additional inline level boxes (not inline boxes) or the root inline box has content.
-        // e.g. <!DOCTYPE html><div><span style="font-size: 100px;"></span><img src="" style="width: 0px; height: 0px;"></div>
-        return inlineBoxHasImaginaryStrut && (lineBox.hasNonInlineBox() || lineBox.rootInlineBox().hasContent());
+        return inlineBoxHasImaginaryStrut;
     }
     if (inlineLevelBox.isAtomicInlineLevelBox()) {
         if (inlineLevelBox.layoutBounds().height())
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to