Title: [272725] trunk/Source/WebCore
Revision
272725
Author
[email protected]
Date
2021-02-11 06:56:18 -0800 (Thu, 11 Feb 2021)

Log Message

[LFC][IFC] Introduce dedicated logical rect getter for each inline level box type
https://bugs.webkit.org/show_bug.cgi?id=221725

Reviewed by Antti Koivisto.

This helps when different type of rects (margin vs. border) are returned for different type of boxes.

* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
* layout/inlineformatting/InlineLineBox.cpp:
(WebCore::Layout::LineBox::logicalRectForTextRun const):
(WebCore::Layout::LineBox::logicalRectForLineBreakBox const):
(WebCore::Layout::LineBox::logicalRectForInlineLevelBox const):
(WebCore::Layout::LineBox::logicalMarginRectForAtomicInlineLevelBox const):
(WebCore::Layout::LineBox::logicalRectForInlineBox const):
(WebCore::Layout::LineBox::logicalMarginRectForInlineLevelBox const): Deleted.
* layout/inlineformatting/InlineLineBox.h:
* layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
(WebCore::LayoutIntegration::InlineContentBuilder::createDisplayNonRootInlineBoxes const):
* layout/layouttree/LayoutTreeBuilder.cpp:
(WebCore::Layout::showInlineTreeAndRuns):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (272724 => 272725)


--- trunk/Source/WebCore/ChangeLog	2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/ChangeLog	2021-02-11 14:56:18 UTC (rev 272725)
@@ -1,5 +1,29 @@
 2021-02-11  Zalan Bujtas  <[email protected]>
 
+        [LFC][IFC] Introduce dedicated logical rect getter for each inline level box type
+        https://bugs.webkit.org/show_bug.cgi?id=221725
+
+        Reviewed by Antti Koivisto.
+
+        This helps when different type of rects (margin vs. border) are returned for different type of boxes.
+
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent):
+        * layout/inlineformatting/InlineLineBox.cpp:
+        (WebCore::Layout::LineBox::logicalRectForTextRun const):
+        (WebCore::Layout::LineBox::logicalRectForLineBreakBox const):
+        (WebCore::Layout::LineBox::logicalRectForInlineLevelBox const):
+        (WebCore::Layout::LineBox::logicalMarginRectForAtomicInlineLevelBox const):
+        (WebCore::Layout::LineBox::logicalRectForInlineBox const):
+        (WebCore::Layout::LineBox::logicalMarginRectForInlineLevelBox const): Deleted.
+        * layout/inlineformatting/InlineLineBox.h:
+        * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+        (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayNonRootInlineBoxes const):
+        * layout/layouttree/LayoutTreeBuilder.cpp:
+        (WebCore::Layout::showInlineTreeAndRuns):
+
+2021-02-11  Zalan Bujtas  <[email protected]>
+
         [LFC][IFC] Inline boxes have incorrect content box height/width values
         https://bugs.webkit.org/show_bug.cgi?id=221739
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (272724 => 272725)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2021-02-11 14:56:18 UTC (rev 272725)
@@ -464,7 +464,7 @@
             }
             for (auto* layoutBox : layoutBoxList) {
                 auto& boxGeometry = formattingState.boxGeometry(*layoutBox);
-                auto inlineBoxLogicalHeight = LayoutUnit::fromFloatCeil(lineBox.logicalMarginRectForInlineLevelBox(*layoutBox, boxGeometry).height());
+                auto inlineBoxLogicalHeight = LayoutUnit::fromFloatCeil(lineBox.logicalRectForInlineBox(*layoutBox, boxGeometry).height());
                 boxGeometry.setContentBoxHeight(inlineBoxLogicalHeight);
                 boxGeometry.setContentBoxWidth({ });
                 boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBoxLogicalRect.topLeft()));
@@ -490,25 +490,26 @@
                 continue;
             }
             if (lineRun.isLineBreak()) {
-                auto lineBreakBoxRect = lineBox.logicalRectForTextRun(lineRun);
-                formattingState.addLineRun({ lineIndex, layoutBox, lineBreakBoxRect, lineRun.expansion(), lineRun.textContent() });
-
                 if (layoutBox.isLineBreakBox()) {
                     // Only hard linebreaks have associated layout boxes.
+                    auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
+                    formattingState.addLineRun({ lineIndex, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
+
                     auto& boxGeometry = formattingState.boxGeometry(layoutBox);
                     lineBreakBoxRect.moveBy(lineBoxLogicalRect.topLeft());
                     boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
                     boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
-                }
+                } else 
+                    formattingState.addLineRun({ lineIndex, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
                 continue;
             }
             if (lineRun.isBox()) {
                 ASSERT(layoutBox.isAtomicInlineLevelBox());
-                auto& boxGeometry = formattingState.boxGeometry(layoutBox);
-                auto logicalMarginRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
+                auto logicalMarginRect = lineBox.logicalMarginRectForAtomicInlineLevelBox(layoutBox);
                 formattingState.addLineRun({ lineIndex, layoutBox, logicalMarginRect, lineRun.expansion(), { } });
 
                 auto borderBoxLogicalTopLeft = logicalMarginRect.topLeft();
+                auto& boxGeometry = formattingState.boxGeometry(layoutBox);
                 borderBoxLogicalTopLeft.move(std::max(0_lu, boxGeometry.marginStart()), std::max(0_lu, boxGeometry.marginBefore()));
                 // Note that inline boxes are relative to the line and their top position can be negative.
                 borderBoxLogicalTopLeft.moveBy(lineBoxLogicalRect.topLeft());
@@ -525,7 +526,7 @@
             }
             if (lineRun.isInlineBoxStart()) {
                 auto& boxGeometry = formattingState.boxGeometry(layoutBox);
-                auto inlineBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
+                auto inlineBoxLogicalRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry);
                 formattingState.addLineRun({ lineIndex, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { } });
                 inlineBoxStartSet.add(&layoutBox);
                 enclosingTopAndBottom.top = std::min(enclosingTopAndBottom.top, inlineBoxLogicalRect.top());
@@ -533,7 +534,7 @@
             }
             if (lineRun.isInlineBoxEnd()) {
                 inlineBoxEndSet.add(&layoutBox);
-                auto inlineBoxLogicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, formattingState.boxGeometry(layoutBox));
+                auto inlineBoxLogicalRect = lineBox.logicalRectForInlineBox(layoutBox, formattingState.boxGeometry(layoutBox));
                 enclosingTopAndBottom.bottom = std::max(enclosingTopAndBottom.bottom, inlineBoxLogicalRect.bottom());
                 continue;
             }
@@ -554,7 +555,7 @@
             auto& layoutBox = inlineLevelBox->layoutBox();
             auto& boxGeometry = formattingState.boxGeometry(layoutBox);
             // Inline boxes may or may not be wrapped and have runs on multiple lines (e.g. <span>first line<br>second line<br>third line</span>)
-            auto inlineBoxMarginRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
+            auto inlineBoxMarginRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry);
             auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxMarginRect.width()), LayoutUnit::fromFloatCeil(inlineBoxMarginRect.height()) };
             auto logicalRect = Rect { LayoutPoint { inlineBoxMarginRect.topLeft() }, inlineBoxSize };
             logicalRect.moveBy(LayoutPoint { lineBoxLogicalRect.topLeft() });

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp (272724 => 272725)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp	2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp	2021-02-11 14:56:18 UTC (rev 272725)
@@ -106,7 +106,7 @@
 
 InlineRect LineBox::logicalRectForTextRun(const Line::Run& run) const
 {
-    ASSERT(run.isText() || run.isLineBreak());
+    ASSERT(run.isText() || run.isSoftLineBreak());
     auto* parentInlineBox = &inlineLevelBoxForLayoutBox(run.layoutBox().parent());
     ASSERT(parentInlineBox->isInlineBox());
     auto& fontMetrics = parentInlineBox->style().fontMetrics();
@@ -121,30 +121,46 @@
     return { runlogicalTop, m_horizontalAlignmentOffset.valueOr(InlineLayoutUnit { }) + run.logicalLeft(), run.logicalWidth(), logicalHeight };
 }
 
-InlineRect LineBox::logicalMarginRectForInlineLevelBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const
+InlineRect LineBox::logicalRectForLineBreakBox(const Box& layoutBox) const
 {
-    auto logicalRect = [&] {
-        auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox);
-        auto inlineBoxLogicalRect = inlineBox->logicalRect();
-        if (inlineBox->hasLineBoxRelativeAlignment())
-            return inlineBoxLogicalRect;
+    ASSERT(layoutBox.isLineBreakBox());
+    return logicalRectForInlineLevelBox(layoutBox);
+}
 
-        if (&layoutBox.parent() == &m_rootInlineBox->layoutBox()) {
-            inlineBoxLogicalRect.moveVertically(m_rootInlineBox->logicalTop());
-            return inlineBoxLogicalRect;
-        }
+InlineRect LineBox::logicalRectForInlineLevelBox(const Box& layoutBox) const
+{
+    ASSERT(layoutBox.isInlineLevelBox() || layoutBox.isLineBreakBox());
+    // Inline level boxes are relative to their parent unless the vertical alignment makes them relative to the line box (e.g. top, bottom).
+    auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox);
+    auto inlineBoxLogicalRect = inlineBox->logicalRect();
+    if (inlineBox->hasLineBoxRelativeAlignment())
+        return inlineBoxLogicalRect;
 
-        auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top();
-        while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) {
-            inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent());
-            ASSERT(inlineBox->isInlineBox());
-            inlineBoxAbsolutelogicalTop += inlineBox->logicalTop();
-        }
-        return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() };
-    }();
-    if (!layoutBox.isInlineBox())
-        return logicalRect;
+    // Fast path for inline level boxes on the root inline box (e.g <div><img></div>).
+    if (&layoutBox.parent() == &m_rootInlineBox->layoutBox()) {
+        inlineBoxLogicalRect.moveVertically(m_rootInlineBox->logicalTop());
+        return inlineBoxLogicalRect;
+    }
 
+    // e.g <div><span><img></span></div>
+    auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top();
+    while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) {
+        inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent());
+        ASSERT(inlineBox->isInlineBox());
+        inlineBoxAbsolutelogicalTop += inlineBox->logicalTop();
+    }
+    return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() };
+}
+
+InlineRect LineBox::logicalMarginRectForAtomicInlineLevelBox(const Box& layoutBox) const
+{
+    ASSERT(layoutBox.isAtomicInlineLevelBox());
+    return logicalRectForInlineLevelBox(layoutBox);
+}
+
+InlineRect LineBox::logicalRectForInlineBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const
+{
+    auto logicalRect = logicalRectForInlineLevelBox(layoutBox);
     // This logical rect is as tall as the "text" content is. Let's adjust with vertical border and padding -vertical margin is ignored.
     auto verticalBorderAndPadding = boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0_lu);
     logicalRect.expandVertically(verticalBorderAndPadding);

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h (272724 => 272725)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h	2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h	2021-02-11 14:56:18 UTC (rev 272725)
@@ -150,8 +150,10 @@
     const InlineLevelBox& inlineLevelBoxForLayoutBox(const Box& layoutBox) const { return *m_inlineLevelBoxRectMap.get(&layoutBox); }
 
     InlineRect logicalRectForTextRun(const Line::Run&) const;
+    InlineRect logicalRectForLineBreakBox(const Box&) const;
+    InlineRect logicalMarginRectForAtomicInlineLevelBox(const Box&) const;
     InlineRect logicalRectForRootInlineBox() const { return m_rootInlineBox->logicalRect(); }
-    InlineRect logicalMarginRectForInlineLevelBox(const Box&, const BoxGeometry&) const;
+    InlineRect logicalRectForInlineBox(const Box&, const BoxGeometry&) const;
 
     const InlineLevelBox& rootInlineBox() const { return *m_rootInlineBox; }
     using InlineLevelBoxList = Vector<std::unique_ptr<InlineLevelBox>>;
@@ -171,6 +173,7 @@
     InlineLevelBox& rootInlineBox() { return *m_rootInlineBox; }
 
     InlineLevelBox& inlineLevelBoxForLayoutBox(const Box& layoutBox) { return *m_inlineLevelBoxRectMap.get(&layoutBox); }
+    InlineRect logicalRectForInlineLevelBox(const Box& layoutBox) const;
 
     void setHasContent(bool hasContent) { m_hasContent = hasContent; }
 

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (272724 => 272725)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2021-02-11 14:56:18 UTC (rev 272725)
@@ -341,7 +341,7 @@
                 continue;
             auto& layoutBox = inlineLevelBox->layoutBox();
             auto& boxGeometry = m_layoutState.geometryForBox(layoutBox);
-            auto inlineBoxRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);
+            auto inlineBoxRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry);
             inlineBoxRect.moveBy(lineBoxLogicalRect.topLeft());
 
             inlineContent.nonRootInlineBoxes.append({ lineIndex, layoutBox, inlineBoxRect });

Modified: trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp (272724 => 272725)


--- trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp	2021-02-11 14:46:56 UTC (rev 272724)
+++ trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp	2021-02-11 14:56:18 UTC (rev 272725)
@@ -406,18 +406,22 @@
         auto outputInlineLevelBox = [&](const auto& inlineLevelBox) {
             addSpacing();
             stream << "    ";
-            if (inlineLevelBox.isRootInlineBox())
+            auto logicalRect = InlineRect { };
+            auto& layoutBox = inlineLevelBox.layoutBox();
+            if (inlineLevelBox.isRootInlineBox()) {
                 stream << "Root inline box";
-            else if (inlineLevelBox.isAtomicInlineLevelBox())
+                logicalRect = lineBox.logicalRectForRootInlineBox();
+            } else if (inlineLevelBox.isAtomicInlineLevelBox()) {
                 stream << "Atomic inline level box";
-            else if (inlineLevelBox.isLineBreakBox())
+                logicalRect = lineBox.logicalMarginRectForAtomicInlineLevelBox(layoutBox);
+            } else if (inlineLevelBox.isLineBreakBox()) {
                 stream << "Line break box";
-            else if (inlineLevelBox.isInlineBox())
-                stream << "Generic inline box";
-            else
+                logicalRect = lineBox.logicalRectForLineBreakBox(layoutBox);
+            } else if (inlineLevelBox.isInlineBox()) {
+                stream << "Inline box";
+                logicalRect = lineBox.logicalRectForInlineBox(layoutBox, layoutState.geometryForBox(layoutBox));
+            } else
                 stream << "Generic inline level box";
-            auto& layoutBox = inlineLevelBox.layoutBox();
-            auto logicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, layoutState.geometryForBox(layoutBox));
             stream
                 << " at (" << logicalRect.left() << "," << logicalRect.top() << ")"
                 << " size (" << logicalRect.width() << "x" << logicalRect.height() << ")"
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to