Title: [281680] trunk/Source/WebCore
Revision
281680
Author
[email protected]
Date
2021-08-26 20:08:57 -0700 (Thu, 26 Aug 2021)

Log Message

[LFC][Integration] Use the line runs to check for legacy integral positioning
https://bugs.webkit.org/show_bug.cgi?id=228069
<rdar://problem/81087857>

Reviewed by Antti Koivisto.

Now that the line runs list has all the inline boxes (including spanning inline boxes), we
can use this list to check for legacy integral positioning and not directly iterating the LineBox's non-rootinlinebox list.
While this may be a bit more expensive, the legacy positioning is temporary and will be removed shortly.

This is in preparation for keeping the inline box structure private to the layout code.

* layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
(WebCore::LayoutIntegration::InlineContentBuilder::build const):
(WebCore::LayoutIntegration::InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns const):
* layout/integration/LayoutIntegrationInlineContentBuilder.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (281679 => 281680)


--- trunk/Source/WebCore/ChangeLog	2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/ChangeLog	2021-08-27 03:08:57 UTC (rev 281680)
@@ -1,5 +1,24 @@
 2021-08-26  Alan Bujtas  <[email protected]>
 
+        [LFC][Integration] Use the line runs to check for legacy integral positioning
+        https://bugs.webkit.org/show_bug.cgi?id=228069
+        <rdar://problem/81087857>
+
+        Reviewed by Antti Koivisto.
+
+        Now that the line runs list has all the inline boxes (including spanning inline boxes), we
+        can use this list to check for legacy integral positioning and not directly iterating the LineBox's non-rootinlinebox list.
+        While this may be a bit more expensive, the legacy positioning is temporary and will be removed shortly.
+
+        This is in preparation for keeping the inline box structure private to the layout code.
+
+        * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+        (WebCore::LayoutIntegration::InlineContentBuilder::build const):
+        (WebCore::LayoutIntegration::InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns const):
+        * layout/integration/LayoutIntegrationInlineContentBuilder.h:
+
+2021-08-26  Alan Bujtas  <[email protected]>
+
         REGRESSION(r275754): Using MarkOnlyThis to make the preferred width dirty introduces unexpected state
         https://bugs.webkit.org/show_bug.cgi?id=229586
         <rdar://82141454>

Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp (281679 => 281680)


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp	2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp	2021-08-27 03:08:57 UTC (rev 281680)
@@ -622,7 +622,7 @@
                 if (layoutBox.isLineBreakBox()) {
                     // Only hard linebreaks have associated layout boxes.
                     auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
-                    formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreak, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
+                    formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreakBox, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
 
                     auto& boxGeometry = formattingState.boxGeometry(layoutBox);
                     lineBreakBoxRect.moveBy(lineBoxLogicalRect.topLeft());
@@ -629,7 +629,7 @@
                     boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
                     boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
                 } else 
-                    formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreak, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
+                    formattingState.addLineRun({ lineIndex, LineRun::Type::SoftLineBreak, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
                 continue;
             }
             if (lineRun.isBox()) {
@@ -650,7 +650,7 @@
             if (lineRun.isInlineBoxStart()) {
                 auto& boxGeometry = formattingState.boxGeometry(layoutBox);
                 auto inlineBoxLogicalRect = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
-                formattingState.addLineRun({ lineIndex, LineRun::Type::InlineBox, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
+                formattingState.addLineRun({ lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
                 inlineBoxStartSet.add(&layoutBox);
                 continue;
             }
@@ -685,7 +685,7 @@
                 continue;
             }
             // Middle or end of the inline box. Let's stretch the box as needed.
-            formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::InlineBox, layoutBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
+            formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
 
             auto enclosingBorderBoxRect = BoxGeometry::borderBoxRect(boxGeometry);
             enclosingBorderBoxRect.expandToContain(logicalRect);

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


--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h	2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h	2021-08-27 03:08:57 UTC (rev 281680)
@@ -61,9 +61,10 @@
 
     enum class Type {
         Text,
-        LineBreak,
+        SoftLineBreak,
+        LineBreakBox,
         AtomicInlineLevelBox,
-        InlineBox,
+        NonRootInlineBox,
         RootInlineBox,
         GenericInlineLevelBox
     };
@@ -71,10 +72,16 @@
     LineRun(size_t lineIndex, Type, const Box&, const InlineRect&, Expansion, std::optional<Text> = std::nullopt, bool hasContent = true, bool isLineSpanning = false);
 
     bool isText() const { return m_type == Type::Text; }
-    bool isLineBreak() const { return m_type == Type::LineBreak; }
+    bool isSoftLineBreak() const { return m_type == Type::SoftLineBreak; }
+    bool isLineBreakBox() const { return m_type == Type::LineBreakBox; }
+    bool isLineBreak() const { return isSoftLineBreak() || isLineBreakBox(); }
     bool isAtomicInlineLevelBox() const { return m_type == Type::AtomicInlineLevelBox; }
-    bool isInlineBox() const { return m_type == Type::InlineBox || isRootInlineBox(); }
+    bool isInlineBox() const { return isNonRootInlineBox() || isRootInlineBox(); }
+    bool isNonRootInlineBox() const { return m_type == Type::NonRootInlineBox; }
     bool isRootInlineBox() const { return m_type == Type::RootInlineBox; }
+    bool isGenericInlineLevelBox() const { return m_type == Type::GenericInlineLevelBox; }
+    bool isInlineLevelBox() const { return isAtomicInlineLevelBox() || isLineBreakBox() || isInlineBox() || isGenericInlineLevelBox(); }
+    bool isNonRootInlineLevelBox() const { return isInlineLevelBox() && !isRootInlineBox(); }
     Type type() const { return m_type; }
 
     bool hasContent() const { return m_hasContent; }

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (281679 => 281680)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp	2021-08-27 03:08:57 UTC (rev 281680)
@@ -164,53 +164,71 @@
 
 void InlineContentBuilder::build(const Layout::InlineFormattingState& inlineFormattingState, InlineContent& inlineContent) const
 {
-    auto lineLevelVisualAdjustmentsForRuns = computeLineLevelVisualAdjustmentsForRuns(inlineFormattingState);
+    auto lineLevelVisualAdjustmentsForRuns = computeLineLevelVisualAdjustmentsForRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns());
     createDisplayLineRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns(), inlineContent, lineLevelVisualAdjustmentsForRuns);
     createDisplayLines(inlineFormattingState.lines(), inlineContent, lineLevelVisualAdjustmentsForRuns);
 }
 
-InlineContentBuilder::LineLevelVisualAdjustmentsForRunsList InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineFormattingState& inlineFormattingState) const
+InlineContentBuilder::LineLevelVisualAdjustmentsForRunsList InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineLines& lines, const Layout::InlineLineRuns& lineRuns) const
 {
-    auto& lines = inlineFormattingState.lines();
+    auto lineLevelVisualAdjustmentsForRuns = LineLevelVisualAdjustmentsForRunsList { lines.size() };
     auto& rootStyle = m_layoutState.root().style();
-    auto shouldCheckHorizontalOverflowForContentReplacement = rootStyle.overflowX() == Overflow::Hidden && rootStyle.textOverflow() != TextOverflow::Clip;
 
-    auto lineLevelVisualAdjustmentsForRuns = LineLevelVisualAdjustmentsForRunsList { lines.size() };
-    for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) {
-        auto lineNeedsLegacyIntegralVerticalPosition = [&] {
+    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).
-            auto& nonRootInlineLevelBoxList = inlineFormattingState.lineBoxes()[lineIndex].nonRootInlineLevelBoxes();
-            if (nonRootInlineLevelBoxList.isEmpty()) {
-                // This is text content only with root inline box.
+            // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
+            auto contentPreventsIntegralSnapping = lineRun.isAtomicInlineLevelBox() || (lineRun.isLineBreakBox() && !m_layoutState.inStandardsMode());
+            if (contentPreventsIntegralSnapping)
                 return true;
-            }
-            for (auto& inlineLevelBox : nonRootInlineLevelBoxList) {
-                // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
-                auto contentPreventsIntegralSnapping = inlineLevelBox.isAtomicInlineLevelBox() || (inlineLevelBox.isLineBreakBox() && !m_layoutState.inStandardsMode());
-                if (contentPreventsIntegralSnapping)
-                    return false;
 
-                auto& inlineLevelBoxStyle = inlineLevelBox.style();
-                auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineLevelBoxStyle.lineHeight() || inlineLevelBoxStyle.verticalAlign() != VerticalAlign::Baseline;
-                if (stylePreventsIntegralSnapping)
-                    return false;
+            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);
-                if (fontPreventsIntegralSnapping)
-                    return false;
-            }
-            return true;
+            auto& rootFontMetrics = rootStyle.fontCascade().fontMetrics();
+            auto& inlineLevelBoxFontMetrics = inlineLevelBoxStyle.fontCascade().fontMetrics();
+            auto fontPreventsIntegralSnapping = !rootFontMetrics.hasIdenticalAscentDescentAndLineGap(inlineLevelBoxFontMetrics);
+            return fontPreventsIntegralSnapping;
         };
-        lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition = lineNeedsLegacyIntegralVerticalPosition();
-        if (shouldCheckHorizontalOverflowForContentReplacement) {
-            auto& line = lines[lineIndex];
-            auto lineBoxLogicalWidth = line.lineBoxLogicalRect().width();
-            auto overflowWidth = lineOverflowWidth(m_blockFlow, lineBoxLogicalWidth, line.contentLogicalWidth());
-            lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement = overflowWidth > lineBoxLogicalWidth;
-        }
+        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;
 }
 

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h (281679 => 281680)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h	2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h	2021-08-27 03:08:57 UTC (rev 281680)
@@ -49,7 +49,7 @@
 private:
     using LineLevelVisualAdjustmentsForRunsList = Vector<LineLevelVisualAdjustmentsForRuns>;
 
-    LineLevelVisualAdjustmentsForRunsList computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineFormattingState&) 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;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to