Skip to content

Commit

Permalink
[IFC] Add non-line-builder based minimum width computation
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=260454

Reviewed by Antti Koivisto.

Minimum size computation with breaking at arbitrary positions does not require line builder.

(This is a 4x speedup on PerformanceTests/Layout/line-layout-preferred-width-break-all.html)

* PerformanceTests/Layout/line-layout.html:
* Source/WebCore/layout/formattingContexts/inline/IntrinsicWidthHandler.cpp:
(WebCore::Layout::isEligibleForNonLineBuilderProcess):
(WebCore::Layout::IntrinsicWidthHandler::computedIntrinsicSizes):
(WebCore::Layout::IntrinsicWidthHandler::simplifiedMinimumWidth const):
* Source/WebCore/layout/formattingContexts/inline/IntrinsicWidthHandler.h:
* Source/WebCore/layout/formattingContexts/inline/TextOnlySimpleLineBuilder.cpp:
(WebCore::Layout::TextOnlySimpleLineBuilder::TextOnlySimpleLineBuilder):
(WebCore::Layout::TextOnlySimpleLineBuilder::layoutInlineContent):
* Source/WebCore/layout/formattingContexts/inline/TextOnlySimpleLineBuilder.h:
(WebCore::Layout::TextOnlySimpleLineBuilder::isWrappingAllowed const):

Canonical link: https://commits.webkit.org/267116@main
  • Loading branch information
alanbaradlay committed Aug 22, 2023
1 parent cb3dfe3 commit 23014dd
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
namespace WebCore {
namespace Layout {

static bool isEligibleForNonLineBuilderProcess(const RenderStyle& style)
{
return TextUtil::isWrappingAllowed(style) && (style.lineBreak() == LineBreak::Anywhere || style.wordBreak() == WordBreak::BreakAll || style.wordBreak() == WordBreak::BreakWord);
}

IntrinsicWidthHandler::IntrinsicWidthHandler(const InlineFormattingContext& inlineFormattingContext)
: m_inlineFormattingContext(inlineFormattingContext)
{
Expand All @@ -44,24 +49,24 @@ IntrinsicWidthHandler::IntrinsicWidthHandler(const InlineFormattingContext& inli
IntrinsicWidthConstraints IntrinsicWidthHandler::computedIntrinsicSizes()
{
auto& inlineFormattingState = formattingState();
auto& rootStyle = root().style();

auto computedIntrinsicValue = [&](auto intrinsicWidthMode, auto& inlineBuilder, MayCacheLayoutResult mayCacheLayoutResult = MayCacheLayoutResult::No) {
inlineBuilder.setIntrinsicWidthMode(intrinsicWidthMode);
return ceiledLayoutUnit(computedIntrinsicWidthForConstraint(intrinsicWidthMode, inlineBuilder, mayCacheLayoutResult));
};

auto intrinsicSizes = IntrinsicWidthConstraints { };
if (TextOnlySimpleLineBuilder::isEligibleForSimplifiedTextOnlyInlineLayout(root(), inlineFormattingState)) {
auto simplifiedLineBuilder = TextOnlySimpleLineBuilder { formattingContext(), { }, inlineFormattingState.inlineItems() };
intrinsicSizes = { computedIntrinsicValue(IntrinsicWidthMode::Minimum, simplifiedLineBuilder), computedIntrinsicValue(IntrinsicWidthMode::Maximum, simplifiedLineBuilder, TextOnlySimpleLineBuilder::hasIntrinsicWidthSpecificStyle(root().style()) ? MayCacheLayoutResult::No : MayCacheLayoutResult::Yes) };
} else {
auto floatingState = FloatingState { root() };
auto parentBlockLayoutState = BlockLayoutState { floatingState, { } };
auto inlineLayoutState = InlineLayoutState { parentBlockLayoutState, { } };
auto lineBuilder = LineBuilder { formattingContext(), inlineLayoutState, floatingState, { }, inlineFormattingState.inlineItems() };
intrinsicSizes = { computedIntrinsicValue(IntrinsicWidthMode::Minimum, lineBuilder), computedIntrinsicValue(IntrinsicWidthMode::Maximum, lineBuilder) };
auto minimumWidth = isEligibleForNonLineBuilderProcess(rootStyle) ? ceiledLayoutUnit(simplifiedMinimumWidth()) : computedIntrinsicValue(IntrinsicWidthMode::Minimum, simplifiedLineBuilder);
return { minimumWidth, computedIntrinsicValue(IntrinsicWidthMode::Maximum, simplifiedLineBuilder, TextOnlySimpleLineBuilder::hasIntrinsicWidthSpecificStyle(rootStyle) ? MayCacheLayoutResult::No : MayCacheLayoutResult::Yes) };
}
return intrinsicSizes;

auto floatingState = FloatingState { root() };
auto parentBlockLayoutState = BlockLayoutState { floatingState, { } };
auto inlineLayoutState = InlineLayoutState { parentBlockLayoutState, { } };
auto lineBuilder = LineBuilder { formattingContext(), inlineLayoutState, floatingState, { }, inlineFormattingState.inlineItems() };
return { computedIntrinsicValue(IntrinsicWidthMode::Minimum, lineBuilder), computedIntrinsicValue(IntrinsicWidthMode::Maximum, lineBuilder) };
}

LayoutUnit IntrinsicWidthHandler::maximumContentSize()
Expand Down Expand Up @@ -119,6 +124,31 @@ InlineLayoutUnit IntrinsicWidthHandler::computedIntrinsicWidthForConstraint(Intr
return maximumContentWidth;
}

InlineLayoutUnit IntrinsicWidthHandler::simplifiedMinimumWidth() const
{
auto& rootStyle = root().style();
auto& fontCascade = rootStyle.fontCascade();

auto maximumWidth = InlineLayoutUnit { };
for (auto& inlineItem : formattingState().inlineItems()) {
if (inlineItem.isText()) {
auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
auto contentLength = inlineTextItem.length();
size_t index = 0;
while (index < contentLength) {
auto characterIndex = inlineTextItem.start() + index;
auto characterLength = TextUtil::firstUserPerceivedCharacterLength(inlineTextItem.inlineTextBox(), characterIndex, contentLength - index);
ASSERT(characterLength);
maximumWidth = std::max(maximumWidth, TextUtil::width(inlineTextItem, fontCascade, characterIndex, characterIndex + characterLength, { }, TextUtil::UseTrailingWhitespaceMeasuringOptimization::No));
index += characterLength;
}
continue;
}
ASSERT(inlineItem.isLineBreak());
}
return maximumWidth;
}

const InlineFormattingContext& IntrinsicWidthHandler::formattingContext() const
{
return m_inlineFormattingContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class IntrinsicWidthHandler {
private:
enum class MayCacheLayoutResult : bool { No, Yes };
InlineLayoutUnit computedIntrinsicWidthForConstraint(IntrinsicWidthMode, AbstractLineBuilder&, MayCacheLayoutResult = MayCacheLayoutResult::No);
InlineLayoutUnit simplifiedMinimumWidth() const;

const InlineFormattingContext& formattingContext() const;
const InlineFormattingState& formattingState() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,14 @@ TextOnlySimpleLineBuilder::TextOnlySimpleLineBuilder(const InlineFormattingConte
, m_rootHorizontalConstraints(rootHorizontalConstraints)
, m_line(inlineFormattingContext)
, m_inlineItems(inlineItems)
, m_isWrappingAllowed(TextUtil::isWrappingAllowed(root().style()))
{
}

LineLayoutResult TextOnlySimpleLineBuilder::layoutInlineContent(const LineInput& lineInput, const std::optional<PreviousLine>& previousLine)
{
initialize(lineInput.needsLayoutRange, lineInput.initialLogicalRect, previousLine);
auto placedContentEnd = TextUtil::isWrappingAllowed(root().style()) ? placeInlineTextContent(lineInput.needsLayoutRange) : placeNonWrappingInlineTextContent(lineInput.needsLayoutRange);
auto placedContentEnd = isWrappingAllowed() ? placeInlineTextContent(lineInput.needsLayoutRange) : placeNonWrappingInlineTextContent(lineInput.needsLayoutRange);
auto result = m_line.close();

auto isLastLine = isLastLineWithInlineContent(placedContentEnd, lineInput.needsLayoutRange.endIndex());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class TextOnlySimpleLineBuilder : public AbstractLineBuilder {
size_t revertToTrailingItem(const InlineItemRange&, const InlineTextItem&);
size_t revertToLastNonOverflowingItem(const InlineItemRange&);
InlineLayoutUnit availableWidth() const;
bool isWrappingAllowed() const { return m_isWrappingAllowed; }

bool isFirstFormattedLine() const { return !m_previousLine.has_value(); }

Expand All @@ -73,6 +74,7 @@ class TextOnlySimpleLineBuilder : public AbstractLineBuilder {
InlineRect m_lineLogicalRect;
const InlineItems& m_inlineItems;
Vector<const InlineTextItem*> m_wrapOpportunityList;
bool m_isWrappingAllowed { false };

std::optional<InlineTextItem> m_partialLeadingTextItem;
};
Expand Down

0 comments on commit 23014dd

Please sign in to comment.