[LFC][Integration] Add support for IFC preferred width computation
https://bugs.webkit.org/show_bug.cgi?id=232621
Reviewed by Alan Bujtas.
The functionality is behind a #define and not enabled yet.
* layout/formattingContexts/inline/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthConstraints):
Return the cached value if it exists.
* layout/formattingContexts/inline/InlineFormattingContext.h:
* layout/integration/LayoutIntegrationLineLayout.cpp:
(WebCore::LayoutIntegration::LineLayout::computeIntrinsicWidthConstraints):
Interface with IFC.
* layout/integration/LayoutIntegrationLineLayout.h:
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::computeAndSetLineLayoutPath):
Factor into a function.
(WebCore::RenderBlockFlow::layoutInlineChildren):
(WebCore::RenderBlockFlow::computeInlinePreferredLogicalWidths const):
(WebCore::RenderBlockFlow::tryComputePreferredWidthsUsingModernPath):
Test if we the content can use the IFC preferred width computation. This way the
feature can be enabled incrementally.
* rendering/RenderBlockFlow.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@285162 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index bd246f8..91fc200 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,38 @@
+2021-11-02 Antti Koivisto <antti@apple.com>
+
+ [LFC][Integration] Add support for IFC preferred width computation
+ https://bugs.webkit.org/show_bug.cgi?id=232621
+
+ Reviewed by Alan Bujtas.
+
+ The functionality is behind a #define and not enabled yet.
+
+ * layout/formattingContexts/inline/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthConstraints):
+
+ Return the cached value if it exists.
+
+ * layout/formattingContexts/inline/InlineFormattingContext.h:
+ * layout/integration/LayoutIntegrationLineLayout.cpp:
+ (WebCore::LayoutIntegration::LineLayout::computeIntrinsicWidthConstraints):
+
+ Interface with IFC.
+
+ * layout/integration/LayoutIntegrationLineLayout.h:
+ * rendering/RenderBlockFlow.cpp:
+ (WebCore::RenderBlockFlow::computeAndSetLineLayoutPath):
+
+ Factor into a function.
+
+ (WebCore::RenderBlockFlow::layoutInlineChildren):
+ (WebCore::RenderBlockFlow::computeInlinePreferredLogicalWidths const):
+ (WebCore::RenderBlockFlow::tryComputePreferredWidthsUsingModernPath):
+
+ Test if we the content can use the IFC preferred width computation. This way the
+ feature can be enabled incrementally.
+
+ * rendering/RenderBlockFlow.h:
+
2021-11-02 Chris Lord <clord@igalia.com>
[GTK][WPE] Use the display refresh to drive scrolling animations (async scroll)
diff --git a/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp b/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp
index 75c30a2..0ad7e89d 100644
--- a/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp
+++ b/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp
@@ -359,7 +359,8 @@
IntrinsicWidthConstraints InlineFormattingContext::computedIntrinsicWidthConstraints()
{
auto& layoutState = this->layoutState();
- ASSERT(!formattingState().intrinsicWidthConstraints());
+ if (formattingState().intrinsicWidthConstraints())
+ return *formattingState().intrinsicWidthConstraints();
if (!root().hasInFlowOrFloatingChild()) {
auto constraints = formattingGeometry().constrainByMinMaxWidth(root(), { });
diff --git a/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.h b/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.h
index 5682b87..ce805c0 100644
--- a/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.h
+++ b/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.h
@@ -58,9 +58,9 @@
const InlineFormattingGeometry& formattingGeometry() const final { return m_inlineFormattingGeometry; }
const InlineFormattingQuirks& formattingQuirks() const final { return m_inlineFormattingQuirks; }
-private:
IntrinsicWidthConstraints computedIntrinsicWidthConstraints() override;
+private:
void lineLayout(InlineItems&, LineBuilder::InlineItemRange, const ConstraintsForInFlowContent&);
void computeStaticPositionForOutOfFlowContent(const FormattingState::OutOfFlowBoxList&);
diff --git a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp b/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp
index 44c85f8..8d4446b 100644
--- a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp
+++ b/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.cpp
@@ -217,6 +217,14 @@
m_boxTree.updateStyle(renderer);
}
+std::pair<LayoutUnit, LayoutUnit> LineLayout::computeIntrinsicWidthConstraints()
+{
+ auto inlineFormattingContext = Layout::InlineFormattingContext { rootLayoutBox(), m_inlineFormattingState, nullptr };
+ auto constraints = inlineFormattingContext.computedIntrinsicWidthConstraints();
+
+ return { constraints.minimum, constraints.maximum };
+}
+
void LineLayout::layout()
{
auto& rootLayoutBox = this->rootLayoutBox();
diff --git a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h b/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h
index 93f11a2..90e38a4 100644
--- a/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h
+++ b/Source/WebCore/layout/integration/LayoutIntegrationLineLayout.h
@@ -79,6 +79,9 @@
void updateLineBreakBoxDimensions(const RenderLineBreak&);
void updateInlineBoxDimensions(const RenderInline&);
void updateStyle(const RenderBoxModelObject&, const RenderStyle& oldStyle);
+
+ std::pair<LayoutUnit, LayoutUnit> computeIntrinsicWidthConstraints();
+
void layout();
LayoutUnit contentLogicalHeight() const;
diff --git a/Source/WebCore/rendering/RenderBlockFlow.cpp b/Source/WebCore/rendering/RenderBlockFlow.cpp
index f2c628f..65eeb16 100644
--- a/Source/WebCore/rendering/RenderBlockFlow.cpp
+++ b/Source/WebCore/rendering/RenderBlockFlow.cpp
@@ -69,6 +69,9 @@
namespace WebCore {
+#define ENABLE_MODERN_PREFERRED_WIDTH_COMPUTATION 0
+#define ENABLE_MODERN_PREFERRED_WIDTH_COMPUTATION_FOR_INLINE_BOXES 0
+
WTF_MAKE_ISO_ALLOCATED_IMPL(RenderBlockFlow);
bool RenderBlock::s_canPropagateFloatIntoSibling = false;
@@ -683,9 +686,12 @@
handleAfterSideOfBlock(beforeEdge, afterEdge, marginInfo);
}
-void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
+void RenderBlockFlow::computeAndSetLineLayoutPath()
{
- auto computeLineLayoutPath = [&] {
+ if (lineLayoutPath() != UndeterminedPath)
+ return;
+
+ auto compute = [&] {
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
if (LayoutIntegration::LineLayout::canUseFor(*this))
return ModernPath;
@@ -693,8 +699,12 @@
return LegacyPath;
};
- if (lineLayoutPath() == UndeterminedPath)
- setLineLayoutPath(computeLineLayoutPath());
+ setLineLayoutPath(compute());
+}
+
+void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom)
+{
+ computeAndSetLineLayoutPath();
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
if (lineLayoutPath() == ModernPath) {
@@ -4261,6 +4271,11 @@
void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
{
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+ if (const_cast<RenderBlockFlow&>(*this).tryComputePreferredWidthsUsingModernPath(minLogicalWidth, maxLogicalWidth))
+ return;
+#endif
+
float inlineMax = 0;
float inlineMin = 0;
@@ -4599,5 +4614,46 @@
maxLogicalWidth = preferredWidth(maxLogicalWidth, inlineMax);
}
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+bool RenderBlockFlow::tryComputePreferredWidthsUsingModernPath(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth)
+{
+#if ENABLE_MODERN_PREFERRED_WIDTH_COMPUTATION
+ computeAndSetLineLayoutPath();
+
+ // FIXME: Pass the replaced and inline block constrainst to IFC.
+ auto canUseModernPathForPreferredWidthComputation = [&] {
+ if (lineLayoutPath() != ModernPath)
+ return false;
+ for (auto walker = InlineWalker(*this); !walker.atEnd(); walker.advance()) {
+ auto& renderer = *walker.current();
+ if (renderer.isText())
+ continue;
+ if (is<RenderLineBreak>(renderer))
+ continue;
+#if ENABLE_MODERN_PREFERRED_WIDTH_COMPUTATION_FOR_INLINE_BOXES
+ if (is<RenderInline>(renderer))
+ continue;
+#endif
+ return false;
+ }
+ return true;
+ };
+
+ if (!canUseModernPathForPreferredWidthComputation())
+ return false;
+
+ if (!modernLineLayout())
+ m_lineLayout = makeUnique<LayoutIntegration::LineLayout>(*this);
+
+ std::tie(minLogicalWidth, maxLogicalWidth) = modernLineLayout()->computeIntrinsicWidthConstraints();
+ return true;
+#else
+ UNUSED_PARAM(minLogicalWidth);
+ UNUSED_PARAM(maxLogicalWidth);
+ return false;
+#endif
+}
+#endif
+
}
// namespace WebCore
diff --git a/Source/WebCore/rendering/RenderBlockFlow.h b/Source/WebCore/rendering/RenderBlockFlow.h
index e0c7973..2be3ba0 100644
--- a/Source/WebCore/rendering/RenderBlockFlow.h
+++ b/Source/WebCore/rendering/RenderBlockFlow.h
@@ -344,6 +344,7 @@
bool hasLines() const;
void invalidateLineLayoutPath() final;
+ void computeAndSetLineLayoutPath();
enum LineLayoutPath { UndeterminedPath = 0, ModernPath, LegacyPath, ForcedLegacyPath };
LineLayoutPath lineLayoutPath() const { return static_cast<LineLayoutPath>(renderBlockFlowLineLayoutPath()); }
@@ -545,6 +546,7 @@
#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
bool hasModernLineLayout() const;
void layoutModernLines(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom);
+ bool tryComputePreferredWidthsUsingModernPath(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
#endif
void adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;