Skip to content

Commit a7d6999

Browse files
vitorrorizDan Robson
authored and
Dan Robson
committed
Cherry-pick c1353df. rdar://123854267
text-wrap balance should consider line-clamp when balancing https://bugs.webkit.org/show_bug.cgi?id=268302 rdar://121858978 Reviewed by Alan Baradlay. According to spec resolution [1], if line-clamp is defined, text-wrap: balance should balance only within the clamped lines. Up to this patch, we would balance taking into consideration all the lines and we would clamp it after balance. This patches makes InlineContentBalancer::initialize() take the maximum number of visible lines into account, based into the line-clamp property. Also, this allows for a small optimization: If line-clamp clamps to 1 line, we can skip balacing. [1] w3c/csswg-drafts#9310 * LayoutTests/TestExpectations: * Source/WebCore/layout/formattingContexts/block/BlockLayoutState.h: (WebCore::Layout::BlockLayoutState::LineClamp::allowedLineCount const): * Source/WebCore/layout/formattingContexts/inline/InlineContentBalancer.cpp: (WebCore::Layout::InlineContentBalancer::initialize): (WebCore::Layout::InlineContentBalancer::computeBalanceConstraints): * Source/WebCore/layout/formattingContexts/inline/InlineContentBalancer.h: * Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp: (WebCore::Layout::InlineFormattingContext::createDisplayContentForInlineContent): Canonical link: https://commits.webkit.org/273800@main Canonical link: https://commits.webkit.org/272448.662@safari-7618-branch
1 parent a3ef1a9 commit a7d6999

File tree

5 files changed

+19
-8
lines changed

5 files changed

+19
-8
lines changed

LayoutTests/TestExpectations

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3071,7 +3071,6 @@ webkit.org/b/257049 imported/w3c/web-platform-tests/css/css-text/white-space/ful
30713071
webkit.org/b/257049 imported/w3c/web-platform-tests/css/css-text/white-space/seg-break-transformation-018.tentative.html [ ImageOnlyFailure ]
30723072
webkit.org/b/257049 imported/w3c/web-platform-tests/css/css-text/white-space/seg-break-transformation-019.tentative.html [ ImageOnlyFailure ]
30733073
webkit.org/b/257049 imported/w3c/web-platform-tests/css/css-text/white-space/tab-bidi-001.html [ ImageOnlyFailure ]
3074-
webkit.org/b/257049 imported/w3c/web-platform-tests/css/css-text/white-space/text-wrap-balance-line-clamp-001.html [ ImageOnlyFailure ]
30753074
imported/w3c/web-platform-tests/css/css-text/white-space/text-wrap-balance-float-001.html [ ImageOnlyFailure ]
30763075
imported/w3c/web-platform-tests/css/css-text/white-space/text-wrap-balance-float-002.html [ ImageOnlyFailure ]
30773076
imported/w3c/web-platform-tests/css/css-text/white-space/text-wrap-balance-float-003.html [ ImageOnlyFailure ]

Source/WebCore/layout/formattingContexts/block/BlockLayoutState.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ namespace Layout {
3333

3434
class BlockFormattingContext;
3535

36-
// This class holds block level information shared across child inline formatting contexts.
36+
// This class holds block level information shared across child inline formatting contexts.
3737
class BlockLayoutState {
3838
public:
3939
struct LineClamp {
40+
size_t allowedLineCount() const { return std::max(maximumLineCount - currentLineCount, 0lu); }
4041
size_t maximumLineCount { 0 };
4142
size_t currentLineCount { 0 };
4243
};

Source/WebCore/layout/formattingContexts/inline/InlineContentBalancer.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,20 @@ InlineContentBalancer::InlineContentBalancer(InlineFormattingContext& inlineForm
110110

111111
void InlineContentBalancer::initialize()
112112
{
113+
auto lineClamp = m_inlineFormattingContext.layoutState().parentBlockLayoutState().lineClamp();
114+
auto numberOfVisibleLinesAllowed = lineClamp ? std::make_optional(lineClamp->allowedLineCount()) : std::nullopt;
115+
113116
if (!m_inlineFormattingContext.layoutState().placedFloats().isEmpty()) {
114117
m_cannotBalanceContent = true;
115118
return;
116119
}
117120

121+
// if we have a single line content, we don't have anything to be balanced.
122+
if (numberOfVisibleLinesAllowed == 1) {
123+
m_hasSingleLineVisibleContent = true;
124+
return;
125+
}
126+
118127
m_numberOfInlineItems = m_inlineItemList.size();
119128
m_maximumLineWidth = m_horizontalConstraints.logicalWidth;
120129

@@ -153,6 +162,10 @@ void InlineContentBalancer::initialize()
153162
auto textIndent = m_inlineFormattingContext.formattingUtils().computedTextIndent(InlineFormattingUtils::IsIntrinsicWidthMode::No, previousLineEndsWithLineBreak, m_maximumLineWidth);
154163
m_originalLineWidths.append(textIndent + lineSlidingWidth.width());
155164

165+
// If next line count would match (or exceed) the number of visible lines due to line-clamp, we can bail out early.
166+
if (numberOfVisibleLinesAllowed && (lineIndex + 1 >= numberOfVisibleLinesAllowed))
167+
break;
168+
156169
layoutRange.start = InlineFormattingUtils::leadingInlineItemPositionForNextLine(lineLayoutResult.inlineItemRange.end, previousLineEnd, layoutRange.end);
157170
previousLineEnd = layoutRange.start;
158171
previousLine = PreviousLine { lineIndex, lineLayoutResult.contentGeometry.trailingOverflowingContentWidth, !lineLayoutResult.inlineContent.isEmpty() && lineLayoutResult.inlineContent.last().isLineBreak(), !lineLayoutResult.inlineContent.isEmpty(), lineLayoutResult.directionality.inlineBaseDirection, WTFMove(lineLayoutResult.floatContent.suspendedFloats) };
@@ -164,7 +177,7 @@ void InlineContentBalancer::initialize()
164177

165178
std::optional> InlineContentBalancer::computeBalanceConstraints()
166179
{
167-
if (m_cannotBalanceContent)
180+
if (m_cannotBalanceContent || m_hasSingleLineVisibleContent)
168181
return std::nullopt;
169182

170183
// If forced line breaks exist, then we can balance each forced-break-delimited

Source/WebCore/layout/formattingContexts/inline/InlineContentBalancer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class InlineContentBalancer {
6363
size_t m_numberOfInlineItems { 0 };
6464
double m_maximumLineWidth { 0 };
6565
bool m_cannotBalanceContent { false };
66+
bool m_hasSingleLineVisibleContent { false };
6667

6768
struct SlidingWidth {
6869
SlidingWidth(const InlineContentBalancer&, const InlineItemList&, size_t start, size_t end, bool useFirstLineStyle, bool isFirstLineInChunk);

Source/WebCore/layout/formattingContexts/inline/InlineFormattingContext.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -314,11 +314,8 @@ void InlineFormattingContext::updateBoxGeometryForPlacedFloats(const LineLayoutR
314314

315315
InlineRect InlineFormattingContext::createDisplayContentForInlineContent(const LineBox& lineBox, const LineLayoutResult& lineLayoutResult, const ConstraintsForInlineContent& constraints, InlineDisplay::Content& displayContent, size_t numberOfPreviousLinesWithInlineContent)
316316
{
317-
auto numberOfVisibleLinesAllowed = [&] () -> std::optional<size_t> {
318-
if (auto lineClamp = layoutState().parentBlockLayoutState().lineClamp())
319-
return lineClamp->maximumLineCount > lineClamp->currentLineCount ? lineClamp->maximumLineCount - lineClamp->currentLineCount : 0;
320-
return { };
321-
}();
317+
auto numberOfVisibleLinesAllowed = layoutState().parentBlockLayoutState().lineClamp() ? std::make_optional(layoutState().parentBlockLayoutState().lineClamp()->allowedLineCount()) : std::nullopt;
318+
322319
auto numberOfLinesWithInlineContent = numberOfPreviousLinesWithInlineContent + (!lineLayoutResult.inlineContent.isEmpty() ? 1 : 0);
323320
auto lineIsFullyTruncatedInBlockDirection = numberOfVisibleLinesAllowed && numberOfLinesWithInlineContent > *numberOfVisibleLinesAllowed;
324321
auto displayLine = InlineDisplayLineBuilder { *this, constraints }.build(lineLayoutResult, lineBox, lineIsFullyTruncatedInBlockDirection);

0 commit comments

Comments
 (0)