Title: [281746] trunk/Source/WebCore
Revision
281746
Author
[email protected]
Date
2021-08-29 11:57:47 -0700 (Sun, 29 Aug 2021)

Log Message

[LFC][IFC] Add ink overflow to the line runs
https://bugs.webkit.org/show_bug.cgi?id=229653

Reviewed by Antti Koivisto.

Let's move the ink overflow computation from the integration layer to IFC.
This is in preparation for merging display runs (IFC) and the integration layer runs.

* layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::build):
(WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent):
(WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineSpanningInlineBoxes):
* layout/formattingContexts/inline/InlineLineRun.h:
(WebCore::Layout::LineRun::inkOverflow const):
(WebCore::Layout::LineRun::LineRun):
* layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
(WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (281745 => 281746)


--- trunk/Source/WebCore/ChangeLog	2021-08-29 17:38:29 UTC (rev 281745)
+++ trunk/Source/WebCore/ChangeLog	2021-08-29 18:57:47 UTC (rev 281746)
@@ -1,3 +1,23 @@
+2021-08-29  Alan Bujtas  <[email protected]>
+
+        [LFC][IFC] Add ink overflow to the line runs
+        https://bugs.webkit.org/show_bug.cgi?id=229653
+
+        Reviewed by Antti Koivisto.
+
+        Let's move the ink overflow computation from the integration layer to IFC.
+        This is in preparation for merging display runs (IFC) and the integration layer runs.
+
+        * layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
+        (WebCore::Layout::InlineDisplayContentBuilder::build):
+        (WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent):
+        (WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineSpanningInlineBoxes):
+        * layout/formattingContexts/inline/InlineLineRun.h:
+        (WebCore::Layout::LineRun::inkOverflow const):
+        (WebCore::Layout::LineRun::LineRun):
+        * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+        (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):
+
 2021-08-29  Rob Buis  <[email protected]>
 
         Nullptr crash in ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp	2021-08-29 17:38:29 UTC (rev 281745)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp	2021-08-29 18:57:47 UTC (rev 281746)
@@ -28,7 +28,10 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
+#include "FontCascade.h"
 #include "LayoutBoxGeometry.h"
+#include "LayoutInitialContainingBlock.h"
+#include "RuntimeEnabledFeatures.h"
 
 namespace WebCore {
 namespace Layout {
@@ -47,7 +50,7 @@
     // Every line starts with a root run, even the empty ones.
     auto rootInlineBoxRect = lineBox.logicalRectForRootInlineBox();
     rootInlineBoxRect.moveBy(lineBoxLogicalTopLeft);
-    formattingState.addLineRun({ lineIndex, LineRun::Type::RootInlineBox, root(), rootInlineBoxRect, { }, { },  lineBox.rootInlineBox().hasContent()});
+    formattingState.addLineRun({ lineIndex, LineRun::Type::RootInlineBox, root(), rootInlineBoxRect, rootInlineBoxRect, { }, { },  lineBox.rootInlineBox().hasContent()});
 
     // Spanning inline boxes start at the very beginning of the line.
     auto lineSpanningInlineBoxIndex = formattingState.lineRuns().size();
@@ -65,13 +68,29 @@
         case InlineItem::Type::Text: {
             auto textRunRect = lineBox.logicalRectForTextRun(lineRun);
             textRunRect.moveBy(lineBoxLogicalTopLeft);
-            formattingState.addLineRun({ lineIndex, LineRun::Type::Text, layoutBox, textRunRect, lineRun.expansion(), lineRun.textContent() });
+
+            auto inkOverflow = [&] {
+                auto& style = layoutBox.style();
+                auto initialContaingBlockSize = RuntimeEnabledFeatures::sharedFeatures().layoutFormattingContextIntegrationEnabled()
+                    ? formattingState.layoutState().viewportSize()
+                    : formattingState.layoutState().geometryForBox(layoutBox.initialContainingBlock()).contentBox().size();
+                auto strokeOverflow = std::ceil(style.computedStrokeWidth(ceiledIntSize(initialContaingBlockSize)));
+                auto inkOverflow = textRunRect;
+                inkOverflow.inflate(strokeOverflow);
+                auto letterSpacing = style.fontCascade().letterSpacing();
+                if (letterSpacing < 0) {
+                    // Last letter's negative spacing shrinks logical rect. Push it to ink overflow.
+                    inkOverflow.expand(-letterSpacing, { });
+                }
+                return inkOverflow;
+            };
+            formattingState.addLineRun({ lineIndex, LineRun::Type::Text, layoutBox, textRunRect, inkOverflow(), lineRun.expansion(), lineRun.textContent() });
             break;
         }
         case InlineItem::Type::SoftLineBreak: {
             auto softLineBreakRunRect = lineBox.logicalRectForTextRun(lineRun);
             softLineBreakRunRect.moveBy(lineBoxLogicalTopLeft);
-            formattingState.addLineRun({ lineIndex, LineRun::Type::SoftLineBreak, layoutBox, softLineBreakRunRect, lineRun.expansion(), lineRun.textContent() });
+            formattingState.addLineRun({ lineIndex, LineRun::Type::SoftLineBreak, layoutBox, softLineBreakRunRect, softLineBreakRunRect, lineRun.expansion(), lineRun.textContent() });
             break;
         }
         case InlineItem::Type::HardLineBreak: {
@@ -78,7 +97,7 @@
             // Only hard linebreaks have associated layout boxes.
             auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
             lineBreakBoxRect.moveBy(lineBoxLogicalTopLeft);
-            formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreakBox, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
+            formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreakBox, layoutBox, lineBreakBoxRect, lineBreakBoxRect, lineRun.expansion(), { } });
 
             auto& boxGeometry = formattingState.boxGeometry(layoutBox);
             boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
@@ -90,7 +109,7 @@
             auto& boxGeometry = formattingState.boxGeometry(layoutBox);
             auto logicalBorderBox = lineBox.logicalBorderBoxForAtomicInlineLevelBox(layoutBox, boxGeometry);
             logicalBorderBox.moveBy(lineBoxLogicalTopLeft);
-            formattingState.addLineRun({ lineIndex, LineRun::Type::AtomicInlineLevelBox, layoutBox, logicalBorderBox, lineRun.expansion(), { } });
+            formattingState.addLineRun({ lineIndex, LineRun::Type::AtomicInlineLevelBox, layoutBox, logicalBorderBox, logicalBorderBox, lineRun.expansion(), { } });
 
             auto borderBoxLogicalTopLeft = logicalBorderBox.topLeft();
             // Note that inline boxes are relative to the line and their top position can be negative.
@@ -105,7 +124,7 @@
             inlineBoxBorderBox.moveBy(lineBoxLogicalTopLeft);
             if (lineBox.hasContent()) {
                 // FIXME: It's expected to not have any runs on empty lines. We should reconsider this.
-                formattingState.addLineRun({ lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, { }, { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
+                formattingState.addLineRun({ lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, inlineBoxBorderBox, { }, { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
             }
 
             auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxBorderBox.width()), LayoutUnit::fromFloatCeil(inlineBoxBorderBox.height()) };
@@ -143,7 +162,7 @@
         auto inlineBoxBorderBox = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
         inlineBoxBorderBox.moveBy(lineBoxLogicalTopLeft);
 
-        formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
+        formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
 
         auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxBorderBox.width()), LayoutUnit::fromFloatCeil(inlineBoxBorderBox.height()) };
         auto logicalRect = Rect { LayoutPoint { inlineBoxBorderBox.topLeft() }, inlineBoxSize };

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h	2021-08-29 17:38:29 UTC (rev 281745)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h	2021-08-29 18:57:47 UTC (rev 281746)
@@ -69,7 +69,7 @@
         GenericInlineLevelBox
     };
     struct Expansion;
-    LineRun(size_t lineIndex, Type, const Box&, const InlineRect&, Expansion, std::optional<Text> = std::nullopt, bool hasContent = true, bool isLineSpanning = false);
+    LineRun(size_t lineIndex, Type, const Box&, const InlineRect&, const InlineRect& inkOverflow, Expansion, std::optional<Text> = std::nullopt, bool hasContent = true, bool isLineSpanning = false);
 
     bool isText() const { return m_type == Type::Text; }
     bool isSoftLineBreak() const { return m_type == Type::SoftLineBreak; }
@@ -88,6 +88,7 @@
     bool isLineSpanning() const { return m_isLineSpanning; }
 
     const InlineRect& logicalRect() const { return m_logicalRect; }
+    const InlineRect& inkOverflow() const { return m_inkOverflow; }
 
     InlineLayoutUnit logicalTop() const { return logicalRect().top(); }
     InlineLayoutUnit logicalBottom() const { return logicalRect().bottom(); }
@@ -115,6 +116,7 @@
     const Type m_type;
     WeakPtr<const Layout::Box> m_layoutBox;
     InlineRect m_logicalRect;
+    InlineRect m_inkOverflow;
     bool m_hasContent { true };
     // FIXME: This is temporary until after iterators can skip over line spanning/root inline boxes.
     bool m_isLineSpanning { false };
@@ -122,11 +124,12 @@
     std::optional<Text> m_text;
 };
 
-inline LineRun::LineRun(size_t lineIndex, Type type, const Layout::Box& layoutBox, const InlineRect& logicalRect, Expansion expansion, std::optional<Text> text, bool hasContent, bool isLineSpanning)
+inline LineRun::LineRun(size_t lineIndex, Type type, const Layout::Box& layoutBox, const InlineRect& logicalRect, const InlineRect& inkOverflow, Expansion expansion, std::optional<Text> text, bool hasContent, bool isLineSpanning)
     : m_lineIndex(lineIndex)
     , m_type(type)
     , m_layoutBox(makeWeakPtr(layoutBox))
     , m_logicalRect(logicalRect)
+    , m_inkOverflow(inkOverflow)
     , m_hasContent(hasContent)
     , m_isLineSpanning(isLineSpanning)
     , m_expansion(expansion)

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (281745 => 281746)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2021-08-29 17:38:29 UTC (rev 281745)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2021-08-29 18:57:47 UTC (rev 281746)
@@ -258,10 +258,13 @@
         // Inline boxes are relative to the line box while final runs need to be relative to the parent box
         // FIXME: Shouldn't we just leave them be relative to the line box?
         auto runRect = FloatRect { lineRun.logicalRect() };
+        auto inkOverflow = FloatRect { lineRun.inkOverflow() };
         auto& geometry = m_layoutState.geometryForBox(layoutBox);
         runRect.setSize({ geometry.borderBoxWidth(), geometry.borderBoxHeight() });
-        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition)
+        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
             runRect.setY(roundToInt(runRect.y()));
+            inkOverflow.setY(roundToInt(inkOverflow.y()));
+        }
         // FIXME: Add support for non-text ink overflow.
         // FIXME: Add support for cases when the run is after ellipsis.
         if (lineRun.isInlineBox()) {
@@ -273,10 +276,10 @@
             inlineContent.nonRootInlineBoxes.append({ lineIndex, layoutBox, lineRunRect, hasScrollableContent() });
             if (!lineRun.isLineSpanning()) {
                 // FIXME: Run iterators with (text)runs spanning over multiple lines expect no "in-between" runs (e.g. line spanning or root inline boxes).
-                inlineContent.runs.append({ lineIndex, layoutBox, runRect, runRect, { }, { } });
+                inlineContent.runs.append({ lineIndex, layoutBox, runRect, inkOverflow, { }, { } });
             }
         } else
-            inlineContent.runs.append({ lineIndex, layoutBox, runRect, runRect, { }, { } });
+            inlineContent.runs.append({ lineIndex, layoutBox, runRect, inkOverflow, { }, { } });
     };
 
     auto createDisplayTextRunForRange = [&](auto& lineRun, auto startOffset, auto endOffset) {
@@ -285,8 +288,11 @@
         auto lineIndex = lineRun.lineIndex();
         auto& lineBoxLogicalRect = lines[lineIndex].lineBoxLogicalRect();
         auto runRect = FloatRect { lineRun.logicalRect() };
-        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition)
+        auto inkOverflow = FloatRect { lineRun.inkOverflow() };
+        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
             runRect.setY(roundToInt(runRect.y()));
+            inkOverflow.setY(roundToInt(inkOverflow.y()));
+        }
 
         auto& style = layoutBox.style();
         auto text = lineRun.text();
@@ -314,24 +320,11 @@
             return String();
         };
 
-        auto computedInkOverflow = [&] (auto runRect) {
-            auto inkOverflow = runRect;
-            auto initialContaingBlockSize = m_layoutState.viewportSize();
-            auto strokeOverflow = std::ceil(style.computedStrokeWidth(ceiledIntSize(initialContaingBlockSize)));
-            inkOverflow.inflate(strokeOverflow);
-            auto letterSpacing = style.fontCascade().letterSpacing();
-            if (letterSpacing < 0) {
-                // Last letter's negative spacing shrinks logical rect. Push it to ink overflow.
-                inkOverflow.expand(-letterSpacing, { });
-            }
-            return inkOverflow;
-        };
         RELEASE_ASSERT(startOffset >= text->start() && startOffset < text->end());
         RELEASE_ASSERT(endOffset > text->start() && endOffset <= text->end());
         auto textContent = Run::TextContent { startOffset, endOffset - startOffset, text->content(), adjustedContentToRender(), text->needsHyphen() };
         auto expansion = Run::Expansion { lineRun.expansion().behavior, lineRun.expansion().horizontalExpansion };
-        auto displayRun = Run { lineIndex, layoutBox, runRect, computedInkOverflow(runRect), expansion, textContent };
-        inlineContent.runs.append(displayRun);
+        inlineContent.runs.append({ lineIndex, layoutBox, runRect, inkOverflow, expansion, textContent });
     };
 
     inlineContent.runs.reserveInitialCapacity(lineRuns.size());
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to