| Index: Source/core/rendering/RenderBlock.cpp
|
| diff --git a/Source/core/rendering/RenderBlock.cpp b/Source/core/rendering/RenderBlock.cpp
|
| index 5d873a83ff09aba10beb5d9a24e06d69d593c644..04427a39aba1aad42c6243c76bd9ff8829da066d 100644
|
| --- a/Source/core/rendering/RenderBlock.cpp
|
| +++ b/Source/core/rendering/RenderBlock.cpp
|
| @@ -38,6 +38,7 @@
|
| #include "core/frame/LocalFrame.h"
|
| #include "core/frame/Settings.h"
|
| #include "core/page/Page.h"
|
| +#include "core/paint/BlockPainter.h"
|
| #include "core/paint/BoxPainter.h"
|
| #include "core/rendering/GraphicsContextAnnotator.h"
|
| #include "core/rendering/HitTestLocation.h"
|
| @@ -1758,214 +1759,7 @@ void RenderBlock::markForPaginationRelayoutIfNeeded(SubtreeLayoutScope& layoutSc
|
|
|
| void RenderBlock::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
|
| {
|
| - ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
|
| -
|
| - LayoutPoint adjustedPaintOffset = paintOffset + location();
|
| -
|
| - PaintPhase phase = paintInfo.phase;
|
| -
|
| - LayoutRect overflowBox;
|
| - // Check if we need to do anything at all.
|
| - // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView
|
| - // paints the root's background.
|
| - if (!isDocumentElement()) {
|
| - overflowBox = overflowRectForPaintRejection();
|
| - flipForWritingMode(overflowBox);
|
| - overflowBox.moveBy(adjustedPaintOffset);
|
| - if (!overflowBox.intersects(paintInfo.rect))
|
| - return;
|
| - }
|
| -
|
| - // There are some cases where not all clipped visual overflow is accounted for.
|
| - // FIXME: reduce the number of such cases.
|
| - ContentsClipBehavior contentsClipBehavior = ForceContentsClip;
|
| - if (hasOverflowClip() && !hasControlClip() && !(shouldPaintSelectionGaps() && phase == PaintPhaseForeground) && !hasCaret())
|
| - contentsClipBehavior = SkipContentsClipIfPossible;
|
| -
|
| - bool pushedClip = pushContentsClip(paintInfo, adjustedPaintOffset, contentsClipBehavior);
|
| - {
|
| - GraphicsContextCullSaver cullSaver(*paintInfo.context);
|
| - // Cull if we have more than one child and we didn't already clip.
|
| - bool shouldCull = document().settings()->containerCullingEnabled() && !pushedClip && !isDocumentElement()
|
| - && firstChild() && lastChild() && firstChild() != lastChild();
|
| - if (shouldCull)
|
| - cullSaver.cull(overflowBox);
|
| -
|
| - paintObject(paintInfo, adjustedPaintOffset);
|
| - }
|
| - if (pushedClip)
|
| - popContentsClip(paintInfo, phase, adjustedPaintOffset);
|
| -
|
| - // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with
|
| - // z-index. We paint after we painted the background/border, so that the scrollbars will
|
| - // sit above the background/border.
|
| - if (hasOverflowClip() && style()->visibility() == VISIBLE && (phase == PaintPhaseBlockBackground || phase == PaintPhaseChildBlockBackground) && paintInfo.shouldPaintWithinRoot(this) && !paintInfo.paintRootBackgroundOnly())
|
| - layer()->scrollableArea()->paintOverflowControls(paintInfo.context, roundedIntPoint(adjustedPaintOffset), paintInfo.rect, false /* paintingOverlayControls */);
|
| -}
|
| -
|
| -void RenderBlock::paintColumnRules(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
|
| -{
|
| - const Color& ruleColor = resolveColor(CSSPropertyWebkitColumnRuleColor);
|
| - bool ruleTransparent = style()->columnRuleIsTransparent();
|
| - EBorderStyle ruleStyle = style()->columnRuleStyle();
|
| - LayoutUnit ruleThickness = style()->columnRuleWidth();
|
| - LayoutUnit colGap = columnGap();
|
| - bool renderRule = ruleStyle > BHIDDEN && !ruleTransparent;
|
| - if (!renderRule)
|
| - return;
|
| -
|
| - ColumnInfo* colInfo = columnInfo();
|
| - unsigned colCount = columnCount(colInfo);
|
| -
|
| - bool antialias = BoxPainter::shouldAntialiasLines(paintInfo.context);
|
| -
|
| - if (colInfo->progressionAxis() == ColumnInfo::InlineAxis) {
|
| - bool leftToRight = style()->isLeftToRightDirection();
|
| - LayoutUnit currLogicalLeftOffset = leftToRight ? LayoutUnit() : contentLogicalWidth();
|
| - LayoutUnit ruleAdd = logicalLeftOffsetForContent();
|
| - LayoutUnit ruleLogicalLeft = leftToRight ? LayoutUnit() : contentLogicalWidth();
|
| - LayoutUnit inlineDirectionSize = colInfo->desiredColumnWidth();
|
| - BoxSide boxSide = isHorizontalWritingMode()
|
| - ? leftToRight ? BSLeft : BSRight
|
| - : leftToRight ? BSTop : BSBottom;
|
| -
|
| - for (unsigned i = 0; i < colCount; i++) {
|
| - // Move to the next position.
|
| - if (leftToRight) {
|
| - ruleLogicalLeft += inlineDirectionSize + colGap / 2;
|
| - currLogicalLeftOffset += inlineDirectionSize + colGap;
|
| - } else {
|
| - ruleLogicalLeft -= (inlineDirectionSize + colGap / 2);
|
| - currLogicalLeftOffset -= (inlineDirectionSize + colGap);
|
| - }
|
| -
|
| - // Now paint the column rule.
|
| - if (i < colCount - 1) {
|
| - LayoutUnit ruleLeft = isHorizontalWritingMode() ? paintOffset.x() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd : paintOffset.x() + borderLeft() + paddingLeft();
|
| - LayoutUnit ruleRight = isHorizontalWritingMode() ? ruleLeft + ruleThickness : ruleLeft + contentWidth();
|
| - LayoutUnit ruleTop = isHorizontalWritingMode() ? paintOffset.y() + borderTop() + paddingTop() : paintOffset.y() + ruleLogicalLeft - ruleThickness / 2 + ruleAdd;
|
| - LayoutUnit ruleBottom = isHorizontalWritingMode() ? ruleTop + contentHeight() : ruleTop + ruleThickness;
|
| - IntRect pixelSnappedRuleRect = pixelSnappedIntRectFromEdges(ruleLeft, ruleTop, ruleRight, ruleBottom);
|
| - drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
|
| - }
|
| -
|
| - ruleLogicalLeft = currLogicalLeftOffset;
|
| - }
|
| - } else {
|
| - bool topToBottom = !style()->isFlippedBlocksWritingMode();
|
| - LayoutUnit ruleLeft = isHorizontalWritingMode()
|
| - ? borderLeft() + paddingLeft()
|
| - : colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore();
|
| - LayoutUnit ruleWidth = isHorizontalWritingMode() ? contentWidth() : ruleThickness;
|
| - LayoutUnit ruleTop = isHorizontalWritingMode()
|
| - ? colGap / 2 - colGap - ruleThickness / 2 + borderBefore() + paddingBefore()
|
| - : borderStart() + paddingStart();
|
| - LayoutUnit ruleHeight = isHorizontalWritingMode() ? ruleThickness : contentHeight();
|
| - LayoutRect ruleRect(ruleLeft, ruleTop, ruleWidth, ruleHeight);
|
| -
|
| - if (!topToBottom) {
|
| - if (isHorizontalWritingMode())
|
| - ruleRect.setY(height() - ruleRect.maxY());
|
| - else
|
| - ruleRect.setX(width() - ruleRect.maxX());
|
| - }
|
| -
|
| - ruleRect.moveBy(paintOffset);
|
| -
|
| - BoxSide boxSide = isHorizontalWritingMode()
|
| - ? topToBottom ? BSTop : BSBottom
|
| - : topToBottom ? BSLeft : BSRight;
|
| -
|
| - LayoutSize step(0, topToBottom ? colInfo->columnHeight() + colGap : -(colInfo->columnHeight() + colGap));
|
| - if (!isHorizontalWritingMode())
|
| - step = step.transposedSize();
|
| -
|
| - for (unsigned i = 1; i < colCount; i++) {
|
| - ruleRect.move(step);
|
| - IntRect pixelSnappedRuleRect = pixelSnappedIntRect(ruleRect);
|
| - drawLineForBoxSide(paintInfo.context, pixelSnappedRuleRect.x(), pixelSnappedRuleRect.y(), pixelSnappedRuleRect.maxX(), pixelSnappedRuleRect.maxY(), boxSide, ruleColor, ruleStyle, 0, 0, antialias);
|
| - }
|
| - }
|
| -}
|
| -
|
| -void RenderBlock::paintColumnContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset, bool paintingFloats)
|
| -{
|
| - // We need to do multiple passes, breaking up our child painting into strips.
|
| - GraphicsContext* context = paintInfo.context;
|
| - ColumnInfo* colInfo = columnInfo();
|
| - unsigned colCount = columnCount(colInfo);
|
| - if (!colCount)
|
| - return;
|
| - LayoutUnit currLogicalTopOffset = 0;
|
| - LayoutUnit colGap = columnGap();
|
| - for (unsigned i = 0; i < colCount; i++) {
|
| - // For each rect, we clip to the rect, and then we adjust our coords.
|
| - LayoutRect colRect = columnRectAt(colInfo, i);
|
| - flipForWritingMode(colRect);
|
| - LayoutUnit logicalLeftOffset = (isHorizontalWritingMode() ? colRect.x() : colRect.y()) - logicalLeftOffsetForContent();
|
| - LayoutSize offset = isHorizontalWritingMode() ? LayoutSize(logicalLeftOffset, currLogicalTopOffset) : LayoutSize(currLogicalTopOffset, logicalLeftOffset);
|
| - if (colInfo->progressionAxis() == ColumnInfo::BlockAxis) {
|
| - if (isHorizontalWritingMode())
|
| - offset.expand(0, colRect.y() - borderTop() - paddingTop());
|
| - else
|
| - offset.expand(colRect.x() - borderLeft() - paddingLeft(), 0);
|
| - }
|
| - colRect.moveBy(paintOffset);
|
| - PaintInfo info(paintInfo);
|
| - info.rect.intersect(enclosingIntRect(colRect));
|
| -
|
| - if (!info.rect.isEmpty()) {
|
| - GraphicsContextStateSaver stateSaver(*context);
|
| - LayoutRect clipRect(colRect);
|
| -
|
| - if (i < colCount - 1) {
|
| - if (isHorizontalWritingMode())
|
| - clipRect.expand(colGap / 2, 0);
|
| - else
|
| - clipRect.expand(0, colGap / 2);
|
| - }
|
| - // Each strip pushes a clip, since column boxes are specified as being
|
| - // like overflow:hidden.
|
| - // FIXME: Content and column rules that extend outside column boxes at the edges of the multi-column element
|
| - // are clipped according to the 'overflow' property.
|
| - context->clip(enclosingIntRect(clipRect));
|
| -
|
| - // Adjust our x and y when painting.
|
| - LayoutPoint adjustedPaintOffset = paintOffset + offset;
|
| - if (paintingFloats)
|
| - paintFloats(info, adjustedPaintOffset, paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip);
|
| - else
|
| - paintContents(info, adjustedPaintOffset);
|
| - }
|
| -
|
| - LayoutUnit blockDelta = (isHorizontalWritingMode() ? colRect.height() : colRect.width());
|
| - if (style()->isFlippedBlocksWritingMode())
|
| - currLogicalTopOffset += blockDelta;
|
| - else
|
| - currLogicalTopOffset -= blockDelta;
|
| - }
|
| -}
|
| -
|
| -void RenderBlock::paintContents(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
|
| -{
|
| - // Avoid painting descendants of the root element when stylesheets haven't loaded. This eliminates FOUC.
|
| - // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
|
| - // will do a full paint invalidation.
|
| - if (document().didLayoutWithPendingStylesheets() && !isRenderView())
|
| - return;
|
| -
|
| - if (childrenInline())
|
| - m_lineBoxes.paint(this, paintInfo, paintOffset);
|
| - else {
|
| - PaintPhase newPhase = (paintInfo.phase == PaintPhaseChildOutlines) ? PaintPhaseOutline : paintInfo.phase;
|
| - newPhase = (newPhase == PaintPhaseChildBlockBackgrounds) ? PaintPhaseChildBlockBackground : newPhase;
|
| -
|
| - // We don't paint our own background, but we do let the kids paint their backgrounds.
|
| - PaintInfo paintInfoForChild(paintInfo);
|
| - paintInfoForChild.phase = newPhase;
|
| - paintInfoForChild.updatePaintingRootForChildren(this);
|
| - paintChildren(paintInfoForChild, paintOffset);
|
| - }
|
| + BlockPainter(*this).paint(paintInfo, paintOffset);
|
| }
|
|
|
| void RenderBlock::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
|
| @@ -2013,114 +1807,9 @@ void RenderBlock::paintAsInlineBlock(RenderObject* renderer, PaintInfo& paintInf
|
| }
|
| }
|
|
|
| -static inline bool caretBrowsingEnabled(const Frame* frame)
|
| -{
|
| - Settings* settings = frame->settings();
|
| - return settings && settings->caretBrowsingEnabled();
|
| -}
|
| -
|
| -static inline bool hasCursorCaret(const FrameSelection& selection, const RenderBlock* block, bool caretBrowsing)
|
| -{
|
| - return selection.caretRenderer() == block && (selection.hasEditableStyle() || caretBrowsing);
|
| -}
|
| -
|
| -static inline bool hasDragCaret(const DragCaretController& dragCaretController, const RenderBlock* block, bool caretBrowsing)
|
| -{
|
| - return dragCaretController.caretRenderer() == block && (dragCaretController.isContentEditable() || caretBrowsing);
|
| -}
|
| -
|
| -bool RenderBlock::hasCaret() const
|
| -{
|
| - bool caretBrowsing = caretBrowsingEnabled(frame());
|
| - return hasCursorCaret(frame()->selection(), this, caretBrowsing)
|
| - || hasDragCaret(frame()->page()->dragCaretController(), this, caretBrowsing);
|
| -}
|
| -
|
| -void RenderBlock::paintCarets(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
|
| -{
|
| - bool caretBrowsing = caretBrowsingEnabled(frame());
|
| -
|
| - FrameSelection& selection = frame()->selection();
|
| - if (hasCursorCaret(selection, this, caretBrowsing)) {
|
| - selection.paintCaret(paintInfo.context, paintOffset, paintInfo.rect);
|
| - }
|
| -
|
| - DragCaretController& dragCaretController = frame()->page()->dragCaretController();
|
| - if (hasDragCaret(dragCaretController, this, caretBrowsing)) {
|
| - dragCaretController.paintDragCaret(frame(), paintInfo.context, paintOffset, paintInfo.rect);
|
| - }
|
| -}
|
| -
|
| void RenderBlock::paintObject(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
|
| {
|
| - PaintPhase paintPhase = paintInfo.phase;
|
| -
|
| - // Adjust our painting position if we're inside a scrolled layer (e.g., an overflow:auto div).
|
| - LayoutPoint scrolledOffset = paintOffset;
|
| - if (hasOverflowClip())
|
| - scrolledOffset.move(-scrolledContentOffset());
|
| -
|
| - // 1. paint background, borders etc
|
| - if ((paintPhase == PaintPhaseBlockBackground || paintPhase == PaintPhaseChildBlockBackground) && style()->visibility() == VISIBLE) {
|
| - if (hasBoxDecorationBackground())
|
| - paintBoxDecorationBackground(paintInfo, paintOffset);
|
| - if (hasColumns() && !paintInfo.paintRootBackgroundOnly())
|
| - paintColumnRules(paintInfo, scrolledOffset);
|
| - }
|
| -
|
| - if (paintPhase == PaintPhaseMask && style()->visibility() == VISIBLE) {
|
| - paintMask(paintInfo, paintOffset);
|
| - return;
|
| - }
|
| -
|
| - if (paintPhase == PaintPhaseClippingMask && style()->visibility() == VISIBLE) {
|
| - paintClippingMask(paintInfo, paintOffset);
|
| - return;
|
| - }
|
| -
|
| - // We're done. We don't bother painting any children.
|
| - if (paintPhase == PaintPhaseBlockBackground || paintInfo.paintRootBackgroundOnly())
|
| - return;
|
| -
|
| - // 2. paint contents
|
| - if (paintPhase != PaintPhaseSelfOutline) {
|
| - if (hasColumns())
|
| - paintColumnContents(paintInfo, scrolledOffset);
|
| - else
|
| - paintContents(paintInfo, scrolledOffset);
|
| - }
|
| -
|
| - // 3. paint selection
|
| - // FIXME: Make this work with multi column layouts. For now don't fill gaps.
|
| - bool isPrinting = document().printing();
|
| - if (!isPrinting && !hasColumns())
|
| - paintSelection(paintInfo, scrolledOffset); // Fill in gaps in selection on lines and between blocks.
|
| -
|
| - // 4. paint floats.
|
| - if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip) {
|
| - if (hasColumns())
|
| - paintColumnContents(paintInfo, scrolledOffset, true);
|
| - else
|
| - paintFloats(paintInfo, scrolledOffset, paintPhase == PaintPhaseSelection || paintPhase == PaintPhaseTextClip);
|
| - }
|
| -
|
| - // 5. paint outline.
|
| - if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && style()->hasOutline() && style()->visibility() == VISIBLE) {
|
| - // Don't paint focus ring for anonymous block continuation because the
|
| - // inline element having outline-style:auto paints the whole focus ring.
|
| - if (!style()->outlineStyleIsAuto() || !isAnonymousBlockContinuation())
|
| - paintOutline(paintInfo, LayoutRect(paintOffset, size()));
|
| - }
|
| -
|
| - // 6. paint continuation outlines.
|
| - if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseChildOutlines))
|
| - paintContinuationOutlines(paintInfo, paintOffset);
|
| -
|
| - // 7. paint caret.
|
| - // If the caret's node's render object's containing block is this block, and the paint action is PaintPhaseForeground,
|
| - // then paint the caret.
|
| - if (paintPhase == PaintPhaseForeground)
|
| - paintCarets(paintInfo, paintOffset);
|
| + BlockPainter(*this).paintObject(paintInfo, paintOffset);
|
| }
|
|
|
| RenderInline* RenderBlock::inlineElementContinuation() const
|
|
|