Skip to content

Commit

Permalink
[IFC][Intrinsic width] Maximum content size may be computed during mi…
Browse files Browse the repository at this point in the history
…nimum phase in some limited cases

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

Reviewed by Antti Koivisto.

Let's compute the maximum content width between 2 forced line breaks and cache it.
'Preserve whitespace' type of text only content may reuse it as maximum content size.

* Source/WebCore/layout/formattingContexts/inline/InlineLine.cpp: Hanging content is still there, it just does not count as content width.

(WebCore::Layout::Line::handleTrailingHangingContent):
* Source/WebCore/layout/formattingContexts/inline/IntrinsicWidthHandler.cpp:
(WebCore::Layout::mayUseContentWidthBetweenLineBreaksAsMaximumSize):
(WebCore::Layout::IntrinsicWidthHandler::maximumContentSize):
(WebCore::Layout::IntrinsicWidthHandler::computedIntrinsicWidthForConstraint):
* Source/WebCore/layout/formattingContexts/inline/IntrinsicWidthHandler.h:

Canonical link: https://commits.webkit.org/272853@main
  • Loading branch information
alanbaradlay committed Jan 10, 2024
1 parent 058ed67 commit 7ab6ffc
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ void Line::handleTrailingHangingContent(std::optional<IntrinsicWidthMode> intrin
if (*intrinsicWidthMode == IntrinsicWidthMode::Minimum || !hangingTrailingContentIsConditional) {
ASSERT(m_trimmableTrailingContent.isEmpty());
m_contentLogicalWidth -= m_hangingContent.trailingWidth();
m_hangingContent.resetTrailingContent();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ static bool isContentEligibleForNonLineBuilderMinimumWidth(const ElementBox& roo
return (mayUseSimplifiedTextOnlyInlineLayout && isBoxEligibleForNonLineBuilderMinimumWidth(rootBox)) || (!mayUseSimplifiedTextOnlyInlineLayout && isSubtreeEligibleForNonLineBuilderMinimumWidth(rootBox));
}

static bool mayUseContentWidthBetweenLineBreaksAsMaximumSize(const ElementBox& rootBox)
{
return TextUtil::shouldPreserveSpacesAndTabs(rootBox);
}

IntrinsicWidthHandler::IntrinsicWidthHandler(InlineFormattingContext& inlineFormattingContext, const InlineItemList& inlineItemList, bool mayUseSimplifiedTextOnlyInlineLayout)
: m_inlineFormattingContext(inlineFormattingContext)
, m_inlineItemList(inlineItemList)
Expand Down Expand Up @@ -99,8 +104,16 @@ InlineLayoutUnit IntrinsicWidthHandler::maximumContentSize()
if (isContentEligibleForNonLineBuilderMaximumWidth(root(), m_inlineItemList))
maximumContentSize = simplifiedMaximumWidth(mayCacheLayoutResult);
else if (m_mayUseSimplifiedTextOnlyInlineLayout) {
auto simplifiedLineBuilder = TextOnlySimpleLineBuilder { formattingContext(), { }, m_inlineItemList };
maximumContentSize = computedIntrinsicWidthForConstraint(IntrinsicWidthMode::Maximum, simplifiedLineBuilder, mayCacheLayoutResult);
if (m_maximumContentWidthBetweenLineBreaks && mayUseContentWidthBetweenLineBreaksAsMaximumSize(root())) {
#ifndef NDEBUG
auto simplifiedLineBuilder = TextOnlySimpleLineBuilder { formattingContext(), { }, m_inlineItemList };
ASSERT(*m_maximumContentWidthBetweenLineBreaks == computedIntrinsicWidthForConstraint(IntrinsicWidthMode::Maximum, simplifiedLineBuilder, MayCacheLayoutResult::No));
#endif
maximumContentSize = *m_maximumContentWidthBetweenLineBreaks;
} else {
auto simplifiedLineBuilder = TextOnlySimpleLineBuilder { formattingContext(), { }, m_inlineItemList };
maximumContentSize = computedIntrinsicWidthForConstraint(IntrinsicWidthMode::Maximum, simplifiedLineBuilder, mayCacheLayoutResult);
}
} else {
auto lineBuilder = LineBuilder { formattingContext(), { }, m_inlineItemList };
maximumContentSize = computedIntrinsicWidthForConstraint(IntrinsicWidthMode::Maximum, lineBuilder, mayCacheLayoutResult);
Expand All @@ -119,6 +132,11 @@ InlineLayoutUnit IntrinsicWidthHandler::computedIntrinsicWidthForConstraint(Intr
return { };

auto maximumContentWidth = InlineLayoutUnit { };
struct ContentWidthBetweenLineBreaks {
InlineLayoutUnit maximum { };
InlineLayoutUnit current { };
};
auto contentWidthBetweenLineBreaks = ContentWidthBetweenLineBreaks { };
auto previousLineEnd = std::optional<InlineItemPosition> { };
auto previousLine = std::optional<PreviousLine> { };
auto lineIndex = 0lu;
Expand All @@ -139,7 +157,13 @@ InlineLayoutUnit IntrinsicWidthHandler::computedIntrinsicWidthForConstraint(Intr
}
return InlineLayoutUnit { leftWidth + rightWidth };
};
maximumContentWidth = std::max(maximumContentWidth, lineLayoutResult.lineGeometry.logicalTopLeft.x() + lineLayoutResult.contentGeometry.logicalWidth + floatContentWidth());

auto lineEndsWithLineBreak = !lineLayoutResult.inlineContent.isEmpty() && lineLayoutResult.inlineContent.last().isLineBreak();
auto lineContentLogicalWidth = lineLayoutResult.lineGeometry.logicalTopLeft.x() + lineLayoutResult.contentGeometry.logicalWidth + floatContentWidth();
maximumContentWidth = std::max(maximumContentWidth, lineContentLogicalWidth);
contentWidthBetweenLineBreaks.current += (lineContentLogicalWidth + lineLayoutResult.hangingContent.logicalWidth);
if (lineEndsWithLineBreak)
contentWidthBetweenLineBreaks = { std::max(contentWidthBetweenLineBreaks.maximum, contentWidthBetweenLineBreaks.current), { } };

layoutRange.start = InlineFormattingUtils::leadingInlineItemPositionForNextLine(lineLayoutResult.inlineItemRange.end, previousLineEnd, layoutRange.end);
if (layoutRange.isEmpty()) {
Expand All @@ -157,8 +181,9 @@ InlineLayoutUnit IntrinsicWidthHandler::computedIntrinsicWidthForConstraint(Intr
mayCacheLayoutResult = MayCacheLayoutResult::No;
previousLineEnd = layoutRange.start;
auto hasSeenInlineContent = previousLine ? previousLine->hasInlineContent || !lineLayoutResult.inlineContent.isEmpty() : !lineLayoutResult.inlineContent.isEmpty();
previousLine = PreviousLine { lineIndex++, lineLayoutResult.contentGeometry.trailingOverflowingContentWidth, !lineLayoutResult.inlineContent.isEmpty() && lineLayoutResult.inlineContent.last().isLineBreak(), hasSeenInlineContent, { }, WTFMove(lineLayoutResult.floatContent.suspendedFloats) };
previousLine = PreviousLine { lineIndex++, lineLayoutResult.contentGeometry.trailingOverflowingContentWidth, lineEndsWithLineBreak, hasSeenInlineContent, { }, WTFMove(lineLayoutResult.floatContent.suspendedFloats) };
}
m_maximumContentWidthBetweenLineBreaks = contentWidthBetweenLineBreaks.maximum;
return maximumContentWidth;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class IntrinsicWidthHandler {
const InlineItemList& m_inlineItemList;
const bool m_mayUseSimplifiedTextOnlyInlineLayout { false };

std::optional<InlineLayoutUnit> m_maximumContentWidthBetweenLineBreaks { };
std::optional<LineBreakingResult> m_maximumIntrinsicWidthResultForSingleLine { };
};

Expand Down

0 comments on commit 7ab6ffc

Please sign in to comment.