Title: [281750] trunk/Source/WebCore
Revision
281750
Author
[email protected]
Date
2021-08-29 19:19:29 -0700 (Sun, 29 Aug 2021)

Log Message

[LFC][IFC] Move "line needs integral snapping" computing to IFC from the integration layer
https://bugs.webkit.org/show_bug.cgi?id=229654

Reviewed by Antti Koivisto.

This is in preparation for merging the integration layer runs with IFC's display runs.
This also save a loop over the runs to compute the "line needs integration position" bit.

* layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
(WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent):
* layout/formattingContexts/inline/InlineLineGeometry.h:
(WebCore::Layout::LineGeometry::needsIntegralPosition const):
(WebCore::Layout::LineGeometry::setNeedsIntegralPosition):
* layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
(WebCore::LayoutIntegration::InlineContentBuilder::build const):
(WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):
(WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLines const):
(WebCore::LayoutIntegration::InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns const): Deleted.
* layout/integration/LayoutIntegrationInlineContentBuilder.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (281749 => 281750)


--- trunk/Source/WebCore/ChangeLog	2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/ChangeLog	2021-08-30 02:19:29 UTC (rev 281750)
@@ -1,5 +1,27 @@
 2021-08-29  Alan Bujtas  <[email protected]>
 
+        [LFC][IFC] Move "line needs integral snapping" computing to IFC from the integration layer
+        https://bugs.webkit.org/show_bug.cgi?id=229654
+
+        Reviewed by Antti Koivisto.
+
+        This is in preparation for merging the integration layer runs with IFC's display runs.
+        This also save a loop over the runs to compute the "line needs integration position" bit.
+
+        * layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
+        (WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent):
+        * layout/formattingContexts/inline/InlineLineGeometry.h:
+        (WebCore::Layout::LineGeometry::needsIntegralPosition const):
+        (WebCore::Layout::LineGeometry::setNeedsIntegralPosition):
+        * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+        (WebCore::LayoutIntegration::InlineContentBuilder::build const):
+        (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):
+        (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLines const):
+        (WebCore::LayoutIntegration::InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns const): Deleted.
+        * layout/integration/LayoutIntegrationInlineContentBuilder.h:
+
+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
 

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp	2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp	2021-08-30 02:19:29 UTC (rev 281750)
@@ -61,6 +61,10 @@
 void InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent(const LineBuilder::LineContent& lineContent, const LineBox& lineBox, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex)
 {
     auto& formattingState = this->formattingState();
+    // Legacy inline tree integral rounds the vertical position for certain content (see LegacyInlineFlowBox::placeBoxesInBlockDirection and ::addToLine).
+    // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
+    auto lineNeedIntegralPosition = true;
+    auto& rootStyle = root().style();
     // Create the inline runs on the current line. This is mostly text and atomic inline runs.
     for (auto& lineRun : lineContent.runs) {
         auto& layoutBox = lineRun.layoutBox();
@@ -102,6 +106,8 @@
             auto& boxGeometry = formattingState.boxGeometry(layoutBox);
             boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
             boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
+            if (!formattingState.layoutState().inStandardsMode())
+                lineNeedIntegralPosition = false;
             break;
         }
         case InlineItem::Type::Box: {
@@ -115,6 +121,7 @@
             // Note that inline boxes are relative to the line and their top position can be negative.
             // 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;
             break;
         }
         case InlineItem::Type::InlineBoxStart: {
@@ -134,6 +141,14 @@
             boxGeometry.setContentBoxHeight(contentBoxHeight);
             auto contentBoxWidth = logicalRect.width() - (boxGeometry.horizontalBorder() + boxGeometry.horizontalPadding().value_or(0_lu));
             boxGeometry.setContentBoxWidth(contentBoxWidth);
+
+            if (lineNeedIntegralPosition) {
+                auto& inlineBoxStyle = layoutBox.style();
+                auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineBoxStyle.lineHeight() || inlineBoxStyle.verticalAlign() != VerticalAlign::Baseline;
+                auto fontPreventsIntegralSnapping = !rootStyle.fontCascade().fontMetrics().hasIdenticalAscentDescentAndLineGap(inlineBoxStyle.fontCascade().fontMetrics());
+                if (stylePreventsIntegralSnapping || fontPreventsIntegralSnapping)
+                    lineNeedIntegralPosition = false;
+            }
             break;
         }
         default:
@@ -141,6 +156,8 @@
             break;
         }
     }
+    // FIXME: This is temporary. Remove when legacy line layout's integral snapping is removed.
+    formattingState.lines().last().setNeedsIntegralPosition(lineNeedIntegralPosition);
 }
 
 void InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineSpanningInlineBoxes(const LineBox& lineBox, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex, size_t lineSpanningInlineBoxIndex)
@@ -152,7 +169,9 @@
         return;
     }
 
+    auto& rootStyle = root().style();
     auto& formattingState = this->formattingState();
+    auto lineNeedIntegralPosition = formattingState.lines().last().needsIntegralPosition();
     for (auto& inlineLevelBox : lineBox.nonRootInlineLevelBoxes()) {
         if (!inlineLevelBox.isLineSpanningInlineBox())
             continue;
@@ -173,7 +192,17 @@
 
         boxGeometry.setContentBoxHeight(enclosingBorderBoxRect.height() - (boxGeometry.verticalBorder() + boxGeometry.verticalPadding().value_or(0_lu)));
         boxGeometry.setContentBoxWidth(enclosingBorderBoxRect.width() - (boxGeometry.horizontalBorder() + boxGeometry.horizontalPadding().value_or(0_lu)));
+
+        if (lineNeedIntegralPosition) {
+            auto& inlineBoxStyle = layoutBox.style();
+            auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineBoxStyle.lineHeight() || inlineBoxStyle.verticalAlign() != VerticalAlign::Baseline;
+            auto fontPreventsIntegralSnapping = !rootStyle.fontCascade().fontMetrics().hasIdenticalAscentDescentAndLineGap(inlineBoxStyle.fontCascade().fontMetrics());
+            if (stylePreventsIntegralSnapping || fontPreventsIntegralSnapping)
+                lineNeedIntegralPosition = false;
+        }
     }
+    // FIXME: This is temporary. Remove when legacy line layout's integral snapping is removed.
+    formattingState.lines().last().setNeedsIntegralPosition(lineNeedIntegralPosition);
 }
 
 }

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h (281749 => 281750)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h	2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h	2021-08-30 02:19:29 UTC (rev 281750)
@@ -51,7 +51,10 @@
     InlineLayoutUnit contentLogicalLeft() const { return m_contentLogicalLeft; }
     InlineLayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
 
+    bool needsIntegralPosition() const { return m_needsIntegralPosition; }
+
     void moveVertically(InlineLayoutUnit offset) { m_lineBoxLogicalRect.moveVertically(offset); }
+    void setNeedsIntegralPosition(bool needsIntegralPosition) { m_needsIntegralPosition = needsIntegralPosition; }
 
 private:
     // This is line box geometry (see https://www.w3.org/TR/css-inline-3/#line-box).
@@ -63,6 +66,9 @@
     InlineLayoutUnit m_aligmentBaseline { 0 };
     InlineLayoutUnit m_contentLogicalLeft { 0 };
     InlineLayoutUnit m_contentLogicalWidth { 0 };
+    // FIXME: This is just matching legacy line layout integral snapping.
+    // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
+    bool m_needsIntegralPosition { true };
 };
 
 inline LineGeometry::LineGeometry(const InlineRect& lineBoxLogicalRect, EnclosingTopAndBottom enclosingTopAndBottom, InlineLayoutUnit aligmentBaseline, InlineLayoutUnit contentLogicalLeft, InlineLayoutUnit contentLogicalWidth)

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (281749 => 281750)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2021-08-30 02:19:29 UTC (rev 281750)
@@ -44,12 +44,6 @@
 
 #define PROCESS_BIDI_CONTENT 0
 
-struct LineLevelVisualAdjustmentsForRuns {
-    bool needsIntegralPosition { false };
-    // It's only 'text-overflow: ellipsis' for now.
-    bool needsTrailingContentReplacement { false };
-};
-
 inline Layout::LineGeometry::EnclosingTopAndBottom operator+(const Layout::LineGeometry::EnclosingTopAndBottom enclosingTopAndBottom, float offset)
 {
     return { enclosingTopAndBottom.top + offset, enclosingTopAndBottom.bottom + offset };
@@ -164,76 +158,12 @@
 
 void InlineContentBuilder::build(const Layout::InlineFormattingState& inlineFormattingState, InlineContent& inlineContent) const
 {
-    auto lineLevelVisualAdjustmentsForRuns = computeLineLevelVisualAdjustmentsForRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns());
-    createDisplayLineRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns(), inlineContent, lineLevelVisualAdjustmentsForRuns);
-    createDisplayLines(inlineFormattingState.lines(), inlineContent, lineLevelVisualAdjustmentsForRuns);
+    createDisplayLineRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns(), inlineContent);
+    createDisplayLines(inlineFormattingState.lines(), inlineContent);
 }
 
-InlineContentBuilder::LineLevelVisualAdjustmentsForRunsList InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineLines& lines, const Layout::InlineLineRuns& lineRuns) const
+void InlineContentBuilder::createDisplayLineRuns(const Layout::InlineLines& lines, const Layout::InlineLineRuns& lineRuns, InlineContent& inlineContent) const
 {
-    auto lineLevelVisualAdjustmentsForRuns = LineLevelVisualAdjustmentsForRunsList { lines.size() };
-    auto& rootStyle = m_layoutState.root().style();
-
-    auto inlineLevelBoxPreventsIntegralPosition = std::optional<bool> { };
-    size_t lineIndexToCheck = 0;
-    for (auto& lineRun : lineRuns) {
-        auto lineIndex = lineRun.lineIndex();
-        auto& layoutBox = lineRun.layoutBox();
-
-        if (lineIndexToCheck != lineIndex) {
-            auto lineNeedsIntegralPositioning = [&] {
-                if (!inlineLevelBoxPreventsIntegralPosition.has_value()) {
-                    // This line does not have any non-root inline boxes.
-                    // Lines like this with root inline box only force integral positioning.
-                    return true;
-                }
-                return !*inlineLevelBoxPreventsIntegralPosition;
-            };
-            lineLevelVisualAdjustmentsForRuns[lineIndexToCheck].needsIntegralPosition = lineNeedsIntegralPositioning();
-            lineIndexToCheck = lineIndex;
-            inlineLevelBoxPreventsIntegralPosition = { };
-        }
-
-        if (!lineRun.isNonRootInlineLevelBox() || (inlineLevelBoxPreventsIntegralPosition.has_value() && *inlineLevelBoxPreventsIntegralPosition))
-            continue;
-
-        auto inlineLevelBoxPreventsLegacyIntegralVerticalPosition = [&] {
-            ASSERT(lineRun.isNonRootInlineLevelBox());
-            // Legacy inline tree integral rounds the vertical position for certain content (see LegacyInlineFlowBox::placeBoxesInBlockDirection and ::addToLine).
-            // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
-            auto contentPreventsIntegralSnapping = lineRun.isAtomicInlineLevelBox() || (lineRun.isLineBreakBox() && !m_layoutState.inStandardsMode());
-            if (contentPreventsIntegralSnapping)
-                return true;
-
-            auto& inlineLevelBoxStyle = layoutBox.style();
-            auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineLevelBoxStyle.lineHeight() || inlineLevelBoxStyle.verticalAlign() != VerticalAlign::Baseline;
-            if (stylePreventsIntegralSnapping)
-                return true;
-
-            auto& rootFontMetrics = rootStyle.fontCascade().fontMetrics();
-            auto& inlineLevelBoxFontMetrics = inlineLevelBoxStyle.fontCascade().fontMetrics();
-            auto fontPreventsIntegralSnapping = !rootFontMetrics.hasIdenticalAscentDescentAndLineGap(inlineLevelBoxFontMetrics);
-            return fontPreventsIntegralSnapping;
-        };
-        inlineLevelBoxPreventsIntegralPosition = inlineLevelBoxPreventsLegacyIntegralVerticalPosition();
-    }
-    lineLevelVisualAdjustmentsForRuns[lineIndexToCheck].needsIntegralPosition = !inlineLevelBoxPreventsIntegralPosition.has_value() || !*inlineLevelBoxPreventsIntegralPosition;
-
-    auto shouldCheckHorizontalOverflowForContentReplacement = rootStyle.overflowX() == Overflow::Hidden && rootStyle.textOverflow() != TextOverflow::Clip;
-    if (!shouldCheckHorizontalOverflowForContentReplacement)
-        return lineLevelVisualAdjustmentsForRuns;
-
-    for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) {
-        auto& line = lines[lineIndex];
-        auto lineBoxLogicalWidth = line.lineBoxLogicalRect().width();
-        auto overflowWidth = lineOverflowWidth(m_blockFlow, lineBoxLogicalWidth, line.contentLogicalWidth());
-        lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement = overflowWidth > lineBoxLogicalWidth;
-    }
-    return lineLevelVisualAdjustmentsForRuns;
-}
-
-void InlineContentBuilder::createDisplayLineRuns(const Layout::InlineLines& lines, const Layout::InlineLineRuns& lineRuns, InlineContent& inlineContent, const LineLevelVisualAdjustmentsForRunsList& lineLevelVisualAdjustmentsForRuns) const
-{
     if (lineRuns.isEmpty())
         return;
 
@@ -261,7 +191,7 @@
         auto inkOverflow = FloatRect { lineRun.inkOverflow() };
         auto& geometry = m_layoutState.geometryForBox(layoutBox);
         runRect.setSize({ geometry.borderBoxWidth(), geometry.borderBoxHeight() });
-        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
+        if (lines[lineIndex].needsIntegralPosition()) {
             runRect.setY(roundToInt(runRect.y()));
             inkOverflow.setY(roundToInt(inkOverflow.y()));
         }
@@ -286,10 +216,9 @@
         RELEASE_ASSERT(startOffset < endOffset);
         auto& layoutBox = lineRun.layoutBox();
         auto lineIndex = lineRun.lineIndex();
-        auto& lineBoxLogicalRect = lines[lineIndex].lineBoxLogicalRect();
         auto runRect = FloatRect { lineRun.logicalRect() };
         auto inkOverflow = FloatRect { lineRun.inkOverflow() };
-        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
+        if (lines[lineIndex].needsIntegralPosition()) {
             runRect.setY(roundToInt(runRect.y()));
             inkOverflow.setY(roundToInt(inkOverflow.y()));
         }
@@ -300,23 +229,6 @@
             auto originalContent = text->content().substring(text->start(), text->length());
             if (text->needsHyphen())
                 return makeString(originalContent, style.hyphenString());
-            if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement) {
-                // Currently it's ellipsis replacement only, but adding support for "text-overflow: string" should be relatively simple.
-                if (hasAdjustedTrailingLineList[lineIndex]) {
-                    // This line already has adjusted trailing. Any runs after the ellipsis should render blank.
-                    return emptyString();
-                }
-                auto runLogicalRect = lineRun.logicalRect();
-                auto ellipsisWidth = style.fontCascade().width(WebCore::TextRun { &horizontalEllipsis });
-                if (runLogicalRect.right() + ellipsisWidth > lineBoxLogicalRect.right()) {
-                    // The next run with ellipsis would surely overflow. So let's just add it to this run even if
-                    // it makes the run wider than it originally was.
-                    hasAdjustedTrailingLineList[lineIndex] = true;
-                    float resultWidth = 0;
-                    auto maxWidth = lineBoxLogicalRect.width() - runLogicalRect.left();
-                    return StringTruncator::rightTruncate(originalContent, maxWidth, style.fontCascade(), resultWidth, true);
-                }
-            }
             return String();
         };
 
@@ -336,7 +248,7 @@
     }
 }
 
-void InlineContentBuilder::createDisplayLines(const Layout::InlineLines& lines, InlineContent& inlineContent, const LineLevelVisualAdjustmentsForRunsList& lineLevelVisualAdjustmentsForRuns) const
+void InlineContentBuilder::createDisplayLines(const Layout::InlineLines& lines, InlineContent& inlineContent) const
 {
     auto& runs = inlineContent.runs;
     auto& nonRootInlineBoxes = inlineContent.nonRootInlineBoxes;
@@ -381,7 +293,7 @@
         auto adjustedLineBoxRect = FloatRect { lineBoxLogicalRect };
         // Final enclosing top and bottom values are in the same coordinate space as the line itself.
         auto enclosingTopAndBottom = line.enclosingTopAndBottom() + lineBoxLogicalRect.top();
-        if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
+        if (line.needsIntegralPosition()) {
             adjustedLineBoxRect.setY(roundToInt(adjustedLineBoxRect.y()));
             enclosingTopAndBottom.top = roundToInt(enclosingTopAndBottom.top);
             enclosingTopAndBottom.bottom = roundToInt(enclosingTopAndBottom.bottom);

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h (281749 => 281750)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h	2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h	2021-08-30 02:19:29 UTC (rev 281750)
@@ -38,7 +38,6 @@
 
 class BoxTree;
 struct InlineContent;
-struct LineLevelVisualAdjustmentsForRuns;
 
 class InlineContentBuilder {
 public:
@@ -47,12 +46,9 @@
     void build(const Layout::InlineFormattingState&, InlineContent&) const;
 
 private:
-    using LineLevelVisualAdjustmentsForRunsList = Vector<LineLevelVisualAdjustmentsForRuns>;
+    void createDisplayLineRuns(const Layout::InlineLines&, const Layout::InlineLineRuns&, InlineContent&) const;
+    void createDisplayLines(const Layout::InlineLines&, InlineContent&) const;
 
-    LineLevelVisualAdjustmentsForRunsList computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineLines&, const Layout::InlineLineRuns&) const;
-    void createDisplayLineRuns(const Layout::InlineLines&, const Layout::InlineLineRuns&, InlineContent&, const LineLevelVisualAdjustmentsForRunsList&) const;
-    void createDisplayLines(const Layout::InlineLines&, InlineContent&, const LineLevelVisualAdjustmentsForRunsList&) const;
-
     const Layout::LayoutState& m_layoutState;
     const RenderBlockFlow& m_blockFlow;
     const BoxTree& m_boxTree;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to