Diff
Modified: trunk/Source/WebCore/ChangeLog (252858 => 252859)
--- trunk/Source/WebCore/ChangeLog 2019-11-25 14:44:16 UTC (rev 252858)
+++ trunk/Source/WebCore/ChangeLog 2019-11-25 15:52:56 UTC (rev 252859)
@@ -1,3 +1,37 @@
+2019-11-25 Zalan Bujtas <[email protected]>
+
+ [LFC][IFC] Decouple LineLayout and Line
+ https://bugs.webkit.org/show_bug.cgi?id=204560
+ <rdar://problem/57463295>
+
+ Reviewed by Antti Koivisto.
+
+ This is in preparation for constructing only one LineLayout/Line object for an inline formatting context and not
+ one per line.
+
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::lineLayout):
+ (WebCore::Layout::InlineFormattingContext::computedIntrinsicWidthForConstraint const):
+ (WebCore::Layout::InlineFormattingContext::constraintsForLine):
+ (WebCore::Layout::InlineFormattingContext::initialConstraintsForLine): Deleted.
+ * layout/inlineformatting/InlineFormattingContext.h:
+ * layout/inlineformatting/InlineFormattingContextQuirks.cpp:
+ (WebCore::Layout::InlineFormattingContext::Quirks::lineHeightConstraints const):
+ * layout/inlineformatting/InlineLine.cpp:
+ (WebCore::Layout::Line::Line):
+ (WebCore::Layout::Line::initialize):
+ * layout/inlineformatting/InlineLine.h:
+ (WebCore::Layout::Line::hasIntrusiveFloat const):
+ (WebCore::Layout::Line::setHasIntrusiveFloat):
+ * layout/inlineformatting/InlineLineLayout.cpp:
+ (WebCore::Layout::LineLayout::LineInput::LineInput):
+ (WebCore::Layout::LineLayout::LineLayout):
+ (WebCore::Layout::LineLayout::close):
+ (WebCore::Layout::LineLayout::placeInlineItem):
+ (WebCore::Layout::LineLayout::processUncommittedContent):
+ (WebCore::Layout::LineLayout::shouldProcessUncommittedContent const):
+ * layout/inlineformatting/InlineLineLayout.h:
+
2019-11-25 Zan Dobersek <[email protected]> and Chris Lord <[email protected]>
Basic OffscreenCanvas functionality
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp (252858 => 252859)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2019-11-25 14:44:16 UTC (rev 252858)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp 2019-11-25 15:52:56 UTC (rev 252859)
@@ -95,12 +95,13 @@
auto lineLogicalTop = geometryForBox(root()).contentBoxTop();
unsigned leadingInlineItemIndex = 0;
Optional<LineLayout::PartialContent> leadingPartialContent;
+ auto line = Line { *this, root().style().textAlign(), Line::SkipAlignment::No };
+
while (leadingInlineItemIndex < inlineItems.size()) {
- auto lineConstraints = initialConstraintsForLine(usedHorizontalValues, lineLogicalTop);
+ line.initialize(constraintsForLine(usedHorizontalValues, lineLogicalTop));
+ auto lineInput = LineLayout::LineInput { inlineItems, leadingInlineItemIndex, leadingPartialContent };
+ auto lineLayout = LineLayout { *this, lineInput, line };
- auto lineInput = LineLayout::LineInput { lineConstraints, root().style().textAlign(), inlineItems, leadingInlineItemIndex, leadingPartialContent };
- auto lineLayout = LineLayout { *this, Line::SkipAlignment::No, lineInput };
-
auto lineContent = lineLayout.layout();
setDisplayBoxesForLine(lineContent, usedHorizontalValues);
@@ -117,7 +118,7 @@
leadingInlineItemIndex = *lineContent.trailingInlineItemIndex + 1;
} else {
// Floats prevented us placing any content on the line.
- ASSERT(lineInput.initialConstraints.lineIsConstrainedByFloat);
+ ASSERT(line.hasIntrusiveFloat());
// Move the next line below the intrusive float.
auto floatingContext = FloatingContext { root(), *this, formattingState().floatingState() };
auto floatConstraints = floatingContext.constraints({ lineLogicalTop });
@@ -234,12 +235,13 @@
auto& inlineItems = formattingState().inlineItems();
LayoutUnit maximumLineWidth;
unsigned leadingInlineItemIndex = 0;
+ auto line = Line { *this, root().style().textAlign(), Line::SkipAlignment::Yes };
while (leadingInlineItemIndex < inlineItems.size()) {
// Only the horiztonal available width is constrained when computing intrinsic width.
- auto initialLineConstraints = Line::InitialConstraints { { }, usedHorizontalValues.constraints.width, false, { } };
- auto lineInput = LineLayout::LineInput { initialLineConstraints, root().style().textAlign(), inlineItems, leadingInlineItemIndex, { } };
+ line.initialize(Line::Constraints { { }, usedHorizontalValues.constraints.width, false, { } });
+ auto lineInput = LineLayout::LineInput { inlineItems, leadingInlineItemIndex, { } };
- auto lineContent = LineLayout(*this, Line::SkipAlignment::Yes, lineInput).layout();
+ auto lineContent = LineLayout(*this, lineInput, line).layout();
leadingInlineItemIndex = *lineContent.trailingInlineItemIndex + 1;
LayoutUnit floatsWidth;
@@ -372,7 +374,7 @@
}
}
-Line::InitialConstraints InlineFormattingContext::initialConstraintsForLine(UsedHorizontalValues usedHorizontalValues, const LayoutUnit lineLogicalTop)
+Line::Constraints InlineFormattingContext::constraintsForLine(UsedHorizontalValues usedHorizontalValues, const LayoutUnit lineLogicalTop)
{
auto lineLogicalLeft = geometryForBox(root()).contentBoxLeft();
auto availableWidth = usedHorizontalValues.constraints.width;
@@ -405,7 +407,7 @@
availableWidth = floatConstraints.right->x - lineLogicalLeft;
}
}
- return Line::InitialConstraints { { lineLogicalLeft, lineLogicalTop }, availableWidth, lineIsConstrainedByFloat, quirks().lineHeightConstraints(root()) };
+ return Line::Constraints { { lineLogicalLeft, lineLogicalTop }, availableWidth, lineIsConstrainedByFloat, quirks().lineHeightConstraints(root()) };
}
void InlineFormattingContext::setDisplayBoxesForLine(const LineLayout::LineContent& lineContent, UsedHorizontalValues usedHorizontalValues)
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h (252858 => 252859)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2019-11-25 14:44:16 UTC (rev 252858)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.h 2019-11-25 15:52:56 UTC (rev 252859)
@@ -51,7 +51,7 @@
class Quirks : public FormattingContext::Quirks {
public:
bool lineDescentNeedsCollapsing(const Line::RunList&) const;
- Line::InitialConstraints::HeightAndBaseline lineHeightConstraints(const Box& formattingRoot) const;
+ Line::Constraints::HeightAndBaseline lineHeightConstraints(const Box& formattingRoot) const;
private:
friend class InlineFormattingContext;
@@ -89,7 +89,7 @@
void computeWidthAndMargin(const Box&, UsedHorizontalValues);
void collectInlineContentIfNeeded();
- Line::InitialConstraints initialConstraintsForLine(UsedHorizontalValues, const LayoutUnit lineLogicalTop);
+ Line::Constraints constraintsForLine(UsedHorizontalValues, const LayoutUnit lineLogicalTop);
void setDisplayBoxesForLine(const LineLayout::LineContent&, UsedHorizontalValues);
void invalidateFormattingState(const InvalidationState&);
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp (252858 => 252859)
--- trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp 2019-11-25 14:44:16 UTC (rev 252858)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp 2019-11-25 15:52:56 UTC (rev 252859)
@@ -75,7 +75,7 @@
return true;
}
-Line::InitialConstraints::HeightAndBaseline InlineFormattingContext::Quirks::lineHeightConstraints(const Box& formattingRoot) const
+Line::Constraints::HeightAndBaseline InlineFormattingContext::Quirks::lineHeightConstraints(const Box& formattingRoot) const
{
// computedLineHeight takes font-size into account when line-height is not set.
// Strut is the imaginary box that we put on every line. It sets the initial vertical constraints for each new line.
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp (252858 => 252859)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp 2019-11-25 14:44:16 UTC (rev 252858)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.cpp 2019-11-25 15:52:56 UTC (rev 252859)
@@ -204,19 +204,11 @@
m_textContext->setExpansion({ m_textContext->expansion()->behavior, logicalExpansion });
}
-Line::Line(const InlineFormattingContext& inlineFormattingContext, const InitialConstraints& initialConstraints, Optional<TextAlignMode> horizontalAlignment, SkipAlignment skipAlignment)
+Line::Line(const InlineFormattingContext& inlineFormattingContext, Optional<TextAlignMode> horizontalAlignment, SkipAlignment skipAlignment)
: m_inlineFormattingContext(inlineFormattingContext)
- , m_initialStrut(initialConstraints.heightAndBaseline ? initialConstraints.heightAndBaseline->strut : WTF::nullopt)
- , m_lineLogicalWidth(initialConstraints.availableLogicalWidth)
, m_horizontalAlignment(horizontalAlignment)
, m_skipAlignment(skipAlignment == SkipAlignment::Yes)
{
- ASSERT(m_skipAlignment || initialConstraints.heightAndBaseline);
- auto initialLineHeight = initialConstraints.heightAndBaseline ? initialConstraints.heightAndBaseline->height : LayoutUnit();
- auto initialBaselineOffset = initialConstraints.heightAndBaseline ? initialConstraints.heightAndBaseline->baselineOffset : LayoutUnit();
- auto lineRect = Display::Rect { initialConstraints.logicalTopLeft, { }, initialLineHeight };
- auto baseline = LineBox::Baseline { initialBaselineOffset, initialLineHeight - initialBaselineOffset };
- m_lineBox = LineBox { lineRect, baseline, initialBaselineOffset };
}
Line::~Line()
@@ -223,6 +215,29 @@
{
}
+void Line::initialize(const Constraints& constraints)
+{
+ ASSERT(m_skipAlignment || constraints.heightAndBaseline);
+
+ LayoutUnit initialLineHeight;
+ LayoutUnit initialBaselineOffset;
+ if (constraints.heightAndBaseline) {
+ m_initialStrut = constraints.heightAndBaseline->strut;
+ initialLineHeight = constraints.heightAndBaseline->height;
+ initialBaselineOffset = constraints.heightAndBaseline->baselineOffset;
+ } else
+ m_initialStrut = { };
+
+ auto lineRect = Display::Rect { constraints.logicalTopLeft, { }, initialLineHeight };
+ auto baseline = LineBox::Baseline { initialBaselineOffset, initialLineHeight - initialBaselineOffset };
+ m_lineBox = LineBox { lineRect, baseline, initialBaselineOffset };
+ m_lineLogicalWidth = constraints.availableLogicalWidth;
+ m_hasIntrusiveFloat = constraints.lineIsConstrainedByFloat;
+
+ m_inlineItemRuns.clear();
+ m_trimmableContent.clear();
+}
+
static bool shouldPreserveTrailingContent(const InlineTextItem& inlineTextItem)
{
if (!inlineTextItem.isWhitespace())
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLine.h (252858 => 252859)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLine.h 2019-11-25 14:44:16 UTC (rev 252858)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLine.h 2019-11-25 15:52:56 UTC (rev 252859)
@@ -43,7 +43,7 @@
class Line {
WTF_MAKE_ISO_ALLOCATED(Line);
public:
- struct InitialConstraints {
+ struct Constraints {
LayoutPoint logicalTopLeft;
LayoutUnit availableLogicalWidth;
bool lineIsConstrainedByFloat { false };
@@ -55,11 +55,13 @@
Optional<HeightAndBaseline> heightAndBaseline;
};
enum class SkipAlignment { No, Yes };
- Line(const InlineFormattingContext&, const InitialConstraints&, Optional<TextAlignMode>, SkipAlignment);
+ Line(const InlineFormattingContext&, Optional<TextAlignMode>, SkipAlignment);
~Line();
+ void initialize(const Constraints&);
void append(const InlineItem&, LayoutUnit logicalWidth);
bool isVisuallyEmpty() const { return m_lineBox.isConsideredEmpty(); }
+ bool hasIntrusiveFloat() const { return m_hasIntrusiveFloat; }
LayoutUnit availableWidth() const { return logicalWidth() - contentLogicalWidth(); }
LayoutUnit trailingTrimmableWidth() const { return m_trimmableContent.width(); }
@@ -67,6 +69,7 @@
const LineBox& lineBox() const { return m_lineBox; }
void moveLogicalLeft(LayoutUnit);
void moveLogicalRight(LayoutUnit);
+ void setHasIntrusiveFloat() { m_hasIntrusiveFloat = true; }
struct Run {
Run(const InlineItemRun&);
@@ -167,6 +170,7 @@
LayoutUnit m_lineLogicalWidth;
Optional<TextAlignMode> m_horizontalAlignment;
bool m_skipAlignment { false };
+ bool m_hasIntrusiveFloat { false };
LineBox m_lineBox;
};
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp (252858 => 252859)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp 2019-11-25 14:44:16 UTC (rev 252858)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.cpp 2019-11-25 15:52:56 UTC (rev 252859)
@@ -67,10 +67,8 @@
return boxGeometry.width();
}
-LineLayout::LineInput::LineInput(const Line::InitialConstraints& initialLineConstraints, TextAlignMode horizontalAlignment, const InlineItems& inlineItems, unsigned leadingInlineItemIndex, Optional<PartialContent> leadingPartialContent)
- : initialConstraints(initialLineConstraints)
- , horizontalAlignment(horizontalAlignment)
- , inlineItems(inlineItems)
+LineLayout::LineInput::LineInput(const InlineItems& inlineItems, unsigned leadingInlineItemIndex, Optional<PartialContent> leadingPartialContent)
+ : inlineItems(inlineItems)
, leadingInlineItemIndex(leadingInlineItemIndex)
, leadingPartialContent(leadingPartialContent)
{
@@ -88,11 +86,10 @@
m_width = 0;
}
-LineLayout::LineLayout(const InlineFormattingContext& inlineFormattingContext, Line::SkipAlignment skipAlignment, const LineInput& lineInput)
+LineLayout::LineLayout(const InlineFormattingContext& inlineFormattingContext, const LineInput& lineInput, Line& line)
: m_inlineFormattingContext(inlineFormattingContext)
, m_lineInput(lineInput)
- , m_line(inlineFormattingContext, lineInput.initialConstraints, lineInput.horizontalAlignment, skipAlignment)
- , m_lineHasIntrusiveFloat(lineInput.initialConstraints.lineIsConstrainedByFloat)
+ , m_line(line)
{
}
@@ -136,7 +133,7 @@
LineLayout::LineContent LineLayout::close()
{
- ASSERT(m_committedInlineItemCount || m_lineHasIntrusiveFloat);
+ ASSERT(m_committedInlineItemCount || m_line.hasIntrusiveFloat());
m_uncommittedContent.reset();
if (!m_committedInlineItemCount)
return LineContent { { }, { }, WTFMove(m_floats), m_line.close(), m_line.lineBox() };
@@ -177,7 +174,7 @@
if (processUncommittedContent() == IsEndOfLine::Yes)
return IsEndOfLine::Yes;
}
- auto lineIsConsideredEmpty = m_line.isVisuallyEmpty() && !m_lineHasIntrusiveFloat;
+ auto lineIsConsideredEmpty = m_line.isVisuallyEmpty() && !m_line.hasIntrusiveFloat();
if (LineBreaker().shouldWrapFloatBox(itemLogicalWidth, m_line.availableWidth() + m_line.trailingTrimmableWidth(), lineIsConsideredEmpty))
return IsEndOfLine::Yes;
@@ -187,7 +184,7 @@
floatBox.isLeftFloatingPositioned() ? m_line.moveLogicalLeft(itemLogicalWidth) : m_line.moveLogicalRight(itemLogicalWidth);
m_floats.append(makeWeakPtr(inlineItem));
++m_committedInlineItemCount;
- m_lineHasIntrusiveFloat = true;
+ m_line.setHasIntrusiveFloat();
return IsEndOfLine::No;
}
// Forced line breaks are also special.
@@ -213,7 +210,7 @@
LineLayout::IsEndOfLine LineLayout::processUncommittedContent()
{
// Check if the pending content fits.
- auto lineIsConsideredEmpty = m_line.isVisuallyEmpty() && !m_lineHasIntrusiveFloat;
+ auto lineIsConsideredEmpty = m_line.isVisuallyEmpty() && !m_line.hasIntrusiveFloat();
auto breakingContext = LineBreaker().breakingContextForInlineContent(m_uncommittedContent.runs(), m_uncommittedContent.width(), m_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)
@@ -257,6 +254,10 @@
// 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;
@@ -278,10 +279,6 @@
if (lastUncomittedContent->isContainerEnd())
return false;
}
- // texttext -> continuous content.
- // ' 'text -> commit boundary.
- if (lastUncomittedContent->isText())
- return downcast<InlineTextItem>(*lastUncomittedContent).isWhitespace();
// <img>text -> the inline box is on a commit boundary.
if (lastUncomittedContent->isBox())
return true;
Modified: trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h (252858 => 252859)
--- trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h 2019-11-25 14:44:16 UTC (rev 252858)
+++ trunk/Source/WebCore/layout/inlineformatting/InlineLineLayout.h 2019-11-25 15:52:56 UTC (rev 252859)
@@ -36,7 +36,7 @@
class LineLayout {
public:
struct LineInput;
- LineLayout(const InlineFormattingContext&, Line::SkipAlignment, const LineInput&);
+ LineLayout(const InlineFormattingContext&, const LineInput&, Line&);
struct LineContent;
LineContent layout();
@@ -46,10 +46,8 @@
unsigned length;
};
struct LineInput {
- LineInput(const Line::InitialConstraints&, TextAlignMode horizontalAlignment, const InlineItems&, unsigned leadingInlineItemIndex, Optional<PartialContent> leadingPartialContent);
+ LineInput(const InlineItems&, unsigned leadingInlineItemIndex, Optional<PartialContent> leadingPartialContent);
- Line::InitialConstraints initialConstraints;
- TextAlignMode horizontalAlignment;
const InlineItems& inlineItems;
unsigned leadingInlineItemIndex { 0 };
Optional<PartialContent> leadingPartialContent;
@@ -98,8 +96,7 @@
const InlineFormattingContext& m_inlineFormattingContext;
const LineInput& m_lineInput;
- Line m_line;
- bool m_lineHasIntrusiveFloat { false };
+ Line& m_line;
UncommittedContent m_uncommittedContent;
unsigned m_committedInlineItemCount { 0 };
Vector<WeakPtr<InlineItem>> m_floats;