[LFC][Render tree] Add LFC line layout path to RenderBlockFlow
https://bugs.webkit.org/show_bug.cgi?id=204613

Reviewed by Zalan Bujtas.

Source/WebCore:

Add a basic LFC line layout implementation for RenderBlockFlow.
It can layout lines and do simple painting but doesn't do anything else (like hit testing) yet.

Add a new layoutFormattingContextRenderTreeIntegrationEnabled feature flag, default to false.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/RenderBlockFlowLineLayout.cpp: Added.
(WebCore::Layout::RenderBlockFlowLineLayout::RenderBlockFlowLineLayout):
(WebCore::Layout::RenderBlockFlowLineLayout::canUseFor):
(WebCore::Layout::RenderBlockFlowLineLayout::layout):
(WebCore::Layout::RenderBlockFlowLineLayout::height const):
(WebCore::Layout::RenderBlockFlowLineLayout::paint):
* layout/RenderBlockFlowLineLayout.h: Copied from Source/WebCore/layout/displaytree/DisplayPainter.h.
* layout/displaytree/DisplayPainter.cpp:
(WebCore::Display::Painter::paintInlineFlow):
* layout/displaytree/DisplayPainter.h:
* layout/invalidation/InvalidationState.cpp:
(WebCore::Layout::InvalidationState::markNeedsUpdate):
* layout/layouttree/LayoutTreeBuilder.cpp:
(WebCore::Layout::TreeBuilder::buildLayoutTree):
* layout/layouttree/LayoutTreeBuilder.h:
* page/RuntimeEnabledFeatures.h:
(WebCore::RuntimeEnabledFeatures::setLayoutFormattingContextRenderTreeIntegrationEnabled):
(WebCore::RuntimeEnabledFeatures::layoutFormattingContextRenderTreeIntegrationEnabled const):
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::layoutInlineChildren):
(WebCore::RenderBlockFlow::addOverflowFromInlineChildren):
(WebCore::RenderBlockFlow::paintInlineChildren):
(WebCore::RenderBlockFlow::invalidateLineLayoutPath):
(WebCore::RenderBlockFlow::layoutSimpleLines):
(WebCore::RenderBlockFlow::layoutLFCLines):
(WebCore::RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout):
* rendering/RenderBlockFlow.h:
(WebCore::RenderBlockFlow::hasLFCLineLayout const):
(WebCore::RenderBlockFlow::lfcLineLayout const):
(WebCore::RenderBlockFlow::lfcLineLayout):

Source/WebKit:

* Shared/WebPreferences.yaml:
* WebProcess/InjectedBundle/InjectedBundle.cpp:
(WebKit::InjectedBundle::overrideBoolPreferenceForTestRunner):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@252893 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderBlockFlow.cpp b/Source/WebCore/rendering/RenderBlockFlow.cpp
index 7e70658..e61fc26 100644
--- a/Source/WebCore/rendering/RenderBlockFlow.cpp
+++ b/Source/WebCore/rendering/RenderBlockFlow.cpp
@@ -37,6 +37,7 @@
 #include "InlineTextBox.h"
 #include "LayoutRepainter.h"
 #include "Logging.h"
+#include "RenderBlockFlowLineLayout.h"
 #include "RenderCombineText.h"
 #include "RenderFlexibleBox.h"
 #include "RenderInline.h"
@@ -667,14 +668,31 @@
 
 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
 {
+    auto computeLineLayoutPath = [&] {
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+        if (Layout::RenderBlockFlowLineLayout::canUseFor(*this))
+            return LFCPath;
+#endif
+        if (SimpleLineLayout::canUseFor(*this))
+            return SimpleLinesPath;
+        return LineBoxesPath;
+    };
+
     if (lineLayoutPath() == UndeterminedPath)
-        setLineLayoutPath(SimpleLineLayout::canUseFor(*this) ? SimpleLinesPath : LineBoxesPath);
+        setLineLayoutPath(computeLineLayoutPath());
 
     if (lineLayoutPath() == SimpleLinesPath) {
         layoutSimpleLines(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
         return;
     }
 
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+    if (lineLayoutPath() == LFCPath) {
+        layoutLFCLines(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+        return;
+    }
+#endif
+
     if (!complexLineLayout())
         m_lineLayout = makeUnique<ComplexLineLayout>(*this);
 
@@ -3530,6 +3548,13 @@
 {
     ASSERT(childrenInline());
 
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+    if (lfcLineLayout()) {
+        lfcLineLayout()->paint(paintInfo, paintOffset);
+        return;
+    }
+#endif
+
     if (auto simpleLineLayout = this->simpleLineLayout()) {
         SimpleLineLayout::paintFlow(*this, *simpleLineLayout, paintInfo, paintOffset);
         return;
@@ -3602,6 +3627,7 @@
         ASSERT(!simpleLineLayout());
         return;
     case LineBoxesPath:
+    case LFCPath:
         ASSERT(!simpleLineLayout());
         setLineLayoutPath(UndeterminedPath);
         return;
@@ -3641,6 +3667,27 @@
     setLogicalHeight(lineLayoutTop + lineLayoutHeight + borderAndPaddingAfter());
 }
 
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+void RenderBlockFlow::layoutLFCLines(bool, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
+{
+    if (!lfcLineLayout())
+        m_lineLayout = makeUnique<Layout::RenderBlockFlowLineLayout>(*this);
+
+    auto& lfcLineLayout = *this->lfcLineLayout();
+
+    for (auto& renderer : childrenOfType<RenderObject>(*this))
+        renderer.clearNeedsLayout();
+
+    lfcLineLayout.layout();
+
+    LayoutUnit lineLayoutHeight = lfcLineLayout.contentBoxHeight();
+    LayoutUnit lineLayoutTop = borderAndPaddingBefore();
+    repaintLogicalTop = lineLayoutTop;
+    repaintLogicalBottom = repaintLogicalTop + lineLayoutHeight + borderAndPaddingAfter();
+    setLogicalHeight(lineLayoutTop + lineLayoutHeight + borderAndPaddingAfter());
+}
+#endif
+
 void RenderBlockFlow::ensureLineBoxes()
 {
     if (!childrenInline())