Changeset 283392 in webkit
- Timestamp:
- Oct 1, 2021, 1:20:58 PM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
-
ChangeLog (modified) (1 diff)
-
layout/formattingContexts/inline/InlineContentBreaker.cpp (modified) (11 diffs)
-
layout/formattingContexts/inline/InlineContentBreaker.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r283390 r283392 1 2021-10-01 Alan Bujtas <zalan@apple.com> 2 3 REGRESSION(r283047): PerformanceTests/Layout/line-layout-simple.html regressed by ~10% 4 https://bugs.webkit.org/show_bug.cgi?id=231089 5 6 Reviewed by Antti Koivisto. 7 8 Let's just hold on to the applicable RenderStyle instead of constructing a dedicated Style structure. 9 Note that the expected style for line breaking is not necessarily the style of the inline item (e.g. in case of an atomic inline box, it's the parent inline box's style). 10 11 * layout/formattingContexts/inline/InlineContentBreaker.cpp: 12 (WebCore::Layout::InlineContentBreaker::isWrappingAllowed): 13 (WebCore::Layout::InlineContentBreaker::shouldKeepEndOfLineWhitespace const): 14 (WebCore::Layout::InlineContentBreaker::processOverflowingContent const): 15 (WebCore::Layout::InlineContentBreaker::wordBreakBehavior const): 16 (WebCore::Layout::InlineContentBreaker::tryBreakingTextRun const): 17 * layout/formattingContexts/inline/InlineContentBreaker.h: 18 (WebCore::Layout::InlineContentBreaker::ContinuousContent::Run::Run): 19 (WebCore::Layout::logicalWidth): Deleted. 20 1 21 2021-10-01 Alan Bujtas <zalan@apple.com> 2 22 -
trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.cpp
r283080 r283392 116 116 { 117 117 // Do not try to wrap overflown 'pre' and 'no-wrap' content to next line. 118 return run.style.whiteSpace != WhiteSpace::Pre && run.style.whiteSpace!= WhiteSpace::NoWrap;118 return run.style.whiteSpace() != WhiteSpace::Pre && run.style.whiteSpace() != WhiteSpace::NoWrap; 119 119 } 120 120 … … 125 125 // It might very well get collapsed when we close the line (normal/nowrap/pre-line). 126 126 // See https://www.w3.org/TR/css-text-3/#white-space-property 127 auto whitespace = continuousContent.runs()[*firstTextRunIndex(continuousContent)].style.whiteSpace ;127 auto whitespace = continuousContent.runs()[*firstTextRunIndex(continuousContent)].style.whiteSpace(); 128 128 return whitespace == WhiteSpace::Normal || whitespace == WhiteSpace::NoWrap || whitespace == WhiteSpace::PreWrap || whitespace == WhiteSpace::PreLine; 129 129 } … … 234 234 return Result { Result::Action::Keep, IsEndOfLine::Yes }; 235 235 236 auto firstCodePointWidth = TextUtil::width(inlineTextItem, leadingTextRun.style.fontCascade , inlineTextItem.start(), inlineTextItem.start() + firstCodePointLength, lineStatus.contentLogicalRight);236 auto firstCodePointWidth = TextUtil::width(inlineTextItem, leadingTextRun.style.fontCascade(), inlineTextItem.start(), inlineTextItem.start() + firstCodePointLength, lineStatus.contentLogicalRight); 237 237 return Result { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, PartialRun { firstCodePointLength, firstCodePointWidth } } }; 238 238 } … … 406 406 } 407 407 408 OptionSet<InlineContentBreaker::WordBreakRule> InlineContentBreaker::wordBreakBehavior(const ContinuousContent::Run::Style& style, bool hasWrapOpportunityAtPreviousPosition) const408 OptionSet<InlineContentBreaker::WordBreakRule> InlineContentBreaker::wordBreakBehavior(const RenderStyle& style, bool hasWrapOpportunityAtPreviousPosition) const 409 409 { 410 410 // Disregard any prohibition against line breaks mandated by the word-break property. 411 411 // The different wrapping opportunities must not be prioritized. 412 412 // Note hyphenation is not applied. 413 if (style.lineBreak == LineBreak::Anywhere)413 if (style.lineBreak() == LineBreak::Anywhere) 414 414 return { WordBreakRule::AtArbitraryPosition }; 415 415 416 416 auto includeHyphenationIfAllowed = [&](std::optional<InlineContentBreaker::WordBreakRule> wordBreakRule) -> OptionSet<InlineContentBreaker::WordBreakRule> { 417 auto hyphenationIsAllowed = !n_hyphenationIsDisabled && style.hyphens == Hyphens::Auto && canHyphenate(style.locale);417 auto hyphenationIsAllowed = !n_hyphenationIsDisabled && style.hyphens() == Hyphens::Auto && canHyphenate(style.computedLocale()); 418 418 if (hyphenationIsAllowed) { 419 419 if (wordBreakRule) … … 426 426 }; 427 427 // Breaking is allowed within “words”. 428 if (style.wordBreak == WordBreak::BreakAll)428 if (style.wordBreak() == WordBreak::BreakAll) 429 429 return includeHyphenationIfAllowed(WordBreakRule::AtArbitraryPosition); 430 430 // For compatibility with legacy content, the word-break property also supports a deprecated break-word keyword. 431 431 // When specified, this has the same effect as word-break: normal and overflow-wrap: anywhere, regardless of the actual value of the overflow-wrap property. 432 if (style.wordBreak == WordBreak::BreakWord && !hasWrapOpportunityAtPreviousPosition)432 if (style.wordBreak() == WordBreak::BreakWord && !hasWrapOpportunityAtPreviousPosition) 433 433 return includeHyphenationIfAllowed(WordBreakRule::AtArbitraryPosition); 434 434 // OverflowWrap::BreakWord/Anywhere An otherwise unbreakable sequence of characters may be broken at an arbitrary point if there are no otherwise-acceptable break points in the line. 435 435 // Note that this applies to content where CSS properties (e.g. WordBreak::KeepAll) make it unbreakable. 436 if ((style.overflowWrap == OverflowWrap::BreakWord || style.overflowWrap== OverflowWrap::Anywhere) && !hasWrapOpportunityAtPreviousPosition)436 if ((style.overflowWrap() == OverflowWrap::BreakWord || style.overflowWrap() == OverflowWrap::Anywhere) && !hasWrapOpportunityAtPreviousPosition) 437 437 return includeHyphenationIfAllowed(WordBreakRule::AtArbitraryPosition); 438 438 // Breaking is forbidden within “words”. 439 if (style.wordBreak == WordBreak::KeepAll)439 if (style.wordBreak() == WordBreak::KeepAll) 440 440 return { }; 441 441 return includeHyphenationIfAllowed({ }); … … 453 453 return { }; 454 454 455 auto& fontCascade = style.fontCascade(); 455 456 if (breakRules.contains(WordBreakRule::AtHyphenationOpportunities)) { 456 457 auto tryBreakingAtHyphenationOpportunity = [&]() -> std::optional<PartialRun> { … … 463 464 } 464 465 auto runLength = inlineTextItem.length(); 465 auto limitBefore = style.hyphenationLimitBefore.value_or(0);466 auto limitAfter = style.hyphenationLimitAfter.value_or(0);466 unsigned limitBefore = style.hyphenationLimitBefore() == RenderStyle::initialHyphenationLimitBefore() ? 0 : style.hyphenationLimitBefore(); 467 unsigned limitAfter = style.hyphenationLimitAfter() == RenderStyle::initialHyphenationLimitAfter() ? 0 : style.hyphenationLimitAfter(); 467 468 // Check if this run can accommodate the before/after limits at all before start measuring text. 468 469 if (limitBefore >= runLength || limitAfter >= runLength || limitBefore + limitAfter > runLength) … … 470 471 471 472 unsigned leftSideLength = runLength; 472 auto hyphenWidth = InlineLayoutUnit { style.fontCascade.width(TextRun { StringView { style.hyphenString} }) };473 auto hyphenWidth = InlineLayoutUnit { fontCascade.width(TextRun { StringView { style.hyphenString() } }) }; 473 474 if (!availableSpaceIsInfinite) { 474 475 auto availableWidthExcludingHyphen = *availableWidth - hyphenWidth; 475 if (availableWidthExcludingHyphen <= 0 || !enoughWidthForHyphenation(availableWidthExcludingHyphen, style.fontCascade.pixelSize()))476 if (availableWidthExcludingHyphen <= 0 || !enoughWidthForHyphenation(availableWidthExcludingHyphen, fontCascade.pixelSize())) 476 477 return { }; 477 leftSideLength = TextUtil::midWordBreak(inlineTextItem, overflowingRun.style.fontCascade, overflowingRun.logicalWidth, availableWidthExcludingHyphen, logicalLeft).length;478 leftSideLength = TextUtil::midWordBreak(inlineTextItem, fontCascade, overflowingRun.logicalWidth, availableWidthExcludingHyphen, logicalLeft).length; 478 479 } 479 480 if (leftSideLength < limitBefore) … … 481 482 // Adjust before index to accommodate the limit-after value (it's the last potential hyphen location in this run). 482 483 auto hyphenBefore = std::min(leftSideLength, runLength - limitAfter) + 1; 483 unsigned hyphenLocation = lastHyphenLocation(StringView(inlineTextItem.inlineTextBox().content()).substring(inlineTextItem.start(), inlineTextItem.length()), hyphenBefore, style. locale);484 unsigned hyphenLocation = lastHyphenLocation(StringView(inlineTextItem.inlineTextBox().content()).substring(inlineTextItem.start(), inlineTextItem.length()), hyphenBefore, style.computedLocale()); 484 485 if (!hyphenLocation || hyphenLocation < limitBefore) 485 486 return { }; 486 487 // hyphenLocation is relative to the start of this InlineItemText. 487 488 ASSERT(inlineTextItem.start() + hyphenLocation < inlineTextItem.end()); 488 auto trailingPartialRunWidthWithHyphen = TextUtil::width(inlineTextItem, overflowingRun.style.fontCascade, inlineTextItem.start(), inlineTextItem.start() + hyphenLocation, logicalLeft);489 auto trailingPartialRunWidthWithHyphen = TextUtil::width(inlineTextItem, fontCascade, inlineTextItem.start(), inlineTextItem.start() + hyphenLocation, logicalLeft); 489 490 return PartialRun { hyphenLocation, trailingPartialRunWidthWithHyphen, hyphenWidth }; 490 491 }; … … 502 503 // When the run can be split at arbitrary position let's just return the entire run when it is intended to fit on the line. 503 504 ASSERT(inlineTextItem.length()); 504 auto trailingPartialRunWidth = TextUtil::width(inlineTextItem, overflowingRun.style.fontCascade, logicalLeft);505 auto trailingPartialRunWidth = TextUtil::width(inlineTextItem, fontCascade, logicalLeft); 505 506 return { inlineTextItem.length(), trailingPartialRunWidth }; 506 507 } … … 509 510 return { }; 510 511 } 511 auto midWordBreak = TextUtil::midWordBreak(inlineTextItem, overflowingRun.style.fontCascade, overflowingRun.logicalWidth, *availableWidth, logicalLeft);512 auto midWordBreak = TextUtil::midWordBreak(inlineTextItem, fontCascade, overflowingRun.logicalWidth, *availableWidth, logicalLeft); 512 513 return { midWordBreak.length, midWordBreak.logicalWidth }; 513 514 }; -
trunk/Source/WebCore/layout/formattingContexts/inline/InlineContentBreaker.h
r283055 r283392 92 92 93 93 const InlineItem& inlineItem; 94 struct Style { 95 WhiteSpace whiteSpace { WhiteSpace::Normal }; 96 LineBreak lineBreak { LineBreak::Auto }; 97 WordBreak wordBreak { WordBreak::Normal }; 98 OverflowWrap overflowWrap { OverflowWrap::Normal }; 99 Hyphens hyphens { Hyphens::None }; 100 std::optional<unsigned> hyphenationLimitBefore; 101 std::optional<unsigned> hyphenationLimitAfter; 102 const FontCascade& fontCascade; 103 const AtomString& hyphenString; 104 const AtomString& locale; 105 }; 106 Style style; 94 const RenderStyle& style; 107 95 InlineLayoutUnit logicalWidth { 0 }; 108 96 }; … … 139 127 AtHyphenationOpportunities = 1 << 1 140 128 }; 141 OptionSet<WordBreakRule> wordBreakBehavior(const ContinuousContent::Run::Style&, bool hasWrapOpportunityAtPreviousPosition) const;129 OptionSet<WordBreakRule> wordBreakBehavior(const RenderStyle&, bool hasWrapOpportunityAtPreviousPosition) const; 142 130 bool shouldKeepEndOfLineWhitespace(const ContinuousContent&) const; 143 131 … … 147 135 inline InlineContentBreaker::ContinuousContent::Run::Run(const InlineItem& inlineItem, const RenderStyle& style, InlineLayoutUnit logicalWidth) 148 136 : inlineItem(inlineItem) 149 , style({ style.whiteSpace() 150 , style.lineBreak() 151 , style.wordBreak() 152 , style.overflowWrap() 153 , style.hyphens() 154 , style.hyphenationLimitBefore() != style.initialHyphenationLimitBefore() ? std::make_optional(style.hyphenationLimitBefore()) : std::nullopt 155 , style.hyphenationLimitAfter() != style.initialHyphenationLimitAfter() ? std::make_optional(style.hyphenationLimitAfter()) : std::nullopt 156 , style.fontCascade() 157 , (style.hyphens() == Hyphens::None ? nullAtom() : style.hyphenString()) 158 , style.fontDescription().computedLocale() }) 137 , style(style) 159 138 , logicalWidth(logicalWidth) 160 139 {
Note:
See TracChangeset
for help on using the changeset viewer.