Diff
Modified: trunk/Source/WebCore/ChangeLog (281749 => 281750)
--- trunk/Source/WebCore/ChangeLog 2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/ChangeLog 2021-08-30 02:19:29 UTC (rev 281750)
@@ -1,5 +1,27 @@
2021-08-29 Alan Bujtas <[email protected]>
+ [LFC][IFC] Move "line needs integral snapping" computing to IFC from the integration layer
+ https://bugs.webkit.org/show_bug.cgi?id=229654
+
+ Reviewed by Antti Koivisto.
+
+ This is in preparation for merging the integration layer runs with IFC's display runs.
+ This also save a loop over the runs to compute the "line needs integration position" bit.
+
+ * layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp:
+ (WebCore::Layout::InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent):
+ * layout/formattingContexts/inline/InlineLineGeometry.h:
+ (WebCore::Layout::LineGeometry::needsIntegralPosition const):
+ (WebCore::Layout::LineGeometry::setNeedsIntegralPosition):
+ * layout/integration/LayoutIntegrationInlineContentBuilder.cpp:
+ (WebCore::LayoutIntegration::InlineContentBuilder::build const):
+ (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLineRuns const):
+ (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayLines const):
+ (WebCore::LayoutIntegration::InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns const): Deleted.
+ * layout/integration/LayoutIntegrationInlineContentBuilder.h:
+
+2021-08-29 Alan Bujtas <[email protected]>
+
[LFC][IFC] Add ink overflow to the line runs
https://bugs.webkit.org/show_bug.cgi?id=229653
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp (281749 => 281750)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineDisplayContentBuilder.cpp 2021-08-30 02:19:29 UTC (rev 281750)
@@ -61,6 +61,10 @@
void InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineContent(const LineBuilder::LineContent& lineContent, const LineBox& lineBox, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex)
{
auto& formattingState = this->formattingState();
+ // Legacy inline tree integral rounds the vertical position for certain content (see LegacyInlineFlowBox::placeBoxesInBlockDirection and ::addToLine).
+ // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
+ auto lineNeedIntegralPosition = true;
+ auto& rootStyle = root().style();
// Create the inline runs on the current line. This is mostly text and atomic inline runs.
for (auto& lineRun : lineContent.runs) {
auto& layoutBox = lineRun.layoutBox();
@@ -102,6 +106,8 @@
auto& boxGeometry = formattingState.boxGeometry(layoutBox);
boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft()));
boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height()));
+ if (!formattingState.layoutState().inStandardsMode())
+ lineNeedIntegralPosition = false;
break;
}
case InlineItem::Type::Box: {
@@ -115,6 +121,7 @@
// Note that inline boxes are relative to the line and their top position can be negative.
// Atomic inline boxes are all set. Their margin/border/content box geometries are already computed. We just have to position them here.
boxGeometry.setLogicalTopLeft(toLayoutPoint(borderBoxLogicalTopLeft));
+ lineNeedIntegralPosition = false;
break;
}
case InlineItem::Type::InlineBoxStart: {
@@ -134,6 +141,14 @@
boxGeometry.setContentBoxHeight(contentBoxHeight);
auto contentBoxWidth = logicalRect.width() - (boxGeometry.horizontalBorder() + boxGeometry.horizontalPadding().value_or(0_lu));
boxGeometry.setContentBoxWidth(contentBoxWidth);
+
+ if (lineNeedIntegralPosition) {
+ auto& inlineBoxStyle = layoutBox.style();
+ auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineBoxStyle.lineHeight() || inlineBoxStyle.verticalAlign() != VerticalAlign::Baseline;
+ auto fontPreventsIntegralSnapping = !rootStyle.fontCascade().fontMetrics().hasIdenticalAscentDescentAndLineGap(inlineBoxStyle.fontCascade().fontMetrics());
+ if (stylePreventsIntegralSnapping || fontPreventsIntegralSnapping)
+ lineNeedIntegralPosition = false;
+ }
break;
}
default:
@@ -141,6 +156,8 @@
break;
}
}
+ // FIXME: This is temporary. Remove when legacy line layout's integral snapping is removed.
+ formattingState.lines().last().setNeedsIntegralPosition(lineNeedIntegralPosition);
}
void InlineDisplayContentBuilder::createRunsAndUpdateGeometryForLineSpanningInlineBoxes(const LineBox& lineBox, const InlineLayoutPoint& lineBoxLogicalTopLeft, const size_t lineIndex, size_t lineSpanningInlineBoxIndex)
@@ -152,7 +169,9 @@
return;
}
+ auto& rootStyle = root().style();
auto& formattingState = this->formattingState();
+ auto lineNeedIntegralPosition = formattingState.lines().last().needsIntegralPosition();
for (auto& inlineLevelBox : lineBox.nonRootInlineLevelBoxes()) {
if (!inlineLevelBox.isLineSpanningInlineBox())
continue;
@@ -173,7 +192,17 @@
boxGeometry.setContentBoxHeight(enclosingBorderBoxRect.height() - (boxGeometry.verticalBorder() + boxGeometry.verticalPadding().value_or(0_lu)));
boxGeometry.setContentBoxWidth(enclosingBorderBoxRect.width() - (boxGeometry.horizontalBorder() + boxGeometry.horizontalPadding().value_or(0_lu)));
+
+ if (lineNeedIntegralPosition) {
+ auto& inlineBoxStyle = layoutBox.style();
+ auto stylePreventsIntegralSnapping = rootStyle.lineHeight() != inlineBoxStyle.lineHeight() || inlineBoxStyle.verticalAlign() != VerticalAlign::Baseline;
+ auto fontPreventsIntegralSnapping = !rootStyle.fontCascade().fontMetrics().hasIdenticalAscentDescentAndLineGap(inlineBoxStyle.fontCascade().fontMetrics());
+ if (stylePreventsIntegralSnapping || fontPreventsIntegralSnapping)
+ lineNeedIntegralPosition = false;
+ }
}
+ // FIXME: This is temporary. Remove when legacy line layout's integral snapping is removed.
+ formattingState.lines().last().setNeedsIntegralPosition(lineNeedIntegralPosition);
}
}
Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h (281749 => 281750)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h 2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineLineGeometry.h 2021-08-30 02:19:29 UTC (rev 281750)
@@ -51,7 +51,10 @@
InlineLayoutUnit contentLogicalLeft() const { return m_contentLogicalLeft; }
InlineLayoutUnit contentLogicalWidth() const { return m_contentLogicalWidth; }
+ bool needsIntegralPosition() const { return m_needsIntegralPosition; }
+
void moveVertically(InlineLayoutUnit offset) { m_lineBoxLogicalRect.moveVertically(offset); }
+ void setNeedsIntegralPosition(bool needsIntegralPosition) { m_needsIntegralPosition = needsIntegralPosition; }
private:
// This is line box geometry (see https://www.w3.org/TR/css-inline-3/#line-box).
@@ -63,6 +66,9 @@
InlineLayoutUnit m_aligmentBaseline { 0 };
InlineLayoutUnit m_contentLogicalLeft { 0 };
InlineLayoutUnit m_contentLogicalWidth { 0 };
+ // FIXME: This is just matching legacy line layout integral snapping.
+ // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
+ bool m_needsIntegralPosition { true };
};
inline LineGeometry::LineGeometry(const InlineRect& lineBoxLogicalRect, EnclosingTopAndBottom enclosingTopAndBottom, InlineLayoutUnit aligmentBaseline, InlineLayoutUnit contentLogicalLeft, InlineLayoutUnit contentLogicalWidth)
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp (281749 => 281750)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp 2021-08-30 02:19:29 UTC (rev 281750)
@@ -44,12 +44,6 @@
#define PROCESS_BIDI_CONTENT 0
-struct LineLevelVisualAdjustmentsForRuns {
- bool needsIntegralPosition { false };
- // It's only 'text-overflow: ellipsis' for now.
- bool needsTrailingContentReplacement { false };
-};
-
inline Layout::LineGeometry::EnclosingTopAndBottom operator+(const Layout::LineGeometry::EnclosingTopAndBottom enclosingTopAndBottom, float offset)
{
return { enclosingTopAndBottom.top + offset, enclosingTopAndBottom.bottom + offset };
@@ -164,76 +158,12 @@
void InlineContentBuilder::build(const Layout::InlineFormattingState& inlineFormattingState, InlineContent& inlineContent) const
{
- auto lineLevelVisualAdjustmentsForRuns = computeLineLevelVisualAdjustmentsForRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns());
- createDisplayLineRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns(), inlineContent, lineLevelVisualAdjustmentsForRuns);
- createDisplayLines(inlineFormattingState.lines(), inlineContent, lineLevelVisualAdjustmentsForRuns);
+ createDisplayLineRuns(inlineFormattingState.lines(), inlineFormattingState.lineRuns(), inlineContent);
+ createDisplayLines(inlineFormattingState.lines(), inlineContent);
}
-InlineContentBuilder::LineLevelVisualAdjustmentsForRunsList InlineContentBuilder::computeLineLevelVisualAdjustmentsForRuns(const Layout::InlineLines& lines, const Layout::InlineLineRuns& lineRuns) const
+void InlineContentBuilder::createDisplayLineRuns(const Layout::InlineLines& lines, const Layout::InlineLineRuns& lineRuns, InlineContent& inlineContent) const
{
- auto lineLevelVisualAdjustmentsForRuns = LineLevelVisualAdjustmentsForRunsList { lines.size() };
- auto& rootStyle = m_layoutState.root().style();
-
- 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).
- // See shouldClearDescendantsHaveSameLineHeightAndBaseline in LegacyInlineFlowBox::addToLine.
- auto contentPreventsIntegralSnapping = lineRun.isAtomicInlineLevelBox() || (lineRun.isLineBreakBox() && !m_layoutState.inStandardsMode());
- if (contentPreventsIntegralSnapping)
- return true;
-
- 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);
- return fontPreventsIntegralSnapping;
- };
- 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;
-}
-
-void InlineContentBuilder::createDisplayLineRuns(const Layout::InlineLines& lines, const Layout::InlineLineRuns& lineRuns, InlineContent& inlineContent, const LineLevelVisualAdjustmentsForRunsList& lineLevelVisualAdjustmentsForRuns) const
-{
if (lineRuns.isEmpty())
return;
@@ -261,7 +191,7 @@
auto inkOverflow = FloatRect { lineRun.inkOverflow() };
auto& geometry = m_layoutState.geometryForBox(layoutBox);
runRect.setSize({ geometry.borderBoxWidth(), geometry.borderBoxHeight() });
- if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
+ if (lines[lineIndex].needsIntegralPosition()) {
runRect.setY(roundToInt(runRect.y()));
inkOverflow.setY(roundToInt(inkOverflow.y()));
}
@@ -286,10 +216,9 @@
RELEASE_ASSERT(startOffset < endOffset);
auto& layoutBox = lineRun.layoutBox();
auto lineIndex = lineRun.lineIndex();
- auto& lineBoxLogicalRect = lines[lineIndex].lineBoxLogicalRect();
auto runRect = FloatRect { lineRun.logicalRect() };
auto inkOverflow = FloatRect { lineRun.inkOverflow() };
- if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
+ if (lines[lineIndex].needsIntegralPosition()) {
runRect.setY(roundToInt(runRect.y()));
inkOverflow.setY(roundToInt(inkOverflow.y()));
}
@@ -300,23 +229,6 @@
auto originalContent = text->content().substring(text->start(), text->length());
if (text->needsHyphen())
return makeString(originalContent, style.hyphenString());
- if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement) {
- // Currently it's ellipsis replacement only, but adding support for "text-overflow: string" should be relatively simple.
- if (hasAdjustedTrailingLineList[lineIndex]) {
- // This line already has adjusted trailing. Any runs after the ellipsis should render blank.
- return emptyString();
- }
- auto runLogicalRect = lineRun.logicalRect();
- auto ellipsisWidth = style.fontCascade().width(WebCore::TextRun { &horizontalEllipsis });
- if (runLogicalRect.right() + ellipsisWidth > lineBoxLogicalRect.right()) {
- // The next run with ellipsis would surely overflow. So let's just add it to this run even if
- // it makes the run wider than it originally was.
- hasAdjustedTrailingLineList[lineIndex] = true;
- float resultWidth = 0;
- auto maxWidth = lineBoxLogicalRect.width() - runLogicalRect.left();
- return StringTruncator::rightTruncate(originalContent, maxWidth, style.fontCascade(), resultWidth, true);
- }
- }
return String();
};
@@ -336,7 +248,7 @@
}
}
-void InlineContentBuilder::createDisplayLines(const Layout::InlineLines& lines, InlineContent& inlineContent, const LineLevelVisualAdjustmentsForRunsList& lineLevelVisualAdjustmentsForRuns) const
+void InlineContentBuilder::createDisplayLines(const Layout::InlineLines& lines, InlineContent& inlineContent) const
{
auto& runs = inlineContent.runs;
auto& nonRootInlineBoxes = inlineContent.nonRootInlineBoxes;
@@ -381,7 +293,7 @@
auto adjustedLineBoxRect = FloatRect { lineBoxLogicalRect };
// Final enclosing top and bottom values are in the same coordinate space as the line itself.
auto enclosingTopAndBottom = line.enclosingTopAndBottom() + lineBoxLogicalRect.top();
- if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) {
+ if (line.needsIntegralPosition()) {
adjustedLineBoxRect.setY(roundToInt(adjustedLineBoxRect.y()));
enclosingTopAndBottom.top = roundToInt(enclosingTopAndBottom.top);
enclosingTopAndBottom.bottom = roundToInt(enclosingTopAndBottom.bottom);
Modified: trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h (281749 => 281750)
--- trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h 2021-08-30 00:53:02 UTC (rev 281749)
+++ trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.h 2021-08-30 02:19:29 UTC (rev 281750)
@@ -38,7 +38,6 @@
class BoxTree;
struct InlineContent;
-struct LineLevelVisualAdjustmentsForRuns;
class InlineContentBuilder {
public:
@@ -47,12 +46,9 @@
void build(const Layout::InlineFormattingState&, InlineContent&) const;
private:
- using LineLevelVisualAdjustmentsForRunsList = Vector<LineLevelVisualAdjustmentsForRuns>;
+ void createDisplayLineRuns(const Layout::InlineLines&, const Layout::InlineLineRuns&, InlineContent&) const;
+ void createDisplayLines(const Layout::InlineLines&, InlineContent&) 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;
-
const Layout::LayoutState& m_layoutState;
const RenderBlockFlow& m_blockFlow;
const BoxTree& m_boxTree;