Changeset 286104 in webkit
- Timestamp:
- Nov 21, 2021, 12:43:00 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
-
ChangeLog (modified) (1 diff)
-
layout/formattingContexts/inline/InlineItem.h (modified) (2 diffs)
-
layout/formattingContexts/inline/InlineItemsBuilder.cpp (modified) (7 diffs)
-
layout/formattingContexts/inline/InlineItemsBuilder.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r286101 r286104 1 2021-11-21 Alan Bujtas <zalan@apple.com> 2 3 [LFC][IFC] Add support for caching bidi InlineTextItem widths 4 https://bugs.webkit.org/show_bug.cgi?id=233402 5 6 Reviewed by Antti Koivisto. 7 8 Let's do a "text content measure" pass when the inline item boundaries are finalized (including bidi split). 9 10 * layout/formattingContexts/inline/InlineItem.h: 11 (WebCore::Layout::InlineItem::setWidth): 12 * layout/formattingContexts/inline/InlineItemsBuilder.cpp: 13 (WebCore::Layout::InlineItemsBuilder::build): 14 (WebCore::Layout::InlineItemsBuilder::computeInlineTextItemWidths): 15 (WebCore::Layout::InlineItemsBuilder::handleTextContent): 16 * layout/formattingContexts/inline/InlineItemsBuilder.h: 17 1 18 2021-11-21 Alan Bujtas <zalan@apple.com> 2 19 -
trunk/Source/WebCore/layout/formattingContexts/inline/InlineItem.h
r285119 r286104 71 71 72 72 void setBidiLevel(UBiDiLevel bidiLevel) { m_bidiLevel = bidiLevel; } 73 void setWidth(InlineLayoutUnit); 73 74 74 75 const Box* m_layoutBox { nullptr }; … … 97 98 } 98 99 100 inline void InlineItem::setWidth(InlineLayoutUnit width) 101 { 102 m_width = width; 103 m_hasWidth = true; 104 } 105 99 106 #define SPECIALIZE_TYPE_TRAITS_INLINE_ITEM(ToValueTypeName, predicate) \ 100 107 SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::Layout::ToValueTypeName) \ -
trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.cpp
r286101 r286104 89 89 if (hasSeenBidiContent()) 90 90 breakAndComputeBidiLevels(inlineItems); 91 computeInlineTextItemWidths(inlineItems); 91 92 return inlineItems; 92 93 } … … 368 369 } 369 370 371 void InlineItemsBuilder::computeInlineTextItemWidths(InlineItems& inlineItems) 372 { 373 for (auto& inlineItem : inlineItems) { 374 if (!inlineItem.isText()) 375 continue; 376 377 auto& inlineTextItem = downcast<InlineTextItem>(inlineItem); 378 auto& inlineTextBox = inlineTextItem.inlineTextBox(); 379 auto start = inlineTextItem.start(); 380 auto length = inlineTextItem.length(); 381 if (!canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, start, length, inlineTextItem.isWhitespace())) 382 continue; 383 384 auto width = [&]() -> std::optional<InlineLayoutUnit> { 385 auto singleWhiteSpace = inlineTextItem.isWhitespace() && (!TextUtil::shouldPreserveSpacesAndTabs(inlineTextBox) || (length == 1 && inlineTextBox.canUseSimplifiedContentMeasuring())); 386 if (singleWhiteSpace) 387 return inlineTextItem.style().fontCascade().spaceWidth(); 388 if (length && !inlineTextItem.isZeroWidthSpaceSeparator()) 389 return TextUtil::width(inlineTextBox, inlineTextItem.style().fontCascade(), start, start + length, { }); 390 return { }; 391 }(); 392 if (width) 393 inlineTextItem.setWidth(*width); 394 } 395 } 396 370 397 void InlineItemsBuilder::handleTextContent(const InlineTextBox& inlineTextBox, InlineItems& inlineItems) 371 398 { … … 379 406 380 407 auto& style = inlineTextBox.style(); 381 auto& fontCascade = style.fontCascade();382 auto whiteSpaceWidth = std::optional<InlineLayoutUnit> { fontCascade.spaceWidth() };383 408 auto shouldPreserveSpacesAndTabs = TextUtil::shouldPreserveSpacesAndTabs(inlineTextBox); 384 auto whitespaceContentIsTreatedAsSingleSpace = !shouldPreserveSpacesAndTabs;385 409 auto shouldPreserveNewline = TextUtil::shouldPreserveNewline(inlineTextBox); 386 410 auto shouldTreatNonBreakingSpaceAsRegularSpace = style.nbspMode() == NBSPMode::Space; … … 401 425 402 426 auto handleWhitespace = [&] { 403 auto stopAtWordSeparatorBoundary = shouldPreserveSpacesAndTabs && fontCascade.wordSpacing();427 auto stopAtWordSeparatorBoundary = shouldPreserveSpacesAndTabs && style.fontCascade().wordSpacing(); 404 428 auto whitespaceContent = moveToNextNonWhitespacePosition(text, currentPosition, shouldPreserveNewline, shouldPreserveSpacesAndTabs, shouldTreatNonBreakingSpaceAsRegularSpace, stopAtWordSeparatorBoundary); 405 429 if (!whitespaceContent) … … 407 431 408 432 ASSERT(whitespaceContent->length); 409 auto appendWhitespaceItem = [&] (auto startPosition, auto itemLength) {410 auto width = [&]() -> std::optional<InlineLayoutUnit> {411 if (!canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, startPosition, itemLength, true))412 return { };413 if (whitespaceContentIsTreatedAsSingleSpace || (itemLength == 1 && inlineTextBox.canUseSimplifiedContentMeasuring()))414 return whiteSpaceWidth;415 return TextUtil::width(inlineTextBox, fontCascade, startPosition, startPosition + itemLength, { });416 }();417 inlineItems.append(InlineTextItem::createWhitespaceItem(inlineTextBox, startPosition, itemLength, UBIDI_DEFAULT_LTR, whitespaceContent->isWordSeparator, width));418 };419 433 if (style.whiteSpace() == WhiteSpace::BreakSpaces) { 420 434 // https://www.w3.org/TR/css-text-3/#white-space-phase-1 … … 422 436 // 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. 423 437 for (size_t i = 0; i < whitespaceContent->length; ++i) 424 appendWhitespaceItem(currentPosition + i, 1);438 inlineItems.append(InlineTextItem::createWhitespaceItem(inlineTextBox, currentPosition + i, 1, UBIDI_DEFAULT_LTR, whitespaceContent->isWordSeparator, { })); 425 439 } else 426 appendWhitespaceItem(currentPosition, whitespaceContent->length);440 inlineItems.append(InlineTextItem::createWhitespaceItem(inlineTextBox, currentPosition, whitespaceContent->length, UBIDI_DEFAULT_LTR, whitespaceContent->isWordSeparator, { })); 427 441 currentPosition += whitespaceContent->length; 428 442 return true; … … 447 461 } 448 462 ASSERT_IMPLIES(style.hyphens() == Hyphens::None, !hasTrailingSoftHyphen); 449 auto length = endPosition - startPosition; 450 auto textWidth = [&]() -> std::optional<InlineLayoutUnit> { 451 // Delay non-whitespace content measuring until after bidi split. 452 if (hasSeenBidiContent() || !canCacheMeasuredWidthOnInlineTextItem(inlineTextBox, startPosition, length, false)) 453 return { }; 454 return TextUtil::width(inlineTextBox, fontCascade, startPosition, endPosition, { }); 455 }(); 456 inlineItems.append(InlineTextItem::createNonWhitespaceItem(inlineTextBox, startPosition, length, UBIDI_DEFAULT_LTR, hasTrailingSoftHyphen, textWidth)); 463 inlineItems.append(InlineTextItem::createNonWhitespaceItem(inlineTextBox, startPosition, endPosition - startPosition, UBIDI_DEFAULT_LTR, hasTrailingSoftHyphen, { })); 457 464 currentPosition = endPosition; 458 465 return true; -
trunk/Source/WebCore/layout/formattingContexts/inline/InlineItemsBuilder.h
r285369 r286104 44 44 void collectInlineItems(InlineItems&); 45 45 void breakAndComputeBidiLevels(InlineItems&); 46 void computeInlineTextItemWidths(InlineItems&); 46 47 47 48 void handleTextContent(const InlineTextBox&, InlineItems&);
Note:
See TracChangeset
for help on using the changeset viewer.