Title: [282141] trunk/Source/WebCore
Revision
282141
Author
za...@apple.com
Date
2021-09-08 06:33:30 -0700 (Wed, 08 Sep 2021)

Log Message

[LFC][IFC] Add support for inline box ink overflow
https://bugs.webkit.org/show_bug.cgi?id=230026

Reviewed by Antti Koivisto.

Collecting the ink overflow from the descendant boxes has 2 phases.
1. Update the ink overflow on the parent inline box (unless it's a root inline box) as we walk the line content
and find the atomic inline level boxes (e.g. <span><img></span>)
2. Collect the ink overflow on nested inline boxes (e.g. <span>some<span style="font-size: 100px">text</span><span>).

* layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::InlineDisplayContentBuilder):
(WebCore::Layout::InlineDisplayContentBuilder::build):
(WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent):
(WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineSpanningInlineBoxes):
(WebCore::Layout::InlineDisplayContentBuilder::collectInkOverflowForInlineBoxRuns):
* layout/formattingContexts/inline/InlineDisplayContentBuilder.h:
* layout/formattingContexts/inline/InlineLineRun.h:
(WebCore::Layout::Run::adjustInkOverflow):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (282140 => 282141)


--- trunk/Source/WebCore/ChangeLog	2021-09-08 12:56:13 UTC (rev 282140)
+++ trunk/Source/WebCore/ChangeLog	2021-09-08 13:33:30 UTC (rev 282141)
@@ -1,3 +1,25 @@
+2021-09-08  Alan Bujtas  <za...@apple.com>
+
+        [LFC][IFC] Add support for inline box ink overflow
+        https://bugs.webkit.org/show_bug.cgi?id=230026
+
+        Reviewed by Antti Koivisto.
+
+        Collecting the ink overflow from the descendant boxes has 2 phases.
+        1. Update the ink overflow on the parent inline box (unless it's a root inline box) as we walk the line content
+        and find the atomic inline level boxes (e.g. <span><img></span>)
+        2. Collect the ink overflow on nested inline boxes (e.g. <span>some<span style="font-size: 100px">text</span><span>). 
+
+        * layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
+        (WebCore::Layout::InlineDisplayContentBuilder::InlineDisplayContentBuilder):
+        (WebCore::Layout::InlineDisplayContentBuilder::build):
+        (WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent):
+        (WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineSpanningInlineBoxes):
+        (WebCore::Layout::InlineDisplayContentBuilder::collectInkOverflowForInlineBoxRuns):
+        * layout/formattingContexts/inline/InlineDisplayContentBuilder.h:
+        * layout/formattingContexts/inline/InlineLineRun.h:
+        (WebCore::Layout::Run::adjustInkOverflow):
+
 2021-09-08  Martin Robinson  <mrobin...@webkit.org>
 
         [css-position-sticky] Sticky constraints are calculated incorrectly when scrolling container has padding and borders

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp (282140 => 282141)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp	2021-09-08 12:56:13 UTC (rev 282140)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp	2021-09-08 13:33:30 UTC (rev 282141)
@@ -40,7 +40,6 @@
     : m_formattingContextRoot(formattingContextRoot)
     , m_formattingState(formattingState)
 {
-
 }
 
 void InlineDisplayContentBuilder::build(const LineBuilder::LineContent& lineContent, const LineBox& lineBox, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex)
@@ -52,6 +51,7 @@
     formattingState.addRun({ lineIndex, Run::Type::RootInlineBox, root(), rootInlineBoxRect, rootInlineBoxRect, { }, { },  lineBox.rootInlineBox().hasContent()});
     createRunsAndUpdateGeometryForLineSpanningInlineBoxes(lineBox, lineBoxLogicalTopLeft, lineIndex);
     createRunsAndUpdateGeometryForLineContent(lineContent, lineBox, lineBoxLogicalTopLeft, lineIndex);
+    collectInkOverflowForInlineBoxRuns(lineBox);
 }
 
 void InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent(const LineBuilder::LineContent& lineContent, const LineBox& lineBox, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex)
@@ -132,6 +132,7 @@
             auto& boxGeometry = formattingState.boxGeometry(layoutBox);
             auto logicalBorderBox = lineBox.logicalBorderBoxForAtomicInlineLevelBox(layoutBox, boxGeometry);
             logicalBorderBox.moveBy(lineBoxLogicalTopLeft);
+            // FIXME: Add ink overflow support for atomic inline level boxes (e.g. box shadow).
             formattingState.addRun({ lineIndex, Run::Type::AtomicInlineLevelBox, layoutBox, logicalBorderBox, logicalBorderBox, lineRun.expansion(), { } });
 
             auto borderBoxLogicalTopLeft = logicalBorderBox.topLeft();
@@ -139,6 +140,17 @@
             // Atomic inline boxes are all set. Their margin/border/content box geometries are already computed. We just have to position them here.
             boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
             lineNeedIntegralPosition = false;
+
+            auto adjustParentInlineBoxInkOverflow = [&] {
+                auto& parentInlineBox = layoutBox.parent();
+                if (&parentInlineBox == &root()) {
+                    // We don't collect ink overflow for the root inline box run.
+                    return;
+                }
+                RELEASE_ASSERT(m_inlineBoxRunIndexMap.contains(&parentInlineBox));
+                formattingState.runs()[m_inlineBoxRunIndexMap.get(&parentInlineBox)].adjustInkOverflow(logicalBorderBox);
+            };
+            adjustParentInlineBoxInkOverflow();
             break;
         }
         case InlineItem::Type::InlineBoxStart: {
@@ -148,6 +160,7 @@
             inlineBoxBorderBox.moveBy(lineBoxLogicalTopLeft);
             if (lineBox.hasContent()) {
                 // FIXME: It's expected to not have any runs on empty lines. We should reconsider this.
+                m_inlineBoxRunIndexMap.add(&layoutBox, formattingState.runs().size());
                 formattingState.addRun({ lineIndex, Run::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, inlineBoxBorderBox, { }, { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
             }
 
@@ -198,6 +211,7 @@
         auto inlineBoxBorderBox = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
         inlineBoxBorderBox.moveBy(lineBoxLogicalTopLeft);
 
+        m_inlineBoxRunIndexMap.add(&layoutBox, formattingState.runs().size());
         formattingState.addRun({ lineIndex, Run::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
 
         auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxBorderBox.width()), LayoutUnit::fromFloatCeil(inlineBoxBorderBox.height()) };
@@ -222,7 +236,32 @@
     formattingState.lines().last().setNeedsIntegralPosition(lineNeedIntegralPosition);
 }
 
+void InlineDisplayContentBuilder::collectInkOverflowForInlineBoxRuns(const LineBox& lineBox)
+{
+    if (m_inlineBoxRunIndexMap.isEmpty() || !lineBox.hasContent()) {
+        // This line has no inline box (only root, but we don't collect ink overflow for the root inline box atm)
+        return;
+    }
+
+    auto& formattingState = this->formattingState();
+    auto& nonRootInlineLevelBoxes = lineBox.nonRootInlineLevelBoxes();
+    // Visit the inline boxes and propagate ink overflow to their parents -except to the root inline box.
+    // (e.g. <span style="font-size: 10px;">Small font size<span style="font-size: 300px;">Larger font size. This overflows the top most span.</span></span>).
+    for (size_t index = nonRootInlineLevelBoxes.size(); index--;) {
+        if (!nonRootInlineLevelBoxes[index].isInlineBox())
+            continue;
+        auto& inlineBox = nonRootInlineLevelBoxes[index].layoutBox();
+        auto& parentInlineBox = inlineBox.parent();
+        if (&parentInlineBox == &root())
+            continue;
+        RELEASE_ASSERT(m_inlineBoxRunIndexMap.contains(&inlineBox) && m_inlineBoxRunIndexMap.contains(&parentInlineBox));
+        auto& inkOverflow = formattingState.runs()[m_inlineBoxRunIndexMap.get(&inlineBox)].inkOverflow();
+        auto& parentInlineBoxRun = formattingState.runs()[m_inlineBoxRunIndexMap.get(&parentInlineBox)];
+        parentInlineBoxRun.adjustInkOverflow(inkOverflow);
+    }
 }
+
 }
+}
 
 #endif

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h (282140 => 282141)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h	2021-09-08 12:56:13 UTC (rev 282140)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.h	2021-09-08 13:33:30 UTC (rev 282141)
@@ -46,6 +46,7 @@
 private:
     void createRunsAndUpdateGeometryForLineContent(const LineBuilder::LineContent&, const LineBox&, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex);
     void createRunsAndUpdateGeometryForLineSpanningInlineBoxes(const LineBox&, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex);
+    void collectInkOverflowForInlineBoxRuns(const LineBox&);
 
     const ContainerBox& root() const { return m_formattingContextRoot; }
     InlineFormattingState& formattingState() const { return m_formattingState; } 
@@ -52,6 +53,7 @@
 
     const ContainerBox& m_formattingContextRoot;
     InlineFormattingState& m_formattingState;
+    HashMap<const Box*, size_t> m_inlineBoxRunIndexMap;
 };
 
 }

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h (282140 => 282141)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h	2021-09-08 12:56:13 UTC (rev 282140)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h	2021-09-08 13:33:30 UTC (rev 282141)
@@ -97,6 +97,8 @@
     InlineLayoutUnit logicalHeight() const { return logicalRect().height(); }
 
     void moveVertically(InlineLayoutUnit offset) { m_logicalRect.moveVertically(offset); }
+    void adjustInkOverflow(const InlineRect& childBorderBox) { return m_inkOverflow.expandToContain(childBorderBox); }
+
     std::optional<Text>& text() { return m_text; }
     const std::optional<Text>& text() const { return m_text; }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to