Changeset 272725 in webkit
- Timestamp:
- Feb 11, 2021, 6:56:18 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r272724 r272725 1 2021-02-11 Zalan Bujtas <zalan@apple.com> 2 3 [LFC][IFC] Introduce dedicated logical rect getter for each inline level box type 4 https://bugs.webkit.org/show_bug.cgi?id=221725 5 6 Reviewed by Antti Koivisto. 7 8 This helps when different type of rects (margin vs. border) are returned for different type of boxes. 9 10 * layout/inlineformatting/InlineFormattingContext.cpp: 11 (WebCore::Layout::InlineFormattingContext::computeGeometryForLineContent): 12 * layout/inlineformatting/InlineLineBox.cpp: 13 (WebCore::Layout::LineBox::logicalRectForTextRun const): 14 (WebCore::Layout::LineBox::logicalRectForLineBreakBox const): 15 (WebCore::Layout::LineBox::logicalRectForInlineLevelBox const): 16 (WebCore::Layout::LineBox::logicalMarginRectForAtomicInlineLevelBox const): 17 (WebCore::Layout::LineBox::logicalRectForInlineBox const): 18 (WebCore::Layout::LineBox::logicalMarginRectForInlineLevelBox const): Deleted. 19 * layout/inlineformatting/InlineLineBox.h: 20 * layout/integration/LayoutIntegrationInlineContentBuilder.cpp: 21 (WebCore::LayoutIntegration::InlineContentBuilder::createDisplayNonRootInlineBoxes const): 22 * layout/layouttree/LayoutTreeBuilder.cpp: 23 (WebCore::Layout::showInlineTreeAndRuns): 24 1 25 2021-02-11 Zalan Bujtas <zalan@apple.com> 2 26 -
trunk/Source/WebCore/layout/inlineformatting/InlineFormattingContext.cpp
r272724 r272725 465 465 for (auto* layoutBox : layoutBoxList) { 466 466 auto& boxGeometry = formattingState.boxGeometry(*layoutBox); 467 auto inlineBoxLogicalHeight = LayoutUnit::fromFloatCeil(lineBox.logical MarginRectForInlineLevelBox(*layoutBox, boxGeometry).height());467 auto inlineBoxLogicalHeight = LayoutUnit::fromFloatCeil(lineBox.logicalRectForInlineBox(*layoutBox, boxGeometry).height()); 468 468 boxGeometry.setContentBoxHeight(inlineBoxLogicalHeight); 469 469 boxGeometry.setContentBoxWidth({ }); … … 491 491 } 492 492 if (lineRun.isLineBreak()) { 493 auto lineBreakBoxRect = lineBox.logicalRectForTextRun(lineRun);494 formattingState.addLineRun({ lineIndex, layoutBox, lineBreakBoxRect, lineRun.expansion(), lineRun.textContent() });495 496 493 if (layoutBox.isLineBreakBox()) { 497 494 // Only hard linebreaks have associated layout boxes. 495 auto lineBreakBoxRect = lineBox.logicalRectForLineBreakBox(layoutBox); 496 formattingState.addLineRun({ lineIndex, layoutBox, lineBreakBoxRect, lineRun.expansion(), { } }); 497 498 498 auto& boxGeometry = formattingState.boxGeometry(layoutBox); 499 499 lineBreakBoxRect.moveBy(lineBoxLogicalRect.topLeft()); 500 500 boxGeometry.setLogicalTopLeft(toLayoutPoint(lineBreakBoxRect.topLeft())); 501 501 boxGeometry.setContentBoxHeight(toLayoutUnit(lineBreakBoxRect.height())); 502 } 502 } else 503 formattingState.addLineRun({ lineIndex, layoutBox, lineBox.logicalRectForTextRun(lineRun), lineRun.expansion(), lineRun.textContent() }); 503 504 continue; 504 505 } 505 506 if (lineRun.isBox()) { 506 507 ASSERT(layoutBox.isAtomicInlineLevelBox()); 508 auto logicalMarginRect = lineBox.logicalMarginRectForAtomicInlineLevelBox(layoutBox); 509 formattingState.addLineRun({ lineIndex, layoutBox, logicalMarginRect, lineRun.expansion(), { } }); 510 511 auto borderBoxLogicalTopLeft = logicalMarginRect.topLeft(); 507 512 auto& boxGeometry = formattingState.boxGeometry(layoutBox); 508 auto logicalMarginRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, boxGeometry);509 formattingState.addLineRun({ lineIndex, layoutBox, logicalMarginRect, lineRun.expansion(), { } });510 511 auto borderBoxLogicalTopLeft = logicalMarginRect.topLeft();512 513 borderBoxLogicalTopLeft.move(std::max(0_lu, boxGeometry.marginStart()), std::max(0_lu, boxGeometry.marginBefore())); 513 514 // Note that inline boxes are relative to the line and their top position can be negative. … … 526 527 if (lineRun.isInlineBoxStart()) { 527 528 auto& boxGeometry = formattingState.boxGeometry(layoutBox); 528 auto inlineBoxLogicalRect = lineBox.logical MarginRectForInlineLevelBox(layoutBox, boxGeometry);529 auto inlineBoxLogicalRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry); 529 530 formattingState.addLineRun({ lineIndex, layoutBox, inlineBoxLogicalRect, lineRun.expansion(), { } }); 530 531 inlineBoxStartSet.add(&layoutBox); … … 534 535 if (lineRun.isInlineBoxEnd()) { 535 536 inlineBoxEndSet.add(&layoutBox); 536 auto inlineBoxLogicalRect = lineBox.logical MarginRectForInlineLevelBox(layoutBox, formattingState.boxGeometry(layoutBox));537 auto inlineBoxLogicalRect = lineBox.logicalRectForInlineBox(layoutBox, formattingState.boxGeometry(layoutBox)); 537 538 enclosingTopAndBottom.bottom = std::max(enclosingTopAndBottom.bottom, inlineBoxLogicalRect.bottom()); 538 539 continue; … … 555 556 auto& boxGeometry = formattingState.boxGeometry(layoutBox); 556 557 // Inline boxes may or may not be wrapped and have runs on multiple lines (e.g. <span>first line<br>second line<br>third line</span>) 557 auto inlineBoxMarginRect = lineBox.logical MarginRectForInlineLevelBox(layoutBox, boxGeometry);558 auto inlineBoxMarginRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry); 558 559 auto inlineBoxSize = LayoutSize { LayoutUnit::fromFloatCeil(inlineBoxMarginRect.width()), LayoutUnit::fromFloatCeil(inlineBoxMarginRect.height()) }; 559 560 auto logicalRect = Rect { LayoutPoint { inlineBoxMarginRect.topLeft() }, inlineBoxSize }; -
trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.cpp
r272724 r272725 107 107 InlineRect LineBox::logicalRectForTextRun(const Line::Run& run) const 108 108 { 109 ASSERT(run.isText() || run.is LineBreak());109 ASSERT(run.isText() || run.isSoftLineBreak()); 110 110 auto* parentInlineBox = &inlineLevelBoxForLayoutBox(run.layoutBox().parent()); 111 111 ASSERT(parentInlineBox->isInlineBox()); … … 122 122 } 123 123 124 InlineRect LineBox::logical MarginRectForInlineLevelBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const124 InlineRect LineBox::logicalRectForLineBreakBox(const Box& layoutBox) const 125 125 { 126 auto logicalRect = [&] { 127 auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox); 128 auto inlineBoxLogicalRect = inlineBox->logicalRect(); 129 if (inlineBox->hasLineBoxRelativeAlignment()) 130 return inlineBoxLogicalRect; 126 ASSERT(layoutBox.isLineBreakBox()); 127 return logicalRectForInlineLevelBox(layoutBox); 128 } 131 129 132 if (&layoutBox.parent() == &m_rootInlineBox->layoutBox()) { 133 inlineBoxLogicalRect.moveVertically(m_rootInlineBox->logicalTop()); 134 return inlineBoxLogicalRect; 135 } 130 InlineRect LineBox::logicalRectForInlineLevelBox(const Box& layoutBox) const 131 { 132 ASSERT(layoutBox.isInlineLevelBox() || layoutBox.isLineBreakBox()); 133 // Inline level boxes are relative to their parent unless the vertical alignment makes them relative to the line box (e.g. top, bottom). 134 auto* inlineBox = &inlineLevelBoxForLayoutBox(layoutBox); 135 auto inlineBoxLogicalRect = inlineBox->logicalRect(); 136 if (inlineBox->hasLineBoxRelativeAlignment()) 137 return inlineBoxLogicalRect; 136 138 137 auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top(); 138 while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) { 139 inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent()); 140 ASSERT(inlineBox->isInlineBox()); 141 inlineBoxAbsolutelogicalTop += inlineBox->logicalTop(); 142 } 143 return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() }; 144 }(); 145 if (!layoutBox.isInlineBox()) 146 return logicalRect; 139 // Fast path for inline level boxes on the root inline box (e.g <div><img></div>). 140 if (&layoutBox.parent() == &m_rootInlineBox->layoutBox()) { 141 inlineBoxLogicalRect.moveVertically(m_rootInlineBox->logicalTop()); 142 return inlineBoxLogicalRect; 143 } 147 144 145 // e.g <div><span><img></span></div> 146 auto inlineBoxAbsolutelogicalTop = inlineBoxLogicalRect.top(); 147 while (inlineBox != m_rootInlineBox.get() && !inlineBox->hasLineBoxRelativeAlignment()) { 148 inlineBox = &inlineLevelBoxForLayoutBox(inlineBox->layoutBox().parent()); 149 ASSERT(inlineBox->isInlineBox()); 150 inlineBoxAbsolutelogicalTop += inlineBox->logicalTop(); 151 } 152 return InlineRect { inlineBoxAbsolutelogicalTop, inlineBoxLogicalRect.left(), inlineBoxLogicalRect.width(), inlineBoxLogicalRect.height() }; 153 } 154 155 InlineRect LineBox::logicalMarginRectForAtomicInlineLevelBox(const Box& layoutBox) const 156 { 157 ASSERT(layoutBox.isAtomicInlineLevelBox()); 158 return logicalRectForInlineLevelBox(layoutBox); 159 } 160 161 InlineRect LineBox::logicalRectForInlineBox(const Box& layoutBox, const BoxGeometry& boxGeometry) const 162 { 163 auto logicalRect = logicalRectForInlineLevelBox(layoutBox); 148 164 // This logical rect is as tall as the "text" content is. Let's adjust with vertical border and padding -vertical margin is ignored. 149 165 auto verticalBorderAndPadding = boxGeometry.verticalBorder() + boxGeometry.verticalPadding().valueOr(0_lu); -
trunk/Source/WebCore/layout/inlineformatting/InlineLineBox.h
r272701 r272725 151 151 152 152 InlineRect logicalRectForTextRun(const Line::Run&) const; 153 InlineRect logicalRectForLineBreakBox(const Box&) const; 154 InlineRect logicalMarginRectForAtomicInlineLevelBox(const Box&) const; 153 155 InlineRect logicalRectForRootInlineBox() const { return m_rootInlineBox->logicalRect(); } 154 InlineRect logical MarginRectForInlineLevelBox(const Box&, const BoxGeometry&) const;156 InlineRect logicalRectForInlineBox(const Box&, const BoxGeometry&) const; 155 157 156 158 const InlineLevelBox& rootInlineBox() const { return *m_rootInlineBox; } … … 172 174 173 175 InlineLevelBox& inlineLevelBoxForLayoutBox(const Box& layoutBox) { return *m_inlineLevelBoxRectMap.get(&layoutBox); } 176 InlineRect logicalRectForInlineLevelBox(const Box& layoutBox) const; 174 177 175 178 void setHasContent(bool hasContent) { m_hasContent = hasContent; } -
trunk/Source/WebCore/layout/integration/LayoutIntegrationInlineContentBuilder.cpp
r272602 r272725 342 342 auto& layoutBox = inlineLevelBox->layoutBox(); 343 343 auto& boxGeometry = m_layoutState.geometryForBox(layoutBox); 344 auto inlineBoxRect = lineBox.logical MarginRectForInlineLevelBox(layoutBox, boxGeometry);344 auto inlineBoxRect = lineBox.logicalRectForInlineBox(layoutBox, boxGeometry); 345 345 inlineBoxRect.moveBy(lineBoxLogicalRect.topLeft()); 346 346 -
trunk/Source/WebCore/layout/layouttree/LayoutTreeBuilder.cpp
r270932 r272725 407 407 addSpacing(); 408 408 stream << " "; 409 if (inlineLevelBox.isRootInlineBox()) 409 auto logicalRect = InlineRect { }; 410 auto& layoutBox = inlineLevelBox.layoutBox(); 411 if (inlineLevelBox.isRootInlineBox()) { 410 412 stream << "Root inline box"; 411 else if (inlineLevelBox.isAtomicInlineLevelBox()) 413 logicalRect = lineBox.logicalRectForRootInlineBox(); 414 } else if (inlineLevelBox.isAtomicInlineLevelBox()) { 412 415 stream << "Atomic inline level box"; 413 else if (inlineLevelBox.isLineBreakBox()) 416 logicalRect = lineBox.logicalMarginRectForAtomicInlineLevelBox(layoutBox); 417 } else if (inlineLevelBox.isLineBreakBox()) { 414 418 stream << "Line break box"; 415 else if (inlineLevelBox.isInlineBox()) 416 stream << "Generic inline box"; 417 else 419 logicalRect = lineBox.logicalRectForLineBreakBox(layoutBox); 420 } else if (inlineLevelBox.isInlineBox()) { 421 stream << "Inline box"; 422 logicalRect = lineBox.logicalRectForInlineBox(layoutBox, layoutState.geometryForBox(layoutBox)); 423 } else 418 424 stream << "Generic inline level box"; 419 auto& layoutBox = inlineLevelBox.layoutBox();420 auto logicalRect = lineBox.logicalMarginRectForInlineLevelBox(layoutBox, layoutState.geometryForBox(layoutBox));421 425 stream 422 426 << " at (" << logicalRect.left() << "," << logicalRect.top() << ")"
Note:
See TracChangeset
for help on using the changeset viewer.