Changeset 282223 in webkit
- Timestamp:
- Sep 9, 2021, 10:06:51 AM (5 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 16 edited
-
ChangeLog (modified) (1 diff)
-
editing/SimplifyMarkupCommand.cpp (modified) (1 diff)
-
page/FrameView.cpp (modified) (1 diff)
-
rendering/LegacyInlineFlowBox.cpp (modified) (2 diffs)
-
rendering/LegacyLineLayout.cpp (modified) (2 diffs)
-
rendering/RenderElement.cpp (modified) (1 diff)
-
rendering/RenderElement.h (modified) (2 diffs)
-
rendering/RenderInline.cpp (modified) (13 diffs)
-
rendering/RenderInline.h (modified) (3 diffs)
-
rendering/RenderLineBoxList.cpp (modified) (4 diffs)
-
rendering/RenderText.cpp (modified) (1 diff)
-
rendering/RenderText.h (modified) (1 diff)
-
rendering/RenderTextLineBoxes.cpp (modified) (1 diff)
-
rendering/RenderTextLineBoxes.h (modified) (1 diff)
-
rendering/RenderTreeAsText.cpp (modified) (1 diff)
-
rendering/svg/RenderSVGInline.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r282222 r282223 1 2021-09-09 Antti Koivisto <antti@apple.com> 2 3 Cull inline culling 4 https://bugs.webkit.org/show_bug.cgi?id=202920 5 6 Reviewed by Alan Bujtas. 7 8 The optimization was already disabled in r282129. 9 This patch removes all the associated code. 10 11 * editing/SimplifyMarkupCommand.cpp: 12 (WebCore::SimplifyMarkupCommand::doApply): 13 * page/FrameView.cpp: 14 (WebCore::FrameView::paintContents): 15 * rendering/LegacyInlineFlowBox.cpp: 16 (WebCore::LegacyInlineFlowBox::nodeAtPoint): 17 * rendering/LegacyLineLayout.cpp: 18 (WebCore::LegacyLineLayout::createLineBoxes): 19 (WebCore::LegacyLineLayout::layoutLineBoxes): 20 * rendering/RenderElement.cpp: 21 (WebCore::RenderElement::RenderElement): 22 * rendering/RenderElement.h: 23 (WebCore::RenderElement::setRenderInlineAlwaysCreatesLineBoxes): Deleted. 24 (WebCore::RenderElement::renderInlineAlwaysCreatesLineBoxes const): Deleted. 25 * rendering/RenderInline.cpp: 26 (WebCore::RenderInline::styleDidChange): 27 (WebCore::RenderInline::mayAffectLayout const): 28 29 Rename mayAffectRendering -> mayAffectLayout for specificity. 30 31 (WebCore::RenderInline::generateLineBoxRects const): 32 (WebCore::RenderInline::firstInlineBoxTopLeft const): 33 (WebCore::RenderInline::linesBoundingBox const): 34 (WebCore::RenderInline::linesVisualOverflowBoundingBox const): 35 (WebCore::RenderInline::linesVisualOverflowBoundingBoxInFragment const): 36 (WebCore::RenderInline::clippedOverflowRect const): 37 (WebCore::RenderInline::dirtyLineBoxes): 38 (WebCore::RenderInline::createAndAppendInlineFlowBox): 39 (WebCore::RenderInline::mayAffectRendering const): Deleted. 40 (WebCore::RenderInline::updateAlwaysCreateLineBoxes): Deleted. 41 (WebCore::RenderInline::generateCulledLineBoxRects const): Deleted. 42 (WebCore::RenderInline::hitTestCulledInline): Deleted. 43 (WebCore::RenderInline::culledInlineFirstLineBox const): Deleted. 44 (WebCore::RenderInline::culledInlineLastLineBox const): Deleted. 45 (WebCore::RenderInline::culledInlineVisualOverflowBoundingBox const): Deleted. 46 * rendering/RenderInline.h: 47 (WebCore::RenderInline::lastLineBox const): 48 (WebCore::RenderInline::firstLineBoxIncludingCulling const): Deleted. 49 (WebCore::RenderInline::lastLineBoxIncludingCulling const): Deleted. 50 (WebCore::RenderInline::alwaysCreateLineBoxes const): Deleted. 51 (WebCore::RenderInline::setAlwaysCreateLineBoxes): Deleted. 52 * rendering/RenderLineBoxList.cpp: 53 (WebCore::RenderLineBoxList::dirtyLinesFromChangedChild): 54 * rendering/RenderText.cpp: 55 (WebCore::RenderText::linesVisualOverflowBoundingBox const): Deleted. 56 * rendering/RenderText.h: 57 * rendering/RenderTextLineBoxes.cpp: 58 (WebCore::RenderTextLineBoxes::visualOverflowBoundingBox const): Deleted. 59 * rendering/RenderTextLineBoxes.h: 60 * rendering/RenderTreeAsText.cpp: 61 (WebCore::hasNonEmptySibling): 62 * rendering/svg/RenderSVGInline.cpp: 63 (WebCore::RenderSVGInline::RenderSVGInline): 64 1 65 2021-09-09 Sihui Liu <sihui_liu@apple.com> 2 66 -
trunk/Source/WebCore/editing/SimplifyMarkupCommand.cpp
r282129 r282223 72 72 73 73 auto* renderer = currentNode->renderer(); 74 if (!is<RenderInline>(renderer) || downcast<RenderInline>(*renderer).mayAffect Rendering())74 if (!is<RenderInline>(renderer) || downcast<RenderInline>(*renderer).mayAffectLayout()) 75 75 continue; 76 76 -
trunk/Source/WebCore/page/FrameView.cpp
r282020 r282223 4325 4325 RenderObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(rootLayer->renderer()); 4326 4326 4327 // To work around http://webkit.org/b/135106, ensure that the paint root isn't an inline with culled line boxes.4328 // FIXME: This can cause additional content to be included in the snapshot, so remove this once that bug is fixed.4329 while (is<RenderInline>(renderer) && !downcast<RenderInline>(*renderer).firstLineBox())4330 renderer = renderer->parent();4331 4332 4327 rootLayer->paint(context, dirtyRect, LayoutSize(), m_paintBehavior, renderer, { }, securityOriginPaintPolicy == SecurityOriginPaintPolicy::AnyOrigin ? RenderLayer::SecurityOriginPaintPolicy::AnyOrigin : RenderLayer::SecurityOriginPaintPolicy::AccessibleOriginOnly, eventRegionContext); 4333 4328 if (auto* scrollableRootLayer = rootLayer->scrollableArea()) { -
trunk/Source/WebCore/rendering/LegacyInlineFlowBox.cpp
r281241 r282223 1069 1069 1070 1070 // Check children first. 1071 // We need to account for culled inline parents of the hit-tested nodes, so that they may also get included in area-based hit-tests.1072 RenderElement* culledParent = nullptr;1073 1071 for (auto* child = lastChild(); child; child = child->previousOnLine()) { 1074 1072 if (is<RenderText>(child->renderer()) || !child->boxModelObject()->hasSelfPaintingLayer()) { 1075 RenderElement* newParent = nullptr;1076 // Culled parents are only relevant for area-based hit-tests, so ignore it in point-based ones.1077 if (locationInContainer.isRectBasedTest()) {1078 newParent = child->renderer().parent();1079 if (newParent == &renderer())1080 newParent = nullptr;1081 }1082 // Check the culled parent after all its children have been checked, to do this we wait until1083 // we are about to test an element with a different parent.1084 if (newParent != culledParent) {1085 if (!newParent || !newParent->isDescendantOf(culledParent)) {1086 while (culledParent && culledParent != &renderer() && culledParent != newParent) {1087 if (is<RenderInline>(*culledParent) && downcast<RenderInline>(*culledParent).hitTestCulledInline(request, result, locationInContainer, accumulatedOffset))1088 return true;1089 culledParent = culledParent->parent();1090 }1091 }1092 culledParent = newParent;1093 }1094 1073 if (child->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom, hitTestAction)) { 1095 1074 renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset)); … … 1097 1076 } 1098 1077 } 1099 }1100 // Check any culled ancestor of the final children tested.1101 while (culledParent && culledParent != &renderer()) {1102 if (is<RenderInline>(*culledParent) && downcast<RenderInline>(*culledParent).hitTestCulledInline(request, result, locationInContainer, accumulatedOffset))1103 return true;1104 culledParent = culledParent->parent();1105 1078 } 1106 1079 -
trunk/Source/WebCore/rendering/LegacyLineLayout.cpp
r281241 r282223 228 228 // the same line (this can happen with very fancy language mixtures). 229 229 bool constructedNewBox = false; 230 bool allowedToConstructNewBox = !hasDefaultLineBoxContain || !inlineFlow || inlineFlow->alwaysCreateLineBoxes();231 230 bool canUseExistingParentBox = parentBox && !parentIsConstructedOrHaveNext(parentBox); 232 if ( allowedToConstructNewBox &&!canUseExistingParentBox) {231 if (!canUseExistingParentBox) { 233 232 // We need to make a new box for this render object. Once 234 233 // made, we need to place it at the end of the current line. … … 1770 1769 } 1771 1770 } else if (o.isTextOrLineBreak() || (is<RenderInline>(o) && !walker.atEndOfInline())) { 1772 if (is<RenderInline>(o))1773 downcast<RenderInline>(o).updateAlwaysCreateLineBoxes(layoutState.isFullLayout());1774 1771 if (layoutState.isFullLayout() || o.selfNeedsLayout()) 1775 1772 dirtyLineBoxesForRenderer(o, layoutState.isFullLayout()); -
trunk/Source/WebCore/rendering/RenderElement.cpp
r281967 r282223 110 110 , m_ancestorLineBoxDirty(false) 111 111 , m_hasInitializedStyle(false) 112 , m_renderInlineAlwaysCreatesLineBoxes(false)113 112 , m_renderBoxNeedsLazyRepaint(false) 114 113 , m_hasPausedImageAnimations(false) -
trunk/Source/WebCore/rendering/RenderElement.h
r281967 r282223 299 299 void notifyFinished(CachedResource&, const NetworkLoadMetrics&) override; 300 300 301 void setRenderInlineAlwaysCreatesLineBoxes(bool b) { m_renderInlineAlwaysCreatesLineBoxes = b; }302 bool renderInlineAlwaysCreatesLineBoxes() const { return m_renderInlineAlwaysCreatesLineBoxes; }303 304 301 void setHasContinuationChainNode(bool b) { m_hasContinuationChainNode = b; } 305 302 … … 373 370 unsigned m_hasInitializedStyle : 1; 374 371 375 unsigned m_renderInlineAlwaysCreatesLineBoxes : 1;376 372 unsigned m_renderBoxNeedsLazyRepaint : 1; 377 373 unsigned m_hasPausedImageAnimations : 1; -
trunk/Source/WebCore/rendering/RenderInline.cpp
r282202 r282223 187 187 } 188 188 189 if (!alwaysCreateLineBoxes()) {190 bool alwaysCreateLineBoxes = hasSelfPaintingLayer() || hasVisibleBoxDecorations() || newStyle.hasBorder() || newStyle.hasPadding() || newStyle.hasMargin() || hasOutline();191 if (oldStyle && alwaysCreateLineBoxes) {192 dirtyLineBoxes(false);193 setNeedsLayout();194 }195 setRenderInlineAlwaysCreatesLineBoxes(alwaysCreateLineBoxes);196 }197 198 189 #if ENABLE(LAYOUT_FORMATTING_CONTEXT) 199 190 if (auto* lineLayout = LayoutIntegration::LineLayout::containing(*this)) { … … 208 199 } 209 200 210 bool RenderInline::mayAffectRendering() const 211 { 212 // Test if we can get away with culling. 201 bool RenderInline::mayAffectLayout() const 202 { 213 203 auto* parentStyle = &parent()->style(); 214 204 RenderInline* parentRenderInline = is<RenderInline>(*parent()) ? downcast<RenderInline>(parent()) : nullptr; 215 205 auto hasHardLineBreakChildOnly = firstChild() && firstChild() == lastChild() && firstChild()->isBR(); 216 206 bool checkFonts = document().inNoQuirksMode(); 217 auto mayAffect Rendering = (parentRenderInline && parentRenderInline->mayAffectRendering())207 auto mayAffectLayout = (parentRenderInline && parentRenderInline->mayAffectLayout()) 218 208 || (parentRenderInline && parentStyle->verticalAlign() != VerticalAlign::Baseline) 219 209 || style().verticalAlign() != VerticalAlign::Baseline … … 223 213 || hasHardLineBreakChildOnly; 224 214 225 if (!mayAffect Rendering&& checkFonts && view().usesFirstLineRules()) {215 if (!mayAffectLayout && checkFonts && view().usesFirstLineRules()) { 226 216 // Have to check the first line style as well. 227 217 parentStyle = &parent()->firstLineStyle(); 228 218 auto& childStyle = firstLineStyle(); 229 mayAffect Rendering= !parentStyle->fontCascade().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.fontCascade().fontMetrics())219 mayAffectLayout = !parentStyle->fontCascade().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle.fontCascade().fontMetrics()) 230 220 || childStyle.verticalAlign() != VerticalAlign::Baseline 231 221 || parentStyle->lineHeight() != childStyle.lineHeight(); 232 222 } 233 return mayAffectRendering; 234 } 235 236 void RenderInline::updateAlwaysCreateLineBoxes(bool fullLayout) 237 { 238 // Once we have been tainted once, just assume it will happen again. This way effects like hover highlighting that change the 239 // background color will only cause a layout on the first rollover. 240 if (alwaysCreateLineBoxes() || !mayAffectRendering()) 241 return; 242 243 setAlwaysCreateLineBoxes(); 244 if (!fullLayout) 245 dirtyLineBoxes(false); 223 return mayAffectLayout; 246 224 } 247 225 … … 266 244 } 267 245 #endif 268 if (!alwaysCreateLineBoxes()) 269 generateCulledLineBoxRects(context, this); 270 else if (LegacyInlineFlowBox* curr = firstLineBox()) { 246 if (LegacyInlineFlowBox* curr = firstLineBox()) { 271 247 for (; curr; curr = curr->nextLineBox()) 272 248 context.addRect(FloatRect(curr->topLeft(), curr->size())); 273 249 } else 274 250 context.addRect(FloatRect()); 275 }276 277 template<typename GeneratorContext>278 void RenderInline::generateCulledLineBoxRects(GeneratorContext& context, const RenderInline* container) const279 {280 if (!culledInlineFirstLineBox()) {281 context.addRect(FloatRect());282 return;283 }284 285 bool isHorizontal = style().isHorizontalWritingMode();286 287 for (auto& current : childrenOfType<RenderObject>(*this)) {288 if (current.isFloatingOrOutOfFlowPositioned())289 continue;290 291 // We want to get the margin box in the inline direction, and then use our font ascent/descent in the block292 // direction (aligned to the root box's baseline).293 if (is<RenderBox>(current)) {294 auto& renderBox = downcast<RenderBox>(current);295 if (renderBox.inlineBoxWrapper()) {296 const LegacyRootInlineBox& rootBox = renderBox.inlineBoxWrapper()->root();297 const RenderStyle& containerStyle = rootBox.isFirstLine() ? container->firstLineStyle() : container->style();298 int logicalTop = rootBox.logicalTop() + (rootBox.lineStyle().fontCascade().fontMetrics().ascent() - containerStyle.fontCascade().fontMetrics().ascent());299 int logicalHeight = containerStyle.fontCascade().fontMetrics().height();300 if (isHorizontal)301 context.addRect(FloatRect(renderBox.inlineBoxWrapper()->x() - renderBox.marginLeft(), logicalTop, renderBox.width() + renderBox.horizontalMarginExtent(), logicalHeight));302 else303 context.addRect(FloatRect(logicalTop, renderBox.inlineBoxWrapper()->y() - renderBox.marginTop(), logicalHeight, renderBox.height() + renderBox.verticalMarginExtent()));304 }305 } else if (is<RenderInline>(current)) {306 // If the child doesn't need line boxes either, then we can recur.307 auto& renderInline = downcast<RenderInline>(current);308 if (!renderInline.alwaysCreateLineBoxes())309 renderInline.generateCulledLineBoxRects(context, container);310 else {311 for (auto* childLine = renderInline.firstLineBox(); childLine; childLine = childLine->nextLineBox()) {312 const LegacyRootInlineBox& rootBox = childLine->root();313 const RenderStyle& containerStyle = rootBox.isFirstLine() ? container->firstLineStyle() : container->style();314 int logicalTop = rootBox.logicalTop() + (rootBox.lineStyle().fontCascade().fontMetrics().ascent() - containerStyle.fontCascade().fontMetrics().ascent());315 int logicalHeight = containerStyle.fontMetrics().height();316 if (isHorizontal) {317 context.addRect(FloatRect(childLine->x() - childLine->marginLogicalLeft(),318 logicalTop,319 childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight(),320 logicalHeight));321 } else {322 context.addRect(FloatRect(logicalTop,323 childLine->y() - childLine->marginLogicalLeft(),324 logicalHeight,325 childLine->logicalWidth() + childLine->marginLogicalLeft() + childLine->marginLogicalRight()));326 }327 }328 }329 } else if (is<RenderText>(current)) {330 auto& currText = downcast<RenderText>(current);331 for (auto* childText = currText.firstTextBox(); childText; childText = childText->nextTextBox()) {332 const LegacyRootInlineBox& rootBox = childText->root();333 const RenderStyle& containerStyle = rootBox.isFirstLine() ? container->firstLineStyle() : container->style();334 int logicalTop = rootBox.logicalTop() + (rootBox.lineStyle().fontCascade().fontMetrics().ascent() - containerStyle.fontCascade().fontMetrics().ascent());335 int logicalHeight = containerStyle.fontCascade().fontMetrics().height();336 if (isHorizontal)337 context.addRect(FloatRect(childText->x(), logicalTop, childText->logicalWidth(), logicalHeight));338 else339 context.addRect(FloatRect(logicalTop, childText->y(), logicalHeight, childText->logicalWidth()));340 }341 } else if (is<RenderLineBreak>(current)) {342 if (auto* inlineBox = downcast<RenderLineBreak>(current).inlineBoxWrapper()) {343 // FIXME: This could use a helper to share these with text path.344 const LegacyRootInlineBox& rootBox = inlineBox->root();345 const RenderStyle& containerStyle = rootBox.isFirstLine() ? container->firstLineStyle() : container->style();346 int logicalTop = rootBox.logicalTop() + (rootBox.lineStyle().fontCascade().fontMetrics().ascent() - containerStyle.fontCascade().fontMetrics().ascent());347 int logicalHeight = containerStyle.fontMetrics().height();348 if (isHorizontal)349 context.addRect(FloatRect(inlineBox->x(), logicalTop, inlineBox->logicalWidth(), logicalHeight));350 else351 context.addRect(FloatRect(logicalTop, inlineBox->y(), logicalHeight, inlineBox->logicalWidth()));352 }353 }354 }355 251 } 356 252 … … 448 344 return lineLayout->firstInlineBoxRect(*this).location(); 449 345 #endif 450 if (LegacyInlineBox* firstBox = firstLineBox IncludingCulling())346 if (LegacyInlineBox* firstBox = firstLineBox()) 451 347 return flooredLayoutPoint(firstBox->topLeft()); 452 348 return { }; … … 528 424 } 529 425 530 namespace {531 532 class HitTestCulledInlinesGeneratorContext {533 public:534 HitTestCulledInlinesGeneratorContext(Region& region, const HitTestLocation& location)535 : m_intersected(false)536 , m_region(region)537 , m_location(location)538 { }539 540 void addRect(const FloatRect& rect)541 {542 m_intersected = m_intersected || m_location.intersects(rect);543 m_region.unite(enclosingIntRect(rect));544 }545 546 bool intersected() const { return m_intersected; }547 548 private:549 bool m_intersected;550 Region& m_region;551 const HitTestLocation& m_location;552 };553 554 } // unnamed namespace555 556 bool RenderInline::hitTestCulledInline(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset)557 {558 ASSERT(result.isRectBasedTest() && !alwaysCreateLineBoxes());559 if (!visibleToHitTesting(request))560 return false;561 562 HitTestLocation tmpLocation(locationInContainer, -toLayoutSize(accumulatedOffset));563 564 Region regionResult;565 HitTestCulledInlinesGeneratorContext context(regionResult, tmpLocation);566 generateCulledLineBoxRects(context, this);567 568 if (context.intersected()) {569 updateHitTestResult(result, tmpLocation.point());570 // We cannot use addNodeToListBasedTestResult to determine if we fully enclose the hit-test area571 // because it can only handle rectangular targets.572 result.addNodeToListBasedTestResult(nodeForHitTest(), request, locationInContainer);573 return regionResult.contains(enclosingIntRect(tmpLocation.boundingBox()));574 }575 return false;576 }577 578 426 VisiblePosition RenderInline::positionForPoint(const LayoutPoint& point, const RenderFragmentContainer* fragment) 579 427 { … … 626 474 return enclosingIntRect(layout->enclosingBorderBoxRectFor(*this)); 627 475 #endif 628 629 if (!alwaysCreateLineBoxes()) {630 ASSERT(!firstLineBox());631 FloatRect floatResult;632 LinesBoundingBoxGeneratorContext context(floatResult);633 generateCulledLineBoxRects(context, this);634 return enclosingIntRect(floatResult);635 }636 476 637 477 IntRect result; … … 664 504 } 665 505 666 LegacyInlineBox* RenderInline::culledInlineFirstLineBox() const667 {668 for (auto& current : childrenOfType<RenderObject>(*this)) {669 if (current.isFloatingOrOutOfFlowPositioned())670 continue;671 672 // We want to get the margin box in the inline direction, and then use our font ascent/descent in the block673 // direction (aligned to the root box's baseline).674 if (is<RenderBox>(current)) {675 auto& renderBox = downcast<RenderBox>(current);676 if (renderBox.inlineBoxWrapper())677 return renderBox.inlineBoxWrapper();678 } else if (is<RenderLineBreak>(current)) {679 auto& renderBR = downcast<RenderLineBreak>(current);680 if (renderBR.inlineBoxWrapper())681 return renderBR.inlineBoxWrapper();682 } else if (is<RenderInline>(current)) {683 auto& renderInline = downcast<RenderInline>(current);684 if (LegacyInlineBox* result = renderInline.firstLineBoxIncludingCulling())685 return result;686 } else if (is<RenderText>(current)) {687 auto& renderText = downcast<RenderText>(current);688 if (renderText.firstTextBox())689 return renderText.firstTextBox();690 }691 }692 return nullptr;693 }694 695 LegacyInlineBox* RenderInline::culledInlineLastLineBox() const696 {697 for (RenderObject* current = lastChild(); current; current = current->previousSibling()) {698 if (current->isFloatingOrOutOfFlowPositioned())699 continue;700 701 // We want to get the margin box in the inline direction, and then use our font ascent/descent in the block702 // direction (aligned to the root box's baseline).703 if (is<RenderBox>(*current)) {704 const auto& renderBox = downcast<RenderBox>(*current);705 if (renderBox.inlineBoxWrapper())706 return renderBox.inlineBoxWrapper();707 } else if (is<RenderLineBreak>(*current)) {708 RenderLineBreak& renderBR = downcast<RenderLineBreak>(*current);709 if (renderBR.inlineBoxWrapper())710 return renderBR.inlineBoxWrapper();711 } else if (is<RenderInline>(*current)) {712 RenderInline& renderInline = downcast<RenderInline>(*current);713 if (LegacyInlineBox* result = renderInline.lastLineBoxIncludingCulling())714 return result;715 } else if (is<RenderText>(*current)) {716 RenderText& renderText = downcast<RenderText>(*current);717 if (renderText.lastTextBox())718 return renderText.lastTextBox();719 }720 }721 return nullptr;722 }723 724 LayoutRect RenderInline::culledInlineVisualOverflowBoundingBox() const725 {726 FloatRect floatResult;727 LinesBoundingBoxGeneratorContext context(floatResult);728 generateCulledLineBoxRects(context, this);729 LayoutRect result(enclosingLayoutRect(floatResult));730 bool isHorizontal = style().isHorizontalWritingMode();731 for (auto& current : childrenOfType<RenderObject>(*this)) {732 if (current.isFloatingOrOutOfFlowPositioned())733 continue;734 735 // For overflow we just have to propagate by hand and recompute it all.736 if (is<RenderBox>(current)) {737 auto& renderBox = downcast<RenderBox>(current);738 if (!renderBox.hasSelfPaintingLayer() && renderBox.inlineBoxWrapper()) {739 LayoutRect logicalRect = renderBox.logicalVisualOverflowRectForPropagation(&style());740 if (isHorizontal) {741 logicalRect.moveBy(renderBox.location());742 result.uniteIfNonZero(logicalRect);743 } else {744 logicalRect.moveBy(renderBox.location());745 result.uniteIfNonZero(logicalRect.transposedRect());746 }747 }748 } else if (is<RenderInline>(current)) {749 // If the child doesn't need line boxes either, then we can recur.750 auto& renderInline = downcast<RenderInline>(current);751 if (!renderInline.alwaysCreateLineBoxes())752 result.uniteIfNonZero(renderInline.culledInlineVisualOverflowBoundingBox());753 else if (!renderInline.hasSelfPaintingLayer())754 result.uniteIfNonZero(renderInline.linesVisualOverflowBoundingBox());755 } else if (is<RenderText>(current)) {756 // FIXME; Overflow from text boxes is lost. We will need to cache this information in757 // LegacyInlineTextBoxes.758 auto& renderText = downcast<RenderText>(current);759 result.uniteIfNonZero(renderText.linesVisualOverflowBoundingBox());760 }761 }762 return result;763 }764 765 506 LayoutRect RenderInline::linesVisualOverflowBoundingBox() const 766 507 { … … 769 510 return layout->visualOverflowBoundingBoxRectFor(*this); 770 511 #endif 771 772 if (!alwaysCreateLineBoxes())773 return culledInlineVisualOverflowBoundingBox();774 512 775 513 if (!firstLineBox() || !lastLineBox()) … … 799 537 LayoutRect RenderInline::linesVisualOverflowBoundingBoxInFragment(const RenderFragmentContainer* fragment) const 800 538 { 801 ASSERT(alwaysCreateLineBoxes());802 539 ASSERT(fragment); 803 540 … … 847 584 848 585 auto knownEmpty = [&] { 849 if (firstLineBox IncludingCulling())586 if (firstLineBox()) 850 587 return false; 851 588 if (continuation()) … … 1095 832 } 1096 833 1097 if (!alwaysCreateLineBoxes()) { 1098 // We have to grovel into our children in order to dirty the appropriate lines. 1099 for (auto& current : childrenOfType<RenderObject>(*this)) { 1100 if (current.isFloatingOrOutOfFlowPositioned()) 1101 continue; 1102 if (is<RenderBox>(current) && !current.needsLayout()) { 1103 auto& renderBox = downcast<RenderBox>(current); 1104 if (renderBox.inlineBoxWrapper()) 1105 renderBox.inlineBoxWrapper()->root().markDirty(); 1106 } else if (!current.selfNeedsLayout()) { 1107 if (is<RenderInline>(current)) { 1108 auto& renderInline = downcast<RenderInline>(current); 1109 for (auto* childLine = renderInline.firstLineBox(); childLine; childLine = childLine->nextLineBox()) 1110 childLine->root().markDirty(); 1111 } else if (is<RenderText>(current)) { 1112 auto& renderText = downcast<RenderText>(current); 1113 for (auto* childText = renderText.firstTextBox(); childText; childText = childText->nextTextBox()) 1114 childText->root().markDirty(); 1115 } else if (is<RenderLineBreak>(current)) { 1116 auto& renderBR = downcast<RenderLineBreak>(current); 1117 if (renderBR.inlineBoxWrapper()) 1118 renderBR.inlineBoxWrapper()->root().markDirty(); 1119 } 1120 } 1121 } 1122 } else 1123 m_lineBoxes.dirtyLineBoxes(); 834 m_lineBoxes.dirtyLineBoxes(); 1124 835 } 1125 836 … … 1136 847 LegacyInlineFlowBox* RenderInline::createAndAppendInlineFlowBox() 1137 848 { 1138 setAlwaysCreateLineBoxes();1139 849 auto newFlowBox = createInlineFlowBox(); 1140 850 auto flowBox = newFlowBox.get(); -
trunk/Source/WebCore/rendering/RenderInline.h
r282202 r282223 71 71 LegacyInlineFlowBox* firstLineBox() const { return m_lineBoxes.firstLineBox(); } 72 72 LegacyInlineFlowBox* lastLineBox() const { return m_lineBoxes.lastLineBox(); } 73 LegacyInlineBox* firstLineBoxIncludingCulling() const { return alwaysCreateLineBoxes() ? firstLineBox() : culledInlineFirstLineBox(); }74 LegacyInlineBox* lastLineBoxIncludingCulling() const { return alwaysCreateLineBoxes() ? lastLineBox() : culledInlineLastLineBox(); }75 73 76 74 #if PLATFORM(IOS_FAMILY) … … 83 81 void paintOutline(PaintInfo&, const LayoutPoint&); 84 82 85 bool alwaysCreateLineBoxes() const { return true; } 86 void setAlwaysCreateLineBoxes() { setRenderInlineAlwaysCreatesLineBoxes(true); } 87 bool mayAffectRendering() const; 88 void updateAlwaysCreateLineBoxes(bool fullLayout); 89 90 bool hitTestCulledInline(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset); 83 bool mayAffectLayout() const; 91 84 92 85 bool requiresLayer() const override { return isInFlowPositioned() || createsGroup() || hasClipPath() || willChangeCreatesStackingContext() || hasRunningAcceleratedAnimations(); } … … 105 98 bool canHaveChildren() const final { return true; } 106 99 107 LayoutRect culledInlineVisualOverflowBoundingBox() const;108 LegacyInlineBox* culledInlineFirstLineBox() const;109 LegacyInlineBox* culledInlineLastLineBox() const;110 111 100 void absoluteQuadsIgnoringContinuation(const FloatRect&, Vector<FloatQuad>&, bool* wasFixed) const override; 112 101 113 102 template<typename GeneratorContext> 114 103 void generateLineBoxRects(GeneratorContext& yield) const; 115 template<typename GeneratorContext>116 void generateCulledLineBoxRects(GeneratorContext& yield, const RenderInline* container) const;117 104 118 105 void layout() final { ASSERT_NOT_REACHED(); } // Do nothing for layout() -
trunk/Source/WebCore/rendering/RenderLineBoxList.cpp
r278698 r282223 312 312 313 313 RenderInline* inlineContainer = is<RenderInline>(container) ? &downcast<RenderInline>(container) : nullptr; 314 LegacyInlineBox* firstBox = inlineContainer ? inlineContainer->firstLineBox IncludingCulling() : firstLineBox();314 LegacyInlineBox* firstBox = inlineContainer ? inlineContainer->firstLineBox() : firstLineBox(); 315 315 316 316 // If we have no first line box, then just bail early. … … 343 343 box = &textBox->root(); 344 344 } else if (is<RenderInline>(*current)) { 345 LegacyInlineBox* lastSiblingBox = downcast<RenderInline>(*current).lastLineBox IncludingCulling();345 LegacyInlineBox* lastSiblingBox = downcast<RenderInline>(*current).lastLineBox(); 346 346 if (lastSiblingBox) 347 347 box = &lastSiblingBox->root(); … … 351 351 break; 352 352 } 353 if (!box) { 354 if (inlineContainer && !inlineContainer->alwaysCreateLineBoxes()) { 355 // https://bugs.webkit.org/show_bug.cgi?id=60778 356 // We may have just removed a <br> with no line box that was our first child. In this case 357 // we won't find a previous sibling, but firstBox can be pointing to a following sibling. 358 // This isn't good enough, since we won't locate the root line box that encloses the removed 359 // <br>. We have to just over-invalidate a bit and go up to our parent. 360 if (!inlineContainer->ancestorLineBoxDirty()) { 361 inlineContainer->parent()->dirtyLinesFromChangedChild(*inlineContainer); 362 inlineContainer->setAncestorLineBoxDirty(); // Mark the container to avoid dirtying the same lines again across multiple destroy() calls of the same subtree. 363 } 364 return; 365 } 353 if (!box) 366 354 box = &firstBox->root(); 367 }368 355 369 356 // If we found a line box, then dirty it. … … 388 375 // the parent flow, we need to invalidate it explicitly. 389 376 // FIXME: We should be able to figure out the actual "changed child" even when we are calling through empty inlines recursively. 390 if (is<RenderInline>(child) && !downcast<RenderInline>(child).firstLineBox IncludingCulling()) {377 if (is<RenderInline>(child) && !downcast<RenderInline>(child).firstLineBox()) { 391 378 auto* lastRootBox = nextBox->blockFlow().lastRootBox(); 392 379 if (lastRootBox->isForTrailingFloats() && !lastRootBox->isDirty()) -
trunk/Source/WebCore/rendering/RenderText.cpp
r281731 r282223 1585 1585 } 1586 1586 1587 LayoutRect RenderText::linesVisualOverflowBoundingBox() const1588 {1589 return m_lineBoxes.visualOverflowBoundingBox(*this);1590 }1591 1592 1587 LayoutRect RenderText::clippedOverflowRect(const RenderLayerModelObject* repaintContainer, VisibleRectContext context) const 1593 1588 { -
trunk/Source/WebCore/rendering/RenderText.h
r278525 r282223 118 118 119 119 WEBCORE_EXPORT virtual IntRect linesBoundingBox() const; 120 LayoutRect linesVisualOverflowBoundingBox() const;121 122 120 WEBCORE_EXPORT IntPoint firstRunLocation() const; 123 121 -
trunk/Source/WebCore/rendering/RenderTextLineBoxes.cpp
r278534 r282223 148 148 } 149 149 150 LayoutRect RenderTextLineBoxes::visualOverflowBoundingBox(const RenderText& renderer) const151 {152 if (!m_first)153 return LayoutRect();154 155 // Return the width of the minimal left side and the maximal right side.156 auto logicalLeftSide = LayoutUnit::max();157 auto logicalRightSide = LayoutUnit::min();158 for (auto* current = m_first; current; current = current->nextTextBox()) {159 logicalLeftSide = std::min(logicalLeftSide, current->logicalLeftVisualOverflow());160 logicalRightSide = std::max(logicalRightSide, current->logicalRightVisualOverflow());161 }162 163 auto logicalTop = m_first->logicalTopVisualOverflow();164 auto logicalWidth = logicalRightSide - logicalLeftSide;165 auto logicalHeight = m_last->logicalBottomVisualOverflow() - logicalTop;166 167 LayoutRect rect(logicalLeftSide, logicalTop, logicalWidth, logicalHeight);168 if (!renderer.style().isHorizontalWritingMode())169 rect = rect.transposedRect();170 return rect;171 }172 173 150 void RenderTextLineBoxes::dirtyAll() 174 151 { -
trunk/Source/WebCore/rendering/RenderTextLineBoxes.h
r278525 r282223 57 57 LegacyInlineTextBox* findNext(int offset, int& position) const; 58 58 59 LayoutRect visualOverflowBoundingBox(const RenderText&) const;60 61 59 #if ASSERT_ENABLED 62 60 ~RenderTextLineBoxes(); -
trunk/Source/WebCore/rendering/RenderTreeAsText.cpp
r282129 r282223 203 203 return true; 204 204 auto& siblingRendererInline = downcast<RenderInline>(sibling); 205 if (siblingRendererInline.mayAffect Rendering() || !isRenderInlineEmpty(siblingRendererInline))205 if (siblingRendererInline.mayAffectLayout() || !isRenderInlineEmpty(siblingRendererInline)) 206 206 return true; 207 207 } -
trunk/Source/WebCore/rendering/svg/RenderSVGInline.cpp
r281239 r282223 37 37 : RenderInline(element, WTFMove(style)) 38 38 { 39 setAlwaysCreateLineBoxes();40 39 } 41 40
Note:
See TracChangeset
for help on using the changeset viewer.