Title: [245811] trunk/Source/WebCore
Revision
245811
Author
[email protected]
Date
2019-05-28 07:51:16 -0700 (Tue, 28 May 2019)

Log Message

[LFC][IFC] Move intrinsic width computation from InlineFormattingContext to LineLayout
https://bugs.webkit.org/show_bug.cgi?id=198258

Reviewed by Antti Koivisto.

This is in preparation for sharing even more code between line layout and preferred width computation.

* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::layout const):
(WebCore::Layout::InlineFormattingContext::computeIntrinsicWidthConstraints const):
* layout/inlineformatting/InlineFormattingContext.h:
* layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
(WebCore::Layout::InlineFormattingContext::LineLayout::initializeLine const):
(WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
(WebCore::Layout::InlineFormattingContext::LineLayout::computedIntrinsicWidth const):
(WebCore::Layout::InlineFormattingContext::LineLayout::closeLine const):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (245810 => 245811)


--- trunk/Source/WebCore/ChangeLog	2019-05-28 14:48:57 UTC (rev 245810)
+++ trunk/Source/WebCore/ChangeLog	2019-05-28 14:51:16 UTC (rev 245811)
@@ -1,5 +1,24 @@
 2019-05-28  Zalan Bujtas  <[email protected]>
 
+        [LFC][IFC] Move intrinsic width computation from InlineFormattingContext to LineLayout
+        https://bugs.webkit.org/show_bug.cgi?id=198258
+
+        Reviewed by Antti Koivisto.
+
+        This is in preparation for sharing even more code between line layout and preferred width computation. 
+
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::layout const):
+        (WebCore::Layout::InlineFormattingContext::computeIntrinsicWidthConstraints const):
+        * layout/inlineformatting/InlineFormattingContext.h:
+        * layout/inlineformatting/InlineFormattingContextLineLayout.cpp:
+        (WebCore::Layout::InlineFormattingContext::LineLayout::initializeLine const):
+        (WebCore::Layout::InlineFormattingContext::LineLayout::layout const):
+        (WebCore::Layout::InlineFormattingContext::LineLayout::computedIntrinsicWidth const):
+        (WebCore::Layout::InlineFormattingContext::LineLayout::closeLine const):
+
+2019-05-28  Zalan Bujtas  <[email protected]>
+
         [LFC[IFC] Ignore the initial strut's height when the line does not have any content.
         https://bugs.webkit.org/show_bug.cgi?id=198268
         <rdar://problem/51150057>

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (245810 => 245811)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2019-05-28 14:48:57 UTC (rev 245810)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2019-05-28 14:51:16 UTC (rev 245811)
@@ -71,7 +71,8 @@
 
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[Start] -> inline formatting context -> formatting root(" << &root() << ")");
     auto& root = downcast<Container>(this->root());
-    auto usedValues = UsedHorizontalValues { layoutState().displayBoxForLayoutBox(root).contentBoxWidth() };
+    auto availableWidth = layoutState().displayBoxForLayoutBox(root).contentBoxWidth();
+    auto usedValues = UsedHorizontalValues { availableWidth };
     auto* layoutBox = root.firstInFlowOrFloatingChild();
     // Compute width/height for non-text content and margin/border/padding for inline containers.
     while (layoutBox) {
@@ -93,7 +94,7 @@
     formattingState().inlineRuns().clear();
 
     collectInlineContent();
-    LineLayout(*this).layout();
+    LineLayout(*this).layout(availableWidth);
     LOG_WITH_STREAM(FormattingContextLayout, stream << "[End] -> inline formatting context -> formatting root(" << &root << ")");
 }
 
@@ -139,20 +140,7 @@
             auto intrinsicWidths = layoutState.formattingStateForBox(*formattingRoot).intrinsicWidthConstraints(*formattingRoot);
             layoutState.displayBoxForLayoutBox(*formattingRoot).setContentBoxWidth(availableWidth ? intrinsicWidths->maximum : intrinsicWidths->minimum);
         }
-        LayoutUnit maxContentLogicalRight;
-        LayoutUnit lineLogicalRight;
-
-        LineBreaker lineBreaker(layoutState);
-        auto& inlineContent = formattingState().inlineItems();
-        for (auto& inlineItem : inlineContent) {
-            auto breakingContext = lineBreaker.breakingContext(*inlineItem, { availableWidth, lineLogicalRight, !lineLogicalRight });
-            if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
-                lineLogicalRight = 0;
-            lineLogicalRight += inlineItem->width();
-
-            maxContentLogicalRight = std::max(maxContentLogicalRight, lineLogicalRight);
-        }
-        return maxContentLogicalRight;
+        return LineLayout(*this).computedIntrinsicWidth(availableWidth);
     };
 
     auto intrinsicWidthConstraints = Geometry::constrainByMinMaxWidth(root, { maximumLineWidth(0), maximumLineWidth(LayoutUnit::max()) });

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (245810 => 245811)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2019-05-28 14:48:57 UTC (rev 245810)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2019-05-28 14:51:16 UTC (rev 245811)
@@ -53,11 +53,12 @@
     class LineLayout {
     public:
         LineLayout(const InlineFormattingContext&);
-        void layout() const;
+        void layout(LayoutUnit widthConstraint) const;
+        LayoutUnit computedIntrinsicWidth(LayoutUnit widthConstraint) const;
 
     private:
         LayoutState& layoutState() const { return m_formattingContext.layoutState(); }
-        void initializeLine(Line&, LayoutUnit lineLogicalTop) const;
+        void initializeLine(Line&, LayoutUnit lineLogicalTop, LayoutUnit widthConstraint) const;
         void closeLine(Line&) const;
         void commitInlineItemToLine(Line&, const InlineItem&) const;
         void handleFloat(Line&, const FloatingContext&, const InlineItem& floatBox) const;

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp (245810 => 245811)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp	2019-05-28 14:48:57 UTC (rev 245810)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextLineLayout.cpp	2019-05-28 14:51:16 UTC (rev 245811)
@@ -363,11 +363,10 @@
 {
 }
 
-void InlineFormattingContext::LineLayout::initializeLine(Line& line, LayoutUnit lineLogicalTop) const
+void InlineFormattingContext::LineLayout::initializeLine(Line& line, LayoutUnit lineLogicalTop, LayoutUnit availableWidth) const
 {
     auto& formattingRootDisplayBox = layoutState().displayBoxForLayoutBox(m_formattingRoot);
     auto lineLogicalLeft = formattingRootDisplayBox.contentBoxLeft();
-    auto availableWidth = formattingRootDisplayBox.contentBoxWidth();
 
     // Check for intruding floats and adjust logical left/available width for this line accordingly.
     if (!m_floatingState.isEmpty()) {
@@ -399,11 +398,11 @@
     line.reset({ lineLogicalLeft, lineLogicalTop }, availableWidth, mimimumLineHeight, baselineOffset);
 }
 
-void InlineFormattingContext::LineLayout::layout() const
+void InlineFormattingContext::LineLayout::layout(LayoutUnit widthConstraint) const
 {
     auto floatingContext = FloatingContext { m_floatingState };
     Line line(layoutState());
-    initializeLine(line, layoutState().displayBoxForLayoutBox(m_formattingRoot).contentBoxTop());
+    initializeLine(line, layoutState().displayBoxForLayoutBox(m_formattingRoot).contentBoxTop(), widthConstraint);
 
     UncommittedContent uncommittedContent;
     auto commitPendingContent = [&] {
@@ -412,15 +411,19 @@
         uncommittedContent.reset();
     };
 
+    auto closeCurrentAndInitializeNewLine = [&] {
+        closeLine(line);
+        initializeLine(line, line.logicalBottom(), widthConstraint);
+    };
+
     LineBreaker lineBreaker(layoutState());
     auto& inlineContent = m_formattingState.inlineItems();
     for (auto& inlineItem : inlineContent) {
         // Iterate through the inline content and try to put the inline boxes on the current line.
         if (inlineItem->isHardLineBreak()) {
-            // Close the current line then create and immediately close another one.
             commitPendingContent();
             commitInlineItemToLine(line, *inlineItem);
-            closeLine(line);
+            closeCurrentAndInitializeNewLine();
         } else {
             auto availableWidth = line.availableWidth() - uncommittedContent.width();
             auto currentLogicalRight = line.contentLogicalRight() + uncommittedContent.width();
@@ -435,7 +438,7 @@
             }
 
             if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap)
-                closeLine(line);
+                closeCurrentAndInitializeNewLine();
 
             if (inlineItem->isFloat())
                 handleFloat(line, floatingContext, *inlineItem);
@@ -450,12 +453,40 @@
     // Process remaining uncommitted content.
     if (!uncommittedContent.isEmpty()) {
         if (line.availableWidth() < uncommittedContent.width())
-            closeLine(line);
+            closeCurrentAndInitializeNewLine();
         commitPendingContent();
     }
     closeLine(line);
 }
 
+LayoutUnit InlineFormattingContext::LineLayout::computedIntrinsicWidth(LayoutUnit widthConstraint) const
+{
+    // FIXME: Consider running it through layout().
+    LayoutUnit maximumLineWidth;
+    LayoutUnit lineLogicalRight;
+    LayoutUnit trimmableTrailingWidth;
+
+    LineBreaker lineBreaker(layoutState());
+    auto& inlineContent = m_formattingState.inlineItems();
+    for (auto& inlineItem : inlineContent) {
+        auto breakingContext = lineBreaker.breakingContext(*inlineItem, { widthConstraint, lineLogicalRight, !lineLogicalRight });
+        if (breakingContext.breakingBehavior == LineBreaker::BreakingBehavior::Wrap) {
+            maximumLineWidth = std::max(maximumLineWidth, lineLogicalRight - trimmableTrailingWidth);
+            trimmableTrailingWidth = { };
+            lineLogicalRight = { };
+        }
+        if (isTrimmableContent(*inlineItem)) {
+            // Skip leading whitespace.
+            if (!lineLogicalRight)
+                continue;
+            trimmableTrailingWidth += inlineItem->width();
+        } else
+            trimmableTrailingWidth = { };
+        lineLogicalRight += inlineItem->width();
+    }
+    return std::max(maximumLineWidth, lineLogicalRight - trimmableTrailingWidth);
+}
+
 void InlineFormattingContext::LineLayout::closeLine(Line& line) const
 {
     auto& lineItems = line.close();
@@ -556,7 +587,6 @@
     m_formattingState.addLineBox({ lineBox });
     if (line.hasContent())
         alignRuns(m_formattingRoot.style().textAlign(), previousLineLastRunIndex.valueOr(-1) + 1, line.availableWidth());
-    initializeLine(line, line.logicalBottom());
 }
 
 void InlineFormattingContext::LineLayout::handleFloat(Line& line, const FloatingContext& floatingContext, const InlineItem& floatItem) const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to