Diff
Modified: trunk/Source/WebCore/ChangeLog (237285 => 237286)
--- trunk/Source/WebCore/ChangeLog 2018-10-19 13:55:32 UTC (rev 237285)
+++ trunk/Source/WebCore/ChangeLog 2018-10-19 15:52:08 UTC (rev 237286)
@@ -1,3 +1,86 @@
+2018-10-19 Zalan Bujtas <za...@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="" 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 <aj...@chromium.org>
[IntersectionObserver] Handle zero-area intersections
Modified: trunk/Source/WebCore/Sources.txt (237285 => 237286)
--- trunk/Source/WebCore/Sources.txt 2018-10-19 13:55:32 UTC (rev 237285)
+++ trunk/Source/WebCore/Sources.txt 2018-10-19 15:52:08 UTC (rev 237286)
@@ -1259,6 +1259,7 @@
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/LayoutContainer.cpp
layout/layouttree/LayoutInlineBox.cpp
layout/layouttree/LayoutInlineContainer.cpp
+layout/layouttree/LayoutLineBreakBox.cpp
layout/layouttree/LayoutReplaced.cpp
layout/layouttree/LayoutTreeBuilder.cpp
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (237285 => 237286)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-10-19 13:55:32 UTC (rev 237285)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2018-10-19 15:52:08 UTC (rev 237286)
@@ -1990,6 +1990,7 @@
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 */; };
@@ -2008,6 +2009,8 @@
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, ); }; };
@@ -9064,6 +9067,8 @@
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>"; };
@@ -9100,6 +9105,9 @@
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>"; };
@@ -16014,6 +16022,8 @@
1199FA4E208E3899002358CC /* LayoutInlineContainer.cpp */,
1199FA4D208E3899002358CC /* LayoutInlineContainer.h */,
11100FC72092764C0081AA6C /* LayoutIterator.h */,
+ 6FE7CFA52177F069005B1573 /* LayoutLineBreakBox.cpp */,
+ 6FE7CFA32177EF10005B1573 /* LayoutLineBreakBox.h */,
111C615720AD1AE1005B82FA /* LayoutReplaced.cpp */,
111C615620AD1AE1005B82FA /* LayoutReplaced.h */,
11100FD5209514DE0081AA6C /* LayoutTreeBuilder.cpp */,
@@ -16047,6 +16057,9 @@
115CFA7C208B8E10001E6991 /* InlineFormattingState.h */,
1123AFDD209ABBBA00736ACC /* InlineInvalidation.cpp */,
1123AFDC209ABBBA00736ACC /* InlineInvalidation.h */,
+ 6FE7CFA02177EEF1005B1573 /* InlineItem.h */,
+ 6F5217C62177F5A6006583BB /* InlineRunProvider.cpp */,
+ 6F5217C42177F5A6006583BB /* InlineRunProvider.h */,
);
path = inlineformatting;
sourceTree = "<group>";
@@ -28815,7 +28828,9 @@
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 */,
@@ -29762,6 +29777,7 @@
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 */,
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (237285 => 237286)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2018-10-19 13:55:32 UTC (rev 237285)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2018-10-19 15:52:08 UTC (rev 237286)
@@ -70,8 +70,8 @@
}
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) {
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h (237285 => 237286)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h 2018-10-19 13:55:32 UTC (rev 237285)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingState.h 2018-10-19 15:52:08 UTC (rev 237286)
@@ -28,11 +28,11 @@
#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 @@
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;
};
Added: trunk/Source/WebCore/layout/inlineformatting/InlineItem.h (0 => 237286)
--- trunk/Source/WebCore/layout/inlineformatting/InlineItem.h (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineItem.h 2018-10-19 15:52:08 UTC (rev 237286)
@@ -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
Added: trunk/Source/WebCore/layout/inlineformatting/InlineRunProvider.cpp (0 => 237286)
--- trunk/Source/WebCore/layout/inlineformatting/InlineRunProvider.cpp (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineRunProvider.cpp 2018-10-19 15:52:08 UTC (rev 237286)
@@ -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="" (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
Added: trunk/Source/WebCore/layout/inlineformatting/InlineRunProvider.h (0 => 237286)
--- trunk/Source/WebCore/layout/inlineformatting/InlineRunProvider.h (rev 0)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineRunProvider.h 2018-10-19 15:52:08 UTC (rev 237286)
@@ -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
Modified: trunk/Source/WebCore/layout/layouttree/LayoutBox.h (237285 => 237286)
--- trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2018-10-19 13:55:32 UTC (rev 237285)
+++ trunk/Source/WebCore/layout/layouttree/LayoutBox.h 2018-10-19 15:52:08 UTC (rev 237286)
@@ -96,6 +96,7 @@
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 @@
ContainerFlag = 1 << 0,
BlockContainerFlag = 1 << 1,
InlineBoxFlag = 1 << 2,
- InlineContainerFlag = 1 << 3
+ InlineContainerFlag = 1 << 3,
+ LineBreakBoxFlag = 1 << 4
};
Box(std::optional<ElementAttributes>, RenderStyle&&, BaseTypeFlags);
Modified: trunk/Source/WebCore/layout/layouttree/LayoutInlineBox.cpp (237285 => 237286)
--- trunk/Source/WebCore/layout/layouttree/LayoutInlineBox.cpp 2018-10-19 13:55:32 UTC (rev 237285)
+++ trunk/Source/WebCore/layout/layouttree/LayoutInlineBox.cpp 2018-10-19 15:52:08 UTC (rev 237286)
@@ -36,8 +36,8 @@
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)
{
}
Modified: trunk/Source/WebCore/layout/layouttree/LayoutInlineBox.h (237285 => 237286)
--- trunk/Source/WebCore/layout/layouttree/LayoutInlineBox.h 2018-10-19 13:55:32 UTC (rev 237285)
+++ trunk/Source/WebCore/layout/layouttree/LayoutInlineBox.h 2018-10-19 15:52:08 UTC (rev 237286)
@@ -39,13 +39,14 @@
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;
};
}
Copied: trunk/Source/WebCore/layout/layouttree/LayoutLineBreakBox.cpp (from rev 237285, trunk/Source/WebCore/layout/layouttree/LayoutInlineBox.cpp) (0 => 237286)
--- trunk/Source/WebCore/layout/layouttree/LayoutLineBreakBox.cpp (rev 0)
+++ trunk/Source/WebCore/layout/layouttree/LayoutLineBreakBox.cpp 2018-10-19 15:52:08 UTC (rev 237286)
@@ -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
Copied: trunk/Source/WebCore/layout/layouttree/LayoutLineBreakBox.h (from rev 237285, trunk/Source/WebCore/layout/layouttree/LayoutInlineBox.cpp) (0 => 237286)
--- trunk/Source/WebCore/layout/layouttree/LayoutLineBreakBox.h (rev 0)
+++ trunk/Source/WebCore/layout/layouttree/LayoutLineBreakBox.h 2018-10-19 15:52:08 UTC (rev 237286)
@@ -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