Changeset 272124 in webkit
- Timestamp:
- Jan 31, 2021, 9:16:58 AM (6 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 edited
-
ChangeLog (modified) (1 diff)
-
layout/inlineformatting/InlineContentBreaker.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r272123 r272124 1 2021-01-31 Zalan Bujtas <zalan@apple.com> 2 3 [LFC][IFC] TrailingTextContent should be able to tell if even the first run in the set does not fit 4 https://bugs.webkit.org/show_bug.cgi?id=221185 5 6 Reviewed by Antti Koivisto. 7 8 There are 3 distinct cases here that we should be able to encode with the return value of processOverflowingTextContent. 9 10 1. We did not find any breakable run in the set -> return value is nullopt 11 2. We did find a breakable run but even the first run does not fit at all -> TrailingTextContent::runIndex is nullopt 12 3. We did find a breakable run and we can fit the first run (either fully or partially) -> TrailingTextContent::runIndex is 0. 13 14 Make TrailingTextContent::runIndex optional so that we can tell the difference between #2 and #3. 15 16 * layout/inlineformatting/InlineContentBreaker.cpp: 17 (WebCore::Layout::InlineContentBreaker::processOverflowingContent const): 18 (WebCore::Layout::InlineContentBreaker::processOverflowingTextContent const): 19 1 20 2021-01-30 Sam Weinig <weinig@apple.com> 2 21 -
trunk/Source/WebCore/layout/inlineformatting/InlineContentBreaker.cpp
r271562 r272124 161 161 162 162 struct TrailingTextContent { 163 size_t runIndex { 0 };164 bool hasOverflow { false }; // Trailing content still overflows the line.163 Optional<size_t> runIndex; // In some cases when the first run is breakable but it does not fit, there's not trailing run index. 164 bool hasOverflow { false }; // Trailing content overflows the available space. 165 165 Optional<InlineContentBreaker::PartialRun> partialRun; 166 166 }; … … 196 196 if (isTextContent(continuousContent)) { 197 197 if (auto trailingContent = processOverflowingTextContent(continuousContent, lineStatus)) { 198 if (!trailingContent->runIndex && trailingContent->hasOverflow) { 199 // We tried to break the content but the available space can't even accommodate the first character. 200 // 1. Wrap the content over to the next line when we've got content on the line already. 201 // 2. Keep the first character on the empty line (or keep the whole run if it has only one character/completely empty). 198 if (trailingContent->hasOverflow) { 199 if (!trailingContent->runIndex.hasValue()) { 200 // We tried to break the content but the available space can't even accommodate the first character. 201 // 1. Wrap the content over to the next line when we've got content on the line already. 202 // 2. Keep the first character on the empty line (or keep the whole run if it has only one character/completely empty). 203 if (lineStatus.hasContent) 204 return { Result::Action::Wrap, IsEndOfLine::Yes }; 205 auto leadingTextRunIndex = *firstTextRunIndex(continuousContent); 206 auto& inlineTextItem = downcast<InlineTextItem>(continuousContent.runs()[leadingTextRunIndex].inlineItem); 207 if (inlineTextItem.length() <= 1) 208 return Result { Result::Action::Keep, IsEndOfLine::Yes }; 209 auto firstCharacterWidth = TextUtil::width(inlineTextItem, inlineTextItem.start(), inlineTextItem.start() + 1, lineStatus.contentLogicalRight); 210 auto firstCharacterRun = PartialRun { 1, firstCharacterWidth }; 211 return { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, firstCharacterRun } }; 212 } 213 // We managed to break a run with overflow. Should not keep this on the line unless it's the only content. 202 214 if (lineStatus.hasContent) 203 215 return { Result::Action::Wrap, IsEndOfLine::Yes }; 204 auto leadingTextRunIndex = *firstTextRunIndex(continuousContent); 205 auto& inlineTextItem = downcast<InlineTextItem>(continuousContent.runs()[leadingTextRunIndex].inlineItem); 206 if (inlineTextItem.length() <= 1) 207 return Result { Result::Action::Keep, IsEndOfLine::Yes }; 208 auto firstCharacterWidth = TextUtil::width(inlineTextItem, inlineTextItem.start(), inlineTextItem.start() + 1, lineStatus.contentLogicalRight); 209 auto firstCharacterRun = PartialRun { 1, firstCharacterWidth }; 210 return { Result::Action::Break, IsEndOfLine::Yes, Result::PartialTrailingContent { leadingTextRunIndex, firstCharacterRun } }; 211 } 212 auto trailingPartialContent = Result::PartialTrailingContent { trailingContent->runIndex, trailingContent->partialRun }; 213 return { Result::Action::Break, IsEndOfLine::Yes, trailingPartialContent }; 214 } 216 } 217 auto trailingPartialContent = Result::PartialTrailingContent { *trailingContent->runIndex, trailingContent->partialRun }; 218 return { Result::Action::Break, IsEndOfLine::Yes, trailingPartialContent }; } 215 219 } 216 220 // If we are not allowed to break this overflowing content, we still need to decide whether keep it or wrap it to the next line. … … 282 286 if (partialRun->length) 283 287 return TrailingTextContent { index, false, partialRun }; 284 if (index) { 285 // When the content is wrapped at the run boundary, the trailing run is the previous run. 286 auto trailingCandidateIndex = index - 1; 287 // Try not break content at inline box boundary 288 // e.g. <span>fits</span><span>overflows</span> 289 // when the text "overflows" completely overflows, let's not wrap the content at '<span>'. 290 auto isAtInlineBox = runs[trailingCandidateIndex].inlineItem.isInlineBoxStart(); 291 if (isAtInlineBox) { 292 if (!trailingCandidateIndex) { 293 // This content starts at an inline box and clearly does not fit. 294 // Let's wrap this content over to the next line 295 // e.g <span>this_content_does_not_fit</span> 296 return TrailingTextContent { 0, true, { } }; 297 } 298 --trailingCandidateIndex; 299 } 288 // When the breaking position is at the beginning of the run, the trailing run is the previous one. 289 if (!index) { 290 // Sometimes we can't accommodate even the very first character. 291 // Note that this is different from when there's no breakable run in this set. 292 return TrailingTextContent { { }, true, { } }; 293 } 294 auto trailingCandidateIndex = index - 1; 295 // Try not break content at inline box boundary 296 // e.g. <span>fits</span><span>overflows</span> 297 // when the text "overflows" completely overflows, let's break the content right before the '<span>'. 298 auto isAtInlineBox = runs[trailingCandidateIndex].inlineItem.isInlineBoxStart(); 299 if (!isAtInlineBox) 300 300 return TrailingTextContent { trailingCandidateIndex, false, { } }; 301 } 302 // Sometimes we can't accommodate even the very first character. 303 return TrailingTextContent { 0, true, { } }; 304 } 305 // If this run is not breakable, we need to check if any previous run is breakable. 301 // Let's return the run right before the inline box start, or return nothing if we are at the beginning of the set. 302 // e.g. <span>this_is_breakable</span> vs. some_breakable_content<span>and_more</span> 303 if (trailingCandidateIndex) 304 return TrailingTextContent { trailingCandidateIndex - 1, false, { } }; 305 // This content starts with an inline box and clearly does not fit. 306 return TrailingTextContent { { }, true, { } }; 307 } 308 // If this run is not breakable, we need to check if any previous or next runs are breakable. 306 309 break; 307 310 }
Note:
See TracChangeset
for help on using the changeset viewer.