Index: third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp |
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp |
index 6041079e9fc0239551ff9cf3c13c68c1d41a5929..def8c0977ebf6e4227513d816b84d021de5f2c55 100644 |
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp |
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.cpp |
@@ -2103,11 +2103,6 @@ void LayoutBlockFlow::paintFloats(const PaintInfo& paintInfo, const LayoutPoint& |
BlockFlowPainter(*this).paintFloats(paintInfo, paintOffset); |
} |
-void LayoutBlockFlow::paintSelection(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) const |
-{ |
- BlockFlowPainter(*this).paintSelection(paintInfo, paintOffset); |
-} |
- |
void LayoutBlockFlow::clipOutFloatingObjects(const LayoutBlock* rootBlock, ClipScope& clipScope, |
const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock) const |
{ |
@@ -2643,139 +2638,6 @@ LayoutUnit LayoutBlockFlow::logicalRightFloatOffsetForLine(LayoutUnit logicalTop |
return fixedOffset; |
} |
-LayoutRect LayoutBlockFlow::selectionRectForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer) const |
-{ |
- LayoutRect rect = selectionGapRectsForPaintInvalidation(paintInvalidationContainer); |
- // FIXME: groupedMapping() leaks the squashing abstraction. |
- if (paintInvalidationContainer->layer()->groupedMapping()) |
- PaintLayer::mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect); |
- return rect; |
-} |
- |
-GapRects LayoutBlockFlow::selectionGapRectsForPaintInvalidation(const LayoutBoxModelObject* paintInvalidationContainer) const |
-{ |
- ASSERT(!needsLayout()); |
- |
- if (!shouldPaintSelectionGaps()) |
- return GapRects(); |
- |
- TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint()); |
- mapLocalToAncestor(paintInvalidationContainer, transformState, ApplyContainerFlip | UseTransforms); |
- LayoutPoint offsetFromPaintInvalidationContainer = roundedLayoutPoint(transformState.mappedPoint()); |
- |
- if (hasOverflowClip()) |
- offsetFromPaintInvalidationContainer -= scrolledContentOffset(); |
- |
- LayoutUnit lastTop = 0; |
- LayoutUnit lastLeft = logicalLeftSelectionOffset(this, lastTop); |
- LayoutUnit lastRight = logicalRightSelectionOffset(this, lastTop); |
- |
- return selectionGaps(this, offsetFromPaintInvalidationContainer, LayoutSize(), lastTop, lastLeft, lastRight); |
-} |
- |
-static void clipOutPositionedObjects(ClipScope& clipScope, const LayoutPoint& offset, TrackedLayoutBoxListHashSet* positionedObjects) |
-{ |
- if (!positionedObjects) |
- return; |
- |
- TrackedLayoutBoxListHashSet::const_iterator end = positionedObjects->end(); |
- for (TrackedLayoutBoxListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) { |
- LayoutBox* r = *it; |
- clipScope.clip(LayoutRect(flooredIntPoint(r->location() + offset), flooredIntSize(r->size())), SkRegion::kDifference_Op); |
- } |
-} |
- |
-GapRects LayoutBlockFlow::selectionGaps(const LayoutBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, |
- const LayoutSize& offsetFromRootBlock, LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, |
- const PaintInfo* paintInfo, ClipScope* clipScope) const |
-{ |
- // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore. |
- if (clipScope) { |
- // Note that we don't clip out overflow for positioned objects. We just stick to the border box. |
- LayoutRect flippedBlockRect(LayoutPoint(offsetFromRootBlock), size()); |
- rootBlock->flipForWritingMode(flippedBlockRect); |
- flippedBlockRect.moveBy(rootBlockPhysicalPosition); |
- clipOutPositionedObjects(*clipScope, flippedBlockRect.location(), positionedObjects()); |
- if (isBody() || isDocumentElement()) // The <body> must make sure to examine its containingBlock's positioned objects. |
- for (LayoutBlock* cb = containingBlock(); cb && !cb->isLayoutView(); cb = cb->containingBlock()) |
- clipOutPositionedObjects(*clipScope, cb->location(), cb->positionedObjects()); // FIXME: Not right for flipped writing modes. |
- clipOutFloatingObjects(rootBlock, *clipScope, rootBlockPhysicalPosition, offsetFromRootBlock); |
- } |
- |
- GapRects result; |
- |
- if (hasTransformRelatedProperty() || style()->columnSpan()) |
- return result; |
- |
- if (childrenInline()) |
- result = inlineSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); |
- else |
- result = blockSelectionGaps(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo); |
- |
- // Go ahead and fill the vertical gap all the way to the bottom of our block if the selection extends past our block. |
- if (rootBlock == this && (selectionState() != SelectionBoth && selectionState() != SelectionEnd)) { |
- result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, |
- lastLogicalTop, lastLogicalLeft, lastLogicalRight, logicalHeight(), paintInfo)); |
- } |
- return result; |
-} |
- |
- |
-GapRects LayoutBlockFlow::inlineSelectionGaps(const LayoutBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, |
- LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo) const |
-{ |
- GapRects result; |
- |
- bool containsStart = selectionState() == SelectionStart || selectionState() == SelectionBoth; |
- |
- if (!firstLineBox()) { |
- if (containsStart) { |
- // Go ahead and update our lastLogicalTop to be the bottom of the block. <hr>s or empty blocks with height can trip this |
- // case. |
- lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalHeight(); |
- lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight()); |
- lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight()); |
- } |
- return result; |
- } |
- |
- RootInlineBox* lastSelectedLine = nullptr; |
- RootInlineBox* curr; |
- for (curr = firstRootBox(); curr && !curr->hasSelectedChildren(); curr = curr->nextRootBox()) { } |
- |
- // Now paint the gaps for the lines. |
- for (; curr && curr->hasSelectedChildren(); curr = curr->nextRootBox()) { |
- LayoutUnit selTop = curr->selectionTopAdjustedForPrecedingBlock(); |
- LayoutUnit selHeight = curr->selectionHeightAdjustedForPrecedingBlock(); |
- |
- if (!containsStart && !lastSelectedLine && selectionState() != SelectionStart && selectionState() != SelectionBoth) { |
- result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, |
- lastLogicalLeft, lastLogicalRight, selTop, paintInfo)); |
- } |
- |
- LayoutRect logicalRect(curr->logicalLeft(), selTop, curr->logicalWidth(), selTop + selHeight); |
- logicalRect.move(isHorizontalWritingMode() ? offsetFromRootBlock : offsetFromRootBlock.transposedSize()); |
- LayoutRect physicalRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect); |
- if (!paintInfo || paintInfo->cullRect().intersectsCullRect(enclosingIntRect(physicalRect))) |
- result.unite(curr->lineSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, selTop, selHeight, paintInfo)); |
- |
- lastSelectedLine = curr; |
- } |
- |
- if (containsStart && !lastSelectedLine) { |
- // VisibleSelection must start just after our last line. |
- lastSelectedLine = lastRootBox(); |
- } |
- |
- if (lastSelectedLine && selectionState() != SelectionEnd && selectionState() != SelectionBoth) { |
- // Go ahead and update our lastY to be the bottom of the last selected line. |
- lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + lastSelectedLine->selectionBottom(); |
- lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); |
- lastLogicalRight = logicalRightSelectionOffset(rootBlock, lastSelectedLine->selectionBottom()); |
- } |
- return result; |
-} |
- |
IntRect alignSelectionRectToDevicePixels(LayoutRect& rect) |
{ |
LayoutUnit roundedX = rect.x().round(); |
@@ -2784,147 +2646,6 @@ IntRect alignSelectionRectToDevicePixels(LayoutRect& rect) |
snapSizeToPixel(rect.height(), rect.y())); |
} |
-bool LayoutBlockFlow::shouldPaintSelectionGaps() const |
-{ |
- if (RuntimeEnabledFeatures::selectionPaintingWithoutSelectionGapsEnabled()) |
- return false; |
- return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot(); |
-} |
- |
-LayoutRect LayoutBlockFlow::blockSelectionGap(const LayoutBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, |
- LayoutUnit lastLogicalTop, LayoutUnit lastLogicalLeft, LayoutUnit lastLogicalRight, LayoutUnit logicalBottom, const PaintInfo* paintInfo) const |
-{ |
- LayoutUnit logicalTop = lastLogicalTop; |
- LayoutUnit logicalHeight = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalBottom - logicalTop; |
- if (logicalHeight <= 0) |
- return LayoutRect(); |
- |
- // Get the selection offsets for the bottom of the gap |
- LayoutUnit logicalLeft = std::max(lastLogicalLeft, logicalLeftSelectionOffset(rootBlock, logicalBottom)); |
- LayoutUnit logicalRight = std::min(lastLogicalRight, logicalRightSelectionOffset(rootBlock, logicalBottom)); |
- LayoutUnit logicalWidth = logicalRight - logicalLeft; |
- if (logicalWidth <= 0) |
- return LayoutRect(); |
- |
- LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(logicalLeft, logicalTop, logicalWidth, logicalHeight)); |
- if (paintInfo) { |
- IntRect selectionGapRect = alignSelectionRectToDevicePixels(gapRect); |
- paintInfo->context.fillRect(selectionGapRect, selectionBackgroundColor()); |
- } |
- return gapRect; |
-} |
- |
-GapRects LayoutBlockFlow::blockSelectionGaps(const LayoutBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, |
- LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo) const |
-{ |
- GapRects result; |
- |
- // Go ahead and jump right to the first block child that contains some selected objects. |
- LayoutBox* curr; |
- for (curr = firstChildBox(); curr && curr->selectionState() == SelectionNone; curr = curr->nextSiblingBox()) { } |
- |
- for (bool sawSelectionEnd = false; curr && !sawSelectionEnd; curr = curr->nextSiblingBox()) { |
- SelectionState childState = curr->selectionState(); |
- if (childState == SelectionBoth || childState == SelectionEnd) |
- sawSelectionEnd = true; |
- |
- if (curr->isFloatingOrOutOfFlowPositioned()) |
- continue; // We must be a normal flow object in order to even be considered. |
- |
- if (curr->isInFlowPositioned() && curr->hasLayer()) { |
- // If the relposition offset is anything other than 0, then treat this just like an absolute positioned element. |
- // Just disregard it completely. |
- LayoutSize relOffset = curr->layer()->offsetForInFlowPosition(); |
- if (relOffset.width() || relOffset.height()) |
- continue; |
- } |
- |
- bool paintsOwnSelection = curr->shouldPaintSelectionGaps() || curr->isTable(); // FIXME: Eventually we won't special-case table like this. |
- bool fillBlockGaps = paintsOwnSelection || (curr->canBeSelectionLeaf() && childState != SelectionNone); |
- if (fillBlockGaps) { |
- // We need to fill the vertical gap above this object. |
- if (childState == SelectionEnd || childState == SelectionInside) { |
- // Fill the gap above the object. |
- result.uniteCenter(blockSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, lastLogicalTop, lastLogicalLeft, lastLogicalRight, |
- curr->logicalTop(), paintInfo)); |
- } |
- |
- // Only fill side gaps for objects that paint their own selection if we know for sure the selection is going to extend all the way *past* |
- // our object. We know this if the selection did not end inside our object. |
- if (paintsOwnSelection && (childState == SelectionStart || sawSelectionEnd)) |
- childState = SelectionNone; |
- |
- // Fill side gaps on this object based off its state. |
- bool leftGap, rightGap; |
- getSelectionGapInfo(childState, leftGap, rightGap); |
- |
- if (leftGap) |
- result.uniteLeft(logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, LineLayoutItem(const_cast<LayoutBlockFlow*>(this)), curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo)); |
- if (rightGap) |
- result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, LineLayoutItem(const_cast<LayoutBlockFlow*>(this)), curr->logicalRight(), curr->logicalTop(), curr->logicalHeight(), paintInfo)); |
- |
- // Update lastLogicalTop to be just underneath the object. lastLogicalLeft and lastLogicalRight extend as far as |
- // they can without bumping into floating or positioned objects. Ideally they will go right up |
- // to the border of the root selection block. |
- lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + curr->logicalBottom(); |
- lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, curr->logicalBottom()); |
- lastLogicalRight = logicalRightSelectionOffset(rootBlock, curr->logicalBottom()); |
- } else if (childState != SelectionNone && curr->isLayoutBlockFlow()) { |
- // We must be a block that has some selected object inside it. Go ahead and recur. |
- result.unite(toLayoutBlockFlow(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->location().x(), offsetFromRootBlock.height() + curr->location().y()), |
- lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo)); |
- } |
- } |
- return result; |
-} |
- |
-LayoutRect LayoutBlockFlow::logicalLeftSelectionGap(const LayoutBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, |
- const LineLayoutItem selObj, LayoutUnit logicalLeft, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo) const |
-{ |
- LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalTop; |
- LayoutUnit rootBlockLogicalLeft = std::max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight)); |
- LayoutUnit rootBlockLogicalRight = std::min(rootBlock->inlineDirectionOffset(offsetFromRootBlock) + logicalLeft, std::min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight))); |
- LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft; |
- if (rootBlockLogicalWidth <= 0) |
- return LayoutRect(); |
- |
- LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight)); |
- if (paintInfo) { |
- IntRect selectionGapRect = alignSelectionRectToDevicePixels(gapRect); |
- paintInfo->context.fillRect(selectionGapRect, selObj.selectionBackgroundColor()); |
- } |
- return gapRect; |
-} |
- |
-LayoutRect LayoutBlockFlow::logicalRightSelectionGap(const LayoutBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, |
- const LineLayoutItem selObj, LayoutUnit logicalRight, LayoutUnit logicalTop, LayoutUnit logicalHeight, const PaintInfo* paintInfo) const |
-{ |
- LayoutUnit rootBlockLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalTop; |
- LayoutUnit rootBlockLogicalLeft = std::max(rootBlock->inlineDirectionOffset(offsetFromRootBlock) + logicalRight, max(logicalLeftSelectionOffset(rootBlock, logicalTop), logicalLeftSelectionOffset(rootBlock, logicalTop + logicalHeight))); |
- LayoutUnit rootBlockLogicalRight = std::min(logicalRightSelectionOffset(rootBlock, logicalTop), logicalRightSelectionOffset(rootBlock, logicalTop + logicalHeight)); |
- LayoutUnit rootBlockLogicalWidth = rootBlockLogicalRight - rootBlockLogicalLeft; |
- if (rootBlockLogicalWidth <= 0) |
- return LayoutRect(); |
- |
- LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, LayoutRect(rootBlockLogicalLeft, rootBlockLogicalTop, rootBlockLogicalWidth, logicalHeight)); |
- if (paintInfo) { |
- IntRect selectionGapRect = alignSelectionRectToDevicePixels(gapRect); |
- paintInfo->context.fillRect(selectionGapRect, selObj.selectionBackgroundColor()); |
- } |
- return gapRect; |
-} |
- |
-void LayoutBlockFlow::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap) const |
-{ |
- bool ltr = style()->isLeftToRightDirection(); |
- leftGap = (state == SelectionInside) |
- || (state == SelectionEnd && ltr) |
- || (state == SelectionStart && !ltr); |
- rightGap = (state == SelectionInside) |
- || (state == SelectionStart && ltr) |
- || (state == SelectionEnd && !ltr); |
-} |
- |
bool LayoutBlockFlow::allowsPaginationStrut() const |
{ |
// The block needs to be contained by a LayoutBlockFlow (and not by e.g. a flexbox, grid, or a |