Title: [269424] trunk/Source/WebCore
Revision
269424
Author
[email protected]
Date
2020-11-05 04:23:37 -0800 (Thu, 05 Nov 2020)

Log Message

[LFC][Integration] Let's compute display lines visual alignments first before the runs
https://bugs.webkit.org/show_bug.cgi?id=218551

Reviewed by Antti Koivisto.

In this patch we pre-compute visual adjustement properties that we later use during run construction
(e.g. whether the runs on the line need vertical snapping).
This patch is also in preparation for adding support for "text-overflow: ellipsis". The pre-computed
LineLevelVisualAdjustmentsForRuns.needsTrailingContentReplacement will drive the content truncation logic for the ellipsis.

* layout/integration/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::lineOverflowWidth):
(WebCore::LayoutIntegration::LineLayout::constructContent):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (269423 => 269424)


--- trunk/Source/WebCore/ChangeLog	2020-11-05 12:17:19 UTC (rev 269423)
+++ trunk/Source/WebCore/ChangeLog	2020-11-05 12:23:37 UTC (rev 269424)
@@ -1,3 +1,19 @@
+2020-11-05  Zalan Bujtas  <[email protected]>
+
+        [LFC][Integration] Let's compute display lines visual alignments first before the runs
+        https://bugs.webkit.org/show_bug.cgi?id=218551
+
+        Reviewed by Antti Koivisto.
+
+        In this patch we pre-compute visual adjustement properties that we later use during run construction
+        (e.g. whether the runs on the line need vertical snapping).
+        This patch is also in preparation for adding support for "text-overflow: ellipsis". The pre-computed
+        LineLevelVisualAdjustmentsForRuns.needsTrailingContentReplacement will drive the content truncation logic for the ellipsis.
+
+        * layout/integration/LayoutIntegrationLineLayout.cpp:
+        (WebCore::LayoutIntegration::lineOverflowWidth):
+        (WebCore::LayoutIntegration::LineLayout::constructContent):
+
 2020-11-05  Yusuke Suzuki  <[email protected]>
 
         Unreviewed, build fix for ARM64E part 2

Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp (269423 => 269424)


--- trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2020-11-05 12:17:19 UTC (rev 269423)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp	2020-11-05 12:23:37 UTC (rev 269424)
@@ -139,35 +139,63 @@
     constructContent();
 }
 
+inline static float lineOverflowWidth(const RenderBlockFlow& flow, InlineLayoutUnit lineLogicalWidth, InlineLayoutUnit lineBoxLogicalWidth)
+{
+    // FIXME: It's the copy of the lets-adjust-overflow-for-the-caret behavior from ComplexLineLayout::addOverflowFromInlineChildren.
+    auto endPadding = flow.hasOverflowClip() ? flow.paddingEnd() : 0_lu;
+    if (!endPadding)
+        endPadding = flow.endPaddingWidthForCaret();
+    if (flow.hasOverflowClip() && !endPadding && flow.element() && flow.element()->isRootEditableElement())
+        endPadding = 1;
+    lineBoxLogicalWidth += endPadding;
+    return std::max(lineLogicalWidth, lineBoxLogicalWidth);
+}
+
 void LineLayout::constructContent()
 {
     auto& displayInlineContent = ensureInlineContent();
+    auto& lines = m_inlineFormattingState.lines();
 
-    auto lineNeedsLegacyIntegralVerticalPosition = [&](size_t lineIndex) {
-        RELEASE_ASSERT(m_inlineFormattingState.lineBoxes().size() > lineIndex);
-        // InlineTree rounds y position to integral value for certain content (see InlineFlowBox::placeBoxesInBlockDirection).
-        auto inlineLevelBoxList = m_inlineFormattingState.lineBoxes()[lineIndex].inlineLevelBoxList();
-        if (inlineLevelBoxList.size() == 1) {
-            // This is text content only with root inline box.
-            return true;
-        }
-        // Text + <br> (or just <br> or text<span></span><br>) behaves like text.
-        for (auto& inlineLevelBox : inlineLevelBoxList) {
-            if (inlineLevelBox->isAtomicInlineLevelBox()) {
-                // Content like text<img> prevents legacy snapping.
-                return false;
+    struct LineLevelVisualAdjustmentsForRuns {
+        bool needsIntegralPosition { false };
+        // It's only 'text-overflow: ellipsis' for now.
+        bool needsTrailingContentReplacement { false };
+    };
+    Vector<LineLevelVisualAdjustmentsForRuns> lineLevelVisualAdjustmentsForRuns(lines.size());
+
+    auto computeLineLevelVisualAdjustmentsForRuns = [&] {
+        auto& rootStyle = rootLayoutBox().style();
+        auto shouldCheckHorizontalOverflowForContentReplacement = rootStyle.overflowX() == Overflow::Hidden && rootStyle.textOverflow() != TextOverflow::Clip;
+
+        for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) {
+            auto lineNeedsLegacyIntegralVerticalPosition = [&] {
+                // InlineTree rounds y position to integral value for certain content (see InlineFlowBox::placeBoxesInBlockDirection).
+                auto inlineLevelBoxList = m_inlineFormattingState.lineBoxes()[lineIndex].inlineLevelBoxList();
+                if (inlineLevelBoxList.size() == 1) {
+                    // This is text content only with root inline box.
+                    return true;
+                }
+                // Text + <br> (or just <br> or text<span></span><br>) behaves like text.
+                for (auto& inlineLevelBox : inlineLevelBoxList) {
+                    if (inlineLevelBox->isAtomicInlineLevelBox()) {
+                        // Content like text<img> prevents legacy snapping.
+                        return false;
+                    }
+                }
+                return true;
+            };
+            lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition = lineNeedsLegacyIntegralVerticalPosition();
+            if (shouldCheckHorizontalOverflowForContentReplacement) {
+                auto& line = lines[lineIndex];
+                auto overflowWidth = lineOverflowWidth(flow(), line.logicalWidth(), line.lineBoxLogicalRect().width());
+                lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement = overflowWidth > line.logicalWidth();
             }
         }
-        return true;
     };
+    computeLineLevelVisualAdjustmentsForRuns();
 
     auto constructDisplayLineRuns = [&] {
         auto initialContaingBlockSize = m_layoutState.viewportSize();
-        struct LineLegacyVerticalPositionPolicy {
-            size_t lineIndex { 0 };
-            bool needsIntegralPosition { true }; 
-        };
-        auto lineLegacyVerticalPositionPolicy = LineLegacyVerticalPositionPolicy { 0, lineNeedsLegacyIntegralVerticalPosition(0) };
         for (auto& lineRun : m_inlineFormattingState.lineRuns()) {
             auto& layoutBox = lineRun.layoutBox();
             auto computedInkOverflow = [&] (auto runRect) {
@@ -190,11 +218,9 @@
             // 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 lineIndex = lineRun.lineIndex();
-            auto lineBoxLogicalRect = m_inlineFormattingState.lines()[lineIndex].lineBoxLogicalRect();
+            auto lineBoxLogicalRect = lines[lineIndex].lineBoxLogicalRect();
             runRect.moveBy({ lineBoxLogicalRect.left(), lineBoxLogicalRect.top() });
-            if (lineIndex != lineLegacyVerticalPositionPolicy.lineIndex)
-                lineLegacyVerticalPositionPolicy = LineLegacyVerticalPositionPolicy { lineIndex, lineNeedsLegacyIntegralVerticalPosition(lineIndex) };
-            if (lineLegacyVerticalPositionPolicy.needsIntegralPosition)
+            if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition)
                 runRect.setY(roundToInt(runRect.y()));
 
             WTF::Optional<Run::TextContent> textContent;
@@ -220,7 +246,6 @@
     constructDisplayLineRuns();
 
     auto constructDisplayLines = [&] {
-        auto& lines = m_inlineFormattingState.lines();
         auto& lineBoxes = m_inlineFormattingState.lineBoxes();
         auto& runs = displayInlineContent.runs;
         size_t runIndex = 0;
@@ -228,19 +253,9 @@
             auto& line = lines[lineIndex];
             auto lineBoxLogicalRect = line.lineBoxLogicalRect();
             // FIXME: This is where the logical to physical translate should happen.
-            auto overflowWidth = [&] {
-                // FIXME: It's the copy of the lets-adjust-overflow-for-the-caret behavior from ComplexLineLayout::addOverflowFromInlineChildren.
-                auto endPadding = flow().hasOverflowClip() ? flow().paddingEnd() : 0_lu;
-                if (!endPadding)
-                    endPadding = flow().endPaddingWidthForCaret();
-                if (flow().hasOverflowClip() && !endPadding && flow().element() && flow().element()->isRootEditableElement())
-                    endPadding = 1;
-                auto lineBoxLogicalWidth = lineBoxLogicalRect.width() + endPadding;
-                return std::max(line.logicalWidth(), lineBoxLogicalWidth);
-            };
             auto lineBoxLogicalBottom = (lineBoxLogicalRect.top() - line.logicalTop()) + lineBoxLogicalRect.height();
             auto overflowHeight = std::max(line.logicalHeight(), lineBoxLogicalBottom);
-            auto scrollableOverflowRect = FloatRect { line.logicalLeft(), line.logicalTop(), overflowWidth(), overflowHeight };
+            auto scrollableOverflowRect = FloatRect { line.logicalLeft(), line.logicalTop(), lineOverflowWidth(flow(), line.logicalWidth(), lineBoxLogicalRect.width()), overflowHeight };
 
             auto firstRunIndex = runIndex;
             auto lineInkOverflowRect = scrollableOverflowRect;
@@ -264,7 +279,7 @@
                 }
                 return enclosingRect;
             }();
-            if (lineNeedsLegacyIntegralVerticalPosition(lineIndex)) {
+            if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
                 lineRect.setY(roundToInt(lineRect.y()));
                 enclosingLineRect.setY(roundToInt(enclosingLineRect.y()));
             }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to