Modified: trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp (286103 => 286104)
--- trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp 2021-11-21 20:10:00 UTC (rev 286103)
+++ trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp 2021-11-21 20:43:00 UTC (rev 286104)
@@ -88,6 +88,7 @@
collectInlineItems(inlineItems);
if (hasSeenBidiContent())
breakAndComputeBidiLevels(inlineItems);
+ computeInlineTextItemWidths(inlineItems);
return inlineItems;
}
@@ -367,6 +368,32 @@
return true;
}
+void InlineItemsBuilder::computeInlineTextItemWidths(InlineItems& inlineItems)
+{
+ for (auto& inlineItem : inlineItems) {
+ if (!inlineItem.isText())
+ continue;
+
+ auto& inlineTextItem = downcast<InlineTextItem>(inlineItem);
+ auto& inlineTextBox = inlineTextItem.inlineTextBox();
+ auto start = inlineTextItem.start();
+ auto length = inlineTextItem.length();
+ if (!canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, start, length, inlineTextItem.isWhitespace()))
+ continue;
+
+ auto width = [&]() -> std::optional<InlineLayoutUnit> {
+ auto singleWhiteSpace = inlineTextItem.isWhitespace() && (!TextUtil::shouldPreserveSpacesAndTabs(inlineTextBox) || (length == 1 && inlineTextBox.canUseSimplifiedContentMeasuring()));
+ if (singleWhiteSpace)
+ return inlineTextItem.style().fontCascade().spaceWidth();
+ if (length && !inlineTextItem.isZeroWidthSpaceSeparator())
+ return TextUtil::width(inlineTextBox, inlineTextItem.style().fontCascade(), start, start + length, { });
+ return { };
+ }();
+ if (width)
+ inlineTextItem.setWidth(*width);
+ }
+}
+
void InlineItemsBuilder::handleTextContent(const InlineTextBox& inlineTextBox, InlineItems& inlineItems)
{
auto text = inlineTextBox.content();
@@ -378,10 +405,7 @@
m_hasSeenBidiContent = true;
auto& style = inlineTextBox.style();
- auto& fontCascade = style.fontCascade();
- auto whiteSpaceWidth = std::optional<InlineLayoutUnit> { fontCascade.spaceWidth() };
auto shouldPreserveSpacesAndTabs = TextUtil::shouldPreserveSpacesAndTabs(inlineTextBox);
- auto whitespaceContentIsTreatedAsSingleSpace = !shouldPreserveSpacesAndTabs;
auto shouldPreserveNewline = TextUtil::shouldPreserveNewline(inlineTextBox);
auto shouldTreatNonBreakingSpaceAsRegularSpace = style.nbspMode() == NBSPMode::Space;
auto lineBreakIterator = LazyLineBreakIterator { text, style.computedLocale(), TextUtil::lineBreakIteratorMode(style.lineBreak()) };
@@ -400,30 +424,20 @@
continue;
auto handleWhitespace = [&] {
- auto stopAtWordSeparatorBoundary = shouldPreserveSpacesAndTabs && fontCascade.wordSpacing();
+ auto stopAtWordSeparatorBoundary = shouldPreserveSpacesAndTabs && style.fontCascade().wordSpacing();
auto whitespaceContent = moveToNextNonWhitespacePosition(text, currentPosition, shouldPreserveNewline, shouldPreserveSpacesAndTabs, shouldTreatNonBreakingSpaceAsRegularSpace, stopAtWordSeparatorBoundary);
if (!whitespaceContent)
return false;
ASSERT(whitespaceContent->length);
- auto appendWhitespaceItem = [&] (auto startPosition, auto itemLength) {
- auto width = [&]() -> std::optional<InlineLayoutUnit> {
- if (!canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, startPosition, itemLength, true))
- return { };
- if (whitespaceContentIsTreatedAsSingleSpace || (itemLength == 1 && inlineTextBox.canUseSimplifiedContentMeasuring()))
- return whiteSpaceWidth;
- return TextUtil::width(inlineTextBox, fontCascade, startPosition, startPosition + itemLength, { });
- }();
- inlineItems.append(InlineTextItem::createWhitespaceItem(inlineTextBox, startPosition, itemLength, UBIDI_DEFAULT_LTR, whitespaceContent->isWordSeparator, width));
- };
if (style.whiteSpace() == WhiteSpace::BreakSpaces) {
// https://www.w3.org/TR/css-text-3/#white-space-phase-1
// For break-spaces, a soft wrap opportunity exists after every space and every tab.
// FIXME: if this turns out to be a perf hit with too many individual whitespace inline items, we should transition this logic to line breaking.
for (size_t i = 0; i < whitespaceContent->length; ++i)
- appendWhitespaceItem(currentPosition + i, 1);
+ inlineItems.append(InlineTextItem::createWhitespaceItem(inlineTextBox, currentPosition + i, 1, UBIDI_DEFAULT_LTR, whitespaceContent->isWordSeparator, { }));
} else
- appendWhitespaceItem(currentPosition, whitespaceContent->length);
+ inlineItems.append(InlineTextItem::createWhitespaceItem(inlineTextBox, currentPosition, whitespaceContent->length, UBIDI_DEFAULT_LTR, whitespaceContent->isWordSeparator, { }));
currentPosition += whitespaceContent->length;
return true;
};
@@ -446,14 +460,7 @@
hasTrailingSoftHyphen = text[endPosition - 1] == softHyphen;
}
ASSERT_IMPLIES(style.hyphens() == Hyphens::None, !hasTrailingSoftHyphen);
- auto length = endPosition - startPosition;
- auto textWidth = [&]() -> std::optional<InlineLayoutUnit> {
- // Delay non-whitespace content measuring until after bidi split.
- if (hasSeenBidiContent() || !canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, startPosition, length, false))
- return { };
- return TextUtil::width(inlineTextBox, fontCascade, startPosition, endPosition, { });
- }();
- inlineItems.append(InlineTextItem::createNonWhitespaceItem(inlineTextBox, startPosition, length, UBIDI_DEFAULT_LTR, hasTrailingSoftHyphen, textWidth));
+ inlineItems.append(InlineTextItem::createNonWhitespaceItem(inlineTextBox, startPosition, endPosition - startPosition, UBIDI_DEFAULT_LTR, hasTrailingSoftHyphen, { }));
currentPosition = endPosition;
return true;
};