Only construct ComplexLineLayout when needed
https://bugs.webkit.org/show_bug.cgi?id=200625
Reviewed by Zalan Bujtas.
* rendering/ComplexLineLayout.cpp:
(WebCore::ComplexLineLayout::createInlineBoxForRenderer):
(WebCore::ComplexLineLayout::createLineBoxes):
(WebCore::ComplexLineLayout::constructLine):
(WebCore::ComplexLineLayout::updateLogicalWidthForAlignment):
Make static so this can be invoked without constructing complex line layout (from startAlignedOffsetForLine).
(WebCore::ComplexLineLayout::computeInlineDirectionPositionsForSegment):
(WebCore::ComplexLineLayout::deleteEllipsisLineBoxes):
(WebCore::ComplexLineLayout::checkLinesForTextOverflow):
(WebCore::ComplexLineLayout::startAlignedOffsetForLine): Deleted.
This is also used in block layout to set static positions of positioned objects.
Move to RenderBlockFlow where its only caller is.
* rendering/ComplexLineLayout.h:
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::RenderBlockFlow):
(WebCore::RenderBlockFlow::willBeDestroyed):
(WebCore::RenderBlockFlow::layoutInlineChildren):
(WebCore::RenderBlockFlow::updateStaticInlinePositionForChild):
(WebCore::RenderBlockFlow::startAlignedOffsetForLine):
(WebCore::RenderBlockFlow::deleteLines):
(WebCore::RenderBlockFlow::hitTestInlineChildren):
(WebCore::RenderBlockFlow::addOverflowFromInlineChildren):
(WebCore::RenderBlockFlow::paintInlineChildren):
(WebCore::RenderBlockFlow::hasLines const):
(WebCore::RenderBlockFlow::layoutSimpleLines):
(WebCore::RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout):
(WebCore::RenderBlockFlow::ensureLineBoxes):
* rendering/RenderBlockFlow.h:
(WebCore::RenderBlockFlow::firstRootBox const):
(WebCore::RenderBlockFlow::lastRootBox const):
(WebCore::RenderBlockFlow::complexLineLayout):
(WebCore::RenderBlockFlow::lineBoxes): Deleted.
(WebCore::RenderBlockFlow::lineBoxes const): Deleted.
* rendering/RootInlineBox.cpp:
(WebCore::RootInlineBox::removeLineBoxFromRenderObject):
(WebCore::RootInlineBox::extractLineBoxFromRenderObject):
(WebCore::RootInlineBox::attachLineBoxToRenderObject):
* rendering/SimpleLineLayoutFunctions.cpp:
(WebCore::SimpleLineLayout::generateLineBoxTree):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@248528 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderBlockFlow.cpp b/Source/WebCore/rendering/RenderBlockFlow.cpp
index 70b04d8..7f1e639 100644
--- a/Source/WebCore/rendering/RenderBlockFlow.cpp
+++ b/Source/WebCore/rendering/RenderBlockFlow.cpp
@@ -111,7 +111,6 @@
, m_widthForTextAutosizing(-1)
, m_lineCountForTextAutosizing(NOT_SET)
#endif
- , m_complexLineLayout(*this)
{
setChildrenInline(true);
}
@@ -122,7 +121,6 @@
, m_widthForTextAutosizing(-1)
, m_lineCountForTextAutosizing(NOT_SET)
#endif
- , m_complexLineLayout(*this)
{
setChildrenInline(true);
}
@@ -154,7 +152,8 @@
parent()->dirtyLinesFromChangedChild(*this);
}
- lineBoxes().deleteLineBoxes();
+ if (m_complexLineLayout)
+ m_complexLineLayout->lineBoxes().deleteLineBoxes();
blockWillBeDestroyed();
@@ -677,7 +676,11 @@
}
m_simpleLineLayout = nullptr;
- complexLineLayout().layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+
+ if (!m_complexLineLayout)
+ m_complexLineLayout = std::make_unique<ComplexLineLayout>(*this);
+
+ m_complexLineLayout->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
}
void RenderBlockFlow::layoutBlockChild(RenderBox& child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
@@ -899,7 +902,7 @@
void RenderBlockFlow::updateStaticInlinePositionForChild(RenderBox& child, LayoutUnit logicalTop, IndentTextOrNot shouldIndentText)
{
if (child.style().isOriginalDisplayInlineType())
- setStaticInlinePositionForChild(child, logicalTop, complexLineLayout().startAlignedOffsetForLine(logicalTop, shouldIndentText));
+ setStaticInlinePositionForChild(child, logicalTop, startAlignedOffsetForLine(logicalTop, shouldIndentText));
else
setStaticInlinePositionForChild(child, logicalTop, startOffsetForContent(logicalTop));
}
@@ -913,6 +916,45 @@
child.layer()->setStaticInlinePosition(inlinePosition);
}
+LayoutUnit RenderBlockFlow::startAlignedOffsetForLine(LayoutUnit position, IndentTextOrNot shouldIndentText)
+{
+ TextAlignMode textAlign = style().textAlign();
+ bool shouldApplyIndentText = false;
+ switch (textAlign) {
+ case TextAlignMode::Left:
+ case TextAlignMode::WebKitLeft:
+ shouldApplyIndentText = style().isLeftToRightDirection();
+ break;
+ case TextAlignMode::Right:
+ case TextAlignMode::WebKitRight:
+ shouldApplyIndentText = !style().isLeftToRightDirection();
+ break;
+ case TextAlignMode::Start:
+ shouldApplyIndentText = true;
+ break;
+ default:
+ shouldApplyIndentText = false;
+ }
+ // <rdar://problem/15427571>
+ // https://bugs.webkit.org/show_bug.cgi?id=124522
+ // This quirk is for legacy content that doesn't work properly with the center positioning scheme
+ // being honored (e.g., epubs).
+ if (shouldApplyIndentText || settings().useLegacyTextAlignPositionedElementBehavior()) // FIXME: Handle TextAlignMode::End here
+ return startOffsetForLine(position, shouldIndentText);
+
+ // updateLogicalWidthForAlignment() handles the direction of the block so no need to consider it here
+ float totalLogicalWidth = 0;
+ float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), DoNotIndentText);
+ float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), DoNotIndentText) - logicalLeft;
+
+ ComplexLineLayout::updateLogicalWidthForAlignment(*this, textAlign, nullptr, nullptr, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
+
+ if (!style().isLeftToRightDirection())
+ return LayoutUnit(logicalWidth() - logicalLeft);
+
+ return LayoutUnit(logicalLeft);
+}
+
RenderBlockFlow::MarginValues RenderBlockFlow::marginValuesForChild(RenderBox& child) const
{
LayoutUnit childBeforePositive;
@@ -2067,10 +2109,10 @@
m_floatingObjects->clearLineBoxTreePointers();
if (m_simpleLineLayout) {
- ASSERT(!lineBoxes().firstLineBox());
+ ASSERT(!m_complexLineLayout);
m_simpleLineLayout = nullptr;
- } else
- lineBoxes().deleteLineBoxTree();
+ } else if (m_complexLineLayout)
+ m_complexLineLayout->lineBoxes().deleteLineBoxTree();
RenderBlock::deleteLines();
}
@@ -2907,7 +2949,7 @@
if (auto simpleLineLayout = this->simpleLineLayout())
return SimpleLineLayout::hitTestFlow(*this, *simpleLineLayout, request, result, locationInContainer, accumulatedOffset, hitTestAction);
- return lineBoxes().hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction);
+ return m_complexLineLayout && m_complexLineLayout->lineBoxes().hitTest(this, request, result, locationInContainer, accumulatedOffset, hitTestAction);
}
void RenderBlockFlow::addOverflowFromInlineChildren()
@@ -2918,7 +2960,7 @@
return;
}
- complexLineLayout().addOverflowFromInlineChildren();
+ m_complexLineLayout->addOverflowFromInlineChildren();
}
void RenderBlockFlow::adjustForBorderFit(LayoutUnit x, LayoutUnit& left, LayoutUnit& right) const
@@ -3500,7 +3542,9 @@
SimpleLineLayout::paintFlow(*this, *simpleLineLayout, paintInfo, paintOffset);
return;
}
- lineBoxes().paint(this, paintInfo, paintOffset);
+
+ if (m_complexLineLayout)
+ m_complexLineLayout->lineBoxes().paint(this, paintInfo, paintOffset);
}
bool RenderBlockFlow::relayoutForPagination()
@@ -3555,7 +3599,7 @@
if (auto simpleLineLayout = this->simpleLineLayout())
return simpleLineLayout->lineCount();
- return lineBoxes().firstLineBox();
+ return m_complexLineLayout && m_complexLineLayout->lineBoxes().firstLineBox();
}
void RenderBlockFlow::invalidateLineLayoutPath()
@@ -3595,7 +3639,7 @@
}
for (auto& renderer : childrenOfType<RenderObject>(*this))
renderer.clearNeedsLayout();
- ASSERT(!lineBoxes().firstLineBox());
+ ASSERT(!m_complexLineLayout);
LayoutUnit lineLayoutHeight = SimpleLineLayout::computeFlowHeight(*this, *m_simpleLineLayout);
LayoutUnit lineLayoutTop = borderAndPaddingBefore();
repaintLogicalTop = lineLayoutTop;
@@ -3606,7 +3650,10 @@
void RenderBlockFlow::deleteLineBoxesBeforeSimpleLineLayout()
{
ASSERT(lineLayoutPath() == SimpleLinesPath);
- lineBoxes().deleteLineBoxes();
+
+ if (m_complexLineLayout)
+ m_complexLineLayout->lineBoxes().deleteLineBoxes();
+
for (auto& renderer : childrenOfType<RenderObject>(*this)) {
if (is<RenderText>(renderer))
downcast<RenderText>(renderer).deleteLineBoxesBeforeSimpleLineLayout();
@@ -3615,14 +3662,23 @@
else
ASSERT_NOT_REACHED();
}
+
+ m_complexLineLayout = nullptr;
}
void RenderBlockFlow::ensureLineBoxes()
{
+ if (!childrenInline())
+ return;
+
setLineLayoutPath(ForceLineBoxesPath);
+
if (!m_simpleLineLayout)
return;
+ ASSERT(!m_complexLineLayout);
+ m_complexLineLayout = std::make_unique<ComplexLineLayout>(*this);
+
if (SimpleLineLayout::canUseForLineBoxTree(*this, *m_simpleLineLayout)) {
SimpleLineLayout::generateLineBoxTree(*this, *m_simpleLineLayout);
m_simpleLineLayout = nullptr;
@@ -3641,14 +3697,14 @@
LayoutUnit repaintLogicalBottom;
if (isPaginated) {
PaginatedLayoutStateMaintainer state(*this);
- complexLineLayout().layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+ m_complexLineLayout->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
// This matches relayoutToAvoidWidows.
if (shouldBreakAtLineToAvoidWidow())
- complexLineLayout().layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+ m_complexLineLayout->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
// FIXME: This is needed as long as simple and normal line layout produce different line breakings.
repaint();
} else
- complexLineLayout().layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
+ m_complexLineLayout->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
updateLogicalHeight();
ASSERT(didNeedLayout || logicalHeight() == oldHeight);