Changeset 269769 in webkit
- Timestamp:
- Nov 13, 2020 4:07:38 AM (3 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r269768 r269769 1 2020-11-13 Zalan Bujtas <zalan@apple.com> 2 3 [LFC][Integration] Decouple box and text run construction 4 https://bugs.webkit.org/show_bug.cgi?id=218882 5 6 Reviewed by Antti Koivisto. 7 8 This is in preparation for adding bidi support where we may need to split a run on bidi boundaries. 9 10 * layout/integration/LayoutIntegrationInlineContentBuilder.cpp: 11 (WebCore::LayoutIntegration::InlineContentBuilder::constructDisplayLineRuns const): 12 1 13 2020-11-13 Kimmo Kinnunen <kkinnunen@apple.com> 2 14 -
trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp
r269571 r269769 109 109 void InlineContentBuilder::constructDisplayLineRuns(InlineContent& inlineContent, const Layout::InlineFormattingState& inlineFormattingState, const LineLevelVisualAdjustmentsForRunsList& lineLevelVisualAdjustmentsForRuns) const 110 110 { 111 auto& runList = inlineFormattingState.lineRuns(); 112 if (runList.isEmpty()) 113 return; 111 114 auto& lines = inlineFormattingState.lines(); 112 auto initialContaingBlockSize = m_layoutState.viewportSize();113 115 Vector<bool> hasAdjustedTrailingLineList(lines.size(), false); 114 for (auto& lineRun : inlineFormattingState.lineRuns()) { 116 117 auto createDisplayBoxRun = [&](auto& lineRun) { 118 auto lineIndex = lineRun.lineIndex(); 119 auto& line = lines[lineIndex]; 120 // Inline boxes are relative to the line box while final Runs need to be relative to the parent Box 121 // FIXME: Shouldn't we just leave them be relative to the line box? 122 auto runRect = FloatRect { lineRun.logicalRect() }; 123 runRect.moveBy({ line.logicalLeft(), line.logicalTop() }); 124 if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) 125 runRect.setY(roundToInt(runRect.y())); 126 // FIXME: Add support for non-text ink overflow. 127 // FIXME: Add support for cases when the run is after ellipsis. 128 inlineContent.runs.append({ lineIndex, lineRun.layoutBox(), runRect, runRect, { }, { } }); 129 }; 130 131 auto createDisplayTextRunForRange = [&](auto& lineRun, auto startOffset, auto endOffset) { 132 RELEASE_ASSERT(startOffset < endOffset); 115 133 auto& layoutBox = lineRun.layoutBox(); 134 auto lineIndex = lineRun.lineIndex(); 135 auto& line = lines[lineIndex]; 136 auto runRect = FloatRect { lineRun.logicalRect() }; 137 // Inline boxes are relative to the line box while final Runs need to be relative to the parent Box 138 // FIXME: Shouldn't we just leave them be relative to the line box? 139 runRect.moveBy({ line.logicalLeft(), line.logicalTop() }); 140 if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) 141 runRect.setY(roundToInt(runRect.y())); 142 116 143 auto& style = layoutBox.style(); 144 auto text = lineRun.text(); 145 auto adjustedContentToRenderer = [&] { 146 auto originalContent = text->content().substring(text->start(), text->length()); 147 if (text->needsHyphen()) 148 return makeString(originalContent, style.hyphenString()); 149 if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement) { 150 // Currently it's ellipsis replacement only, but adding support for "text-overflow: string" should be relatively simple. 151 if (hasAdjustedTrailingLineList[lineIndex]) { 152 // This line already has adjusted trailing. Any runs after the ellipsis should render blank. 153 return emptyString(); 154 } 155 auto runLogicalRect = lineRun.logicalRect(); 156 auto lineLogicalRight = line.logicalRight(); 157 auto ellipsisWidth = style.fontCascade().width(WebCore::TextRun { &horizontalEllipsis }); 158 if (runLogicalRect.right() + ellipsisWidth > lineLogicalRight) { 159 // The next run with ellipsis would surely overflow. So let's just add it to this run even if 160 // it makes the run wider than it originally was. 161 hasAdjustedTrailingLineList[lineIndex] = true; 162 float resultWidth = 0; 163 auto maxWidth = line.logicalWidth() - runLogicalRect.left(); 164 return StringTruncator::rightTruncate(originalContent, maxWidth, style.fontCascade(), resultWidth, true); 165 } 166 } 167 return String(); 168 }; 169 117 170 auto computedInkOverflow = [&] (auto runRect) { 118 // FIXME: Add support for non-text ink overflow.119 if (!lineRun.text())120 return runRect;121 171 auto inkOverflow = runRect; 172 auto initialContaingBlockSize = m_layoutState.viewportSize(); 122 173 auto strokeOverflow = std::ceil(style.computedStrokeWidth(ceiledIntSize(initialContaingBlockSize))); 123 174 inkOverflow.inflate(strokeOverflow); 124 125 175 auto letterSpacing = style.fontCascade().letterSpacing(); 126 176 if (letterSpacing < 0) { … … 130 180 return inkOverflow; 131 181 }; 132 auto runRect = FloatRect { lineRun.logicalRect() }; 133 // Inline boxes are relative to the line box while final Runs need to be relative to the parent Box 134 // FIXME: Shouldn't we just leave them be relative to the line box? 135 auto lineIndex = lineRun.lineIndex(); 136 auto& line = lines[lineIndex]; 137 runRect.moveBy({ line.logicalLeft(), line.logicalTop() }); 138 if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsIntegralPosition) 139 runRect.setY(roundToInt(runRect.y())); 140 141 WTF::Optional<Run::TextContent> textContent; 142 if (auto text = lineRun.text()) { 143 auto adjustedContentToRenderer = [&] { 144 auto originalContent = text->content().substring(text->start(), text->length()); 145 if (text->needsHyphen()) 146 return makeString(originalContent, style.hyphenString()); 147 if (lineLevelVisualAdjustmentsForRuns[lineIndex].needsTrailingContentReplacement) { 148 // Currently it's ellipsis replacement only, but adding support for "text-overflow: string" should be relatively simple. 149 if (hasAdjustedTrailingLineList[lineIndex]) { 150 // This line already has adjusted trailing. Any runs after the ellipsis should render blank. 151 return emptyString(); 152 } 153 auto runLogicalRect = lineRun.logicalRect(); 154 auto lineLogicalRight = line.logicalRight(); 155 auto ellipsisWidth = style.fontCascade().width(WebCore::TextRun { &horizontalEllipsis }); 156 if (runLogicalRect.right() + ellipsisWidth > lineLogicalRight) { 157 // The next run with ellipsis would surely overflow. So let's just add it to this run even if 158 // it makes the run wider than it originally was. 159 hasAdjustedTrailingLineList[lineIndex] = true; 160 float resultWidth = 0; 161 auto maxWidth = line.logicalWidth() - runLogicalRect.left(); 162 return StringTruncator::rightTruncate(originalContent, maxWidth, style.fontCascade(), resultWidth, true); 163 } 164 } 165 return String(); 166 }; 167 textContent = Run::TextContent { text->start(), text->length(), text->content(), adjustedContentToRenderer(), text->needsHyphen() }; 168 } 182 RELEASE_ASSERT(startOffset >= text->start() && startOffset < text->end()); 183 RELEASE_ASSERT(endOffset > text->start() && endOffset <= text->end()); 184 auto textContent = Run::TextContent { startOffset, endOffset - startOffset, text->content(), adjustedContentToRenderer(), text->needsHyphen() }; 169 185 auto expansion = Run::Expansion { lineRun.expansion().behavior, lineRun.expansion().horizontalExpansion }; 170 186 auto displayRun = Run { lineIndex, layoutBox, runRect, computedInkOverflow(runRect), expansion, textContent }; 171 187 inlineContent.runs.append(displayRun); 188 }; 189 190 for (auto& lineRun : inlineFormattingState.lineRuns()) { 191 if (auto& text = lineRun.text()) 192 createDisplayTextRunForRange(lineRun, text->start(), text->end()); 193 else 194 createDisplayBoxRun(lineRun); 172 195 } 173 196 }
Note: See TracChangeset
for help on using the changeset viewer.