Diff
Modified: trunk/Source/WebCore/ChangeLog (281679 => 281680)
--- trunk/Source/WebCore/ChangeLog 2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/ChangeLog 2021-08-27 03:08:57 UTC (rev 281680)
@@ -1,5 +1,24 @@
2021-08-26 Alan Bujtas <[email protected]>
+ [LFC][Integration] Use the line runs to check for legacy integral positioning
+ https://bugs.webkit.org/show_bug.cgi?id=228069
+ <rdar://problem/81087857>
+
+ Reviewed by Antti Koivisto.
+
+ Now that the line runs list has all the inline boxes (including spanning inline boxes), we
+ can use this list to check for legacy integral positioning and not directly iterating the LineBox's non-rootinlinebox list.
+ While this may be a bit more expensive, the legacy positioning is temporary and will be removed shortly.
+
+ This is in preparation for keeping the inline box structure private to the layout code.
+
+ * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+ (WebCore::LayoutIntegration::InlineContentBuilder::build const):
+ (WebCore::LayoutIntegration::InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns const):
+ * layout/integration/LayoutIntegrationInlineContentBuilder.h:
+
+2021-08-26 Alan Bujtas <[email protected]>
+
REGRESSION(r275754): Using MarkOnlyThis to make the preferred width dirty introduces unexpected state
https://bugs.webkit.org/show_bug.cgi?id=229586
<rdar://82141454>
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp (281679 => 281680)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp 2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp 2021-08-27 03:08:57 UTC (rev 281680)
@@ -622,7 +622,7 @@
if (layoutBox.isLineBreakBox()) {
// Only hard linebreaks have associated layout boxes.
auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox);
- formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreak, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
+ formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreakBox, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } });
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
lineBreakBoxRect.moveBy(lineBoxLogicalRect.topLeft());
@@ -629,7 +629,7 @@
boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
} else
- formattingState.addLineRun({ lineIndex, LineRun::Type::LineBreak, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
+ formattingState.addLineRun({ lineIndex, LineRun::Type::SoftLineBreak, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() });
continue;
}
if (lineRun.isBox()) {
@@ -650,7 +650,7 @@
if (lineRun.isInlineBoxStart()) {
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
auto inlineBoxLogicalRect = lineBox.logicalBorderBoxForInlineBox(layoutBox, boxGeometry);
- formattingState.addLineRun({ lineIndex, LineRun::Type::InlineBox, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
+ formattingState.addLineRun({ lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { }, lineBox.inlineLevelBoxForLayoutBox(layoutBox).hasContent() });
inlineBoxStartSet.add(&layoutBox);
continue;
}
@@ -685,7 +685,7 @@
continue;
}
// Middle or end of the inline box. Let's stretch the box as needed.
- formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::InlineBox, layoutBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
+ formattingState.lineRuns().insert(lineSpanningInlineBoxIndex++, { lineIndex, LineRun::Type::NonRootInlineBox, layoutBox, inlineBoxBorderBox, { }, { }, inlineLevelBox.hasContent(), true });
auto enclosingBorderBoxRect = BoxGeometry::borderBoxRect(boxGeometry);
enclosingBorderBoxRect.expandToContain(logicalRect);
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h (281679 => 281680)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h 2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineRun.h 2021-08-27 03:08:57 UTC (rev 281680)
@@ -61,9 +61,10 @@
enum class Type {
Text,
- LineBreak,
+ SoftLineBreak,
+ LineBreakBox,
AtomicInlineLevelBox,
- InlineBox,
+ NonRootInlineBox,
RootInlineBox,
GenericInlineLevelBox
};
@@ -71,10 +72,16 @@
LineRun(size_t lineIndex, Type, const Box&, const InlineRect&, Expansion, std::optional<Text> = std::nullopt, bool hasContent = true, bool isLineSpanning = false);
bool isText() const { return m_type == Type::Text; }
- bool isLineBreak() const { return m_type == Type::LineBreak; }
+ bool isSoftLineBreak() const { return m_type == Type::SoftLineBreak; }
+ bool isLineBreakBox() const { return m_type == Type::LineBreakBox; }
+ bool isLineBreak() const { return isSoftLineBreak() || isLineBreakBox(); }
bool isAtomicInlineLevelBox() const { return m_type == Type::AtomicInlineLevelBox; }
- bool isInlineBox() const { return m_type == Type::InlineBox || isRootInlineBox(); }
+ bool isInlineBox() const { return isNonRootInlineBox() || isRootInlineBox(); }
+ bool isNonRootInlineBox() const { return m_type == Type::NonRootInlineBox; }
bool isRootInlineBox() const { return m_type == Type::RootInlineBox; }
+ bool isGenericInlineLevelBox() const { return m_type == Type::GenericInlineLevelBox; }
+ bool isInlineLevelBox() const { return isAtomicInlineLevelBox() || isLineBreakBox() || isInlineBox() || isGenericInlineLevelBox(); }
+ bool isNonRootInlineLevelBox() const { return isInlineLevelBox() && !isRootInlineBox(); }
Type type() const { return m_type; }
bool hasContent() const { return m_hasContent; }
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (281679 => 281680)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2021-08-27 03:08:57 UTC (rev 281680)
@@ -164,53 +164,71 @@
void InlineContentBuilder::build(const Layout::InlineFormattingState& inlineFormattingState, InlineContent& inlineContent) const
{
- auto lineLevelVisualAdjustmentsForRuns = computeLineLevelVisualAdjustmentsForRuns(inlineFormattingState);
+ auto lineLevelVisualAdjustmentsForRuns = computeLineLevelVisualAdjustmentsForRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns());
createDisplayLineRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns(), inlineContent, lineLevelVisualAdjustmentsForRuns);
createDisplayLines(inlineFormattingState.lines(), inlineContent, lineLevelVisualAdjustmentsForRuns);
}
-InlineContentBuilder::LineLevelVisualAdjustmentsForRunsList InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineFormattingState& inlineFormattingState) const
+InlineContentBuilder::LineLevelVisualAdjustmentsForRunsList InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineLines& lines, const Layout::InlineLineRuns& lineRuns) const
{
- auto& lines = inlineFormattingState.lines();
+ auto lineLevelVisualAdjustmentsForRuns = LineLevelVisualAdjustmentsForRunsList { lines.size() };
auto& rootStyle = m_layoutState.root().style();
- auto shouldCheckHorizontalOverflowForContentReplacement = rootStyle.overflowX() == Overflow::Hidden && rootStyle.textOverflow() != TextOverflow::Clip;
- auto lineLevelVisualAdjustmentsForRuns = LineLevelVisualAdjustmentsForRunsList { lines.size() };
- for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) {
- auto lineNeedsLegacyIntegralVerticalPosition = [&] {
+ auto inlineLevelBoxPreventsIntegralPosition = std::optional<bool> { };
+ size_t lineIndexToCheck = 0;
+ for (auto& lineRun : lineRuns) {
+ auto lineIndex = lineRun.lineIndex();
+ auto& layoutBox = lineRun.layoutBox();
+
+ if (lineIndexToCheck != lineIndex) {
+ auto lineNeedsIntegralPositioning = [&] {
+ if (!inlineLevelBoxPreventsIntegralPosition.has_value()) {
+ // This line does not have any non-root inline boxes.
+ // Lines like this with root inline box only force integral positioning.
+ return true;
+ }
+ return !*inlineLevelBoxPreventsIntegralPosition;
+ };
+ lineLevelVisualAdjustmentsForRuns[lineIndexToCheck].needsIntegralPosition = lineNeedsIntegralPositioning();
+ lineIndexToCheck = lineIndex;
+ inlineLevelBoxPreventsIntegralPosition = { };
+ }
+
+ if (!lineRun.isNonRootInlineLevelBox() || (inlineLevelBoxPreventsIntegralPosition.has_value() && *inlineLevelBoxPreventsIntegralPosition))
+ continue;
+
+ auto inlineLevelBoxPreventsLegacyIntegralVerticalPosition = [&] {
+ ASSERT(lineRun.isNonRootInlineLevelBox());
// Legacy inline tree integral rounds the vertical position for certain content (see LegacyInlineFlowBox::placeBoxesInBlockDirection and ::addToLine).
- auto& nonRootInlineLevelBoxList = inlineFormattingState.lineBoxes()[lineIndex].nonRootInlineLevelBoxes();
- if (nonRootInlineLevelBoxList.isEmpty()) {
- // This is text content only with root inline box.
+ // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
+ auto contentPreventsIntegralSnapping = lineRun.isAtomicInlineLevelBox() || (lineRun.isLineBreakBox() && !m_layoutState.inStandardsMode());
+ if (contentPreventsIntegralSnapping)
return true;
- }
- for (auto& inlineLevelBox : nonRootInlineLevelBoxList) {
- // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
- auto contentPreventsIntegralSnapping = inlineLevelBox.isAtomicInlineLevelBox() || (inlineLevelBox.isLineBreakBox() && !m_layoutState.inStandardsMode());
- if (contentPreventsIntegralSnapping)
- return false;
- auto& inlineLevelBoxStyle = inlineLevelBox.style();
- auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineLevelBoxStyle.lineHeight() || inlineLevelBoxStyle.verticalAlign() != VerticalAlign::Baseline;
- if (stylePreventsIntegralSnapping)
- return false;
+ auto& inlineLevelBoxStyle = layoutBox.style();
+ auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineLevelBoxStyle.lineHeight() || inlineLevelBoxStyle.verticalAlign() != VerticalAlign::Baseline;
+ if (stylePreventsIntegralSnapping)
+ return true;
- auto& rootFontMetrics = rootStyle.fontCascade().fontMetrics();
- auto& inlineLevelBoxFontMetrics = inlineLevelBoxStyle.fontCascade().fontMetrics();
- auto fontPreventsIntegralSnapping = !rootFontMetrics.hasIdenticalAscentDescentAndLineGap(inlineLevelBoxFontMetrics);
- if (fontPreventsIntegralSnapping)
- return false;
- }
- return true;
+ auto& rootFontMetrics = rootStyle.fontCascade().fontMetrics();
+ auto& inlineLevelBoxFontMetrics = inlineLevelBoxStyle.fontCascade().fontMetrics();
+ auto fontPreventsIntegralSnapping = !rootFontMetrics.hasIdenticalAscentDescentAndLineGap(inlineLevelBoxFontMetrics);
+ return fontPreventsIntegralSnapping;
};
- lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition = lineNeedsLegacyIntegralVerticalPosition();
- if (shouldCheckHorizontalOverflowForContentReplacement) {
- auto& line = lines[lineIndex];
- auto lineBoxLogicalWidth = line.lineBoxLogicalRect().width();
- auto overflowWidth = lineOverflowWidth(m_blockFlow, lineBoxLogicalWidth, line.contentLogicalWidth());
- lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement = overflowWidth > lineBoxLogicalWidth;
- }
+ inlineLevelBoxPreventsIntegralPosition = inlineLevelBoxPreventsLegacyIntegralVerticalPosition();
}
+ lineLevelVisualAdjustmentsForRuns[lineIndexToCheck].needsIntegralPosition = !inlineLevelBoxPreventsIntegralPosition.has_value() || !*inlineLevelBoxPreventsIntegralPosition;
+
+ auto shouldCheckHorizontalOverflowForContentReplacement = rootStyle.overflowX() == Overflow::Hidden && rootStyle.textOverflow() != TextOverflow::Clip;
+ if (!shouldCheckHorizontalOverflowForContentReplacement)
+ return lineLevelVisualAdjustmentsForRuns;
+
+ for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) {
+ auto& line = lines[lineIndex];
+ auto lineBoxLogicalWidth = line.lineBoxLogicalRect().width();
+ auto overflowWidth = lineOverflowWidth(m_blockFlow, lineBoxLogicalWidth, line.contentLogicalWidth());
+ lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement = overflowWidth > lineBoxLogicalWidth;
+ }
return lineLevelVisualAdjustmentsForRuns;
}
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h (281679 => 281680)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h 2021-08-27 02:06:37 UTC (rev 281679)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h 2021-08-27 03:08:57 UTC (rev 281680)
@@ -49,7 +49,7 @@
private:
using LineLevelVisualAdjustmentsForRunsList = Vector<LineLevelVisualAdjustmentsForRuns>;
- LineLevelVisualAdjustmentsForRunsList computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineFormattingState&) const;
+ LineLevelVisualAdjustmentsForRunsList computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineLines&, const Layout::InlineLineRuns&) const;
void createDisplayLineRuns(const Layout::InlineLines&, const Layout::InlineLineRuns&, InlineContent&, const LineLevelVisualAdjustmentsForRunsList&) const;
void createDisplayLines(const Layout::InlineLines&, InlineContent&, const LineLevelVisualAdjustmentsForRunsList&) const;