Skip to content

Commit

Permalink
[IFC] Incorrect out-of-flow box placement when text-indent is present…
Browse files Browse the repository at this point in the history
… (display: inline)

https://bugs.webkit.org/show_bug.cgi?id=254492

Reviewed by Antti Koivisto.

Take text-ident (mainly each-line) into account when computing the static position for a "display: inline" out-of-flow box
on "overflowing line" after the last line with inline content.

* LayoutTests/fast/inline/out-of-flow-inline-with-text-indent-on-last-line-expected.html: Added.
* LayoutTests/fast/inline/out-of-flow-inline-with-text-indent-on-last-line.html: Added.
* Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.cpp:
(WebCore::Layout::InlineFormattingGeometry::lineBoxOffsetAfterLastLine const):
(WebCore::Layout::InlineFormattingGeometry::staticPositionForOutOfFlowInlineLevelBox const):
* Source/WebCore/layout/formattingContexts/inline/InlineFormattingGeometry.h:

Canonical link: https://commits.webkit.org/262170@main
  • Loading branch information
alanbaradlay committed Mar 27, 2023
1 parent 6485d96 commit fd637ab
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 4 deletions.
@@ -0,0 +1,24 @@
<style>
.container {
width: 50px;
height: 45px;
font-size: 10px;
color: transparent;
font-family: Ahem;
background-color: green;
}
.ref {
display: inline-block;
width: 25px;
height: 25px;
background-color: blue;
position: relative;
}
</style>
<div class=container>some text<br><div class=ref></div></div>
<div class=container>some text<br><div class=ref style="left: 25px;"></div></div>
<div class=container>some text<br><div class=ref style="left: -25px;"></div></div>
<div class=container>some text<br><div class=ref></div></div>
<div class=container>some text<br><div class=ref style="left: 50px;"></div></div>
<div class=container>some text<br><div class=ref style="left: 20px; top: 0px; height: 30px;"></div></div>
<div class=container></div>
@@ -0,0 +1,24 @@
<style>
.container {
width: 50px;
height: 45px;
font-size: 10px;
color: transparent;
font-family: Ahem;
background-color: green;
}
.out_of_flow {
display: inline;
width: 25px;
height: 25px;
background-color: blue;
position: absolute;
}
</style>
<div class=container style="text-indent: 10px;">some text<br><div class=out_of_flow></div></div>
<div class=container style="text-indent: 25px each-line;">some text<br><div class=out_of_flow></div></div>
<div class=container style="text-indent: -25px each-line;">some text<br><div class=out_of_flow></div></div>
<div class=container style="direction: rtl; text-indent: 25px each-line;">some text<br><div class=out_of_flow></div></div>
<div class=container style="direction: rtl; text-indent: -25px each-line;">some text<br><div class=out_of_flow></div></div>
<div class=container style="writing-mode: vertical-lr; text-indent: 20px each-line;">some text<br><div class=out_of_flow></div></div>
<div class=container style="writing-mode: vertical-lr; text-indent: -20px each-line;">some text<br><div class=out_of_flow></div></div>
Expand Up @@ -261,6 +261,13 @@ static std::optional<size_t> nextDisplayBoxIndex(const Box& outOfFlowBox, const
return { };
}

InlineLayoutUnit InlineFormattingGeometry::lineBoxOffsetAfterLastLine(const ConstraintsForInFlowContent& constraints) const
{
auto alignmentOffset = horizontalAlignmentOffset(constraints.horizontal().logicalWidth, IsLastLineOrAfterLineBreak::Yes);
auto textIndent = computedTextIndent(IsIntrinsicWidthMode::No, true, constraints.horizontal().logicalWidth);
return alignmentOffset + constraints.horizontal().logicalLeft + textIndent;
}

LayoutPoint InlineFormattingGeometry::staticPositionForOutOfFlowInlineLevelBox(const Box& outOfFlowBox, const ConstraintsForInFlowContent& constraints, const InlineDisplay::Content& displayContent) const
{
ASSERT(outOfFlowBox.style().isOriginalDisplayInlineType());
Expand All @@ -269,8 +276,7 @@ LayoutPoint InlineFormattingGeometry::staticPositionForOutOfFlowInlineLevelBox(c

if (lines.isEmpty()) {
ASSERT(boxes.isEmpty());
auto alignmentOffset = horizontalAlignmentOffset(constraints.horizontal().logicalWidth, IsLastLineOrAfterLineBreak::Yes);
return { constraints.horizontal().logicalLeft + alignmentOffset, constraints.logicalTop() };
return { lineBoxOffsetAfterLastLine(constraints), constraints.logicalTop() };
}

auto isHorizontalWritingMode = formattingContext().root().style().isHorizontalWritingMode();
Expand Down Expand Up @@ -313,8 +319,7 @@ LayoutPoint InlineFormattingGeometry::staticPositionForOutOfFlowInlineLevelBox(c
auto nextDisplayBoxIndexAfterOutOfFlow = nextDisplayBoxIndex(outOfFlowBox, boxes);
if (!nextDisplayBoxIndexAfterOutOfFlow) {
// This is the last content on the block and it does not fit the last line.
auto alignmentOffset = horizontalAlignmentOffset(constraints.horizontal().logicalWidth, IsLastLineOrAfterLineBreak::Yes);
return { constraints.horizontal().logicalLeft + alignmentOffset, isHorizontalWritingMode ? currentLine.bottom() : currentLine.right() };
return { lineBoxOffsetAfterLastLine(constraints), isHorizontalWritingMode ? currentLine.bottom() : currentLine.right() };
}
auto& nextDisplayBox = boxes[*nextDisplayBoxIndexAfterOutOfFlow];
return leftSideToLogicalTopLeft(nextDisplayBox, lines[nextDisplayBox.lineIndex()]);
Expand Down
Expand Up @@ -65,6 +65,8 @@ class InlineFormattingGeometry : public FormattingGeometry {
InlineLayoutUnit horizontalAlignmentOffset(InlineLayoutUnit horizontalAvailableSpace, IsLastLineOrAfterLineBreak, std::optional<TextDirection> inlineBaseDirectionOverride = std::nullopt) const;

private:
InlineLayoutUnit lineBoxOffsetAfterLastLine(const ConstraintsForInFlowContent&) const;

const InlineFormattingContext& formattingContext() const { return downcast<InlineFormattingContext>(FormattingGeometry::formattingContext()); }

};
Expand Down

0 comments on commit fd637ab

Please sign in to comment.