[LFC][IFC] Add Display::Run/LineBox mapping
https://bugs.webkit.org/show_bug.cgi?id=203051
<rdar://problem/56342487>
Reviewed by Antti Koivisto.
Mapping enables us to paint baseline aligned runs on the current line. This is temporary until after we figure out the final run/line structure.
* layout/FormattingContextGeometry.cpp:
(WebCore::Layout::FormattingContext::Geometry::contentHeightForFormattingContextRoot const):
* layout/Verification.cpp:
(WebCore::Layout::outputMismatchingSimpleLineInformationIfNeeded):
(WebCore::Layout::outputMismatchingComplexLineInformationIfNeeded):
* layout/blockformatting/BlockFormattingContextGeometry.cpp:
(WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
* layout/displaytree/DisplayPainter.cpp:
(WebCore::Display::paintInlineContent):
* layout/inlineformatting/InlineFormattingContext.cpp:
(WebCore::Layout::InlineFormattingContext::setDisplayBoxesForLine):
* layout/inlineformatting/InlineFormattingContextQuirks.cpp:
(WebCore::Layout::InlineFormattingContext::Quirks::lineDescentNeedsCollapsing const):
* layout/inlineformatting/InlineFormattingState.h:
(WebCore::Layout::InlineFormattingState::addLineBox):
(WebCore::Layout::InlineFormattingState::lineBoxForRun const):
(WebCore::Layout::InlineFormattingState::addInlineRun):
* layout/inlineformatting/InlineLine.cpp:
(WebCore::Layout::Line::Run::Run):
(WebCore::Layout::Line::alignContentVertically):
(WebCore::Layout::Line::adjustBaselineAndLineHeight):
* layout/inlineformatting/InlineLine.h:
(WebCore::Layout::Line::Run::displayRun const):
(WebCore::Layout::Line::Run::logicalRect const):
(WebCore::Layout::Line::Run::adjustLogicalTop):
(WebCore::Layout::Line::Run::moveVertically):
(WebCore::Layout::Line::Run::moveHorizontally):
(WebCore::Layout::Line::Run::expand):
* layout/inlineformatting/InlineLineBox.h:
* layout/inlineformatting/InlineLineLayout.h:
* layout/layouttree/LayoutTreeBuilder.cpp:
(WebCore::Layout::outputInlineRuns):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@251238 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index d962f5c..42f50db 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,46 @@
+2019-10-17 Zalan Bujtas <zalan@apple.com>
+
+ [LFC][IFC] Add Display::Run/LineBox mapping
+ https://bugs.webkit.org/show_bug.cgi?id=203051
+ <rdar://problem/56342487>
+
+ Reviewed by Antti Koivisto.
+
+ Mapping enables us to paint baseline aligned runs on the current line. This is temporary until after we figure out the final run/line structure.
+
+ * layout/FormattingContextGeometry.cpp:
+ (WebCore::Layout::FormattingContext::Geometry::contentHeightForFormattingContextRoot const):
+ * layout/Verification.cpp:
+ (WebCore::Layout::outputMismatchingSimpleLineInformationIfNeeded):
+ (WebCore::Layout::outputMismatchingComplexLineInformationIfNeeded):
+ * layout/blockformatting/BlockFormattingContextGeometry.cpp:
+ (WebCore::Layout::BlockFormattingContext::Geometry::inFlowNonReplacedHeightAndMargin):
+ * layout/displaytree/DisplayPainter.cpp:
+ (WebCore::Display::paintInlineContent):
+ * layout/inlineformatting/InlineFormattingContext.cpp:
+ (WebCore::Layout::InlineFormattingContext::setDisplayBoxesForLine):
+ * layout/inlineformatting/InlineFormattingContextQuirks.cpp:
+ (WebCore::Layout::InlineFormattingContext::Quirks::lineDescentNeedsCollapsing const):
+ * layout/inlineformatting/InlineFormattingState.h:
+ (WebCore::Layout::InlineFormattingState::addLineBox):
+ (WebCore::Layout::InlineFormattingState::lineBoxForRun const):
+ (WebCore::Layout::InlineFormattingState::addInlineRun):
+ * layout/inlineformatting/InlineLine.cpp:
+ (WebCore::Layout::Line::Run::Run):
+ (WebCore::Layout::Line::alignContentVertically):
+ (WebCore::Layout::Line::adjustBaselineAndLineHeight):
+ * layout/inlineformatting/InlineLine.h:
+ (WebCore::Layout::Line::Run::displayRun const):
+ (WebCore::Layout::Line::Run::logicalRect const):
+ (WebCore::Layout::Line::Run::adjustLogicalTop):
+ (WebCore::Layout::Line::Run::moveVertically):
+ (WebCore::Layout::Line::Run::moveHorizontally):
+ (WebCore::Layout::Line::Run::expand):
+ * layout/inlineformatting/InlineLineBox.h:
+ * layout/inlineformatting/InlineLineLayout.h:
+ * layout/layouttree/LayoutTreeBuilder.cpp:
+ (WebCore::Layout::outputInlineRuns):
+
2019-10-17 Antoine Quint <graouts@apple.com>
[Web Animations] Enable the Web Animations JavaScript API by default
diff --git a/Source/WebCore/layout/FormattingContextGeometry.cpp b/Source/WebCore/layout/FormattingContextGeometry.cpp
index 0d61d0d..1306201 100644
--- a/Source/WebCore/layout/FormattingContextGeometry.cpp
+++ b/Source/WebCore/layout/FormattingContextGeometry.cpp
@@ -134,8 +134,8 @@
auto& lineBoxes = downcast<InlineFormattingState>(layoutState.establishedFormattingState(formattingRootContainer)).lineBoxes();
// Even empty containers generate one line.
ASSERT(!lineBoxes.isEmpty());
- top = lineBoxes.first().logicalTop();
- bottom = lineBoxes.last().logicalBottom();
+ top = lineBoxes.first()->logicalTop();
+ bottom = lineBoxes.last()->logicalBottom();
} else if (formattingRootContainer.establishesBlockFormattingContext() || formattingRootContainer.establishesTableFormattingContext() || formattingRootContainer.isDocumentBox()) {
if (formattingRootContainer.hasInFlowChild()) {
auto& firstBoxGeometry = formattingContext.geometryForBox(*formattingRootContainer.firstInFlowChild(), EscapeType::AccessChildFormattingContext);
diff --git a/Source/WebCore/layout/Verification.cpp b/Source/WebCore/layout/Verification.cpp
index 2f56f62..3efc23b 100644
--- a/Source/WebCore/layout/Verification.cpp
+++ b/Source/WebCore/layout/Verification.cpp
@@ -87,7 +87,7 @@
auto mismatched = false;
for (unsigned i = 0; i < lineLayoutData->runCount(); ++i) {
auto& simpleRun = lineLayoutData->runAt(i);
- auto& inlineRun = inlineRunList[i];
+ auto& inlineRun = *inlineRunList[i];
auto matchingRuns = areEssentiallyEqual(simpleRun.logicalLeft, inlineRun.logicalLeft()) && areEssentiallyEqual(simpleRun.logicalRight, inlineRun.logicalRight());
if (matchingRuns && inlineRun.textContext()) {
@@ -173,7 +173,7 @@
}
for (unsigned inlineBoxIndex = 0; inlineBoxIndex < inlineBoxes.size() && runIndex < inlineRunList.size(); ++inlineBoxIndex) {
- auto& inlineRun = inlineRunList[runIndex];
+ auto& inlineRun = *inlineRunList[runIndex];
auto* inlineBox = inlineBoxes[inlineBoxIndex];
auto* inlineTextBox = is<InlineTextBox>(inlineBox) ? downcast<InlineTextBox>(inlineBox) : nullptr;
bool matchingRuns = inlineTextBox ? checkForMatchingTextRuns(inlineRun, *inlineTextBox) : matchingRuns = checkForMatchingNonTextRuns(inlineRun, *inlineBox);
diff --git a/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp b/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp
index ed8a386..54f7e6f 100644
--- a/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp
+++ b/Source/WebCore/layout/blockformatting/BlockFormattingContextGeometry.cpp
@@ -75,7 +75,7 @@
auto& lineBoxes = downcast<InlineFormattingState>(layoutState().establishedFormattingState(layoutContainer)).lineBoxes();
// Even empty containers generate one line.
ASSERT(!lineBoxes.isEmpty());
- return { lineBoxes.last().logicalBottom() - borderAndPaddingTop, nonCollapsedMargin };
+ return { lineBoxes.last()->logicalBottom() - borderAndPaddingTop, nonCollapsedMargin };
}
// 2. the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin...
diff --git a/Source/WebCore/layout/displaytree/DisplayPainter.cpp b/Source/WebCore/layout/displaytree/DisplayPainter.cpp
index 5f051a1..4ad95c6 100644
--- a/Source/WebCore/layout/displaytree/DisplayPainter.cpp
+++ b/Source/WebCore/layout/displaytree/DisplayPainter.cpp
@@ -113,11 +113,11 @@
auto& inlineTextItem = downcast<Layout::InlineTextItem>(*inlineItem);
auto inlineContent = inlineTextItem.layoutBox().textContent();
while (true) {
- auto& run = inlineRuns[runIndex++];
+ auto& run = *inlineRuns[runIndex++];
auto textContext = run.textContext().value();
auto runContent = inlineContent.substring(textContext.start(), textContext.length());
auto logicalTopLeft = rootAbsoluteDisplayBox.topLeft() + run.logicalTopLeft();
- context.drawText(style.fontCascade(), TextRun { runContent }, { logicalTopLeft.x(), logicalTopLeft.y() + formattingState.lineBoxes()[0].baselineOffset() });
+ context.drawText(style.fontCascade(), TextRun { runContent }, { logicalTopLeft.x(), logicalTopLeft.y() + formattingState.lineBoxes()[0]->baselineOffset() });
if (inlineTextItem.end() == textContext.end())
break;
if (runIndex == inlineRuns.size())
@@ -127,7 +127,7 @@
}
if (inlineItem->isBox()) {
- auto& run = inlineRuns[runIndex++];
+ auto& run = *inlineRuns[runIndex++];
auto logicalTopLeft = rootAbsoluteDisplayBox.topLeft() + run.logicalTopLeft();
context.fillRect({ logicalTopLeft, FloatSize { run.logicalWidth(), run.logicalHeight() } });
continue;
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
index d4d89e85..12f24b3 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
@@ -418,6 +418,9 @@
}
// Add final display runs to state.
+ formattingState.addLineBox(lineContent.lineBox);
+ // FIXME: This is tempoary.
+ auto& currentLine = *formattingState.lineBoxes().last();
for (auto& lineRun : lineContent.runList) {
// Inline level containers (<span>) don't generate inline runs.
if (lineRun->isContainerStart() || lineRun->isContainerEnd())
@@ -425,7 +428,7 @@
// Collapsed line runs don't generate display runs.
if (lineRun->isVisuallyEmpty())
continue;
- formattingState.addInlineRun(lineRun->displayRun());
+ formattingState.addInlineRun(lineRun->displayRun(), currentLine);
}
// Compute box final geometry.
@@ -491,7 +494,6 @@
}
ASSERT_NOT_REACHED();
}
- formattingState.addLineBox(lineContent.lineBox);
}
}
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp b/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp
index 37f67f1..2f5e5bb 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingContextQuirks.cpp
@@ -64,7 +64,7 @@
if (layoutBox.isInlineBlockBox() && layoutBox.establishesInlineFormattingContext()) {
auto& formattingState = downcast<InlineFormattingState>(layoutState.establishedFormattingState(downcast<Container>(layoutBox)));
ASSERT(!formattingState.lineBoxes().isEmpty());
- auto inlineBlockBaseline = formattingState.lineBoxes().last().baseline();
+ auto inlineBlockBaseline = formattingState.lineBoxes().last()->baseline();
if (inlineBlockBaseline.descent())
return false;
}
diff --git a/Source/WebCore/layout/inlineformatting/InlineFormattingState.h b/Source/WebCore/layout/inlineformatting/InlineFormattingState.h
index 3534588..006ae6d 100644
--- a/Source/WebCore/layout/inlineformatting/InlineFormattingState.h
+++ b/Source/WebCore/layout/inlineformatting/InlineFormattingState.h
@@ -39,8 +39,8 @@
// Temp
using InlineItems = Vector<std::unique_ptr<InlineItem>>;
-using InlineRuns = Vector<Display::Run>;
-using LineBoxes = Vector<LineBox>;
+using InlineRuns = Vector<std::unique_ptr<Display::Run>>;
+using LineBoxes = Vector<std::unique_ptr<LineBox>>;
// InlineFormattingState holds the state for a particular inline formatting context tree.
class InlineFormattingState : public FormattingState {
WTF_MAKE_ISO_ALLOCATED(InlineFormattingState);
@@ -54,18 +54,29 @@
const InlineRuns& inlineRuns() const { return m_inlineRuns; }
InlineRuns& inlineRuns() { return m_inlineRuns; }
- void addInlineRun(const Display::Run& inlineRun) { m_inlineRuns.append(inlineRun); }
+ void addInlineRun(const Display::Run&, const LineBox&);
const LineBoxes& lineBoxes() const { return m_lineBoxes; }
LineBoxes& lineBoxes() { return m_lineBoxes; }
- void addLineBox(LineBox lineBox) { m_lineBoxes.append(lineBox); }
+ void addLineBox(const LineBox& lineBox) { m_lineBoxes.append(makeUnique<LineBox>(lineBox)); }
+
+ const LineBox& lineBoxForRun(const Display::Run& inlineRun) const { return *m_inlineRunToLineMap.get(&inlineRun); }
private:
InlineItems m_inlineItems;
InlineRuns m_inlineRuns;
LineBoxes m_lineBoxes;
+ // This is temporary until after we figure out the display run/line relationships.
+ HashMap<const Display::Run*, const LineBox*> m_inlineRunToLineMap;
};
+inline void InlineFormattingState::addInlineRun(const Display::Run& inlineRun, const LineBox& line)
+{
+ auto run = makeUnique<Display::Run>(inlineRun);
+ m_inlineRunToLineMap.set(run.get(), &line);
+ m_inlineRuns.append(WTFMove(run));
+}
+
}
}
diff --git a/Source/WebCore/layout/inlineformatting/InlineLine.cpp b/Source/WebCore/layout/inlineformatting/InlineLine.cpp
index c1f7150..62c327d 100644
--- a/Source/WebCore/layout/inlineformatting/InlineLine.cpp
+++ b/Source/WebCore/layout/inlineformatting/InlineLine.cpp
@@ -173,7 +173,7 @@
auto& formattingState = downcast<InlineFormattingState>(layoutState.establishedFormattingState(downcast<Container>(layoutBox)));
// Spec makes us generate at least one line -even if it is empty.
ASSERT(!formattingState.lineBoxes().isEmpty());
- auto inlineBlockBaselineOffset = formattingState.lineBoxes().last().baselineOffset();
+ auto inlineBlockBaselineOffset = formattingState.lineBoxes().last()->baselineOffset();
// The inline-block's baseline offset is relative to its content box. Let's convert it relative to the margin box.
// inline-block
// \
@@ -459,7 +459,7 @@
auto& formattingState = downcast<InlineFormattingState>(layoutState().establishedFormattingState(downcast<Container>(layoutBox)));
// Spec makes us generate at least one line -even if it is empty.
ASSERT(!formattingState.lineBoxes().isEmpty());
- auto& lastLineBox = formattingState.lineBoxes().last();
+ auto& lastLineBox = *formattingState.lineBoxes().last();
auto inlineBlockBaseline = lastLineBox.baseline();
auto beforeHeight = boxGeometry.marginBefore() + boxGeometry.borderTop() + boxGeometry.paddingTop().valueOr(0);
diff --git a/Source/WebCore/layout/inlineformatting/InlineLineBox.h b/Source/WebCore/layout/inlineformatting/InlineLineBox.h
index d1bd051..daf4b07 100644
--- a/Source/WebCore/layout/inlineformatting/InlineLineBox.h
+++ b/Source/WebCore/layout/inlineformatting/InlineLineBox.h
@@ -33,6 +33,7 @@
namespace Layout {
class LineBox {
+ WTF_MAKE_FAST_ALLOCATED;
public:
struct Baseline {
Baseline(LayoutUnit ascent, LayoutUnit descent);
diff --git a/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
index 71928a8..e5b588b 100644
--- a/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
+++ b/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
@@ -274,7 +274,7 @@
stream << "lines are -> ";
for (auto& lineBox : lineBoxes)
- stream << "[" << lineBox.logicalLeft() << "," << lineBox.logicalTop() << " " << lineBox.logicalWidth() << "x" << lineBox.logicalHeight() << "] ";
+ stream << "[" << lineBox->logicalLeft() << "," << lineBox->logicalTop() << " " << lineBox->logicalWidth() << "x" << lineBox->logicalHeight() << "] ";
stream.nextLine();
for (auto& inlineRun : inlineRuns) {
@@ -282,13 +282,13 @@
while (++printedCharacters <= depth * 2)
stream << " ";
stream << " ";
- if (inlineRun.textContext())
+ if (inlineRun->textContext())
stream << "inline text box";
else
stream << "inline box";
- stream << " at (" << inlineRun.logicalLeft() << "," << inlineRun.logicalTop() << ") size " << inlineRun.logicalWidth() << "x" << inlineRun.logicalHeight();
- if (inlineRun.textContext())
- stream << " run(" << inlineRun.textContext()->start() << ", " << inlineRun.textContext()->end() << ")";
+ stream << " at (" << inlineRun->logicalLeft() << "," << inlineRun->logicalTop() << ") size " << inlineRun->logicalWidth() << "x" << inlineRun->logicalHeight();
+ if (inlineRun->textContext())
+ stream << " run(" << inlineRun->textContext()->start() << ", " << inlineRun->textContext()->end() << ")";
stream.nextLine();
}
}