Index: Source/core/rendering/RenderBlock.cpp |
diff --git a/Source/core/rendering/RenderBlock.cpp b/Source/core/rendering/RenderBlock.cpp |
index 20b4954c4a9260be7e408f52d41638597c70758e..f593265dc53df5e1b39b485c162ba4123467de44 100644 |
--- a/Source/core/rendering/RenderBlock.cpp |
+++ b/Source/core/rendering/RenderBlock.cpp |
@@ -242,14 +242,6 @@ void RenderBlock::destroy() |
#endif |
} |
-LayoutRect RenderBlock::selectionRectForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const |
-{ |
- LayoutRect rect = selectionGapRectsForPaintInvalidation(paintInvalidationContainer); |
- // FIXME: groupedMapping() leaks the squashing abstraction. |
- if (paintInvalidationContainer->layer()->groupedMapping()) |
- RenderLayer::mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect); |
- return rect; |
-} |
void RenderBlock::willBeDestroyed() |
{ |
// Mark as being destroyed to avoid trouble with merges in removeChild(). |
@@ -1840,11 +1832,6 @@ void RenderBlock::addContinuationWithOutline(RenderInline* flow) |
continuations->add(flow); |
} |
-bool RenderBlock::shouldPaintSelectionGaps() const |
-{ |
- return selectionState() != SelectionNone && style()->visibility() == VISIBLE && isSelectionRoot(); |
-} |
- |
bool RenderBlock::isSelectionRoot() const |
{ |
if (isPseudoElement()) |
@@ -1871,39 +1858,6 @@ bool RenderBlock::isSelectionRoot() const |
return false; |
} |
-GapRects RenderBlock::selectionGapRectsForPaintInvalidation(const RenderLayerModelObject* paintInvalidationContainer) const |
-{ |
- ASSERT(!needsLayout()); |
- |
- if (!shouldPaintSelectionGaps()) |
- return GapRects(); |
- |
- TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint()); |
- mapLocalToContainer(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, IntSize(), lastTop, lastLeft, lastRight); |
-} |
- |
-static void clipOutPositionedObjects(const PaintInfo* paintInfo, const LayoutPoint& offset, TrackedRendererListHashSet* positionedObjects) |
-{ |
- if (!positionedObjects) |
- return; |
- |
- TrackedRendererListHashSet::const_iterator end = positionedObjects->end(); |
- for (TrackedRendererListHashSet::const_iterator it = positionedObjects->begin(); it != end; ++it) { |
- RenderBox* r = *it; |
- paintInfo->context->clipOut(IntRect(offset.x() + r->x(), offset.y() + r->y(), r->width(), r->height())); |
- } |
-} |
- |
LayoutUnit RenderBlock::blockDirectionOffset(const LayoutSize& offsetFromBlock) const |
{ |
return isHorizontalWritingMode() ? offsetFromBlock.height() : offsetFromBlock.width(); |
@@ -1926,192 +1880,6 @@ LayoutRect RenderBlock::logicalRectToPhysicalRect(const LayoutPoint& rootBlockPh |
return result; |
} |
-GapRects RenderBlock::selectionGaps(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, |
- LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo* paintInfo) const |
-{ |
- // IMPORTANT: Callers of this method that intend for painting to happen need to do a save/restore. |
- // Clip out floating and positioned objects when painting selection gaps. |
- if (paintInfo) { |
- // Note that we don't clip out overflow for positioned objects. We just stick to the border box. |
- LayoutRect flippedBlockRect(offsetFromRootBlock.width(), offsetFromRootBlock.height(), width(), height()); |
- rootBlock->flipForWritingMode(flippedBlockRect); |
- flippedBlockRect.moveBy(rootBlockPhysicalPosition); |
- clipOutPositionedObjects(paintInfo, flippedBlockRect.location(), positionedObjects()); |
- if (isBody() || isDocumentElement()) // The <body> must make sure to examine its containingBlock's positioned objects. |
- for (RenderBlock* cb = containingBlock(); cb && !cb->isRenderView(); cb = cb->containingBlock()) |
- clipOutPositionedObjects(paintInfo, LayoutPoint(cb->x(), cb->y()), cb->positionedObjects()); // FIXME: Not right for flipped writing modes. |
- clipOutFloatingObjects(rootBlock, paintInfo, rootBlockPhysicalPosition, offsetFromRootBlock); |
- } |
- |
- // FIXME: overflow: auto/scroll regions need more math here, since painting in the border box is different from painting in the padding box (one is scrolled, the other is |
- // fixed). |
- GapRects result; |
- if (!isRenderBlockFlow()) // FIXME: Make multi-column selection gap filling work someday. |
- return result; |
- |
- if (hasColumns() || hasTransformRelatedProperty() || style()->columnSpan()) { |
- // FIXME: We should learn how to gap fill multiple columns and transforms eventually. |
- lastLogicalTop = rootBlock->blockDirectionOffset(offsetFromRootBlock) + logicalHeight(); |
- lastLogicalLeft = logicalLeftSelectionOffset(rootBlock, logicalHeight()); |
- lastLogicalRight = logicalRightSelectionOffset(rootBlock, logicalHeight()); |
- return result; |
- } |
- |
- if (childrenInline()) |
- result = toRenderBlockFlow(this)->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 RenderBlock::blockSelectionGaps(const RenderBlock* 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. |
- RenderBox* 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->isRelPositioned() && 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, this, curr->logicalLeft(), curr->logicalTop(), curr->logicalHeight(), paintInfo)); |
- if (rightGap) |
- result.uniteRight(logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock, 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) |
- // We must be a block that has some selected object inside it. Go ahead and recur. |
- result.unite(toRenderBlock(curr)->selectionGaps(rootBlock, rootBlockPhysicalPosition, LayoutSize(offsetFromRootBlock.width() + curr->x(), offsetFromRootBlock.height() + curr->y()), |
- lastLogicalTop, lastLogicalLeft, lastLogicalRight, paintInfo)); |
- } |
- return result; |
-} |
- |
-IntRect alignSelectionRectToDevicePixels(LayoutRect& rect) |
-{ |
- LayoutUnit roundedX = rect.x().round(); |
- return IntRect(roundedX, rect.y().round(), |
- (rect.maxX() - roundedX).round(), |
- snapSizeToPixel(rect.height(), rect.y())); |
-} |
- |
-LayoutRect RenderBlock::blockSelectionGap(const RenderBlock* 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); |
- DrawingRecorder recorder(paintInfo->context, this, paintInfo->phase, selectionGapRect); |
- paintInfo->context->fillRect(selectionGapRect, selectionBackgroundColor()); |
- } |
- return gapRect; |
-} |
- |
-LayoutRect RenderBlock::logicalLeftSelectionGap(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, |
- const RenderObject* 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); |
- DrawingRecorder recorder(paintInfo->context, this, paintInfo->phase, selectionGapRect); |
- paintInfo->context->fillRect(selectionGapRect, selObj->selectionBackgroundColor()); |
- } |
- return gapRect; |
-} |
- |
-LayoutRect RenderBlock::logicalRightSelectionGap(const RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, |
- const RenderObject* 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); |
- DrawingRecorder recorder(paintInfo->context, this, paintInfo->phase, selectionGapRect); |
- paintInfo->context->fillRect(selectionGapRect, selObj->selectionBackgroundColor()); |
- } |
- return gapRect; |
-} |
- |
-void RenderBlock::getSelectionGapInfo(SelectionState state, bool& leftGap, bool& rightGap) const |
-{ |
- bool ltr = style()->isLeftToRightDirection(); |
- leftGap = (state == RenderObject::SelectionInside) || |
- (state == RenderObject::SelectionEnd && ltr) || |
- (state == RenderObject::SelectionStart && !ltr); |
- rightGap = (state == RenderObject::SelectionInside) || |
- (state == RenderObject::SelectionStart && ltr) || |
- (state == RenderObject::SelectionEnd && !ltr); |
-} |
- |
LayoutUnit RenderBlock::logicalLeftSelectionOffset(const RenderBlock* rootBlock, LayoutUnit position) const |
{ |
// The border can potentially be further extended by our containingBlock(). |