Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1493)

Unified Diff: Source/core/rendering/RenderBlock.cpp

Issue 720313002: Push selection gaps logic down to RenderBlockFlow (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: move even MOAR! Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | Source/core/rendering/RenderBlockFlow.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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().
« no previous file with comments | « Source/core/rendering/RenderBlock.h ('k') | Source/core/rendering/RenderBlockFlow.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698