Exemplo n.º 1
0
void BlockPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    Optional<SubtreeRecorder> subtreeRecorder;
    if (needsSubtreeRecorder(m_layoutBlock)) {
        subtreeRecorder.emplace(*paintInfo.context, m_layoutBlock, paintInfo.phase);
        if (subtreeRecorder->canUseCache())
            return;
    }

    PaintInfo localPaintInfo(paintInfo);

    LayoutPoint adjustedPaintOffset = paintOffset + m_layoutBlock.location();

    PaintPhase originalPhase = localPaintInfo.phase;

    // Check if we need to do anything at all.
    LayoutRect overflowBox = overflowRectForPaintRejection();
    m_layoutBlock.flipForWritingMode(overflowBox);
    overflowBox.moveBy(adjustedPaintOffset);
    if (!overflowBox.intersects(LayoutRect(localPaintInfo.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 (m_layoutBlock.hasOverflowClip() && !m_layoutBlock.hasControlClip() && !(m_layoutBlock.shouldPaintSelectionGaps() && originalPhase == PaintPhaseForeground) && !hasCaret())
        contentsClipBehavior = SkipContentsClipIfPossible;

    if (localPaintInfo.phase == PaintPhaseOutline) {
        localPaintInfo.phase = PaintPhaseChildOutlines;
    } else if (localPaintInfo.phase == PaintPhaseChildBlockBackground) {
        localPaintInfo.phase = PaintPhaseBlockBackground;
        m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
        localPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
    }

    {
        BoxClipper boxClipper(m_layoutBlock, localPaintInfo, adjustedPaintOffset, contentsClipBehavior);
        m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
    }

    if (originalPhase == PaintPhaseOutline) {
        localPaintInfo.phase = PaintPhaseSelfOutline;
        m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
        localPaintInfo.phase = originalPhase;
    } else if (originalPhase == PaintPhaseChildBlockBackground) {
        localPaintInfo.phase = originalPhase;
    }

    // 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.
    paintOverflowControlsIfNeeded(localPaintInfo, adjustedPaintOffset);
}