Title: [252863] trunk/Source/WebCore
Revision
252863
Author
[email protected]
Date
2019-11-25 09:29:31 -0800 (Mon, 25 Nov 2019)

Log Message

[LFC][IFC] Rename LineLayout to LineLayoutContext
https://bugs.webkit.org/show_bug.cgi?id=204582
<rdar://problem/57474018>

Reviewed by Antti Koivisto.

LineLayoutContext is the context for the inline content and not just for a single line.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::lineLayout):
(WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthForConstraint const):
(WebCore::Layout::InlineFormattingContext::setDisplayBoxesForLine):
* layout/inlineformatting/InlineFormattingContext.h:
* layout/inlineformatting/InlineLineBreaker.cpp:
(WebCore::Layout::LineBreaker::breakingContextForInlineContent):
(WebCore::Layout::LineBreaker::wordBreakingBehavior const):
(WebCore::Layout::LineBreaker::tryBreakingTextRun const):
* layout/inlineformatting/InlineLineBreaker.h:
* layout/inlineformatting/LineLayoutContext.cpp: Renamed from Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp.
(WebCore::Layout::inlineItemWidth):
(WebCore::Layout::LineLayoutContext::UncommittedContent::add):
(WebCore::Layout::LineLayoutContext::UncommittedContent::reset):
(WebCore::Layout::LineLayoutContext::LineLayoutContext):
(WebCore::Layout::LineLayoutContext::layoutLine):
(WebCore::Layout::LineLayoutContext::commitPendingContent):
(WebCore::Layout::LineLayoutContext::close):
(WebCore::Layout::LineLayoutContext::placeInlineItem):
(WebCore::Layout::LineLayoutContext::processUncommittedContent):
(WebCore::Layout::LineLayoutContext::shouldProcessUncommittedContent const):
(WebCore::Layout::LineLayoutContext::UncommittedContent::trim):
* layout/inlineformatting/LineLayoutContext.h: Renamed from Source/WebCore/layout/inlineformatting/InlineLineLayout.h.
(WebCore::Layout::LineLayoutContext::formattingContext const):
(WebCore::Layout::LineLayoutContext::UncommittedContent::runs):
(WebCore::Layout::LineLayoutContext::UncommittedContent::runs const):
(WebCore::Layout::LineLayoutContext::UncommittedContent::isEmpty const):
(WebCore::Layout::LineLayoutContext::UncommittedContent::size const):
(WebCore::Layout::LineLayoutContext::UncommittedContent::width const):

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (252862 => 252863)


--- trunk/Source/WebCore/ChangeLog	2019-11-25 16:19:42 UTC (rev 252862)
+++ trunk/Source/WebCore/ChangeLog	2019-11-25 17:29:31 UTC (rev 252863)
@@ -1,5 +1,47 @@
 2019-11-25  Zalan Bujtas  <[email protected]>
 
+        [LFC][IFC] Rename LineLayout to LineLayoutContext
+        https://bugs.webkit.org/show_bug.cgi?id=204582
+        <rdar://problem/57474018>
+
+        Reviewed by Antti Koivisto.
+
+        LineLayoutContext is the context for the inline content and not just for a single line.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::lineLayout):
+        (WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthForConstraint const):
+        (WebCore::Layout::InlineFormattingContext::setDisplayBoxesForLine):
+        * layout/inlineformatting/InlineFormattingContext.h:
+        * layout/inlineformatting/InlineLineBreaker.cpp:
+        (WebCore::Layout::LineBreaker::breakingContextForInlineContent):
+        (WebCore::Layout::LineBreaker::wordBreakingBehavior const):
+        (WebCore::Layout::LineBreaker::tryBreakingTextRun const):
+        * layout/inlineformatting/InlineLineBreaker.h:
+        * layout/inlineformatting/LineLayoutContext.cpp: Renamed from Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp.
+        (WebCore::Layout::inlineItemWidth):
+        (WebCore::Layout::LineLayoutContext::UncommittedContent::add):
+        (WebCore::Layout::LineLayoutContext::UncommittedContent::reset):
+        (WebCore::Layout::LineLayoutContext::LineLayoutContext):
+        (WebCore::Layout::LineLayoutContext::layoutLine):
+        (WebCore::Layout::LineLayoutContext::commitPendingContent):
+        (WebCore::Layout::LineLayoutContext::close):
+        (WebCore::Layout::LineLayoutContext::placeInlineItem):
+        (WebCore::Layout::LineLayoutContext::processUncommittedContent):
+        (WebCore::Layout::LineLayoutContext::shouldProcessUncommittedContent const):
+        (WebCore::Layout::LineLayoutContext::UncommittedContent::trim):
+        * layout/inlineformatting/LineLayoutContext.h: Renamed from Source/WebCore/layout/inlineformatting/InlineLineLayout.h.
+        (WebCore::Layout::LineLayoutContext::formattingContext const):
+        (WebCore::Layout::LineLayoutContext::UncommittedContent::runs):
+        (WebCore::Layout::LineLayoutContext::UncommittedContent::runs const):
+        (WebCore::Layout::LineLayoutContext::UncommittedContent::isEmpty const):
+        (WebCore::Layout::LineLayoutContext::UncommittedContent::size const):
+        (WebCore::Layout::LineLayoutContext::UncommittedContent::width const):
+
+2019-11-25  Zalan Bujtas  <[email protected]>
+
         [LFC] Pass UsedHorizontal/VerticalValues in by const reference
         https://bugs.webkit.org/show_bug.cgi?id=204563
         <rdar://problem/57464129>

Modified: trunk/Source/WebCore/Sources.txt (252862 => 252863)


--- trunk/Source/WebCore/Sources.txt	2019-11-25 16:19:42 UTC (rev 252862)
+++ trunk/Source/WebCore/Sources.txt	2019-11-25 17:29:31 UTC (rev 252863)
@@ -1440,8 +1440,8 @@
 layout/inlineformatting/InlineItem.cpp
 layout/inlineformatting/InlineLine.cpp
 layout/inlineformatting/InlineLineBreaker.cpp
-layout/inlineformatting/InlineLineLayout.cpp
 layout/inlineformatting/InlineTextItem.cpp
+layout/inlineformatting/LineLayoutContext.cpp
 layout/inlineformatting/text/TextUtil.cpp
 layout/invalidation/InvalidationContext.cpp
 layout/invalidation/InvalidationState.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (252862 => 252863)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-11-25 16:19:42 UTC (rev 252862)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2019-11-25 17:29:31 UTC (rev 252863)
@@ -2023,7 +2023,7 @@
 		6F0CD695229ED32700C5994E /* InlineLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F0CD694229ED32700C5994E /* InlineLine.h */; };
 		6F1CC1DE225F8B4900720AD2 /* InlineTextItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F1CC1DD225F8B4200720AD2 /* InlineTextItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6F26BB6C23343E6F002F2BEA /* LayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F26BB6B23343E5B002F2BEA /* LayoutContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
-		6F26EB48234004A5006906E2 /* InlineLineLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F26EB46234004A5006906E2 /* InlineLineLayout.h */; };
+		6F26EB48234004A5006906E2 /* LineLayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F26EB46234004A5006906E2 /* LineLayoutContext.h */; };
 		6F3E1F622136142000A65A08 /* FloatBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F3E1F612136141700A65A08 /* FloatBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6F77868823491AD8004D9636 /* DisplayPainter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F77868723491AD7004D9636 /* DisplayPainter.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		6F7CA3C6208C2957002F29AB /* LayoutState.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F7CA3C4208C2956002F29AB /* LayoutState.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -9252,10 +9252,10 @@
 		6F1CC1DD225F8B4200720AD2 /* InlineTextItem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InlineTextItem.h; sourceTree = "<group>"; };
 		6F222B741AB52D640094651A /* WebGLVertexArrayObjectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebGLVertexArrayObjectBase.h; sourceTree = "<group>"; };
 		6F222B751AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebGLVertexArrayObjectBase.cpp; sourceTree = "<group>"; };
-		6F25B200220A85AB0000011B /* InlineLineLayout.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineLineLayout.cpp; sourceTree = "<group>"; };
+		6F25B200220A85AB0000011B /* LineLayoutContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LineLayoutContext.cpp; sourceTree = "<group>"; };
 		6F26BB6923343E5A002F2BEA /* LayoutContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutContext.cpp; sourceTree = "<group>"; };
 		6F26BB6B23343E5B002F2BEA /* LayoutContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutContext.h; sourceTree = "<group>"; };
-		6F26EB46234004A5006906E2 /* InlineLineLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineLineLayout.h; sourceTree = "<group>"; };
+		6F26EB46234004A5006906E2 /* LineLayoutContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LineLayoutContext.h; sourceTree = "<group>"; };
 		6F35EFAF2187CBD50044E0F4 /* InlineFormattingContextGeometry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineFormattingContextGeometry.cpp; sourceTree = "<group>"; };
 		6F3E1F5F2136141700A65A08 /* FloatBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = FloatBox.cpp; sourceTree = "<group>"; };
 		6F3E1F612136141700A65A08 /* FloatBox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FloatBox.h; sourceTree = "<group>"; };
@@ -16691,10 +16691,10 @@
 				6FB47E612277425A00C7BCB0 /* InlineLineBox.h */,
 				6FE198132178397B00446F08 /* InlineLineBreaker.cpp */,
 				6FE198152178397C00446F08 /* InlineLineBreaker.h */,
-				6F25B200220A85AB0000011B /* InlineLineLayout.cpp */,
-				6F26EB46234004A5006906E2 /* InlineLineLayout.h */,
 				6F1CC1DC225F8B4100720AD2 /* InlineTextItem.cpp */,
 				6F1CC1DD225F8B4200720AD2 /* InlineTextItem.h */,
+				6F25B200220A85AB0000011B /* LineLayoutContext.cpp */,
+				6F26EB46234004A5006906E2 /* LineLayoutContext.h */,
 			);
 			path = inlineformatting;
 			sourceTree = "<group>";
@@ -30176,7 +30176,6 @@
 				6F0CD695229ED32700C5994E /* InlineLine.h in Headers */,
 				6FB47E632277425A00C7BCB0 /* InlineLineBox.h in Headers */,
 				6FE198172178397C00446F08 /* InlineLineBreaker.h in Headers */,
-				6F26EB48234004A5006906E2 /* InlineLineLayout.h in Headers */,
 				AA4C3A770B2B1679002334A2 /* InlineStyleSheetOwner.h in Headers */,
 				BCEA485A097D93020094C9E4 /* InlineTextBox.h in Headers */,
 				1C010701192594DF008A4201 /* InlineTextBoxStyle.h in Headers */,
@@ -31182,6 +31181,7 @@
 				84730D911248F0B300D3A9C9 /* LightSource.h in Headers */,
 				B22279650D00BF220071B782 /* LinearGradientAttributes.h in Headers */,
 				AB31C91E10AE1B8E000C7B92 /* LineClampValue.h in Headers */,
+				6F26EB48234004A5006906E2 /* LineLayoutContext.h in Headers */,
 				FFEFAB2A18380DA000514534 /* LineLayoutState.h in Headers */,
 				E484A33E23055325009ADE6A /* LineLayoutTraversal.h in Headers */,
 				FFDBC047183D27B700407109 /* LineWidth.h in Headers */,

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (252862 => 252863)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2019-11-25 16:19:42 UTC (rev 252862)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp	2019-11-25 17:29:31 UTC (rev 252863)
@@ -94,13 +94,13 @@
     auto& inlineItems = formattingState().inlineItems();
     auto lineLogicalTop = geometryForBox(root()).contentBoxTop();
     unsigned leadingInlineItemIndex = 0;
-    Optional<LineLayout::PartialContent> leadingPartialContent;
+    Optional<LineLayoutContext::PartialContent> leadingPartialContent;
     auto line = Line { *this, root().style().textAlign(), Line::SkipAlignment::No };
-    auto lineLayout = LineLayout { *this, inlineItems };
+    auto lineLayoutContext = LineLayoutContext { *this, inlineItems };
 
     while (leadingInlineItemIndex < inlineItems.size()) {
         line.initialize(constraintsForLine(usedHorizontalValues, lineLogicalTop));
-        auto lineContent = lineLayout.layout(line, leadingInlineItemIndex, leadingPartialContent);
+        auto lineContent = lineLayoutContext.layoutLine(line, leadingInlineItemIndex, leadingPartialContent);
         setDisplayBoxesForLine(lineContent, usedHorizontalValues);
 
         leadingPartialContent = { };
@@ -111,7 +111,7 @@
                 leadingInlineItemIndex = *lineContent.trailingInlineItemIndex;
                 // Turn previous line's overflow content length into the next line's leading content partial length.
                 // "sp<->litcontent" -> overflow length: 10 -> leading partial content length: 10. 
-                leadingPartialContent = LineLayout::PartialContent { lineContent.trailingPartialContent->length };
+                leadingPartialContent = LineLayoutContext::PartialContent { lineContent.trailingPartialContent->length };
             } else
                 leadingInlineItemIndex = *lineContent.trailingInlineItemIndex + 1;
         } else {
@@ -234,11 +234,11 @@
     LayoutUnit maximumLineWidth;
     unsigned leadingInlineItemIndex = 0;
     auto line = Line { *this, root().style().textAlign(), Line::SkipAlignment::Yes };
-    auto lineLayout = LineLayout { *this, inlineItems };
+    auto lineLayoutContext = LineLayoutContext { *this, inlineItems };
     while (leadingInlineItemIndex < inlineItems.size()) {
         // Only the horiztonal available width is constrained when computing intrinsic width.
         line.initialize(Line::Constraints { { }, usedHorizontalValues.constraints.width, false, { } });
-        auto lineContent = lineLayout.layout(line, leadingInlineItemIndex, { });
+        auto lineContent = lineLayoutContext.layoutLine(line, leadingInlineItemIndex, { });
 
         leadingInlineItemIndex = *lineContent.trailingInlineItemIndex + 1;
         LayoutUnit floatsWidth;
@@ -407,7 +407,7 @@
     return Line::Constraints { { lineLogicalLeft, lineLogicalTop }, availableWidth, lineIsConstrainedByFloat, quirks().lineHeightConstraints(root()) };
 }
 
-void InlineFormattingContext::setDisplayBoxesForLine(const LineLayout::LineContent& lineContent, const UsedHorizontalValues& usedHorizontalValues)
+void InlineFormattingContext::setDisplayBoxesForLine(const LineLayoutContext::LineContent& lineContent, const UsedHorizontalValues& usedHorizontalValues)
 {
     auto& formattingState = this->formattingState();
 

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (252862 => 252863)


--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2019-11-25 16:19:42 UTC (rev 252862)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h	2019-11-25 17:29:31 UTC (rev 252863)
@@ -28,7 +28,7 @@
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "FormattingContext.h"
-#include "InlineLineLayout.h"
+#include "LineLayoutContext.h"
 #include <wtf/IsoMalloc.h>
 
 namespace WebCore {
@@ -90,7 +90,7 @@
 
     void collectInlineContentIfNeeded();
     Line::Constraints constraintsForLine(const UsedHorizontalValues&, const LayoutUnit lineLogicalTop);
-    void setDisplayBoxesForLine(const LineLayout::LineContent&, const UsedHorizontalValues&);
+    void setDisplayBoxesForLine(const LineLayoutContext::LineContent&, const UsedHorizontalValues&);
     void invalidateFormattingState(const InvalidationState&);
 
     const InlineFormattingState& formattingState() const { return downcast<InlineFormattingState>(FormattingContext::formattingState()); }

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp (252862 => 252863)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp	2019-11-25 16:19:42 UTC (rev 252862)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.cpp	2019-11-25 17:29:31 UTC (rev 252863)
@@ -47,7 +47,7 @@
     return trailingInlineItem.style().whiteSpace() == WhiteSpace::PreWrap && downcast<InlineTextItem>(trailingInlineItem).isWhitespace();
 }
 
-LineBreaker::BreakingContext LineBreaker::breakingContextForInlineContent(const LineLayout::RunList& runs, LayoutUnit logicalWidth, LayoutUnit availableWidth, bool lineIsEmpty)
+LineBreaker::BreakingContext LineBreaker::breakingContextForInlineContent(const LineLayoutContext::RunList& runs, LayoutUnit logicalWidth, LayoutUnit availableWidth, bool lineIsEmpty)
 {
     if (logicalWidth <= availableWidth)
         return { BreakingContext::ContentBreak::Keep, { } };
@@ -87,7 +87,7 @@
     return !lineIsEmpty && floatLogicalWidth > availableWidth;
 }
 
-Optional<LineBreaker::BreakingContext::TrailingPartialContent> LineBreaker::wordBreakingBehavior(const LineLayout::RunList& runs, LayoutUnit availableWidth) const
+Optional<LineBreaker::BreakingContext::TrailingPartialContent> LineBreaker::wordBreakingBehavior(const LineLayoutContext::RunList& runs, LayoutUnit availableWidth) const
 {
     // Check where the overflow occurs and use the corresponding style to figure out the breaking behaviour.
     // <span style="word-break: normal">first</span><span style="word-break: break-all">second</span><span style="word-break: normal">third</span>
@@ -120,7 +120,7 @@
     return { };
 }
 
-Optional<LineBreaker::SplitLengthAndWidth> LineBreaker::tryBreakingTextRun(const LineLayout::Run overflowRun, LayoutUnit availableWidth) const
+Optional<LineBreaker::SplitLengthAndWidth> LineBreaker::tryBreakingTextRun(const LineLayoutContext::Run overflowRun, LayoutUnit availableWidth) const
 {
     ASSERT(overflowRun.inlineItem.isText());
     auto breakWords = overflowRun.inlineItem.style().wordBreak();

Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h (252862 => 252863)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h	2019-11-25 16:19:42 UTC (rev 252862)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineBreaker.h	2019-11-25 17:29:31 UTC (rev 252863)
@@ -27,8 +27,8 @@
 
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
-#include "InlineLineLayout.h"
 #include "LayoutUnit.h"
+#include "LineLayoutContext.h"
 
 namespace WebCore {
 namespace Layout {
@@ -48,18 +48,18 @@
         };
         Optional<TrailingPartialContent> trailingPartialContent;
     };
-    BreakingContext breakingContextForInlineContent(const LineLayout::RunList&, LayoutUnit logicalWidth, LayoutUnit availableWidth, bool lineIsEmpty);
+    BreakingContext breakingContextForInlineContent(const LineLayoutContext::RunList&, LayoutUnit logicalWidth, LayoutUnit availableWidth, bool lineIsEmpty);
     bool shouldWrapFloatBox(LayoutUnit floatLogicalWidth, LayoutUnit availableWidth, bool lineIsEmpty);
 
 private:
 
-    Optional<BreakingContext::TrailingPartialContent> wordBreakingBehavior(const LineLayout::RunList&, LayoutUnit availableWidth) const;
+    Optional<BreakingContext::TrailingPartialContent> wordBreakingBehavior(const LineLayoutContext::RunList&, LayoutUnit availableWidth) const;
 
     struct SplitLengthAndWidth {
         unsigned length { 0 };
         LayoutUnit leftLogicalWidth;
     };
-    Optional<SplitLengthAndWidth> tryBreakingTextRun(const LineLayout::Run overflowRun, LayoutUnit availableWidth) const;
+    Optional<SplitLengthAndWidth> tryBreakingTextRun(const LineLayoutContext::Run overflowRun, LayoutUnit availableWidth) const;
 };
 
 }

Deleted: trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp (252862 => 252863)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp	2019-11-25 16:19:42 UTC (rev 252862)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp	2019-11-25 17:29:31 UTC (rev 252863)
@@ -1,331 +0,0 @@
-/*
- * Copyright (C) 2019 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "InlineLineLayout.h"
-
-#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
-
-#include "InlineLineBreaker.h"
-#include "LayoutBox.h"
-#include "TextUtil.h"
-
-namespace WebCore {
-namespace Layout {
-
-static LayoutUnit inlineItemWidth(const FormattingContext& formattingContext, const InlineItem& inlineItem, LayoutUnit contentLogicalLeft)
-{
-    if (inlineItem.isForcedLineBreak())
-        return 0;
-
-    if (is<InlineTextItem>(inlineItem)) {
-        auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
-        if (auto contentWidth = inlineTextItem.width())
-            return *contentWidth;
-        auto end = inlineTextItem.isCollapsible() ? inlineTextItem.start() + 1 : inlineTextItem.end();
-        return TextUtil::width(inlineTextItem.layoutBox(), inlineTextItem.start(), end, contentLogicalLeft);
-    }
-
-    auto& layoutBox = inlineItem.layoutBox();
-    auto& boxGeometry = formattingContext.geometryForBox(layoutBox);
-
-    if (layoutBox.isFloatingPositioned())
-        return boxGeometry.marginBoxWidth();
-
-    if (layoutBox.replaced())
-        return boxGeometry.width();
-
-    if (inlineItem.isContainerStart())
-        return boxGeometry.marginStart() + boxGeometry.borderLeft() + boxGeometry.paddingLeft().valueOr(0);
-
-    if (inlineItem.isContainerEnd())
-        return boxGeometry.marginEnd() + boxGeometry.borderRight() + boxGeometry.paddingRight().valueOr(0);
-
-    // Non-replaced inline box (e.g. inline-block)
-    return boxGeometry.width();
-}
-
-void LineLayout::UncommittedContent::add(const InlineItem& inlineItem, LayoutUnit logicalWidth)
-{
-    m_uncommittedRuns.append({ inlineItem, logicalWidth });
-    m_width += logicalWidth;
-}
-
-void LineLayout::UncommittedContent::reset()
-{
-    m_uncommittedRuns.clear();
-    m_width = 0;
-}
-
-LineLayout::LineLayout(const InlineFormattingContext& inlineFormattingContext, const InlineItems& inlineItems)
-    : m_inlineFormattingContext(inlineFormattingContext)
-    , m_inlineItems(inlineItems)
-{
-}
-
-LineLayout::LineContent LineLayout::layout(Line& line, unsigned leadingInlineItemIndex, Optional<PartialContent> leadingPartialContent)
-{
-    auto initialize = [&] {
-        m_committedInlineItemCount = 0;
-        m_uncommittedContent.reset();
-        m_leadingPartialTextItem = { };
-        m_trailingPartialTextItem = { };
-        m_overflowTextLength = { };
-    };
-    initialize();
-    // Iterate through the inline content and place the inline boxes on the current line.
-    // Start with the partial leading text from the previous line.
-    auto firstNonPartialInlineItemIndex = leadingInlineItemIndex;
-    if (leadingPartialContent) {
-        // Handle partial inline item (split text from the previous line).
-        auto& leadingTextItem = m_inlineItems[leadingInlineItemIndex];
-        RELEASE_ASSERT(leadingTextItem->isText());
-        // Construct a partial leading inline item.
-        ASSERT(!m_leadingPartialTextItem);
-        m_leadingPartialTextItem = downcast<InlineTextItem>(*leadingTextItem).right(leadingPartialContent->length);
-        if (placeInlineItem(line, *m_leadingPartialTextItem) == IsEndOfLine::Yes)
-            return close(line, leadingInlineItemIndex);
-        ++firstNonPartialInlineItemIndex;
-    }
-
-    for (auto inlineItemIndex = firstNonPartialInlineItemIndex; inlineItemIndex < m_inlineItems.size(); ++inlineItemIndex) {
-        // FIXME: We should not need to re-measure the dropped, uncommitted content when re-using them on the next line.
-        if (placeInlineItem(line, *m_inlineItems[inlineItemIndex]) == IsEndOfLine::Yes)
-            return close(line, leadingInlineItemIndex);
-    }
-    // Check the uncommitted content whether they fit now that we know we are at a commit boundary.
-    if (!m_uncommittedContent.isEmpty())
-        processUncommittedContent(line);
-    return close(line, leadingInlineItemIndex);
-}
-
-void LineLayout::commitPendingContent(Line& line)
-{
-    if (m_uncommittedContent.isEmpty())
-        return;
-    m_committedInlineItemCount += m_uncommittedContent.size();
-    for (auto& uncommittedRun : m_uncommittedContent.runs())
-        line.append(uncommittedRun.inlineItem, uncommittedRun.logicalWidth);
-    m_uncommittedContent.reset();
-}
-
-LineLayout::LineContent LineLayout::close(Line& line, unsigned leadingInlineItemIndex)
-{
-    ASSERT(m_committedInlineItemCount || line.hasIntrusiveFloat());
-    m_uncommittedContent.reset();
-    if (!m_committedInlineItemCount)
-        return LineContent { { }, { }, WTFMove(m_floats), line.close(), line.lineBox() };
-
-    Optional<PartialContent> overflowContent;
-    if (m_overflowTextLength)
-        overflowContent = PartialContent { *m_overflowTextLength };
-    auto trailingInlineItemIndex = leadingInlineItemIndex + m_committedInlineItemCount - 1;
-
-    auto isLastLineWithInlineContent = [&] {
-        if (overflowContent)
-            return Line::IsLastLineWithInlineContent::No;
-        // Skip floats backwards to see if this is going to be the last line with inline content.
-        for (auto i = m_inlineItems.size(); i--;) {
-            if (!m_inlineItems[i]->isFloat())
-                return i == trailingInlineItemIndex ? Line::IsLastLineWithInlineContent::Yes : Line::IsLastLineWithInlineContent::No;
-        }
-        // There has to be at least one non-float item.
-        ASSERT_NOT_REACHED();
-        return Line::IsLastLineWithInlineContent::No;
-    };
-
-    return LineContent { trailingInlineItemIndex, overflowContent, WTFMove(m_floats), line.close(isLastLineWithInlineContent()), line.lineBox() };
-}
-
-LineLayout::IsEndOfLine LineLayout::placeInlineItem(Line& line, const InlineItem& inlineItem)
-{
-    auto currentLogicalRight = line.lineBox().logicalRight();
-    auto itemLogicalWidth = inlineItemWidth(formattingContext(), inlineItem, currentLogicalRight);
-
-    // Floats are special, they are intrusive but they don't really participate in the line layout context.
-    if (inlineItem.isFloat()) {
-        // FIXME: It gets a bit more complicated when there's some uncommitted content whether they should be added to the current line
-        // e.g. text_content<div style="float: left"></div>continuous_text_content
-        // Not sure what to do when the float takes up the available space and we've got continuous content. Browser engines don't agree.
-        // Let's just commit the pending content and try placing the float for now.
-        if (!m_uncommittedContent.isEmpty()) {
-            if (processUncommittedContent(line) == IsEndOfLine::Yes)
-                return IsEndOfLine::Yes;
-        }
-        auto lineIsConsideredEmpty = line.isVisuallyEmpty() && !line.hasIntrusiveFloat();
-        if (LineBreaker().shouldWrapFloatBox(itemLogicalWidth, line.availableWidth() + line.trailingTrimmableWidth(), lineIsConsideredEmpty))
-            return IsEndOfLine::Yes;
-
-        // This float can sit on the current line.
-        auto& floatBox = inlineItem.layoutBox();
-        // Shrink available space for current line and move existing inline runs.
-        floatBox.isLeftFloatingPositioned() ? line.moveLogicalLeft(itemLogicalWidth) : line.moveLogicalRight(itemLogicalWidth);
-        m_floats.append(makeWeakPtr(inlineItem));
-        ++m_committedInlineItemCount;
-        line.setHasIntrusiveFloat();
-        return IsEndOfLine::No;
-    }
-    // Forced line breaks are also special.
-    if (inlineItem.isForcedLineBreak()) {
-        auto isEndOfLine = !m_uncommittedContent.isEmpty() ? processUncommittedContent(line) : IsEndOfLine::No;
-        // When the uncommitted content fits(or the line is empty), add the line break to this line as well.
-        if (isEndOfLine == IsEndOfLine::No) {
-            m_uncommittedContent.add(inlineItem, itemLogicalWidth);
-            commitPendingContent(line);
-        }
-        return IsEndOfLine::Yes;
-    }
-    //
-    auto isEndOfLine = IsEndOfLine::No;
-    if (!m_uncommittedContent.isEmpty() && shouldProcessUncommittedContent(inlineItem))
-        isEndOfLine = processUncommittedContent(line);
-    // The current item might fit as well.
-    if (isEndOfLine == IsEndOfLine::No)
-        m_uncommittedContent.add(inlineItem, itemLogicalWidth);
-    return isEndOfLine;
-}
-
-LineLayout::IsEndOfLine LineLayout::processUncommittedContent(Line& line)
-{
-    // Check if the pending content fits.
-    auto lineIsConsideredEmpty = line.isVisuallyEmpty() && !line.hasIntrusiveFloat();
-    auto breakingContext = LineBreaker().breakingContextForInlineContent(m_uncommittedContent.runs(), m_uncommittedContent.width(), line.availableWidth(), lineIsConsideredEmpty);
-    // The uncommitted content can fully, partially fit the current line (commit/partial commit) or not at all (reset).
-    if (breakingContext.contentBreak == LineBreaker::BreakingContext::ContentBreak::Keep)
-        commitPendingContent(line);
-    else if (breakingContext.contentBreak == LineBreaker::BreakingContext::ContentBreak::Split) {
-        ASSERT(breakingContext.trailingPartialContent);
-        ASSERT(m_uncommittedContent.runs()[breakingContext.trailingPartialContent->runIndex].inlineItem.isText());
-        // Turn the uncommitted trailing run into a partial trailing run.
-        auto overflowInlineTextItemIndex = breakingContext.trailingPartialContent->runIndex;
-        auto& overflowInlineTextItem = downcast<InlineTextItem>(m_uncommittedContent.runs()[overflowInlineTextItemIndex].inlineItem);
-
-        // Construct a partial trailing inline run.
-        ASSERT(!m_trailingPartialTextItem);
-        auto trailingContentLength = breakingContext.trailingPartialContent->length;
-        m_trailingPartialTextItem = overflowInlineTextItem.left(trailingContentLength);
-        m_overflowTextLength = overflowInlineTextItem.length() - trailingContentLength;
-        // Keep the non-overflow part of the uncommitted runs and add the trailing partial content.
-        m_uncommittedContent.trim(overflowInlineTextItemIndex);
-        m_uncommittedContent.add(*m_trailingPartialTextItem, breakingContext.trailingPartialContent->logicalWidth);
-        commitPendingContent(line);
-    } else if (breakingContext.contentBreak == LineBreaker::BreakingContext::ContentBreak::Wrap)
-        m_uncommittedContent.reset();
-    else
-        ASSERT_NOT_REACHED();
-    return breakingContext.contentBreak == LineBreaker::BreakingContext::ContentBreak::Keep ? IsEndOfLine::No :IsEndOfLine::Yes;
-}
-
-bool LineLayout::shouldProcessUncommittedContent(const InlineItem& inlineItem) const
-{
-    // https://drafts.csswg.org/css-text-3/#line-break-details
-    // Figure out if the new incoming content puts the uncommitted content on commit boundary.
-    // e.g. <span>continuous</span> <- uncomitted content ->
-    // [inline container start][text content][inline container end]
-    // An incoming <img> box would enable us to commit the "<span>continuous</span>" content
-    // while additional text content would not.
-    ASSERT(!inlineItem.isFloat() && !inlineItem.isForcedLineBreak());
-    ASSERT(!m_uncommittedContent.isEmpty());
-
-    auto* lastUncomittedContent = &m_uncommittedContent.runs().last().inlineItem;
-    if (inlineItem.isText()) {
-        // any content' ' -> whitespace is always a commit boundary.
-        if (downcast<InlineTextItem>(inlineItem).isWhitespace())
-            return true;
-        // texttext -> continuous content.
-        // ' 'text -> commit boundary.
-        if (lastUncomittedContent->isText())
-            return downcast<InlineTextItem>(*lastUncomittedContent).isWhitespace();
-        // <span>text -> the inline container start and the text content form an unbreakable continuous content.
-        if (lastUncomittedContent->isContainerStart())
-            return false;
-        // </span>text -> need to check what's before the </span>.
-        // text</span>text -> continuous content
-        // <img></span>text -> commit bounday
-        if (lastUncomittedContent->isContainerEnd()) {
-            auto& runs = m_uncommittedContent.runs();
-            // text</span><span></span></span>text -> check all the way back until we hit either a box or some text
-            for (auto i = m_uncommittedContent.size(); i--;) {
-                auto& previousInlineItem = runs[i].inlineItem;
-                if (previousInlineItem.isContainerStart() || previousInlineItem.isContainerEnd())
-                    continue;
-                ASSERT(previousInlineItem.isText() || previousInlineItem.isBox());
-                lastUncomittedContent = &previousInlineItem;
-                break;
-            }
-            // Did not find any content (e.g. <span></span>text)
-            if (lastUncomittedContent->isContainerEnd())
-                return false;
-        }
-        // <img>text -> the inline box is on a commit boundary.
-        if (lastUncomittedContent->isBox())
-            return true;
-        ASSERT_NOT_REACHED();
-    }
-
-    if (inlineItem.isBox()) {
-        // <span><img> -> the inline container start and the content form an unbreakable continuous content.
-        if (lastUncomittedContent->isContainerStart())
-            return false;
-        // </span><img> -> ok to commit the </span>.
-        if (lastUncomittedContent->isContainerEnd())
-            return true;
-        // <img>text and <img><img> -> these combinations are ok to commit.
-        if (lastUncomittedContent->isText() || lastUncomittedContent->isBox())
-            return true;
-        ASSERT_NOT_REACHED();
-    }
-
-    if (inlineItem.isContainerStart() || inlineItem.isContainerEnd()) {
-        // <span><span> or </span><span> -> can't commit the previous content yet.
-        if (lastUncomittedContent->isContainerStart() || lastUncomittedContent->isContainerEnd())
-            return false;
-        // ' '<span> -> let's commit the whitespace
-        // text<span> -> but not yet the non-whitespace; we need to know what comes next (e.g. text<span>text or text<span><img>).
-        if (lastUncomittedContent->isText())
-            return downcast<InlineTextItem>(*lastUncomittedContent).isWhitespace();
-        // <img><span> -> it's ok to commit the inline box content.
-        // <img></span> -> the inline box and the closing inline container form an unbreakable continuous content.
-        if (lastUncomittedContent->isBox())
-            return inlineItem.isContainerStart();
-        ASSERT_NOT_REACHED();
-    }
-
-    ASSERT_NOT_REACHED();
-    return true;
-}
-
-void LineLayout::UncommittedContent::trim(unsigned newSize)
-{
-    for (auto i = m_uncommittedRuns.size(); i--;)
-        m_width -= m_uncommittedRuns[i].logicalWidth;
-    m_uncommittedRuns.shrink(newSize);
-}
-
-
-}
-}
-
-#endif

Deleted: trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h (252862 => 252863)


--- trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h	2019-11-25 16:19:42 UTC (rev 252862)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h	2019-11-25 17:29:31 UTC (rev 252863)
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2019 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
-
-#include "InlineLine.h"
-#include <wtf/IsoMalloc.h>
-
-namespace WebCore {
-namespace Layout {
-
-class LineLayout {
-public:
-    LineLayout(const InlineFormattingContext&, const InlineItems&);
-
-    struct PartialContent {
-        // This will potentially gain some more members. 
-        unsigned length;
-    };
-    struct LineContent {
-        Optional<unsigned> trailingInlineItemIndex;
-        Optional<PartialContent> trailingPartialContent;
-        Vector<WeakPtr<InlineItem>> floats;
-        const Line::RunList runList;
-        const LineBox lineBox;
-    };
-    LineContent layout(Line&, unsigned leadingInlineItemIndex, Optional<PartialContent> leadingPartialContent);
-
-    struct Run {
-        const InlineItem& inlineItem;
-        LayoutUnit logicalWidth;
-    };
-
-    using RunList = Vector<Run, 30>;
-
-private:
-    const InlineFormattingContext& formattingContext() const { return m_inlineFormattingContext; }
-    enum class IsEndOfLine { No, Yes };
-    IsEndOfLine placeInlineItem(Line&, const InlineItem&);
-    void commitPendingContent(Line&);
-    LineContent close(Line&, unsigned leadingInlineItemIndex);
-    bool shouldProcessUncommittedContent(const InlineItem&) const;
-    IsEndOfLine processUncommittedContent(Line&);
-    
-    struct UncommittedContent {
-        void add(const InlineItem&, LayoutUnit logicalWidth);
-        void reset();
-        void trim(unsigned newSize);
-
-        RunList& runs() { return m_uncommittedRuns; }
-        const RunList& runs() const { return m_uncommittedRuns; }
-        bool isEmpty() const { return m_uncommittedRuns.isEmpty(); }
-        unsigned size() const { return m_uncommittedRuns.size(); }
-        LayoutUnit width() const { return m_width; }
-
-    private:
-        RunList m_uncommittedRuns;
-        LayoutUnit m_width;
-    };
-
-    const InlineFormattingContext& m_inlineFormattingContext;
-    const InlineItems& m_inlineItems;
-    UncommittedContent m_uncommittedContent;
-    unsigned m_committedInlineItemCount { 0 };
-    Vector<WeakPtr<InlineItem>> m_floats;
-    std::unique_ptr<InlineTextItem> m_leadingPartialTextItem;
-    std::unique_ptr<InlineTextItem> m_trailingPartialTextItem;
-    Optional<unsigned> m_overflowTextLength;
-};
-
-}
-}
-#endif

Copied: trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp (from rev 252862, trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp) (0 => 252863)


--- trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp	                        (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.cpp	2019-11-25 17:29:31 UTC (rev 252863)
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LineLayoutContext.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "InlineLineBreaker.h"
+#include "LayoutBox.h"
+#include "TextUtil.h"
+
+namespace WebCore {
+namespace Layout {
+
+static LayoutUnit inlineItemWidth(const FormattingContext& formattingContext, const InlineItem& inlineItem, LayoutUnit contentLogicalLeft)
+{
+    if (inlineItem.isForcedLineBreak())
+        return 0;
+
+    if (is<InlineTextItem>(inlineItem)) {
+        auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
+        if (auto contentWidth = inlineTextItem.width())
+            return *contentWidth;
+        auto end = inlineTextItem.isCollapsible() ? inlineTextItem.start() + 1 : inlineTextItem.end();
+        return TextUtil::width(inlineTextItem.layoutBox(), inlineTextItem.start(), end, contentLogicalLeft);
+    }
+
+    auto& layoutBox = inlineItem.layoutBox();
+    auto& boxGeometry = formattingContext.geometryForBox(layoutBox);
+
+    if (layoutBox.isFloatingPositioned())
+        return boxGeometry.marginBoxWidth();
+
+    if (layoutBox.replaced())
+        return boxGeometry.width();
+
+    if (inlineItem.isContainerStart())
+        return boxGeometry.marginStart() + boxGeometry.borderLeft() + boxGeometry.paddingLeft().valueOr(0);
+
+    if (inlineItem.isContainerEnd())
+        return boxGeometry.marginEnd() + boxGeometry.borderRight() + boxGeometry.paddingRight().valueOr(0);
+
+    // Non-replaced inline box (e.g. inline-block)
+    return boxGeometry.width();
+}
+
+void LineLayoutContext::UncommittedContent::add(const InlineItem& inlineItem, LayoutUnit logicalWidth)
+{
+    m_uncommittedRuns.append({ inlineItem, logicalWidth });
+    m_width += logicalWidth;
+}
+
+void LineLayoutContext::UncommittedContent::reset()
+{
+    m_uncommittedRuns.clear();
+    m_width = 0;
+}
+
+LineLayoutContext::LineLayoutContext(const InlineFormattingContext& inlineFormattingContext, const InlineItems& inlineItems)
+    : m_inlineFormattingContext(inlineFormattingContext)
+    , m_inlineItems(inlineItems)
+{
+}
+
+LineLayoutContext::LineContent LineLayoutContext::layoutLine(Line& line, unsigned leadingInlineItemIndex, Optional<PartialContent> leadingPartialContent)
+{
+    auto initialize = [&] {
+        m_committedInlineItemCount = 0;
+        m_uncommittedContent.reset();
+        m_leadingPartialTextItem = { };
+        m_trailingPartialTextItem = { };
+        m_overflowTextLength = { };
+    };
+    initialize();
+    // Iterate through the inline content and place the inline boxes on the current line.
+    // Start with the partial leading text from the previous line.
+    auto firstNonPartialInlineItemIndex = leadingInlineItemIndex;
+    if (leadingPartialContent) {
+        // Handle partial inline item (split text from the previous line).
+        auto& leadingTextItem = m_inlineItems[leadingInlineItemIndex];
+        RELEASE_ASSERT(leadingTextItem->isText());
+        // Construct a partial leading inline item.
+        ASSERT(!m_leadingPartialTextItem);
+        m_leadingPartialTextItem = downcast<InlineTextItem>(*leadingTextItem).right(leadingPartialContent->length);
+        if (placeInlineItem(line, *m_leadingPartialTextItem) == IsEndOfLine::Yes)
+            return close(line, leadingInlineItemIndex);
+        ++firstNonPartialInlineItemIndex;
+    }
+
+    for (auto inlineItemIndex = firstNonPartialInlineItemIndex; inlineItemIndex < m_inlineItems.size(); ++inlineItemIndex) {
+        // FIXME: We should not need to re-measure the dropped, uncommitted content when re-using them on the next line.
+        if (placeInlineItem(line, *m_inlineItems[inlineItemIndex]) == IsEndOfLine::Yes)
+            return close(line, leadingInlineItemIndex);
+    }
+    // Check the uncommitted content whether they fit now that we know we are at a commit boundary.
+    if (!m_uncommittedContent.isEmpty())
+        processUncommittedContent(line);
+    return close(line, leadingInlineItemIndex);
+}
+
+void LineLayoutContext::commitPendingContent(Line& line)
+{
+    if (m_uncommittedContent.isEmpty())
+        return;
+    m_committedInlineItemCount += m_uncommittedContent.size();
+    for (auto& uncommittedRun : m_uncommittedContent.runs())
+        line.append(uncommittedRun.inlineItem, uncommittedRun.logicalWidth);
+    m_uncommittedContent.reset();
+}
+
+LineLayoutContext::LineContent LineLayoutContext::close(Line& line, unsigned leadingInlineItemIndex)
+{
+    ASSERT(m_committedInlineItemCount || line.hasIntrusiveFloat());
+    m_uncommittedContent.reset();
+    if (!m_committedInlineItemCount)
+        return LineContent { { }, { }, WTFMove(m_floats), line.close(), line.lineBox() };
+
+    Optional<PartialContent> overflowContent;
+    if (m_overflowTextLength)
+        overflowContent = PartialContent { *m_overflowTextLength };
+    auto trailingInlineItemIndex = leadingInlineItemIndex + m_committedInlineItemCount - 1;
+
+    auto isLastLineWithInlineContent = [&] {
+        if (overflowContent)
+            return Line::IsLastLineWithInlineContent::No;
+        // Skip floats backwards to see if this is going to be the last line with inline content.
+        for (auto i = m_inlineItems.size(); i--;) {
+            if (!m_inlineItems[i]->isFloat())
+                return i == trailingInlineItemIndex ? Line::IsLastLineWithInlineContent::Yes : Line::IsLastLineWithInlineContent::No;
+        }
+        // There has to be at least one non-float item.
+        ASSERT_NOT_REACHED();
+        return Line::IsLastLineWithInlineContent::No;
+    };
+
+    return LineContent { trailingInlineItemIndex, overflowContent, WTFMove(m_floats), line.close(isLastLineWithInlineContent()), line.lineBox() };
+}
+
+LineLayoutContext::IsEndOfLine LineLayoutContext::placeInlineItem(Line& line, const InlineItem& inlineItem)
+{
+    auto currentLogicalRight = line.lineBox().logicalRight();
+    auto itemLogicalWidth = inlineItemWidth(formattingContext(), inlineItem, currentLogicalRight);
+
+    // Floats are special, they are intrusive but they don't really participate in the line layout context.
+    if (inlineItem.isFloat()) {
+        // FIXME: It gets a bit more complicated when there's some uncommitted content whether they should be added to the current line
+        // e.g. text_content<div style="float: left"></div>continuous_text_content
+        // Not sure what to do when the float takes up the available space and we've got continuous content. Browser engines don't agree.
+        // Let's just commit the pending content and try placing the float for now.
+        if (!m_uncommittedContent.isEmpty()) {
+            if (processUncommittedContent(line) == IsEndOfLine::Yes)
+                return IsEndOfLine::Yes;
+        }
+        auto lineIsConsideredEmpty = line.isVisuallyEmpty() && !line.hasIntrusiveFloat();
+        if (LineBreaker().shouldWrapFloatBox(itemLogicalWidth, line.availableWidth() + line.trailingTrimmableWidth(), lineIsConsideredEmpty))
+            return IsEndOfLine::Yes;
+
+        // This float can sit on the current line.
+        auto& floatBox = inlineItem.layoutBox();
+        // Shrink available space for current line and move existing inline runs.
+        floatBox.isLeftFloatingPositioned() ? line.moveLogicalLeft(itemLogicalWidth) : line.moveLogicalRight(itemLogicalWidth);
+        m_floats.append(makeWeakPtr(inlineItem));
+        ++m_committedInlineItemCount;
+        line.setHasIntrusiveFloat();
+        return IsEndOfLine::No;
+    }
+    // Forced line breaks are also special.
+    if (inlineItem.isForcedLineBreak()) {
+        auto isEndOfLine = !m_uncommittedContent.isEmpty() ? processUncommittedContent(line) : IsEndOfLine::No;
+        // When the uncommitted content fits(or the line is empty), add the line break to this line as well.
+        if (isEndOfLine == IsEndOfLine::No) {
+            m_uncommittedContent.add(inlineItem, itemLogicalWidth);
+            commitPendingContent(line);
+        }
+        return IsEndOfLine::Yes;
+    }
+    //
+    auto isEndOfLine = IsEndOfLine::No;
+    if (!m_uncommittedContent.isEmpty() && shouldProcessUncommittedContent(inlineItem))
+        isEndOfLine = processUncommittedContent(line);
+    // The current item might fit as well.
+    if (isEndOfLine == IsEndOfLine::No)
+        m_uncommittedContent.add(inlineItem, itemLogicalWidth);
+    return isEndOfLine;
+}
+
+LineLayoutContext::IsEndOfLine LineLayoutContext::processUncommittedContent(Line& line)
+{
+    // Check if the pending content fits.
+    auto lineIsConsideredEmpty = line.isVisuallyEmpty() && !line.hasIntrusiveFloat();
+    auto breakingContext = LineBreaker().breakingContextForInlineContent(m_uncommittedContent.runs(), m_uncommittedContent.width(), line.availableWidth(), lineIsConsideredEmpty);
+    // The uncommitted content can fully, partially fit the current line (commit/partial commit) or not at all (reset).
+    if (breakingContext.contentBreak == LineBreaker::BreakingContext::ContentBreak::Keep)
+        commitPendingContent(line);
+    else if (breakingContext.contentBreak == LineBreaker::BreakingContext::ContentBreak::Split) {
+        ASSERT(breakingContext.trailingPartialContent);
+        ASSERT(m_uncommittedContent.runs()[breakingContext.trailingPartialContent->runIndex].inlineItem.isText());
+        // Turn the uncommitted trailing run into a partial trailing run.
+        auto overflowInlineTextItemIndex = breakingContext.trailingPartialContent->runIndex;
+        auto& overflowInlineTextItem = downcast<InlineTextItem>(m_uncommittedContent.runs()[overflowInlineTextItemIndex].inlineItem);
+
+        // Construct a partial trailing inline run.
+        ASSERT(!m_trailingPartialTextItem);
+        auto trailingContentLength = breakingContext.trailingPartialContent->length;
+        m_trailingPartialTextItem = overflowInlineTextItem.left(trailingContentLength);
+        m_overflowTextLength = overflowInlineTextItem.length() - trailingContentLength;
+        // Keep the non-overflow part of the uncommitted runs and add the trailing partial content.
+        m_uncommittedContent.trim(overflowInlineTextItemIndex);
+        m_uncommittedContent.add(*m_trailingPartialTextItem, breakingContext.trailingPartialContent->logicalWidth);
+        commitPendingContent(line);
+    } else if (breakingContext.contentBreak == LineBreaker::BreakingContext::ContentBreak::Wrap)
+        m_uncommittedContent.reset();
+    else
+        ASSERT_NOT_REACHED();
+    return breakingContext.contentBreak == LineBreaker::BreakingContext::ContentBreak::Keep ? IsEndOfLine::No :IsEndOfLine::Yes;
+}
+
+bool LineLayoutContext::shouldProcessUncommittedContent(const InlineItem& inlineItem) const
+{
+    // https://drafts.csswg.org/css-text-3/#line-break-details
+    // Figure out if the new incoming content puts the uncommitted content on commit boundary.
+    // e.g. <span>continuous</span> <- uncomitted content ->
+    // [inline container start][text content][inline container end]
+    // An incoming <img> box would enable us to commit the "<span>continuous</span>" content
+    // while additional text content would not.
+    ASSERT(!inlineItem.isFloat() && !inlineItem.isForcedLineBreak());
+    ASSERT(!m_uncommittedContent.isEmpty());
+
+    auto* lastUncomittedContent = &m_uncommittedContent.runs().last().inlineItem;
+    if (inlineItem.isText()) {
+        // any content' ' -> whitespace is always a commit boundary.
+        if (downcast<InlineTextItem>(inlineItem).isWhitespace())
+            return true;
+        // texttext -> continuous content.
+        // ' 'text -> commit boundary.
+        if (lastUncomittedContent->isText())
+            return downcast<InlineTextItem>(*lastUncomittedContent).isWhitespace();
+        // <span>text -> the inline container start and the text content form an unbreakable continuous content.
+        if (lastUncomittedContent->isContainerStart())
+            return false;
+        // </span>text -> need to check what's before the </span>.
+        // text</span>text -> continuous content
+        // <img></span>text -> commit bounday
+        if (lastUncomittedContent->isContainerEnd()) {
+            auto& runs = m_uncommittedContent.runs();
+            // text</span><span></span></span>text -> check all the way back until we hit either a box or some text
+            for (auto i = m_uncommittedContent.size(); i--;) {
+                auto& previousInlineItem = runs[i].inlineItem;
+                if (previousInlineItem.isContainerStart() || previousInlineItem.isContainerEnd())
+                    continue;
+                ASSERT(previousInlineItem.isText() || previousInlineItem.isBox());
+                lastUncomittedContent = &previousInlineItem;
+                break;
+            }
+            // Did not find any content (e.g. <span></span>text)
+            if (lastUncomittedContent->isContainerEnd())
+                return false;
+        }
+        // <img>text -> the inline box is on a commit boundary.
+        if (lastUncomittedContent->isBox())
+            return true;
+        ASSERT_NOT_REACHED();
+    }
+
+    if (inlineItem.isBox()) {
+        // <span><img> -> the inline container start and the content form an unbreakable continuous content.
+        if (lastUncomittedContent->isContainerStart())
+            return false;
+        // </span><img> -> ok to commit the </span>.
+        if (lastUncomittedContent->isContainerEnd())
+            return true;
+        // <img>text and <img><img> -> these combinations are ok to commit.
+        if (lastUncomittedContent->isText() || lastUncomittedContent->isBox())
+            return true;
+        ASSERT_NOT_REACHED();
+    }
+
+    if (inlineItem.isContainerStart() || inlineItem.isContainerEnd()) {
+        // <span><span> or </span><span> -> can't commit the previous content yet.
+        if (lastUncomittedContent->isContainerStart() || lastUncomittedContent->isContainerEnd())
+            return false;
+        // ' '<span> -> let's commit the whitespace
+        // text<span> -> but not yet the non-whitespace; we need to know what comes next (e.g. text<span>text or text<span><img>).
+        if (lastUncomittedContent->isText())
+            return downcast<InlineTextItem>(*lastUncomittedContent).isWhitespace();
+        // <img><span> -> it's ok to commit the inline box content.
+        // <img></span> -> the inline box and the closing inline container form an unbreakable continuous content.
+        if (lastUncomittedContent->isBox())
+            return inlineItem.isContainerStart();
+        ASSERT_NOT_REACHED();
+    }
+
+    ASSERT_NOT_REACHED();
+    return true;
+}
+
+void LineLayoutContext::UncommittedContent::trim(unsigned newSize)
+{
+    for (auto i = m_uncommittedRuns.size(); i--;)
+        m_width -= m_uncommittedRuns[i].logicalWidth;
+    m_uncommittedRuns.shrink(newSize);
+}
+
+
+}
+}
+
+#endif

Copied: trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h (from rev 252862, trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h) (0 => 252863)


--- trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h	                        (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/LineLayoutContext.h	2019-11-25 17:29:31 UTC (rev 252863)
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "InlineLine.h"
+
+namespace WebCore {
+namespace Layout {
+
+class LineLayoutContext {
+public:
+    LineLayoutContext(const InlineFormattingContext&, const InlineItems&);
+
+    struct PartialContent {
+        // This will potentially gain some more members. 
+        unsigned length;
+    };
+    struct LineContent {
+        Optional<unsigned> trailingInlineItemIndex;
+        Optional<PartialContent> trailingPartialContent;
+        Vector<WeakPtr<InlineItem>> floats;
+        const Line::RunList runList;
+        const LineBox lineBox;
+    };
+    LineContent layoutLine(Line&, unsigned leadingInlineItemIndex, Optional<PartialContent> leadingPartialContent);
+
+    struct Run {
+        const InlineItem& inlineItem;
+        LayoutUnit logicalWidth;
+    };
+
+    using RunList = Vector<Run, 30>;
+
+private:
+    const InlineFormattingContext& formattingContext() const { return m_inlineFormattingContext; }
+    enum class IsEndOfLine { No, Yes };
+    IsEndOfLine placeInlineItem(Line&, const InlineItem&);
+    void commitPendingContent(Line&);
+    LineContent close(Line&, unsigned leadingInlineItemIndex);
+    bool shouldProcessUncommittedContent(const InlineItem&) const;
+    IsEndOfLine processUncommittedContent(Line&);
+    
+    struct UncommittedContent {
+        void add(const InlineItem&, LayoutUnit logicalWidth);
+        void reset();
+        void trim(unsigned newSize);
+
+        RunList& runs() { return m_uncommittedRuns; }
+        const RunList& runs() const { return m_uncommittedRuns; }
+        bool isEmpty() const { return m_uncommittedRuns.isEmpty(); }
+        unsigned size() const { return m_uncommittedRuns.size(); }
+        LayoutUnit width() const { return m_width; }
+
+    private:
+        RunList m_uncommittedRuns;
+        LayoutUnit m_width;
+    };
+
+    const InlineFormattingContext& m_inlineFormattingContext;
+    const InlineItems& m_inlineItems;
+    UncommittedContent m_uncommittedContent;
+    unsigned m_committedInlineItemCount { 0 };
+    Vector<WeakPtr<InlineItem>> m_floats;
+    std::unique_ptr<InlineTextItem> m_leadingPartialTextItem;
+    std::unique_ptr<InlineTextItem> m_trailingPartialTextItem;
+    Optional<unsigned> m_overflowTextLength;
+};
+
+}
+}
+#endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to