Skip to content

Commit f650a44

Browse files
committed
Incorrect repaint when inline content shrinks vertically
https://bugs.webkit.org/show_bug.cgi?id=250864 <rdar://103363945> Reviewed by Antti Koivisto. After-layout-repaint-rects take both before and after layout dimensions. This patch ensures that we have access to the "before geometry" even when we nuke the inline content as part of "line layout path" invalidation before running inline layout (this is going to change soon when we introduce partial invalidation). * LayoutTests/fast/repaint/leftover-after-shrinking-content-expected.txt: Added. * LayoutTests/fast/repaint/leftover-after-shrinking-content.html: Added. * Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp: (WebCore::LayoutIntegration::LineLayout::lastLineIndexForContentHeight const): * Source/WebCore/rendering/RenderBlockFlow.cpp: (WebCore::RenderBlockFlow::layoutInlineChildren): (WebCore::RenderBlockFlow::invalidateLineLayoutPath): (WebCore::RenderBlockFlow::layoutModernLines): * Source/WebCore/rendering/RenderBlockFlow.h: Canonical link: https://commits.webkit.org/259141@main
1 parent d6ca4dc commit f650a44

File tree

6 files changed

+78
-4
lines changed

6 files changed

+78
-4
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
12text content
2+
(repaint rects
3+
(rect 8 8 400 100)
4+
(rect 8 8 400 10)
5+
(rect 58 8 1 50)
6+
(rect 28 8 1 10)
7+
)
8+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<style>
2+
body {
3+
width: 400px;
4+
}
5+
span {
6+
font-family: Ahem;
7+
font-size: 50px;
8+
}
9+
</style>
10+
<!-- PASS if no repaint issue after shrinking the text content -->
11+
<span id=content>text content</span>
12+
<script>
13+
document.designMode = "on";
14+
let counter = 0;
15+
document.body.addEventListener("beforeinput", e => {
16+
if (++counter == 2) {
17+
content.style.fontSize = "10px";
18+
document.body.offsetHeight;
19+
}
20+
});
21+
22+
document.body.offsetHeight;
23+
24+
if (window.testRunner) {
25+
testRunner.dumpAsText();
26+
testRunner.waitUntilDone();
27+
}
28+
29+
setTimeout(function() {
30+
document.body.focus();
31+
document.execCommand("insertText", false, "1");
32+
33+
setTimeout(function() {
34+
if (window.internals)
35+
internals.startTrackingRepaints();
36+
document.execCommand("insertText", false, "2");
37+
document.body.offsetTop;
38+
39+
if (window.internals) {
40+
var repaintRects = internals.repaintRectsAsText();
41+
internals.stopTrackingRepaints();
42+
var pre = document.createElement('pre');
43+
document.body.appendChild(pre);
44+
pre.innerHTML = repaintRects;
45+
}
46+
if (window.testRunner)
47+
testRunner.notifyDone();
48+
}, 10);
49+
}, 10);
50+
</script>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
12text content
2+
(repaint rects
3+
(rect 8 8 400 100)
4+
(rect 8 8 400 10)
5+
)
6+

Source/WebCore/layout/integration/inline/LayoutIntegrationLineLayout.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,12 +707,13 @@ std::optional<size_t> LineLayout::lastLineIndexForContentHeight() const
707707
return { };
708708

709709
auto& lines = m_inlineContent->lines;
710-
auto* layoutState = flow().view().frameView().layoutContext().layoutState();
711-
if (!layoutState || lines.isEmpty()) {
710+
if (lines.isEmpty()) {
711+
// We should always have at least one line whenever we have inline content.
712712
ASSERT_NOT_REACHED();
713713
return { };
714714
}
715-
if (!layoutState->hasLineClamp())
715+
auto* layoutState = flow().view().frameView().layoutContext().layoutState();
716+
if (!layoutState || !layoutState->hasLineClamp())
716717
return lines.size() - 1;
717718

718719
auto maximumLines = *layoutState->maximumLineCountForLineClamp();

Source/WebCore/rendering/RenderBlockFlow.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& re
878878
m_lineLayout = makeUnique<LegacyLineLayout>(*this);
879879

880880
legacyLineLayout()->layoutLineBoxes(relayoutChildren, repaintLogicalTop, repaintLogicalBottom);
881+
m_previousModernLineLayoutContentBoxLogicalHeight = { };
881882
}
882883

883884
void RenderBlockFlow::layoutBlockChild(RenderBox& child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
@@ -3724,6 +3725,8 @@ void RenderBlockFlow::invalidateLineLayoutPath()
37243725
return;
37253726
case ModernPath: {
37263727
// FIXME: Implement partial invalidation.
3728+
if (modernLineLayout())
3729+
m_previousModernLineLayoutContentBoxLogicalHeight = modernLineLayout()->contentBoxLogicalHeight();
37273730
auto path = UndeterminedPath;
37283731
if (modernLineLayout() && modernLineLayout()->shouldSwitchToLegacyOnInvalidation())
37293732
path = ForcedLegacyPath;
@@ -3789,8 +3792,11 @@ void RenderBlockFlow::layoutModernLines(bool relayoutChildren, LayoutUnit& repai
37893792
auto contentBoxTop = borderAndPaddingBefore();
37903793

37913794
auto computeContentHeight = [&] {
3792-
if (!hasLines() && hasLineIfEmpty())
3795+
if (!hasLines() && hasLineIfEmpty()) {
3796+
if (m_previousModernLineLayoutContentBoxLogicalHeight)
3797+
return *m_previousModernLineLayoutContentBoxLogicalHeight;
37933798
return lineHeight(true, isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
3799+
}
37943800

37953801
return layoutFormattingContextLineLayout.contentBoxLogicalHeight();
37963802
};
@@ -3801,6 +3807,7 @@ void RenderBlockFlow::layoutModernLines(bool relayoutChildren, LayoutUnit& repai
38013807
};
38023808

38033809
auto oldBorderBoxBottom = computeBorderBoxBottom();
3810+
m_previousModernLineLayoutContentBoxLogicalHeight = { };
38043811

38053812
layoutFormattingContextLineLayout.layout();
38063813

Source/WebCore/rendering/RenderBlockFlow.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,8 @@ class RenderBlockFlow : public RenderBlock {
537537
int m_widthForTextAutosizing;
538538
unsigned m_lineCountForTextAutosizing : 2;
539539
#endif
540+
// FIXME: This is temporary until after we remove the forced "line layout codepath" invalidation.
541+
std::optional<LayoutUnit> m_previousModernLineLayoutContentBoxLogicalHeight;
540542

541543
public:
542544
// FIXME-BLOCKFLOW: These can be made protected again once all callers have been moved here.

0 commit comments

Comments
 (0)