[LFC][IFC] Add generic inline run generator.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Oct 2018 15:52:08 +0000 (15:52 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 19 Oct 2018 15:52:08 +0000 (15:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190696

Reviewed by Antti Koivisto.

InlineRunProvider turns the following inline content ->

    <span>foo<span>bar</span></span>
    <img src="broken.jpg"><span>hello world</span>

into a set of runs ->

    <foobar><image box><hello>< ><world>

Note that a text run can overlap multiple inline elements. InlineRunProvider::Run only stores a reference to
the first inline element (continuous content can be accessed by iterating through the InlineContent ListHashSet).
These runs are the input to the line breaking algoritm.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::layout const):
* layout/inlineformatting/InlineFormattingState.h:
(WebCore::Layout::InlineFormattingState::inlineContent):
* layout/inlineformatting/InlineItem.h: Added.
(WebCore::Layout::InlineItem::layoutBox const):
(WebCore::Layout::InlineItem::style const):
(WebCore::Layout::InlineItemHashFunctions::hash):
(WebCore::Layout::InlineItemHashFunctions::equal):
(WebCore::Layout::InlineItemHashTranslator::hash):
(WebCore::Layout::InlineItemHashTranslator::equal):
(WebCore::Layout::InlineItem::InlineItem):
(WebCore::Layout::InlineItem::type const):
(WebCore::Layout::InlineItem::textContent const):
* layout/inlineformatting/InlineRunProvider.cpp: Added.
(WebCore::Layout::InlineRunProvider::InlineRunProvider):
(WebCore::Layout::InlineRunProvider::append):
(WebCore::Layout::InlineRunProvider::insertBefore):
(WebCore::Layout::InlineRunProvider::remove):
(WebCore::Layout::isWhitespace):
(WebCore::Layout::isSoftLineBreak):
(WebCore::Layout::InlineRunProvider::isContinousContent):
(WebCore::Layout::InlineRunProvider::processInlineTextItem):
(WebCore::Layout::InlineRunProvider::moveToNextNonWhitespacePosition):
(WebCore::Layout::InlineRunProvider::moveToNextBreakablePosition):
* layout/inlineformatting/InlineRunProvider.h: Added.
(WebCore::Layout::InlineRunProvider::Run::type const):
(WebCore::Layout::InlineRunProvider::Run::isText const):
(WebCore::Layout::InlineRunProvider::Run::isWhitespace const):
(WebCore::Layout::InlineRunProvider::Run::isNonWhitespace const):
(WebCore::Layout::InlineRunProvider::Run::isLineBreak const):
(WebCore::Layout::InlineRunProvider::Run::isBox const):
(WebCore::Layout::InlineRunProvider::Run::isFloat const):
(WebCore::Layout::InlineRunProvider::Run::TextContext::start const):
(WebCore::Layout::InlineRunProvider::Run::TextContext::length const):
(WebCore::Layout::InlineRunProvider::Run::TextContext::isCollapsed const):
(WebCore::Layout::InlineRunProvider::Run::TextContext::setStart):
(WebCore::Layout::InlineRunProvider::Run::TextContext::setLength):
(WebCore::Layout::InlineRunProvider::Run::textContext const):
(WebCore::Layout::InlineRunProvider::Run::style const):
(WebCore::Layout::InlineRunProvider::Run::inlineItem const):
(WebCore::Layout::InlineRunProvider::runs const):
(WebCore::Layout::InlineRunProvider::Run::createBoxRun):
(WebCore::Layout::InlineRunProvider::Run::createFloatRun):
(WebCore::Layout::InlineRunProvider::Run::createSoftLineBreakRun):
(WebCore::Layout::InlineRunProvider::Run::createHardLineBreakRun):
(WebCore::Layout::InlineRunProvider::Run::createWhitespaceRun):
(WebCore::Layout::InlineRunProvider::Run::createNonWhitespaceRun):
(WebCore::Layout::InlineRunProvider::Run::Run):
(WebCore::Layout::InlineRunProvider::Run::TextContext::TextContext):
* layout/layouttree/LayoutBox.h:
(WebCore::Layout::Box::isLineBreakBox const):
* layout/layouttree/LayoutInlineBox.cpp:
(WebCore::Layout::InlineBox::InlineBox):
* layout/layouttree/LayoutInlineBox.h:
(WebCore::Layout::InlineBox::hasTextContent const):
(WebCore::Layout::InlineBox::textContent const):
* layout/layouttree/LayoutLineBreakBox.cpp: Copied from Source/WebCore/layout/layouttree/LayoutInlineBox.cpp.
(WebCore::Layout::LineBreakBox::LineBreakBox):
* layout/layouttree/LayoutLineBreakBox.h: Copied from Source/WebCore/layout/layouttree/LayoutInlineBox.cpp.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237286 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
Source/WebCore/layout/inlineformatting/InlineFormattingState.h
Source/WebCore/layout/inlineformatting/InlineItem.h [new file with mode: 0644]
Source/WebCore/layout/inlineformatting/InlineRunProvider.cpp [new file with mode: 0644]
Source/WebCore/layout/inlineformatting/InlineRunProvider.h [new file with mode: 0644]
Source/WebCore/layout/layouttree/LayoutBox.h
Source/WebCore/layout/layouttree/LayoutInlineBox.cpp
Source/WebCore/layout/layouttree/LayoutInlineBox.h
Source/WebCore/layout/layouttree/LayoutLineBreakBox.cpp [new file with mode: 0644]
Source/WebCore/layout/layouttree/LayoutLineBreakBox.h [new file with mode: 0644]

index d222558..de7960b 100644 (file)
@@ -1,3 +1,86 @@
+2018-10-19  Zalan Bujtas  <zalan@apple.com>
+
+        [LFC][IFC] Add generic inline run generator.
+        https://bugs.webkit.org/show_bug.cgi?id=190696
+
+        Reviewed by Antti Koivisto.
+
+        InlineRunProvider turns the following inline content ->
+
+            <span>foo<span>bar</span></span>
+            <img src="broken.jpg"><span>hello world</span>
+
+        into a set of runs ->
+
+            <foobar><image box><hello>< ><world>
+
+        Note that a text run can overlap multiple inline elements. InlineRunProvider::Run only stores a reference to
+        the first inline element (continuous content can be accessed by iterating through the InlineContent ListHashSet).
+        These runs are the input to the line breaking algoritm.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * layout/inlineformatting/InlineFormattingContext.cpp:
+        (WebCore::Layout::InlineFormattingContext::layout const):
+        * layout/inlineformatting/InlineFormattingState.h:
+        (WebCore::Layout::InlineFormattingState::inlineContent):
+        * layout/inlineformatting/InlineItem.h: Added.
+        (WebCore::Layout::InlineItem::layoutBox const):
+        (WebCore::Layout::InlineItem::style const):
+        (WebCore::Layout::InlineItemHashFunctions::hash):
+        (WebCore::Layout::InlineItemHashFunctions::equal):
+        (WebCore::Layout::InlineItemHashTranslator::hash):
+        (WebCore::Layout::InlineItemHashTranslator::equal):
+        (WebCore::Layout::InlineItem::InlineItem):
+        (WebCore::Layout::InlineItem::type const):
+        (WebCore::Layout::InlineItem::textContent const):
+        * layout/inlineformatting/InlineRunProvider.cpp: Added.
+        (WebCore::Layout::InlineRunProvider::InlineRunProvider):
+        (WebCore::Layout::InlineRunProvider::append):
+        (WebCore::Layout::InlineRunProvider::insertBefore):
+        (WebCore::Layout::InlineRunProvider::remove):
+        (WebCore::Layout::isWhitespace):
+        (WebCore::Layout::isSoftLineBreak):
+        (WebCore::Layout::InlineRunProvider::isContinousContent):
+        (WebCore::Layout::InlineRunProvider::processInlineTextItem):
+        (WebCore::Layout::InlineRunProvider::moveToNextNonWhitespacePosition):
+        (WebCore::Layout::InlineRunProvider::moveToNextBreakablePosition):
+        * layout/inlineformatting/InlineRunProvider.h: Added.
+        (WebCore::Layout::InlineRunProvider::Run::type const):
+        (WebCore::Layout::InlineRunProvider::Run::isText const):
+        (WebCore::Layout::InlineRunProvider::Run::isWhitespace const):
+        (WebCore::Layout::InlineRunProvider::Run::isNonWhitespace const):
+        (WebCore::Layout::InlineRunProvider::Run::isLineBreak const):
+        (WebCore::Layout::InlineRunProvider::Run::isBox const):
+        (WebCore::Layout::InlineRunProvider::Run::isFloat const):
+        (WebCore::Layout::InlineRunProvider::Run::TextContext::start const):
+        (WebCore::Layout::InlineRunProvider::Run::TextContext::length const):
+        (WebCore::Layout::InlineRunProvider::Run::TextContext::isCollapsed const):
+        (WebCore::Layout::InlineRunProvider::Run::TextContext::setStart):
+        (WebCore::Layout::InlineRunProvider::Run::TextContext::setLength):
+        (WebCore::Layout::InlineRunProvider::Run::textContext const):
+        (WebCore::Layout::InlineRunProvider::Run::style const):
+        (WebCore::Layout::InlineRunProvider::Run::inlineItem const):
+        (WebCore::Layout::InlineRunProvider::runs const):
+        (WebCore::Layout::InlineRunProvider::Run::createBoxRun):
+        (WebCore::Layout::InlineRunProvider::Run::createFloatRun):
+        (WebCore::Layout::InlineRunProvider::Run::createSoftLineBreakRun):
+        (WebCore::Layout::InlineRunProvider::Run::createHardLineBreakRun):
+        (WebCore::Layout::InlineRunProvider::Run::createWhitespaceRun):
+        (WebCore::Layout::InlineRunProvider::Run::createNonWhitespaceRun):
+        (WebCore::Layout::InlineRunProvider::Run::Run):
+        (WebCore::Layout::InlineRunProvider::Run::TextContext::TextContext):
+        * layout/layouttree/LayoutBox.h:
+        (WebCore::Layout::Box::isLineBreakBox const):
+        * layout/layouttree/LayoutInlineBox.cpp:
+        (WebCore::Layout::InlineBox::InlineBox):
+        * layout/layouttree/LayoutInlineBox.h:
+        (WebCore::Layout::InlineBox::hasTextContent const):
+        (WebCore::Layout::InlineBox::textContent const):
+        * layout/layouttree/LayoutLineBreakBox.cpp: Copied from Source/WebCore/layout/layouttree/LayoutInlineBox.cpp.
+        (WebCore::Layout::LineBreakBox::LineBreakBox):
+        * layout/layouttree/LayoutLineBreakBox.h: Copied from Source/WebCore/layout/layouttree/LayoutInlineBox.cpp.
+
 2018-10-19  Ali Juma  <ajuma@chromium.org>
 
         [IntersectionObserver] Handle zero-area intersections
index 8021ace..9a079f4 100644 (file)
@@ -1259,6 +1259,7 @@ layout/floats/FloatingState.cpp
 layout/inlineformatting/InlineFormattingContext.cpp
 layout/inlineformatting/InlineFormattingState.cpp
 layout/inlineformatting/InlineInvalidation.cpp
+layout/inlineformatting/InlineRunProvider.cpp
 layout/inlineformatting/textlayout/TextContentProvider.cpp
 layout/inlineformatting/textlayout/simple/SimpleTextRunGenerator.cpp
 layout/inlineformatting/textlayout/simple/SimpleLineBreaker.cpp
@@ -1267,6 +1268,7 @@ layout/layouttree/LayoutBox.cpp
 layout/layouttree/LayoutContainer.cpp
 layout/layouttree/LayoutInlineBox.cpp
 layout/layouttree/LayoutInlineContainer.cpp
+layout/layouttree/LayoutLineBreakBox.cpp
 layout/layouttree/LayoutReplaced.cpp
 layout/layouttree/LayoutTreeBuilder.cpp
 
index 876aab8..1236da7 100644 (file)
                6EE8A77310F803F3005A4A24 /* JSWebGLContextAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EE8A77110F803F3005A4A24 /* JSWebGLContextAttributes.h */; };
                6F222B761AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F222B751AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp */; };
                6F3E1F622136142000A65A08 /* FloatBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F3E1F612136141700A65A08 /* FloatBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               6F5217C72177F5A7006583BB /* InlineRunProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F5217C42177F5A6006583BB /* InlineRunProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6F7CA3C6208C2957002F29AB /* LayoutContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F7CA3C4208C2956002F29AB /* LayoutContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6F7CA3CA208C2B2E002F29AB /* InlineFormattingContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F7CA3C8208C2B2E002F29AB /* InlineFormattingContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6F995A151A70756200A735F4 /* WebGLSync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6F995A131A70756200A735F4 /* WebGLSync.cpp */; };
                6F995A381A70833700A735F4 /* JSWebGLTransformFeedback.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F995A2E1A70833700A735F4 /* JSWebGLTransformFeedback.h */; };
                6F995A3A1A70833700A735F4 /* JSWebGLVertexArrayObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 6F995A301A70833700A735F4 /* JSWebGLVertexArrayObject.h */; };
                6FA4454E898F2FC168BC38C1 /* JSBeforeUnloadEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 29E04A27BED2F81F98E9022B /* JSBeforeUnloadEvent.h */; };
+               6FE7CFA22177EEF2005B1573 /* InlineItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FE7CFA02177EEF1005B1573 /* InlineItem.h */; };
+               6FE7CFA42177EF10005B1573 /* LayoutLineBreakBox.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FE7CFA32177EF10005B1573 /* LayoutLineBreakBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6FFDC442212EFF1700A9CA91 /* FloatAvoider.h in Headers */ = {isa = PBXBuildFile; fileRef = 6FFDC440212EFF1600A9CA91 /* FloatAvoider.h */; settings = {ATTRIBUTES = (Private, ); }; };
                709A01FE1E3D0BDD006B0D4C /* ModuleFetchFailureKind.h in Headers */ = {isa = PBXBuildFile; fileRef = 709A01FD1E3D0BCC006B0D4C /* ModuleFetchFailureKind.h */; settings = {ATTRIBUTES = (Private, ); }; };
                71025ECD1F99F0CE004A250C /* AnimationTimeline.h in Headers */ = {isa = PBXBuildFile; fileRef = 71025EC71F99F096004A250C /* AnimationTimeline.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6F222B751AB52D8A0094651A /* WebGLVertexArrayObjectBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebGLVertexArrayObjectBase.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>"; };
+               6F5217C42177F5A6006583BB /* InlineRunProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineRunProvider.h; sourceTree = "<group>"; };
+               6F5217C62177F5A6006583BB /* InlineRunProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InlineRunProvider.cpp; sourceTree = "<group>"; };
                6F73918C2106CEDD006AF262 /* LayoutUnits.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutUnits.h; sourceTree = "<group>"; };
                6F7CA3C4208C2956002F29AB /* LayoutContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayoutContext.h; sourceTree = "<group>"; };
                6F7CA3C5208C2956002F29AB /* LayoutContext.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutContext.cpp; sourceTree = "<group>"; };
                6FCD19C120F9727A00FD4529 /* TextContentProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TextContentProvider.h; sourceTree = "<group>"; };
                6FCD19C720F9727D00FD4529 /* TextContentProvider.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TextContentProvider.cpp; sourceTree = "<group>"; };
                6FCF975220F02B3500214960 /* Runs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Runs.h; sourceTree = "<group>"; };
+               6FE7CFA02177EEF1005B1573 /* InlineItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineItem.h; sourceTree = "<group>"; };
+               6FE7CFA32177EF10005B1573 /* LayoutLineBreakBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LayoutLineBreakBox.h; sourceTree = "<group>"; };
+               6FE7CFA52177F069005B1573 /* LayoutLineBreakBox.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LayoutLineBreakBox.cpp; sourceTree = "<group>"; };
                6FFDC43E212EFF1600A9CA91 /* FloatAvoider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FloatAvoider.cpp; sourceTree = "<group>"; };
                6FFDC440212EFF1600A9CA91 /* FloatAvoider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FloatAvoider.h; sourceTree = "<group>"; };
                709A01FD1E3D0BCC006B0D4C /* ModuleFetchFailureKind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleFetchFailureKind.h; sourceTree = "<group>"; };
                                1199FA4E208E3899002358CC /* LayoutInlineContainer.cpp */,
                                1199FA4D208E3899002358CC /* LayoutInlineContainer.h */,
                                11100FC72092764C0081AA6C /* LayoutIterator.h */,
+                               6FE7CFA52177F069005B1573 /* LayoutLineBreakBox.cpp */,
+                               6FE7CFA32177EF10005B1573 /* LayoutLineBreakBox.h */,
                                111C615720AD1AE1005B82FA /* LayoutReplaced.cpp */,
                                111C615620AD1AE1005B82FA /* LayoutReplaced.h */,
                                11100FD5209514DE0081AA6C /* LayoutTreeBuilder.cpp */,
                                115CFA7C208B8E10001E6991 /* InlineFormattingState.h */,
                                1123AFDD209ABBBA00736ACC /* InlineInvalidation.cpp */,
                                1123AFDC209ABBBA00736ACC /* InlineInvalidation.h */,
+                               6FE7CFA02177EEF1005B1573 /* InlineItem.h */,
+                               6F5217C62177F5A6006583BB /* InlineRunProvider.cpp */,
+                               6F5217C42177F5A6006583BB /* InlineRunProvider.h */,
                        );
                        path = inlineformatting;
                        sourceTree = "<group>";
                                6F7CA3CA208C2B2E002F29AB /* InlineFormattingContext.h in Headers */,
                                115CFA7E208B8E10001E6991 /* InlineFormattingState.h in Headers */,
                                11310CF820BA4A6A0065A8D0 /* InlineInvalidation.h in Headers */,
+                               6FE7CFA22177EEF2005B1573 /* InlineItem.h in Headers */,
                                BCE789161120D6080060ECE5 /* InlineIterator.h in Headers */,
+                               6F5217C72177F5A7006583BB /* InlineRunProvider.h in Headers */,
                                AA4C3A770B2B1679002334A2 /* InlineStyleSheetOwner.h in Headers */,
                                BCEA485A097D93020094C9E4 /* InlineTextBox.h in Headers */,
                                1C010701192594DF008A4201 /* InlineTextBoxStyle.h in Headers */,
                                1199FA53208E38D3002358CC /* LayoutInlineBox.h in Headers */,
                                1199FA4F208E3899002358CC /* LayoutInlineContainer.h in Headers */,
                                11310CF420BA4A3D0065A8D0 /* LayoutIterator.h in Headers */,
+                               6FE7CFA42177EF10005B1573 /* LayoutLineBreakBox.h in Headers */,
                                931D72F615FE695300C4C07E /* LayoutMilestones.h in Headers */,
                                141DC051164834B900371E5A /* LayoutPoint.h in Headers */,
                                141DC053164834B900371E5A /* LayoutRect.h in Headers */,
index a5bf1ad..7de23c1 100644 (file)
@@ -70,8 +70,8 @@ void InlineFormattingContext::layout(LayoutContext& layoutContext, FormattingSta
         }
         auto& inlineBox = downcast<InlineBox>(*layoutBox);
         // Only text content at this point.
-        if (inlineBox.textContent())
-            textContentProvider.appendText(*inlineBox.textContent(), inlineBox.style(), true);
+        if (inlineBox.hasTextContent())
+            textContentProvider.appendText(inlineBox.textContent(), inlineBox.style(), true);
 
         for (; layoutBox; layoutBox = layoutBox->containingBlock()) {
             if (layoutBox == &formattingRoot) {
index ef26277..caace2e 100644 (file)
 #if ENABLE(LAYOUT_FORMATTING_CONTEXT)
 
 #include "FormattingState.h"
+#include "InlineItem.h"
 #include "Runs.h"
 #include <wtf/IsoMalloc.h>
 
 namespace WebCore {
-
 namespace Layout {
 
 // InlineFormattingState holds the state for a particular inline formatting context tree.
@@ -42,11 +42,13 @@ public:
     InlineFormattingState(Ref<FloatingState>&&, const LayoutContext&);
     virtual ~InlineFormattingState();
 
+    InlineContent& inlineContent() { return m_inlineContent; }
     // This is temporary. We need to construct a display tree context for inlines.
     void addLayoutRuns(Vector<LayoutRun>&& layoutRuns) { m_layoutRuns = WTFMove(layoutRuns); }
     const Vector<LayoutRun>& layoutRuns() const { return m_layoutRuns; }
 
 private:
+    InlineContent m_inlineContent;
     Vector<LayoutRun> m_layoutRuns;
 };
 
diff --git a/Source/WebCore/layout/inlineformatting/InlineItem.h b/Source/WebCore/layout/inlineformatting/InlineItem.h
new file mode 100644 (file)
index 0000000..bfcb9c8
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2018 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 "LayoutBox.h"
+#include "LayoutInlineBox.h"
+#include "LayoutLineBreakBox.h"
+
+namespace WebCore {
+namespace Layout {
+
+class InlineItem {
+public:
+    InlineItem(const Box& layoutBox);
+
+    enum class Type { Text, HardLineBreak, InlineBox, Float };
+    Type type() const;
+    const Box& layoutBox() const { return m_layoutBox; }
+    const RenderStyle& style() const { return m_layoutBox.style(); }
+    String textContent() const;
+
+private:
+    const Box& m_layoutBox;
+};
+
+// FIXME: Fix HashSet/ListHashSet to support smart pointer types.
+struct InlineItemHashFunctions {
+    static unsigned hash(const std::unique_ptr<InlineItem>& key) { return PtrHash<InlineItem*>::hash(key.get()); }
+    static bool equal(const std::unique_ptr<InlineItem>& a, const std::unique_ptr<InlineItem>& b) { return a.get() == b.get(); }
+};
+
+struct InlineItemHashTranslator {
+    static unsigned hash(const InlineItem& key) { return PtrHash<const InlineItem*>::hash(&key); }
+    static bool equal(const std::unique_ptr<InlineItem>& a, const InlineItem& b) { return a.get() == &b; }
+};
+using InlineContent = ListHashSet<std::unique_ptr<InlineItem>, InlineItemHashFunctions>;
+
+inline InlineItem::InlineItem(const Box& layoutBox)
+    : m_layoutBox(layoutBox)
+{
+}
+
+inline InlineItem::Type InlineItem::type() const
+{
+    if (is<InlineBox>(m_layoutBox) && downcast<InlineBox>(m_layoutBox).hasTextContent())
+        return Type::Text;
+
+    if (is<LineBreakBox>(m_layoutBox))
+        return Type::HardLineBreak;
+
+    if (m_layoutBox.isFloatingPositioned())
+        return Type::Float;
+
+    ASSERT(m_layoutBox.isInlineLevelBox());
+    return Type::InlineBox;
+}
+
+inline String InlineItem::textContent() const
+{
+    if (type() != Type::Text)
+        return { };
+
+    return downcast<InlineBox>(m_layoutBox).textContent();
+}
+
+}
+}
+#endif
diff --git a/Source/WebCore/layout/inlineformatting/InlineRunProvider.cpp b/Source/WebCore/layout/inlineformatting/InlineRunProvider.cpp
new file mode 100644 (file)
index 0000000..9c1658a
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2018 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 "InlineRunProvider.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "BreakLines.h"
+#include "LayoutInlineBox.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(InlineRunProvider);
+
+InlineRunProvider::InlineRunProvider(InlineFormattingState& inlineFormattingState)
+    : m_inlineFormattingState(inlineFormattingState)
+{
+}
+
+void InlineRunProvider::append(const Box& layoutBox)
+{
+    auto inlineItem = std::make_unique<InlineItem>(layoutBox);
+
+    // Special case text item. Texts can overlap multiple items. <span>foo</span><span>bar</span>
+    switch (inlineItem->type()) {
+    case InlineItem::Type::Text:
+        processInlineTextItem(*inlineItem);
+        break;
+    case InlineItem::Type::HardLineBreak:
+        m_inlineRuns.append(InlineRunProvider::Run::createHardLineBreakRun(*inlineItem));
+        break;
+    case InlineItem::Type::InlineBox:
+        m_inlineRuns.append(InlineRunProvider::Run::createBoxRun(*inlineItem));
+        break;
+    case InlineItem::Type::Float:
+        m_inlineRuns.append(InlineRunProvider::Run::createFloatRun(*inlineItem));
+        break;
+    default:
+        ASSERT_NOT_IMPLEMENTED_YET();
+    }
+
+    m_inlineFormattingState.inlineContent().add(WTFMove(inlineItem));
+}
+
+void InlineRunProvider::insertBefore(const Box&, const Box&)
+{
+}
+
+void InlineRunProvider::remove(const Box&)
+{
+}
+
+static inline bool isWhitespace(char character, bool preserveNewline)
+{
+    return character == ' ' || character == '\t' || (character == '\n' && !preserveNewline);
+}
+
+static inline bool isSoftLineBreak(char character, bool preserveNewline)
+{
+    return preserveNewline && character == '\n';
+}
+
+bool InlineRunProvider::isContinousContent(InlineRunProvider::Run::Type newRunType, const InlineItem& newInlineItem)
+{
+    if (m_inlineRuns.isEmpty())
+        return false;
+
+    auto& lastRun = m_inlineRuns.last();
+    // Same element, check type only.
+    if (&newInlineItem == &lastRun.inlineItem())
+        return newRunType == lastRun.type();
+
+    // This new run is from a different inline box.
+    // FIXME: check style.
+    if (newRunType == InlineRunProvider::Run::Type::NonWhitespace && lastRun.isNonWhitespace())
+        return true;
+
+    if (newRunType == InlineRunProvider::Run::Type::Whitespace && lastRun.isWhitespace())
+        return newInlineItem.style().collapseWhiteSpace() == lastRun.style().collapseWhiteSpace();
+
+    return false;
+}
+
+void InlineRunProvider::processInlineTextItem(const InlineItem& inlineItem)
+{
+    // We need to reset the run iterator when the text content is not continuous.
+    // <span>foo</span><img src=""><span>bar</span> (FIXME: floats?)
+    if (!m_inlineRuns.isEmpty() && !m_inlineRuns.last().isText()) {
+        m_lineBreakIterator.resetPriorContext();
+        m_lineBreakIterator.resetStringAndReleaseIterator("", "", LineBreakIteratorMode::Default);
+    }
+
+    auto& style = inlineItem.style();
+    auto text = inlineItem.textContent();
+    ItemPosition currentItemPosition = 0;
+    while (currentItemPosition < text.length()) {
+
+        // Soft linebreak?
+        if (isSoftLineBreak(text[currentItemPosition], style.preserveNewline())) {
+            m_inlineRuns.append(InlineRunProvider::Run::createSoftLineBreakRun(inlineItem));
+            ++currentItemPosition;
+            continue;
+        }
+
+        auto isWhitespaceRun = isWhitespace(text[currentItemPosition], style.preserveNewline());
+        auto length = isWhitespaceRun ? moveToNextNonWhitespacePosition(inlineItem, currentItemPosition) : moveToNextBreakablePosition(inlineItem, currentItemPosition);
+
+        if (isContinousContent(isWhitespaceRun ? InlineRunProvider::Run::Type::Whitespace : InlineRunProvider::Run::Type::NonWhitespace, inlineItem)) {
+            auto textContext = m_inlineRuns.last().textContext();
+            textContext->setLength(textContext->length() + length);
+        } else {
+            m_inlineRuns.append(isWhitespaceRun ? InlineRunProvider::Run::createWhitespaceRun(inlineItem, currentItemPosition, length, style.collapseWhiteSpace())
+                : InlineRunProvider::Run::createNonWhitespaceRun(inlineItem, currentItemPosition, length));
+        }
+
+        currentItemPosition += length;
+    }
+}
+
+unsigned InlineRunProvider::moveToNextNonWhitespacePosition(const InlineItem& inlineItem, ItemPosition currentItemPosition)
+{
+    auto text = inlineItem.textContent();
+    auto preserveNewline = inlineItem.style().preserveNewline();
+    auto nextNonWhiteSpacePosition = currentItemPosition;
+
+    while (nextNonWhiteSpacePosition < text.length() && isWhitespace(text[nextNonWhiteSpacePosition], preserveNewline))
+        ++nextNonWhiteSpacePosition;
+    return nextNonWhiteSpacePosition - currentItemPosition;
+}
+
+unsigned InlineRunProvider::moveToNextBreakablePosition(const InlineItem& inlineItem, ItemPosition currentItemPosition)
+{
+    auto findNextBreakablePosition = [&](auto inlineText, auto& style, ItemPosition startPosition) {
+        // Swap iterator's content if we advanced to a new string.
+        auto iteratorText = m_lineBreakIterator.stringView();
+
+        if (iteratorText != inlineText) {
+            auto textLength = iteratorText.length();
+            auto lastCharacter = textLength > 0 ? iteratorText[textLength - 1] : 0;
+            auto secondToLastCharacter = textLength > 1 ? iteratorText[textLength - 2] : 0;
+            m_lineBreakIterator.setPriorContext(lastCharacter, secondToLastCharacter);
+            m_lineBreakIterator.resetStringAndReleaseIterator(inlineText, style.locale(), LineBreakIteratorMode::Default);
+        }
+
+        auto keepAllWordsForCJK = style.wordBreak() == WordBreak::KeepAll;
+        auto breakNBSP = style.autoWrap() && style.nbspMode() == NBSPMode::Space;
+
+        if (keepAllWordsForCJK) {
+            if (breakNBSP)
+                return nextBreakablePositionKeepingAllWords(m_lineBreakIterator, startPosition);
+            return nextBreakablePositionKeepingAllWordsIgnoringNBSP(m_lineBreakIterator, startPosition);
+        }
+
+        if (m_lineBreakIterator.mode() == LineBreakIteratorMode::Default) {
+            if (breakNBSP)
+                return WebCore::nextBreakablePosition(m_lineBreakIterator, startPosition);
+            return nextBreakablePositionIgnoringNBSP(m_lineBreakIterator, startPosition);
+        }
+
+        if (breakNBSP)
+            return nextBreakablePositionWithoutShortcut(m_lineBreakIterator, startPosition);
+        return nextBreakablePositionIgnoringNBSPWithoutShortcut(m_lineBreakIterator, startPosition);
+    };
+
+    auto& style = inlineItem.style();
+    auto nextBreakablePosition = findNextBreakablePosition(inlineItem.textContent(), style, currentItemPosition);
+    return nextBreakablePosition - currentItemPosition;
+}
+
+}
+}
+#endif
diff --git a/Source/WebCore/layout/inlineformatting/InlineRunProvider.h b/Source/WebCore/layout/inlineformatting/InlineRunProvider.h
new file mode 100644 (file)
index 0000000..10a4cde
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2018 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 "InlineItem.h"
+#include <wtf/IsoMalloc.h>
+#include <wtf/text/TextBreakIterator.h>
+
+namespace WebCore {
+namespace Layout {
+
+class InlineFormattingState;
+
+using ItemPosition = unsigned;
+
+class InlineRunProvider {
+    WTF_MAKE_ISO_ALLOCATED(InlineRunProvider);
+public:
+    InlineRunProvider(InlineFormattingState&);
+
+    void append(const Box&);
+    void insertBefore(const Box&, const Box& before);
+    void remove(const Box&);
+
+    struct Run {
+
+        static Run createBoxRun(const InlineItem&);
+        static Run createFloatRun(const InlineItem&);
+        static Run createHardLineBreakRun(const InlineItem&);
+        static Run createSoftLineBreakRun(const InlineItem&);
+        static Run createWhitespaceRun(const InlineItem&, ItemPosition start, unsigned length, bool isCollapsible);
+        static Run createNonWhitespaceRun(const InlineItem&, ItemPosition start, unsigned length);
+
+        enum class Type {
+            Box,
+            Float,
+            SoftLineBreak,
+            HardLineBreak,
+            Whitespace,
+            NonWhitespace
+        };
+        Type type() const { return m_type; }
+        bool isText() const { return m_type == Run::Type::Whitespace || m_type == Run::Type::NonWhitespace || m_type == Run::Type::SoftLineBreak || m_type == Run::Type::HardLineBreak; }
+        bool isWhitespace() const { return m_type == Type::Whitespace; }
+        bool isNonWhitespace() const { return m_type == Type::NonWhitespace; }
+        bool isLineBreak() const { return m_type == Run::Type::SoftLineBreak || m_type == Run::Type::HardLineBreak; }
+        bool isBox() const { return m_type == Type::Box; }
+        bool isFloat() const { return m_type == Type::Float; }
+
+        struct TextContext {
+
+            enum class IsCollapsed { No, Yes };
+            TextContext(ItemPosition, unsigned length, IsCollapsed);
+
+            ItemPosition start() const { return m_start; }
+            // Note that 'end' position does not equal to start + length when run overlaps multiple InlineItems.
+            unsigned length() const { return m_length; }
+            bool isCollapsed() const { return m_isCollapsed == IsCollapsed::Yes; }
+
+            void setStart(ItemPosition start) { m_start = start; }
+            void setLength(unsigned length) { m_length = length; }
+
+        private:
+            ItemPosition m_start { 0 };
+            unsigned m_length { 0 };
+            IsCollapsed m_isCollapsed { IsCollapsed::No };
+        };
+        std::optional<TextContext> textContext() const { return m_textContext; }
+        // Note that style() and inlineItem() always returns the first InlineItem for a run.
+        const RenderStyle& style() const { return m_inlineItem.style(); }
+        const InlineItem& inlineItem() const { return m_inlineItem; }
+
+    private:
+        Run(const InlineItem&, Type, std::optional<TextContext>);
+
+        const Type m_type;
+        const InlineItem& m_inlineItem;
+        std::optional<TextContext> m_textContext;
+    };
+    const Vector<InlineRunProvider::Run>& runs() const { return m_inlineRuns; }
+
+private:
+    void commitTextRun();
+    void processInlineTextItem(const InlineItem&);
+    unsigned moveToNextNonWhitespacePosition(const InlineItem&, ItemPosition currentPosition);
+    unsigned moveToNextBreakablePosition(const InlineItem&, ItemPosition currentPosition);
+    bool isContinousContent(Run::Type newRunType, const InlineItem& newInlineItem);
+
+    LazyLineBreakIterator m_lineBreakIterator;
+
+    InlineFormattingState& m_inlineFormattingState;
+    Vector<InlineRunProvider::Run> m_inlineRuns;
+};
+
+inline InlineRunProvider::Run InlineRunProvider::Run::createBoxRun(const InlineItem& inlineItem)
+{
+    return { inlineItem, Type::Box, std::nullopt };
+}
+
+inline InlineRunProvider::Run InlineRunProvider::Run::createFloatRun(const InlineItem& inlineItem)
+{
+    return { inlineItem, Type::Float, std::nullopt };
+}
+
+inline InlineRunProvider::Run InlineRunProvider::Run::createSoftLineBreakRun(const InlineItem& inlineItem)
+{
+    return { inlineItem, Type::SoftLineBreak, std::nullopt };
+}
+
+inline InlineRunProvider::Run InlineRunProvider::Run::createHardLineBreakRun(const InlineItem& inlineItem)
+{
+    return { inlineItem, Type::HardLineBreak, std::nullopt };
+}
+
+inline InlineRunProvider::Run InlineRunProvider::Run::createWhitespaceRun(const InlineItem& inlineItem, ItemPosition start, unsigned length, bool isCollapsible)
+{
+    ASSERT(length);
+    auto isCollapsed = isCollapsible && length > 1 ? TextContext::IsCollapsed::Yes : TextContext::IsCollapsed::No;
+    return { inlineItem, Type::Whitespace, TextContext(start, length, isCollapsed) };
+}
+
+inline InlineRunProvider::Run InlineRunProvider::Run::createNonWhitespaceRun(const InlineItem& inlineItem, ItemPosition start, unsigned length)
+{
+    return { inlineItem, Type::NonWhitespace, TextContext(start, length, TextContext::IsCollapsed::No) };
+}
+
+inline InlineRunProvider::Run::Run(const InlineItem& inlineItem, Type type, std::optional<TextContext> textContext)
+    : m_type(type)
+    , m_inlineItem(inlineItem)
+    , m_textContext(textContext)
+{
+}
+
+inline InlineRunProvider::Run::TextContext::TextContext(ItemPosition start, unsigned length, IsCollapsed isCollapsed)
+    : m_start(start)
+    , m_length(length)
+    , m_isCollapsed(isCollapsed)
+{
+}
+
+}
+}
+#endif
index 0d1831b..c301317 100644 (file)
@@ -96,6 +96,7 @@ public:
     bool isBlockContainer() const { return m_baseTypeFlags & BlockContainerFlag; }
     bool isInlineBox() const { return m_baseTypeFlags & InlineBoxFlag; }
     bool isInlineContainer() const { return m_baseTypeFlags & InlineContainerFlag; }
+    bool isLineBreakBox() const { return m_baseTypeFlags & LineBreakBoxFlag; }
 
     bool isPaddingApplicable() const;
     bool isOverflowVisible() const;
@@ -125,7 +126,8 @@ protected:
         ContainerFlag         = 1 << 0,
         BlockContainerFlag    = 1 << 1,
         InlineBoxFlag         = 1 << 2,
-        InlineContainerFlag   = 1 << 3
+        InlineContainerFlag   = 1 << 3,
+        LineBreakBoxFlag      = 1 << 4
     };
     Box(std::optional<ElementAttributes>, RenderStyle&&, BaseTypeFlags);
 
index ee9b139..fb134f7 100644 (file)
@@ -36,8 +36,8 @@ namespace Layout {
 
 WTF_MAKE_ISO_ALLOCATED_IMPL(InlineBox);
 
-InlineBox::InlineBox(std::optional<ElementAttributes> attributes, RenderStyle&& style)
-    : Box(attributes, WTFMove(style), InlineBoxFlag)
+InlineBox::InlineBox(std::optional<ElementAttributes> attributes, RenderStyle&& style, BaseTypeFlags baseTypeFlags)
+    : Box(attributes, WTFMove(style), baseTypeFlags | InlineBoxFlag)
 {
 }
 
index 09191c7..88f5cd3 100644 (file)
@@ -39,13 +39,14 @@ namespace Layout {
 class InlineBox : public Box {
     WTF_MAKE_ISO_ALLOCATED(InlineBox);
 public:
-    InlineBox(std::optional<ElementAttributes>, RenderStyle&&);
+    InlineBox(std::optional<ElementAttributes>, RenderStyle&&, BaseTypeFlags = InlineBoxFlag);
 
     void setTextContent(String text) { m_textContent = text; }
-    std::optional<String> textContent() const { return m_textContent; }
+    bool hasTextContent() const { return !m_textContent.isNull(); }
+    String textContent() const { return m_textContent; }
 
 private:
-    std::optional<String> m_textContent;
+    String m_textContent;
 };
 
 }
diff --git a/Source/WebCore/layout/layouttree/LayoutLineBreakBox.cpp b/Source/WebCore/layout/layouttree/LayoutLineBreakBox.cpp
new file mode 100644 (file)
index 0000000..6a1d215
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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 "LayoutLineBreakBox.h"
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+#include "RenderStyle.h"
+#include <wtf/IsoMallocInlines.h>
+
+namespace WebCore {
+namespace Layout {
+
+WTF_MAKE_ISO_ALLOCATED_IMPL(LineBreakBox);
+
+LineBreakBox::LineBreakBox(std::optional<ElementAttributes> attributes, RenderStyle&& style)
+    : InlineBox(attributes, WTFMove(style), LineBreakBoxFlag)
+{
+}
+
+}
+}
+#endif
diff --git a/Source/WebCore/layout/layouttree/LayoutLineBreakBox.h b/Source/WebCore/layout/layouttree/LayoutLineBreakBox.h
new file mode 100644 (file)
index 0000000..0be528a
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 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
+
+#include "LayoutInlineBox.h"
+#include <wtf/IsoMalloc.h>
+
+#if ENABLE(LAYOUT_FORMATTING_CONTEXT)
+
+namespace WebCore {
+
+class RenderStyle;
+
+namespace Layout {
+
+class LineBreakBox : public InlineBox {
+    WTF_MAKE_ISO_ALLOCATED(LineBreakBox);
+public:
+    LineBreakBox(std::optional<ElementAttributes>, RenderStyle&&);
+};
+
+}
+}
+
+SPECIALIZE_TYPE_TRAITS_LAYOUT_BOX(LineBreakBox, isLineBreakBox())
+
+#endif